[boehm] Put *_freelists into thread_local_freelists (as in BDWGC v7)
authorIvan Maidanski <ivmai@mail.ru>
Mon, 16 Nov 2015 07:09:55 +0000 (10:09 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 17 Nov 2015 22:05:36 +0000 (01:05 +0300)
Mono create_allocator accesses libgc private *_freelists directly.
These fields have been grouped together into struct
thread_local_freelists in BDWGC v7.
This commit does code refactoring to match the structure of external
GC regarding *_freelists.

 * Move GRANULARITY, NFREELISTS (used by *_freelists) out of
   GC_Thread_Rep.

 * Move ptrfree_freelists, normal_freelists, gcj_freelists from
   GC_Thread_Rep to struct thread_local_freelists.

 * Add tlfs field (of type struct thread_local_freelists) to
   GC_Thread_Rep.

 * Update pthread_support.c and boehm-gc.c code accordingly.

libgc/include/private/pthread_support.h
libgc/pthread_support.c
mono/metadata/boehm-gc.c

index 4046a2666b846d404ddf5edc4aada8945f5a00fd..bcb89b6a1982ab53a0ee338491c61a35997d0ba2 100644 (file)
 
 /* We use the allocation lock to protect thread-related data structures. */
 
+#ifdef THREAD_LOCAL_ALLOC
+#   if CPP_WORDSZ == 64 && defined(ALIGN_DOUBLE)
+#      define GRANULARITY 16
+#      define NFREELISTS 49
+#   else
+#      define GRANULARITY 8
+#      define NFREELISTS 65
+#   endif
+    struct thread_local_freelists {
+       ptr_t ptrfree_freelists[NFREELISTS];
+       ptr_t normal_freelists[NFREELISTS];
+#      ifdef GC_GCJ_SUPPORT
+           ptr_t gcj_freelists[NFREELISTS];
+#      endif
+    };
+#endif
+
 /* The set of all known threads.  We intercept thread creation and     */
 /* joins.                                                              */
 /* Protected by allocation/GC lock.                                    */
@@ -60,23 +77,12 @@ typedef struct GC_Thread_Rep {
                                /* reclamation of any data it might     */
                                /* reference.                           */
 #   ifdef THREAD_LOCAL_ALLOC
-#      if CPP_WORDSZ == 64 && defined(ALIGN_DOUBLE)
-#          define GRANULARITY 16
-#          define NFREELISTS 49
-#      else
-#          define GRANULARITY 8
-#          define NFREELISTS 65
-#      endif
        /* The ith free list corresponds to size i*GRANULARITY */
 #      define INDEX_FROM_BYTES(n) ((ADD_SLOP(n) + GRANULARITY - 1)/GRANULARITY)
 #      define BYTES_FROM_INDEX(i) ((i) * GRANULARITY - EXTRA_BYTES)
 #      define SMALL_ENOUGH(bytes) (ADD_SLOP(bytes) <= \
                                    (NFREELISTS-1)*GRANULARITY)
-       ptr_t ptrfree_freelists[NFREELISTS];
-       ptr_t normal_freelists[NFREELISTS];
-#      ifdef GC_GCJ_SUPPORT
-         ptr_t gcj_freelists[NFREELISTS];
-#      endif
+       struct thread_local_freelists tlfs;
                /* Free lists contain either a pointer or a small count */
                /* reflecting the number of granules allocated at that  */
                /* size.                                                */
index d2fec41c448cfcf972a70d3d46b69355ce9cb95a..623a94e7c8c22fb4c670d9fbff4e12869e087ee9 100644 (file)
@@ -294,17 +294,17 @@ void GC_init_thread_local(GC_thread p)
        ABORT("Failed to set thread specific allocation pointers");
     }
     for (i = 1; i < NFREELISTS; ++i) {
-       p -> ptrfree_freelists[i] = (ptr_t)1;
-       p -> normal_freelists[i] = (ptr_t)1;
+       p -> tlfs.ptrfree_freelists[i] = (ptr_t)1;
+       p -> tlfs.normal_freelists[i] = (ptr_t)1;
 #      ifdef GC_GCJ_SUPPORT
-         p -> gcj_freelists[i] = (ptr_t)1;
+         p -> tlfs.gcj_freelists[i] = (ptr_t)1;
 #      endif
     }   
     /* Set up the size 0 free lists.   */
-    p -> ptrfree_freelists[0] = (ptr_t)(&size_zero_object);
-    p -> normal_freelists[0] = (ptr_t)(&size_zero_object);
+    p -> tlfs.ptrfree_freelists[0] = (ptr_t)(&size_zero_object);
+    p -> tlfs.normal_freelists[0] = (ptr_t)(&size_zero_object);
 #   ifdef GC_GCJ_SUPPORT
-        p -> gcj_freelists[0] = (ptr_t)(-1);
+       p -> tlfs.gcj_freelists[0] = (ptr_t)(-1);
 #   endif
 }
 
@@ -320,10 +320,10 @@ void GC_destroy_thread_local(GC_thread p)
 #   ifndef HANDLE_FORK
       GC_ASSERT(GC_getspecific(GC_thread_key) == (void *)p);
 #   endif
-    return_freelists(p -> ptrfree_freelists, GC_aobjfreelist);
-    return_freelists(p -> normal_freelists, GC_objfreelist);
+    return_freelists(p -> tlfs.ptrfree_freelists, GC_aobjfreelist);
+    return_freelists(p -> tlfs.normal_freelists, GC_objfreelist);
 #   ifdef GC_GCJ_SUPPORT
-       return_freelists(p -> gcj_freelists, GC_gcjobjfreelist);
+       return_freelists(p -> tlfs.gcj_freelists, GC_gcjobjfreelist);
 #   endif
 }
 
@@ -357,7 +357,7 @@ GC_PTR GC_local_malloc(size_t bytes)
          GC_ASSERT(tsd == (void *)GC_lookup_thread(pthread_self()));
          UNLOCK();
 #      endif
-       my_fl = ((GC_thread)tsd) -> normal_freelists + index;
+       my_fl = ((GC_thread)tsd) -> tlfs.normal_freelists + index;
        my_entry = *my_fl;
        if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
            ptr_t next = obj_link(my_entry);
@@ -384,7 +384,7 @@ GC_PTR GC_local_malloc_atomic(size_t bytes)
     } else {
        int index = INDEX_FROM_BYTES(bytes);
        ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
-                       -> ptrfree_freelists + index;
+                       -> tlfs.ptrfree_freelists + index;
        ptr_t my_entry = *my_fl;
     
        if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
@@ -424,7 +424,7 @@ GC_PTR GC_local_gcj_malloc(size_t bytes,
     } else {
        int index = INDEX_FROM_BYTES(bytes);
        ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
-                       -> gcj_freelists + index;
+                       -> tlfs.gcj_freelists + index;
        ptr_t my_entry = *my_fl;
        if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
            GC_PTR result = (GC_PTR)my_entry;
@@ -463,7 +463,7 @@ GC_PTR GC_local_gcj_malloc(size_t bytes,
 void * GC_local_gcj_fast_malloc(size_t lw, void * ptr_to_struct_containing_descr)
 {
        ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
-               -> gcj_freelists + lw;
+               -> tlfs.gcj_freelists + lw;
        ptr_t my_entry = *my_fl;
 
     GC_ASSERT(GC_gcj_malloc_initialized);
@@ -666,12 +666,12 @@ void GC_mark_thread_local_free_lists(void)
     for (i = 0; i < THREAD_TABLE_SZ; ++i) {
       for (p = GC_threads[i]; 0 != p; p = p -> next) {
        for (j = 1; j < NFREELISTS; ++j) {
-         q = p -> ptrfree_freelists[j];
+         q = p -> tlfs.ptrfree_freelists[j];
          if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
-         q = p -> normal_freelists[j];
+         q = p -> tlfs.normal_freelists[j];
          if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
 #        ifdef GC_GCJ_SUPPORT
-           q = p -> gcj_freelists[j];
+           q = p -> tlfs.gcj_freelists[j];
            if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
 #        endif /* GC_GCJ_SUPPORT */
        }
index e0f6cd08c07f2c5212915e723d9e5a708e74bdcd..be49ff71188d32d78e604eb3d4e9ead814b90773 100644 (file)
@@ -925,11 +925,17 @@ create_allocator (int atype, int tls_key, gboolean slowpath)
        mono_mb_emit_byte (mb, 0x0D); /* CEE_MONO_TLS */
        mono_mb_emit_i4 (mb, tls_key);
        if (atype == ATYPE_FREEPTR || atype == ATYPE_FREEPTR_FOR_BOX || atype == ATYPE_STRING)
-               mono_mb_emit_icon (mb, G_STRUCT_OFFSET (struct GC_Thread_Rep, ptrfree_freelists));
+               mono_mb_emit_icon (mb, G_STRUCT_OFFSET (struct GC_Thread_Rep, tlfs)
+                                       + G_STRUCT_OFFSET (struct thread_local_freelists,
+                                                          ptrfree_freelists));
        else if (atype == ATYPE_NORMAL)
-               mono_mb_emit_icon (mb, G_STRUCT_OFFSET (struct GC_Thread_Rep, normal_freelists));
+               mono_mb_emit_icon (mb, G_STRUCT_OFFSET (struct GC_Thread_Rep, tlfs)
+                                       + G_STRUCT_OFFSET (struct thread_local_freelists,
+                                                          normal_freelists));
        else if (atype == ATYPE_GCJ)
-               mono_mb_emit_icon (mb, G_STRUCT_OFFSET (struct GC_Thread_Rep, gcj_freelists));
+               mono_mb_emit_icon (mb, G_STRUCT_OFFSET (struct GC_Thread_Rep, tlfs)
+                                       + G_STRUCT_OFFSET (struct thread_local_freelists,
+                                                          gcj_freelists));
        else
                g_assert_not_reached ();
        mono_mb_emit_byte (mb, MONO_CEE_ADD);