-
Simon Marlow authored
Fix the large block allocation bug (Yay!) ----------------------------------------- In order to do this, I had to 1. in each heap-check failure branch, return the amount of heap actually requested, in a known location (I added another slot in StgRegTable called HpAlloc for this purpose). This is useful for other reasons - in particular it makes it possible to get accurate allocation statistics. 2. In the scheduler, if a heap check fails and we wanted more than BLOCK_SIZE_W words, then allocate a special large block and place it in the nursery. The nursery now has to be double-linked so we can insert the new block in the middle. 3. The garbage collector has to be able to deal with multiple objects in a large block. It turns out that this isn't a problem as long as the large blocks only occur in the nursery, because we always copy objects from the nursery during GC. One small change had to be made: in evacuate(), we may need to follow the link field from the block descriptor to get to the block descriptor for the head of a large block. 4. Various other parts of the storage manager had to be modified to cope with a nursery containing a mixture of block sizes. Point (3) causes a slight pessimization in the garbage collector. I don't see a way to avoid this. Point (1) causes some code bloat (a rough measurement is around 5%), so to offset this I made the following change which I'd been meaning to do for some time: - Store the values of some commonly-used absolute addresses (eg. stg_update_PAP) in the register table. This lets us use shorter instruction forms for some absolute jumps and saves some code space. - The type of Capability is no longer the same as an StgRegTable. MainRegTable renamed to MainCapability. See Regs.h for details. Other minor changes: - remove individual declarations for the heap-check-failure jump points, and declare them all in StgMiscClosures.h instead. Remove HeapStackCheck.h. Updates to the native code generator to follow.
0671ef05