"Simon Marlow" <[EMAIL PROTECTED]> writes: > Nice trick. Unfortunately the same assumptions don't hold for GHC's > garbage collector - objects are aged in the youngest generation, so > it is usually at least two GCs before an object is promoted. We > could still do the same trick, but instead we'd have to find maximum > stack depth at which all objects below are in an older generation.
I don't know how to do it under these assumptions, i.e. how to find that depth. > Incedentally, how do you mark the stack depth? Overwrite a return > address with a special one, and keep the real one around in a known > place? This is the first thing I tried :-) and even implemented it before I realized that it doesn't work under my assumptions. The problem is that I pass the return address in a virtual register, and it's saved on the stack by the callee only if it performs some non-tail calls. The return address is saved at the end of the stack frame. This means that a tail call followed by a non-tail call might read the special return address from the stack, but without jumping through it immediately. This return address is put again on the stack by a different function, with a possibly different stack frame size, so it lands in a different position on the stack, and thus it can't be found when GC wants to restore it. While changing the stack frame layout could perhaps make this workable, I found a much simpler solution. Since forever each stack frame contained a pointer used only by the GC and by stack trace printing. It points to a static structure containing the frame size and return address -> source location mapping. This pointer is now marked in the lowest bit by the GC. Pushing a fresh stack frame always puts an even pointer. BTW, a few days earlier I fixed a similar behavior for extensible arrays. Most mutable objects use a write barrier which stores changed locations, but arrays store references to changed objects because their payload is malloced and may be reallocated without a GC. This meant that code which repeatedly appends to a given array has O(N^2) complexity for huge arrays, as each GC scans the whole array. So I now store the size of the initial part of the array which is known to be unchanged since last GC. This is updated manually by particular operations. -- __("< Marcin Kowalczyk \__/ [EMAIL PROTECTED] ^^ http://qrnik.knm.org.pl/~qrczak/ _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users