Skip to content

Commit 1ee4790

Browse files
author
Roman Kennke
committed
Implement load-reference barriers for Shenandoah
1 parent 87ba200 commit 1ee4790

File tree

8 files changed

+155
-24
lines changed

8 files changed

+155
-24
lines changed

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java

+4
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ private static String markWordField(String simpleName) {
636636
public final int shenandoahSATBQueueMarkingOffset;
637637
public final int shenandoahSATBQueueIndexOffset;
638638
public final int shenandoahSATBQueueBufferOffset;
639+
public final int shenandoahGCStateOffset;
639640
{
640641
if (JDK <= 8) {
641642
int satbMarkQueueBufferOffset = getFieldOffset("PtrQueue::_buf", Integer.class, "void**");
@@ -646,10 +647,12 @@ private static String markWordField(String simpleName) {
646647
shenandoahSATBQueueMarkingOffset = javaThreadSatbMarkQueueOffset + satbMarkQueueActiveOffset;
647648
shenandoahSATBQueueIndexOffset = javaThreadSatbMarkQueueOffset + satbMarkQueueIndexOffset;
648649
shenandoahSATBQueueBufferOffset = javaThreadSatbMarkQueueOffset + satbMarkQueueBufferOffset;
650+
shenandoahGCStateOffset = getFieldOffset("JavaThread::_gc_state", Integer.class);
649651
} else {
650652
shenandoahSATBQueueMarkingOffset = getConstant("ShenandoahThreadLocalData::satb_mark_queue_active_offset", Integer.class);
651653
shenandoahSATBQueueIndexOffset = getConstant("ShenandoahThreadLocalData::satb_mark_queue_index_offset", Integer.class);
652654
shenandoahSATBQueueBufferOffset = getConstant("ShenandoahThreadLocalData::satb_mark_queue_buffer_offset", Integer.class);
655+
shenandoahGCStateOffset = getConstant("ShenandoahThreadLocalData::gc_state_offset", Integer.class);
653656
}
654657
}
655658

@@ -856,6 +859,7 @@ private boolean checkNullAllocationStubs() {
856859
public final long validateObject = getAddress("JVMCIRuntime::validate_object");
857860

858861
public final long shenandoahConcmarkBarrierAddress = getAddress("JVMCIRuntime::shenandoah_concmark_barrier");
862+
public final long shenandoahLoadReferenceBarrierAddress = getAddress("JVMCIRuntime::shenandoah_load_reference_barrier");
859863

860864
public final long testDeoptimizeCallInt = getAddress("JVMCIRuntime::test_deoptimize_call_int");
861865

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java

+3
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier;
140140
import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
141141
import org.graalvm.compiler.nodes.gc.ShenandoahArrayRangePreWriteBarrier;
142+
import org.graalvm.compiler.nodes.gc.ShenandoahLoadReferenceBarrier;
142143
import org.graalvm.compiler.nodes.gc.ShenandoahPreWriteBarrier;
143144
import org.graalvm.compiler.nodes.gc.ShenandoahReferentFieldReadBarrier;
144145
import org.graalvm.compiler.nodes.java.ClassIsAssignableFromNode;
@@ -373,6 +374,8 @@ public void lower(Node n, LoweringTool tool) {
373374
shenandoahBarrierSnippets.lower((ShenandoahPreWriteBarrier) n, tool);
374375
} else if (n instanceof ShenandoahReferentFieldReadBarrier) {
375376
shenandoahBarrierSnippets.lower((ShenandoahReferentFieldReadBarrier) n, tool);
377+
} else if (n instanceof ShenandoahLoadReferenceBarrier) {
378+
shenandoahBarrierSnippets.lower((ShenandoahLoadReferenceBarrier) n, tool);
376379
} else if (n instanceof SerialWriteBarrier) {
377380
serialWriteBarrierSnippets.lower((SerialWriteBarrier) n, tool);
378381
} else if (n instanceof SerialArrayRangeWriteBarrier) {

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPRECALL;
8585
import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.VALIDATE_OBJECT;
8686
import static org.graalvm.compiler.hotspot.replacements.HotSpotShenandoahBarrierSnippets.SHENANDOAHWBPRECALL;
87+
import static org.graalvm.compiler.hotspot.replacements.HotSpotShenandoahBarrierSnippets.SHENANDOAHLRBCALL;
8788
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
8889
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION;
8990
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION;
@@ -355,6 +356,7 @@ public void initialize(HotSpotProviders providers, OptionValues options) {
355356
linkForeignCall(options, providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
356357
linkForeignCall(options, providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
357358
linkForeignCall(options, providers, SHENANDOAHWBPRECALL, c.shenandoahConcmarkBarrierAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
359+
linkForeignCall(options, providers, SHENANDOAHLRBCALL, c.shenandoahLoadReferenceBarrierAddress, PREPEND_THREAD, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);
358360

359361
if (GeneratePIC.getValue(options)) {
360362
registerForeignCall(WRONG_METHOD_HANDLER, c.handleWrongMethodStub, NativeCall, LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS);

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java

+5
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,11 @@ public static int shenandoahSATBQueueBufferOffset(@InjectedParameter GraalHotSpo
668668
return config.shenandoahSATBQueueBufferOffset;
669669
}
670670

671+
@Fold
672+
public static int shenandoahGCStateOffset(@InjectedParameter GraalHotSpotVMConfig config) {
673+
return config.shenandoahGCStateOffset;
674+
}
675+
671676
public static final LocationIdentity KLASS_SUPER_CHECK_OFFSET_LOCATION = NamedLocationIdentity.immutable("Klass::_super_check_offset");
672677

673678
@Fold

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotShenandoahBarrierSnippets.java

+18-8
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,26 @@
1111
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl;
1212
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
1313
import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
14-
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
1514
import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode;
1615
import org.graalvm.compiler.nodes.ValueNode;
17-
import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier;
18-
import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier;
19-
import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
20-
import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
21-
import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
2216
import org.graalvm.compiler.nodes.gc.ShenandoahArrayRangePreWriteBarrier;
17+
import org.graalvm.compiler.nodes.gc.ShenandoahLoadReferenceBarrier;
2318
import org.graalvm.compiler.nodes.gc.ShenandoahPreWriteBarrier;
2419
import org.graalvm.compiler.nodes.gc.ShenandoahReferentFieldReadBarrier;
2520
import org.graalvm.compiler.nodes.spi.LoweringTool;
2621
import org.graalvm.compiler.options.OptionValues;
2722
import org.graalvm.compiler.replacements.ReplacementsUtil;
2823
import org.graalvm.compiler.replacements.SnippetCounter;
2924
import org.graalvm.compiler.replacements.SnippetTemplate;
30-
import org.graalvm.compiler.replacements.gc.G1WriteBarrierSnippets;
3125
import org.graalvm.compiler.replacements.gc.ShenandoahBarrierSnippets;
3226
import org.graalvm.compiler.word.Word;
33-
import org.graalvm.word.WordFactory;
3427

3528
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_METAACCESS;
3629
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
3730

3831
public final class HotSpotShenandoahBarrierSnippets extends ShenandoahBarrierSnippets {
3932
public static final ForeignCallDescriptor SHENANDOAHWBPRECALL = new ForeignCallDescriptor("shenandoah_concmark_barrier", void.class, Object.class);
33+
public static final ForeignCallDescriptor SHENANDOAHLRBCALL = new ForeignCallDescriptor("shenandoah_load_reference_barrier", Object.class, Object.class);
4034
public static final ForeignCallDescriptor VALIDATE_OBJECT = new ForeignCallDescriptor("validate_object", boolean.class, Word.class, Word.class);
4135

4236
private final GraalHotSpotVMConfig config;
@@ -77,11 +71,21 @@ protected int satbQueueIndexOffset() {
7771
return HotSpotReplacementsUtil.shenandoahSATBQueueIndexOffset(INJECTED_VMCONFIG);
7872
}
7973

74+
@Override
75+
protected int gcStateOffset() {
76+
return HotSpotReplacementsUtil.shenandoahGCStateOffset(INJECTED_VMCONFIG);
77+
}
78+
8079
@Override
8180
protected ForeignCallDescriptor preWriteBarrierCallDescriptor() {
8281
return SHENANDOAHWBPRECALL;
8382
}
8483

84+
@Override
85+
protected ForeignCallDescriptor loadReferenceBarrierCallDescriptor() {
86+
return SHENANDOAHLRBCALL;
87+
}
88+
8589
@Override
8690
protected boolean verifyOops() {
8791
return HotSpotReplacementsUtil.verifyOops(INJECTED_VMCONFIG);
@@ -126,6 +130,7 @@ public static class Templates extends SnippetTemplate.AbstractTemplates {
126130
private final SnippetTemplate.SnippetInfo shenandoahPreWriteBarrier;
127131
private final SnippetTemplate.SnippetInfo shenandoahReferentReadBarrier;
128132
private final SnippetTemplate.SnippetInfo shenandoahArrayRangePreWriteBarrier;
133+
private final SnippetTemplate.SnippetInfo shenandoahLoadReferenceBarrier;
129134

130135
private final ShenandoahBarrierLowerer lowerer;
131136

@@ -140,6 +145,7 @@ public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories,
140145
SATB_QUEUE_INDEX_LOCATION, SATB_QUEUE_BUFFER_LOCATION);
141146
shenandoahArrayRangePreWriteBarrier = snippet(ShenandoahBarrierSnippets.class, "shenandoahArrayRangePreWriteBarrier", null, receiver, GC_INDEX_LOCATION, GC_LOG_LOCATION, SATB_QUEUE_MARKING_LOCATION,
142147
SATB_QUEUE_INDEX_LOCATION, SATB_QUEUE_BUFFER_LOCATION);
148+
shenandoahLoadReferenceBarrier = snippet(ShenandoahBarrierSnippets.class, "shenandoahLoadReferenceBarrier", null, receiver, GC_STATE_LOCATION);
143149
}
144150

145151
public void lower(ShenandoahPreWriteBarrier barrier, LoweringTool tool) {
@@ -153,6 +159,10 @@ public void lower(ShenandoahReferentFieldReadBarrier barrier, LoweringTool tool)
153159
public void lower(ShenandoahArrayRangePreWriteBarrier barrier, LoweringTool tool) {
154160
lowerer.lower(this, shenandoahArrayRangePreWriteBarrier, barrier, tool);
155161
}
162+
163+
public void lower(ShenandoahLoadReferenceBarrier barrier, LoweringTool tool) {
164+
lowerer.lower(this, shenandoahLoadReferenceBarrier, barrier, tool);
165+
}
156166
}
157167

158168
static final class HotspotShenandoahBarrierLowerer extends ShenandoahBarrierLowerer {

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ShenandoahBarrierSet.java

+20-11
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import jdk.vm.ci.meta.ResolvedJavaType;
3131
import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
3232
import org.graalvm.compiler.debug.GraalError;
33+
import org.graalvm.compiler.graph.Node;
34+
import org.graalvm.compiler.graph.iterators.NodePredicate;
3335
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
3436
import org.graalvm.compiler.nodes.NodeView;
3537
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -53,11 +55,6 @@ public class ShenandoahBarrierSet implements BarrierSet {
5355
public ShenandoahBarrierSet(GraalHotSpotVMConfig config, ResolvedJavaType objectArrayType, ResolvedJavaField referentField) {
5456
this.objectArrayType = objectArrayType;
5557
this.referentField = referentField;
56-
57-
if (!config.getFlag("ShenandoahGCMode", String.class).equals("passive")) {
58-
System.err.println("ShenandoahGCMode other than passive not supported yet");
59-
System.exit(-1);
60-
}
6158
}
6259

6360
@Override
@@ -81,11 +78,19 @@ public void addBarriers(FixedAccessNode n) {
8178
}
8279

8380
private static void addReadNodeBarriers(ReadNode node) {
84-
if (node.getBarrierType() == BarrierType.WEAK_FIELD || node.getBarrierType() == BarrierType.MAYBE_WEAK_FIELD) {
81+
ValueNode value = node;
82+
if (node.getBarrierType() != BarrierType.NONE) {
8583
StructuredGraph graph = node.graph();
86-
ShenandoahReferentFieldReadBarrier barrier = graph.add(new ShenandoahReferentFieldReadBarrier(node.getAddress(), node, node.getBarrierType() == BarrierType.MAYBE_WEAK_FIELD));
87-
graph.addAfterFixed(node, barrier);
84+
ShenandoahLoadReferenceBarrier lrb = graph.add(new ShenandoahLoadReferenceBarrier(node));
85+
value = lrb;
86+
node.graph().addAfterFixed(node, lrb);
87+
node.replaceAtMatchingUsages(lrb, n -> n != lrb);
8888
}
89+
// if (node.getBarrierType() == BarrierType.WEAK_FIELD || node.getBarrierType() == BarrierType.MAYBE_WEAK_FIELD) {
90+
// StructuredGraph graph = node.graph();
91+
// ShenandoahReferentFieldReadBarrier barrier = graph.add(new ShenandoahReferentFieldReadBarrier(node.getAddress(), value, node.getBarrierType() == BarrierType.MAYBE_WEAK_FIELD));
92+
// graph.addAfterFixed(node, barrier);
93+
// }
8994
}
9095

9196
private void addWriteBarriers(FixedAccessNode node, ValueNode writtenValue, ValueNode expectedValue, boolean doLoad, boolean nullCheck) {
@@ -138,8 +143,12 @@ private static boolean isObjectValue(ValueNode value) {
138143

139144
@Override
140145
public BarrierType fieldLoadBarrierType(ResolvedJavaField field, JavaKind storageKind) {
141-
if (field.getJavaKind() == JavaKind.Object && field.equals(referentField)) {
142-
return BarrierType.WEAK_FIELD;
146+
if (field.getJavaKind() == JavaKind.Object) {
147+
if (field.equals(referentField)) {
148+
return BarrierType.WEAK_FIELD;
149+
} else {
150+
return BarrierType.FIELD;
151+
}
143152
}
144153
return BarrierType.NONE;
145154
}
@@ -159,7 +168,7 @@ public BarrierType readBarrierType(RawLoadNode load) {
159168

160169
if (load.offset().isJavaConstant() && referentOffset != load.offset().asJavaConstant().asLong()) {
161170
// Reading at a constant offset which is different than the referent field.
162-
return BarrierType.NONE;
171+
return BarrierType.FIELD;
163172
}
164173
ResolvedJavaType referenceType = referentField.getDeclaringClass();
165174
ResolvedJavaType type = StampTool.typeOrNull(load.object());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2020, Red Hat Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
package org.graalvm.compiler.nodes.gc;
27+
28+
import org.graalvm.compiler.core.common.type.StampFactory;
29+
import org.graalvm.compiler.graph.NodeClass;
30+
import org.graalvm.compiler.nodeinfo.InputType;
31+
import org.graalvm.compiler.nodeinfo.NodeInfo;
32+
import org.graalvm.compiler.nodeinfo.Verbosity;
33+
import org.graalvm.compiler.nodes.FixedWithNextNode;
34+
import org.graalvm.compiler.nodes.NodeView;
35+
import org.graalvm.compiler.nodes.ValueNode;
36+
import org.graalvm.compiler.nodes.memory.MemoryKill;
37+
import org.graalvm.compiler.nodes.memory.address.AddressNode;
38+
import org.graalvm.compiler.nodes.spi.Lowerable;
39+
import org.graalvm.compiler.nodes.spi.LoweringTool;
40+
41+
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
42+
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
43+
44+
@NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Guard}, cycles = CYCLES_64, size = SIZE_64)
45+
public class ShenandoahLoadReferenceBarrier extends FixedWithNextNode implements Lowerable, MemoryKill {
46+
public static final NodeClass<ShenandoahLoadReferenceBarrier> TYPE = NodeClass.create(ShenandoahLoadReferenceBarrier.class);
47+
48+
@Input(InputType.Value)
49+
private ValueNode value;
50+
51+
public ShenandoahLoadReferenceBarrier(ValueNode value) {
52+
super(TYPE, value.stamp(NodeView.DEFAULT));
53+
this.value = value;
54+
}
55+
56+
public ValueNode getValue() {
57+
return value;
58+
}
59+
60+
@Override
61+
public void lower(LoweringTool tool) {
62+
assert graph().getGuardsStage().areFrameStatesAtDeopts();
63+
tool.getLowerer().lower(this, tool);
64+
}
65+
}

0 commit comments

Comments
 (0)