2010-04-27 10:51:00 -04:00
|
|
|
! Copyright (C) 2009, 2010 Slava Pestov.
|
2009-05-31 13:20:46 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2010-04-27 10:51:00 -04:00
|
|
|
USING: accessors assocs combinators fry kernel layouts locals
|
|
|
|
math make namespaces sequences cpu.architecture
|
|
|
|
compiler.cfg
|
2009-07-30 10:19:44 -04:00
|
|
|
compiler.cfg.rpo
|
2010-04-27 10:51:00 -04:00
|
|
|
compiler.cfg.hats
|
2009-07-30 10:19:44 -04:00
|
|
|
compiler.cfg.registers
|
2010-04-27 10:51:00 -04:00
|
|
|
compiler.cfg.utilities
|
|
|
|
compiler.cfg.comparisons
|
2009-07-30 10:19:44 -04:00
|
|
|
compiler.cfg.instructions
|
2010-04-27 10:51:00 -04:00
|
|
|
compiler.cfg.predecessors
|
|
|
|
compiler.cfg.liveness
|
|
|
|
compiler.cfg.liveness.ssa
|
2009-07-30 10:19:44 -04:00
|
|
|
compiler.cfg.stacks.uninitialized ;
|
2009-05-31 13:20:46 -04:00
|
|
|
IN: compiler.cfg.gc-checks
|
|
|
|
|
2010-04-27 10:51:00 -04:00
|
|
|
<PRIVATE
|
|
|
|
|
|
|
|
! Garbage collection check insertion. This pass runs after
|
|
|
|
! representation selection, since it needs to know which vregs
|
|
|
|
! can contain tagged pointers.
|
2009-08-08 05:02:18 -04:00
|
|
|
|
2009-07-30 10:19:44 -04:00
|
|
|
: insert-gc-check? ( bb -- ? )
|
2009-05-31 13:20:46 -04:00
|
|
|
instructions>> [ ##allocation? ] any? ;
|
|
|
|
|
2009-07-30 10:19:44 -04:00
|
|
|
: blocks-with-gc ( cfg -- bbs )
|
|
|
|
post-order [ insert-gc-check? ] filter ;
|
|
|
|
|
2010-04-27 10:51:00 -04:00
|
|
|
! A GC check for bb consists of two new basic blocks, gc-check
|
|
|
|
! and gc-call:
|
|
|
|
!
|
|
|
|
! gc-check
|
|
|
|
! / \
|
|
|
|
! | gc-call
|
|
|
|
! \ /
|
|
|
|
! bb
|
|
|
|
|
2010-04-28 02:53:01 -04:00
|
|
|
! Any ##phi instructions at the start of bb are transplanted
|
|
|
|
! into the gc-check block.
|
|
|
|
|
|
|
|
: <gc-check> ( phis size -- bb )
|
|
|
|
[ <basic-block> ] 2dip
|
2010-04-27 10:51:00 -04:00
|
|
|
[
|
2010-04-28 02:53:01 -04:00
|
|
|
[ % ]
|
|
|
|
[
|
|
|
|
cc<= int-rep next-vreg-rep int-rep next-vreg-rep
|
|
|
|
##check-nursery-branch
|
|
|
|
] bi*
|
2010-04-27 10:51:00 -04:00
|
|
|
] V{ } make >>instructions ;
|
|
|
|
|
|
|
|
: wipe-locs ( uninitialized-locs -- )
|
|
|
|
'[
|
|
|
|
int-rep next-vreg-rep
|
|
|
|
[ 0 ##load-tagged ]
|
|
|
|
[ '[ [ _ ] dip ##replace ] each ] bi
|
|
|
|
] unless-empty ;
|
|
|
|
|
|
|
|
: <gc-call> ( uninitialized-locs gc-roots -- bb )
|
|
|
|
[ <basic-block> ] 2dip
|
|
|
|
[ [ wipe-locs ] [ ##call-gc ] bi* ##branch ] V{ } make
|
|
|
|
>>instructions t >>unlikely? ;
|
|
|
|
|
2010-04-28 02:53:01 -04:00
|
|
|
:: insert-guard ( body check bb -- )
|
2010-05-05 16:52:54 -04:00
|
|
|
bb predecessors>> check predecessors<<
|
|
|
|
V{ bb body } check successors<<
|
2010-04-27 10:51:00 -04:00
|
|
|
|
2010-05-05 16:52:54 -04:00
|
|
|
V{ check } body predecessors<<
|
|
|
|
V{ bb } body successors<<
|
2010-04-27 10:51:00 -04:00
|
|
|
|
2010-05-05 16:52:54 -04:00
|
|
|
V{ check body } bb predecessors<<
|
2010-04-27 10:51:00 -04:00
|
|
|
|
|
|
|
check predecessors>> [ bb check update-successors ] each ;
|
|
|
|
|
2010-04-28 02:53:01 -04:00
|
|
|
: (insert-gc-check) ( uninitialized-locs gc-roots phis size bb -- )
|
|
|
|
[ [ <gc-call> ] 2dip <gc-check> ] dip insert-guard ;
|
2010-04-27 10:51:00 -04:00
|
|
|
|
2009-10-05 06:27:49 -04:00
|
|
|
GENERIC: allocation-size* ( insn -- n )
|
|
|
|
|
|
|
|
M: ##allot allocation-size* size>> ;
|
|
|
|
|
2009-11-02 04:25:39 -05:00
|
|
|
M: ##box-alien allocation-size* drop 5 cells ;
|
2009-10-05 06:27:49 -04:00
|
|
|
|
2009-11-02 04:25:39 -05:00
|
|
|
M: ##box-displaced-alien allocation-size* drop 5 cells ;
|
2009-10-05 06:27:49 -04:00
|
|
|
|
|
|
|
: allocation-size ( bb -- n )
|
2009-11-02 04:25:39 -05:00
|
|
|
instructions>>
|
|
|
|
[ ##allocation? ] filter
|
2009-11-02 18:41:36 -05:00
|
|
|
[ allocation-size* data-alignment get align ] map-sum ;
|
2009-10-05 06:27:49 -04:00
|
|
|
|
2010-04-28 02:53:01 -04:00
|
|
|
: gc-live-in ( bb -- vregs )
|
|
|
|
[ live-in keys ] [ instructions>> [ ##phi? ] filter [ dst>> ] map ] bi
|
|
|
|
append ;
|
|
|
|
|
2010-04-27 10:51:00 -04:00
|
|
|
: live-tagged ( bb -- vregs )
|
2010-04-28 02:53:01 -04:00
|
|
|
gc-live-in [ rep-of tagged-rep? ] filter ;
|
|
|
|
|
|
|
|
: remove-phis ( bb -- phis )
|
|
|
|
[ [ ##phi? ] partition ] change-instructions drop ;
|
2010-04-27 10:51:00 -04:00
|
|
|
|
2009-07-30 10:19:44 -04:00
|
|
|
: insert-gc-check ( bb -- )
|
2010-04-27 10:51:00 -04:00
|
|
|
{
|
|
|
|
[ uninitialized-locs ]
|
|
|
|
[ live-tagged ]
|
2010-04-28 02:53:01 -04:00
|
|
|
[ remove-phis ]
|
|
|
|
[ allocation-size ]
|
2010-04-27 10:51:00 -04:00
|
|
|
[ ]
|
|
|
|
} cleave
|
|
|
|
(insert-gc-check) ;
|
|
|
|
|
|
|
|
PRIVATE>
|
2009-05-31 13:20:46 -04:00
|
|
|
|
|
|
|
: insert-gc-checks ( cfg -- cfg' )
|
2009-07-30 10:19:44 -04:00
|
|
|
dup blocks-with-gc [
|
2010-04-27 10:51:00 -04:00
|
|
|
[
|
|
|
|
needs-predecessors
|
|
|
|
dup compute-ssa-live-sets
|
|
|
|
dup compute-uninitialized-sets
|
|
|
|
] dip
|
2009-07-30 10:19:44 -04:00
|
|
|
[ insert-gc-check ] each
|
2010-04-27 10:51:00 -04:00
|
|
|
cfg-changed
|
2009-10-29 15:34:04 -04:00
|
|
|
] unless-empty ;
|