changeset 466:edfc23d84113

meth-lazy: misc. compiler fixes
author twisti
date Tue, 10 Jul 2012 18:30:57 -0700
parents 93e8421c14a6
children 747688368d8f
files meth-lazy-7023639.jit.patch
diffstat 1 files changed, 437 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/meth-lazy-7023639.jit.patch	Tue Jul 10 13:25:34 2012 -0700
+++ b/meth-lazy-7023639.jit.patch	Tue Jul 10 18:30:57 2012 -0700
@@ -52,6 +52,293 @@
      ConstantPoolCacheEntry::verify_tos_state_shift();
      __ cmp(G1_scratch, atos );
      __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
+diff --git a/src/cpu/x86/vm/assembler_x86.cpp b/src/cpu/x86/vm/assembler_x86.cpp
+--- a/src/cpu/x86/vm/assembler_x86.cpp
++++ b/src/cpu/x86/vm/assembler_x86.cpp
+@@ -5492,45 +5492,7 @@
+     // To see where a verify_oop failed, get $ebx+40/X for this frame.
+     // This is the value of eip which points to where verify_oop will return.
+     if (os::message_box(msg, "Execution stopped, print registers?")) {
+-      ttyLocker ttyl;
+-      FlagSetting fs(Debugging, true);
+-      tty->print_cr("eip = 0x%08x", eip);
+-#ifndef PRODUCT
+-      if ((WizardMode || Verbose) && PrintMiscellaneous) {
+-        tty->cr();
+-        findpc(eip);
+-        tty->cr();
+-      }
+-#endif
+-#define PRINT_REG(rax) \
+-      { tty->print("%s = ", #rax); os::print_location(tty, rax); }
+-      PRINT_REG(rax);
+-      PRINT_REG(rbx);
+-      PRINT_REG(rcx);
+-      PRINT_REG(rdx);
+-      PRINT_REG(rdi);
+-      PRINT_REG(rsi);
+-      PRINT_REG(rbp);
+-      PRINT_REG(rsp);
+-#undef PRINT_REG
+-      // Print some words near top of staack.
+-      int* dump_sp = (int*) rsp;
+-      for (int col1 = 0; col1 < 8; col1++) {
+-        tty->print("(rsp+0x%03x) 0x%08x: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (intptr_t)dump_sp);
+-        os::print_location(tty, *dump_sp++);
+-      }
+-      for (int row = 0; row < 16; row++) {
+-        tty->print("(rsp+0x%03x) 0x%08x: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (intptr_t)dump_sp);
+-        for (int col = 0; col < 8; col++) {
+-          tty->print(" 0x%08x", *dump_sp++);
+-        }
+-        tty->cr();
+-      }
+-      // Print some instructions around pc:
+-      Disassembler::decode((address)eip-64, (address)eip);
+-      tty->print_cr("--------");
+-      Disassembler::decode((address)eip, (address)eip+32);
+-      Debugging = false;
++      print_state32(rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax, eip);
+       BREAKPOINT;
+       assert(false, "start up GDB");
+     }
+@@ -5542,12 +5504,53 @@
+   ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
+ }
+ 
++void MacroAssembler::print_state32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip) {
++  ttyLocker ttyl;
++  FlagSetting fs(Debugging, true);
++  tty->print_cr("eip = 0x%08x", eip);
++#ifndef PRODUCT
++  if ((WizardMode || Verbose) && PrintMiscellaneous) {
++    tty->cr();
++    findpc(eip);
++    tty->cr();
++  }
++#endif
++#define PRINT_REG(rax) \
++  { tty->print("%s = ", #rax); os::print_location(tty, rax); }
++  PRINT_REG(rax);
++  PRINT_REG(rbx);
++  PRINT_REG(rcx);
++  PRINT_REG(rdx);
++  PRINT_REG(rdi);
++  PRINT_REG(rsi);
++  PRINT_REG(rbp);
++  PRINT_REG(rsp);
++#undef PRINT_REG
++  // Print some words near top of staack.
++  int* dump_sp = (int*) rsp;
++  for (int col1 = 0; col1 < 8; col1++) {
++    tty->print("(rsp+0x%03x) 0x%08x: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (intptr_t)dump_sp);
++    os::print_location(tty, *dump_sp++);
++  }
++  for (int row = 0; row < 16; row++) {
++    tty->print("(rsp+0x%03x) 0x%08x: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (intptr_t)dump_sp);
++    for (int col = 0; col < 8; col++) {
++      tty->print(" 0x%08x", *dump_sp++);
++    }
++    tty->cr();
++  }
++  // Print some instructions around pc:
++  Disassembler::decode((address)eip-64, (address)eip);
++  tty->print_cr("--------");
++  Disassembler::decode((address)eip, (address)eip+32);
++}
++
+ void MacroAssembler::stop(const char* msg) {
+   ExternalAddress message((address)msg);
+   // push address of message
+   pushptr(message.addr());
+   { Label L; call(L, relocInfo::none); bind(L); }     // push eip
+-  pusha();                                           // push registers
++  pusha();                                            // push registers
+   call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32)));
+   hlt();
+ }
+@@ -5564,6 +5567,18 @@
+   pop_CPU_state();
+ }
+ 
++void MacroAssembler::print_state() {
++  { Label L; call(L, relocInfo::none); bind(L); }     // push eip
++  pusha();                                            // push registers
++
++  push_CPU_state();
++  call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::print_state32)));
++  pop_CPU_state();
++
++  popa();
++  addl(rsp, wordSize);
++}
++
+ #else // _LP64
+ 
+ // 64 bit versions
+@@ -6029,14 +6044,33 @@
+ }
+ 
+ void MacroAssembler::warn(const char* msg) {
+-  push(rsp);
++  push(rbp);
++  movq(rbp, rsp);
+   andq(rsp, -16);     // align stack as required by push_CPU_state and call
+-
+   push_CPU_state();   // keeps alignment at 16 bytes
+   lea(c_rarg0, ExternalAddress((address) msg));
+   call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0);
+   pop_CPU_state();
+-  pop(rsp);
++  mov(rsp, rbp);
++  pop(rbp);
++}
++
++void MacroAssembler::print_state() {
++  address rip = pc();
++  pusha();            // get regs on stack
++  push(rbp);
++  movq(rbp, rsp);
++  andq(rsp, -16);     // align stack as required by push_CPU_state and call
++  push_CPU_state();   // keeps alignment at 16 bytes
++
++  lea(c_rarg0, InternalAddress(rip));
++  lea(c_rarg1, Address(rbp, wordSize)); // pass pointer to regs array
++  call_VM_leaf(CAST_FROM_FN_PTR(address, MacroAssembler::print_state64), c_rarg0, c_rarg1);
++
++  pop_CPU_state();
++  mov(rsp, rbp);
++  pop(rbp);
++  popa();
+ }
+ 
+ #ifndef PRODUCT
+@@ -6059,52 +6093,7 @@
+     // XXX correct this offset for amd64
+     // This is the value of eip which points to where verify_oop will return.
+     if (os::message_box(msg, "Execution stopped, print registers?")) {
+-      ttyLocker ttyl;
+-      FlagSetting fs(Debugging, true);
+-      tty->print_cr("rip = 0x%016lx", pc);
+-#ifndef PRODUCT
+-      tty->cr();
+-      findpc(pc);
+-      tty->cr();
+-#endif
+-#define PRINT_REG(rax, value) \
+-      { tty->print("%s = ", #rax); os::print_location(tty, value); }
+-      PRINT_REG(rax, regs[15]);
+-      PRINT_REG(rbx, regs[12]);
+-      PRINT_REG(rcx, regs[14]);
+-      PRINT_REG(rdx, regs[13]);
+-      PRINT_REG(rdi, regs[8]);
+-      PRINT_REG(rsi, regs[9]);
+-      PRINT_REG(rbp, regs[10]);
+-      PRINT_REG(rsp, regs[11]);
+-      PRINT_REG(r8, regs[7]);
+-      PRINT_REG(r9, regs[6]);
+-      PRINT_REG(r10, regs[5]);
+-      PRINT_REG(r11, regs[4]);
+-      PRINT_REG(r12, regs[3]);
+-      PRINT_REG(r13, regs[2]);
+-      PRINT_REG(r14, regs[1]);
+-      PRINT_REG(r15, regs[0]);
+-#undef PRINT_REG
+-      // Print some words near top of staack.
+-      int64_t* rsp = (int64_t*) regs[11];
+-      int64_t* dump_sp = rsp;
+-      for (int col1 = 0; col1 < 8; col1++) {
+-        tty->print("(rsp+0x%03x) 0x%016lx: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (int64_t)dump_sp);
+-        os::print_location(tty, *dump_sp++);
+-      }
+-      for (int row = 0; row < 25; row++) {
+-        tty->print("(rsp+0x%03x) 0x%016lx: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (int64_t)dump_sp);
+-        for (int col = 0; col < 4; col++) {
+-          tty->print(" 0x%016lx", *dump_sp++);
+-        }
+-        tty->cr();
+-      }
+-      // Print some instructions around pc:
+-      Disassembler::decode((address)pc-64, (address)pc);
+-      tty->print_cr("--------");
+-      Disassembler::decode((address)pc, (address)pc+32);
+-      Debugging = false;
++      print_state64(pc, regs);
+       BREAKPOINT;
+       assert(false, "start up GDB");
+     }
+@@ -6117,6 +6106,54 @@
+   }
+ }
+ 
++void MacroAssembler::print_state64(int64_t pc, int64_t regs[]) {
++  ttyLocker ttyl;
++  FlagSetting fs(Debugging, true);
++  tty->print_cr("rip = 0x%016lx", pc);
++#ifndef PRODUCT
++  tty->cr();
++  findpc(pc);
++  tty->cr();
++#endif
++#define PRINT_REG(rax, value) \
++  { tty->print("%s = ", #rax); os::print_location(tty, value); }
++  PRINT_REG(rax, regs[15]);
++  PRINT_REG(rbx, regs[12]);
++  PRINT_REG(rcx, regs[14]);
++  PRINT_REG(rdx, regs[13]);
++  PRINT_REG(rdi, regs[8]);
++  PRINT_REG(rsi, regs[9]);
++  PRINT_REG(rbp, regs[10]);
++  PRINT_REG(rsp, regs[11]);
++  PRINT_REG(r8 , regs[7]);
++  PRINT_REG(r9 , regs[6]);
++  PRINT_REG(r10, regs[5]);
++  PRINT_REG(r11, regs[4]);
++  PRINT_REG(r12, regs[3]);
++  PRINT_REG(r13, regs[2]);
++  PRINT_REG(r14, regs[1]);
++  PRINT_REG(r15, regs[0]);
++#undef PRINT_REG
++  // Print some words near top of staack.
++  int64_t* rsp = (int64_t*) regs[11];
++  int64_t* dump_sp = rsp;
++  for (int col1 = 0; col1 < 8; col1++) {
++    tty->print("(rsp+0x%03x) 0x%016lx: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (int64_t)dump_sp);
++    os::print_location(tty, *dump_sp++);
++  }
++  for (int row = 0; row < 25; row++) {
++    tty->print("(rsp+0x%03x) 0x%016lx: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (int64_t)dump_sp);
++    for (int col = 0; col < 4; col++) {
++      tty->print(" 0x%016lx", *dump_sp++);
++    }
++    tty->cr();
++  }
++  // Print some instructions around pc:
++  Disassembler::decode((address)pc-64, (address)pc);
++  tty->print_cr("--------");
++  Disassembler::decode((address)pc, (address)pc+32);
++}
++
+ #endif // _LP64
+ 
+ // Now versions that are common to 32/64 bit
+diff --git a/src/cpu/x86/vm/assembler_x86.hpp b/src/cpu/x86/vm/assembler_x86.hpp
+--- a/src/cpu/x86/vm/assembler_x86.hpp
++++ b/src/cpu/x86/vm/assembler_x86.hpp
+@@ -2173,8 +2173,13 @@
+   // prints msg and continues
+   void warn(const char* msg);
+ 
++  // dumps registers and other state
++  void print_state();
++
+   static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
+   static void debug64(char* msg, int64_t pc, int64_t regs[]);
++  static void print_state32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip);
++  static void print_state64(int64_t pc, int64_t regs[]);
+ 
+   void os_breakpoint();
+ 
 diff --git a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
@@ -91,6 +378,17 @@
  #ifdef _LP64
      Label notObj;
      __ cmpl(rdx, atos);
+diff --git a/src/cpu/x86/vm/methodHandles_x86.cpp b/src/cpu/x86/vm/methodHandles_x86.cpp
+--- a/src/cpu/x86/vm/methodHandles_x86.cpp
++++ b/src/cpu/x86/vm/methodHandles_x86.cpp
+@@ -154,6 +154,7 @@
+   // This is the initial entry point of a lazy method handle.
+   // After type checking, it picks up the invoker from the LambdaForm.
+   assert_different_registers(recv, method_temp, temp2);
++  assert(recv != noreg, "required register");
+   assert(method_temp == rbx, "required register for loading method");
+ 
+   //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
 diff --git a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
@@ -381,29 +679,43 @@
        ShouldNotReachHere();
        break;
    }
-@@ -1604,31 +1644,50 @@
+@@ -1604,31 +1644,64 @@
  
  
  void GraphBuilder::invoke(Bytecodes::Code code) {
++  const bool has_receiver =
++    code == Bytecodes::_invokespecial   ||
++    code == Bytecodes::_invokevirtual   ||
++    code == Bytecodes::_invokeinterface;
 +  const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
++
    bool will_link;
 -  ciMethod* target = stream()->get_method(will_link);
 +  ciMethod*             target = stream()->get_method(will_link);
 +  ciKlass*              holder = stream()->get_declared_method_holder();
 +  const Bytecodes::Code bc_raw = stream()->cur_bc_raw();
 +
++  // FIXME bail out for now
++  if ((bc_raw == Bytecodes::_invokehandle || is_invokedynamic) && !will_link) {
++    BAILOUT("unlinked call site (FIXME needs patching or recompile support)");
++  }
++
    // we have to make sure the argument size (incl. the receiver)
    // is correct for compilation (the call would fail later during
    // linkage anyway) - was bug (gri 7/28/99)
 -  if (target->is_loaded() && target->is_static() != (code == Bytecodes::_invokestatic)) BAILOUT("will cause link error");
 +  {
 +    // Use raw to get rewritten bytecode.
++    const bool is_invokestatic = bc_raw == Bytecodes::_invokestatic;
 +    const bool allow_static =
-+          bc_raw == Bytecodes::_invokestatic ||
++          is_invokestatic ||
 +          bc_raw == Bytecodes::_invokehandle ||
 +          bc_raw == Bytecodes::_invokedynamic;
-+    if (target->is_loaded() && target->is_static() != allow_static) {
-+      BAILOUT("will cause link error");
++    if (target->is_loaded()) {
++      if (( target->is_static() && !allow_static) ||
++          (!target->is_static() &&  is_invokestatic)) {
++        BAILOUT("will cause link error");
++      }
 +    }
 +  }
    ciInstanceKlass* klass = target->holder();
@@ -442,7 +754,7 @@
    // how klass->is_loaded() can be true and yet target->is_loaded() is false.
    // this happened while running the JCK invokevirtual tests under doit.  TKR
    ciMethod* cha_monomorphic_target = NULL;
-@@ -1763,25 +1822,15 @@
+@@ -1763,25 +1836,15 @@
          code == Bytecodes::_invokedynamic) {
        ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
        bool success = false;
@@ -472,7 +784,7 @@
        clear_inline_bailout();
        if (success) {
          // Register dependence if JVMTI has either breakpoint
-@@ -1792,8 +1841,13 @@
+@@ -1792,8 +1855,13 @@
          }
          return;
        }
@@ -486,7 +798,18 @@
    // If we attempted an inline which did not succeed because of a
    // bailout during construction of the callee graph, the entire
    // compilation has to be aborted. This is fairly rare and currently
-@@ -1859,7 +1913,7 @@
+@@ -1807,10 +1875,6 @@
+ 
+   // inlining not successful => standard invoke
+   bool is_loaded = target->is_loaded();
+-  bool has_receiver =
+-    code == Bytecodes::_invokespecial   ||
+-    code == Bytecodes::_invokevirtual   ||
+-    code == Bytecodes::_invokeinterface;
+   ValueType* result_type = as_ValueType(target->return_type());
+ 
+   // We require the debug info to be the "state before" because
+@@ -1859,7 +1923,7 @@
        } else if (exact_target != NULL) {
          target_klass = exact_target->holder();
        }
@@ -495,7 +818,7 @@
      }
    }
  
-@@ -3101,30 +3155,61 @@
+@@ -3101,30 +3165,61 @@
  }
  
  
@@ -578,7 +901,7 @@
  }
  
  
-@@ -3308,7 +3393,7 @@
+@@ -3308,7 +3403,7 @@
            recv = args->at(0);
            null_check(recv);
          }
@@ -587,7 +910,7 @@
        }
      }
    }
-@@ -3319,13 +3404,6 @@
+@@ -3319,13 +3414,6 @@
    Value value = append_split(result);
    if (result_type != voidType) push(result_type, value);
  
@@ -601,7 +924,7 @@
    // done
    return true;
  }
-@@ -3481,7 +3559,7 @@
+@@ -3481,7 +3569,7 @@
  }
  
  
@@ -610,7 +933,7 @@
    assert(!callee->is_native(), "callee must not be native");
    if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
      INLINE_BAILOUT("inlining prohibited by policy");
-@@ -3511,10 +3589,10 @@
+@@ -3511,10 +3599,10 @@
    // now perform tests that are based on flag settings
    if (callee->force_inline() || callee->should_inline()) {
      // ignore heuristic controls on inlining
@@ -624,7 +947,7 @@
      if (callee->code_size_for_inlining() > max_inline_size()    ) INLINE_BAILOUT("callee is too large");
  
      // don't inline throwable methods unless the inlining tree is rooted in a throwable class
-@@ -3533,28 +3611,25 @@
+@@ -3533,28 +3621,25 @@
      if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) {
        INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
      }
@@ -659,7 +982,7 @@
      // note: null check must happen even if first instruction of callee does
      //       an implicit null check since the callee is in a different scope
      //       and we must make sure exception handling does the right thing
-@@ -3570,7 +3645,7 @@
+@@ -3570,7 +3655,7 @@
      compilation()->set_would_profile(true);
  
      if (profile_calls()) {
@@ -668,7 +991,7 @@
      }
    }
  
-@@ -3612,17 +3687,10 @@
+@@ -3612,17 +3697,10 @@
    // note: this will also ensure that all arguments are computed before being passed
    ValueStack* callee_state = state();
    ValueStack* caller_state = state()->caller_state();
@@ -690,7 +1013,7 @@
    }
  
    // Remove args from stack.
-@@ -3736,26 +3804,88 @@
+@@ -3736,26 +3814,88 @@
  
  
  bool GraphBuilder::for_method_handle_inline(ciMethod* callee) {
@@ -798,7 +1121,7 @@
    return false;
  }
  
-@@ -3947,22 +4077,24 @@
+@@ -3947,22 +4087,24 @@
  }
  
  
@@ -1905,7 +2228,7 @@
    if (FieldType::is_array(class_name)) {
      return resolve_array_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL);
    } else if (FieldType::is_obj(class_name)) {
-@@ -2367,7 +2370,7 @@
+@@ -2367,19 +2370,16 @@
    assert(MethodHandles::is_signature_polymorphic(iid) &&
           MethodHandles::is_signature_polymorphic_intrinsic(iid) &&
           iid != vmIntrinsics::_invokeGeneric,
@@ -1914,7 +2237,28 @@
  
    unsigned int hash  = invoke_method_table()->compute_hash(signature, iid);
    int          index = invoke_method_table()->hash_to_index(hash);
-@@ -2486,6 +2489,7 @@
+   SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, iid);
+   methodHandle m;
+-  bool start_compile = false;
+   if (spe == NULL || spe->property_oop() == NULL) {
+     spe = NULL;
+     // Must create lots of stuff here, but outside of the SystemDictionary lock.
+     m = methodOopDesc::make_method_handle_intrinsic(iid, signature, CHECK_(empty));
+-    if (!PreferInterpreterMethodHandles)
+-      start_compile = true;
+ 
+     // Now grab the lock.  We might have to throw away the new method,
+     // if a racing thread has managed to install one at the same time.
+@@ -2396,7 +2396,7 @@
+   assert(spe != NULL && spe->property_oop() != NULL, "");
+   m = methodOop(spe->property_oop());
+   assert(m->is_method(), "");
+-  if (start_compile && m->code() == NULL) {
++  if (m->code() == NULL) {
+     CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier,
+                                   methodHandle(), CompileThreshold, "MH", CHECK_(empty));
+   }
+@@ -2486,6 +2486,7 @@
      assert(java_lang_invoke_MethodType::is_instance(spe->property_oop()), "");
      return Handle(THREAD, spe->property_oop());
    } else if (THREAD->is_Compiler_thread()) {
@@ -1922,7 +2266,7 @@
      return Handle();  // do not attempt from within compiler, unless it was cached
    }
  
-@@ -2634,13 +2638,13 @@
+@@ -2634,13 +2635,13 @@
    guarantee(java_lang_invoke_MethodHandle::is_instance(bsm()),
              "caller must supply a valid BSM");
  
@@ -1938,7 +2282,7 @@
    assert(appendix_box->obj_at(0) == NULL, "");
  
    // call java.lang.invoke.MethodHandleNatives::makeDynamicCallSite(bsm, name, mtype, info, caller_mname, caller_pos)
-@@ -2657,7 +2661,7 @@
+@@ -2657,7 +2658,7 @@
                           SystemDictionary::MethodHandleNatives_klass(),
                           vmSymbols::linkCallSite_name(),
                           vmSymbols::linkCallSite_signature(),
@@ -1972,7 +2316,18 @@
 diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp
 --- a/src/share/vm/code/nmethod.cpp
 +++ b/src/share/vm/code/nmethod.cpp
-@@ -2383,6 +2383,7 @@
+@@ -968,7 +968,9 @@
+   if (printmethod) {
+     print_code();
+     print_pcs();
+-    oop_maps()->print();
++    if (oop_maps()) {
++      oop_maps()->print();
++    }
+   }
+   if (PrintDebugInfo) {
+     print_scopes();
+@@ -2387,6 +2389,7 @@
      if (on_scavenge_root_list())  tty->print("scavenge_root ");
      tty->print_cr("}:");
    }
@@ -1980,7 +2335,7 @@
    if (size              () > 0) tty->print_cr(" total in heap  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
                                                (address)this,
                                                (address)this + size(),
-@@ -2427,6 +2428,7 @@
+@@ -2431,6 +2434,7 @@
                                                nul_chk_table_begin(),
                                                nul_chk_table_end(),
                                                nul_chk_table_size());
@@ -3688,6 +4043,19 @@
    return r;
  }
  
+diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp
+--- a/src/share/vm/runtime/globals.hpp
++++ b/src/share/vm/runtime/globals.hpp
+@@ -3839,9 +3839,6 @@
+   diagnostic(bool, VerifyMethodHandles, trueInDebug,                        \
+           "perform extra checks when constructing method handles")          \
+                                                                             \
+-  diagnostic(bool, PreferInterpreterMethodHandles, false,                   \
+-          "suppress compiled fast-paths for out-of-line MH calls")          \
+-                                                                            \
+   diagnostic(bool, ShowMethodHandleFrames, false,                           \
+           "show intermediate compile lambda form frames (usually hidden)")  \
+                                                                             \
 diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp
 --- a/src/share/vm/runtime/sharedRuntime.cpp
 +++ b/src/share/vm/runtime/sharedRuntime.cpp
@@ -3702,7 +4070,17 @@
  
    // Find bytecode
    Bytecode_invoke bytecode(caller, bci);
-@@ -1040,25 +1040,32 @@
+@@ -1019,7 +1019,8 @@
+   int bytecode_index = bytecode.index();
+ 
+   // Find receiver for non-static call
+-  if (bc != Bytecodes::_invokestatic) {
++  if (bc != Bytecodes::_invokestatic &&
++      bc != Bytecodes::_invokedynamic) {
+     // This register map must be update since we need to find the receiver for
+     // compiled frames. The receiver might be in a register.
+     RegisterMap reg_map2(thread);
+@@ -1040,25 +1041,32 @@
    }
  
    // Resolve method. This is parameterized by bytecode.
@@ -3741,7 +4119,7 @@
      }
    }
  #endif
-@@ -1152,6 +1159,7 @@
+@@ -1152,6 +1160,7 @@
    methodHandle callee_method = call_info.selected_method();
  
    assert((!is_virtual && invoke_code == Bytecodes::_invokestatic) ||
@@ -3749,6 +4127,40 @@
           ( is_virtual && invoke_code != Bytecodes::_invokestatic), "inconsistent bytecode");
  
  #ifndef PRODUCT
+@@ -1167,7 +1176,7 @@
+       (is_optimized) ? "optimized " : "", (is_virtual) ? "virtual" : "static",
+       Bytecodes::name(invoke_code));
+     callee_method->print_short_name(tty);
+-    tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
++    tty->print_cr(" at pc: " INTPTR_FORMAT " to code: " INTPTR_FORMAT, caller_frame.pc(), callee_method->code());
+   }
+ #endif
+ 
+@@ -1175,8 +1184,9 @@
+   // If the resolved method is a MethodHandle invoke target the call
+   // site must be a MethodHandle call site, because the lambda form might tail-call
+   // leaving the stack in a state unknown to either caller or callee
+-  assert(!callee_method->is_compiled_lambda_form() ||
+-         caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
++  // TODO detune for now but we might need it again
++//  assert(!callee_method->is_compiled_lambda_form() ||
++//         caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
+ 
+   // Compute entry points. This might require generation of C2I converter
+   // frames, so we cannot be holding any locks here. Furthermore, the
+@@ -1640,12 +1650,6 @@
+   // Get the return PC for the passed caller PC.
+   address return_pc = caller_pc + frame::pc_return_offset;
+ 
+-  // Don't fixup method handle call sites as the executed method
+-  // handle adapters are doing the required MethodHandle chain work.
+-  if (nm->is_method_handle_return(return_pc)) {
+-    return;
+-  }
+-
+   // There is a benign race here. We could be attempting to patch to a compiled
+   // entry point at the same time the callee is being deoptimized. If that is
+   // the case then entry_point may in fact point to a c2i and we'd patch the
 diff --git a/src/share/vm/runtime/vframeArray.cpp b/src/share/vm/runtime/vframeArray.cpp
 --- a/src/share/vm/runtime/vframeArray.cpp
 +++ b/src/share/vm/runtime/vframeArray.cpp