http://d.puremagic.com/issues/show_bug.cgi?id=2927





------- Comment #3 from dsim...@yahoo.com  2009-05-03 12:50 -------
I've submitted patches that implement this feature.  If the BlkAttr.NO_INTERIOR
flag is set, then only pointers to the base address of a GC-allocated block can
keep that block alive.  Here's a small test program demonstrating how this
works:

import std.stdio, core.memory;

void main() {
    // Test for < PAGESIZE
    test(32, cast(GC.BlkAttr) 0, 0);
    test(32, cast(GC.BlkAttr) 0, 1);
    test(32, GC.BlkAttr.NO_INTERIOR, 0);
    test(32, GC.BlkAttr.NO_INTERIOR, 1);

    // Test for > PAGESIZE
    enum megabyte = 1024 * 1024;
    test(megabyte, cast(GC.BlkAttr) 0, 0);
    test(megabyte, cast(GC.BlkAttr) 0, 1);
    test(megabyte, GC.BlkAttr.NO_INTERIOR, 0);
    test(megabyte, GC.BlkAttr.NO_INTERIOR, 1);
}

// In this test case, we expect the GC to allocate the same address more than
// once only when NO_INTERIOR is set and we store an interior pointer in ptrs
// instead of a pointer to the root address.
void test(size_t size, GC.BlkAttr attr, uint toAdd) {
    uint[] oldPtrs = new uint[10];
    void*[10] ptrs;
    foreach(i; 0..10) {
        auto ptr = GC.malloc(size, attr);
        ptrs[i] = ptr + toAdd;

        foreach(oldPtr; oldPtrs) {
            if(oldPtr == cast(uint) ptr) {
                writeln("GC re-allocated address ", oldPtr, ".  (Parameters: 
",
                        size, " ", attr, "  ", toAdd, ")");
                return;
            }
        }
        oldPtrs[i] = cast(uint) ptr;
        GC.collect();
    }
}


-- 

Reply via email to