# HG changeset patch # User Lukas Stadler # Date 1363784503 -3600 # Node ID 701290361dadf58c663d1810ac064a578dac0b40 # Parent afb190b1eeb348baf563c806308220b4ab1ae3e2# Parent 0e2c530885d101ecf6d33f077060c3950b93638c Merge diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -52,8 +52,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -70,8 +70,8 @@ } @Override - public Object getLocationIdentity() { - return locationIdentity; + public Object[] getLocationIdentities() { + return new Object[]{locationIdentity}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -44,8 +44,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -116,14 +116,15 @@ ResolvedJavaType type = getConcreteType(obj.objectStamp(), tool.getAssumptions()); if (isCloneableType(type, tool.getMetaAccessProvider())) { if (!type.isArray()) { - ResolvedJavaField[] fields = type.getInstanceFields(true); + VirtualInstanceNode newVirtual = new VirtualInstanceNode(type); + ResolvedJavaField[] fields = newVirtual.getFields(); + ValueNode[] state = new ValueNode[fields.length]; final LoadFieldNode[] loads = new LoadFieldNode[fields.length]; for (int i = 0; i < fields.length; i++) { state[i] = loads[i] = graph().add(new LoadFieldNode(obj, fields[i])); } - VirtualObjectNode newVirtual = new VirtualInstanceNode(type, fields); final StructuredGraph structuredGraph = (StructuredGraph) graph(); tool.customAction(new Runnable() { diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -109,8 +109,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -162,8 +162,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } public FrameState stateDuring() { diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -30,7 +30,7 @@ public class StartNode extends BeginStateSplitNode implements MemoryCheckpoint { @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -0,0 +1,120 @@ +/* + * 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.debug; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * This node can be used to add a counter to the code that will estimate the dynamic number of calls + * by adding an increment to the compiled code. This should of course only be used for + * debugging/testing purposes, and is not 100% accurate (because of concurrency issues while + * accessing the counters). + * + * A unique counter will be created for each unique String passed to the constructor. + */ +public class DynamicCounterNode extends FixedWithNextNode implements Lowerable { + + private static final int MAX_COUNTERS = 10 * 1024; + private static final long[] COUNTERS = new long[MAX_COUNTERS]; + private static final HashMap INDEXES = new HashMap<>(); + private final String name; + private final boolean addContext; + + public DynamicCounterNode(String name, boolean addContext) { + super(StampFactory.forVoid()); + this.name = name; + this.addContext = addContext; + } + + private static synchronized int getIndex(String name) { + Integer index = INDEXES.get(name); + if (index == null) { + index = INDEXES.size(); + if (index == 0) { + Runtime.getRuntime().addShutdownHook(new Thread() { + + @Override + public void run() { + dump(); + } + }); + } + INDEXES.put(name, index); + if (index >= MAX_COUNTERS) { + throw new GraalInternalError("too many dynamic counters"); + } + return index; + } else { + return index; + } + } + + private static synchronized void dump() { + TreeMap sorted = new TreeMap<>(); + + long sum = 0; + for (int i = 0; i < MAX_COUNTERS; i++) { + sum += COUNTERS[i]; + } + int cnt = 0; + for (Map.Entry entry : INDEXES.entrySet()) { + sorted.put(COUNTERS[entry.getValue()] * MAX_COUNTERS + cnt++, entry.getKey()); + } + + for (Map.Entry entry : sorted.entrySet()) { + System.out.println((entry.getKey() / MAX_COUNTERS) + ": " + entry.getValue()); + } + System.out.println(sum + ": total"); + + } + + @Override + public void lower(LoweringTool tool) { + int index = addContext ? getIndex(name + " @ " + MetaUtil.format("%h.%n", ((StructuredGraph) graph()).method())) : getIndex(name); + + StructuredGraph graph = (StructuredGraph) graph(); + ConstantNode arrayConstant = ConstantNode.forObject(COUNTERS, tool.getRuntime(), graph); + ConstantNode indexConstant = ConstantNode.forInt(index, graph); + LoadIndexedNode load = graph.add(new LoadIndexedNode(arrayConstant, indexConstant, Kind.Long)); + IntegerAddNode add = graph.add(new IntegerAddNode(Kind.Long, load, ConstantNode.forLong(1, graph))); + StoreIndexedNode store = graph.add(new StoreIndexedNode(arrayConstant, indexConstant, Kind.Long, add)); + + graph.addBeforeFixed(this, load); + graph.addBeforeFixed(this, store); + graph.removeFixed(this); + } + + public static void createCounter(String name, FixedNode before, boolean addContext) { + StructuredGraph graph = (StructuredGraph) before.graph(); + DynamicCounterNode counter = graph.add(new DynamicCounterNode(name, addContext)); + graph.addBeforeFixed(before, counter); + } +} diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java Wed Mar 20 14:01:43 2013 +0100 @@ -29,7 +29,7 @@ ValueNode object(); - LocationNode location(); + LocationNode nullCheckLocation(); void setNullCheck(boolean check); diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -30,7 +30,8 @@ /** * Accesses a value at an memory address specified by an {@linkplain #object object} and a - * {@linkplain #location() location}. The access does not include a null check on the object. + * {@linkplain #nullCheckLocation() location}. The access does not include a null check on the + * object. */ public abstract class AccessNode extends FixedWithNextNode implements Access { @@ -46,6 +47,10 @@ return (LocationNode) location; } + public LocationNode nullCheckLocation() { + return (LocationNode) location; + } + public boolean getNullCheck() { return nullCheck; } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -43,6 +43,10 @@ return location; } + public LocationNode nullCheckLocation() { + return location; + } + public boolean getNullCheck() { return nullCheck; } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -58,6 +58,6 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - return ReadNode.canonicalizeRead(this, tool); + return ReadNode.canonicalizeRead(this, location(), object(), tool); } } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -43,8 +43,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java Wed Mar 20 14:01:43 2013 +0100 @@ -26,8 +26,8 @@ /** * This interface marks is used for subclasses of {@link FixedNode} that kill a set of memory - * locations represented by a location identity (i.e. change a value at one or more locations that - * belong to this location identity). + * locations represented by location identities (i.e. change a value at one or more locations that + * belong to these location identities). */ public interface MemoryCheckpoint { @@ -35,8 +35,8 @@ * This method is used to determine which set of memory locations is killed by this node. * Returning the special value {@link LocationNode#ANY_LOCATION} will kill all memory locations. * - * @return the identity of the location killed by this node. + * @return the identities of all locations killed by this node. */ - Object getLocationIdentity(); + Object[] getLocationIdentities(); } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -62,35 +62,35 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - return canonicalizeRead(this, tool); + return canonicalizeRead(this, location(), object(), tool); } - public static ValueNode canonicalizeRead(Access read, CanonicalizerTool tool) { + public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); - if (runtime != null && read.object() != null && read.object().isConstant()) { - if (read.location().locationIdentity() == LocationNode.FINAL_LOCATION && read.location().getClass() == LocationNode.class) { - long displacement = read.location().displacement(); - Kind kind = read.location().getValueKind(); - if (read.object().kind() == Kind.Object) { - Object base = read.object().asConstant().asObject(); + if (runtime != null && object != null && object.isConstant()) { + if (location.locationIdentity() == LocationNode.FINAL_LOCATION && location.getClass() == LocationNode.class) { + long displacement = location.displacement(); + Kind kind = location.getValueKind(); + if (object.kind() == Kind.Object) { + Object base = object.asConstant().asObject(); if (base != null) { Constant constant = tool.runtime().readUnsafeConstant(kind, base, displacement); if (constant != null) { - return ConstantNode.forConstant(constant, runtime, read.node().graph()); + return ConstantNode.forConstant(constant, runtime, read.graph()); } } - } else if (read.object().kind() == Kind.Long || read.object().kind().getStackKind() == Kind.Int) { - long base = read.object().asConstant().asLong(); + } else if (object.kind() == Kind.Long || object.kind().getStackKind() == Kind.Int) { + long base = object.asConstant().asLong(); if (base != 0L) { Constant constant = tool.runtime().readUnsafeConstant(kind, null, base + displacement); if (constant != null) { - return ConstantNode.forConstant(constant, runtime, read.node().graph()); + return ConstantNode.forConstant(constant, runtime, read.graph()); } } } } } - return (ValueNode) read; + return read; } /** diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -49,8 +49,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -72,8 +72,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -37,8 +37,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -66,7 +66,7 @@ public static native void writeMemory(Object object, Object value, Object location); @Override - public Object getLocationIdentity() { - return location().locationIdentity(); + public Object[] getLocationIdentities() { + return new Object[]{location().locationIdentity()}; } } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -71,8 +71,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -42,8 +42,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } @Override diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -41,8 +41,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } public void lower(LoweringTool tool) { diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -42,8 +42,8 @@ } @Override - public Object getLocationIdentity() { - return LocationNode.ANY_LOCATION; + public Object[] getLocationIdentities() { + return new Object[]{LocationNode.ANY_LOCATION}; } public void lower(LoweringTool tool) { diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -95,12 +95,12 @@ public void virtualize(VirtualizerTool tool) { if (instanceClass != null) { assert !instanceClass().isArray(); - ResolvedJavaField[] fields = instanceClass().getInstanceFields(true); + VirtualInstanceNode virtualObject = new VirtualInstanceNode(instanceClass()); + ResolvedJavaField[] fields = virtualObject.getFields(); ValueNode[] state = new ValueNode[fields.length]; for (int i = 0; i < state.length; i++) { state[i] = ConstantNode.defaultForKind(fields[i].getType().getKind(), graph()); } - VirtualObjectNode virtualObject = new VirtualInstanceNode(instanceClass(), fields); tool.createVirtualObject(virtualObject, state, 0); tool.replaceWithVirtual(virtualObject); } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -32,7 +32,7 @@ * This node is used to perform the finalizer registration at the end of the java.lang.Object * constructor. */ -public final class RegisterFinalizerNode extends AbstractStateSplit implements StateSplit, Canonicalizable, LIRLowerable { +public final class RegisterFinalizerNode extends AbstractStateSplit implements StateSplit, Canonicalizable, LIRLowerable, Virtualizable { public static final Descriptor REGISTER_FINALIZER = new Descriptor("registerFinalizer", true, void.class, Object.class); @@ -74,4 +74,12 @@ return this; } + + @Override + public void virtualize(VirtualizerTool tool) { + State state = tool.getObjectState(object); + if (state != null && !state.getVirtualObject().type().hasFinalizer()) { + tool.delete(); + } + } } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Wed Mar 20 14:01:43 2013 +0100 @@ -22,8 +22,6 @@ */ package com.oracle.graal.nodes.virtual; -import java.util.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; @@ -32,21 +30,10 @@ private final ResolvedJavaType type; private final ResolvedJavaField[] fields; - private final HashMap fieldMap; - public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { + public VirtualInstanceNode(ResolvedJavaType type) { this.type = type; - this.fields = fields; - fieldMap = new HashMap<>(); - for (int i = 0; i < fields.length; i++) { - fieldMap.put(fields[i], i); - } - } - - private VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields, HashMap fieldMap) { - this.type = type; - this.fields = fields; - this.fieldMap = fieldMap; + this.fields = type.getInstanceFields(true); } @Override @@ -63,6 +50,10 @@ return fields[index]; } + public ResolvedJavaField[] getFields() { + return fields; + } + @Override public String toString(Verbosity verbosity) { if (verbosity == Verbosity.Name) { @@ -78,8 +69,13 @@ } public int fieldIndex(ResolvedJavaField field) { - Integer index = fieldMap.get(field); - return index == null ? -1 : index; + // on average fields.length == ~6, so a linear search is fast enough + for (int i = 0; i < fields.length; i++) { + if (fields[i] == field) { + return i; + } + } + return -1; } @Override @@ -95,6 +91,6 @@ @Override public VirtualInstanceNode duplicate() { - return new VirtualInstanceNode(type, fields, fieldMap); + return new VirtualInstanceNode(type); } } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Wed Mar 20 14:01:43 2013 +0100 @@ -84,7 +84,9 @@ @Override protected void processNode(FixedNode node, Set currentState) { if (node instanceof MemoryCheckpoint) { - currentState.add(((MemoryCheckpoint) node).getLocationIdentity()); + for (Object identity : ((MemoryCheckpoint) node).getLocationIdentities()) { + currentState.add(identity); + } } } @@ -132,10 +134,12 @@ } private void processCheckpoint(MemoryCheckpoint checkpoint, MemoryMap state) { - if (checkpoint.getLocationIdentity() == LocationNode.ANY_LOCATION) { - state.lastMemorySnapshot.clear(); + for (Object identity : checkpoint.getLocationIdentities()) { + if (identity == LocationNode.ANY_LOCATION) { + state.lastMemorySnapshot.clear(); + } + state.lastMemorySnapshot.put(identity, (ValueNode) checkpoint); } - state.lastMemorySnapshot.put(checkpoint.getLocationIdentity(), (ValueNode) checkpoint); } private void processRead(ReadNode readNode, MemoryMap state) { @@ -210,7 +214,9 @@ * needs to choose by putting in the location identity on both successors. */ InvokeWithExceptionNode checkpoint = (InvokeWithExceptionNode) node.predecessor(); - result.lastMemorySnapshot.put(checkpoint.getLocationIdentity(), node); + for (Object identity : checkpoint.getLocationIdentities()) { + result.lastMemorySnapshot.put(identity, node); + } } return result; } diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Wed Mar 20 14:01:43 2013 +0100 @@ -133,11 +133,11 @@ } else if (node instanceof Access) { Access access = (Access) node; GuardNode guard = nullGuarded.get(access.object()); - if (guard != null && isImplicitNullCheck(access.location(), target)) { + if (guard != null && isImplicitNullCheck(access.nullCheckLocation(), target)) { NodeInputList dependencies = ((ValueNode) access).dependencies(); dependencies.remove(guard); if (access instanceof FloatingReadNode) { - ReadNode read = graph.add(new ReadNode(access.object(), access.location(), ((FloatingReadNode) access).stamp(), dependencies)); + ReadNode read = graph.add(new ReadNode(access.object(), access.nullCheckLocation(), ((FloatingReadNode) access).stamp(), dependencies)); node.replaceAndDelete(read); access = read; lastFixed.setNext(read); diff -r 0e2c530885d1 -r 701290361dad graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Wed Mar 20 12:00:18 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Wed Mar 20 14:01:43 2013 +0100 @@ -64,12 +64,13 @@ if (node instanceof FloatingReadNode) { currentState.add((FloatingReadNode) node); } else if (node instanceof MemoryCheckpoint) { - Object identity = ((MemoryCheckpoint) node).getLocationIdentity(); - for (Iterator iter = currentState.iterator(); iter.hasNext();) { - FloatingReadNode read = iter.next(); - FixedNode fixed = (FixedNode) node; - if (identity == LocationNode.ANY_LOCATION || read.location().locationIdentity() == identity) { - addPhantomReference(read, fixed); + for (Object identity : ((MemoryCheckpoint) node).getLocationIdentities()) { + for (Iterator iter = currentState.iterator(); iter.hasNext();) { + FloatingReadNode read = iter.next(); + FixedNode fixed = (FixedNode) node; + if (identity == LocationNode.ANY_LOCATION || read.location().locationIdentity() == identity) { + addPhantomReference(read, fixed); + } } } }