compiler.codegen.gc-maps: simplies largest-spill-slot and refactors serialize-gc-maps

db4
Björn Lindqvist 2015-06-14 04:15:38 +02:00
parent ca2d64af68
commit 9dbb3e9171
3 changed files with 65 additions and 48 deletions

View File

@ -1,32 +1,13 @@
USING: bit-arrays byte-arrays compiler.cfg.instructions help.markup help.syntax USING: bit-arrays byte-arrays compiler.cfg compiler.cfg.instructions
kernel math ; compiler.cfg.stack-frame help.markup help.syntax kernel math sequences ;
IN: compiler.codegen.gc-maps IN: compiler.codegen.gc-maps
ARTICLE: "compiler.codegen.gc-maps" "GC maps"
"The " { $vocab-link "compiler.codegen.gc-maps" } " handles generating code for keeping track of garbage collection maps. Every code block either ends with:"
{ $list "uint 0" }
"or"
{ $list
{
"bitmap, byte aligned, five subsequences:"
{ $list
"scrubbed data stack locations"
"scrubbed retain stack locations"
"GC root spill slots"
}
}
"uint[] base pointers"
"uint[] return addresses"
"uint largest scrubbed data stack location"
"uint largest scrubbed retain stack location"
"uint largest GC root spill slot"
"uint largest derived root spill slot"
"int number of return addresses"
} ;
HELP: emit-gc-info-bitmaps HELP: emit-gc-info-bitmaps
{ $values { "counts" "counts of the three different types of gc checks" } } { $values
{ $description "Emits the scrub location data in all gc-maps registered in the " { $link gc-maps } " variable to the make sequence being created. The result is a concatenation of all datastack scrub locations, retainstack scrub locations and gc root locations converted into a byte-array. Given that byte-array and knowledge of the number of scrub locations, the original gc-map can be reconstructed." } ; { "gc-maps" sequence }
{ "counts" "counts of the three different types of gc checks" }
}
{ $description "Emits the scrub location data in the 'gc-maps' to the make sequence being created. The result is a concatenation of all datastack scrub locations, retainstack scrub locations and gc root locations converted into a byte-array. Given that byte-array and knowledge of the number of scrub locations, the original gc-map can be reconstructed." } ;
HELP: emit-scrub HELP: emit-scrub
{ $values { $values
@ -55,13 +36,20 @@ HELP: emit-uint
} }
} ; } ;
HELP: emit-gc-maps
{ $description "GC maps are emitted so that the end is aligned to a 16-byte boundary." } ;
HELP: gc-maps HELP: gc-maps
{ $var-description "Variable that holds a sequence of " { $link gc-map } " tuples." } ; { $var-description "Variable that holds a sequence of " { $link gc-map } " tuples. Gc maps are added to the sequence by " { $link gc-map-here } "." } ;
HELP: gc-map-needed? HELP: gc-map-needed?
{ $values { "gc-map/f" { $maybe gc-map } } { "?" boolean } } { $values { "gc-map/f" { $maybe gc-map } } { "?" boolean } }
{ $description "If all slots in the gc-map are empty, then it doesn't need to be emitted." } ; { $description "If all slots in the gc-map are empty, then it doesn't need to be emitted." } ;
HELP: gc-root-offsets
{ $values { "gc-map" gc-map } { "offsets" sequence } }
{ $description "Gets the offets of all roots in a gc-map. The " { $link stack-frame } " variable must have been setup first." } ;
HELP: serialize-gc-maps HELP: serialize-gc-maps
{ $values { "byte-array" byte-array } } { $values { "byte-array" byte-array } }
{ $description "Serializes the gc-maps that have been registered in the " { $link gc-maps } " variable into a byte-array." } ; { $description "Serializes the gc-maps that have been registered in the " { $link gc-maps } " variable into a byte-array." } ;
@ -70,4 +58,30 @@ HELP: gc-map-here
{ $values { "gc-map" gc-map } } { $values { "gc-map" gc-map } }
{ $description "Registers the gc map in the " { $link gc-maps } " dynamic variable at the current compiled offset." } ; { $description "Registers the gc map in the " { $link gc-maps } " dynamic variable at the current compiled offset." } ;
ARTICLE: "compiler.codegen.gc-maps" "GC maps"
"The " { $vocab-link "compiler.codegen.gc-maps" } " handles generating code for keeping track of garbage collection maps. Every code block either ends with:"
{ $list "uint 0" }
"or"
{ $list
{
"bitmap, byte aligned, five subsequences:"
{ $list
"scrubbed data stack locations"
"scrubbed retain stack locations"
"GC root spill slots"
}
}
"uint[] base pointers"
"uint[] return addresses"
"uint largest scrubbed data stack location"
"uint largest scrubbed retain stack location"
"uint largest GC root spill slot"
"uint largest derived root spill slot"
"int number of return addresses"
}
"The " { $link gc-map } " tuples of the " { $link cfg } " are serialized to the above format and placed directly after the generated code."
$nl
"Main entry point:"
{ $subsections emit-gc-maps } ;
ABOUT: "compiler.codegen.gc-maps" ABOUT: "compiler.codegen.gc-maps"

View File

@ -112,7 +112,7 @@ cpu x86.64? [
T{ spill-slot { n 0 } } T{ spill-slot { n 0 } }
T{ spill-slot { n 24 } } T{ spill-slot { n 24 } }
} } } }
} 1array gc-maps set } 1array
[ emit-gc-info-bitmaps ] B{ } make drop [ emit-gc-info-bitmaps ] B{ } make drop
] with-variable ] with-variable
] unit-test ] unit-test
@ -125,7 +125,7 @@ cpu x86.64? [
T{ spill-slot { n 0 } } T{ spill-slot { n 0 } }
T{ spill-slot { n 24 } } T{ spill-slot { n 24 } }
} } } }
} 1array gc-maps set } 1array
[ emit-gc-info-bitmaps ] B{ } make drop [ emit-gc-info-bitmaps ] B{ } make drop
] with-variable ] with-variable
] unit-test ] unit-test
@ -133,6 +133,16 @@ cpu x86.64? [
fake-cpu \ cpu set fake-cpu \ cpu set
] when ] when
! largest-spill-slot
{
5 0 4 1
} [
{ { 4 } } largest-spill-slot
{ { } } largest-spill-slot
{ { 2 3 } { 0 } } largest-spill-slot
{ { 0 } } largest-spill-slot
] unit-test
! gc-map-needed? ! gc-map-needed?
{ t t } [ { t t } [
T{ gc-map { scrub-d { 0 1 1 1 0 } } { scrub-r { 1 0 } } } gc-map-needed? T{ gc-map { scrub-d { 0 1 1 1 0 } } { scrub-r { 1 0 } } } gc-map-needed?
@ -149,7 +159,7 @@ cpu x86.64? [
{ 4 2 0 } { 4 2 0 }
V{ 1 } V{ 1 }
} [ } [
{ T{ gc-map { scrub-d { 0 1 1 1 } } { scrub-r { 1 1 } } } } gc-maps set { T{ gc-map { scrub-d { 0 1 1 1 } } { scrub-r { 1 1 } } } }
[ emit-gc-info-bitmaps ] V{ } make [ emit-gc-info-bitmaps ] V{ } make
] unit-test ] unit-test
@ -157,7 +167,7 @@ cpu x86.64? [
{ 1 0 0 } { 1 0 0 }
V{ 1 } V{ 1 }
} [ } [
{ T{ gc-map { scrub-d { 0 } } } } gc-maps set { T{ gc-map { scrub-d { 0 } } } }
[ emit-gc-info-bitmaps ] V{ } make [ emit-gc-info-bitmaps ] V{ } make
] unit-test ] unit-test
@ -174,7 +184,7 @@ USING: present prettyprint ;
{ {
3 B{ 255 255 255 255 255 255 255 255 4 0 0 0 } 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 { T{ gc-map { derived-roots V{ { 2 4 } } } } }
[ emit-base-tables ] B{ } make [ emit-base-tables ] B{ } make
] unit-test ] unit-test

View File

@ -25,7 +25,7 @@ SYMBOLS: return-addresses gc-maps ;
<bit-array> [ '[ [ t ] dip _ set-nth ] each ] keep ; <bit-array> [ '[ [ t ] dip _ set-nth ] each ] keep ;
: largest-spill-slot ( seqs -- n ) : largest-spill-slot ( seqs -- n )
[ [ 0 ] [ supremum 1 + ] if-empty ] [ max ] map-reduce ; concat [ 0 ] [ supremum 1 + ] if-empty ;
: emit-gc-roots ( seqs -- n ) : emit-gc-roots ( seqs -- n )
! seqs is a sequence of sequences of integers 0..n-1 ! seqs is a sequence of sequences of integers 0..n-1
@ -40,9 +40,8 @@ SYMBOLS: return-addresses gc-maps ;
: gc-root-offsets ( gc-map -- offsets ) : gc-root-offsets ( gc-map -- offsets )
gc-roots>> [ gc-root-offset ] map ; gc-roots>> [ gc-root-offset ] map ;
: emit-gc-info-bitmaps ( -- counts ) : emit-gc-info-bitmaps ( gc-maps -- counts )
[ [
gc-maps get
[ [ scrub-d>> ] map emit-scrub ] [ [ scrub-d>> ] map emit-scrub ]
[ [ scrub-r>> ] map emit-scrub ] [ [ scrub-r>> ] map emit-scrub ]
[ [ gc-root-offsets ] map emit-gc-roots ] tri 3array [ [ gc-root-offsets ] map emit-gc-roots ] tri 3array
@ -54,23 +53,19 @@ SYMBOLS: return-addresses gc-maps ;
: derived-root-offsets ( gc-map -- offsets ) : derived-root-offsets ( gc-map -- offsets )
derived-roots>> [ [ gc-root-offset ] bi@ ] assoc-map ; derived-roots>> [ [ gc-root-offset ] bi@ ] assoc-map ;
: emit-base-tables ( -- count ) : emit-base-tables ( gc-maps -- count )
gc-maps get [ derived-root-offsets ] map [ derived-root-offsets ] map
dup [ keys ] map largest-spill-slot dup [ keys ] map largest-spill-slot
[ '[ _ emit-base-table ] each ] keep ; [ '[ _ emit-base-table ] each ] keep ;
: emit-return-addresses ( -- )
return-addresses get emit-uints ;
: serialize-gc-maps ( -- byte-array ) : serialize-gc-maps ( -- byte-array )
[ [
return-addresses get empty? [ 0 emit-uint ] [ return-addresses get empty? [ { } ] [
emit-gc-info-bitmaps gc-maps get [ emit-gc-info-bitmaps ] [ emit-base-tables ] bi suffix
emit-base-tables suffix
emit-return-addresses
emit-uints
return-addresses get length emit-uint
] if ] if
return-addresses get emit-uints
emit-uints
return-addresses get length emit-uint
] B{ } make ; ] B{ } make ;
: init-gc-maps ( -- ) : init-gc-maps ( -- )
@ -78,8 +73,6 @@ SYMBOLS: return-addresses gc-maps ;
V{ } clone gc-maps set ; V{ } clone gc-maps set ;
: emit-gc-maps ( -- ) : emit-gc-maps ( -- )
! We want to place the GC maps so that the end is aligned
! on a 16-byte boundary.
serialize-gc-maps [ serialize-gc-maps [
length compiled-offset + length compiled-offset +
[ data-alignment get align ] keep - [ data-alignment get align ] keep -