More compact relocation layout
parent
53e519b87b
commit
ae09d85d84
|
@ -11,12 +11,34 @@ void iterate_relocations(F_CODE_BLOCK *compiled, RELOCATION_ITERATOR iter)
|
|||
{
|
||||
F_BYTE_ARRAY *relocation = untag_object(compiled->relocation);
|
||||
|
||||
F_REL *rel = (F_REL *)(relocation + 1);
|
||||
F_REL *rel_end = (F_REL *)((char *)rel + byte_array_capacity(relocation));
|
||||
CELL index = 1;
|
||||
|
||||
CELL *rel = (CELL *)(relocation + 1);
|
||||
CELL *rel_end = (CELL *)((char *)rel + byte_array_capacity(relocation));
|
||||
|
||||
while(rel < rel_end)
|
||||
{
|
||||
iter(rel,compiled);
|
||||
iter(*rel,index,compiled);
|
||||
|
||||
switch(REL_TYPE(*rel))
|
||||
{
|
||||
case RT_PRIMITIVE:
|
||||
case RT_XT:
|
||||
case RT_IMMEDIATE:
|
||||
case RT_HERE:
|
||||
index++;
|
||||
break;
|
||||
case RT_DLSYM:
|
||||
index += 2;
|
||||
break;
|
||||
case RT_THIS:
|
||||
case RT_STACK_CHAIN:
|
||||
break;
|
||||
default:
|
||||
critical_error("Bad rel type",*rel);
|
||||
return; /* Can't happen */
|
||||
}
|
||||
|
||||
rel++;
|
||||
}
|
||||
}
|
||||
|
@ -85,13 +107,13 @@ void store_address_in_code_block(CELL class, CELL offset, F_FIXNUM absolute_valu
|
|||
}
|
||||
}
|
||||
|
||||
void update_literal_references_step(F_REL *rel, F_CODE_BLOCK *compiled)
|
||||
void update_literal_references_step(CELL rel, CELL index, F_CODE_BLOCK *compiled)
|
||||
{
|
||||
if(REL_TYPE(rel) == RT_IMMEDIATE)
|
||||
{
|
||||
CELL offset = rel->offset + (CELL)(compiled + 1);
|
||||
CELL offset = REL_OFFSET(rel) + (CELL)(compiled + 1);
|
||||
F_ARRAY *literals = untag_object(compiled->literals);
|
||||
F_FIXNUM absolute_value = array_nth(literals,REL_ARGUMENT(rel));
|
||||
F_FIXNUM absolute_value = array_nth(literals,index);
|
||||
store_address_in_code_block(REL_CLASS(rel),offset,absolute_value);
|
||||
}
|
||||
}
|
||||
|
@ -136,13 +158,13 @@ CELL object_xt(CELL obj)
|
|||
return (CELL)untag_quotation(obj)->xt;
|
||||
}
|
||||
|
||||
void update_word_references_step(F_REL *rel, F_CODE_BLOCK *compiled)
|
||||
void update_word_references_step(CELL rel, CELL index, F_CODE_BLOCK *compiled)
|
||||
{
|
||||
if(REL_TYPE(rel) == RT_XT)
|
||||
{
|
||||
CELL offset = rel->offset + (CELL)(compiled + 1);
|
||||
CELL offset = REL_OFFSET(rel) + (CELL)(compiled + 1);
|
||||
F_ARRAY *literals = untag_object(compiled->literals);
|
||||
CELL xt = object_xt(array_nth(literals,REL_ARGUMENT(rel)));
|
||||
CELL xt = object_xt(array_nth(literals,index));
|
||||
store_address_in_code_block(REL_CLASS(rel),offset,xt);
|
||||
}
|
||||
}
|
||||
|
@ -228,11 +250,10 @@ void undefined_symbol(void)
|
|||
}
|
||||
|
||||
/* Look up an external library symbol referenced by a compiled code block */
|
||||
void *get_rel_symbol(F_REL *rel, F_ARRAY *literals)
|
||||
void *get_rel_symbol(F_ARRAY *literals, CELL index)
|
||||
{
|
||||
CELL arg = REL_ARGUMENT(rel);
|
||||
CELL symbol = array_nth(literals,arg);
|
||||
CELL library = array_nth(literals,arg + 1);
|
||||
CELL symbol = array_nth(literals,index);
|
||||
CELL library = array_nth(literals,index + 1);
|
||||
|
||||
F_DLL *dll = (library == F ? NULL : untag_dll(library));
|
||||
|
||||
|
@ -265,37 +286,37 @@ void *get_rel_symbol(F_REL *rel, F_ARRAY *literals)
|
|||
}
|
||||
|
||||
/* Compute an address to store at a relocation */
|
||||
void relocate_code_block_step(F_REL *rel, F_CODE_BLOCK *compiled)
|
||||
void relocate_code_block_step(CELL rel, CELL index, F_CODE_BLOCK *compiled)
|
||||
{
|
||||
CELL offset = rel->offset + (CELL)(compiled + 1);
|
||||
CELL offset = REL_OFFSET(rel) + (CELL)(compiled + 1);
|
||||
F_ARRAY *literals = untag_object(compiled->literals);
|
||||
F_FIXNUM absolute_value;
|
||||
|
||||
switch(REL_TYPE(rel))
|
||||
{
|
||||
case RT_PRIMITIVE:
|
||||
absolute_value = (CELL)primitives[REL_ARGUMENT(rel)];
|
||||
absolute_value = (CELL)primitives[to_fixnum(array_nth(literals,index))];
|
||||
break;
|
||||
case RT_DLSYM:
|
||||
absolute_value = (CELL)get_rel_symbol(rel,literals);
|
||||
absolute_value = (CELL)get_rel_symbol(literals,index);
|
||||
break;
|
||||
case RT_IMMEDIATE:
|
||||
absolute_value = array_nth(literals,REL_ARGUMENT(rel));
|
||||
absolute_value = array_nth(literals,index);
|
||||
break;
|
||||
case RT_XT:
|
||||
absolute_value = object_xt(array_nth(literals,REL_ARGUMENT(rel)));
|
||||
absolute_value = object_xt(array_nth(literals,index));
|
||||
break;
|
||||
case RT_HERE:
|
||||
absolute_value = rel->offset + (CELL)(compiled + 1) + (short)REL_ARGUMENT(rel);
|
||||
absolute_value = offset + (short)to_fixnum(array_nth(literals,index));
|
||||
break;
|
||||
case RT_LABEL:
|
||||
absolute_value = (CELL)(compiled + 1) + REL_ARGUMENT(rel);
|
||||
case RT_THIS:
|
||||
absolute_value = (CELL)(compiled + 1);
|
||||
break;
|
||||
case RT_STACK_CHAIN:
|
||||
absolute_value = (CELL)&stack_chain;
|
||||
break;
|
||||
default:
|
||||
critical_error("Bad rel type",rel->type);
|
||||
critical_error("Bad rel type",rel);
|
||||
return; /* Can't happen */
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ typedef enum {
|
|||
RT_XT,
|
||||
/* current offset */
|
||||
RT_HERE,
|
||||
/* a local label */
|
||||
RT_LABEL,
|
||||
/* current code block */
|
||||
RT_THIS,
|
||||
/* immediate literal */
|
||||
RT_IMMEDIATE,
|
||||
/* address of stack_chain var */
|
||||
|
@ -43,21 +43,14 @@ typedef enum {
|
|||
#define REL_INDIRECT_ARM_MASK 0xfff
|
||||
#define REL_RELATIVE_ARM_3_MASK 0xffffff
|
||||
|
||||
/* the rel type is built like a cell to avoid endian-specific code in
|
||||
the compiler */
|
||||
#define REL_TYPE(r) ((r)->type & 0x000000ff)
|
||||
#define REL_CLASS(r) (((r)->type & 0x0000ff00) >> 8)
|
||||
#define REL_ARGUMENT(r) (((r)->type & 0xffff0000) >> 16)
|
||||
|
||||
/* code relocation consists of a table of entries for each fixup */
|
||||
typedef struct {
|
||||
unsigned int type;
|
||||
unsigned int offset;
|
||||
} F_REL;
|
||||
/* code relocation table consists of a table of entries for each fixup */
|
||||
#define REL_TYPE(r) (((r) & 0xf0000000) >> 28)
|
||||
#define REL_CLASS(r) (((r) & 0x0f000000) >> 24)
|
||||
#define REL_OFFSET(r) ((r) & 0x00ffffff)
|
||||
|
||||
void flush_icache_for(F_CODE_BLOCK *compiled);
|
||||
|
||||
typedef void (*RELOCATION_ITERATOR)(F_REL *rel, F_CODE_BLOCK *compiled);
|
||||
typedef void (*RELOCATION_ITERATOR)(CELL rel, CELL index, F_CODE_BLOCK *compiled);
|
||||
|
||||
void iterate_relocations(F_CODE_BLOCK *compiled, RELOCATION_ITERATOR iter);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/* Allocates memory */
|
||||
F_CODE_BLOCK *compile_profiling_stub(F_WORD *word)
|
||||
{
|
||||
CELL literals = allot_array_1(tag_object(word));
|
||||
CELL literals = allot_array_2(tag_object(word),tag_object(word));
|
||||
REGISTER_ROOT(literals);
|
||||
|
||||
F_ARRAY *quadruple = untag_object(userenv[JIT_PROFILING]);
|
||||
|
@ -11,12 +11,12 @@ F_CODE_BLOCK *compile_profiling_stub(F_WORD *word)
|
|||
CELL code = array_nth(quadruple,0);
|
||||
REGISTER_ROOT(code);
|
||||
|
||||
F_REL rel;
|
||||
rel.type = to_fixnum(array_nth(quadruple,2)) | (to_fixnum(array_nth(quadruple,1)) << 8);
|
||||
rel.offset = to_fixnum(array_nth(quadruple,3)) * compiled_code_format();
|
||||
CELL rel = (to_fixnum(array_nth(quadruple,1)) << 24)
|
||||
| (to_fixnum(array_nth(quadruple,2)) << 28)
|
||||
| (to_fixnum(array_nth(quadruple,3)) * compiled_code_format());
|
||||
|
||||
F_BYTE_ARRAY *relocation = allot_byte_array(sizeof(F_REL));
|
||||
memcpy((void *)BREF(relocation,0),&rel,sizeof(F_REL));
|
||||
F_BYTE_ARRAY *relocation = allot_byte_array(sizeof(CELL));
|
||||
memcpy(relocation + 1,&rel,sizeof(CELL));
|
||||
|
||||
UNREGISTER_ROOT(code);
|
||||
UNREGISTER_ROOT(literals);
|
||||
|
|
|
@ -94,38 +94,31 @@ F_ARRAY *code_to_emit(CELL code)
|
|||
return untag_object(array_nth(untag_object(code),0));
|
||||
}
|
||||
|
||||
F_REL rel_to_emit(CELL code, CELL code_format, CELL code_length,
|
||||
CELL rel_argument, bool *rel_p)
|
||||
CELL rel_to_emit(CELL code, CELL code_format, CELL code_length, bool *rel_p)
|
||||
{
|
||||
F_ARRAY *quadruple = untag_object(code);
|
||||
CELL rel_class = array_nth(quadruple,1);
|
||||
CELL rel_type = array_nth(quadruple,2);
|
||||
CELL offset = array_nth(quadruple,3);
|
||||
|
||||
F_REL rel;
|
||||
|
||||
if(rel_class == F)
|
||||
{
|
||||
*rel_p = false;
|
||||
rel.type = 0;
|
||||
rel.offset = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rel_p = true;
|
||||
rel.type = to_fixnum(rel_type)
|
||||
| (to_fixnum(rel_class) << 8)
|
||||
| (rel_argument << 16);
|
||||
rel.offset = (code_length + to_fixnum(offset)) * code_format;
|
||||
return (to_fixnum(rel_type) << 28)
|
||||
| (to_fixnum(rel_class) << 24)
|
||||
| ((code_length + to_fixnum(offset)) * code_format);
|
||||
}
|
||||
|
||||
return rel;
|
||||
}
|
||||
|
||||
#define EMIT(name,rel_argument) { \
|
||||
#define EMIT(name) { \
|
||||
bool rel_p; \
|
||||
F_REL rel = rel_to_emit(name,code_format,code_count,rel_argument,&rel_p); \
|
||||
if(rel_p) GROWABLE_BYTE_ARRAY_APPEND(relocation,&rel,sizeof(F_REL)); \
|
||||
CELL rel = rel_to_emit(name,code_format,code_count,&rel_p); \
|
||||
if(rel_p) GROWABLE_BYTE_ARRAY_APPEND(relocation,&rel,sizeof(CELL)); \
|
||||
GROWABLE_ARRAY_APPEND(code,code_to_emit(name)); \
|
||||
}
|
||||
|
||||
|
@ -192,7 +185,7 @@ void jit_compile(CELL quot, bool relocate)
|
|||
bool stack_frame = jit_stack_frame_p(untag_object(array));
|
||||
|
||||
if(stack_frame)
|
||||
EMIT(userenv[JIT_PROLOG],0);
|
||||
EMIT(userenv[JIT_PROLOG]);
|
||||
|
||||
CELL i;
|
||||
CELL length = array_capacity(untag_object(array));
|
||||
|
@ -217,35 +210,36 @@ void jit_compile(CELL quot, bool relocate)
|
|||
GROWABLE_ARRAY_ADD(literals,T);
|
||||
}
|
||||
|
||||
EMIT(word->subprimitive,literals_count - 1);
|
||||
EMIT(word->subprimitive);
|
||||
}
|
||||
else
|
||||
{
|
||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||
GROWABLE_ARRAY_ADD(literals,obj);
|
||||
|
||||
if(i == length - 1)
|
||||
{
|
||||
if(stack_frame)
|
||||
EMIT(userenv[JIT_EPILOG],0);
|
||||
EMIT(userenv[JIT_EPILOG]);
|
||||
|
||||
EMIT(userenv[JIT_WORD_JUMP],literals_count - 1);
|
||||
EMIT(userenv[JIT_WORD_JUMP]);
|
||||
|
||||
tail_call = true;
|
||||
}
|
||||
else
|
||||
EMIT(userenv[JIT_WORD_CALL],literals_count - 1);
|
||||
EMIT(userenv[JIT_WORD_CALL]);
|
||||
}
|
||||
break;
|
||||
case WRAPPER_TYPE:
|
||||
wrapper = untag_object(obj);
|
||||
GROWABLE_ARRAY_ADD(literals,wrapper->object);
|
||||
EMIT(userenv[JIT_PUSH_IMMEDIATE],literals_count - 1);
|
||||
EMIT(userenv[JIT_PUSH_IMMEDIATE]);
|
||||
break;
|
||||
case FIXNUM_TYPE:
|
||||
if(jit_primitive_call_p(untag_object(array),i))
|
||||
{
|
||||
EMIT(userenv[JIT_SAVE_STACK],0);
|
||||
EMIT(userenv[JIT_PRIMITIVE],to_fixnum(obj));
|
||||
EMIT(userenv[JIT_SAVE_STACK]);
|
||||
GROWABLE_ARRAY_ADD(literals,obj);
|
||||
EMIT(userenv[JIT_PRIMITIVE]);
|
||||
|
||||
i++;
|
||||
|
||||
|
@ -256,15 +250,15 @@ void jit_compile(CELL quot, bool relocate)
|
|||
if(jit_fast_if_p(untag_object(array),i))
|
||||
{
|
||||
if(stack_frame)
|
||||
EMIT(userenv[JIT_EPILOG],0);
|
||||
EMIT(userenv[JIT_EPILOG]);
|
||||
|
||||
jit_compile(array_nth(untag_object(array),i),relocate);
|
||||
jit_compile(array_nth(untag_object(array),i + 1),relocate);
|
||||
|
||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||
EMIT(userenv[JIT_IF_1],literals_count - 1);
|
||||
EMIT(userenv[JIT_IF_1]);
|
||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i + 1));
|
||||
EMIT(userenv[JIT_IF_2],literals_count - 1);
|
||||
EMIT(userenv[JIT_IF_2]);
|
||||
|
||||
i += 2;
|
||||
|
||||
|
@ -276,7 +270,7 @@ void jit_compile(CELL quot, bool relocate)
|
|||
jit_compile(obj,relocate);
|
||||
|
||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||
EMIT(userenv[JIT_DIP],literals_count - 1);
|
||||
EMIT(userenv[JIT_DIP]);
|
||||
|
||||
i++;
|
||||
break;
|
||||
|
@ -286,7 +280,7 @@ void jit_compile(CELL quot, bool relocate)
|
|||
jit_compile(obj,relocate);
|
||||
|
||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||
EMIT(userenv[JIT_2DIP],literals_count - 1);
|
||||
EMIT(userenv[JIT_2DIP]);
|
||||
|
||||
i++;
|
||||
break;
|
||||
|
@ -296,7 +290,7 @@ void jit_compile(CELL quot, bool relocate)
|
|||
jit_compile(obj,relocate);
|
||||
|
||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||
EMIT(userenv[JIT_3DIP],literals_count - 1);
|
||||
EMIT(userenv[JIT_3DIP]);
|
||||
|
||||
i++;
|
||||
break;
|
||||
|
@ -305,10 +299,10 @@ void jit_compile(CELL quot, bool relocate)
|
|||
if(jit_fast_dispatch_p(untag_object(array),i))
|
||||
{
|
||||
if(stack_frame)
|
||||
EMIT(userenv[JIT_EPILOG],0);
|
||||
EMIT(userenv[JIT_EPILOG]);
|
||||
|
||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||
EMIT(userenv[JIT_DISPATCH],literals_count - 1);
|
||||
EMIT(userenv[JIT_DISPATCH]);
|
||||
|
||||
i++;
|
||||
|
||||
|
@ -322,7 +316,7 @@ void jit_compile(CELL quot, bool relocate)
|
|||
}
|
||||
default:
|
||||
GROWABLE_ARRAY_ADD(literals,obj);
|
||||
EMIT(userenv[JIT_PUSH_IMMEDIATE],literals_count - 1);
|
||||
EMIT(userenv[JIT_PUSH_IMMEDIATE]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -330,9 +324,9 @@ void jit_compile(CELL quot, bool relocate)
|
|||
if(!tail_call)
|
||||
{
|
||||
if(stack_frame)
|
||||
EMIT(userenv[JIT_EPILOG],0);
|
||||
EMIT(userenv[JIT_EPILOG]);
|
||||
|
||||
EMIT(userenv[JIT_RETURN],0);
|
||||
EMIT(userenv[JIT_RETURN]);
|
||||
}
|
||||
|
||||
GROWABLE_ARRAY_TRIM(code);
|
||||
|
|
12
vm/types.c
12
vm/types.c
|
@ -139,6 +139,18 @@ CELL allot_array_1(CELL obj)
|
|||
return tag_object(a);
|
||||
}
|
||||
|
||||
CELL allot_array_2(CELL v1, CELL v2)
|
||||
{
|
||||
REGISTER_ROOT(v1);
|
||||
REGISTER_ROOT(v2);
|
||||
F_ARRAY *a = allot_array_internal(ARRAY_TYPE,2);
|
||||
UNREGISTER_ROOT(v2);
|
||||
UNREGISTER_ROOT(v1);
|
||||
set_array_nth(a,0,v1);
|
||||
set_array_nth(a,1,v2);
|
||||
return tag_object(a);
|
||||
}
|
||||
|
||||
CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4)
|
||||
{
|
||||
REGISTER_ROOT(v1);
|
||||
|
|
|
@ -109,6 +109,7 @@ F_ARRAY *allot_array(CELL type, CELL capacity, CELL fill);
|
|||
F_BYTE_ARRAY *allot_byte_array(CELL size);
|
||||
|
||||
CELL allot_array_1(CELL obj);
|
||||
CELL allot_array_2(CELL v1, CELL v2);
|
||||
CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4);
|
||||
|
||||
void primitive_array(void);
|
||||
|
|
Loading…
Reference in New Issue