diff --git a/libgst/interp-bc.inl b/libgst/interp-bc.inl index 8819481..25b756a 100644 --- a/libgst/interp-bc.inl +++ b/libgst/interp-bc.inl @@ -173,6 +173,7 @@ } while(0) + void _gst_send_message_internal (OOP sendSelector, int sendArgs, @@ -192,6 +193,7 @@ _gst_send_message_internal (OOP sendSelector, zeros. */ _gst_sample_counter++; + hashIndex = METHOD_CACHE_HASH (sendSelector, method_class); methodData = &method_cache[hashIndex]; diff --git a/libgst/oop.c b/libgst/oop.c index 2e8b7fd..5ab82df 100644 --- a/libgst/oop.c +++ b/libgst/oop.c @@ -66,6 +66,7 @@ /* Define this flag to turn on debugging code for OOP table management */ /* #define GC_DEBUGGING */ +#define GC_DEBUGGING /* Define this flag to disable incremental garbage collection */ /* #define NO_INCREMENTAL_GC */ @@ -353,6 +354,9 @@ _gst_init_mem (size_t eden, size_t survivor, size_t old, _gst_inc_init_registry (); } + _gst_mem.markQueue = xcalloc (128 * K, sizeof (*_gst_mem.markQueue)); + _gst_mem.currentMarkQueue = &_gst_mem.markQueue[0]; + _gst_mem.lastMarkQueue = &_gst_mem.markQueue[128 * K]; } void _gst_update_object_memory_oop (OOP oop) @@ -2207,7 +2211,6 @@ mark_ephemeron_oops (void) } #define TAIL_MARK_OOP(newOOP) do { \ - PREFETCH_ADDR ((newOOP)->object, PREF_READ | PREF_NTA); \ oop = (newOOP); \ goto markOne; /* tail recurse!!! */ \ } while(0) @@ -2223,52 +2226,40 @@ mark_ephemeron_oops (void) void _gst_mark_an_oop_internal (OOP oop) { - OOP *curOOP, *atEndOOP; - goto markOne; + OOP *curOOP, *atEndOOP; + + goto markOne; markRange: - { /* in the loop! */ -#if defined (GC_DEBUGGING) - gst_object obj = (gst_object) (curOOP - 1); /* for debugging */ -#endif - for (;;) + { + while (curOOP < atEndOOP) { - /* in a loop, do next iteration */ oop = *curOOP; - PREFETCH_LOOP (curOOP, PREF_READ | PREF_NTA); - curOOP++; - if (IS_OOP (oop)) + + if (!IS_OOP (oop) || IS_OOP_MARKED (oop)) { -#if defined (GC_DEBUGGING) - if UNCOMMON (!IS_OOP_ADDR (oop)) - { - printf - ("Error! Invalid OOP %p was found inside %p!\n", - oop, obj); - abort (); - } - else -#endif - if (!IS_OOP_MARKED (oop)) - { - PREFETCH_START (oop->object, PREF_READ | PREF_NTA); - - /* On the last object in the set, reuse the - current invocation. oop is valid, so we go to - the single-object case */ - if UNCOMMON (curOOP == atEndOOP) - goto markOne; - - _gst_mark_an_oop_internal (oop); - continue; - } + curOOP++; + continue ; + } + + if (_gst_mem.currentMarkQueue == _gst_mem.lastMarkQueue) + { + const size_t size = _gst_mem.lastMarkQueue - _gst_mem.markQueue; + + _gst_mem.markQueue = (OOP *) xrealloc (_gst_mem.markQueue, 10 * size * sizeof (*_gst_mem.markQueue)); + _gst_mem.currentMarkQueue = &_gst_mem.markQueue[size]; + _gst_mem.lastMarkQueue = &_gst_mem.markQueue[10 * size]; } - /* Place the check here so that the continue above skips it. */ - if UNCOMMON (curOOP == atEndOOP) - return; + oop->flags |= F_REACHABLE; + *_gst_mem.currentMarkQueue = oop; + _gst_mem.currentMarkQueue++; + + curOOP++; } - } + + goto loop; + } markOne: { @@ -2329,10 +2320,18 @@ _gst_mark_an_oop_internal (OOP oop) TAIL_MARK_OOP (objClass); } } + + loop: + if (_gst_mem.currentMarkQueue > _gst_mem.markQueue) + { + _gst_mem.currentMarkQueue--; + oop = *_gst_mem.currentMarkQueue; + goto markOne; + } } -void -_gst_mark_oop_range (OOP *curOOP, OOP *atEndOOP) + void + _gst_mark_oop_range (OOP *curOOP, OOP *atEndOOP) { OOP *pOOP; for (pOOP = curOOP; pOOP < atEndOOP; pOOP++) diff --git a/libgst/oop.h b/libgst/oop.h index 6816b3f..8d1c274 100644 --- a/libgst/oop.h +++ b/libgst/oop.h @@ -193,6 +193,9 @@ struct memory_space struct new_space eden; struct surv_space surv[2], tenuring_queue; + OOP *markQueue; + OOP *currentMarkQueue, *lastMarkQueue; + /* The current state of the copying collector's scan phase. */ struct cheney_scan_state scan; @@ -380,10 +383,6 @@ extern void _gst_grey_oop_range (PTR from, size_t size) ATTRIBUTE_HIDDEN; -/* Mark OOP and the pointers pointed by that. */ -extern void _gst_mark_an_oop_internal (OOP oop) - ATTRIBUTE_HIDDEN; - /* Fully initialize the builtin objects, possible after the respective classes have been created. */ extern void _gst_init_builtin_objects_classes (void) diff --git a/libgst/oop.inl b/libgst/oop.inl index 279dd1b..f2abd7e 100644 --- a/libgst/oop.inl +++ b/libgst/oop.inl @@ -62,10 +62,10 @@ static inline OOP alloc_oop (PTR obj, intptr_t flags); /* Mark the OOP object because it is part of the root set. Integers and already-marked OOPs are not processed silently. */ -#define MAYBE_MARK_OOP(oop) do { \ - if (IS_OOP(oop) && !IS_OOP_MARKED(oop)) { \ - _gst_mark_an_oop_internal((oop)); \ - } \ +#define MAYBE_MARK_OOP(oop) do { \ + if (IS_OOP(oop) && !IS_OOP_MARKED(oop)) { \ + _gst_mark_an_oop_internal (oop); \ + } \ } while(0) #define IS_OOP_COPIED(oop) \