Although I now seem to have other issues with action values, I'm beginning
to believe the description was not the problem. It looks like
getOrEmitGlobalVariable(...) should be allocating from a separate buffer other
than the used dwarf emitted buffer as can be seen in JIT::getMemoryForGV(...).
If this is the case, it seems that JITCodeEmitter::emitInt64(...) is emitting
the true address value to the dwarf buffer, and that I can go back to using
initialized StructType GlobalVariables for my type infos. If this is a correct
interpretation, there two ways for me to proceed:
1) use false for GVsWithCode as the last argument to
ExecutionEngine::createJIT(...) (default is false), or:
2) add a X86JITInfo::allocateSeparateGVMemory(...) which would return true.
As these two options involve different allocation mechanisms for GlobalVariables
in a JIT environment--the first using a memory manager (JITMemoryManager derived
instance), and the second using malloc(...), is there a "proper"
preference? The second option of course requires modifications to LLVM. At least
the first option is producing the correct offset addresses in the dwarf
exception type info block, and I assume that the 2nd option would do the same.
Or is it the case that I'm still in outer space? :-)
Garrison
On Dec 25, 2009, at 6:52, Garrison Venn wrote:
> On OS X (10.6.2) running on an Intel Core 2 duo with LLVM 2.7 pulled about
a month ago from CVS and built in debug mode:
>
> Using the JIT system with exception handling, I am having issues with type
infos. "Finally" code (llvm.eh.selector intrinsic call with 0)
> works fine (correct landing pads found), as does this call with one type
info. My type infos are each 64 bit array GlobalVariables with
> pointers to external addresses shoved into them; type
ArrayType::get(builder.getInt8Ty(), 8). I used arrays versus integers because
> the resulting 8 byte alignment resulted in JIT emitted addresses which did
not seem match the excepted type info offset. In truth I'm
> not sure what a type info is anyway, as I know they are not c++ type infos,
but the array trick seems to work ... sort of. My question
> though is:
>
> 1) In JITDwarfEmitter.cpp these GlobalVariables are emitted with:
> JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
> (in JITDwarfEmitter::EmitExceptionTable)
>
> 2) The allocated emitted space is calculated by:
> JITCodeEmitter::allocateSpace(...) as eventually called by
getOrEmitGlobalVariable(...)
>
> 3) If the correctly sized buffer was already allocated, and alignment did
not affect the current buffer pointer, JITCodeEmitter::allocateSpace(...)
returns the current buffer pointer (CurBufferPtr), BEFORE this pointer is offset
by the size of the value to be stored, which in my case is 8 bytes.
>
> 4) getOrEmitGlobalVariable(...) subsequently sets the initialized
GlobalVariable instance value in the returned address.
>
> 5) So far so good as this address fits within the correct offset of
JITDwarfEmitter's contained TypeOffset which was previously emitted in the
dwarf exception header.
>
> 6) However JITDwarfEmitter then calls emitInt64(...) in
(JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));) on the above
emitted address returned by Jit.getOrEmitGlobalVariable(...).
>
> 7) My confusion is that JITCodeEmitter::emitInt64(...) subsequently stores
this very address at the next current buffer pointer (CurBufferPtr) which was
already updated by 8 bytes in step 3, and then adds another 8 bytes to this
current buffer pointer.
>
> 8) Therefore after the first type info is stored, the next type info will
be stored 16 bytes away from the beginning of the first type info location. The
JITCodeEmitter calculated and previously emitted TypeOffset seems to only
understand 8 byte intervals for each type info, and therefore the final action
offset applied to the type info ptr location in one's personality function
will not work (and doesn't).
>
> 9) So why is emitInt64(...) called when it seems that the GlobalVariable
value has already been allocated and stored, and the next current buffer pointer
(CurBufferPtr), is already prepped for the next storage value all via the
previous call to getOrEmitGlobalVariable(...)?
>
> Since this code also exists in 2.6, I'm gathering the issue is mine,
and has something to do with what a type info should be, but the above code is
throwing me off.
>
> Any clarification would be appreciated.
>
> Thanks in advance
>
> Garrison
>