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

release
Slava Pestov 2010-04-12 14:22:41 -07:00
parent 3be3fdeb46
commit 1434a305c8
11 changed files with 97 additions and 81 deletions

View File

@ -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? ;

View File

@ -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)

View File

@ -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 ;

View File

@ -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 ;

View File

@ -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

View File

@ -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());

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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. */

View File

@ -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)