<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div><div><div><div>On 2008-04-29, at 01:51, Jonathan S. Shapiro wrote:</div><br><blockquote type="cite">Gordon: assume, for a moment, that I'm willing to go the extra several miles to do this type if thing in my GC implementation. How might I go about getting per-call-site register typings, register save locations, and return-pc information extracted for use by this hypothetical sophisticated walker?<br></blockquote></div><br><div>There are two complementary interfaces here, which mesh neatly into the existing collection of GC algorithms exposed by Collector.</div><div><br></div><div>The first is liveness analysis, for stack roots as well as register maps. The Collector API is set up for this, although it is not yet implemented.</div><div><br></div><div>The second is register maps (which of course are necessarily liveness accurate). The Collector API is not presently set up for this, but I expect the API additions would be rather simple:</div><div><br></div></div></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><font class="Apple-style-span" face="'Courier New'"> MyCollector() {<br>+ // Please don't spill roots to stack slots at safe points.<br>+ RegisterRoots = true; <br> }<br> <br> void MyCollector::finishAssembly(std::ostream &OS, AsmPrinter &AP,<br> const TargetAsmInfo &TAI) {<br> // Iterate functions.<br> for (iterator I = begin(), E = end(); I != E; ++I) {<br> // Iterate safe points.<br> for (CollectorMetadata::iterator PI = MD.begin(),<br> PE = MD.end(); PI != PE; ++PI) {<br> // Live stack roots.<br> for (CollectorMetadata::live_iterator LI = MD.live_begin(PI),<br> LE = MD.live_end(PI);<br> LI != LE; ++LI) {<br> // Print its offset within the stack frame.<br> AP.EmitInt32(LI->StackOffset);<br> AP.EOL("stack offset");<br> }<br>+ for (CollectorMetadata::reg_iterator RI = MD.reg_begin(PI),<br>+ RE = MD.reg_end(PI);<br>+ RI != RE; ++RI) {<br>+ int TargetRegNum = RI->Register;<br>+ Constant *RootMetadata = RI->Metadata;<br>+ }<br> }<br> }</font></blockquote><div><div><div><div><div><br></div><div>Both of these require a more sophisticated SelectionDAG representation of GC pointers. I'm still mulling this representation over, but I think the derived pointer problem could be solved simultaneously.</div><div><br></div><div>That done, I think liveness w/ register roots would be the first feature to be enabled.</div><div><br></div><div>Next, liveness w/o register roots. (This is simply liveness with register roots, where each root is forcibly spilled.)</div><div><br></div></div></div></div></div><div><div><div><div><div>— Gordon<br></div></div></div><br></div></div></body></html>