Clean up bootstrap.image, and implement new calling convention for tail calls; tail call sites now have PICs
							parent
							
								
									12a34d81f7
								
							
						
					
					
						commit
						4915e1ced7
					
				| 
						 | 
				
			
			@ -9,7 +9,7 @@ classes.builtin classes.tuple classes.tuple.private vocabs
 | 
			
		|||
vocabs.loader source-files definitions debugger quotations.private
 | 
			
		||||
sequences.private combinators math.order math.private accessors
 | 
			
		||||
slots.private generic.single.private compiler.units compiler.constants
 | 
			
		||||
fry ;
 | 
			
		||||
fry bootstrap.image.syntax ;
 | 
			
		||||
IN: bootstrap.image
 | 
			
		||||
 | 
			
		||||
: arch ( os cpu -- arch )
 | 
			
		||||
| 
						 | 
				
			
			@ -123,96 +123,59 @@ SYMBOL: big-endian
 | 
			
		|||
! Bootstrap architecture name
 | 
			
		||||
SYMBOL: architecture
 | 
			
		||||
 | 
			
		||||
! Bootstrap global namesapce
 | 
			
		||||
SYMBOL: bootstrap-global
 | 
			
		||||
RESET
 | 
			
		||||
 | 
			
		||||
! Boot quotation, set in stage1.factor
 | 
			
		||||
SYMBOL: bootstrap-boot-quot
 | 
			
		||||
USERENV: bootstrap-boot-quot 20
 | 
			
		||||
 | 
			
		||||
! Bootstrap global namesapce
 | 
			
		||||
USERENV: bootstrap-global 21
 | 
			
		||||
 | 
			
		||||
! JIT parameters
 | 
			
		||||
SYMBOL: jit-prolog
 | 
			
		||||
SYMBOL: jit-primitive-word
 | 
			
		||||
SYMBOL: jit-primitive
 | 
			
		||||
SYMBOL: jit-word-jump
 | 
			
		||||
SYMBOL: jit-word-call
 | 
			
		||||
SYMBOL: jit-push-immediate
 | 
			
		||||
SYMBOL: jit-if-word
 | 
			
		||||
SYMBOL: jit-if
 | 
			
		||||
SYMBOL: jit-dip-word
 | 
			
		||||
SYMBOL: jit-dip
 | 
			
		||||
SYMBOL: jit-2dip-word
 | 
			
		||||
SYMBOL: jit-2dip
 | 
			
		||||
SYMBOL: jit-3dip-word
 | 
			
		||||
SYMBOL: jit-3dip
 | 
			
		||||
SYMBOL: jit-execute-word
 | 
			
		||||
SYMBOL: jit-execute-jump
 | 
			
		||||
SYMBOL: jit-execute-call
 | 
			
		||||
SYMBOL: jit-epilog
 | 
			
		||||
SYMBOL: jit-return
 | 
			
		||||
SYMBOL: jit-profiling
 | 
			
		||||
USERENV: jit-prolog 23
 | 
			
		||||
USERENV: jit-primitive-word 24
 | 
			
		||||
USERENV: jit-primitive 25
 | 
			
		||||
USERENV: jit-word-jump 26
 | 
			
		||||
USERENV: jit-word-call 27
 | 
			
		||||
USERENV: jit-word-special 28
 | 
			
		||||
USERENV: jit-if-word 29
 | 
			
		||||
USERENV: jit-if 30
 | 
			
		||||
USERENV: jit-epilog 31
 | 
			
		||||
USERENV: jit-return 32
 | 
			
		||||
USERENV: jit-profiling 33
 | 
			
		||||
USERENV: jit-push-immediate 34
 | 
			
		||||
USERENV: jit-dip-word 35
 | 
			
		||||
USERENV: jit-dip 36
 | 
			
		||||
USERENV: jit-2dip-word 37
 | 
			
		||||
USERENV: jit-2dip 38
 | 
			
		||||
USERENV: jit-3dip-word 39
 | 
			
		||||
USERENV: jit-3dip 40
 | 
			
		||||
USERENV: jit-execute-word 41
 | 
			
		||||
USERENV: jit-execute-jump 42
 | 
			
		||||
USERENV: jit-execute-call 43
 | 
			
		||||
 | 
			
		||||
! PIC stubs
 | 
			
		||||
SYMBOL: pic-load
 | 
			
		||||
SYMBOL: pic-tag
 | 
			
		||||
SYMBOL: pic-hi-tag
 | 
			
		||||
SYMBOL: pic-tuple
 | 
			
		||||
SYMBOL: pic-hi-tag-tuple
 | 
			
		||||
SYMBOL: pic-check-tag
 | 
			
		||||
SYMBOL: pic-check
 | 
			
		||||
SYMBOL: pic-hit
 | 
			
		||||
SYMBOL: pic-miss-word
 | 
			
		||||
SYMBOL: pic-miss-tail-word
 | 
			
		||||
USERENV: pic-load 47
 | 
			
		||||
USERENV: pic-tag 48
 | 
			
		||||
USERENV: pic-hi-tag 49
 | 
			
		||||
USERENV: pic-tuple 50
 | 
			
		||||
USERENV: pic-hi-tag-tuple 51
 | 
			
		||||
USERENV: pic-check-tag 52
 | 
			
		||||
USERENV: pic-check 53
 | 
			
		||||
USERENV: pic-hit 54
 | 
			
		||||
USERENV: pic-miss-word 55
 | 
			
		||||
USERENV: pic-miss-tail-word 56
 | 
			
		||||
 | 
			
		||||
! Megamorphic dispatch
 | 
			
		||||
SYMBOL: mega-lookup
 | 
			
		||||
SYMBOL: mega-lookup-word
 | 
			
		||||
SYMBOL: mega-miss-word
 | 
			
		||||
USERENV: mega-lookup 57
 | 
			
		||||
USERENV: mega-lookup-word 58
 | 
			
		||||
USERENV: mega-miss-word 59
 | 
			
		||||
 | 
			
		||||
! Default definition for undefined words
 | 
			
		||||
SYMBOL: undefined-quot
 | 
			
		||||
 | 
			
		||||
: userenvs ( -- assoc )
 | 
			
		||||
    H{
 | 
			
		||||
        { bootstrap-boot-quot 20 }
 | 
			
		||||
        { bootstrap-global 21 }
 | 
			
		||||
        { jit-prolog 23 }
 | 
			
		||||
        { jit-primitive-word 24 }
 | 
			
		||||
        { jit-primitive 25 }
 | 
			
		||||
        { jit-word-jump 26 }
 | 
			
		||||
        { jit-word-call 27 }
 | 
			
		||||
        { jit-if-word 28 }
 | 
			
		||||
        { jit-if 29 }
 | 
			
		||||
        { jit-epilog 33 }
 | 
			
		||||
        { jit-return 34 }
 | 
			
		||||
        { jit-profiling 35 }
 | 
			
		||||
        { jit-push-immediate 36 }
 | 
			
		||||
        { jit-dip-word 38 }
 | 
			
		||||
        { jit-dip 39 }
 | 
			
		||||
        { jit-2dip-word 40 }
 | 
			
		||||
        { jit-2dip 41 }
 | 
			
		||||
        { jit-3dip-word 42 }
 | 
			
		||||
        { jit-3dip 43 }
 | 
			
		||||
        { jit-execute-word 44 }
 | 
			
		||||
        { jit-execute-jump 45 }
 | 
			
		||||
        { jit-execute-call 46 }
 | 
			
		||||
        { pic-load 47 }
 | 
			
		||||
        { pic-tag 48 }
 | 
			
		||||
        { pic-hi-tag 49 }
 | 
			
		||||
        { pic-tuple 50 }
 | 
			
		||||
        { pic-hi-tag-tuple 51 }
 | 
			
		||||
        { pic-check-tag 52 }
 | 
			
		||||
        { pic-check 53 }
 | 
			
		||||
        { pic-hit 54 }
 | 
			
		||||
        { pic-miss-word 55 }
 | 
			
		||||
        { pic-miss-tail-word 56 }
 | 
			
		||||
        { mega-lookup 57 }
 | 
			
		||||
        { mega-lookup-word 58 }
 | 
			
		||||
        { mega-miss-word 59 }
 | 
			
		||||
        { undefined-quot 60 }
 | 
			
		||||
    } ; inline
 | 
			
		||||
USERENV: undefined-quot 60
 | 
			
		||||
 | 
			
		||||
: userenv-offset ( symbol -- n )
 | 
			
		||||
    userenvs at header-size + ;
 | 
			
		||||
    userenvs get at header-size + ;
 | 
			
		||||
 | 
			
		||||
: emit ( cell -- ) image get push ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -504,11 +467,7 @@ M: quotation '
 | 
			
		|||
        class<=-cache class-not-cache classes-intersect-cache
 | 
			
		||||
        class-and-cache class-or-cache next-method-quot-cache
 | 
			
		||||
    } [ H{ } clone ] H{ } map>assoc assoc-union
 | 
			
		||||
    bootstrap-global set
 | 
			
		||||
    bootstrap-global emit-userenv ;
 | 
			
		||||
 | 
			
		||||
: emit-boot-quot ( -- )
 | 
			
		||||
    bootstrap-boot-quot emit-userenv ;
 | 
			
		||||
    bootstrap-global set ;
 | 
			
		||||
 | 
			
		||||
: emit-jit-data ( -- )
 | 
			
		||||
    \ if jit-if-word set
 | 
			
		||||
| 
						 | 
				
			
			@ -521,43 +480,10 @@ M: quotation '
 | 
			
		|||
    \ inline-cache-miss-tail \ pic-miss-tail-word set
 | 
			
		||||
    \ mega-cache-lookup \ mega-lookup-word set
 | 
			
		||||
    \ mega-cache-miss \ mega-miss-word set
 | 
			
		||||
    [ undefined ] undefined-quot set
 | 
			
		||||
    {
 | 
			
		||||
        jit-prolog
 | 
			
		||||
        jit-primitive-word
 | 
			
		||||
        jit-primitive
 | 
			
		||||
        jit-word-jump
 | 
			
		||||
        jit-word-call
 | 
			
		||||
        jit-push-immediate
 | 
			
		||||
        jit-if-word
 | 
			
		||||
        jit-if
 | 
			
		||||
        jit-dip-word
 | 
			
		||||
        jit-dip
 | 
			
		||||
        jit-2dip-word
 | 
			
		||||
        jit-2dip
 | 
			
		||||
        jit-3dip-word
 | 
			
		||||
        jit-3dip
 | 
			
		||||
        jit-execute-word
 | 
			
		||||
        jit-execute-jump
 | 
			
		||||
        jit-execute-call
 | 
			
		||||
        jit-epilog
 | 
			
		||||
        jit-return
 | 
			
		||||
        jit-profiling
 | 
			
		||||
        pic-load
 | 
			
		||||
        pic-tag
 | 
			
		||||
        pic-hi-tag
 | 
			
		||||
        pic-tuple
 | 
			
		||||
        pic-hi-tag-tuple
 | 
			
		||||
        pic-check-tag
 | 
			
		||||
        pic-check
 | 
			
		||||
        pic-hit
 | 
			
		||||
        pic-miss-word
 | 
			
		||||
        pic-miss-tail-word
 | 
			
		||||
        mega-lookup
 | 
			
		||||
        mega-lookup-word
 | 
			
		||||
        mega-miss-word
 | 
			
		||||
        undefined-quot
 | 
			
		||||
    } [ emit-userenv ] each ;
 | 
			
		||||
    [ undefined ] undefined-quot set ;
 | 
			
		||||
 | 
			
		||||
: emit-userenvs ( -- )
 | 
			
		||||
    userenvs get keys [ emit-userenv ] each ;
 | 
			
		||||
 | 
			
		||||
: fixup-header ( -- )
 | 
			
		||||
    heap-size data-heap-size-offset fixup ;
 | 
			
		||||
| 
						 | 
				
			
			@ -574,8 +500,8 @@ M: quotation '
 | 
			
		|||
    emit-jit-data
 | 
			
		||||
    "Serializing global namespace..." print flush
 | 
			
		||||
    emit-global
 | 
			
		||||
    "Serializing boot quotation..." print flush
 | 
			
		||||
    emit-boot-quot
 | 
			
		||||
    "Serializing user environment..." print flush
 | 
			
		||||
    emit-userenvs
 | 
			
		||||
    "Performing word fixups..." print flush
 | 
			
		||||
    fixup-words
 | 
			
		||||
    "Performing header fixups..." print flush
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Slava Pestov
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
! Copyright (C) 2009 Slava Pestov.
 | 
			
		||||
! See http://factorcode.org/license.txt for BSD license.
 | 
			
		||||
USING: parser kernel namespaces assocs words.symbol ;
 | 
			
		||||
IN: bootstrap.image.syntax
 | 
			
		||||
 | 
			
		||||
SYMBOL: userenvs
 | 
			
		||||
 | 
			
		||||
SYNTAX: RESET H{ } clone userenvs set-global ;
 | 
			
		||||
 | 
			
		||||
SYNTAX: USERENV:
 | 
			
		||||
    CREATE-WORD scan-word
 | 
			
		||||
    [ swap userenvs get set-at ]
 | 
			
		||||
    [ drop define-symbol ]
 | 
			
		||||
    2bi ;
 | 
			
		||||
| 
						 | 
				
			
			@ -42,13 +42,18 @@ big-endian off
 | 
			
		|||
] jit-push-immediate jit-define
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
    0 JMP rc-relative rt-xt jit-rel
 | 
			
		||||
    temp3 0 MOV rc-absolute-cell rt-here jit-rel
 | 
			
		||||
    0 JMP rc-relative rt-xt-pic-tail jit-rel
 | 
			
		||||
] jit-word-jump jit-define
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
    0 CALL rc-relative rt-xt-pic jit-rel
 | 
			
		||||
] jit-word-call jit-define
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
    0 JMP rc-relative rt-xt jit-rel
 | 
			
		||||
] jit-word-special jit-define
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
    ! load boolean
 | 
			
		||||
    temp0 ds-reg [] MOV
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,8 @@ namespace factor
 | 
			
		|||
 | 
			
		||||
inline static void flush_icache(cell start, cell len) {}
 | 
			
		||||
 | 
			
		||||
static const fixnum xt_tail_pic_offset = 2 * sizeof(cell) + 1;
 | 
			
		||||
 | 
			
		||||
static const unsigned char call_opcode = 0xe8;
 | 
			
		||||
static const unsigned char jmp_opcode = 0xe9;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -144,7 +144,7 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
 | 
			
		|||
	push(methods.value());
 | 
			
		||||
	push(tag_fixnum(index));
 | 
			
		||||
	push(cache_entries.value());
 | 
			
		||||
	word_jump(userenv[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD]);
 | 
			
		||||
	word_special(userenv[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static code_block *compile_inline_cache(fixnum index,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,13 +25,19 @@ struct jit {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	void word_jump(cell word) {
 | 
			
		||||
		emit_with(userenv[JIT_WORD_JUMP],word);
 | 
			
		||||
		literal(tag_fixnum(xt_tail_pic_offset));
 | 
			
		||||
		literal(word);
 | 
			
		||||
		emit(userenv[JIT_WORD_JUMP]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void word_call(cell word) {
 | 
			
		||||
		emit_with(userenv[JIT_WORD_CALL],word);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void word_special(cell word) {
 | 
			
		||||
		emit_with(userenv[JIT_WORD_SPECIAL],word);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void emit_subprimitive(cell word_) {
 | 
			
		||||
		gc_root<word> word(word_);
 | 
			
		||||
		gc_root<array> code_template(word->subprimitive);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -152,7 +152,16 @@ void quotation_jit::iterate_quotation()
 | 
			
		|||
				{
 | 
			
		||||
					if(stack_frame) emit(userenv[JIT_EPILOG]);
 | 
			
		||||
					tail_call = true;
 | 
			
		||||
					word_jump(obj.value());
 | 
			
		||||
					/* Inline cache misses are special-cased */
 | 
			
		||||
					if(obj.value() == userenv[PIC_MISS_WORD]
 | 
			
		||||
					   || obj.value() == userenv[PIC_MISS_TAIL_WORD])
 | 
			
		||||
					{
 | 
			
		||||
						word_special(obj.value());
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						word_jump(obj.value());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					word_call(obj.value());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,13 +41,14 @@ enum special_object {
 | 
			
		|||
	JIT_PRIMITIVE,
 | 
			
		||||
	JIT_WORD_JUMP,
 | 
			
		||||
	JIT_WORD_CALL,
 | 
			
		||||
	JIT_WORD_SPECIAL,
 | 
			
		||||
	JIT_IF_WORD,
 | 
			
		||||
	JIT_IF,
 | 
			
		||||
	JIT_EPILOG          = 33,
 | 
			
		||||
	JIT_EPILOG,
 | 
			
		||||
	JIT_RETURN,
 | 
			
		||||
	JIT_PROFILING,
 | 
			
		||||
	JIT_PUSH_IMMEDIATE,
 | 
			
		||||
	JIT_DIP_WORD        = 38,
 | 
			
		||||
	JIT_DIP_WORD,
 | 
			
		||||
	JIT_DIP,
 | 
			
		||||
	JIT_2DIP_WORD,
 | 
			
		||||
	JIT_2DIP,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue