[LLVMdev] JIT buffer code skipping 8 bytes?
gvenn.cfe.dev at gmail.com
Fri Dec 25 05:52:17 CST 2009
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
1) In JITDwarfEmitter.cpp these GlobalVariables are emitted with:
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
More information about the LLVMdev