Normally, any "use after free" behavior by code is a bug. But in this case, we know that doing so is safe because the object being freed cannot be reused until the callback happens on this line: dc->dc_func(dc->dc_ctxt); The code is faster now because the continuations is immediately made available for reuse (as opposed to freeing it after dc_func returns). The better assembly is a side effect of this optimization. If you want to see the difference, just apply the following gratuitous "use after free" fix and compare the resulting assembly. Index: src/queue.c =================================================================== --- src/queue.c (revision 55311) +++ src/queue.c (working copy) @@ -358,15 +358,15 @@ // The ccache version is per-thread. // Therefore, the object has not been reused yet. // This generates better assembly. - if ((long)dou._do->do_vtable & DISPATCH_OBJ_ASYNC_BIT) { - _dispatch_continuation_free(dc); - } if ((long)dou._do->do_vtable & DISPATCH_OBJ_GROUP_BIT) { dg = dc->dc_group; } else { dg = NULL; } dc->dc_func(dc->dc_ctxt); + if ((long)dou._do->do_vtable & DISPATCH_OBJ_ASYNC_BIT) { + _dispatch_continuation_free(dc); + } if (dg) { dispatch_group_leave(dg); _dispatch_release(dg); davez On Aug 1, 2010, at 10:33 PM, cee1 wrote:
Hi all,
I've read "_dispatch_continuation_pop" in src/queue.c(line 338). For async dispatch_continuation_t, it will first free, then execute it. The comment says this will generate better assembly, why?
Regards, -- cee1 _______________________________________________ libdispatch-dev mailing list libdispatch-dev@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/libdispatch-dev