# HG changeset patch # User Thomas Wuerthinger # Date 1329942248 -3600 # Node ID 03ea39a3cf681771dce3843f92e8f5149e2508b3 # Parent c2384f5b2e6e1c243acddb13acc51fa545668515# Parent 7167f487cc3146968acb629eeac12d777e5687da Merge. diff -r c2384f5b2e6e -r 03ea39a3cf68 graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAssumptions.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAssumptions.java Wed Feb 22 14:07:10 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAssumptions.java Wed Feb 22 21:24:08 2012 +0100 @@ -34,16 +34,10 @@ */ public final class CiAssumptions implements Serializable, Iterable { - /** - * - */ private static final long serialVersionUID = 5152062717588239131L; public abstract static class Assumption implements Serializable { - /** - * - */ private static final long serialVersionUID = -1936652569665112915L; } @@ -51,9 +45,7 @@ * An assumption about a unique subtype of a given type. */ public static final class ConcreteSubtype extends Assumption { - /** - * - */ + private static final long serialVersionUID = -1457173265437676252L; /** @@ -95,9 +87,6 @@ */ public static final class ConcreteMethod extends Assumption { - /** - * - */ private static final long serialVersionUID = -7636746737947390059L; /** @@ -143,6 +132,37 @@ } /** + * An assumption that specified that a method was used during the compilation. + */ + public static final class MethodContents extends Assumption { + + private static final long serialVersionUID = -4821594103928571659L; + + public final RiResolvedMethod method; + + public MethodContents(RiResolvedMethod method) { + this.method = method; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + method.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ConcreteMethod) { + ConcreteMethod other = (ConcreteMethod) obj; + return other.method == method; + } + return false; + } + } + + /** * Array with the assumptions. This field is directly accessed from C++ code in the Graal/HotSpot implementation. */ private Assumption[] list; @@ -209,6 +229,15 @@ record(new ConcreteMethod(method, context, impl)); } + /** + * Records that {@code method} was used during the compilation. + * + * @param method a method whose contents were used + */ + public void recordMethodContents(RiResolvedMethod method) { + record(new MethodContents(method)); + } + private void record(Assumption assumption) { if (list == null) { list = new Assumption[4]; diff -r c2384f5b2e6e -r 03ea39a3cf68 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Wed Feb 22 14:07:10 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Wed Feb 22 21:24:08 2012 +0100 @@ -197,6 +197,13 @@ assumptions.recordConcreteMethod(method, context, impl); } + @Override + public void recordMethodContentsAssumption(RiResolvedMethod method) { + if (assumptions != null) { + assumptions.recordMethodContents(method); + } + } + private static int computeInliningLevel(Invoke invoke) { int count = 0; FrameState curState = invoke.stateAfter(); diff -r c2384f5b2e6e -r 03ea39a3cf68 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Wed Feb 22 14:07:10 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Wed Feb 22 21:24:08 2012 +0100 @@ -48,6 +48,7 @@ public interface InliningCallback { StructuredGraph buildGraph(RiResolvedMethod method); double inliningWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke); + void recordMethodContentsAssumption(RiResolvedMethod method); void recordConcreteMethodAssumption(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl); } @@ -129,6 +130,7 @@ public void inline(StructuredGraph compilerGraph, GraalRuntime runtime, final InliningCallback callback) { StructuredGraph graph = getGraph(concrete, callback); assert !IntrinsificationPhase.canIntrinsify(invoke, concrete, runtime); + callback.recordMethodContentsAssumption(concrete); InliningUtil.inline(invoke, graph, true); } @@ -189,6 +191,7 @@ StructuredGraph calleeGraph = getGraph(concrete, callback); assert !IntrinsificationPhase.canIntrinsify(invoke, concrete, runtime); + callback.recordMethodContentsAssumption(concrete); InliningUtil.inline(invoke, calleeGraph, false); } @@ -333,6 +336,7 @@ RiResolvedMethod concrete = concretes.get(i); StructuredGraph calleeGraph = getGraph(concrete, callback); + callback.recordMethodContentsAssumption(concrete); assert !IntrinsificationPhase.canIntrinsify(invokeForInlining, concrete, runtime); InliningUtil.inline(invokeForInlining, calleeGraph, false); } @@ -371,6 +375,7 @@ RiResolvedMethod concrete = concretes.get(0); StructuredGraph calleeGraph = getGraph(concrete, callback); assert !IntrinsificationPhase.canIntrinsify(invoke, concrete, runtime); + callback.recordMethodContentsAssumption(concrete); InliningUtil.inline(invoke, calleeGraph, false); } diff -r c2384f5b2e6e -r 03ea39a3cf68 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/Condition.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/Condition.java Wed Feb 22 14:07:10 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/Condition.java Wed Feb 22 21:24:08 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -273,4 +273,180 @@ assert false : "missed folding of constant operands: " + lt + " " + this + " " + rt; return null; } + + public Condition join(Condition other) { + if (other == this) { + return this; + } + if (this == OF || this == NOF || other == OF || other == NOF) { + return null; + } + switch (this) { + case EQ: + if (other == LE || other == GE || other == BE || other == AE) { + return EQ; + } else { + return null; + } + case NE: + if (other == LT || other == GT || other == BT || other == AT) { + return other; + } else if (other == LE) { + return LT; + } else if (other == GE) { + return GT; + } else if (other == BE) { + return BT; + } else if (other == AE) { + return AT; + } else { + return null; + } + case LE: + if (other == GE || other == EQ) { + return EQ; + } else if (other == NE || other == LT) { + return LT; + } else { + return null; + } + case LT: + if (other == NE || other == LE) { + return LT; + } else { + return null; + } + case GE: + if (other == LE || other == EQ) { + return EQ; + } else if (other == NE || other == GT) { + return GT; + } else { + return null; + } + case GT: + if (other == NE || other == GE) { + return GT; + } else { + return null; + } + case BE: + if (other == AE || other == EQ) { + return EQ; + } else if (other == NE || other == BT) { + return BT; + } else { + return null; + } + case BT: + if (other == NE || other == BE) { + return BT; + } else { + return null; + } + case AE: + if (other == BE || other == EQ) { + return EQ; + } else if (other == NE || other == AT) { + return AT; + } else { + return null; + } + case AT: + if (other == NE || other == AE) { + return AT; + } else { + return null; + } + } + throw new IllegalArgumentException(this.toString()); + } + + public Condition meet(Condition other) { + if (other == this) { + return this; + } + if (this == OF || this == NOF || other == OF || other == NOF) { + return null; + } + switch (this) { + case EQ: + if (other == LE || other == GE || other == BE || other == AE) { + return other; + } else if (other == LT) { + return LE; + } else if (other == GT) { + return GE; + } else if (other == BT) { + return BE; + } else if (other == AT) { + return AE; + } else { + return null; + } + case NE: + if (other == LT || other == GT || other == BT || other == AT) { + return NE; + } else { + return null; + } + case LE: + if (other == EQ || other == LT) { + return LE; + } else { + return null; + } + case LT: + if (other == EQ || other == LE) { + return LE; + } else if (other == NE || other == GT) { + return NE; + } else { + return null; + } + case GE: + if (other == EQ || other == GT) { + return GE; + } else { + return null; + } + case GT: + if (other == EQ || other == GE) { + return GE; + } else if (other == NE || other == LT) { + return NE; + } else { + return null; + } + case BE: + if (other == EQ || other == BT) { + return BE; + } else { + return null; + } + case BT: + if (other == EQ || other == BE) { + return BE; + } else if (other == NE || other == AT) { + return NE; + } else { + return null; + } + case AE: + if (other == EQ || other == AT) { + return AE; + } else { + return null; + } + case AT: + if (other == EQ || other == AE) { + return AE; + } else if (other == NE || other == BT) { + return NE; + } else { + return null; + } + } + throw new IllegalArgumentException(this.toString()); + } } diff -r c2384f5b2e6e -r 03ea39a3cf68 graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/ConditionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/ConditionTest.java Wed Feb 22 21:24:08 2012 +0100 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012, 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.max.graal.compiler.tests; + +import static org.junit.Assert.*; + +import java.util.*; + +import org.junit.*; + +import com.oracle.max.cri.ci.*; +import com.oracle.max.graal.nodes.calc.*; + + +public class ConditionTest { + + @Test + public void testImplies() { + Random rand = new Random(13); + for (Condition c1 : Condition.values()) { + for (Condition c2 : Condition.values()) { + boolean implies = c1.implies(c2); + if (implies && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) { + for (int i = 0; i < 10000; i++) { + CiConstant a = CiConstant.forInt(rand.nextInt()); + CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt()); + boolean result1 = c1.foldCondition(a, b, null, false); + boolean result2 = c2.foldCondition(a, b, null, false); + if (result1 && implies) { + assertTrue(result2); + } + } + } + } + } + } + + @Test + public void testJoin() { + Random rand = new Random(13); + for (Condition c1 : Condition.values()) { + for (Condition c2 : Condition.values()) { + Condition join = c1.join(c2); + assertTrue(join == c2.join(c1)); + if (join != null && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) { + for (int i = 0; i < 10000; i++) { + CiConstant a = CiConstant.forInt(rand.nextInt()); + CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt()); + boolean result1 = c1.foldCondition(a, b, null, false); + boolean result2 = c2.foldCondition(a, b, null, false); + boolean resultJoin = join.foldCondition(a, b, null, false); + if (result1 && result2) { + assertTrue(resultJoin); + } + } + } + } + } + } + + @Test + public void testMeet() { + Random rand = new Random(13); + for (Condition c1 : Condition.values()) { + for (Condition c2 : Condition.values()) { + Condition meet = c1.meet(c2); + assertTrue(meet == c2.meet(c1)); + if (meet != null && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) { + for (int i = 0; i < 10000; i++) { + CiConstant a = CiConstant.forInt(rand.nextInt()); + CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt()); + boolean result1 = c1.foldCondition(a, b, null, false); + boolean result2 = c2.foldCondition(a, b, null, false); + boolean resultMeet = meet.foldCondition(a, b, null, false); + if (result1 || result2) { + assertTrue(resultMeet); + } + } + } + } + } + } + +} diff -r c2384f5b2e6e -r 03ea39a3cf68 src/cpu/x86/vm/frame_x86.cpp --- a/src/cpu/x86/vm/frame_x86.cpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/cpu/x86/vm/frame_x86.cpp Wed Feb 22 21:24:08 2012 +0100 @@ -301,6 +301,11 @@ ptr_at_put(interpreter_frame_sender_sp_offset, (intptr_t) sender_sp); } +intptr_t** frame::interpreter_frame_sender_sp_addr() const { + assert(is_interpreted_frame(), "interpreted frame expected"); + return (intptr_t**) addr_at(interpreter_frame_sender_sp_offset); +} + // monitor elements diff -r c2384f5b2e6e -r 03ea39a3cf68 src/cpu/x86/vm/frame_x86.hpp --- a/src/cpu/x86/vm/frame_x86.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/cpu/x86/vm/frame_x86.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -197,6 +197,7 @@ // expression stack tos if we are nested in a java call intptr_t* interpreter_frame_last_sp() const; + intptr_t** interpreter_frame_last_sp_addr() const; // helper to update a map with callee-saved RBP static void update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr); diff -r c2384f5b2e6e -r 03ea39a3cf68 src/cpu/x86/vm/frame_x86.inline.hpp --- a/src/cpu/x86/vm/frame_x86.inline.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/cpu/x86/vm/frame_x86.inline.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -131,8 +131,9 @@ -inline intptr_t* frame::link() const { return (intptr_t*) *(intptr_t **)addr_at(link_offset); } -inline void frame::set_link(intptr_t* addr) { *(intptr_t **)addr_at(link_offset) = addr; } +inline intptr_t* frame::link() const { return (intptr_t*) *(intptr_t **)addr_at(link_offset); } +inline intptr_t** frame::link_addr() const { return (intptr_t **)addr_at(link_offset); } +inline void frame::set_link(intptr_t* addr) { *(intptr_t **)addr_at(link_offset) = addr; } inline intptr_t* frame::unextended_sp() const { return _unextended_sp; } @@ -208,6 +209,10 @@ return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset); } +inline intptr_t** frame::interpreter_frame_last_sp_addr() const { + return (intptr_t**)addr_at(interpreter_frame_last_sp_offset); +} + inline intptr_t* frame::interpreter_frame_bcx_addr() const { return (intptr_t*)addr_at(interpreter_frame_bcx_offset); } diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -198,6 +198,7 @@ template(HotSpotExceptionHandler_klass, com_oracle_max_graal_hotspot_HotSpotExceptionHandler, Opt) \ template(HotSpotProxy_klass, com_oracle_max_graal_hotspot_HotSpotProxy, Opt) \ template(CiAssumptions_klass, com_oracle_max_cri_ci_CiAssumptions, Opt) \ + template(CiAssumptions_MethodContents_klass, com_oracle_max_cri_ci_CiAssumptions_MethodContents, Opt) \ template(CiAssumptions_ConcreteSubtype_klass, com_oracle_max_cri_ci_CiAssumptions_ConcreteSubtype, Opt) \ template(CiAssumptions_ConcreteMethod_klass, com_oracle_max_cri_ci_CiAssumptions_ConcreteMethod, Opt) \ template(CiTargetMethod_klass, com_oracle_max_cri_ci_CiTargetMethod, Opt) \ diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -288,6 +288,7 @@ template(com_oracle_max_cri_ri_RiConstantPool, "com/oracle/max/cri/ri/RiConstantPool") \ template(com_oracle_max_cri_ri_RiExceptionHandler, "com/oracle/max/cri/ri/RiExceptionHandler") \ template(com_oracle_max_cri_ci_CiAssumptions, "com/oracle/max/cri/ci/CiAssumptions") \ + template(com_oracle_max_cri_ci_CiAssumptions_MethodContents, "com/oracle/max/cri/ci/CiAssumptions$MethodContents") \ template(com_oracle_max_cri_ci_CiAssumptions_ConcreteSubtype, "com/oracle/max/cri/ci/CiAssumptions$ConcreteSubtype") \ template(com_oracle_max_cri_ci_CiAssumptions_ConcreteMethod, "com/oracle/max/cri/ci/CiAssumptions$ConcreteMethod") \ template(com_oracle_max_cri_ci_CiGenericCallback, "com/oracle/max/cri/ci/CiGenericCallback") \ diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Feb 22 21:24:08 2012 +0100 @@ -245,7 +245,9 @@ for (int i = 0; i < length; ++i) { Handle assumption = assumptions->obj_at(i); if (!assumption.is_null()) { - if (assumption->klass() == CiAssumptions_ConcreteSubtype::klass()) { + if (assumption->klass() == CiAssumptions_MethodContents::klass()) { + assumption_MethodContents(assumption); + } else if (assumption->klass() == CiAssumptions_ConcreteSubtype::klass()) { assumption_ConcreteSubtype(assumption); } else if (assumption->klass() == CiAssumptions_ConcreteMethod::klass()) { assumption_ConcreteMethod(assumption); @@ -371,6 +373,14 @@ } } +void CodeInstaller::assumption_MethodContents(Handle assumption) { + Handle method_handle = CiAssumptions_MethodContents::method(assumption()); + methodHandle method = getMethodFromHotSpotMethod(method_handle()); + ciMethod* m = (ciMethod*) CURRENT_ENV->get_object(method()); + + _dependencies->assert_evol_method(m); +} + void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) { Handle context_handle = CiAssumptions_ConcreteSubtype::context(assumption()); ciKlass* context = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(context_handle))); diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -97,6 +97,7 @@ // perform data and call relocation on the CodeBuffer void initialize_buffer(CodeBuffer& buffer); + void assumption_MethodContents(Handle assumption); void assumption_ConcreteSubtype(Handle assumption); void assumption_ConcreteMethod(Handle assumption); diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -115,12 +115,15 @@ start_class(CiAssumptions) \ oop_field(CiAssumptions, list, "[Lcom/oracle/max/cri/ci/CiAssumptions$Assumption;") \ end_class \ + start_class(CiAssumptions_MethodContents) \ + oop_field(CiAssumptions_MethodContents, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \ + end_class \ start_class(CiAssumptions_ConcreteSubtype) \ oop_field(CiAssumptions_ConcreteSubtype, context, "Lcom/oracle/max/cri/ri/RiResolvedType;") \ oop_field(CiAssumptions_ConcreteSubtype, subtype, "Lcom/oracle/max/cri/ri/RiResolvedType;") \ end_class \ start_class(CiAssumptions_ConcreteMethod) \ - oop_field(CiAssumptions_ConcreteMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \ + oop_field(CiAssumptions_ConcreteMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \ oop_field(CiAssumptions_ConcreteMethod, context, "Lcom/oracle/max/cri/ri/RiResolvedType;") \ oop_field(CiAssumptions_ConcreteMethod, impl, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \ end_class \ diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/basicLock.hpp --- a/src/share/vm/runtime/basicLock.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/basicLock.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -63,6 +63,7 @@ public: // Manipulation oop obj() const { return _obj; } + oop* obj_addr() { return &_obj; } void set_obj(oop obj) { _obj = obj; } BasicLock* lock() { return &_lock; } diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/deoptimization.cpp Wed Feb 22 21:24:08 2012 +0100 @@ -176,7 +176,7 @@ // the vframeArray is created. // - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("fetching unroll info"); } @@ -236,7 +236,7 @@ assert(result == NULL || result->is_oop(), "must be oop"); return_value = Handle(thread, result); assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread); } } @@ -249,7 +249,7 @@ if (reallocated) { reassign_fields(&deoptee, &map, objects); #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { ttyLocker ttyl; tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); print_objects(objects); @@ -272,7 +272,7 @@ if (monitors->is_nonempty()) { relock_objects(monitors, thread); #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { ttyLocker ttyl; for (int j = 0; j < monitors->length(); j++) { MonitorInfo* mi = monitors->at(j); @@ -497,7 +497,7 @@ info->set_initial_info((intptr_t) array->sender().initial_deoptimization_info()); if (array->frames() > 1) { - if (VerifyStack && TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("Deoptimizing method containing inlining"); } } @@ -577,7 +577,7 @@ vframeArray* array = thread->vframe_array_head(); #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d", thread, array, exec_mode); } #endif @@ -920,7 +920,7 @@ KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); Handle obj = sv->value(); assert(obj.not_null(), "reallocation was missed"); - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("reassign fields for object of type %s!", k->name()->as_C_string()); } @@ -990,7 +990,7 @@ vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk) { #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { ttyLocker ttyl; tty->print("DEOPT PACKING thread " INTPTR_FORMAT " ", thread); fr.print_on(tty); @@ -1036,7 +1036,7 @@ Events::log("# vframes = %d", (intptr_t)chunk->length()); #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { ttyLocker ttyl; tty->print_cr(" Created vframeArray " INTPTR_FORMAT, array); } @@ -1284,7 +1284,7 @@ Bytecodes::Code trap_bc = trap_method->java_code_at(trap_bci); if (trap_scope->rethrow_exception()) { - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("Exception to be rethrown in the interpreter for method %s::%s at bci %d", instanceKlass::cast(trap_method->method_holder())->name()->as_C_string(), trap_method->name()->as_C_string(), trap_bci); } GrowableArray* expressions = trap_scope->expressions(); diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/frame.cpp --- a/src/share/vm/runtime/frame.cpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/frame.cpp Wed Feb 22 21:24:08 2012 +0100 @@ -605,43 +605,63 @@ #ifndef PRODUCT assert(is_interpreted_frame(), "Not an interpreted frame"); jint i; - for (i = 0; i < interpreter_frame_method()->max_locals(); i++ ) { - intptr_t x = *interpreter_frame_local_at(i); - st->print(" - local [" INTPTR_FORMAT "]", x); - st->fill_to(23); - st->print_cr("; #%d", i); - } + st->print_cr(" - sp = " INTPTR_FORMAT, sp()); + // expressions for (i = interpreter_frame_expression_stack_size() - 1; i >= 0; --i ) { - intptr_t x = *interpreter_frame_expression_stack_at(i); - st->print(" - stack [" INTPTR_FORMAT "]", x); - st->fill_to(23); + intptr_t* x = interpreter_frame_expression_stack_at(i); + st->print(" - stack at " INTPTR_FORMAT " = " INTPTR_FORMAT, x, *x); + st->fill_to(70); st->print_cr("; #%d", i); } // locks for synchronization + st->print_cr(" - monitorend = " INTPTR_FORMAT, interpreter_frame_monitor_end()); for (BasicObjectLock* current = interpreter_frame_monitor_end(); current < interpreter_frame_monitor_begin(); current = next_monitor_in_interpreter_frame(current)) { - st->print(" - obj ["); - current->obj()->print_value_on(st); - st->print_cr("]"); - st->print(" - lock ["); + st->print (" - lock at " INTPTR_FORMAT " = ", current->lock()); current->lock()->print_on(st); - st->print_cr("]"); + st->cr(); + st->print (" - obj at " INTPTR_FORMAT " = " INTPTR_FORMAT " ", current->obj_addr(), *current->obj_addr()); + current->obj()->print_value_on(st); + st->cr(); } - // monitor - st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin()); - // bcp - st->print(" - bcp [" INTPTR_FORMAT "]", interpreter_frame_bcp()); - st->fill_to(23); + st->print_cr(" - monitorbegin = " INTPTR_FORMAT, interpreter_frame_monitor_begin()); + + // bcp/bcx + st->print (" - bcp at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_bcx_addr(), interpreter_frame_bcp()); + st->fill_to(70); st->print_cr("; @%d", interpreter_frame_bci()); // locals - st->print_cr(" - locals [" INTPTR_FORMAT "]", interpreter_frame_local_at(0)); + st->print_cr(" - locals at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_locals_addr(), *interpreter_frame_locals_addr()); + // constant pool cache + st->print_cr(" - constant pool at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_cache_addr(), *interpreter_frame_cache_addr()); + // method data + st->print_cr(" - method data at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_mdx_addr(), *interpreter_frame_mdx_addr()); // method - st->print(" - method [" INTPTR_FORMAT "]", (address)interpreter_frame_method()); - st->fill_to(23); + st->print (" - method at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_method_addr(), *interpreter_frame_method_addr()); + st->fill_to(70); st->print("; "); interpreter_frame_method()->print_name(st); st->cr(); + // last sp + st->print_cr(" - last sp at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_last_sp_addr(), *interpreter_frame_last_sp_addr()); + // sender sp + st->print_cr(" - sender sp at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_sender_sp_addr(), *interpreter_frame_sender_sp_addr()); + // old fp + st->print_cr(" - old fp at " INTPTR_FORMAT " = " INTPTR_FORMAT, link_addr(), *link_addr()); + // return address + st->print_cr(" - return pc at " INTPTR_FORMAT " = " INTPTR_FORMAT, sender_pc_addr(), *sender_pc_addr()); + + // locals + for (i = interpreter_frame_method()->max_locals() - 1; i >= 0; i--) { + intptr_t* x = interpreter_frame_local_at(i); + st->print (" - local at " INTPTR_FORMAT " = " INTPTR_FORMAT, x, *x); + st->fill_to(70); + st->print_cr("; #%d", i); + } + + // fp + st->print_cr(" - fp = " INTPTR_FORMAT, fp()); #endif } diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/frame.hpp --- a/src/share/vm/runtime/frame.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/frame.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -206,6 +206,7 @@ public: // Link (i.e., the pointer to the previous frame) intptr_t* link() const; + intptr_t** link_addr() const; void set_link(intptr_t* addr); // Return address @@ -296,6 +297,7 @@ jint interpreter_frame_expression_stack_size() const; intptr_t* interpreter_frame_sender_sp() const; + intptr_t** interpreter_frame_sender_sp_addr() const; #ifndef CC_INTERP // template based interpreter deoptimization support diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/globals.hpp Wed Feb 22 21:24:08 2012 +0100 @@ -2976,6 +2976,9 @@ product(bool, TraceDeoptimization, false, \ "Trace deoptimization") \ \ + product(bool, PrintDeoptimizationDetails, false, \ + "Print more information about deoptimization") \ + \ develop(bool, DebugDeoptimization, false, \ "Tracing various information while debugging deoptimization") \ \ diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/sharedRuntime.cpp Wed Feb 22 21:24:08 2012 +0100 @@ -718,6 +718,7 @@ nm->make_not_entrant(); JavaThread::current()->set_exception_pc(ret_pc); JavaThread::current()->set_exception_oop(exception()); + JavaThread::current()->clear_pending_exception(); return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); #else assert(nm->unwind_handler_begin() != NULL, ""); diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/vframe.cpp --- a/src/share/vm/runtime/vframe.cpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/vframe.cpp Wed Feb 22 21:24:08 2012 +0100 @@ -266,8 +266,8 @@ // Get oopmap describing oops and int for current bci InterpreterOopMap oop_mask; - if (TraceDeoptimization && Verbose) { - methodHandle m_h(thread(), method()); + if (PrintDeoptimizationDetails) { + methodHandle m_h(method()); OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); } else { method()->mask_for(bci(), &oop_mask); @@ -333,7 +333,7 @@ InterpreterOopMap oop_mask; // Get oopmap describing oops and int for current bci - if (TraceDeoptimization && Verbose) { + if (PrintDeoptimizationDetails) { methodHandle m_h(method()); OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); } else { @@ -570,14 +570,6 @@ if (size > 4*K) warning("SUSPICIOUSLY LARGE FRAME (%d)", size); #endif } - - tty->print_cr(""); - int i = -1; - for (intptr_t* a = _fr.sp() - 1; a <= _fr.fp(); a++) { - oop o = (oop)(*a); - tty->print_cr("sp[%d] = " INTPTR_FORMAT " (%d)", i, *a, o->is_oop()); - ++i; - } } diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/vframeArray.cpp Wed Feb 22 21:24:08 2012 +0100 @@ -317,7 +317,7 @@ } } - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("Expressions size: %d", expressions()->size()); } @@ -333,7 +333,7 @@ case T_INT: *addr = value->get_int(); #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("Reconstructed expression %d (INT): %d", i, (int)(*addr)); } #endif @@ -341,7 +341,7 @@ case T_OBJECT: *addr = value->get_int(T_OBJECT); #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print("Reconstructed expression %d (OBJECT): ", i); oop o = (oop)(*addr); if (o == NULL) { @@ -370,7 +370,7 @@ case T_INT: *addr = value->get_int(); #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("Reconstructed local %d (INT): %d", i, (int)(*addr)); } #endif @@ -378,7 +378,7 @@ case T_OBJECT: *addr = value->get_int(T_OBJECT); #ifndef PRODUCT - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print("Reconstructed local %d (OBJECT): ", i); oop o = (oop)(*addr); if (o == NULL) { @@ -429,18 +429,13 @@ } #ifndef PRODUCT - if (TraceDeoptimization && Verbose) { + if (PrintDeoptimizationDetails) { ttyLocker ttyl; tty->print_cr("[%d Interpreted Frame]", ++unpack_counter); iframe()->print_on(tty); RegisterMap map(thread); vframe* f = vframe::new_vframe(iframe(), &map, thread); f->print(); - - tty->print_cr("locals size %d", locals()->size()); - tty->print_cr("expression size %d", expressions()->size()); - - method()->print_value(); tty->cr(); // method()->print_codes(); } else if (TraceDeoptimization) { diff -r c2384f5b2e6e -r 03ea39a3cf68 src/share/vm/runtime/vframe_hp.cpp --- a/src/share/vm/runtime/vframe_hp.cpp Wed Feb 22 14:07:10 2012 +0100 +++ b/src/share/vm/runtime/vframe_hp.cpp Wed Feb 22 21:24:08 2012 +0100 @@ -70,7 +70,7 @@ } } - if (TraceDeoptimization) { + if (PrintDeoptimizationDetails) { tty->print_cr("bci=%d length=%d", this->bci(), length); tty->print_cr(err_msg("method name = %s", this->method()->name()->as_C_string())); tty->print_cr("relative pc=%d", this->fr().pc() - this->nm()->code_begin());