VM: Refactor quotations.cpp/hpp to Factor style
parent
4dffb25fe6
commit
435ac636c6
|
@ -1,12 +1,12 @@
|
||||||
#include "master.hpp"
|
#include "master.hpp"
|
||||||
|
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
/* Simple non-optimizing compiler.
|
/* Simple non-optimizing compiler.
|
||||||
|
|
||||||
This is one of the two compilers implementing Factor; the second one is written
|
This is one of the two compilers implementing Factor; the second one is written
|
||||||
in Factor and performs advanced optimizations. See basis/compiler/compiler.factor.
|
in Factor and performs advanced optimizations. See
|
||||||
|
basis/compiler/compiler.factor.
|
||||||
|
|
||||||
The non-optimizing compiler compiles a quotation at a time by concatenating
|
The non-optimizing compiler compiles a quotation at a time by concatenating
|
||||||
machine code chunks; prolog, epilog, call word, jump to word, etc. These machine
|
machine code chunks; prolog, epilog, call word, jump to word, etc. These machine
|
||||||
|
@ -36,83 +36,79 @@ includes stack shufflers, some fixnum arithmetic words, and words such as tag,
|
||||||
slot and eq?. A primitive call is relatively expensive (two subroutine calls)
|
slot and eq?. A primitive call is relatively expensive (two subroutine calls)
|
||||||
so this results in a big speedup for relatively little effort. */
|
so this results in a big speedup for relatively little effort. */
|
||||||
|
|
||||||
void quotation_jit::init_quotation(cell quot)
|
void quotation_jit::init_quotation(cell quot) {
|
||||||
{
|
|
||||||
elements = untag<quotation>(quot)->array;
|
elements = untag<quotation>(quot)->array;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::primitive_call_p(cell i, cell length)
|
bool quotation_jit::primitive_call_p(cell i, cell length) {
|
||||||
{
|
return (i + 2) <= length && array_nth(elements.untagged(), i + 1) ==
|
||||||
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_PRIMITIVE_WORD];
|
parent->special_objects[JIT_PRIMITIVE_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::fast_if_p(cell i, cell length)
|
bool quotation_jit::fast_if_p(cell i, cell length) {
|
||||||
{
|
return (i + 3) == length &&
|
||||||
return (i + 3) == length
|
tagged<object>(array_nth(elements.untagged(), i + 1))
|
||||||
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(QUOTATION_TYPE)
|
.type_p(QUOTATION_TYPE) &&
|
||||||
&& array_nth(elements.untagged(),i + 2) == parent->special_objects[JIT_IF_WORD];
|
array_nth(elements.untagged(), i + 2) ==
|
||||||
|
parent->special_objects[JIT_IF_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::fast_dip_p(cell i, cell length)
|
bool quotation_jit::fast_dip_p(cell i, cell length) {
|
||||||
{
|
return (i + 2) <= length && array_nth(elements.untagged(), i + 1) ==
|
||||||
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_DIP_WORD];
|
parent->special_objects[JIT_DIP_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::fast_2dip_p(cell i, cell length)
|
bool quotation_jit::fast_2dip_p(cell i, cell length) {
|
||||||
{
|
return (i + 2) <= length && array_nth(elements.untagged(), i + 1) ==
|
||||||
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_2DIP_WORD];
|
parent->special_objects[JIT_2DIP_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::fast_3dip_p(cell i, cell length)
|
bool quotation_jit::fast_3dip_p(cell i, cell length) {
|
||||||
{
|
return (i + 2) <= length && array_nth(elements.untagged(), i + 1) ==
|
||||||
return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_3DIP_WORD];
|
parent->special_objects[JIT_3DIP_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::mega_lookup_p(cell i, cell length)
|
bool quotation_jit::mega_lookup_p(cell i, cell length) {
|
||||||
{
|
return (i + 4) <= length &&
|
||||||
return (i + 4) <= length
|
tagged<object>(array_nth(elements.untagged(), i + 1))
|
||||||
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(FIXNUM_TYPE)
|
.type_p(FIXNUM_TYPE) &&
|
||||||
&& tagged<object>(array_nth(elements.untagged(),i + 2)).type_p(ARRAY_TYPE)
|
tagged<object>(array_nth(elements.untagged(), i + 2))
|
||||||
&& array_nth(elements.untagged(),i + 3) == parent->special_objects[MEGA_LOOKUP_WORD];
|
.type_p(ARRAY_TYPE) &&
|
||||||
|
array_nth(elements.untagged(), i + 3) ==
|
||||||
|
parent->special_objects[MEGA_LOOKUP_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::declare_p(cell i, cell length)
|
bool quotation_jit::declare_p(cell i, cell length) {
|
||||||
{
|
return (i + 2) <= length && array_nth(elements.untagged(), i + 1) ==
|
||||||
return (i + 2) <= length
|
parent->special_objects[JIT_DECLARE_WORD];
|
||||||
&& array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_DECLARE_WORD];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::special_subprimitive_p(cell obj)
|
bool quotation_jit::special_subprimitive_p(cell obj) {
|
||||||
{
|
|
||||||
// Subprimitives should be flagged with whether they require a stack frame.
|
// Subprimitives should be flagged with whether they require a stack frame.
|
||||||
// See #295.
|
// See #295.
|
||||||
return obj == parent->special_objects[SIGNAL_HANDLER_WORD]
|
return obj == parent->special_objects[SIGNAL_HANDLER_WORD] ||
|
||||||
|| obj == parent->special_objects[LEAF_SIGNAL_HANDLER_WORD]
|
obj == parent->special_objects[LEAF_SIGNAL_HANDLER_WORD] ||
|
||||||
|| obj == parent->special_objects[FFI_SIGNAL_HANDLER_WORD]
|
obj == parent->special_objects[FFI_SIGNAL_HANDLER_WORD] ||
|
||||||
|| obj == parent->special_objects[FFI_LEAF_SIGNAL_HANDLER_WORD]
|
obj == parent->special_objects[FFI_LEAF_SIGNAL_HANDLER_WORD] ||
|
||||||
|| obj == parent->special_objects[UNWIND_NATIVE_FRAMES_WORD];
|
obj == parent->special_objects[UNWIND_NATIVE_FRAMES_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::word_stack_frame_p(cell obj)
|
bool quotation_jit::word_stack_frame_p(cell obj) {
|
||||||
{
|
return (to_boolean(untag<word>(obj)->subprimitive) &&
|
||||||
return (to_boolean(untag<word>(obj)->subprimitive) && !special_subprimitive_p(obj))
|
!special_subprimitive_p(obj)) ||
|
||||||
|| obj == parent->special_objects[JIT_PRIMITIVE_WORD];
|
obj == parent->special_objects[JIT_PRIMITIVE_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::word_safepoint_p(cell obj)
|
bool quotation_jit::word_safepoint_p(cell obj) {
|
||||||
{
|
|
||||||
return !special_subprimitive_p(obj);
|
return !special_subprimitive_p(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::safepoint_p()
|
bool quotation_jit::safepoint_p() {
|
||||||
{
|
|
||||||
fixnum length = array_capacity(elements.untagged());
|
fixnum length = array_capacity(elements.untagged());
|
||||||
|
|
||||||
for(fixnum i = 0; i < length; i++)
|
for (fixnum i = 0; i < length; i++) {
|
||||||
{
|
|
||||||
cell obj = array_nth(elements.untagged(), i);
|
cell obj = array_nth(elements.untagged(), i);
|
||||||
switch(tagged<object>(obj).type())
|
switch (tagged<object>(obj).type()) {
|
||||||
{
|
|
||||||
case WORD_TYPE:
|
case WORD_TYPE:
|
||||||
if (!word_safepoint_p(obj))
|
if (!word_safepoint_p(obj))
|
||||||
return false;
|
return false;
|
||||||
|
@ -125,12 +121,10 @@ bool quotation_jit::safepoint_p()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::stack_frame_p()
|
bool quotation_jit::stack_frame_p() {
|
||||||
{
|
|
||||||
fixnum length = array_capacity(elements.untagged());
|
fixnum length = array_capacity(elements.untagged());
|
||||||
|
|
||||||
for(fixnum i = 0; i < length; i++)
|
for (fixnum i = 0; i < length; i++) {
|
||||||
{
|
|
||||||
cell obj = array_nth(elements.untagged(), i);
|
cell obj = array_nth(elements.untagged(), i);
|
||||||
if (tagged<object>(obj).type() == WORD_TYPE && !word_safepoint_p(obj))
|
if (tagged<object>(obj).type() == WORD_TYPE && !word_safepoint_p(obj))
|
||||||
return false;
|
return false;
|
||||||
|
@ -139,26 +133,27 @@ bool quotation_jit::stack_frame_p()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quotation_jit::trivial_quotation_p(array *elements)
|
bool quotation_jit::trivial_quotation_p(array* elements) {
|
||||||
{
|
return array_capacity(elements) == 1 &&
|
||||||
return array_capacity(elements) == 1 && tagged<object>(array_nth(elements,0)).type_p(WORD_TYPE);
|
tagged<object>(array_nth(elements, 0)).type_p(WORD_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void quotation_jit::emit_prolog(bool safepoint, bool stack_frame)
|
void quotation_jit::emit_prolog(bool safepoint, bool stack_frame) {
|
||||||
{
|
if (safepoint)
|
||||||
if(safepoint) emit(parent->special_objects[JIT_SAFEPOINT]);
|
emit(parent->special_objects[JIT_SAFEPOINT]);
|
||||||
if(stack_frame) emit(parent->special_objects[JIT_PROLOG]);
|
if (stack_frame)
|
||||||
|
emit(parent->special_objects[JIT_PROLOG]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void quotation_jit::emit_epilog(bool safepoint, bool stack_frame)
|
void quotation_jit::emit_epilog(bool safepoint, bool stack_frame) {
|
||||||
{
|
if (safepoint)
|
||||||
if(safepoint) emit(parent->special_objects[JIT_SAFEPOINT]);
|
emit(parent->special_objects[JIT_SAFEPOINT]);
|
||||||
if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
|
if (stack_frame)
|
||||||
|
emit(parent->special_objects[JIT_EPILOG]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory conditionally */
|
/* Allocates memory conditionally */
|
||||||
void quotation_jit::emit_quot(cell quot_)
|
void quotation_jit::emit_quot(cell quot_) {
|
||||||
{
|
|
||||||
data_root<quotation> quot(quot_, parent);
|
data_root<quotation> quot(quot_, parent);
|
||||||
|
|
||||||
array* elements = untag<array>(quot->array);
|
array* elements = untag<array>(quot->array);
|
||||||
|
@ -167,16 +162,15 @@ void quotation_jit::emit_quot(cell quot_)
|
||||||
to the word. */
|
to the word. */
|
||||||
if (trivial_quotation_p(elements))
|
if (trivial_quotation_p(elements))
|
||||||
literal(array_nth(elements, 0));
|
literal(array_nth(elements, 0));
|
||||||
else
|
else {
|
||||||
{
|
if (compiling)
|
||||||
if(compiling) parent->jit_compile_quot(quot.value(),relocate);
|
parent->jit_compile_quot(quot.value(), relocate);
|
||||||
literal(quot.value());
|
literal(quot.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
void quotation_jit::iterate_quotation()
|
void quotation_jit::iterate_quotation() {
|
||||||
{
|
|
||||||
bool safepoint = safepoint_p();
|
bool safepoint = safepoint_p();
|
||||||
bool stack_frame = stack_frame_p();
|
bool stack_frame = stack_frame_p();
|
||||||
|
|
||||||
|
@ -188,30 +182,24 @@ void quotation_jit::iterate_quotation()
|
||||||
cell length = array_capacity(elements.untagged());
|
cell length = array_capacity(elements.untagged());
|
||||||
bool tail_call = false;
|
bool tail_call = false;
|
||||||
|
|
||||||
for(i = 0; i < length; i++)
|
for (i = 0; i < length; i++) {
|
||||||
{
|
|
||||||
set_position(i);
|
set_position(i);
|
||||||
|
|
||||||
data_root<object> obj(array_nth(elements.untagged(), i), parent);
|
data_root<object> obj(array_nth(elements.untagged(), i), parent);
|
||||||
|
|
||||||
switch(obj.type())
|
switch (obj.type()) {
|
||||||
{
|
|
||||||
case WORD_TYPE:
|
case WORD_TYPE:
|
||||||
/* Sub-primitives */
|
/* Sub-primitives */
|
||||||
if(to_boolean(obj.as<word>()->subprimitive))
|
if (to_boolean(obj.as<word>()->subprimitive)) {
|
||||||
{
|
|
||||||
tail_call = emit_subprimitive(obj.value(), /* word */
|
tail_call = emit_subprimitive(obj.value(), /* word */
|
||||||
i == length - 1, /* tail_call_p */
|
i == length - 1, /* tail_call_p */
|
||||||
stack_frame); /* stack_frame_p */
|
stack_frame); /* stack_frame_p */
|
||||||
}
|
} /* Everything else */
|
||||||
/* Everything else */
|
else if (i == length - 1) {
|
||||||
else if(i == length - 1)
|
|
||||||
{
|
|
||||||
emit_epilog(safepoint, stack_frame);
|
emit_epilog(safepoint, stack_frame);
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
word_jump(obj.value());
|
word_jump(obj.value());
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
word_call(obj.value());
|
word_call(obj.value());
|
||||||
break;
|
break;
|
||||||
case WRAPPER_TYPE:
|
case WRAPPER_TYPE:
|
||||||
|
@ -219,8 +207,7 @@ void quotation_jit::iterate_quotation()
|
||||||
break;
|
break;
|
||||||
case BYTE_ARRAY_TYPE:
|
case BYTE_ARRAY_TYPE:
|
||||||
/* Primitive calls */
|
/* Primitive calls */
|
||||||
if(primitive_call_p(i,length))
|
if (primitive_call_p(i, length)) {
|
||||||
{
|
|
||||||
/* On x86-64 and PowerPC, the VM pointer is stored in
|
/* On x86-64 and PowerPC, the VM pointer is stored in
|
||||||
a register; on other platforms, the RT_VM relocation
|
a register; on other platforms, the RT_VM relocation
|
||||||
is used and it needs an offset parameter */
|
is used and it needs an offset parameter */
|
||||||
|
@ -236,15 +223,13 @@ void quotation_jit::iterate_quotation()
|
||||||
emit(parent->special_objects[JIT_PRIMITIVE]);
|
emit(parent->special_objects[JIT_PRIMITIVE]);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
push(obj.value());
|
push(obj.value());
|
||||||
break;
|
break;
|
||||||
case QUOTATION_TYPE:
|
case QUOTATION_TYPE:
|
||||||
/* 'if' preceded by two literal quotations (this is why if and ? are
|
/* 'if' preceded by two literal quotations (this is why if and ? are
|
||||||
mutually recursive in the library, but both still work) */
|
mutually recursive in the library, but both still work) */
|
||||||
if(fast_if_p(i,length))
|
if (fast_if_p(i, length)) {
|
||||||
{
|
|
||||||
emit_epilog(safepoint, stack_frame);
|
emit_epilog(safepoint, stack_frame);
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
|
|
||||||
|
@ -253,48 +238,38 @@ void quotation_jit::iterate_quotation()
|
||||||
emit(parent->special_objects[JIT_IF]);
|
emit(parent->special_objects[JIT_IF]);
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
} /* dip */
|
||||||
/* dip */
|
else if (fast_dip_p(i, length)) {
|
||||||
else if(fast_dip_p(i,length))
|
|
||||||
{
|
|
||||||
emit_quot(obj.value());
|
emit_quot(obj.value());
|
||||||
emit(parent->special_objects[JIT_DIP]);
|
emit(parent->special_objects[JIT_DIP]);
|
||||||
i++;
|
i++;
|
||||||
}
|
} /* 2dip */
|
||||||
/* 2dip */
|
else if (fast_2dip_p(i, length)) {
|
||||||
else if(fast_2dip_p(i,length))
|
|
||||||
{
|
|
||||||
emit_quot(obj.value());
|
emit_quot(obj.value());
|
||||||
emit(parent->special_objects[JIT_2DIP]);
|
emit(parent->special_objects[JIT_2DIP]);
|
||||||
i++;
|
i++;
|
||||||
}
|
} /* 3dip */
|
||||||
/* 3dip */
|
else if (fast_3dip_p(i, length)) {
|
||||||
else if(fast_3dip_p(i,length))
|
|
||||||
{
|
|
||||||
emit_quot(obj.value());
|
emit_quot(obj.value());
|
||||||
emit(parent->special_objects[JIT_3DIP]);
|
emit(parent->special_objects[JIT_3DIP]);
|
||||||
i++;
|
i++;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
push(obj.value());
|
push(obj.value());
|
||||||
break;
|
break;
|
||||||
case ARRAY_TYPE:
|
case ARRAY_TYPE:
|
||||||
/* Method dispatch */
|
/* Method dispatch */
|
||||||
if(mega_lookup_p(i,length))
|
if (mega_lookup_p(i, length)) {
|
||||||
{
|
|
||||||
fixnum index = untag_fixnum(array_nth(elements.untagged(), i + 1));
|
fixnum index = untag_fixnum(array_nth(elements.untagged(), i + 1));
|
||||||
/* Load the object from the datastack, then remove our stack frame. */
|
/* Load the object from the datastack, then remove our stack frame. */
|
||||||
emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
|
emit_with_literal(parent->special_objects[PIC_LOAD],
|
||||||
|
tag_fixnum(-index * sizeof(cell)));
|
||||||
emit_epilog(safepoint, stack_frame);
|
emit_epilog(safepoint, stack_frame);
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
|
|
||||||
emit_mega_cache_lookup(
|
emit_mega_cache_lookup(array_nth(elements.untagged(), i), index,
|
||||||
array_nth(elements.untagged(),i),
|
|
||||||
index,
|
|
||||||
array_nth(elements.untagged(), i + 2));
|
array_nth(elements.untagged(), i + 2));
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
} /* Non-optimizing compiler ignores declarations */
|
||||||
/* Non-optimizing compiler ignores declarations */
|
|
||||||
else if (declare_p(i, length))
|
else if (declare_p(i, length))
|
||||||
i++;
|
i++;
|
||||||
else
|
else
|
||||||
|
@ -306,8 +281,7 @@ void quotation_jit::iterate_quotation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tail_call)
|
if (!tail_call) {
|
||||||
{
|
|
||||||
set_position(length);
|
set_position(length);
|
||||||
|
|
||||||
emit_epilog(safepoint, stack_frame);
|
emit_epilog(safepoint, stack_frame);
|
||||||
|
@ -315,8 +289,7 @@ void quotation_jit::iterate_quotation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cell quotation_jit::word_stack_frame_size(cell obj)
|
cell quotation_jit::word_stack_frame_size(cell obj) {
|
||||||
{
|
|
||||||
if (special_subprimitive_p(obj))
|
if (special_subprimitive_p(obj))
|
||||||
return SIGNAL_HANDLER_STACK_FRAME_SIZE;
|
return SIGNAL_HANDLER_STACK_FRAME_SIZE;
|
||||||
else
|
else
|
||||||
|
@ -324,8 +297,8 @@ cell quotation_jit::word_stack_frame_size(cell obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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) {
|
||||||
data_root<object> owner(owner_, this);
|
data_root<object> owner(owner_, this);
|
||||||
data_root<quotation> quot(quot_, this);
|
data_root<quotation> quot(quot_, this);
|
||||||
|
|
||||||
|
@ -337,37 +310,32 @@ code_block *factor_vm::jit_compile_quot(cell owner_, cell quot_, bool relocating
|
||||||
|
|
||||||
code_block* compiled = compiler.to_code_block(frame_size);
|
code_block* compiled = compiler.to_code_block(frame_size);
|
||||||
|
|
||||||
if(relocating) initialize_code_block(compiled);
|
if (relocating)
|
||||||
|
initialize_code_block(compiled);
|
||||||
|
|
||||||
return compiled;
|
return compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
void factor_vm::jit_compile_quot(cell quot_, bool relocating)
|
void factor_vm::jit_compile_quot(cell quot_, bool relocating) {
|
||||||
{
|
|
||||||
data_root<quotation> quot(quot_, this);
|
data_root<quotation> quot(quot_, this);
|
||||||
if(!quot_compiled_p(quot.untagged()))
|
if (!quot_compiled_p(quot.untagged())) {
|
||||||
{
|
code_block* compiled =
|
||||||
code_block *compiled = jit_compile_quot(quot.value(),quot.value(),relocating);
|
jit_compile_quot(quot.value(), quot.value(), relocating);
|
||||||
quot.untagged()->entry_point = compiled->entry_point();
|
quot.untagged()->entry_point = compiled->entry_point();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
void factor_vm::primitive_jit_compile()
|
void factor_vm::primitive_jit_compile() { jit_compile_quot(ctx->pop(), true); }
|
||||||
{
|
|
||||||
jit_compile_quot(ctx->pop(),true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *factor_vm::lazy_jit_compile_entry_point()
|
void* factor_vm::lazy_jit_compile_entry_point() {
|
||||||
{
|
|
||||||
return untag<word>(special_objects[LAZY_JIT_COMPILE_WORD])->entry_point;
|
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 */
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
void factor_vm::primitive_array_to_quotation()
|
void factor_vm::primitive_array_to_quotation() {
|
||||||
{
|
|
||||||
quotation* quot = allot<quotation>(sizeof(quotation));
|
quotation* quot = allot<quotation>(sizeof(quotation));
|
||||||
|
|
||||||
quot->array = ctx->peek();
|
quot->array = ctx->peek();
|
||||||
|
@ -379,8 +347,7 @@ void factor_vm::primitive_array_to_quotation()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory (from_unsigned_cell) */
|
/* Allocates memory (from_unsigned_cell) */
|
||||||
void factor_vm::primitive_quotation_code()
|
void factor_vm::primitive_quotation_code() {
|
||||||
{
|
|
||||||
data_root<quotation> quot(ctx->pop(), this);
|
data_root<quotation> quot(ctx->pop(), this);
|
||||||
|
|
||||||
ctx->push(from_unsigned_cell((cell) quot->entry_point));
|
ctx->push(from_unsigned_cell((cell) quot->entry_point));
|
||||||
|
@ -388,8 +355,7 @@ void factor_vm::primitive_quotation_code()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
fixnum factor_vm::quot_code_offset_to_scan(cell quot_, cell offset)
|
fixnum factor_vm::quot_code_offset_to_scan(cell quot_, cell offset) {
|
||||||
{
|
|
||||||
data_root<quotation> quot(quot_, this);
|
data_root<quotation> quot(quot_, this);
|
||||||
data_root<array> array(quot->array, this);
|
data_root<array> array(quot->array, this);
|
||||||
|
|
||||||
|
@ -402,8 +368,7 @@ fixnum factor_vm::quot_code_offset_to_scan(cell quot_, cell offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
cell factor_vm::lazy_jit_compile(cell quot_)
|
cell factor_vm::lazy_jit_compile(cell quot_) {
|
||||||
{
|
|
||||||
data_root<quotation> quot(quot_, this);
|
data_root<quotation> quot(quot_, this);
|
||||||
|
|
||||||
FACTOR_ASSERT(!quot_compiled_p(quot.untagged()));
|
FACTOR_ASSERT(!quot_compiled_p(quot.untagged()));
|
||||||
|
@ -415,37 +380,30 @@ cell factor_vm::lazy_jit_compile(cell quot_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
VM_C_API cell lazy_jit_compile(cell quot, factor_vm *parent)
|
VM_C_API cell lazy_jit_compile(cell quot, factor_vm* parent) {
|
||||||
{
|
|
||||||
return parent->lazy_jit_compile(quot);
|
return parent->lazy_jit_compile(quot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool factor_vm::quot_compiled_p(quotation *quot)
|
bool factor_vm::quot_compiled_p(quotation* quot) {
|
||||||
{
|
return quot->entry_point != NULL &&
|
||||||
return quot->entry_point != NULL && quot->entry_point != lazy_jit_compile_entry_point();
|
quot->entry_point != lazy_jit_compile_entry_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_quot_compiled_p()
|
void factor_vm::primitive_quot_compiled_p() {
|
||||||
{
|
|
||||||
tagged<quotation> quot(ctx->pop());
|
tagged<quotation> quot(ctx->pop());
|
||||||
quot.untag_check(this);
|
quot.untag_check(this);
|
||||||
ctx->push(tag_boolean(quot_compiled_p(quot.untagged())));
|
ctx->push(tag_boolean(quot_compiled_p(quot.untagged())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
cell factor_vm::find_all_quotations()
|
cell factor_vm::find_all_quotations() { return instances(QUOTATION_TYPE); }
|
||||||
{
|
|
||||||
return instances(QUOTATION_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
void factor_vm::initialize_all_quotations()
|
void factor_vm::initialize_all_quotations() {
|
||||||
{
|
|
||||||
data_root<array> quotations(find_all_quotations(), this);
|
data_root<array> quotations(find_all_quotations(), this);
|
||||||
|
|
||||||
cell length = array_capacity(quotations.untagged());
|
cell length = array_capacity(quotations.untagged());
|
||||||
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->entry_point)
|
if (!quot->entry_point)
|
||||||
quot.untagged()->entry_point = lazy_jit_compile_entry_point();
|
quot.untagged()->entry_point = lazy_jit_compile_entry_point();
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
namespace factor
|
namespace factor {
|
||||||
{
|
|
||||||
|
|
||||||
struct quotation_jit : public jit {
|
struct quotation_jit : public jit {
|
||||||
data_root<array> elements;
|
data_root<array> elements;
|
||||||
bool compiling, relocate;
|
bool compiling, relocate;
|
||||||
|
|
||||||
explicit quotation_jit(cell owner, bool compiling_, bool relocate_, factor_vm *vm)
|
explicit quotation_jit(cell owner, bool compiling_, bool relocate_,
|
||||||
|
factor_vm* vm)
|
||||||
: jit(code_block_unoptimized, owner, vm),
|
: jit(code_block_unoptimized, owner, vm),
|
||||||
elements(false_object, vm),
|
elements(false_object, vm),
|
||||||
compiling(compiling_),
|
compiling(compiling_),
|
||||||
relocate(relocate_){};
|
relocate(relocate_) {}
|
||||||
|
;
|
||||||
|
|
||||||
void init_quotation(cell quot);
|
void init_quotation(cell quot);
|
||||||
void emit_mega_cache_lookup(cell methods, fixnum index, cell cache);
|
void emit_mega_cache_lookup(cell methods, fixnum index, cell cache);
|
||||||
|
|
Loading…
Reference in New Issue