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-05-02 10:19:09 -04:00
|
|
|
jit::jit(CELL type_, CELL owner_)
|
|
|
|
: type(type_),
|
|
|
|
owner(owner_),
|
|
|
|
code(),
|
|
|
|
relocation(),
|
|
|
|
literals(),
|
|
|
|
computing_offset_p(false),
|
|
|
|
position(0),
|
|
|
|
offset(0)
|
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-02 10:19:09 -04:00
|
|
|
F_REL jit::rel_to_emit(CELL code_template, bool *rel_p)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-02 21:47:29 -04:00
|
|
|
F_ARRAY *quadruple = untag<F_ARRAY>(code_template);
|
2009-05-02 05:04:19 -04:00
|
|
|
CELL rel_class = array_nth(quadruple,1);
|
|
|
|
CELL rel_type = array_nth(quadruple,2);
|
|
|
|
CELL offset = array_nth(quadruple,3);
|
|
|
|
|
|
|
|
if(rel_class == F)
|
|
|
|
{
|
|
|
|
*rel_p = false;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*rel_p = true;
|
2009-05-02 21:47:29 -04:00
|
|
|
return (untag_fixnum(rel_type) << 28)
|
|
|
|
| (untag_fixnum(rel_class) << 24)
|
|
|
|
| ((code.count + untag_fixnum(offset)));
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocates memory */
|
2009-05-02 10:19:09 -04:00
|
|
|
void jit::emit(CELL code_template_)
|
2009-05-02 05:04:19 -04:00
|
|
|
{
|
2009-05-02 10:19:09 -04:00
|
|
|
gc_root<F_ARRAY> code_template(code_template_);
|
2009-05-02 05:04:19 -04:00
|
|
|
|
|
|
|
bool rel_p;
|
2009-05-02 10:19:09 -04:00
|
|
|
F_REL rel = rel_to_emit(code_template.value(),&rel_p);
|
|
|
|
if(rel_p) relocation.append_bytes(&rel,sizeof(F_REL));
|
2009-05-02 05:04:19 -04:00
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
gc_root<F_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-02 10:19:09 -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());
|
|
|
|
}
|
|
|
|
|
|
|
|
void jit::emit_with(CELL code_template_, CELL argument_) {
|
|
|
|
gc_root<F_ARRAY> code_template(code_template_);
|
|
|
|
gc_root<F_OBJECT> argument(argument_);
|
|
|
|
literal(argument.value());
|
|
|
|
emit(code_template.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
void jit::emit_class_lookup(F_FIXNUM index, CELL type)
|
|
|
|
{
|
|
|
|
emit_with(userenv[PIC_LOAD],tag_fixnum(-index * CELLS));
|
|
|
|
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. */
|
|
|
|
void jit::compute_position(CELL offset_)
|
|
|
|
{
|
|
|
|
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 */
|
|
|
|
F_CODE_BLOCK *jit::code_block()
|
|
|
|
{
|
|
|
|
code.trim();
|
|
|
|
relocation.trim();
|
|
|
|
literals.trim();
|
|
|
|
|
|
|
|
return add_code_block(
|
|
|
|
type,
|
|
|
|
code.array.value(),
|
|
|
|
F, /* no labels */
|
|
|
|
relocation.array.value(),
|
|
|
|
literals.array.value());
|
2009-05-02 05:04:19 -04:00
|
|
|
}
|
|
|
|
|
2009-05-02 10:19:09 -04:00
|
|
|
|
2009-05-04 02:46:13 -04:00
|
|
|
|
|
|
|
}
|