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
parent
46082d836a
commit
8c0f9698de
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 } ;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue