compiler.codegen.gc-maps: check-d>> and check-r>> now used in the code generator

the approach looks sound and now the gc can be fixed to take advantage
of the extra info.
db4
Björn Lindqvist 2014-08-26 04:44:03 +02:00 committed by Doug Coleman
parent 46082d836a
commit 8c0f9698de
4 changed files with 179 additions and 73 deletions

View 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 } }
}
} gc-maps set
{ 123 } return-addresses set
serialize-gc-maps length
] unit-test
! 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-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
] unit-test
[ ] [ "result" get length "expect" get length assert= ] unit-test
[ ] [ "result" get "expect" get assert= ] unit-test

View 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 ;

View 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 } ;

View 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) {