Early binding JIT work in progress

db4
Slava Pestov 2007-12-26 02:33:49 -05:00
parent c09af2f2c6
commit 4bb2a43a10
12 changed files with 131 additions and 52 deletions

View File

@ -50,17 +50,15 @@ big-endian off
] rc-relative rt-primitive 12 jit-word-primitive-call jit-define
[
arg0 scan-reg bootstrap-cell [+] MOV ! load word
arg0 word-xt@ [+] JMP ! jump to word XT
] f f f jit-word-jump jit-define
(JMP) drop
] rc-relative rt-xt 1 jit-word-jump jit-define
[
advance-scan
scan-save scan-reg MOV ! save scan pointer
arg0 scan-reg [] MOV ! load word
arg0 word-xt@ [+] CALL ! call word XT
(CALL) drop
scan-reg scan-save MOV ! restore scan pointer
] f f f jit-word-call jit-define
] rc-relative rt-xt 8 jit-word-call jit-define
[
arg1 0 MOV ! load addr of true quotation

View File

@ -378,7 +378,7 @@ void forward_object_xts(void)
{
F_WORD *word = untag_object(obj);
if(word->compiledp != F)
if(word_references_code_heap_p(word))
word->code = forward_xt(word->code);
}
else if(type_of(obj) == QUOTATION_TYPE)
@ -414,6 +414,8 @@ void fixup_object_xts(void)
if(word->compiledp != F)
set_word_xt(word,word->code);
else
word->xt = word->code + sizeof(F_COMPILED);
}
else if(type_of(obj) == QUOTATION_TYPE)
{

View File

@ -38,11 +38,6 @@ void *get_rel_symbol(F_REL *rel, CELL literals_start)
static CELL xt_offset;
void incompatible_call_error(void)
{
critical_error("Calling non-optimized word from optimized word",0);
}
/* Compute an address to store at a relocation */
INLINE CELL compute_code_rel(F_REL *rel,
CELL code_start, CELL literals_start, CELL words_start)
@ -62,15 +57,12 @@ INLINE CELL compute_code_rel(F_REL *rel,
case RT_XT:
word = untag_word(get(CREF(words_start,REL_ARGUMENT(rel))));
if(word->compiledp == F)
return (CELL)incompatible_call_error;
return (CELL)word->code + sizeof(F_COMPILED);
else
return (CELL)word->code + sizeof(F_COMPILED) + xt_offset;
case RT_XT_PROFILING:
word = untag_word(get(CREF(words_start,REL_ARGUMENT(rel))));
if(word->compiledp == F)
return (CELL)incompatible_call_error;
else
return (CELL)word->code + sizeof(F_COMPILED);
return (CELL)word->code + sizeof(F_COMPILED);
case RT_LABEL:
return code_start + REL_ARGUMENT(rel);
default:
@ -347,7 +339,19 @@ DEFINE_PRIMITIVE(modify_code_heap)
if(data == F)
{
word->compiledp = F;
word->xt = default_word_xt(word);
if(type_of(word->def) == QUOTATION_TYPE)
{
REGISTER_UNTAGGED(alist);
REGISTER_UNTAGGED(word);
jit_compile(word->def);
UNREGISTER_UNTAGGED(word);
UNREGISTER_UNTAGGED(alist);
}
default_word_xt(word);
}
else
{

View File

@ -557,7 +557,7 @@ CELL collect_next(CELL scan)
{
case WORD_TYPE:
word = (F_WORD *)scan;
if(collecting_code && word->compiledp != F)
if(collecting_code && word_references_code_heap_p(word))
recursive_mark(compiled_to_block(word->code));
break;
case QUOTATION_TYPE:

View File

@ -29,6 +29,39 @@ void default_parameters(F_PARAMETERS *p)
p->console = false;
}
/* Do some initialization that we do once only */
void do_stage1_init(void)
{
fprintf(stderr,"*** Starting stage 2 early init...\n");
fflush(stderr);
begin_scan();
CELL obj;
while((obj = next_object()) != F)
{
if(type_of(obj) == WORD_TYPE)
{
F_WORD *word = untag_object(obj);
if(type_of(word->def) == QUOTATION_TYPE)
{
jit_compile(word->def);
default_word_xt(word);
}
}
}
/* End heap scan */
gc_off = false;
iterate_code_heap(finalize_code_block);
userenv[STAGE2_ENV] = T;
fprintf(stderr,"*** Finished stage 2 early init\n");
fflush(stderr);
}
/* Get things started */
void init_factor(F_PARAMETERS *p)
{
@ -69,6 +102,9 @@ void init_factor(F_PARAMETERS *p)
/* We can GC now */
gc_off = false;
if(!stage2)
do_stage1_init();
}
INLINE bool factor_arg(const F_CHAR* str, const F_CHAR* arg, CELL* value)

View File

@ -9,6 +9,8 @@ void init_objects(F_HEADER *h)
bignum_zero = h->bignum_zero;
bignum_pos_one = h->bignum_pos_one;
bignum_neg_one = h->bignum_neg_one;
stage2 = (userenv[STAGE2_ENV] != F);
}
INLINE void load_data_heap(FILE *file, F_HEADER *h, F_PARAMETERS *p)
@ -176,12 +178,25 @@ void fixup_word(F_WORD *word)
/* If this is a compiled word, relocate the code pointer. Otherwise,
reset it based on the primitive number of the word. */
if(word->compiledp == F)
word->xt = default_word_xt(word);
else
{
code_fixup((CELL)&word->xt);
code_fixup((CELL)&word->code);
if(type_of(word->def) == QUOTATION_TYPE)
{
if(!stage2)
{
/* Word XTs are fixed up in do_stage1_init() */
return;
}
}
else
{
/* Primitive or undefined */
default_word_xt(word);
return;
}
}
code_fixup((CELL)&word->xt);
code_fixup((CELL)&word->code);
}
void fixup_quotation(F_QUOTATION *quot)

17
vm/profiler.c Normal file → Executable file
View File

@ -8,16 +8,13 @@ bool profiling_p(void)
void profiling_word(F_WORD *word)
{
/* If we just enabled the profiler, reset call count */
if(profiling_p())
word->counter = tag_fixnum(0);
if(word->compiledp == F)
{
if(type_of(word->def) == QUOTATION_TYPE)
word->xt = default_word_xt(word);
}
else
set_word_xt(word,word->code);
// if(profiling_p())
// word->counter = tag_fixnum(0);
//
// if(word->compiledp == F)
// default_word_xt(word);
// else
// set_word_xt(word,word->code);
}
void set_profiling(bool profiling)

View File

@ -90,6 +90,9 @@ void set_quot_xt(F_QUOTATION *quot, F_COMPILED *code)
/* Might GC */
void jit_compile(CELL quot)
{
if(untag_quotation(quot)->compiledp != F)
return;
CELL code_format = compiled_code_format();
REGISTER_ROOT(quot);
@ -149,7 +152,11 @@ void jit_compile(CELL quot)
to_fixnum(word->def));
}
else
EMIT(JIT_WORD_JUMP,0);
{
GROWABLE_ADD(words,array_nth(untag_object(array),i));
EMIT(JIT_WORD_JUMP,words_count - 1);
}
tail_call = true;
}
else
@ -160,7 +167,10 @@ void jit_compile(CELL quot)
to_fixnum(word->def));
}
else
EMIT(JIT_WORD_CALL,0);
{
GROWABLE_ADD(words,array_nth(untag_object(array),i));
EMIT(JIT_WORD_CALL,words_count - 1);
}
}
break;
case WRAPPER_TYPE:

View File

@ -259,19 +259,27 @@ DEFINE_PRIMITIVE(set_retainstack)
rs = array_to_stack(untag_array(dpop()),rs_bot);
}
XT default_word_xt(F_WORD *word)
void default_word_xt(F_WORD *word)
{
if(type_of(word->def) == QUOTATION_TYPE)
{
if(profiling_p())
return docol_profiling;
else
return docol;
F_QUOTATION *quot = untag_quotation(word->def);
if(quot->compiledp == F)
critical_error("default_word_xt invariant lost",0);
word->xt = quot->xt;
word->code = quot->code;
//if(profiling_p())
// word->xt = docol_profiling;
//else
// word->xt = docol;
}
else if(type_of(word->def) == FIXNUM_TYPE)
return primitives[to_fixnum(word->def)];
word->xt = primitives[to_fixnum(word->def)];
else if(word->def == F)
word->xt = undefined;
else
return undefined;
critical_error("bad word-def",tag_object(word));
}
DEFINE_PRIMITIVE(getenv)

View File

@ -7,21 +7,21 @@ typedef enum {
CURRENT_CALLBACK_ENV = 2, /* used by library only, per-callback */
WALKER_HOOK_ENV, /* non-local exit hook, used by library only */
CALLCC_1_ENV, /* used to pass the value in callcc1 */
BREAK_ENV = 5, /* quotation called by throw primitive */
ERROR_ENV, /* a marker consed onto kernel errors */
CELL_SIZE_ENV = 7, /* sizeof(CELL) */
CPU_ENV, /* CPU architecture */
OS_ENV, /* operating system name */
ARGS_ENV = 10, /* command line arguments */
IN_ENV, /* stdin FILE* handle */
OUT_ENV, /* stdout FILE* handle */
IMAGE_ENV = 13, /* image path name */
EXECUTABLE_ENV, /* runtime executable path name */
EMBEDDED_ENV = 15, /* are we embedded in another app? */
EVAL_CALLBACK_ENV, /* used when Factor is embedded in a C app */
YIELD_CALLBACK_ENV, /* used when Factor is embedded in a C app */
@ -40,18 +40,20 @@ typedef enum {
JIT_WORD_PRIMITIVE_CALL,
JIT_WORD_JUMP,
JIT_WORD_CALL,
JIT_PUSH_WRAPPER,
UNUSED_1,
JIT_PUSH_LITERAL,
JIT_IF_WORD,
JIT_IF_JUMP,
JIT_IF_CALL,
UNUSED_2,
JIT_DISPATCH_WORD,
JIT_DISPATCH,
JIT_EPILOG,
JIT_RETURN,
/* Profiler support */
/* Profiler support */
PROFILING_ENV = 38, /* is the profiler on? */
STAGE2_ENV = 39 /* Have we bootstrapped? */
} F_ENVTYPE;
#define FIRST_SAVE_ENV BOOT_ENV
@ -223,7 +225,7 @@ DECLARE_PRIMITIVE(from_r);
DECLARE_PRIMITIVE(datastack);
DECLARE_PRIMITIVE(retainstack);
XT default_word_xt(F_WORD *word);
void default_word_xt(F_WORD *word);
DECLARE_PRIMITIVE(execute);
DECLARE_PRIMITIVE(call);
@ -240,3 +242,5 @@ DECLARE_PRIMITIVE(tag);
DECLARE_PRIMITIVE(class_hash);
DECLARE_PRIMITIVE(slot);
DECLARE_PRIMITIVE(set_slot);
bool stage2;

View File

@ -463,7 +463,7 @@ F_WORD *allot_word(CELL vocab, CELL name)
word->props = F;
word->counter = tag_fixnum(0);
word->compiledp = F;
word->xt = default_word_xt(word);
word->xt = undefined;
return word;
}

View File

@ -109,6 +109,11 @@ INLINE F_QUOTATION *untag_quotation(CELL tagged)
return untag_object(tagged);
}
INLINE bool word_references_code_heap_p(F_WORD *word)
{
return (word->compiledp != F || type_of(word->def) == QUOTATION_TYPE);
}
INLINE F_WORD *untag_word(CELL tagged)
{
type_check(WORD_TYPE,tagged);