Debugging inline caching
parent
8c25569e9e
commit
9243316489
|
@ -347,7 +347,7 @@ M: f '
|
|||
[ vocabulary>> , ]
|
||||
[ def>> , ]
|
||||
[ props>> , ]
|
||||
[ drop f , ]
|
||||
[ direct-entry-def>> , ] ! direct-entry-def
|
||||
[ drop 0 , ] ! count
|
||||
[ word-sub-primitive , ]
|
||||
[ drop 0 , ] ! xt
|
||||
|
|
|
@ -175,48 +175,53 @@ big-endian off
|
|||
! The 'make' trick lets us compute the jump distance for the conditional branches there
|
||||
|
||||
! Tag
|
||||
[
|
||||
: make-pic-tag ( -- )
|
||||
ds-reg bootstrap-cell SUB
|
||||
temp0 tag-bits get AND
|
||||
] pic-tag jit-define
|
||||
temp1 temp0 MOV
|
||||
temp1 tag-mask get AND
|
||||
temp1 tag-bits get SHL ;
|
||||
|
||||
[ make-pic-tag ] pic-tag jit-define
|
||||
|
||||
! Hi-tag
|
||||
[
|
||||
ds-reg bootstrap-cell SUB
|
||||
temp0 object tag-number TEST
|
||||
[ temp0 temp0 object tag-number neg [+] MOV ] { } make
|
||||
make-pic-tag
|
||||
temp1 object tag-number tag-fixnum CMP
|
||||
[ temp1 temp0 object tag-number neg [+] MOV ] { } make
|
||||
[ length JNE ] [ % ] bi
|
||||
] pic-hi-tag jit-define
|
||||
|
||||
! Tuple
|
||||
[
|
||||
ds-reg bootstrap-cell SUB
|
||||
temp0 tuple tag-number TEST
|
||||
[ temp0 temp0 tuple tag-number neg bootstrap-cell + [+] MOV ] { } make
|
||||
make-pic-tag
|
||||
temp1 tuple tag-number tag-fixnum CMP
|
||||
[ temp1 temp0 tuple tag-number neg bootstrap-cell + [+] MOV ] { } make
|
||||
[ length JNE ] [ % ] bi
|
||||
] pic-tuple jit-define
|
||||
|
||||
! Hi-tag and tuple
|
||||
[
|
||||
ds-reg bootstrap-cell SUB
|
||||
make-pic-tag
|
||||
! If bits 2 and 3 are set, the tag is either 6 (object) or 7 (tuple)
|
||||
temp0 6 TEST
|
||||
temp1 BIN: 110 tag-fixnum CMP
|
||||
[
|
||||
temp1 temp0 MOV
|
||||
! Make temp0 untagged
|
||||
temp0 tag-mask get bitnot AND
|
||||
! Set temp1 to 0 for objects, and 4 or 8 for tuples
|
||||
temp1 1 AND
|
||||
temp1 1 tag-fixnum AND
|
||||
bootstrap-cell {
|
||||
{ 4 [ temp1 2 SHL ] }
|
||||
{ 8 [ temp1 3 SHL ] }
|
||||
} case
|
||||
! Load header cell or tuple layout cell
|
||||
temp0 temp0 temp1 [+] MOV
|
||||
temp1 temp0 temp1 [+] MOV
|
||||
] [ ] make [ length JNE ] [ % ] bi
|
||||
] pic-hi-tag-tuple jit-define
|
||||
|
||||
[ temp0 HEX: ffffffff CMP ] pic-check jit-define
|
||||
[
|
||||
temp2 HEX: ffffffff MOV rc-absolute-cell rt-immediate jit-rel
|
||||
temp1 temp2 CMP
|
||||
] pic-check jit-define
|
||||
|
||||
[ f JE rc-relative rt-xt jit-rel ] pic-hit jit-define
|
||||
|
||||
|
|
|
@ -194,7 +194,14 @@ void update_word_references_step(F_REL rel, CELL index, F_CODE_BLOCK *compiled)
|
|||
{
|
||||
CELL offset = REL_OFFSET(rel) + (CELL)(compiled + 1);
|
||||
F_ARRAY *literals = untag_object(compiled->literals);
|
||||
CELL xt = object_xt(array_nth(literals,index));
|
||||
CELL obj = array_nth(literals,index);
|
||||
|
||||
CELL xt;
|
||||
if(type == RT_XT)
|
||||
xt = object_xt(obj);
|
||||
else
|
||||
xt = word_direct_xt(obj);
|
||||
|
||||
store_address_in_code_block(REL_CLASS(rel),offset,xt);
|
||||
}
|
||||
}
|
||||
|
@ -214,6 +221,12 @@ void update_word_references(F_CODE_BLOCK *compiled)
|
|||
}
|
||||
}
|
||||
|
||||
void update_literal_and_word_references(F_CODE_BLOCK *compiled)
|
||||
{
|
||||
update_literal_references(compiled);
|
||||
update_word_references(compiled);
|
||||
}
|
||||
|
||||
INLINE void check_code_address(CELL address)
|
||||
{
|
||||
#ifdef FACTOR_DEBUG
|
||||
|
|
|
@ -67,6 +67,8 @@ void copy_literal_references(F_CODE_BLOCK *compiled);
|
|||
|
||||
void update_word_references(F_CODE_BLOCK *compiled);
|
||||
|
||||
void update_literal_and_word_references(F_CODE_BLOCK *compiled);
|
||||
|
||||
void mark_code_block(F_CODE_BLOCK *compiled);
|
||||
|
||||
void mark_active_blocks(F_CONTEXT *stacks);
|
||||
|
|
|
@ -212,6 +212,9 @@ void free_unmarked(F_HEAP *heap, HEAP_ITERATOR iter)
|
|||
switch(scan->status)
|
||||
{
|
||||
case B_ALLOCATED:
|
||||
if(secure_gc)
|
||||
memset(scan + 1,0,scan->size - sizeof(F_BLOCK));
|
||||
|
||||
if(prev && prev->status == B_FREE)
|
||||
prev->size += scan->size;
|
||||
else
|
||||
|
|
|
@ -51,7 +51,7 @@ void copy_code_heap_roots(void)
|
|||
collections, done at the end. */
|
||||
void update_code_heap_roots(void)
|
||||
{
|
||||
iterate_code_heap(update_literal_references);
|
||||
iterate_code_heap(update_literal_and_word_references);
|
||||
}
|
||||
|
||||
/* Update pointers to words referenced from all code blocks. Only after
|
||||
|
|
|
@ -20,3 +20,10 @@ void primitive_modify_code_heap(void);
|
|||
void primitive_code_room(void);
|
||||
|
||||
void compact_code_heap(void);
|
||||
|
||||
INLINE void check_code_pointer(CELL pointer)
|
||||
{
|
||||
#ifdef FACTOR_DEBUG
|
||||
assert(pointer >= code_heap.segment->start && pointer < code_heap.segment->end);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ DEF(F_FASTCALL void,primitive_inline_cache_miss,(void)):
|
|||
push %eax
|
||||
call MANGLE(inline_cache_miss)
|
||||
add $12,%esp
|
||||
jmp *WORD_XT_OFFSET(%eax)
|
||||
jmp *%eax
|
||||
|
||||
#include "cpu-x86.S"
|
||||
|
||||
|
|
|
@ -20,5 +20,5 @@ INLINE void set_call_site(CELL return_address, CELL target)
|
|||
#ifdef FACTOR_DEBUG
|
||||
assert(*(unsigned char *)(return_address - 5) == 0xe8);
|
||||
#endif
|
||||
*(F_FIXNUM *)(return_address - 4) = (target - (return_address - 4));
|
||||
*(F_FIXNUM *)(return_address - 4) = (target - return_address);
|
||||
}
|
||||
|
|
|
@ -507,7 +507,7 @@ void garbage_collection(CELL gen,
|
|||
code_heap_scans++;
|
||||
|
||||
if(collecting_gen == TENURED)
|
||||
free_unmarked(&code_heap,(HEAP_ITERATOR)update_literal_references);
|
||||
free_unmarked(&code_heap,(HEAP_ITERATOR)update_literal_and_word_references);
|
||||
else
|
||||
copy_code_heap_roots();
|
||||
|
||||
|
|
|
@ -54,6 +54,12 @@ static void update_pic_count(CELL type)
|
|||
cache_entries: array of class/method pairs */
|
||||
static F_CODE_BLOCK *compile_inline_cache(CELL picker, CELL generic_word, CELL cache_entries)
|
||||
{
|
||||
#ifdef FACTOR_DEBUG
|
||||
type_check(WORD_TYPE,picker);
|
||||
type_check(WORD_TYPE,generic_word);
|
||||
type_check(ARRAY_TYPE,cache_entries);
|
||||
#endif
|
||||
|
||||
REGISTER_ROOT(picker);
|
||||
REGISTER_ROOT(generic_word);
|
||||
REGISTER_ROOT(cache_entries);
|
||||
|
@ -94,6 +100,8 @@ static F_CODE_BLOCK *compile_inline_cache(CELL picker, CELL generic_word, CELL c
|
|||
jit_word_jump(&jit,userenv[PIC_MISS_WORD]);
|
||||
|
||||
F_CODE_BLOCK *code = jit_make_code_block(&jit);
|
||||
relocate_code_block(code);
|
||||
|
||||
jit_dispose(&jit);
|
||||
|
||||
UNREGISTER_ROOT(cache_entries);
|
||||
|
@ -137,7 +145,7 @@ static void examine_generic_word(CELL generic_word, CELL *picker, CELL *all_meth
|
|||
|
||||
static CELL inline_cache_size(CELL cache_entries)
|
||||
{
|
||||
return (cache_entries == F ? 0 : array_capacity(untag_array(cache_entries)));
|
||||
return (cache_entries == F ? 0 : array_capacity(untag_array(cache_entries)) / 2);
|
||||
}
|
||||
|
||||
/* Allocates memory */
|
||||
|
@ -170,6 +178,8 @@ static void update_pic_transitions(CELL pic_size)
|
|||
Called from assembly with the actual return address */
|
||||
XT inline_cache_miss(CELL return_address)
|
||||
{
|
||||
check_code_pointer(return_address);
|
||||
|
||||
CELL cache_entries = dpop();
|
||||
CELL generic_word = dpop();
|
||||
CELL object = dpop();
|
||||
|
@ -195,7 +205,7 @@ XT inline_cache_miss(CELL return_address)
|
|||
CELL class = object_class(object);
|
||||
CELL method = lookup_method(object,all_methods);
|
||||
|
||||
cache_entries = add_inline_cache_entry(cache_entries,class,method);
|
||||
cache_entries = add_inline_cache_entry(cache_entries,class,method);
|
||||
block = compile_inline_cache(picker,generic_word,cache_entries);
|
||||
|
||||
UNREGISTER_ROOT(all_methods);
|
||||
|
|
Loading…
Reference in New Issue