On 07/04/2011 01:07 PM, Paolo Bonzini wrote:
On 07/04/2011 12:48 PM, Gwenael Casaccio wrote:
Is it better Paolo ?
What's the difference from v1? I see nothing of what I asked for:
Modulo the usual comments about irrelevant hunks :) it looks good,
thanks! Can you however ensure the invariant that the queue is empty
upon entry to _gst_mark, by making it accept an OOP? I believe this
simplifies the code and lets you add back the tail recursion
optimization you removed.
And it would be even better if you could keep the distinction between
marking one OOP and marking a range, because it removes a lot of traffic
to/from the mark queue (a bit cheaper than the stack because of no stack
frame overhead, but still expensive cache-wise). Which in turn means,
keep the API as is! :)
Paolo
Sorry it was not the good patch.
Gwen
diff --git a/libgst/oop.c b/libgst/oop.c
index 9d7b242..244601d 100644
--- 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)
{
- while (_gst_mem.currentMarkQueue > _gst_mem.markQueue)
- {
- int i, n;
- OOP oop;
- gst_object obj;
+ int n;
+ OOP oop;
+ gst_object obj;
- PREFETCH_LOOP (_gst_mem.currentMarkQueue, PREF_READ | PREF_NTA);
- _gst_mem.currentMarkQueue--;
- oop = *_gst_mem.currentMarkQueue;
- obj = OOP_TO_OBJ (oop);
+ if (_gst_mem.currentMarkQueue <= _gst_mem.markQueue)
+ return ;
+
+ _gst_mem.currentMarkQueue--;
+ oop = *_gst_mem.currentMarkQueue;
+ obj = OOP_TO_OBJ (oop);
#if defined(GC_DEBUG_OUTPUT)
- printf (">Mark ");
- _gst_display_oop (oop);
+ printf (">Mark ");
+ _gst_display_oop (oop);
- if UNCOMMON (!IS_OOP_ADDR (oop))
- {
- printf
- ("Error! Invalid OOP %p was found inside %p!\n",
- oop, obj);
- abort ();
- }
+ if UNCOMMON (!IS_OOP_ADDR (oop))
+ {
+ printf
+ ("Error! Invalid OOP %p was found inside %p!\n",
+ oop, obj);
+ abort ();
+ }
#endif
- if UNCOMMON (oop->flags & F_CONTEXT)
- {
- gst_method_context ctx;
- intptr_t methodSP;
- ctx = (gst_method_context) obj;
- methodSP = TO_INT (ctx->spOffset);
- n = ctx->contextStack + methodSP + 1 - obj->data;
-
- for (i = 0; i < n; i++)
- _gst_add_an_oop_to_mark_queue (obj->data[i]);
-
- _gst_add_an_oop_to_mark_queue (obj->objClass);
- }
- else if UNCOMMON (oop->flags & (F_EPHEMERON | F_WEAK))
- {
- if (oop->flags & F_EPHEMERON)
- _gst_add_buf_pointer (oop);
+ if UNCOMMON (oop->flags & F_CONTEXT)
+ {
+ gst_method_context ctx;
+ intptr_t methodSP;
+ ctx = (gst_method_context) obj;
+ methodSP = TO_INT (ctx->spOffset);
+ n = ctx->contextStack + methodSP + 1 - obj->data;
- _gst_add_an_oop_to_mark_queue (obj->objClass);
- }
- else
- {
- n = NUM_OOPS (obj);
+ _gst_mark_oop_range (&obj->data[0], &obj->data[n]);
+ _gst_add_an_oop_to_mark_queue (obj->objClass);
+ }
+ else if UNCOMMON (oop->flags & (F_EPHEMERON | F_WEAK))
+ {
+ if (oop->flags & F_EPHEMERON)
+ _gst_add_buf_pointer (oop);
- for (i = 0; i < n; i++)
- _gst_add_an_oop_to_mark_queue (obj->data[i]);
+ _gst_add_an_oop_to_mark_queue (obj->objClass);
+ }
+ else
+ {
+ n = NUM_OOPS (obj);
- _gst_add_an_oop_to_mark_queue (obj->objClass);
- }
+ _gst_mark_oop_range (&obj->data[0], &obj->data[n]);
+ _gst_add_an_oop_to_mark_queue (obj->objClass);
}
+
+ _gst_mark ();
}
void
_gst_mark_oop_range (OOP *curOOP, OOP *atEndOOP)
{
- OOP *pOOP;
- for (pOOP = curOOP; pOOP < atEndOOP; pOOP++)
- MAYBE_MARK_OOP (*pOOP);
+ OOP *pOOP = curOOP;
+
+ while (pOOP < atEndOOP)
+ {
+ OOP oop = *pOOP;
+
+ if (!IS_OOP (oop) || IS_OOP_MARKED (oop))
+ {
+ pOOP++;
+ 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];
+ }
+
+ oop->flags |= F_REACHABLE;
+ *_gst_mem.currentMarkQueue = oop;
+ _gst_mem.currentMarkQueue++;
+
+ pOOP++;
+ }
}
_______________________________________________
help-smalltalk mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-smalltalk