[M3devel] explanation of CheckLoadTracedRef?

Jay jay.krell at cornell.edu
Mon Apr 20 05:46:30 CEST 2009


 - What does CheckLoadTracedRef and co. do?
 - Can the compiler be smarter?
 Easily/effectively?
 I'm just reading code to understand the object model..
 and I see like this:
 b.F1(1);  (* line 60 *)
 b.F2(2);
 
 

 .stabn 68,0,60,LM17-LFBB2 (",60," means line 60)
LM17:
 movl _MM_Main+584, %esi
 testl %esi, %esi
 je L13
 testb $64, -2(%esi)
 je L13
 movl %esi, (%esp)
 call _RTHooks__CheckLoadTracedRef
L13:
 movl (%esi), %eax
 movl (%eax), %ebx
 movl $1, 4(%esp)
 movl %esi, (%esp)
 call *%ebx
 .stabn 68,0,61,LM18-LFBB2 (",61," means line 61)
LM18:
 movl _MM_Main+584, %ebx
 testl %ebx, %ebx
 je L14
 testb $64, -2(%ebx)
 je L14
 movl %ebx, (%esp)
 call _RTHooks__CheckLoadTracedRef
L14:
 movl (%ebx), %eax
 movl 4(%eax), %esi
 movl $2, 4(%esp)
 movl %ebx, (%esp)
 call *%esi
 

Does one really need to "check" pointers so often?
You know, like twice in a row?
Granted, there is a call in between.
 I understand, that one call could have done "anything".
 

Ok, here is another case cm3 -O, cm3cg -O3, no intervening function call, still two checks:
 

  T3 = OBJECT
    a: INTEGER;
  END;
 

 c := NEW(T3);
 

 RTIO.PutInt(c.a + c.a);
 

 .stabn 68,0,63,LM20-LFBB2
LM20:
 movl _MM_Main+588, %esi
 testl %esi, %esi
 je L15
 testb $64, -2(%esi)
 je L15
 movl %esi, (%esp)
 call _RTHooks__CheckLoadTracedRef
L15:
 movl _MM_Main+588, %ebx
 testl %ebx, %ebx
 je L16
 testb $64, -2(%ebx)
 je L16
 movl %ebx, (%esp)
 call _RTHooks__CheckLoadTracedRef
L16:
 movl $0, 4(%esp)
 movl 4(%ebx), %eax
 addl 4(%esi), %eax
 movl %eax, (%esp)
 call _RTIO__PutInt
 

I'm of two minds on optimizing though.
 Do it. Don't it.

I don't like debugging optimize code.
Nor do I want to waste time having the compiler make the code less debuggable.
But when I look at the code and how bad the code quality is, and that it could be substantially
better without sacrificing debuging...
 

This example is somewhat contrived, but the code seems like 33% waste.
Eventually that much bloat is going to cost in terms of I/O in the assembly, linker,
paging it in at runtime, and even a little extra to run it.
 
 
"Now that I understand things somewhat better.."
How bad/unportable was it the previous way, the VM-synchronized way?
 
 
Can the checks only be generated for calls to extern functions?
 
 
When I write C wrappers, am I missing checks?
 (I can check, maybe the checks are generated).
Are they missing sometimes with regard to X Windows?
 
 
I think I understand just barely some of what is going on.
That writes through pointers need to be checked.
Because objects can move around.
But moving objects doesn't update the references, but instead
marks pages as different? (In the VM-synchronized world,
moving an object would mark its original page invalid, triggering
a page fault upon subsequent access, which is handled by referencing
the new location and maybe updating the old pointer).
 
 
??? Something like that ???
 
 
 - Jay


More information about the M3devel mailing list