-! Copyright (C) 2004, 2010 Slava Pestov.
+! Copyright (C) 2004, 2011 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: alien alien.strings arrays byte-arrays generic hashtables
hashtables.private io io.binary io.files io.encodings.binary
io.pathnames kernel kernel.private math namespaces make parser
-prettyprint sequences sequences.generalizations strings sbufs
-vectors words quotations assocs system layouts splitting
-grouping growable classes classes.private classes.builtin
-classes.tuple classes.tuple.private vocabs vocabs.loader
-source-files definitions debugger quotations.private combinators
+prettyprint sequences combinators.smart strings sbufs vectors
+words quotations assocs system layouts splitting grouping
+growable classes classes.private classes.builtin classes.tuple
+classes.tuple.private vocabs vocabs.loader source-files
+definitions debugger quotations.private combinators
combinators.short-circuit math.order math.private accessors
slots.private generic.single.private compiler.units
-compiler.constants fry locals bootstrap.image.syntax
-generalizations parser.notes ;
+compiler.constants compiler.codegen.relocation fry locals
+bootstrap.image.syntax parser.notes ;
IN: bootstrap.image
: arch ( os cpu -- arch )
: images ( -- seq )
{
"windows-x86.32" "unix-x86.32"
- "linux-ppc.32" "linux-ppc.64"
"windows-x86.64" "unix-x86.64"
} ;
SYMBOL: sub-primitives
-SYMBOL: jit-relocations
-
-SYMBOL: jit-offset
-
-: compute-offset ( -- offset )
- building get length jit-offset get + ;
-
-: jit-rel ( rc rt -- )
- compute-offset 3array jit-relocations get push-all ;
-
-SYMBOL: jit-parameters
-
-: jit-parameter ( parameter -- )
- jit-parameters get push ;
-
-SYMBOL: jit-literals
-
-: jit-literal ( literal -- )
- jit-literals get push ;
-
-: jit-vm ( offset rc -- )
- [ jit-parameter ] dip rt-vm jit-rel ;
-
-: jit-dlsym ( name rc -- )
- rt-dlsym jit-rel string>symbol jit-parameter f jit-parameter ;
-
-: jit-dlsym-toc ( name rc -- )
- rt-dlsym-toc jit-rel string>symbol jit-parameter f jit-parameter ;
-
:: jit-conditional ( test-quot false-quot -- )
[ 0 test-quot call ] B{ } make length :> len
- building get length jit-offset get + len +
- [ jit-offset set false-quot call ] B{ } make
+ building get length extra-offset get + len +
+ [ extra-offset set false-quot call ] B{ } make
[ length test-quot call ] [ % ] bi ; inline
-: make-jit ( quot -- jit-parameters jit-literals jit-code )
+: make-jit ( quot -- parameters literals code )
+ #! code is a { relocation insns } pair
[
- 0 jit-offset set
- V{ } clone jit-parameters set
- V{ } clone jit-literals set
- V{ } clone jit-relocations set
+ 0 extra-offset set
+ init-relocation
call( -- )
- jit-parameters get >array
- jit-literals get >array
- jit-relocations get >array
- ] B{ } make prefix ;
+ parameter-table get >array
+ literal-table get >array
+ relocation-table get >byte-array
+ ] B{ } make 2array ;
+
+: make-jit-no-params ( quot -- code )
+ make-jit 2nip ;
: jit-define ( quot name -- )
- [ make-jit 2nip ] dip set ;
+ [ make-jit-no-params ] dip set ;
: define-sub-primitive ( quot word -- )
[ make-jit 3array ] dip sub-primitives get set-at ;
: define-combinator-primitive ( quot non-tail-quot tail-quot word -- )
[
- [ make-jit ]
- [ make-jit 2nip ]
- [ make-jit 2nip ]
- tri* 5 narray
+ [
+ [ make-jit ]
+ [ make-jit-no-params ]
+ [ make-jit-no-params ]
+ tri*
+ ] output>array
] dip
sub-primitives get set-at ;
! Code is compiled into the 'make' vector.
-: compiled-offset ( -- n ) building get length ;
+SYMBOL: extra-offset ! Only used by non-optimizing compiler
+
+: compiled-offset ( -- n )
+ building get length extra-offset get + ;
: alignment ( align -- n )
[ compiled-offset dup ] dip align swap - ;
SYMBOL: relocation-table
: push-uint ( value vector -- )
+ ! If we ever revive PowerPC support again, this needs to be
+ ! changed to reverse the byte order when bootstrapping from
+ ! x86 to PowerPC or vice versa
[ length ] [ B{ 0 0 0 0 } swap push-all ] [ underlying>> ] tri
swap set-alien-unsigned-4 ;
: rel-literal ( literal class -- )
[ add-literal ] dip rt-literal add-relocation ;
+: rel-untagged ( literal class -- )
+ [ add-literal ] dip rt-untagged add-relocation ;
+
: rel-this ( class -- )
rt-this add-relocation ;
: rel-decks-offset ( class -- )
rt-decks-offset add-relocation ;
+: rel-megamorphic-cache-hits ( class -- )
+ rt-megamorphic-cache-hits add-relocation ;
+
+: rel-exception-handler ( class -- )
+ rt-exception-handler add-relocation ;
+
: init-relocation ( -- )
V{ } clone parameter-table set
V{ } clone literal-table set
- BV{ } clone relocation-table set ;
+ BV{ } clone relocation-table set
+ 0 extra-offset set ;
-! Copyright (C) 2007, 2010 Slava Pestov.
+! Copyright (C) 2007, 2011 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image.private kernel kernel.private namespaces
system cpu.x86.assembler cpu.x86.assembler.operands layouts
-vocabs parser compiler.constants sequences math math.private
-generic.single.private threads.private ;
+vocabs parser compiler.constants compiler.codegen.relocation
+sequences math math.private generic.single.private
+threads.private ;
IN: bootstrap.x86
4 \ cell set
: rex-length ( -- n ) 0 ;
: jit-call ( name -- )
- 0 CALL rc-relative jit-dlsym ;
+ 0 CALL f rc-relative rel-dlsym ;
[
! save stack frame size
stack-frame-size PUSH
! push entry point
- 0 PUSH rc-absolute-cell rt-this jit-rel
+ 0 PUSH rc-absolute-cell rel-this
! alignment
ESP stack-frame-size 3 bootstrap-cells - SUB
] jit-prolog jit-define
[
- pic-tail-reg 0 MOV rc-absolute-cell rt-here jit-rel
- 0 JMP rc-relative rt-entry-point-pic-tail jit-rel
+ pic-tail-reg 0 MOV 0 rc-absolute-cell rel-here
+ 0 JMP f rc-relative rel-word-pic-tail
] jit-word-jump jit-define
: jit-load-vm ( -- )
- vm-reg 0 MOV 0 rc-absolute-cell jit-vm ;
+ vm-reg 0 MOV 0 rc-absolute-cell rel-vm ;
: jit-load-context ( -- )
! VM pointer must be in vm-reg already
rs-reg ctx-reg context-retainstack-offset [+] MOV ;
[
- ! ctx-reg is preserved across the call because it is non-volatile
- ! in the C ABI
+ ! ctx-reg is preserved across the call because it is
+ ! non-volatile in the C ABI
jit-load-vm
jit-save-context
! call the primitive
ESP [] vm-reg MOV
- 0 CALL rc-relative rt-dlsym jit-rel
+ 0 CALL f f rc-relative rel-dlsym
jit-restore-context
] jit-primitive jit-define
\ lazy-jit-compile define-combinator-primitive
[
- temp1 HEX: ffffffff CMP rc-absolute-cell rt-literal jit-rel
+ temp1 HEX: ffffffff CMP f rc-absolute-cell rel-literal
] pic-check-tuple jit-define
! Inline cache miss entry points
! Copyright (C) 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image.private compiler.constants
-cpu.x86.assembler cpu.x86.assembler.operands kernel layouts
-locals parser sequences ;
+compiler.codegen.relocation cpu.x86.assembler
+cpu.x86.assembler.operands kernel layouts locals parser
+sequences ;
IN: bootstrap.x86
: tib-segment ( -- ) FS ;
! Align stack
ESP 3 bootstrap-cells ADD
! Exception handler address filled in by callback.cpp
- tib-temp 0 MOV rc-absolute-cell rt-exception-handler jit-rel
+ tib-temp 0 MOV rc-absolute-cell rel-exception-handler
tib-temp PUSH
! No next handler
0 PUSH
-! Copyright (C) 2007, 2010 Slava Pestov.
+! Copyright (C) 2007, 2011 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image.private kernel kernel.private namespaces
-system layouts vocabs parser compiler.constants math
-math.private cpu.x86.assembler cpu.x86.assembler.operands
-sequences generic.single.private threads.private ;
+system layouts vocabs parser compiler.constants
+compiler.codegen.relocation math math.private cpu.x86.assembler
+cpu.x86.assembler.operands sequences generic.single.private
+threads.private ;
IN: bootstrap.x86
8 \ cell set
: rex-length ( -- n ) 1 ;
: jit-call ( name -- )
- RAX 0 MOV rc-absolute-cell jit-dlsym
+ RAX 0 MOV f rc-absolute-cell rel-dlsym
RAX CALL ;
[
! load entry point
- RAX 0 MOV rc-absolute-cell rt-this jit-rel
+ RAX 0 MOV rc-absolute-cell rel-this
! save stack frame size
stack-frame-size PUSH
! push entry point
[
pic-tail-reg 5 [RIP+] LEA
- 0 JMP rc-relative rt-entry-point-pic-tail jit-rel
+ 0 JMP f rc-relative rel-word-pic-tail
] jit-word-jump jit-define
: jit-load-context ( -- )
jit-save-context
! call the primitive
arg1 vm-reg MOV
- RAX 0 MOV rc-absolute-cell rt-dlsym jit-rel
+ RAX 0 MOV f f rc-absolute-cell rel-dlsym
RAX CALL
jit-restore-context
] jit-primitive jit-define
! Load VM pointer into vm-reg, since we're entering from
! C code
- vm-reg 0 MOV 0 rc-absolute-cell jit-vm
+ vm-reg 0 MOV 0 rc-absolute-cell rel-vm
! Load ds and rs registers
jit-load-context
\ lazy-jit-compile define-combinator-primitive
[
- temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel
+ temp2 HEX: ffffffff MOV f rc-absolute-cell rel-literal
temp1 temp2 CMP
] pic-check-tuple jit-define
-! Copyright (C) 2007, 2010 Slava Pestov.
+! Copyright (C) 2007, 2011 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image.private compiler.constants
-compiler.units cpu.x86.assembler cpu.x86.assembler.operands
-kernel kernel.private layouts locals.backend make math
-math.private namespaces sequences slots.private strings.private
-vocabs ;
+compiler.codegen.relocation compiler.units cpu.x86.assembler
+cpu.x86.assembler.operands kernel kernel.private layouts
+locals.backend make math math.private namespaces sequences
+slots.private strings.private vocabs ;
IN: bootstrap.x86
big-endian off
jit-save-tib
! Load VM into vm-reg
- vm-reg 0 MOV rc-absolute-cell rt-vm jit-rel
+ vm-reg 0 MOV 0 rc-absolute-cell rel-vm
! Save old context
nv-reg vm-reg vm-context-offset [+] MOV
ds-reg nv-reg context-datastack-offset [+] MOV
! Call into Factor code
- link-reg 0 MOV rc-absolute-cell rt-entry-point jit-rel
+ link-reg 0 MOV f rc-absolute-cell rel-word
link-reg CALL
! Load VM into vm-reg; only needed on x86-32, but doesn't
! hurt on x86-64
- vm-reg 0 MOV rc-absolute-cell rt-vm jit-rel
+ vm-reg 0 MOV 0 rc-absolute-cell rel-vm
! Load C callstack pointer
nv-reg vm-reg vm-context-offset [+] MOV
! need a parameter here.
! See the comment for M\ x86.32 stack-cleanup in cpu.x86.32
- HEX: ffff RET rc-absolute-2 rt-untagged jit-rel
+ HEX: ffff RET f rc-absolute-2 rel-untagged
] callback-stub jit-define
[
! Load word
- temp0 0 MOV rc-absolute-cell rt-literal jit-rel
+ temp0 0 MOV f rc-absolute-cell rel-literal
! Bump profiling counter
temp0 profile-count-offset [+] 1 tag-fixnum ADD
! Load word->code
[
! load literal
- temp0 0 MOV rc-absolute-cell rt-literal jit-rel
+ temp0 0 MOV f rc-absolute-cell rel-literal
! increment datastack pointer
ds-reg bootstrap-cell ADD
! store literal on datastack
] jit-push jit-define
[
- 0 CALL rc-relative rt-entry-point-pic jit-rel
+ 0 CALL f rc-relative rel-word-pic
] jit-word-call jit-define
[
! compare boolean with f
temp0 \ f type-number CMP
! jump to true branch if not equal
- 0 JNE rc-relative rt-entry-point jit-rel
+ 0 JNE f rc-relative rel-word
! jump to false branch if equal
- 0 JMP rc-relative rt-entry-point jit-rel
+ 0 JMP f rc-relative rel-word
] jit-if jit-define
: jit->r ( -- )
[
jit->r
- 0 CALL rc-relative rt-entry-point jit-rel
+ 0 CALL f rc-relative rel-word
jit-r>
] jit-dip jit-define
[
jit-2>r
- 0 CALL rc-relative rt-entry-point jit-rel
+ 0 CALL f rc-relative rel-word
jit-2r>
] jit-2dip jit-define
[
jit-3>r
- 0 CALL rc-relative rt-entry-point jit-rel
+ 0 CALL f rc-relative rel-word
jit-3r>
] jit-3dip jit-define
! Load a value from a stack position
[
- temp1 ds-reg HEX: 7f [+] MOV rc-absolute-1 rt-untagged jit-rel
+ temp1 ds-reg HEX: 7f [+] MOV f rc-absolute-1 rel-untagged
] pic-load jit-define
[ temp1 tag-mask get AND ] pic-tag jit-define
] pic-tuple jit-define
[
- temp1 HEX: 7f CMP rc-absolute-1 rt-untagged jit-rel
+ temp1 HEX: 7f CMP f rc-absolute-1 rel-untagged
] pic-check-tag jit-define
-[ 0 JE rc-relative rt-entry-point jit-rel ] pic-hit jit-define
+[ 0 JE f rc-relative rel-word ] pic-hit jit-define
! ! ! Megamorphic caches
[ temp1 temp0 tuple-class-offset [+] MOV ]
jit-conditional
! cache = ...
- temp0 0 MOV rc-absolute-cell rt-literal jit-rel
+ temp0 0 MOV f rc-absolute-cell rel-literal
! key = hashcode(class)
temp2 temp1 MOV
bootstrap-cell 4 = [ temp2 1 SHR ] when
[ JNE ]
[
! megamorphic_cache_hits++
- temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel
+ temp1 0 MOV rc-absolute-cell rel-megamorphic-cache-hits
temp1 [] 1 ADD
! goto get(cache + bootstrap-cell)
temp0 temp0 bootstrap-cell [+] MOV
! Comparisons
: jit-compare ( insn -- )
! load t
- t jit-literal
- temp3 0 MOV rc-absolute-cell rt-literal jit-rel
+ temp3 0 MOV t rc-absolute-cell rel-literal
! load f
temp1 \ f type-number MOV
! load first value
instruction_operand callback_heap::callback_operand(code_block *stub, cell index)
{
tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
+ tagged<byte_array> relocation_template(array_nth(code_template.untagged(),0));
- cell rel_class = untag_fixnum(array_nth(code_template.untagged(),3 * index + 1));
- cell rel_type = untag_fixnum(array_nth(code_template.untagged(),3 * index + 2));
- cell offset = untag_fixnum(array_nth(code_template.untagged(),3 * index + 3));
-
- relocation_entry rel(
- (relocation_type)rel_type,
- (relocation_class)rel_class,
- offset);
-
- instruction_operand op(rel,stub,0);
-
- return op;
+ relocation_entry entry(relocation_template->data<relocation_entry>()[index]);
+ return instruction_operand(entry,stub,0);
}
void callback_heap::store_callback_operand(code_block *stub, cell index)
code_block *callback_heap::add(cell owner, cell return_rewind)
{
tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
- tagged<byte_array> insns(array_nth(code_template.untagged(),0));
+ tagged<byte_array> insns(array_nth(code_template.untagged(),1));
cell size = array_capacity(insns.untagged());
cell bump = align(size + sizeof(code_block),data_alignment);
parent(vm)
{}
-void jit::emit_relocation(cell code_template_)
+void jit::emit_relocation(cell relocation_template_)
{
- data_root<array> code_template(code_template_,parent);
- cell capacity = array_capacity(code_template.untagged());
- for(cell i = 1; i < capacity; i += 3)
+ data_root<byte_array> relocation_template(relocation_template_,parent);
+ cell capacity = array_capacity(relocation_template.untagged())
+ / sizeof(relocation_entry);
+ relocation_entry *relocations = relocation_template->data<relocation_entry>();
+ for(cell i = 0; i < capacity; i++)
{
- relocation_class rel_class = (relocation_class)untag_fixnum(array_nth(code_template.untagged(),i));
- relocation_type rel_type = (relocation_type)untag_fixnum(array_nth(code_template.untagged(),i + 1));
- cell offset = array_nth(code_template.untagged(),i + 2);
-
- relocation_entry new_entry(rel_type,rel_class,code.count + untag_fixnum(offset));
+ relocation_entry entry = relocations[i];
+ relocation_entry new_entry(entry.rel_type(), entry.rel_class(),
+ entry.rel_offset() + code.count);
relocation.append_bytes(&new_entry,sizeof(relocation_entry));
}
}
{
data_root<array> code_template(code_template_,parent);
- emit_relocation(code_template.value());
+ emit_relocation(array_nth(code_template.untagged(),0));
- data_root<byte_array> insns(array_nth(code_template.untagged(),0),parent);
+ data_root<byte_array> insns(array_nth(code_template.untagged(),1),parent);
if(computing_offset_p)
{
explicit jit(code_block_type type, cell owner, factor_vm *parent);
void compute_position(cell offset);
- void emit_relocation(cell code_template);
+ void emit_relocation(cell relocation_template);
void emit(cell code_template);
void parameter(cell parameter) { parameters.add(parameter); }