1 ; File: "mem.scm", Time-stamp: <2009-05-14 14:21:50 feeley>
3 ; Copyright (c) 1996-2009 by Marc Feeley, All Rights Reserved.
5 ; Test program for Gambit-C's memory management system.
7 ;------------------------------------------------------------------------------
11 ; pseudo-random number generator
15 (define (reset-random)
16 (set! seed 1923202963))
19 (let* ((hi (quotient seed 44488))
20 (lo (remainder seed 44488))
21 (test (- (* lo 48271) (* hi 3399))))
22 (set! seed (if (> test 0) test (+ test 2147483647)))
25 ; repetition of an evaluation
27 (define (repeat n thunk)
34 (define gc-reports? #t)
36 (define (setup-gc-reports)
37 (gc-report-set! gc-reports?))
42 ;------------------------------------------------------------------------------
46 ; Allocate and deallocate medium size objects and large objects. The
47 ; GC reports show that movable and non-movable objects are allocated
59 (v (make-vector n #f)))
65 (size (if (= 0 (random 2)) 1000 35000)))
66 (vector-set! v i (make-vector size))))))
70 ;------------------------------------------------------------------------------
74 ; Allocate and deallocate medium size objects and large objects. The
75 ; GC reports show that movable and non-movable objects are allocated
88 ; allocate roughly 1 MB of data
94 (cons (make-vector (if (= 0 (random 2)) 1000 35000))
99 ; release roughly .5 MB of data
104 (set! test2-data (cdr test2-data))))
108 ; allocate roughly 1 MB more
114 (cons (make-vector (if (= 0 (random 2)) 1000 35000))
125 (define test2-data #f)
131 (make-vector (if (= 0 (random 2)) 1000 35000))
134 ;------------------------------------------------------------------------------
138 ; Show how to recover from heap overflows.
140 ; Note: make sure you specify a heap size limit when you start the
141 ; compiler or interpreter, otherwise it may take a long time before
142 ; the virtual memory is exhausted.
149 (test3-helper 10) ; this call should terminate normally
150 (test3-helper 1000000) ; this one will cause a heap overflow
151 (test3-helper 10) ; this call should terminate normally
154 (define (test3-helper n)
157 (call-with-current-continuation
159 (with-exception-handler
163 (trigger-gc) ; clean up heap and recover overflow reserve
164 (display "caught exception ")
168 (let ((data (create-big-set-of-data n)))
171 (write (map vector? data))
175 (define (create-big-set-of-data n)
176 (let loop ((lst '()) (i n))
179 (cons (case (random 6)
180 ((0) (make-string (random 80000)))
181 ((1) (make-vector (random 40000)))
184 ((4) (lambda (x) lst))
185 (else (* 1.23 (random 100))))
190 ;------------------------------------------------------------------------------
194 ; Show how to recover from stack overflows.
196 ; Note: make sure you specify a heap size limit when you start the
197 ; compiler or interpreter, otherwise it may take a long time before
198 ; the virtual memory is exhausted.
205 (test4-helper 10) ; this call should terminate normally
206 (test4-helper 1000000) ; this one will cause a heap overflow
207 (test4-helper 10) ; this call should terminate normally
210 (define (test4-helper n)
213 (call-with-current-continuation
215 (with-exception-handler
219 (trigger-gc) ; clean up heap and recover overflow reserve
220 (display "caught exception ")
224 (let ((data (deeply-nested-computation n)))
227 (write (map even? data))
231 (define (deeply-nested-computation n)
233 (cons n (deeply-nested-computation (- n 1)))
236 ;------------------------------------------------------------------------------
240 ; Allocation of Scheme objects from C.
246 static ___SCMOBJ obj1, obj2, obj3, obj4, obj5; /* some Scheme objects */
248 void foo (double x, int n, int (*f)(char*))
250 ___EXT(___DOUBLE_to_SCMOBJ) (___CLIBEXT(sqrt) (x), &obj1, 0);
251 obj2 = ___EXT(___make_vector) (n, obj1, ___STILL);
252 ___EXT(___CHARSTRING_to_SCMOBJ) (\"hello world!\", &obj3, 0);
253 ___EXT(___CHARSTRING_to_SCMOBJ) (\"another string\", &obj4, 0);
254 obj5 = ___EXT(___make_pair) (obj2, obj3, ___STILL);
255 ___EXT(___still_obj_refcount_dec) (obj1); /* no direct need for obj1, etc */
256 ___EXT(___still_obj_refcount_dec) (obj2);
257 ___EXT(___still_obj_refcount_dec) (obj3);
258 f (\"was called from C\");
268 ___EXT(___still_obj_refcount_dec) (obj5);
273 (c-define-type real double)
274 (c-define-type integer int)
276 (define foo (c-lambda (real integer (function (char-string) int)) void "foo"))
277 (define bar (c-lambda () scheme-object "bar"))
278 (define baz (c-lambda () scheme-object "baz"))
280 (c-define (hop str) (char-string) int "hop" ""
281 (write (list 'hop str))
291 (hop "was called from Scheme")
294 (declare (standard-bindings) (not safe) (flonum)) ; inline "sqrt"
295 (foo (sqrt (##first-argument .0625)) 5 hop)) ; create objects from C
297 (trigger-gc) ; they will show up as "not movable" objects in the GC report
299 (let ((x (bar))) ; get obj4 from C
301 (trigger-gc) ; no problem if a GC happens here
315 (trigger-gc)) ; at this point, only obj4 is not reclaimed (because refcount != 0)
317 ;------------------------------------------------------------------------------
333 (v (make-vector n #f))
342 (make-string (random 10)))
344 (make-vector (random 10) x))
352 (make-will (cons x x) (lambda (o) #f)))
355 (set! expect (+ expect id))
357 (make-will (make-vector (random 40000))
358 (lambda (o) (set! result (+ result id))))))
360 (+ 1.23 (random 100))))))
362 (make-will obj (lambda (o) #f))
364 (set! expect (+ expect id))
367 (lambda (o) (set! result (+ result id))))))
373 (let ((i (random n)))
374 (vector-set! v i (new (vector-ref v (random n)))))))
391 ;------------------------------------------------------------------------------
399 (define (printer name)
401 (display "===> calling the action procedure for object ")
408 (display "--------------------------------------- GC")
412 (let* ((obj1 (list 'obj1))
415 (obj4 (list 'obj4 (make-will (list 'obj4) (lambda (o) #f))))
416 (obj5 (list 'obj5 (make-will (list 'obj5) (lambda (o) #f))))
417 (obj6 (list 'obj6 (make-will (list 'obj6) (lambda (o) #f))))
418 (obj7 (list 'obj7 (make-will (list 'obj7) (lambda (o) #f))))
419 (obj8 (list 'obj8 (make-will (list 'obj8) (lambda (o) #f))))
420 (obj9 (vector 1 2 3 4 5)))
422 (let* ((will1 (make-will obj1 (lambda (o) #f)))
423 (will2 (make-will obj2 (printer 'obj2)))
424 (will3 (make-will obj3 (lambda (o) #f)))
425 (will4 (make-will obj4 (printer 'obj4)))
426 (will5 (make-will obj5 (lambda (o) #f)))
427 (will6 (make-will obj6 (printer 'obj6)))
428 (will7 (make-will obj7 (lambda (o) #f)))
429 (will8 (make-will obj8 (printer 'obj8))))
431 (define (print-testators)
433 (define (print name will)
434 (display "(will-testator ")
437 (write (will-testator will))
447 (print 'will8 will8))
452 (lambda (o) (p o) (set! obj9 o)))) ; resurect object
496 (let* ((a (cons 11 22))
501 (pretty-print (list 'executing-will 'a x)))))))
504 (pretty-print (list 'executing-will 'b))))
512 ;------------------------------------------------------------------------------
515 (set! gc-reports? #f)
523 (pretty-print 'all-tests-done))