<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
</style>
</head>
<body class='hmmessage'>
Yes this helps, thank you. Maybe checkin under doc? One thing you didn't understand my wording about and you seemed to contradict is "VAR to VAR".<BR>
 <BR>
 <BR>
PROCEDURE F1() =<BR>
VAR i;<BR>
BEGIN<BR>
 F2(i);<BR>
END F1;<BR>
 <BR>
<BR>PROCEDURE F2(VAR a:INTEGER)=<BR>BEGIN<BR>
 F3(i);<BR>
END F2;<BR>
 <BR>
<BR>PROCEDURE F3(VAR a:INTEGER)=<BR>BEGIN<BR>
 a := 1;<BR>
END F3;<BR>
 <BR>
<BR>Where are the calls to CheckLoad/StoreTracedRef?<BR>
  (Duh, I can try it out..)<BR>
It seems redundant to put them "everywhere".<BR>Esp. it seems that F2 shouldn't have do anything.<BR><BR>
 <BR>
But throw in that F3 might extern and that is unclear.<BR>
So I just made up a suggestion that VAR is not good to pass to C code.<BR>
That checks are inserted when 1) a pointer is dereferenced -- loaded<BR>
or stored in Modula-3 or 2) a<BR>
pointer becomes untraced (var becomes untraced ref, among others).<BR>
 <BR>
 <BR>
 > Right.  I think I did see you compute and pass an offset to C code<BR>
 <BR>
 <BR>
I had something like that very recently but think I didn't set it or commit it.<BR>
I had something like:<BR>
 <BR>
 <BR>
size_t offset;<BR>
 <BR>
 <BR>
Init(Mutex* root, int* interior)<BR>
{<BR>
  offset = (size_t)interior - (size_t)root;<BR>
}<BR>
 <BR>
 <BR>
DoSomething(Mutex* anotherRoot)<BR>
{<BR>
  int* interior = (int*)(offset + (size_t)anotherRoot);<BR>
 printf("%d\n", *interior);<BR>
}<BR>
 <BR>
 <BR>
but I came up with a way to avoid that I think, and then rolled it all back or something anyway.<BR>
 <BR>
 <BR>
 <BR>
 - Jay<BR>
 <BR>
<HR id=stopSpelling>
CC: m3devel@elegosoft.com<BR>From: hosking@cs.purdue.edu<BR>To: jay.krell@cornell.edu<BR>Subject: Re: [M3devel] explanation of CheckLoadTracedRef?<BR>Date: Wed, 22 Apr 2009 10:02:52 +1000<BR><BR>
<DIV><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV style="WORD-WRAP: break-word"><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate"><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate"><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate"><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate"><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate"><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate"><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate"><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV>On 21 Apr 2009, at 19:37, Jay wrote:</DIV></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></DIV></SPAN></DIV>
<DIV><BR class=EC_Apple-interchange-newline>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">> > How bad/unportable was it the previous way, the VM-synchronized way?<BR>><SPAN class=EC_Apple-converted-space> </SPAN><BR>> Not compatible with system threading.<BR><BR> <BR>Really? NT386 wasn't VM-synchronized back in 3.6, 4.1, etc.?</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>It was, but every system call had to be wrapped with a call to acquire the global heap lock!</DIV>
<DIV><BR></DIV>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Or only with great cost?</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Yes, taking the lock was expensive and prevented scaling on multi-cores.</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">I have to admit, those old import .libs, kernel32.lib, etc. I didn't realize what was in them when I deleted them. I thought they were just regular import .libs.</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>There was also the work to wrap all dll symbols to acquire the lock.</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">I think I got luckly in that the overlap between me deleting them and you removing VM-synchronized GC was small or zero.</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>You should have seen the mess it was before...  ;-)</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">> You should *never* access a field in the heap in C code! All<SPAN class=EC_Apple-converted-space> </SPAN><BR>> accesses to traced fields in the heap must take place in Modula-3.<SPAN class=EC_Apple-converted-space> </SPAN><BR>> Otherwise things will break! C wrappers should not do anything other<SPAN class=EC_Apple-converted-space> </SPAN><BR>> than forward calls to C library calls. They should not perform heap<SPAN class=EC_Apple-converted-space> </SPAN><BR>> accesses.<BR><BR> <BR>Ok, that makes sense.<BR>Important "out" is the accessing stack is always ok.</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Yes, so long as a references to an object is held on the stack then it is safe to pass an address within it to external calls.  Thus, many C functions can take VAR arguments that may end being references to the fields of objects.  The compiler injects the necessary CheckLoad/CheckStore operations when passing  VAR parameters, etc., and the GC maintains the invariant that all stack-referenced objects don't move, stay black (for incremental GC), and remain dirty (for generational GC).</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">But this is a requirement I didn't keep in mind.<BR>Now, luckily, the C wrappers are all relatively thin and not difficult<BR>to re-review in their entirety.</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Right.  I think I did see you compute and pass an offset to C code, but that may have only been in code you e-mailed me for perusal rather than code that got checked in.  Might be worth reviewing...</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">But, take for example "open".<BR>The first parameter to it is bound to be in the heap.</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>The ambiguous roots garbage collector we use maintains the invariant that pointers to the interior of heap objects from the stack *pin* that object in the heap: it will not move while the pointer from the stack exists, and invariants will be maintained so that its contenst can be manipulated safely even in the face of incremental and generational GC.</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">But probably it is untraced or somehow ok, since it does<BR>come from a module used primarily for C interop.</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Certainly, C code should never be manipulating the *traced* fields of traced heap objects.  It is fine for it to manipulate the untraced fields of traced heap objects.</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">And, the line between C wrappers and the "C library" that they forward to<BR>does not exist.<BR>If I, say, pass a VAR to a VAR..no check is made?</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Not sure what you mean by this.  Any call that passes traced VAR params will generate a check as necessary before the call.</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Important to declare extern/C functions as taking UNTRACED REF and not VAR?</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>No, VAR is fine.  So long as the VAR value being passed is not traced.</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">> I think you are confusing incremental and incremental GC.<BR>You assume I understand more than I do (I assume you have a typo. :))</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>;-)</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">"generational" -- the concept that most objects die young.<BR>  (aka most objects could have been allocated on the stack...)</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Not quite.  The idea is that the likelihood of an object dying is a function of its age.  There is a *weak* generational hypothesis that "most objects die young", and a *strong* generational hypothesis that "the older an object is the less likely it is to die".  Many (but not all) programs support these hypotheses, which permits generational GC to focus effort where it is likely to be profitable (i.e., to free up a lot of space).</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">But does that imply detailed implementation choices, or is just like a "guiding principle"?<BR>I guess it implies the heap is split into at least two generations, old and young.<BR>Though I guess in reality there is a range of young, less young, lesser young, least young, etc.</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Right, many different collectors have exploited age in this way.  For the M3 collector we have just two generations: old and young.</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">And that has objects age, they should be moved from young to old heaps, and references to them either updated right away, or "caught" upon use and updated then...something like that.</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Old-space objects are "clean" if they contain no references to young-space objects.  The Modula-3 compiler injects checks to make sure that whenever we store a reference into a clean old-space object it is marked "dirty".  When a young-space collection occurs we must process the references in dirty old-space objects as roots into the young-space.</DIV><BR>
<BLOCKQUOTE><SPAN class=EC_Apple-style-span style="WORD-SPACING: 0px; FONT: 12px Helvetica; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">
<DIV class=EC_hmmessage style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">"incremental" -- don't pause the world..</DIV></SPAN></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Not quite.  The opposite of stop-the-world (stopping all the mutator threads to process their stacks) is on-the-fly.  Incremental refers to the ability to interleave GC work with mutator work.  If the GC work can be interleaved with mutator threads without stopping the mutator threads at each increment then the collector is said to be concurrent (GC work proceeds concurrently with mutator work).</DIV>
<DIV>The current M3 collector has a stop-the-world non-moving phase, followed by an concurrent copying phase.  I have some incomplete work that will also make the M3 collector on-the-fly (no STW phase) and parallel (multiple GC threads can operate concurrently).</DIV>
<DIV><BR></DIV>
<DIV>Hope all this helps!</DIV></DIV><BR></body>
</html>