Debugging inline caching
parent
8c25569e9e
commit
9243316489
|
@ -347,7 +347,7 @@ M: f '
|
||||||
[ vocabulary>> , ]
|
[ vocabulary>> , ]
|
||||||
[ def>> , ]
|
[ def>> , ]
|
||||||
[ props>> , ]
|
[ props>> , ]
|
||||||
[ drop f , ]
|
[ direct-entry-def>> , ] ! direct-entry-def
|
||||||
[ drop 0 , ] ! count
|
[ drop 0 , ] ! count
|
||||||
[ word-sub-primitive , ]
|
[ word-sub-primitive , ]
|
||||||
[ drop 0 , ] ! xt
|
[ drop 0 , ] ! xt
|
||||||
|
|
|
@ -175,48 +175,53 @@ big-endian off
|
||||||
! The 'make' trick lets us compute the jump distance for the conditional branches there
|
! The 'make' trick lets us compute the jump distance for the conditional branches there
|
||||||
|
|
||||||
! Tag
|
! Tag
|
||||||
[
|
: make-pic-tag ( -- )
|
||||||
ds-reg bootstrap-cell SUB
|
ds-reg bootstrap-cell SUB
|
||||||
temp0 tag-bits get AND
|
temp1 temp0 MOV
|
||||||
] pic-tag jit-define
|
temp1 tag-mask get AND
|
||||||
|
temp1 tag-bits get SHL ;
|
||||||
|
|
||||||
|
[ make-pic-tag ] pic-tag jit-define
|
||||||
|
|
||||||
! Hi-tag
|
! Hi-tag
|
||||||
[
|
[
|
||||||
ds-reg bootstrap-cell SUB
|
make-pic-tag
|
||||||
temp0 object tag-number TEST
|
temp1 object tag-number tag-fixnum CMP
|
||||||
[ temp0 temp0 object tag-number neg [+] MOV ] { } make
|
[ temp1 temp0 object tag-number neg [+] MOV ] { } make
|
||||||
[ length JNE ] [ % ] bi
|
[ length JNE ] [ % ] bi
|
||||||
] pic-hi-tag jit-define
|
] pic-hi-tag jit-define
|
||||||
|
|
||||||
! Tuple
|
! Tuple
|
||||||
[
|
[
|
||||||
ds-reg bootstrap-cell SUB
|
make-pic-tag
|
||||||
temp0 tuple tag-number TEST
|
temp1 tuple tag-number tag-fixnum CMP
|
||||||
[ temp0 temp0 tuple tag-number neg bootstrap-cell + [+] MOV ] { } make
|
[ temp1 temp0 tuple tag-number neg bootstrap-cell + [+] MOV ] { } make
|
||||||
[ length JNE ] [ % ] bi
|
[ length JNE ] [ % ] bi
|
||||||
] pic-tuple jit-define
|
] pic-tuple jit-define
|
||||||
|
|
||||||
! Hi-tag and tuple
|
! 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)
|
! 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
|
! Make temp0 untagged
|
||||||
temp0 tag-mask get bitnot AND
|
temp0 tag-mask get bitnot AND
|
||||||
! Set temp1 to 0 for objects, and 4 or 8 for tuples
|
! Set temp1 to 0 for objects, and 4 or 8 for tuples
|
||||||
temp1 1 AND
|
temp1 1 tag-fixnum AND
|
||||||
bootstrap-cell {
|
bootstrap-cell {
|
||||||
{ 4 [ temp1 2 SHL ] }
|
{ 4 [ temp1 2 SHL ] }
|
||||||
{ 8 [ temp1 3 SHL ] }
|
{ 8 [ temp1 3 SHL ] }
|
||||||
} case
|
} case
|
||||||
! Load header cell or tuple layout cell
|
! Load header cell or tuple layout cell
|
||||||
temp0 temp0 temp1 [+] MOV
|
temp1 temp0 temp1 [+] MOV
|
||||||
] [ ] make [ length JNE ] [ % ] bi
|
] [ ] make [ length JNE ] [ % ] bi
|
||||||
] pic-hi-tag-tuple jit-define
|
] 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
|
[ 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);
|
CELL offset = REL_OFFSET(rel) + (CELL)(compiled + 1);
|
||||||
F_ARRAY *literals = untag_object(compiled->literals);
|
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);
|
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)
|
INLINE void check_code_address(CELL address)
|
||||||
{
|
{
|
||||||
#ifdef FACTOR_DEBUG
|
#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_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_code_block(F_CODE_BLOCK *compiled);
|
||||||
|
|
||||||
void mark_active_blocks(F_CONTEXT *stacks);
|
void mark_active_blocks(F_CONTEXT *stacks);
|
||||||
|
|
|
@ -212,6 +212,9 @@ void free_unmarked(F_HEAP *heap, HEAP_ITERATOR iter)
|
||||||
switch(scan->status)
|
switch(scan->status)
|
||||||
{
|
{
|
||||||
case B_ALLOCATED:
|
case B_ALLOCATED:
|
||||||
|
if(secure_gc)
|
||||||
|
memset(scan + 1,0,scan->size - sizeof(F_BLOCK));
|
||||||
|
|
||||||
if(prev && prev->status == B_FREE)
|
if(prev && prev->status == B_FREE)
|
||||||
prev->size += scan->size;
|
prev->size += scan->size;
|
||||||
else
|
else
|
||||||
|
|
|
@ -51,7 +51,7 @@ void copy_code_heap_roots(void)
|
||||||
collections, done at the end. */
|
collections, done at the end. */
|
||||||
void update_code_heap_roots(void)
|
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
|
/* 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 primitive_code_room(void);
|
||||||
|
|
||||||
void compact_code_heap(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
|
push %eax
|
||||||
call MANGLE(inline_cache_miss)
|
call MANGLE(inline_cache_miss)
|
||||||
add $12,%esp
|
add $12,%esp
|
||||||
jmp *WORD_XT_OFFSET(%eax)
|
jmp *%eax
|
||||||
|
|
||||||
#include "cpu-x86.S"
|
#include "cpu-x86.S"
|
||||||
|
|
||||||
|
|
|
@ -20,5 +20,5 @@ INLINE void set_call_site(CELL return_address, CELL target)
|
||||||
#ifdef FACTOR_DEBUG
|
#ifdef FACTOR_DEBUG
|
||||||
assert(*(unsigned char *)(return_address - 5) == 0xe8);
|
assert(*(unsigned char *)(return_address - 5) == 0xe8);
|
||||||
#endif
|
#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++;
|
code_heap_scans++;
|
||||||
|
|
||||||
if(collecting_gen == TENURED)
|
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
|
else
|
||||||
copy_code_heap_roots();
|
copy_code_heap_roots();
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,12 @@ static void update_pic_count(CELL type)
|
||||||
cache_entries: array of class/method pairs */
|
cache_entries: array of class/method pairs */
|
||||||
static F_CODE_BLOCK *compile_inline_cache(CELL picker, CELL generic_word, CELL cache_entries)
|
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(picker);
|
||||||
REGISTER_ROOT(generic_word);
|
REGISTER_ROOT(generic_word);
|
||||||
REGISTER_ROOT(cache_entries);
|
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]);
|
jit_word_jump(&jit,userenv[PIC_MISS_WORD]);
|
||||||
|
|
||||||
F_CODE_BLOCK *code = jit_make_code_block(&jit);
|
F_CODE_BLOCK *code = jit_make_code_block(&jit);
|
||||||
|
relocate_code_block(code);
|
||||||
|
|
||||||
jit_dispose(&jit);
|
jit_dispose(&jit);
|
||||||
|
|
||||||
UNREGISTER_ROOT(cache_entries);
|
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)
|
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 */
|
/* Allocates memory */
|
||||||
|
@ -170,6 +178,8 @@ static void update_pic_transitions(CELL pic_size)
|
||||||
Called from assembly with the actual return address */
|
Called from assembly with the actual return address */
|
||||||
XT inline_cache_miss(CELL return_address)
|
XT inline_cache_miss(CELL return_address)
|
||||||
{
|
{
|
||||||
|
check_code_pointer(return_address);
|
||||||
|
|
||||||
CELL cache_entries = dpop();
|
CELL cache_entries = dpop();
|
||||||
CELL generic_word = dpop();
|
CELL generic_word = dpop();
|
||||||
CELL object = dpop();
|
CELL object = dpop();
|
||||||
|
|
Loading…
Reference in New Issue