Oooh. and you documented jhc's RTS while you were at it. that is great :) I have been thinking about a way to extend JGC to seamlessly handle interfaces that utilize stack allocated C structs. The main target being GMP. Right now I can do pretty well by having a 'self-pointing' 'self-cleaning' ForeignPtr. The definition of ForeignPtr is
data ForeginPtr = ForeignPtr Addr_
However, it is a little magic in that you can allocate it in a larger space than it would naturally take up, I can then have Addr_ point to the word following it directly in memory. The garbage collector treats it just like normal and needs no finalizer, as long as the ForeginPtr is live, the area it points to is live since they are the same space, as far as the code is concerned it could be pointing to an external C structure. This is very efficient and a very fast way to throw around C structures without having to worry about whether they were allocated in haskell or in C. However, things like GMP require the memory region to be initialized and freed since it may have internal pointers. I could just continue with standard foreign pointers, attaching a destructor, but this has a couple problems - I have to initialize the memory area, this is hard to do without invoking the IO monad to ensure proper sequencing, for the result of an addition, that seems heavy, it is hard for the complier to "see through" an unsafePerformIO when optimizing. - every Integer will have to carry around two extra words, a self pointer that always points to its own memory location, and a pointer to a destructor that is always going to be the same. - memory will be destructed when it is likely to immediately be re-used as an Integer, it would be good to deforest this destruct-construct pair. To solve both I was thinking of assosciating a contructor/destructor with a type rather than a value. By creating an entire block of the same type, it can initialize the entire block at once, then delay the destructor until the entire block is freed. since GMP ints can be re-used in place, it would get rid of almost all initialization and destruction overhead. A 'delayed destructor' if you will, that only needs to be called if the memory location is going to be used for a different type. Allocations in jhc are already tagged by type so this isn't difficult to keep track of. I was thinking something like data {-# CCONSTRUCTOR "init_integer" #-} {-# CDESTRUCTOR delayed "fini_integer" #-} Integer_ :: # data Integer = Integer Integer_ since Integer_ is unboxed, we can ensure they are only created in the right heap by using a primitive to do so, there is no way for a user to conjure up an unboxed type that doesn't take part in unboxed num polymorphism so can be represented by 0# 1# etc. John On Tue, Jun 10, 2014 at 3:13 AM, Kiwamu Okabe <kiwamu@debian.or.jp> wrote:
Hi jhc-hackers,
I have written a paper "Experience Report: Writing NetBSD Sound Drivers in Haskell".
http://metasepi.org/papers.html
It explains Ajhc customized jhc GC, and sometime useful to develop jhc.
Thank's, -- Kiwamu Okabe at METASEPI DESIGN _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- John Meacham - http://notanumber.net/