More compact relocation layout

db4
Slava Pestov 2009-03-19 20:03:07 -05:00
parent 53e519b87b
commit ae09d85d84
6 changed files with 99 additions and 78 deletions

View File

@ -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 */
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);