vm: add a new rc-absolute-1 relocation class to allow storing values in 8-bit operands, and optimized code sequences for inline caches using this
parent
3be3fdeb46
commit
1434a305c8
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008, 2010 Slava Pestov.
|
! Copyright (C) 2008, 2010 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: math kernel layouts system strings words quotations byte-arrays
|
USING: math kernel layouts system strings words quotations byte-arrays
|
||||||
alien arrays literals sequences ;
|
alien alien.syntax arrays literals sequences ;
|
||||||
IN: compiler.constants
|
IN: compiler.constants
|
||||||
|
|
||||||
! These constants must match vm/memory.h
|
! These constants must match vm/memory.h
|
||||||
|
@ -40,32 +40,41 @@ CONSTANT: deck-bits 18
|
||||||
: segment-end-offset ( -- n ) 2 bootstrap-cells ; inline
|
: segment-end-offset ( -- n ) 2 bootstrap-cells ; inline
|
||||||
|
|
||||||
! Relocation classes
|
! Relocation classes
|
||||||
CONSTANT: rc-absolute-cell 0
|
C-ENUM: f
|
||||||
CONSTANT: rc-absolute 1
|
rc-absolute-cell
|
||||||
CONSTANT: rc-relative 2
|
rc-absolute
|
||||||
CONSTANT: rc-absolute-ppc-2/2 3
|
rc-relative
|
||||||
CONSTANT: rc-absolute-ppc-2 4
|
rc-absolute-ppc-2/2
|
||||||
CONSTANT: rc-relative-ppc-2 5
|
rc-absolute-ppc-2
|
||||||
CONSTANT: rc-relative-ppc-3 6
|
rc-relative-ppc-2
|
||||||
CONSTANT: rc-relative-arm-3 7
|
rc-relative-ppc-3
|
||||||
CONSTANT: rc-indirect-arm 8
|
rc-relative-arm-3
|
||||||
CONSTANT: rc-indirect-arm-pc 9
|
rc-indirect-arm
|
||||||
CONSTANT: rc-absolute-2 10
|
rc-indirect-arm-pc
|
||||||
|
rc-absolute-2
|
||||||
|
rc-absolute-1 ;
|
||||||
|
|
||||||
! Relocation types
|
! Relocation types
|
||||||
CONSTANT: rt-dlsym 0
|
C-ENUM: f
|
||||||
CONSTANT: rt-entry-point 1
|
rt-dlsym
|
||||||
CONSTANT: rt-entry-point-pic 2
|
rt-entry-point
|
||||||
CONSTANT: rt-entry-point-pic-tail 3
|
rt-entry-point-pic
|
||||||
CONSTANT: rt-here 4
|
rt-entry-point-pic-tail
|
||||||
CONSTANT: rt-this 5
|
rt-here
|
||||||
CONSTANT: rt-literal 6
|
rt-this
|
||||||
CONSTANT: rt-untagged 7
|
rt-literal
|
||||||
CONSTANT: rt-megamorphic-cache-hits 8
|
rt-untagged
|
||||||
CONSTANT: rt-vm 9
|
rt-megamorphic-cache-hits
|
||||||
CONSTANT: rt-cards-offset 10
|
rt-vm
|
||||||
CONSTANT: rt-decks-offset 11
|
rt-cards-offset
|
||||||
CONSTANT: rt-exception-handler 12
|
rt-decks-offset
|
||||||
|
rt-exception-handler ;
|
||||||
|
|
||||||
: rc-absolute? ( n -- ? )
|
: rc-absolute? ( n -- ? )
|
||||||
${ rc-absolute-ppc-2/2 rc-absolute-cell rc-absolute } member? ;
|
${
|
||||||
|
rc-absolute-ppc-2/2
|
||||||
|
rc-absolute-cell
|
||||||
|
rc-absolute
|
||||||
|
rc-absolute-2
|
||||||
|
rc-absolute-1
|
||||||
|
} member? ;
|
||||||
|
|
|
@ -286,25 +286,19 @@ CONSTANT: nv-reg 17
|
||||||
4 ds-reg 0 LWZ rc-absolute-ppc-2 rt-untagged jit-rel
|
4 ds-reg 0 LWZ rc-absolute-ppc-2 rt-untagged jit-rel
|
||||||
] pic-load jit-define
|
] pic-load jit-define
|
||||||
|
|
||||||
! Tag
|
[ 4 4 tag-mask get ANDI ] pic-tag jit-define
|
||||||
: load-tag ( -- )
|
|
||||||
4 4 tag-mask get ANDI
|
|
||||||
4 4 tag-bits get SLWI ;
|
|
||||||
|
|
||||||
[ load-tag ] pic-tag jit-define
|
|
||||||
|
|
||||||
! Tuple
|
|
||||||
[
|
[
|
||||||
3 4 MR
|
3 4 MR
|
||||||
load-tag
|
4 4 tag-mask get ANDI
|
||||||
0 4 tuple type-number tag-fixnum CMPI
|
0 4 tuple type-number CMPI
|
||||||
[ BNE ]
|
[ BNE ]
|
||||||
[ 4 3 tuple type-number neg 4 + LWZ ]
|
[ 4 3 tuple-class-offset LWZ ]
|
||||||
jit-conditional*
|
jit-conditional*
|
||||||
] pic-tuple jit-define
|
] pic-tuple jit-define
|
||||||
|
|
||||||
[
|
[
|
||||||
0 4 0 CMPI rc-absolute-ppc-2 rt-literal jit-rel
|
0 4 0 CMPI rc-absolute-ppc-2 rt-untagged jit-rel
|
||||||
] pic-check-tag jit-define
|
] pic-check-tag jit-define
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -342,6 +336,14 @@ CONSTANT: nv-reg 17
|
||||||
! ! ! Megamorphic caches
|
! ! ! Megamorphic caches
|
||||||
|
|
||||||
[
|
[
|
||||||
|
! class = ...
|
||||||
|
3 4 MR
|
||||||
|
4 4 tag-mask get ANDI
|
||||||
|
4 4 tag-bits get SLWI
|
||||||
|
0 4 tuple type-number tag-fixnum CMPI
|
||||||
|
[ BNE ]
|
||||||
|
[ 4 3 tuple-class-offset LWZ ]
|
||||||
|
jit-conditional*
|
||||||
! cache = ...
|
! cache = ...
|
||||||
0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel
|
0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel
|
||||||
! key = hashcode(class)
|
! key = hashcode(class)
|
||||||
|
|
|
@ -176,6 +176,10 @@ IN: bootstrap.x86
|
||||||
[ jit-jump-quot ]
|
[ jit-jump-quot ]
|
||||||
\ lazy-jit-compile define-combinator-primitive
|
\ lazy-jit-compile define-combinator-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
temp1 HEX: ffffffff CMP rc-absolute-cell rt-literal jit-rel
|
||||||
|
] pic-check-tuple jit-define
|
||||||
|
|
||||||
! Inline cache miss entry points
|
! Inline cache miss entry points
|
||||||
: jit-load-return-address ( -- )
|
: jit-load-return-address ( -- )
|
||||||
pic-tail-reg ESP stack-frame-size bootstrap-cell - [+] MOV ;
|
pic-tail-reg ESP stack-frame-size bootstrap-cell - [+] MOV ;
|
||||||
|
|
|
@ -160,6 +160,11 @@ IN: bootstrap.x86
|
||||||
[ jit-jump-quot ]
|
[ jit-jump-quot ]
|
||||||
\ lazy-jit-compile define-combinator-primitive
|
\ lazy-jit-compile define-combinator-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel
|
||||||
|
temp1 temp2 CMP
|
||||||
|
] pic-check-tuple jit-define
|
||||||
|
|
||||||
! Inline cache miss entry points
|
! Inline cache miss entry points
|
||||||
: jit-load-return-address ( -- )
|
: jit-load-return-address ( -- )
|
||||||
RBX RSP stack-frame-size bootstrap-cell - [+] MOV ;
|
RBX RSP stack-frame-size bootstrap-cell - [+] MOV ;
|
||||||
|
|
|
@ -206,43 +206,37 @@ big-endian off
|
||||||
|
|
||||||
! Load a value from a stack position
|
! Load a value from a stack position
|
||||||
[
|
[
|
||||||
temp1 ds-reg HEX: ffffffff [+] MOV rc-absolute rt-untagged jit-rel
|
temp1 ds-reg HEX: 7f [+] MOV rc-absolute-1 rt-untagged jit-rel
|
||||||
] pic-load jit-define
|
] pic-load jit-define
|
||||||
|
|
||||||
! Tag
|
[ temp1 tag-mask get AND ] pic-tag jit-define
|
||||||
: load-tag ( -- )
|
|
||||||
temp1 tag-mask get AND
|
|
||||||
temp1 tag-bits get SHL ;
|
|
||||||
|
|
||||||
[ load-tag ] pic-tag jit-define
|
|
||||||
|
|
||||||
! The 'make' trick lets us compute the jump distance for the
|
|
||||||
! conditional branches there
|
|
||||||
|
|
||||||
! Tuple
|
|
||||||
[
|
[
|
||||||
temp0 temp1 MOV
|
temp0 temp1 MOV
|
||||||
load-tag
|
temp1 tag-mask get AND
|
||||||
temp1 tuple type-number tag-fixnum CMP
|
temp1 tuple type-number CMP
|
||||||
[ JNE ]
|
[ JNE ]
|
||||||
[ temp1 temp0 tuple type-number neg bootstrap-cell + [+] MOV ]
|
[ temp1 temp0 tuple-class-offset [+] MOV ]
|
||||||
jit-conditional
|
jit-conditional
|
||||||
] pic-tuple jit-define
|
] pic-tuple jit-define
|
||||||
|
|
||||||
[
|
[
|
||||||
temp1 HEX: ffffffff CMP rc-absolute rt-literal jit-rel
|
temp1 HEX: 7f CMP rc-absolute-1 rt-untagged jit-rel
|
||||||
] pic-check-tag jit-define
|
] pic-check-tag jit-define
|
||||||
|
|
||||||
[
|
|
||||||
temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel
|
|
||||||
temp1 temp2 CMP
|
|
||||||
] pic-check-tuple jit-define
|
|
||||||
|
|
||||||
[ 0 JE rc-relative rt-entry-point jit-rel ] pic-hit jit-define
|
[ 0 JE rc-relative rt-entry-point jit-rel ] pic-hit jit-define
|
||||||
|
|
||||||
! ! ! Megamorphic caches
|
! ! ! Megamorphic caches
|
||||||
|
|
||||||
[
|
[
|
||||||
|
! class = ...
|
||||||
|
temp0 temp1 MOV
|
||||||
|
temp1 tag-mask get AND
|
||||||
|
temp1 tag-bits get SHL
|
||||||
|
temp1 tuple type-number tag-fixnum CMP
|
||||||
|
[ JNE ]
|
||||||
|
[ temp1 temp0 tuple-class-offset [+] MOV ]
|
||||||
|
jit-conditional
|
||||||
! cache = ...
|
! cache = ...
|
||||||
temp0 0 MOV rc-absolute-cell rt-literal jit-rel
|
temp0 0 MOV rc-absolute-cell rt-literal jit-rel
|
||||||
! key = hashcode(class)
|
! key = hashcode(class)
|
||||||
|
@ -256,14 +250,16 @@ big-endian off
|
||||||
temp0 temp2 ADD
|
temp0 temp2 ADD
|
||||||
! if(get(cache) == class)
|
! if(get(cache) == class)
|
||||||
temp0 [] temp1 CMP
|
temp0 [] temp1 CMP
|
||||||
bootstrap-cell 4 = 14 22 ? JNE ! Yuck!
|
[ JNE ]
|
||||||
! megamorphic_cache_hits++
|
[
|
||||||
temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel
|
! megamorphic_cache_hits++
|
||||||
temp1 [] 1 ADD
|
temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel
|
||||||
! goto get(cache + bootstrap-cell)
|
temp1 [] 1 ADD
|
||||||
temp0 temp0 bootstrap-cell [+] MOV
|
! goto get(cache + bootstrap-cell)
|
||||||
temp0 word-entry-point-offset [+] JMP
|
temp0 temp0 bootstrap-cell [+] MOV
|
||||||
! fall-through on miss
|
temp0 word-entry-point-offset [+] JMP
|
||||||
|
! fall-through on miss
|
||||||
|
] jit-conditional
|
||||||
] mega-lookup jit-define
|
] mega-lookup jit-define
|
||||||
|
|
||||||
! ! ! Sub-primitives
|
! ! ! Sub-primitives
|
||||||
|
|
|
@ -148,8 +148,8 @@ void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cac
|
||||||
data_root<array> methods(methods_,parent);
|
data_root<array> methods(methods_,parent);
|
||||||
data_root<array> cache(cache_,parent);
|
data_root<array> cache(cache_,parent);
|
||||||
|
|
||||||
/* Generate machine code to determine the object's class. */
|
/* Load the object from the datastack. */
|
||||||
emit_class_lookup(index,PIC_TUPLE);
|
emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
|
||||||
|
|
||||||
/* Do a cache lookup. */
|
/* Do a cache lookup. */
|
||||||
emit_with_literal(parent->special_objects[MEGA_LOOKUP],cache.value());
|
emit_with_literal(parent->special_objects[MEGA_LOOKUP],cache.value());
|
||||||
|
|
|
@ -89,7 +89,8 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
|
||||||
parent->update_pic_count(inline_cache_type);
|
parent->update_pic_count(inline_cache_type);
|
||||||
|
|
||||||
/* Generate machine code to determine the object's class. */
|
/* Generate machine code to determine the object's class. */
|
||||||
emit_class_lookup(index,inline_cache_type);
|
emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
|
||||||
|
emit(parent->special_objects[inline_cache_type]);
|
||||||
|
|
||||||
/* Generate machine code to check, in turn, if the class is one of the cached entries. */
|
/* Generate machine code to check, in turn, if the class is one of the cached entries. */
|
||||||
cell i;
|
cell i;
|
||||||
|
|
|
@ -49,6 +49,8 @@ fixnum instruction_operand::load_value(cell relative_to)
|
||||||
return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell);
|
return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell);
|
||||||
case RC_ABSOLUTE_2:
|
case RC_ABSOLUTE_2:
|
||||||
return *(u16 *)(pointer - sizeof(u16));
|
return *(u16 *)(pointer - sizeof(u16));
|
||||||
|
case RC_ABSOLUTE_1:
|
||||||
|
return *(u8 *)(pointer - sizeof(u8));
|
||||||
default:
|
default:
|
||||||
critical_error("Bad rel class",rel.rel_class());
|
critical_error("Bad rel class",rel.rel_class());
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -124,6 +126,9 @@ void instruction_operand::store_value(fixnum absolute_value)
|
||||||
case RC_ABSOLUTE_2:
|
case RC_ABSOLUTE_2:
|
||||||
*(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value;
|
*(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value;
|
||||||
break;
|
break;
|
||||||
|
case RC_ABSOLUTE_1:
|
||||||
|
*(u8 *)(pointer - sizeof(u8)) = (u8)absolute_value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
critical_error("Bad rel class",rel.rel_class());
|
critical_error("Bad rel class",rel.rel_class());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -33,11 +33,11 @@ enum relocation_type {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum relocation_class {
|
enum relocation_class {
|
||||||
/* absolute address in a 64-bit location */
|
/* absolute address in a pointer-width location */
|
||||||
RC_ABSOLUTE_CELL,
|
RC_ABSOLUTE_CELL,
|
||||||
/* absolute address in a 32-bit location */
|
/* absolute address in a 4 byte location */
|
||||||
RC_ABSOLUTE,
|
RC_ABSOLUTE,
|
||||||
/* relative address in a 32-bit location */
|
/* relative address in a 4 byte location */
|
||||||
RC_RELATIVE,
|
RC_RELATIVE,
|
||||||
/* absolute address in a PowerPC LIS/ORI sequence */
|
/* absolute address in a PowerPC LIS/ORI sequence */
|
||||||
RC_ABSOLUTE_PPC_2_2,
|
RC_ABSOLUTE_PPC_2_2,
|
||||||
|
@ -53,8 +53,10 @@ enum relocation_class {
|
||||||
RC_INDIRECT_ARM,
|
RC_INDIRECT_ARM,
|
||||||
/* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
|
/* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
|
||||||
RC_INDIRECT_ARM_PC,
|
RC_INDIRECT_ARM_PC,
|
||||||
/* absolute address in a 16-bit location */
|
/* absolute address in a 2 byte location */
|
||||||
RC_ABSOLUTE_2
|
RC_ABSOLUTE_2,
|
||||||
|
/* absolute address in a 1 byte location */
|
||||||
|
RC_ABSOLUTE_1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const cell rel_absolute_ppc_2_mask = 0xffff;
|
static const cell rel_absolute_ppc_2_mask = 0xffff;
|
||||||
|
|
|
@ -103,12 +103,6 @@ bool jit::emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jit::emit_class_lookup(fixnum index, cell type)
|
|
||||||
{
|
|
||||||
emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
|
|
||||||
emit(parent->special_objects[type]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Facility to convert compiled code offsets to quotation offsets.
|
/* Facility to convert compiled code offsets to quotation offsets.
|
||||||
Call jit_compute_offset() with the compiled code offset, then emit
|
Call jit_compute_offset() with the compiled code offset, then emit
|
||||||
code, and at the end jit->position is the quotation position. */
|
code, and at the end jit->position is the quotation position. */
|
||||||
|
|
|
@ -47,8 +47,6 @@ struct jit {
|
||||||
|
|
||||||
bool emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p);
|
bool emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p);
|
||||||
|
|
||||||
void emit_class_lookup(fixnum index, cell type);
|
|
||||||
|
|
||||||
fixnum get_position()
|
fixnum get_position()
|
||||||
{
|
{
|
||||||
if(computing_offset_p)
|
if(computing_offset_p)
|
||||||
|
|
Loading…
Reference in New Issue