<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>