[M3devel] explanation of CheckLoadTracedRef?

Jay jay.krell at cornell.edu
Mon Apr 20 05:47:09 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