]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler.codegen.gc-maps: check-d>> and check-r>> now used in the code generator
authorBjörn Lindqvist <bjourne@gmail.com>
Tue, 26 Aug 2014 02:44:03 +0000 (04:44 +0200)
committerDoug Coleman <doug.coleman@gmail.com>
Mon, 8 Sep 2014 21:54:17 +0000 (14:54 -0700)
the approach looks sound and now the gc can be fixed to take advantage
of the extra info.

basis/compiler/codegen/gc-maps/gc-maps-tests.factor
basis/compiler/codegen/gc-maps/gc-maps.factor
basis/vm/vm.factor
vm/gc_info.hpp

index 9c35766bcb515f26cf37eb1403a47b7c0ca1178b..2dbf5ea3c9e8c381b34ea6056ff0454609942d63 100644 (file)
@@ -12,65 +12,154 @@ fake-cpu \ cpu set
 
 M: fake-cpu gc-root-offset ;
 
-[ ] [
-    [
-        init-relocation
-        init-gc-maps
+[
+    init-relocation
+    init-gc-maps
 
-        50 <byte-array> %
+    50 <byte-array> %
 
-        <gc-map> gc-map-here
+    <gc-map> gc-map-here
 
-        50 <byte-array> %
+    50 <byte-array> %
 
+    T{ gc-map
+       { scrub-d { 0 1 1 1 0 } }
+       { scrub-r { 1 0 } }
+       { gc-roots V{ 1 3 } }
+       { derived-roots V{ { 2 4 } } }
+    } gc-map-here
+    emit-gc-maps
+] B{ } make
+"result" set
+
+[ 0 ] [ "result" get length 16 mod ] unit-test
+
+[
+    100 <byte-array> %
+
+    ! The below data is 46 bytes -- 14 bytes padding needed to
+    ! align
+    14 <byte-array> %
+
+    ! Bitmap - 2 bytes
+    ?{
+        ! scrub-d
+        t f f f t
+        ! scrub-r
+        f t
+        ! gc-roots
+        f t f t
+    } underlying>> %
+
+    ! Derived pointers
+    uint-array{ -1 -1 4 } underlying>> %
+
+    ! Return addresses
+    uint-array{ 100 } underlying>> %
+
+    ! GC info footer - 28 bytes
+    S{ gc-info
+       { scrub-d-count 5 }
+       { scrub-r-count 2 }
+       { check-d-count 0 }
+       { check-r-count 0 }
+       { gc-root-count 4 }
+       { derived-root-count 3 }
+       { return-address-count 1 }
+    } (underlying)>> %
+] B{ } make
+"expect" set
+
+[ t ] [ "result" get length "expect" get length = ] unit-test
+[ t ] [ "result" get "expect" get = ] unit-test
+
+! gc-map-needed?
+{ t t } [
+    T{ gc-map { scrub-d { 0 1 1 1 0 } } { scrub-r { 1 0 } } } gc-map-needed?
+    T{ gc-map { check-d { 0 1 1 1 } } } gc-map-needed?
+] unit-test
+
+! emit-scrub
+{ 3 V{ t t t f f f } } [
+    [ { { 0 0 0 } { 1 1 1 } } emit-scrub ] V{ } make
+] unit-test
+
+! emit-gc-info-bitmaps
+{
+    { 4 2 0 0 0 }
+    V{ 1 }
+} [
+    { T{ gc-map { scrub-d { 0 1 1 1 } } { scrub-r { 1 1 } } } } gc-maps set
+    [ emit-gc-info-bitmaps ] V{ } make
+] unit-test
+
+{
+    { 1 0 1 0 0 }
+    V{ 3 }
+} [
+    { T{ gc-map { scrub-d { 0 } } { check-d { 0 } } } } gc-maps set
+    [ emit-gc-info-bitmaps ] V{ } make
+] unit-test
+
+! derived-root-offsets
+USING: present prettyprint ;
+{
+    V{ { 2 4 } }
+} [
+    T{ gc-map { derived-roots V{ { 2 4 } } } }
+    derived-root-offsets
+] unit-test
+
+! emit-base-tables
+{
+    3 B{ 255 255 255 255 255 255 255 255 4 0 0 0 }
+} [
+    { T{ gc-map { derived-roots V{ { 2 4 } } } } } gc-maps set
+    [ emit-base-tables ] B{ } make
+] unit-test
+
+
+! serialize-gc-maps
+{
+    B{ 0 0 0 0 }
+} [
+    { } return-addresses set serialize-gc-maps
+] unit-test
+
+{
+    B{
+        17 123 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+        1 0 0 0
+    }
+} [
+    { 123 } return-addresses set
+    { T{ gc-map { scrub-d { 0 1 1 1 0 } } } } gc-maps set
+    serialize-gc-maps
+] unit-test
+
+! gc-info + ret-addr + 9bits (5+2+2) = 28 + 4 + 2 = 34
+{ 34 } [
+    {
         T{ gc-map
            { scrub-d { 0 1 1 1 0 } }
            { scrub-r { 1 0 } }
            { gc-roots V{ 1 3 } }
-           { derived-roots V{ { 2 4 } } }
-        } gc-map-here
-        emit-gc-maps
-    ] B{ } make
-    "result" set
+        }
+    } gc-maps set
+    { 123 } return-addresses set
+    serialize-gc-maps length
 ] unit-test
 
-[ 0 ] [ "result" get length 16 mod ] unit-test
-
-[ ] [
-    [
-        100 <byte-array> %
-
-        ! The below data is 22 bytes -- 6 bytes padding needed to
-        ! align
-        6 <byte-array> %
-
-        ! Bitmap - 2 bytes
-        ?{
-            ! scrub-d
-            t f f f t
-            ! scrub-r
-            f t
-            ! gc-roots
-            f t f t
-        } underlying>> %
-
-        ! Derived pointers
-        uint-array{ -1 -1 4 } underlying>> %
-
-        ! Return addresses
-        uint-array{ 100 } underlying>> %
-
-        ! GC info footer - 20 bytes
-        S{ gc-info
-            { scrub-d-count 5 }
-            { scrub-r-count 2 }
-            { gc-root-count 4 }
-            { derived-root-count 3 }
-            { return-address-count 1 }
-        } (underlying)>> %
-    ] B{ } make
-    "expect" set
+! gc-info + ret-addr + 3 base-pointers + 9bits = 28 + 4 + 12 + 2 = 46
+{ 46 } [
+    {
+        T{ gc-map
+           { scrub-d { 0 1 1 1 0 } }
+           { scrub-r { 1 0 } }
+           { gc-roots V{ 1 3 } }
+           { derived-roots V{ { 2 4 } } }
+        }
+    } gc-maps set
+    { 123 } return-addresses set
+    serialize-gc-maps length
 ] unit-test
-
-[ ] [ "result" get length "expect" get length assert= ] unit-test
-[ ] [ "result" get "expect" get assert= ] unit-test
index 474781ea95a561189d65ebdefde394ebc65491a0..e17c96c0880dd0772e88b8a87175a8b336726ae5 100644 (file)
@@ -1,12 +1,12 @@
 ! Copyright (C) 2011 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs bit-arrays combinators
+USING: accessors arrays assocs bit-arrays classes.tuple combinators
 combinators.short-circuit compiler.cfg.instructions
 compiler.codegen.relocation cpu.architecture fry kernel layouts
-make math math.order namespaces sequences ;
+make math math.order namespaces sequences sequences.generalizations ;
 IN: compiler.codegen.gc-maps
 
-! GC maps                                                       
+! GC maps
 
 ! Every code block either ends with
 !
@@ -22,23 +22,19 @@ IN: compiler.codegen.gc-maps
 ! uint[] <return addresses>
 ! uint <largest scrubbed data stack location>
 ! uint <largest scrubbed retain stack location>
+! uint <largest checked data stack location>
+! uint <largest checked retain stack location>
 ! uint <largest GC root spill slot>
 ! uint <largest derived root spill slot>
 ! int <number of return addresses>
 
 SYMBOLS: return-addresses gc-maps ;
 
+
 : gc-map-needed? ( gc-map -- ? )
-    ! If there are no stack locations to scrub and no GC roots,
-    ! there's no point storing the GC map.
-    dup [
-        {
-            [ scrub-d>> empty? ]
-            [ scrub-r>> empty? ]
-            [ gc-roots>> empty? ]
-            [ derived-roots>> empty? ]
-        } 1&& not
-    ] when ;
+    ! If there are no stack locations to scrub or check, and no GC
+    ! roots, there's no point storing the GC map.
+    tuple-slots [ empty? ] all? not ;
 
 : gc-map-here ( gc-map -- )
     dup gc-map-needed? [
@@ -71,13 +67,15 @@ SYMBOLS: return-addresses gc-maps ;
 : gc-root-offsets ( gc-map -- offsets )
     gc-roots>> [ gc-root-offset ] map ;
 
-: emit-gc-info-bitmaps ( -- scrub-d-count scrub-r-count gc-root-count )
+: emit-gc-info-bitmaps ( -- scrub-and-check-counts )
     [
         gc-maps get {
             [ [ scrub-d>> ] map emit-scrub ]
             [ [ scrub-r>> ] map emit-scrub ]
+            [ [ check-d>> ] map emit-scrub ]
+            [ [ check-r>> ] map emit-scrub ]
             [ [ gc-root-offsets ] map emit-gc-roots ]
-        } cleave
+        } cleave 5 narray
     ] ?{ } make underlying>> % ;
 
 : emit-base-table ( alist longest -- )
@@ -98,9 +96,9 @@ SYMBOLS: return-addresses gc-maps ;
     [
         return-addresses get empty? [ 0 emit-uint ] [
             emit-gc-info-bitmaps
-            emit-base-tables
+            emit-base-tables suffix
             emit-return-addresses
-            4array emit-uints
+            emit-uints
             return-addresses get length emit-uint
         ] if
     ] B{ } make ;
index 1c64b0ed9b4b83f8a401c985ebea75e0e7e7550a..bda004ff7e20cb1cf111a3453995567ce1ac84fc 100644 (file)
@@ -92,9 +92,13 @@ STRUCT: dispatch-statistics
 { pic-tag-count cell }
 { pic-tuple-count cell } ;
 
+! gc-info should be kept in sync with:
+!   vm/gc_info.hpp
 STRUCT: gc-info
     { scrub-d-count uint read-only }
     { scrub-r-count uint read-only }
+    { check-d-count uint read-only }
+    { check-r-count uint read-only }
     { gc-root-count uint read-only }
     { derived-root-count uint read-only }
     { return-address-count uint read-only } ;
index f2aeb1fb4c849576c8a300f508ffa44b76d03cb3..84ae69ccfe41064838c9c3c61c417a5b8232112f 100644 (file)
@@ -1,14 +1,24 @@
 namespace factor {
 
+// gc_info should be kept in sync with:
+//   core/vm/vm.factor
+
 struct gc_info {
   uint32_t scrub_d_count;
   uint32_t scrub_r_count;
+  uint32_t check_d_count;
+  uint32_t check_r_count;
   uint32_t gc_root_count;
   uint32_t derived_root_count;
   uint32_t return_address_count;
 
   cell callsite_bitmap_size() {
-    return scrub_d_count + scrub_r_count + gc_root_count;
+    return
+        scrub_d_count +
+        scrub_r_count +
+        check_d_count +
+        check_r_count +
+        gc_root_count;
   }
 
   cell total_bitmap_size() {
@@ -32,12 +42,17 @@ struct gc_info {
   cell callsite_scrub_d(cell index) { return index * scrub_d_count; }
 
   cell callsite_scrub_r(cell index) {
-    return return_address_count * scrub_d_count + index * scrub_r_count;
+    cell base = return_address_count * scrub_d_count;
+    return base + index * scrub_r_count;
   }
 
   cell callsite_gc_roots(cell index) {
-    return return_address_count * scrub_d_count +
-           return_address_count * scrub_r_count + index * gc_root_count;
+    cell base =
+        return_address_count * scrub_d_count +
+        return_address_count * scrub_r_count +
+        return_address_count * check_d_count +
+        return_address_count * check_r_count;
+    return base + index * gc_root_count;
   }
 
   uint32_t lookup_base_pointer(cell index, cell derived_root) {