use of org.graalvm.compiler.nodes.FieldLocationIdentity in project graal by oracle.
the class GraalObjectReplacer method registerImmutableObjects.
public void registerImmutableObjects(CompilationAccess access) {
for (SubstrateMethod method : methods.values()) {
access.registerAsImmutable(method);
access.registerAsImmutable(method.getRawImplementations());
access.registerAsImmutable(method.getEncodedLineNumberTable());
}
for (SubstrateField field : fields.values()) {
access.registerAsImmutable(field);
}
for (FieldLocationIdentity fieldLocationIdentity : fieldLocationIdentities.values()) {
access.registerAsImmutable(fieldLocationIdentity);
}
for (SubstrateType type : types.values()) {
access.registerAsImmutable(type);
access.registerAsImmutable(type.getRawInstanceFields());
}
for (SubstrateSignature signature : signatures.values()) {
access.registerAsImmutable(signature);
access.registerAsImmutable(signature.getRawParameterTypes());
}
}
use of org.graalvm.compiler.nodes.FieldLocationIdentity in project graal by oracle.
the class ReferenceGetLoopTest method checkMidTierGraph.
@Override
protected boolean checkMidTierGraph(StructuredGraph graph) {
final LoopsData loops = new LoopsData(graph);
boolean found = false;
for (LoopEx loop : loops.loops()) {
for (Node node : loop.inside().nodes()) {
if (node instanceof Access) {
Access access = (Access) node;
LocationIdentity location = access.getLocationIdentity();
if (location instanceof FieldLocationIdentity) {
ResolvedJavaField field = ((FieldLocationIdentity) location).getField();
if (field.getName().equals("referent") && field.getDeclaringClass().equals(getMetaAccess().lookupJavaType(Reference.class))) {
found = true;
}
}
}
}
}
if (!found) {
assertTrue(false, "Reference.referent not found in loop: " + getCanonicalGraphString(graph, true, false));
}
return true;
}
use of org.graalvm.compiler.nodes.FieldLocationIdentity in project graal by oracle.
the class BytecodeParser method genGetField.
private void genGetField(ResolvedJavaField resolvedField, ValueNode receiver) {
if (!parsingIntrinsic() && GeneratePIC.getValue(getOptions())) {
graph.recordField(resolvedField);
}
for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
if (plugin.handleLoadField(this, receiver, resolvedField)) {
return;
}
}
ValueNode fieldRead = append(genLoadField(receiver, resolvedField));
if (resolvedField.getDeclaringClass().getName().equals("Ljava/lang/ref/Reference;") && resolvedField.getName().equals("referent")) {
LocationIdentity referentIdentity = new FieldLocationIdentity(resolvedField);
append(new MembarNode(0, referentIdentity));
}
JavaKind fieldKind = resolvedField.getJavaKind();
if (resolvedField.isVolatile() && fieldRead instanceof LoadFieldNode) {
StateSplitProxyNode readProxy = append(genVolatileFieldReadProxy(fieldRead));
frameState.push(fieldKind, readProxy);
readProxy.setStateAfter(frameState.create(stream.nextBCI(), readProxy));
} else {
frameState.push(fieldKind, fieldRead);
}
}
use of org.graalvm.compiler.nodes.FieldLocationIdentity in project graal by oracle.
the class WriteBarrierVerificationTest method testPredicate.
@SuppressWarnings("try")
private void testPredicate(final String snippet, final GraphPredicate expectedBarriers, final int... removedBarrierIndices) {
DebugContext debug = getDebugContext();
try (DebugCloseable d = debug.disableIntercept();
DebugContext.Scope s = debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) {
final StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
HighTierContext highTierContext = getDefaultHighTierContext();
new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext);
MidTierContext midTierContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
new GuardLoweringPhase().apply(graph, midTierContext);
new LoopSafepointInsertionPhase().apply(graph);
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, highTierContext);
new WriteBarrierAdditionPhase(config).apply(graph);
int barriers = 0;
// First, the total number of expected barriers is checked.
if (config.useG1GC) {
barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count();
Assert.assertTrue(expectedBarriers.apply(graph) * 2 == barriers);
} else {
barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count();
Assert.assertTrue(expectedBarriers.apply(graph) == barriers);
}
ResolvedJavaField barrierIndexField = getMetaAccess().lookupJavaField(WriteBarrierVerificationTest.class.getDeclaredField("barrierIndex"));
LocationIdentity barrierIdentity = new FieldLocationIdentity(barrierIndexField);
// Iterate over all write nodes and remove barriers according to input indices.
NodeIteratorClosure<Boolean> closure = new NodeIteratorClosure<Boolean>() {
@Override
protected Boolean processNode(FixedNode node, Boolean currentState) {
if (node instanceof WriteNode) {
WriteNode write = (WriteNode) node;
LocationIdentity obj = write.getLocationIdentity();
if (obj.equals(barrierIdentity)) {
/*
* A "barrierIndex" variable was found and is checked against the input
* barrier array.
*/
if (eliminateBarrier(write.value().asJavaConstant().asInt(), removedBarrierIndices)) {
return true;
}
}
} else if (node instanceof SerialWriteBarrier || node instanceof G1PostWriteBarrier) {
// Remove flagged write barriers.
if (currentState) {
graph.removeFixed(((FixedWithNextNode) node));
return false;
}
}
return currentState;
}
private boolean eliminateBarrier(int index, int[] map) {
for (int i = 0; i < map.length; i++) {
if (map[i] == index) {
return true;
}
}
return false;
}
@Override
protected EconomicMap<LoopExitNode, Boolean> processLoop(LoopBeginNode loop, Boolean initialState) {
return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates;
}
@Override
protected Boolean merge(AbstractMergeNode merge, List<Boolean> states) {
return false;
}
@Override
protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) {
return false;
}
};
try (Scope disabled = debug.disable()) {
ReentrantNodeIterator.apply(closure, graph.start(), false);
new WriteBarrierVerificationPhase(config).apply(graph);
} catch (AssertionError error) {
/*
* Catch assertion, test for expected one and re-throw in order to validate unit
* test.
*/
Assert.assertTrue(error.getMessage().contains("Write barrier must be present"));
throw error;
}
} catch (Throwable e) {
throw debug.handle(e);
}
}
use of org.graalvm.compiler.nodes.FieldLocationIdentity in project graal by oracle.
the class ReadEliminationClosure method processNode.
@Override
protected boolean processNode(Node node, ReadEliminationBlockState state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
boolean deleted = false;
if (node instanceof AccessFieldNode) {
AccessFieldNode access = (AccessFieldNode) node;
if (access.isVolatile()) {
processIdentity(state, any());
} else {
ValueNode object = GraphUtil.unproxify(access.object());
LoadCacheEntry identifier = new LoadCacheEntry(object, new FieldLocationIdentity(access.field()));
ValueNode cachedValue = state.getCacheEntry(identifier);
if (node instanceof LoadFieldNode) {
if (cachedValue != null && access.stamp(NodeView.DEFAULT).isCompatible(cachedValue.stamp(NodeView.DEFAULT))) {
effects.replaceAtUsages(access, cachedValue, access);
addScalarAlias(access, cachedValue);
deleted = true;
} else {
state.addCacheEntry(identifier, access);
}
} else {
assert node instanceof StoreFieldNode;
StoreFieldNode store = (StoreFieldNode) node;
ValueNode value = getScalarAlias(store.value());
if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
effects.deleteNode(store);
deleted = true;
}
state.killReadCache(identifier.identity);
state.addCacheEntry(identifier, value);
}
}
} else if (node instanceof ReadNode) {
ReadNode read = (ReadNode) node;
if (read.getLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(read.getAddress());
LoadCacheEntry identifier = new LoadCacheEntry(object, read.getLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
if (cachedValue != null && areValuesReplaceable(read, cachedValue, considerGuards)) {
effects.replaceAtUsages(read, cachedValue, read);
addScalarAlias(read, cachedValue);
deleted = true;
} else {
state.addCacheEntry(identifier, read);
}
}
} else if (node instanceof WriteNode) {
WriteNode write = (WriteNode) node;
if (write.getLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(write.getAddress());
LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
ValueNode value = getScalarAlias(write.value());
if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
effects.deleteNode(write);
deleted = true;
}
processIdentity(state, write.getLocationIdentity());
state.addCacheEntry(identifier, value);
} else {
processIdentity(state, write.getLocationIdentity());
}
} else if (node instanceof UnsafeAccessNode) {
ResolvedJavaType type = StampTool.typeOrNull(((UnsafeAccessNode) node).object());
if (type != null && !type.isArray()) {
if (node instanceof RawLoadNode) {
RawLoadNode load = (RawLoadNode) node;
if (load.getLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(load.object());
UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, load.offset(), load.getLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
if (cachedValue != null && areValuesReplaceable(load, cachedValue, considerGuards)) {
effects.replaceAtUsages(load, cachedValue, load);
addScalarAlias(load, cachedValue);
deleted = true;
} else {
state.addCacheEntry(identifier, load);
}
}
} else {
assert node instanceof RawStoreNode;
RawStoreNode write = (RawStoreNode) node;
if (write.getLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(write.object());
UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, write.offset(), write.getLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
ValueNode value = getScalarAlias(write.value());
if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
effects.deleteNode(write);
deleted = true;
}
processIdentity(state, write.getLocationIdentity());
state.addCacheEntry(identifier, value);
} else {
processIdentity(state, write.getLocationIdentity());
}
}
}
} else if (node instanceof MemoryCheckpoint.Single) {
LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
processIdentity(state, identity);
} else if (node instanceof MemoryCheckpoint.Multi) {
for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
processIdentity(state, identity);
}
}
return deleted;
}
Aggregations