]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/stacks/uninitialized/uninitialized.factor
GC maps for more compact inline GC checks
[factor.git] / basis / compiler / cfg / stacks / uninitialized / uninitialized.factor
1 ! Copyright (C) 2009, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel sequences byte-arrays namespaces accessors classes math
4 math.order fry arrays combinators compiler.cfg.registers
5 compiler.cfg.instructions compiler.cfg.dataflow-analysis ;
6 IN: compiler.cfg.stacks.uninitialized
7
8 ! Uninitialized stack location analysis.
9
10 ! Consider the following sequence of instructions:
11 ! ##inc-d 2
12 ! ##gc
13 ! ##replace ... D 0
14 ! ##replace ... D 1
15 ! The GC check runs before stack locations 0 and 1 have been initialized,
16 ! and it needs to zero them out so that GC doesn't try to trace them.
17
18 <PRIVATE
19
20 GENERIC: visit-insn ( insn -- )
21
22 : handle-inc ( n symbol -- )
23     [
24         swap {
25             { [ dup 0 < ] [ neg short tail ] }
26             { [ dup 0 > ] [ <byte-array> prepend ] }
27         } cond
28     ] change ;
29
30 M: ##inc-d visit-insn n>> ds-loc handle-inc ;
31
32 M: ##inc-r visit-insn n>> rs-loc handle-inc ;
33
34 ERROR: uninitialized-peek insn ;
35
36 : visit-peek ( ##peek -- )
37     dup loc>> [ n>> ] [ class get ] bi ?nth 0 =
38     [ uninitialized-peek ] [ drop ] if ; inline
39
40 M: ##peek visit-insn visit-peek ;
41
42 : visit-replace ( ##replace -- )
43     loc>> [ n>> ] [ class get ] bi
44     2dup length < [ [ 1 ] 2dip set-nth ] [ 2drop ] if ;
45
46 M: ##replace visit-insn visit-replace ;
47 M: ##replace-imm visit-insn visit-replace ;
48
49 M: insn visit-insn drop ;
50
51 : prepare ( pair -- )
52     [ first2 [ [ clone ] [ B{ } ] if* ] bi@ ] [ B{ } B{ } ] if*
53     [ ds-loc set ] [ rs-loc set ] bi* ;
54
55 : visit-block ( bb -- ) instructions>> [ visit-insn ] each ;
56
57 : finish ( -- pair ) ds-loc get rs-loc get 2array ;
58
59 : (join-sets) ( seq1 seq2 -- seq )
60     2dup [ length ] bi@ max '[ _ 1 pad-tail ] bi@ [ bitand ] 2map ;
61
62 : (uninitialized-locs) ( seq quot -- seq' )
63     [ [ drop 0 = ] selector [ each-index ] dip ] dip map ; inline
64
65 PRIVATE>
66
67 FORWARD-ANALYSIS: uninitialized
68
69 M: uninitialized-analysis transfer-set ( pair bb analysis -- pair' )
70     drop [ prepare ] dip visit-block finish ;
71
72 M: uninitialized-analysis join-sets ( sets analysis -- pair )
73     2drop sift [ f ] [ [ ] [ [ (join-sets) ] 2map ] map-reduce ] if-empty ;
74
75 : uninitialized-locs ( bb -- locs )
76     uninitialized-in dup [
77         first2
78         [ [ <ds-loc> ] (uninitialized-locs) ]
79         [ [ <rs-loc> ] (uninitialized-locs) ]
80         bi* append f like
81     ] when ;