diff --git a/tango/core/rt/gc/basic/gcx.d b/tango/core/rt/gc/basic/gcx.d
index 93c8078..6cf7c6f 100644
--- a/tango/core/rt/gc/basic/gcx.d
+++ b/tango/core/rt/gc/basic/gcx.d
@@ -114,6 +114,9 @@ private bool g_scan_precise = true;
 
 private bool use_bitmask(uint bits)
 {
+    //classes carry the bitmask in their ClassInfo!
+    if (bits & BlkAttr.FINALIZE)
+        return false;
     return !(bits & BlkAttr.NO_SCAN) && g_enable_precise;
 }
 
@@ -442,6 +445,9 @@ class GC
                 auto biti = cast(size_t)(p - pool.baseAddr) / 16;
 
                 oldb = gcx.getBits(pool, biti);
+                //don't change the FINALIZE bit - the FINALIZE bit affects
+                //assumptions about the internal memory layout
+                mask = (mask & ~BlkAttr.FINALIZE) | (oldb & BlkAttr.FINALIZE);
                 gcx.setBits(pool, biti, mask);
             }
             return oldb;
@@ -2404,12 +2410,18 @@ struct Gcx
                 pool = pooltable[n];
 
                 auto bbase = pool.scan.base();
+                auto fbase = pool.finals.nbits ? pool.finals.base() : null;
                 auto btop = bbase + pool.scan.nwords;
-                for (auto b = bbase; b < btop;)
+                auto b = bbase;
+                auto f = fbase;
+                for (; b < btop;)
                 {
                     auto bitm = *b;
+                    auto bitf = f ? *f : 0;
                     if (!bitm)
                     {   b++;
+                        if (f)
+                            f++;
                         continue;
                     }
                     *b = 0;
@@ -2418,14 +2430,16 @@ struct Gcx
                     if (!(bitm & 0xFFFF))
                     {
                         bitm >>= 16;
+                        bitf >>= 16;
                         o += 16 * 16;
                     }
                     if (!(bitm & 0xFF))
                     {
                         bitm >>= 8;
+                        bitf >>= 8;
                         o += 8 * 16;
                     }
-                    for (; bitm; o += 16, bitm >>= 1)
+                    for (; bitm; o += 16, bitm >>= 1, bitf >>= 1)
                     {
                         if (!(bitm & 1))
                             continue;
@@ -2452,9 +2466,28 @@ struct Gcx
                             size_t* bitMask = null;
                             if (g_enable_precise)
                             {
-                                size_t bitMaskSize = (size_t*).sizeof;
-                                bitMask = *(cast(size_t**) (o + blockSize - bitMaskSize));
-                                blockSize -= bitMaskSize;
+                                if (!(bitf & 1))
+                                {
+                                    size_t bitMaskSize = (size_t*).sizeof;
+                                    bitMask = *(cast(size_t**) (o + blockSize - bitMaskSize));
+                                    blockSize -= bitMaskSize;
+                                }
+                                else
+                                {
+                                    //special handling for D objects
+                                    //this relies on the fact that BlkAttr.FINALIZE is
+                                    //set if and only if the allocation is a D object
+                                    //(see rt_finalize in lifetime.d)
+                                    Object obj = cast(Object)cast(void*)(o + SENTINEL_PRE);
+                                    ClassInfo ci = obj.classinfo;
+                                    version (D_HavePointerMap) {
+                                        bitMask = ci.pointermap.bits.ptr;
+                                    }
+                                    else
+                                    {
+                                        bitMask = null; //conservative
+                                    }
+                                }
                             }
 
                             debug(PRINTF) printf("Bitmask:  %p\n", bitMask);
