Merge
authoriveresov
Fri, 09 Sep 2011 12:44:37 -0700
changeset 10543 2c0914969c10
parent 10531 ec78e506afa8 (current diff)
parent 10542 93e6f995c75c (diff)
child 10544 e323817a5fe0
Merge
hotspot/src/share/vm/runtime/arguments.cpp
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -839,3 +839,9 @@
 }
 
 #endif
+
+intptr_t *frame::initial_deoptimization_info() {
+  // unused... but returns fp() to minimize changes introduced by 7087445
+  return fp();
+}
+
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -666,3 +666,9 @@
 
 }
 #endif
+
+intptr_t *frame::initial_deoptimization_info() {
+  // used to reset the saved FP
+  return fp();
+}
+
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -2471,7 +2471,7 @@
   __ movl(counter, rbx);
 
   // Pick up the initial fp we should save
-  __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
+  __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
 
   // Now adjust the caller's stack to make up for the extra locals
   // but record the original sp so that we can save it in the skeletal interpreter
@@ -2691,7 +2691,7 @@
   __ movl(counter, rbx);
 
   // Pick up the initial fp we should save
-  __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
+  __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
 
   // Now adjust the caller's stack to make up for the extra locals
   // but record the original sp so that we can save it in the skeletal interpreter
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -2730,7 +2730,7 @@
   __ movl(rdx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()));
 
   // Pick up the initial fp we should save
-  __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
+  __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
 
   // Now adjust the caller's stack to make up for the extra locals
   // but record the original sp so that we can save it in the skeletal interpreter
@@ -2922,7 +2922,7 @@
   // Pick up the initial fp we should save
   __ movptr(rbp,
             Address(rdi,
-                    Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
+                    Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
 
   // Now adjust the caller's stack to make up for the extra locals but
   // record the original sp so that we can save it in the skeletal
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -425,3 +425,9 @@
 }
 
 #endif
+
+intptr_t *frame::initial_deoptimization_info() {
+  // unused... but returns fp() to minimize changes introduced by 7087445
+  return fp();
+}
+
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -2707,14 +2707,6 @@
   }
 }
 
-oop java_lang_invoke_CallSite::target(oop site) {
-  return site->obj_field(_target_offset);
-}
-
-void java_lang_invoke_CallSite::set_target(oop site, oop target) {
-  site->obj_field_put(_target_offset, target);
-}
-
 
 // Support for java_security_AccessControlContext
 
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Fri Sep 09 12:44:37 2011 -0700
@@ -771,7 +771,7 @@
     ref->obj_field_put(referent_offset, value);
   }
   static void set_referent_raw(oop ref, oop value) {
-    ref->obj_field_raw_put(referent_offset, value);
+    ref->obj_field_put_raw(referent_offset, value);
   }
   static HeapWord* referent_addr(oop ref) {
     return ref->obj_field_addr<HeapWord>(referent_offset);
@@ -783,7 +783,7 @@
     ref->obj_field_put(next_offset, value);
   }
   static void set_next_raw(oop ref, oop value) {
-    ref->obj_field_raw_put(next_offset, value);
+    ref->obj_field_put_raw(next_offset, value);
   }
   static HeapWord* next_addr(oop ref) {
     return ref->obj_field_addr<HeapWord>(next_offset);
@@ -795,7 +795,7 @@
     ref->obj_field_put(discovered_offset, value);
   }
   static void set_discovered_raw(oop ref, oop value) {
-    ref->obj_field_raw_put(discovered_offset, value);
+    ref->obj_field_put_raw(discovered_offset, value);
   }
   static HeapWord* discovered_addr(oop ref) {
     return ref->obj_field_addr<HeapWord>(discovered_offset);
@@ -1163,14 +1163,17 @@
 
 public:
   // Accessors
-  static oop            target(oop site);
-  static void       set_target(oop site, oop target);
+  static oop              target(         oop site)             { return site->obj_field(             _target_offset);         }
+  static void         set_target(         oop site, oop target) {        site->obj_field_put(         _target_offset, target); }
+
+  static volatile oop     target_volatile(oop site)             { return site->obj_field_volatile(    _target_offset);         }
+  static void         set_target_volatile(oop site, oop target) {        site->obj_field_put_volatile(_target_offset, target); }
 
-  static oop            caller_method(oop site);
-  static void       set_caller_method(oop site, oop ref);
+  static oop              caller_method(oop site);
+  static void         set_caller_method(oop site, oop ref);
 
-  static jint           caller_bci(oop site);
-  static void       set_caller_bci(oop site, jint bci);
+  static jint             caller_bci(oop site);
+  static void         set_caller_bci(oop site, jint bci);
 
   // Testers
   static bool is_subclass(klassOop klass) {
--- a/hotspot/src/share/vm/oops/klassOop.hpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/oops/klassOop.hpp	Fri Sep 09 12:44:37 2011 -0700
@@ -53,8 +53,10 @@
  private:
   // These have no implementation since klassOop should never be accessed in this fashion
   oop obj_field(int offset) const;
+  volatile oop obj_field_volatile(int offset) const;
   void obj_field_put(int offset, oop value);
-  void obj_field_raw_put(int offset, oop value);
+  void obj_field_put_raw(int offset, oop value);
+  void obj_field_put_volatile(int offset, oop value);
 
   jbyte byte_field(int offset) const;
   void byte_field_put(int offset, jbyte contents);
--- a/hotspot/src/share/vm/oops/oop.hpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/oops/oop.hpp	Fri Sep 09 12:44:37 2011 -0700
@@ -214,8 +214,10 @@
 
   // Access to fields in a instanceOop through these methods.
   oop obj_field(int offset) const;
+  volatile oop obj_field_volatile(int offset) const;
   void obj_field_put(int offset, oop value);
-  void obj_field_raw_put(int offset, oop value);
+  void obj_field_put_raw(int offset, oop value);
+  void obj_field_put_volatile(int offset, oop value);
 
   jbyte byte_field(int offset) const;
   void byte_field_put(int offset, jbyte contents);
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Fri Sep 09 12:44:37 2011 -0700
@@ -321,15 +321,25 @@
     load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
     load_decode_heap_oop(obj_field_addr<oop>(offset));
 }
+inline volatile oop oopDesc::obj_field_volatile(int offset) const {
+  volatile oop value = obj_field(offset);
+  OrderAccess::acquire();
+  return value;
+}
 inline void oopDesc::obj_field_put(int offset, oop value) {
   UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
                       oop_store(obj_field_addr<oop>(offset),       value);
 }
-inline void oopDesc::obj_field_raw_put(int offset, oop value) {
+inline void oopDesc::obj_field_put_raw(int offset, oop value) {
   UseCompressedOops ?
     encode_store_heap_oop(obj_field_addr<narrowOop>(offset), value) :
     encode_store_heap_oop(obj_field_addr<oop>(offset),       value);
 }
+inline void oopDesc::obj_field_put_volatile(int offset, oop value) {
+  OrderAccess::release();
+  obj_field_put(offset, value);
+  OrderAccess::fence();
+}
 
 inline jbyte oopDesc::byte_field(int offset) const                  { return (jbyte) *byte_field_addr(offset);    }
 inline void oopDesc::byte_field_put(int offset, jbyte contents)     { *byte_field_addr(offset) = (jint) contents; }
--- a/hotspot/src/share/vm/opto/chaitin.hpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/opto/chaitin.hpp	Fri Sep 09 12:44:37 2011 -0700
@@ -482,6 +482,7 @@
   }
 
   int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
+  int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
   int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs );
   int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List &regnd );
   bool may_be_copy_of_callee( Node *def ) const;
--- a/hotspot/src/share/vm/opto/loopTransform.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -709,10 +709,13 @@
 
   // Adjust body_size to determine if we unroll or not
   uint body_size = _body.size();
+  // Key test to unroll loop in CRC32 java code
+  int xors_in_loop = 0;
   // Also count ModL, DivL and MulL which expand mightly
   for (uint k = 0; k < _body.size(); k++) {
     Node* n = _body.at(k);
     switch (n->Opcode()) {
+      case Op_XorI: xors_in_loop++; break; // CRC32 java code
       case Op_ModL: body_size += 30; break;
       case Op_DivL: body_size += 30; break;
       case Op_MulL: body_size += 10; break;
@@ -729,7 +732,8 @@
 
   // Check for being too big
   if (body_size > (uint)LoopUnrollLimit) {
-     // Normal case: loop too big
+    if (xors_in_loop >= 4 && body_size < (uint)LoopUnrollLimit*4) return true;
+    // Normal case: loop too big
     return false;
   }
 
--- a/hotspot/src/share/vm/opto/postaloc.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/opto/postaloc.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -72,7 +72,22 @@
   return i == limit;
 }
 
-
+//------------------------------yank-----------------------------------
+// Helper function for yank_if_dead
+int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
+  int blk_adjust=0;
+  Block *oldb = _cfg._bbs[old->_idx];
+  oldb->find_remove(old);
+  // Count 1 if deleting an instruction from the current block
+  if( oldb == current_block ) blk_adjust++;
+  _cfg._bbs.map(old->_idx,NULL);
+  OptoReg::Name old_reg = lrgs(n2lidx(old)).reg();
+  if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
+    value->map(old_reg,NULL);  // Yank from value/regnd maps
+    regnd->map(old_reg,NULL);  // This register's value is now unknown
+  }
+  return blk_adjust;
+}
 
 //------------------------------yank_if_dead-----------------------------------
 // Removed an edge from 'old'.  Yank if dead.  Return adjustment counts to
@@ -80,18 +95,20 @@
 int PhaseChaitin::yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
   int blk_adjust=0;
   while (old->outcnt() == 0 && old != C->top()) {
-    Block *oldb = _cfg._bbs[old->_idx];
-    oldb->find_remove(old);
-    // Count 1 if deleting an instruction from the current block
-    if( oldb == current_block ) blk_adjust++;
-    _cfg._bbs.map(old->_idx,NULL);
-    OptoReg::Name old_reg = lrgs(n2lidx(old)).reg();
-    if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
-      value->map(old_reg,NULL);  // Yank from value/regnd maps
-      regnd->map(old_reg,NULL);  // This register's value is now unknown
+    blk_adjust += yank(old, current_block, value, regnd);
+
+    Node *tmp = NULL;
+    for (uint i = 1; i < old->req(); i++) {
+      if (old->in(i)->is_MachTemp()) {
+        Node* machtmp = old->in(i);
+        assert(machtmp->outcnt() == 1, "expected for a MachTemp");
+        blk_adjust += yank(machtmp, current_block, value, regnd);
+        machtmp->disconnect_inputs(NULL);
+      } else {
+        assert(tmp == NULL, "can't handle more non MachTemp inputs");
+        tmp = old->in(i);
+      }
     }
-    assert(old->req() <= 2, "can't handle more inputs");
-    Node *tmp = old->req() > 1 ? old->in(1) : NULL;
     old->disconnect_inputs(NULL);
     if( !tmp ) break;
     old = tmp;
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -3081,6 +3081,30 @@
 }
 JVM_END
 
+JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
+  oop call_site = JNIHandles::resolve_non_null(call_site_jh);
+  oop target    = JNIHandles::resolve(target_jh);
+  {
+    // Walk all nmethods depending on this call site.
+    MutexLocker mu(Compile_lock, thread);
+    Universe::flush_dependents_on(call_site, target);
+  }
+  java_lang_invoke_CallSite::set_target(call_site, target);
+}
+JVM_END
+
+JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
+  oop call_site = JNIHandles::resolve_non_null(call_site_jh);
+  oop target    = JNIHandles::resolve(target_jh);
+  {
+    // Walk all nmethods depending on this call site.
+    MutexLocker mu(Compile_lock, thread);
+    Universe::flush_dependents_on(call_site, target);
+  }
+  java_lang_invoke_CallSite::set_target_volatile(call_site, target);
+}
+JVM_END
+
 methodOop MethodHandles::resolve_raise_exception_method(TRAPS) {
   if (_raise_exception_method != NULL) {
     // no need to do it twice
@@ -3137,12 +3161,15 @@
 
 /// JVM_RegisterMethodHandleMethods
 
+#undef CS  // Solaris builds complain
+
 #define LANG "Ljava/lang/"
 #define JLINV "Ljava/lang/invoke/"
 
 #define OBJ   LANG"Object;"
 #define CLS   LANG"Class;"
 #define STRG  LANG"String;"
+#define CS    JLINV"CallSite;"
 #define MT    JLINV"MethodType;"
 #define MH    JLINV"MethodHandle;"
 #define MEM   JLINV"MemberName;"
@@ -3153,29 +3180,34 @@
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
 
-// These are the native methods on sun.invoke.MethodHandleNatives.
+// These are the native methods on java.lang.invoke.MethodHandleNatives.
 static JNINativeMethod methods[] = {
   // void init(MemberName self, AccessibleObject ref)
-  {CC"init",                    CC"("AMH""MH"I)V",              FN_PTR(MHN_init_AMH)},
-  {CC"init",                    CC"("BMH""OBJ"I)V",             FN_PTR(MHN_init_BMH)},
-  {CC"init",                    CC"("DMH""OBJ"Z"CLS")V",        FN_PTR(MHN_init_DMH)},
-  {CC"init",                    CC"("MT")V",                    FN_PTR(MHN_init_MT)},
-  {CC"init",                    CC"("MEM""OBJ")V",              FN_PTR(MHN_init_Mem)},
-  {CC"expand",                  CC"("MEM")V",                   FN_PTR(MHN_expand_Mem)},
-  {CC"resolve",                 CC"("MEM""CLS")V",              FN_PTR(MHN_resolve_Mem)},
-  {CC"getTarget",               CC"("MH"I)"OBJ,                 FN_PTR(MHN_getTarget)},
-  {CC"getConstant",             CC"(I)I",                       FN_PTR(MHN_getConstant)},
+  {CC"init",                      CC"("AMH""MH"I)V",                     FN_PTR(MHN_init_AMH)},
+  {CC"init",                      CC"("BMH""OBJ"I)V",                    FN_PTR(MHN_init_BMH)},
+  {CC"init",                      CC"("DMH""OBJ"Z"CLS")V",               FN_PTR(MHN_init_DMH)},
+  {CC"init",                      CC"("MT")V",                           FN_PTR(MHN_init_MT)},
+  {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
+  {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
+  {CC"resolve",                   CC"("MEM""CLS")V",                     FN_PTR(MHN_resolve_Mem)},
+  {CC"getTarget",                 CC"("MH"I)"OBJ,                        FN_PTR(MHN_getTarget)},
+  {CC"getConstant",               CC"(I)I",                              FN_PTR(MHN_getConstant)},
   //  static native int getNamedCon(int which, Object[] name)
-  {CC"getNamedCon",             CC"(I["OBJ")I",                 FN_PTR(MHN_getNamedCon)},
+  {CC"getNamedCon",               CC"(I["OBJ")I",                        FN_PTR(MHN_getNamedCon)},
   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
-  {CC"getMembers",              CC"("CLS""STRG""STRG"I"CLS"I["MEM")I",  FN_PTR(MHN_getMembers)}
+  {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
+};
+
+static JNINativeMethod call_site_methods[] = {
+  {CC"setCallSiteTargetNormal",   CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetNormal)},
+  {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)}
 };
 
 static JNINativeMethod invoke_methods[] = {
   // void init(MemberName self, AccessibleObject ref)
-  {CC"invoke",                  CC"(["OBJ")"OBJ,                FN_PTR(MH_invoke_UOE)},
-  {CC"invokeExact",             CC"(["OBJ")"OBJ,                FN_PTR(MH_invokeExact_UOE)}
+  {CC"invoke",                    CC"(["OBJ")"OBJ,                       FN_PTR(MH_invoke_UOE)},
+  {CC"invokeExact",               CC"(["OBJ")"OBJ,                       FN_PTR(MH_invokeExact_UOE)}
 };
 
 // This one function is exported, used by NativeLookup.
@@ -3188,11 +3220,11 @@
     return;  // bind nothing
   }
 
+  assert(!MethodHandles::enabled(), "must not be enabled");
   bool enable_MH = true;
 
   {
     ThreadToNativeFromVM ttnfv(thread);
-
     int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
     if (!env->ExceptionOccurred()) {
       const char* L_MH_name = (JLINV "MethodHandle");
@@ -3201,11 +3233,16 @@
       status = env->RegisterNatives(MH_class, invoke_methods, sizeof(invoke_methods)/sizeof(JNINativeMethod));
     }
     if (env->ExceptionOccurred()) {
-      MethodHandles::set_enabled(false);
       warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
       enable_MH = false;
       env->ExceptionClear();
     }
+
+    status = env->RegisterNatives(MHN_class, call_site_methods, sizeof(call_site_methods)/sizeof(JNINativeMethod));
+    if (env->ExceptionOccurred()) {
+      // Exception is okay until 7087357
+      env->ExceptionClear();
+    }
   }
 
   if (enable_MH) {
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -3021,9 +3021,6 @@
   }
 
 #ifdef JAVASE_EMBEDDED
-  #ifdef PPC
-    UNSUPPORTED_OPTION(EnableInvokeDynamic, "Invoke dynamic");
-  #endif
   UNSUPPORTED_OPTION(UseG1GC, "G1 GC");
 #endif
 
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Fri Sep 09 12:44:37 2011 -0700
@@ -103,7 +103,7 @@
   _frame_pcs                 = frame_pcs;
   _register_block            = NEW_C_HEAP_ARRAY(intptr_t, RegisterMap::reg_count * 2);
   _return_type               = return_type;
-  _initial_fp                = 0;
+  _initial_info              = 0;
   // PD (x86 only)
   _counter_temp              = 0;
   _unpack_kind               = 0;
@@ -486,9 +486,10 @@
                                       frame_sizes,
                                       frame_pcs,
                                       return_type);
-  // On some platforms, we need a way to pass fp to the unpacking code
-  // so the skeletal frames come out correct.
-  info->set_initial_fp((intptr_t) array->sender().fp());
+  // On some platforms, we need a way to pass some platform dependent
+  // information to the unpacking code so the skeletal frames come out
+  // correct (initial fp value, unextended sp, ...)
+  info->set_initial_info((intptr_t) array->sender().initial_deoptimization_info());
 
   if (array->frames() > 1) {
     if (VerifyStack && TraceDeoptimization) {
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp	Fri Sep 09 12:44:37 2011 -0700
@@ -137,7 +137,7 @@
     address*  _frame_pcs;                 // Array of frame pc's, in bytes, for unrolling the stack
     intptr_t* _register_block;            // Block for storing callee-saved registers.
     BasicType _return_type;               // Tells if we have to restore double or long return value
-    intptr_t  _initial_fp;                // FP of the sender frame
+    intptr_t  _initial_info;              // Platform dependent data for the sender frame (was FP on x86)
     int       _caller_actual_parameters;  // The number of actual arguments at the
                                           // interpreted caller of the deoptimized frame
 
@@ -170,7 +170,7 @@
     // Returns the total size of frames
     int size_of_frames() const;
 
-    void set_initial_fp(intptr_t fp) { _initial_fp = fp; }
+    void set_initial_info(intptr_t info) { _initial_info = info; }
 
     int caller_actual_parameters() const { return _caller_actual_parameters; }
 
@@ -184,7 +184,7 @@
     static int register_block_offset_in_bytes()            { return offset_of(UnrollBlock, _register_block);            }
     static int return_type_offset_in_bytes()               { return offset_of(UnrollBlock, _return_type);               }
     static int counter_temp_offset_in_bytes()              { return offset_of(UnrollBlock, _counter_temp);              }
-    static int initial_fp_offset_in_bytes()                { return offset_of(UnrollBlock, _initial_fp);                }
+    static int initial_info_offset_in_bytes()              { return offset_of(UnrollBlock, _initial_info);              }
     static int unpack_kind_offset_in_bytes()               { return offset_of(UnrollBlock, _unpack_kind);               }
     static int sender_sp_temp_offset_in_bytes()            { return offset_of(UnrollBlock, _sender_sp_temp);            }
 
--- a/hotspot/src/share/vm/runtime/frame.hpp	Fri Sep 09 14:44:43 2011 +0200
+++ b/hotspot/src/share/vm/runtime/frame.hpp	Fri Sep 09 12:44:37 2011 -0700
@@ -221,6 +221,10 @@
   // returns the stack pointer of the calling frame
   intptr_t* sender_sp() const;
 
+  // Deoptimization info, if needed (platform dependent).
+  // Stored in the initial_info field of the unroll info, to be used by
+  // the platform dependent deoptimization blobs.
+  intptr_t *initial_deoptimization_info();
 
   // Interpreter frames:
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7068051/Test7068051.java	Fri Sep 09 12:44:37 2011 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011, 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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7068051
+ * @summary SIGSEGV in PhaseIdealLoop::build_loop_late_post on T5440
+ *
+ * @run shell/timeout=300 Test7068051.sh
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+import java.util.zip.*;
+
+public class Test7068051 {
+
+    public static void main (String[] args) throws Throwable {
+
+        ZipFile zf = new ZipFile(args[0]);
+
+        Enumeration<? extends ZipEntry> entries = zf.entries();
+        ArrayList<String> names = new ArrayList<String>();
+        while (entries.hasMoreElements()) {
+            names.add(entries.nextElement().getName());
+        }
+
+        byte[] bytes = new byte[16];
+        for (String name : names) {
+            ZipEntry e = zf.getEntry(name);
+
+            if (e.isDirectory())
+                continue;
+
+            final InputStream is = zf.getInputStream(e);
+
+            try  {
+                while (is.read(bytes) >= 0) {
+                }
+                is.close();
+
+            } catch (IOException x) {
+                 System.out.println("..................................");
+                 System.out.println("          -->  is :" + is);
+                 System.out.println("          is.hash :" + is.hashCode());
+                 System.out.println();
+                 System.out.println("           e.name :" + e.getName());
+                 System.out.println("           e.hash :" + e.hashCode());
+                 System.out.println("         e.method :" + e.getMethod());
+                 System.out.println("           e.size :" + e.getSize());
+                 System.out.println("          e.csize :" + e.getCompressedSize());
+
+                 x.printStackTrace();
+                 System.out.println("..................................");
+                 System.exit(97);
+            }
+        }
+        zf.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7068051/Test7068051.sh	Fri Sep 09 12:44:37 2011 -0700
@@ -0,0 +1,49 @@
+#!/bin/sh
+# 
+# Copyright (c) 2011, 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.
+# 
+# 
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTSRC=${TESTSRC}"
+if [ "${TESTJAVA}" = "" ]
+then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTJAVA=${TESTJAVA}"
+
+set -x
+
+${TESTJAVA}/bin/jar xf ${TESTJAVA}/jre/lib/javaws.jar
+${TESTJAVA}/bin/jar cf foo.jar *
+cp ${TESTSRC}/Test7068051.java ./
+${TESTJAVA}/bin/jar -uf0 foo.jar Test7068051.java
+
+${TESTJAVA}/bin/javac -d . Test7068051.java
+
+${TESTJAVA}/bin/java -showversion -Xbatch ${TESTVMOPTS} Test7068051 foo.jar
+