]> gitweb.factorcode.org Git - factor.git/commitdiff
Store forwarding table off to the side instead of in the code block; saves one cell...
authorSlava Pestov <slava@shill.internal.stack-effects.com>
Tue, 5 May 2009 16:07:20 +0000 (11:07 -0500)
committerSlava Pestov <slava@shill.internal.stack-effects.com>
Tue, 5 May 2009 16:07:20 +0000 (11:07 -0500)
vm/callstack.cpp
vm/code_block.cpp
vm/code_gc.cpp
vm/code_gc.hpp
vm/code_heap.cpp
vm/inline_cache.cpp
vm/layouts.hpp
vm/master.hpp
vm/quotations.cpp
vm/words.cpp
vm/words.hpp

index ade0b45db7d3a8d486e9920a4c05f10d94e8f988..2ad58534b5febfc096e4ff32cb45ca8b1258c217 100755 (executable)
@@ -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)
index 4694381ed38b13866bf22470bb327671428974f5..80adb1feac40911b5a5dacf0eba14ec5b8e7ffb3 100644 (file)
@@ -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 */
index b86d08cf5221699fec7afc4aadfbf981cdaf3722..721c3f3a7ae52f33722d439a3a3dc383467d29d3 100755 (executable)
@@ -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<heap_block *,char *> &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<heap_block *,char *> &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;
        }
 }
index 3879d3c8e821da07f5e6ac2d09f3c9f9bdd5473a..1ad68f46fd9c0df59bba03b4dfbee6e63782cd61 100755 (executable)
@@ -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<heap_block *,char *> &forwarding);
+void compact_heap(heap *h, std::tr1::unordered_map<heap_block *,char *> &forwarding);
 
 inline static heap_block *next_block(heap *h, heap_block *block)
 {
index 5dca29b4203984e6f87ac9c05215fd8f8891ca2f..2342a3dd09403b6a1195e7d24f6f0a095426448d 100755 (executable)
@@ -119,9 +119,11 @@ PRIMITIVE(code_room)
        dpush(tag_fixnum(max_free / 1024));
 }
 
+static std::tr1::unordered_map<heap_block *,char *> 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();
index 5d9fbf069e102d5df5c232c548cf59a77f2b6828..23c4b27c472cf5969bae67fbf955e1294192cf69 100644 (file)
@@ -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
index 4928fda632114b9fbc60a403fd49d6ea56422c25..114b88b9255848e764e43f962288fcebf02a034a 100755 (executable)
@@ -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 */
        
index fa7d7fa1a4064395f703d4add153e3baea46778b..65d17fab4b4615bd3df734ca7854cd867ee82b99 100644 (file)
@@ -9,6 +9,7 @@
 #include <assert.h>
 #endif
 
+/* C headers */
 #include <fcntl.h>
 #include <limits.h>
 #include <math.h>
 #include <time.h>
 #include <sys/param.h>
 
+/* C++ headers */
+#include <tr1/unordered_map>
+
+/* Factor headers */
 #include "layouts.hpp"
 #include "platform.hpp"
 #include "primitives.hpp"
index c87cf8dc8275fb2d3715e6d242809b5ec9ebacbd..af00bb468bceb423e49bba65f3ba603ebc500f34 100755 (executable)
@@ -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;
index cb2fdf0dd6a3f463f0f01072eb8e4a4c9b956a8a..6e7c633c8464f03c97bfbe72ce767ea9fd9afedf 100644 (file)
@@ -44,7 +44,7 @@ PRIMITIVE(word_xt)
        word *w = untag_check<word>(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 */
index 9c8e7ad57a1b325d974c1df89d88985a086d72da..f9d5a7aff46fc5847163f3421aee62a54ef5669f 100644 (file)
@@ -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);