On Thu, Mar 13, 2014 at 12:44:44PM +0100, pluijzer . wrote: > I am assigning non-immediate objects to foreign void pointers. To > prevent them from moving during garbage collection I turn the pointer > into a gc-root. > > This works like I expect it would work, with one exception: > > It seems that the finalizers of the objects assigned to the objects > inside the gc-root get fired prematurely. > > I think I'm a little difficult to follow, I'll give an example: > > ---- > #> > void* ptr; > <# > > (define init-root > (foreign-lambda* void ((scheme-object obj)) " > ptr = CHICKEN_new_gc_root(); > CHICKEN_gc_root_set(ptr, obj);")) > > (define root-ref > (foreign-lambda* scheme-object () " > C_return(CHICKEN_gc_root_ref(ptr));")) > > (define (make-some-string) > (set-finalizer! "hello" (lambda (s) (print s ", just got freed.")))) > > (define-record metadata > data) > > (init-root (make-metadata (make-some-string))) > > ; prints "hello" > (print (metadata-data (root-ref))) > > ; will fire finalizer printing "hello, just got freed." > ; I didn't expect this because there is still a refrence to the object > inside the root. > (gc #t) > > ; prints "hello", object seems to still be around. > (print (metadata-data (root-ref))) > --- > > Maybe I don't understand gc-roots and use them wrongly or for the > wrong purpose. If so, would somebody kindly explain.
Hello Pluijzer, I had a look at the GC again, and from what I can make of it, this happens only for constants (objects that do not live in the stack or heap). Those don't get marked, so they appear to be dead (the GC root has no effect on this). I'm not sure if this is by design, and if this is a bug or not. This is probably slightly wrong. I've CCed Felix, maybe he can shed some light on this. The compiler will optimize away some calls to pure functions and replace them by a constant at compile-time, which means even some seemingly dynamically-allocated objects will trigger this. You can see this in action with the following simplified program: ----- (define foobar (let ((x (string-append "some" " string"))) (set-finalizer! x (lambda (s) (print s ", just got freed."))))) ; With -O1 or more, will fire finalizer printing "some string, just got freed." (gc #t) ; prints "some string", object is still around. (print foobar) ----- If you compile the above program with -O0, it will only print "some string", because the string-append call doesn't get optimized away to a constant. With -O1, it does get replaced and the GC sees it as being available (this shows up as "folded constant expression" when you use csc -debug o). Now, in most normal code this won't be a problem because it only makes sense to put finalizers on objects that need special destruction logic, which don't tend to be constant-foldable. Cheers, Peter -- http://www.more-magic.net _______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users