diff --git a/vm/callstack.cpp b/vm/callstack.cpp index ade0b45db7..2ad58534b5 100755 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -100,7 +100,7 @@ code_block *frame_code(stack_frame *frame) cell frame_type(stack_frame *frame) { - return frame_code(frame)->block.type; + return frame_code(frame)->type; } cell frame_executing(stack_frame *frame) diff --git a/vm/code_block.cpp b/vm/code_block.cpp index 4694381ed3..80adb1feac 100644 --- a/vm/code_block.cpp +++ b/vm/code_block.cpp @@ -5,7 +5,7 @@ namespace factor void flush_icache_for(code_block *block) { - flush_icache((cell)block,block->block.size); + flush_icache((cell)block,block->size); } void iterate_relocations(code_block *compiled, relocation_iterator iter) @@ -122,7 +122,7 @@ void update_literal_references_step(relocation_entry rel, cell index, code_block /* Update pointers to literals from compiled code. */ void update_literal_references(code_block *compiled) { - if(!compiled->block.needs_fixup) + if(!compiled->needs_fixup) { iterate_relocations(compiled,update_literal_references_step); flush_icache_for(compiled); @@ -133,12 +133,12 @@ void update_literal_references(code_block *compiled) aging and nursery collections */ void copy_literal_references(code_block *compiled) { - if(collecting_gen >= compiled->block.last_scan) + if(collecting_gen >= compiled->last_scan) { if(collecting_accumulation_gen_p()) - compiled->block.last_scan = collecting_gen; + compiled->last_scan = collecting_gen; else - compiled->block.last_scan = collecting_gen + 1; + compiled->last_scan = collecting_gen + 1; /* initialize chase pointer */ cell scan = newspace->here; @@ -208,7 +208,7 @@ to update references to other words, without worrying about literals or dlsyms. */ void update_word_references(code_block *compiled) { - if(compiled->block.needs_fixup) + if(compiled->needs_fixup) relocate_code_block(compiled); /* update_word_references() is always applied to every block in the code heap. Since it resets all call sites to point to @@ -217,8 +217,8 @@ void update_word_references(code_block *compiled) are referenced after this is done. So instead of polluting the code heap with dead PICs that will be freed on the next GC, we add them to the free list immediately. */ - else if(compiled->block.type == PIC_TYPE) - heap_free(&code,&compiled->block); + else if(compiled->type == PIC_TYPE) + heap_free(&code,compiled); else { iterate_relocations(compiled,update_word_references_step); @@ -248,7 +248,7 @@ void mark_code_block(code_block *compiled) { check_code_address((cell)compiled); - mark_block(&compiled->block); + mark_block(compiled); copy_handle(&compiled->literals); copy_handle(&compiled->relocation); @@ -405,8 +405,8 @@ void relocate_code_block_step(relocation_entry rel, cell index, code_block *comp /* Perform all fixups on a code block */ void relocate_code_block(code_block *compiled) { - compiled->block.last_scan = NURSERY; - compiled->block.needs_fixup = false; + compiled->last_scan = NURSERY; + compiled->needs_fixup = false; iterate_relocations(compiled,relocate_code_block_step); flush_icache_for(compiled); } @@ -474,9 +474,9 @@ code_block *add_code_block( code_block *compiled = allot_code_block(code_length); /* compiled header */ - compiled->block.type = type; - compiled->block.last_scan = NURSERY; - compiled->block.needs_fixup = true; + compiled->type = type; + compiled->last_scan = NURSERY; + compiled->needs_fixup = true; compiled->relocation = relocation.value(); /* slight space optimization */ diff --git a/vm/code_gc.cpp b/vm/code_gc.cpp index b86d08cf52..721c3f3a7a 100755 --- a/vm/code_gc.cpp +++ b/vm/code_gc.cpp @@ -22,9 +22,9 @@ void new_heap(heap *heap, cell size) static void add_to_free_list(heap *heap, free_heap_block *block) { - if(block->block.size < FREE_LIST_COUNT * BLOCK_SIZE_INCREMENT) + if(block->size < FREE_LIST_COUNT * BLOCK_SIZE_INCREMENT) { - int index = block->block.size / BLOCK_SIZE_INCREMENT; + int index = block->size / BLOCK_SIZE_INCREMENT; block->next_free = heap->free.small_blocks[index]; heap->free.small_blocks[index] = block; } @@ -73,8 +73,8 @@ void build_free_list(heap *heap, cell size) branch is only taken after loading a new image, not after code GC */ if((cell)(end + 1) <= heap->seg->end) { - end->block.status = B_FREE; - end->block.size = heap->seg->end - (cell)end; + end->status = B_FREE; + end->size = heap->seg->end - (cell)end; /* add final free block */ add_to_free_list(heap,end); @@ -93,7 +93,7 @@ void build_free_list(heap *heap, cell size) static void assert_free_block(free_heap_block *block) { - if(block->block.status != B_FREE) + if(block->status != B_FREE) critical_error("Invalid block in free list",(cell)block); } @@ -121,7 +121,7 @@ static free_heap_block *find_free_block(heap *heap, cell size) while(block) { assert_free_block(block); - if(block->block.size >= size) + if(block->size >= size) { if(prev) prev->next_free = block->next_free; @@ -139,14 +139,14 @@ static free_heap_block *find_free_block(heap *heap, cell size) static free_heap_block *split_free_block(heap *heap, free_heap_block *block, cell size) { - if(block->block.size != size ) + if(block->size != size ) { /* split the block in two */ free_heap_block *split = (free_heap_block *)((cell)block + size); - split->block.status = B_FREE; - split->block.size = block->block.size - size; + split->status = B_FREE; + split->size = block->size - size; split->next_free = block->next_free; - block->block.size = size; + block->size = size; add_to_free_list(heap,split); } @@ -163,8 +163,8 @@ heap_block *heap_allot(heap *heap, cell size) { block = split_free_block(heap,block,size); - block->block.status = B_ALLOCATED; - return &block->block; + block->status = B_ALLOCATED; + return block; } else return NULL; @@ -303,16 +303,16 @@ cell heap_size(heap *heap) } /* Compute where each block is going to go, after compaction */ -cell compute_heap_forwarding(heap *heap) + cell compute_heap_forwarding(heap *heap, std::tr1::unordered_map &forwarding) { heap_block *scan = first_block(heap); - cell address = (cell)first_block(heap); + char *address = (char *)first_block(heap); while(scan) { if(scan->status == B_ALLOCATED) { - scan->forwarding = (heap_block *)address; + forwarding[scan] = address; address += scan->size; } else if(scan->status == B_MARKED) @@ -321,10 +321,10 @@ cell compute_heap_forwarding(heap *heap) scan = next_block(heap,scan); } - return address - heap->seg->start; + return (cell)address - heap->seg->start; } -void compact_heap(heap *heap) + void compact_heap(heap *heap, std::tr1::unordered_map &forwarding) { heap_block *scan = first_block(heap); @@ -332,8 +332,8 @@ void compact_heap(heap *heap) { heap_block *next = next_block(heap,scan); - if(scan->status == B_ALLOCATED && scan != scan->forwarding) - memcpy(scan->forwarding,scan,scan->size); + if(scan->status == B_ALLOCATED) + memmove(forwarding[scan],scan,scan->size); scan = next; } } diff --git a/vm/code_gc.hpp b/vm/code_gc.hpp index 3879d3c8e8..1ad68f46fd 100755 --- a/vm/code_gc.hpp +++ b/vm/code_gc.hpp @@ -25,8 +25,8 @@ void unmark_marked(heap *heap); void free_unmarked(heap *heap, heap_iterator iter); void heap_usage(heap *h, cell *used, cell *total_free, cell *max_free); cell heap_size(heap *h); -cell compute_heap_forwarding(heap *h); -void compact_heap(heap *h); +cell compute_heap_forwarding(heap *h, std::tr1::unordered_map &forwarding); +void compact_heap(heap *h, std::tr1::unordered_map &forwarding); inline static heap_block *next_block(heap *h, heap_block *block) { diff --git a/vm/code_heap.cpp b/vm/code_heap.cpp index 5dca29b420..2342a3dd09 100755 --- a/vm/code_heap.cpp +++ b/vm/code_heap.cpp @@ -119,9 +119,11 @@ PRIMITIVE(code_room) dpush(tag_fixnum(max_free / 1024)); } +static std::tr1::unordered_map forwarding; + code_block *forward_xt(code_block *compiled) { - return (code_block *)compiled->block.forwarding; + return (code_block *)forwarding[compiled]; } void forward_frame_xt(stack_frame *frame) @@ -132,7 +134,7 @@ void forward_frame_xt(stack_frame *frame) FRAME_RETURN_ADDRESS(frame) = (void *)((cell)forwarded + offset); } -void forward_object_xts(void) +void forward_object_xts() { begin_scan(); @@ -215,13 +217,13 @@ void compact_code_heap(void) gc(); /* Figure out where the code heap blocks are going to end up */ - cell size = compute_heap_forwarding(&code); + cell size = compute_heap_forwarding(&code, forwarding); /* Update word and quotation code pointers */ forward_object_xts(); /* Actually perform the compaction */ - compact_heap(&code); + compact_heap(&code,forwarding); /* Update word and quotation XTs */ fixup_object_xts(); diff --git a/vm/inline_cache.cpp b/vm/inline_cache.cpp index 5d9fbf069e..23c4b27c47 100644 --- a/vm/inline_cache.cpp +++ b/vm/inline_cache.cpp @@ -22,7 +22,7 @@ void deallocate_inline_cache(cell return_address) /* Find the call target. */ void *old_xt = get_call_target(return_address); code_block *old_block = (code_block *)old_xt - 1; - cell old_type = old_block->block.type; + cell old_type = old_block->type; #ifdef FACTOR_DEBUG /* The call target was either another PIC, @@ -31,7 +31,7 @@ void deallocate_inline_cache(cell return_address) #endif if(old_type == PIC_TYPE) - heap_free(&code,&old_block->block); + heap_free(&code,old_block); } /* Figure out what kind of type check the PIC needs based on the methods diff --git a/vm/layouts.hpp b/vm/layouts.hpp index 4928fda632..114b88b925 100755 --- a/vm/layouts.hpp +++ b/vm/layouts.hpp @@ -193,26 +193,19 @@ struct heap_block unsigned char status; /* free or allocated? */ unsigned char type; /* this is WORD_TYPE or QUOTATION_TYPE */ unsigned char last_scan; /* the youngest generation in which this block's literals may live */ - char needs_fixup; /* is this a new block that needs full fixup? */ + unsigned char needs_fixup; /* is this a new block that needs full fixup? */ /* In bytes, includes this header */ cell size; - - /* Used during compaction */ - heap_block *forwarding; }; -struct free_heap_block +struct free_heap_block : public heap_block { - heap_block block; - - /* Filled in on image load */ free_heap_block *next_free; }; -struct code_block +struct code_block : public heap_block { - heap_block block; cell literals; /* # bytes */ cell relocation; /* tagged pointer to byte-array or f */ diff --git a/vm/master.hpp b/vm/master.hpp index fa7d7fa1a4..65d17fab4b 100644 --- a/vm/master.hpp +++ b/vm/master.hpp @@ -9,6 +9,7 @@ #include #endif +/* C headers */ #include #include #include @@ -20,6 +21,10 @@ #include #include +/* C++ headers */ +#include + +/* Factor headers */ #include "layouts.hpp" #include "platform.hpp" #include "primitives.hpp" diff --git a/vm/quotations.cpp b/vm/quotations.cpp index c87cf8dc82..af00bb468b 100755 --- a/vm/quotations.cpp +++ b/vm/quotations.cpp @@ -251,7 +251,7 @@ void quotation_jit::iterate_quotation() void set_quot_xt(quotation *quot, code_block *code) { - if(code->block.type != QUOTATION_TYPE) + if(code->type != QUOTATION_TYPE) critical_error("Bad param to set_quot_xt",(cell)code); quot->code = code; diff --git a/vm/words.cpp b/vm/words.cpp index cb2fdf0dd6..6e7c633c84 100644 --- a/vm/words.cpp +++ b/vm/words.cpp @@ -44,7 +44,7 @@ PRIMITIVE(word_xt) word *w = untag_check(dpop()); code_block *code = (profiling_p ? w->profiling : w->code); dpush(allot_cell((cell)code->xt())); - dpush(allot_cell((cell)code + code->block.size)); + dpush(allot_cell((cell)code + code->size)); } /* Allocates memory */ diff --git a/vm/words.hpp b/vm/words.hpp index 9c8e7ad57a..f9d5a7aff4 100644 --- a/vm/words.hpp +++ b/vm/words.hpp @@ -9,7 +9,7 @@ void update_word_xt(cell word); inline bool word_optimized_p(word *word) { - return word->code->block.type == WORD_TYPE; + return word->code->type == WORD_TYPE; } PRIMITIVE(optimized_p);