2009-05-02 05:04:19 -04:00
|
|
|
#include "master.hpp"
|
|
|
|
|
2009-05-04 02:46:13 -04:00
|
|
|
namespace factor
|
|
|
|
{
|
|
|
|
|
2009-05-02 05:04:19 -04:00
|
|
|
/* Simple code generator used by:
|
2009-05-02 10:19:09 -04:00
|
|
|
- profiler (profiler.cpp),
|
|
|
|
- quotation compiler (quotations.cpp),
|
|
|
|
- megamorphic caches (dispatch.cpp),
|
|
|
|
- polymorphic inline caches (inline_cache.cpp) */
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
/* Allocates memory */
|
2009-08-17 16:37:09 -04:00
|
|
|
jit::jit(cell type_, cell owner_, factorvm *vm)
|
2009-05-02 10:19:09 -04:00
|
|
|
: type(type_),
|
|
|
|
owner(owner_),
|
|
|
|
code(),
|
|
|
|
relocation(),
|
|
|
|
literals(),
|
|
|
|
computing_offset_p(false),
|
|
|
|
position(0),
|
2009-08-17 16:37:09 -04:00
|
|
|
offset(0),
|
|
|
|
myvm(vm)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
if(stack_traces_p()) literal(owner.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-06 21:04:49 -04:00
|
|
|
void jit::emit_relocation(cell code_template_)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-06 21:04:49 -04:00
|
|
|
gc_root<array> code_template(code_template_);
|
|
|
|
cell capacity = array_capacity(code_template.untagged());
|
|
|
|
for(cell i = 1; i < capacity; i += 3)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-06 21:04:49 -04:00
|
|
|
cell rel_class = array_nth(code_template.untagged(),i);
|
|
|
|
cell rel_type = array_nth(code_template.untagged(),i + 1);
|
|
|
|
cell offset = array_nth(code_template.untagged(),i + 2);
|
|
|
|
|
|
|
|
relocation_entry new_entry
|
|
|
|
= (untag_fixnum(rel_type) << 28)
|
2009-05-02 21:47:29 -04:00
|
|
|
| (untag_fixnum(rel_class) << 24)
|
|
|
|
| ((code.count + untag_fixnum(offset)));
|
2009-05-06 21:04:49 -04:00
|
|
|
relocation.append_bytes(&new_entry,sizeof(relocation_entry));
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocates memory */
|
2009-05-04 05:50:24 -04:00
|
|
|
void jit::emit(cell code_template_)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
gc_root<array> code_template(code_template_);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-06 21:04:49 -04:00
|
|
|
emit_relocation(code_template.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
gc_root<byte_array> insns(array_nth(code_template.untagged(),0));
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
if(computing_offset_p)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
cell size = array_capacity(insns.untagged());
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
if(offset == 0)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
position--;
|
|
|
|
computing_offset_p = false;
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
2009-05-02 10:19:09 -04:00
|
|
|
else if(offset < size)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
position++;
|
|
|
|
computing_offset_p = false;
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
else
|
2009-05-02 10:19:09 -04:00
|
|
|
offset -= size;
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
code.append_byte_array(insns.value());
|
|
|
|
}
|
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
void jit::emit_with(cell code_template_, cell argument_) {
|
|
|
|
gc_root<array> code_template(code_template_);
|
|
|
|
gc_root<object> argument(argument_);
|
2009-05-02 10:19:09 -04:00
|
|
|
literal(argument.value());
|
|
|
|
emit(code_template.value());
|
|
|
|
}
|
|
|
|
|
2009-05-04 05:50:24 -04:00
|
|
|
void jit::emit_class_lookup(fixnum index, cell type)
|
2009-05-02 10:19:09 -04:00
|
|
|
{
|
2009-05-04 05:50:24 -04:00
|
|
|
emit_with(userenv[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
|
2009-05-02 10:19:09 -04:00
|
|
|
emit(userenv[type]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Facility to convert compiled code offsets to quotation offsets.
|
|
|
|
Call jit_compute_offset() with the compiled code offset, then emit
|
|
|
|
code, and at the end jit->position is the quotation position. */
|
2009-05-04 05:50:24 -04:00
|
|
|
void jit::compute_position(cell offset_)
|
2009-05-02 10:19:09 -04:00
|
|
|
{
|
|
|
|
computing_offset_p = true;
|
|
|
|
position = 0;
|
|
|
|
offset = offset_;
|
|
|
|
}
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
/* Allocates memory */
|
2009-05-04 05:50:24 -04:00
|
|
|
code_block *jit::to_code_block()
|
2009-05-02 10:19:09 -04:00
|
|
|
{
|
|
|
|
code.trim();
|
|
|
|
relocation.trim();
|
|
|
|
literals.trim();
|
|
|
|
|
|
|
|
return add_code_block(
|
|
|
|
type,
|
2009-05-04 05:50:24 -04:00
|
|
|
code.elements.value(),
|
2009-05-02 10:19:09 -04:00
|
|
|
F, /* no labels */
|
2009-05-04 05:50:24 -04:00
|
|
|
relocation.elements.value(),
|
|
|
|
literals.elements.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-04 02:46:13 -04:00
|
|
|
}
|