JIT buffer code skipping 8 bytes?

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:
  (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)):wink: 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


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? :slight_smile: