# HG changeset patch
# User Thomas Wuerthinger
# Date 1399321126 -7200
# Node ID a3f897fb3289b4e9b2f716c1d17c1bae4ee91363
# Parent ff5cacf47b68317e23b495eda21b1f3f6fed11eb# Parent fbe9e7088e3500ce54b650c2b1c4516f895ae9c4
Merge.
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Mon May 05 22:18:46 2014 +0200
@@ -203,7 +203,7 @@
boxingSnippets.lower((BoxNode) n, tool);
} else if (n instanceof UnboxNode) {
boxingSnippets.lower((UnboxNode) n, tool);
- } else if (n instanceof DeoptimizeNode || n instanceof UnwindNode) {
+ } else if (n instanceof DeoptimizeNode || n instanceof UnwindNode || n instanceof FloatRemNode) {
/* No lowering, we generate LIR directly for these nodes. */
} else {
throw GraalInternalError.shouldNotReachHere("Node implementing Lowerable not handled: " + n);
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Mon May 05 22:18:46 2014 +0200
@@ -31,7 +31,7 @@
import com.oracle.graal.nodes.spi.*;
@NodeInfo(shortName = "%")
-public final class FloatRemNode extends FloatArithmeticNode implements Canonicalizable {
+public class FloatRemNode extends FloatArithmeticNode implements Canonicalizable, Lowerable {
public FloatRemNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) {
super(stamp, x, y, isStrictFP);
@@ -57,6 +57,11 @@
}
@Override
+ public void lower(LoweringTool tool) {
+ tool.getLowerer().lower(this, tool);
+ }
+
+ @Override
public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
builder.setResult(this, gen.emitRem(builder.operand(x()), builder.operand(y()), null));
}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Mon May 05 22:18:46 2014 +0200
@@ -200,7 +200,7 @@
private void connectBlocks() {
for (Block block : reversePostOrder) {
List predecessors = new ArrayList<>(4);
- double probability = 0;
+ double probability = block.getBeginNode() instanceof StartNode ? 1D : 0D;
for (Node predNode : block.getBeginNode().cfgPredecessors()) {
Block predBlock = nodeToBlock.get(predNode);
if (predBlock.getId() >= 0) {
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/BaseReduction.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/BaseReduction.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/BaseReduction.java Mon May 05 22:18:46 2014 +0200
@@ -57,10 +57,11 @@
*/
public abstract class BaseReduction extends PostOrderNodeIterator {
- protected static final DebugMetric metricCheckCastRemoved = Debug.metric("CheckCastRemoved");
- protected static final DebugMetric metricGuardingPiNodeRemoved = Debug.metric("GuardingPiNodeRemoved");
- protected static final DebugMetric metricFixedGuardNodeRemoved = Debug.metric("FixedGuardNodeRemoved");
- protected static final DebugMetric metricMethodResolved = Debug.metric("MethodResolved");
+ protected static final DebugMetric metricCheckCastRemoved = Debug.metric("FSR-CheckCastRemoved");
+ protected static final DebugMetric metricGuardingPiNodeRemoved = Debug.metric("FSR-GuardingPiNodeRemoved");
+ protected static final DebugMetric metricFixedGuardNodeRemoved = Debug.metric("FSR-FixedGuardNodeRemoved");
+ protected static final DebugMetric metricMethodResolved = Debug.metric("FSR-MethodResolved");
+ protected static final DebugMetric metricUnconditionalDeoptInserted = Debug.metric("FSR-UnconditionalDeoptInserted");
/**
*
@@ -95,6 +96,7 @@
* a bug in FlowSensitiveReduction (the code was reachable, after all).
*/
public void doRewrite(LogicNode falseConstant) {
+ metricUnconditionalDeoptInserted.increment();
StructuredGraph graph = fixed.graph();
// have to insert a FixedNode other than a ControlSinkNode
FixedGuardNode buckStopsHere = graph.add(new FixedGuardNode(falseConstant, deoptReason, DeoptimizationAction.None));
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java Mon May 05 22:18:46 2014 +0200
@@ -122,7 +122,7 @@
assert !StampTool.isObjectAlwaysNull(subject) : "Null as per stamp subjects should have been handled above";
// --------- checkCast deemed unsatisfiable by subject-stamp alone ---------
- if (state.knownNotToConform(subject, toType)) {
+ if (state.knownNotToPassCheckCast(subject, toType)) {
postponedDeopts.addDeoptBefore(checkCast, checkCast.isForStoreCheck() ? ArrayStoreException : ClassCastException);
state.impossiblePath();
// let FixedGuardNode(false).simplify() prune the dead-code control-path
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java Mon May 05 22:18:46 2014 +0200
@@ -65,11 +65,12 @@
*/
public final class EquationalReasoner {
- private static final DebugMetric metricInstanceOfRemoved = Debug.metric("InstanceOfRemoved");
- private static final DebugMetric metricNullCheckRemoved = Debug.metric("NullCheckRemoved");
- private static final DebugMetric metricObjectEqualsRemoved = Debug.metric("ObjectEqualsRemoved");
- private static final DebugMetric metricEquationalReasoning = Debug.metric("EquationalReasoning");
- private static final DebugMetric metricDowncasting = Debug.metric("Downcasting");
+ private static final DebugMetric metricInstanceOfRemoved = Debug.metric("FSR-InstanceOfRemoved");
+ private static final DebugMetric metricNullCheckRemoved = Debug.metric("FSR-NullCheckRemoved");
+ private static final DebugMetric metricObjectEqualsRemoved = Debug.metric("FSR-ObjectEqualsRemoved");
+ private static final DebugMetric metricEquationalReasoning = Debug.metric("FSR-EquationalReasoning");
+ private static final DebugMetric metricDowncasting = Debug.metric("FSR-Downcasting");
+ private static final DebugMetric metricNullInserted = Debug.metric("FSR-NullInserted");
private final StructuredGraph graph;
private final CanonicalizerTool tool;
@@ -114,6 +115,7 @@
*/
public void forceState(State s) {
state = s;
+ assert state.repOK();
substs.clear();
added.clear();
visited = null;
@@ -235,6 +237,17 @@
// picked cached substitution
return result;
}
+ if (FlowUtil.hasLegalObjectStamp(v) && state.isNull(v)) {
+ // it's ok to return nullConstant in deverbosify unlike in downcast
+ metricNullInserted.increment();
+ return nullConstant;
+ }
+ if (v instanceof ValueProxy) {
+ return v;
+ }
+ if (!(n instanceof FloatingNode)) {
+ return n;
+ }
if ((visited != null && visited.contains(n)) || added.contains(v)) {
return v;
}
@@ -252,25 +265,13 @@
* Past this point, if we ever want `n` to be deverbosified, it must be looked-up by one of
* the cases above. One sure way to achieve that is with `rememberSubstitution(old, new)`
*/
- if (v instanceof ValueProxy) {
- return downcast(v);
- }
- if (n instanceof FloatingNode) {
- /*
- * `deverbosifyFloatingNode()` will drill down over floating inputs, when that not
- * possible anymore it resorts to calling `downcast()`. Thus it's ok to take the
- * `deverbosifyFloatingNode()` route first, as no downcasting opportunity will be
- * missed.
- */
- return deverbosifyFloatingNode((FloatingNode) n);
- }
-
- if (FlowUtil.hasLegalObjectStamp(v)) {
- return downcast(v);
- }
-
- return n;
+ /*
+ * `deverbosifyFloatingNode()` will drill down over floating inputs, when that not possible
+ * anymore it resorts to calling `downcast()`. Thus it's ok to take the
+ * `deverbosifyFloatingNode()` route first, as no downcasting opportunity will be missed.
+ */
+ return deverbosifyFloatingNode((FloatingNode) n);
}
/**
@@ -334,16 +335,7 @@
}
if (changed == null) {
assert visited.contains(f) || added.contains(f);
- if (FlowUtil.hasLegalObjectStamp(f)) {
- /*
- * No input has changed doesn't imply there's no witness to refine the
- * floating-object value.
- */
- ValueNode d = downcast(f);
- return d;
- } else {
- return f;
- }
+ return f;
}
FlowUtil.inferStampAndCheck(changed);
added.add(changed);
@@ -441,6 +433,8 @@
return baseCaseIsNullNode((IsNullNode) condition);
} else if (condition instanceof ObjectEqualsNode) {
return baseCaseObjectEqualsNode((ObjectEqualsNode) condition);
+ } else if (condition instanceof ShortCircuitOrNode) {
+ return baseCaseShortCircuitOrNode((ShortCircuitOrNode) condition);
}
}
return condition;
@@ -465,6 +459,11 @@
if (state.isNull(scrutinee)) {
metricInstanceOfRemoved.increment();
return falseConstant;
+ } else if (state.knownNotToPassInstanceOf(scrutinee, instanceOf.type())) {
+ // scrutinee turns out to be null -> falseConstant right answer
+ // scrutinee not null, but known-not-to-conform -> falseConstant
+ metricInstanceOfRemoved.increment();
+ return falseConstant;
} else if (state.isNonNull(scrutinee) && state.knownToConform(scrutinee, instanceOf.type())) {
metricInstanceOfRemoved.increment();
return trueConstant;
@@ -477,21 +476,19 @@
* performed; otherwise the unmodified argument.
*
*/
- private FloatingNode baseCaseIsNullNode(IsNullNode isNull) {
- ValueNode object = isNull.object();
+ private FloatingNode baseCaseIsNullNode(IsNullNode isNu) {
+ ValueNode object = isNu.object();
if (!FlowUtil.hasLegalObjectStamp(object)) {
- return isNull;
+ return isNu;
}
- ValueNode scrutinee = GraphUtil.unproxify(isNull.object());
- GuardingNode evidence = nonTrivialNullAnchor(scrutinee);
- if (evidence != null) {
+ if (state.isNull(object)) {
metricNullCheckRemoved.increment();
return trueConstant;
- } else if (state.isNonNull(scrutinee)) {
+ } else if (state.isNonNull(object)) {
metricNullCheckRemoved.increment();
return falseConstant;
}
- return isNull;
+ return isNu;
}
/**
@@ -515,6 +512,38 @@
}
/**
+ * The following is tried:
+ *
+ *
+ * -
+ * A {@link com.oracle.graal.phases.common.cfs.Witness} that is at check-cast level level
+ * doesn't entail {@link com.oracle.graal.nodes.calc.IsNullNode} (on its own) nor
+ * {@link com.oracle.graal.nodes.java.InstanceOfNode} (also on its own) but of course it entails
+ *
(IsNull || IsInstanceOf)
. Good thing
+ * {@link com.oracle.graal.phases.common.cfs.CastCheckExtractor} detects that very pattern.
+ * -
+ * Otherwise return the unmodified argument (later on,
+ * {@link #deverbosifyFloatingNode(com.oracle.graal.nodes.calc.FloatingNode)} will attempt to
+ * simplify the {@link com.oracle.graal.nodes.ShortCircuitOrNode}).
+ *
+ *
+ * @return a {@link com.oracle.graal.nodes.LogicConstantNode}, in case a reduction was made;
+ * otherwise the unmodified argument.
+ */
+ private LogicNode baseCaseShortCircuitOrNode(ShortCircuitOrNode orNode) {
+ CastCheckExtractor cast = CastCheckExtractor.extract(orNode);
+ if (cast != null) {
+ if (state.knownToConform(cast.subject, cast.type)) {
+ return trueConstant;
+ } else if (state.knownNotToPassCheckCast(cast.subject, cast.type)) {
+ return falseConstant;
+ }
+ return orNode;
+ }
+ return orNode;
+ }
+
+ /**
* It's always ok to use "downcast(object)
" instead of " object
"
* because this method re-wraps the argument in a {@link com.oracle.graal.nodes.PiNode} only if
* the new stamp is strictly more refined than the original.
@@ -558,6 +587,7 @@
PiNode untrivialNull = nonTrivialNull(scrutinee);
if (untrivialNull != null) {
+ metricNullInserted.increment();
return untrivialNull;
}
@@ -646,24 +676,6 @@
}
/**
- *
- * If the argument is known null due to its stamp, there's no need to have an anchor for that
- * fact and this method returns null.
- *
- *
- *
- * Otherwise, if an anchor is found it is returned, null otherwise.
- *
- */
- public GuardingNode nonTrivialNullAnchor(ValueNode object) {
- assert FlowUtil.hasLegalObjectStamp(object);
- if (StampTool.isObjectAlwaysNull(object)) {
- return null;
- }
- return state.knownNull.get(GraphUtil.unproxify(object));
- }
-
- /**
*
* This method returns:
*
@@ -680,7 +692,7 @@
*/
public PiNode nonTrivialNull(ValueNode object) {
assert FlowUtil.hasLegalObjectStamp(object);
- GuardingNode anchor = nonTrivialNullAnchor(object);
+ GuardingNode anchor = state.nonTrivialNullAnchor(object);
if (anchor == null) {
return null;
}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/Evidence.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/Evidence.java Mon May 05 22:18:46 2014 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 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.phases.common.cfs;
+
+import com.oracle.graal.nodes.extended.GuardingNode;
+
+public class Evidence {
+
+ public final GuardingNode success;
+ public final boolean failure;
+
+ public Evidence(GuardingNode success, boolean failure) {
+ this.success = success;
+ this.failure = failure;
+ assert repOK();
+ }
+
+ public Evidence(GuardingNode success) {
+ this(success, false);
+ }
+
+ private Evidence(boolean failure) {
+ this(null, failure);
+ }
+
+ public boolean isPositive() {
+ return success != null;
+ }
+
+ public boolean isNegative() {
+ return failure;
+ }
+
+ private boolean repOK() {
+ // either success or failure, ie boolean-XOR
+ return (success != null) != failure;
+ }
+
+ public static Evidence COUNTEREXAMPLE = new Evidence(true);
+
+}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FixedGuardReduction.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FixedGuardReduction.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FixedGuardReduction.java Mon May 05 22:18:46 2014 +0200
@@ -23,9 +23,7 @@
package com.oracle.graal.phases.common.cfs;
import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.IsNullNode;
import com.oracle.graal.nodes.extended.GuardingNode;
-import com.oracle.graal.nodes.java.*;
import com.oracle.graal.phases.tiers.PhaseContext;
/**
@@ -99,118 +97,33 @@
return;
}
- /*
- * Attempt to eliminate the current FixedGuardNode by using another GuardingNode already in
- * scope and with equivalent condition.
- */
+ final boolean isTrue = !f.isNegated();
+ final Evidence evidence = state.outcome(isTrue, f.condition());
- GuardingNode existingGuard = f.isNegated() ? state.falseFacts.get(f.condition()) : state.trueFacts.get(f.condition());
- if (existingGuard != null) {
- // assert existingGuard instanceof FixedGuardNode;
- metricFixedGuardNodeRemoved.increment();
- f.replaceAtUsages(existingGuard.asNode());
- graph.removeFixed(f);
+ // can't produce evidence, must be information gain
+ if (evidence == null) {
+ state.addFact(isTrue, f.condition(), f);
return;
}
- final LogicNode cond = f.condition();
- final boolean isTrue = !f.isNegated();
-
- /*
- * A FixedGuardNode can only be removed provided a replacement anchor is found (so called
- * "evidence"), ie an anchor that amounts to the same combination of (negated, condition) as
- * for the FixedGuardNode at hand. Just deverbosifying the condition in place isn't
- * semantics-preserving.
- */
-
- // TODO what about isDependencyTainted
-
- if (cond instanceof IsNullNode) {
- final IsNullNode isNullNode = (IsNullNode) cond;
- if (isTrue) {
- // grab an anchor attesting nullness
- final GuardingNode replacement = reasoner.nonTrivialNullAnchor(isNullNode.object());
- if (replacement != null) {
- removeFixedGuardNode(f, replacement);
- return;
- }
- if (state.isNonNull(isNullNode.object())) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- // can't produce evidence, fall-through to addFact
- } else {
- // grab an anchor attesting non-nullness
- final Witness w = state.typeInfo(isNullNode.object());
- if (w != null && w.isNonNull()) {
- removeFixedGuardNode(f, w.guard());
- return;
- }
- if (state.isNull(isNullNode.object())) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- // can't produce evidence, fall-through to addFact
- }
- } else if (cond instanceof InstanceOfNode) {
- final InstanceOfNode iOf = (InstanceOfNode) cond;
- final Witness w = state.typeInfo(iOf.object());
- if (isTrue) {
- // grab an anchor attesting instanceof
- if (w != null) {
- if (w.isNonNull() && w.type() != null) {
- if (iOf.type().isAssignableFrom(w.type())) {
- removeFixedGuardNode(f, w.guard());
- return;
- }
- if (State.knownNotToConform(w.type(), iOf.type())) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- }
- }
- if (state.isNull(iOf.object())) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- // can't produce evidence, fall-through to addFact
- } else {
- // grab an anchor attesting not-instanceof
- // (1 of 2) attempt determining nullness
- final GuardingNode nullGuard = reasoner.nonTrivialNullAnchor(iOf.object());
- if (nullGuard != null) {
- removeFixedGuardNode(f, nullGuard);
- return;
- }
- // (2 of 2) attempt determining known-not-to-conform
- if (w != null && !w.cluelessAboutType()) {
- if (State.knownNotToConform(w.type(), iOf.type())) {
- removeFixedGuardNode(f, w.guard());
- return;
- }
- }
- // can't produce evidence, fall-through to addFact
- }
- } else if (isTrue && cond instanceof ShortCircuitOrNode) {
- CastCheckExtractor cce = CastCheckExtractor.extract(cond);
- if (cce != null && !State.isDependencyTainted(cce.subject, f)) {
- // grab an anchor attesting check-cast
- Witness w = state.typeInfo(cce.subject);
- if (w != null && w.type() != null) {
- if (cce.type.isAssignableFrom(w.type())) {
- removeFixedGuardNode(f, w.guard());
- return;
- }
- if (State.knownNotToConform(w.type(), cce.type)) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- }
- }
- // can't produce evidence, fall-through to addFact
+ if (evidence.isPositive()) {
+ /*
+ * A FixedGuardNode can only be removed provided a replacement anchor is found (so
+ * called "evidence"), ie an anchor that amounts to the same combination of (negated,
+ * condition) as for the FixedGuardNode at hand. Just deverbosifying the condition in
+ * place isn't semantics-preserving.
+ *
+ * Eliminate the current FixedGuardNode by using another GuardingNode already in scope,
+ * a GuardingNode that guards a condition that is at least as strong as that of the
+ * FixedGuardNode.
+ */
+ removeFixedGuardNode(f, evidence.success);
+ return;
}
- state.addFact(isTrue, cond, f);
+ assert evidence.isNegative();
+ markFixedGuardNodeAlwaysFails(f);
+
}
/**
@@ -232,9 +145,7 @@
*
*/
private void removeFixedGuardNode(FixedGuardNode old, GuardingNode replacement) {
- if (replacement == null) {
- return;
- }
+ assert replacement != null;
metricFixedGuardNodeRemoved.increment();
old.replaceAtUsages(replacement.asNode());
graph.removeFixed(old);
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java Mon May 05 22:18:46 2014 +0200
@@ -54,6 +54,14 @@
*
* - simplification of side-effects free expressions, via
* {@link com.oracle.graal.phases.common.cfs.EquationalReasoner#deverbosify(com.oracle.graal.graph.Node)}
+ *
+ * -
+ * at certain {@link com.oracle.graal.nodes.FixedNode}, see
+ * {@link #deverbosifyInputsInPlace(com.oracle.graal.nodes.ValueNode)}
+ * -
+ * including for devirtualization, see
+ * {@link #deverbosifyInputsCopyOnWrite(com.oracle.graal.nodes.java.MethodCallTargetNode)}
+ *
*
* - simplification of control-flow:
*
@@ -76,6 +84,13 @@
*
*
*
+ *
+ * Metrics for this phase are displayed starting with FSR-
prefix, their counters are
+ * hosted in {@link com.oracle.graal.phases.common.cfs.BaseReduction},
+ * {@link com.oracle.graal.phases.common.cfs.EquationalReasoner} and
+ * {@link com.oracle.graal.phases.common.cfs.State}.
+ *
+ *
* @see com.oracle.graal.phases.common.cfs.CheckCastReduction
* @see com.oracle.graal.phases.common.cfs.GuardingPiReduction
* @see com.oracle.graal.phases.common.cfs.FixedGuardReduction
@@ -217,13 +232,8 @@
// `begin` denotes the default case of the TypeSwitchNode
return;
}
- if (state.knownNotToConform(loadHub.object(), type)) {
- postponedDeopts.addDeoptAfter(begin, UnreachedCode);
- state.impossiblePath();
- return;
- }
// it's unwarranted to assume loadHub.object() to be non-null
- // it also seems unwarranted state.trackCC(loadHub.object(), type, begin);
+ state.trackCC(loadHub.object(), type, begin);
}
}
@@ -295,9 +305,16 @@
*
*/
private MethodCallTargetNode deverbosifyInputsCopyOnWrite(MethodCallTargetNode parent) {
+ final MethodCallTargetNode.InvokeKind ik = parent.invokeKind();
+ final boolean shouldTryDevirt = (ik == MethodCallTargetNode.InvokeKind.Interface || ik == MethodCallTargetNode.InvokeKind.Virtual);
+ boolean shouldDowncastReceiver = shouldTryDevirt;
MethodCallTargetNode changed = null;
for (ValueNode i : FlowUtil.distinctValueAndConditionInputs(parent)) {
- Node j = reasoner.deverbosify(i);
+ ValueNode j = (ValueNode) reasoner.deverbosify(i);
+ if (shouldDowncastReceiver) {
+ shouldDowncastReceiver = false;
+ j = reasoner.downcast(j);
+ }
if (i != j) {
assert j != parent;
if (changed == null) {
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java Sat May 03 21:46:35 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java Mon May 05 22:18:46 2014 +0200
@@ -50,10 +50,10 @@
*/
public final class State extends MergeableState implements Cloneable {
- private static final DebugMetric metricTypeRegistered = Debug.metric("TypeRegistered");
- private static final DebugMetric metricNullnessRegistered = Debug.metric("NullnessRegistered");
- private static final DebugMetric metricObjectEqualsRegistered = Debug.metric("ObjectEqualsRegistered");
- private static final DebugMetric metricImpossiblePathDetected = Debug.metric("ImpossiblePathDetected");
+ private static final DebugMetric metricTypeRegistered = Debug.metric("FSR-TypeRegistered");
+ private static final DebugMetric metricNullnessRegistered = Debug.metric("FSR-NullnessRegistered");
+ private static final DebugMetric metricObjectEqualsRegistered = Debug.metric("FSR-ObjectEqualsRegistered");
+ private static final DebugMetric metricImpossiblePathDetected = Debug.metric("FSR-ImpossiblePathDetected");
/**
*
@@ -141,6 +141,18 @@
this.falseFacts = new IdentityHashMap<>(other.falseFacts);
}
+ public boolean repOK() {
+ // trueFacts and falseFacts disjoint
+ for (LogicNode trueFact : trueFacts.keySet()) {
+ assert !falseFacts.containsKey(trueFact) : trueFact + " tracked as both true and false fact.";
+ }
+ // no scrutinee tracked as both known-null and known-non-null
+ for (ValueNode subject : knownNull.keySet()) {
+ assert !isNonNull(subject) : subject + " tracked as both known-null and known-non-null.";
+ }
+ return true;
+ }
+
/**
* @return A new list containing only those states that are reachable.
*/
@@ -300,6 +312,9 @@
this.trueFacts = mergeTrueFacts(withReachableStates, merge);
this.falseFacts = mergeFalseFacts(withReachableStates, merge);
+
+ assert repOK();
+
return true;
}
@@ -393,7 +408,8 @@
}
/**
- * @return true iff the argument is known to stand for an object conforming to the given type.
+ * @return true iff the argument definitely stands for an object-value that conforms to the
+ * given type.
*/
public boolean knownToConform(ValueNode object, ResolvedJavaType to) {
assert FlowUtil.hasLegalObjectStamp(object);
@@ -415,14 +431,20 @@
}
/**
- * @return true iff the argument is known to stand for an object that definitely does not
- * conform to the given type.
+ * @return true iff the argument is known to stand for an object that is definitely non-null and
+ * moreover does not conform to the given type.
*/
- public boolean knownNotToConform(ValueNode object, ResolvedJavaType to) {
+ public boolean knownNotToPassCheckCast(ValueNode object, ResolvedJavaType to) {
assert FlowUtil.hasLegalObjectStamp(object);
assert !to.isPrimitive();
final ValueNode scrutinee = GraphUtil.unproxify(object);
if (isNull(scrutinee)) {
+ // known-null means it conforms to whatever `to`
+ // and thus passes the check-cast
+ return false;
+ }
+ if (!isNonNull(scrutinee)) {
+ // unless `null` can be ruled out, a positive answer isn't safe
return false;
}
ResolvedJavaType stampType = StampTool.typeOrNull(object);
@@ -437,6 +459,34 @@
return false;
}
+ /**
+ * @return true iff the argument is known to stand for an object that definitely does not
+ * conform to the given type (no matter whether the object turns out to be null or
+ * non-null).
+ */
+ public boolean knownNotToPassInstanceOf(ValueNode object, ResolvedJavaType to) {
+ assert FlowUtil.hasLegalObjectStamp(object);
+ assert !to.isPrimitive();
+ final ValueNode scrutinee = GraphUtil.unproxify(object);
+ if (isNull(scrutinee)) {
+ return true;
+ }
+ ResolvedJavaType stampType = StampTool.typeOrNull(object);
+ if (stampType != null && knownNotToConform(stampType, to)) {
+ // object turns out to be null, positive answer is correct
+ // object turns out non-null, positive answer is also correct
+ return true;
+ }
+ Witness w = typeInfo(scrutinee);
+ boolean witnessAnswer = w != null && !w.cluelessAboutType() && knownNotToConform(w.type(), to);
+ if (witnessAnswer) {
+ // object turns out to be null, positive answer is correct
+ // object turns out non-null, positive answer is also correct
+ return true;
+ }
+ return false;
+ }
+
// @formatter:off
/**
* \ | | | |
@@ -526,6 +576,7 @@
Witness w = getOrElseAddTypeInfo(object);
if (w.trackNN(anchor)) {
versionNr++;
+ assert repOK();
return true;
}
return false;
@@ -558,6 +609,7 @@
if (w.trackCC(observed, anchor)) {
versionNr++;
metricTypeRegistered.increment();
+ assert repOK();
return true;
}
return false;
@@ -584,6 +636,7 @@
if (w.trackIO(observed, anchor)) {
versionNr++;
metricTypeRegistered.increment();
+ assert repOK();
return true;
}
return false;
@@ -665,6 +718,7 @@
} else {
addFactPrimordial(condition, isTrue ? trueFacts : falseFacts, anchor);
}
+ assert repOK();
}
/**
@@ -675,7 +729,7 @@
private void addFactInstanceOf(boolean isTrue, InstanceOfNode instanceOf, GuardingNode anchor) {
ValueNode object = instanceOf.object();
if (isTrue) {
- if (knownNotToConform(object, instanceOf.type())) {
+ if (knownNotToPassInstanceOf(object, instanceOf.type())) {
impossiblePath();
return;
}
@@ -776,6 +830,7 @@
trackNN(original, anchor);
}
}
+ assert repOK();
}
/**
@@ -813,4 +868,178 @@
falseFacts.clear();
}
+ /**
+ *
+ * If the argument is known null due to its stamp, there's no need to have an anchor for that
+ * fact and this method returns null.
+ *
+ *
+ *
+ * Otherwise, if an anchor is found it is returned, null otherwise.
+ *
+ */
+ public GuardingNode nonTrivialNullAnchor(ValueNode object) {
+ assert FlowUtil.hasLegalObjectStamp(object);
+ if (StampTool.isObjectAlwaysNull(object)) {
+ return null;
+ }
+ return knownNull.get(GraphUtil.unproxify(object));
+ }
+
+ /**
+ * This method:
+ *
+ * -
+ * attempts to find an existing {@link com.oracle.graal.nodes.extended.GuardingNode} that
+ * implies the property stated by the arguments. If found, returns it as positive evidence.
+ * -
+ * otherwise, if the property of interest is known not to hold, negative evidence is returned.
+ * -
+ * otherwise, null is returned.
+ *
+ */
+ public Evidence outcome(boolean isTrue, LogicNode cond) {
+
+ // attempt to find an anchor for the condition of interest, verbatim
+ if (isTrue) {
+ GuardingNode existingGuard = trueFacts.get(cond);
+ if (existingGuard != null) {
+ return new Evidence(existingGuard);
+ }
+ if (falseFacts.containsKey(cond)) {
+ return Evidence.COUNTEREXAMPLE;
+ }
+ } else {
+ GuardingNode existingGuard = falseFacts.get(cond);
+ if (existingGuard != null) {
+ return new Evidence(existingGuard);
+ }
+ if (trueFacts.containsKey(cond)) {
+ return Evidence.COUNTEREXAMPLE;
+ }
+ }
+
+ if (cond instanceof IsNullNode) {
+ return outcomeIsNullNode(isTrue, (IsNullNode) cond);
+ }
+
+ if (cond instanceof InstanceOfNode) {
+ return outcomeInstanceOfNode(isTrue, (InstanceOfNode) cond);
+ }
+
+ if (cond instanceof ShortCircuitOrNode) {
+ return outcomeShortCircuitOrNode(isTrue, (ShortCircuitOrNode) cond);
+ }
+
+ // can't produce evidence
+ return null;
+ }
+
+ /**
+ * Utility method for {@link #outcome(boolean, com.oracle.graal.nodes.LogicNode)}
+ */
+ private Evidence outcomeIsNullNode(boolean isTrue, IsNullNode isNullNode) {
+ if (isTrue) {
+ // grab an anchor attesting nullness
+ final GuardingNode replacement = nonTrivialNullAnchor(isNullNode.object());
+ if (replacement != null) {
+ return new Evidence(replacement);
+ }
+ if (isNonNull(isNullNode.object())) {
+ return Evidence.COUNTEREXAMPLE;
+ }
+ } else {
+ // grab an anchor attesting non-nullness
+ final Witness w = typeInfo(isNullNode.object());
+ if (w != null && w.isNonNull()) {
+ return new Evidence(w.guard());
+ }
+ if (isNull(isNullNode.object())) {
+ return Evidence.COUNTEREXAMPLE;
+ }
+ }
+ // can't produce evidence
+ return null;
+ }
+
+ /**
+ * Utility method for {@link #outcome(boolean, com.oracle.graal.nodes.LogicNode)}
+ */
+ private Evidence outcomeInstanceOfNode(boolean isTrue, InstanceOfNode iOf) {
+ final Witness w = typeInfo(iOf.object());
+ if (isTrue) {
+ if (isNull(iOf.object())) {
+ return Evidence.COUNTEREXAMPLE;
+ }
+ // grab an anchor attesting instanceof
+ if ((w != null) && (w.type() != null)) {
+ if (w.isNonNull()) {
+ if (iOf.type().isAssignableFrom(w.type())) {
+ return new Evidence(w.guard());
+ }
+ }
+ if (State.knownNotToConform(w.type(), iOf.type())) {
+ // null -> fails instanceof
+ // non-null but non-conformant -> also fails instanceof
+ return Evidence.COUNTEREXAMPLE;
+ }
+ }
+ } else {
+ // grab an anchor attesting not-instanceof
+ // (1 of 2) attempt determining nullness
+ final GuardingNode nullGuard = nonTrivialNullAnchor(iOf.object());
+ if (nullGuard != null) {
+ return new Evidence(nullGuard);
+ }
+ // (2 of 2) attempt determining known-not-to-conform
+ if (w != null && !w.cluelessAboutType()) {
+ if (State.knownNotToConform(w.type(), iOf.type())) {
+ return new Evidence(w.guard());
+ }
+ }
+ }
+ // can't produce evidence
+ return null;
+ }
+
+ /**
+ * Utility method for {@link #outcome(boolean, com.oracle.graal.nodes.LogicNode)}
+ */
+ private Evidence outcomeShortCircuitOrNode(boolean isTrue, ShortCircuitOrNode orNode) {
+ if (!isTrue) {
+ // too tricky to reason about
+ return null;
+ }
+ CastCheckExtractor cce = CastCheckExtractor.extract(orNode);
+ if (cce != null) {
+ // grab an anchor attesting check-cast
+ Witness w = typeInfo(cce.subject);
+ if (w != null && w.type() != null) {
+ if (cce.type.isAssignableFrom(w.type())) {
+ return new Evidence(w.guard());
+ }
+ if (isNonNull(cce.subject) && State.knownNotToConform(w.type(), cce.type)) {
+ return Evidence.COUNTEREXAMPLE;
+ }
+ }
+ }
+ // search for positive-evidence for the first or-input
+ Evidence evidenceX = outcome(!orNode.isXNegated(), orNode.getX());
+ if (evidenceX != null && evidenceX.isPositive()) {
+ return evidenceX;
+ }
+ // search for positive-evidence for the second or-input
+ Evidence evidenceY = outcome(!orNode.isYNegated(), orNode.getY());
+ if (evidenceY != null && evidenceY.isPositive()) {
+ return evidenceY;
+ }
+ // check for contradictions on both or-inputs
+ if (evidenceX != null && evidenceY != null) {
+ assert evidenceX.isNegative() && evidenceY.isNegative();
+ return Evidence.COUNTEREXAMPLE;
+ }
+ // can't produce evidence
+ return null;
+ }
+
}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitCore.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitCore.java Mon May 05 22:18:46 2014 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014, 2014, 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.test;
+
+import java.util.*;
+
+import junit.runner.*;
+
+import org.junit.internal.*;
+import org.junit.runner.*;
+import org.junit.runner.notification.*;
+
+public class GraalJUnitCore {
+
+ /**
+ * Run the tests contained in the classes named in the args
. If all tests run
+ * successfully, exit with a status of 0. Otherwise exit with a status of 1. Write feedback
+ * while tests are running and write stack traces for all failed tests after the tests all
+ * complete.
+ *
+ * @param args names of classes in which to find tests to run
+ */
+ public static void main(String... args) {
+ JUnitSystem system = new RealSystem();
+ JUnitCore junitCore = new JUnitCore();
+ system.out().println("GraalJUnitCore");
+ system.out().println("JUnit version " + Version.id());
+ List> classes = new ArrayList<>();
+ List missingClasses = new ArrayList<>();
+ boolean verbose = false;
+ boolean enableTiming = false;
+ for (String each : args) {
+ if (each.charAt(0) == '-') {
+ // command line arguments
+ if (each.contentEquals("-JUnitVerbose")) {
+ verbose = true;
+ } else if (each.contentEquals("-JUnitEnableTiming")) {
+ enableTiming = true;
+ } else {
+ system.out().println("Unknown command line argument: " + each);
+ }
+
+ } else {
+ try {
+ classes.add(Class.forName(each));
+ } catch (ClassNotFoundException e) {
+ system.out().println("Could not find class: " + each);
+ Description description = Description.createSuiteDescription(each);
+ Failure failure = new Failure(description, e);
+ missingClasses.add(failure);
+ }
+ }
+ }
+ GraalJUnitRunListener graalListener;
+ if (!verbose) {
+ graalListener = new GraalTextListener(system);
+ } else {
+ graalListener = new GraalVerboseTextListener(system);
+ }
+ if (enableTiming) {
+ graalListener = new TimingDecorator(graalListener);
+ }
+ junitCore.addListener(GraalTextListener.createRunListener(graalListener));
+ Result result = junitCore.run(classes.toArray(new Class[0]));
+ for (Failure each : missingClasses) {
+ result.getFailures().add(each);
+ }
+ System.exit(result.wasSuccessful() ? 0 : 1);
+ }
+}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitRunListener.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitRunListener.java Mon May 05 22:18:46 2014 +0200
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014, 2014, 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.test;
+
+import java.io.*;
+
+import org.junit.internal.*;
+import org.junit.runner.*;
+import org.junit.runner.notification.*;
+
+public interface GraalJUnitRunListener {
+
+ /**
+ * Called before any tests have been run.
+ *
+ * @param description describes the tests to be run
+ */
+ public void testRunStarted(Description description);
+
+ /**
+ * Called when all tests have finished
+ *
+ * @param result the summary of the test run, including all the tests that failed
+ */
+ public void testRunFinished(Result result);
+
+ /**
+ * Called when a test class is about to be started.
+ *
+ * @param clazz the test class
+ */
+ void testClassStarted(Class> clazz);
+
+ /**
+ * Called when all tests of a test class have finished.
+ *
+ * @param clazz the test class
+ */
+ void testClassFinished(Class> clazz);
+
+ /**
+ * Called when an atomic test is about to be started. This is also called for ignored tests.
+ *
+ * @param description the description of the test that is about to be run (generally a class and
+ * method name)
+ */
+ void testStarted(Description description);
+
+ /**
+ * Called when an atomic test has finished, whether the test succeeds, fails or is ignored.
+ *
+ * @param description the description of the test that just ran
+ */
+ void testFinished(Description description);
+
+ /**
+ * Called when an atomic test fails.
+ *
+ * @param failure describes the test that failed and the exception that was thrown
+ */
+ void testFailed(Failure failure);
+
+ /**
+ * Called when a test will not be run, generally because a test method is annotated with
+ * {@link org.junit.Ignore}.
+ *
+ * @param description describes the test that will not be run
+ */
+ public void testIgnored(Description description);
+
+ /**
+ * Called when an atomic test succeeds.
+ *
+ * @param description describes the test that will not be run
+ */
+ void testSucceeded(Description description);
+
+ /**
+ * Called when an atomic test flags that it assumes a condition that is false
+ *
+ * @param failure describes the test that failed and the {@link AssumptionViolatedException}
+ * that was thrown
+ */
+ public void testAssumptionFailure(Failure failure);
+
+ /**
+ * Called after {@link #testClassFinished(Class)}.
+ */
+ public void testClassFinishedDelimiter();
+
+ /**
+ * Called after {@link #testClassStarted(Class)}
+ */
+ public void testClassStartedDelimiter();
+
+ /**
+ * Called after {@link #testStarted(Description)}
+ */
+ public void testStartedDelimiter();
+
+ /**
+ * Called after {@link #testFailed(Failure)}
+ */
+ public void testFinishedDelimiter();
+
+ public PrintStream getWriter();
+
+}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitRunListenerDecorator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitRunListenerDecorator.java Mon May 05 22:18:46 2014 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014, 2014, 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.test;
+
+import java.io.*;
+
+import org.junit.runner.*;
+import org.junit.runner.notification.*;
+
+public class GraalJUnitRunListenerDecorator implements GraalJUnitRunListener {
+
+ private final GraalJUnitRunListener l;
+
+ public GraalJUnitRunListenerDecorator(GraalJUnitRunListener l) {
+ this.l = l;
+ }
+
+ @Override
+ public void testRunStarted(Description description) {
+ l.testRunStarted(description);
+ }
+
+ @Override
+ public void testRunFinished(Result result) {
+ l.testRunFinished(result);
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ l.testAssumptionFailure(failure);
+ }
+
+ @Override
+ public void testIgnored(Description description) {
+ l.testIgnored(description);
+ }
+
+ @Override
+ public void testClassStarted(Class> clazz) {
+ l.testClassStarted(clazz);
+ }
+
+ @Override
+ public void testClassFinished(Class> clazz) {
+ l.testClassFinished(clazz);
+ }
+
+ @Override
+ public void testStarted(Description description) {
+ l.testStarted(description);
+ }
+
+ @Override
+ public void testFinished(Description description) {
+ l.testFinished(description);
+ }
+
+ @Override
+ public void testFailed(Failure failure) {
+ l.testFailed(failure);
+ }
+
+ @Override
+ public void testSucceeded(Description description) {
+ l.testSucceeded(description);
+ }
+
+ @Override
+ public PrintStream getWriter() {
+ return l.getWriter();
+ }
+
+ public void testClassFinishedDelimiter() {
+ l.testClassFinishedDelimiter();
+ }
+
+ public void testClassStartedDelimiter() {
+ l.testClassStartedDelimiter();
+ }
+
+ public void testStartedDelimiter() {
+ l.testStartedDelimiter();
+ }
+
+ public void testFinishedDelimiter() {
+ l.testFinishedDelimiter();
+ }
+
+}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTextListener.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTextListener.java Mon May 05 22:18:46 2014 +0200
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2014, 2014, 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.test;
+
+import java.io.*;
+
+import org.junit.internal.*;
+import org.junit.runner.*;
+import org.junit.runner.notification.*;
+
+public class GraalTextListener implements GraalJUnitRunListener {
+
+ private final PrintStream fWriter;
+
+ public GraalTextListener(JUnitSystem system) {
+ this(system.out());
+ }
+
+ public GraalTextListener(PrintStream writer) {
+ fWriter = writer;
+ }
+
+ @Override
+ public PrintStream getWriter() {
+ return fWriter;
+ }
+
+ @Override
+ public void testRunStarted(Description description) {
+ }
+
+ @Override
+ public void testRunFinished(Result result) {
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ }
+
+ @Override
+ public void testClassStarted(Class> clazz) {
+ }
+
+ @Override
+ public void testClassFinished(Class> clazz) {
+ }
+
+ @Override
+ public void testStarted(Description description) {
+ getWriter().print('.');
+ }
+
+ @Override
+ public void testFinished(Description description) {
+ }
+
+ @Override
+ public void testFailed(Failure failure) {
+ getWriter().print('E');
+ }
+
+ @Override
+ public void testSucceeded(Description description) {
+ }
+
+ @Override
+ public void testIgnored(Description description) {
+ getWriter().print('I');
+ }
+
+ @Override
+ public void testClassFinishedDelimiter() {
+ }
+
+ @Override
+ public void testClassStartedDelimiter() {
+ }
+
+ @Override
+ public void testStartedDelimiter() {
+ }
+
+ @Override
+ public void testFinishedDelimiter() {
+ }
+
+ public static RunListener createRunListener(GraalJUnitRunListener l) {
+ return new TextListener(l.getWriter()) {
+ private Class> lastClass;
+ private boolean failed;
+
+ @Override
+ public final void testStarted(Description description) {
+ Class> currentClass = description.getTestClass();
+ if (currentClass != lastClass) {
+ if (lastClass != null) {
+ l.testClassFinished(lastClass);
+ l.testClassFinishedDelimiter();
+ }
+ lastClass = currentClass;
+ l.testClassStarted(currentClass);
+ l.testClassStartedDelimiter();
+ }
+ failed = false;
+ l.testStarted(description);
+ l.testStartedDelimiter();
+ }
+
+ @Override
+ public final void testFailure(Failure failure) {
+ failed = true;
+ l.testFailed(failure);
+ }
+
+ @Override
+ public final void testFinished(Description description) {
+ // we have to do this because there is no callback for successful tests
+ if (!failed) {
+ l.testSucceeded(description);
+ }
+ l.testFinished(description);
+ l.testFinishedDelimiter();
+ }
+
+ @Override
+ public void testIgnored(Description description) {
+ l.testStarted(description);
+ l.testStartedDelimiter();
+ l.testIgnored(description);
+ l.testFinished(description);
+ l.testFinishedDelimiter();
+ }
+
+ @Override
+ public void testRunStarted(Description description) {
+ l.testRunStarted(description);
+ }
+
+ @Override
+ public void testRunFinished(Result result) {
+ if (lastClass != null) {
+ l.testClassFinished(lastClass);
+ }
+ l.testRunFinished(result);
+ super.testRunFinished(result);
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ l.testAssumptionFailure(failure);
+ }
+
+ };
+ }
+
+}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalVerboseTextListener.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalVerboseTextListener.java Mon May 05 22:18:46 2014 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014, 2014, 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.test;
+
+import java.io.*;
+
+import org.junit.internal.*;
+import org.junit.runner.*;
+import org.junit.runner.notification.*;
+
+public class GraalVerboseTextListener extends GraalTextListener {
+
+ public GraalVerboseTextListener(JUnitSystem system) {
+ this(system.out());
+ }
+
+ public GraalVerboseTextListener(PrintStream writer) {
+ super(writer);
+ }
+
+ @Override
+ public void testClassStarted(Class> clazz) {
+ getWriter().print(clazz.getName() + " started");
+ }
+
+ @Override
+ public void testClassFinished(Class> clazz) {
+ getWriter().print(clazz.getName() + " finished");
+ }
+
+ @Override
+ public void testStarted(Description description) {
+ getWriter().print(" " + description.getMethodName() + ": ");
+ }
+
+ @Override
+ public void testIgnored(Description description) {
+ getWriter().print("Ignored");
+ }
+
+ @Override
+ public void testSucceeded(Description description) {
+ getWriter().print("Passed");
+ }
+
+ @Override
+ public void testFailed(Failure failure) {
+ getWriter().print("FAILED");
+ }
+
+ @Override
+ public void testClassFinishedDelimiter() {
+ getWriter().println();
+ }
+
+ @Override
+ public void testClassStartedDelimiter() {
+ getWriter().println();
+ }
+
+ @Override
+ public void testFinishedDelimiter() {
+ getWriter().println();
+ }
+
+}
diff -r ff5cacf47b68 -r a3f897fb3289 graal/com.oracle.graal.test/src/com/oracle/graal/test/TimingDecorator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/TimingDecorator.java Mon May 05 22:18:46 2014 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, 2014, 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.test;
+
+import org.junit.runner.*;
+
+/**
+ * Timing support for JUnit test runs.
+ */
+public class TimingDecorator extends GraalJUnitRunListenerDecorator {
+
+ private long startTime;
+ private long classStartTime;
+
+ public TimingDecorator(GraalJUnitRunListener l) {
+ super(l);
+ }
+
+ @Override
+ public void testClassStarted(Class> clazz) {
+ classStartTime = System.nanoTime();
+ super.testClassStarted(clazz);
+ }
+
+ @Override
+ public void testClassFinished(Class> clazz) {
+ long totalTime = System.nanoTime() - classStartTime;
+ super.testClassFinished(clazz);
+ getWriter().print(' ' + valueToString(totalTime));
+ }
+
+ @Override
+ public void testStarted(Description description) {
+ startTime = System.nanoTime();
+ super.testStarted(description);
+ }
+
+ @Override
+ public void testFinished(Description description) {
+ long totalTime = System.nanoTime() - startTime;
+ super.testFinished(description);
+ getWriter().print(" " + valueToString(totalTime));
+ }
+
+ private static String valueToString(long value) {
+ return String.format("%d.%d ms", value / 1000000, (value / 100000) % 10);
+ }
+
+}
diff -r ff5cacf47b68 -r a3f897fb3289 mx/JUnitWrapper.java
--- a/mx/JUnitWrapper.java Sat May 03 21:46:35 2014 +0200
+++ b/mx/JUnitWrapper.java Mon May 05 22:18:46 2014 +0200
@@ -27,8 +27,7 @@
* linux [depending on the settings]: ~2097k)
* see http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx
*/
-
-import org.junit.runner.*;
+import com.oracle.graal.test.*;
import java.io.*;
import java.util.*;
@@ -44,6 +43,10 @@
System.exit(1);
}
ArrayList tests = new ArrayList(1000);
+ // add JUnit command line arguments
+ for (int i = 1; i < args.length; i++) {
+ tests.add(args[i]);
+ }
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(args[0]));
@@ -72,6 +75,6 @@
} else {
System.out.printf("executing junit tests now... (%d test classes)\n", strargs.length);
}
- JUnitCore.main(strargs);
+ GraalJUnitCore.main(strargs);
}
}
diff -r ff5cacf47b68 -r a3f897fb3289 mx/mx_graal.py
--- a/mx/mx_graal.py Sat May 03 21:46:35 2014 +0200
+++ b/mx/mx_graal.py Mon May 05 22:18:46 2014 +0200
@@ -946,7 +946,7 @@
f_testfile.close()
harness(projectscp, vmArgs)
-def _unittest(args, annotations, prefixcp="", whitelist=None):
+def _unittest(args, annotations, prefixcp="", whitelist=None, verbose=False, enable_timing=False):
mxdir = dirname(__file__)
name = 'JUnitWrapper'
javaSource = join(mxdir, name + '.java')
@@ -955,6 +955,12 @@
if testfile is None:
(_, testfile) = tempfile.mkstemp(".testclasses", "graal")
os.close(_)
+ corecp = mx.classpath(['com.oracle.graal.test'])
+ coreArgs = []
+ if verbose:
+ coreArgs.append('-JUnitVerbose')
+ if enable_timing:
+ coreArgs.append('-JUnitEnableTiming')
def harness(projectscp, vmArgs):
if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource):
@@ -968,9 +974,9 @@
if len(testclasses) == 1:
# Execute Junit directly when one test is being run. This simplifies
# replaying the VM execution in a native debugger (e.g., gdb).
- vm(prefixArgs + vmArgs + ['-cp', prefixcp + projectscp, 'org.junit.runner.JUnitCore'] + testclasses)
+ vm(prefixArgs + vmArgs + ['-cp', prefixcp + corecp + ':' + projectscp, 'com.oracle.graal.test.GraalJUnitCore'] + coreArgs + testclasses)
else:
- vm(prefixArgs + vmArgs + ['-cp', prefixcp + projectscp + os.pathsep + mxdir, name] + [testfile])
+ vm(prefixArgs + vmArgs + ['-cp', prefixcp + corecp + ':' + projectscp + os.pathsep + mxdir, name] + [testfile] + coreArgs)
try:
_run_tests(args, harness, annotations, testfile, whitelist)
@@ -983,6 +989,8 @@
--whitelist run only testcases which are included
in the given whitelist
+ --verbose enable verbose JUnit output
+ --enable-timing enable JUnit test timing
To avoid conflicts with VM options '--' can be used as delimiter.
@@ -1020,6 +1028,8 @@
epilog=_unittestHelpSuffix,
)
parser.add_argument('--whitelist', help='run testcases specified in whitelist only', metavar='')
+ parser.add_argument('--verbose', help='enable verbose JUnit output', action='store_true')
+ parser.add_argument('--enable-timing', help='enable JUnit test timing', action='store_true')
ut_args = []
delimiter = False
@@ -1046,7 +1056,7 @@
except IOError:
mx.log('warning: could not read whitelist: ' + parsed_args.whitelist)
- _unittest(args, ['@Test', '@Parameters'], whitelist=whitelist)
+ _unittest(args, ['@Test', '@Parameters'], whitelist=whitelist, verbose=parsed_args.verbose, enable_timing=parsed_args.enable_timing)
def shortunittest(args):
"""alias for 'unittest --whitelist test/whitelist_shortunittest.txt'{0}"""
@@ -1158,12 +1168,12 @@
with VM('server', 'product'): # hosted mode
t = Task('UnitTests:hosted-product')
- unittest([])
+ unittest(['--enable-timing', '--verbose'])
tasks.append(t.stop())
with VM('server', 'product'): # hosted mode
t = Task('UnitTests-BaselineCompiler:hosted-product')
- unittest(['--whitelist', 'test/whitelist_baseline.txt', '-G:+UseBaselineCompiler'])
+ unittest(['--enable-timing', '--verbose', '--whitelist', 'test/whitelist_baseline.txt', '-G:+UseBaselineCompiler'])
tasks.append(t.stop())
for vmbuild in ['fastdebug', 'product']:
diff -r ff5cacf47b68 -r a3f897fb3289 mxtool/mx.py
--- a/mxtool/mx.py Sat May 03 21:46:35 2014 +0200
+++ b/mxtool/mx.py Mon May 05 22:18:46 2014 +0200
@@ -1300,8 +1300,21 @@
time.sleep(delay)
# Makes the current subprocess accessible to the abort() function
-# This is a tuple of the Popen object and args.
-_currentSubprocess = (None, None)
+# This is a list of tuples of the subprocess.Popen or
+# multiprocessing.Process object and args.
+_currentSubprocesses = []
+
+def _addSubprocess(p, args):
+ entry = (p, args)
+ _currentSubprocesses.append(entry)
+ return entry
+
+def _removeSubprocess(entry):
+ if entry and entry in _currentSubprocesses:
+ try:
+ _currentSubprocesses.remove(entry)
+ except:
+ pass
def waitOn(p):
if get_os() == 'windows':
@@ -1340,8 +1353,7 @@
if timeout is None and _opts.ptimeout != 0:
timeout = _opts.ptimeout
- global _currentSubprocess
-
+ sub = None
try:
# On Unix, the new subprocess should be in a separate group so that a timeout alarm
# can use os.killpg() to kill the whole subprocess group
@@ -1359,7 +1371,7 @@
stdout = out if not callable(out) else subprocess.PIPE
stderr = err if not callable(err) else subprocess.PIPE
p = subprocess.Popen(args, cwd=cwd, stdout=stdout, stderr=stderr, preexec_fn=preexec_fn, creationflags=creationflags, env=env)
- _currentSubprocess = (p, args)
+ sub = _addSubprocess(p, args)
if callable(out):
t = Thread(target=redirect, args=(p.stdout, out))
t.daemon = True # thread dies with the program
@@ -1382,7 +1394,7 @@
except KeyboardInterrupt:
abort(1)
finally:
- _currentSubprocess = (None, None)
+ _removeSubprocess(sub)
if retcode and nonZeroIsFatal:
if _opts.verbose:
@@ -1663,21 +1675,20 @@
return result
def _send_sigquit():
- p, args = _currentSubprocess
-
- def _isJava():
- if args:
- name = args[0].split(os.sep)[-1]
- return name == "java"
- return False
-
- if p is not None and _isJava():
- if get_os() == 'windows':
- log("mx: implement me! want to send SIGQUIT to my child process")
- else:
- _kill_process_group(p.pid, sig=signal.SIGQUIT)
- time.sleep(0.1)
-
+ for p, args in _currentSubprocesses:
+
+ def _isJava():
+ if args:
+ name = args[0].split(os.sep)[-1]
+ return name == "java"
+ return False
+
+ if p is not None and _isJava():
+ if get_os() == 'windows':
+ log("mx: implement me! want to send SIGQUIT to my child process")
+ else:
+ _kill_process_group(p.pid, sig=signal.SIGQUIT)
+ time.sleep(0.1)
def abort(codeOrMessage):
"""
@@ -1692,12 +1703,14 @@
# import traceback
# traceback.print_stack()
- p, _ = _currentSubprocess
- if p is not None:
- if get_os() == 'windows':
- p.kill()
- else:
- _kill_process_group(p.pid, signal.SIGKILL)
+ for p, args in _currentSubprocesses:
+ try:
+ if get_os() == 'windows':
+ p.terminate()
+ else:
+ _kill_process_group(p.pid, signal.SIGKILL)
+ except BaseException as e:
+ log('error while killing subprocess {} "{}": {}'.format(p.pid, ' '.join(args), e))
raise SystemExit(codeOrMessage)
@@ -1798,7 +1811,7 @@
return get_env('JDT', join(_primary_suite.mxDir, 'ecj.jar'))
class JavaCompileTask:
- def __init__(self, args, proj, reason, javafilelist, jdk, outputDir, deps):
+ def __init__(self, args, proj, reason, javafilelist, jdk, outputDir, jdtJar, deps):
self.proj = proj
self.reason = reason
self.javafilelist = javafilelist
@@ -1806,6 +1819,7 @@
self.jdk = jdk
self.outputDir = outputDir
self.done = False
+ self.jdtJar = jdtJar
self.args = args
def __str__(self):
@@ -1840,20 +1854,8 @@
cp = classpath(self.proj.name, includeSelf=True)
toBeDeleted = [argfileName]
- jdtJar = None
- if not args.javac and args.jdt is not None:
- if not args.jdt.endswith('.jar'):
- abort('Path for Eclipse batch compiler does not look like a jar file: ' + args.jdt)
- jdtJar = args.jdt
- if not exists(jdtJar):
- if os.path.abspath(jdtJar) == os.path.abspath(_defaultEcjPath()) and get_env('JDT', None) is None:
- # Silently ignore JDT if default location is used but does not exist
- jdtJar = None
- else:
- abort('Eclipse batch compiler jar does not exist: ' + args.jdt)
-
try:
- if not jdtJar:
+ if not self.jdtJar:
mainJava = java()
if not args.error_prone:
self.logCompilation('javac')
@@ -1878,7 +1880,7 @@
else:
self.logCompilation('JDT')
- jdtVmArgs = ['-Xmx1g', '-jar', jdtJar]
+ jdtVmArgs = ['-Xmx1g', '-jar', self.jdtJar]
jdtArgs = ['-' + compliance,
'-cp', cp, '-g', '-enableJavadoc',
@@ -1946,12 +1948,23 @@
compilerSelect.add_argument('--jdt', help='path to ecj.jar, the Eclipse batch compiler', default=_defaultEcjPath(), metavar='')
compilerSelect.add_argument('--force-javac', action='store_true', dest='javac', help='use javac despite ecj.jar is found or not')
-
if suppliedParser:
parser.add_argument('remainder', nargs=REMAINDER, metavar='...')
args = parser.parse_args(args)
+ jdtJar = None
+ if not args.javac and args.jdt is not None:
+ if not args.jdt.endswith('.jar'):
+ abort('Path for Eclipse batch compiler does not look like a jar file: ' + args.jdt)
+ jdtJar = args.jdt
+ if not exists(jdtJar):
+ if os.path.abspath(jdtJar) == os.path.abspath(_defaultEcjPath()) and get_env('JDT', None) is None:
+ # Silently ignore JDT if default location is used but does not exist
+ jdtJar = None
+ else:
+ abort('Eclipse batch compiler jar does not exist: ' + args.jdt)
+
if args.only is not None:
# N.B. This build will not include dependencies including annotation processor dependencies
sortedProjects = [project(name) for name in args.only.split(',')]
@@ -2087,7 +2100,7 @@
logv('[no Java sources for {0} - skipping]'.format(p.name))
continue
- task = JavaCompileTask(args, p, buildReason, javafilelist, jdk, outputDir, taskDeps)
+ task = JavaCompileTask(args, p, buildReason, javafilelist, jdk, outputDir, jdtJar, taskDeps)
if args.parallelize:
# Best to initialize class paths on main process
@@ -2113,6 +2126,7 @@
if t.proc.is_alive():
active.append(t)
else:
+ _removeSubprocess(t.sub)
if t.proc.exitcode != 0:
return ([], joinTasks(tasks))
return (active, [])
@@ -2126,10 +2140,18 @@
task._d = max([remainingDepsDepth(t) for t in incompleteDeps]) + 1
return task._d
+ def compareTasks(t1, t2):
+ d = remainingDepsDepth(t1) - remainingDepsDepth(t2)
+ if d == 0:
+ t1Work = (1 + len(t1.proj.annotation_processors())) * len(t1.javafilelist)
+ t2Work = (1 + len(t2.proj.annotation_processors())) * len(t2.javafilelist)
+ d = t1Work - t2Work
+ return d
+
def sortWorklist(tasks):
for t in tasks:
t._d = None
- return sorted(tasks, lambda x, y: remainingDepsDepth(x) - remainingDepsDepth(y))
+ return sorted(tasks, compareTasks)
import multiprocessing
cpus = multiprocessing.cpu_count()
@@ -2162,6 +2184,7 @@
task.proc = multiprocessing.Process(target=executeTask, args=(task,))
task.proc.start()
active.append(task)
+ task.sub = _addSubprocess(task.proc, ['JavaCompileTask', str(task)])
if len(active) == cpus:
break
diff -r ff5cacf47b68 -r a3f897fb3289 src/cpu/x86/vm/templateTable_x86_64.cpp
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp Sat May 03 21:46:35 2014 +0200
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Mon May 05 22:18:46 2014 +0200
@@ -107,10 +107,6 @@
return Address(rsp, Interpreter::expr_offset_in_bytes(2));
}
-static inline Address at_tos_p3() {
- return Address(rsp, Interpreter::expr_offset_in_bytes(3));
-}
-
// Condition conversion
static Assembler::Condition j_not(TemplateTable::Condition cc) {
switch (cc) {
diff -r ff5cacf47b68 -r a3f897fb3289 src/share/vm/code/nmethod.cpp
--- a/src/share/vm/code/nmethod.cpp Sat May 03 21:46:35 2014 +0200
+++ b/src/share/vm/code/nmethod.cpp Mon May 05 22:18:46 2014 +0200
@@ -1064,7 +1064,6 @@
void nmethod::print_on(outputStream* st, const char* msg) const {
if (st != NULL) {
ttyLocker ttyl;
- if (CIPrintCompilerName) st->print("%s:", compiler()->name());
if (WizardMode) {
CompileTask::print_compilation(st, this, msg, /*short_form:*/ true);
st->print_cr(" (" INTPTR_FORMAT ")", this);
diff -r ff5cacf47b68 -r a3f897fb3289 src/share/vm/compiler/compileBroker.cpp
--- a/src/share/vm/compiler/compileBroker.cpp Sat May 03 21:46:35 2014 +0200
+++ b/src/share/vm/compiler/compileBroker.cpp Mon May 05 22:18:46 2014 +0200
@@ -370,8 +370,6 @@
// CompileTask::print_line
void CompileTask::print_line() {
ttyLocker ttyl; // keep the following output all in one block
- // print compiler name if requested
- if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler_name(comp_level()));
print_compilation();
}
@@ -384,6 +382,8 @@
if (!short_form) {
st->print("%7d ", (int) st->time_stamp().milliseconds()); // print timestamp
}
+ // print compiler name if requested
+ if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler_name(comp_level));
st->print("%4d ", compile_id); // print compilation number
// For unloaded methods the transition to zombie occurs after the
diff -r ff5cacf47b68 -r a3f897fb3289 src/share/vm/graal/graalCompiler.cpp
--- a/src/share/vm/graal/graalCompiler.cpp Sat May 03 21:46:35 2014 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp Mon May 05 22:18:46 2014 +0200
@@ -48,10 +48,6 @@
return;
}
- ThreadToNativeFromVM trans(JavaThread::current());
- JavaThread* THREAD = JavaThread::current();
- TRACE_graal_1("GraalCompiler::initialize");
-
uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
AMD64_ONLY(guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)"));
@@ -71,6 +67,10 @@
}
#endif
+ ThreadToNativeFromVM trans(JavaThread::current());
+ JavaThread* THREAD = JavaThread::current();
+ TRACE_graal_1("GraalCompiler::initialize");
+
JNIEnv *env = ((JavaThread *) Thread::current())->jni_environment();
jclass klass = env->FindClass("com/oracle/graal/hotspot/bridge/CompilerToVMImpl");
if (klass == NULL) {
diff -r ff5cacf47b68 -r a3f897fb3289 src/share/vm/prims/jvmtiTagMap.cpp
--- a/src/share/vm/prims/jvmtiTagMap.cpp Sat May 03 21:46:35 2014 +0200
+++ b/src/share/vm/prims/jvmtiTagMap.cpp Mon May 05 22:18:46 2014 +0200
@@ -2790,6 +2790,7 @@
return true;
}
+#ifdef ASSERT
// verify that a static oop field is in range
static inline bool verify_static_oop(InstanceKlass* ik,
oop mirror, int offset) {
@@ -2804,6 +2805,7 @@
return false;
}
}
+#endif // #ifdef ASSERT
// a class references its super class, interfaces, class loader, ...
// and finally its static fields
diff -r ff5cacf47b68 -r a3f897fb3289 src/share/vm/runtime/mutex.cpp
--- a/src/share/vm/runtime/mutex.cpp Sat May 03 21:46:35 2014 +0200
+++ b/src/share/vm/runtime/mutex.cpp Mon May 05 22:18:46 2014 +0200
@@ -280,16 +280,6 @@
return x & 0x7FFFFFFF ;
}
-static inline jint MarsagliaXOR (jint * const a) {
- jint x = *a ;
- if (x == 0) x = UNS(a)|1 ;
- x ^= x << 6;
- x ^= ((unsigned)x) >> 21;
- x ^= x << 7 ;
- *a = x ;
- return x & 0x7FFFFFFF ;
-}
-
static int Stall (int its) {
static volatile jint rv = 1 ;
volatile int OnFrame = 0 ;