Debugging inline caching

db4
Slava Pestov 2009-04-28 23:05:18 -05:00
parent 8c25569e9e
commit 9243316489
11 changed files with 63 additions and 23 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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"

View File

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

View File

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

View File

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