On 07/04/2011 01:40 PM, Paolo Bonzini wrote:
What I asked:
by making it accept an OOP
What you have:
--- a/libgst/oop.c
+++ b/libgst/oop.c
@@ -2242,68 +2242,89 @@ _gst_add_an_oop_to_mark_queue (OOP oop)
void
_gst_mark (void)
What I asked:
What's the difference from v1?
What you have:
Sorry it was not the good patch.
Please read messages _before_ replying to them.
Paolo
Hello,
I've made some changes:
1) I keep _gst_mark_an_oop_internal and removed
_gst_add_an_oop_to_mark_queue for adding an OOP in the Queue. So like
the previous one, it has an OOP has argument and visit it.
2) in _gst_mark_an_oop_internal when visiting one OOP I keep the same
behavior with TAIL_MARK_OOP, and TAIL_MARK_OOPRANGE add OOPs in the Queue.
3) _gst_mark_oop_range keeps the same behavior as the old one
The patch is tested and produced with master (all tests are green)
Gwen
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) \
_______________________________________________
help-smalltalk mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-smalltalk