On Dec 4, 2011, at 5:46 PM, dsimcha wrote: > I'm at my traditional passtime of trying to speed up D's garbage collector > again, and I've stumbled on the fact that rt_finalize is taking up a > ridiculous share of the time (~30% of total runtime) on a benchmark where > huge numbers of classes **that don't have destructors** are being created and > collected. Here's the code to this function, from lifetime.d: > > extern (C) void rt_finalize(void* p, bool det = true) > { > debug(PRINTF) printf("rt_finalize(p = %p)\n", p); > > if (p) // not necessary if called from gc > { > ClassInfo** pc = cast(ClassInfo**)p; > > if (*pc) > { > ClassInfo c = **pc; > byte[] w = c.init; > > try > { > if (det || collectHandler is null || > collectHandler(cast(Object)p)) > { > do > { > if (c.destructor) > { > fp_t fp = cast(fp_t)c.destructor; > (*fp)(cast(Object)p); // call destructor > } > c = c.base; > } while (c); > } > if ((cast(void**)p)[1]) // if monitor is not null > _d_monitordelete(cast(Object)p, det); > (cast(byte*) p)[0 .. w.length] = w[]; // WTF? > } > catch (Throwable e) > { > onFinalizeError(**pc, e); > } > finally // WTF? > { > *pc = null; // zero vptr > } > } > } > } > > Getting rid of the stuff I've marked with //WTF? comments (namely the finally > block and the re-initializing of the memory occupied by the finalized object) > speeds things up by ~15% on the benchmark in question. Why do we care what > state the blob of memory is left in after we finalize it? I can kind of see > that we want to clear things if delete/clear was called manually and we want > to leave the object in a state that doesn't look valid. However, this has > significant performance costs and IIRC is already done in clear() and delete > is supposed to be deprecated. Furthermore, I'd like to get rid of the > finally block entirely, since I assume its presence and the effect on the > generated code is causing the slowdown, not the body, which just assigns a > pointer.
Now that having multiple in-flight exceptions is actually legal, we can probably just throw out the try/catch entirely. The try/catch and call to onFinalizeError is a holdover from when it was effectively illegal to throw from a finalizer.