diff --git a/vm/code_block.cpp b/vm/code_block.cpp index 54fd455ae4..f61be7ab1c 100755 --- a/vm/code_block.cpp +++ b/vm/code_block.cpp @@ -533,9 +533,13 @@ code_block *factor_vm::add_code_block(cell type, cell code_, cell labels_, cell compiled->type = type; compiled->last_scan = data->nursery(); compiled->needs_fixup = true; - compiled->relocation = relocation.value(); /* slight space optimization */ + if(relocation.type() == BYTE_ARRAY_TYPE && array_capacity(relocation.untagged()) == 0) + compiled->relocation = F; + else + compiled->relocation = relocation.value(); + if(literals.type() == ARRAY_TYPE && array_capacity(literals.untagged()) == 0) compiled->literals = F; else diff --git a/vm/quotations.cpp b/vm/quotations.cpp index c1ab60b43d..f8a9a7183b 100755 --- a/vm/quotations.cpp +++ b/vm/quotations.cpp @@ -103,6 +103,28 @@ bool quotation_jit::stack_frame_p() return false; } +bool quotation_jit::trivial_quotation_p(array *elements) +{ + return array_capacity(elements) == 1 && tagged(array_nth(elements,0)).type_p(WORD_TYPE); +} + +void quotation_jit::emit_quot(cell quot_) +{ + gc_root quot(quot_,parent_vm); + + array *elements = parent_vm->untag(quot->array); + + /* If the quotation consists of a single word, compile a direct call + to the word. */ + if(trivial_quotation_p(elements)) + literal(array_nth(elements,0)); + else + { + if(compiling) parent_vm->jit_compile(quot.value(),relocate); + literal(quot.value()); + } +} + /* Allocates memory */ void quotation_jit::iterate_quotation() { @@ -194,14 +216,8 @@ void quotation_jit::iterate_quotation() if(stack_frame) emit(parent_vm->userenv[JIT_EPILOG]); tail_call = true; - if(compiling) - { - parent_vm->jit_compile(array_nth(elements.untagged(),i),relocate); - parent_vm->jit_compile(array_nth(elements.untagged(),i + 1),relocate); - } - - literal(array_nth(elements.untagged(),i)); - literal(array_nth(elements.untagged(),i + 1)); + emit_quot(array_nth(elements.untagged(),i)); + emit_quot(array_nth(elements.untagged(),i + 1)); emit(parent_vm->userenv[JIT_IF]); i += 2; @@ -209,25 +225,22 @@ void quotation_jit::iterate_quotation() /* dip */ else if(fast_dip_p(i,length)) { - if(compiling) - parent_vm->jit_compile(obj.value(),relocate); - emit_with(parent_vm->userenv[JIT_DIP],obj.value()); + emit_quot(obj.value()); + emit(parent_vm->userenv[JIT_DIP]); i++; } /* 2dip */ else if(fast_2dip_p(i,length)) { - if(compiling) - parent_vm->jit_compile(obj.value(),relocate); - emit_with(parent_vm->userenv[JIT_2DIP],obj.value()); + emit_quot(obj.value()); + emit(parent_vm->userenv[JIT_2DIP]); i++; } /* 3dip */ else if(fast_3dip_p(i,length)) { - if(compiling) - parent_vm->jit_compile(obj.value(),relocate); - emit_with(parent_vm->userenv[JIT_3DIP],obj.value()); + emit_quot(obj.value()); + emit(parent_vm->userenv[JIT_3DIP]); i++; } else diff --git a/vm/quotations.hpp b/vm/quotations.hpp index 10d2a96f66..aee4468102 100755 --- a/vm/quotations.hpp +++ b/vm/quotations.hpp @@ -13,6 +13,8 @@ struct quotation_jit : public jit { void emit_mega_cache_lookup(cell methods, fixnum index, cell cache); bool primitive_call_p(cell i, cell length); + bool trivial_quotation_p(array *elements); + void emit_quot(cell quot); bool fast_if_p(cell i, cell length); bool fast_dip_p(cell i, cell length); bool fast_2dip_p(cell i, cell length);