<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>I repeatedly read that "precise GC" is difficult/impossible to achieve when producing C.<BR> <BR> <BR>That the C compiler will stash things in registers, it will spill the registers to difficult/impossible to know locations. And this is close to true, and it worse than people realize (or at least I ralized) -- non-volatile registers get spilled in functions you call. They get spilled to varying places depending on the current callstack.<BR> <BR><br>So instead of "precise GC", runtimes resort to looking at registers and scanning every location in the stack. Including garbage left behind by returned functions (unless you zero the frame/registers upon function exit). Including confusing integers for pointers possibly (mostly unlikely, but consider a 32bit program processing a large file, over 4GB in size, and storing some file offsets -- they'll be all over the place).<BR> <BR> <BR>So, the question is..what to do? What can be done?<BR> <BR> <BR>What about a design where locals and params are put in "frame" struct, and everything is volatile?<BR> <BR> <BR>Then what?<BR>Put the frame struct pointer somewhere?<BR> (for that matter -- no struct, no fixed layout, but take the address of each local and put it..somewhere?)<BR> <BR> <BR>Of course, integers and floats, don't care.<BR>They can be left "free floating" as usual (unless they are uplevel, of course).<BR> <BR> <BR>What would one then do?<BR> <BR> <BR>Clearly this is the point of M3CG.init_offset.<BR> <BR> <BR>But what would one do in portable C or C++?<BR>Maintain a per-thread linked list of frame pointers?<BR>i.e. arrange for portable stack walking?<BR> <BR> <BR>Somewhat alternatively, combine this with preemptive suspend?<BR>One could imagine having two sets of locals -- "normal" "free floating" non-volatile ones and the frame.<BR> <BR> <BR>Preemptive suspend is I think best implemented by occasionally calling out to a function.<BR>But it can be done occasionally reading a global, and either acting on its value, or the global's page being made inaccessible and triggering a fault. "acting on its value" make for larger code; triggering a fault is slow and less portable, but is the smallest code. I like the idea of calling a function.<BR> <BR> <BR>So then, to further develop the idea..and slow things down more...before calling the "Should I Suspend" function, one could store all the "free floating" locals into the frame, and load them back up after the call. Better yet, "should I suspend" could return a boolean as to if any live data was moved, and only if that is true would the non-volatiles be restored from the volatiles.<BR> <BR> <BR>But that is still kind of big and slow.<BR> <BR> <BR>It is worse than this though.<BR>It isn't just calls out to suspend, it is called to any function, which themselves might call out to suspend. You'd want to "home" all locals to the "frame" before any function call, and restore them afterward.<BR> <BR> <BR>To be fair, this is analogous to how things work anyway, with regard to register save/restore.<BR>Compiler would be left with no registers to save/restore..we'd be doing it for it, essentially.<BR> <BR> <BR>Do we have a moving/compacting GC? I think so. I think it is desirable. To prevent heap fragmentation.<BR>If the GC didn't move/compact, then this idea can be done a little more efficiently -- then you just have to expose live data to the GC at findable places. But you don't have to keep it in sync as aggressively. You could just make all writes volatile, but not reads, for example.<BR> <BR> <BR>Alternatively...one would have to study how well C compilers optimize..but maybe something in between..maybe put everything in frame struct, not volatile, take the address of the struct before any function call (heck -- pass it as an extra last parameter..given how we violate function signatures already)..and leave the C comiler to save/restore as needed -- i.e. if a variable is dead, it wouldn't bother.<BR>Just because something is in a frame struct, doesn't mean the C compiler won't enregister it across runs of code.<BR> <BR> <BR>Thoughts?<BR>Ideas?<BR> <BR> <BR> - Jay<BR> </div></body>
</html>