vm: eliminating literal table work in progress
parent
43e08c76fb
commit
57c541ea46
3
Makefile
3
Makefile
|
@ -39,13 +39,14 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
|
||||||
vm/byte_arrays.o \
|
vm/byte_arrays.o \
|
||||||
vm/callbacks.o \
|
vm/callbacks.o \
|
||||||
vm/callstack.o \
|
vm/callstack.o \
|
||||||
vm/code_block.o \
|
vm/code_blocks.o \
|
||||||
vm/code_heap.o \
|
vm/code_heap.o \
|
||||||
vm/compaction.o \
|
vm/compaction.o \
|
||||||
vm/contexts.o \
|
vm/contexts.o \
|
||||||
vm/data_heap.o \
|
vm/data_heap.o \
|
||||||
vm/debug.o \
|
vm/debug.o \
|
||||||
vm/dispatch.o \
|
vm/dispatch.o \
|
||||||
|
vm/embedded_pointers.o \
|
||||||
vm/errors.o \
|
vm/errors.o \
|
||||||
vm/factor.o \
|
vm/factor.o \
|
||||||
vm/free_list.o \
|
vm/free_list.o \
|
||||||
|
|
|
@ -26,9 +26,8 @@ void callback_heap::update(callback *stub)
|
||||||
cell rel_class = untag_fixnum(array_nth(code_template.untagged(),1));
|
cell rel_class = untag_fixnum(array_nth(code_template.untagged(),1));
|
||||||
cell offset = untag_fixnum(array_nth(code_template.untagged(),3));
|
cell offset = untag_fixnum(array_nth(code_template.untagged(),3));
|
||||||
|
|
||||||
parent->store_address_in_code_block(rel_class,
|
embedded_pointer ptr(rel_class,offset + (cell)(stub + 1));
|
||||||
(cell)(stub + 1) + offset,
|
ptr.store_address((cell)(stub->compiled + 1));
|
||||||
(cell)(stub->compiled + 1));
|
|
||||||
|
|
||||||
flush_icache((cell)stub,stub->size);
|
flush_icache((cell)stub,stub->size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,53 +3,11 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
relocation_type factor_vm::relocation_type_of(relocation_entry r)
|
|
||||||
{
|
|
||||||
return (relocation_type)((r & 0xf0000000) >> 28);
|
|
||||||
}
|
|
||||||
|
|
||||||
relocation_class factor_vm::relocation_class_of(relocation_entry r)
|
|
||||||
{
|
|
||||||
return (relocation_class)((r & 0x0f000000) >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
cell factor_vm::relocation_offset_of(relocation_entry r)
|
|
||||||
{
|
|
||||||
return (r & 0x00ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
void factor_vm::flush_icache_for(code_block *block)
|
void factor_vm::flush_icache_for(code_block *block)
|
||||||
{
|
{
|
||||||
flush_icache((cell)block,block->size());
|
flush_icache((cell)block,block->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
int factor_vm::number_of_parameters(relocation_type type)
|
|
||||||
{
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case RT_PRIMITIVE:
|
|
||||||
case RT_XT:
|
|
||||||
case RT_XT_PIC:
|
|
||||||
case RT_XT_PIC_TAIL:
|
|
||||||
case RT_IMMEDIATE:
|
|
||||||
case RT_HERE:
|
|
||||||
case RT_UNTAGGED:
|
|
||||||
case RT_VM:
|
|
||||||
return 1;
|
|
||||||
case RT_DLSYM:
|
|
||||||
return 2;
|
|
||||||
case RT_THIS:
|
|
||||||
case RT_CONTEXT:
|
|
||||||
case RT_MEGAMORPHIC_CACHE_HITS:
|
|
||||||
case RT_CARDS_OFFSET:
|
|
||||||
case RT_DECKS_OFFSET:
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
critical_error("Bad rel type",type);
|
|
||||||
return -1; /* Can't happen */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *factor_vm::object_xt(cell obj)
|
void *factor_vm::object_xt(cell obj)
|
||||||
{
|
{
|
||||||
switch(tagged<object>(obj).type())
|
switch(tagged<object>(obj).type())
|
||||||
|
@ -148,11 +106,11 @@ cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block
|
||||||
{
|
{
|
||||||
array *literals = (to_boolean(compiled->literals)
|
array *literals = (to_boolean(compiled->literals)
|
||||||
? untag<array>(compiled->literals) : NULL);
|
? untag<array>(compiled->literals) : NULL);
|
||||||
cell offset = relocation_offset_of(rel) + (cell)compiled->xt();
|
cell offset = rel.rel_offset() + (cell)compiled->xt();
|
||||||
|
|
||||||
#define ARG array_nth(literals,index)
|
#define ARG array_nth(literals,index)
|
||||||
|
|
||||||
switch(relocation_type_of(rel))
|
switch(rel.rel_type())
|
||||||
{
|
{
|
||||||
case RT_PRIMITIVE:
|
case RT_PRIMITIVE:
|
||||||
return (cell)primitives[untag_fixnum(ARG)];
|
return (cell)primitives[untag_fixnum(ARG)];
|
||||||
|
@ -186,7 +144,7 @@ cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block
|
||||||
case RT_DECKS_OFFSET:
|
case RT_DECKS_OFFSET:
|
||||||
return decks_offset;
|
return decks_offset;
|
||||||
default:
|
default:
|
||||||
critical_error("Bad rel type",rel);
|
critical_error("Bad rel type",rel.rel_type());
|
||||||
return 0; /* Can't happen */
|
return 0; /* Can't happen */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,75 +164,11 @@ template<typename Iterator> void factor_vm::iterate_relocations(code_block *comp
|
||||||
{
|
{
|
||||||
relocation_entry rel = relocation->data<relocation_entry>()[i];
|
relocation_entry rel = relocation->data<relocation_entry>()[i];
|
||||||
iter(rel,index,compiled);
|
iter(rel,index,compiled);
|
||||||
index += number_of_parameters(relocation_type_of(rel));
|
index += rel.number_of_parameters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
|
|
||||||
void factor_vm::store_address_2_2(cell *ptr, cell value)
|
|
||||||
{
|
|
||||||
ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff));
|
|
||||||
ptr[ 0] = ((ptr[ 0] & ~0xffff) | (value & 0xffff));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store a value into a bitfield of a PowerPC instruction */
|
|
||||||
void factor_vm::store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shift)
|
|
||||||
{
|
|
||||||
/* This is unaccurate but good enough */
|
|
||||||
fixnum test = (fixnum)mask >> 1;
|
|
||||||
if(value <= -test || value >= test)
|
|
||||||
critical_error("Value does not fit inside relocation",0);
|
|
||||||
|
|
||||||
*ptr = ((*ptr & ~mask) | ((value >> shift) & mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform a fixup on a code block */
|
|
||||||
void factor_vm::store_address_in_code_block(cell klass, cell offset, fixnum absolute_value)
|
|
||||||
{
|
|
||||||
fixnum relative_value = absolute_value - offset;
|
|
||||||
|
|
||||||
switch(klass)
|
|
||||||
{
|
|
||||||
case RC_ABSOLUTE_CELL:
|
|
||||||
*(cell *)offset = absolute_value;
|
|
||||||
break;
|
|
||||||
case RC_ABSOLUTE:
|
|
||||||
*(u32*)offset = absolute_value;
|
|
||||||
break;
|
|
||||||
case RC_RELATIVE:
|
|
||||||
*(u32*)offset = relative_value - sizeof(u32);
|
|
||||||
break;
|
|
||||||
case RC_ABSOLUTE_PPC_2_2:
|
|
||||||
store_address_2_2((cell *)offset,absolute_value);
|
|
||||||
break;
|
|
||||||
case RC_ABSOLUTE_PPC_2:
|
|
||||||
store_address_masked((cell *)offset,absolute_value,rel_absolute_ppc_2_mask,0);
|
|
||||||
break;
|
|
||||||
case RC_RELATIVE_PPC_2:
|
|
||||||
store_address_masked((cell *)offset,relative_value,rel_relative_ppc_2_mask,0);
|
|
||||||
break;
|
|
||||||
case RC_RELATIVE_PPC_3:
|
|
||||||
store_address_masked((cell *)offset,relative_value,rel_relative_ppc_3_mask,0);
|
|
||||||
break;
|
|
||||||
case RC_RELATIVE_ARM_3:
|
|
||||||
store_address_masked((cell *)offset,relative_value - sizeof(cell) * 2,
|
|
||||||
rel_relative_arm_3_mask,2);
|
|
||||||
break;
|
|
||||||
case RC_INDIRECT_ARM:
|
|
||||||
store_address_masked((cell *)offset,relative_value - sizeof(cell),
|
|
||||||
rel_indirect_arm_mask,0);
|
|
||||||
break;
|
|
||||||
case RC_INDIRECT_ARM_PC:
|
|
||||||
store_address_masked((cell *)offset,relative_value - sizeof(cell) * 2,
|
|
||||||
rel_indirect_arm_mask,0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
critical_error("Bad rel class",klass);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct literal_references_updater {
|
struct literal_references_updater {
|
||||||
factor_vm *parent;
|
factor_vm *parent;
|
||||||
|
|
||||||
|
@ -282,12 +176,11 @@ struct literal_references_updater {
|
||||||
|
|
||||||
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
||||||
{
|
{
|
||||||
if(parent->relocation_type_of(rel) == RT_IMMEDIATE)
|
if(rel.rel_type() == RT_IMMEDIATE)
|
||||||
{
|
{
|
||||||
cell offset = parent->relocation_offset_of(rel) + (cell)(compiled + 1);
|
embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
|
||||||
array *literals = untag<array>(compiled->literals);
|
array *literals = untag<array>(compiled->literals);
|
||||||
fixnum absolute_value = array_nth(literals,index);
|
ptr.store_address(array_nth(literals,index));
|
||||||
parent->store_address_in_code_block(parent->relocation_class_of(rel),offset,absolute_value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -313,9 +206,8 @@ void factor_vm::relocate_code_block_step(relocation_entry rel, cell index, code_
|
||||||
tagged<byte_array>(compiled->relocation).untag_check(this);
|
tagged<byte_array>(compiled->relocation).untag_check(this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
store_address_in_code_block(relocation_class_of(rel),
|
embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
|
||||||
relocation_offset_of(rel) + (cell)compiled->xt(),
|
ptr.store_address(compute_relocation(rel,index,compiled));
|
||||||
compute_relocation(rel,index,compiled));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct word_references_updater {
|
struct word_references_updater {
|
||||||
|
@ -324,7 +216,7 @@ struct word_references_updater {
|
||||||
explicit word_references_updater(factor_vm *parent_) : parent(parent_) {}
|
explicit word_references_updater(factor_vm *parent_) : parent(parent_) {}
|
||||||
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
||||||
{
|
{
|
||||||
relocation_type type = parent->relocation_type_of(rel);
|
relocation_type type = rel.rel_type();
|
||||||
if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
|
if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
|
||||||
parent->relocate_code_block_step(rel,index,compiled);
|
parent->relocate_code_block_step(rel,index,compiled);
|
||||||
}
|
}
|
||||||
|
@ -363,7 +255,8 @@ struct literal_and_word_references_updater {
|
||||||
|
|
||||||
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
||||||
{
|
{
|
||||||
relocation_type type = parent->relocation_type_of(rel);
|
relocation_type type = rel.rel_type();
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case RT_IMMEDIATE:
|
case RT_IMMEDIATE:
|
||||||
|
@ -425,13 +318,12 @@ void factor_vm::fixup_labels(array *labels, code_block *compiled)
|
||||||
|
|
||||||
for(i = 0; i < size; i += 3)
|
for(i = 0; i < size; i += 3)
|
||||||
{
|
{
|
||||||
cell klass = untag_fixnum(array_nth(labels,i));
|
cell rel_class = untag_fixnum(array_nth(labels,i));
|
||||||
cell offset = untag_fixnum(array_nth(labels,i + 1));
|
cell offset = untag_fixnum(array_nth(labels,i + 1));
|
||||||
cell target = untag_fixnum(array_nth(labels,i + 2));
|
cell target = untag_fixnum(array_nth(labels,i + 2));
|
||||||
|
|
||||||
store_address_in_code_block(klass,
|
embedded_pointer ptr(rel_class,offset + (cell)(compiled + 1));
|
||||||
offset + (cell)(compiled + 1),
|
ptr.store_address(target + (cell)(compiled + 1));
|
||||||
target + (cell)(compiled + 1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
namespace factor
|
||||||
|
{
|
||||||
|
|
||||||
|
/* The compiled code heap is structured into blocks. */
|
||||||
|
struct code_block
|
||||||
|
{
|
||||||
|
cell header;
|
||||||
|
cell owner; /* tagged pointer to word, quotation or f */
|
||||||
|
cell literals; /* tagged pointer to array or f */
|
||||||
|
cell relocation; /* tagged pointer to byte-array or f */
|
||||||
|
|
||||||
|
bool free_p() const
|
||||||
|
{
|
||||||
|
return header & 1 == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
code_block_type type() const
|
||||||
|
{
|
||||||
|
return (code_block_type)((header >> 1) & 0x3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_type(code_block_type type)
|
||||||
|
{
|
||||||
|
header = ((header & ~0x7) | (type << 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pic_p() const
|
||||||
|
{
|
||||||
|
return type() == code_block_pic;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool optimized_p() const
|
||||||
|
{
|
||||||
|
return type() == code_block_optimized;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell size() const
|
||||||
|
{
|
||||||
|
return header & ~7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *xt() const
|
||||||
|
{
|
||||||
|
return (void *)(this + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
#include "master.hpp"
|
||||||
|
|
||||||
|
namespace factor
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Load a 32-bit value from a PowerPC LIS/ORI sequence */
|
||||||
|
fixnum embedded_pointer::load_address_2_2()
|
||||||
|
{
|
||||||
|
cell *ptr = (cell *)pointer;
|
||||||
|
cell hi = (ptr[-1] & 0xffff);
|
||||||
|
cell lo = (ptr[ 0] & 0xffff);
|
||||||
|
return hi << 16 | lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load a value from a bitfield of a PowerPC instruction */
|
||||||
|
fixnum embedded_pointer::load_address_masked(cell mask, fixnum shift)
|
||||||
|
{
|
||||||
|
cell *ptr = (cell *)pointer;
|
||||||
|
|
||||||
|
return (*ptr & mask) << shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixnum embedded_pointer::load_address()
|
||||||
|
{
|
||||||
|
switch(rel_class)
|
||||||
|
{
|
||||||
|
case RC_ABSOLUTE_CELL:
|
||||||
|
return *(cell *)pointer;
|
||||||
|
case RC_ABSOLUTE:
|
||||||
|
return *(u32*)pointer;
|
||||||
|
case RC_RELATIVE:
|
||||||
|
return *(u32*)pointer + pointer + sizeof(u32);
|
||||||
|
case RC_ABSOLUTE_PPC_2_2:
|
||||||
|
return load_address_2_2();
|
||||||
|
case RC_ABSOLUTE_PPC_2:
|
||||||
|
return load_address_masked(rel_absolute_ppc_2_mask,0);
|
||||||
|
case RC_RELATIVE_PPC_2:
|
||||||
|
return load_address_masked(rel_relative_ppc_2_mask,0) + pointer;
|
||||||
|
case RC_RELATIVE_PPC_3:
|
||||||
|
return load_address_masked(rel_relative_ppc_3_mask,0) + pointer;
|
||||||
|
case RC_RELATIVE_ARM_3:
|
||||||
|
return load_address_masked(rel_relative_arm_3_mask,2) + pointer + sizeof(cell) * 2;
|
||||||
|
case RC_INDIRECT_ARM:
|
||||||
|
return load_address_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell);
|
||||||
|
case RC_INDIRECT_ARM_PC:
|
||||||
|
return load_address_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell) * 2;
|
||||||
|
default:
|
||||||
|
critical_error("Bad rel class",rel_class);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
|
||||||
|
void embedded_pointer::store_address_2_2(fixnum value)
|
||||||
|
{
|
||||||
|
cell *ptr = (cell *)pointer;
|
||||||
|
ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff));
|
||||||
|
ptr[ 0] = ((ptr[ 0] & ~0xffff) | (value & 0xffff));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store a value into a bitfield of a PowerPC instruction */
|
||||||
|
void embedded_pointer::store_address_masked(fixnum value, cell mask, fixnum shift)
|
||||||
|
{
|
||||||
|
cell *ptr = (cell *)pointer;
|
||||||
|
|
||||||
|
/* This is unaccurate but good enough */
|
||||||
|
fixnum test = (fixnum)mask >> 1;
|
||||||
|
if(value <= -test || value >= test)
|
||||||
|
critical_error("Value does not fit inside relocation",0);
|
||||||
|
|
||||||
|
*ptr = ((*ptr & ~mask) | ((value >> shift) & mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
void embedded_pointer::store_address(fixnum absolute_value)
|
||||||
|
{
|
||||||
|
fixnum relative_value = absolute_value - pointer;
|
||||||
|
|
||||||
|
switch(rel_class)
|
||||||
|
{
|
||||||
|
case RC_ABSOLUTE_CELL:
|
||||||
|
*(cell *)pointer = absolute_value;
|
||||||
|
break;
|
||||||
|
case RC_ABSOLUTE:
|
||||||
|
*(u32*)pointer = absolute_value;
|
||||||
|
break;
|
||||||
|
case RC_RELATIVE:
|
||||||
|
*(u32*)pointer = relative_value - sizeof(u32);
|
||||||
|
break;
|
||||||
|
case RC_ABSOLUTE_PPC_2_2:
|
||||||
|
store_address_2_2(absolute_value);
|
||||||
|
break;
|
||||||
|
case RC_ABSOLUTE_PPC_2:
|
||||||
|
store_address_masked(absolute_value,rel_absolute_ppc_2_mask,0);
|
||||||
|
break;
|
||||||
|
case RC_RELATIVE_PPC_2:
|
||||||
|
store_address_masked(relative_value,rel_relative_ppc_2_mask,0);
|
||||||
|
break;
|
||||||
|
case RC_RELATIVE_PPC_3:
|
||||||
|
store_address_masked(relative_value,rel_relative_ppc_3_mask,0);
|
||||||
|
break;
|
||||||
|
case RC_RELATIVE_ARM_3:
|
||||||
|
store_address_masked(relative_value - sizeof(cell) * 2,rel_relative_arm_3_mask,2);
|
||||||
|
break;
|
||||||
|
case RC_INDIRECT_ARM:
|
||||||
|
store_address_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0);
|
||||||
|
break;
|
||||||
|
case RC_INDIRECT_ARM_PC:
|
||||||
|
store_address_masked(relative_value - sizeof(cell) * 2,rel_indirect_arm_mask,0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
critical_error("Bad rel class",rel_class);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -64,6 +64,75 @@ static const cell rel_indirect_arm_mask = 0xfff;
|
||||||
static const cell rel_relative_arm_3_mask = 0xffffff;
|
static const cell rel_relative_arm_3_mask = 0xffffff;
|
||||||
|
|
||||||
/* code relocation table consists of a table of entries for each fixup */
|
/* code relocation table consists of a table of entries for each fixup */
|
||||||
typedef u32 relocation_entry;
|
struct relocation_entry {
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
relocation_entry(u32 value_) : value(value_) {}
|
||||||
|
|
||||||
|
relocation_entry(relocation_type rel_type,
|
||||||
|
relocation_class rel_class,
|
||||||
|
cell offset)
|
||||||
|
{
|
||||||
|
value = (rel_type << 28) | (rel_class << 24) | offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
relocation_type rel_type()
|
||||||
|
{
|
||||||
|
return (relocation_type)((value & 0xf0000000) >> 28);
|
||||||
|
}
|
||||||
|
|
||||||
|
relocation_class rel_class()
|
||||||
|
{
|
||||||
|
return (relocation_class)((value & 0x0f000000) >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell rel_offset()
|
||||||
|
{
|
||||||
|
return (value & 0x00ffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
int number_of_parameters()
|
||||||
|
{
|
||||||
|
switch(rel_type())
|
||||||
|
{
|
||||||
|
case RT_PRIMITIVE:
|
||||||
|
case RT_XT:
|
||||||
|
case RT_XT_PIC:
|
||||||
|
case RT_XT_PIC_TAIL:
|
||||||
|
case RT_IMMEDIATE:
|
||||||
|
case RT_HERE:
|
||||||
|
case RT_UNTAGGED:
|
||||||
|
case RT_VM:
|
||||||
|
return 1;
|
||||||
|
case RT_DLSYM:
|
||||||
|
return 2;
|
||||||
|
case RT_THIS:
|
||||||
|
case RT_CONTEXT:
|
||||||
|
case RT_MEGAMORPHIC_CACHE_HITS:
|
||||||
|
case RT_CARDS_OFFSET:
|
||||||
|
case RT_DECKS_OFFSET:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
critical_error("Bad rel type",rel_type());
|
||||||
|
return -1; /* Can't happen */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct embedded_pointer {
|
||||||
|
cell rel_class;
|
||||||
|
cell pointer;
|
||||||
|
|
||||||
|
embedded_pointer(cell rel_class_, cell pointer_) :
|
||||||
|
rel_class(rel_class_), pointer(pointer_) {}
|
||||||
|
|
||||||
|
fixnum load_address_2_2();
|
||||||
|
fixnum load_address_masked(cell mask, fixnum shift);
|
||||||
|
fixnum load_address();
|
||||||
|
|
||||||
|
void store_address_2_2(fixnum value);
|
||||||
|
void store_address_masked(fixnum value, cell mask, fixnum shift);
|
||||||
|
void store_address(fixnum value);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -32,10 +32,10 @@ void jit::emit_relocation(cell code_template_)
|
||||||
cell rel_type = array_nth(code_template.untagged(),i + 1);
|
cell rel_type = array_nth(code_template.untagged(),i + 1);
|
||||||
cell offset = array_nth(code_template.untagged(),i + 2);
|
cell offset = array_nth(code_template.untagged(),i + 2);
|
||||||
|
|
||||||
relocation_entry new_entry
|
relocation_entry new_entry(
|
||||||
= (untag_fixnum(rel_type) << 28)
|
(relocation_type)untag_fixnum(rel_type),
|
||||||
| (untag_fixnum(rel_class) << 24)
|
(relocation_class)untag_fixnum(rel_class),
|
||||||
| ((code.count + untag_fixnum(offset)));
|
code.count + untag_fixnum(offset));
|
||||||
relocation.append_bytes(&new_entry,sizeof(relocation_entry));
|
relocation.append_bytes(&new_entry,sizeof(relocation_entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,49 +211,7 @@ struct string : public object {
|
||||||
cell nth(cell i) const;
|
cell nth(cell i) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The compiled code heap is structured into blocks. */
|
struct code_block;
|
||||||
struct code_block
|
|
||||||
{
|
|
||||||
cell header;
|
|
||||||
cell owner; /* tagged pointer to word, quotation or f */
|
|
||||||
cell literals; /* tagged pointer to array or f */
|
|
||||||
cell relocation; /* tagged pointer to byte-array or f */
|
|
||||||
|
|
||||||
bool free_p() const
|
|
||||||
{
|
|
||||||
return header & 1 == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
code_block_type type() const
|
|
||||||
{
|
|
||||||
return (code_block_type)((header >> 1) & 0x3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_type(code_block_type type)
|
|
||||||
{
|
|
||||||
header = ((header & ~0x7) | (type << 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pic_p() const
|
|
||||||
{
|
|
||||||
return type() == code_block_pic;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool optimized_p() const
|
|
||||||
{
|
|
||||||
return type() == code_block_optimized;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell size() const
|
|
||||||
{
|
|
||||||
return header & ~7;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *xt() const
|
|
||||||
{
|
|
||||||
return (void *)(this + 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Assembly code makes assumptions about the layout of this struct */
|
/* Assembly code makes assumptions about the layout of this struct */
|
||||||
struct word : public object {
|
struct word : public object {
|
||||||
|
|
|
@ -49,7 +49,8 @@ namespace factor
|
||||||
#include "errors.hpp"
|
#include "errors.hpp"
|
||||||
#include "bignumint.hpp"
|
#include "bignumint.hpp"
|
||||||
#include "bignum.hpp"
|
#include "bignum.hpp"
|
||||||
#include "code_block.hpp"
|
#include "embedded_pointers.hpp"
|
||||||
|
#include "code_blocks.hpp"
|
||||||
#include "bump_allocator.hpp"
|
#include "bump_allocator.hpp"
|
||||||
#include "bitwise_hacks.hpp"
|
#include "bitwise_hacks.hpp"
|
||||||
#include "mark_bits.hpp"
|
#include "mark_bits.hpp"
|
||||||
|
|
|
@ -8,14 +8,18 @@ template<typename Visitor> struct slot_visitor {
|
||||||
explicit slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
|
explicit slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
|
||||||
parent(parent_), visitor(visitor_) {}
|
parent(parent_), visitor(visitor_) {}
|
||||||
|
|
||||||
void visit_handle(cell *handle)
|
cell visit_pointer(cell pointer)
|
||||||
{
|
{
|
||||||
cell pointer = *handle;
|
if(immediate_p(pointer)) return pointer;
|
||||||
if(immediate_p(pointer)) return;
|
|
||||||
|
|
||||||
object *untagged = untag<object>(pointer);
|
object *untagged = untag<object>(pointer);
|
||||||
untagged = visitor(untagged);
|
untagged = visitor(untagged);
|
||||||
*handle = RETAG(untagged,TAG(pointer));
|
return RETAG(untagged,TAG(pointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void visit_handle(cell *handle)
|
||||||
|
{
|
||||||
|
*handle = visit_pointer(*handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_slots(object *ptr, cell payload_start)
|
void visit_slots(object *ptr, cell payload_start)
|
||||||
|
|
|
@ -485,11 +485,7 @@ struct factor_vm
|
||||||
void primitive_fclose();
|
void primitive_fclose();
|
||||||
|
|
||||||
//code_block
|
//code_block
|
||||||
relocation_type relocation_type_of(relocation_entry r);
|
|
||||||
relocation_class relocation_class_of(relocation_entry r);
|
|
||||||
cell relocation_offset_of(relocation_entry r);
|
|
||||||
void flush_icache_for(code_block *block);
|
void flush_icache_for(code_block *block);
|
||||||
int number_of_parameters(relocation_type type);
|
|
||||||
void *object_xt(cell obj);
|
void *object_xt(cell obj);
|
||||||
void *xt_pic(word *w, cell tagged_quot);
|
void *xt_pic(word *w, cell tagged_quot);
|
||||||
void *word_xt_pic(word *w);
|
void *word_xt_pic(word *w);
|
||||||
|
@ -498,9 +494,6 @@ struct factor_vm
|
||||||
void *get_rel_symbol(array *literals, cell index);
|
void *get_rel_symbol(array *literals, cell index);
|
||||||
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
|
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
|
||||||
template<typename Iterator> void iterate_relocations(code_block *compiled, Iterator &iter);
|
template<typename Iterator> void iterate_relocations(code_block *compiled, Iterator &iter);
|
||||||
void store_address_2_2(cell *ptr, cell value);
|
|
||||||
void store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shift);
|
|
||||||
void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value);
|
|
||||||
void update_literal_references(code_block *compiled);
|
void update_literal_references(code_block *compiled);
|
||||||
void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
|
void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
|
||||||
void update_word_references(code_block *compiled);
|
void update_word_references(code_block *compiled);
|
||||||
|
|
Loading…
Reference in New Issue