slot and eq?. A primitive call is relatively expensive (two subroutine calls)
so this results in a big speedup for relatively little effort. */
-bool quotation_jit::primitive_call_p(cell i)
+bool quotation_jit::primitive_call_p(cell i, cell length)
{
- return (i + 2) == array_capacity(elements.untagged())
- && tagged<object>(array_nth(elements.untagged(),i)).type_p(FIXNUM_TYPE)
- && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_PRIMITIVE_WORD];
+ return (i + 2) == length && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_PRIMITIVE_WORD];
}
-bool quotation_jit::fast_if_p(cell i)
+bool quotation_jit::fast_if_p(cell i, cell length)
{
- return (i + 3) == array_capacity(elements.untagged())
- && tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE)
+ return (i + 3) == length
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(QUOTATION_TYPE)
&& array_nth(elements.untagged(),i + 2) == parent_vm->userenv[JIT_IF_WORD];
}
-bool quotation_jit::fast_dip_p(cell i)
+bool quotation_jit::fast_dip_p(cell i, cell length)
{
- return (i + 2) <= array_capacity(elements.untagged())
- && tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE)
- && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_DIP_WORD];
+ return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_DIP_WORD];
}
-bool quotation_jit::fast_2dip_p(cell i)
+bool quotation_jit::fast_2dip_p(cell i, cell length)
{
- return (i + 2) <= array_capacity(elements.untagged())
- && tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE)
- && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_2DIP_WORD];
+ return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_2DIP_WORD];
}
-bool quotation_jit::fast_3dip_p(cell i)
+bool quotation_jit::fast_3dip_p(cell i, cell length)
{
- return (i + 2) <= array_capacity(elements.untagged())
- && tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE)
- && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_3DIP_WORD];
+ return (i + 2) <= length && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_3DIP_WORD];
}
-bool quotation_jit::mega_lookup_p(cell i)
+bool quotation_jit::mega_lookup_p(cell i, cell length)
{
- return (i + 3) < array_capacity(elements.untagged())
- && tagged<object>(array_nth(elements.untagged(),i)).type_p(ARRAY_TYPE)
+ return (i + 4) <= length
&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(FIXNUM_TYPE)
&& tagged<object>(array_nth(elements.untagged(),i + 2)).type_p(ARRAY_TYPE)
&& array_nth(elements.untagged(),i + 3) == parent_vm->userenv[MEGA_LOOKUP_WORD];
}
+bool quotation_jit::declare_p(cell i, cell length)
+{
+ return (i + 2) <= length
+ && array_nth(elements.untagged(),i + 1) == parent_vm->userenv[JIT_DECLARE_WORD];
+}
+
bool quotation_jit::stack_frame_p()
{
fixnum length = array_capacity(elements.untagged());
return true;
break;
case QUOTATION_TYPE:
- if(fast_dip_p(i) || fast_2dip_p(i) || fast_3dip_p(i))
+ if(fast_dip_p(i,length) || fast_2dip_p(i,length) || fast_3dip_p(i,length))
return true;
break;
default:
break;
case FIXNUM_TYPE:
/* Primitive calls */
- if(primitive_call_p(i))
+ if(primitive_call_p(i,length))
{
emit_with(parent_vm->userenv[JIT_PRIMITIVE],obj.value());
i++;
tail_call = true;
- break;
}
+ else
+ push(obj.value());
+ break;
case QUOTATION_TYPE:
/* 'if' preceeded by two literal quotations (this is why if and ? are
mutually recursive in the library, but both still work) */
- if(fast_if_p(i))
+ if(fast_if_p(i,length))
{
if(stack_frame) emit(parent_vm->userenv[JIT_EPILOG]);
tail_call = true;
emit(parent_vm->userenv[JIT_IF]);
i += 2;
-
- break;
}
/* dip */
- else if(fast_dip_p(i))
+ 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());
i++;
- break;
}
/* 2dip */
- else if(fast_2dip_p(i))
+ 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());
i++;
- break;
}
/* 3dip */
- else if(fast_3dip_p(i))
+ 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());
i++;
- break;
}
+ else
+ push(obj.value());
+ break;
case ARRAY_TYPE:
/* Method dispatch */
- if(mega_lookup_p(i))
+ if(mega_lookup_p(i,length))
{
emit_mega_cache_lookup(
array_nth(elements.untagged(),i),
array_nth(elements.untagged(),i + 2));
i += 3;
tail_call = true;
- break;
}
+ /* Non-optimizing compiler ignores declarations */
+ else if(declare_p(i,length))
+ i++;
+ else
+ push(obj.value());
+ break;
default:
push(obj.value());
break;