Bring small bitmap gc descriptor back to life.
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 28 Dec 2011 00:08:54 +0000 (22:08 -0200)
committerRodrigo Kumpera <kumpera@gmail.com>
Wed, 28 Dec 2011 00:54:20 +0000 (22:54 -0200)
* sgen-descriptor.h:
* sgen-descriptor.c:
* sgen-scan-object.h: Bring small bitmap back to life.
It covers most cases large bitmap does and can hold size
information.

mono/metadata/sgen-descriptor.c
mono/metadata/sgen-descriptor.h
mono/metadata/sgen-scan-object.h

index c76565791ef7453278eb000db0e37d4658b162ee..15a06269c56bdac7c76d2ff039293a8a5e9003a6 100644 (file)
@@ -164,6 +164,14 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size)
                        return (void*) desc;
                }
        }
+
+       /* we know the 2-word header is ptr-free */
+       if (last_set < SMALL_BITMAP_SIZE + OBJECT_HEADER_WORDS) {
+               desc = DESC_TYPE_SMALL_BITMAP | (stored_size << 1) | ((*bitmap >> OBJECT_HEADER_WORDS) << SMALL_BITMAP_SHIFT);
+               DEBUG (6, fprintf (gc_debug_file, "Smallbitmap descriptor %p, size: %zd, last set: %d\n", (void*)desc, stored_size, last_set));
+               return (void*) desc;
+       }
+
        /* we know the 2-word header is ptr-free */
        if (last_set < LARGE_BITMAP_SIZE + OBJECT_HEADER_WORDS) {
                desc = DESC_TYPE_LARGE_BITMAP | ((*bitmap >> OBJECT_HEADER_WORDS) << LOW_TYPE_BITS);
@@ -235,6 +243,15 @@ mono_gc_get_bitmap_for_descr (void *descr, int *numbits)
 
                return bitmap;
        }
+
+       case DESC_TYPE_SMALL_BITMAP:
+               bitmap = g_new0 (gsize, 1);
+
+               bitmap [0] = (d >> SMALL_BITMAP_SHIFT) << OBJECT_HEADER_WORDS;
+
+               *numbits = GC_BITS_PER_WORD;
+               return bitmap;
+
        case DESC_TYPE_LARGE_BITMAP: {
                gsize bmap = (d >> LOW_TYPE_BITS) << OBJECT_HEADER_WORDS;
 
index 4753e1c2454d467024e71fa22ad3313edecb2e02..71ad9389cac1e8e69259344f0730e075fe9b25cc 100644 (file)
@@ -80,6 +80,7 @@ enum {
         * object's class.
         */
        DESC_TYPE_RUN_LENGTH = 1, /* 15 bits aligned byte size | 1-3 (offset, numptr) bytes tuples */
+       DESC_TYPE_SMALL_BITMAP,   /* 15 bits aligned byte size | 16-48 bit bitmap */
        DESC_TYPE_COMPLEX,      /* index for bitmap into complex_descriptors */
        DESC_TYPE_VECTOR,       /* 10 bits element size | 1 bit array | 2 bits desc | element desc */
        DESC_TYPE_ARRAY,        /* 10 bits element size | 1 bit array | 2 bits desc | element desc */
@@ -128,7 +129,7 @@ MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL
     } while (0)
 
 #define OBJ_BITMAP_SIZE(size,desc,obj) do { \
-               (size) = ((desc) & 0xfff8) >> 1;        \
+               (size) = ((desc) & 0xfff8 >> 1);        \
     } while (0)
 
 #ifdef __GNUC__
@@ -152,6 +153,20 @@ MonoGCRootMarkFunc mono_sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL
                }       \
        } while (0)
 
+#define OBJ_BITMAP_FOREACH_PTR(desc,obj)       do {    \
+               /* there are pointers */        \
+               void **_objptr = (void**)(obj); \
+               gsize _bmap = (desc) >> 16;     \
+               _objptr += OBJECT_HEADER_WORDS; \
+               while (_bmap) { \
+                       if ((_bmap & 1)) {      \
+                               HANDLE_PTR (_objptr, (obj));    \
+                       }       \
+                       _bmap >>= 1;    \
+                       ++_objptr;      \
+                       }       \
+       } while (0)
+
 /* a bitmap desc means that there are pointer references or we'd have
  * choosen run-length, instead: add an assert to check.
  */
index 1f35d4ee0dbc70d16efd1332edb53d18bfa8f55f..50f688158cd4c675d6c37e5f499638c0e50ec135 100644 (file)
        switch (desc & 0x7) {
        case DESC_TYPE_RUN_LENGTH:
 #define SCAN OBJ_RUN_LEN_FOREACH_PTR (desc, start)
+#ifndef SCAN_OBJECT_NOSCAN
+               SCAN;
+#endif
+               SCAN_OBJECT_ACTION;
+#undef SCAN
+               break;
+       case DESC_TYPE_SMALL_BITMAP:
+#define SCAN OBJ_BITMAP_FOREACH_PTR (desc, start)
 #ifndef SCAN_OBJECT_NOSCAN
                SCAN;
 #endif