mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
Merge branch 'master' into vm
This commit is contained in:
commit
d5968e7f4e
51 changed files with 92141 additions and 1108 deletions
97
INSTALL
97
INSTALL
|
@ -2,15 +2,15 @@ Installation Instructions
|
|||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package.
|
||||
|
@ -67,15 +67,12 @@ The simplest way to compile this package is:
|
|||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
6. Often, you can also type `make uninstall' to remove the installed
|
||||
files again.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
|
@ -88,7 +85,7 @@ is an example:
|
|||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
|
@ -100,24 +97,10 @@ architecture at a time in the source code directory. After you have
|
|||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
@ -140,7 +123,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
|||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
|
@ -152,36 +135,14 @@ find the X include and library files automatically, but if it doesn't,
|
|||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
|
@ -207,9 +168,9 @@ eventually be run) with `--host=TYPE'.
|
|||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
|
@ -218,7 +179,7 @@ A warning: not all `configure' scripts look for a site script.
|
|||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
|
@ -237,19 +198,11 @@ an Autoconf bug. Until the bug is fixed you can use this workaround:
|
|||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
|
@ -276,16 +229,6 @@ operates.
|
|||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *Note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
|
|
280
gc-benchmarks/gc-profile.scm
Executable file
280
gc-benchmarks/gc-profile.scm
Executable file
|
@ -0,0 +1,280 @@
|
|||
#!/bin/sh
|
||||
# -*- Scheme -*-
|
||||
exec ${GUILE-guile} --no-debug -q -l "$0" \
|
||||
-c '(apply main (cdr (command-line)))' "$@"
|
||||
!#
|
||||
;;; Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
;;;
|
||||
;;; This program is free software; you can redistribute it and/or modify
|
||||
;;; it under the terms of the GNU General Public License as published by
|
||||
;;; the Free Software Foundation; either version 2, or (at your option)
|
||||
;;; any later version.
|
||||
;;;
|
||||
;;; This program is distributed in the hope that it will be useful,
|
||||
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;;; GNU General Public License for more details.
|
||||
;;;
|
||||
;;; You should have received a copy of the GNU General Public License
|
||||
;;; along with this software; see the file COPYING. If not, write to
|
||||
;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
;;; Boston, MA 02110-1301 USA
|
||||
|
||||
(use-modules (ice-9 format)
|
||||
(ice-9 rdelim)
|
||||
(ice-9 regex)
|
||||
(srfi srfi-1)
|
||||
(srfi srfi-37)
|
||||
(srfi srfi-39))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Memory usage.
|
||||
;;;
|
||||
|
||||
(define (memory-mappings pid)
|
||||
"Return an list of alists, each of which contains information about a
|
||||
memory mapping of process @var{pid}. This information is obtained by reading
|
||||
@file{/proc/PID/smaps} on Linux. See `procs(5)' for details."
|
||||
|
||||
(define mapping-line-rx
|
||||
(make-regexp
|
||||
"^([[:xdigit:]]+)-([[:xdigit:]]+) ([rwx-]{3}[ps]) ([[:xdigit:]]+) [0-9]{2}:[0-9]{2} [0-9]+[[:blank:]]+(.*)$"))
|
||||
|
||||
(define rss-line-rx
|
||||
(make-regexp
|
||||
"^Rss:[[:blank:]]+([[:digit:]]+) kB$"))
|
||||
|
||||
(with-input-from-port (open-input-file (format #f "/proc/~a/smaps" pid))
|
||||
(lambda ()
|
||||
(let loop ((line (read-line))
|
||||
(result '()))
|
||||
(if (eof-object? line)
|
||||
(reverse result)
|
||||
(cond ((regexp-exec mapping-line-rx line)
|
||||
=>
|
||||
(lambda (match)
|
||||
(let ((mapping-start (string->number
|
||||
(match:substring match 1)
|
||||
16))
|
||||
(mapping-end (string->number
|
||||
(match:substring match 2)
|
||||
16))
|
||||
(access-bits (match:substring match 3))
|
||||
(name (match:substring match 5)))
|
||||
(loop (read-line)
|
||||
(cons `((mapping-start . ,mapping-start)
|
||||
(mapping-end . ,mapping-end)
|
||||
(access-bits . ,access-bits)
|
||||
(name . ,(if (string=? name "")
|
||||
#f
|
||||
name)))
|
||||
result)))))
|
||||
((regexp-exec rss-line-rx line)
|
||||
=>
|
||||
(lambda (match)
|
||||
(let ((section+ (cons (cons 'rss
|
||||
(string->number
|
||||
(match:substring match 1)))
|
||||
(car result))))
|
||||
(loop (read-line)
|
||||
(cons section+ (cdr result))))))
|
||||
(else
|
||||
(loop (read-line) result))))))))
|
||||
|
||||
(define (total-heap-size pid)
|
||||
"Return the total heap size of process @var{pid}."
|
||||
|
||||
(define heap-or-anon-rx
|
||||
(make-regexp "\\[(heap|anon)\\]"))
|
||||
|
||||
(define private-mapping-rx
|
||||
(make-regexp "^[r-][w-][x-]p$"))
|
||||
|
||||
(fold (lambda (heap total+rss)
|
||||
(let ((name (assoc-ref heap 'name))
|
||||
(perm (assoc-ref heap 'access-bits)))
|
||||
;; Include anonymous private mappings.
|
||||
(if (or (and (not name)
|
||||
(regexp-exec private-mapping-rx perm))
|
||||
(and name
|
||||
(regexp-exec heap-or-anon-rx name)))
|
||||
(let ((start (assoc-ref heap 'mapping-start))
|
||||
(end (assoc-ref heap 'mapping-end))
|
||||
(rss (assoc-ref heap 'rss)))
|
||||
(cons (+ (car total+rss) (- end start))
|
||||
(+ (cdr total+rss) rss)))
|
||||
total+rss)))
|
||||
'(0 . 0)
|
||||
(memory-mappings pid)))
|
||||
|
||||
|
||||
(define (display-stats start end)
|
||||
(define (->usecs sec+usecs)
|
||||
(+ (* 1000000 (car sec+usecs))
|
||||
(cdr sec+usecs)))
|
||||
|
||||
(let ((usecs (- (->usecs end) (->usecs start)))
|
||||
(heap-size (total-heap-size (getpid)))
|
||||
(gc-heap-size (assoc-ref (gc-stats) 'heap-size)))
|
||||
|
||||
(format #t "execution time: ~6,3f seconds~%"
|
||||
(/ usecs 1000000.0))
|
||||
|
||||
(and gc-heap-size
|
||||
(format #t "GC-reported heap size: ~8d B (~1,2f MiB)~%"
|
||||
gc-heap-size
|
||||
(/ gc-heap-size 1024.0 1024.0)))
|
||||
|
||||
(format #t "heap size: ~8d B (~1,2f MiB)~%"
|
||||
(car heap-size)
|
||||
(/ (car heap-size) 1024.0 1024.0))
|
||||
(format #t "heap RSS: ~8d KiB (~1,2f MiB)~%"
|
||||
(cdr heap-size)
|
||||
(/ (cdr heap-size) 1024.0))
|
||||
;; (system (format #f "cat /proc/~a/smaps" (getpid)))
|
||||
;; (system (format #f "exmtool procs | grep -E '^(PID|~a)'" (getpid)))
|
||||
))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Larceny/Twobit benchmarking compability layer.
|
||||
;;;
|
||||
|
||||
(define *iteration-count*
|
||||
(make-parameter #f))
|
||||
|
||||
(define (run-benchmark name . args)
|
||||
"A @code{run-benchmark} procedure compatible with Larceny's GC benchmarking
|
||||
framework. See
|
||||
@url{http://www.ccs.neu.edu/home/will/Twobit/benchmarksAbout.html} for
|
||||
details."
|
||||
|
||||
(define %concise-invocation?
|
||||
;; This procedure can be called with only two arguments, NAME and
|
||||
;; RUN-MAKER.
|
||||
(procedure? (car args)))
|
||||
|
||||
(let ((count (or (*iteration-count*)
|
||||
(if %concise-invocation? 0 (car args))))
|
||||
(run-maker (if %concise-invocation? (car args) (cadr args)))
|
||||
(ok? (if %concise-invocation?
|
||||
(lambda (result) #t)
|
||||
(caddr args)))
|
||||
(args (if %concise-invocation? '() (cdddr args))))
|
||||
(let loop ((i 0))
|
||||
(and (< i count)
|
||||
(let ((result (apply run-maker args)))
|
||||
(if (not (ok? result))
|
||||
(begin
|
||||
(format (current-output-port) "invalid result for `~A'~%"
|
||||
name)
|
||||
(exit 1)))
|
||||
(loop (1+ i)))))))
|
||||
|
||||
(define (save-directory-excursion directory thunk)
|
||||
(let ((previous-dir (getcwd)))
|
||||
(dynamic-wind
|
||||
(lambda ()
|
||||
(chdir directory))
|
||||
thunk
|
||||
(lambda ()
|
||||
(chdir previous-dir)))))
|
||||
|
||||
(define (load-larceny-benchmark file)
|
||||
"Load the Larceny benchmark from @var{file}."
|
||||
(let ((name (let ((base (basename file)))
|
||||
(substring base 0 (or (string-rindex base #\.)
|
||||
(string-length base)))))
|
||||
(module (let ((m (make-module)))
|
||||
(beautify-user-module! m)
|
||||
(module-use! m (resolve-interface '(ice-9 syncase)))
|
||||
m)))
|
||||
(save-directory-excursion (dirname file)
|
||||
(lambda ()
|
||||
(save-module-excursion
|
||||
(lambda ()
|
||||
(set-current-module module)
|
||||
(module-define! module 'run-benchmark run-benchmark)
|
||||
(load (basename file))
|
||||
|
||||
;; Invoke the benchmark's entry point.
|
||||
(let ((entry (module-ref (current-module)
|
||||
(symbol-append (string->symbol name)
|
||||
'-benchmark))))
|
||||
(entry))))))))
|
||||
|
||||
|
||||
|
||||
;;;
|
||||
;;; Option processing.
|
||||
;;;
|
||||
|
||||
(define %options
|
||||
(list (option '(#\h "help") #f #f
|
||||
(lambda args
|
||||
(show-help)
|
||||
(exit 0)))
|
||||
(option '(#\l "larceny") #f #f
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'larceny? #t result)))
|
||||
(option '(#\i "iterations") #t #f
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'iterations (string->number arg) result)))))
|
||||
|
||||
(define (show-help)
|
||||
(format #t "Usage: gc-profile [OPTIONS] FILE.SCM
|
||||
Load FILE.SCM, a Guile Scheme source file, and report its execution time and
|
||||
final heap usage.
|
||||
|
||||
-h, --help Show this help message
|
||||
|
||||
-l, --larceny Provide mechanisms compatible with the Larceny/Twobit
|
||||
GC benchmark suite.
|
||||
-i, --iterations=COUNT
|
||||
Run the given benchmark COUNT times, regardless of the
|
||||
iteration count passed to `run-benchmark' (for Larceny
|
||||
benchmarks).
|
||||
|
||||
Report bugs to <bug-guile@gnu.org>.~%"))
|
||||
|
||||
(define (parse-args args)
|
||||
(define (leave fmt . args)
|
||||
(apply format (current-error-port) (string-append fmt "~%") args)
|
||||
(exit 1))
|
||||
|
||||
(args-fold args %options
|
||||
(lambda (opt name arg result)
|
||||
(leave "~A: unrecognized option" opt))
|
||||
(lambda (file result)
|
||||
(if (pair? (assoc 'input result))
|
||||
(leave "~a: only one input file at a time" file)
|
||||
(alist-cons 'input file result)))
|
||||
'()))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Main program.
|
||||
;;;
|
||||
|
||||
(define (main . args)
|
||||
(let* ((options (parse-args args))
|
||||
(prog (assoc-ref options 'input))
|
||||
(load (if (assoc-ref options 'larceny?)
|
||||
load-larceny-benchmark
|
||||
load)))
|
||||
|
||||
(parameterize ((*iteration-count* (assoc-ref options 'iterations)))
|
||||
(format #t "running `~a' with Guile ~a...~%" prog (version))
|
||||
|
||||
(let ((start (gettimeofday)))
|
||||
(dynamic-wind
|
||||
(lambda ()
|
||||
#t)
|
||||
(lambda ()
|
||||
(set! quit (lambda args args))
|
||||
(load prog))
|
||||
(lambda ()
|
||||
(let ((end (gettimeofday)))
|
||||
(format #t "done~%")
|
||||
(display-stats start end))))))))
|
210
gc-benchmarks/gcbench.scm
Normal file
210
gc-benchmarks/gcbench.scm
Normal file
|
@ -0,0 +1,210 @@
|
|||
; This is adapted from a benchmark written by John Ellis and Pete Kovac
|
||||
; of Post Communications.
|
||||
; It was modified by Hans Boehm of Silicon Graphics.
|
||||
; It was translated into Scheme by William D Clinger of Northeastern Univ;
|
||||
; the Scheme version uses (RUN-BENCHMARK <string> <thunk>)
|
||||
; Last modified 30 May 1997.
|
||||
;
|
||||
; This is no substitute for real applications. No actual application
|
||||
; is likely to behave in exactly this way. However, this benchmark was
|
||||
; designed to be more representative of real applications than other
|
||||
; Java GC benchmarks of which we are aware.
|
||||
; It attempts to model those properties of allocation requests that
|
||||
; are important to current GC techniques.
|
||||
; It is designed to be used either to obtain a single overall performance
|
||||
; number, or to give a more detailed estimate of how collector
|
||||
; performance varies with object lifetimes. It prints the time
|
||||
; required to allocate and collect balanced binary trees of various
|
||||
; sizes. Smaller trees result in shorter object lifetimes. Each cycle
|
||||
; allocates roughly the same amount of memory.
|
||||
; Two data structures are kept around during the entire process, so
|
||||
; that the measured performance is representative of applications
|
||||
; that maintain some live in-memory data. One of these is a tree
|
||||
; containing many pointers. The other is a large array containing
|
||||
; double precision floating point numbers. Both should be of comparable
|
||||
; size.
|
||||
;
|
||||
; The results are only really meaningful together with a specification
|
||||
; of how much memory was used. It is possible to trade memory for
|
||||
; better time performance. This benchmark should be run in a 32 MB
|
||||
; heap, though we don't currently know how to enforce that uniformly.
|
||||
|
||||
; In the Java version, this routine prints the heap size and the amount
|
||||
; of free memory. There is no portable way to do this in Scheme; each
|
||||
; implementation needs its own version.
|
||||
|
||||
(use-modules (ice-9 syncase))
|
||||
|
||||
(define (PrintDiagnostics)
|
||||
(display " Total memory available= ???????? bytes")
|
||||
(display " Free memory= ???????? bytes")
|
||||
(newline))
|
||||
|
||||
|
||||
|
||||
(define (run-benchmark str thu)
|
||||
(display str)
|
||||
(thu))
|
||||
; Should we implement a Java class as procedures or hygienic macros?
|
||||
; Take your pick.
|
||||
|
||||
(define-syntax let-class
|
||||
(syntax-rules
|
||||
()
|
||||
|
||||
;; Put this rule first to implement a class using procedures.
|
||||
((let-class (((method . args) . method-body) ...) . body)
|
||||
(let () (define (method . args) . method-body) ... . body))
|
||||
|
||||
|
||||
;; Put this rule first to implement a class using hygienic macros.
|
||||
((let-class (((method . args) . method-body) ...) . body)
|
||||
(letrec-syntax ((method (syntax-rules () ((method . args) (begin . method-body))))
|
||||
...)
|
||||
. body))
|
||||
|
||||
|
||||
))
|
||||
|
||||
|
||||
(define (gcbench kStretchTreeDepth)
|
||||
|
||||
; Nodes used by a tree of a given size
|
||||
(define (TreeSize i)
|
||||
(- (expt 2 (+ i 1)) 1))
|
||||
|
||||
; Number of iterations to use for a given tree depth
|
||||
(define (NumIters i)
|
||||
(quotient (* 2 (TreeSize kStretchTreeDepth))
|
||||
(TreeSize i)))
|
||||
|
||||
; Parameters are determined by kStretchTreeDepth.
|
||||
; In Boehm's version the parameters were fixed as follows:
|
||||
; public static final int kStretchTreeDepth = 18; // about 16Mb
|
||||
; public static final int kLongLivedTreeDepth = 16; // about 4Mb
|
||||
; public static final int kArraySize = 500000; // about 4Mb
|
||||
; public static final int kMinTreeDepth = 4;
|
||||
; public static final int kMaxTreeDepth = 16;
|
||||
; In Larceny the storage numbers above would be 12 Mby, 3 Mby, 6 Mby.
|
||||
|
||||
(let* ((kLongLivedTreeDepth (- kStretchTreeDepth 2))
|
||||
(kArraySize (* 4 (TreeSize kLongLivedTreeDepth)))
|
||||
(kMinTreeDepth 4)
|
||||
(kMaxTreeDepth kLongLivedTreeDepth))
|
||||
|
||||
; Elements 3 and 4 of the allocated vectors are useless.
|
||||
|
||||
(let-class (((make-node l r)
|
||||
(let ((v (make-empty-node)))
|
||||
(vector-set! v 0 l)
|
||||
(vector-set! v 1 r)
|
||||
v))
|
||||
((make-empty-node) (make-vector 4 0))
|
||||
((node.left node) (vector-ref node 0))
|
||||
((node.right node) (vector-ref node 1))
|
||||
((node.left-set! node x) (vector-set! node 0 x))
|
||||
((node.right-set! node x) (vector-set! node 1 x)))
|
||||
|
||||
; Build tree top down, assigning to older objects.
|
||||
(define (Populate iDepth thisNode)
|
||||
(if (<= iDepth 0)
|
||||
#f
|
||||
(let ((iDepth (- iDepth 1)))
|
||||
(node.left-set! thisNode (make-empty-node))
|
||||
(node.right-set! thisNode (make-empty-node))
|
||||
(Populate iDepth (node.left thisNode))
|
||||
(Populate iDepth (node.right thisNode)))))
|
||||
|
||||
; Build tree bottom-up
|
||||
(define (MakeTree iDepth)
|
||||
(if (<= iDepth 0)
|
||||
(make-empty-node)
|
||||
(make-node (MakeTree (- iDepth 1))
|
||||
(MakeTree (- iDepth 1)))))
|
||||
|
||||
(define (TimeConstruction depth)
|
||||
(let ((iNumIters (NumIters depth)))
|
||||
(display (string-append "Creating "
|
||||
(number->string iNumIters)
|
||||
" trees of depth "
|
||||
(number->string depth)))
|
||||
(newline)
|
||||
(run-benchmark "GCBench: Top down construction"
|
||||
(lambda ()
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i iNumIters))
|
||||
(Populate depth (make-empty-node)))))
|
||||
(run-benchmark "GCBench: Bottom up construction"
|
||||
(lambda ()
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i iNumIters))
|
||||
(MakeTree depth))))))
|
||||
|
||||
(define (main)
|
||||
(display "Garbage Collector Test")
|
||||
(newline)
|
||||
(display (string-append
|
||||
" Stretching memory with a binary tree of depth "
|
||||
(number->string kStretchTreeDepth)))
|
||||
(newline)
|
||||
(run-benchmark "GCBench: Main"
|
||||
(lambda ()
|
||||
; Stretch the memory space quickly
|
||||
(MakeTree kStretchTreeDepth)
|
||||
|
||||
; Create a long lived object
|
||||
(display (string-append
|
||||
" Creating a long-lived binary tree of depth "
|
||||
(number->string kLongLivedTreeDepth)))
|
||||
(newline)
|
||||
(let ((longLivedTree (make-empty-node)))
|
||||
(Populate kLongLivedTreeDepth longLivedTree)
|
||||
|
||||
; Create long-lived array, filling half of it
|
||||
(display (string-append
|
||||
" Creating a long-lived array of "
|
||||
(number->string kArraySize)
|
||||
" inexact reals"))
|
||||
(newline)
|
||||
(let ((array (make-vector kArraySize 0.0)))
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i (quotient kArraySize 2)))
|
||||
(vector-set! array i (/ 1.0 (exact->inexact i))))
|
||||
(PrintDiagnostics)
|
||||
|
||||
(do ((d kMinTreeDepth (+ d 2)))
|
||||
((> d kMaxTreeDepth))
|
||||
(TimeConstruction d))
|
||||
|
||||
(if (or (eq? longLivedTree '())
|
||||
(let ((n (min 1000
|
||||
(- (quotient (vector-length array)
|
||||
2)
|
||||
1))))
|
||||
(not (= (vector-ref array n)
|
||||
(/ 1.0 (exact->inexact
|
||||
n))))))
|
||||
(begin (display "Failed") (newline)))
|
||||
; fake reference to LongLivedTree
|
||||
; and array
|
||||
; to keep them from being optimized away
|
||||
))))
|
||||
(PrintDiagnostics))
|
||||
|
||||
(main))))
|
||||
|
||||
(define (gc-benchmark . rest)
|
||||
(let ((k (if (null? rest) 18 (car rest))))
|
||||
(display "The garbage collector should touch about ")
|
||||
(display (expt 2 (- k 13)))
|
||||
(display " megabytes of heap storage.")
|
||||
(newline)
|
||||
(display "The use of more or less memory will skew the results.")
|
||||
(newline)
|
||||
(run-benchmark (string-append "GCBench" (number->string k))
|
||||
(lambda () (gcbench k)))))
|
||||
|
||||
|
||||
|
||||
(gc-benchmark )
|
||||
(display (gc-stats))
|
9
gc-benchmarks/guile-test.scm
Normal file
9
gc-benchmarks/guile-test.scm
Normal file
|
@ -0,0 +1,9 @@
|
|||
(set! %load-path (cons (string-append (getenv "HOME") "/src/guile")
|
||||
%load-path))
|
||||
|
||||
(load "../test-suite/guile-test")
|
||||
|
||||
(main `("guile-test"
|
||||
"--test-suite" ,(string-append (getenv "HOME")
|
||||
"/src/guile/test-suite/tests")
|
||||
"--log-file" ",,test-suite.log"))
|
340
gc-benchmarks/larceny/GPL
Normal file
340
gc-benchmarks/larceny/GPL
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
92
gc-benchmarks/larceny/README
Normal file
92
gc-benchmarks/larceny/README
Normal file
|
@ -0,0 +1,92 @@
|
|||
Source Code for Selected GC Benchmarks
|
||||
|
||||
These benchmarks are derived from the benchmarks that Lars Hansen used for
|
||||
his thesis on Older-first garbage collection in practice . That thesis
|
||||
contains storage profiles and detailed discussion for most of these
|
||||
benchmarks.
|
||||
|
||||
Portability
|
||||
|
||||
Apart from a run-benchmark procedure, most of these benchmarks are intended
|
||||
to run in any R5RS-conforming implementation of Scheme. (The softscheme
|
||||
benchmark is an exception.) Please report any portability problems that you
|
||||
encounter.
|
||||
|
||||
To find the main entry point(s) of a benchmark, search for calls to
|
||||
run-benchmark, which calculates and reports the run time and any other
|
||||
relevant statistics. The run-benchmark procedure is
|
||||
implementation-dependent; see run-benchmark.chez for an example of how to
|
||||
write it.
|
||||
|
||||
GC Benchmarks
|
||||
|
||||
To obtain a gzip'ed tar file containing source code for all of the
|
||||
benchmarks described below, click here .
|
||||
|
||||
dummy
|
||||
Description: A null benchmark for testing the implementation-specific
|
||||
run-benchmark procedure.
|
||||
dynamic
|
||||
Description: Fritz Henglein's algorithm for dynamic type inference.
|
||||
Three inputs are available for this benchmark. In increasing order of
|
||||
size, they are:
|
||||
1. dynamic.sch, the code for the benchmark itself
|
||||
2. dynamic-input-small.sch, which is macro-expanded code for the
|
||||
Twobit compiler
|
||||
3. dynamic-input-large.sch, which is macro-expanded code for the
|
||||
Twobit compiler and SPARC assembler.
|
||||
earley
|
||||
Description: Earley's context-free parsing algorithm, as implemented by
|
||||
Marc Feeley, given a simple ambiguous grammar, generating all the parse
|
||||
trees for a short input.
|
||||
gcbench
|
||||
Description: A synthetic benchmark originally written in Java by John
|
||||
Ellis, Pete Kovac, and Hans Boehm.
|
||||
graphs
|
||||
Description: Enumeration of directed graphs, possibly written by Jim
|
||||
Miller. Makes heavy use of higher-order procedures.
|
||||
lattice
|
||||
Description: Enumeration of lattices of monotone maps between lattices,
|
||||
obtained from Andrew Wright, possibly written by Wright or Jim Miller.
|
||||
nboyer
|
||||
Description: Bob Boyer's theorem proving benchmark, with a scaling
|
||||
parameter suggested by Boyer, some bug fixes noted by Henry Baker and
|
||||
ourselves, and rewritten to use a more reasonable representation for
|
||||
the database (with constant-time lookups) instead of property lists
|
||||
(which gave linear-time lookups for the most widely distributed form of
|
||||
the boyer benchmark in Scheme).
|
||||
nucleic2
|
||||
Description: Marc Feeley et al's Pseudoknot benchmark, revised to use
|
||||
R5RS macros instead of implementation-dependent macro systems.
|
||||
perm
|
||||
Description: Zaks's algorithm for generating a list of permutations.
|
||||
This is a diabolical garbage collection benchmark with four parameters
|
||||
M, N, K, and L. The MpermNKL benchmark allocates a queue of size K and
|
||||
then performs M iterations of the following operation: Fill the queue
|
||||
with individually computed copies of all permutations of a list of size
|
||||
N, and then remove the oldest L copies from the queue. At the end of
|
||||
each iteration, the oldest L/K of the live storage becomes garbage, and
|
||||
object lifetimes are distributed uniformly between two volumes that
|
||||
depend upon N, K, and L.
|
||||
sboyer
|
||||
Description: This is the nboyer benchmark with a small but effective
|
||||
tweak: shared consing as implemented by Henry Baker.
|
||||
softscheme
|
||||
Description: Andrew's Wright's soft type inference for Scheme. This
|
||||
software is covered by the GNU GENERAL PUBLIC LICENSE. This benchmark
|
||||
is nonportable because it uses a low-level syntax definition to define
|
||||
a non-hygienic defmacro construct. Requires an input file; the inputs
|
||||
used with the dynamic and twobit benchmarks should be suitable.
|
||||
twobit
|
||||
Description: A portable version of the Twobit Scheme compiler and
|
||||
Larceny's SPARC assembler, written by Will Clinger and Lars Hansen. Two
|
||||
input files are provided:
|
||||
1. twobit-input-short.sch, the nucleic2 benchmark stripped of
|
||||
implementation-specific alternatives to its R4RS macros
|
||||
2. twobit.sch, the twobit benchmark itself
|
||||
twobit-smaller.sch
|
||||
Description: The twobit benchmark without the SPARC assembler.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Last updated 4 April 2001.
|
21
gc-benchmarks/larceny/dumb.sch
Normal file
21
gc-benchmarks/larceny/dumb.sch
Normal file
|
@ -0,0 +1,21 @@
|
|||
; Dumb benchmark to test the reporting of words marked during gc.
|
||||
; Example: (foo 1000000)
|
||||
|
||||
(define (ballast bytes)
|
||||
(do ((bytes bytes (- bytes 8))
|
||||
(x '() (cons bytes x)))
|
||||
((zero? bytes) x)))
|
||||
|
||||
(define (words-benchmark bytes0 bytes1)
|
||||
(let ((x (ballast bytes0)))
|
||||
(do ((bytes1 bytes1 (- bytes1 8)))
|
||||
((not (positive? bytes1))
|
||||
(car (last-pair x)))
|
||||
(cons (car x) bytes1))))
|
||||
|
||||
(define (foo n)
|
||||
(collect)
|
||||
(display-memstats (memstats))
|
||||
(run-benchmark "foo" (lambda () (words-benchmark 1000000 n)) 1)
|
||||
(display-memstats (memstats)))
|
||||
|
19
gc-benchmarks/larceny/dummy.sch
Normal file
19
gc-benchmarks/larceny/dummy.sch
Normal file
|
@ -0,0 +1,19 @@
|
|||
; Dummy benchmark (for testing)
|
||||
;
|
||||
; $Id: dummy.sch,v 1.2 1999/07/12 18:03:37 lth Exp $
|
||||
|
||||
(define (dummy-benchmark . args)
|
||||
(run-benchmark "dummy"
|
||||
1
|
||||
(lambda ()
|
||||
(collect)
|
||||
(display "This is the dummy benchmark!")
|
||||
(newline)
|
||||
(display "My arguments are: ")
|
||||
(display args)
|
||||
(newline)
|
||||
args)
|
||||
(lambda (result)
|
||||
(equal? result args))))
|
||||
|
||||
; eof
|
2111
gc-benchmarks/larceny/dynamic-input-large.sch
Normal file
2111
gc-benchmarks/larceny/dynamic-input-large.sch
Normal file
File diff suppressed because one or more lines are too long
1201
gc-benchmarks/larceny/dynamic-input-small.sch
Normal file
1201
gc-benchmarks/larceny/dynamic-input-small.sch
Normal file
File diff suppressed because one or more lines are too long
2348
gc-benchmarks/larceny/dynamic.sch
Normal file
2348
gc-benchmarks/larceny/dynamic.sch
Normal file
File diff suppressed because it is too large
Load diff
658
gc-benchmarks/larceny/earley.sch
Normal file
658
gc-benchmarks/larceny/earley.sch
Normal file
|
@ -0,0 +1,658 @@
|
|||
;;; EARLEY -- Earley's parser, written by Marc Feeley.
|
||||
|
||||
; $Id: earley.sch,v 1.2 1999/07/12 18:05:19 lth Exp $
|
||||
; 990708 / lth -- changed 'main' to 'earley-benchmark'.
|
||||
;
|
||||
; (make-parser grammar lexer) is used to create a parser from the grammar
|
||||
; description `grammar' and the lexer function `lexer'.
|
||||
;
|
||||
; A grammar is a list of definitions. Each definition defines a non-terminal
|
||||
; by a set of rules. Thus a definition has the form: (nt rule1 rule2...).
|
||||
; A given non-terminal can only be defined once. The first non-terminal
|
||||
; defined is the grammar's goal. Each rule is a possibly empty list of
|
||||
; non-terminals. Thus a rule has the form: (nt1 nt2...). A non-terminal
|
||||
; can be any scheme value. Note that all grammar symbols are treated as
|
||||
; non-terminals. This is fine though because the lexer will be outputing
|
||||
; non-terminals.
|
||||
;
|
||||
; The lexer defines what a token is and the mapping between tokens and
|
||||
; the grammar's non-terminals. It is a function of one argument, the input,
|
||||
; that returns the list of tokens corresponding to the input. Each token is
|
||||
; represented by a list. The first element is some `user-defined' information
|
||||
; associated with the token and the rest represents the token's class(es) (as a
|
||||
; list of non-terminals that this token corresponds to).
|
||||
;
|
||||
; The result of `make-parser' is a function that parses the single input it
|
||||
; is given into the grammar's goal. The result is a `parse' which can be
|
||||
; manipulated with the procedures: `parse->parsed?', `parse->trees'
|
||||
; and `parse->nb-trees' (see below).
|
||||
;
|
||||
; Let's assume that we want a parser for the grammar
|
||||
;
|
||||
; S -> x = E
|
||||
; E -> E + E | V
|
||||
; V -> V y |
|
||||
;
|
||||
; and that the input to the parser is a string of characters. Also, assume we
|
||||
; would like to map the characters `x', `y', `+' and `=' into the corresponding
|
||||
; non-terminals in the grammar. Such a parser could be created with
|
||||
;
|
||||
; (make-parser
|
||||
; '(
|
||||
; (s (x = e))
|
||||
; (e (e + e) (v))
|
||||
; (v (v y) ())
|
||||
; )
|
||||
; (lambda (str)
|
||||
; (map (lambda (char)
|
||||
; (list char ; user-info = the character itself
|
||||
; (case char
|
||||
; ((#\x) 'x)
|
||||
; ((#\y) 'y)
|
||||
; ((#\+) '+)
|
||||
; ((#\=) '=)
|
||||
; (else (fatal-error "lexer error")))))
|
||||
; (string->list str)))
|
||||
; )
|
||||
;
|
||||
; An alternative definition (that does not check for lexical errors) is
|
||||
;
|
||||
; (make-parser
|
||||
; '(
|
||||
; (s (#\x #\= e))
|
||||
; (e (e #\+ e) (v))
|
||||
; (v (v #\y) ())
|
||||
; )
|
||||
; (lambda (str) (map (lambda (char) (list char char)) (string->list str)))
|
||||
; )
|
||||
;
|
||||
; To help with the rest of the discussion, here are a few definitions:
|
||||
;
|
||||
; An input pointer (for an input of `n' tokens) is a value between 0 and `n'.
|
||||
; It indicates a point between two input tokens (0 = beginning, `n' = end).
|
||||
; For example, if `n' = 4, there are 5 input pointers:
|
||||
;
|
||||
; input token1 token2 token3 token4
|
||||
; input pointers 0 1 2 3 4
|
||||
;
|
||||
; A configuration indicates the extent to which a given rule is parsed (this
|
||||
; is the common `dot notation'). For simplicity, a configuration is
|
||||
; represented as an integer, with successive configurations in the same
|
||||
; rule associated with successive integers. It is assumed that the grammar
|
||||
; has been extended with rules to aid scanning. These rules are of the
|
||||
; form `nt ->', and there is one such rule for every non-terminal. Note
|
||||
; that these rules are special because they only apply when the corresponding
|
||||
; non-terminal is returned by the lexer.
|
||||
;
|
||||
; A configuration set is a configuration grouped with the set of input pointers
|
||||
; representing where the head non-terminal of the configuration was predicted.
|
||||
;
|
||||
; Here are the rules and configurations for the grammar given above:
|
||||
;
|
||||
; S -> . \
|
||||
; 0 |
|
||||
; x -> . |
|
||||
; 1 |
|
||||
; = -> . |
|
||||
; 2 |
|
||||
; E -> . |
|
||||
; 3 > special rules (for scanning)
|
||||
; + -> . |
|
||||
; 4 |
|
||||
; V -> . |
|
||||
; 5 |
|
||||
; y -> . |
|
||||
; 6 /
|
||||
; S -> . x . = . E .
|
||||
; 7 8 9 10
|
||||
; E -> . E . + . E .
|
||||
; 11 12 13 14
|
||||
; E -> . V .
|
||||
; 15 16
|
||||
; V -> . V . y .
|
||||
; 17 18 19
|
||||
; V -> .
|
||||
; 20
|
||||
;
|
||||
; Starters of the non-terminal `nt' are configurations that are leftmost
|
||||
; in a non-special rule for `nt'. Enders of the non-terminal `nt' are
|
||||
; configurations that are rightmost in any rule for `nt'. Predictors of the
|
||||
; non-terminal `nt' are configurations that are directly to the left of `nt'
|
||||
; in any rule.
|
||||
;
|
||||
; For the grammar given above,
|
||||
;
|
||||
; Starters of V = (17 20)
|
||||
; Enders of V = (5 19 20)
|
||||
; Predictors of V = (15 17)
|
||||
|
||||
(define (make-parser grammar lexer)
|
||||
|
||||
(define (non-terminals grammar) ; return vector of non-terminals in grammar
|
||||
|
||||
(define (add-nt nt nts)
|
||||
(if (member nt nts) nts (cons nt nts))) ; use equal? for equality tests
|
||||
|
||||
(let def-loop ((defs grammar) (nts '()))
|
||||
(if (pair? defs)
|
||||
(let* ((def (car defs))
|
||||
(head (car def)))
|
||||
(let rule-loop ((rules (cdr def))
|
||||
(nts (add-nt head nts)))
|
||||
(if (pair? rules)
|
||||
(let ((rule (car rules)))
|
||||
(let loop ((l rule) (nts nts))
|
||||
(if (pair? l)
|
||||
(let ((nt (car l)))
|
||||
(loop (cdr l) (add-nt nt nts)))
|
||||
(rule-loop (cdr rules) nts))))
|
||||
(def-loop (cdr defs) nts))))
|
||||
(list->vector (reverse nts))))) ; goal non-terminal must be at index 0
|
||||
|
||||
(define (ind nt nts) ; return index of non-terminal `nt' in `nts'
|
||||
(let loop ((i (- (vector-length nts) 1)))
|
||||
(if (>= i 0)
|
||||
(if (equal? (vector-ref nts i) nt) i (loop (- i 1)))
|
||||
#f)))
|
||||
|
||||
(define (nb-configurations grammar) ; return nb of configurations in grammar
|
||||
(let def-loop ((defs grammar) (nb-confs 0))
|
||||
(if (pair? defs)
|
||||
(let ((def (car defs)))
|
||||
(let rule-loop ((rules (cdr def)) (nb-confs nb-confs))
|
||||
(if (pair? rules)
|
||||
(let ((rule (car rules)))
|
||||
(let loop ((l rule) (nb-confs nb-confs))
|
||||
(if (pair? l)
|
||||
(loop (cdr l) (+ nb-confs 1))
|
||||
(rule-loop (cdr rules) (+ nb-confs 1)))))
|
||||
(def-loop (cdr defs) nb-confs))))
|
||||
nb-confs)))
|
||||
|
||||
; First, associate a numeric identifier to every non-terminal in the
|
||||
; grammar (with the goal non-terminal associated with 0).
|
||||
;
|
||||
; So, for the grammar given above we get:
|
||||
;
|
||||
; s -> 0 x -> 1 = -> 4 e ->3 + -> 4 v -> 5 y -> 6
|
||||
|
||||
(let* ((nts (non-terminals grammar)) ; id map = list of non-terms
|
||||
(nb-nts (vector-length nts)) ; the number of non-terms
|
||||
(nb-confs (+ (nb-configurations grammar) nb-nts)) ; the nb of confs
|
||||
(starters (make-vector nb-nts '())) ; starters for every non-term
|
||||
(enders (make-vector nb-nts '())) ; enders for every non-term
|
||||
(predictors (make-vector nb-nts '())) ; predictors for every non-term
|
||||
(steps (make-vector nb-confs #f)) ; what to do in a given conf
|
||||
(names (make-vector nb-confs #f))) ; name of rules
|
||||
|
||||
(define (setup-tables grammar nts starters enders predictors steps names)
|
||||
|
||||
(define (add-conf conf nt nts class)
|
||||
(let ((i (ind nt nts)))
|
||||
(vector-set! class i (cons conf (vector-ref class i)))))
|
||||
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
|
||||
(let nt-loop ((i (- nb-nts 1)))
|
||||
(if (>= i 0)
|
||||
(begin
|
||||
(vector-set! steps i (- i nb-nts))
|
||||
(vector-set! names i (list (vector-ref nts i) 0))
|
||||
(vector-set! enders i (list i))
|
||||
(nt-loop (- i 1)))))
|
||||
|
||||
(let def-loop ((defs grammar) (conf (vector-length nts)))
|
||||
(if (pair? defs)
|
||||
(let* ((def (car defs))
|
||||
(head (car def)))
|
||||
(let rule-loop ((rules (cdr def)) (conf conf) (rule-num 1))
|
||||
(if (pair? rules)
|
||||
(let ((rule (car rules)))
|
||||
(vector-set! names conf (list head rule-num))
|
||||
(add-conf conf head nts starters)
|
||||
(let loop ((l rule) (conf conf))
|
||||
(if (pair? l)
|
||||
(let ((nt (car l)))
|
||||
(vector-set! steps conf (ind nt nts))
|
||||
(add-conf conf nt nts predictors)
|
||||
(loop (cdr l) (+ conf 1)))
|
||||
(begin
|
||||
(vector-set! steps conf (- (ind head nts) nb-nts))
|
||||
(add-conf conf head nts enders)
|
||||
(rule-loop (cdr rules) (+ conf 1) (+ rule-num 1))))))
|
||||
(def-loop (cdr defs) conf))))))))
|
||||
|
||||
; Now, for each non-terminal, compute the starters, enders and predictors and
|
||||
; the names and steps tables.
|
||||
|
||||
(setup-tables grammar nts starters enders predictors steps names)
|
||||
|
||||
; Build the parser description
|
||||
|
||||
(let ((parser-descr (vector lexer
|
||||
nts
|
||||
starters
|
||||
enders
|
||||
predictors
|
||||
steps
|
||||
names)))
|
||||
(lambda (input)
|
||||
|
||||
(define (ind nt nts) ; return index of non-terminal `nt' in `nts'
|
||||
(let loop ((i (- (vector-length nts) 1)))
|
||||
(if (>= i 0)
|
||||
(if (equal? (vector-ref nts i) nt) i (loop (- i 1)))
|
||||
#f)))
|
||||
|
||||
(define (comp-tok tok nts) ; transform token to parsing format
|
||||
(let loop ((l1 (cdr tok)) (l2 '()))
|
||||
(if (pair? l1)
|
||||
(let ((i (ind (car l1) nts)))
|
||||
(if i
|
||||
(loop (cdr l1) (cons i l2))
|
||||
(loop (cdr l1) l2)))
|
||||
(cons (car tok) (reverse l2)))))
|
||||
|
||||
(define (input->tokens input lexer nts)
|
||||
(list->vector (map (lambda (tok) (comp-tok tok nts)) (lexer input))))
|
||||
|
||||
(define (make-states nb-toks nb-confs)
|
||||
(let ((states (make-vector (+ nb-toks 1) #f)))
|
||||
(let loop ((i nb-toks))
|
||||
(if (>= i 0)
|
||||
(let ((v (make-vector (+ nb-confs 1) #f)))
|
||||
(vector-set! v 0 -1)
|
||||
(vector-set! states i v)
|
||||
(loop (- i 1)))
|
||||
states))))
|
||||
|
||||
(define (conf-set-get state conf)
|
||||
(vector-ref state (+ conf 1)))
|
||||
|
||||
(define (conf-set-get* state state-num conf)
|
||||
(let ((conf-set (conf-set-get state conf)))
|
||||
(if conf-set
|
||||
conf-set
|
||||
(let ((conf-set (make-vector (+ state-num 6) #f)))
|
||||
(vector-set! conf-set 1 -3) ; old elems tail (points to head)
|
||||
(vector-set! conf-set 2 -1) ; old elems head
|
||||
(vector-set! conf-set 3 -1) ; new elems tail (points to head)
|
||||
(vector-set! conf-set 4 -1) ; new elems head
|
||||
(vector-set! state (+ conf 1) conf-set)
|
||||
conf-set))))
|
||||
|
||||
(define (conf-set-merge-new! conf-set)
|
||||
(vector-set! conf-set
|
||||
(+ (vector-ref conf-set 1) 5)
|
||||
(vector-ref conf-set 4))
|
||||
(vector-set! conf-set 1 (vector-ref conf-set 3))
|
||||
(vector-set! conf-set 3 -1)
|
||||
(vector-set! conf-set 4 -1))
|
||||
|
||||
(define (conf-set-head conf-set)
|
||||
(vector-ref conf-set 2))
|
||||
|
||||
(define (conf-set-next conf-set i)
|
||||
(vector-ref conf-set (+ i 5)))
|
||||
|
||||
(define (conf-set-member? state conf i)
|
||||
(let ((conf-set (vector-ref state (+ conf 1))))
|
||||
(if conf-set
|
||||
(conf-set-next conf-set i)
|
||||
#f)))
|
||||
|
||||
(define (conf-set-adjoin state conf-set conf i)
|
||||
(let ((tail (vector-ref conf-set 3))) ; put new element at tail
|
||||
(vector-set! conf-set (+ i 5) -1)
|
||||
(vector-set! conf-set (+ tail 5) i)
|
||||
(vector-set! conf-set 3 i)
|
||||
(if (< tail 0)
|
||||
(begin
|
||||
(vector-set! conf-set 0 (vector-ref state 0))
|
||||
(vector-set! state 0 conf)))))
|
||||
|
||||
(define (conf-set-adjoin* states state-num l i)
|
||||
(let ((state (vector-ref states state-num)))
|
||||
(let loop ((l1 l))
|
||||
(if (pair? l1)
|
||||
(let* ((conf (car l1))
|
||||
(conf-set (conf-set-get* state state-num conf)))
|
||||
(if (not (conf-set-next conf-set i))
|
||||
(begin
|
||||
(conf-set-adjoin state conf-set conf i)
|
||||
(loop (cdr l1)))
|
||||
(loop (cdr l1))))))))
|
||||
|
||||
(define (conf-set-adjoin** states states* state-num conf i)
|
||||
(let ((state (vector-ref states state-num)))
|
||||
(if (conf-set-member? state conf i)
|
||||
(let* ((state* (vector-ref states* state-num))
|
||||
(conf-set* (conf-set-get* state* state-num conf)))
|
||||
(if (not (conf-set-next conf-set* i))
|
||||
(conf-set-adjoin state* conf-set* conf i))
|
||||
#t)
|
||||
#f)))
|
||||
|
||||
(define (conf-set-union state conf-set conf other-set)
|
||||
(let loop ((i (conf-set-head other-set)))
|
||||
(if (>= i 0)
|
||||
(if (not (conf-set-next conf-set i))
|
||||
(begin
|
||||
(conf-set-adjoin state conf-set conf i)
|
||||
(loop (conf-set-next other-set i)))
|
||||
(loop (conf-set-next other-set i))))))
|
||||
|
||||
(define (forw states state-num starters enders predictors steps nts)
|
||||
|
||||
(define (predict state state-num conf-set conf nt starters enders)
|
||||
|
||||
; add configurations which start the non-terminal `nt' to the
|
||||
; right of the dot
|
||||
|
||||
(let loop1 ((l (vector-ref starters nt)))
|
||||
(if (pair? l)
|
||||
(let* ((starter (car l))
|
||||
(starter-set (conf-set-get* state state-num starter)))
|
||||
(if (not (conf-set-next starter-set state-num))
|
||||
(begin
|
||||
(conf-set-adjoin state starter-set starter state-num)
|
||||
(loop1 (cdr l)))
|
||||
(loop1 (cdr l))))))
|
||||
|
||||
; check for possible completion of the non-terminal `nt' to the
|
||||
; right of the dot
|
||||
|
||||
(let loop2 ((l (vector-ref enders nt)))
|
||||
(if (pair? l)
|
||||
(let ((ender (car l)))
|
||||
(if (conf-set-member? state ender state-num)
|
||||
(let* ((next (+ conf 1))
|
||||
(next-set (conf-set-get* state state-num next)))
|
||||
(conf-set-union state next-set next conf-set)
|
||||
(loop2 (cdr l)))
|
||||
(loop2 (cdr l)))))))
|
||||
|
||||
(define (reduce states state state-num conf-set head preds)
|
||||
|
||||
; a non-terminal is now completed so check for reductions that
|
||||
; are now possible at the configurations `preds'
|
||||
|
||||
(let loop1 ((l preds))
|
||||
(if (pair? l)
|
||||
(let ((pred (car l)))
|
||||
(let loop2 ((i head))
|
||||
(if (>= i 0)
|
||||
(let ((pred-set (conf-set-get (vector-ref states i) pred)))
|
||||
(if pred-set
|
||||
(let* ((next (+ pred 1))
|
||||
(next-set (conf-set-get* state state-num next)))
|
||||
(conf-set-union state next-set next pred-set)))
|
||||
(loop2 (conf-set-next conf-set i)))
|
||||
(loop1 (cdr l))))))))
|
||||
|
||||
(let ((state (vector-ref states state-num))
|
||||
(nb-nts (vector-length nts)))
|
||||
(let loop ()
|
||||
(let ((conf (vector-ref state 0)))
|
||||
(if (>= conf 0)
|
||||
(let* ((step (vector-ref steps conf))
|
||||
(conf-set (vector-ref state (+ conf 1)))
|
||||
(head (vector-ref conf-set 4)))
|
||||
(vector-set! state 0 (vector-ref conf-set 0))
|
||||
(conf-set-merge-new! conf-set)
|
||||
(if (>= step 0)
|
||||
(predict state state-num conf-set conf step starters enders)
|
||||
(let ((preds (vector-ref predictors (+ step nb-nts))))
|
||||
(reduce states state state-num conf-set head preds)))
|
||||
(loop)))))))
|
||||
|
||||
(define (forward starters enders predictors steps nts toks)
|
||||
(let* ((nb-toks (vector-length toks))
|
||||
(nb-confs (vector-length steps))
|
||||
(states (make-states nb-toks nb-confs))
|
||||
(goal-starters (vector-ref starters 0)))
|
||||
(conf-set-adjoin* states 0 goal-starters 0) ; predict goal
|
||||
(forw states 0 starters enders predictors steps nts)
|
||||
(let loop ((i 0))
|
||||
(if (< i nb-toks)
|
||||
(let ((tok-nts (cdr (vector-ref toks i))))
|
||||
(conf-set-adjoin* states (+ i 1) tok-nts i) ; scan token
|
||||
(forw states (+ i 1) starters enders predictors steps nts)
|
||||
(loop (+ i 1)))))
|
||||
states))
|
||||
|
||||
(define (produce conf i j enders steps toks states states* nb-nts)
|
||||
(let ((prev (- conf 1)))
|
||||
(if (and (>= conf nb-nts) (>= (vector-ref steps prev) 0))
|
||||
(let loop1 ((l (vector-ref enders (vector-ref steps prev))))
|
||||
(if (pair? l)
|
||||
(let* ((ender (car l))
|
||||
(ender-set (conf-set-get (vector-ref states j)
|
||||
ender)))
|
||||
(if ender-set
|
||||
(let loop2 ((k (conf-set-head ender-set)))
|
||||
(if (>= k 0)
|
||||
(begin
|
||||
(and (>= k i)
|
||||
(conf-set-adjoin** states states* k prev i)
|
||||
(conf-set-adjoin** states states* j ender k))
|
||||
(loop2 (conf-set-next ender-set k)))
|
||||
(loop1 (cdr l))))
|
||||
(loop1 (cdr l)))))))))
|
||||
|
||||
(define (back states states* state-num enders steps nb-nts toks)
|
||||
(let ((state* (vector-ref states* state-num)))
|
||||
(let loop1 ()
|
||||
(let ((conf (vector-ref state* 0)))
|
||||
(if (>= conf 0)
|
||||
(let* ((conf-set (vector-ref state* (+ conf 1)))
|
||||
(head (vector-ref conf-set 4)))
|
||||
(vector-set! state* 0 (vector-ref conf-set 0))
|
||||
(conf-set-merge-new! conf-set)
|
||||
(let loop2 ((i head))
|
||||
(if (>= i 0)
|
||||
(begin
|
||||
(produce conf i state-num enders steps
|
||||
toks states states* nb-nts)
|
||||
(loop2 (conf-set-next conf-set i)))
|
||||
(loop1)))))))))
|
||||
|
||||
(define (backward states enders steps nts toks)
|
||||
(let* ((nb-toks (vector-length toks))
|
||||
(nb-confs (vector-length steps))
|
||||
(nb-nts (vector-length nts))
|
||||
(states* (make-states nb-toks nb-confs))
|
||||
(goal-enders (vector-ref enders 0)))
|
||||
(let loop1 ((l goal-enders))
|
||||
(if (pair? l)
|
||||
(let ((conf (car l)))
|
||||
(conf-set-adjoin** states states* nb-toks conf 0)
|
||||
(loop1 (cdr l)))))
|
||||
(let loop2 ((i nb-toks))
|
||||
(if (>= i 0)
|
||||
(begin
|
||||
(back states states* i enders steps nb-nts toks)
|
||||
(loop2 (- i 1)))))
|
||||
states*))
|
||||
|
||||
(define (parsed? nt i j nts enders states)
|
||||
(let ((nt* (ind nt nts)))
|
||||
(if nt*
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
(let loop ((l (vector-ref enders nt*)))
|
||||
(if (pair? l)
|
||||
(let ((conf (car l)))
|
||||
(if (conf-set-member? (vector-ref states j) conf i)
|
||||
#t
|
||||
(loop (cdr l))))
|
||||
#f)))
|
||||
#f)))
|
||||
|
||||
(define (deriv-trees conf i j enders steps names toks states nb-nts)
|
||||
(let ((name (vector-ref names conf)))
|
||||
|
||||
(if name ; `conf' is at the start of a rule (either special or not)
|
||||
(if (< conf nb-nts)
|
||||
(list (list name (car (vector-ref toks i))))
|
||||
(list (list name)))
|
||||
|
||||
(let ((prev (- conf 1)))
|
||||
(let loop1 ((l1 (vector-ref enders (vector-ref steps prev)))
|
||||
(l2 '()))
|
||||
(if (pair? l1)
|
||||
(let* ((ender (car l1))
|
||||
(ender-set (conf-set-get (vector-ref states j)
|
||||
ender)))
|
||||
(if ender-set
|
||||
(let loop2 ((k (conf-set-head ender-set)) (l2 l2))
|
||||
(if (>= k 0)
|
||||
(if (and (>= k i)
|
||||
(conf-set-member? (vector-ref states k)
|
||||
prev i))
|
||||
(let ((prev-trees
|
||||
(deriv-trees prev i k enders steps names
|
||||
toks states nb-nts))
|
||||
(ender-trees
|
||||
(deriv-trees ender k j enders steps names
|
||||
toks states nb-nts)))
|
||||
(let loop3 ((l3 ender-trees) (l2 l2))
|
||||
(if (pair? l3)
|
||||
(let ((ender-tree (list (car l3))))
|
||||
(let loop4 ((l4 prev-trees) (l2 l2))
|
||||
(if (pair? l4)
|
||||
(loop4 (cdr l4)
|
||||
(cons (append (car l4)
|
||||
ender-tree)
|
||||
l2))
|
||||
(loop3 (cdr l3) l2))))
|
||||
(loop2 (conf-set-next ender-set k) l2))))
|
||||
(loop2 (conf-set-next ender-set k) l2))
|
||||
(loop1 (cdr l1) l2)))
|
||||
(loop1 (cdr l1) l2)))
|
||||
l2))))))
|
||||
|
||||
(define (deriv-trees* nt i j nts enders steps names toks states)
|
||||
(let ((nt* (ind nt nts)))
|
||||
(if nt*
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
(let loop ((l (vector-ref enders nt*)) (trees '()))
|
||||
(if (pair? l)
|
||||
(let ((conf (car l)))
|
||||
(if (conf-set-member? (vector-ref states j) conf i)
|
||||
(loop (cdr l)
|
||||
(append (deriv-trees conf i j enders steps names
|
||||
toks states nb-nts)
|
||||
trees))
|
||||
(loop (cdr l) trees)))
|
||||
trees)))
|
||||
#f)))
|
||||
|
||||
(define (nb-deriv-trees conf i j enders steps toks states nb-nts)
|
||||
(let ((prev (- conf 1)))
|
||||
(if (or (< conf nb-nts) (< (vector-ref steps prev) 0))
|
||||
1
|
||||
(let loop1 ((l (vector-ref enders (vector-ref steps prev)))
|
||||
(n 0))
|
||||
(if (pair? l)
|
||||
(let* ((ender (car l))
|
||||
(ender-set (conf-set-get (vector-ref states j)
|
||||
ender)))
|
||||
(if ender-set
|
||||
(let loop2 ((k (conf-set-head ender-set)) (n n))
|
||||
(if (>= k 0)
|
||||
(if (and (>= k i)
|
||||
(conf-set-member? (vector-ref states k)
|
||||
prev i))
|
||||
(let ((nb-prev-trees
|
||||
(nb-deriv-trees prev i k enders steps
|
||||
toks states nb-nts))
|
||||
(nb-ender-trees
|
||||
(nb-deriv-trees ender k j enders steps
|
||||
toks states nb-nts)))
|
||||
(loop2 (conf-set-next ender-set k)
|
||||
(+ n (* nb-prev-trees nb-ender-trees))))
|
||||
(loop2 (conf-set-next ender-set k) n))
|
||||
(loop1 (cdr l) n)))
|
||||
(loop1 (cdr l) n)))
|
||||
n)))))
|
||||
|
||||
(define (nb-deriv-trees* nt i j nts enders steps toks states)
|
||||
(let ((nt* (ind nt nts)))
|
||||
(if nt*
|
||||
(let ((nb-nts (vector-length nts)))
|
||||
(let loop ((l (vector-ref enders nt*)) (nb-trees 0))
|
||||
(if (pair? l)
|
||||
(let ((conf (car l)))
|
||||
(if (conf-set-member? (vector-ref states j) conf i)
|
||||
(loop (cdr l)
|
||||
(+ (nb-deriv-trees conf i j enders steps
|
||||
toks states nb-nts)
|
||||
nb-trees))
|
||||
(loop (cdr l) nb-trees)))
|
||||
nb-trees)))
|
||||
#f)))
|
||||
|
||||
(let* ((lexer (vector-ref parser-descr 0))
|
||||
(nts (vector-ref parser-descr 1))
|
||||
(starters (vector-ref parser-descr 2))
|
||||
(enders (vector-ref parser-descr 3))
|
||||
(predictors (vector-ref parser-descr 4))
|
||||
(steps (vector-ref parser-descr 5))
|
||||
(names (vector-ref parser-descr 6))
|
||||
(toks (input->tokens input lexer nts)))
|
||||
|
||||
(vector nts
|
||||
starters
|
||||
enders
|
||||
predictors
|
||||
steps
|
||||
names
|
||||
toks
|
||||
(backward (forward starters enders predictors steps nts toks)
|
||||
enders steps nts toks)
|
||||
parsed?
|
||||
deriv-trees*
|
||||
nb-deriv-trees*))))))
|
||||
|
||||
(define (parse->parsed? parse nt i j)
|
||||
(let* ((nts (vector-ref parse 0))
|
||||
(enders (vector-ref parse 2))
|
||||
(states (vector-ref parse 7))
|
||||
(parsed? (vector-ref parse 8)))
|
||||
(parsed? nt i j nts enders states)))
|
||||
|
||||
(define (parse->trees parse nt i j)
|
||||
(let* ((nts (vector-ref parse 0))
|
||||
(enders (vector-ref parse 2))
|
||||
(steps (vector-ref parse 4))
|
||||
(names (vector-ref parse 5))
|
||||
(toks (vector-ref parse 6))
|
||||
(states (vector-ref parse 7))
|
||||
(deriv-trees* (vector-ref parse 9)))
|
||||
(deriv-trees* nt i j nts enders steps names toks states)))
|
||||
|
||||
(define (parse->nb-trees parse nt i j)
|
||||
(let* ((nts (vector-ref parse 0))
|
||||
(enders (vector-ref parse 2))
|
||||
(steps (vector-ref parse 4))
|
||||
(toks (vector-ref parse 6))
|
||||
(states (vector-ref parse 7))
|
||||
(nb-deriv-trees* (vector-ref parse 10)))
|
||||
(nb-deriv-trees* nt i j nts enders steps toks states)))
|
||||
|
||||
(define (test k)
|
||||
(let ((p (make-parser '( (s (a) (s s)) )
|
||||
(lambda (l) (map (lambda (x) (list x x)) l)))))
|
||||
(let ((x (p (vector->list (make-vector k 'a)))))
|
||||
(length (parse->trees x 's 0 k)))))
|
||||
|
||||
(define (earley-benchmark . args)
|
||||
(let ((k (if (null? args) 9 (car args))))
|
||||
(run-benchmark
|
||||
"earley"
|
||||
1
|
||||
(lambda () (test k))
|
||||
(lambda (result)
|
||||
(display result)
|
||||
(newline)
|
||||
#t))))
|
233
gc-benchmarks/larceny/gcbench.sch
Normal file
233
gc-benchmarks/larceny/gcbench.sch
Normal file
|
@ -0,0 +1,233 @@
|
|||
; This is adapted from a benchmark written by John Ellis and Pete Kovac
|
||||
; of Post Communications.
|
||||
; It was modified by Hans Boehm of Silicon Graphics.
|
||||
; It was translated into Scheme by William D Clinger of Northeastern Univ;
|
||||
; the Scheme version uses (RUN-BENCHMARK <string> <thunk>)
|
||||
; It was later hacked by Lars T Hansen of Northeastern University;
|
||||
; this version has a fixed tree height but accepts a number of
|
||||
; iterations to run.
|
||||
;
|
||||
; Modified 2000-02-15 / lth: changed gc-benchmark to only stretch once,
|
||||
; and to have a different interface (now accepts iteration numbers,
|
||||
; not tree height)
|
||||
; Last modified 2000-07-14 / lth -- fixed a buggy comment about storage
|
||||
; use in Larceny.
|
||||
;
|
||||
; This is no substitute for real applications. No actual application
|
||||
; is likely to behave in exactly this way. However, this benchmark was
|
||||
; designed to be more representative of real applications than other
|
||||
; Java GC benchmarks of which we are aware.
|
||||
; It attempts to model those properties of allocation requests that
|
||||
; are important to current GC techniques.
|
||||
; It is designed to be used either to obtain a single overall performance
|
||||
; number, or to give a more detailed estimate of how collector
|
||||
; performance varies with object lifetimes. It prints the time
|
||||
; required to allocate and collect balanced binary trees of various
|
||||
; sizes. Smaller trees result in shorter object lifetimes. Each cycle
|
||||
; allocates roughly the same amount of memory.
|
||||
; Two data structures are kept around during the entire process, so
|
||||
; that the measured performance is representative of applications
|
||||
; that maintain some live in-memory data. One of these is a tree
|
||||
; containing many pointers. The other is a large array containing
|
||||
; double precision floating point numbers. Both should be of comparable
|
||||
; size.
|
||||
;
|
||||
; The results are only really meaningful together with a specification
|
||||
; of how much memory was used. It is possible to trade memory for
|
||||
; better time performance. This benchmark should be run in a 32 MB
|
||||
; heap, though we don't currently know how to enforce that uniformly.
|
||||
|
||||
; In the Java version, this routine prints the heap size and the amount
|
||||
; of free memory. There is no portable way to do this in Scheme; each
|
||||
; implementation needs its own version.
|
||||
|
||||
(define (PrintDiagnostics)
|
||||
(display " Total memory available= ???????? bytes")
|
||||
(display " Free memory= ???????? bytes")
|
||||
(newline))
|
||||
|
||||
(define (yes answer) #t)
|
||||
|
||||
; Should we implement a Java class as procedures or hygienic macros?
|
||||
; Take your pick.
|
||||
|
||||
(define-syntax let-class
|
||||
(syntax-rules
|
||||
()
|
||||
; Put this rule first to implement a class using hygienic macros.
|
||||
((let-class (((method . args) . method-body) ...) . body)
|
||||
(letrec-syntax ((method (syntax-rules ()
|
||||
((method . args) (begin . method-body))))
|
||||
...)
|
||||
. body))
|
||||
; Put this rule first to implement a class using procedures.
|
||||
((let-class (((method . args) . method-body) ...) . body)
|
||||
(let () (define (method . args) . method-body) ... . body))
|
||||
))
|
||||
|
||||
|
||||
(define stretch #t) ; Controls whether stretching phase is run
|
||||
|
||||
(define (gcbench kStretchTreeDepth)
|
||||
|
||||
; Use for inner calls to reduce noise.
|
||||
|
||||
(define (run-benchmark name iters thunk test)
|
||||
(do ((i 0 (+ i 1)))
|
||||
((= i iters))
|
||||
(thunk)))
|
||||
|
||||
; Nodes used by a tree of a given size
|
||||
(define (TreeSize i)
|
||||
(- (expt 2 (+ i 1)) 1))
|
||||
|
||||
; Number of iterations to use for a given tree depth
|
||||
(define (NumIters i)
|
||||
(quotient (* 2 (TreeSize kStretchTreeDepth))
|
||||
(TreeSize i)))
|
||||
|
||||
; Parameters are determined by kStretchTreeDepth.
|
||||
; In Boehm's version the parameters were fixed as follows:
|
||||
; public static final int kStretchTreeDepth = 18; // about 16Mb
|
||||
; public static final int kLongLivedTreeDepth = 16; // about 4Mb
|
||||
; public static final int kArraySize = 500000; // about 4Mb
|
||||
; public static final int kMinTreeDepth = 4;
|
||||
; public static final int kMaxTreeDepth = 16;
|
||||
; wdc: In Larceny the storage numbers above would be 12 Mby, 3 Mby, 6 Mby.
|
||||
; lth: No they would not. A flonum requires 16 bytes, so the size
|
||||
; of array + flonums would be 500,000*4 + 500,000*16=10 Mby.
|
||||
|
||||
(let* ((kLongLivedTreeDepth (- kStretchTreeDepth 2))
|
||||
(kArraySize (* 4 (TreeSize kLongLivedTreeDepth)))
|
||||
(kMinTreeDepth 4)
|
||||
(kMaxTreeDepth kLongLivedTreeDepth))
|
||||
|
||||
; Elements 3 and 4 of the allocated vectors are useless.
|
||||
|
||||
(let-class (((make-node l r)
|
||||
(let ((v (make-empty-node)))
|
||||
(vector-set! v 0 l)
|
||||
(vector-set! v 1 r)
|
||||
v))
|
||||
((make-empty-node) (make-vector 4 0))
|
||||
((node.left node) (vector-ref node 0))
|
||||
((node.right node) (vector-ref node 1))
|
||||
((node.left-set! node x) (vector-set! node 0 x))
|
||||
((node.right-set! node x) (vector-set! node 1 x)))
|
||||
|
||||
; Build tree top down, assigning to older objects.
|
||||
(define (Populate iDepth thisNode)
|
||||
(if (<= iDepth 0)
|
||||
#f
|
||||
(let ((iDepth (- iDepth 1)))
|
||||
(node.left-set! thisNode (make-empty-node))
|
||||
(node.right-set! thisNode (make-empty-node))
|
||||
(Populate iDepth (node.left thisNode))
|
||||
(Populate iDepth (node.right thisNode)))))
|
||||
|
||||
; Build tree bottom-up
|
||||
(define (MakeTree iDepth)
|
||||
(if (<= iDepth 0)
|
||||
(make-empty-node)
|
||||
(make-node (MakeTree (- iDepth 1))
|
||||
(MakeTree (- iDepth 1)))))
|
||||
|
||||
(define (TimeConstruction depth)
|
||||
(let ((iNumIters (NumIters depth)))
|
||||
(display (string-append "Creating "
|
||||
(number->string iNumIters)
|
||||
" trees of depth "
|
||||
(number->string depth)))
|
||||
(newline)
|
||||
(run-benchmark "GCBench: Top down construction"
|
||||
1
|
||||
(lambda ()
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i iNumIters))
|
||||
(Populate depth (make-empty-node))))
|
||||
yes)
|
||||
(run-benchmark "GCBench: Bottom up construction"
|
||||
1
|
||||
(lambda ()
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i iNumIters))
|
||||
(MakeTree depth)))
|
||||
yes)))
|
||||
|
||||
(define (main)
|
||||
(display "Garbage Collector Test")
|
||||
(newline)
|
||||
(if stretch
|
||||
(begin
|
||||
(display (string-append
|
||||
" Stretching memory with a binary tree of depth "
|
||||
(number->string kStretchTreeDepth)))
|
||||
(newline)))
|
||||
(PrintDiagnostics)
|
||||
(run-benchmark "GCBench: Main"
|
||||
1
|
||||
(lambda ()
|
||||
; Stretch the memory space quickly
|
||||
(if stretch
|
||||
(MakeTree kStretchTreeDepth))
|
||||
|
||||
; Create a long lived object
|
||||
(display
|
||||
(string-append
|
||||
" Creating a long-lived binary tree of depth "
|
||||
(number->string kLongLivedTreeDepth)))
|
||||
(newline)
|
||||
(let ((longLivedTree (make-empty-node)))
|
||||
(Populate kLongLivedTreeDepth longLivedTree)
|
||||
|
||||
; Create long-lived array, filling half of it
|
||||
(display (string-append
|
||||
" Creating a long-lived array of "
|
||||
(number->string kArraySize)
|
||||
" inexact reals"))
|
||||
(newline)
|
||||
(let ((array (make-vector kArraySize 0.0)))
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i (quotient kArraySize 2)))
|
||||
(vector-set! array i
|
||||
(/ 1.0 (exact->inexact i))))
|
||||
(PrintDiagnostics)
|
||||
|
||||
(do ((d kMinTreeDepth (+ d 2)))
|
||||
((> d kMaxTreeDepth))
|
||||
(TimeConstruction d))
|
||||
|
||||
(if (or (eq? longLivedTree '())
|
||||
(let ((n (min 1000
|
||||
(- (quotient (vector-length array)
|
||||
2)
|
||||
1))))
|
||||
(not (= (vector-ref array n)
|
||||
(/ 1.0 (exact->inexact n))))))
|
||||
(begin (display "Failed") (newline)))
|
||||
; fake reference to LongLivedTree
|
||||
; and array
|
||||
; to keep them from being optimized away
|
||||
)))
|
||||
yes)
|
||||
(PrintDiagnostics))
|
||||
|
||||
(main))))
|
||||
|
||||
(define (gc-benchmark . rest)
|
||||
(let ((k 18)
|
||||
(n (if (null? rest) 1 (car rest))))
|
||||
(display "The garbage collector should touch about ")
|
||||
(display (expt 2 (- k 13)))
|
||||
(display " megabytes of heap storage.")
|
||||
(newline)
|
||||
(display "The use of more or less memory will skew the results.")
|
||||
(newline)
|
||||
(set! stretch #t)
|
||||
(run-benchmark (string-append "GCBench" (number->string k))
|
||||
n
|
||||
(lambda ()
|
||||
(gcbench k)
|
||||
(set! stretch #f))
|
||||
yes)
|
||||
(set! stretch #t)))
|
386
gc-benchmarks/larceny/gcold.scm
Normal file
386
gc-benchmarks/larceny/gcold.scm
Normal file
|
@ -0,0 +1,386 @@
|
|||
;
|
||||
; GCOld.sch x.x 00/08/03
|
||||
; translated from GCOld.java 2.0a 00/08/23
|
||||
;
|
||||
; Copyright 2000 Sun Microsystems, Inc. All rights reserved.
|
||||
;
|
||||
;
|
||||
|
||||
; Should be good enough for this benchmark.
|
||||
|
||||
(define (newRandom)
|
||||
(letrec ((random14
|
||||
(lambda (n)
|
||||
(set! x (remainder (+ (* a x) c) m))
|
||||
(remainder (quotient x 8) n)))
|
||||
(a 701)
|
||||
(x 1)
|
||||
(c 743483)
|
||||
(m 524288)
|
||||
(loop
|
||||
(lambda (q r n)
|
||||
(if (zero? q)
|
||||
(remainder r n)
|
||||
(loop (quotient q 16384)
|
||||
(+ (* 16384 r) (random14 16384))
|
||||
n)))))
|
||||
(lambda (n)
|
||||
(if (and (exact? n) (integer? n) (< n 16384))
|
||||
(random14 n)
|
||||
(loop n (random14 16384) n)))))
|
||||
|
||||
; A TreeNode is a record with three fields: left, right, val.
|
||||
; The left and right fields contain a TreeNode or 0, and the
|
||||
; val field will contain the integer height of the tree.
|
||||
|
||||
(define-syntax newTreeNode
|
||||
(syntax-rules ()
|
||||
((newTreeNode left right val)
|
||||
(vector left right val))
|
||||
((newTreeNode)
|
||||
(vector 0 0 0))))
|
||||
|
||||
(define-syntax TreeNode.left
|
||||
(syntax-rules ()
|
||||
((TreeNode.left node)
|
||||
(vector-ref node 0))))
|
||||
|
||||
(define-syntax TreeNode.right
|
||||
(syntax-rules ()
|
||||
((TreeNode.right node)
|
||||
(vector-ref node 1))))
|
||||
|
||||
(define-syntax TreeNode.val
|
||||
(syntax-rules ()
|
||||
((TreeNode.val node)
|
||||
(vector-ref node 2))))
|
||||
|
||||
(define-syntax setf
|
||||
(syntax-rules (TreeNode.left TreeNode.right TreeNode.val)
|
||||
((setf (TreeNode.left node) x)
|
||||
(vector-set! node 0 x))
|
||||
((setf (TreeNode.right node) x)
|
||||
(vector-set! node 1 x))
|
||||
((setf (TreeNode.val node) x)
|
||||
(vector-set! node 2 x))))
|
||||
|
||||
; Args:
|
||||
; live-data-size: in megabytes.
|
||||
; work: units of mutator non-allocation work per byte allocated,
|
||||
; (in unspecified units. This will affect the promotion rate
|
||||
; printed at the end of the run: more mutator work per step implies
|
||||
; fewer steps per second implies fewer bytes promoted per second.)
|
||||
; short/long ratio: ratio of short-lived bytes allocated to long-lived
|
||||
; bytes allocated.
|
||||
; pointer mutation rate: number of pointer mutations per step.
|
||||
; steps: number of steps to do.
|
||||
;
|
||||
|
||||
(define (GCOld size workUnits promoteRate ptrMutRate steps)
|
||||
|
||||
(define (println . args)
|
||||
(for-each display args)
|
||||
(newline))
|
||||
|
||||
; Rounds an inexact real to two decimal places.
|
||||
|
||||
(define (round2 x)
|
||||
(/ (round (* 100.0 x)) 100.0))
|
||||
|
||||
; Returns the height of the given tree.
|
||||
|
||||
(define (height t)
|
||||
(if (eqv? t 0)
|
||||
0
|
||||
(+ 1 (max (height (TreeNode.left t))
|
||||
(height (TreeNode.right t))))))
|
||||
|
||||
; Returns the length of the shortest path in the given tree.
|
||||
|
||||
(define (shortestPath t)
|
||||
(if (eqv? t 0)
|
||||
0
|
||||
(+ 1 (min (shortestPath (TreeNode.left t))
|
||||
(shortestPath (TreeNode.right t))))))
|
||||
|
||||
; Returns the number of nodes in a balanced tree of the given height.
|
||||
|
||||
(define (heightToNodes h)
|
||||
(- (expt 2 h) 1))
|
||||
|
||||
; Returns the height of the largest balanced tree
|
||||
; that has no more than the given number of nodes.
|
||||
|
||||
(define (nodesToHeight nodes)
|
||||
(do ((h 1 (+ h 1))
|
||||
(n 1 (+ n n)))
|
||||
((> (+ n n -1) nodes)
|
||||
(- h 1))))
|
||||
|
||||
(let* (
|
||||
|
||||
; Constants.
|
||||
|
||||
(null 0) ; Java's null
|
||||
(pathBits 65536) ; to generate 16 random bits
|
||||
|
||||
(MEG 1000000)
|
||||
(INSIGNIFICANT 999) ; this many bytes don't matter
|
||||
(bytes/word 4)
|
||||
(bytes/node 20) ; bytes per tree node in typical JVM
|
||||
(words/dead 100) ; size of young garbage objects
|
||||
|
||||
; Returns the number of bytes in a balanced tree of the given height.
|
||||
|
||||
(heightToBytes
|
||||
(lambda (h)
|
||||
(* bytes/node (heightToNodes h))))
|
||||
|
||||
; Returns the height of the largest balanced tree
|
||||
; that occupies no more than the given number of bytes.
|
||||
|
||||
(bytesToHeight
|
||||
(lambda (bytes)
|
||||
(nodesToHeight (/ bytes bytes/node))))
|
||||
|
||||
(treeHeight 14)
|
||||
(treeSize (heightToBytes treeHeight))
|
||||
|
||||
(msg1 "Usage: java GCOld <size> <work> <ratio> <mutation> <steps>")
|
||||
(msg2 " where <size> is the live storage in megabytes")
|
||||
(msg3 " <work> is the mutator work per step (arbitrary units)")
|
||||
(msg4 " <ratio> is the ratio of short-lived to long-lived allocation")
|
||||
(msg5 " <mutation> is the mutations per step")
|
||||
(msg6 " <steps> is the number of steps")
|
||||
|
||||
; Counters (and global variables that discourage optimization).
|
||||
|
||||
(youngBytes 0)
|
||||
(nodes 0)
|
||||
(actuallyMut 0)
|
||||
(mutatorSum 0)
|
||||
(aexport '#())
|
||||
|
||||
; Global variables.
|
||||
|
||||
(trees '#())
|
||||
(where 0)
|
||||
(rnd (newRandom))
|
||||
|
||||
)
|
||||
|
||||
; Returns a newly allocated balanced binary tree of height h.
|
||||
|
||||
(define (makeTree h)
|
||||
(if (zero? h)
|
||||
null
|
||||
(let ((res (newTreeNode)))
|
||||
(set! nodes (+ nodes 1))
|
||||
(setf (TreeNode.left res) (makeTree (- h 1)))
|
||||
(setf (TreeNode.right res) (makeTree (- h 1)))
|
||||
(setf (TreeNode.val res) h)
|
||||
res)))
|
||||
|
||||
; Allocates approximately size megabytes of trees and stores
|
||||
; them into a global array.
|
||||
|
||||
(define (init)
|
||||
; Each tree will be about a megabyte.
|
||||
(let ((ntrees (quotient (* size MEG) treeSize)))
|
||||
(set! trees (make-vector ntrees null))
|
||||
(println "Allocating " ntrees " trees.")
|
||||
(println " (" (* ntrees treeSize) " bytes)")
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i ntrees))
|
||||
(vector-set! trees i (makeTree treeHeight))
|
||||
(doYoungGenAlloc (* promoteRate ntrees treeSize) words/dead))
|
||||
(println " (" nodes " nodes)")))
|
||||
|
||||
; Confirms that all trees are balanced and have the correct height.
|
||||
|
||||
(define (checkTrees)
|
||||
(let ((ntrees (vector-length trees)))
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i ntrees))
|
||||
(let* ((t (vector-ref trees i))
|
||||
(h1 (height t))
|
||||
(h2 (shortestPath t)))
|
||||
(if (or (not (= h1 treeHeight))
|
||||
(not (= h2 treeHeight)))
|
||||
(println "*****BUG: " h1 " " h2))))))
|
||||
|
||||
; Called only by replaceTree (below) and by itself.
|
||||
|
||||
(define (replaceTreeWork full partial dir)
|
||||
(let ((canGoLeft (and (not (eq? (TreeNode.left full) null))
|
||||
(> (TreeNode.val (TreeNode.left full))
|
||||
(TreeNode.val partial))))
|
||||
(canGoRight (and (not (eq? (TreeNode.right full) null))
|
||||
(> (TreeNode.val (TreeNode.right full))
|
||||
(TreeNode.val partial)))))
|
||||
(cond ((and canGoLeft canGoRight)
|
||||
(if dir
|
||||
(replaceTreeWork (TreeNode.left full)
|
||||
partial
|
||||
(not dir))
|
||||
(replaceTreeWork (TreeNode.right full)
|
||||
partial
|
||||
(not dir))))
|
||||
((and (not canGoLeft) (not canGoRight))
|
||||
(if dir
|
||||
(setf (TreeNode.left full) partial)
|
||||
(setf (TreeNode.right full) partial)))
|
||||
((not canGoLeft)
|
||||
(setf (TreeNode.left full) partial))
|
||||
(else
|
||||
(setf (TreeNode.right full) partial)))))
|
||||
|
||||
; Given a balanced tree full and a smaller balanced tree partial,
|
||||
; replaces an appropriate subtree of full by partial, taking care
|
||||
; to preserve the shape of the full tree.
|
||||
|
||||
(define (replaceTree full partial)
|
||||
(let ((dir (zero? (modulo (TreeNode.val partial) 2))))
|
||||
(set! actuallyMut (+ actuallyMut 1))
|
||||
(replaceTreeWork full partial dir)))
|
||||
|
||||
; Allocates approximately n bytes of long-lived storage,
|
||||
; replacing oldest existing long-lived storage.
|
||||
|
||||
(define (oldGenAlloc n)
|
||||
(let ((full (quotient n treeSize))
|
||||
(partial (modulo n treeSize)))
|
||||
;(println "In oldGenAlloc, doing "
|
||||
; full
|
||||
; " full trees and one partial tree of size "
|
||||
; partial)
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i full))
|
||||
(vector-set! trees where (makeTree treeHeight))
|
||||
(set! where
|
||||
(modulo (+ where 1) (vector-length trees))))
|
||||
(let loop ((partial partial))
|
||||
(if (> partial INSIGNIFICANT)
|
||||
(let* ((h (bytesToHeight partial))
|
||||
(newTree (makeTree h)))
|
||||
(replaceTree (vector-ref trees where) newTree)
|
||||
(set! where
|
||||
(modulo (+ where 1) (vector-length trees)))
|
||||
(loop (- partial (heightToBytes h))))))))
|
||||
|
||||
; Interchanges two randomly selected subtrees (of same size and depth).
|
||||
|
||||
(define (oldGenSwapSubtrees)
|
||||
; Randomly pick:
|
||||
; * two tree indices
|
||||
; * A depth
|
||||
; * A path to that depth.
|
||||
(let* ((index1 (rnd (vector-length trees)))
|
||||
(index2 (rnd (vector-length trees)))
|
||||
(depth (rnd treeHeight))
|
||||
(path (rnd pathBits))
|
||||
(tn1 (vector-ref trees index1))
|
||||
(tn2 (vector-ref trees index2)))
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i depth))
|
||||
(if (even? path)
|
||||
(begin (set! tn1 (TreeNode.left tn1))
|
||||
(set! tn2 (TreeNode.left tn2)))
|
||||
(begin (set! tn1 (TreeNode.right tn1))
|
||||
(set! tn2 (TreeNode.right tn2))))
|
||||
(set! path (quotient path 2)))
|
||||
(if (even? path)
|
||||
(let ((tmp (TreeNode.left tn1)))
|
||||
(setf (TreeNode.left tn1) (TreeNode.left tn2))
|
||||
(setf (TreeNode.left tn2) tmp))
|
||||
(let ((tmp (TreeNode.right tn1)))
|
||||
(setf (TreeNode.right tn1) (TreeNode.right tn2))
|
||||
(setf (TreeNode.right tn2) tmp)))
|
||||
(set! actuallyMut (+ actuallyMut 2))))
|
||||
|
||||
; Update "n" old-generation pointers.
|
||||
|
||||
(define (oldGenMut n)
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i (quotient n 2)))
|
||||
(oldGenSwapSubtrees)))
|
||||
|
||||
; Does the amount of mutator work appropriate for n bytes of young-gen
|
||||
; garbage allocation.
|
||||
|
||||
(define (doMutWork n)
|
||||
(let ((limit (quotient (* workUnits n) 10)))
|
||||
(do ((k 0 (+ k 1))
|
||||
(sum 0 (+ sum 1)))
|
||||
((>= k limit)
|
||||
; We don't want dead code elimination to eliminate this loop.
|
||||
(set! mutatorSum (+ mutatorSum sum))))))
|
||||
|
||||
; Allocate n bytes of young-gen garbage, in units of "nwords"
|
||||
; words.
|
||||
|
||||
(define (doYoungGenAlloc n nwords)
|
||||
(let ((nbytes (* nwords bytes/word)))
|
||||
(do ((allocated 0 (+ allocated nbytes)))
|
||||
((>= allocated n)
|
||||
(set! youngBytes (+ youngBytes allocated)))
|
||||
(set! aexport (make-vector nwords 0)))))
|
||||
|
||||
; Allocate "n" bytes of young-gen data; and do the
|
||||
; corresponding amount of old-gen allocation and pointer
|
||||
; mutation.
|
||||
|
||||
; oldGenAlloc may perform some mutations, so this code
|
||||
; takes those mutations into account.
|
||||
|
||||
(define (doStep n)
|
||||
(let ((mutations actuallyMut))
|
||||
(doYoungGenAlloc n words/dead)
|
||||
(doMutWork n)
|
||||
; Now do old-gen allocation
|
||||
(oldGenAlloc (quotient n promoteRate))
|
||||
(oldGenMut (max 0 (- (+ mutations ptrMutRate) actuallyMut)))))
|
||||
|
||||
(println size " megabytes")
|
||||
(println workUnits " work units per step.")
|
||||
(println "promotion ratio is 1:" promoteRate)
|
||||
(println "pointer mutation rate is " ptrMutRate)
|
||||
(println steps " steps")
|
||||
|
||||
(init)
|
||||
(checkTrees)
|
||||
(set! youngBytes 0)
|
||||
(set! nodes 0)
|
||||
|
||||
(println "Initialization complete...")
|
||||
|
||||
(run-benchmark "GCOld"
|
||||
1
|
||||
(lambda ()
|
||||
(lambda ()
|
||||
(do ((step 0 (+ step 1)))
|
||||
((>= step steps))
|
||||
(doStep MEG))))
|
||||
(lambda (result) #t))
|
||||
|
||||
(checkTrees)
|
||||
|
||||
(println "Allocated " steps " Mb of young gen garbage")
|
||||
(println " (actually allocated "
|
||||
(round2 (/ youngBytes MEG))
|
||||
" megabytes)")
|
||||
(println "Promoted " (round2 (/ steps promoteRate)) " Mb")
|
||||
(println " (actually promoted "
|
||||
(round2 (/ (* nodes bytes/node) MEG))
|
||||
" megabytes)")
|
||||
(if (not (zero? ptrMutRate))
|
||||
(println "Mutated " actuallyMut " pointers"))
|
||||
|
||||
; This output serves mainly to discourage optimization.
|
||||
|
||||
(+ mutatorSum (vector-length aexport))))
|
||||
|
||||
(define (gcold-benchmark . args)
|
||||
(define gcold-iters 1)
|
||||
|
||||
(GCOld 25 0 10 10 gcold-iters))
|
644
gc-benchmarks/larceny/graphs.sch
Normal file
644
gc-benchmarks/larceny/graphs.sch
Normal file
|
@ -0,0 +1,644 @@
|
|||
; Modified 2 March 1997 by Will Clinger to add graphs-benchmark
|
||||
; and to expand the four macros below.
|
||||
; Modified 11 June 1997 by Will Clinger to eliminate assertions
|
||||
; and to replace a use of "recur" with a named let.
|
||||
;
|
||||
; Performance note: (graphs-benchmark 7) allocates
|
||||
; 34509143 pairs
|
||||
; 389625 vectors with 2551590 elements
|
||||
; 56653504 closures (not counting top level and known procedures)
|
||||
|
||||
(define (graphs-benchmark . rest)
|
||||
(let ((N (if (null? rest) 7 (car rest))))
|
||||
(run-benchmark (string-append "graphs" (number->string N))
|
||||
(lambda ()
|
||||
(fold-over-rdg N
|
||||
2
|
||||
cons
|
||||
'())))))
|
||||
|
||||
; End of new code.
|
||||
|
||||
;;; ==== std.ss ====
|
||||
|
||||
; (define-syntax assert
|
||||
; (syntax-rules ()
|
||||
; ((assert test info-rest ...)
|
||||
; #F)))
|
||||
;
|
||||
; (define-syntax deny
|
||||
; (syntax-rules ()
|
||||
; ((deny test info-rest ...)
|
||||
; #F)))
|
||||
;
|
||||
; (define-syntax when
|
||||
; (syntax-rules ()
|
||||
; ((when test e-first e-rest ...)
|
||||
; (if test
|
||||
; (begin e-first
|
||||
; e-rest ...)))))
|
||||
;
|
||||
; (define-syntax unless
|
||||
; (syntax-rules ()
|
||||
; ((unless test e-first e-rest ...)
|
||||
; (if (not test)
|
||||
; (begin e-first
|
||||
; e-rest ...)))))
|
||||
|
||||
(define assert
|
||||
(lambda (test . info)
|
||||
#f))
|
||||
|
||||
;;; ==== util.ss ====
|
||||
|
||||
|
||||
; Fold over list elements, associating to the left.
|
||||
(define fold
|
||||
(lambda (lst folder state)
|
||||
'(assert (list? lst)
|
||||
lst)
|
||||
'(assert (procedure? folder)
|
||||
folder)
|
||||
(do ((lst lst
|
||||
(cdr lst))
|
||||
(state state
|
||||
(folder (car lst)
|
||||
state)))
|
||||
((null? lst)
|
||||
state))))
|
||||
|
||||
; Given the size of a vector and a procedure which
|
||||
; sends indicies to desired vector elements, create
|
||||
; and return the vector.
|
||||
(define proc->vector
|
||||
(lambda (size f)
|
||||
'(assert (and (integer? size)
|
||||
(exact? size)
|
||||
(>= size 0))
|
||||
size)
|
||||
'(assert (procedure? f)
|
||||
f)
|
||||
(if (zero? size)
|
||||
(vector)
|
||||
(let ((x (make-vector size (f 0))))
|
||||
(let loop ((i 1))
|
||||
(if (< i size) (begin ; [wdc - was when]
|
||||
(vector-set! x i (f i))
|
||||
(loop (+ i 1)))))
|
||||
x))))
|
||||
|
||||
(define vector-fold
|
||||
(lambda (vec folder state)
|
||||
'(assert (vector? vec)
|
||||
vec)
|
||||
'(assert (procedure? folder)
|
||||
folder)
|
||||
(let ((len
|
||||
(vector-length vec)))
|
||||
(do ((i 0
|
||||
(+ i 1))
|
||||
(state state
|
||||
(folder (vector-ref vec i)
|
||||
state)))
|
||||
((= i len)
|
||||
state)))))
|
||||
|
||||
(define vector-map
|
||||
(lambda (vec proc)
|
||||
(proc->vector (vector-length vec)
|
||||
(lambda (i)
|
||||
(proc (vector-ref vec i))))))
|
||||
|
||||
; Given limit, return the list 0, 1, ..., limit-1.
|
||||
(define giota
|
||||
(lambda (limit)
|
||||
'(assert (and (integer? limit)
|
||||
(exact? limit)
|
||||
(>= limit 0))
|
||||
limit)
|
||||
(let -*-
|
||||
((limit
|
||||
limit)
|
||||
(res
|
||||
'()))
|
||||
(if (zero? limit)
|
||||
res
|
||||
(let ((limit
|
||||
(- limit 1)))
|
||||
(-*- limit
|
||||
(cons limit res)))))))
|
||||
|
||||
; Fold over the integers [0, limit).
|
||||
(define gnatural-fold
|
||||
(lambda (limit folder state)
|
||||
'(assert (and (integer? limit)
|
||||
(exact? limit)
|
||||
(>= limit 0))
|
||||
limit)
|
||||
'(assert (procedure? folder)
|
||||
folder)
|
||||
(do ((i 0
|
||||
(+ i 1))
|
||||
(state state
|
||||
(folder i state)))
|
||||
((= i limit)
|
||||
state))))
|
||||
|
||||
; Iterate over the integers [0, limit).
|
||||
(define gnatural-for-each
|
||||
(lambda (limit proc!)
|
||||
'(assert (and (integer? limit)
|
||||
(exact? limit)
|
||||
(>= limit 0))
|
||||
limit)
|
||||
'(assert (procedure? proc!)
|
||||
proc!)
|
||||
(do ((i 0
|
||||
(+ i 1)))
|
||||
((= i limit))
|
||||
(proc! i))))
|
||||
|
||||
(define natural-for-all?
|
||||
(lambda (limit ok?)
|
||||
'(assert (and (integer? limit)
|
||||
(exact? limit)
|
||||
(>= limit 0))
|
||||
limit)
|
||||
'(assert (procedure? ok?)
|
||||
ok?)
|
||||
(let -*-
|
||||
((i 0))
|
||||
(or (= i limit)
|
||||
(and (ok? i)
|
||||
(-*- (+ i 1)))))))
|
||||
|
||||
(define natural-there-exists?
|
||||
(lambda (limit ok?)
|
||||
'(assert (and (integer? limit)
|
||||
(exact? limit)
|
||||
(>= limit 0))
|
||||
limit)
|
||||
'(assert (procedure? ok?)
|
||||
ok?)
|
||||
(let -*-
|
||||
((i 0))
|
||||
(and (not (= i limit))
|
||||
(or (ok? i)
|
||||
(-*- (+ i 1)))))))
|
||||
|
||||
(define there-exists?
|
||||
(lambda (lst ok?)
|
||||
'(assert (list? lst)
|
||||
lst)
|
||||
'(assert (procedure? ok?)
|
||||
ok?)
|
||||
(let -*-
|
||||
((lst lst))
|
||||
(and (not (null? lst))
|
||||
(or (ok? (car lst))
|
||||
(-*- (cdr lst)))))))
|
||||
|
||||
|
||||
;;; ==== ptfold.ss ====
|
||||
|
||||
|
||||
; Fold over the tree of permutations of a universe.
|
||||
; Each branch (from the root) is a permutation of universe.
|
||||
; Each node at depth d corresponds to all permutations which pick the
|
||||
; elements spelled out on the branch from the root to that node as
|
||||
; the first d elements.
|
||||
; Their are two components to the state:
|
||||
; The b-state is only a function of the branch from the root.
|
||||
; The t-state is a function of all nodes seen so far.
|
||||
; At each node, b-folder is called via
|
||||
; (b-folder elem b-state t-state deeper accross)
|
||||
; where elem is the next element of the universe picked.
|
||||
; If b-folder can determine the result of the total tree fold at this stage,
|
||||
; it should simply return the result.
|
||||
; If b-folder can determine the result of folding over the sub-tree
|
||||
; rooted at the resulting node, it should call accross via
|
||||
; (accross new-t-state)
|
||||
; where new-t-state is that result.
|
||||
; Otherwise, b-folder should call deeper via
|
||||
; (deeper new-b-state new-t-state)
|
||||
; where new-b-state is the b-state for the new node and new-t-state is
|
||||
; the new folded t-state.
|
||||
; At the leaves of the tree, t-folder is called via
|
||||
; (t-folder b-state t-state accross)
|
||||
; If t-folder can determine the result of the total tree fold at this stage,
|
||||
; it should simply return that result.
|
||||
; If not, it should call accross via
|
||||
; (accross new-t-state)
|
||||
; Note, fold-over-perm-tree always calls b-folder in depth-first order.
|
||||
; I.e., when b-folder is called at depth d, the branch leading to that
|
||||
; node is the most recent calls to b-folder at all the depths less than d.
|
||||
; This is a gross efficiency hack so that b-folder can use mutation to
|
||||
; keep the current branch.
|
||||
(define fold-over-perm-tree
|
||||
(lambda (universe b-folder b-state t-folder t-state)
|
||||
'(assert (list? universe)
|
||||
universe)
|
||||
'(assert (procedure? b-folder)
|
||||
b-folder)
|
||||
'(assert (procedure? t-folder)
|
||||
t-folder)
|
||||
(let -*-
|
||||
((universe
|
||||
universe)
|
||||
(b-state
|
||||
b-state)
|
||||
(t-state
|
||||
t-state)
|
||||
(accross
|
||||
(lambda (final-t-state)
|
||||
final-t-state)))
|
||||
(if (null? universe)
|
||||
(t-folder b-state t-state accross)
|
||||
(let -**-
|
||||
((in
|
||||
universe)
|
||||
(out
|
||||
'())
|
||||
(t-state
|
||||
t-state))
|
||||
(let* ((first
|
||||
(car in))
|
||||
(rest
|
||||
(cdr in))
|
||||
(accross
|
||||
(if (null? rest)
|
||||
accross
|
||||
(lambda (new-t-state)
|
||||
(-**- rest
|
||||
(cons first out)
|
||||
new-t-state)))))
|
||||
(b-folder first
|
||||
b-state
|
||||
t-state
|
||||
(lambda (new-b-state new-t-state)
|
||||
(-*- (fold out cons rest)
|
||||
new-b-state
|
||||
new-t-state
|
||||
accross))
|
||||
accross)))))))
|
||||
|
||||
|
||||
;;; ==== minimal.ss ====
|
||||
|
||||
|
||||
; A directed graph is stored as a connection matrix (vector-of-vectors)
|
||||
; where the first index is the `from' vertex and the second is the `to'
|
||||
; vertex. Each entry is a bool indicating if the edge exists.
|
||||
; The diagonal of the matrix is never examined.
|
||||
; Make-minimal? returns a procedure which tests if a labelling
|
||||
; of the verticies is such that the matrix is minimal.
|
||||
; If it is, then the procedure returns the result of folding over
|
||||
; the elements of the automoriphism group. If not, it returns #F.
|
||||
; The folding is done by calling folder via
|
||||
; (folder perm state accross)
|
||||
; If the folder wants to continue, it should call accross via
|
||||
; (accross new-state)
|
||||
; If it just wants the entire minimal? procedure to return something,
|
||||
; it should return that.
|
||||
; The ordering used is lexicographic (with #T > #F) and entries
|
||||
; are examined in the following order:
|
||||
; 1->0, 0->1
|
||||
;
|
||||
; 2->0, 0->2
|
||||
; 2->1, 1->2
|
||||
;
|
||||
; 3->0, 0->3
|
||||
; 3->1, 1->3
|
||||
; 3->2, 2->3
|
||||
; ...
|
||||
(define make-minimal?
|
||||
(lambda (max-size)
|
||||
'(assert (and (integer? max-size)
|
||||
(exact? max-size)
|
||||
(>= max-size 0))
|
||||
max-size)
|
||||
(let ((iotas
|
||||
(proc->vector (+ max-size 1)
|
||||
giota))
|
||||
(perm
|
||||
(make-vector max-size 0)))
|
||||
(lambda (size graph folder state)
|
||||
'(assert (and (integer? size)
|
||||
(exact? size)
|
||||
(<= 0 size max-size))
|
||||
size
|
||||
max-size)
|
||||
'(assert (vector? graph)
|
||||
graph)
|
||||
'(assert (procedure? folder)
|
||||
folder)
|
||||
(fold-over-perm-tree (vector-ref iotas size)
|
||||
(lambda (perm-x x state deeper accross)
|
||||
(case (cmp-next-vertex graph perm x perm-x)
|
||||
((less)
|
||||
#F)
|
||||
((equal)
|
||||
(vector-set! perm x perm-x)
|
||||
(deeper (+ x 1)
|
||||
state))
|
||||
((more)
|
||||
(accross state))
|
||||
(else
|
||||
(assert #F))))
|
||||
0
|
||||
(lambda (leaf-depth state accross)
|
||||
'(assert (eqv? leaf-depth size)
|
||||
leaf-depth
|
||||
size)
|
||||
(folder perm state accross))
|
||||
state)))))
|
||||
|
||||
; Given a graph, a partial permutation vector, the next input and the next
|
||||
; output, return 'less, 'equal or 'more depending on the lexicographic
|
||||
; comparison between the permuted and un-permuted graph.
|
||||
(define cmp-next-vertex
|
||||
(lambda (graph perm x perm-x)
|
||||
(let ((from-x
|
||||
(vector-ref graph x))
|
||||
(from-perm-x
|
||||
(vector-ref graph perm-x)))
|
||||
(let -*-
|
||||
((y
|
||||
0))
|
||||
(if (= x y)
|
||||
'equal
|
||||
(let ((x->y?
|
||||
(vector-ref from-x y))
|
||||
(perm-y
|
||||
(vector-ref perm y)))
|
||||
(cond ((eq? x->y?
|
||||
(vector-ref from-perm-x perm-y))
|
||||
(let ((y->x?
|
||||
(vector-ref (vector-ref graph y)
|
||||
x)))
|
||||
(cond ((eq? y->x?
|
||||
(vector-ref (vector-ref graph perm-y)
|
||||
perm-x))
|
||||
(-*- (+ y 1)))
|
||||
(y->x?
|
||||
'less)
|
||||
(else
|
||||
'more))))
|
||||
(x->y?
|
||||
'less)
|
||||
(else
|
||||
'more))))))))
|
||||
|
||||
|
||||
;;; ==== rdg.ss ====
|
||||
|
||||
|
||||
; Fold over rooted directed graphs with bounded out-degree.
|
||||
; Size is the number of verticies (including the root). Max-out is the
|
||||
; maximum out-degree for any vertex. Folder is called via
|
||||
; (folder edges state)
|
||||
; where edges is a list of length size. The ith element of the list is
|
||||
; a list of the verticies j for which there is an edge from i to j.
|
||||
; The last vertex is the root.
|
||||
(define fold-over-rdg
|
||||
(lambda (size max-out folder state)
|
||||
'(assert (and (exact? size)
|
||||
(integer? size)
|
||||
(> size 0))
|
||||
size)
|
||||
'(assert (and (exact? max-out)
|
||||
(integer? max-out)
|
||||
(>= max-out 0))
|
||||
max-out)
|
||||
'(assert (procedure? folder)
|
||||
folder)
|
||||
(let* ((root
|
||||
(- size 1))
|
||||
(edge?
|
||||
(proc->vector size
|
||||
(lambda (from)
|
||||
(make-vector size #F))))
|
||||
(edges
|
||||
(make-vector size '()))
|
||||
(out-degrees
|
||||
(make-vector size 0))
|
||||
(minimal-folder
|
||||
(make-minimal? root))
|
||||
(non-root-minimal?
|
||||
(let ((cont
|
||||
(lambda (perm state accross)
|
||||
'(assert (eq? state #T)
|
||||
state)
|
||||
(accross #T))))
|
||||
(lambda (size)
|
||||
(minimal-folder size
|
||||
edge?
|
||||
cont
|
||||
#T))))
|
||||
(root-minimal?
|
||||
(let ((cont
|
||||
(lambda (perm state accross)
|
||||
'(assert (eq? state #T)
|
||||
state)
|
||||
(case (cmp-next-vertex edge? perm root root)
|
||||
((less)
|
||||
#F)
|
||||
((equal more)
|
||||
(accross #T))
|
||||
(else
|
||||
(assert #F))))))
|
||||
(lambda ()
|
||||
(minimal-folder root
|
||||
edge?
|
||||
cont
|
||||
#T)))))
|
||||
(let -*-
|
||||
((vertex
|
||||
0)
|
||||
(state
|
||||
state))
|
||||
(cond ((not (non-root-minimal? vertex))
|
||||
state)
|
||||
((= vertex root)
|
||||
'(assert
|
||||
(begin
|
||||
(gnatural-for-each root
|
||||
(lambda (v)
|
||||
'(assert (= (vector-ref out-degrees v)
|
||||
(length (vector-ref edges v)))
|
||||
v
|
||||
(vector-ref out-degrees v)
|
||||
(vector-ref edges v))))
|
||||
#T))
|
||||
(let ((reach?
|
||||
(make-reach? root edges))
|
||||
(from-root
|
||||
(vector-ref edge? root)))
|
||||
(let -*-
|
||||
((v
|
||||
0)
|
||||
(outs
|
||||
0)
|
||||
(efr
|
||||
'())
|
||||
(efrr
|
||||
'())
|
||||
(state
|
||||
state))
|
||||
(cond ((not (or (= v root)
|
||||
(= outs max-out)))
|
||||
(vector-set! from-root v #T)
|
||||
(let ((state
|
||||
(-*- (+ v 1)
|
||||
(+ outs 1)
|
||||
(cons v efr)
|
||||
(cons (vector-ref reach? v)
|
||||
efrr)
|
||||
state)))
|
||||
(vector-set! from-root v #F)
|
||||
(-*- (+ v 1)
|
||||
outs
|
||||
efr
|
||||
efrr
|
||||
state)))
|
||||
((and (natural-for-all? root
|
||||
(lambda (v)
|
||||
(there-exists? efrr
|
||||
(lambda (r)
|
||||
(vector-ref r v)))))
|
||||
(root-minimal?))
|
||||
(vector-set! edges root efr)
|
||||
(folder
|
||||
(proc->vector size
|
||||
(lambda (i)
|
||||
(vector-ref edges i)))
|
||||
state))
|
||||
(else
|
||||
state)))))
|
||||
(else
|
||||
(let ((from-vertex
|
||||
(vector-ref edge? vertex)))
|
||||
(let -**-
|
||||
((sv
|
||||
0)
|
||||
(outs
|
||||
0)
|
||||
(state
|
||||
state))
|
||||
(if (= sv vertex)
|
||||
(begin
|
||||
(vector-set! out-degrees vertex outs)
|
||||
(-*- (+ vertex 1)
|
||||
state))
|
||||
(let* ((state
|
||||
; no sv->vertex, no vertex->sv
|
||||
(-**- (+ sv 1)
|
||||
outs
|
||||
state))
|
||||
(from-sv
|
||||
(vector-ref edge? sv))
|
||||
(sv-out
|
||||
(vector-ref out-degrees sv))
|
||||
(state
|
||||
(if (= sv-out max-out)
|
||||
state
|
||||
(begin
|
||||
(vector-set! edges
|
||||
sv
|
||||
(cons vertex
|
||||
(vector-ref edges sv)))
|
||||
(vector-set! from-sv vertex #T)
|
||||
(vector-set! out-degrees sv (+ sv-out 1))
|
||||
(let* ((state
|
||||
; sv->vertex, no vertex->sv
|
||||
(-**- (+ sv 1)
|
||||
outs
|
||||
state))
|
||||
(state
|
||||
(if (= outs max-out)
|
||||
state
|
||||
(begin
|
||||
(vector-set! from-vertex sv #T)
|
||||
(vector-set! edges
|
||||
vertex
|
||||
(cons sv
|
||||
(vector-ref edges vertex)))
|
||||
(let ((state
|
||||
; sv->vertex, vertex->sv
|
||||
(-**- (+ sv 1)
|
||||
(+ outs 1)
|
||||
state)))
|
||||
(vector-set! edges
|
||||
vertex
|
||||
(cdr (vector-ref edges vertex)))
|
||||
(vector-set! from-vertex sv #F)
|
||||
state)))))
|
||||
(vector-set! out-degrees sv sv-out)
|
||||
(vector-set! from-sv vertex #F)
|
||||
(vector-set! edges
|
||||
sv
|
||||
(cdr (vector-ref edges sv)))
|
||||
state)))))
|
||||
(if (= outs max-out)
|
||||
state
|
||||
(begin
|
||||
(vector-set! edges
|
||||
vertex
|
||||
(cons sv
|
||||
(vector-ref edges vertex)))
|
||||
(vector-set! from-vertex sv #T)
|
||||
(let ((state
|
||||
; no sv->vertex, vertex->sv
|
||||
(-**- (+ sv 1)
|
||||
(+ outs 1)
|
||||
state)))
|
||||
(vector-set! from-vertex sv #F)
|
||||
(vector-set! edges
|
||||
vertex
|
||||
(cdr (vector-ref edges vertex)))
|
||||
state)))))))))))))
|
||||
|
||||
; Given a vector which maps vertex to out-going-edge list,
|
||||
; return a vector which gives reachability.
|
||||
(define make-reach?
|
||||
(lambda (size vertex->out)
|
||||
(let ((res
|
||||
(proc->vector size
|
||||
(lambda (v)
|
||||
(let ((from-v
|
||||
(make-vector size #F)))
|
||||
(vector-set! from-v v #T)
|
||||
(for-each
|
||||
(lambda (x)
|
||||
(vector-set! from-v x #T))
|
||||
(vector-ref vertex->out v))
|
||||
from-v)))))
|
||||
(gnatural-for-each size
|
||||
(lambda (m)
|
||||
(let ((from-m
|
||||
(vector-ref res m)))
|
||||
(gnatural-for-each size
|
||||
(lambda (f)
|
||||
(let ((from-f
|
||||
(vector-ref res f)))
|
||||
(if (vector-ref from-f m); [wdc - was when]
|
||||
(begin
|
||||
(gnatural-for-each size
|
||||
(lambda (t)
|
||||
(if (vector-ref from-m t)
|
||||
(begin ; [wdc - was when]
|
||||
(vector-set! from-f t #T)))))))))))))
|
||||
res)))
|
||||
|
||||
|
||||
;;; ==== test input ====
|
||||
|
||||
; Produces all directed graphs with N verticies, distinguished root,
|
||||
; and out-degree bounded by 2, upto isomorphism (there are 44).
|
||||
|
||||
;(define go
|
||||
; (let ((N 7))
|
||||
; (fold-over-rdg N
|
||||
; 2
|
||||
; cons
|
||||
; '())))
|
219
gc-benchmarks/larceny/lattice.sch
Normal file
219
gc-benchmarks/larceny/lattice.sch
Normal file
|
@ -0,0 +1,219 @@
|
|||
; This benchmark was obtained from Andrew Wright.
|
||||
; 970215 / wdc Added lattice-benchmark.
|
||||
|
||||
; Given a comparison routine that returns one of
|
||||
; less
|
||||
; more
|
||||
; equal
|
||||
; uncomparable
|
||||
; return a new comparison routine that applies to sequences.
|
||||
(define lexico
|
||||
(lambda (base)
|
||||
(define lex-fixed
|
||||
(lambda (fixed lhs rhs)
|
||||
(define check
|
||||
(lambda (lhs rhs)
|
||||
(if (null? lhs)
|
||||
fixed
|
||||
(let ((probe
|
||||
(base (car lhs)
|
||||
(car rhs))))
|
||||
(if (or (eq? probe 'equal)
|
||||
(eq? probe fixed))
|
||||
(check (cdr lhs)
|
||||
(cdr rhs))
|
||||
'uncomparable)))))
|
||||
(check lhs rhs)))
|
||||
(define lex-first
|
||||
(lambda (lhs rhs)
|
||||
(if (null? lhs)
|
||||
'equal
|
||||
(let ((probe
|
||||
(base (car lhs)
|
||||
(car rhs))))
|
||||
(case probe
|
||||
((less more)
|
||||
(lex-fixed probe
|
||||
(cdr lhs)
|
||||
(cdr rhs)))
|
||||
((equal)
|
||||
(lex-first (cdr lhs)
|
||||
(cdr rhs)))
|
||||
((uncomparable)
|
||||
'uncomparable))))))
|
||||
lex-first))
|
||||
|
||||
(define (make-lattice elem-list cmp-func)
|
||||
(cons elem-list cmp-func))
|
||||
|
||||
(define lattice->elements car)
|
||||
|
||||
(define lattice->cmp cdr)
|
||||
|
||||
; Select elements of a list which pass some test.
|
||||
(define zulu-select
|
||||
(lambda (test lst)
|
||||
(define select-a
|
||||
(lambda (ac lst)
|
||||
(if (null? lst)
|
||||
(reverse! ac)
|
||||
(select-a
|
||||
(let ((head (car lst)))
|
||||
(if (test head)
|
||||
(cons head ac)
|
||||
ac))
|
||||
(cdr lst)))))
|
||||
(select-a '() lst)))
|
||||
|
||||
(define reverse!
|
||||
(letrec ((rotate
|
||||
(lambda (fo fum)
|
||||
(let ((next (cdr fo)))
|
||||
(set-cdr! fo fum)
|
||||
(if (null? next)
|
||||
fo
|
||||
(rotate next fo))))))
|
||||
(lambda (lst)
|
||||
(if (null? lst)
|
||||
'()
|
||||
(rotate lst '())))))
|
||||
|
||||
; Select elements of a list which pass some test and map a function
|
||||
; over the result. Note, only efficiency prevents this from being the
|
||||
; composition of select and map.
|
||||
(define select-map
|
||||
(lambda (test func lst)
|
||||
(define select-a
|
||||
(lambda (ac lst)
|
||||
(if (null? lst)
|
||||
(reverse! ac)
|
||||
(select-a
|
||||
(let ((head (car lst)))
|
||||
(if (test head)
|
||||
(cons (func head)
|
||||
ac)
|
||||
ac))
|
||||
(cdr lst)))))
|
||||
(select-a '() lst)))
|
||||
|
||||
|
||||
|
||||
; This version of map-and tail-recurses on the last test.
|
||||
(define map-and
|
||||
(lambda (proc lst)
|
||||
(if (null? lst)
|
||||
#T
|
||||
(letrec ((drudge
|
||||
(lambda (lst)
|
||||
(let ((rest (cdr lst)))
|
||||
(if (null? rest)
|
||||
(proc (car lst))
|
||||
(and (proc (car lst))
|
||||
(drudge rest)))))))
|
||||
(drudge lst)))))
|
||||
|
||||
(define (maps-1 source target pas new)
|
||||
(let ((scmp (lattice->cmp source))
|
||||
(tcmp (lattice->cmp target)))
|
||||
(let ((less
|
||||
(select-map
|
||||
(lambda (p)
|
||||
(eq? 'less
|
||||
(scmp (car p) new)))
|
||||
cdr
|
||||
pas))
|
||||
(more
|
||||
(select-map
|
||||
(lambda (p)
|
||||
(eq? 'more
|
||||
(scmp (car p) new)))
|
||||
cdr
|
||||
pas)))
|
||||
(zulu-select
|
||||
(lambda (t)
|
||||
(and
|
||||
(map-and
|
||||
(lambda (t2)
|
||||
(memq (tcmp t2 t) '(less equal)))
|
||||
less)
|
||||
(map-and
|
||||
(lambda (t2)
|
||||
(memq (tcmp t2 t) '(more equal)))
|
||||
more)))
|
||||
(lattice->elements target)))))
|
||||
|
||||
(define (maps-rest source target pas rest to-1 to-collect)
|
||||
(if (null? rest)
|
||||
(to-1 pas)
|
||||
(let ((next (car rest))
|
||||
(rest (cdr rest)))
|
||||
(to-collect
|
||||
(map
|
||||
(lambda (x)
|
||||
(maps-rest source target
|
||||
(cons
|
||||
(cons next x)
|
||||
pas)
|
||||
rest
|
||||
to-1
|
||||
to-collect))
|
||||
(maps-1 source target pas next))))))
|
||||
|
||||
(define (maps source target)
|
||||
(make-lattice
|
||||
(maps-rest source
|
||||
target
|
||||
'()
|
||||
(lattice->elements source)
|
||||
(lambda (x) (list (map cdr x)))
|
||||
(lambda (x) (apply append x)))
|
||||
(lexico (lattice->cmp target))))
|
||||
|
||||
(define print-frequency 10000)
|
||||
|
||||
(define (count-maps source target)
|
||||
(let ((count 0))
|
||||
(maps-rest source
|
||||
target
|
||||
'()
|
||||
(lattice->elements source)
|
||||
(lambda (x)
|
||||
(set! count (+ count 1))
|
||||
(if (= 0 (remainder count print-frequency))
|
||||
(begin #f))
|
||||
1)
|
||||
(lambda (x) (apply + x)))))
|
||||
|
||||
(define (lattice-benchmark)
|
||||
(run-benchmark "Lattice"
|
||||
(lambda ()
|
||||
(let* ((l2
|
||||
(make-lattice '(low high)
|
||||
(lambda (lhs rhs)
|
||||
(case lhs
|
||||
((low)
|
||||
(case rhs
|
||||
((low)
|
||||
'equal)
|
||||
((high)
|
||||
'less)
|
||||
(else
|
||||
(error 'make-lattice "base" rhs))))
|
||||
((high)
|
||||
(case rhs
|
||||
((low)
|
||||
'more)
|
||||
((high)
|
||||
'equal)
|
||||
(else
|
||||
(error 'make-lattice "base" rhs))))
|
||||
(else
|
||||
(error 'make-lattice "base" lhs))))))
|
||||
(l3 (maps l2 l2))
|
||||
(l4 (maps l3 l3)))
|
||||
(count-maps l2 l2)
|
||||
(count-maps l3 l3)
|
||||
(count-maps l2 l3)
|
||||
(count-maps l3 l2)
|
||||
(count-maps l4 l4)))))
|
||||
|
770
gc-benchmarks/larceny/nboyer.sch
Normal file
770
gc-benchmarks/larceny/nboyer.sch
Normal file
|
@ -0,0 +1,770 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; File: nboyer.sch
|
||||
; Description: The Boyer benchmark
|
||||
; Author: Bob Boyer
|
||||
; Created: 5-Apr-85
|
||||
; Modified: 10-Apr-85 14:52:20 (Bob Shaw)
|
||||
; 22-Jul-87 (Will Clinger)
|
||||
; 2-Jul-88 (Will Clinger -- distinguished #f and the empty list)
|
||||
; 13-Feb-97 (Will Clinger -- fixed bugs in unifier and rules,
|
||||
; rewrote to eliminate property lists, and added
|
||||
; a scaling parameter suggested by Bob Boyer)
|
||||
; 19-Mar-99 (Will Clinger -- cleaned up comments)
|
||||
; 4-Apr-01 (Will Clinger -- changed four 1- symbols to sub1)
|
||||
; Language: Scheme
|
||||
; Status: Public Domain
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;; NBOYER -- Logic programming benchmark, originally written by Bob Boyer.
|
||||
;;; Fairly CONS intensive.
|
||||
|
||||
; Note: The version of this benchmark that appears in Dick Gabriel's book
|
||||
; contained several bugs that are corrected here. These bugs are discussed
|
||||
; by Henry Baker, "The Boyer Benchmark Meets Linear Logic", ACM SIGPLAN Lisp
|
||||
; Pointers 6(4), October-December 1993, pages 3-10. The fixed bugs are:
|
||||
;
|
||||
; The benchmark now returns a boolean result.
|
||||
; FALSEP and TRUEP use TERM-MEMBER? rather than MEMV (which is called MEMBER
|
||||
; in Common Lisp)
|
||||
; ONE-WAY-UNIFY1 now treats numbers correctly
|
||||
; ONE-WAY-UNIFY1-LST now treats empty lists correctly
|
||||
; Rule 19 has been corrected (this rule was not touched by the original
|
||||
; benchmark, but is used by this version)
|
||||
; Rules 84 and 101 have been corrected (but these rules are never touched
|
||||
; by the benchmark)
|
||||
;
|
||||
; According to Baker, these bug fixes make the benchmark 10-25% slower.
|
||||
; Please do not compare the timings from this benchmark against those of
|
||||
; the original benchmark.
|
||||
;
|
||||
; This version of the benchmark also prints the number of rewrites as a sanity
|
||||
; check, because it is too easy for a buggy version to return the correct
|
||||
; boolean result. The correct number of rewrites is
|
||||
;
|
||||
; n rewrites peak live storage (approximate, in bytes)
|
||||
; 0 95024 520,000
|
||||
; 1 591777 2,085,000
|
||||
; 2 1813975 5,175,000
|
||||
; 3 5375678
|
||||
; 4 16445406
|
||||
; 5 51507739
|
||||
|
||||
; Nboyer is a 2-phase benchmark.
|
||||
; The first phase attaches lemmas to symbols. This phase is not timed,
|
||||
; but it accounts for very little of the runtime anyway.
|
||||
; The second phase creates the test problem, and tests to see
|
||||
; whether it is implied by the lemmas.
|
||||
|
||||
(define (nboyer-benchmark . args)
|
||||
(let ((n (if (null? args) 0 (car args))))
|
||||
(setup-boyer)
|
||||
(run-benchmark (string-append "nboyer"
|
||||
(number->string n))
|
||||
1
|
||||
(lambda () (test-boyer n))
|
||||
(lambda (rewrites)
|
||||
(and (number? rewrites)
|
||||
(case n
|
||||
((0) (= rewrites 95024))
|
||||
((1) (= rewrites 591777))
|
||||
((2) (= rewrites 1813975))
|
||||
((3) (= rewrites 5375678))
|
||||
((4) (= rewrites 16445406))
|
||||
((5) (= rewrites 51507739))
|
||||
; If it works for n <= 5, assume it works.
|
||||
(else #t)))))))
|
||||
|
||||
(define (setup-boyer) #t) ; assigned below
|
||||
(define (test-boyer) #t) ; assigned below
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;
|
||||
; The first phase.
|
||||
;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; In the original benchmark, it stored a list of lemmas on the
|
||||
; property lists of symbols.
|
||||
; In the new benchmark, it maintains an association list of
|
||||
; symbols and symbol-records, and stores the list of lemmas
|
||||
; within the symbol-records.
|
||||
|
||||
(let ()
|
||||
|
||||
(define (setup)
|
||||
(add-lemma-lst
|
||||
(quote ((equal (compile form)
|
||||
(reverse (codegen (optimize form)
|
||||
(nil))))
|
||||
(equal (eqp x y)
|
||||
(equal (fix x)
|
||||
(fix y)))
|
||||
(equal (greaterp x y)
|
||||
(lessp y x))
|
||||
(equal (lesseqp x y)
|
||||
(not (lessp y x)))
|
||||
(equal (greatereqp x y)
|
||||
(not (lessp x y)))
|
||||
(equal (boolean x)
|
||||
(or (equal x (t))
|
||||
(equal x (f))))
|
||||
(equal (iff x y)
|
||||
(and (implies x y)
|
||||
(implies y x)))
|
||||
(equal (even1 x)
|
||||
(if (zerop x)
|
||||
(t)
|
||||
(odd (sub1 x))))
|
||||
(equal (countps- l pred)
|
||||
(countps-loop l pred (zero)))
|
||||
(equal (fact- i)
|
||||
(fact-loop i 1))
|
||||
(equal (reverse- x)
|
||||
(reverse-loop x (nil)))
|
||||
(equal (divides x y)
|
||||
(zerop (remainder y x)))
|
||||
(equal (assume-true var alist)
|
||||
(cons (cons var (t))
|
||||
alist))
|
||||
(equal (assume-false var alist)
|
||||
(cons (cons var (f))
|
||||
alist))
|
||||
(equal (tautology-checker x)
|
||||
(tautologyp (normalize x)
|
||||
(nil)))
|
||||
(equal (falsify x)
|
||||
(falsify1 (normalize x)
|
||||
(nil)))
|
||||
(equal (prime x)
|
||||
(and (not (zerop x))
|
||||
(not (equal x (add1 (zero))))
|
||||
(prime1 x (sub1 x))))
|
||||
(equal (and p q)
|
||||
(if p (if q (t)
|
||||
(f))
|
||||
(f)))
|
||||
(equal (or p q)
|
||||
(if p (t)
|
||||
(if q (t)
|
||||
(f))))
|
||||
(equal (not p)
|
||||
(if p (f)
|
||||
(t)))
|
||||
(equal (implies p q)
|
||||
(if p (if q (t)
|
||||
(f))
|
||||
(t)))
|
||||
(equal (fix x)
|
||||
(if (numberp x)
|
||||
x
|
||||
(zero)))
|
||||
(equal (if (if a b c)
|
||||
d e)
|
||||
(if a (if b d e)
|
||||
(if c d e)))
|
||||
(equal (zerop x)
|
||||
(or (equal x (zero))
|
||||
(not (numberp x))))
|
||||
(equal (plus (plus x y)
|
||||
z)
|
||||
(plus x (plus y z)))
|
||||
(equal (equal (plus a b)
|
||||
(zero))
|
||||
(and (zerop a)
|
||||
(zerop b)))
|
||||
(equal (difference x x)
|
||||
(zero))
|
||||
(equal (equal (plus a b)
|
||||
(plus a c))
|
||||
(equal (fix b)
|
||||
(fix c)))
|
||||
(equal (equal (zero)
|
||||
(difference x y))
|
||||
(not (lessp y x)))
|
||||
(equal (equal x (difference x y))
|
||||
(and (numberp x)
|
||||
(or (equal x (zero))
|
||||
(zerop y))))
|
||||
(equal (meaning (plus-tree (append x y))
|
||||
a)
|
||||
(plus (meaning (plus-tree x)
|
||||
a)
|
||||
(meaning (plus-tree y)
|
||||
a)))
|
||||
(equal (meaning (plus-tree (plus-fringe x))
|
||||
a)
|
||||
(fix (meaning x a)))
|
||||
(equal (append (append x y)
|
||||
z)
|
||||
(append x (append y z)))
|
||||
(equal (reverse (append a b))
|
||||
(append (reverse b)
|
||||
(reverse a)))
|
||||
(equal (times x (plus y z))
|
||||
(plus (times x y)
|
||||
(times x z)))
|
||||
(equal (times (times x y)
|
||||
z)
|
||||
(times x (times y z)))
|
||||
(equal (equal (times x y)
|
||||
(zero))
|
||||
(or (zerop x)
|
||||
(zerop y)))
|
||||
(equal (exec (append x y)
|
||||
pds envrn)
|
||||
(exec y (exec x pds envrn)
|
||||
envrn))
|
||||
(equal (mc-flatten x y)
|
||||
(append (flatten x)
|
||||
y))
|
||||
(equal (member x (append a b))
|
||||
(or (member x a)
|
||||
(member x b)))
|
||||
(equal (member x (reverse y))
|
||||
(member x y))
|
||||
(equal (length (reverse x))
|
||||
(length x))
|
||||
(equal (member a (intersect b c))
|
||||
(and (member a b)
|
||||
(member a c)))
|
||||
(equal (nth (zero)
|
||||
i)
|
||||
(zero))
|
||||
(equal (exp i (plus j k))
|
||||
(times (exp i j)
|
||||
(exp i k)))
|
||||
(equal (exp i (times j k))
|
||||
(exp (exp i j)
|
||||
k))
|
||||
(equal (reverse-loop x y)
|
||||
(append (reverse x)
|
||||
y))
|
||||
(equal (reverse-loop x (nil))
|
||||
(reverse x))
|
||||
(equal (count-list z (sort-lp x y))
|
||||
(plus (count-list z x)
|
||||
(count-list z y)))
|
||||
(equal (equal (append a b)
|
||||
(append a c))
|
||||
(equal b c))
|
||||
(equal (plus (remainder x y)
|
||||
(times y (quotient x y)))
|
||||
(fix x))
|
||||
(equal (power-eval (big-plus1 l i base)
|
||||
base)
|
||||
(plus (power-eval l base)
|
||||
i))
|
||||
(equal (power-eval (big-plus x y i base)
|
||||
base)
|
||||
(plus i (plus (power-eval x base)
|
||||
(power-eval y base))))
|
||||
(equal (remainder y 1)
|
||||
(zero))
|
||||
(equal (lessp (remainder x y)
|
||||
y)
|
||||
(not (zerop y)))
|
||||
(equal (remainder x x)
|
||||
(zero))
|
||||
(equal (lessp (quotient i j)
|
||||
i)
|
||||
(and (not (zerop i))
|
||||
(or (zerop j)
|
||||
(not (equal j 1)))))
|
||||
(equal (lessp (remainder x y)
|
||||
x)
|
||||
(and (not (zerop y))
|
||||
(not (zerop x))
|
||||
(not (lessp x y))))
|
||||
(equal (power-eval (power-rep i base)
|
||||
base)
|
||||
(fix i))
|
||||
(equal (power-eval (big-plus (power-rep i base)
|
||||
(power-rep j base)
|
||||
(zero)
|
||||
base)
|
||||
base)
|
||||
(plus i j))
|
||||
(equal (gcd x y)
|
||||
(gcd y x))
|
||||
(equal (nth (append a b)
|
||||
i)
|
||||
(append (nth a i)
|
||||
(nth b (difference i (length a)))))
|
||||
(equal (difference (plus x y)
|
||||
x)
|
||||
(fix y))
|
||||
(equal (difference (plus y x)
|
||||
x)
|
||||
(fix y))
|
||||
(equal (difference (plus x y)
|
||||
(plus x z))
|
||||
(difference y z))
|
||||
(equal (times x (difference c w))
|
||||
(difference (times c x)
|
||||
(times w x)))
|
||||
(equal (remainder (times x z)
|
||||
z)
|
||||
(zero))
|
||||
(equal (difference (plus b (plus a c))
|
||||
a)
|
||||
(plus b c))
|
||||
(equal (difference (add1 (plus y z))
|
||||
z)
|
||||
(add1 y))
|
||||
(equal (lessp (plus x y)
|
||||
(plus x z))
|
||||
(lessp y z))
|
||||
(equal (lessp (times x z)
|
||||
(times y z))
|
||||
(and (not (zerop z))
|
||||
(lessp x y)))
|
||||
(equal (lessp y (plus x y))
|
||||
(not (zerop x)))
|
||||
(equal (gcd (times x z)
|
||||
(times y z))
|
||||
(times z (gcd x y)))
|
||||
(equal (value (normalize x)
|
||||
a)
|
||||
(value x a))
|
||||
(equal (equal (flatten x)
|
||||
(cons y (nil)))
|
||||
(and (nlistp x)
|
||||
(equal x y)))
|
||||
(equal (listp (gopher x))
|
||||
(listp x))
|
||||
(equal (samefringe x y)
|
||||
(equal (flatten x)
|
||||
(flatten y)))
|
||||
(equal (equal (greatest-factor x y)
|
||||
(zero))
|
||||
(and (or (zerop y)
|
||||
(equal y 1))
|
||||
(equal x (zero))))
|
||||
(equal (equal (greatest-factor x y)
|
||||
1)
|
||||
(equal x 1))
|
||||
(equal (numberp (greatest-factor x y))
|
||||
(not (and (or (zerop y)
|
||||
(equal y 1))
|
||||
(not (numberp x)))))
|
||||
(equal (times-list (append x y))
|
||||
(times (times-list x)
|
||||
(times-list y)))
|
||||
(equal (prime-list (append x y))
|
||||
(and (prime-list x)
|
||||
(prime-list y)))
|
||||
(equal (equal z (times w z))
|
||||
(and (numberp z)
|
||||
(or (equal z (zero))
|
||||
(equal w 1))))
|
||||
(equal (greatereqp x y)
|
||||
(not (lessp x y)))
|
||||
(equal (equal x (times x y))
|
||||
(or (equal x (zero))
|
||||
(and (numberp x)
|
||||
(equal y 1))))
|
||||
(equal (remainder (times y x)
|
||||
y)
|
||||
(zero))
|
||||
(equal (equal (times a b)
|
||||
1)
|
||||
(and (not (equal a (zero)))
|
||||
(not (equal b (zero)))
|
||||
(numberp a)
|
||||
(numberp b)
|
||||
(equal (sub1 a)
|
||||
(zero))
|
||||
(equal (sub1 b)
|
||||
(zero))))
|
||||
(equal (lessp (length (delete x l))
|
||||
(length l))
|
||||
(member x l))
|
||||
(equal (sort2 (delete x l))
|
||||
(delete x (sort2 l)))
|
||||
(equal (dsort x)
|
||||
(sort2 x))
|
||||
(equal (length (cons x1
|
||||
(cons x2
|
||||
(cons x3 (cons x4
|
||||
(cons x5
|
||||
(cons x6 x7)))))))
|
||||
(plus 6 (length x7)))
|
||||
(equal (difference (add1 (add1 x))
|
||||
2)
|
||||
(fix x))
|
||||
(equal (quotient (plus x (plus x y))
|
||||
2)
|
||||
(plus x (quotient y 2)))
|
||||
(equal (sigma (zero)
|
||||
i)
|
||||
(quotient (times i (add1 i))
|
||||
2))
|
||||
(equal (plus x (add1 y))
|
||||
(if (numberp y)
|
||||
(add1 (plus x y))
|
||||
(add1 x)))
|
||||
(equal (equal (difference x y)
|
||||
(difference z y))
|
||||
(if (lessp x y)
|
||||
(not (lessp y z))
|
||||
(if (lessp z y)
|
||||
(not (lessp y x))
|
||||
(equal (fix x)
|
||||
(fix z)))))
|
||||
(equal (meaning (plus-tree (delete x y))
|
||||
a)
|
||||
(if (member x y)
|
||||
(difference (meaning (plus-tree y)
|
||||
a)
|
||||
(meaning x a))
|
||||
(meaning (plus-tree y)
|
||||
a)))
|
||||
(equal (times x (add1 y))
|
||||
(if (numberp y)
|
||||
(plus x (times x y))
|
||||
(fix x)))
|
||||
(equal (nth (nil)
|
||||
i)
|
||||
(if (zerop i)
|
||||
(nil)
|
||||
(zero)))
|
||||
(equal (last (append a b))
|
||||
(if (listp b)
|
||||
(last b)
|
||||
(if (listp a)
|
||||
(cons (car (last a))
|
||||
b)
|
||||
b)))
|
||||
(equal (equal (lessp x y)
|
||||
z)
|
||||
(if (lessp x y)
|
||||
(equal (t) z)
|
||||
(equal (f) z)))
|
||||
(equal (assignment x (append a b))
|
||||
(if (assignedp x a)
|
||||
(assignment x a)
|
||||
(assignment x b)))
|
||||
(equal (car (gopher x))
|
||||
(if (listp x)
|
||||
(car (flatten x))
|
||||
(zero)))
|
||||
(equal (flatten (cdr (gopher x)))
|
||||
(if (listp x)
|
||||
(cdr (flatten x))
|
||||
(cons (zero)
|
||||
(nil))))
|
||||
(equal (quotient (times y x)
|
||||
y)
|
||||
(if (zerop y)
|
||||
(zero)
|
||||
(fix x)))
|
||||
(equal (get j (set i val mem))
|
||||
(if (eqp j i)
|
||||
val
|
||||
(get j mem)))))))
|
||||
|
||||
(define (add-lemma-lst lst)
|
||||
(cond ((null? lst)
|
||||
#t)
|
||||
(else (add-lemma (car lst))
|
||||
(add-lemma-lst (cdr lst)))))
|
||||
|
||||
(define (add-lemma term)
|
||||
(cond ((and (pair? term)
|
||||
(eq? (car term)
|
||||
(quote equal))
|
||||
(pair? (cadr term)))
|
||||
(put (car (cadr term))
|
||||
(quote lemmas)
|
||||
(cons
|
||||
(translate-term term)
|
||||
(get (car (cadr term)) (quote lemmas)))))
|
||||
(else (error "ADD-LEMMA did not like term: " term))))
|
||||
|
||||
; Translates a term by replacing its constructor symbols by symbol-records.
|
||||
|
||||
(define (translate-term term)
|
||||
(cond ((not (pair? term))
|
||||
term)
|
||||
(else (cons (symbol->symbol-record (car term))
|
||||
(translate-args (cdr term))))))
|
||||
|
||||
(define (translate-args lst)
|
||||
(cond ((null? lst)
|
||||
'())
|
||||
(else (cons (translate-term (car lst))
|
||||
(translate-args (cdr lst))))))
|
||||
|
||||
; For debugging only, so the use of MAP does not change
|
||||
; the first-order character of the benchmark.
|
||||
|
||||
(define (untranslate-term term)
|
||||
(cond ((not (pair? term))
|
||||
term)
|
||||
(else (cons (get-name (car term))
|
||||
(map untranslate-term (cdr term))))))
|
||||
|
||||
; A symbol-record is represented as a vector with two fields:
|
||||
; the symbol (for debugging) and
|
||||
; the list of lemmas associated with the symbol.
|
||||
|
||||
(define (put sym property value)
|
||||
(put-lemmas! (symbol->symbol-record sym) value))
|
||||
|
||||
(define (get sym property)
|
||||
(get-lemmas (symbol->symbol-record sym)))
|
||||
|
||||
(define (symbol->symbol-record sym)
|
||||
(let ((x (assq sym *symbol-records-alist*)))
|
||||
(if x
|
||||
(cdr x)
|
||||
(let ((r (make-symbol-record sym)))
|
||||
(set! *symbol-records-alist*
|
||||
(cons (cons sym r)
|
||||
*symbol-records-alist*))
|
||||
r))))
|
||||
|
||||
; Association list of symbols and symbol-records.
|
||||
|
||||
(define *symbol-records-alist* '())
|
||||
|
||||
; A symbol-record is represented as a vector with two fields:
|
||||
; the symbol (for debugging) and
|
||||
; the list of lemmas associated with the symbol.
|
||||
|
||||
(define (make-symbol-record sym)
|
||||
(vector sym '()))
|
||||
|
||||
(define (put-lemmas! symbol-record lemmas)
|
||||
(vector-set! symbol-record 1 lemmas))
|
||||
|
||||
(define (get-lemmas symbol-record)
|
||||
(vector-ref symbol-record 1))
|
||||
|
||||
(define (get-name symbol-record)
|
||||
(vector-ref symbol-record 0))
|
||||
|
||||
(define (symbol-record-equal? r1 r2)
|
||||
(eq? r1 r2))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;
|
||||
; The second phase.
|
||||
;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (test n)
|
||||
(let ((term
|
||||
(apply-subst
|
||||
(translate-alist
|
||||
(quote ((x f (plus (plus a b)
|
||||
(plus c (zero))))
|
||||
(y f (times (times a b)
|
||||
(plus c d)))
|
||||
(z f (reverse (append (append a b)
|
||||
(nil))))
|
||||
(u equal (plus a b)
|
||||
(difference x y))
|
||||
(w lessp (remainder a b)
|
||||
(member a (length b))))))
|
||||
(translate-term
|
||||
(do ((term
|
||||
(quote (implies (and (implies x y)
|
||||
(and (implies y z)
|
||||
(and (implies z u)
|
||||
(implies u w))))
|
||||
(implies x w)))
|
||||
(list 'or term '(f)))
|
||||
(n n (- n 1)))
|
||||
((zero? n) term))))))
|
||||
(tautp term)))
|
||||
|
||||
(define (translate-alist alist)
|
||||
(cond ((null? alist)
|
||||
'())
|
||||
(else (cons (cons (caar alist)
|
||||
(translate-term (cdar alist)))
|
||||
(translate-alist (cdr alist))))))
|
||||
|
||||
(define (apply-subst alist term)
|
||||
(cond ((not (pair? term))
|
||||
(let ((temp-temp (assq term alist)))
|
||||
(if temp-temp
|
||||
(cdr temp-temp)
|
||||
term)))
|
||||
(else (cons (car term)
|
||||
(apply-subst-lst alist (cdr term))))))
|
||||
|
||||
(define (apply-subst-lst alist lst)
|
||||
(cond ((null? lst)
|
||||
'())
|
||||
(else (cons (apply-subst alist (car lst))
|
||||
(apply-subst-lst alist (cdr lst))))))
|
||||
|
||||
(define (tautp x)
|
||||
(tautologyp (rewrite x)
|
||||
'() '()))
|
||||
|
||||
(define (tautologyp x true-lst false-lst)
|
||||
(cond ((truep x true-lst)
|
||||
#t)
|
||||
((falsep x false-lst)
|
||||
#f)
|
||||
((not (pair? x))
|
||||
#f)
|
||||
((eq? (car x) if-constructor)
|
||||
(cond ((truep (cadr x)
|
||||
true-lst)
|
||||
(tautologyp (caddr x)
|
||||
true-lst false-lst))
|
||||
((falsep (cadr x)
|
||||
false-lst)
|
||||
(tautologyp (cadddr x)
|
||||
true-lst false-lst))
|
||||
(else (and (tautologyp (caddr x)
|
||||
(cons (cadr x)
|
||||
true-lst)
|
||||
false-lst)
|
||||
(tautologyp (cadddr x)
|
||||
true-lst
|
||||
(cons (cadr x)
|
||||
false-lst))))))
|
||||
(else #f)))
|
||||
|
||||
(define if-constructor '*) ; becomes (symbol->symbol-record 'if)
|
||||
|
||||
(define rewrite-count 0) ; sanity check
|
||||
|
||||
(define (rewrite term)
|
||||
(set! rewrite-count (+ rewrite-count 1))
|
||||
(cond ((not (pair? term))
|
||||
term)
|
||||
(else (rewrite-with-lemmas (cons (car term)
|
||||
(rewrite-args (cdr term)))
|
||||
(get-lemmas (car term))))))
|
||||
|
||||
(define (rewrite-args lst)
|
||||
(cond ((null? lst)
|
||||
'())
|
||||
(else (cons (rewrite (car lst))
|
||||
(rewrite-args (cdr lst))))))
|
||||
|
||||
(define (rewrite-with-lemmas term lst)
|
||||
(cond ((null? lst)
|
||||
term)
|
||||
((one-way-unify term (cadr (car lst)))
|
||||
(rewrite (apply-subst unify-subst (caddr (car lst)))))
|
||||
(else (rewrite-with-lemmas term (cdr lst)))))
|
||||
|
||||
(define unify-subst '*)
|
||||
|
||||
(define (one-way-unify term1 term2)
|
||||
(begin (set! unify-subst '())
|
||||
(one-way-unify1 term1 term2)))
|
||||
|
||||
(define (one-way-unify1 term1 term2)
|
||||
(cond ((not (pair? term2))
|
||||
(let ((temp-temp (assq term2 unify-subst)))
|
||||
(cond (temp-temp
|
||||
(term-equal? term1 (cdr temp-temp)))
|
||||
((number? term2) ; This bug fix makes
|
||||
(equal? term1 term2)) ; nboyer 10-25% slower!
|
||||
(else
|
||||
(set! unify-subst (cons (cons term2 term1)
|
||||
unify-subst))
|
||||
#t))))
|
||||
((not (pair? term1))
|
||||
#f)
|
||||
((eq? (car term1)
|
||||
(car term2))
|
||||
(one-way-unify1-lst (cdr term1)
|
||||
(cdr term2)))
|
||||
(else #f)))
|
||||
|
||||
(define (one-way-unify1-lst lst1 lst2)
|
||||
(cond ((null? lst1)
|
||||
(null? lst2))
|
||||
((null? lst2)
|
||||
#f)
|
||||
((one-way-unify1 (car lst1)
|
||||
(car lst2))
|
||||
(one-way-unify1-lst (cdr lst1)
|
||||
(cdr lst2)))
|
||||
(else #f)))
|
||||
|
||||
(define (falsep x lst)
|
||||
(or (term-equal? x false-term)
|
||||
(term-member? x lst)))
|
||||
|
||||
(define (truep x lst)
|
||||
(or (term-equal? x true-term)
|
||||
(term-member? x lst)))
|
||||
|
||||
(define false-term '*) ; becomes (translate-term '(f))
|
||||
(define true-term '*) ; becomes (translate-term '(t))
|
||||
|
||||
; The next two procedures were in the original benchmark
|
||||
; but were never used.
|
||||
|
||||
(define (trans-of-implies n)
|
||||
(translate-term
|
||||
(list (quote implies)
|
||||
(trans-of-implies1 n)
|
||||
(list (quote implies)
|
||||
0 n))))
|
||||
|
||||
(define (trans-of-implies1 n)
|
||||
(cond ((equal? n 1)
|
||||
(list (quote implies)
|
||||
0 1))
|
||||
(else (list (quote and)
|
||||
(list (quote implies)
|
||||
(- n 1)
|
||||
n)
|
||||
(trans-of-implies1 (- n 1))))))
|
||||
|
||||
; Translated terms can be circular structures, which can't be
|
||||
; compared using Scheme's equal? and member procedures, so we
|
||||
; use these instead.
|
||||
|
||||
(define (term-equal? x y)
|
||||
(cond ((pair? x)
|
||||
(and (pair? y)
|
||||
(symbol-record-equal? (car x) (car y))
|
||||
(term-args-equal? (cdr x) (cdr y))))
|
||||
(else (equal? x y))))
|
||||
|
||||
(define (term-args-equal? lst1 lst2)
|
||||
(cond ((null? lst1)
|
||||
(null? lst2))
|
||||
((null? lst2)
|
||||
#f)
|
||||
((term-equal? (car lst1) (car lst2))
|
||||
(term-args-equal? (cdr lst1) (cdr lst2)))
|
||||
(else #f)))
|
||||
|
||||
(define (term-member? x lst)
|
||||
(cond ((null? lst)
|
||||
#f)
|
||||
((term-equal? x (car lst))
|
||||
#t)
|
||||
(else (term-member? x (cdr lst)))))
|
||||
|
||||
(set! setup-boyer
|
||||
(lambda ()
|
||||
(set! *symbol-records-alist* '())
|
||||
(set! if-constructor (symbol->symbol-record 'if))
|
||||
(set! false-term (translate-term '(f)))
|
||||
(set! true-term (translate-term '(t)))
|
||||
(setup)))
|
||||
|
||||
(set! test-boyer
|
||||
(lambda (n)
|
||||
(set! rewrite-count 0)
|
||||
(let ((answer (test n)))
|
||||
(write rewrite-count)
|
||||
(display " rewrites")
|
||||
(newline)
|
||||
(if answer
|
||||
rewrite-count
|
||||
#f)))))
|
3772
gc-benchmarks/larceny/nucleic2.sch
Normal file
3772
gc-benchmarks/larceny/nucleic2.sch
Normal file
File diff suppressed because it is too large
Load diff
324
gc-benchmarks/larceny/perm.sch
Normal file
324
gc-benchmarks/larceny/perm.sch
Normal file
|
@ -0,0 +1,324 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; File: perm9.sch
|
||||
; Description: memory system benchmark using Zaks's permutation generator
|
||||
; Author: Lars Hansen, Will Clinger, and Gene Luks
|
||||
; Created: 18-Mar-94
|
||||
; Language: Scheme
|
||||
; Status: Public Domain
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; 940720 / lth Added some more benchmarks for the thesis paper.
|
||||
; 970215 / wdc Increased problem size from 8 to 9; improved tenperm9-benchmark.
|
||||
; 970531 / wdc Cleaned up for public release.
|
||||
; 000820 / wdc Added the MpermNKL benchmark; revised for new run-benchmark.
|
||||
|
||||
; This benchmark is in four parts. Each tests a different aspect of
|
||||
; the memory system.
|
||||
;
|
||||
; perm storage allocation
|
||||
; 10perm storage allocation and garbage collection
|
||||
; sumperms traversal of a large, linked, self-sharing structure
|
||||
; mergesort! side effects and write barrier
|
||||
;
|
||||
; The perm9 benchmark generates a list of all 362880 permutations of
|
||||
; the first 9 integers, allocating 1349288 pairs (typically 10,794,304
|
||||
; bytes), all of which goes into the generated list. (That is, the
|
||||
; perm9 benchmark generates absolutely no garbage.) This represents
|
||||
; a savings of about 63% over the storage that would be required by
|
||||
; an unshared list of permutations. The generated permutations are
|
||||
; in order of a grey code that bears no obvious relationship to a
|
||||
; lexicographic order.
|
||||
;
|
||||
; The 10perm9 benchmark repeats the perm9 benchmark 10 times, so it
|
||||
; allocates and reclaims 13492880 pairs (typically 107,943,040 bytes).
|
||||
; The live storage peaks at twice the storage that is allocated by the
|
||||
; perm9 benchmark. At the end of each iteration, the oldest half of
|
||||
; the live storage becomes garbage. Object lifetimes are distributed
|
||||
; uniformly between 10.3 and 20.6 megabytes.
|
||||
;
|
||||
; The 10perm9 benchmark is the 10perm9:2:1 special case of the
|
||||
; MpermNKL benchmark, which allocates a queue of size K and then
|
||||
; performs M iterations of the following operation: Fill the queue
|
||||
; with individually computed copies of all permutations of a list of
|
||||
; size N, and then remove the oldest L copies from the queue. At the
|
||||
; end of each iteration, the oldest L/K of the live storage becomes
|
||||
; garbage, and object lifetimes are distributed uniformly between two
|
||||
; volumes that depend upon N, K, and L.
|
||||
;
|
||||
; The sumperms benchmark computes the sum of the permuted integers
|
||||
; over all permutations.
|
||||
;
|
||||
; The mergesort! benchmark destructively sorts the generated permutations
|
||||
; into lexicographic order, allocating no storage whatsoever.
|
||||
;
|
||||
; The benchmarks are run by calling the following procedures:
|
||||
;
|
||||
; (perm-benchmark n)
|
||||
; (tenperm-benchmark n)
|
||||
; (sumperms-benchmark n)
|
||||
; (mergesort-benchmark n)
|
||||
;
|
||||
; The argument n may be omitted, in which case it defaults to 9.
|
||||
;
|
||||
; These benchmarks assume that
|
||||
;
|
||||
; (RUN-BENCHMARK <string> <thunk> <count>)
|
||||
; (RUN-BENCHMARK <string> <count> <thunk> <predicate>)
|
||||
;
|
||||
; reports the time required to call <thunk> the number of times
|
||||
; specified by <count>, and uses <predicate> to test whether the
|
||||
; result returned by <thunk> is correct.
|
||||
|
||||
; Date: Thu, 17 Mar 94 19:43:32 -0800
|
||||
; From: luks@sisters.cs.uoregon.edu
|
||||
; To: will
|
||||
; Subject: Pancake flips
|
||||
;
|
||||
; Procedure P_n generates a grey code of all perms of n elements
|
||||
; on top of stack ending with reversal of starting sequence
|
||||
;
|
||||
; F_n is flip of top n elements.
|
||||
;
|
||||
;
|
||||
; procedure P_n
|
||||
;
|
||||
; if n>1 then
|
||||
; begin
|
||||
; repeat P_{n-1},F_n n-1 times;
|
||||
; P_{n-1}
|
||||
; end
|
||||
;
|
||||
|
||||
(define (permutations x)
|
||||
(let ((x x)
|
||||
(perms (list x)))
|
||||
(define (P n)
|
||||
(if (> n 1)
|
||||
(do ((j (- n 1) (- j 1)))
|
||||
((zero? j)
|
||||
(P (- n 1)))
|
||||
(P (- n 1))
|
||||
(F n))))
|
||||
(define (F n)
|
||||
(set! x (revloop x n (list-tail x n)))
|
||||
(set! perms (cons x perms)))
|
||||
(define (revloop x n y)
|
||||
(if (zero? n)
|
||||
y
|
||||
(revloop (cdr x)
|
||||
(- n 1)
|
||||
(cons (car x) y))))
|
||||
(define (list-tail x n)
|
||||
(if (zero? n)
|
||||
x
|
||||
(list-tail (cdr x) (- n 1))))
|
||||
(P (length x))
|
||||
perms))
|
||||
|
||||
; Given a list of lists of numbers, returns the sum of the sums
|
||||
; of those lists.
|
||||
;
|
||||
; for (; x != NULL; x = x->rest)
|
||||
; for (y = x->first; y != NULL; y = y->rest)
|
||||
; sum = sum + y->first;
|
||||
|
||||
(define (sumlists x)
|
||||
(do ((x x (cdr x))
|
||||
(sum 0 (do ((y (car x) (cdr y))
|
||||
(sum sum (+ sum (car y))))
|
||||
((null? y) sum))))
|
||||
((null? x) sum)))
|
||||
|
||||
; Destructive merge of two sorted lists.
|
||||
; From Hansen's MS thesis.
|
||||
|
||||
(define (merge!! a b less?)
|
||||
|
||||
(define (loop r a b)
|
||||
(if (less? (car b) (car a))
|
||||
(begin (set-cdr! r b)
|
||||
(if (null? (cdr b))
|
||||
(set-cdr! b a)
|
||||
(loop b a (cdr b)) ))
|
||||
;; (car a) <= (car b)
|
||||
(begin (set-cdr! r a)
|
||||
(if (null? (cdr a))
|
||||
(set-cdr! a b)
|
||||
(loop a (cdr a) b)) )) )
|
||||
|
||||
(cond ((null? a) b)
|
||||
((null? b) a)
|
||||
((less? (car b) (car a))
|
||||
(if (null? (cdr b))
|
||||
(set-cdr! b a)
|
||||
(loop b a (cdr b)))
|
||||
b)
|
||||
(else ; (car a) <= (car b)
|
||||
(if (null? (cdr a))
|
||||
(set-cdr! a b)
|
||||
(loop a (cdr a) b))
|
||||
a)))
|
||||
|
||||
|
||||
;; Stable sort procedure which copies the input list and then sorts
|
||||
;; the new list imperatively. On the systems we have benchmarked,
|
||||
;; this generic list sort has been at least as fast and usually much
|
||||
;; faster than the library's sort routine.
|
||||
;; Due to Richard O'Keefe; algorithm attributed to D.H.D. Warren.
|
||||
|
||||
(define (sort!! seq less?)
|
||||
|
||||
(define (step n)
|
||||
(cond ((> n 2)
|
||||
(let* ((j (quotient n 2))
|
||||
(a (step j))
|
||||
(k (- n j))
|
||||
(b (step k)))
|
||||
(merge!! a b less?)))
|
||||
((= n 2)
|
||||
(let ((x (car seq))
|
||||
(y (cadr seq))
|
||||
(p seq))
|
||||
(set! seq (cddr seq))
|
||||
(if (less? y x)
|
||||
(begin
|
||||
(set-car! p y)
|
||||
(set-car! (cdr p) x)))
|
||||
(set-cdr! (cdr p) '())
|
||||
p))
|
||||
((= n 1)
|
||||
(let ((p seq))
|
||||
(set! seq (cdr seq))
|
||||
(set-cdr! p '())
|
||||
p))
|
||||
(else
|
||||
'())))
|
||||
|
||||
(step (length seq)))
|
||||
|
||||
(define lexicographically-less?
|
||||
(lambda (x y)
|
||||
(define (lexicographically-less? x y)
|
||||
(cond ((null? x) (not (null? y)))
|
||||
((null? y) #f)
|
||||
((< (car x) (car y)) #t)
|
||||
((= (car x) (car y))
|
||||
(lexicographically-less? (cdr x) (cdr y)))
|
||||
(else #f)))
|
||||
(lexicographically-less? x y)))
|
||||
|
||||
; This procedure isn't used by the benchmarks,
|
||||
; but is provided as a public service.
|
||||
|
||||
(define (internally-imperative-mergesort list less?)
|
||||
|
||||
(define (list-copy l)
|
||||
(define (loop l prev)
|
||||
(if (null? l)
|
||||
#t
|
||||
(let ((q (cons (car l) '())))
|
||||
(set-cdr! prev q)
|
||||
(loop (cdr l) q))))
|
||||
(if (null? l)
|
||||
l
|
||||
(let ((first (cons (car l) '())))
|
||||
(loop (cdr l) first)
|
||||
first)))
|
||||
|
||||
(sort!! (list-copy list) less?))
|
||||
|
||||
(define *perms* '())
|
||||
|
||||
(define (one..n n)
|
||||
(do ((n n (- n 1))
|
||||
(p '() (cons n p)))
|
||||
((zero? n) p)))
|
||||
|
||||
(define (perm-benchmark . rest)
|
||||
(let ((n (if (null? rest) 9 (car rest))))
|
||||
(set! *perms* '())
|
||||
(run-benchmark (string-append "Perm" (number->string n))
|
||||
1
|
||||
(lambda ()
|
||||
(set! *perms* (permutations (one..n n)))
|
||||
#t)
|
||||
(lambda (x) #t))))
|
||||
|
||||
(define (tenperm-benchmark . rest)
|
||||
(let ((n (if (null? rest) 9 (car rest))))
|
||||
(set! *perms* '())
|
||||
(MpermNKL-benchmark 10 n 2 1)))
|
||||
|
||||
(define (MpermNKL-benchmark m n k ell)
|
||||
(if (and (<= 0 m)
|
||||
(positive? n)
|
||||
(positive? k)
|
||||
(<= 0 ell k))
|
||||
(let ((id (string-append (number->string m)
|
||||
"perm"
|
||||
(number->string n)
|
||||
":"
|
||||
(number->string k)
|
||||
":"
|
||||
(number->string ell)))
|
||||
(queue (make-vector k '())))
|
||||
|
||||
; Fills queue positions [i, j).
|
||||
|
||||
(define (fill-queue i j)
|
||||
(if (< i j)
|
||||
(begin (vector-set! queue i (permutations (one..n n)))
|
||||
(fill-queue (+ i 1) j))))
|
||||
|
||||
; Removes ell elements from queue.
|
||||
|
||||
(define (flush-queue)
|
||||
(let loop ((i 0))
|
||||
(if (< i k)
|
||||
(begin (vector-set! queue
|
||||
i
|
||||
(let ((j (+ i ell)))
|
||||
(if (< j k)
|
||||
(vector-ref queue j)
|
||||
'())))
|
||||
(loop (+ i 1))))))
|
||||
|
||||
(fill-queue 0 (- k ell))
|
||||
(run-benchmark id
|
||||
m
|
||||
(lambda ()
|
||||
(fill-queue (- k ell) k)
|
||||
(flush-queue)
|
||||
queue)
|
||||
(lambda (q)
|
||||
(let ((q0 (vector-ref q 0))
|
||||
(qi (vector-ref q (max 0 (- k ell 1)))))
|
||||
(or (and (null? q0) (null? qi))
|
||||
(and (pair? q0)
|
||||
(pair? qi)
|
||||
(equal? (car q0) (car qi))))))))
|
||||
(begin (display "Incorrect arguments to MpermNKL-benchmark")
|
||||
(newline))))
|
||||
|
||||
(define (sumperms-benchmark . rest)
|
||||
(let ((n (if (null? rest) 9 (car rest))))
|
||||
(if (or (null? *perms*)
|
||||
(not (= n (length (car *perms*)))))
|
||||
(set! *perms* (permutations (one..n n))))
|
||||
(run-benchmark (string-append "Sumperms" (number->string n))
|
||||
1
|
||||
(lambda ()
|
||||
(sumlists *perms*))
|
||||
(lambda (x) #t))))
|
||||
|
||||
(define (mergesort-benchmark . rest)
|
||||
(let ((n (if (null? rest) 9 (car rest))))
|
||||
(if (or (null? *perms*)
|
||||
(not (= n (length (car *perms*)))))
|
||||
(set! *perms* (permutations (one..n n))))
|
||||
(run-benchmark (string-append "Mergesort!" (number->string n))
|
||||
1
|
||||
(lambda ()
|
||||
(sort!! *perms* lexicographically-less?)
|
||||
#t)
|
||||
(lambda (x) #t))))
|
50
gc-benchmarks/larceny/run-benchmark.chez
Normal file
50
gc-benchmarks/larceny/run-benchmark.chez
Normal file
|
@ -0,0 +1,50 @@
|
|||
;;; Gambit-style run-benchmark.
|
||||
;;;
|
||||
;;; Invoke this procedure to run a benchmark.
|
||||
;;; The first argument is a string identifying the benchmark.
|
||||
;;; The second argument is the number of times to run the benchmark.
|
||||
;;; The third argument is a thunk that runs the benchmark.
|
||||
;;; The fourth argument is a unary predicate that warns if the result
|
||||
;;; returned by the benchmark is incorrect.
|
||||
;;;
|
||||
;;; Example:
|
||||
;;; (run-benchmark "make-vector"
|
||||
;;; 1
|
||||
;;; (lambda () (make-vector 1000000))
|
||||
;;; (lambda (v) (and (vector? v) (= (vector-length v) #e1e6))))
|
||||
|
||||
;;; For backward compatibility, this procedure also works with the
|
||||
;;; arguments that we once used to run benchmarks in Larceny.
|
||||
|
||||
(define (run-benchmark name arg2 . rest)
|
||||
(let* ((old-style (procedure? arg2))
|
||||
(thunk (if old-style arg2 (car rest)))
|
||||
(n (if old-style
|
||||
(if (null? rest) 1 (car rest))
|
||||
arg2))
|
||||
(ok? (if (or old-style (null? (cdr rest)))
|
||||
(lambda (result) #t)
|
||||
(cadr rest)))
|
||||
(result '*))
|
||||
(define (loop n)
|
||||
(cond ((zero? n) #t)
|
||||
((= n 1)
|
||||
(set! result (thunk)))
|
||||
(else
|
||||
(thunk)
|
||||
(loop (- n 1)))))
|
||||
(if old-style
|
||||
(begin (newline)
|
||||
(display "Warning: Using old-style run-benchmark")
|
||||
(newline)))
|
||||
(newline)
|
||||
(display "--------------------------------------------------------")
|
||||
(newline)
|
||||
(display name)
|
||||
(newline)
|
||||
; time is a macro supplied by Chez Scheme
|
||||
(time (loop n))
|
||||
(if (not (ok? result))
|
||||
(begin (display "Error: Benchmark program returned wrong result: ")
|
||||
(write result)
|
||||
(newline)))))
|
784
gc-benchmarks/larceny/sboyer.sch
Normal file
784
gc-benchmarks/larceny/sboyer.sch
Normal file
|
@ -0,0 +1,784 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; File: sboyer.sch
|
||||
; Description: The Boyer benchmark
|
||||
; Author: Bob Boyer
|
||||
; Created: 5-Apr-85
|
||||
; Modified: 10-Apr-85 14:52:20 (Bob Shaw)
|
||||
; 22-Jul-87 (Will Clinger)
|
||||
; 2-Jul-88 (Will Clinger -- distinguished #f and the empty list)
|
||||
; 13-Feb-97 (Will Clinger -- fixed bugs in unifier and rules,
|
||||
; rewrote to eliminate property lists, and added
|
||||
; a scaling parameter suggested by Bob Boyer)
|
||||
; 19-Mar-99 (Will Clinger -- cleaned up comments)
|
||||
; 4-Apr-01 (Will Clinger -- changed four 1- symbols to sub1)
|
||||
; Language: Scheme
|
||||
; Status: Public Domain
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;; SBOYER -- Logic programming benchmark, originally written by Bob Boyer.
|
||||
;;; Much less CONS-intensive than NBOYER because it uses Henry Baker's
|
||||
;;; "sharing cons".
|
||||
|
||||
; Note: The version of this benchmark that appears in Dick Gabriel's book
|
||||
; contained several bugs that are corrected here. These bugs are discussed
|
||||
; by Henry Baker, "The Boyer Benchmark Meets Linear Logic", ACM SIGPLAN Lisp
|
||||
; Pointers 6(4), October-December 1993, pages 3-10. The fixed bugs are:
|
||||
;
|
||||
; The benchmark now returns a boolean result.
|
||||
; FALSEP and TRUEP use TERM-MEMBER? rather than MEMV (which is called MEMBER
|
||||
; in Common Lisp)
|
||||
; ONE-WAY-UNIFY1 now treats numbers correctly
|
||||
; ONE-WAY-UNIFY1-LST now treats empty lists correctly
|
||||
; Rule 19 has been corrected (this rule was not touched by the original
|
||||
; benchmark, but is used by this version)
|
||||
; Rules 84 and 101 have been corrected (but these rules are never touched
|
||||
; by the benchmark)
|
||||
;
|
||||
; According to Baker, these bug fixes make the benchmark 10-25% slower.
|
||||
; Please do not compare the timings from this benchmark against those of
|
||||
; the original benchmark.
|
||||
;
|
||||
; This version of the benchmark also prints the number of rewrites as a sanity
|
||||
; check, because it is too easy for a buggy version to return the correct
|
||||
; boolean result. The correct number of rewrites is
|
||||
;
|
||||
; n rewrites peak live storage (approximate, in bytes)
|
||||
; 0 95024
|
||||
; 1 591777
|
||||
; 2 1813975
|
||||
; 3 5375678
|
||||
; 4 16445406
|
||||
; 5 51507739
|
||||
|
||||
; Sboyer is a 2-phase benchmark.
|
||||
; The first phase attaches lemmas to symbols. This phase is not timed,
|
||||
; but it accounts for very little of the runtime anyway.
|
||||
; The second phase creates the test problem, and tests to see
|
||||
; whether it is implied by the lemmas.
|
||||
|
||||
(define (sboyer-benchmark . args)
|
||||
(let ((n (if (null? args) 0 (car args))))
|
||||
(setup-boyer)
|
||||
(run-benchmark (string-append "sboyer"
|
||||
(number->string n))
|
||||
1
|
||||
(lambda () (test-boyer n))
|
||||
(lambda (rewrites)
|
||||
(and (number? rewrites)
|
||||
(case n
|
||||
((0) (= rewrites 95024))
|
||||
((1) (= rewrites 591777))
|
||||
((2) (= rewrites 1813975))
|
||||
((3) (= rewrites 5375678))
|
||||
((4) (= rewrites 16445406))
|
||||
((5) (= rewrites 51507739))
|
||||
; If it works for n <= 5, assume it works.
|
||||
(else #t)))))))
|
||||
|
||||
(define (setup-boyer) #t) ; assigned below
|
||||
(define (test-boyer) #t) ; assigned below
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;
|
||||
; The first phase.
|
||||
;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; In the original benchmark, it stored a list of lemmas on the
|
||||
; property lists of symbols.
|
||||
; In the new benchmark, it maintains an association list of
|
||||
; symbols and symbol-records, and stores the list of lemmas
|
||||
; within the symbol-records.
|
||||
|
||||
(let ()
|
||||
|
||||
(define (setup)
|
||||
(add-lemma-lst
|
||||
(quote ((equal (compile form)
|
||||
(reverse (codegen (optimize form)
|
||||
(nil))))
|
||||
(equal (eqp x y)
|
||||
(equal (fix x)
|
||||
(fix y)))
|
||||
(equal (greaterp x y)
|
||||
(lessp y x))
|
||||
(equal (lesseqp x y)
|
||||
(not (lessp y x)))
|
||||
(equal (greatereqp x y)
|
||||
(not (lessp x y)))
|
||||
(equal (boolean x)
|
||||
(or (equal x (t))
|
||||
(equal x (f))))
|
||||
(equal (iff x y)
|
||||
(and (implies x y)
|
||||
(implies y x)))
|
||||
(equal (even1 x)
|
||||
(if (zerop x)
|
||||
(t)
|
||||
(odd (sub1 x))))
|
||||
(equal (countps- l pred)
|
||||
(countps-loop l pred (zero)))
|
||||
(equal (fact- i)
|
||||
(fact-loop i 1))
|
||||
(equal (reverse- x)
|
||||
(reverse-loop x (nil)))
|
||||
(equal (divides x y)
|
||||
(zerop (remainder y x)))
|
||||
(equal (assume-true var alist)
|
||||
(cons (cons var (t))
|
||||
alist))
|
||||
(equal (assume-false var alist)
|
||||
(cons (cons var (f))
|
||||
alist))
|
||||
(equal (tautology-checker x)
|
||||
(tautologyp (normalize x)
|
||||
(nil)))
|
||||
(equal (falsify x)
|
||||
(falsify1 (normalize x)
|
||||
(nil)))
|
||||
(equal (prime x)
|
||||
(and (not (zerop x))
|
||||
(not (equal x (add1 (zero))))
|
||||
(prime1 x (sub1 x))))
|
||||
(equal (and p q)
|
||||
(if p (if q (t)
|
||||
(f))
|
||||
(f)))
|
||||
(equal (or p q)
|
||||
(if p (t)
|
||||
(if q (t)
|
||||
(f))))
|
||||
(equal (not p)
|
||||
(if p (f)
|
||||
(t)))
|
||||
(equal (implies p q)
|
||||
(if p (if q (t)
|
||||
(f))
|
||||
(t)))
|
||||
(equal (fix x)
|
||||
(if (numberp x)
|
||||
x
|
||||
(zero)))
|
||||
(equal (if (if a b c)
|
||||
d e)
|
||||
(if a (if b d e)
|
||||
(if c d e)))
|
||||
(equal (zerop x)
|
||||
(or (equal x (zero))
|
||||
(not (numberp x))))
|
||||
(equal (plus (plus x y)
|
||||
z)
|
||||
(plus x (plus y z)))
|
||||
(equal (equal (plus a b)
|
||||
(zero))
|
||||
(and (zerop a)
|
||||
(zerop b)))
|
||||
(equal (difference x x)
|
||||
(zero))
|
||||
(equal (equal (plus a b)
|
||||
(plus a c))
|
||||
(equal (fix b)
|
||||
(fix c)))
|
||||
(equal (equal (zero)
|
||||
(difference x y))
|
||||
(not (lessp y x)))
|
||||
(equal (equal x (difference x y))
|
||||
(and (numberp x)
|
||||
(or (equal x (zero))
|
||||
(zerop y))))
|
||||
(equal (meaning (plus-tree (append x y))
|
||||
a)
|
||||
(plus (meaning (plus-tree x)
|
||||
a)
|
||||
(meaning (plus-tree y)
|
||||
a)))
|
||||
(equal (meaning (plus-tree (plus-fringe x))
|
||||
a)
|
||||
(fix (meaning x a)))
|
||||
(equal (append (append x y)
|
||||
z)
|
||||
(append x (append y z)))
|
||||
(equal (reverse (append a b))
|
||||
(append (reverse b)
|
||||
(reverse a)))
|
||||
(equal (times x (plus y z))
|
||||
(plus (times x y)
|
||||
(times x z)))
|
||||
(equal (times (times x y)
|
||||
z)
|
||||
(times x (times y z)))
|
||||
(equal (equal (times x y)
|
||||
(zero))
|
||||
(or (zerop x)
|
||||
(zerop y)))
|
||||
(equal (exec (append x y)
|
||||
pds envrn)
|
||||
(exec y (exec x pds envrn)
|
||||
envrn))
|
||||
(equal (mc-flatten x y)
|
||||
(append (flatten x)
|
||||
y))
|
||||
(equal (member x (append a b))
|
||||
(or (member x a)
|
||||
(member x b)))
|
||||
(equal (member x (reverse y))
|
||||
(member x y))
|
||||
(equal (length (reverse x))
|
||||
(length x))
|
||||
(equal (member a (intersect b c))
|
||||
(and (member a b)
|
||||
(member a c)))
|
||||
(equal (nth (zero)
|
||||
i)
|
||||
(zero))
|
||||
(equal (exp i (plus j k))
|
||||
(times (exp i j)
|
||||
(exp i k)))
|
||||
(equal (exp i (times j k))
|
||||
(exp (exp i j)
|
||||
k))
|
||||
(equal (reverse-loop x y)
|
||||
(append (reverse x)
|
||||
y))
|
||||
(equal (reverse-loop x (nil))
|
||||
(reverse x))
|
||||
(equal (count-list z (sort-lp x y))
|
||||
(plus (count-list z x)
|
||||
(count-list z y)))
|
||||
(equal (equal (append a b)
|
||||
(append a c))
|
||||
(equal b c))
|
||||
(equal (plus (remainder x y)
|
||||
(times y (quotient x y)))
|
||||
(fix x))
|
||||
(equal (power-eval (big-plus1 l i base)
|
||||
base)
|
||||
(plus (power-eval l base)
|
||||
i))
|
||||
(equal (power-eval (big-plus x y i base)
|
||||
base)
|
||||
(plus i (plus (power-eval x base)
|
||||
(power-eval y base))))
|
||||
(equal (remainder y 1)
|
||||
(zero))
|
||||
(equal (lessp (remainder x y)
|
||||
y)
|
||||
(not (zerop y)))
|
||||
(equal (remainder x x)
|
||||
(zero))
|
||||
(equal (lessp (quotient i j)
|
||||
i)
|
||||
(and (not (zerop i))
|
||||
(or (zerop j)
|
||||
(not (equal j 1)))))
|
||||
(equal (lessp (remainder x y)
|
||||
x)
|
||||
(and (not (zerop y))
|
||||
(not (zerop x))
|
||||
(not (lessp x y))))
|
||||
(equal (power-eval (power-rep i base)
|
||||
base)
|
||||
(fix i))
|
||||
(equal (power-eval (big-plus (power-rep i base)
|
||||
(power-rep j base)
|
||||
(zero)
|
||||
base)
|
||||
base)
|
||||
(plus i j))
|
||||
(equal (gcd x y)
|
||||
(gcd y x))
|
||||
(equal (nth (append a b)
|
||||
i)
|
||||
(append (nth a i)
|
||||
(nth b (difference i (length a)))))
|
||||
(equal (difference (plus x y)
|
||||
x)
|
||||
(fix y))
|
||||
(equal (difference (plus y x)
|
||||
x)
|
||||
(fix y))
|
||||
(equal (difference (plus x y)
|
||||
(plus x z))
|
||||
(difference y z))
|
||||
(equal (times x (difference c w))
|
||||
(difference (times c x)
|
||||
(times w x)))
|
||||
(equal (remainder (times x z)
|
||||
z)
|
||||
(zero))
|
||||
(equal (difference (plus b (plus a c))
|
||||
a)
|
||||
(plus b c))
|
||||
(equal (difference (add1 (plus y z))
|
||||
z)
|
||||
(add1 y))
|
||||
(equal (lessp (plus x y)
|
||||
(plus x z))
|
||||
(lessp y z))
|
||||
(equal (lessp (times x z)
|
||||
(times y z))
|
||||
(and (not (zerop z))
|
||||
(lessp x y)))
|
||||
(equal (lessp y (plus x y))
|
||||
(not (zerop x)))
|
||||
(equal (gcd (times x z)
|
||||
(times y z))
|
||||
(times z (gcd x y)))
|
||||
(equal (value (normalize x)
|
||||
a)
|
||||
(value x a))
|
||||
(equal (equal (flatten x)
|
||||
(cons y (nil)))
|
||||
(and (nlistp x)
|
||||
(equal x y)))
|
||||
(equal (listp (gopher x))
|
||||
(listp x))
|
||||
(equal (samefringe x y)
|
||||
(equal (flatten x)
|
||||
(flatten y)))
|
||||
(equal (equal (greatest-factor x y)
|
||||
(zero))
|
||||
(and (or (zerop y)
|
||||
(equal y 1))
|
||||
(equal x (zero))))
|
||||
(equal (equal (greatest-factor x y)
|
||||
1)
|
||||
(equal x 1))
|
||||
(equal (numberp (greatest-factor x y))
|
||||
(not (and (or (zerop y)
|
||||
(equal y 1))
|
||||
(not (numberp x)))))
|
||||
(equal (times-list (append x y))
|
||||
(times (times-list x)
|
||||
(times-list y)))
|
||||
(equal (prime-list (append x y))
|
||||
(and (prime-list x)
|
||||
(prime-list y)))
|
||||
(equal (equal z (times w z))
|
||||
(and (numberp z)
|
||||
(or (equal z (zero))
|
||||
(equal w 1))))
|
||||
(equal (greatereqp x y)
|
||||
(not (lessp x y)))
|
||||
(equal (equal x (times x y))
|
||||
(or (equal x (zero))
|
||||
(and (numberp x)
|
||||
(equal y 1))))
|
||||
(equal (remainder (times y x)
|
||||
y)
|
||||
(zero))
|
||||
(equal (equal (times a b)
|
||||
1)
|
||||
(and (not (equal a (zero)))
|
||||
(not (equal b (zero)))
|
||||
(numberp a)
|
||||
(numberp b)
|
||||
(equal (sub1 a)
|
||||
(zero))
|
||||
(equal (sub1 b)
|
||||
(zero))))
|
||||
(equal (lessp (length (delete x l))
|
||||
(length l))
|
||||
(member x l))
|
||||
(equal (sort2 (delete x l))
|
||||
(delete x (sort2 l)))
|
||||
(equal (dsort x)
|
||||
(sort2 x))
|
||||
(equal (length (cons x1
|
||||
(cons x2
|
||||
(cons x3 (cons x4
|
||||
(cons x5
|
||||
(cons x6 x7)))))))
|
||||
(plus 6 (length x7)))
|
||||
(equal (difference (add1 (add1 x))
|
||||
2)
|
||||
(fix x))
|
||||
(equal (quotient (plus x (plus x y))
|
||||
2)
|
||||
(plus x (quotient y 2)))
|
||||
(equal (sigma (zero)
|
||||
i)
|
||||
(quotient (times i (add1 i))
|
||||
2))
|
||||
(equal (plus x (add1 y))
|
||||
(if (numberp y)
|
||||
(add1 (plus x y))
|
||||
(add1 x)))
|
||||
(equal (equal (difference x y)
|
||||
(difference z y))
|
||||
(if (lessp x y)
|
||||
(not (lessp y z))
|
||||
(if (lessp z y)
|
||||
(not (lessp y x))
|
||||
(equal (fix x)
|
||||
(fix z)))))
|
||||
(equal (meaning (plus-tree (delete x y))
|
||||
a)
|
||||
(if (member x y)
|
||||
(difference (meaning (plus-tree y)
|
||||
a)
|
||||
(meaning x a))
|
||||
(meaning (plus-tree y)
|
||||
a)))
|
||||
(equal (times x (add1 y))
|
||||
(if (numberp y)
|
||||
(plus x (times x y))
|
||||
(fix x)))
|
||||
(equal (nth (nil)
|
||||
i)
|
||||
(if (zerop i)
|
||||
(nil)
|
||||
(zero)))
|
||||
(equal (last (append a b))
|
||||
(if (listp b)
|
||||
(last b)
|
||||
(if (listp a)
|
||||
(cons (car (last a))
|
||||
b)
|
||||
b)))
|
||||
(equal (equal (lessp x y)
|
||||
z)
|
||||
(if (lessp x y)
|
||||
(equal (t) z)
|
||||
(equal (f) z)))
|
||||
(equal (assignment x (append a b))
|
||||
(if (assignedp x a)
|
||||
(assignment x a)
|
||||
(assignment x b)))
|
||||
(equal (car (gopher x))
|
||||
(if (listp x)
|
||||
(car (flatten x))
|
||||
(zero)))
|
||||
(equal (flatten (cdr (gopher x)))
|
||||
(if (listp x)
|
||||
(cdr (flatten x))
|
||||
(cons (zero)
|
||||
(nil))))
|
||||
(equal (quotient (times y x)
|
||||
y)
|
||||
(if (zerop y)
|
||||
(zero)
|
||||
(fix x)))
|
||||
(equal (get j (set i val mem))
|
||||
(if (eqp j i)
|
||||
val
|
||||
(get j mem)))))))
|
||||
|
||||
(define (add-lemma-lst lst)
|
||||
(cond ((null? lst)
|
||||
#t)
|
||||
(else (add-lemma (car lst))
|
||||
(add-lemma-lst (cdr lst)))))
|
||||
|
||||
(define (add-lemma term)
|
||||
(cond ((and (pair? term)
|
||||
(eq? (car term)
|
||||
(quote equal))
|
||||
(pair? (cadr term)))
|
||||
(put (car (cadr term))
|
||||
(quote lemmas)
|
||||
(cons
|
||||
(translate-term term)
|
||||
(get (car (cadr term)) (quote lemmas)))))
|
||||
(else (error "ADD-LEMMA did not like term: " term))))
|
||||
|
||||
; Translates a term by replacing its constructor symbols by symbol-records.
|
||||
|
||||
(define (translate-term term)
|
||||
(cond ((not (pair? term))
|
||||
term)
|
||||
(else (cons (symbol->symbol-record (car term))
|
||||
(translate-args (cdr term))))))
|
||||
|
||||
(define (translate-args lst)
|
||||
(cond ((null? lst)
|
||||
'())
|
||||
(else (cons (translate-term (car lst))
|
||||
(translate-args (cdr lst))))))
|
||||
|
||||
; For debugging only, so the use of MAP does not change
|
||||
; the first-order character of the benchmark.
|
||||
|
||||
(define (untranslate-term term)
|
||||
(cond ((not (pair? term))
|
||||
term)
|
||||
(else (cons (get-name (car term))
|
||||
(map untranslate-term (cdr term))))))
|
||||
|
||||
; A symbol-record is represented as a vector with two fields:
|
||||
; the symbol (for debugging) and
|
||||
; the list of lemmas associated with the symbol.
|
||||
|
||||
(define (put sym property value)
|
||||
(put-lemmas! (symbol->symbol-record sym) value))
|
||||
|
||||
(define (get sym property)
|
||||
(get-lemmas (symbol->symbol-record sym)))
|
||||
|
||||
(define (symbol->symbol-record sym)
|
||||
(let ((x (assq sym *symbol-records-alist*)))
|
||||
(if x
|
||||
(cdr x)
|
||||
(let ((r (make-symbol-record sym)))
|
||||
(set! *symbol-records-alist*
|
||||
(cons (cons sym r)
|
||||
*symbol-records-alist*))
|
||||
r))))
|
||||
|
||||
; Association list of symbols and symbol-records.
|
||||
|
||||
(define *symbol-records-alist* '())
|
||||
|
||||
; A symbol-record is represented as a vector with two fields:
|
||||
; the symbol (for debugging) and
|
||||
; the list of lemmas associated with the symbol.
|
||||
|
||||
(define (make-symbol-record sym)
|
||||
(vector sym '()))
|
||||
|
||||
(define (put-lemmas! symbol-record lemmas)
|
||||
(vector-set! symbol-record 1 lemmas))
|
||||
|
||||
(define (get-lemmas symbol-record)
|
||||
(vector-ref symbol-record 1))
|
||||
|
||||
(define (get-name symbol-record)
|
||||
(vector-ref symbol-record 0))
|
||||
|
||||
(define (symbol-record-equal? r1 r2)
|
||||
(eq? r1 r2))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;
|
||||
; The second phase.
|
||||
;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (test n)
|
||||
(let ((term
|
||||
(apply-subst
|
||||
(translate-alist
|
||||
(quote ((x f (plus (plus a b)
|
||||
(plus c (zero))))
|
||||
(y f (times (times a b)
|
||||
(plus c d)))
|
||||
(z f (reverse (append (append a b)
|
||||
(nil))))
|
||||
(u equal (plus a b)
|
||||
(difference x y))
|
||||
(w lessp (remainder a b)
|
||||
(member a (length b))))))
|
||||
(translate-term
|
||||
(do ((term
|
||||
(quote (implies (and (implies x y)
|
||||
(and (implies y z)
|
||||
(and (implies z u)
|
||||
(implies u w))))
|
||||
(implies x w)))
|
||||
(list 'or term '(f)))
|
||||
(n n (- n 1)))
|
||||
((zero? n) term))))))
|
||||
(tautp term)))
|
||||
|
||||
(define (translate-alist alist)
|
||||
(cond ((null? alist)
|
||||
'())
|
||||
(else (cons (cons (caar alist)
|
||||
(translate-term (cdar alist)))
|
||||
(translate-alist (cdr alist))))))
|
||||
|
||||
(define (apply-subst alist term)
|
||||
(cond ((not (pair? term))
|
||||
(let ((temp-temp (assq term alist)))
|
||||
(if temp-temp
|
||||
(cdr temp-temp)
|
||||
term)))
|
||||
(else (cons (car term)
|
||||
(apply-subst-lst alist (cdr term))))))
|
||||
|
||||
(define (apply-subst-lst alist lst)
|
||||
(cond ((null? lst)
|
||||
'())
|
||||
(else (cons (apply-subst alist (car lst))
|
||||
(apply-subst-lst alist (cdr lst))))))
|
||||
|
||||
(define (tautp x)
|
||||
(tautologyp (rewrite x)
|
||||
'() '()))
|
||||
|
||||
(define (tautologyp x true-lst false-lst)
|
||||
(cond ((truep x true-lst)
|
||||
#t)
|
||||
((falsep x false-lst)
|
||||
#f)
|
||||
((not (pair? x))
|
||||
#f)
|
||||
((eq? (car x) if-constructor)
|
||||
(cond ((truep (cadr x)
|
||||
true-lst)
|
||||
(tautologyp (caddr x)
|
||||
true-lst false-lst))
|
||||
((falsep (cadr x)
|
||||
false-lst)
|
||||
(tautologyp (cadddr x)
|
||||
true-lst false-lst))
|
||||
(else (and (tautologyp (caddr x)
|
||||
(cons (cadr x)
|
||||
true-lst)
|
||||
false-lst)
|
||||
(tautologyp (cadddr x)
|
||||
true-lst
|
||||
(cons (cadr x)
|
||||
false-lst))))))
|
||||
(else #f)))
|
||||
|
||||
(define if-constructor '*) ; becomes (symbol->symbol-record 'if)
|
||||
|
||||
(define rewrite-count 0) ; sanity check
|
||||
|
||||
; The next procedure is Henry Baker's sharing CONS, which avoids
|
||||
; allocation if the result is already in hand.
|
||||
; The REWRITE and REWRITE-ARGS procedures have been modified to
|
||||
; use SCONS instead of CONS.
|
||||
|
||||
(define (scons x y original)
|
||||
(if (and (eq? x (car original))
|
||||
(eq? y (cdr original)))
|
||||
original
|
||||
(cons x y)))
|
||||
|
||||
(define (rewrite term)
|
||||
(set! rewrite-count (+ rewrite-count 1))
|
||||
(cond ((not (pair? term))
|
||||
term)
|
||||
(else (rewrite-with-lemmas (scons (car term)
|
||||
(rewrite-args (cdr term))
|
||||
term)
|
||||
(get-lemmas (car term))))))
|
||||
|
||||
(define (rewrite-args lst)
|
||||
(cond ((null? lst)
|
||||
'())
|
||||
(else (scons (rewrite (car lst))
|
||||
(rewrite-args (cdr lst))
|
||||
lst))))
|
||||
|
||||
(define (rewrite-with-lemmas term lst)
|
||||
(cond ((null? lst)
|
||||
term)
|
||||
((one-way-unify term (cadr (car lst)))
|
||||
(rewrite (apply-subst unify-subst (caddr (car lst)))))
|
||||
(else (rewrite-with-lemmas term (cdr lst)))))
|
||||
|
||||
(define unify-subst '*)
|
||||
|
||||
(define (one-way-unify term1 term2)
|
||||
(begin (set! unify-subst '())
|
||||
(one-way-unify1 term1 term2)))
|
||||
|
||||
(define (one-way-unify1 term1 term2)
|
||||
(cond ((not (pair? term2))
|
||||
(let ((temp-temp (assq term2 unify-subst)))
|
||||
(cond (temp-temp
|
||||
(term-equal? term1 (cdr temp-temp)))
|
||||
((number? term2) ; This bug fix makes
|
||||
(equal? term1 term2)) ; nboyer 10-25% slower!
|
||||
(else
|
||||
(set! unify-subst (cons (cons term2 term1)
|
||||
unify-subst))
|
||||
#t))))
|
||||
((not (pair? term1))
|
||||
#f)
|
||||
((eq? (car term1)
|
||||
(car term2))
|
||||
(one-way-unify1-lst (cdr term1)
|
||||
(cdr term2)))
|
||||
(else #f)))
|
||||
|
||||
(define (one-way-unify1-lst lst1 lst2)
|
||||
(cond ((null? lst1)
|
||||
(null? lst2))
|
||||
((null? lst2)
|
||||
#f)
|
||||
((one-way-unify1 (car lst1)
|
||||
(car lst2))
|
||||
(one-way-unify1-lst (cdr lst1)
|
||||
(cdr lst2)))
|
||||
(else #f)))
|
||||
|
||||
(define (falsep x lst)
|
||||
(or (term-equal? x false-term)
|
||||
(term-member? x lst)))
|
||||
|
||||
(define (truep x lst)
|
||||
(or (term-equal? x true-term)
|
||||
(term-member? x lst)))
|
||||
|
||||
(define false-term '*) ; becomes (translate-term '(f))
|
||||
(define true-term '*) ; becomes (translate-term '(t))
|
||||
|
||||
; The next two procedures were in the original benchmark
|
||||
; but were never used.
|
||||
|
||||
(define (trans-of-implies n)
|
||||
(translate-term
|
||||
(list (quote implies)
|
||||
(trans-of-implies1 n)
|
||||
(list (quote implies)
|
||||
0 n))))
|
||||
|
||||
(define (trans-of-implies1 n)
|
||||
(cond ((equal? n 1)
|
||||
(list (quote implies)
|
||||
0 1))
|
||||
(else (list (quote and)
|
||||
(list (quote implies)
|
||||
(- n 1)
|
||||
n)
|
||||
(trans-of-implies1 (- n 1))))))
|
||||
|
||||
; Translated terms can be circular structures, which can't be
|
||||
; compared using Scheme's equal? and member procedures, so we
|
||||
; use these instead.
|
||||
|
||||
(define (term-equal? x y)
|
||||
(cond ((pair? x)
|
||||
(and (pair? y)
|
||||
(symbol-record-equal? (car x) (car y))
|
||||
(term-args-equal? (cdr x) (cdr y))))
|
||||
(else (equal? x y))))
|
||||
|
||||
(define (term-args-equal? lst1 lst2)
|
||||
(cond ((null? lst1)
|
||||
(null? lst2))
|
||||
((null? lst2)
|
||||
#f)
|
||||
((term-equal? (car lst1) (car lst2))
|
||||
(term-args-equal? (cdr lst1) (cdr lst2)))
|
||||
(else #f)))
|
||||
|
||||
(define (term-member? x lst)
|
||||
(cond ((null? lst)
|
||||
#f)
|
||||
((term-equal? x (car lst))
|
||||
#t)
|
||||
(else (term-member? x (cdr lst)))))
|
||||
|
||||
(set! setup-boyer
|
||||
(lambda ()
|
||||
(set! *symbol-records-alist* '())
|
||||
(set! if-constructor (symbol->symbol-record 'if))
|
||||
(set! false-term (translate-term '(f)))
|
||||
(set! true-term (translate-term '(t)))
|
||||
(setup)))
|
||||
|
||||
(set! test-boyer
|
||||
(lambda (n)
|
||||
(set! rewrite-count 0)
|
||||
(let ((answer (test n)))
|
||||
(write rewrite-count)
|
||||
(display " rewrites")
|
||||
(newline)
|
||||
(if answer
|
||||
rewrite-count
|
||||
#f)))))
|
9319
gc-benchmarks/larceny/softscheme.sch
Normal file
9319
gc-benchmarks/larceny/softscheme.sch
Normal file
File diff suppressed because it is too large
Load diff
23798
gc-benchmarks/larceny/twobit-input-long.sch
Normal file
23798
gc-benchmarks/larceny/twobit-input-long.sch
Normal file
File diff suppressed because it is too large
Load diff
3623
gc-benchmarks/larceny/twobit-input-short.sch
Normal file
3623
gc-benchmarks/larceny/twobit-input-short.sch
Normal file
File diff suppressed because it is too large
Load diff
15408
gc-benchmarks/larceny/twobit-smaller.sch
Normal file
15408
gc-benchmarks/larceny/twobit-smaller.sch
Normal file
File diff suppressed because it is too large
Load diff
23798
gc-benchmarks/larceny/twobit.sch
Normal file
23798
gc-benchmarks/larceny/twobit.sch
Normal file
File diff suppressed because it is too large
Load diff
4
gc-benchmarks/loop.scm
Normal file
4
gc-benchmarks/loop.scm
Normal file
|
@ -0,0 +1,4 @@
|
|||
(let loop ((i 10000000))
|
||||
(and (> i 0)
|
||||
(loop (1- i))))
|
||||
|
269
gc-benchmarks/run-benchmark.scm
Executable file
269
gc-benchmarks/run-benchmark.scm
Executable file
|
@ -0,0 +1,269 @@
|
|||
#!/bin/sh
|
||||
# -*- Scheme -*-
|
||||
exec ${GUILE-guile} -q -l "$0" \
|
||||
-c '(apply main (cdr (command-line)))' \
|
||||
--benchmark-dir="$(dirname $0)" "$@"
|
||||
!#
|
||||
;;; Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
;;;
|
||||
;;; This program is free software; you can redistribute it and/or modify
|
||||
;;; it under the terms of the GNU General Public License as published by
|
||||
;;; the Free Software Foundation; either version 2, or (at your option)
|
||||
;;; any later version.
|
||||
;;;
|
||||
;;; This program is distributed in the hope that it will be useful,
|
||||
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;;; GNU General Public License for more details.
|
||||
;;;
|
||||
;;; You should have received a copy of the GNU General Public License
|
||||
;;; along with this software; see the file COPYING. If not, write to
|
||||
;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
;;; Boston, MA 02110-1301 USA
|
||||
|
||||
(use-modules (ice-9 rdelim)
|
||||
(ice-9 popen)
|
||||
(ice-9 regex)
|
||||
(ice-9 format)
|
||||
(srfi srfi-1)
|
||||
(srfi srfi-37))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Running Guile.
|
||||
;;;
|
||||
|
||||
(define (run-reference-guile env bench-dir profile-opts bench)
|
||||
"Run the ``mainstream'' Guile, i.e., Guile 1.9 with its own GC."
|
||||
(open-input-pipe (string-append
|
||||
env " "
|
||||
bench-dir "/gc-profile.scm " profile-opts
|
||||
" \"" bench "\"")))
|
||||
|
||||
(define (run-bdwgc-guile env bench-dir profile-opts options bench)
|
||||
"Run the Guile port to the Boehm-Demers-Weiser GC (BDW-GC)."
|
||||
(let ((fsd (assoc-ref options 'free-space-divisor)))
|
||||
(open-input-pipe (string-append env " "
|
||||
"GC_FREE_SPACE_DIVISOR="
|
||||
(number->string fsd)
|
||||
|
||||
(if (or (assoc-ref options 'incremental?)
|
||||
(assoc-ref options 'generational?))
|
||||
" GC_ENABLE_INCREMENTAL=yes"
|
||||
"")
|
||||
(if (assoc-ref options 'generational?)
|
||||
" GC_PAUSE_TIME_TARGET=999999"
|
||||
"")
|
||||
(if (assoc-ref options 'parallel?)
|
||||
"" ;; let it choose the number of procs
|
||||
" GC_MARKERS=1")
|
||||
" "
|
||||
bench-dir "/gc-profile.scm " profile-opts
|
||||
" \"" bench "\""))))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Extracting performance results.
|
||||
;;;
|
||||
|
||||
(define (grep regexp input)
|
||||
"Read line by line from the @var{input} port and return all matches for
|
||||
@var{regexp}."
|
||||
(let ((regexp (if (string? regexp) (make-regexp regexp) regexp)))
|
||||
(with-input-from-port input
|
||||
(lambda ()
|
||||
(let loop ((line (read-line))
|
||||
(result '()))
|
||||
(format #t "> ~A~%" line)
|
||||
(if (eof-object? line)
|
||||
(reverse result)
|
||||
(cond ((regexp-exec regexp line)
|
||||
=>
|
||||
(lambda (match)
|
||||
(loop (read-line)
|
||||
(cons match result))))
|
||||
(else
|
||||
(loop (read-line) result)))))))))
|
||||
|
||||
(define (parse-result benchmark-output)
|
||||
(let ((result (grep "^(execution time|heap size):[[:blank:]]+([0-9.]+)"
|
||||
benchmark-output)))
|
||||
(fold (lambda (match result)
|
||||
(cond ((equal? (match:substring match 1) "execution time")
|
||||
(cons (cons 'execution-time
|
||||
(string->number (match:substring match 2)))
|
||||
result))
|
||||
((equal? (match:substring match 1) "heap size")
|
||||
(cons (cons 'heap-size
|
||||
(string->number (match:substring match 2)))
|
||||
result))
|
||||
(else
|
||||
result)))
|
||||
'()
|
||||
result)))
|
||||
|
||||
(define (pretty-print-result benchmark reference bdwgc)
|
||||
(define (print-line name result ref?)
|
||||
(let ((name (string-pad-right name 23))
|
||||
(time (assoc-ref result 'execution-time))
|
||||
(heap (assoc-ref result 'heap-size))
|
||||
(ref-heap (assoc-ref reference 'heap-size))
|
||||
(ref-time (assoc-ref reference 'execution-time)))
|
||||
(format #t "~a ~1,2f (~,2fx) ~6,3f (~,2fx)~A~%"
|
||||
name
|
||||
(/ heap 1000000.0) (/ heap ref-heap 1.0)
|
||||
time (/ time ref-time 1.0)
|
||||
(if (and (not ref?)
|
||||
(<= heap ref-heap) (<= time ref-time))
|
||||
" !"
|
||||
""))))
|
||||
|
||||
(format #t "benchmark: `~a'~%" benchmark)
|
||||
(format #t " heap size (MiB) execution time (s.)~%")
|
||||
(print-line "Guile" reference #t)
|
||||
(for-each (lambda (bdwgc)
|
||||
(let ((name (format #f "BDW-GC, FSD=~a~a"
|
||||
(assoc-ref bdwgc 'free-space-divisor)
|
||||
(cond ((assoc-ref bdwgc 'incremental?)
|
||||
" incr.")
|
||||
((assoc-ref bdwgc 'generational?)
|
||||
" gene.")
|
||||
((assoc-ref bdwgc 'parallel?)
|
||||
" paral.")
|
||||
(else "")))))
|
||||
(print-line name bdwgc #f)))
|
||||
bdwgc))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Option processing.
|
||||
;;;
|
||||
|
||||
(define %options
|
||||
(list (option '(#\h "help") #f #f
|
||||
(lambda args
|
||||
(show-help)
|
||||
(exit 0)))
|
||||
(option '(#\r "reference") #t #f
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'reference-environment arg
|
||||
(alist-delete 'reference-environment result
|
||||
eq?))))
|
||||
(option '(#\b "bdw-gc") #t #f
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'bdwgc-environment arg
|
||||
(alist-delete 'bdwgc-environment result
|
||||
eq?))))
|
||||
(option '(#\d "benchmark-dir") #t #f
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'benchmark-directory arg
|
||||
(alist-delete 'benchmark-directory result
|
||||
eq?))))
|
||||
(option '(#\p "profile-options") #t #f
|
||||
(lambda (opt name arg result)
|
||||
(let ((opts (assoc-ref result 'profile-options)))
|
||||
(alist-cons 'profile-options
|
||||
(string-append opts " " arg)
|
||||
(alist-delete 'profile-options result
|
||||
eq?)))))
|
||||
(option '(#\l "log-file") #t #f
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'log-port (open-output-file arg)
|
||||
(alist-delete 'log-port result
|
||||
eq?))))))
|
||||
|
||||
(define %default-options
|
||||
`((reference-environment . "GUILE=guile")
|
||||
(benchmark-directory . "./gc-benchmarks")
|
||||
(log-port . ,(current-output-port))
|
||||
(profile-options . "")
|
||||
(input . ())))
|
||||
|
||||
(define (show-help)
|
||||
(format #t "Usage: run-benchmark [OPTIONS] BENCHMARKS...
|
||||
Run BENCHMARKS (a list of Scheme files) and display a performance
|
||||
comparison of standard Guile (1.9) and the BDW-GC-based Guile.
|
||||
|
||||
-h, --help Show this help message
|
||||
|
||||
-r, --reference=ENV
|
||||
-b, --bdw-gc=ENV
|
||||
Use ENV as the environment necessary to run the
|
||||
\"reference\" Guile (1.9) or the BDW-GC-based Guile,
|
||||
respectively. At a minimum, ENV should define the
|
||||
`GUILE' environment variable. For example:
|
||||
|
||||
--reference='GUILE=/foo/bar/guile LD_LIBRARY_PATH=/foo'
|
||||
|
||||
-p, --profile-options=OPTS
|
||||
Pass OPTS as additional options for `gc-profile.scm'.
|
||||
-l, --log-file=FILE
|
||||
Save output to FILE instead of the standard output.
|
||||
-d, --benchmark-dir=DIR
|
||||
Use DIR as the GC benchmark directory where `gc-profile.scm'
|
||||
lives (it is automatically determined by default).
|
||||
|
||||
Report bugs to <bug-guile@gnu.org>.~%"))
|
||||
|
||||
(define (parse-args args)
|
||||
(define (leave fmt . args)
|
||||
(apply format (current-error-port) (string-append fmt "~%") args)
|
||||
(exit 1))
|
||||
|
||||
(args-fold args %options
|
||||
(lambda (opt name arg result)
|
||||
(leave "~A: unrecognized option" opt))
|
||||
(lambda (file result)
|
||||
(let ((files (or (assoc-ref result 'input) '())))
|
||||
(alist-cons 'input (cons file files)
|
||||
(alist-delete 'input result eq?))))
|
||||
%default-options))
|
||||
|
||||
|
||||
;;;
|
||||
;;; The main program.
|
||||
;;;
|
||||
|
||||
(define (main . args)
|
||||
(let* ((args (parse-args args))
|
||||
(benchmark-files (assoc-ref args 'input)))
|
||||
|
||||
(let* ((log (assoc-ref args 'log-port))
|
||||
(bench-dir (assoc-ref args 'benchmark-directory))
|
||||
(ref-env (assoc-ref args 'reference-environment))
|
||||
(bdwgc-env (or (assoc-ref args 'bdwgc-environment)
|
||||
(string-append "GUILE=" bench-dir
|
||||
"/../pre-inst-guile")))
|
||||
(prof-opts (assoc-ref args 'profile-options)))
|
||||
(for-each (lambda (benchmark)
|
||||
(let ((ref (parse-result (run-reference-guile ref-env
|
||||
bench-dir
|
||||
prof-opts
|
||||
benchmark)))
|
||||
(bdwgc (map (lambda (fsd incremental?
|
||||
generational? parallel?)
|
||||
(let ((opts
|
||||
(list
|
||||
(cons 'free-space-divisor fsd)
|
||||
(cons 'incremental? incremental?)
|
||||
(cons 'generational? generational?)
|
||||
(cons 'parallel? parallel?))))
|
||||
(append opts
|
||||
(parse-result
|
||||
(run-bdwgc-guile bdwgc-env
|
||||
bench-dir
|
||||
prof-opts
|
||||
opts
|
||||
benchmark)))))
|
||||
'( 3 6 9 3 3)
|
||||
'(#f #f #f #t #f) ;; incremental
|
||||
'(#f #f #f #f #t) ;; generational
|
||||
'(#f #f #f #f #f)))) ;; parallel
|
||||
;;(format #t "ref=~A~%" ref)
|
||||
;;(format #t "bdw-gc=~A~%" bdwgc)
|
||||
(with-output-to-port log
|
||||
(lambda ()
|
||||
(pretty-print-result benchmark ref bdwgc)
|
||||
(newline)
|
||||
(force-output)))))
|
||||
benchmark-files))))
|
25
gc-benchmarks/string.scm
Normal file
25
gc-benchmarks/string.scm
Normal file
|
@ -0,0 +1,25 @@
|
|||
;;; From from http://www.ccs.neu.edu/home/will/Twobit/KVW/string.txt .
|
||||
; string test
|
||||
; (try 100000)
|
||||
|
||||
(define s "abcdef")
|
||||
|
||||
(define (grow)
|
||||
(set! s (string-append "123" s "456" s "789"))
|
||||
(set! s (string-append
|
||||
(substring s (quotient (string-length s) 2) (string-length s))
|
||||
(substring s 0 (+ 1 (quotient (string-length s) 2)))))
|
||||
s)
|
||||
|
||||
(define (trial n)
|
||||
(do ((i 0 (+ i 1)))
|
||||
((> (string-length s) n) (string-length s))
|
||||
(grow)))
|
||||
|
||||
(define (try n)
|
||||
(do ((i 0 (+ i 1)))
|
||||
((>= i 10) (string-length s))
|
||||
(set! s "abcdef")
|
||||
(trial n)))
|
||||
|
||||
(try 50000000)
|
9
lib/.gitignore
vendored
Normal file
9
lib/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
/config.charset
|
||||
/localcharset.c
|
||||
/localcharset.h
|
||||
/mbrlen.c
|
||||
/mbrtowc.c
|
||||
/mbsinit.c
|
||||
/ref-add.sin
|
||||
/ref-del.sin
|
||||
/streq.h
|
197
lib/Makefile.am
197
lib/Makefile.am
|
@ -1,6 +1,6 @@
|
|||
## DO NOT EDIT! GENERATED AUTOMATICALLY!
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
# Copyright (C) 2002-2008 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software, distributed under the terms of the GNU
|
||||
# General Public License. As a special exception to the GNU General
|
||||
|
@ -9,7 +9,7 @@
|
|||
# the same distribution terms as the rest of that program.
|
||||
#
|
||||
# Generated by gnulib-tool.
|
||||
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl alloca autobuild count-one-bits extensions full-read full-write strcase strftime
|
||||
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl alloca-opt autobuild count-one-bits extensions full-read full-write strcase strftime
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.5 gnits
|
||||
|
||||
|
@ -36,17 +36,6 @@ libgnu_la_DEPENDENCIES = $(gl_LTLIBOBJS)
|
|||
EXTRA_libgnu_la_SOURCES =
|
||||
libgnu_la_LDFLAGS = $(AM_LDFLAGS)
|
||||
|
||||
## begin gnulib module alloca
|
||||
|
||||
|
||||
EXTRA_DIST += alloca.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += alloca.c
|
||||
|
||||
libgnu_la_LIBADD += @LTALLOCA@
|
||||
libgnu_la_DEPENDENCIES += @LTALLOCA@
|
||||
## end gnulib module alloca
|
||||
|
||||
## begin gnulib module alloca-opt
|
||||
|
||||
BUILT_SOURCES += $(ALLOCA_H)
|
||||
|
@ -64,6 +53,62 @@ EXTRA_DIST += alloca.in.h
|
|||
|
||||
## end gnulib module alloca-opt
|
||||
|
||||
## begin gnulib module configmake
|
||||
|
||||
# Retrieve values of the variables through 'configure' followed by
|
||||
# 'make', not directly through 'configure', so that a user who
|
||||
# sets some of these variables consistently on the 'make' command
|
||||
# line gets correct results.
|
||||
#
|
||||
# One advantage of this approach, compared to the classical
|
||||
# approach of adding -DLIBDIR=\"$(libdir)\" etc. to AM_CPPFLAGS,
|
||||
# is that it protects against the use of undefined variables.
|
||||
# If, say, $(libdir) is not set in the Makefile, LIBDIR is not
|
||||
# defined by this module, and code using LIBDIR gives a
|
||||
# compilation error.
|
||||
#
|
||||
# Another advantage is that 'make' output is shorter.
|
||||
#
|
||||
# Listed in the same order as the GNU makefile conventions.
|
||||
# The Automake-defined pkg* macros are appended, in the order
|
||||
# listed in the Automake 1.10a+ documentation.
|
||||
configmake.h: Makefile
|
||||
rm -f $@-t $@
|
||||
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
|
||||
echo '#define PREFIX "$(prefix)"'; \
|
||||
echo '#define EXEC_PREFIX "$(exec_prefix)"'; \
|
||||
echo '#define BINDIR "$(bindir)"'; \
|
||||
echo '#define SBINDIR "$(sbindir)"'; \
|
||||
echo '#define LIBEXECDIR "$(libexecdir)"'; \
|
||||
echo '#define DATAROOTDIR "$(datarootdir)"'; \
|
||||
echo '#define DATADIR "$(datadir)"'; \
|
||||
echo '#define SYSCONFDIR "$(sysconfdir)"'; \
|
||||
echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \
|
||||
echo '#define LOCALSTATEDIR "$(localstatedir)"'; \
|
||||
echo '#define INCLUDEDIR "$(includedir)"'; \
|
||||
echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \
|
||||
echo '#define DOCDIR "$(docdir)"'; \
|
||||
echo '#define INFODIR "$(infodir)"'; \
|
||||
echo '#define HTMLDIR "$(htmldir)"'; \
|
||||
echo '#define DVIDIR "$(dvidir)"'; \
|
||||
echo '#define PDFDIR "$(pdfdir)"'; \
|
||||
echo '#define PSDIR "$(psdir)"'; \
|
||||
echo '#define LIBDIR "$(libdir)"'; \
|
||||
echo '#define LISPDIR "$(lispdir)"'; \
|
||||
echo '#define LOCALEDIR "$(localedir)"'; \
|
||||
echo '#define MANDIR "$(mandir)"'; \
|
||||
echo '#define MANEXT "$(manext)"'; \
|
||||
echo '#define PKGDATADIR "$(pkgdatadir)"'; \
|
||||
echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \
|
||||
echo '#define PKGLIBDIR "$(pkglibdir)"'; \
|
||||
echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \
|
||||
} | sed '/""/d' > $@-t
|
||||
mv $@-t $@
|
||||
BUILT_SOURCES += configmake.h
|
||||
CLEANFILES += configmake.h configmake.h-t
|
||||
|
||||
## end gnulib module configmake
|
||||
|
||||
## begin gnulib module count-one-bits
|
||||
|
||||
|
||||
|
@ -91,6 +136,91 @@ EXTRA_DIST += $(top_srcdir)/build-aux/link-warning.h
|
|||
|
||||
## end gnulib module link-warning
|
||||
|
||||
## begin gnulib module localcharset
|
||||
|
||||
libgnu_la_SOURCES += localcharset.h localcharset.c
|
||||
|
||||
# We need the following in order to install a simple file in $(libdir)
|
||||
# which is shared with other installed packages. We use a list of referencing
|
||||
# packages so that "make uninstall" will remove the file if and only if it
|
||||
# is not used by another installed package.
|
||||
# On systems with glibc-2.1 or newer, the file is redundant, therefore we
|
||||
# avoid installing it.
|
||||
|
||||
all-local: charset.alias ref-add.sed ref-del.sed
|
||||
|
||||
charset_alias = $(DESTDIR)$(libdir)/charset.alias
|
||||
charset_tmp = $(DESTDIR)$(libdir)/charset.tmp
|
||||
install-exec-local: all-local
|
||||
test $(GLIBC21) != no || $(mkinstalldirs) $(DESTDIR)$(libdir)
|
||||
if test -f $(charset_alias); then \
|
||||
sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \
|
||||
$(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
|
||||
rm -f $(charset_tmp) ; \
|
||||
else \
|
||||
if test $(GLIBC21) = no; then \
|
||||
sed -f ref-add.sed charset.alias > $(charset_tmp) ; \
|
||||
$(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
|
||||
rm -f $(charset_tmp) ; \
|
||||
fi ; \
|
||||
fi
|
||||
|
||||
uninstall-local: all-local
|
||||
if test -f $(charset_alias); then \
|
||||
sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \
|
||||
if grep '^# Packages using this file: $$' $(charset_tmp) \
|
||||
> /dev/null; then \
|
||||
rm -f $(charset_alias); \
|
||||
else \
|
||||
$(INSTALL_DATA) $(charset_tmp) $(charset_alias); \
|
||||
fi; \
|
||||
rm -f $(charset_tmp); \
|
||||
fi
|
||||
|
||||
charset.alias: config.charset
|
||||
rm -f t-$@ $@
|
||||
$(SHELL) $(srcdir)/config.charset '$(host)' > t-$@
|
||||
mv t-$@ $@
|
||||
|
||||
SUFFIXES += .sed .sin
|
||||
.sin.sed:
|
||||
rm -f t-$@ $@
|
||||
sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@
|
||||
mv t-$@ $@
|
||||
|
||||
CLEANFILES += charset.alias ref-add.sed ref-del.sed
|
||||
|
||||
EXTRA_DIST += config.charset ref-add.sin ref-del.sin
|
||||
|
||||
## end gnulib module localcharset
|
||||
|
||||
## begin gnulib module mbrlen
|
||||
|
||||
|
||||
EXTRA_DIST += mbrlen.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mbrlen.c
|
||||
|
||||
## end gnulib module mbrlen
|
||||
|
||||
## begin gnulib module mbrtowc
|
||||
|
||||
|
||||
EXTRA_DIST += mbrtowc.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mbrtowc.c
|
||||
|
||||
## end gnulib module mbrtowc
|
||||
|
||||
## begin gnulib module mbsinit
|
||||
|
||||
|
||||
EXTRA_DIST += mbsinit.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mbsinit.c
|
||||
|
||||
## end gnulib module mbsinit
|
||||
|
||||
## begin gnulib module safe-read
|
||||
|
||||
|
||||
|
@ -136,6 +266,13 @@ EXTRA_libgnu_la_SOURCES += strcasecmp.c strncasecmp.c
|
|||
|
||||
## end gnulib module strcase
|
||||
|
||||
## begin gnulib module streq
|
||||
|
||||
|
||||
EXTRA_DIST += streq.h
|
||||
|
||||
## end gnulib module streq
|
||||
|
||||
## begin gnulib module strftime
|
||||
|
||||
|
||||
|
@ -291,10 +428,40 @@ wchar.h: wchar.in.h
|
|||
sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
|
||||
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||
-e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \
|
||||
-e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \
|
||||
-e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \
|
||||
-e 's|@''GNULIB_BTOWC''@|$(GNULIB_BTOWC)|g' \
|
||||
-e 's|@''GNULIB_WCTOB''@|$(GNULIB_WCTOB)|g' \
|
||||
-e 's|@''GNULIB_MBSINIT''@|$(GNULIB_MBSINIT)|g' \
|
||||
-e 's|@''GNULIB_MBRTOWC''@|$(GNULIB_MBRTOWC)|g' \
|
||||
-e 's|@''GNULIB_MBRLEN''@|$(GNULIB_MBRLEN)|g' \
|
||||
-e 's|@''GNULIB_MBSRTOWCS''@|$(GNULIB_MBSRTOWCS)|g' \
|
||||
-e 's|@''GNULIB_MBSNRTOWCS''@|$(GNULIB_MBSNRTOWCS)|g' \
|
||||
-e 's|@''GNULIB_WCRTOMB''@|$(GNULIB_WCRTOMB)|g' \
|
||||
-e 's|@''GNULIB_WCSRTOMBS''@|$(GNULIB_WCSRTOMBS)|g' \
|
||||
-e 's|@''GNULIB_WCSNRTOMBS''@|$(GNULIB_WCSNRTOMBS)|g' \
|
||||
-e 's|@''GNULIB_WCWIDTH''@|$(GNULIB_WCWIDTH)|g' \
|
||||
-e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \
|
||||
-e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \
|
||||
-e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \
|
||||
-e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \
|
||||
-e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \
|
||||
-e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \
|
||||
-e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \
|
||||
-e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \
|
||||
-e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \
|
||||
-e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \
|
||||
-e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \
|
||||
-e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \
|
||||
-e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \
|
||||
-e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \
|
||||
-e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \
|
||||
-e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \
|
||||
-e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \
|
||||
-e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \
|
||||
-e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \
|
||||
-e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \
|
||||
-e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \
|
||||
-e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \
|
||||
-e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \
|
||||
-e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \
|
||||
-e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
|
||||
< $(srcdir)/wchar.in.h; \
|
||||
|
|
489
lib/alloca.c
489
lib/alloca.c
|
@ -1,489 +0,0 @@
|
|||
/* alloca.c -- allocate automatically reclaimed memory
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
This implementation of the PWB library alloca function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||
|
||||
There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <alloca.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef emacs
|
||||
# include "lisp.h"
|
||||
# include "blockinput.h"
|
||||
# ifdef EMACS_FREE
|
||||
# undef free
|
||||
# define free EMACS_FREE
|
||||
# endif
|
||||
#else
|
||||
# define memory_full() abort ()
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
/* If someone has defined alloca as a macro,
|
||||
there must be some other way alloca is supposed to work. */
|
||||
# ifndef alloca
|
||||
|
||||
# ifdef emacs
|
||||
# ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
# ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
/* Using #error here is not wise since this file should work for
|
||||
old and obscure compilers. */
|
||||
# endif /* STACK_DIRECTION undefined */
|
||||
# endif /* static */
|
||||
# endif /* emacs */
|
||||
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
|
||||
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc ();
|
||||
# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
# else
|
||||
# define ADDRESS_FUNCTION(arg) &(arg)
|
||||
# endif
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
# ifndef STACK_DIRECTION
|
||||
# define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
# endif
|
||||
|
||||
# if STACK_DIRECTION != 0
|
||||
|
||||
# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
# else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
# define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction (void)
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
|
||||
# endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
# ifndef ALIGN_SIZE
|
||||
# define ALIGN_SIZE sizeof(double)
|
||||
# endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
|
||||
/* Return a pointer to at least SIZE bytes of storage,
|
||||
which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca. Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
void *
|
||||
alloca (size_t size)
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
|
||||
# if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
# endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
# ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
# endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free (hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
}
|
||||
else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
# ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
# endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
/* Address of header. */
|
||||
register header *new;
|
||||
|
||||
size_t combined_size = sizeof (header) + size;
|
||||
if (combined_size < sizeof (header))
|
||||
memory_full ();
|
||||
|
||||
new = malloc (combined_size);
|
||||
|
||||
if (! new)
|
||||
memory_full ();
|
||||
|
||||
new->h.next = last_alloca_header;
|
||||
new->h.deep = depth;
|
||||
|
||||
last_alloca_header = new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (void *) (new + 1);
|
||||
}
|
||||
}
|
||||
|
||||
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
|
||||
# ifdef DEBUG_I00AFUNC
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
|
||||
# ifndef CRAY_STACK
|
||||
# define CRAY_STACK
|
||||
# ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
the high-address end of a stack segment. (The stack
|
||||
grows from low addresses to high addresses.) The initial
|
||||
part of the stack segment linkage control information is
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
|
||||
# else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
|
||||
# endif /* CRAY2 */
|
||||
# endif /* not CRAY_STACK */
|
||||
|
||||
# ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc (long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
|
||||
STKSTAT (&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort ();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0)
|
||||
{
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
# else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc (long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END ();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl))
|
||||
{
|
||||
# ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
# endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
|
||||
while (pseg != 0)
|
||||
{
|
||||
# ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||
# endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
# endif /* not CRAY2 */
|
||||
# endif /* CRAY */
|
||||
|
||||
# endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
57
lib/alloca.h
Normal file
57
lib/alloca.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
||||
/* Memory allocation on the stack.
|
||||
|
||||
Copyright (C) 1995, 1999, 2001-2004, 2006-2008 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
USA. */
|
||||
|
||||
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
|
||||
means there is a real alloca function. */
|
||||
#ifndef _GL_ALLOCA_H
|
||||
#define _GL_ALLOCA_H
|
||||
|
||||
/* alloca (N) returns a pointer to N bytes of memory
|
||||
allocated on the stack, which will last until the function returns.
|
||||
Use of alloca should be avoided:
|
||||
- inside arguments of function calls - undefined behaviour,
|
||||
- in inline functions - the allocation may actually last until the
|
||||
calling function returns,
|
||||
- for huge N (say, N >= 65536) - you never know how large (or small)
|
||||
the stack is, and when the stack cannot fulfill the memory allocation
|
||||
request, the program just crashes.
|
||||
*/
|
||||
|
||||
#ifndef alloca
|
||||
# ifdef __GNUC__
|
||||
# define alloca __builtin_alloca
|
||||
# elif defined _AIX
|
||||
# define alloca __alloca
|
||||
# elif defined _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define alloca _alloca
|
||||
# elif defined __DECC && defined __VMS
|
||||
# define alloca __ALLOCA
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void *alloca (size_t);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* _GL_ALLOCA_H */
|
5
lib/charset.alias
Normal file
5
lib/charset.alias
Normal file
|
@ -0,0 +1,5 @@
|
|||
# This file contains a table of character encoding aliases,
|
||||
# suitable for operating system 'linux-gnu'.
|
||||
# It was automatically generated from config.charset.
|
||||
# Packages using this file:
|
||||
ISO_646.IRV:1983 ASCII
|
26
lib/configmake.h
Normal file
26
lib/configmake.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
||||
#define PREFIX "/usr/local"
|
||||
#define EXEC_PREFIX "/usr/local"
|
||||
#define BINDIR "/usr/local/bin"
|
||||
#define SBINDIR "/usr/local/sbin"
|
||||
#define LIBEXECDIR "/usr/local/libexec"
|
||||
#define DATAROOTDIR "/usr/local/share"
|
||||
#define DATADIR "/usr/local/share"
|
||||
#define SYSCONFDIR "/usr/local/etc"
|
||||
#define SHAREDSTATEDIR "/usr/local/com"
|
||||
#define LOCALSTATEDIR "/usr/local/var"
|
||||
#define INCLUDEDIR "/usr/local/include"
|
||||
#define OLDINCLUDEDIR "/usr/include"
|
||||
#define DOCDIR "/usr/local/share/doc/guile"
|
||||
#define INFODIR "/usr/local/share/info"
|
||||
#define HTMLDIR "/usr/local/share/doc/guile"
|
||||
#define DVIDIR "/usr/local/share/doc/guile"
|
||||
#define PDFDIR "/usr/local/share/doc/guile"
|
||||
#define PSDIR "/usr/local/share/doc/guile"
|
||||
#define LIBDIR "/usr/local/lib"
|
||||
#define LISPDIR "/usr/local/share/emacs/site-lisp"
|
||||
#define LOCALEDIR "/usr/local/share/locale"
|
||||
#define MANDIR "/usr/local/share/man"
|
||||
#define PKGDATADIR "/usr/local/share/guile"
|
||||
#define PKGINCLUDEDIR "/usr/local/include/guile"
|
||||
#define PKGLIBDIR "/usr/local/lib/guile"
|
10
lib/ref-add.sed
Normal file
10
lib/ref-add.sed
Normal file
|
@ -0,0 +1,10 @@
|
|||
/^# Packages using this file: / {
|
||||
s/# Packages using this file://
|
||||
ta
|
||||
:a
|
||||
s/ guile / guile /
|
||||
tb
|
||||
s/ $/ guile /
|
||||
:b
|
||||
s/^/# Packages using this file:/
|
||||
}
|
5
lib/ref-del.sed
Normal file
5
lib/ref-del.sed
Normal file
|
@ -0,0 +1,5 @@
|
|||
/^# Packages using this file: / {
|
||||
s/# Packages using this file://
|
||||
s/ guile / /
|
||||
s/^/# Packages using this file:/
|
||||
}
|
|
@ -50,14 +50,7 @@ extern char *tzname[];
|
|||
#define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
|
||||
|
||||
#if DO_MULTIBYTE
|
||||
# if HAVE_MBRLEN
|
||||
# include <wchar.h>
|
||||
# else
|
||||
/* Simulate mbrlen with mblen as best we can. */
|
||||
# define mbstate_t int
|
||||
# define mbrlen(s, n, ps) mblen (s, n)
|
||||
# define mbsinit(ps) (*(ps) == 0)
|
||||
# endif
|
||||
# include <wchar.h>
|
||||
static const mbstate_t mbstate_zero;
|
||||
#endif
|
||||
|
||||
|
|
119
lib/strings.h
Normal file
119
lib/strings.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
||||
/* A substitute <strings.h>.
|
||||
|
||||
Copyright (C) 2007-2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef _GL_STRINGS_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#include_next <strings.h>
|
||||
|
||||
#ifndef _GL_STRINGS_H
|
||||
#define _GL_STRINGS_H
|
||||
|
||||
|
||||
/* The definition of GL_LINK_WARNING is copied here. */
|
||||
/* GL_LINK_WARNING("literal string") arranges to emit the literal string as
|
||||
a linker warning on most glibc systems.
|
||||
We use a linker warning rather than a preprocessor warning, because
|
||||
#warning cannot be used inside macros. */
|
||||
#ifndef GL_LINK_WARNING
|
||||
/* This works on platforms with GNU ld and ELF object format.
|
||||
Testing __GLIBC__ is sufficient for asserting that GNU ld is in use.
|
||||
Testing __ELF__ guarantees the ELF object format.
|
||||
Testing __GNUC__ is necessary for the compound expression syntax. */
|
||||
# if defined __GLIBC__ && defined __ELF__ && defined __GNUC__
|
||||
# define GL_LINK_WARNING(message) \
|
||||
GL_LINK_WARNING1 (__FILE__, __LINE__, message)
|
||||
# define GL_LINK_WARNING1(file, line, message) \
|
||||
GL_LINK_WARNING2 (file, line, message) /* macroexpand file and line */
|
||||
# define GL_LINK_WARNING2(file, line, message) \
|
||||
GL_LINK_WARNING3 (file ":" #line ": warning: " message)
|
||||
# define GL_LINK_WARNING3(message) \
|
||||
({ static const char warning[sizeof (message)] \
|
||||
__attribute__ ((__unused__, \
|
||||
__section__ (".gnu.warning"), \
|
||||
__aligned__ (1))) \
|
||||
= message "\n"; \
|
||||
(void)0; \
|
||||
})
|
||||
# else
|
||||
# define GL_LINK_WARNING(message) ((void) 0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
|
||||
greater than zero if S1 is lexicographically less than, equal to or greater
|
||||
than S2.
|
||||
Note: This function does not work in multibyte locales. */
|
||||
#if ! 1
|
||||
extern int strcasecmp (char const *s1, char const *s2);
|
||||
#endif
|
||||
#if defined GNULIB_POSIXCHECK
|
||||
/* strcasecmp() does not work with multibyte strings:
|
||||
POSIX says that it operates on "strings", and "string" in POSIX is defined
|
||||
as a sequence of bytes, not of characters. */
|
||||
# undef strcasecmp
|
||||
# define strcasecmp(a,b) \
|
||||
(GL_LINK_WARNING ("strcasecmp cannot work correctly on character strings " \
|
||||
"in multibyte locales - " \
|
||||
"use mbscasecmp if you care about " \
|
||||
"internationalization, or use c_strcasecmp (from " \
|
||||
"gnulib module c-strcase) if you want a locale " \
|
||||
"independent function"), \
|
||||
strcasecmp (a, b))
|
||||
#endif
|
||||
|
||||
/* Compare no more than N bytes of strings S1 and S2, ignoring case,
|
||||
returning less than, equal to or greater than zero if S1 is
|
||||
lexicographically less than, equal to or greater than S2.
|
||||
Note: This function cannot work correctly in multibyte locales. */
|
||||
#if ! 1
|
||||
extern int strncasecmp (char const *s1, char const *s2, size_t n);
|
||||
#endif
|
||||
#if defined GNULIB_POSIXCHECK
|
||||
/* strncasecmp() does not work with multibyte strings:
|
||||
POSIX says that it operates on "strings", and "string" in POSIX is defined
|
||||
as a sequence of bytes, not of characters. */
|
||||
# undef strncasecmp
|
||||
# define strncasecmp(a,b,n) \
|
||||
(GL_LINK_WARNING ("strncasecmp cannot work correctly on character " \
|
||||
"strings in multibyte locales - " \
|
||||
"use mbsncasecmp or mbspcasecmp if you care about " \
|
||||
"internationalization, or use c_strncasecmp (from " \
|
||||
"gnulib module c-strcase) if you want a locale " \
|
||||
"independent function"), \
|
||||
strncasecmp (a, b, n))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GL_STRING_H */
|
||||
#endif /* _GL_STRING_H */
|
119
lib/time.h
Normal file
119
lib/time.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
||||
/* A more-standard <time.h>.
|
||||
|
||||
Copyright (C) 2007-2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
/* Don't get in the way of glibc when it includes time.h merely to
|
||||
declare a few standard symbols, rather than to declare all the
|
||||
symbols. Also, Solaris 8 <time.h> eventually includes itself
|
||||
recursively; if that is happening, just include the system <time.h>
|
||||
without adding our own declarations. */
|
||||
#if (defined __need_time_t || defined __need_clock_t \
|
||||
|| defined __need_timespec \
|
||||
|| defined _GL_TIME_H)
|
||||
|
||||
# include_next <time.h>
|
||||
|
||||
#else
|
||||
|
||||
# define _GL_TIME_H
|
||||
|
||||
# include_next <time.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
/* Some systems don't define struct timespec (e.g., AIX 4.1, Ultrix 4.3).
|
||||
Or they define it with the wrong member names or define it in <sys/time.h>
|
||||
(e.g., FreeBSD circa 1997). */
|
||||
# if ! 1
|
||||
# if 0
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# undef timespec
|
||||
# define timespec rpl_timespec
|
||||
struct timespec
|
||||
{
|
||||
time_t tv_sec;
|
||||
long int tv_nsec;
|
||||
};
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Sleep for at least RQTP seconds unless interrupted, If interrupted,
|
||||
return -1 and store the remaining time into RMTP. See
|
||||
<http://www.opengroup.org/susv3xsh/nanosleep.html>. */
|
||||
# if GNULIB_PORTCHECK
|
||||
# define nanosleep rpl_nanosleep
|
||||
int nanosleep (struct timespec const *__rqtp, struct timespec *__rmtp);
|
||||
# endif
|
||||
|
||||
/* Convert TIMER to RESULT, assuming local time and UTC respectively. See
|
||||
<http://www.opengroup.org/susv3xsh/localtime_r.html> and
|
||||
<http://www.opengroup.org/susv3xsh/gmtime_r.html>. */
|
||||
# if 0
|
||||
# undef localtime_r
|
||||
# define localtime_r rpl_localtime_r
|
||||
# undef gmtime_r
|
||||
# define gmtime_r rpl_gmtime_r
|
||||
struct tm *localtime_r (time_t const *restrict __timer,
|
||||
struct tm *restrict __result);
|
||||
struct tm *gmtime_r (time_t const *restrict __timer,
|
||||
struct tm *restrict __result);
|
||||
# endif
|
||||
|
||||
/* Parse BUF as a time stamp, assuming FORMAT specifies its layout, and store
|
||||
the resulting broken-down time into TM. See
|
||||
<http://www.opengroup.org/susv3xsh/strptime.html>. */
|
||||
# if GNULIB_PORTCHECK
|
||||
# undef strptime
|
||||
# define strptime rpl_strptime
|
||||
char *strptime (char const *restrict __buf, char const *restrict __format,
|
||||
struct tm *restrict __tm);
|
||||
# endif
|
||||
|
||||
/* Convert TM to a time_t value, assuming UTC. */
|
||||
# if GNULIB_PORTCHECK
|
||||
# undef timegm
|
||||
# define timegm rpl_timegm
|
||||
time_t timegm (struct tm *__tm);
|
||||
# endif
|
||||
|
||||
/* Encourage applications to avoid unsafe functions that can overrun
|
||||
buffers when given outlandish struct tm values. Portable
|
||||
applications should use strftime (or even sprintf) instead. */
|
||||
# if GNULIB_PORTCHECK
|
||||
# undef asctime
|
||||
# define asctime eschew_asctime
|
||||
# undef asctime_r
|
||||
# define asctime_r eschew_asctime_r
|
||||
# undef ctime
|
||||
# define ctime eschew_ctime
|
||||
# undef ctime_r
|
||||
# define ctime_r eschew_ctime_r
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
583
lib/unistd.h
Normal file
583
lib/unistd.h
Normal file
|
@ -0,0 +1,583 @@
|
|||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
||||
/* Substitute for and wrapper around <unistd.h>.
|
||||
Copyright (C) 2003-2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef _GL_UNISTD_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#if 1
|
||||
# include_next <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef _GL_UNISTD_H
|
||||
#define _GL_UNISTD_H
|
||||
|
||||
/* mingw doesn't define the SEEK_* macros in <unistd.h>. */
|
||||
#if !(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET)
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* mingw fails to declare _exit in <unistd.h>. */
|
||||
/* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */
|
||||
#include <stdlib.h>
|
||||
|
||||
#if 1 && 0 && 0
|
||||
/* Get ssize_t. */
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Get all possible declarations of gethostname(). */
|
||||
# if 0
|
||||
# include <winsock2.h>
|
||||
# if !defined _GL_SYS_SOCKET_H
|
||||
# undef socket
|
||||
# define socket socket_used_without_including_sys_socket_h
|
||||
# undef connect
|
||||
# define connect connect_used_without_including_sys_socket_h
|
||||
# undef accept
|
||||
# define accept accept_used_without_including_sys_socket_h
|
||||
# undef bind
|
||||
# define bind bind_used_without_including_sys_socket_h
|
||||
# undef getpeername
|
||||
# define getpeername getpeername_used_without_including_sys_socket_h
|
||||
# undef getsockname
|
||||
# define getsockname getsockname_used_without_including_sys_socket_h
|
||||
# undef getsockopt
|
||||
# define getsockopt getsockopt_used_without_including_sys_socket_h
|
||||
# undef listen
|
||||
# define listen listen_used_without_including_sys_socket_h
|
||||
# undef recv
|
||||
# define recv recv_used_without_including_sys_socket_h
|
||||
# undef send
|
||||
# define send send_used_without_including_sys_socket_h
|
||||
# undef recvfrom
|
||||
# define recvfrom recvfrom_used_without_including_sys_socket_h
|
||||
# undef sendto
|
||||
# define sendto sendto_used_without_including_sys_socket_h
|
||||
# undef setsockopt
|
||||
# define setsockopt setsockopt_used_without_including_sys_socket_h
|
||||
# undef shutdown
|
||||
# define shutdown shutdown_used_without_including_sys_socket_h
|
||||
# endif
|
||||
# if !defined _GL_SYS_SELECT_H
|
||||
# undef select
|
||||
# define select select_used_without_including_sys_select_h
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The definition of GL_LINK_WARNING is copied here. */
|
||||
/* GL_LINK_WARNING("literal string") arranges to emit the literal string as
|
||||
a linker warning on most glibc systems.
|
||||
We use a linker warning rather than a preprocessor warning, because
|
||||
#warning cannot be used inside macros. */
|
||||
#ifndef GL_LINK_WARNING
|
||||
/* This works on platforms with GNU ld and ELF object format.
|
||||
Testing __GLIBC__ is sufficient for asserting that GNU ld is in use.
|
||||
Testing __ELF__ guarantees the ELF object format.
|
||||
Testing __GNUC__ is necessary for the compound expression syntax. */
|
||||
# if defined __GLIBC__ && defined __ELF__ && defined __GNUC__
|
||||
# define GL_LINK_WARNING(message) \
|
||||
GL_LINK_WARNING1 (__FILE__, __LINE__, message)
|
||||
# define GL_LINK_WARNING1(file, line, message) \
|
||||
GL_LINK_WARNING2 (file, line, message) /* macroexpand file and line */
|
||||
# define GL_LINK_WARNING2(file, line, message) \
|
||||
GL_LINK_WARNING3 (file ":" #line ": warning: " message)
|
||||
# define GL_LINK_WARNING3(message) \
|
||||
({ static const char warning[sizeof (message)] \
|
||||
__attribute__ ((__unused__, \
|
||||
__section__ (".gnu.warning"), \
|
||||
__aligned__ (1))) \
|
||||
= message "\n"; \
|
||||
(void)0; \
|
||||
})
|
||||
# else
|
||||
# define GL_LINK_WARNING(message) ((void) 0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Declare overridden functions. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
# ifndef REPLACE_CHOWN
|
||||
# define REPLACE_CHOWN 1
|
||||
# endif
|
||||
# if REPLACE_CHOWN
|
||||
/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
|
||||
to GID (if GID is not -1). Follow symbolic links.
|
||||
Return 0 if successful, otherwise -1 and errno set.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/chown.html>. */
|
||||
# define chown rpl_chown
|
||||
extern int chown (const char *file, uid_t uid, gid_t gid);
|
||||
# endif
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef chown
|
||||
# define chown(f,u,g) \
|
||||
(GL_LINK_WARNING ("chown fails to follow symlinks on some systems and " \
|
||||
"doesn't treat a uid or gid of -1 on some systems - " \
|
||||
"use gnulib module chown for portability"), \
|
||||
chown (f, u, g))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
/* Need a gnulib internal function. */
|
||||
# define HAVE__GL_CLOSE_FD_MAYBE_SOCKET 1
|
||||
# endif
|
||||
# if 0
|
||||
/* Automatically included by modules that need a replacement for close. */
|
||||
# undef close
|
||||
# define close rpl_close
|
||||
extern int close (int);
|
||||
# endif
|
||||
#elif 0
|
||||
# undef close
|
||||
# define close close_used_without_requesting_gnulib_module_close
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef close
|
||||
# define close(f) \
|
||||
(GL_LINK_WARNING ("close does not portably work on sockets - " \
|
||||
"use gnulib module close for portability"), \
|
||||
close (f))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if !1
|
||||
/* Copy the file descriptor OLDFD into file descriptor NEWFD. Do nothing if
|
||||
NEWFD = OLDFD, otherwise close NEWFD first if it is open.
|
||||
Return 0 if successful, otherwise -1 and errno set.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/dup2.html>. */
|
||||
extern int dup2 (int oldfd, int newfd);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef dup2
|
||||
# define dup2(o,n) \
|
||||
(GL_LINK_WARNING ("dup2 is unportable - " \
|
||||
"use gnulib module dup2 for portability"), \
|
||||
dup2 (o, n))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if !1
|
||||
/* Set of environment variables and values. An array of strings of the form
|
||||
"VARIABLE=VALUE", terminated with a NULL. */
|
||||
# if defined __APPLE__ && defined __MACH__
|
||||
# include <crt_externs.h>
|
||||
# define environ (*_NSGetEnviron ())
|
||||
# else
|
||||
extern char **environ;
|
||||
# endif
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef environ
|
||||
# define environ \
|
||||
(GL_LINK_WARNING ("environ is unportable - " \
|
||||
"use gnulib module environ for portability"), \
|
||||
environ)
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if !1
|
||||
/* Like access(), except that is uses the effective user id and group id of
|
||||
the current process. */
|
||||
extern int euidaccess (const char *filename, int mode);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef euidaccess
|
||||
# define euidaccess(f,m) \
|
||||
(GL_LINK_WARNING ("euidaccess is unportable - " \
|
||||
"use gnulib module euidaccess for portability"), \
|
||||
euidaccess (f, m))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
|
||||
/* Change the process' current working directory to the directory on which
|
||||
the given file descriptor is open.
|
||||
Return 0 if successful, otherwise -1 and errno set.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/fchdir.html>. */
|
||||
extern int fchdir (int /*fd*/);
|
||||
|
||||
# define dup rpl_dup
|
||||
extern int dup (int);
|
||||
# define dup2 rpl_dup2
|
||||
extern int dup2 (int, int);
|
||||
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef fchdir
|
||||
# define fchdir(f) \
|
||||
(GL_LINK_WARNING ("fchdir is unportable - " \
|
||||
"use gnulib module fchdir for portability"), \
|
||||
fchdir (f))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Synchronize changes to a file.
|
||||
Return 0 if successful, otherwise -1 and errno set.
|
||||
See POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/fsync.html>. */
|
||||
# if !1
|
||||
extern int fsync (int fd);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef fsync
|
||||
# define fsync(fd) \
|
||||
(GL_LINK_WARNING ("fsync is unportable - " \
|
||||
"use gnulib module fsync for portability"), \
|
||||
fsync (fd))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if !1
|
||||
/* Change the size of the file to which FD is opened to become equal to LENGTH.
|
||||
Return 0 if successful, otherwise -1 and errno set.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/ftruncate.html>. */
|
||||
extern int ftruncate (int fd, off_t length);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef ftruncate
|
||||
# define ftruncate(f,l) \
|
||||
(GL_LINK_WARNING ("ftruncate is unportable - " \
|
||||
"use gnulib module ftruncate for portability"), \
|
||||
ftruncate (f, l))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Include the headers that might declare getcwd so that they will not
|
||||
cause confusion if included after this file. */
|
||||
# include <stdlib.h>
|
||||
# if 0
|
||||
/* Get the name of the current working directory, and put it in SIZE bytes
|
||||
of BUF.
|
||||
Return BUF if successful, or NULL if the directory couldn't be determined
|
||||
or SIZE was too small.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/getcwd.html>.
|
||||
Additionally, the gnulib module 'getcwd' guarantees the following GNU
|
||||
extension: If BUF is NULL, an array is allocated with 'malloc'; the array
|
||||
is SIZE bytes long, unless SIZE == 0, in which case it is as big as
|
||||
necessary. */
|
||||
# define getcwd rpl_getcwd
|
||||
extern char * getcwd (char *buf, size_t size);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getcwd
|
||||
# define getcwd(b,s) \
|
||||
(GL_LINK_WARNING ("getcwd is unportable - " \
|
||||
"use gnulib module getcwd for portability"), \
|
||||
getcwd (b, s))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Return the NIS domain name of the machine.
|
||||
WARNING! The NIS domain name is unrelated to the fully qualified host name
|
||||
of the machine. It is also unrelated to email addresses.
|
||||
WARNING! The NIS domain name is usually the empty string or "(none)" when
|
||||
not using NIS.
|
||||
|
||||
Put up to LEN bytes of the NIS domain name into NAME.
|
||||
Null terminate it if the name is shorter than LEN.
|
||||
If the NIS domain name is longer than LEN, set errno = EINVAL and return -1.
|
||||
Return 0 if successful, otherwise set errno and return -1. */
|
||||
# if !1
|
||||
extern int getdomainname(char *name, size_t len);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getdomainname
|
||||
# define getdomainname(n,l) \
|
||||
(GL_LINK_WARNING ("getdomainname is unportable - " \
|
||||
"use gnulib module getdomainname for portability"), \
|
||||
getdomainname (n, l))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if !1
|
||||
/* Return the maximum number of file descriptors in the current process. */
|
||||
extern int getdtablesize (void);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getdtablesize
|
||||
# define getdtablesize() \
|
||||
(GL_LINK_WARNING ("getdtablesize is unportable - " \
|
||||
"use gnulib module getdtablesize for portability"), \
|
||||
getdtablesize ())
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Return the standard host name of the machine.
|
||||
WARNING! The host name may or may not be fully qualified.
|
||||
|
||||
Put up to LEN bytes of the host name into NAME.
|
||||
Null terminate it if the name is shorter than LEN.
|
||||
If the host name is longer than LEN, set errno = EINVAL and return -1.
|
||||
Return 0 if successful, otherwise set errno and return -1. */
|
||||
# if 0
|
||||
# undef gethostname
|
||||
# define gethostname rpl_gethostname
|
||||
# endif
|
||||
# if 0 || !1
|
||||
extern int gethostname(char *name, size_t len);
|
||||
# endif
|
||||
#elif 0
|
||||
# undef gethostname
|
||||
# define gethostname gethostname_used_without_requesting_gnulib_module_gethostname
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef gethostname
|
||||
# define gethostname(n,l) \
|
||||
(GL_LINK_WARNING ("gethostname is unportable - " \
|
||||
"use gnulib module gethostname for portability"), \
|
||||
gethostname (n, l))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Copies the user's login name to NAME.
|
||||
The array pointed to by NAME has room for SIZE bytes.
|
||||
|
||||
Returns 0 if successful. Upon error, an error number is returned, or -1 in
|
||||
the case that the login name cannot be found but no specific error is
|
||||
provided (this case is hopefully rare but is left open by the POSIX spec).
|
||||
|
||||
See <http://www.opengroup.org/susv3xsh/getlogin.html>.
|
||||
*/
|
||||
# if !1
|
||||
# include <stddef.h>
|
||||
extern int getlogin_r (char *name, size_t size);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getlogin_r
|
||||
# define getlogin_r(n,s) \
|
||||
(GL_LINK_WARNING ("getlogin_r is unportable - " \
|
||||
"use gnulib module getlogin_r for portability"), \
|
||||
getlogin_r (n, s))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
# define getpagesize rpl_getpagesize
|
||||
extern int getpagesize (void);
|
||||
# elif !1
|
||||
/* This is for POSIX systems. */
|
||||
# if !defined getpagesize && defined _SC_PAGESIZE
|
||||
# if ! (defined __VMS && __VMS_VER < 70000000)
|
||||
# define getpagesize() sysconf (_SC_PAGESIZE)
|
||||
# endif
|
||||
# endif
|
||||
/* This is for older VMS. */
|
||||
# if !defined getpagesize && defined __VMS
|
||||
# ifdef __ALPHA
|
||||
# define getpagesize() 8192
|
||||
# else
|
||||
# define getpagesize() 512
|
||||
# endif
|
||||
# endif
|
||||
/* This is for BeOS. */
|
||||
# if !defined getpagesize && 0
|
||||
# include <OS.h>
|
||||
# if defined B_PAGE_SIZE
|
||||
# define getpagesize() B_PAGE_SIZE
|
||||
# endif
|
||||
# endif
|
||||
/* This is for AmigaOS4.0. */
|
||||
# if !defined getpagesize && defined __amigaos4__
|
||||
# define getpagesize() 2048
|
||||
# endif
|
||||
/* This is for older Unix systems. */
|
||||
# if !defined getpagesize && 0
|
||||
# include <sys/param.h>
|
||||
# ifdef EXEC_PAGESIZE
|
||||
# define getpagesize() EXEC_PAGESIZE
|
||||
# else
|
||||
# ifdef NBPG
|
||||
# ifndef CLSIZE
|
||||
# define CLSIZE 1
|
||||
# endif
|
||||
# define getpagesize() (NBPG * CLSIZE)
|
||||
# else
|
||||
# ifdef NBPC
|
||||
# define getpagesize() NBPC
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getpagesize
|
||||
# define getpagesize() \
|
||||
(GL_LINK_WARNING ("getpagesize is unportable - " \
|
||||
"use gnulib module getpagesize for portability"), \
|
||||
getpagesize ())
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if !1
|
||||
/* Return the next valid login shell on the system, or NULL when the end of
|
||||
the list has been reached. */
|
||||
extern char *getusershell (void);
|
||||
/* Rewind to pointer that is advanced at each getusershell() call. */
|
||||
extern void setusershell (void);
|
||||
/* Free the pointer that is advanced at each getusershell() call and
|
||||
associated resources. */
|
||||
extern void endusershell (void);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getusershell
|
||||
# define getusershell() \
|
||||
(GL_LINK_WARNING ("getusershell is unportable - " \
|
||||
"use gnulib module getusershell for portability"), \
|
||||
getusershell ())
|
||||
# undef setusershell
|
||||
# define setusershell() \
|
||||
(GL_LINK_WARNING ("setusershell is unportable - " \
|
||||
"use gnulib module getusershell for portability"), \
|
||||
setusershell ())
|
||||
# undef endusershell
|
||||
# define endusershell() \
|
||||
(GL_LINK_WARNING ("endusershell is unportable - " \
|
||||
"use gnulib module getusershell for portability"), \
|
||||
endusershell ())
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
|
||||
to GID (if GID is not -1). Do not follow symbolic links.
|
||||
Return 0 if successful, otherwise -1 and errno set.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/lchown.html>. */
|
||||
# define lchown rpl_lchown
|
||||
extern int lchown (char const *file, uid_t owner, gid_t group);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef lchown
|
||||
# define lchown(f,u,g) \
|
||||
(GL_LINK_WARNING ("lchown is unportable to pre-POSIX.1-2001 " \
|
||||
"systems - use gnulib module lchown for portability"), \
|
||||
lchown (f, u, g))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
/* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END.
|
||||
Return the new offset if successful, otherwise -1 and errno set.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/lseek.html>. */
|
||||
# define lseek rpl_lseek
|
||||
extern off_t lseek (int fd, off_t offset, int whence);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef lseek
|
||||
# define lseek(f,o,w) \
|
||||
(GL_LINK_WARNING ("lseek does not fail with ESPIPE on pipes on some " \
|
||||
"systems - use gnulib module lseek for portability"), \
|
||||
lseek (f, o, w))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Read the contents of the symbolic link FILE and place the first BUFSIZE
|
||||
bytes of it into BUF. Return the number of bytes placed into BUF if
|
||||
successful, otherwise -1 and errno set.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/readlink.html>. */
|
||||
# if !1
|
||||
# include <stddef.h>
|
||||
extern int readlink (const char *file, char *buf, size_t bufsize);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef readlink
|
||||
# define readlink(f,b,s) \
|
||||
(GL_LINK_WARNING ("readlink is unportable - " \
|
||||
"use gnulib module readlink for portability"), \
|
||||
readlink (f, b, s))
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/* Pause the execution of the current thread for N seconds.
|
||||
Returns the number of seconds left to sleep.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/sleep.html>. */
|
||||
# if !1
|
||||
extern unsigned int sleep (unsigned int n);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef sleep
|
||||
# define sleep(n) \
|
||||
(GL_LINK_WARNING ("sleep is unportable - " \
|
||||
"use gnulib module sleep for portability"), \
|
||||
sleep (n))
|
||||
#endif
|
||||
|
||||
|
||||
#if 1 && 0 && 0
|
||||
/* Write up to COUNT bytes starting at BUF to file descriptor FD.
|
||||
See the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/write.html>. */
|
||||
# undef write
|
||||
# define write rpl_write
|
||||
extern ssize_t write (int fd, const void *buf, size_t count);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FCHDIR_REPLACEMENT
|
||||
/* gnulib internal function. */
|
||||
extern void _gl_unregister_fd (int fd);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _GL_UNISTD_H */
|
||||
#endif /* _GL_UNISTD_H */
|
|
@ -35,6 +35,7 @@
|
|||
#endif
|
||||
|
||||
/* mingw fails to declare _exit in <unistd.h>. */
|
||||
/* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */
|
||||
#include <stdlib.h>
|
||||
|
||||
#if @GNULIB_WRITE@ && @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@
|
||||
|
|
191
lib/wchar.in.h
191
lib/wchar.in.h
|
@ -68,6 +68,197 @@ extern "C" {
|
|||
/* Define wint_t. (Also done in wctype.in.h.) */
|
||||
#if !@HAVE_WINT_T@ && !defined wint_t
|
||||
# define wint_t int
|
||||
# ifndef WEOF
|
||||
# define WEOF -1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Override mbstate_t if it is too small.
|
||||
On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for
|
||||
implementing mbrtowc for encodings like UTF-8. */
|
||||
#if !(@HAVE_MBSINIT@ && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@
|
||||
typedef int rpl_mbstate_t;
|
||||
# undef mbstate_t
|
||||
# define mbstate_t rpl_mbstate_t
|
||||
# define GNULIB_defined_mbstate_t 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a single-byte character to a wide character. */
|
||||
#if @GNULIB_BTOWC@
|
||||
# if @REPLACE_BTOWC@
|
||||
# undef btowc
|
||||
# define btowc rpl_btowc
|
||||
# endif
|
||||
# if !@HAVE_BTOWC@ || @REPLACE_BTOWC@
|
||||
extern wint_t btowc (int c);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef btowc
|
||||
# define btowc(c) \
|
||||
(GL_LINK_WARNING ("btowc is unportable - " \
|
||||
"use gnulib module btowc for portability"), \
|
||||
btowc (c))
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a wide character to a single-byte character. */
|
||||
#if @GNULIB_WCTOB@
|
||||
# if @REPLACE_WCTOB@
|
||||
# undef wctob
|
||||
# define wctob rpl_wctob
|
||||
# endif
|
||||
# if (!defined wctob && !@HAVE_DECL_WCTOB@) || @REPLACE_WCTOB@
|
||||
/* wctob is provided by gnulib, or wctob exists but is not declared. */
|
||||
extern int wctob (wint_t wc);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef wctob
|
||||
# define wctob(w) \
|
||||
(GL_LINK_WARNING ("wctob is unportable - " \
|
||||
"use gnulib module wctob for portability"), \
|
||||
wctob (w))
|
||||
#endif
|
||||
|
||||
|
||||
/* Test whether *PS is in the initial state. */
|
||||
#if @GNULIB_MBSINIT@
|
||||
# if @REPLACE_MBSINIT@
|
||||
# undef mbsinit
|
||||
# define mbsinit rpl_mbsinit
|
||||
# endif
|
||||
# if !@HAVE_MBSINIT@ || @REPLACE_MBSINIT@
|
||||
extern int mbsinit (const mbstate_t *ps);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef mbsinit
|
||||
# define mbsinit(p) \
|
||||
(GL_LINK_WARNING ("mbsinit is unportable - " \
|
||||
"use gnulib module mbsinit for portability"), \
|
||||
mbsinit (p))
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a multibyte character to a wide character. */
|
||||
#if @GNULIB_MBRTOWC@
|
||||
# if @REPLACE_MBRTOWC@
|
||||
# undef mbrtowc
|
||||
# define mbrtowc rpl_mbrtowc
|
||||
# endif
|
||||
# if !@HAVE_MBRTOWC@ || @REPLACE_MBRTOWC@
|
||||
extern size_t mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef mbrtowc
|
||||
# define mbrtowc(w,s,n,p) \
|
||||
(GL_LINK_WARNING ("mbrtowc is unportable - " \
|
||||
"use gnulib module mbrtowc for portability"), \
|
||||
mbrtowc (w, s, n, p))
|
||||
#endif
|
||||
|
||||
|
||||
/* Recognize a multibyte character. */
|
||||
#if @GNULIB_MBRLEN@
|
||||
# if @REPLACE_MBRLEN@
|
||||
# undef mbrlen
|
||||
# define mbrlen rpl_mbrlen
|
||||
# endif
|
||||
# if !@HAVE_MBRLEN@ || @REPLACE_MBRLEN@
|
||||
extern size_t mbrlen (const char *s, size_t n, mbstate_t *ps);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef mbrlen
|
||||
# define mbrlen(s,n,p) \
|
||||
(GL_LINK_WARNING ("mbrlen is unportable - " \
|
||||
"use gnulib module mbrlen for portability"), \
|
||||
mbrlen (s, n, p))
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a string to a wide string. */
|
||||
#if @GNULIB_MBSRTOWCS@
|
||||
# if @REPLACE_MBSRTOWCS@
|
||||
# undef mbsrtowcs
|
||||
# define mbsrtowcs rpl_mbsrtowcs
|
||||
# endif
|
||||
# if !@HAVE_MBSRTOWCS@ || @REPLACE_MBSRTOWCS@
|
||||
extern size_t mbsrtowcs (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef mbsrtowcs
|
||||
# define mbsrtowcs(d,s,l,p) \
|
||||
(GL_LINK_WARNING ("mbsrtowcs is unportable - " \
|
||||
"use gnulib module mbsrtowcs for portability"), \
|
||||
mbsrtowcs (d, s, l, p))
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a string to a wide string. */
|
||||
#if @GNULIB_MBSNRTOWCS@
|
||||
# if @REPLACE_MBSNRTOWCS@
|
||||
# undef mbsnrtowcs
|
||||
# define mbsnrtowcs rpl_mbsnrtowcs
|
||||
# endif
|
||||
# if !@HAVE_MBSNRTOWCS@ || @REPLACE_MBSNRTOWCS@
|
||||
extern size_t mbsnrtowcs (wchar_t *dest, const char **srcp, size_t srclen, size_t len, mbstate_t *ps);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef mbsnrtowcs
|
||||
# define mbsnrtowcs(d,s,n,l,p) \
|
||||
(GL_LINK_WARNING ("mbsnrtowcs is unportable - " \
|
||||
"use gnulib module mbsnrtowcs for portability"), \
|
||||
mbsnrtowcs (d, s, n, l, p))
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a wide character to a multibyte character. */
|
||||
#if @GNULIB_WCRTOMB@
|
||||
# if @REPLACE_WCRTOMB@
|
||||
# undef wcrtomb
|
||||
# define wcrtomb rpl_wcrtomb
|
||||
# endif
|
||||
# if !@HAVE_WCRTOMB@ || @REPLACE_WCRTOMB@
|
||||
extern size_t wcrtomb (char *s, wchar_t wc, mbstate_t *ps);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef wcrtomb
|
||||
# define wcrtomb(s,w,p) \
|
||||
(GL_LINK_WARNING ("wcrtomb is unportable - " \
|
||||
"use gnulib module wcrtomb for portability"), \
|
||||
wcrtomb (s, w, p))
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a wide string to a string. */
|
||||
#if @GNULIB_WCSRTOMBS@
|
||||
# if @REPLACE_WCSRTOMBS@
|
||||
# undef wcsrtombs
|
||||
# define wcsrtombs rpl_wcsrtombs
|
||||
# endif
|
||||
# if !@HAVE_WCSRTOMBS@ || @REPLACE_WCSRTOMBS@
|
||||
extern size_t wcsrtombs (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef wcsrtombs
|
||||
# define wcsrtombs(d,s,l,p) \
|
||||
(GL_LINK_WARNING ("wcsrtombs is unportable - " \
|
||||
"use gnulib module wcsrtombs for portability"), \
|
||||
wcsrtombs (d, s, l, p))
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert a wide string to a string. */
|
||||
#if @GNULIB_WCSNRTOMBS@
|
||||
# if !@HAVE_WCSNRTOMBS@
|
||||
extern size_t wcsnrtombs (char *dest, const wchar_t **srcp, size_t srclen, size_t len, mbstate_t *ps);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef wcsnrtombs
|
||||
# define wcsnrtombs(d,s,n,l,p) \
|
||||
(GL_LINK_WARNING ("wcsnrtombs is unportable - " \
|
||||
"use gnulib module wcsnrtombs for portability"), \
|
||||
wcsnrtombs (d, s, n, l, p))
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,499 +0,0 @@
|
|||
/* alloca.c -- allocate automatically reclaimed memory
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
This implementation of the PWB library alloca function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||
|
||||
There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "libguile/scmconfig.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "libguile/blockinput.h"
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
/* If someone has defined alloca as a macro,
|
||||
there must be some other way alloca is supposed to work. */
|
||||
#ifndef alloca
|
||||
|
||||
#ifdef emacs
|
||||
#ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
#ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc ();
|
||||
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
#else
|
||||
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
typedef void *pointer;
|
||||
#else
|
||||
typedef char *pointer;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
#ifndef STACK_DIRECTION
|
||||
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
#endif
|
||||
|
||||
#if STACK_DIRECTION != 0
|
||||
|
||||
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction ()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
|
||||
/* Return a pointer to at least SIZE bytes of storage,
|
||||
which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca. Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
pointer
|
||||
alloca (unsigned size)
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
#endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
}
|
||||
else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
#ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = (pointer) scm_malloc (sizeof (header) + size);
|
||||
/* Address of header. */
|
||||
|
||||
if (new == 0)
|
||||
{
|
||||
write (2, "alloca emulation: out of memory\n", 32);
|
||||
abort();
|
||||
}
|
||||
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *) new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer) ((char *) new + sizeof (header));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef CRAY_STACK
|
||||
#define CRAY_STACK
|
||||
#ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
the high-address end of a stack segment. (The stack
|
||||
grows from low addresses to high addresses.) The initial
|
||||
part of the stack segment linkage control information is
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
|
||||
#else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
|
||||
#endif /* CRAY2 */
|
||||
#endif /* not CRAY_STACK */
|
||||
|
||||
#ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc (long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
|
||||
STKSTAT (&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort ();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0)
|
||||
{
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
#else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc (long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END ();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl))
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
#endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
|
||||
while (pseg != 0)
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||
#endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
#endif /* not CRAY2 */
|
||||
#endif /* CRAY */
|
||||
|
||||
#endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "gnu"
|
||||
End:
|
||||
*/
|
10
m4/.gitignore
vendored
10
m4/.gitignore
vendored
|
@ -1,2 +1,12 @@
|
|||
/libtool.m4
|
||||
/lt*.m4
|
||||
/codeset.m4
|
||||
/glibc21.m4
|
||||
/gnulib-comp.m4
|
||||
/localcharset.m4
|
||||
/locale-fr.m4
|
||||
/locale-ja.m4
|
||||
/locale-zh.m4
|
||||
/mbrlen.m4
|
||||
/mbrtowc.m4
|
||||
/mbsinit.m4
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# serial 5 -*- Autoconf -*-
|
||||
# serial 6 -*- Autoconf -*-
|
||||
# Enable extensions on systems that normally disable them.
|
||||
|
||||
# Copyright (C) 2003, 2006-2008 Free Software Foundation, Inc.
|
||||
|
@ -24,6 +24,8 @@ AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS],
|
|||
[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl
|
||||
AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
|
||||
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
|
||||
AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=])
|
||||
if test "$MINIX" = yes; then
|
||||
AC_DEFINE([_POSIX_SOURCE], [1],
|
||||
|
@ -36,6 +38,16 @@ AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
|
|||
[Define to 1 if on MINIX.])
|
||||
fi
|
||||
|
||||
dnl HP-UX 11.11 defines mbstate_t only if _XOPEN_SOURCE is defined to 500,
|
||||
dnl regardless of whether the flags -Ae or _D_HPUX_SOURCE=1 are already
|
||||
dnl provided.
|
||||
case "$host_os" in
|
||||
hpux*)
|
||||
AC_DEFINE([_XOPEN_SOURCE], [500],
|
||||
[Define to 500 only on HP-UX.])
|
||||
;;
|
||||
esac
|
||||
|
||||
AH_VERBATIM([__EXTENSIONS__],
|
||||
[/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2002-2008 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software, distributed under the terms of the GNU
|
||||
# General Public License. As a special exception to the GNU General
|
||||
|
@ -15,12 +15,12 @@
|
|||
|
||||
|
||||
# Specification in the form of a command-line invocation:
|
||||
# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl alloca autobuild count-one-bits extensions full-read full-write strcase strftime
|
||||
# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl alloca-opt autobuild count-one-bits extensions full-read full-write strcase strftime
|
||||
|
||||
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
||||
gl_LOCAL_DIR([])
|
||||
gl_MODULES([
|
||||
alloca
|
||||
alloca-opt
|
||||
autobuild
|
||||
count-one-bits
|
||||
extensions
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# DO NOT EDIT! GENERATED AUTOMATICALLY!
|
||||
# Copyright (C) 2002-2008 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software, distributed under the terms of the GNU
|
||||
# General Public License. As a special exception to the GNU General
|
||||
|
@ -42,13 +42,18 @@ AC_DEFUN([gl_INIT],
|
|||
m4_pushdef([gl_LIBSOURCES_DIR], [])
|
||||
gl_COMMON
|
||||
gl_source_base='lib'
|
||||
changequote(,)dnl
|
||||
LTALLOCA=`echo "$ALLOCA" | sed 's/\.[^.]* /.lo /g;s/\.[^.]*$/.lo/'`
|
||||
changequote([, ])dnl
|
||||
AC_SUBST([LTALLOCA])
|
||||
gl_FUNC_ALLOCA
|
||||
gl_COUNT_ONE_BITS
|
||||
gl_INLINE
|
||||
gl_LOCALCHARSET
|
||||
LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(top_builddir)/$gl_source_base\""
|
||||
AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])
|
||||
gl_FUNC_MBRLEN
|
||||
gl_WCHAR_MODULE_INDICATOR([mbrlen])
|
||||
gl_FUNC_MBRTOWC
|
||||
gl_WCHAR_MODULE_INDICATOR([mbrtowc])
|
||||
gl_FUNC_MBSINIT
|
||||
gl_WCHAR_MODULE_INDICATOR([mbsinit])
|
||||
gl_SAFE_READ
|
||||
gl_SAFE_WRITE
|
||||
gt_TYPE_SSIZE_T
|
||||
|
@ -191,19 +196,27 @@ AC_DEFUN([gltests_LIBSOURCES], [
|
|||
# gnulib-tool and may be removed by future gnulib-tool invocations.
|
||||
AC_DEFUN([gl_FILE_LIST], [
|
||||
build-aux/link-warning.h
|
||||
lib/alloca.c
|
||||
lib/alloca.in.h
|
||||
lib/config.charset
|
||||
lib/count-one-bits.h
|
||||
lib/full-read.c
|
||||
lib/full-read.h
|
||||
lib/full-write.c
|
||||
lib/full-write.h
|
||||
lib/localcharset.c
|
||||
lib/localcharset.h
|
||||
lib/mbrlen.c
|
||||
lib/mbrtowc.c
|
||||
lib/mbsinit.c
|
||||
lib/ref-add.sin
|
||||
lib/ref-del.sin
|
||||
lib/safe-read.c
|
||||
lib/safe-read.h
|
||||
lib/safe-write.c
|
||||
lib/safe-write.h
|
||||
lib/stdbool.in.h
|
||||
lib/strcasecmp.c
|
||||
lib/streq.h
|
||||
lib/strftime.c
|
||||
lib/strftime.h
|
||||
lib/strings.in.h
|
||||
|
@ -216,11 +229,20 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/write.c
|
||||
m4/alloca.m4
|
||||
m4/autobuild.m4
|
||||
m4/codeset.m4
|
||||
m4/count-one-bits.m4
|
||||
m4/extensions.m4
|
||||
m4/glibc21.m4
|
||||
m4/gnulib-common.m4
|
||||
m4/include_next.m4
|
||||
m4/inline.m4
|
||||
m4/localcharset.m4
|
||||
m4/locale-fr.m4
|
||||
m4/locale-ja.m4
|
||||
m4/locale-zh.m4
|
||||
m4/mbrlen.m4
|
||||
m4/mbrtowc.m4
|
||||
m4/mbsinit.m4
|
||||
m4/mbstate_t.m4
|
||||
m4/safe-read.m4
|
||||
m4/safe-write.m4
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# mbstate_t.m4 serial 10
|
||||
# mbstate_t.m4 serial 11
|
||||
dnl Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
|
@ -13,7 +13,10 @@ dnl with or without modifications, as long as this notice is preserved.
|
|||
# AC_TYPE_MBSTATE_T
|
||||
# -----------------
|
||||
AC_DEFUN([AC_TYPE_MBSTATE_T],
|
||||
[AC_CACHE_CHECK([for mbstate_t], ac_cv_type_mbstate_t,
|
||||
[
|
||||
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) dnl for HP-UX 11.11
|
||||
|
||||
AC_CACHE_CHECK([for mbstate_t], ac_cv_type_mbstate_t,
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[AC_INCLUDES_DEFAULT[
|
||||
|
@ -27,4 +30,5 @@ AC_DEFUN([AC_TYPE_MBSTATE_T],
|
|||
else
|
||||
AC_DEFINE([mbstate_t], int,
|
||||
[Define to a type if <wchar.h> does not define.])
|
||||
fi])
|
||||
fi
|
||||
])
|
||||
|
|
34
m4/wchar.m4
34
m4/wchar.m4
|
@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
|
|||
|
||||
dnl Written by Eric Blake.
|
||||
|
||||
# wchar.m4 serial 6
|
||||
# wchar.m4 serial 22
|
||||
|
||||
AC_DEFUN([gl_WCHAR_H],
|
||||
[
|
||||
|
@ -61,9 +61,39 @@ AC_DEFUN([gl_WCHAR_MODULE_INDICATOR],
|
|||
|
||||
AC_DEFUN([gl_WCHAR_H_DEFAULTS],
|
||||
[
|
||||
GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH])
|
||||
GNULIB_BTOWC=0; AC_SUBST([GNULIB_BTOWC])
|
||||
GNULIB_WCTOB=0; AC_SUBST([GNULIB_WCTOB])
|
||||
GNULIB_MBSINIT=0; AC_SUBST([GNULIB_MBSINIT])
|
||||
GNULIB_MBRTOWC=0; AC_SUBST([GNULIB_MBRTOWC])
|
||||
GNULIB_MBRLEN=0; AC_SUBST([GNULIB_MBRLEN])
|
||||
GNULIB_MBSRTOWCS=0; AC_SUBST([GNULIB_MBSRTOWCS])
|
||||
GNULIB_MBSNRTOWCS=0; AC_SUBST([GNULIB_MBSNRTOWCS])
|
||||
GNULIB_WCRTOMB=0; AC_SUBST([GNULIB_WCRTOMB])
|
||||
GNULIB_WCSRTOMBS=0; AC_SUBST([GNULIB_WCSRTOMBS])
|
||||
GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS])
|
||||
GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH])
|
||||
dnl Assume proper GNU behavior unless another module says otherwise.
|
||||
HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC])
|
||||
HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT])
|
||||
HAVE_MBRTOWC=1; AC_SUBST([HAVE_MBRTOWC])
|
||||
HAVE_MBRLEN=1; AC_SUBST([HAVE_MBRLEN])
|
||||
HAVE_MBSRTOWCS=1; AC_SUBST([HAVE_MBSRTOWCS])
|
||||
HAVE_MBSNRTOWCS=1; AC_SUBST([HAVE_MBSNRTOWCS])
|
||||
HAVE_WCRTOMB=1; AC_SUBST([HAVE_WCRTOMB])
|
||||
HAVE_WCSRTOMBS=1; AC_SUBST([HAVE_WCSRTOMBS])
|
||||
HAVE_WCSNRTOMBS=1; AC_SUBST([HAVE_WCSNRTOMBS])
|
||||
HAVE_DECL_WCTOB=1; AC_SUBST([HAVE_DECL_WCTOB])
|
||||
HAVE_DECL_WCWIDTH=1; AC_SUBST([HAVE_DECL_WCWIDTH])
|
||||
REPLACE_MBSTATE_T=0; AC_SUBST([REPLACE_MBSTATE_T])
|
||||
REPLACE_BTOWC=0; AC_SUBST([REPLACE_BTOWC])
|
||||
REPLACE_WCTOB=0; AC_SUBST([REPLACE_WCTOB])
|
||||
REPLACE_MBSINIT=0; AC_SUBST([REPLACE_MBSINIT])
|
||||
REPLACE_MBRTOWC=0; AC_SUBST([REPLACE_MBRTOWC])
|
||||
REPLACE_MBRLEN=0; AC_SUBST([REPLACE_MBRLEN])
|
||||
REPLACE_MBSRTOWCS=0; AC_SUBST([REPLACE_MBSRTOWCS])
|
||||
REPLACE_MBSNRTOWCS=0;AC_SUBST([REPLACE_MBSNRTOWCS])
|
||||
REPLACE_WCRTOMB=0; AC_SUBST([REPLACE_WCRTOMB])
|
||||
REPLACE_WCSRTOMBS=0; AC_SUBST([REPLACE_WCSRTOMBS])
|
||||
REPLACE_WCWIDTH=0; AC_SUBST([REPLACE_WCWIDTH])
|
||||
WCHAR_H=''; AC_SUBST([WCHAR_H])
|
||||
])
|
||||
|
|
10
m4/wint_t.m4
10
m4/wint_t.m4
|
@ -1,5 +1,5 @@
|
|||
# wint_t.m4 serial 2 (gettext-0.17)
|
||||
dnl Copyright (C) 2003, 2007 Free Software Foundation, Inc.
|
||||
# wint_t.m4 serial 3 (gettext-0.18)
|
||||
dnl Copyright (C) 2003, 2007-2008 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
@ -10,7 +10,7 @@ dnl Prerequisite: AC_PROG_CC
|
|||
|
||||
AC_DEFUN([gt_TYPE_WINT_T],
|
||||
[
|
||||
AC_CACHE_CHECK([for wint_t], gt_cv_c_wint_t,
|
||||
AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t],
|
||||
[AC_TRY_COMPILE([
|
||||
/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
|
||||
<wchar.h>.
|
||||
|
@ -21,8 +21,8 @@ AC_DEFUN([gt_TYPE_WINT_T],
|
|||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
wint_t foo = (wchar_t)'\0';], ,
|
||||
gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)])
|
||||
[gt_cv_c_wint_t=yes], [gt_cv_c_wint_t=no])])
|
||||
if test $gt_cv_c_wint_t = yes; then
|
||||
AC_DEFINE(HAVE_WINT_T, 1, [Define if you have the 'wint_t' type.])
|
||||
AC_DEFINE([HAVE_WINT_T], 1, [Define if you have the 'wint_t' type.])
|
||||
fi
|
||||
])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue