Make sgen-los.c into a proper C module.
authorZoltan Varga <vargaz@gmail.com>
Wed, 1 Dec 2010 13:04:21 +0000 (14:04 +0100)
committerZoltan Varga <vargaz@gmail.com>
Wed, 1 Dec 2010 13:04:48 +0000 (14:04 +0100)
mono/metadata/Makefile.am
mono/metadata/sgen-cardtable.c
mono/metadata/sgen-cardtable.h
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-los.c

index 47e2a61af518419ea96b162d333c7bc6c97e78b6..c36e370428ea580d5c4de92aeb90d9cd9a7875bf 100644 (file)
@@ -81,7 +81,6 @@ sgen_sources = \
        sgen-gray.c             \
        sgen-pinning.c          \
        sgen-pinning-stats.c    \
-       sgen-los.c              \
        sgen-protocol.c         \
        sgen-workers.c
 
@@ -191,6 +190,7 @@ libmonoruntime_la_SOURCES = \
        sgen-marksweep-par.c    \
        sgen-marksweep-fixed-par.c      \
        sgen-major-copying.c    \
+       sgen-los.c              \
        sgen-gc.h               \
        sgen-archdep.h          \
        sgen-cardtable.h        \
index efd07b1dd7bb2ba6b9df029f11eed44ffaedbbab..caa0b6a8d9457bc132b66359c22d6d375cd2b88d 100644 (file)
@@ -164,12 +164,6 @@ card_table_init (void)
 #endif
 }
 
-
-void los_scan_card_table (GrayQueue *queue);
-void los_iterate_live_block_ranges (sgen_cardtable_block_callback callback);
-
-
-
 #ifdef SGEN_HAVE_OVERLAPPING_CARDS
 
 static void
@@ -224,7 +218,7 @@ card_table_clear (void)
        /*XXX we could do this in 2 ways. using mincore or iterating over all sections/los objects */
        if (use_cardtable) {
                major_collector.iterate_live_block_ranges (clear_cards);
-               los_iterate_live_block_ranges (clear_cards);
+               mono_sgen_los_iterate_live_block_ranges (clear_cards);
        }
 }
 static void
@@ -235,13 +229,13 @@ scan_from_card_tables (void *start_nursery, void *end_nursery, GrayQueue *queue)
        /*FIXME we should have a bit on each block/los object telling if the object have marked cards.*/
        /*First we copy*/
        major_collector.iterate_live_block_ranges (move_cards_to_shadow_table);
-       los_iterate_live_block_ranges (move_cards_to_shadow_table);
+       mono_sgen_los_iterate_live_block_ranges (move_cards_to_shadow_table);
 
        /*Then we clear*/
        card_table_clear ();
 #endif
                major_collector.scan_card_table (queue);
-               los_scan_card_table (queue);
+               mono_sgen_los_scan_card_table (queue);
        }
 }
 
index 97430eab34e73a005469aef7b3b411a0c7e9aa22..c1a87471835d8f1101d08e9d8f30f4fb22553492 100644 (file)
@@ -34,7 +34,6 @@ void sgen_card_table_mark_address (mword address) MONO_INTERNAL;
 void sgen_card_table_mark_range (mword address, mword size) MONO_INTERNAL;
 void sgen_cardtable_scan_object (char *obj, mword obj_size, guint8 *cards, SgenGrayQueue *queue) MONO_INTERNAL;
 gboolean sgen_card_table_get_card_data (guint8 *dest, mword address, mword cards) MONO_INTERNAL;
-typedef void (*sgen_cardtable_block_callback) (mword start, mword size);
 
 /*How many bytes a single card covers*/
 #define CARD_BITS 9
index 4c772e08adf7ea5dadd678d26479efdb721e3998..7bf362934cd64269e55b8fa7ae52f5d2270fdb7e 100644 (file)
@@ -864,7 +864,6 @@ SgenMajorCollector major_collector;
 #include "sgen-pinning-stats.c"
 #include "sgen-gray.c"
 #include "sgen-workers.c"
-#include "sgen-los.c"
 #include "sgen-cardtable.c"
 
 /* Root bitmap descriptors are simpler: the lower three bits describe the type
@@ -1297,7 +1296,6 @@ scan_roots_for_specific_ref (MonoObject *key, int root_type)
 void
 mono_gc_scan_for_specific_ref (MonoObject *key)
 {
-       LOSObject *bigobj;
        RootRecord *root;
        int i;
 
@@ -1306,8 +1304,7 @@ mono_gc_scan_for_specific_ref (MonoObject *key)
 
        major_collector.iterate_objects (TRUE, TRUE, (IterateObjectCallbackFunc)scan_object_for_specific_ref_callback, key);
 
-       for (bigobj = los_object_list; bigobj; bigobj = bigobj->next)
-               scan_object_for_specific_ref (bigobj->data, key);
+       mono_sgen_los_iterate_objects ((IterateObjectCallbackFunc)scan_object_for_specific_ref_callback, key);
 
        scan_roots_for_specific_ref (key, ROOT_TYPE_NORMAL);
        scan_roots_for_specific_ref (key, ROOT_TYPE_WBARRIER);
@@ -1562,7 +1559,7 @@ mono_gc_clear_domain (MonoDomain * domain)
                        bigobj = bigobj->next;
                        DEBUG (4, fprintf (gc_debug_file, "Freeing large object %p\n",
                                        bigobj->data));
-                       free_large_object (to_free);
+                       mono_sgen_los_free_object (to_free);
                        continue;
                }
                prev = bigobj;
@@ -2826,6 +2823,12 @@ need_major_collection (mword space_needed)
                minor_collection_sections_alloced * major_collector.section_size + los_alloced > minor_collection_allowance;
 }
 
+gboolean
+mono_sgen_need_major_collection (mword space_needed)
+{
+       return need_major_collection (space_needed);
+}
+
 /*
  * Collect objects in the nursery.  Returns whether to trigger a major
  * collection.
@@ -3193,7 +3196,7 @@ major_do_collection (const char *reason)
                                los_object_list = bigobj->next;
                        to_free = bigobj;
                        bigobj = bigobj->next;
-                       free_large_object (to_free);
+                       mono_sgen_los_free_object (to_free);
                        continue;
                }
                prevbo = bigobj;
@@ -3203,7 +3206,7 @@ major_do_collection (const char *reason)
        TV_GETTIME (btv);
        time_major_free_bigobjs += TV_ELAPSED_MS (atv, btv);
 
-       los_sweep ();
+       mono_sgen_los_sweep ();
 
        TV_GETTIME (atv);
        time_major_los_sweep += TV_ELAPSED_MS (btv, atv);
@@ -3559,7 +3562,7 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
         */
 
        if (size > MAX_SMALL_OBJ_SIZE) {
-               p = alloc_large_inner (vtable, size);
+               p = mono_sgen_los_alloc_large_inner (vtable, size);
        } else {
                /* tlab_next and tlab_temp_end are TLS vars so accessing them might be expensive */
 
@@ -3864,7 +3867,7 @@ mono_gc_alloc_pinned_obj (MonoVTable *vtable, size_t size)
 
        if (size > MAX_SMALL_OBJ_SIZE) {
                /* large objects are always pinned anyway */
-               p = alloc_large_inner (vtable, size);
+               p = mono_sgen_los_alloc_large_inner (vtable, size);
        } else {
                DEBUG (9, g_assert (vtable->klass->inited));
                p = major_collector.alloc_small_pinned_obj (size, vtable->klass->has_references);
@@ -5965,8 +5968,10 @@ mono_gc_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count)
 static char *found_obj;
 
 static void
-find_object_for_ptr_callback (char *obj, size_t size, char *ptr)
+find_object_for_ptr_callback (char *obj, size_t size, void *user_data)
 {
+       char *ptr = user_data;
+
        if (ptr >= obj && ptr < obj + size) {
                g_assert (!found_obj);
                found_obj = obj;
@@ -5978,27 +5983,25 @@ char* find_object_for_ptr (char *ptr);
 char*
 find_object_for_ptr (char *ptr)
 {
-       LOSObject *bigobj;
-
        if (ptr >= nursery_section->data && ptr < nursery_section->end_data) {
                found_obj = NULL;
                mono_sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
-                               (IterateObjectCallbackFunc)find_object_for_ptr_callback, ptr);
+                                                                                  find_object_for_ptr_callback, ptr);
                if (found_obj)
                        return found_obj;
        }
 
-       for (bigobj = los_object_list; bigobj; bigobj = bigobj->next) {
-               if (ptr >= bigobj->data && ptr < bigobj->data + bigobj->size)
-                       return bigobj->data;
-       }
+       found_obj = NULL;
+       mono_sgen_los_iterate_objects (find_object_for_ptr_callback, ptr);
+       if (found_obj)
+               return found_obj;
 
        /*
         * Very inefficient, but this is debugging code, supposed to
         * be called from gdb, so we don't care.
         */
        found_obj = NULL;
-       major_collector.iterate_objects (TRUE, TRUE, (IterateObjectCallbackFunc)find_object_for_ptr_callback, ptr);
+       major_collector.iterate_objects (TRUE, TRUE, find_object_for_ptr_callback, ptr);
        return found_obj;
 }
 
@@ -6423,8 +6426,6 @@ check_consistency_callback (char *start, size_t size, void *dummy)
 static void
 check_consistency (void)
 {
-       LOSObject *bigobj;
-
        // Need to add more checks
 
        missing_remsets = FALSE;
@@ -6434,8 +6435,7 @@ check_consistency (void)
        // Check that oldspace->newspace pointers are registered with the collector
        major_collector.iterate_objects (TRUE, TRUE, (IterateObjectCallbackFunc)check_consistency_callback, NULL);
 
-       for (bigobj = los_object_list; bigobj; bigobj = bigobj->next)
-               check_consistency_callback (bigobj->data, bigobj->size, NULL);
+       mono_sgen_los_iterate_objects ((IterateObjectCallbackFunc)check_consistency_callback, NULL);
 
        DEBUG (1, fprintf (gc_debug_file, "Heap consistency check done.\n"));
 
@@ -6462,12 +6462,8 @@ check_major_refs_callback (char *start, size_t size, void *dummy)
 static void
 check_major_refs (void)
 {
-       LOSObject *bigobj;
-
        major_collector.iterate_objects (TRUE, TRUE, (IterateObjectCallbackFunc)check_major_refs_callback, NULL);
-
-       for (bigobj = los_object_list; bigobj; bigobj = bigobj->next)
-               check_major_refs_callback (bigobj->data, bigobj->size, NULL);
+       mono_sgen_los_iterate_objects ((IterateObjectCallbackFunc)check_major_refs_callback, NULL);
 }
 
 /* Check that the reference is valid */
@@ -6563,7 +6559,6 @@ int
 mono_gc_walk_heap (int flags, MonoGCReferences callback, void *data)
 {
        HeapWalkInfo hwi;
-       LOSObject *bigobj;
 
        hwi.flags = flags;
        hwi.callback = callback;
@@ -6573,9 +6568,8 @@ mono_gc_walk_heap (int flags, MonoGCReferences callback, void *data)
        mono_sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, walk_references, &hwi);
 
        major_collector.iterate_objects (TRUE, TRUE, walk_references, &hwi);
+       mono_sgen_los_iterate_objects (walk_references, &hwi);
 
-       for (bigobj = los_object_list; bigobj; bigobj = bigobj->next)
-               walk_references (bigobj->data, bigobj->size, &hwi);
        return 0;
 }
 
index 41bf51f86819446ffc9ce951620f4e4c49f0831f..f9f474d6f275bae0adf050a8fe37136cd33d9f25 100644 (file)
@@ -667,6 +667,8 @@ void mono_sgen_add_to_global_remset (gpointer ptr) MONO_INTERNAL;
 
 int mono_sgen_get_current_collection_generation (void) MONO_INTERNAL;
 
+typedef void (*sgen_cardtable_block_callback) (mword start, mword size);
+
 typedef struct _SgenMajorCollector SgenMajorCollector;
 struct _SgenMajorCollector {
        size_t section_size;
@@ -689,7 +691,7 @@ struct _SgenMajorCollector {
        void (*find_pin_queue_start_ends) (SgenGrayQueue *queue);
        void (*pin_objects) (SgenGrayQueue *queue);
        void (*scan_card_table) (SgenGrayQueue *queue);
-       void (*iterate_live_block_ranges) (void *callback);
+       void (*iterate_live_block_ranges) (sgen_cardtable_block_callback callback);
        void (*init_to_space) (void);
        void (*sweep) (void);
        void (*check_scan_starts) (void);
@@ -755,5 +757,32 @@ enum {
 gboolean mono_sgen_try_alloc_space (mword size, int space) MONO_INTERNAL;
 void mono_sgen_release_space (mword size, int space) MONO_INTERNAL;
 void mono_sgen_pin_object (void *object, SgenGrayQueue *queue) MONO_INTERNAL;
-void sgen_collect_major_no_lock (const char *reason) MONO_INTERNAL;;
+void sgen_collect_major_no_lock (const char *reason) MONO_INTERNAL;
+gboolean mono_sgen_need_major_collection (mword space_needed) MONO_INTERNAL;
+
+/* LOS */
+
+typedef struct _LOSObject LOSObject;
+struct _LOSObject {
+       LOSObject *next;
+       mword size; /* this is the object size */
+       guint16 huge_object;
+       int dummy; /* to have a sizeof (LOSObject) a multiple of ALLOC_ALIGN  and data starting at same alignment */
+       char data [MONO_ZERO_LEN_ARRAY];
+};
+
+#define ARRAY_OBJ_INDEX(ptr,array,elem_size) (((char*)(ptr) - ((char*)(array) + G_STRUCT_OFFSET (MonoArray, vector))) / (elem_size))
+
+extern LOSObject *los_object_list;
+extern mword los_memory_usage;
+extern mword last_los_memory_usage;
+
+void mono_sgen_los_free_object (LOSObject *obj) MONO_INTERNAL;
+void* mono_sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size) MONO_INTERNAL;
+void mono_sgen_los_sweep (void) MONO_INTERNAL;
+gboolean mono_sgen_ptr_is_in_los (char *ptr, char **start) MONO_INTERNAL;
+void mono_sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data) MONO_INTERNAL;
+void mono_sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback) MONO_INTERNAL;
+void mono_sgen_los_scan_card_table (SgenGrayQueue *queue) MONO_INTERNAL;
+
 #endif /* __MONO_SGENGC_H__ */
index 753dc14b1bb6d4d2fa2bd09b965559be0fe72f81..be3fa7da3721ca653d04510e1479f5fa6ef7edc4 100644 (file)
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#ifdef HAVE_SGEN_GC
+
+#include "metadata/sgen-gc.h"
+#include "metadata/sgen-protocol.h"
+#include "metadata/sgen-cardtable.h"
+#include "utils/mono-mmap.h"
+
 #define LOS_SECTION_SIZE       (1024 * 1024)
 
 /*
 
 #define LOS_NUM_FAST_SIZES             32
 
-typedef struct _LOSObject LOSObject;
-struct _LOSObject {
-       LOSObject *next;
-       mword size; /* this is the object size */
-       guint16 huge_object;
-       int dummy; /* to have a sizeof (LOSObject) a multiple of ALLOC_ALIGN  and data starting at same alignment */
-       char data [MONO_ZERO_LEN_ARRAY];
-};
-
 typedef struct _LOSFreeChunks LOSFreeChunks;
 struct _LOSFreeChunks {
        LOSFreeChunks *next_size;
@@ -86,11 +84,12 @@ struct _LOSSection {
        unsigned char *free_chunk_map;
 };
 
+LOSObject *los_object_list = NULL;
+mword los_memory_usage = 0;
+mword last_los_memory_usage = 0;
+
 static LOSSection *los_sections = NULL;
-static LOSObject *los_object_list = NULL;
 static LOSFreeChunks *los_fast_free_lists [LOS_NUM_FAST_SIZES]; /* 0 is for larger sizes */
-static mword los_memory_usage = 0;
-static mword last_los_memory_usage = 0;
 static mword los_num_objects = 0;
 static int los_num_sections = 0;
 static mword next_los_collection = 2*1024*1024; /* 2 MB, need to tune */
@@ -298,8 +297,10 @@ free_los_section_memory (LOSObject *obj, size_t size)
        add_free_chunk ((LOSFreeChunks*)obj, size);
 }
 
-static void
-free_large_object (LOSObject *obj)
+static int pagesize;
+
+void
+mono_sgen_los_free_object (LOSObject *obj)
 {
 #ifndef LOS_DUMMY
        size_t size = obj->size;
@@ -313,6 +314,8 @@ free_large_object (LOSObject *obj)
        free (obj);
 #else
        if (size > LOS_SECTION_OBJECT_LIMIT) {
+               if (!pagesize)
+                       pagesize = mono_pagesize ();
                size += sizeof (LOSObject);
                size += pagesize - 1;
                size &= ~(pagesize - 1);
@@ -334,13 +337,13 @@ free_large_object (LOSObject *obj)
  * They don't move, so there is no need to pin them during collection
  * and we avoid the memcpy overhead.
  */
-static void* __attribute__((noinline))
-alloc_large_inner (MonoVTable *vtable, size_t size)
+void*
+mono_sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size)
 {
        LOSObject *obj = NULL;
        void **vtslot;
 
-       g_assert (size > MAX_SMALL_OBJ_SIZE);
+       g_assert (size > SGEN_MAX_SMALL_OBJ_SIZE);
 
 #ifdef LOS_DUMMY
        if (!los_segment)
@@ -351,13 +354,9 @@ alloc_large_inner (MonoVTable *vtable, size_t size)
        los_segment_index += size + sizeof (LOSObject);
        g_assert (los_segment_index <= LOS_SEGMENT_SIZE);
 #else
-       if (need_major_collection (size)) {
+       if (mono_sgen_need_major_collection (size)) {
                DEBUG (4, fprintf (gc_debug_file, "Should trigger major collection: req size %zd (los already: %lu, limit: %lu)\n", size, (unsigned long)los_memory_usage, (unsigned long)next_los_collection));
-               mono_profiler_gc_event (MONO_GC_EVENT_START, 1);
-               stop_world (1);
-               major_collection ("LOS overflow");
-               restart_world (1);
-               mono_profiler_gc_event (MONO_GC_EVENT_END, 1);
+               sgen_collect_major_no_lock ("LOS overflow");
        }
 
 #ifdef USE_MALLOC
@@ -366,6 +365,8 @@ alloc_large_inner (MonoVTable *vtable, size_t size)
 #else
        if (size > LOS_SECTION_OBJECT_LIMIT) {
                size_t alloc_size = size;
+               if (!pagesize)
+                       pagesize = mono_pagesize ();
                alloc_size += sizeof (LOSObject);
                alloc_size += pagesize - 1;
                alloc_size &= ~(pagesize - 1);
@@ -382,7 +383,7 @@ alloc_large_inner (MonoVTable *vtable, size_t size)
 #endif
        if (!obj)
                return NULL;
-       g_assert (!((mword)obj->data & (ALLOC_ALIGN - 1)));
+       g_assert (!((mword)obj->data & (SGEN_ALLOC_ALIGN - 1)));
        obj->size = size;
        vtslot = (void**)obj->data;
        *vtslot = vtable;
@@ -401,8 +402,8 @@ alloc_large_inner (MonoVTable *vtable, size_t size)
        return obj->data;
 }
 
-static void
-los_sweep (void)
+void
+mono_sgen_los_sweep (void)
 {
        LOSSection *section, *prev;
        int i;
@@ -461,7 +462,7 @@ los_sweep (void)
        g_assert (los_num_sections == num_sections);
 }
 
-static gboolean
+gboolean
 mono_sgen_ptr_is_in_los (char *ptr, char **start)
 {
        LOSObject *obj;
@@ -478,23 +479,28 @@ mono_sgen_ptr_is_in_los (char *ptr, char **start)
        return FALSE;
 }
 
-#ifdef SGEN_HAVE_CARDTABLE
+void
+mono_sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data)
+{
+       LOSObject *obj;
 
-static void
-los_iterate_live_block_ranges (sgen_cardtable_block_callback callback)
+       for (obj = los_object_list; obj; obj = obj->next)
+               cb (obj->data, obj->size, user_data);
+}
+
+void
+mono_sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback)
 {
        LOSObject *obj;
        for (obj = los_object_list; obj; obj = obj->next) {
-               MonoVTable *vt = (MonoVTable*)LOAD_VTABLE (obj->data);
+               MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj->data);
                if (vt->klass->has_references)
                        callback ((mword)obj->data, (mword)obj->size);
        }
 }
 
-#define ARRAY_OBJ_INDEX(ptr,array,elem_size) (((char*)(ptr) - ((char*)(array) + G_STRUCT_OFFSET (MonoArray, vector))) / (elem_size))
-
-static void __attribute__((noinline))
-los_scan_card_table (GrayQueue *queue)
+void
+mono_sgen_los_scan_card_table (SgenGrayQueue *queue)
 {
        LOSObject *obj;
 
@@ -503,4 +509,4 @@ los_scan_card_table (GrayQueue *queue)
        }
 }
 
-#endif
+#endif /* HAVE_SGEN_GC */