changeset 485:9717ee54c9f5

meth-lazy: update for review comments
author twisti
date Tue, 17 Jul 2012 17:00:57 -0700
parents ad665697620c
children 65906046e5fd
files meth-lazy-7023639.review.patch
diffstat 1 files changed, 739 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/meth-lazy-7023639.review.patch	Tue Jul 17 05:23:18 2012 -0700
+++ b/meth-lazy-7023639.review.patch	Tue Jul 17 17:00:57 2012 -0700
@@ -1,6 +1,259 @@
 # HG changeset patch
-# Parent 80f2a5825abb717dc55c38358758a373258beadd
+# Parent 640c887b5e2ec7135ab36c38220de7050228608d
 
+diff --git a/src/cpu/sparc/vm/interpreter_sparc.cpp b/src/cpu/sparc/vm/interpreter_sparc.cpp
+--- a/src/cpu/sparc/vm/interpreter_sparc.cpp
++++ b/src/cpu/sparc/vm/interpreter_sparc.cpp
+@@ -397,7 +397,7 @@
+     case Interpreter::java_lang_ref_reference_get
+                                              : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
+     default:
+-      ShouldNotReachHere();
++      fatal(err_msg("unexpected method kind: %d", kind));
+       break;
+   }
+ 
+diff --git a/src/cpu/sparc/vm/methodHandles_sparc.cpp b/src/cpu/sparc/vm/methodHandles_sparc.cpp
+--- a/src/cpu/sparc/vm/methodHandles_sparc.cpp
++++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp
+@@ -133,9 +133,7 @@
+     __ verify_thread();
+     const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
+     __ ld(interp_only, temp);
+-    __ tst(temp);
+-    __ br(Assembler::zero, true, Assembler::pt, run_compiled_code);
+-    __ delayed()->nop();
++    __ cmp_and_br_short(temp, 0, Assembler::zero, Assembler::pt, run_compiled_code);
+     __ ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
+     __ jmp(target, 0);
+     __ delayed()->nop();
+@@ -259,7 +257,8 @@
+   if (TraceMethodHandles) {
+     const char* name = vmIntrinsics::name_at(iid);
+     if (*name == '_')  name += 1;
+-    char* qname = NEW_C_HEAP_ARRAY(char, 100);
++    const size_t len = strlen(name) + 50;
++    char* qname = NEW_C_HEAP_ARRAY(char, len);
+     const char* suffix = "";
+     if (vmIntrinsics::method_for(iid) == NULL ||
+         !vmIntrinsics::method_for(iid)->access_flags().is_public()) {
+@@ -268,7 +267,7 @@
+       else
+         suffix = "/private";
+     }
+-    jio_snprintf(qname, 100, "MethodHandle::interpreter_entry::%s%s", name, suffix);
++    jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
+     if (O0_mh != noreg)
+       __ mov(O0_mh, G3_method_handle);  // make stub happy
+     trace_method_handle(_masm, qname);
+diff --git a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
+--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
++++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
+@@ -888,15 +888,15 @@
+ 
+ static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg, Register temp2_reg,
+                         address code_start, address code_end,
+-                        Label& L_ok, Label& L_fail) {
++                        Label& L_ok) {
++  Label L_fail;
+   __ set(ExternalAddress(code_start), temp_reg);
+-  __ set((int)(intptr_t)(code_end - code_start), temp2_reg);
++  __ set(pointer_delta(code_end, code_start, 1), temp2_reg);
+   __ cmp(pc_reg, temp_reg);
+-  __ br(Assembler::lessEqualUnsigned, false, Assembler::pn, L_fail);
++  __ brx(Assembler::lessEqualUnsigned, false, Assembler::pn, L_fail);
+   __ delayed()->add(temp_reg, temp2_reg, temp_reg);
+   __ cmp(pc_reg, temp_reg);
+-  __ br(Assembler::lessUnsigned, false, Assembler::pt, L_ok);
+-  __ delayed()->nop();
++  __ cmp_and_brx_short(pc_reg, temp_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
+   __ bind(L_fail);
+ }
+ 
+@@ -946,22 +946,19 @@
+     //         StubRoutines::contains($return_addr),
+     //         "i2c adapter must return to an interpreter frame");
+     __ block_comment("verify_i2c { ");
+-    Label L_ok, L_fail0, L_fail1, L_fail2;
++    Label L_ok;
+     if (Interpreter::code() != NULL)
+       range_check(masm, O7, O0, O1,
+                   Interpreter::code()->code_start(), Interpreter::code()->code_end(),
+-                  L_ok, L_fail0);
+-    __ bind(L_fail0);
++                  L_ok);
+     if (StubRoutines::code1() != NULL)
+       range_check(masm, O7, O0, O1,
+                   StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(),
+-                  L_ok, L_fail1);
+-    __ bind(L_fail1);
++                  L_ok);
+     if (StubRoutines::code2() != NULL)
+       range_check(masm, O7, O0, O1, 
+                   StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(),
+-                  L_ok, L_fail2);
+-    __ bind(L_fail2);
++                  L_ok);
+     const char* msg = "i2c adapter must return to an interpreter frame";
+     __ block_comment(msg);
+     __ stop(msg);
+@@ -2044,7 +2041,7 @@
+   } else if (special_dispatch == vmIntrinsics::_invokeBasic) {
+     has_receiver = true;
+   } else {
+-    guarantee(false, err_msg("special_dispatch=%d", special_dispatch));
++    fatal(err_msg("special_dispatch=%d", special_dispatch));
+   }
+ 
+   if (member_reg != noreg) {
+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
+@@ -257,7 +257,8 @@
+   if (TraceMethodHandles) {
+     const char* name = vmIntrinsics::name_at(iid);
+     if (*name == '_')  name += 1;
+-    char* qname = NEW_C_HEAP_ARRAY(char, 100);
++    const size_t len = strlen(name) + 50;
++    char* qname = NEW_C_HEAP_ARRAY(char, len);
+     const char* suffix = "";
+     if (vmIntrinsics::method_for(iid) == NULL ||
+         !vmIntrinsics::method_for(iid)->access_flags().is_public()) {
+@@ -266,7 +267,7 @@
+       else
+         suffix = "/private";
+     }
+-    jio_snprintf(qname, 100, "MethodHandle::interpreter_entry::%s%s", name, suffix);
++    jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
+     // note: stub look for mh in rcx
+     trace_method_handle(_masm, qname);
+   }
+diff --git a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
+--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
++++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
+@@ -645,7 +645,8 @@
+ 
+ static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg,
+                         address code_start, address code_end,
+-                        Label& L_ok, Label& L_fail) {
++                        Label& L_ok) {
++  Label L_fail;
+   __ lea(temp_reg, ExternalAddress(code_start));
+   __ cmpptr(pc_reg, temp_reg);
+   __ jcc(Assembler::belowEqual, L_fail);
+@@ -692,22 +693,19 @@
+     //         StubRoutines::contains($return_addr),
+     //         "i2c adapter must return to an interpreter frame");
+     __ block_comment("verify_i2c { ");
+-    Label L_ok, L_fail0, L_fail1, L_fail2;
++    Label L_ok;
+     if (Interpreter::code() != NULL)
+       range_check(masm, rax, rdi,
+                   Interpreter::code()->code_start(), Interpreter::code()->code_end(),
+-                  L_ok, L_fail0);
+-    __ bind(L_fail0);
++                  L_ok);
+     if (StubRoutines::code1() != NULL)
+       range_check(masm, rax, rdi,
+                   StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(),
+-                  L_ok, L_fail1);
+-    __ bind(L_fail1);
++                  L_ok);
+     if (StubRoutines::code2() != NULL)
+       range_check(masm, rax, rdi,
+                   StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(),
+-                  L_ok, L_fail2);
+-    __ bind(L_fail2);
++                  L_ok);
+     const char* msg = "i2c adapter must return to an interpreter frame";
+     __ block_comment(msg);
+     __ stop(msg);
+diff --git a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
+--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
++++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
+@@ -592,7 +592,8 @@
+ 
+ static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg,
+                         address code_start, address code_end,
+-                        Label& L_ok, Label& L_fail) {
++                        Label& L_ok) {
++  Label L_fail;
+   __ lea(temp_reg, ExternalAddress(code_start));
+   __ cmpptr(pc_reg, temp_reg);
+   __ jcc(Assembler::belowEqual, L_fail);
+@@ -644,22 +645,19 @@
+     //         StubRoutines::contains($return_addr),
+     //         "i2c adapter must return to an interpreter frame");
+     __ block_comment("verify_i2c { ");
+-    Label L_ok, L_fail0, L_fail1, L_fail2;
++    Label L_ok;
+     if (Interpreter::code() != NULL)
+       range_check(masm, rax, r11,
+                   Interpreter::code()->code_start(), Interpreter::code()->code_end(),
+-                  L_ok, L_fail0);
+-    __ bind(L_fail0);
++                  L_ok);
+     if (StubRoutines::code1() != NULL)
+       range_check(masm, rax, r11,
+                   StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(),
+-                  L_ok, L_fail1);
+-    __ bind(L_fail1);
++                  L_ok);
+     if (StubRoutines::code2() != NULL)
+       range_check(masm, rax, r11,
+                   StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(),
+-                  L_ok, L_fail2);
+-    __ bind(L_fail2);
++                  L_ok);
+     const char* msg = "i2c adapter must return to an interpreter frame";
+     __ block_comment(msg);
+     __ stop(msg);
+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
+@@ -1526,7 +1526,7 @@
+     case Interpreter::java_lang_ref_reference_get
+                                              : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
+     default:
+-      ShouldNotReachHere();
++      fatal(err_msg("unexpected method kind: %d", kind));
+       break;
+   }
+ 
+diff --git a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
++++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+@@ -1524,11 +1524,11 @@
+   switch (kind) {
+   case Interpreter::zerolocals             :                                                                             break;
+   case Interpreter::zerolocals_synchronized: synchronized = true;                                                        break;
+-  case Interpreter::native                 : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false); break;
+-  case Interpreter::native_synchronized    : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(true);  break;
+-  case Interpreter::empty                  : entry_point = ((InterpreterGenerator*) this)->generate_empty_entry();       break;
+-  case Interpreter::accessor               : entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry();    break;
+-  case Interpreter::abstract               : entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();    break;
++  case Interpreter::native                 : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break;
++  case Interpreter::native_synchronized    : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true);  break;
++  case Interpreter::empty                  : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry();       break;
++  case Interpreter::accessor               : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry();    break;
++  case Interpreter::abstract               : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry();    break;
+ 
+   case Interpreter::java_lang_math_sin     : // fall thru
+   case Interpreter::java_lang_math_cos     : // fall thru
+@@ -1538,11 +1538,11 @@
+   case Interpreter::java_lang_math_log10   : // fall thru
+   case Interpreter::java_lang_math_sqrt    : // fall thru
+   case Interpreter::java_lang_math_pow     : // fall thru
+-  case Interpreter::java_lang_math_exp     : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);    break;
++  case Interpreter::java_lang_math_exp     : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);    break;
+   case Interpreter::java_lang_ref_reference_get
+                                            : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
+   default:
+-    ShouldNotReachHere();
++    fatal(err_msg("unexpected method kind: %d", kind));
+     break;
+   }
+ 
 diff --git a/src/cpu/zero/vm/cppInterpreter_zero.cpp b/src/cpu/zero/vm/cppInterpreter_zero.cpp
 --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp
 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp
@@ -45,6 +298,105 @@
  
    return stack->sp() + argument_slots;
  }
+diff --git a/src/share/vm/c1/c1_FrameMap.cpp b/src/share/vm/c1/c1_FrameMap.cpp
+--- a/src/share/vm/c1/c1_FrameMap.cpp
++++ b/src/share/vm/c1/c1_FrameMap.cpp
+@@ -66,7 +66,7 @@
+ }
+ 
+ 
+-CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signature, bool outgoing, bool is_method_handle_invoke) {
++CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signature, bool outgoing) {
+   // compute the size of the arguments first.  The signature array
+   // that java_calling_convention takes includes a T_VOID after double
+   // work items but our signatures do not.
+@@ -77,6 +77,7 @@
+   }
+ 
+   BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
++  VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
+   int sig_index = 0;
+   for (i = 0; i < sizeargs; i++, sig_index++) {
+     sig_bt[i] = signature->at(sig_index);
+@@ -86,32 +87,7 @@
+     }
+   }
+ 
+-  VMRegPair* regs;
+-  intptr_t out_preserve;
+-  if (!is_method_handle_invoke) {
+-    regs         = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
+-    out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, outgoing);
+-  } else {
+-    ShouldNotReachHere();
+-    // Rotate signature one-left into a temporary array for allocation:
+-    // { L, I, J, D } -> { I, J, D, L }
+-    BasicType* temp_sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
+-    for (int i = 0; i < sizeargs - 1; i++) {
+-      temp_sig_bt[i] = sig_bt[i + 1];
+-    }
+-    temp_sig_bt[sizeargs - 1] = sig_bt[0];
+-
+-    VMRegPair* temp_regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
+-    out_preserve = SharedRuntime::java_calling_convention(temp_sig_bt, temp_regs, sizeargs, outgoing);
+-
+-    // Rotate calling convention one-right into final array:
+-    // { a1, a2, a3, a0 } -> { a0, a1, a2, a3 }
+-    regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
+-    regs[0] = temp_regs[sizeargs - 1];
+-    for (int i = 0; i < sizeargs - 1; i++) {
+-      regs[i + 1] = temp_regs[i];
+-    }
+-  }
++  intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, outgoing);
+   LIR_OprList* args = new LIR_OprList(signature->length());
+   for (i = 0; i < sizeargs;) {
+     BasicType t = sig_bt[i];
+@@ -205,7 +181,7 @@
+ 
+   _argcount = method->arg_size();
+   _argument_locations = new intArray(_argcount, -1);
+-  _incoming_arguments = java_calling_convention(signature_type_array_for(method), false, method->is_method_handle_intrinsic());
++  _incoming_arguments = java_calling_convention(signature_type_array_for(method), false);
+   _oop_map_arg_count = _incoming_arguments->reserved_stack_slots();
+ 
+   int java_index = 0;
+diff --git a/src/share/vm/c1/c1_FrameMap.hpp b/src/share/vm/c1/c1_FrameMap.hpp
+--- a/src/share/vm/c1/c1_FrameMap.hpp
++++ b/src/share/vm/c1/c1_FrameMap.hpp
+@@ -182,7 +182,7 @@
+   // for outgoing calls, these also update the reserved area to
+   // include space for arguments and any ABI area.
+   CallingConvention* c_calling_convention(const BasicTypeArray* signature);
+-  CallingConvention* java_calling_convention(const BasicTypeArray* signature, bool outgoing, bool is_method_handle_invoke);
++  CallingConvention* java_calling_convention(const BasicTypeArray* signature, bool outgoing);
+ 
+   // deopt support
+   ByteSize sp_offset_for_orig_pc() { return sp_offset_for_monitor_base(_num_monitors); }
+diff --git a/src/share/vm/c1/c1_GraphBuilder.cpp b/src/share/vm/c1/c1_GraphBuilder.cpp
+--- a/src/share/vm/c1/c1_GraphBuilder.cpp
++++ b/src/share/vm/c1/c1_GraphBuilder.cpp
+@@ -1648,7 +1648,7 @@
+     code == Bytecodes::_invokespecial   ||
+     code == Bytecodes::_invokevirtual   ||
+     code == Bytecodes::_invokeinterface;
+-  const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
++  const bool is_invokedynamic = (code == Bytecodes::_invokedynamic);
+ 
+   bool will_link;
+   ciMethod*             target = stream()->get_method(will_link);
+diff --git a/src/share/vm/c1/c1_LIRGenerator.cpp b/src/share/vm/c1/c1_LIRGenerator.cpp
+--- a/src/share/vm/c1/c1_LIRGenerator.cpp
++++ b/src/share/vm/c1/c1_LIRGenerator.cpp
+@@ -2744,7 +2744,7 @@
+ //   we cannot spill it as it is spill-locked
+ //
+ void LIRGenerator::do_Invoke(Invoke* x) {
+-  CallingConvention* cc = frame_map()->java_calling_convention(x->signature(), true, /*is_method_handle_invoke*/ false);
++  CallingConvention* cc = frame_map()->java_calling_convention(x->signature(), true);
+ 
+   LIR_OprList* arg_list = cc->args();
+   LIRItemList* args = invoke_visit_arguments(x);
 diff --git a/src/share/vm/ci/ciSignature.hpp b/src/share/vm/ci/ciSignature.hpp
 --- a/src/share/vm/ci/ciSignature.hpp
 +++ b/src/share/vm/ci/ciSignature.hpp
@@ -361,6 +713,43 @@
    template(java_lang_invoke_ForceInline_signature,    "Ljava/lang/invoke/ForceInline;")           \
    template(java_lang_invoke_DontInline_signature,     "Ljava/lang/invoke/DontInline;")            \
    template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
+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
+@@ -2389,7 +2389,6 @@
+     if (on_scavenge_root_list())  tty->print("scavenge_root ");
+     tty->print_cr("}:");
+   }
+-  if (Verbose) {
+   if (size              () > 0) tty->print_cr(" total in heap  [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                               (address)this,
+                                               (address)this + size(),
+@@ -2434,7 +2433,6 @@
+                                               nul_chk_table_begin(),
+                                               nul_chk_table_end(),
+                                               nul_chk_table_size());
+-  }
+ }
+ 
+ void nmethod::print_code() {
+diff --git a/src/share/vm/interpreter/templateInterpreter.cpp b/src/share/vm/interpreter/templateInterpreter.cpp
+--- a/src/share/vm/interpreter/templateInterpreter.cpp
++++ b/src/share/vm/interpreter/templateInterpreter.cpp
+@@ -374,11 +374,9 @@
+   method_entry(java_lang_ref_reference_get)
+ 
+   // method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
+-  {
+-    for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
+-      Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
+-      Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
+-    }
++  for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
++    Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
++    Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
+   }
+ 
+   // all native method kinds (must be one contiguous block)
 diff --git a/src/share/vm/oops/methodOop.cpp b/src/share/vm/oops/methodOop.cpp
 --- a/src/share/vm/oops/methodOop.cpp
 +++ b/src/share/vm/oops/methodOop.cpp
@@ -380,16 +769,306 @@
  }
  
  // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
+diff --git a/src/share/vm/oops/symbol.cpp b/src/share/vm/oops/symbol.cpp
+--- a/src/share/vm/oops/symbol.cpp
++++ b/src/share/vm/oops/symbol.cpp
+@@ -96,15 +96,15 @@
+   address scan = bytes + i;
+   if (scan > limit)
+     return -1;
+-  for (;;) {
++  for (; scan <= limit; scan++) {
+     scan = (address) memchr(scan, first_char, (limit + 1 - scan));
+     if (scan == NULL)
+       return -1;  // not found
+     assert(scan >= bytes+i && scan <= limit, "scan oob");
+     if (memcmp(scan, str, len) == 0)
+       return (int)(scan - bytes);
+-    ++scan;  // skip the initial matching character
+   }
++  return -1;
+ }
+ 
+ 
+diff --git a/src/share/vm/opto/bytecodeInfo.cpp b/src/share/vm/opto/bytecodeInfo.cpp
+--- a/src/share/vm/opto/bytecodeInfo.cpp
++++ b/src/share/vm/opto/bytecodeInfo.cpp
+@@ -244,7 +244,7 @@
+   }
+ 
+   // use frequency-based objections only for non-trivial methods
+-  if (callee_method->code_size_for_inlining() <= MaxTrivialSize) return NULL;
++  if (callee_method->code_size() <= MaxTrivialSize) return NULL;
+ 
+   // don't use counts with -Xcomp or CTW
+   if (UseInterpreter && !CompileTheWorld) {
+@@ -293,7 +293,7 @@
+   }
+ 
+   // suppress a few checks for accessors and trivial methods
+-  if (callee_method->code_size_for_inlining() > MaxTrivialSize) {
++  if (callee_method->code_size() > MaxTrivialSize) {
+ 
+     // don't inline into giant methods
+     if (C->unique() > (uint)NodeCountInliningCutoff) {
+@@ -435,13 +435,6 @@
+     return NULL;
+   }
+ 
+-  // XXX this is probably to much
+-//  // Always inline ForceInline methods.
+-//  if (callee_method->force_inline()) {
+-//    if (PrintInlining)  print_inlining(callee_method, caller_bci, "force inline by annotation");
+-//    return WarmCallInfo::always_hot();
+-//  }
+-
+   // Check if inlining policy says no.
+   WarmCallInfo wci = *(initial_wci);
+   failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci);
+diff --git a/src/share/vm/opto/callGenerator.cpp b/src/share/vm/opto/callGenerator.cpp
+--- a/src/share/vm/opto/callGenerator.cpp
++++ b/src/share/vm/opto/callGenerator.cpp
+@@ -654,41 +654,6 @@
+ }
+ 
+ 
+-//------------------------PredictedDynamicCallGenerator-----------------------
+-// Internal class which handles all out-of-line calls checking receiver type.
+-class PredictedDynamicCallGenerator : public CallGenerator {
+-  ciMethodHandle* _predicted_method_handle;
+-  CallGenerator*  _hit_cg;
+-  CallGenerator*  _missed_cg;
+-  float           _hit_prob;
+-
+-public:
+-  PredictedDynamicCallGenerator(ciMethodHandle* predicted_method_handle,
+-                                CallGenerator*  hit_cg,
+-                                CallGenerator*  missed_cg,
+-                                float hit_prob)
+-    : CallGenerator(missed_cg->method()),
+-      _predicted_method_handle(predicted_method_handle),
+-      _hit_cg(     hit_cg),
+-      _missed_cg(  missed_cg),
+-      _hit_prob(hit_prob)
+-  {}
+-
+-  virtual bool is_inline()   const { return _hit_cg->is_inline() || _missed_cg->is_inline(); }
+-  virtual bool is_deferred() const { return _hit_cg->is_deferred(); }
+-
+-  virtual JVMState* generate(JVMState* jvms);
+-};
+-
+-
+-// CallGenerator* CallGenerator::for_predicted_dynamic_call(ciMethodHandle* predicted_method_handle,
+-//                                                          CallGenerator* if_missed,
+-//                                                          CallGenerator* if_hit,
+-//                                                          float hit_prob) {
+-//   return new PredictedDynamicCallGenerator(predicted_method_handle, if_missed, if_hit, hit_prob);
+-// }
+-
+-
+ CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee) {
+   assert(callee->is_method_handle_intrinsic() ||
+          callee->is_compiled_lambda_form(), "for_method_handle_call mismatch");
+@@ -779,189 +744,6 @@
+ }
+ 
+ 
+-JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
+-  GraphKit kit(jvms);
+-  Compile* C = kit.C;
+-  PhaseGVN& gvn = kit.gvn();
+-
+-  CompileLog* log = C->log();
+-  if (log != NULL) {
+-    log->elem("predicted_dynamic_call bci='%d'", jvms->bci());
+-  }
+-
+-  const TypeOopPtr* predicted_mh_ptr = TypeOopPtr::make_from_constant(_predicted_method_handle, true);
+-  Node* predicted_mh = kit.makecon(predicted_mh_ptr);
+-
+-  Node* bol = NULL;
+-  int bc = jvms->method()->java_code_at_bci(jvms->bci());
+-  if (bc != Bytecodes::_invokedynamic) {
+-    // This is the selectAlternative idiom for guardWithTest or
+-    // similar idioms.
+-    Node* receiver = kit.argument(0);
+-
+-    // Check if the MethodHandle is the expected one
+-    Node* cmp = gvn.transform(new (C, 3) CmpPNode(receiver, predicted_mh));
+-    bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) );
+-  } else {
+-    // Get the constant pool cache from the caller class.
+-    ciMethod* caller_method = jvms->method();
+-    ciBytecodeStream str(caller_method);
+-    str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
+-    ciCPCache* cpcache = str.get_cpcache();
+-
+-    // Get the offset of the CallSite from the constant pool cache
+-    // pointer.
+-    int index = str.get_method_index();
+-    size_t call_site_offset = cpcache->get_f1_offset(index);
+-
+-    // Load the CallSite object from the constant pool cache.
+-    const TypeOopPtr* cpcache_type   = TypeOopPtr::make_from_constant(cpcache);  // returns TypeAryPtr of type T_OBJECT
+-    const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
+-    Node* cpcache_adr   = kit.makecon(cpcache_type);
+-    Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset);
+-    // The oops in the constant pool cache are not compressed; load then as raw pointers.
+-    Node* call_site     = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw);
+-
+-    // Load the target MethodHandle from the CallSite object.
+-    const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass());
+-    Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
+-    Node* target_mh  = kit.make_load(kit.control(), target_adr, target_type, T_OBJECT);
+-
+-    // Check if the MethodHandle is still the same.
+-    Node* cmp = gvn.transform(new (C, 3) CmpPNode(target_mh, predicted_mh));
+-    bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) );
+-  }
+-  IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN);
+-  kit.set_control(   gvn.transform(new (C, 1) IfTrueNode (iff)));
+-  Node* missed_ctl = gvn.transform(new (C, 1) IfFalseNode(iff));
+-
+-#if 1
+-  // Make the missed call:
+-  SafePointNode* slow_map = NULL;
+-  JVMState* slow_jvms;
+-  { PreserveJVMState pjvms(&kit);
+-    kit.set_control(missed_ctl);
+-    if (!kit.stopped()) {
+-      slow_jvms = _missed_cg->generate(kit.sync_jvms());
+-      if (kit.failing()) {
+-        return NULL;  // might happen because of NodeCountInliningCutoff
+-      }
+-      assert(slow_jvms != NULL, "must be");
+-      kit.add_exception_states_from(slow_jvms);
+-      kit.set_map(slow_jvms->map());
+-      if (!kit.stopped())
+-        slow_map = kit.stop();
+-    }
+-  }
+-
+-  if (kit.stopped()) {
+-    // Instance exactly does not matches the desired type.
+-    kit.set_jvms(slow_jvms);
+-    return kit.transfer_exceptions_into_jvms();
+-  }
+-
+-  // Make the hit call:
+-  JVMState* new_jvms = _hit_cg->generate(kit.sync_jvms());
+-  if (new_jvms == NULL) {
+-    // Inline failed, so make a direct call.
+-    assert(_hit_cg->is_inline(), "must have been a failed inline");
+-    CallGenerator* cg = CallGenerator::for_direct_call(_hit_cg->method());
+-    new_jvms = cg->generate(kit.sync_jvms());
+-  }
+-  kit.add_exception_states_from(new_jvms);
+-  kit.set_jvms(new_jvms);
+-
+-  // Need to merge slow and fast?
+-  if (slow_map == NULL) {
+-    // The fast path is the only path remaining.
+-    return kit.transfer_exceptions_into_jvms();
+-  }
+-
+-  if (kit.stopped()) {
+-    // Inlined method threw an exception, so it's just the slow path after all.
+-    kit.set_jvms(slow_jvms);
+-    return kit.transfer_exceptions_into_jvms();
+-  }
+-  SafePointNode* missed_map = slow_map;
+-#else
+-  // Make the hit call:
+-  JVMState* new_hit_jvms = _hit_cg->generate(kit.sync_jvms());
+-  if (new_hit_jvms == NULL) {
+-    // Inline failed, so make a direct call.
+-    assert(_hit_cg->is_inline(), "must have been a failed inline");
+-    CallGenerator* cg = CallGenerator::for_direct_call(_hit_cg->method());
+-    new_hit_jvms = cg->generate(kit.sync_jvms());
+-    if (new_hit_jvms == NULL) {
+-      return NULL;
+-    }
+-  }
+-  kit.add_exception_states_from(new_hit_jvms);
+-  kit.set_jvms(new_hit_jvms);
+-
+-  if (kit.stopped()) {
+-    return NULL;
+-  }
+-
+-  // Make the missed call:
+-  SafePointNode* missed_map = NULL;
+-  { PreserveJVMState pjvms(&kit);
+-    kit.set_control(missed_ctl);
+-    JVMState* new_missed_jvms = _missed_cg->generate(kit.sync_jvms());
+-    if (new_missed_jvms == NULL) {
+-      // Inline failed, so make a direct call.
+-      assert(_missed_cg->is_inline(), "must have been a failed inline");
+-      CallGenerator* cg = CallGenerator::for_direct_call(_missed_cg->method());
+-      new_missed_jvms = cg->generate(kit.sync_jvms());
+-      if (new_missed_jvms == NULL) {
+-        return NULL;
+-      }
+-    }
+-    kit.add_exception_states_from(new_missed_jvms);
+-    kit.set_map(new_missed_jvms->map());
+-    if (!kit.stopped()) {
+-      missed_map = kit.stop();
+-    }
+-    if (missed_map == NULL) {
+-      return NULL;
+-    }
+-  }
+-
+-  if (kit.stopped()) {
+-    return NULL;
+-  }
+-#endif
+-
+-  // Finish the diamond.
+-  kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
+-  RegionNode* region = new (C, 3) RegionNode(3);
+-  region->init_req(1, kit.control());
+-  region->init_req(2, missed_map->control());
+-  kit.set_control(gvn.transform(region));
+-  Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
+-  iophi->set_req(2, missed_map->i_o());
+-  kit.set_i_o(gvn.transform(iophi));
+-  kit.merge_memory(missed_map->merged_memory(), region, 2);
+-  uint tos = kit.jvms()->stkoff() + kit.sp();
+-  uint limit = missed_map->req();
+-  for (uint i = TypeFunc::Parms; i < limit; i++) {
+-    // Skip unused stack slots; fast forward to monoff();
+-    if (i == tos) {
+-      i = kit.jvms()->monoff();
+-      if (i >= limit)  break;
+-    }
+-    Node* m = kit.map()->in(i);
+-    Node* n = missed_map->in(i);
+-    if (m != n) {
+-      const Type* t = gvn.type(m)->meet(gvn.type(n));
+-      Node* phi = PhiNode::make(region, m, t);
+-      phi->set_req(2, n);
+-      kit.map()->set_req(i, gvn.transform(phi));
+-    }
+-  }
+-  return kit.transfer_exceptions_into_jvms();
+-}
+-
+-
+ //-------------------------UncommonTrapCallGenerator-----------------------------
+ // Internal class which handles all out-of-line calls checking receiver type.
+ class UncommonTrapCallGenerator : public CallGenerator {
 diff --git a/src/share/vm/opto/doCall.cpp b/src/share/vm/opto/doCall.cpp
 --- a/src/share/vm/opto/doCall.cpp
 +++ b/src/share/vm/opto/doCall.cpp
-@@ -496,9 +496,58 @@
+@@ -496,9 +496,57 @@
      // Round double result after a call from strict to non-strict code
      round_double_result(cg->method());
  
 +    ciType* rtype = cg->method()->return_type();
-+    if (iter().cur_bc_raw() == Bytecodes::_invokehandle ||
-+        iter().cur_bc() == Bytecodes::_invokedynamic) {
++    if (iter().cur_bc_raw() == Bytecodes::_invokehandle || is_invokedynamic) {
 +      // Be careful here with return types.
 +      ciType* ctype = iter().get_declared_method_signature()->return_type();
 +      if (ctype != rtype) {
@@ -443,7 +1122,7 @@
  #ifndef PRODUCT
        if (PrintOpto && (Verbose || WizardMode)) {
          method()->print_name(); tty->print_cr(" asserting nullness of result at bci: %d", bci());
-@@ -507,7 +556,7 @@
+@@ -507,7 +555,7 @@
  #endif
        if (C->log() != NULL) {
          C->log()->elem("assert_null reason='return' klass='%d'",
@@ -452,6 +1131,61 @@
        }
        // If there is going to be a trap, put it at the next bytecode:
        set_bci(iter().next_bci());
+diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp
+--- a/src/share/vm/opto/graphKit.cpp
++++ b/src/share/vm/opto/graphKit.cpp
+@@ -963,7 +963,6 @@
+   assert(call->jvms()->debug_start() == non_debug_edges, "");
+   assert(call->jvms()->debug_end()   == call->req(), "");
+   assert(call->jvms()->debug_depth() == call->req() - non_debug_edges, "");
+-//  tty->print("debug info: "); call->dump();
+ }
+ 
+ bool GraphKit::compute_stack_effects(int& inputs, int& depth, bool for_parse) {
+@@ -1383,30 +1382,6 @@
+ }
+ 
+ 
+-//--------------------------insert_argument------------------------------------
+-void GraphKit::insert_argument(ciMethod* callee, uint idx, Node* c) {
+-  const uint nargs = callee->arg_size();
+-  assert(0 <= idx && idx < nargs, err_msg("oob: idx=%d, nargs=%d", idx, nargs));
+-  assert(nargs <= (uint) jvms()->arg_size(), "must have argument stack space");
+-  for (uint i = (nargs - 1); i > idx; i--) {
+-    Node* arg = argument(i - 1);
+-    set_argument(i, arg);
+-  }
+-  set_argument(idx, c);
+-}
+-
+-//--------------------------remove_argument------------------------------------
+-void GraphKit::remove_argument(ciMethod* callee, uint idx) {
+-  const uint nargs = callee->arg_size();
+-  assert(0 <= idx && idx < nargs, err_msg("oob: idx=%d, nargs=%d", idx, nargs));
+-  for (uint i = idx; i < (nargs - 1); i++) {
+-    Node* arg = argument(i + 1);
+-    set_argument(i, arg);
+-  }
+-  set_argument(nargs - 1, top());
+-}
+-
+-
+ //=============================================================================
+ //--------------------------------memory---------------------------------------
+ Node* GraphKit::memory(uint alias_idx) {
+diff --git a/src/share/vm/opto/graphKit.hpp b/src/share/vm/opto/graphKit.hpp
+--- a/src/share/vm/opto/graphKit.hpp
++++ b/src/share/vm/opto/graphKit.hpp
+@@ -430,9 +430,6 @@
+   void set_argument(uint idx, Node* c){ map_not_null(); _map->set_argument(_map->_jvms, idx, c); }
+   void ensure_stack(uint stk_size)    { map_not_null(); _map->ensure_stack(_map->_jvms, stk_size); }
+ 
+-  void insert_argument(ciMethod* callee, uint idx, Node *c);
+-  void remove_argument(ciMethod* callee, uint idx);
+-
+   // Access unaliased memory
+   Node* memory(uint alias_idx);
+   Node* memory(const TypePtr *tp) { return memory(C->get_alias_index(tp)); }
 diff --git a/src/share/vm/prims/methodHandles.cpp b/src/share/vm/prims/methodHandles.cpp
 --- a/src/share/vm/prims/methodHandles.cpp
 +++ b/src/share/vm/prims/methodHandles.cpp