Fix tail call PICs on x86-64

db4
Slava Pestov 2009-05-06 22:44:30 -05:00
parent 88b3be034d
commit 318552ba60
3 changed files with 22 additions and 3 deletions

View File

@ -61,8 +61,12 @@ M: x86 stack-frame-size ( stack-frame -- i )
M: x86 %call ( word -- ) 0 CALL rc-relative rel-word-pic ;
: xt-tail-pic-offset ( -- n )
#! See the comment in vm/cpu-x86.hpp
cell 4 + 1 + ; inline
M: x86 %jump ( word -- )
pic-tail-reg 0 MOV 2 cells 1 + rc-absolute-cell rel-here
pic-tail-reg 0 MOV xt-tail-pic-offset rc-absolute-cell rel-here
0 JMP rc-relative rel-word-pic-tail ;
M: x86 %jump-label ( label -- ) 0 JMP rc-relative label-fixup ;

View File

@ -7,7 +7,15 @@ namespace factor
inline static void flush_icache(cell start, cell len) {}
static const fixnum xt_tail_pic_offset = 2 * sizeof(cell) + 1;
/* In the instruction sequence:
MOV EBX,...
JMP blah
the offset from the immediate operand to MOV to the instruction after
the jump is a cell for the immediate operand, 4 bytes for the JMP
destination, and one byte for the JMP opcode. */
static const fixnum xt_tail_pic_offset = sizeof(cell) + 4 + 1;
static const unsigned char call_opcode = 0xe8;
static const unsigned char jmp_opcode = 0xe9;

View File

@ -152,7 +152,14 @@ void quotation_jit::iterate_quotation()
{
if(stack_frame) emit(userenv[JIT_EPILOG]);
tail_call = true;
/* Inline cache misses are special-cased */
/* Inline cache misses are special-cased.
The calling convention for tail
calls stores the address of the next
instruction in a register. However,
PIC miss stubs themselves tail-call
the inline cache miss primitive, and
we don't want to clobber the saved
address. */
if(obj.value() == userenv[PIC_MISS_WORD]
|| obj.value() == userenv[PIC_MISS_TAIL_WORD])
{