compiler.cfg: fix major facepalm with write barrier elimination
parent
3323284db4
commit
c677c35de4
|
@ -2,15 +2,16 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel compiler.cfg.representations
|
USING: kernel compiler.cfg.representations
|
||||||
compiler.cfg.scheduling compiler.cfg.gc-checks
|
compiler.cfg.scheduling compiler.cfg.gc-checks
|
||||||
compiler.cfg.save-contexts compiler.cfg.ssa.destruction
|
compiler.cfg.write-barrier compiler.cfg.save-contexts
|
||||||
compiler.cfg.build-stack-frame compiler.cfg.linear-scan
|
compiler.cfg.ssa.destruction compiler.cfg.build-stack-frame
|
||||||
compiler.cfg.stacks.uninitialized ;
|
compiler.cfg.linear-scan compiler.cfg.stacks.uninitialized ;
|
||||||
IN: compiler.cfg.finalization
|
IN: compiler.cfg.finalization
|
||||||
|
|
||||||
: finalize-cfg ( cfg -- cfg' )
|
: finalize-cfg ( cfg -- cfg' )
|
||||||
select-representations
|
select-representations
|
||||||
schedule-instructions
|
schedule-instructions
|
||||||
insert-gc-checks
|
insert-gc-checks
|
||||||
|
eliminate-write-barriers
|
||||||
dup compute-uninitialized-sets
|
dup compute-uninitialized-sets
|
||||||
insert-save-contexts
|
insert-save-contexts
|
||||||
destruct-ssa
|
destruct-ssa
|
||||||
|
|
|
@ -9,8 +9,7 @@ compiler.cfg.ssa.construction
|
||||||
compiler.cfg.alias-analysis
|
compiler.cfg.alias-analysis
|
||||||
compiler.cfg.value-numbering
|
compiler.cfg.value-numbering
|
||||||
compiler.cfg.copy-prop
|
compiler.cfg.copy-prop
|
||||||
compiler.cfg.dce
|
compiler.cfg.dce ;
|
||||||
compiler.cfg.write-barrier ;
|
|
||||||
IN: compiler.cfg.optimizer
|
IN: compiler.cfg.optimizer
|
||||||
|
|
||||||
: optimize-cfg ( cfg -- cfg' )
|
: optimize-cfg ( cfg -- cfg' )
|
||||||
|
@ -23,5 +22,4 @@ IN: compiler.cfg.optimizer
|
||||||
alias-analysis
|
alias-analysis
|
||||||
value-numbering
|
value-numbering
|
||||||
copy-propagation
|
copy-propagation
|
||||||
eliminate-dead-code
|
eliminate-dead-code ;
|
||||||
eliminate-write-barriers ;
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
USING: compiler.cfg.instructions compiler.cfg.write-barrier
|
||||||
|
tools.test ;
|
||||||
|
IN: compiler.cfg.write-barrier.tests
|
||||||
|
|
||||||
|
! Do need a write barrier on a random store.
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##peek f 1 }
|
||||||
|
T{ ##set-slot f 2 1 3 }
|
||||||
|
T{ ##write-barrier f 1 3 }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##peek f 1 }
|
||||||
|
T{ ##set-slot f 2 1 3 }
|
||||||
|
T{ ##write-barrier f 1 3 }
|
||||||
|
} write-barriers-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##peek f 1 }
|
||||||
|
T{ ##set-slot-imm f 2 1 }
|
||||||
|
T{ ##write-barrier-imm f 1 }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##peek f 1 }
|
||||||
|
T{ ##set-slot-imm f 2 1 }
|
||||||
|
T{ ##write-barrier-imm f 1 }
|
||||||
|
} write-barriers-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! Don't need a write barrier on freshly allocated objects.
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##allot f 1 }
|
||||||
|
T{ ##set-slot f 2 1 3 }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##allot f 1 }
|
||||||
|
T{ ##set-slot f 2 1 3 }
|
||||||
|
T{ ##write-barrier f 1 3 }
|
||||||
|
} write-barriers-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##allot f 1 }
|
||||||
|
T{ ##set-slot-imm f 2 1 }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##allot f 1 }
|
||||||
|
T{ ##set-slot-imm f 2 1 }
|
||||||
|
T{ ##write-barrier-imm f 1 }
|
||||||
|
} write-barriers-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! Do need a write barrier if there's a subroutine call between
|
||||||
|
! the allocation and the store.
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##allot f 1 }
|
||||||
|
T{ ##box }
|
||||||
|
T{ ##set-slot f 2 1 3 }
|
||||||
|
T{ ##write-barrier f 1 3 }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##allot f 1 }
|
||||||
|
T{ ##box }
|
||||||
|
T{ ##set-slot f 2 1 3 }
|
||||||
|
T{ ##write-barrier f 1 3 }
|
||||||
|
} write-barriers-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##allot f 1 }
|
||||||
|
T{ ##box }
|
||||||
|
T{ ##set-slot-imm f 2 1 }
|
||||||
|
T{ ##write-barrier-imm f 1 }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##allot f 1 }
|
||||||
|
T{ ##box }
|
||||||
|
T{ ##set-slot-imm f 2 1 }
|
||||||
|
T{ ##write-barrier-imm f 1 }
|
||||||
|
} write-barriers-step
|
||||||
|
] unit-test
|
|
@ -6,6 +6,8 @@ sequences sets ;
|
||||||
FROM: namespaces => set ;
|
FROM: namespaces => set ;
|
||||||
IN: compiler.cfg.write-barrier
|
IN: compiler.cfg.write-barrier
|
||||||
|
|
||||||
|
! This pass must run after GC check insertion and scheduling.
|
||||||
|
|
||||||
SYMBOL: fresh-allocations
|
SYMBOL: fresh-allocations
|
||||||
|
|
||||||
SYMBOL: mutated-objects
|
SYMBOL: mutated-objects
|
||||||
|
@ -22,7 +24,10 @@ M: ##set-slot-imm eliminate-write-barrier
|
||||||
obj>> mutated-objects get conjoin t ;
|
obj>> mutated-objects get conjoin t ;
|
||||||
|
|
||||||
: needs-write-barrier? ( insn -- ? )
|
: needs-write-barrier? ( insn -- ? )
|
||||||
{ [ fresh-allocations get key? not ] [ mutated-objects get key? ] } 1&& ;
|
{
|
||||||
|
[ fresh-allocations get key? not ]
|
||||||
|
[ mutated-objects get key? ]
|
||||||
|
} 1&& ;
|
||||||
|
|
||||||
M: ##write-barrier eliminate-write-barrier
|
M: ##write-barrier eliminate-write-barrier
|
||||||
src>> needs-write-barrier? ;
|
src>> needs-write-barrier? ;
|
||||||
|
@ -30,6 +35,9 @@ M: ##write-barrier eliminate-write-barrier
|
||||||
M: ##write-barrier-imm eliminate-write-barrier
|
M: ##write-barrier-imm eliminate-write-barrier
|
||||||
src>> needs-write-barrier? ;
|
src>> needs-write-barrier? ;
|
||||||
|
|
||||||
|
M: gc-map-insn eliminate-write-barrier
|
||||||
|
fresh-allocations get clear-assoc ;
|
||||||
|
|
||||||
M: ##copy eliminate-write-barrier
|
M: ##copy eliminate-write-barrier
|
||||||
"Run copy propagation first" throw ;
|
"Run copy propagation first" throw ;
|
||||||
|
|
||||||
|
|
|
@ -823,3 +823,25 @@ TUPLE: some-tuple x ;
|
||||||
aa-indirect-1 >>x
|
aa-indirect-1 >>x
|
||||||
] compile-call
|
] compile-call
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
! Write barrier elimination was being done before scheduling and
|
||||||
|
! GC check insertion, and didn't take subroutine calls into
|
||||||
|
! account. Oops...
|
||||||
|
: write-barrier-elim-in-wrong-place ( -- obj )
|
||||||
|
! A callback used below
|
||||||
|
void { } cdecl [ compact-gc ] alien-callback
|
||||||
|
! Allocate an object A in the nursery
|
||||||
|
1 f <array>
|
||||||
|
! Subroutine call promotes the object to tenured
|
||||||
|
swap void { } cdecl alien-indirect
|
||||||
|
! Allocate another object B in the nursery, store it into
|
||||||
|
! the first
|
||||||
|
1 f <array> over set-first
|
||||||
|
! Now object A's card should be marked and minor GC should
|
||||||
|
! promote B to aging
|
||||||
|
minor-gc
|
||||||
|
! Do stuff
|
||||||
|
[ 100 [ ] times ] infer.
|
||||||
|
;
|
||||||
|
|
||||||
|
[ { { f } } ] [ write-barrier-elim-in-wrong-place ] unit-test
|
||||||
|
|
Loading…
Reference in New Issue