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/callbacks.o \
 | 
			
		||||
	vm/callstack.o \
 | 
			
		||||
	vm/code_block.o \
 | 
			
		||||
	vm/code_blocks.o \
 | 
			
		||||
	vm/code_heap.o \
 | 
			
		||||
	vm/compaction.o \
 | 
			
		||||
	vm/contexts.o \
 | 
			
		||||
	vm/data_heap.o \
 | 
			
		||||
	vm/debug.o \
 | 
			
		||||
	vm/dispatch.o \
 | 
			
		||||
	vm/embedded_pointers.o \
 | 
			
		||||
	vm/errors.o \
 | 
			
		||||
	vm/factor.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 offset = untag_fixnum(array_nth(code_template.untagged(),3));
 | 
			
		||||
 | 
			
		||||
	parent->store_address_in_code_block(rel_class,
 | 
			
		||||
		(cell)(stub + 1) + offset,
 | 
			
		||||
		(cell)(stub->compiled + 1));
 | 
			
		||||
	embedded_pointer ptr(rel_class,offset + (cell)(stub + 1));
 | 
			
		||||
	ptr.store_address((cell)(stub->compiled + 1));
 | 
			
		||||
 | 
			
		||||
	flush_icache((cell)stub,stub->size);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,53 +3,11 @@
 | 
			
		|||
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)
 | 
			
		||||
{
 | 
			
		||||
	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)
 | 
			
		||||
{
 | 
			
		||||
	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)
 | 
			
		||||
		? 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)
 | 
			
		||||
 | 
			
		||||
	switch(relocation_type_of(rel))
 | 
			
		||||
	switch(rel.rel_type())
 | 
			
		||||
	{
 | 
			
		||||
	case RT_PRIMITIVE:
 | 
			
		||||
		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:
 | 
			
		||||
		return decks_offset;
 | 
			
		||||
	default:
 | 
			
		||||
		critical_error("Bad rel type",rel);
 | 
			
		||||
		critical_error("Bad rel type",rel.rel_type());
 | 
			
		||||
		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];
 | 
			
		||||
			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 {
 | 
			
		||||
	factor_vm *parent;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -282,12 +176,11 @@ struct literal_references_updater {
 | 
			
		|||
 | 
			
		||||
	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);
 | 
			
		||||
			fixnum absolute_value = array_nth(literals,index);
 | 
			
		||||
			parent->store_address_in_code_block(parent->relocation_class_of(rel),offset,absolute_value);
 | 
			
		||||
			ptr.store_address(array_nth(literals,index));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	store_address_in_code_block(relocation_class_of(rel),
 | 
			
		||||
		relocation_offset_of(rel) + (cell)compiled->xt(),
 | 
			
		||||
		compute_relocation(rel,index,compiled));
 | 
			
		||||
	embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
 | 
			
		||||
	ptr.store_address(compute_relocation(rel,index,compiled));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct word_references_updater {
 | 
			
		||||
| 
						 | 
				
			
			@ -324,7 +216,7 @@ struct word_references_updater {
 | 
			
		|||
	explicit word_references_updater(factor_vm *parent_) : parent(parent_) {}
 | 
			
		||||
	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)
 | 
			
		||||
			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)
 | 
			
		||||
	{
 | 
			
		||||
		relocation_type type = parent->relocation_type_of(rel);
 | 
			
		||||
		relocation_type type = rel.rel_type();
 | 
			
		||||
 | 
			
		||||
		switch(type)
 | 
			
		||||
		{
 | 
			
		||||
		case RT_IMMEDIATE:
 | 
			
		||||
| 
						 | 
				
			
			@ -425,13 +318,12 @@ void factor_vm::fixup_labels(array *labels, code_block *compiled)
 | 
			
		|||
 | 
			
		||||
	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 target = untag_fixnum(array_nth(labels,i + 2));
 | 
			
		||||
 | 
			
		||||
		store_address_in_code_block(klass,
 | 
			
		||||
			offset + (cell)(compiled + 1),
 | 
			
		||||
			target + (cell)(compiled + 1));
 | 
			
		||||
		embedded_pointer ptr(rel_class,offset + (cell)(compiled + 1));
 | 
			
		||||
		ptr.store_address(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;
 | 
			
		||||
 | 
			
		||||
/* 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 offset = array_nth(code_template.untagged(),i + 2);
 | 
			
		||||
 | 
			
		||||
		relocation_entry new_entry
 | 
			
		||||
			= (untag_fixnum(rel_type) << 28)
 | 
			
		||||
			| (untag_fixnum(rel_class) << 24)
 | 
			
		||||
			| ((code.count + untag_fixnum(offset)));
 | 
			
		||||
		relocation_entry new_entry(
 | 
			
		||||
			(relocation_type)untag_fixnum(rel_type),
 | 
			
		||||
			(relocation_class)untag_fixnum(rel_class),
 | 
			
		||||
			code.count + untag_fixnum(offset));
 | 
			
		||||
		relocation.append_bytes(&new_entry,sizeof(relocation_entry));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -211,49 +211,7 @@ struct string : public object {
 | 
			
		|||
	cell nth(cell i) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 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);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
struct code_block;
 | 
			
		||||
 | 
			
		||||
/* Assembly code makes assumptions about the layout of this struct */
 | 
			
		||||
struct word : public object {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,8 @@ namespace factor
 | 
			
		|||
#include "errors.hpp"
 | 
			
		||||
#include "bignumint.hpp"
 | 
			
		||||
#include "bignum.hpp"
 | 
			
		||||
#include "code_block.hpp"
 | 
			
		||||
#include "embedded_pointers.hpp"
 | 
			
		||||
#include "code_blocks.hpp"
 | 
			
		||||
#include "bump_allocator.hpp"
 | 
			
		||||
#include "bitwise_hacks.hpp"
 | 
			
		||||
#include "mark_bits.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,14 +8,18 @@ template<typename Visitor> struct slot_visitor {
 | 
			
		|||
	explicit slot_visitor<Visitor>(factor_vm *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;
 | 
			
		||||
		if(immediate_p(pointer)) return pointer;
 | 
			
		||||
 | 
			
		||||
		object *untagged = untag<object>(pointer);
 | 
			
		||||
		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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -485,11 +485,7 @@ struct factor_vm
 | 
			
		|||
	void primitive_fclose();
 | 
			
		||||
 | 
			
		||||
	//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);
 | 
			
		||||
	int number_of_parameters(relocation_type type);
 | 
			
		||||
	void *object_xt(cell obj);
 | 
			
		||||
	void *xt_pic(word *w, cell tagged_quot);
 | 
			
		||||
	void *word_xt_pic(word *w);
 | 
			
		||||
| 
						 | 
				
			
			@ -498,9 +494,6 @@ struct factor_vm
 | 
			
		|||
	void *get_rel_symbol(array *literals, cell index);
 | 
			
		||||
	cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
 | 
			
		||||
	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 relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
 | 
			
		||||
	void update_word_references(code_block *compiled);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue