]> gitweb.factorcode.org Git - factor.git/commitdiff
Replace compiled? primitive with compiled? word slot
authorslava <slava@factorcode.org>
Wed, 27 Sep 2006 07:11:18 +0000 (07:11 +0000)
committerslava <slava@factorcode.org>
Wed, 27 Sep 2006 07:11:18 +0000 (07:11 +0000)
TODO.FACTOR.txt
library/bootstrap/image.factor
library/bootstrap/primitives.factor
vm/code_gc.c
vm/code_gc.h
vm/compiler.c
vm/data_gc.c
vm/layouts.h
vm/primitives.c
vm/types.c
vm/types.h

index dd3a2df5c8c8c2114323fb974d27bbb118aa2154..1eaa8cf92d1cfc14ef310ff091a46dbf0e996b86 100644 (file)
   - files can be reloaded and edited
   - modules can be (re)loaded
   - keyboard navigation
-- editor:
-  - more efficient multi-line inserts
-  - write "foo| " and put caret at | then select word element: selects
-    space
 - ui browser: show currently selected vocab & words
   - keyboard-navigatable list gadget of some kind
 - tuple= in dataflow view
@@ -22,7 +18,6 @@
 - ui quick start doc
 - auto-update browser and help when sources reload
 - how do we refer to command shortcuts in the docs?
-- reliably clonable gadgets
 - figure out if we need both set-model and set-model*
 - if i do 10000 [ . ] each and then clear, the listener window is slow
 - full-height nodes should really be full height
   - editor should support stream output protocol
   - double/triple click
   - autoscroll
-  - undo and redo
   - transpose char/word/line
-  - page up/down
-  - search and replace
   - drag scroll
+  - more efficient multi-line inserts
+  - write "foo| " and put caret at | then select word element: selects
+    space
 - slider needs to be modelized
 - fonts/ should go inside the .app -- we need multi-tier resource-path
 - should be possible to drop an image file on the .app to run it
@@ -50,7 +45,6 @@
 - own-selection violates ICCCM
 - cocoa: windows are not updated while resizing
 - grid slows down with 2000 lines
-- ui uses too much cpu time idling
 - see if its possible to only repaint dirty regions
 - x11 title bars are funny
 - rollover is not updated on window focus changes
 
 + misc:
 
+- symbol redef is an xref false positive
 - signal 4 on datastack underflow on mac intel??
 - fix alien-callback/SEH bug on win32
 - minor GC takes too long now, we should card mark code heap
index 0450ba229783830bb494b2ba603fd2a75cadee1b..79dcfb47239f91a5403372e6b8a4ca1208e1a737 100644 (file)
@@ -172,6 +172,7 @@ M: f '
         dup word-primitive ' ,
         dup word-def ' ,
         dup word-props ' ,
+        f ' ,
         0 ,
     ] { } make
     word-tag word-tag [ emit-seq ] emit-object
index 7963d037ef7f8bba2b1d1a7cff27dc088a24e243..c8b097a43790383770d3f5352102b1613d4b8ed1 100644 (file)
@@ -99,7 +99,6 @@ call
     { "float>=" "math-internals"            }
     { "(word)" "kernel-internals"           }
     { "update-xt" "words"                   }
-    { "compiled?" "words"                   }
     { "drop" "kernel"                       }
     { "2drop" "kernel"                      }
     { "3drop" "kernel"                      }
@@ -284,6 +283,12 @@ num-types f <array> builtins set
         { "word-props" "words" }
         { "set-word-props" "words" }
     }
+    {
+        7
+        object
+        { "compiled?" "words" }
+        f
+    }
 } define-builtin
 
 "ratio?" "math" create t "inline" set-word-prop
index 64e2d9297619f2c4298ea89a0d30772dfd3c7ac0..d2177751374912ec01708ce96d9e50c1a278d989 100644 (file)
@@ -67,6 +67,8 @@ CELL heap_allot(HEAP *heap, CELL size)
        F_BLOCK *prev = NULL;
        F_BLOCK *scan = heap->free_list;
 
+       size = align8(size);
+
        while(scan)
        {
                CELL this_size = scan->size - sizeof(F_BLOCK);
@@ -209,20 +211,20 @@ void mark_sweep_step(F_COMPILED *compiled, CELL code_start,
        if(compiled->finalized)
        {
                for(scan = words_start; scan < words_end; scan += CELLS)
-                       mark_and_sweep(get(scan));
+                       recursive_mark(get(scan));
        }
 }
 
-void mark_and_sweep(CELL xt)
+void recursive_mark(CELL xt)
 {
        F_BLOCK *block = xt_to_block(xt);
 
        if(block->status == B_MARKED)
                return;
-       else if(block->status == B_FREE)
-               critical_error("Marking a free block",(CELL)block);
-
-       block->status = B_MARKED;
+       else if(block->status == B_ALLOCATED)
+               block->status = B_MARKED;
+       else
+               critical_error("Marking the wrong block",(CELL)block);
 
        F_COMPILED *compiled = xt_to_compiled(xt);
        iterate_code_heap_step(compiled,collect_literals_step);
index 8541f568ed846a4690ab0946cbf18e9ee2dd637a..00b703cfaf6c7d3872bc04b40b9a5bca2eecc4ed 100644 (file)
@@ -74,6 +74,6 @@ INLINE F_COMPILED *xt_to_compiled(CELL xt)
 void init_code_heap(CELL size);
 void iterate_code_heap(CODE_HEAP_ITERATOR iter);
 void collect_literals(void);
-void mark_and_sweep(CELL xt);
+void recursive_mark(CELL xt);
 void primitive_code_room(void);
 void primitive_code_gc(void);
index bd2343d7cd7e9f75644410dca7ae49f6d55f4a36..89b916855981894e670609e94a807fc5770faa5b 100644 (file)
@@ -232,6 +232,7 @@ void primitive_finalize_compile(void)
                F_ARRAY *pair = untag_array(get(AREF(array,i)));
                F_WORD *word = untag_word(get(AREF(pair,0)));
                word->xt = to_cell(get(AREF(pair,1)));
+               word->compiledp = T;
        }
 
        /* perform relocation */
index 4ecf4dc687b063e9f9241b8e47b1fd09399b96a8..59654882368772fdb10bcbd7896a5b83a03224ff 100644 (file)
@@ -79,31 +79,6 @@ void primitive_size(void)
        drepl(tag_fixnum(object_size(dpeek())));
 }
 
-/* The number of cells from the start of the object which should be scanned by
-the GC. Some types have a binary payload at the end (string, word, DLL) which
-we ignore. */
-CELL binary_payload_start(CELL pointer)
-{
-       switch(untag_header(get(pointer)))
-       {
-       /* these objects do not refer to other objects at all */
-       case STRING_TYPE:
-       case FLOAT_TYPE:
-       case BYTE_ARRAY_TYPE:
-       case BIGNUM_TYPE:
-               return 0;
-       /* these objects have some binary data at the end */
-       case WORD_TYPE:
-               return sizeof(F_WORD) - CELLS;
-       case ALIEN_TYPE:
-       case DLL_TYPE:
-               return CELLS * 2;
-       /* everything else consists entirely of pointers */
-       default:
-               return unaligned_object_size(pointer);
-       }
-}
-
 void primitive_data_room(void)
 {
        F_ARRAY *a = array(ARRAY_TYPE,gen_count,F);
@@ -417,8 +392,37 @@ CELL copy_object(CELL pointer)
                return RETAG(copy_object_impl(pointer),tag);
 }
 
-INLINE void collect_object(CELL scan)
+/* The number of cells from the start of the object which should be scanned by
+the GC. Some types have a binary payload at the end (string, word, DLL) which
+we ignore. */
+CELL binary_payload_start(CELL pointer)
+{
+       switch(untag_header(get(pointer)))
+       {
+       /* these objects do not refer to other objects at all */
+       case STRING_TYPE:
+       case FLOAT_TYPE:
+       case BYTE_ARRAY_TYPE:
+       case BIGNUM_TYPE:
+               return 0;
+       /* these objects have some binary data at the end */
+       case WORD_TYPE:
+               return sizeof(F_WORD) - CELLS;
+       case ALIEN_TYPE:
+       case DLL_TYPE:
+               return CELLS * 2;
+       /* everything else consists entirely of pointers */
+       default:
+               return unaligned_object_size(pointer);
+       }
+}
+
+/* Every object has a regular representation in the runtime, which makes GC
+much simpler. Every slot of the object until binary_payload_start is a pointer
+to some other object. */
+INLINE void collect_object(CELL start)
 {
+       CELL scan = start;
        CELL payload_start = binary_payload_start(scan);
        CELL end = scan + payload_start;
 
@@ -429,6 +433,16 @@ INLINE void collect_object(CELL scan)
                copy_handle((CELL*)scan);
                scan += CELLS;
        }
+
+       /* It is odd to put this hook here, but this is the only special case
+       made for any type of object by the GC. If code GC is being performed,
+       compiled code blocks referenced by this word must be marked. */
+       if(collecting_code && object_type(start) == WORD_TYPE)
+       {
+               F_WORD *word = (F_WORD *)start;
+               if(word->compiledp != F)
+                       recursive_mark(word->xt);
+       }
 }
 
 CELL collect_next(CELL scan)
@@ -487,6 +501,7 @@ void end_gc()
                fprintf(stderr,"*** %s GC (%ld minor, %ld cards)\n",
                        collecting_code ? "Code and data" : "Data",
                        minor_collections,cards_scanned);
+               fflush(stderr);
                minor_collections = 0;
                cards_scanned = 0;
        }
index 74ff43a7efdca962d5660d576d26aad596302153..04fa715fa84a027d3024dbc0e83da7da47d2d9a8 100644 (file)
@@ -105,6 +105,11 @@ typedef struct {
        CELL array;
 } F_HASHTABLE;
 
+/* When a word is executed we jump to the value of the XT field. However this
+value is an unportable function pointer. Interpreted and primitive words will
+have their XT set to a value in the 'primitives' global (see primitives.c).
+Compiled words are marked as such and their XT, which point inside the code
+heap, are instead relocated on startup, and also considered a code GC root. */
 typedef struct {
        /* TAGGED header */
        CELL header;
@@ -120,6 +125,8 @@ typedef struct {
        CELL def;
        /* TAGGED property hash for library code */
        CELL props;
+       /* TAGGED t or f, depending on if the word is compiled or not */
+       CELL compiledp;
        /* UNTAGGED execution token: jump here to execute word */
        CELL xt;
 } F_WORD;
index f817bc18b1306257161b6ad1a580590e6735c69f..148e9592c04dd6e3cf486a5d272accd54eaf604d 100644 (file)
@@ -68,7 +68,6 @@ void* primitives[] = {
        primitive_float_greatereq,
        primitive_word,
        primitive_update_xt,
-       primitive_word_compiledp,
        primitive_drop,
        primitive_2drop,
        primitive_3drop,
index 6bc3fca734b83e26a36709c00848a2f5c97d903d..d644e4e798e2adf4d784bb290e5a6773206ad0a0 100644 (file)
@@ -417,11 +417,9 @@ void primitive_hashtable(void)
        dpush(tag_object(hash));
 }
 
-/* When a word is executed we jump to the value of the xt field. However this
-   value is an unportable function pointer, so in the image we store a primitive
-   number that indexes a list of xts. */
 void update_xt(F_WORD* word)
 {
+       word->compiledp = F;
        word->xt = primitive_to_xt(to_fixnum(word->primitive));
 }
 
@@ -442,6 +440,7 @@ void primitive_word(void)
        word->primitive = tag_fixnum(0);
        word->def = F;
        word->props = F;
+       word->compiledp = F;
        word->xt = (CELL)undefined;
        dpush(tag_word(word));
 }
@@ -451,23 +450,11 @@ void primitive_update_xt(void)
        update_xt(untag_word(dpop()));
 }
 
-void primitive_word_compiledp(void)
-{
-       F_WORD* word = untag_word(dpop());
-       if(to_fixnum(word->primitive) != 1)
-               box_boolean(false);
-       else
-               box_boolean(word->xt != (CELL)docol);
-}
-
 void fixup_word(F_WORD* word)
 {
        /* If this is a compiled word, relocate the code pointer. Otherwise,
        reset it based on the primitive number of the word. */
-       if(code_relocation_base != 0
-               && word->xt >= code_relocation_base
-               && word->xt < code_relocation_base
-               - compiling.base + compiling.limit)
+       if(word->compiledp != F)
                code_fixup(&word->xt);
        else
                update_xt(word);
index 6be2d9cbd1ffe9126b465813e5d016034c5402e5..035d01efbce0b763260df2536756326e25094b2a 100644 (file)
@@ -161,7 +161,6 @@ INLINE CELL tag_word(F_WORD *word)
 void update_xt(F_WORD* word);
 void primitive_word(void);
 void primitive_update_xt(void);
-void primitive_word_compiledp(void);
 void fixup_word(F_WORD* word);
 
 INLINE F_WRAPPER *untag_wrapper_fast(CELL tagged)