changeset 4676:03ea39a3cf68

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 22 Feb 2012 21:24:08 +0100
parents c2384f5b2e6e (current diff) 7167f487cc31 (diff)
children 74c0b866fe8d
files
diffstat 22 files changed, 434 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- 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<CiAssumptions.Assumption> {
 
-    /**
-     *
-     */
     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];
--- 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();
--- 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);
         }
 
--- 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());
+    }
 }
--- /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);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+}
--- 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
 
--- 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);
--- 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);
 }
--- 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) \
--- 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")                          \
--- 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)));
--- 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);
 
--- 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                                                                             \
--- 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; }
 
--- 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<compiledVFrame*>* 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<ScopeValue*>* expressions = trap_scope->expressions();
--- 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
 }
 
--- 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
--- 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")     \
                                                                             \
--- 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, "");
--- 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;
-  }
 }
 
 
--- 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) {
--- 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());