# HG changeset patch # User Christos Kotselidis # Date 1374430272 -7200 # Node ID 761002c5572884f7de097eeec2f833e34b026235 # Parent b05e1ff3aac0760429b0b2faf410f4791a4bed03 Add new node for referent field read barrier (G1 GC) diff -r b05e1ff3aac0 -r 761002c55728 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Sun Jul 21 19:15:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Sun Jul 21 20:11:12 2013 +0200 @@ -233,7 +233,7 @@ int barriers = 0; if (useG1GC()) { - barriers = graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count(); + barriers = graph.getNodes(G1ReferentFieldReadBarrier.class).count() + graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count(); } else { barriers = graph.getNodes(SerialWriteBarrier.class).count(); } @@ -262,7 +262,7 @@ } Assert.assertTrue(useG1GC()); Assert.assertTrue(read.getBarrierType() == BarrierType.PRECISE); - Assert.assertTrue(read.next() instanceof G1PreWriteBarrier); + Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier); } } } diff -r b05e1ff3aac0 -r 761002c55728 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Sun Jul 21 19:15:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Sun Jul 21 20:11:12 2013 +0200 @@ -806,6 +806,8 @@ writeBarrierSnippets.lower((G1PreWriteBarrier) n, tool); } else if (n instanceof G1PostWriteBarrier) { writeBarrierSnippets.lower((G1PostWriteBarrier) n, tool); + } else if (n instanceof G1ReferentFieldReadBarrier) { + writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool); } else if (n instanceof SerialWriteBarrier) { writeBarrierSnippets.lower((SerialWriteBarrier) n, tool); } else if (n instanceof SerialArrayRangeWriteBarrier) { @@ -849,8 +851,7 @@ assert vtableEntryOffset > 0; // We use LocationNode.ANY_LOCATION for the reads that access the vtable // entry as HotSpot does not guarantee that this is a final value. - ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind()), BarrierType.NONE, - false)); + ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind()), BarrierType.NONE, false)); return metaspaceMethod; } diff -r b05e1ff3aac0 -r 761002c55728 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Sun Jul 21 19:15:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Sun Jul 21 20:11:12 2013 +0200 @@ -56,12 +56,12 @@ private static void addReadNodeBarriers(ReadNode node, StructuredGraph graph) { if (node.getBarrierType() == BarrierType.PRECISE) { assert useG1GC(); - G1PreWriteBarrier barrier = graph.add(new G1PreWriteBarrier(node.object(), node, node.location(), false, node.getNullCheck())); + G1ReferentFieldReadBarrier barrier = graph.add(new G1ReferentFieldReadBarrier(node.object(), node, node.location(), false, node.getNullCheck())); barrier.setDeoptimizationState(node.getDeoptimizationState()); node.setNullCheck(false); graph.addAfterFixed(node, barrier); } else { - assert node.getBarrierType() == BarrierType.NONE : "Non precise write barrier has been attached to read node."; + assert node.getBarrierType() == BarrierType.NONE : "Non precise read barrier has been attached to read node."; } } diff -r b05e1ff3aac0 -r 761002c55728 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Sun Jul 21 19:15:40 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Sun Jul 21 20:11:12 2013 +0200 @@ -295,6 +295,8 @@ private final SnippetInfo serialArrayWriteBarrier = snippet(WriteBarrierSnippets.class, "serialArrayWriteBarrier"); private final SnippetInfo serialArrayRangeWriteBarrier = snippet(WriteBarrierSnippets.class, "serialArrayRangeWriteBarrier"); private final SnippetInfo g1PreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier"); + + private final SnippetInfo g1ReferentReadBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier"); private final SnippetInfo g1PostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PostWriteBarrier"); private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier"); private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier"); @@ -330,6 +332,17 @@ template(args).instantiate(runtime, writeBarrierPre, DEFAULT_REPLACER, args); } + public void lower(G1ReferentFieldReadBarrier readBarrier, @SuppressWarnings("unused") LoweringTool tool) { + Arguments args = new Arguments(g1ReferentReadBarrier); + args.add("object", readBarrier.getObject()); + args.add("expectedObject", readBarrier.getExpectedObject()); + args.add("location", readBarrier.getLocation()); + args.addConst("doLoad", readBarrier.doLoad()); + args.addConst("nullCheck", readBarrier.getNullCheck()); + args.addConst("trace", traceBarrier()); + template(args).instantiate(runtime, readBarrier, DEFAULT_REPLACER, args); + } + public void lower(G1PostWriteBarrier writeBarrierPost, @SuppressWarnings("unused") LoweringTool tool) { Arguments args = new Arguments(g1PostWriteBarrier); args.add("object", writeBarrierPost.getObject()); diff -r b05e1ff3aac0 -r 761002c55728 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1ReferentFieldReadBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1ReferentFieldReadBarrier.java Sun Jul 21 20:11:12 2013 +0200 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.extended.*; + +public class G1ReferentFieldReadBarrier extends WriteBarrier implements DeoptimizingNode { + + @Input private ValueNode expectedObject; + private final boolean doLoad; + + @Input private FrameState deoptimizationState; + private final boolean nullCheck; + + public ValueNode getExpectedObject() { + return expectedObject; + } + + public boolean doLoad() { + return doLoad; + } + + public boolean getNullCheck() { + return nullCheck; + } + + public G1ReferentFieldReadBarrier(ValueNode object, ValueNode expectedObject, LocationNode location, boolean doLoad, boolean nullCheck) { + super(object, location, true); + this.doLoad = doLoad; + this.nullCheck = nullCheck; + this.expectedObject = expectedObject; + } + + @Override + public boolean canDeoptimize() { + return nullCheck; + } + + @Override + public FrameState getDeoptimizationState() { + return deoptimizationState; + } + + @Override + public void setDeoptimizationState(FrameState state) { + updateUsages(deoptimizationState, state); + deoptimizationState = state; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return DeoptimizationReason.NullCheckException; + } +}