! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: math kernel layouts system strings words quotations byte-arrays
-alien arrays literals sequences ;
+alien alien.syntax arrays literals sequences ;
IN: compiler.constants
! These constants must match vm/memory.h
: segment-end-offset ( -- n ) 2 bootstrap-cells ; inline
! Relocation classes
-CONSTANT: rc-absolute-cell 0
-CONSTANT: rc-absolute 1
-CONSTANT: rc-relative 2
-CONSTANT: rc-absolute-ppc-2/2 3
-CONSTANT: rc-absolute-ppc-2 4
-CONSTANT: rc-relative-ppc-2 5
-CONSTANT: rc-relative-ppc-3 6
-CONSTANT: rc-relative-arm-3 7
-CONSTANT: rc-indirect-arm 8
-CONSTANT: rc-indirect-arm-pc 9
-CONSTANT: rc-absolute-2 10
+C-ENUM: f
+ rc-absolute-cell
+ rc-absolute
+ rc-relative
+ rc-absolute-ppc-2/2
+ rc-absolute-ppc-2
+ rc-relative-ppc-2
+ rc-relative-ppc-3
+ rc-relative-arm-3
+ rc-indirect-arm
+ rc-indirect-arm-pc
+ rc-absolute-2
+ rc-absolute-1 ;
! Relocation types
-CONSTANT: rt-dlsym 0
-CONSTANT: rt-entry-point 1
-CONSTANT: rt-entry-point-pic 2
-CONSTANT: rt-entry-point-pic-tail 3
-CONSTANT: rt-here 4
-CONSTANT: rt-this 5
-CONSTANT: rt-literal 6
-CONSTANT: rt-untagged 7
-CONSTANT: rt-megamorphic-cache-hits 8
-CONSTANT: rt-vm 9
-CONSTANT: rt-cards-offset 10
-CONSTANT: rt-decks-offset 11
-CONSTANT: rt-exception-handler 12
+C-ENUM: f
+ rt-dlsym
+ rt-entry-point
+ rt-entry-point-pic
+ rt-entry-point-pic-tail
+ rt-here
+ rt-this
+ rt-literal
+ rt-untagged
+ rt-megamorphic-cache-hits
+ rt-vm
+ rt-cards-offset
+ rt-decks-offset
+ rt-exception-handler ;
: 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? ;
4 ds-reg 0 LWZ rc-absolute-ppc-2 rt-untagged jit-rel\r
] pic-load jit-define\r
\r
-! Tag\r
-: load-tag ( -- )\r
- 4 4 tag-mask get ANDI\r
- 4 4 tag-bits get SLWI ;\r
-\r
-[ load-tag ] pic-tag jit-define\r
+[ 4 4 tag-mask get ANDI ] pic-tag jit-define\r
\r
-! Tuple\r
[\r
3 4 MR\r
- load-tag\r
- 0 4 tuple type-number tag-fixnum CMPI\r
+ 4 4 tag-mask get ANDI\r
+ 0 4 tuple type-number CMPI\r
[ BNE ]\r
- [ 4 3 tuple type-number neg 4 + LWZ ]\r
+ [ 4 3 tuple-class-offset LWZ ]\r
jit-conditional*\r
] pic-tuple jit-define\r
\r
[\r
- 0 4 0 CMPI rc-absolute-ppc-2 rt-literal jit-rel\r
+ 0 4 0 CMPI rc-absolute-ppc-2 rt-untagged jit-rel\r
] pic-check-tag jit-define\r
\r
[\r
! ! ! Megamorphic caches\r
\r
[\r
+ ! class = ...\r
+ 3 4 MR\r
+ 4 4 tag-mask get ANDI\r
+ 4 4 tag-bits get SLWI\r
+ 0 4 tuple type-number tag-fixnum CMPI\r
+ [ BNE ]\r
+ [ 4 3 tuple-class-offset LWZ ]\r
+ jit-conditional*\r
! cache = ...\r
0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel\r
! key = hashcode(class)\r
[ jit-jump-quot ]
\ 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
: jit-load-return-address ( -- )
pic-tail-reg ESP stack-frame-size bootstrap-cell - [+] MOV ;
[ jit-jump-quot ]
\ 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
: jit-load-return-address ( -- )
RBX RSP stack-frame-size bootstrap-cell - [+] MOV ;
! 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
-! Tag
-: load-tag ( -- )
- temp1 tag-mask get AND
- temp1 tag-bits get SHL ;
-
-[ load-tag ] pic-tag jit-define
+[ temp1 tag-mask get AND ] pic-tag jit-define
-! The 'make' trick lets us compute the jump distance for the
-! conditional branches there
-
-! Tuple
[
temp0 temp1 MOV
- load-tag
- temp1 tuple type-number tag-fixnum CMP
+ temp1 tag-mask get AND
+ temp1 tuple type-number CMP
[ JNE ]
- [ temp1 temp0 tuple type-number neg bootstrap-cell + [+] MOV ]
+ [ temp1 temp0 tuple-class-offset [+] MOV ]
jit-conditional
] 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
-[
- 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
! ! ! 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 = ...
temp0 0 MOV rc-absolute-cell rt-literal jit-rel
! key = hashcode(class)
temp0 temp2 ADD
! if(get(cache) == class)
temp0 [] temp1 CMP
- bootstrap-cell 4 = 14 22 ? JNE ! Yuck!
- ! megamorphic_cache_hits++
- temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel
- temp1 [] 1 ADD
- ! goto get(cache + bootstrap-cell)
- temp0 temp0 bootstrap-cell [+] MOV
- temp0 word-entry-point-offset [+] JMP
- ! fall-through on miss
+ [ JNE ]
+ [
+ ! megamorphic_cache_hits++
+ temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel
+ temp1 [] 1 ADD
+ ! goto get(cache + bootstrap-cell)
+ temp0 temp0 bootstrap-cell [+] MOV
+ temp0 word-entry-point-offset [+] JMP
+ ! fall-through on miss
+ ] jit-conditional
] mega-lookup jit-define
! ! ! Sub-primitives
data_root<array> methods(methods_,parent);
data_root<array> cache(cache_,parent);
- /* Generate machine code to determine the object's class. */
- emit_class_lookup(index,PIC_TUPLE);
+ /* Load the object from the datastack. */
+ emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
/* Do a cache lookup. */
emit_with_literal(parent->special_objects[MEGA_LOOKUP],cache.value());
parent->update_pic_count(inline_cache_type);
/* 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. */
cell i;
return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell);
case RC_ABSOLUTE_2:
return *(u16 *)(pointer - sizeof(u16));
+ case RC_ABSOLUTE_1:
+ return *(u8 *)(pointer - sizeof(u8));
default:
critical_error("Bad rel class",rel.rel_class());
return 0;
case RC_ABSOLUTE_2:
*(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value;
break;
+ case RC_ABSOLUTE_1:
+ *(u8 *)(pointer - sizeof(u8)) = (u8)absolute_value;
+ break;
default:
critical_error("Bad rel class",rel.rel_class());
break;
};
enum relocation_class {
- /* absolute address in a 64-bit location */
+ /* absolute address in a pointer-width location */
RC_ABSOLUTE_CELL,
- /* absolute address in a 32-bit location */
+ /* absolute address in a 4 byte location */
RC_ABSOLUTE,
- /* relative address in a 32-bit location */
+ /* relative address in a 4 byte location */
RC_RELATIVE,
/* absolute address in a PowerPC LIS/ORI sequence */
RC_ABSOLUTE_PPC_2_2,
RC_INDIRECT_ARM,
/* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
RC_INDIRECT_ARM_PC,
- /* absolute address in a 16-bit location */
- RC_ABSOLUTE_2
+ /* absolute address in a 2 byte location */
+ RC_ABSOLUTE_2,
+ /* absolute address in a 1 byte location */
+ RC_ABSOLUTE_1,
};
static const cell rel_absolute_ppc_2_mask = 0xffff;
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.
Call jit_compute_offset() with the compiled code offset, then emit
code, and at the end jit->position is the quotation position. */
bool emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p);
- void emit_class_lookup(fixnum index, cell type);
-
fixnum get_position()
{
if(computing_offset_p)