[9] RFR(S) 8065618: C2 RA incorrectly removes kill projections
Vladimir Kozlov
vladimir.kozlov at oracle.com
Sat Nov 22 00:32:47 UTC 2014
http://cr.openjdk.java.net/~kvn/8065618/webrev/
https://bugs.openjdk.java.net/browse/JDK-8065618
Some nodes have SCMemProj projection node to keep them alive even when
their result is not used because they have memory side effects.
For example, EncodeISOArrayNode and loadstore nodes like
CompareAndSwapPNode. Generated code for such nodes may kill some
registers and flags during execution. Killed registers are declared in
'effect' list in mach nodes definitions in .ad files. For each killed
register MachProj node is created without use:
112 encode_iso_array === 103 125 113 114 108 119 120
121 122 [[ 116 117 118 123 124 127 131 134 102 156 ]]
!jvms: ISO_8859_1$Encoder::encode @ bci:32 Test6896617::test @ bci:26
116 MachProj === 112 [[]] #1
117 MachProj === 112 [[]] #2
118 MachProj === 112 [[]] #3
127 SCMemProj === 112 [[ 126 136 138 139 140 150 160
]] Memory: @BotPTR *+bot, idx=Bot; !jvms: ISO_8859_1$Encoder::encode @
bci:32 Test6896617::test @ bci:26
123 MachProj === 112 [[]] #4
124 MachProj === 112 [[]] #5
Register Allocator in PhaseChaitin::build_ifg_physical() removes nodes
which are not used (dead). Nodes with
To keep such nodes alive when their result is not used there method
PhaseChaitin::add_input_to_liveout() puts node's LiveRange on liveout
list when the node has SCMemProj projection.
Unfortunately SCMemProj node could be placed in a block in such order
that kill MachProj nodes are processed first (as in example above). When
those MachProj are processed the def node looks like dead and these
nodes are removed from graph. As result killed register is not marked as
killed anymore and it could be used after code which kills/modifies it.
I was not able to write test with existing VM code. encodeISOArray()
method can't be called directly - it is part of
sun.nio.cs.ISO_8859_1$Encoder::encode() which calls it in a loop. There
is enough code after encodeISOArray() call in encode() method which
prevents using the same register after encode(). I have experimental
project with intrinsics which hits this problem and I verified the fix
with it.
Thanks,
Vladimir
More information about the hotspot-compiler-dev
mailing list