factor/basis/compiler/cfg/gc-checks/gc-checks-tests.factor

417 lines
7.7 KiB
Factor

USING: arrays byte-arrays compiler.cfg.gc-checks
compiler.cfg.gc-checks.private compiler.cfg.debugger
compiler.cfg.registers compiler.cfg.instructions compiler.cfg
compiler.cfg.predecessors compiler.cfg.rpo cpu.architecture
tools.test kernel vectors namespaces accessors sequences alien
memory classes make combinators.short-circuit
compiler.cfg.comparisons compiler.test compiler.cfg.utilities ;
IN: compiler.cfg.gc-checks.tests
! insert-gc-check?
{ t } [
V{
T{ ##inc } T{ ##allot }
} 0 insns>block insert-gc-check?
] unit-test
! allocation-size
{ t } [
V{ T{ ##box-alien f 0 1 } } allocation-size 123 <alien> size =
] unit-test
! add-gc-checks
{
{
V{
T{ ##inc }
T{ ##peek }
T{ ##alien-invoke }
T{ ##check-nursery-branch
{ size 64 }
{ cc cc<= }
{ temp1 1 }
{ temp2 2 }
}
}
V{
T{ ##allot
{ dst 1 }
{ size 64 }
{ class-of byte-array }
}
T{ ##add }
T{ ##branch }
}
}
} [
{
V{ T{ ##inc } T{ ##peek } T{ ##alien-invoke } }
V{
T{ ##allot
{ dst 1 }
{ size 64 }
{ class-of byte-array }
}
T{ ##add }
T{ ##branch }
}
} [ add-gc-checks ] keep
] cfg-unit-test
! gc-check-offsets
{ { } } [
V{
T{ ##inc }
T{ ##peek }
T{ ##add }
T{ ##branch }
} gc-check-offsets
] unit-test
{ { } } [
V{
T{ ##inc }
T{ ##peek }
T{ ##alien-invoke }
T{ ##add }
T{ ##branch }
} gc-check-offsets
] unit-test
{ { 0 } } [
V{
T{ ##inc }
T{ ##peek }
T{ ##allot }
T{ ##alien-invoke }
T{ ##add }
T{ ##branch }
} gc-check-offsets
] unit-test
{ { 0 } } [
V{
T{ ##inc }
T{ ##peek }
T{ ##allot }
T{ ##allot }
T{ ##add }
T{ ##branch }
} gc-check-offsets
] unit-test
{ { 0 4 } } [
V{
T{ ##inc }
T{ ##peek }
T{ ##allot }
T{ ##alien-invoke }
T{ ##allot }
T{ ##add }
T{ ##sub }
T{ ##branch }
} gc-check-offsets
] unit-test
{ { 3 } } [
V{
T{ ##inc }
T{ ##peek }
T{ ##alien-invoke }
T{ ##allot }
T{ ##add }
T{ ##branch }
} gc-check-offsets
] unit-test
{ { { "a" } } } [ { "a" } { } split-instructions ] unit-test
{ { { } { "a" } } } [ { "a" } { 0 } split-instructions ] unit-test
{ { { "a" } { } } } [ { "a" } { 1 } split-instructions ] unit-test
{ { { "a" } { "b" } } } [ { "a" "b" } { 1 } split-instructions ] unit-test
{ { { } { "a" } { "b" "c" } } } [ { "a" "b" "c" } { 0 1 } split-instructions ] unit-test
: test-gc-checks ( -- )
H{ } clone representations set
0 get block>cfg cfg set ;
V{
T{ ##inc f 3 }
T{ ##replace f 0 D 1 }
} 0 test-bb
V{
T{ ##box-alien f 0 1 }
} 1 test-bb
0 1 edge
{ } [ test-gc-checks ] unit-test
{ t } [ cfg get blocks-with-gc 1 get 1array sequence= ] unit-test
: gc-check? ( bb -- ? )
instructions>>
{
[ length 1 = ]
[ first ##check-nursery-branch? ]
} 1&& ;
: gc-call? ( bb -- ? )
instructions>>
V{
T{ ##call-gc f T{ gc-map } }
T{ ##branch }
} = ;
{ t } [ <gc-call> gc-call? ] unit-test
reset-vreg-counter
V{
T{ ##prologue }
T{ ##branch }
} 0 test-bb
V{
T{ ##peek f 2 D 0 }
T{ ##inc { loc D 3 } }
T{ ##branch }
} 1 test-bb
V{
T{ ##allot f 1 64 byte-array }
T{ ##branch }
} 2 test-bb
V{
T{ ##branch }
} 3 test-bb
V{
T{ ##replace f 2 D 1 }
T{ ##branch }
} 4 test-bb
V{
T{ ##epilogue }
T{ ##return }
} 5 test-bb
0 1 edge
1 { 2 3 } edges
2 4 edge
3 4 edge
4 5 edge
{ } [ test-gc-checks ] unit-test
H{
{ 2 tagged-rep }
} representations set
{ } [ cfg get insert-gc-checks ] unit-test
{ } [ 1 get successors>> first successors>> first 2 set ] unit-test
{ 2 } [ 2 get predecessors>> length ] unit-test
{ t } [ 1 get successors>> first gc-check? ] unit-test
{ 64 } [ 1 get successors>> first instructions>> first size>> ] unit-test
{ t } [ 2 get predecessors>> first gc-check? ] unit-test
{
V{
T{ ##call-gc f T{ gc-map } }
T{ ##branch }
}
} [ 2 get predecessors>> second instructions>> ] unit-test
! Don't forget to invalidate RPO after inserting basic blocks!
{ 8 } [ cfg get reverse-post-order length ] unit-test
! Do the right thing with ##phi instructions
V{
T{ ##branch }
} 0 test-bb
V{
T{ ##load-reference f 1 "hi" }
T{ ##branch }
} 1 test-bb
V{
T{ ##load-reference f 2 "bye" }
T{ ##branch }
} 2 test-bb
V{
T{ ##phi f 3 H{ { 1 1 } { 2 2 } } }
T{ ##allot f 1 64 byte-array }
T{ ##branch }
} 3 test-bb
0 { 1 2 } edges
1 3 edge
2 3 edge
{ } [ test-gc-checks ] unit-test
H{
{ 1 tagged-rep }
{ 2 tagged-rep }
{ 3 tagged-rep }
} representations set
{ } [ cfg get insert-gc-checks ] unit-test
{ } [ 1 get successors>> first successors>> first 3 set ] unit-test
{ t } [ 2 get successors>> first instructions>> first ##phi? ] unit-test
{ 2 } [ 3 get instructions>> length ] unit-test
! GC check in a block that is its own successor
V{
T{ ##prologue }
T{ ##branch }
} 0 test-bb
V{
T{ ##allot f 1 64 byte-array }
T{ ##branch }
} 1 test-bb
V{
T{ ##epilogue }
T{ ##return }
} 2 test-bb
0 1 edge
1 { 1 2 } edges
{ } [ test-gc-checks ] unit-test
{ } [ cfg get insert-gc-checks ] unit-test
{ } [
0 get successors>> first predecessors>>
[ first 0 get assert= ]
[ second 1 get [ instructions>> ] bi@ assert= ] bi
] unit-test
{ } [
0 get successors>> first successors>>
[ first 1 get [ instructions>> ] bi@ assert= ]
[ second gc-call? t assert= ] bi
] unit-test
{ } [
2 get predecessors>> first predecessors>>
[ first gc-check? t assert= ]
[ second gc-call? t assert= ] bi
] unit-test
! Brave new world of calls in the middle of BBs
! call then allot
V{
T{ ##prologue }
T{ ##branch }
} 0 test-bb
V{
T{ ##alien-invoke f "malloc" f f f f f T{ gc-map } }
T{ ##allot f 1 64 byte-array }
T{ ##branch }
} 1 test-bb
V{
T{ ##epilogue }
T{ ##return }
} 2 test-bb
0 1 edge
1 2 edge
2 vreg-counter set-global
{ } [ test-gc-checks ] unit-test
{ } [ cfg get insert-gc-checks ] unit-test
! The GC check should come after the alien-invoke
{
V{
T{ ##alien-invoke f "malloc" f f f f f T{ gc-map } }
T{ ##check-nursery-branch f 64 cc<= 3 4 }
}
} [ 0 get successors>> first instructions>> ] unit-test
! call then allot then call then allot
V{
T{ ##prologue }
T{ ##branch }
} 0 test-bb
V{
T{ ##alien-invoke f "malloc" f f f f f T{ gc-map } }
T{ ##allot f 1 64 byte-array }
T{ ##alien-invoke f "malloc" f f f f f T{ gc-map } }
T{ ##allot f 2 64 byte-array }
T{ ##branch }
} 1 test-bb
V{
T{ ##epilogue }
T{ ##return }
} 2 test-bb
0 1 edge
1 2 edge
2 vreg-counter set-global
{ } [ test-gc-checks ] unit-test
{ } [ cfg get insert-gc-checks ] unit-test
{
V{
T{ ##alien-invoke f "malloc" f f f f f T{ gc-map } }
T{ ##check-nursery-branch f 64 cc<= 3 4 }
}
} [
0 get
successors>> first
instructions>>
] unit-test
{
V{
T{ ##allot f 1 64 byte-array }
T{ ##alien-invoke f "malloc" f f f f f T{ gc-map } }
T{ ##check-nursery-branch f 64 cc<= 5 6 }
}
} [
0 get
successors>> first
successors>> first
instructions>>
] unit-test
{
V{
T{ ##allot f 2 64 byte-array }
T{ ##branch }
}
} [
0 get
successors>> first
successors>> first
successors>> first
instructions>>
] unit-test