[ vocabulary>> , ]
[ def>> , ]
[ props>> , ]
- [ drop f , ]
+ [ direct-entry-def>> , ] ! direct-entry-def
[ drop 0 , ] ! count
[ word-sub-primitive , ]
[ drop 0 , ] ! xt
! 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
{
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);
}
}
}
}
+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
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);
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
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
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
+}
push %eax
call MANGLE(inline_cache_miss)
add $12,%esp
- jmp *WORD_XT_OFFSET(%eax)
+ jmp *%eax
#include "cpu-x86.S"
#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);
}
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();
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);
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);
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 */
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();
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);