vm: strip out call-counting profiler
This makes the separate "code" and "entry_point" fields in word and quotation redundant, so also remove them to reclaim an additional cell per word and quotation object, which should help with #318.db4
parent
139c9ca38c
commit
c31530caec
|
@ -34,7 +34,6 @@ ifdef CONFIG
|
||||||
vm/code_heap.o \
|
vm/code_heap.o \
|
||||||
vm/compaction.o \
|
vm/compaction.o \
|
||||||
vm/contexts.o \
|
vm/contexts.o \
|
||||||
vm/counting_profiler.o \
|
|
||||||
vm/data_heap.o \
|
vm/data_heap.o \
|
||||||
vm/data_heap_checker.o \
|
vm/data_heap_checker.o \
|
||||||
vm/debug.o \
|
vm/debug.o \
|
||||||
|
@ -77,7 +76,6 @@ ifdef CONFIG
|
||||||
vm/contexts.hpp \
|
vm/contexts.hpp \
|
||||||
vm/run.hpp \
|
vm/run.hpp \
|
||||||
vm/objects.hpp \
|
vm/objects.hpp \
|
||||||
vm/counting_profiler.hpp \
|
|
||||||
vm/sampling_profiler.hpp \
|
vm/sampling_profiler.hpp \
|
||||||
vm/errors.hpp \
|
vm/errors.hpp \
|
||||||
vm/bignumint.hpp \
|
vm/bignumint.hpp \
|
||||||
|
|
|
@ -37,7 +37,6 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
|
||||||
vm\code_heap.obj \
|
vm\code_heap.obj \
|
||||||
vm\compaction.obj \
|
vm\compaction.obj \
|
||||||
vm\contexts.obj \
|
vm\contexts.obj \
|
||||||
vm\counting_profiler.obj \
|
|
||||||
vm\data_heap.obj \
|
vm\data_heap.obj \
|
||||||
vm\data_heap_checker.obj \
|
vm\data_heap_checker.obj \
|
||||||
vm\debug.obj \
|
vm\debug.obj \
|
||||||
|
|
|
@ -350,11 +350,8 @@ M: f ' drop \ f type-number ;
|
||||||
[ props>> , ]
|
[ props>> , ]
|
||||||
[ pic-def>> , ]
|
[ pic-def>> , ]
|
||||||
[ pic-tail-def>> , ]
|
[ pic-tail-def>> , ]
|
||||||
[ drop 0 , ] ! count
|
|
||||||
[ word-sub-primitive , ]
|
[ word-sub-primitive , ]
|
||||||
[ drop 0 , ] ! xt
|
[ drop 0 , ] ! entry point
|
||||||
[ drop 0 , ] ! code
|
|
||||||
[ drop 0 , ] ! profiling
|
|
||||||
} cleave
|
} cleave
|
||||||
] { } make [ ' ] map
|
] { } make [ ' ] map
|
||||||
] bi
|
] bi
|
||||||
|
@ -493,8 +490,7 @@ M: quotation '
|
||||||
emit ! array
|
emit ! array
|
||||||
f ' emit ! cached-effect
|
f ' emit ! cached-effect
|
||||||
f ' emit ! cache-counter
|
f ' emit ! cache-counter
|
||||||
0 emit ! xt
|
0 emit ! entry point
|
||||||
0 emit ! code
|
|
||||||
] emit-object
|
] emit-object
|
||||||
] cache-eql-object ;
|
] cache-eql-object ;
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ CONSTANT: deck-bits 18
|
||||||
: alien-offset ( -- n ) 4 alien type-number slot-offset ; inline
|
: alien-offset ( -- n ) 4 alien type-number slot-offset ; inline
|
||||||
: underlying-alien-offset ( -- n ) 1 alien type-number slot-offset ; inline
|
: underlying-alien-offset ( -- n ) 1 alien type-number slot-offset ; inline
|
||||||
: tuple-class-offset ( -- n ) 1 tuple type-number slot-offset ; inline
|
: tuple-class-offset ( -- n ) 1 tuple type-number slot-offset ; inline
|
||||||
: word-entry-point-offset ( -- n ) 10 \ word type-number slot-offset ; inline
|
: word-entry-point-offset ( -- n ) 9 \ word type-number slot-offset ; inline
|
||||||
: quot-entry-point-offset ( -- n ) 4 quotation type-number slot-offset ; inline
|
: quot-entry-point-offset ( -- n ) 4 quotation type-number slot-offset ; inline
|
||||||
: word-code-offset ( -- n ) 11 \ word type-number slot-offset ; inline
|
: code-block-entry-point-offset ( -- n ) 4 bootstrap-cells ; inline
|
||||||
: array-start-offset ( -- n ) 2 array type-number slot-offset ; inline
|
: array-start-offset ( -- n ) 2 array type-number slot-offset ; inline
|
||||||
: compiled-header-size ( -- n ) 4 bootstrap-cells ; inline
|
: compiled-header-size ( -- n ) 4 bootstrap-cells ; inline
|
||||||
: callstack-length-offset ( -- n ) 1 \ callstack type-number slot-offset ; inline
|
: callstack-length-offset ( -- n ) 1 \ callstack type-number slot-offset ; inline
|
||||||
|
|
|
@ -76,19 +76,6 @@ big-endian off
|
||||||
HEX: ffff RET f rc-absolute-2 rel-untagged
|
HEX: ffff RET f rc-absolute-2 rel-untagged
|
||||||
] callback-stub jit-define
|
] callback-stub jit-define
|
||||||
|
|
||||||
[
|
|
||||||
! Load word
|
|
||||||
temp0 0 MOV f rc-absolute-cell rel-literal
|
|
||||||
! Bump profiling counter
|
|
||||||
temp0 profile-count-offset [+] 1 tag-fixnum ADD
|
|
||||||
! Load word->code
|
|
||||||
temp0 temp0 word-code-offset [+] MOV
|
|
||||||
! Compute word entry point
|
|
||||||
temp0 compiled-header-size ADD
|
|
||||||
! Jump to entry point
|
|
||||||
temp0 JMP
|
|
||||||
] jit-profiling jit-define
|
|
||||||
|
|
||||||
[
|
[
|
||||||
! load literal
|
! load literal
|
||||||
temp0 0 MOV f rc-absolute-cell rel-literal
|
temp0 0 MOV f rc-absolute-cell rel-literal
|
||||||
|
|
|
@ -241,7 +241,6 @@ bi
|
||||||
"props"
|
"props"
|
||||||
"pic-def"
|
"pic-def"
|
||||||
"pic-tail-def"
|
"pic-tail-def"
|
||||||
{ "counter" { "fixnum" "math" } }
|
|
||||||
{ "sub-primitive" read-only }
|
{ "sub-primitive" read-only }
|
||||||
} define-builtin
|
} define-builtin
|
||||||
|
|
||||||
|
|
|
@ -59,19 +59,15 @@ void code_block_visitor<Fixup>::visit_object_code_block(object *obj)
|
||||||
case WORD_TYPE:
|
case WORD_TYPE:
|
||||||
{
|
{
|
||||||
word *w = (word *)obj;
|
word *w = (word *)obj;
|
||||||
if(w->code)
|
if(w->entry_point)
|
||||||
w->code = visit_code_block(w->code);
|
w->entry_point = visit_code_block(w->code())->entry_point();
|
||||||
if(w->counting_profiler)
|
|
||||||
w->counting_profiler = visit_code_block(w->counting_profiler);
|
|
||||||
|
|
||||||
parent->update_word_entry_point(w);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUOTATION_TYPE:
|
case QUOTATION_TYPE:
|
||||||
{
|
{
|
||||||
quotation *q = (quotation *)obj;
|
quotation *q = (quotation *)obj;
|
||||||
if(q->code)
|
if(q->entry_point)
|
||||||
parent->set_quot_entry_point(q,visit_code_block(q->code));
|
q->entry_point = visit_code_block(q->code())->entry_point();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CALLSTACK_TYPE:
|
case CALLSTACK_TYPE:
|
||||||
|
|
|
@ -84,4 +84,17 @@ struct code_block
|
||||||
};
|
};
|
||||||
|
|
||||||
VM_C_API void undefined_symbol(void);
|
VM_C_API void undefined_symbol(void);
|
||||||
|
|
||||||
|
inline code_block *word::code() const {
|
||||||
|
assert(entry_point != NULL);
|
||||||
|
return (code_block*)entry_point - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline code_block *quotation::code() const {
|
||||||
|
assert(entry_point != NULL);
|
||||||
|
return (code_block*)entry_point - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -178,15 +178,13 @@ void factor_vm::primitive_modify_code_heap()
|
||||||
parameters,
|
parameters,
|
||||||
literals);
|
literals);
|
||||||
|
|
||||||
word->code = compiled;
|
word->entry_point = compiled->entry_point();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
critical_error("Expected a quotation or an array",data.value());
|
critical_error("Expected a quotation or an array",data.value());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_word_entry_point(word.untagged());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(update_existing_words)
|
if(update_existing_words)
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
#include "master.hpp"
|
|
||||||
|
|
||||||
namespace factor
|
|
||||||
{
|
|
||||||
|
|
||||||
void factor_vm::init_counting_profiler()
|
|
||||||
{
|
|
||||||
counting_profiler_p = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocates memory */
|
|
||||||
code_block *factor_vm::compile_counting_profiler_stub(cell word_)
|
|
||||||
{
|
|
||||||
data_root<word> word(word_,this);
|
|
||||||
|
|
||||||
jit jit(code_block_counting_profiler,word.value(),this);
|
|
||||||
jit.emit_with_literal(special_objects[JIT_PROFILING],word.value());
|
|
||||||
|
|
||||||
return jit.to_code_block();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocates memory */
|
|
||||||
void factor_vm::set_counting_profiler(bool counting_profiler)
|
|
||||||
{
|
|
||||||
if(counting_profiler == counting_profiler_p)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Push everything to tenured space so that we can heap scan
|
|
||||||
and allocate counting_profiler blocks if necessary */
|
|
||||||
primitive_full_gc();
|
|
||||||
|
|
||||||
data_root<array> words(find_all_words(),this);
|
|
||||||
|
|
||||||
counting_profiler_p = counting_profiler;
|
|
||||||
|
|
||||||
cell length = array_capacity(words.untagged());
|
|
||||||
for(cell i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
tagged<word> word(array_nth(words.untagged(),i));
|
|
||||||
|
|
||||||
/* Note: can't do w->counting_profiler = ... since LHS evaluates
|
|
||||||
before RHS, and if RHS does a GC, we will have an
|
|
||||||
invalid pointer on the LHS */
|
|
||||||
if(counting_profiler)
|
|
||||||
{
|
|
||||||
if(!word->counting_profiler)
|
|
||||||
{
|
|
||||||
code_block *counting_profiler_block = compile_counting_profiler_stub(word.value());
|
|
||||||
word->counting_profiler = counting_profiler_block;
|
|
||||||
}
|
|
||||||
|
|
||||||
word->counter = tag_fixnum(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
update_word_entry_point(word.untagged());
|
|
||||||
}
|
|
||||||
|
|
||||||
update_code_heap_words(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void factor_vm::primitive_counting_profiler()
|
|
||||||
{
|
|
||||||
set_counting_profiler(to_boolean(ctx->pop()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
namespace factor
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -63,7 +63,7 @@ void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler)
|
||||||
else
|
else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
||||||
*pc = (cell)handler_word->code->entry_point();
|
*pc = (cell)handler_word->entry_point;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,18 +22,14 @@ void factor_vm::c_to_factor(cell quot)
|
||||||
|
|
||||||
template<typename Func> Func factor_vm::get_entry_point(cell n)
|
template<typename Func> Func factor_vm::get_entry_point(cell n)
|
||||||
{
|
{
|
||||||
/* We return word->code->entry_point() and not word->entry_point,
|
|
||||||
because if the counting profiler is enabled, we don't want to go through the
|
|
||||||
entry point's counting profiler stub. This clobbers registers, since entry
|
|
||||||
points use the C ABI and not the Factor ABI. */
|
|
||||||
tagged<word> entry_point_word(special_objects[n]);
|
tagged<word> entry_point_word(special_objects[n]);
|
||||||
return (Func)entry_point_word->code->entry_point();
|
return (Func)entry_point_word->entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::unwind_native_frames(cell quot, stack_frame *to)
|
void factor_vm::unwind_native_frames(cell quot, stack_frame *to)
|
||||||
{
|
{
|
||||||
tagged<word> entry_point_word(special_objects[UNWIND_NATIVE_FRAMES_WORD]);
|
tagged<word> entry_point_word(special_objects[UNWIND_NATIVE_FRAMES_WORD]);
|
||||||
void *func = entry_point_word->code->entry_point();
|
void *func = entry_point_word->entry_point;
|
||||||
CODE_TO_FUNCTION_POINTER(func);
|
CODE_TO_FUNCTION_POINTER(func);
|
||||||
((unwind_native_frames_func_type)func)(quot,to);
|
((unwind_native_frames_func_type)func)(quot,to);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +37,7 @@ void factor_vm::unwind_native_frames(cell quot, stack_frame *to)
|
||||||
cell factor_vm::get_fpu_state()
|
cell factor_vm::get_fpu_state()
|
||||||
{
|
{
|
||||||
tagged<word> entry_point_word(special_objects[GET_FPU_STATE_WORD]);
|
tagged<word> entry_point_word(special_objects[GET_FPU_STATE_WORD]);
|
||||||
void *func = entry_point_word->code->entry_point();
|
void *func = entry_point_word->entry_point;
|
||||||
CODE_TO_FUNCTION_POINTER(func);
|
CODE_TO_FUNCTION_POINTER(func);
|
||||||
return ((get_fpu_state_func_type)func)();
|
return ((get_fpu_state_func_type)func)();
|
||||||
}
|
}
|
||||||
|
@ -49,7 +45,7 @@ cell factor_vm::get_fpu_state()
|
||||||
void factor_vm::set_fpu_state(cell state)
|
void factor_vm::set_fpu_state(cell state)
|
||||||
{
|
{
|
||||||
tagged<word> entry_point_word(special_objects[SET_FPU_STATE_WORD]);
|
tagged<word> entry_point_word(special_objects[SET_FPU_STATE_WORD]);
|
||||||
void *func = entry_point_word->code->entry_point();
|
void *func = entry_point_word->entry_point;
|
||||||
CODE_TO_FUNCTION_POINTER(func);
|
CODE_TO_FUNCTION_POINTER(func);
|
||||||
((set_fpu_state_func_type)func)(state);
|
((set_fpu_state_func_type)func)(state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Simple code generator used by:
|
/* Simple code generator used by:
|
||||||
- counting_profiler (counting_profiler.cpp),
|
|
||||||
- quotation compiler (quotations.cpp),
|
- quotation compiler (quotations.cpp),
|
||||||
- megamorphic caches (dispatch.cpp),
|
- megamorphic caches (dispatch.cpp),
|
||||||
- polymorphic inline caches (inline_cache.cpp) */
|
- polymorphic inline caches (inline_cache.cpp) */
|
||||||
|
|
|
@ -98,7 +98,6 @@ enum code_block_type
|
||||||
{
|
{
|
||||||
code_block_unoptimized,
|
code_block_unoptimized,
|
||||||
code_block_optimized,
|
code_block_optimized,
|
||||||
code_block_counting_profiler,
|
|
||||||
code_block_pic
|
code_block_pic
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -253,7 +252,11 @@ struct string : public object {
|
||||||
|
|
||||||
struct code_block;
|
struct code_block;
|
||||||
|
|
||||||
/* Assembly code makes assumptions about the layout of this struct */
|
/* Assembly code makes assumptions about the layout of this struct:
|
||||||
|
basis/bootstrap/images/images.factor
|
||||||
|
basis/compiler/constants/constants.factor
|
||||||
|
core/bootstrap/primitives.factor
|
||||||
|
*/
|
||||||
struct word : public object {
|
struct word : public object {
|
||||||
static const cell type_number = WORD_TYPE;
|
static const cell type_number = WORD_TYPE;
|
||||||
/* TAGGED hashcode */
|
/* TAGGED hashcode */
|
||||||
|
@ -270,16 +273,14 @@ struct word : public object {
|
||||||
cell pic_def;
|
cell pic_def;
|
||||||
/* TAGGED alternative entry point for direct tail calls. Used for inline caching */
|
/* TAGGED alternative entry point for direct tail calls. Used for inline caching */
|
||||||
cell pic_tail_def;
|
cell pic_tail_def;
|
||||||
/* TAGGED call count for counting_profiler */
|
|
||||||
cell counter;
|
|
||||||
/* TAGGED machine code for sub-primitive */
|
/* TAGGED machine code for sub-primitive */
|
||||||
cell subprimitive;
|
cell subprimitive;
|
||||||
/* UNTAGGED entry point: jump here to execute word */
|
/* UNTAGGED entry point: jump here to execute word */
|
||||||
void *entry_point;
|
void *entry_point;
|
||||||
/* UNTAGGED compiled code block */
|
/* UNTAGGED compiled code block */
|
||||||
code_block *code;
|
|
||||||
/* UNTAGGED counting_profiler stub */
|
/* defined in code_blocks.hpp */
|
||||||
code_block *counting_profiler;
|
code_block *code() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Assembly code makes assumptions about the layout of this struct */
|
/* Assembly code makes assumptions about the layout of this struct */
|
||||||
|
@ -299,7 +300,11 @@ struct boxed_float : object {
|
||||||
double n;
|
double n;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Assembly code makes assumptions about the layout of this struct */
|
/* Assembly code makes assumptions about the layout of this struct:
|
||||||
|
basis/bootstrap/images/images.factor
|
||||||
|
basis/compiler/constants/constants.factor
|
||||||
|
core/bootstrap/primitives.factor
|
||||||
|
*/
|
||||||
struct quotation : public object {
|
struct quotation : public object {
|
||||||
static const cell type_number = QUOTATION_TYPE;
|
static const cell type_number = QUOTATION_TYPE;
|
||||||
/* tagged */
|
/* tagged */
|
||||||
|
@ -310,8 +315,9 @@ struct quotation : public object {
|
||||||
cell cache_counter;
|
cell cache_counter;
|
||||||
/* UNTAGGED entry point; jump here to call quotation */
|
/* UNTAGGED entry point; jump here to call quotation */
|
||||||
void *entry_point;
|
void *entry_point;
|
||||||
/* UNTAGGED compiled code block */
|
|
||||||
code_block *code;
|
/* defined in code_blocks.hpp */
|
||||||
|
code_block *code() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Assembly code makes assumptions about the layout of this struct */
|
/* Assembly code makes assumptions about the layout of this struct */
|
||||||
|
|
|
@ -96,7 +96,6 @@ namespace factor
|
||||||
#include "contexts.hpp"
|
#include "contexts.hpp"
|
||||||
#include "run.hpp"
|
#include "run.hpp"
|
||||||
#include "objects.hpp"
|
#include "objects.hpp"
|
||||||
#include "counting_profiler.hpp"
|
|
||||||
#include "sampling_profiler.hpp"
|
#include "sampling_profiler.hpp"
|
||||||
#include "errors.hpp"
|
#include "errors.hpp"
|
||||||
#include "bignumint.hpp"
|
#include "bignumint.hpp"
|
||||||
|
|
|
@ -46,7 +46,6 @@ namespace factor
|
||||||
_(context_object) \
|
_(context_object) \
|
||||||
_(context_object_for) \
|
_(context_object_for) \
|
||||||
_(current_callback) \
|
_(current_callback) \
|
||||||
_(counting_profiler) \
|
|
||||||
_(data_room) \
|
_(data_room) \
|
||||||
_(datastack) \
|
_(datastack) \
|
||||||
_(datastack_for) \
|
_(datastack_for) \
|
||||||
|
|
|
@ -284,12 +284,6 @@ void quotation_jit::iterate_quotation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::set_quot_entry_point(quotation *quot, code_block *code)
|
|
||||||
{
|
|
||||||
quot->code = code;
|
|
||||||
quot->entry_point = code->entry_point();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
code_block *factor_vm::jit_compile_quot(cell owner_, cell quot_, bool relocating)
|
code_block *factor_vm::jit_compile_quot(cell owner_, cell quot_, bool relocating)
|
||||||
{
|
{
|
||||||
|
@ -313,7 +307,7 @@ void factor_vm::jit_compile_quot(cell quot_, bool relocating)
|
||||||
if(!quot_compiled_p(quot.untagged()))
|
if(!quot_compiled_p(quot.untagged()))
|
||||||
{
|
{
|
||||||
code_block *compiled = jit_compile_quot(quot.value(),quot.value(),relocating);
|
code_block *compiled = jit_compile_quot(quot.value(),quot.value(),relocating);
|
||||||
set_quot_entry_point(quot.untagged(),compiled);
|
quot.untagged()->entry_point = compiled->entry_point();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,9 +316,9 @@ void factor_vm::primitive_jit_compile()
|
||||||
jit_compile_quot(ctx->pop(),true);
|
jit_compile_quot(ctx->pop(),true);
|
||||||
}
|
}
|
||||||
|
|
||||||
code_block *factor_vm::lazy_jit_compile_block()
|
void *factor_vm::lazy_jit_compile_entry_point()
|
||||||
{
|
{
|
||||||
return untag<word>(special_objects[LAZY_JIT_COMPILE_WORD])->code;
|
return untag<word>(special_objects[LAZY_JIT_COMPILE_WORD])->entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push a new quotation on the stack */
|
/* push a new quotation on the stack */
|
||||||
|
@ -335,7 +329,7 @@ void factor_vm::primitive_array_to_quotation()
|
||||||
quot->array = ctx->peek();
|
quot->array = ctx->peek();
|
||||||
quot->cached_effect = false_object;
|
quot->cached_effect = false_object;
|
||||||
quot->cache_counter = false_object;
|
quot->cache_counter = false_object;
|
||||||
set_quot_entry_point(quot,lazy_jit_compile_block());
|
quot->entry_point = lazy_jit_compile_entry_point();
|
||||||
|
|
||||||
ctx->replace(tag<quotation>(quot));
|
ctx->replace(tag<quotation>(quot));
|
||||||
}
|
}
|
||||||
|
@ -344,8 +338,8 @@ void factor_vm::primitive_quotation_code()
|
||||||
{
|
{
|
||||||
quotation *quot = untag_check<quotation>(ctx->pop());
|
quotation *quot = untag_check<quotation>(ctx->pop());
|
||||||
|
|
||||||
ctx->push(from_unsigned_cell((cell)quot->code->entry_point()));
|
ctx->push(from_unsigned_cell((cell)quot->entry_point));
|
||||||
ctx->push(from_unsigned_cell((cell)quot->code + quot->code->size()));
|
ctx->push(from_unsigned_cell((cell)quot->code() + quot->code()->size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
|
@ -369,7 +363,7 @@ cell factor_vm::lazy_jit_compile(cell quot_)
|
||||||
assert(!quot_compiled_p(quot.untagged()));
|
assert(!quot_compiled_p(quot.untagged()));
|
||||||
|
|
||||||
code_block *compiled = jit_compile_quot(quot.value(),quot.value(),true);
|
code_block *compiled = jit_compile_quot(quot.value(),quot.value(),true);
|
||||||
set_quot_entry_point(quot.untagged(),compiled);
|
quot.untagged()->entry_point = compiled->entry_point();
|
||||||
|
|
||||||
return quot.value();
|
return quot.value();
|
||||||
}
|
}
|
||||||
|
@ -381,7 +375,7 @@ VM_C_API cell lazy_jit_compile(cell quot, factor_vm *parent)
|
||||||
|
|
||||||
bool factor_vm::quot_compiled_p(quotation *quot)
|
bool factor_vm::quot_compiled_p(quotation *quot)
|
||||||
{
|
{
|
||||||
return quot->code != NULL && quot->code != lazy_jit_compile_block();
|
return quot->entry_point != NULL && quot->entry_point != lazy_jit_compile_entry_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_quot_compiled_p()
|
void factor_vm::primitive_quot_compiled_p()
|
||||||
|
@ -404,8 +398,8 @@ void factor_vm::initialize_all_quotations()
|
||||||
for(cell i = 0; i < length; i++)
|
for(cell i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
data_root<quotation> quot(array_nth(quotations.untagged(),i),this);
|
data_root<quotation> quot(array_nth(quotations.untagged(),i),this);
|
||||||
if(!quot->code)
|
if(!quot->entry_point)
|
||||||
set_quot_entry_point(quot.untagged(),lazy_jit_compile_block());
|
quot.untagged()->entry_point = lazy_jit_compile_entry_point();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,13 +65,13 @@ cell object::binary_payload_start(Fixup fixup) const
|
||||||
return 0;
|
return 0;
|
||||||
/* these objects have some binary data at the end */
|
/* these objects have some binary data at the end */
|
||||||
case WORD_TYPE:
|
case WORD_TYPE:
|
||||||
return sizeof(word) - sizeof(cell) * 3;
|
return sizeof(word) - sizeof(cell);
|
||||||
case ALIEN_TYPE:
|
case ALIEN_TYPE:
|
||||||
return sizeof(cell) * 3;
|
return sizeof(cell) * 3;
|
||||||
case DLL_TYPE:
|
case DLL_TYPE:
|
||||||
return sizeof(cell) * 2;
|
return sizeof(cell) * 2;
|
||||||
case QUOTATION_TYPE:
|
case QUOTATION_TYPE:
|
||||||
return sizeof(quotation) - sizeof(cell) * 2;
|
return sizeof(quotation) - sizeof(cell);
|
||||||
case STRING_TYPE:
|
case STRING_TYPE:
|
||||||
return sizeof(string);
|
return sizeof(string);
|
||||||
/* everything else consists entirely of pointers */
|
/* everything else consists entirely of pointers */
|
||||||
|
|
|
@ -8,7 +8,6 @@ factor_vm::factor_vm(THREADHANDLE thread) :
|
||||||
thread(thread),
|
thread(thread),
|
||||||
callback_id(0),
|
callback_id(0),
|
||||||
c_to_factor_func(NULL),
|
c_to_factor_func(NULL),
|
||||||
counting_profiler_p(false),
|
|
||||||
sampling_profiler_p(false),
|
sampling_profiler_p(false),
|
||||||
signal_pipe_input(0),
|
signal_pipe_input(0),
|
||||||
signal_pipe_output(0),
|
signal_pipe_output(0),
|
||||||
|
|
13
vm/vm.hpp
13
vm/vm.hpp
|
@ -64,7 +64,6 @@ struct factor_vm
|
||||||
c_to_factor_func_type c_to_factor_func;
|
c_to_factor_func_type c_to_factor_func;
|
||||||
|
|
||||||
/* Is profiling enabled? */
|
/* Is profiling enabled? */
|
||||||
bool counting_profiler_p;
|
|
||||||
volatile cell sampling_profiler_p;
|
volatile cell sampling_profiler_p;
|
||||||
fixnum samples_per_second;
|
fixnum samples_per_second;
|
||||||
|
|
||||||
|
@ -199,13 +198,7 @@ struct factor_vm
|
||||||
void primitive_clone();
|
void primitive_clone();
|
||||||
void primitive_become();
|
void primitive_become();
|
||||||
|
|
||||||
// counting_profiler
|
// sampling_profiler
|
||||||
void init_counting_profiler();
|
|
||||||
code_block *compile_counting_profiler_stub(cell word_);
|
|
||||||
void set_counting_profiler(bool counting_profiler);
|
|
||||||
void primitive_counting_profiler();
|
|
||||||
|
|
||||||
/* Sampling profiler */
|
|
||||||
void clear_samples();
|
void clear_samples();
|
||||||
void record_sample();
|
void record_sample();
|
||||||
void record_callstack_sample(cell *begin, cell *end);
|
void record_callstack_sample(cell *begin, cell *end);
|
||||||
|
@ -458,7 +451,6 @@ struct factor_vm
|
||||||
word *allot_word(cell name_, cell vocab_, cell hashcode_);
|
word *allot_word(cell name_, cell vocab_, cell hashcode_);
|
||||||
void primitive_word();
|
void primitive_word();
|
||||||
void primitive_word_code();
|
void primitive_word_code();
|
||||||
void update_word_entry_point(word *w_);
|
|
||||||
void primitive_optimized_p();
|
void primitive_optimized_p();
|
||||||
void primitive_wrapper();
|
void primitive_wrapper();
|
||||||
void jit_compile_word(cell word_, cell def_, bool relocating);
|
void jit_compile_word(cell word_, cell def_, bool relocating);
|
||||||
|
@ -658,10 +650,9 @@ struct factor_vm
|
||||||
|
|
||||||
// quotations
|
// quotations
|
||||||
void primitive_jit_compile();
|
void primitive_jit_compile();
|
||||||
code_block *lazy_jit_compile_block();
|
void *lazy_jit_compile_entry_point();
|
||||||
void primitive_array_to_quotation();
|
void primitive_array_to_quotation();
|
||||||
void primitive_quotation_code();
|
void primitive_quotation_code();
|
||||||
void set_quot_entry_point(quotation *quot, code_block *code);
|
|
||||||
code_block *jit_compile_quot(cell owner_, cell quot_, bool relocating);
|
code_block *jit_compile_quot(cell owner_, cell quot_, bool relocating);
|
||||||
void jit_compile_quot(cell quot_, bool relocating);
|
void jit_compile_quot(cell quot_, bool relocating);
|
||||||
fixnum quot_code_offset_to_scan(cell quot_, cell offset);
|
fixnum quot_code_offset_to_scan(cell quot_, cell offset);
|
||||||
|
|
42
vm/words.cpp
42
vm/words.cpp
|
@ -11,11 +11,11 @@ void factor_vm::jit_compile_word(cell word_, cell def_, bool relocating)
|
||||||
|
|
||||||
/* Refuse to compile this word more than once, because quot_compiled_p()
|
/* Refuse to compile this word more than once, because quot_compiled_p()
|
||||||
depends on the identity of its code block */
|
depends on the identity of its code block */
|
||||||
if(word->code && word.value() == special_objects[LAZY_JIT_COMPILE_WORD])
|
if(word->entry_point && word.value() == special_objects[LAZY_JIT_COMPILE_WORD])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
code_block *compiled = jit_compile_quot(word.value(),def.value(),relocating);
|
code_block *compiled = jit_compile_quot(word.value(),def.value(),relocating);
|
||||||
word->code = compiled;
|
word->entry_point = compiled->entry_point();
|
||||||
|
|
||||||
if(to_boolean(word->pic_def)) jit_compile_quot(word->pic_def,relocating);
|
if(to_boolean(word->pic_def)) jit_compile_quot(word->pic_def,relocating);
|
||||||
if(to_boolean(word->pic_tail_def)) jit_compile_quot(word->pic_tail_def,relocating);
|
if(to_boolean(word->pic_tail_def)) jit_compile_quot(word->pic_tail_def,relocating);
|
||||||
|
@ -35,10 +35,8 @@ void factor_vm::compile_all_words()
|
||||||
{
|
{
|
||||||
data_root<word> word(array_nth(words.untagged(),i),this);
|
data_root<word> word(array_nth(words.untagged(),i),this);
|
||||||
|
|
||||||
if(!word->code || !word->code->optimized_p())
|
if(!word->entry_point || !word->code()->optimized_p())
|
||||||
jit_compile_word(word.value(),word->def,false);
|
jit_compile_word(word.value(),word->def,false);
|
||||||
|
|
||||||
update_word_entry_point(word.untagged());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,22 +52,12 @@ word *factor_vm::allot_word(cell name_, cell vocab_, cell hashcode_)
|
||||||
new_word->name = name.value();
|
new_word->name = name.value();
|
||||||
new_word->def = special_objects[OBJ_UNDEFINED];
|
new_word->def = special_objects[OBJ_UNDEFINED];
|
||||||
new_word->props = false_object;
|
new_word->props = false_object;
|
||||||
new_word->counter = tag_fixnum(0);
|
|
||||||
new_word->pic_def = false_object;
|
new_word->pic_def = false_object;
|
||||||
new_word->pic_tail_def = false_object;
|
new_word->pic_tail_def = false_object;
|
||||||
new_word->subprimitive = false_object;
|
new_word->subprimitive = false_object;
|
||||||
new_word->counting_profiler = NULL;
|
new_word->entry_point = NULL;
|
||||||
new_word->code = NULL;
|
|
||||||
|
|
||||||
jit_compile_word(new_word.value(),new_word->def,true);
|
jit_compile_word(new_word.value(),new_word->def,true);
|
||||||
if(counting_profiler_p)
|
|
||||||
{
|
|
||||||
code_block *counting_profiler_block = compile_counting_profiler_stub(new_word.value());
|
|
||||||
new_word->counting_profiler = counting_profiler_block;
|
|
||||||
initialize_code_block(new_word->counting_profiler);
|
|
||||||
}
|
|
||||||
|
|
||||||
update_word_entry_point(new_word.untagged());
|
|
||||||
|
|
||||||
return new_word.untagged();
|
return new_word.untagged();
|
||||||
}
|
}
|
||||||
|
@ -89,30 +77,14 @@ void factor_vm::primitive_word_code()
|
||||||
data_root<word> w(ctx->pop(),this);
|
data_root<word> w(ctx->pop(),this);
|
||||||
w.untag_check(this);
|
w.untag_check(this);
|
||||||
|
|
||||||
if(counting_profiler_p)
|
ctx->push(from_unsigned_cell((cell)w->entry_point));
|
||||||
{
|
ctx->push(from_unsigned_cell((cell)w->code() + w->code()->size()));
|
||||||
ctx->push(from_unsigned_cell((cell)w->counting_profiler->entry_point()));
|
|
||||||
ctx->push(from_unsigned_cell((cell)w->counting_profiler + w->counting_profiler->size()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctx->push(from_unsigned_cell((cell)w->code->entry_point()));
|
|
||||||
ctx->push(from_unsigned_cell((cell)w->code + w->code->size()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void factor_vm::update_word_entry_point(word *w)
|
|
||||||
{
|
|
||||||
if(counting_profiler_p && w->counting_profiler)
|
|
||||||
w->entry_point = w->counting_profiler->entry_point();
|
|
||||||
else
|
|
||||||
w->entry_point = w->code->entry_point();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_optimized_p()
|
void factor_vm::primitive_optimized_p()
|
||||||
{
|
{
|
||||||
word *w = untag_check<word>(ctx->peek());
|
word *w = untag_check<word>(ctx->peek());
|
||||||
ctx->replace(tag_boolean(w->code->optimized_p()));
|
ctx->replace(tag_boolean(w->code()->optimized_p()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_wrapper()
|
void factor_vm::primitive_wrapper()
|
||||||
|
|
Loading…
Reference in New Issue