vm: change code heap layout somewhat, remove unused allocation bitmap from mark_bits
parent
931307500e
commit
838a44e901
|
@ -346,7 +346,7 @@ void factor_vm::update_word_references(code_block *compiled)
|
||||||
are referenced after this is done. So instead of polluting
|
are referenced after this is done. So instead of polluting
|
||||||
the code heap with dead PICs that will be freed on the next
|
the code heap with dead PICs that will be freed on the next
|
||||||
GC, we add them to the free list immediately. */
|
GC, we add them to the free list immediately. */
|
||||||
else if(compiled->type() == PIC_TYPE)
|
else if(compiled->pic_p())
|
||||||
code->code_heap_free(compiled);
|
code->code_heap_free(compiled);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -437,9 +437,9 @@ void factor_vm::fixup_labels(array *labels, code_block *compiled)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Might GC */
|
/* Might GC */
|
||||||
code_block *factor_vm::allot_code_block(cell size, cell type)
|
code_block *factor_vm::allot_code_block(cell size, code_block_type type)
|
||||||
{
|
{
|
||||||
heap_block *block = code->heap_allot(size + sizeof(code_block),type);
|
heap_block *block = code->heap_allot(size + sizeof(code_block));
|
||||||
|
|
||||||
/* If allocation failed, do a full GC and compact the code heap.
|
/* If allocation failed, do a full GC and compact the code heap.
|
||||||
A full GC that occurs as a result of the data heap filling up does not
|
A full GC that occurs as a result of the data heap filling up does not
|
||||||
|
@ -449,7 +449,7 @@ code_block *factor_vm::allot_code_block(cell size, cell type)
|
||||||
if(block == NULL)
|
if(block == NULL)
|
||||||
{
|
{
|
||||||
primitive_compact_gc();
|
primitive_compact_gc();
|
||||||
block = code->heap_allot(size + sizeof(code_block),type);
|
block = code->heap_allot(size + sizeof(code_block));
|
||||||
|
|
||||||
/* Insufficient room even after code GC, give up */
|
/* Insufficient room even after code GC, give up */
|
||||||
if(block == NULL)
|
if(block == NULL)
|
||||||
|
@ -465,11 +465,13 @@ code_block *factor_vm::allot_code_block(cell size, cell type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (code_block *)block;
|
code_block *compiled = (code_block *)block;
|
||||||
|
compiled->set_type(type);
|
||||||
|
return compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Might GC */
|
/* Might GC */
|
||||||
code_block *factor_vm::add_code_block(cell type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_)
|
code_block *factor_vm::add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_)
|
||||||
{
|
{
|
||||||
gc_root<byte_array> code(code_,this);
|
gc_root<byte_array> code(code_,this);
|
||||||
gc_root<object> labels(labels_,this);
|
gc_root<object> labels(labels_,this);
|
||||||
|
|
|
@ -144,7 +144,7 @@ void factor_vm::primitive_modify_code_heap()
|
||||||
cell code = array_nth(compiled_data,4);
|
cell code = array_nth(compiled_data,4);
|
||||||
|
|
||||||
code_block *compiled = add_code_block(
|
code_block *compiled = add_code_block(
|
||||||
WORD_TYPE,
|
code_block_optimized,
|
||||||
code,
|
code,
|
||||||
labels,
|
labels,
|
||||||
owner,
|
owner,
|
||||||
|
|
|
@ -295,7 +295,7 @@ void factor_vm::dump_code_heap()
|
||||||
while(scan != end)
|
while(scan != end)
|
||||||
{
|
{
|
||||||
const char *status;
|
const char *status;
|
||||||
if(scan->type() == FREE_BLOCK_TYPE)
|
if(scan->free_p())
|
||||||
status = "free";
|
status = "free";
|
||||||
else if(code->state->is_marked_p(scan))
|
else if(code->state->is_marked_p(scan))
|
||||||
{
|
{
|
||||||
|
|
51
vm/heap.cpp
51
vm/heap.cpp
|
@ -49,15 +49,16 @@ void heap::build_free_list(cell size)
|
||||||
{
|
{
|
||||||
clear_free_list();
|
clear_free_list();
|
||||||
free_heap_block *end = (free_heap_block *)(seg->start + size);
|
free_heap_block *end = (free_heap_block *)(seg->start + size);
|
||||||
end->set_type(FREE_BLOCK_TYPE);
|
end->set_free();
|
||||||
end->set_size(seg->end - (cell)end);
|
end->set_size(seg->end - (cell)end);
|
||||||
add_to_free_list(end);
|
add_to_free_list(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void heap::assert_free_block(free_heap_block *block)
|
void heap::assert_free_block(free_heap_block *block)
|
||||||
{
|
{
|
||||||
if(block->type() != FREE_BLOCK_TYPE)
|
#ifdef FACTOR_DEBUG
|
||||||
critical_error("Invalid block in free list",(cell)block);
|
assert(block->free_p());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
free_heap_block *heap::find_free_block(cell size)
|
free_heap_block *heap::find_free_block(cell size)
|
||||||
|
@ -102,11 +103,11 @@ free_heap_block *heap::find_free_block(cell size)
|
||||||
|
|
||||||
free_heap_block *heap::split_free_block(free_heap_block *block, cell size)
|
free_heap_block *heap::split_free_block(free_heap_block *block, cell size)
|
||||||
{
|
{
|
||||||
if(block->size() != size )
|
if(block->size() != size)
|
||||||
{
|
{
|
||||||
/* split the block in two */
|
/* split the block in two */
|
||||||
free_heap_block *split = (free_heap_block *)((cell)block + size);
|
free_heap_block *split = (free_heap_block *)((cell)block + size);
|
||||||
split->set_type(FREE_BLOCK_TYPE);
|
split->set_free();
|
||||||
split->set_size(block->size() - size);
|
split->set_size(block->size() - size);
|
||||||
split->next_free = block->next_free;
|
split->next_free = block->next_free;
|
||||||
block->set_size(size);
|
block->set_size(size);
|
||||||
|
@ -116,27 +117,25 @@ free_heap_block *heap::split_free_block(free_heap_block *block, cell size)
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a block of memory from the mark and sweep GC heap */
|
heap_block *heap::heap_allot(cell size)
|
||||||
heap_block *heap::heap_allot(cell size, cell type)
|
|
||||||
{
|
{
|
||||||
size = (size + block_size_increment - 1) & ~(block_size_increment - 1);
|
size = align(size,block_size_increment);
|
||||||
|
|
||||||
free_heap_block *block = find_free_block(size);
|
free_heap_block *block = find_free_block(size);
|
||||||
if(block)
|
if(block)
|
||||||
{
|
{
|
||||||
block = split_free_block(block,size);
|
block = split_free_block(block,size);
|
||||||
block->set_type(type);
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deallocates a block manually */
|
|
||||||
void heap::heap_free(heap_block *block)
|
void heap::heap_free(heap_block *block)
|
||||||
{
|
{
|
||||||
block->set_type(FREE_BLOCK_TYPE);
|
free_heap_block *free_block = (free_heap_block *)block;
|
||||||
add_to_free_list((free_heap_block *)block);
|
free_block->set_free();
|
||||||
|
add_to_free_list(free_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void heap::mark_block(heap_block *block)
|
void heap::mark_block(heap_block *block)
|
||||||
|
@ -158,7 +157,7 @@ void heap::heap_usage(cell *used, cell *total_free, cell *max_free)
|
||||||
{
|
{
|
||||||
cell size = scan->size();
|
cell size = scan->size();
|
||||||
|
|
||||||
if(scan->type() == FREE_BLOCK_TYPE)
|
if(scan->free_p())
|
||||||
{
|
{
|
||||||
*total_free += size;
|
*total_free += size;
|
||||||
if(size > *max_free)
|
if(size > *max_free)
|
||||||
|
@ -179,31 +178,19 @@ cell heap::heap_size()
|
||||||
|
|
||||||
while(scan != end)
|
while(scan != end)
|
||||||
{
|
{
|
||||||
if(scan->type() == FREE_BLOCK_TYPE) break;
|
if(scan->free_p()) break;
|
||||||
else scan = scan->next();
|
else scan = scan->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(scan->type() == FREE_BLOCK_TYPE);
|
if(scan != end)
|
||||||
assert((cell)scan + scan->size() == seg->end);
|
|
||||||
|
|
||||||
return (cell)scan - (cell)first_block();
|
|
||||||
}
|
|
||||||
|
|
||||||
heap_block *heap::free_allocated(heap_block *prev, heap_block *scan)
|
|
||||||
{
|
|
||||||
if(secure_gc)
|
|
||||||
memset(scan + 1,0,scan->size() - sizeof(heap_block));
|
|
||||||
|
|
||||||
if(prev && prev->type() == FREE_BLOCK_TYPE)
|
|
||||||
{
|
{
|
||||||
prev->set_size(prev->size() + scan->size());
|
assert(scan->free_p());
|
||||||
return prev;
|
assert((cell)scan + scan->size() == seg->end);
|
||||||
|
|
||||||
|
return (cell)scan - (cell)first_block();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
return seg->size;
|
||||||
scan->set_type(FREE_BLOCK_TYPE);
|
|
||||||
return scan;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
30
vm/heap.hpp
30
vm/heap.hpp
|
@ -34,15 +34,13 @@ struct heap {
|
||||||
void assert_free_block(free_heap_block *block);
|
void assert_free_block(free_heap_block *block);
|
||||||
free_heap_block *find_free_block(cell size);
|
free_heap_block *find_free_block(cell size);
|
||||||
free_heap_block *split_free_block(free_heap_block *block, cell size);
|
free_heap_block *split_free_block(free_heap_block *block, cell size);
|
||||||
heap_block *heap_allot(cell size, cell type);
|
heap_block *heap_allot(cell size);
|
||||||
void heap_free(heap_block *block);
|
void heap_free(heap_block *block);
|
||||||
void mark_block(heap_block *block);
|
void mark_block(heap_block *block);
|
||||||
void heap_usage(cell *used, cell *total_free, cell *max_free);
|
void heap_usage(cell *used, cell *total_free, cell *max_free);
|
||||||
cell heap_size();
|
cell heap_size();
|
||||||
void compact_heap();
|
void compact_heap();
|
||||||
|
|
||||||
heap_block *free_allocated(heap_block *prev, heap_block *scan);
|
|
||||||
|
|
||||||
template<typename Iterator> void sweep_heap(Iterator &iter);
|
template<typename Iterator> void sweep_heap(Iterator &iter);
|
||||||
template<typename Iterator> void compact_heap(Iterator &iter);
|
template<typename Iterator> void compact_heap(Iterator &iter);
|
||||||
|
|
||||||
|
@ -54,7 +52,7 @@ struct heap {
|
||||||
while(scan != end)
|
while(scan != end)
|
||||||
{
|
{
|
||||||
heap_block *next = scan->next();
|
heap_block *next = scan->next();
|
||||||
if(scan->type() != FREE_BLOCK_TYPE) iter(scan,scan->size());
|
if(!scan->free_p()) iter(scan,scan->size());
|
||||||
scan = next;
|
scan = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,27 +70,41 @@ template<typename Iterator> void heap::sweep_heap(Iterator &iter)
|
||||||
|
|
||||||
while(scan != end)
|
while(scan != end)
|
||||||
{
|
{
|
||||||
if(scan->type() == FREE_BLOCK_TYPE)
|
if(scan->free_p())
|
||||||
{
|
{
|
||||||
if(prev && prev->type() == FREE_BLOCK_TYPE)
|
if(prev && prev->free_p())
|
||||||
prev->set_size(prev->size() + scan->size());
|
prev->set_size(prev->size() + scan->size());
|
||||||
else
|
else
|
||||||
prev = scan;
|
prev = scan;
|
||||||
}
|
}
|
||||||
else if(this->state->is_marked_p(scan))
|
else if(this->state->is_marked_p(scan))
|
||||||
{
|
{
|
||||||
if(prev && prev->type() == FREE_BLOCK_TYPE)
|
if(prev && prev->free_p())
|
||||||
this->add_to_free_list((free_heap_block *)prev);
|
this->add_to_free_list((free_heap_block *)prev);
|
||||||
prev = scan;
|
prev = scan;
|
||||||
iter(scan,scan->size());
|
iter(scan,scan->size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
prev = this->free_allocated(prev,scan);
|
{
|
||||||
|
if(secure_gc)
|
||||||
|
memset(scan + 1,0,scan->size() - sizeof(heap_block));
|
||||||
|
|
||||||
|
if(prev && prev->free_p())
|
||||||
|
{
|
||||||
|
free_heap_block *free_prev = (free_heap_block *)prev;
|
||||||
|
free_prev->set_size(free_prev->size() + scan->size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scan->set_free();
|
||||||
|
prev = scan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scan = scan->next();
|
scan = scan->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prev && prev->type() == FREE_BLOCK_TYPE)
|
if(prev && prev->free_p())
|
||||||
this->add_to_free_list((free_heap_block *)prev);
|
this->add_to_free_list((free_heap_block *)prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,15 +19,9 @@ void factor_vm::deallocate_inline_cache(cell return_address)
|
||||||
check_code_pointer((cell)old_xt);
|
check_code_pointer((cell)old_xt);
|
||||||
|
|
||||||
code_block *old_block = (code_block *)old_xt - 1;
|
code_block *old_block = (code_block *)old_xt - 1;
|
||||||
cell old_type = old_block->type();
|
|
||||||
|
|
||||||
#ifdef FACTOR_DEBUG
|
/* Free the old PIC since we know its unreachable */
|
||||||
/* The call target was either another PIC,
|
if(old_block->pic_p())
|
||||||
or a compiled quotation (megamorphic stub) */
|
|
||||||
assert(old_type == PIC_TYPE || old_type == QUOTATION_TYPE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(old_type == PIC_TYPE)
|
|
||||||
code->code_heap_free(old_block);
|
code->code_heap_free(old_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +72,7 @@ void factor_vm::update_pic_count(cell type)
|
||||||
struct inline_cache_jit : public jit {
|
struct inline_cache_jit : public jit {
|
||||||
fixnum index;
|
fixnum index;
|
||||||
|
|
||||||
explicit inline_cache_jit(cell generic_word_,factor_vm *vm) : jit(PIC_TYPE,generic_word_,vm) {};
|
explicit inline_cache_jit(cell generic_word_,factor_vm *vm) : jit(code_block_pic,generic_word_,vm) {};
|
||||||
|
|
||||||
void emit_check(cell klass);
|
void emit_check(cell klass);
|
||||||
void compile_inline_cache(fixnum index,
|
void compile_inline_cache(fixnum index,
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace factor
|
||||||
- polymorphic inline caches (inline_cache.cpp) */
|
- polymorphic inline caches (inline_cache.cpp) */
|
||||||
|
|
||||||
/* Allocates memory */
|
/* Allocates memory */
|
||||||
jit::jit(cell type_, cell owner_, factor_vm *vm)
|
jit::jit(code_block_type type_, cell owner_, factor_vm *vm)
|
||||||
: type(type_),
|
: type(type_),
|
||||||
owner(owner_,vm),
|
owner(owner_,vm),
|
||||||
code(vm),
|
code(vm),
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
struct jit {
|
struct jit {
|
||||||
cell type;
|
code_block_type type;
|
||||||
gc_root<object> owner;
|
gc_root<object> owner;
|
||||||
growable_byte_array code;
|
growable_byte_array code;
|
||||||
growable_byte_array relocation;
|
growable_byte_array relocation;
|
||||||
|
@ -12,7 +12,7 @@ struct jit {
|
||||||
cell offset;
|
cell offset;
|
||||||
factor_vm *parent;
|
factor_vm *parent;
|
||||||
|
|
||||||
explicit jit(cell jit_type, cell owner, factor_vm *vm);
|
explicit jit(code_block_type type, cell owner, factor_vm *parent);
|
||||||
void compute_position(cell offset);
|
void compute_position(cell offset);
|
||||||
|
|
||||||
void emit_relocation(cell code_template);
|
void emit_relocation(cell code_template);
|
||||||
|
|
|
@ -62,8 +62,14 @@ inline static cell align8(cell a)
|
||||||
#define TYPE_COUNT 15
|
#define TYPE_COUNT 15
|
||||||
|
|
||||||
/* Not real types, but code_block's type can be set to this */
|
/* Not real types, but code_block's type can be set to this */
|
||||||
#define PIC_TYPE 16
|
|
||||||
#define FREE_BLOCK_TYPE 17
|
enum code_block_type
|
||||||
|
{
|
||||||
|
code_block_unoptimized,
|
||||||
|
code_block_optimized,
|
||||||
|
code_block_profiling,
|
||||||
|
code_block_pic
|
||||||
|
};
|
||||||
|
|
||||||
/* Constants used when floating-point trap exceptions are thrown */
|
/* Constants used when floating-point trap exceptions are thrown */
|
||||||
enum
|
enum
|
||||||
|
@ -201,16 +207,29 @@ struct heap_block
|
||||||
{
|
{
|
||||||
cell header;
|
cell header;
|
||||||
|
|
||||||
cell type() { return (header >> 1) & 0x1f; }
|
bool free_p()
|
||||||
void set_type(cell type)
|
|
||||||
{
|
{
|
||||||
header = ((header & ~(0x1f << 1)) | (type << 1));
|
return header & 1 == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_free()
|
||||||
|
{
|
||||||
|
header |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_free()
|
||||||
|
{
|
||||||
|
header &= ~1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell size()
|
||||||
|
{
|
||||||
|
return header >> 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell size() { return (header >> 6); }
|
|
||||||
void set_size(cell size)
|
void set_size(cell size)
|
||||||
{
|
{
|
||||||
header = (header & 0x2f) | (size << 6);
|
header = (header & 0x7) | (size << 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline heap_block *next()
|
inline heap_block *next()
|
||||||
|
@ -230,7 +249,30 @@ struct code_block : public heap_block
|
||||||
cell literals; /* tagged pointer to array or f */
|
cell literals; /* tagged pointer to array or f */
|
||||||
cell relocation; /* tagged pointer to byte-array or f */
|
cell relocation; /* tagged pointer to byte-array or f */
|
||||||
|
|
||||||
void *xt() { return (void *)(this + 1); }
|
void *xt()
|
||||||
|
{
|
||||||
|
return (void *)(this + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell type()
|
||||||
|
{
|
||||||
|
return (header >> 1) & 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_type(code_block_type type)
|
||||||
|
{
|
||||||
|
header = ((header & ~0x7) | (type << 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pic_p()
|
||||||
|
{
|
||||||
|
return type() == code_block_pic;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool optimized_p()
|
||||||
|
{
|
||||||
|
return type() == code_block_optimized;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Assembly code makes assumptions about the layout of this struct */
|
/* Assembly code makes assumptions about the layout of this struct */
|
||||||
|
|
|
@ -8,7 +8,6 @@ template<typename Block, int Granularity> struct mark_bits {
|
||||||
cell size;
|
cell size;
|
||||||
cell bits_size;
|
cell bits_size;
|
||||||
u64 *marked;
|
u64 *marked;
|
||||||
u64 *allocated;
|
|
||||||
cell *forwarding;
|
cell *forwarding;
|
||||||
|
|
||||||
void clear_mark_bits()
|
void clear_mark_bits()
|
||||||
|
@ -16,11 +15,6 @@ template<typename Block, int Granularity> struct mark_bits {
|
||||||
memset(marked,0,bits_size * sizeof(u64));
|
memset(marked,0,bits_size * sizeof(u64));
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_allocated_bits()
|
|
||||||
{
|
|
||||||
memset(allocated,0,bits_size * sizeof(u64));
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_forwarding()
|
void clear_forwarding()
|
||||||
{
|
{
|
||||||
memset(forwarding,0,bits_size * sizeof(cell));
|
memset(forwarding,0,bits_size * sizeof(cell));
|
||||||
|
@ -31,11 +25,9 @@ template<typename Block, int Granularity> struct mark_bits {
|
||||||
size(size_),
|
size(size_),
|
||||||
bits_size(size / Granularity / forwarding_granularity),
|
bits_size(size / Granularity / forwarding_granularity),
|
||||||
marked(new u64[bits_size]),
|
marked(new u64[bits_size]),
|
||||||
allocated(new u64[bits_size]),
|
|
||||||
forwarding(new cell[bits_size])
|
forwarding(new cell[bits_size])
|
||||||
{
|
{
|
||||||
clear_mark_bits();
|
clear_mark_bits();
|
||||||
clear_allocated_bits();
|
|
||||||
clear_forwarding();
|
clear_forwarding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +35,6 @@ template<typename Block, int Granularity> struct mark_bits {
|
||||||
{
|
{
|
||||||
delete[] marked;
|
delete[] marked;
|
||||||
marked = NULL;
|
marked = NULL;
|
||||||
delete[] allocated;
|
|
||||||
allocated = NULL;
|
|
||||||
delete[] forwarding;
|
delete[] forwarding;
|
||||||
forwarding = NULL;
|
forwarding = NULL;
|
||||||
}
|
}
|
||||||
|
@ -109,16 +99,6 @@ template<typename Block, int Granularity> struct mark_bits {
|
||||||
set_bitmap_range(marked,address);
|
set_bitmap_range(marked,address);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_allocated_p(Block *address)
|
|
||||||
{
|
|
||||||
return bitmap_elt(allocated,address);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_allocated_p(Block *address)
|
|
||||||
{
|
|
||||||
set_bitmap_range(allocated,address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* From http://chessprogramming.wikispaces.com/Population+Count */
|
/* From http://chessprogramming.wikispaces.com/Population+Count */
|
||||||
cell popcount(u64 x)
|
cell popcount(u64 x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,7 @@ code_block *factor_vm::compile_profiling_stub(cell word_)
|
||||||
{
|
{
|
||||||
gc_root<word> word(word_,this);
|
gc_root<word> word(word_,this);
|
||||||
|
|
||||||
jit jit(WORD_TYPE,word.value(),this);
|
jit jit(code_block_profiling,word.value(),this);
|
||||||
jit.emit_with(userenv[JIT_PROFILING],word.value());
|
jit.emit_with(userenv[JIT_PROFILING],word.value());
|
||||||
|
|
||||||
return jit.to_code_block();
|
return jit.to_code_block();
|
||||||
|
|
|
@ -335,7 +335,7 @@ void factor_vm::compile_all_words()
|
||||||
{
|
{
|
||||||
gc_root<word> word(array_nth(words.untagged(),i),this);
|
gc_root<word> word(array_nth(words.untagged(),i),this);
|
||||||
|
|
||||||
if(!word->code || !word_optimized_p(word.untagged()))
|
if(!word->code || !word->code->optimized_p())
|
||||||
jit_compile_word(word.value(),word->def,false);
|
jit_compile_word(word.value(),word->def,false);
|
||||||
|
|
||||||
update_word_xt(word.value());
|
update_word_xt(word.value());
|
||||||
|
|
|
@ -6,7 +6,7 @@ struct quotation_jit : public jit {
|
||||||
bool compiling, relocate;
|
bool compiling, relocate;
|
||||||
|
|
||||||
explicit quotation_jit(cell quot, bool compiling_, bool relocate_, factor_vm *vm)
|
explicit quotation_jit(cell quot, bool compiling_, bool relocate_, factor_vm *vm)
|
||||||
: jit(QUOTATION_TYPE,quot,vm),
|
: jit(code_block_unoptimized,quot,vm),
|
||||||
elements(owner.as<quotation>().untagged()->array,vm),
|
elements(owner.as<quotation>().untagged()->array,vm),
|
||||||
compiling(compiling_),
|
compiling(compiling_),
|
||||||
relocate(relocate_){};
|
relocate(relocate_){};
|
||||||
|
|
|
@ -27,23 +27,34 @@ struct tagged
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool type_p(cell type_) const { return type() == type_; }
|
bool type_p(cell type_) const
|
||||||
|
{
|
||||||
|
return type() == type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool type_p() const
|
||||||
|
{
|
||||||
|
if(Type::type_number == TYPE_COUNT)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return type_p(Type::type_number);
|
||||||
|
}
|
||||||
|
|
||||||
Type *untag_check(factor_vm *parent) const {
|
Type *untag_check(factor_vm *parent) const {
|
||||||
if(Type::type_number != TYPE_COUNT && !type_p(Type::type_number))
|
if(!type_p())
|
||||||
parent->type_error(Type::type_number,value_);
|
parent->type_error(Type::type_number,value_);
|
||||||
return untagged();
|
return untagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit tagged(cell tagged) : value_(tagged) {
|
explicit tagged(cell tagged) : value_(tagged) {
|
||||||
#ifdef FACTOR_DEBUG
|
#ifdef FACTOR_DEBUG
|
||||||
untag_check(tls_vm());
|
assert(type_p());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit tagged(Type *untagged) : value_(factor::tag(untagged)) {
|
explicit tagged(Type *untagged) : value_(factor::tag(untagged)) {
|
||||||
#ifdef FACTOR_DEBUG
|
#ifdef FACTOR_DEBUG
|
||||||
untag_check(tls_vm());
|
assert(type_p());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -498,8 +498,8 @@ struct factor_vm
|
||||||
void check_code_address(cell address);
|
void check_code_address(cell address);
|
||||||
void relocate_code_block(code_block *compiled);
|
void relocate_code_block(code_block *compiled);
|
||||||
void fixup_labels(array *labels, code_block *compiled);
|
void fixup_labels(array *labels, code_block *compiled);
|
||||||
code_block *allot_code_block(cell size, cell type);
|
code_block *allot_code_block(cell size, code_block_type type);
|
||||||
code_block *add_code_block(cell type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_);
|
code_block *add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_);
|
||||||
|
|
||||||
//code heap
|
//code heap
|
||||||
inline void check_code_pointer(cell ptr)
|
inline void check_code_pointer(cell ptr)
|
||||||
|
|
|
@ -82,7 +82,8 @@ void factor_vm::update_word_xt(cell w_)
|
||||||
|
|
||||||
void factor_vm::primitive_optimized_p()
|
void factor_vm::primitive_optimized_p()
|
||||||
{
|
{
|
||||||
drepl(tag_boolean(word_optimized_p(untag_check<word>(dpeek()))));
|
word *w = untag_check<word>(dpeek());
|
||||||
|
drepl(tag_boolean(w->code->optimized_p()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_wrapper()
|
void factor_vm::primitive_wrapper()
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline bool word_optimized_p(word *word)
|
|
||||||
{
|
|
||||||
return word->code->type() == WORD_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue