meth, indy: change impl.java.dyn => sun.dyn; consolidate final 6655638 changes
authorjrose
Wed Apr 08 02:52:08 2009 -0700 (7 months ago)
changeset 44fafa7c078a66
parent 43cca273ddf383
child 455cb83bb7bf49
meth, indy: change impl.java.dyn => sun.dyn; consolidate final 6655638 changes
indy.patch
meth-6655638.03.patch
meth-6655638.patch
meth.patch
meth.proj.patch
series
--- a/indy.patch Tue Apr 07 01:55:20 2009 -0700
+++ b/indy.patch Wed Apr 08 02:52:08 2009 -0700
@@ -502,7 +502,7 @@ diff --git a/src/cpu/x86/vm/templateInte
+ __ movl(rbx, Address(rbx, rcx,
+ Address::times_4, constantPoolCacheOopDesc::base_offset() +
+ ConstantPoolCacheEntry::f1_offset()));
-+ __ movl(rbx, Address(rbx, __ delayed_value(impl_java_dyn_CallSiteImpl::type_offset_in_bytes, rcx)));
++ __ movl(rbx, Address(rbx, __ delayed_value(sun_dyn_CallSiteImpl::type_offset_in_bytes, rcx)));
+ __ movl(rbx, Address(rbx, __ delayed_value(java_dyn_MethodType::rtype_offset_in_bytes, rcx)));
+ __ movl(rax, Address(rbx, __ delayed_value(java_lang_Class::klass_offset_in_bytes, rcx)));
+ __ check_klass_subtype(rdx, rax, rbx, L_ok_pops);
@@ -797,7 +797,7 @@ diff --git a/src/cpu/x86/vm/templateTabl
+ }
+
+ Label handle_unlinked_site;
-+ __ movptr(rcx, Address(rax, __ delayed_value(impl_java_dyn_CallSiteImpl::target_offset_in_bytes, rcx)));
++ __ movptr(rcx, Address(rax, __ delayed_value(sun_dyn_CallSiteImpl::target_offset_in_bytes, rcx)));
+ __ testptr(rcx, rcx);
+ __ jcc(Assembler::zero, handle_unlinked_site);
+
@@ -1085,7 +1085,7 @@ diff --git a/src/cpu/x86/vm/templateTabl
+ }
+
+ Label handle_unlinked_site;
-+ __ movptr(rcx, Address(rax, __ delayed_value(impl_java_dyn_CallSiteImpl::target_offset_in_bytes, rcx)));
++ __ movptr(rcx, Address(rax, __ delayed_value(sun_dyn_CallSiteImpl::target_offset_in_bytes, rcx)));
+ __ testptr(rcx, rcx);
+ __ jcc(Assembler::zero, handle_unlinked_site);
+
@@ -1293,13 +1293,13 @@ diff --git a/src/share/vm/classfile/java
}
-+// Support for impl_java_dyn_CallSiteImpl
-+
-+int impl_java_dyn_CallSiteImpl::_type_offset;
-+int impl_java_dyn_CallSiteImpl::_target_offset;
-+int impl_java_dyn_CallSiteImpl::_vmmethod_offset;
-+
-+void impl_java_dyn_CallSiteImpl::compute_offsets() {
++// Support for sun_dyn_CallSiteImpl
++
++int sun_dyn_CallSiteImpl::_type_offset;
++int sun_dyn_CallSiteImpl::_target_offset;
++int sun_dyn_CallSiteImpl::_vmmethod_offset;
++
++void sun_dyn_CallSiteImpl::compute_offsets() {
+ if (!EnableInvokeDynamic) return;
+ klassOop k = SystemDictionary::CallSiteImpl_klass();
+ if (k != NULL) {
@@ -1309,23 +1309,23 @@ diff --git a/src/share/vm/classfile/java
+ }
+}
+
-+oop impl_java_dyn_CallSiteImpl::type(oop site) {
++oop sun_dyn_CallSiteImpl::type(oop site) {
+ return site->obj_field(_type_offset);
+}
+
-+oop impl_java_dyn_CallSiteImpl::target(oop site) {
++oop sun_dyn_CallSiteImpl::target(oop site) {
+ return site->obj_field(_target_offset);
+}
+
-+void impl_java_dyn_CallSiteImpl::set_target(oop site, oop target) {
++void sun_dyn_CallSiteImpl::set_target(oop site, oop target) {
+ site->obj_field_put(_target_offset, target);
+}
+
-+oop impl_java_dyn_CallSiteImpl::vmmethod(oop site) {
++oop sun_dyn_CallSiteImpl::vmmethod(oop site) {
+ return site->obj_field(_vmmethod_offset);
+}
+
-+void impl_java_dyn_CallSiteImpl::set_vmmethod(oop site, oop ref) {
++void sun_dyn_CallSiteImpl::set_vmmethod(oop site, oop ref) {
+ site->obj_field_put(_vmmethod_offset, ref);
+}
@@ -1336,7 +1336,7 @@ diff --git a/src/share/vm/classfile/java
java_dyn_MethodTypeForm::compute_offsets();
}
+ if (EnableInvokeDynamic) {
-+ impl_java_dyn_CallSiteImpl::compute_offsets();
++ sun_dyn_CallSiteImpl::compute_offsets();
+ }
java_security_AccessControlContext::compute_offsets();
// Initialize reflection classes. The layouts of these classes
@@ -1348,9 +1348,9 @@ diff --git a/src/share/vm/classfile/java
};
-+// Interface to java.dyn.impl.CallSiteImpl objects
-+
-+class impl_java_dyn_CallSiteImpl: AllStatic {
++// Interface to sun.dyn.CallSiteImpl objects
++
++class sun_dyn_CallSiteImpl: AllStatic {
+ friend class JavaClasses;
+
+private:
@@ -1411,7 +1411,7 @@ diff --git a/src/share/vm/classfile/syst
+ methodHandle mh_invdyn,
+ TRAPS) {
+ Handle empty;
-+ // call java.dyn.impl.CallSiteImpl::makeSite(caller, name, mtype, cmid, cbci)
++ // call sun.dyn.CallSiteImpl::makeSite(caller, name, mtype, cmid, cbci)
+ oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle!
+ JavaCallArguments args(Handle(THREAD, caller->java_mirror()));
+ args.push_oop(name_str_oop);
@@ -1424,7 +1424,7 @@ diff --git a/src/share/vm/classfile/syst
+ vmSymbols::makeSite_name(), vmSymbols::makeSite_signature(),
+ &args, CHECK_(empty));
+ oop call_site_oop = (oop) result.get_jobject();
-+ impl_java_dyn_CallSiteImpl::set_vmmethod(call_site_oop, mh_invdyn());
++ sun_dyn_CallSiteImpl::set_vmmethod(call_site_oop, mh_invdyn());
+ if (TraceMethodHandles) {
+ tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
+ call_site_oop->print();
@@ -1484,7 +1484,7 @@ diff --git a/src/share/vm/classfile/syst
template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
+ template(Linkage_klass, java_dyn_Linkage, Opt) \
+ template(CallSite_klass, java_dyn_CallSite, Opt) \
-+ template(CallSiteImpl_klass, impl_java_dyn_CallSiteImpl, Opt) \
++ template(CallSiteImpl_klass, sun_dyn_CallSiteImpl, Opt) \
+ template(Dynamic_klass, java_dyn_Dynamic, Opt) \
+ /* Note: MethodHandle must be first, and Dynamic last in group */ \
+ \
@@ -1609,10 +1609,10 @@ diff --git a/src/share/vm/classfile/vmSy
template(java_dyn_MethodType, "java/dyn/MethodType") \
template(java_dyn_WrongMethodTypeException, "java/dyn/WrongMethodTypeException") \
@@ -228,8 +231,13 @@
- template(impl_java_dyn_AdapterMethodHandle, "impl/java/dyn/AdapterMethodHandle") \
- template(impl_java_dyn_BoundMethodHandle, "impl/java/dyn/BoundMethodHandle") \
- template(impl_java_dyn_DirectMethodHandle, "impl/java/dyn/DirectMethodHandle") \
-+ template(impl_java_dyn_CallSiteImpl, "impl/java/dyn/CallSiteImpl") \
+ template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") \
+ template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") \
+ template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") \
++ template(sun_dyn_CallSiteImpl, "sun/dyn/CallSiteImpl") \
template(makeImpl_name, "makeImpl") /*MethodType::makeImpl*/ \
template(makeImpl_signature, "(Ljava/lang/Class;[Ljava/lang/Class;ZZ)Ljava/dyn/MethodType;") \
+ template(makeSite_name, "makeSite") /*CallSiteImpl::makeImpl*/ \
@@ -2217,7 +2217,7 @@ diff --git a/src/share/vm/interpreter/in
+// Called on first time execution, and also whenever the CallSite.target is null.
+// FIXME: Do more of this in Java code.
+IRT_ENTRY(void, InterpreterRuntime::bootstrap_invokedynamic(JavaThread* thread, oopDesc* call_site)) {
-+ methodHandle mh_invdyn(thread, (methodOop) impl_java_dyn_CallSiteImpl::vmmethod(call_site));
++ methodHandle mh_invdyn(thread, (methodOop) sun_dyn_CallSiteImpl::vmmethod(call_site));
+ Handle mh_type(thread, mh_invdyn->method_handle_type());
+ objArrayHandle mh_ptypes(thread, java_dyn_MethodType::ptypes(mh_type()));
+
@@ -3128,7 +3128,7 @@ diff --git a/src/share/vm/oops/cpCacheOo
+void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, int extra_data) {
-+ methodOop method = (methodOop) impl_java_dyn_CallSiteImpl::vmmethod(call_site());
++ methodOop method = (methodOop) sun_dyn_CallSiteImpl::vmmethod(call_site());
+ assert(method->is_method(), "must be initialized properly");
+ int param_size = method->size_of_parameters();
+ assert(param_size > 1, "method argument size must include MH.this & initial dynamic receiver");
@@ -3503,7 +3503,7 @@ diff --git a/src/share/vm/prims/methodHa
+ oop site_oop = JNIHandles::resolve(site_jh);
+ if (site_oop == NULL || site_oop->klass() != SystemDictionary::CallSiteImpl_klass())
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "call site");
-+ impl_java_dyn_CallSiteImpl::set_target(site_oop, JNIHandles::resolve(target_jh));
++ sun_dyn_CallSiteImpl::set_target(site_oop, JNIHandles::resolve(target_jh));
+}
+JVM_END
+
--- a/meth-6655638.patch Tue Apr 07 01:55:20 2009 -0700
+++ b/meth-6655638.patch Wed Apr 08 02:52:08 2009 -0700
@@ -1,6 +1,6 @@ 6655638: dynamic languages need method h
6655638: dynamic languages need method handles
Summary: initial implementation, with known omissions (x86/64, sparc, compiler optim., c-oops, C++ interp.)
-Reviewed by: kvn, twisti, never
+Reviewed-by: kvn, twisti, never
diff --git a/src/cpu/sparc/vm/assembler_sparc.cpp b/src/cpu/sparc/vm/assembler_sparc.cpp
--- a/src/cpu/sparc/vm/assembler_sparc.cpp
@@ -773,7 +773,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp
-@@ -0,0 +1,1136 @@
+@@ -0,0 +1,1133 @@
+/*
+ * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -805,6 +805,9 @@ new file mode 100644
+
+address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
+ address interpreted_entry) {
++ // Just before the actual machine code entry point, allocate space
++ // for a MethodHandleEntry::Data record, so that we can manage everything
++ // from one base pointer.
+ __ align(wordSize);
+ address target = __ pc() + sizeof(Data);
+ while (__ pc() < target) {
@@ -874,7 +877,7 @@ new file mode 100644
+ // fetch the MethodType from the method handle into rax (the 'check' register)
+ {
+ Register tem = rbx_method;
-+ for (int* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
++ for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
+ __ movptr(rax_mtype, Address(tem, *pchase));
+ tem = rax_mtype; // in case there is another indirection
+ }
@@ -897,24 +900,12 @@ new file mode 100644
+// Helper to insert argument slots into the stack.
+// arg_slots must be a multiple of stack_move_unit() and <= 0
+void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
-+ RegisterOrConstant arg_slots,
-+ int arg_mask,
-+ Register rax_argslot,
-+ Register rbx_temp, Register rdx_temp) {
++ RegisterOrConstant arg_slots,
++ int arg_mask,
++ Register rax_argslot,
++ Register rbx_temp, Register rdx_temp) {
+ assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
+ (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
-+
-+ int constant_arg_slots = 0;
-+ if (arg_slots.is_constant()) {
-+ constant_arg_slots = arg_slots.as_constant() / stack_move_unit();
-+ } else {
-+ assert(arg_mask == _INSERT_NO_MASK,
-+ "cannot specify arg_mask with non-constant slot count");
-+#ifdef _LP64
-+ // clean high bits of stack motion register (was loaded as an int)
-+ __ movslq(arg_slots.as_register(), arg_slots.as_register());
-+#endif
-+ }
+
+#ifdef ASSERT
+ verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame");
@@ -932,6 +923,13 @@ new file mode 100644
+ assert(arg_slots.as_constant() % -stack_move_unit() == 0, "");
+ }
+#endif //ASSERT
++
++#ifdef _LP64
++ if (arg_slots.is_register()) {
++ // clean high bits of stack motion register (was loaded as an int)
++ __ movslq(arg_slots.as_register(), arg_slots.as_register());
++ }
++#endif
+
+ // Make space on the stack for the inserted argument(s).
+ // Then pull down everything shallower than rax_argslot.
@@ -957,7 +955,10 @@ new file mode 100644
+ // Now move the argslot down, to point to the opened-up space.
+ __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
+
-+ if (TaggedStackInterpreter) {
++ if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) {
++ // The caller has specified a bitmask of tags to put into the opened space.
++ // This only works when the arg_slots value is an assembly-time constant.
++ int constant_arg_slots = arg_slots.as_constant() / stack_move_unit();
+ int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();
+ for (int slot = 0; slot < constant_arg_slots; slot++) {
+ BasicType slot_type = ((arg_mask & (1 << slot)) == 0 ? T_OBJECT : T_INT);
@@ -1048,7 +1049,7 @@ new file mode 100644
+ intptr_t* entry_sp,
+ intptr_t* saved_sp) {
+ // called as a leaf from native code: do not block the JVM!
-+ printf("MH %s %p %p %d\n", adaptername, mh, entry_sp, entry_sp - saved_sp);
++ printf("MH %s "PTR_FORMAT" "PTR_FORMAT" "INTX_FORMAT"\n", adaptername, mh, entry_sp, entry_sp - saved_sp);
+}
+#endif //PRODUCT
+
@@ -1059,7 +1060,7 @@ new file mode 100644
+ // as set up by generate_method_handle_interpreter_entry():
+ // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
+ // - rcx: receiver method handle
-+ // - rax: method handle type (already checked at call site, then unused)
++ // - rax: method handle type (only used by the check_mtype entry point)
+ // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
+ // - rdx: garbage temp, can blow away
+
@@ -1074,14 +1075,14 @@ new file mode 100644
+ Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() );
+
+ Address rcx_mh_vmtarget( rcx_recv, java_dyn_MethodHandle::vmtarget_offset_in_bytes() );
-+ Address rcx_dmh_vmindex( rcx_recv, impl_java_dyn_DirectMethodHandle::vmindex_offset_in_bytes() );
-+
-+ Address rcx_bmh_vmargslot( rcx_recv, impl_java_dyn_BoundMethodHandle::vmargslot_offset_in_bytes() );
-+ Address rcx_bmh_argument( rcx_recv, impl_java_dyn_BoundMethodHandle::argument_offset_in_bytes() );
-+
-+ Address rcx_amh_vmargslot( rcx_recv, impl_java_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() );
-+ Address rcx_amh_argument( rcx_recv, impl_java_dyn_AdapterMethodHandle::argument_offset_in_bytes() );
-+ Address rcx_amh_conversion( rcx_recv, impl_java_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
++ Address rcx_dmh_vmindex( rcx_recv, sun_dyn_DirectMethodHandle::vmindex_offset_in_bytes() );
++
++ Address rcx_bmh_vmargslot( rcx_recv, sun_dyn_BoundMethodHandle::vmargslot_offset_in_bytes() );
++ Address rcx_bmh_argument( rcx_recv, sun_dyn_BoundMethodHandle::argument_offset_in_bytes() );
++
++ Address rcx_amh_vmargslot( rcx_recv, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() );
++ Address rcx_amh_argument( rcx_recv, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes() );
++ Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
+ Address vmarg; // __ argument_address(vmargslot)
+
+ int tag_offset = -1;
@@ -1097,10 +1098,6 @@ new file mode 100644
+
+ address interp_entry = __ pc();
+ if (UseCompressedOops) __ unimplemented("UseCompressedOops");
-+
-+ AdapterKind ak = _adapt_retype_only;
-+ if ((int)ek > (int)_adapter_mh_first)
-+ ak = AdapterKind((int)ek - (int)_adapter_mh_first);
+
+#ifndef PRODUCT
+ if (TraceMethodHandles) {
@@ -1185,7 +1182,7 @@ new file mode 100644
+
+ // get receiver klass
+ Register rax_klass = rax_argslot;
-+ __ movl(rax_klass, Address(rcx_recv, oopDesc::klass_offset_in_bytes()));
++ __ load_klass(rax_klass, rcx_recv);
+ __ verify_oop(rax_klass);
+
+ // get target methodOop & entry point
@@ -1218,7 +1215,7 @@ new file mode 100644
+
+ // get receiver klass
+ Register rax_klass = rax_argslot;
-+ __ movl(rax_klass, Address(rcx_recv, oopDesc::klass_offset_in_bytes()));
++ __ load_klass(rax_klass, rcx_recv);
+ __ verify_oop(rax_klass);
+
+ Register rcx_temp = rcx_recv;
@@ -1302,7 +1299,7 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapter_mh_first+_adapt_retype_only:
++ case _adapter_retype_only:
+ // immediately jump to the next MH layer:
+ __ movptr(rcx_recv, rcx_mh_vmtarget);
+ __ verify_oop(rcx_recv);
@@ -1311,7 +1308,7 @@ new file mode 100644
+ // It is also OK when a return type narrows.
+ break;
+
-+ case _adapter_mh_first+_adapt_check_cast:
++ case _adapter_check_cast:
+ {
+ // temps:
+ Register rbx_klass = rbx_temp; // interesting AMH data
@@ -1332,7 +1329,7 @@ new file mode 100644
+ __ movptr(rdx_temp, vmarg);
+ __ testl(rdx_temp, rdx_temp);
+ __ jcc(Assembler::zero, done); // no cast if null
-+ __ movl(rdx_temp, Address(rdx_temp, oopDesc::klass_offset_in_bytes()));
++ __ load_klass(rdx_temp, rdx_temp);
+
+ // live at this point:
+ // - rbx_klass: klass required by the target method
@@ -1352,8 +1349,8 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapter_mh_first+_adapt_prim_to_prim:
-+ case _adapter_mh_first+_adapt_ref_to_prim:
++ case _adapter_prim_to_prim:
++ case _adapter_ref_to_prim:
+ // handled completely by optimized cases
+ __ stop("init_AdapterMethodHandle should not issue this");
+ break;
@@ -1361,7 +1358,7 @@ new file mode 100644
+ case _adapter_opt_i2i: // optimized subcase of adapt_prim_to_prim
+//case _adapter_opt_f2i: // optimized subcase of adapt_prim_to_prim
+ case _adapter_opt_l2i: // optimized subcase of adapt_prim_to_prim
-+ case _adapter_opt_a2i: // optimized subcase of adapt_ref_to_prim
++ case _adapter_opt_unboxi: // optimized subcase of adapt_ref_to_prim
+ {
+ // perform an in-place conversion to int or an int subword
+ __ movl(rax_argslot, rcx_amh_vmargslot);
@@ -1381,7 +1378,7 @@ new file mode 100644
+ __ movl(rdx_temp, vmarg);
+ }
+ break;
-+ case _adapter_opt_a2i:
++ case _adapter_opt_unboxi:
+ {
+ // Load the value up from the heap.
+ __ movptr(rdx_temp, vmarg);
@@ -1409,7 +1406,7 @@ new file mode 100644
+ {
+ Register rbx_vminfo = rbx_temp;
+ __ movl(rbx_vminfo, rcx_amh_conversion);
-+ assert(_CONV_VMINFO_SHIFT == 0, "preshifted");
++ assert(CONV_VMINFO_SHIFT == 0, "preshifted");
+
+ // get the new MH:
+ __ movptr(rcx_recv, rcx_mh_vmtarget);
@@ -1420,7 +1417,7 @@ new file mode 100644
+ __ xchgl(rcx, rbx_vminfo); // free rcx for shifts
+ __ shll(rdx_temp /*, rcx*/);
+ Label zero_extend, done;
-+ __ testl(rcx, _CONV_VMINFO_SIGN_FLAG);
++ __ testl(rcx, CONV_VMINFO_SIGN_FLAG);
+ __ jcc(Assembler::zero, zero_extend);
+
+ // this path is taken for int->byte, int->short
@@ -1440,7 +1437,7 @@ new file mode 100644
+ break;
+
+ case _adapter_opt_i2l: // optimized subcase of adapt_prim_to_prim
-+ case _adapter_opt_a2l: // optimized subcase of adapt_ref_to_prim
++ case _adapter_opt_unboxl: // optimized subcase of adapt_ref_to_prim
+ {
+ // perform an in-place int-to-long or ref-to-long conversion
+ __ movl(rax_argslot, rcx_amh_vmargslot);
@@ -1460,7 +1457,7 @@ new file mode 100644
+ __ movl(vmarg2, rdx_temp); // store second word
+ }
+ break;
-+ case _adapter_opt_a2l:
++ case _adapter_opt_unboxl:
+ {
+ // Load the value up from the heap.
+ __ movptr(rdx_temp, vmarg1);
@@ -1535,12 +1532,12 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapter_mh_first+_adapt_prim_to_ref:
++ case _adapter_prim_to_ref:
+ __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
+ break;
+
-+ case _adapter_mh_first+_adapt_swap_args:
-+ case _adapter_mh_first+_adapt_rot_args:
++ case _adapter_swap_args:
++ case _adapter_rot_args:
+ // handled completely by optimized cases
+ __ stop("init_AdapterMethodHandle should not issue this");
+ break;
@@ -1573,8 +1570,8 @@ new file mode 100644
+ // 'vminfo' is the second
+ Register rbx_destslot = rbx_temp;
+ __ movl(rbx_destslot, rcx_amh_conversion);
-+ assert(_CONV_VMINFO_SHIFT == 0, "preshifted");
-+ __ andl(rbx_destslot, _CONV_VMINFO_MASK);
++ assert(CONV_VMINFO_SHIFT == 0, "preshifted");
++ __ andl(rbx_destslot, CONV_VMINFO_MASK);
+ __ lea(rbx_destslot, __ argument_address(rbx_destslot));
+ DEBUG_ONLY(verify_argslot(_masm, rbx_destslot, "swap point must fall within current frame"));
+
@@ -1657,7 +1654,7 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapter_mh_first+_adapt_dup_args:
++ case _adapter_dup_args:
+ {
+ // 'argslot' is the position of the first argument to duplicate
+ __ movl(rax_argslot, rcx_amh_vmargslot);
@@ -1666,7 +1663,7 @@ new file mode 100644
+ // 'stack_move' is negative number of words to duplicate
+ Register rdx_stack_move = rdx_temp;
+ __ movl(rdx_stack_move, rcx_amh_conversion);
-+ __ sarl(rdx_stack_move, _CONV_STACK_MOVE_SHIFT);
++ __ sarl(rdx_stack_move, CONV_STACK_MOVE_SHIFT);
+
+ int argslot0_num = 0;
+ Address argslot0 = __ argument_address(RegisterOrConstant(argslot0_num));
@@ -1717,7 +1714,7 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapter_mh_first+_adapt_drop_args:
++ case _adapter_drop_args:
+ {
+ // 'argslot' is the position of the first argument to nuke
+ __ movl(rax_argslot, rcx_amh_vmargslot);
@@ -1729,7 +1726,7 @@ new file mode 100644
+ // 'stack_move' is number of words to drop
+ Register rdi_stack_move = rdi;
+ __ movl(rdi_stack_move, rcx_amh_conversion);
-+ __ sarl(rdi_stack_move, _CONV_STACK_MOVE_SHIFT);
++ __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
+ remove_arg_slots(_masm, rdi_stack_move,
+ rax_argslot, rbx_temp, rdx_temp);
+
@@ -1740,24 +1737,24 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapter_mh_first+_adapt_collect_args:
++ case _adapter_collect_args:
+ __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
+ break;
+
-+ case _adapter_mh_first+_adapt_spread_args:
++ case _adapter_spread_args:
+ // handled completely by optimized cases
+ __ stop("init_AdapterMethodHandle should not issue this");
+ break;
+
-+ case _adapt_opt_spread_0:
-+ case _adapt_opt_spread_1:
-+ case _adapt_opt_spread_more:
++ case _adapter_opt_spread_0:
++ case _adapter_opt_spread_1:
++ case _adapter_opt_spread_more:
+ {
+ // spread an array out into a group of arguments
+ int length_constant = -1;
+ switch (ek) {
-+ case _adapt_opt_spread_0: length_constant = 0; break;
-+ case _adapt_opt_spread_1: length_constant = 1; break;
++ case _adapter_opt_spread_0: length_constant = 0; break;
++ case _adapter_opt_spread_1: length_constant = 1; break;
+ }
+
+ // find the address of the array argument
@@ -1786,7 +1783,7 @@ new file mode 100644
+ __ jcc(Assembler::zero, skip_array_check);
+ }
+ __ null_check(rsi_array, oopDesc::klass_offset_in_bytes());
-+ __ movl(rdx_array_klass, Address(rsi_array, oopDesc::klass_offset_in_bytes()));
++ __ load_klass(rdx_array_klass, rsi_array);
+
+ // Check the array type.
+ Register rbx_klass = rbx_temp;
@@ -1805,8 +1802,8 @@ new file mode 100644
+ } else {
+ Register rbx_vminfo = rbx_temp;
+ __ movl(rbx_vminfo, rcx_amh_conversion);
-+ assert(_CONV_VMINFO_SHIFT == 0, "preshifted");
-+ __ andl(rbx_vminfo, _CONV_VMINFO_MASK);
++ assert(CONV_VMINFO_SHIFT == 0, "preshifted");
++ __ andl(rbx_vminfo, CONV_VMINFO_MASK);
+ __ cmpl(rbx_vminfo, Address(rsi_array, length_offset));
+ }
+ __ jcc(Assembler::notEqual, bad_array_length);
@@ -1820,7 +1817,7 @@ new file mode 100644
+ // 'stack_move' is negative number of words to insert
+ Register rdi_stack_move = rdi;
+ __ movl(rdi_stack_move, rcx_amh_conversion);
-+ __ sarl(rdi_stack_move, _CONV_STACK_MOVE_SHIFT);
++ __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
+ Register rsi_temp = rsi_array; // spill this
+ insert_arg_slots(_masm, rdi_stack_move, -1,
+ rax_argslot, rbx_temp, rsi_temp);
@@ -1896,8 +1893,8 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapter_mh_first+_adapt_flyby:
-+ case _adapter_mh_first+_adapt_ricochet:
++ case _adapter_flyby:
++ case _adapter_ricochet:
+ __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
+ break;
+
@@ -2213,7 +2210,7 @@ diff --git a/src/share/vm/classfile/clas
}
+ // adjust the vmentry field declaration in java.dyn.MethodHandle
-+ if (EnableMethodHandles && class_name() == vmSymbols::impl_java_dyn_MethodHandleImpl() && class_loader.is_null()) {
++ if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
+ java_dyn_MethodHandle_fix_pre(cp, &fields, &fac, CHECK_(nullHandle));
+ }
+
@@ -2542,19 +2539,19 @@ diff --git a/src/share/vm/classfile/java
+int java_dyn_MethodHandle::_vmentry_offset;
+int java_dyn_MethodHandle::_vmslots_offset;
+
-+int impl_java_dyn_MemberName::_clazz_offset;
-+int impl_java_dyn_MemberName::_name_offset;
-+int impl_java_dyn_MemberName::_type_offset;
-+int impl_java_dyn_MemberName::_flags_offset;
-+int impl_java_dyn_MemberName::_vmtarget_offset;
-+int impl_java_dyn_MemberName::_vmindex_offset;
-+
-+int impl_java_dyn_DirectMethodHandle::_vmindex_offset;
-+
-+int impl_java_dyn_BoundMethodHandle::_argument_offset;
-+int impl_java_dyn_BoundMethodHandle::_vmargslot_offset;
-+
-+int impl_java_dyn_AdapterMethodHandle::_conversion_offset;
++int sun_dyn_MemberName::_clazz_offset;
++int sun_dyn_MemberName::_name_offset;
++int sun_dyn_MemberName::_type_offset;
++int sun_dyn_MemberName::_flags_offset;
++int sun_dyn_MemberName::_vmtarget_offset;
++int sun_dyn_MemberName::_vmindex_offset;
++
++int sun_dyn_DirectMethodHandle::_vmindex_offset;
++
++int sun_dyn_BoundMethodHandle::_argument_offset;
++int sun_dyn_BoundMethodHandle::_vmargslot_offset;
++
++int sun_dyn_AdapterMethodHandle::_conversion_offset;
+
+void java_dyn_MethodHandle::compute_offsets() {
+ klassOop k = SystemDictionary::MethodHandle_klass();
@@ -2569,7 +2566,7 @@ diff --git a/src/share/vm/classfile/java
+ }
+}
+
-+void impl_java_dyn_MemberName::compute_offsets() {
++void sun_dyn_MemberName::compute_offsets() {
+ klassOop k = SystemDictionary::MemberName_klass();
+ if (k != NULL && EnableMethodHandles) {
+ compute_offset(_clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature());
@@ -2581,14 +2578,14 @@ diff --git a/src/share/vm/classfile/java
+ }
+}
+
-+void impl_java_dyn_DirectMethodHandle::compute_offsets() {
++void sun_dyn_DirectMethodHandle::compute_offsets() {
+ klassOop k = SystemDictionary::DirectMethodHandle_klass();
+ if (k != NULL && EnableMethodHandles) {
+ compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature(), true);
+ }
+}
+
-+void impl_java_dyn_BoundMethodHandle::compute_offsets() {
++void sun_dyn_BoundMethodHandle::compute_offsets() {
+ klassOop k = SystemDictionary::BoundMethodHandle_klass();
+ if (k != NULL && EnableMethodHandles) {
+ compute_offset(_vmargslot_offset, k, vmSymbols::vmargslot_name(), vmSymbols::int_signature(), true);
@@ -2596,7 +2593,7 @@ diff --git a/src/share/vm/classfile/java
+ }
+}
+
-+void impl_java_dyn_AdapterMethodHandle::compute_offsets() {
++void sun_dyn_AdapterMethodHandle::compute_offsets() {
+ klassOop k = SystemDictionary::AdapterMethodHandle_klass();
+ if (k != NULL && EnableMethodHandles) {
+ compute_offset(_conversion_offset, k, vmSymbols::conversion_name(), vmSymbols::int_signature(), true);
@@ -2625,7 +2622,7 @@ diff --git a/src/share/vm/classfile/java
+ }
+}
+
-+// if MH.vmslots exists, hoist into it the value of type.form.vmslots
++// if MH.vmslots exists, hoist into it the value of type.form.vmslots
+void java_dyn_MethodHandle::init_vmslots(oop mh) {
+ int vmslots_offset = _vmslots_offset;
+ if (vmslots_offset != 0) {
@@ -2662,62 +2659,62 @@ diff --git a/src/share/vm/classfile/java
+
+/// MemberName accessors
+
-+oop impl_java_dyn_MemberName::clazz(oop mname) {
++oop sun_dyn_MemberName::clazz(oop mname) {
+ assert(is_instance(mname), "wrong type");
+ return mname->obj_field(_clazz_offset);
+}
+
-+void impl_java_dyn_MemberName::set_clazz(oop mname, oop clazz) {
++void sun_dyn_MemberName::set_clazz(oop mname, oop clazz) {
+ assert(is_instance(mname), "wrong type");
+ mname->obj_field_put(_clazz_offset, clazz);
+}
+
-+oop impl_java_dyn_MemberName::name(oop mname) {
++oop sun_dyn_MemberName::name(oop mname) {
+ assert(is_instance(mname), "wrong type");
+ return mname->obj_field(_name_offset);
+}
+
-+void impl_java_dyn_MemberName::set_name(oop mname, oop name) {
++void sun_dyn_MemberName::set_name(oop mname, oop name) {
+ assert(is_instance(mname), "wrong type");
+ mname->obj_field_put(_name_offset, name);
+}
+
-+oop impl_java_dyn_MemberName::type(oop mname) {
++oop sun_dyn_MemberName::type(oop mname) {
+ assert(is_instance(mname), "wrong type");
+ return mname->obj_field(_type_offset);
+}
+
-+void impl_java_dyn_MemberName::set_type(oop mname, oop type) {
++void sun_dyn_MemberName::set_type(oop mname, oop type) {
+ assert(is_instance(mname), "wrong type");
+ mname->obj_field_put(_type_offset, type);
+}
+
-+int impl_java_dyn_MemberName::flags(oop mname) {
++int sun_dyn_MemberName::flags(oop mname) {
+ assert(is_instance(mname), "wrong type");
+ return mname->int_field(_flags_offset);
+}
+
-+void impl_java_dyn_MemberName::set_flags(oop mname, int flags) {
++void sun_dyn_MemberName::set_flags(oop mname, int flags) {
+ assert(is_instance(mname), "wrong type");
+ mname->int_field_put(_flags_offset, flags);
+}
+
-+oop impl_java_dyn_MemberName::vmtarget(oop mname) {
++oop sun_dyn_MemberName::vmtarget(oop mname) {
+ assert(is_instance(mname), "wrong type");
+ return mname->obj_field(_vmtarget_offset);
+}
+
-+void impl_java_dyn_MemberName::set_vmtarget(oop mname, oop ref) {
++void sun_dyn_MemberName::set_vmtarget(oop mname, oop ref) {
+ assert(is_instance(mname), "wrong type");
+ mname->obj_field_put(_vmtarget_offset, ref);
+}
+
-+int impl_java_dyn_MemberName::vmindex(oop mname) {
++int sun_dyn_MemberName::vmindex(oop mname) {
+ assert(is_instance(mname), "wrong type");
+ return mname->int_field(_vmindex_offset);
+}
+
-+void impl_java_dyn_MemberName::set_vmindex(oop mname, int index) {
++void sun_dyn_MemberName::set_vmindex(oop mname, int index) {
+ assert(is_instance(mname), "wrong type");
+ mname->int_field_put(_vmindex_offset, index);
+}
@@ -2732,32 +2729,32 @@ diff --git a/src/share/vm/classfile/java
+ mh->obj_field_put(_vmtarget_offset, ref);
+}
+
-+int impl_java_dyn_DirectMethodHandle::vmindex(oop mh) {
++int sun_dyn_DirectMethodHandle::vmindex(oop mh) {
+ assert(is_instance(mh), "DMH only");
+ return mh->int_field(_vmindex_offset);
+}
+
-+void impl_java_dyn_DirectMethodHandle::set_vmindex(oop mh, int index) {
++void sun_dyn_DirectMethodHandle::set_vmindex(oop mh, int index) {
+ assert(is_instance(mh), "DMH only");
+ mh->int_field_put(_vmindex_offset, index);
+}
+
-+int impl_java_dyn_BoundMethodHandle::vmargslot(oop mh) {
++int sun_dyn_BoundMethodHandle::vmargslot(oop mh) {
+ assert(is_instance(mh), "BMH only");
+ return mh->int_field(_vmargslot_offset);
+}
+
-+oop impl_java_dyn_BoundMethodHandle::argument(oop mh) {
++oop sun_dyn_BoundMethodHandle::argument(oop mh) {
+ assert(is_instance(mh), "BMH only");
+ return mh->obj_field(_argument_offset);
+}
+
-+int impl_java_dyn_AdapterMethodHandle::conversion(oop mh) {
++int sun_dyn_AdapterMethodHandle::conversion(oop mh) {
+ assert(is_instance(mh), "AMH only");
+ return mh->int_field(_conversion_offset);
+}
+
-+void impl_java_dyn_AdapterMethodHandle::set_conversion(oop mh, int conv) {
++void sun_dyn_AdapterMethodHandle::set_conversion(oop mh, int conv) {
+ assert(is_instance(mh), "AMH only");
+ mh->int_field_put(_conversion_offset, conv);
+}
@@ -2863,10 +2860,10 @@ diff --git a/src/share/vm/classfile/java
java_lang_ThreadGroup::compute_offsets();
+ if (EnableMethodHandles) {
+ java_dyn_MethodHandle::compute_offsets();
-+ impl_java_dyn_MemberName::compute_offsets();
-+ impl_java_dyn_DirectMethodHandle::compute_offsets();
-+ impl_java_dyn_BoundMethodHandle::compute_offsets();
-+ impl_java_dyn_AdapterMethodHandle::compute_offsets();
++ sun_dyn_MemberName::compute_offsets();
++ sun_dyn_DirectMethodHandle::compute_offsets();
++ sun_dyn_BoundMethodHandle::compute_offsets();
++ sun_dyn_AdapterMethodHandle::compute_offsets();
+ java_dyn_MethodType::compute_offsets();
+ java_dyn_MethodTypeForm::compute_offsets();
+ }
@@ -2886,7 +2883,20 @@ diff --git a/src/share/vm/classfile/java
diff --git a/src/share/vm/classfile/javaClasses.hpp b/src/share/vm/classfile/javaClasses.hpp
--- a/src/share/vm/classfile/javaClasses.hpp
+++ b/src/share/vm/classfile/javaClasses.hpp
-@@ -778,6 +778,283 @@
+@@ -151,6 +151,12 @@
+ // Conversion
+ static klassOop as_klassOop(oop java_class);
+ static BasicType as_BasicType(oop java_class, klassOop* reference_klass = NULL);
++ static BasicType as_BasicType(oop java_class, KlassHandle* reference_klass) {
++ klassOop refk_oop = NULL;
++ BasicType result = as_BasicType(java_class, &refk_oop);
++ (*reference_klass) = KlassHandle(refk_oop);
++ return result;
++ }
+ static symbolOop as_signature(oop java_class, bool intern_if_not_found, TRAPS);
+ static void print_signature(oop java_class, outputStream *st);
+ // Testing
+@@ -778,6 +784,284 @@
};
@@ -2935,7 +2945,7 @@ diff --git a/src/share/vm/classfile/java
+ static int vmslots_offset_in_bytes() { return _vmslots_offset; }
+};
+
-+class impl_java_dyn_DirectMethodHandle: public java_dyn_MethodHandle {
++class sun_dyn_DirectMethodHandle: public java_dyn_MethodHandle {
+ friend class JavaClasses;
+
+ private:
@@ -2960,7 +2970,7 @@ diff --git a/src/share/vm/classfile/java
+ static int vmindex_offset_in_bytes() { return _vmindex_offset; }
+};
+
-+class impl_java_dyn_BoundMethodHandle: public java_dyn_MethodHandle {
++class sun_dyn_BoundMethodHandle: public java_dyn_MethodHandle {
+ friend class JavaClasses;
+
+ private:
@@ -2987,7 +2997,7 @@ diff --git a/src/share/vm/classfile/java
+ static int vmargslot_offset_in_bytes() { return _vmargslot_offset; }
+};
+
-+class impl_java_dyn_AdapterMethodHandle: public impl_java_dyn_BoundMethodHandle {
++class sun_dyn_AdapterMethodHandle: public sun_dyn_BoundMethodHandle {
+ friend class JavaClasses;
+
+ private:
@@ -3008,25 +3018,26 @@ diff --git a/src/share/vm/classfile/java
+
+ // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
+ enum {
-+ RETYPE_ONLY = 0x000, // no argument changes; straight retype
-+ CHECK_CAST = 0x100, // ref-to-ref conversion; requires a Class argument
-+ PRIM_TO_PRIM = 0x200, // converts from one primitive to another
-+ REF_TO_PRIM = 0x300, // unboxes a wrapper to produce a primitive
-+ PRIM_TO_REF = 0x400, // boxes a primitive into a wrapper (NYI)
-+ SWAP_ARGS = 0x500, // swap arguments (vminfo is 2nd arg)
-+ ROT_ARGS = 0x600, // rotate arguments (vminfo is displaced arg)
-+ DUP_ARGS = 0x700, // duplicates one or more arguments (at TOS)
-+ DROP_ARGS = 0x800, // remove one or more argument slots
-+ COLLECT_ARGS = 0x900, // combine one or more arguments into a varargs (NYI)
-+ SPREAD_ARGS = 0xA00, // expand in place a varargs array (of known size)
-+ FLYBY = 0xB00, // operate first on reified argument list (NYI)
-+ RICOCHET = 0xC00, // run an adapter chain on the return value (NYI)
-+
-+ CONV_OP_MASK = 0xF00, // byte 3 contains the conversion op field
++ OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
++ OP_CHECK_CAST = 0x1, // ref-to-ref conversion; requires a Class argument
++ OP_PRIM_TO_PRIM = 0x2, // converts from one primitive to another
++ OP_REF_TO_PRIM = 0x3, // unboxes a wrapper to produce a primitive
++ OP_PRIM_TO_REF = 0x4, // boxes a primitive into a wrapper (NYI)
++ OP_SWAP_ARGS = 0x5, // swap arguments (vminfo is 2nd arg)
++ OP_ROT_ARGS = 0x6, // rotate arguments (vminfo is displaced arg)
++ OP_DUP_ARGS = 0x7, // duplicates one or more arguments (at TOS)
++ OP_DROP_ARGS = 0x8, // remove one or more argument slots
++ OP_COLLECT_ARGS = 0x9, // combine one or more arguments into a varargs (NYI)
++ OP_SPREAD_ARGS = 0xA, // expand in place a varargs array (of known size)
++ OP_FLYBY = 0xB, // operate first on reified argument list (NYI)
++ OP_RICOCHET = 0xC, // run an adapter chain on the return value (NYI)
++ CONV_OP_LIMIT = 0xD, // limit of CONV_OP enumeration
++
++ CONV_OP_MASK = 0xF00, // this nybble contains the conversion op field
+ CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
+ CONV_VMINFO_SHIFT = 0, // position of bits in CONV_VMINFO_MASK
+ CONV_OP_SHIFT = 8, // position of bits in CONV_OP_MASK
-+ CONV_DEST_TYPE_SHIFT = 12, // byte 3 has the adapter BasicType (if needed)
++ CONV_DEST_TYPE_SHIFT = 12, // byte 2 has the adapter BasicType (if needed)
+ CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed)
+ CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change
+ CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1
@@ -3036,10 +3047,10 @@ diff --git a/src/share/vm/classfile/java
+};
+
+
-+// Interface to impl.java.dyn.MemberName objects
++// Interface to sun.dyn.MemberName objects
+// (These are a private interface for Java code to query the class hierarchy.)
+
-+class impl_java_dyn_MemberName: AllStatic {
++class sun_dyn_MemberName: AllStatic {
+ friend class JavaClasses;
+
+ private:
@@ -3366,11 +3377,11 @@ diff --git a/src/share/vm/classfile/syst
\
+ /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
+ template(MethodHandle_klass, java_dyn_MethodHandle, Opt) \
-+ template(MemberName_klass, impl_java_dyn_MemberName, Opt) \
-+ template(MethodHandleImpl_klass, impl_java_dyn_MethodHandleImpl, Opt) \
-+ template(AdapterMethodHandle_klass, impl_java_dyn_AdapterMethodHandle, Opt) \
-+ template(BoundMethodHandle_klass, impl_java_dyn_BoundMethodHandle, Opt) \
-+ template(DirectMethodHandle_klass, impl_java_dyn_DirectMethodHandle, Opt) \
++ template(MemberName_klass, sun_dyn_MemberName, Opt) \
++ template(MethodHandleImpl_klass, sun_dyn_MethodHandleImpl, Opt) \
++ template(AdapterMethodHandle_klass, sun_dyn_AdapterMethodHandle, Opt) \
++ template(BoundMethodHandle_klass, sun_dyn_BoundMethodHandle, Opt) \
++ template(DirectMethodHandle_klass, sun_dyn_DirectMethodHandle, Opt) \
+ template(MethodType_klass, java_dyn_MethodType, Opt) \
+ template(MethodTypeForm_klass, java_dyn_MethodTypeForm, Opt) \
+ template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
@@ -3438,11 +3449,11 @@ diff --git a/src/share/vm/classfile/vmSy
+ /* internal classes known only to the JVM: */ \
+ template(java_dyn_MethodTypeForm, "java/dyn/MethodTypeForm") \
+ template(java_dyn_MethodTypeForm_signature, "Ljava/dyn/MethodTypeForm;") \
-+ template(impl_java_dyn_MemberName, "impl/java/dyn/MemberName") \
-+ template(impl_java_dyn_MethodHandleImpl, "impl/java/dyn/MethodHandleImpl") \
-+ template(impl_java_dyn_AdapterMethodHandle, "impl/java/dyn/AdapterMethodHandle") \
-+ template(impl_java_dyn_BoundMethodHandle, "impl/java/dyn/BoundMethodHandle") \
-+ template(impl_java_dyn_DirectMethodHandle, "impl/java/dyn/DirectMethodHandle") \
++ template(sun_dyn_MemberName, "sun/dyn/MemberName") \
++ template(sun_dyn_MethodHandleImpl, "sun/dyn/MethodHandleImpl") \
++ template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") \
++ template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") \
++ template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") \
+ template(makeImpl_name, "makeImpl") /*MethodType::makeImpl*/ \
+ template(makeImpl_signature, "(Ljava/lang/Class;[Ljava/lang/Class;ZZ)Ljava/dyn/MethodType;") \
+ NOT_LP64( do_alias(machine_word_signature, int_signature) ) \
@@ -3517,13 +3528,14 @@ diff --git a/src/share/vm/includeDB_core
linkResolver.cpp nativeLookup.hpp
linkResolver.cpp objArrayOop.hpp
linkResolver.cpp reflection.hpp
-@@ -2810,6 +2814,24 @@
+@@ -2810,6 +2814,25 @@
methodDataOop.hpp orderAccess.hpp
methodDataOop.hpp universe.hpp
+methodHandles.hpp frame.inline.hpp
+methodHandles.hpp globals.hpp
+methodHandles.hpp interfaceSupport.hpp
++methodHandles.hpp javaClasses.hpp
+methodHandles.hpp vmSymbols.hpp
+
+methodHandles.cpp allocation.inline.hpp
@@ -3542,7 +3554,7 @@ diff --git a/src/share/vm/includeDB_core
methodKlass.cpp collectedHeap.inline.hpp
methodKlass.cpp constMethodKlass.hpp
methodKlass.cpp gcLocker.hpp
-@@ -3059,6 +3081,7 @@
+@@ -3059,6 +3082,7 @@
oop.inline.hpp arrayOop.hpp
oop.inline.hpp atomic.hpp
oop.inline.hpp barrierSet.inline.hpp
@@ -3550,7 +3562,7 @@ diff --git a/src/share/vm/includeDB_core
oop.inline.hpp cardTableModRefBS.hpp
oop.inline.hpp collectedHeap.inline.hpp
oop.inline.hpp compactingPermGenGen.hpp
-@@ -3670,6 +3693,7 @@
+@@ -3670,6 +3694,7 @@
sharedRuntime.cpp interpreter.hpp
sharedRuntime.cpp javaCalls.hpp
sharedRuntime.cpp jvmtiExport.hpp
@@ -3558,7 +3570,7 @@ diff --git a/src/share/vm/includeDB_core
sharedRuntime.cpp nativeInst_<arch>.hpp
sharedRuntime.cpp nativeLookup.hpp
sharedRuntime.cpp oop.inline.hpp
-@@ -3856,6 +3880,7 @@
+@@ -3856,6 +3881,7 @@
stubGenerator_<arch_model>.cpp handles.inline.hpp
stubGenerator_<arch_model>.cpp instanceOop.hpp
stubGenerator_<arch_model>.cpp interpreter.hpp
@@ -4018,7 +4030,7 @@ diff --git a/src/share/vm/oops/methodOop
+#ifdef ASSERT
+ // Make sure the pointer chase works.
+ address p = (address) m();
-+ for (int* pchase = method_type_offsets_chain(); (*pchase) != -1; pchase++) {
++ for (jint* pchase = method_type_offsets_chain(); (*pchase) != -1; pchase++) {
+ p = *(address*)(p + (*pchase));
+ }
+ assert((oop)p == method_type(), "pointer chase is correct");
@@ -4057,7 +4069,7 @@ diff --git a/src/share/vm/oops/methodOop
+ TRAPS);
+ // these operate only on invoke methods:
+ oop method_handle_type() const;
-+ static jint* method_type_offsets_chain();
++ static jint* method_type_offsets_chain(); // series of pointer-offsets, terminated by -1
+ // presize interpreter frames for extra interpreter stack entries, if needed
+ static int extra_stack_entries() { return EnableMethodHandles ? (int)MethodHandlePushLimit : 0; }
+ static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize()
@@ -4094,7 +4106,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/vm/prims/methodHandles.cpp
-@@ -0,0 +1,2299 @@
+@@ -0,0 +1,2347 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -4144,19 +4156,19 @@ new file mode 100644
+ "bound_long_direct",
+
+ // starting at _adapter_mh_first:
-+ "adapt_retype_only", // these are for AMH...
-+ "adapt_check_cast",
-+ "adapt_prim_to_prim",
-+ "adapt_ref_to_prim",
-+ "adapt_prim_to_ref",
-+ "adapt_swap_args",
-+ "adapt_rot_args",
-+ "adapt_dup_args",
-+ "adapt_drop_args",
-+ "adapt_collect_args",
-+ "adapt_spread_args",
-+ "adapt_flyby",
-+ "adapt_ricochet",
++ "adapter_retype_only", // these are for AMH...
++ "adapter_check_cast",
++ "adapter_prim_to_prim",
++ "adapter_ref_to_prim",
++ "adapter_prim_to_ref",
++ "adapter_swap_args",
++ "adapter_rot_args",
++ "adapter_dup_args",
++ "adapter_drop_args",
++ "adapter_collect_args",
++ "adapter_spread_args",
++ "adapter_flyby",
++ "adapter_ricochet",
+
+ // optimized adapter types:
+ "adapter_swap_args/1",
@@ -4165,16 +4177,16 @@ new file mode 100644
+ "adapter_rot_args/1,down",
+ "adapter_rot_args/2,up",
+ "adapter_rot_args/2,down",
-+ "adapt_prim_to_prim/i2i",
-+ "adapt_prim_to_prim/l2i",
-+ "adapt_prim_to_prim/d2f",
-+ "adapt_prim_to_prim/i2l",
-+ "adapt_prim_to_prim/f2d",
-+ "adapt_prim_to_prim/a2i",
-+ "adapt_prim_to_prim/a2l",
-+ "adapt_spread_args/0",
-+ "adapt_spread_args/1",
-+ "adapt_spread_args/more",
++ "adapter_prim_to_prim/i2i",
++ "adapter_prim_to_prim/l2i",
++ "adapter_prim_to_prim/d2f",
++ "adapter_prim_to_prim/i2l",
++ "adapter_prim_to_prim/f2d",
++ "adapter_ref_to_prim/unboxi",
++ "adapter_ref_to_prim/unboxl",
++ "adapter_spread_args/0",
++ "adapter_spread_args/1",
++ "adapter_spread_args/more",
+
+ NULL
+};
@@ -4183,8 +4195,9 @@ new file mode 100644
+bool MethodHandles::spot_check_entry_names() {
+ assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), "");
+ assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), "");
-+ assert(!strcmp(adapter_entry_name(_adapt_retype_only), "adapt_retype_only"), "");
-+ assert(!strcmp(adapter_entry_name(_adapt_ricochet), "adapt_ricochet"), "");
++ assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), "");
++ assert(!strcmp(entry_name(_adapter_ricochet), "adapter_ricochet"), "");
++ assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), "");
+ return true;
+}
+#endif
@@ -4195,6 +4208,11 @@ new file mode 100644
+ _enabled = z;
+ }
+}
++
++// Note: A method which does not have a TRAPS argument cannot block in the GC
++// or throw exceptions. Such methods are used in this file to do something quick
++// and local, like parse a data structure. For speed, such methods work on plain
++// oops, not handles. Trapping methods uniformly operate on handles.
+
+methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
+ klassOop& receiver_limit_result, int& decode_flags_result) {
@@ -4241,9 +4259,9 @@ new file mode 100644
+// (MemberName is the non-operational name used for queries and setup.)
+
+methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
-+ oop vmtarget = impl_java_dyn_DirectMethodHandle::vmtarget(mh);
-+ int vmindex = impl_java_dyn_DirectMethodHandle::vmindex(mh);
-+ oop mtype = impl_java_dyn_DirectMethodHandle::type(mh);
++ oop vmtarget = sun_dyn_DirectMethodHandle::vmtarget(mh);
++ int vmindex = sun_dyn_DirectMethodHandle::vmindex(mh);
++ oop mtype = sun_dyn_DirectMethodHandle::type(mh);
+ return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result);
+}
+
@@ -4267,7 +4285,7 @@ new file mode 100644
+ // short-circuits directly to the methodOop.
+ assert(target->is_method(), "must be a simple method");
+ methodOop m = (methodOop) target;
-+ DEBUG_ONLY(int argslot = impl_java_dyn_BoundMethodHandle::vmargslot(bmh));
++ DEBUG_ONLY(int argslot = sun_dyn_BoundMethodHandle::vmargslot(bmh));
+ assert(argslot == m->size_of_parameters() - 1, "must be initial argument (receiver)");
+ decode_flags_result |= MethodHandles::_dmf_binds_method;
+ return m;
@@ -4280,8 +4298,8 @@ new file mode 100644
+ assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
+ for (oop amh = mh;;) {
+ // Adapter MHs can be stacked to convert several arguments.
-+ AdapterKind ak = adapter_conversion_op(impl_java_dyn_AdapterMethodHandle::conversion(amh));
-+ decode_flags_result |= (_dmf_adapter_lsb << ak);
++ int conv_op = adapter_conversion_op(sun_dyn_AdapterMethodHandle::conversion(amh));
++ decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK;
+ oop target = java_dyn_MethodHandle::vmtarget(amh);
+ if (target == NULL) return NULL;
+ klassOop tk = target->klass();
@@ -4364,7 +4382,7 @@ new file mode 100644
+ } else {
+ // unrecognized object
+ assert(!x->is_method(), "already checked");
-+ assert(!impl_java_dyn_MemberName::is_instance(x), "already checked");
++ assert(!sun_dyn_MemberName::is_instance(x), "already checked");
+ }
+ return NULL;
+}
@@ -4396,38 +4414,18 @@ new file mode 100644
+}
+
+
-+static void throw_IllegalArgumentException(TRAPS) {
-+ THROW(vmSymbols::java_lang_IllegalArgumentException());
-+ ShouldNotReachHere();
-+}
-+
-+static void throw_IllegalArgumentException(const char* message, TRAPS) {
-+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message);
-+ ShouldNotReachHere();
-+}
-+
-+static void throw_InternalError(const char* message, TRAPS) {
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), message);
-+ ShouldNotReachHere();
-+}
-+
-+static void throw_InternalError(TRAPS) {
-+ THROW(vmSymbols::java_lang_InternalError());
-+ ShouldNotReachHere();
-+}
-+
+// MemberName support
+
-+// import impl_java_dyn_MemberName.*
++// import sun_dyn_MemberName.*
+enum {
-+ IS_METHOD = impl_java_dyn_MemberName::MN_IS_METHOD,
-+ IS_CONSTRUCTOR = impl_java_dyn_MemberName::MN_IS_CONSTRUCTOR,
-+ IS_FIELD = impl_java_dyn_MemberName::MN_IS_FIELD,
-+ IS_TYPE = impl_java_dyn_MemberName::MN_IS_TYPE,
-+ SEARCH_SUPERCLASSES = impl_java_dyn_MemberName::MN_SEARCH_SUPERCLASSES,
-+ SEARCH_INTERFACES = impl_java_dyn_MemberName::MN_SEARCH_INTERFACES,
++ IS_METHOD = sun_dyn_MemberName::MN_IS_METHOD,
++ IS_CONSTRUCTOR = sun_dyn_MemberName::MN_IS_CONSTRUCTOR,
++ IS_FIELD = sun_dyn_MemberName::MN_IS_FIELD,
++ IS_TYPE = sun_dyn_MemberName::MN_IS_TYPE,
++ SEARCH_SUPERCLASSES = sun_dyn_MemberName::MN_SEARCH_SUPERCLASSES,
++ SEARCH_INTERFACES = sun_dyn_MemberName::MN_SEARCH_INTERFACES,
+ ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
-+ VM_INDEX_UNINITIALIZED = impl_java_dyn_MemberName::VM_INDEX_UNINITIALIZED
++ VM_INDEX_UNINITIALIZED = sun_dyn_MemberName::VM_INDEX_UNINITIALIZED
+};
+
+void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
@@ -4449,33 +4447,33 @@ new file mode 100644
+
+void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) {
+ int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD)
-+ | (jushort) m->access_flags().as_short());
++ | (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ));
+ oop vmtarget = m;
+ int vmindex = methodOopDesc::invalid_vtable_index; // implies no info yet
+ if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound())
+ vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
+ assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
-+ impl_java_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
-+ impl_java_dyn_MemberName::set_vmindex(mname_oop, vmindex);
-+ impl_java_dyn_MemberName::set_flags(mname_oop, flags);
++ sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
++ sun_dyn_MemberName::set_vmindex(mname_oop, vmindex);
++ sun_dyn_MemberName::set_flags(mname_oop, flags);
+}
+
+void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) {
-+ int flags = (IS_FIELD | (jushort) mods.as_short());
++ int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ));
+ oop vmtarget = field_holder;
+ int vmindex = offset; // implies no info yet
+ assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex");
-+ impl_java_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
-+ impl_java_dyn_MemberName::set_vmindex(mname_oop, vmindex);
-+ impl_java_dyn_MemberName::set_flags(mname_oop, flags);
++ sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
++ sun_dyn_MemberName::set_vmindex(mname_oop, vmindex);
++ sun_dyn_MemberName::set_flags(mname_oop, flags);
+}
+
+
+methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) {
-+ int flags = impl_java_dyn_MemberName::flags(mname);
++ int flags = sun_dyn_MemberName::flags(mname);
+ if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable
-+ oop vmtarget = impl_java_dyn_MemberName::vmtarget(mname);
-+ int vmindex = impl_java_dyn_MemberName::vmindex(mname);
++ oop vmtarget = sun_dyn_MemberName::vmtarget(mname);
++ int vmindex = sun_dyn_MemberName::vmindex(mname);
+ if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved
+ return decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
+}
@@ -4484,7 +4482,7 @@ new file mode 100644
+// Resolving it plants a vmtarget/vmindex in it,
+// which refers dirctly to JVM internals.
+void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
-+ assert(impl_java_dyn_MemberName::is_instance(mname()), "");
++ assert(sun_dyn_MemberName::is_instance(mname()), "");
+#ifdef ASSERT
+ // If this assert throws, renegotiate the sentinel value used by the Java code,
+ // so that it is distinct from any valid vtable index value, and any special
@@ -4495,25 +4493,28 @@ new file mode 100644
+ const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop;
+ assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels");
+#endif
-+ if (impl_java_dyn_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
++ if (sun_dyn_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
+ return; // already resolved
-+ oop defc_oop = impl_java_dyn_MemberName::clazz(mname());
-+ oop name_str = impl_java_dyn_MemberName::name(mname());
-+ oop type_str = impl_java_dyn_MemberName::type(mname());
-+ int flags = impl_java_dyn_MemberName::flags(mname());
-+
-+ if (defc_oop == NULL || name_str == NULL || type_str == NULL)
-+ { throw_IllegalArgumentException("nothing to resolve", CHECK); }
++ oop defc_oop = sun_dyn_MemberName::clazz(mname());
++ oop name_str = sun_dyn_MemberName::name(mname());
++ oop type_str = sun_dyn_MemberName::type(mname());
++ int flags = sun_dyn_MemberName::flags(mname());
++
++ if (defc_oop == NULL || name_str == NULL || type_str == NULL) {
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve");
++ }
+ klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop);
+ defc_oop = NULL; // safety
++ if (defc_klassOop == NULL) return; // a primitive; no resolution possible
+ if (!Klass::cast(defc_klassOop)->oop_is_instance()) {
+ if (!Klass::cast(defc_klassOop)->oop_is_array()) return;
+ defc_klassOop = SystemDictionary::object_klass();
+ }
+ instanceKlassHandle defc(THREAD, defc_klassOop);
+ defc_klassOop = NULL; // safety
-+ if (defc.is_null())
-+ { throw_InternalError("primitive class", CHECK); }
++ if (defc.is_null()) {
++ THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class");
++ }
+ defc->link_class(CHECK);
+
+ // convert the external string name to an internal symbol
@@ -4536,7 +4537,7 @@ new file mode 100644
+ type_sym = java_lang_String::as_symbol_or_null(type_str);
+ }
+ } else {
-+ throw_InternalError("unrecognized type", CHECK);
++ THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized type");
+ }
+ if (type_sym != NULL)
+ type = symbolHandle(THREAD, type_sym);
@@ -4583,9 +4584,10 @@ new file mode 100644
+ } else {
+ vmtarget = result.resolved_klass()->as_klassOop();
+ }
-+ impl_java_dyn_MemberName::set_vmtarget(mname(), vmtarget);
-+ impl_java_dyn_MemberName::set_vmindex(mname(), vmindex);
-+ impl_java_dyn_MemberName::set_modifiers(mname(), m->access_flags().as_short());
++ int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
++ sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
++ sun_dyn_MemberName::set_vmindex(mname(), vmindex);
++ sun_dyn_MemberName::set_modifiers(mname(), mods);
+ DEBUG_ONLY(int junk; klassOop junk2);
+ assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
+ "properly stored for later decoding");
@@ -4611,9 +4613,10 @@ new file mode 100644
+ methodHandle m = result.resolved_method();
+ oop vmtarget = m();
+ int vmindex = methodOopDesc::nonvirtual_vtable_index;
-+ impl_java_dyn_MemberName::set_vmtarget(mname(), vmtarget);
-+ impl_java_dyn_MemberName::set_vmindex(mname(), vmindex);
-+ impl_java_dyn_MemberName::set_modifiers(mname(), m->access_flags().as_short());
++ int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
++ sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
++ sun_dyn_MemberName::set_vmindex(mname(), vmindex);
++ sun_dyn_MemberName::set_modifiers(mname(), mods);
+ DEBUG_ONLY(int junk; klassOop junk2);
+ assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
+ "properly stored for later decoding");
@@ -4628,14 +4631,15 @@ new file mode 100644
+ if (sel_klass.is_null()) return;
+ oop vmtarget = sel_klass->as_klassOop();
+ int vmindex = fd.offset();
++ int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS);
+ if (vmindex == VM_INDEX_UNINITIALIZED) break; // should not happen
-+ impl_java_dyn_MemberName::set_vmtarget(mname(), vmtarget);
-+ impl_java_dyn_MemberName::set_vmindex(mname(), vmindex);
-+ impl_java_dyn_MemberName::set_modifiers(mname(), fd.access_flags().as_short());
++ sun_dyn_MemberName::set_vmtarget(mname(), vmtarget);
++ sun_dyn_MemberName::set_vmindex(mname(), vmindex);
++ sun_dyn_MemberName::set_modifiers(mname(), mods);
+ return;
+ }
+ }
-+ throw_InternalError("unrecognized MemberName format", THREAD);
++ THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
+}
+
+// Conversely, a member name which is only initialized from JVM internals
@@ -4643,16 +4647,17 @@ new file mode 100644
+// Resolving it plants a vmtarget/vmindex in it,
+// which refers directly to JVM internals.
+void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
-+ assert(impl_java_dyn_MemberName::is_instance(mname()), "");
-+ oop vmtarget = impl_java_dyn_MemberName::vmtarget(mname());
-+ int vmindex = impl_java_dyn_MemberName::vmindex(mname());
-+ if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED)
-+ { throw_IllegalArgumentException("nothing to expand", CHECK); }
-+
-+ bool have_defc = (impl_java_dyn_MemberName::clazz(mname()) != NULL);
-+ bool have_name = (impl_java_dyn_MemberName::name(mname()) != NULL);
-+ bool have_type = (impl_java_dyn_MemberName::type(mname()) != NULL);
-+ int flags = impl_java_dyn_MemberName::flags(mname());
++ assert(sun_dyn_MemberName::is_instance(mname()), "");
++ oop vmtarget = sun_dyn_MemberName::vmtarget(mname());
++ int vmindex = sun_dyn_MemberName::vmindex(mname());
++ if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) {
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
++ }
++
++ bool have_defc = (sun_dyn_MemberName::clazz(mname()) != NULL);
++ bool have_name = (sun_dyn_MemberName::name(mname()) != NULL);
++ bool have_type = (sun_dyn_MemberName::type(mname()) != NULL);
++ int flags = sun_dyn_MemberName::flags(mname());
+
+ if (suppress != 0) {
+ if (suppress & _suppress_defc) have_defc = true;
@@ -4676,16 +4681,16 @@ new file mode 100644
+ if (receiver_limit != NULL && receiver_limit != defc
+ && Klass::cast(receiver_limit)->is_subtype_of(defc))
+ defc = receiver_limit;
-+ impl_java_dyn_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
++ sun_dyn_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
+ }
+ if (!have_name) {
+ //not java_lang_String::create_from_symbol; let's intern member names
+ Handle name = StringTable::intern(m->name(), CHECK);
-+ impl_java_dyn_MemberName::set_name(mname(), name());
++ sun_dyn_MemberName::set_name(mname(), name());
+ }
+ if (!have_type) {
+ Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK);
-+ impl_java_dyn_MemberName::set_type(mname(), type());
++ sun_dyn_MemberName::set_type(mname(), type());
+ }
+ return;
+ }
@@ -4700,21 +4705,21 @@ new file mode 100644
+ if (!defc->find_field_from_offset(vmindex, is_static, &fd))
+ break; // cannot expand
+ if (!have_defc) {
-+ impl_java_dyn_MemberName::set_clazz(mname(), defc->java_mirror());
++ sun_dyn_MemberName::set_clazz(mname(), defc->java_mirror());
+ }
+ if (!have_name) {
+ //not java_lang_String::create_from_symbol; let's intern member names
+ Handle name = StringTable::intern(fd.name(), CHECK);
-+ impl_java_dyn_MemberName::set_name(mname(), name());
++ sun_dyn_MemberName::set_name(mname(), name());
+ }
+ if (!have_type) {
+ Handle type = java_lang_String::create_from_symbol(fd.signature(), CHECK);
-+ impl_java_dyn_MemberName::set_type(mname(), type());
++ sun_dyn_MemberName::set_type(mname(), type());
+ }
+ return;
+ }
+ }
-+ throw_InternalError("unrecognized MemberName format", THREAD);
++ THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
+}
+
+int MethodHandles::find_MemberNames(klassOop k,
@@ -4764,7 +4769,7 @@ new file mode 100644
+ --rskip;
+ } else if (rfill < rlimit) {
+ oop result = results->obj_at(rfill++);
-+ if (!impl_java_dyn_MemberName::is_instance(result))
++ if (!sun_dyn_MemberName::is_instance(result))
+ return -99; // caller bug!
+ MethodHandles::init_MemberName(result, st.klass()->as_klassOop(), st.access_flags(), st.offset());
+ } else if (++overflow >= overflow_limit) {
@@ -4812,7 +4817,7 @@ new file mode 100644
+ --rskip;
+ } else if (rfill < rlimit) {
+ oop result = results->obj_at(rfill++);
-+ if (!impl_java_dyn_MemberName::is_instance(result))
++ if (!sun_dyn_MemberName::is_instance(result))
+ return -99; // caller bug!
+ MethodHandles::init_MemberName(result, m, true);
+ } else if (++overflow >= overflow_limit) {
@@ -4831,10 +4836,10 @@ new file mode 100644
+// Decode the vmtarget field of a method handle.
+// Sanitize out methodOops, klassOops, and any other non-Java data.
+// This is for debugging and reflection.
-+oop MethodHandles::encode_target(oop mh, int format, TRAPS) {
-+ assert(java_dyn_MethodHandle::is_instance(mh), "must be a MH");
++oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
++ assert(java_dyn_MethodHandle::is_instance(mh()), "must be a MH");
+ if (format == ETF_HANDLE_OR_METHOD_NAME) {
-+ oop target = java_dyn_MethodHandle::vmtarget(mh);
++ oop target = java_dyn_MethodHandle::vmtarget(mh());
+ if (target == NULL) {
+ return NULL; // unformed MH
+ }
@@ -4844,7 +4849,7 @@ new file mode 100644
+ }
+ }
+ if (format == ETF_DIRECT_HANDLE) {
-+ oop target = mh;
++ oop target = mh();
+ for (;;) {
+ if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
+ return target;
@@ -4861,7 +4866,7 @@ new file mode 100644
+ // - DMH can have klassOop for dispatched (non-static) invoke
+ klassOop receiver_limit = NULL;
+ int decode_flags = 0;
-+ methodOop m = decode_MethodHandle(mh, receiver_limit, decode_flags);
++ methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags);
+ if (m == NULL) return NULL;
+ switch (format) {
+ case ETF_REFLECT_METHOD:
@@ -4879,7 +4884,7 @@ new file mode 100644
+ instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass());
+ mname_klass->initialize(CHECK_NULL);
+ Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL);
-+ impl_java_dyn_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
++ sun_dyn_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
+ bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
+ init_MemberName(mname(), m, do_dispatch);
+ expand_MemberName(mname, 0, CHECK_NULL);
@@ -4888,8 +4893,9 @@ new file mode 100644
+ }
+
+ // Unknown format code.
-+ throw_IllegalArgumentException(THREAD);
-+ return NULL;
++ char msg[50];
++ jio_snprintf(msg, sizeof(msg), "unknown getTarget format=%d", format);
++ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg);
+}
+
+bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) {
@@ -4940,8 +4946,8 @@ new file mode 100644
+ return false;
+}
+
-+const char* MethodHandles::check_method_receiver(methodHandle m,
-+ klassOop passed_recv_type) {
++const char* MethodHandles::check_method_receiver(methodOop m,
++ klassOop passed_recv_type) {
+ assert(!m->is_static(), "caller resp.");
+ if (passed_recv_type == NULL)
+ return "receiver type is primitive";
@@ -4957,10 +4963,10 @@ new file mode 100644
+// of the given method type 'mtype'.
+// It takes a TRAPS argument because it must perform symbol lookups.
+void MethodHandles::verify_method_signature(methodHandle m,
-+ Handle mtype,
-+ int first_ptype_pos,
-+ KlassHandle insert_ptype,
-+ TRAPS) {
++ Handle mtype,
++ int first_ptype_pos,
++ KlassHandle insert_ptype,
++ TRAPS) {
+ objArrayHandle ptypes(THREAD, java_dyn_MethodType::ptypes(mtype()));
+ int pnum = first_ptype_pos;
+ int pmax = ptypes->length();
@@ -5016,22 +5022,17 @@ new file mode 100644
+ }
+
+ if (err != NULL) {
-+ throw_InternalError(err, CHECK);
++ THROW_MSG(vmSymbols::java_lang_InternalError(), err);
+ }
+}
+
+// Main routine for verifying the MethodHandle.type of a proposed
+// direct or bound-direct method handle.
+void MethodHandles::verify_method_type(methodHandle m,
-+ oop mtype_oop,
-+ bool has_bound_recv,
-+ klassOop bound_recv_type_oop,
-+ TRAPS) {
-+ Handle mtype(THREAD, mtype_oop);
-+ KlassHandle bound_recv_type(THREAD, bound_recv_type_oop);
-+
-+ mtype_oop = NULL; bound_recv_type_oop = NULL; // better safe than sorry
-+
++ Handle mtype,
++ bool has_bound_recv,
++ KlassHandle bound_recv_type,
++ TRAPS) {
+ bool m_needs_receiver = !m->is_static();
+
+ const char* err = NULL;
@@ -5048,9 +5049,9 @@ new file mode 100644
+ if (ptypes->length() < first_ptype_pos)
+ { err = "receiver argument is missing"; goto die; }
+ if (first_ptype_pos == -1)
-+ err = check_method_receiver(m, bound_recv_type->as_klassOop());
++ err = check_method_receiver(m(), bound_recv_type->as_klassOop());
+ else
-+ err = check_method_receiver(m, java_lang_Class::as_klassOop(ptypes->obj_at(0)));
++ err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(0)));
+ if (err != NULL) goto die;
+ }
+
@@ -5059,14 +5060,15 @@ new file mode 100644
+ return;
+
+ die:
-+ throw_InternalError(err, CHECK);
++ THROW_MSG(vmSymbols::java_lang_InternalError(), err);
+}
+
+void MethodHandles::verify_vmslots(Handle mh, TRAPS) {
+ // Verify vmslots.
+ int check_slots = argument_slot_count(java_dyn_MethodHandle::type(mh()));
-+ if (java_dyn_MethodHandle::vmslots(mh()) != check_slots)
-+ { throw_InternalError("bad vmslots in BMH", CHECK); }
++ if (java_dyn_MethodHandle::vmslots(mh()) != check_slots) {
++ THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH");
++ }
+}
+
+void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
@@ -5077,7 +5079,7 @@ new file mode 100644
+ size_t msglen = strlen(fmt) + 3*11 + 1;
+ char* msg = NEW_RESOURCE_ARRAY(char, msglen);
+ jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
-+ throw_InternalError(msg, CHECK);
++ THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
+ }
+}
+
@@ -5085,12 +5087,12 @@ new file mode 100644
+// Apart from the advertised changes, caller method type X must
+// be able to invoke the callee method Y type with no violations
+// of type integrity.
-+void MethodHandles::verify_method_type_change(oop src_mtype, int src_beg, int src_end,
-+ int insert_argnum, oop insert_type,
-+ int change_argnum, oop change_type,
-+ int delete_argnum,
-+ oop dst_mtype, int dst_beg, int dst_end,
-+ TRAPS) {
++// Return NULL if all is well, else a short error message.
++const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end,
++ int insert_argnum, oop insert_type,
++ int change_argnum, oop change_type,
++ int delete_argnum,
++ oop dst_mtype, int dst_beg, int dst_end) {
+ objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype);
+ objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype);
+
@@ -5147,31 +5149,23 @@ new file mode 100644
+
+ // Compare the two argument types.
+ if (src_type != dst_type) {
-+ if (src_type == NULL) err = "not enough arguments";
-+ if (dst_type == NULL) err = "too many arguments";
-+ if (err == NULL)
-+ err = check_argument_type_change(src_type, dst_type, dst_idx);
-+ if (err != NULL) break;
-+ }
-+ }
-+
-+ if (err == NULL) {
-+ // Now compare return types also.
-+ oop src_rtype = java_dyn_MethodType::rtype(src_mtype);
-+ oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype);
-+ if (src_rtype != dst_rtype) {
-+ err = check_return_type_change(dst_rtype, src_rtype); // note reversal!
-+ }
-+ }
-+
-+ if (err != NULL) { throw_InternalError(err, CHECK); }
-+}
-+
-+// Handy wrapper for check_argument_type_change, to verify one src/dest pair.
-+void MethodHandles::verify_argument_type_change(oop src_type, oop dst_type,
-+ int argnum, TRAPS) {
-+ const char* err = check_argument_type_change(src_type, dst_type, argnum);
-+ if (err != NULL) { throw_InternalError(err, CHECK); }
++ if (src_type == NULL) return "not enough arguments";
++ if (dst_type == NULL) return "too many arguments";
++ err = check_argument_type_change(src_type, dst_type, dst_idx);
++ if (err != NULL) return err;
++ }
++ }
++
++ // Now compare return types also.
++ oop src_rtype = java_dyn_MethodType::rtype(src_mtype);
++ oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype);
++ if (src_rtype != dst_rtype) {
++ err = check_return_type_change(dst_rtype, src_rtype); // note reversal!
++ if (err != NULL) return err;
++ }
++
++ assert(err == NULL, "");
++ return NULL; // all is well
+}
+
+
@@ -5224,7 +5218,7 @@ new file mode 100644
+ if (src_name == NULL) src_name = "unknown type";
+ if (dst_name == NULL) dst_name = "unknown type";
+
-+ size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
++ size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
+ char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);
+ if (argnum >= 0) {
+ assert(strstr(err, "%d") != NULL, "");
@@ -5273,33 +5267,33 @@ new file mode 100644
+ return -99; // oob slot, or splitting a double-slot arg
+}
+
-+methodOop MethodHandles::dispatch_decoded_method(methodOop m,
-+ klassOop receiver_limit,
-+ int decode_flags,
-+ klassOop receiver_klass,
-+ TRAPS) {
++methodHandle MethodHandles::dispatch_decoded_method(methodHandle m,
++ KlassHandle receiver_limit,
++ int decode_flags,
++ KlassHandle receiver_klass,
++ TRAPS) {
+ assert((decode_flags & ~_DMF_DIRECT_MASK) == 0, "must be direct method reference");
+ assert((decode_flags & _dmf_has_receiver) != 0, "must have a receiver or first reference argument");
+
+ if (!m->is_static() &&
-+ (receiver_klass == NULL || !Klass::cast(receiver_klass)->is_subtype_of(m->method_holder())))
++ (receiver_klass.is_null() || !receiver_klass->is_subtype_of(m->method_holder())))
+ // given type does not match class of method, or receiver is null!
+ // caller should have checked this, but let's be extra careful...
-+ return NULL;
-+
-+ if (receiver_limit != NULL &&
-+ (receiver_klass != NULL && !Klass::cast(receiver_klass)->is_subtype_of(receiver_limit)))
++ return methodHandle();
++
++ if (receiver_limit.not_null() &&
++ (receiver_klass.not_null() && !receiver_klass->is_subtype_of(receiver_limit())))
+ // given type is not limited to the receiver type
+ // note that a null receiver can match any reference value, for a static method
-+ return NULL;
++ return methodHandle();
+
+ if (!(decode_flags & MethodHandles::_dmf_does_dispatch)) {
+ // pre-dispatched or static method (null receiver is OK for static)
+ return m;
+
-+ } else if (receiver_klass == NULL) {
++ } else if (receiver_klass.is_null()) {
+ // null receiver value; cannot dispatch
-+ return NULL;
++ return methodHandle();
+
+ } else if (!(decode_flags & MethodHandles::_dmf_from_interface)) {
+ // perform virtual dispatch
@@ -5309,37 +5303,45 @@ new file mode 100644
+ // receiver_klass might be an arrayKlassOop but all vtables start at
+ // the same place. The cast is to avoid virtual call and assertion.
+ // See also LinkResolver::runtime_resolve_virtual_method.
-+ instanceKlass* inst = (instanceKlass*)Klass::cast(receiver_klass);
++ instanceKlass* inst = (instanceKlass*)Klass::cast(receiver_klass());
+ DEBUG_ONLY(inst->verify_vtable_index(vtable_index));
-+ return inst->method_at_vtable(vtable_index);
++ methodOop m_oop = inst->method_at_vtable(vtable_index);
++ return methodHandle(THREAD, m_oop);
+
+ } else {
+ // perform interface dispatch
-+ int itable_index = klassItable::compute_itable_index(m);
++ int itable_index = klassItable::compute_itable_index(m());
+ guarantee(itable_index >= 0, "valid itable index");
-+ instanceKlass* inst = instanceKlass::cast(receiver_klass);
-+ return inst->method_at_itable(m->method_holder(), itable_index, THREAD);
++ instanceKlass* inst = instanceKlass::cast(receiver_klass());
++ methodOop m_oop = inst->method_at_itable(m->method_holder(), itable_index, THREAD);
++ return methodHandle(THREAD, m_oop);
++ }
++}
++
++void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) {
++ // Verify type.
++ Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
++ verify_method_type(m, mtype, false, KlassHandle(), CHECK);
++
++ // Verify vmslots.
++ if (java_dyn_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
++ THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH");
+ }
+}
+
+void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_dispatch, TRAPS) {
+ // Check arguments.
+ if (mh.is_null() || m.is_null() ||
-+ (!do_dispatch && m->is_abstract()))
-+ { throw_InternalError(CHECK); }
++ (!do_dispatch && m->is_abstract())) {
++ THROW(vmSymbols::java_lang_InternalError());
++ }
+
+ java_dyn_MethodHandle::init_vmslots(mh());
+
-+ // The privileged code which invokes this routine should not make
-+ // a mistake about types, but it's better to verify.
+ if (VerifyMethodHandles) {
-+ // Verify type.
-+ verify_method_type(m, java_dyn_MethodHandle::type(mh()),
-+ false, NULL, CHECK);
-+
-+ // Verify vmslots.
-+ if (java_dyn_MethodHandle::vmslots(mh()) != m->size_of_parameters())
-+ { throw_InternalError("bad vmslots in DMH", CHECK); }
++ // The privileged code which invokes this routine should not make
++ // a mistake about types, but it's better to verify.
++ verify_DirectMethodHandle(mh, m, CHECK);
+ }
+
+ // Finally, after safety checks are done, link to the target method.
@@ -5392,10 +5394,10 @@ new file mode 100644
+ me = MethodHandles::entry(MethodHandles::_invokevirtual_mh);
+ }
+
-+ if (me == NULL) { throw_InternalError(CHECK); }
-+
-+ impl_java_dyn_DirectMethodHandle::set_vmtarget(mh(), vmtarget);
-+ impl_java_dyn_DirectMethodHandle::set_vmindex(mh(), vmindex);
++ if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
++
++ sun_dyn_DirectMethodHandle::set_vmtarget(mh(), vmtarget);
++ sun_dyn_DirectMethodHandle::set_vmindex(mh(), vmindex);
+ DEBUG_ONLY(int flags; klassOop rlimit);
+ assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(),
+ "properly stored for later decoding");
@@ -5409,51 +5411,59 @@ new file mode 100644
+ java_dyn_MethodHandle::set_vmentry(mh(), me);
+}
+
++void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh,
++ methodHandle m,
++ TRAPS) {
++ // Verify type.
++ oop receiver = sun_dyn_BoundMethodHandle::argument(mh());
++ Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
++ KlassHandle bound_recv_type;
++ if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass());
++ verify_method_type(m, mtype, true, bound_recv_type, CHECK);
++
++ int receiver_pos = m->size_of_parameters() - 1;
++
++ // Verify MH.vmargslot, which should point at the bound receiver.
++ verify_vmargslot(mh, -1, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
++ //verify_vmslots(mh, CHECK);
++
++ // Verify vmslots.
++ if (java_dyn_MethodHandle::vmslots(mh()) != receiver_pos) {
++ THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)");
++ }
++}
++
+// Initialize a BMH with a receiver bound directly to a methodOop.
+void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh,
-+ methodOop original_m_oop,
-+ klassOop receiver_limit_oop,
-+ int decode_flags,
-+ TRAPS) {
++ methodHandle original_m,
++ KlassHandle receiver_limit,
++ int decode_flags,
++ TRAPS) {
+ // Check arguments.
-+ if (mh.is_null() || original_m_oop == NULL)
-+ { throw_InternalError(CHECK); }
-+
-+ oop arg_oop = impl_java_dyn_BoundMethodHandle::argument(mh());
-+ methodOop m_oop = dispatch_decoded_method(original_m_oop,
-+ receiver_limit_oop, decode_flags,
-+ (arg_oop == NULL ? klassOop(NULL) : arg_oop->klass()),
-+ CHECK);
-+ // do not use bare oops after this point:
-+ original_m_oop = NULL; receiver_limit_oop = NULL; arg_oop = NULL;
-+
-+ if (m_oop == NULL) { throw_InternalError(CHECK); }
-+ methodHandle m(THREAD, m_oop); m_oop = NULL;
-+
-+ if (m->is_abstract())
-+ THROW(vmSymbols::java_lang_AbstractMethodError());
++ if (mh.is_null() || original_m.is_null()) {
++ THROW(vmSymbols::java_lang_InternalError());
++ }
++
++ KlassHandle receiver_klass;
++ {
++ oop receiver_oop = sun_dyn_BoundMethodHandle::argument(mh());
++ if (receiver_oop != NULL)
++ receiver_klass = KlassHandle(THREAD, receiver_oop->klass());
++ }
++ methodHandle m = dispatch_decoded_method(original_m,
++ receiver_limit, decode_flags,
++ receiver_klass,
++ CHECK);
++ if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); }
++ if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
+
+ java_dyn_MethodHandle::init_vmslots(mh());
+
+ if (VerifyMethodHandles) {
-+ // Verify type.
-+ oop receiver = impl_java_dyn_BoundMethodHandle::argument(mh());
-+ verify_method_type(m, java_dyn_MethodHandle::type(mh()),
-+ true, (receiver == NULL ? klassOop(NULL) : receiver->klass()),
-+ CHECK);
-+
-+ int receiver_pos = m->size_of_parameters() - 1;
-+
-+ // Verify MH.vmargslot, which should point at the bound receiver.
-+ verify_vmargslot(mh, -1, impl_java_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
-+ //verify_vmslots(mh, CHECK);
-+
-+ // Verify vmslots.
-+ if (java_dyn_MethodHandle::vmslots(mh()) != receiver_pos)
-+ { throw_InternalError("bad vmslots in BMH (receiver)", CHECK); }
-+ }
-+
-+ impl_java_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
++ verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
++ }
++
++ sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
+
+ DEBUG_ONLY(int junk; klassOop junk2);
+ assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding");
@@ -5463,16 +5473,102 @@ new file mode 100644
+ java_dyn_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
+}
+
++void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
++ bool direct_to_method, TRAPS) {
++ Handle ptype_handle(THREAD,
++ java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum));
++ KlassHandle ptype_klass;
++ BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass);
++ int slots_pushed = type2size[ptype];
++
++ oop argument = sun_dyn_BoundMethodHandle::argument(mh());
++
++ const char* err = NULL;
++
++ switch (ptype) {
++ case T_OBJECT:
++ if (argument != NULL)
++ // we must implicitly convert from the arg type to the outgoing ptype
++ err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass(), argnum);
++ break;
++
++ case T_ARRAY: case T_VOID:
++ assert(false, "array, void do not appear here");
++ default:
++ if (ptype != T_INT && !is_subword_type(ptype)) {
++ err = "unexpected parameter type";
++ break;
++ }
++ // check subrange of Integer.value, if necessary
++ if (argument == NULL || argument->klass() != SystemDictionary::int_klass()) {
++ err = "bound integer argument must be of type java.lang.Integer";
++ break;
++ }
++ if (ptype != T_INT) {
++ int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
++ jint value = argument->int_field(value_offset);
++ int vminfo = adapter_subword_vminfo(ptype);
++ jint subword = truncate_subword_from_vminfo(value, vminfo);
++ if (value != subword) {
++ err = "bound subword value does not fit into the subword type";
++ break;
++ }
++ }
++ break;
++ case T_FLOAT:
++ case T_DOUBLE:
++ case T_LONG:
++ {
++ // we must implicitly convert from the unboxed arg type to the outgoing ptype
++ BasicType argbox = java_lang_boxing_object::basic_type(argument);
++ if (argbox != ptype) {
++ err = check_argument_type_change(T_OBJECT, (argument == NULL
++ ? SystemDictionary::object_klass()
++ : argument->klass()),
++ ptype, ptype_klass(), argnum);
++ assert(err != NULL, "this must be an error");
++ }
++ break;
++ }
++ }
++
++ if (err == NULL) {
++ DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
++ if (direct_to_method) {
++ assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
++ assert(slots_pushed <= MethodHandlePushLimit, "");
++ } else {
++ int prev_pushes = decode_MethodHandle_stack_pushes(target());
++ assert(this_pushes == slots_pushed + prev_pushes, "BMH stack motion must be correct");
++ // do not blow the stack; use a Java-based adapter if this limit is exceeded
++ if (slots_pushed + prev_pushes > MethodHandlePushLimit)
++ err = "too many bound parameters";
++ }
++ }
++
++ if (err == NULL) {
++ // Verify the rest of the method type.
++ err = check_method_type_insertion(java_dyn_MethodHandle::type(mh()),
++ argnum, ptype_handle(),
++ java_dyn_MethodHandle::type(target()));
++ }
++
++ if (err != NULL) {
++ THROW_MSG(vmSymbols::java_lang_InternalError(), err);
++ }
++}
++
+void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
+ // Check arguments.
-+ if (mh.is_null() || target.is_null() || !java_dyn_MethodHandle::is_instance(target()))
-+ { throw_InternalError(CHECK); }
++ if (mh.is_null() || target.is_null() || !java_dyn_MethodHandle::is_instance(target())) {
++ THROW(vmSymbols::java_lang_InternalError());
++ }
+
+ java_dyn_MethodHandle::init_vmslots(mh());
+
+ if (VerifyMethodHandles) {
+ int insert_after = argnum - 1;
-+ verify_vmargslot(mh, insert_after, impl_java_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
++ verify_vmargslot(mh, insert_after, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
+ verify_vmslots(mh, CHECK);
+ }
+
@@ -5483,14 +5579,15 @@ new file mode 100644
+ bool direct_to_method = false;
+ if (OptimizeMethodHandles &&
+ target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
-+ (argnum == 0 || impl_java_dyn_DirectMethodHandle::vmindex(target()) < 0)) {
-+ int decode_flags = 0; klassOop receiver_limit = NULL;
-+ methodHandle m(THREAD, decode_method(target(), receiver_limit, decode_flags));
-+ if (m.is_null()) { throw_InternalError("DMH failed to decode", CHECK); }
++ (argnum == 0 || sun_dyn_DirectMethodHandle::vmindex(target()) < 0)) {
++ int decode_flags = 0; klassOop receiver_limit_oop = NULL;
++ methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags));
++ if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
+ DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - 1); // pos. of 1st arg.
-+ assert(impl_java_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
++ assert(sun_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
+ if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
-+ init_BoundMethodHandle_with_receiver(mh, m(),
++ KlassHandle receiver_limit(THREAD, receiver_limit_oop);
++ init_BoundMethodHandle_with_receiver(mh, m,
+ receiver_limit, decode_flags,
+ CHECK);
+ return;
@@ -5500,90 +5597,20 @@ new file mode 100644
+ // to bind another argument and still invoke the methodOop directly.
+ if (!(decode_flags & _dmf_does_dispatch)) {
+ direct_to_method = true;
-+ impl_java_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
++ sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
+ }
+ }
+ if (!direct_to_method)
-+ impl_java_dyn_BoundMethodHandle::set_vmtarget(mh(), target());
++ sun_dyn_BoundMethodHandle::set_vmtarget(mh(), target());
++
++ if (VerifyMethodHandles) {
++ verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK);
++ }
+
+ // Next question: Is this a ref, int, or long bound value?
-+ oop target_mtype = java_dyn_MethodHandle::type(target());
-+ klassOop ptype_klass = NULL;
-+ oop ptype_oop = java_dyn_MethodType::ptype(target_mtype, argnum);
-+ BasicType ptype = java_lang_Class::as_BasicType(ptype_oop, &ptype_klass);
-+ assert(ptype != T_ARRAY && ptype != T_VOID, "does not appear here");
++ oop ptype_oop = java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum);
++ BasicType ptype = java_lang_Class::as_BasicType(ptype_oop);
+ int slots_pushed = type2size[ptype];
-+ if (VerifyMethodHandles) {
-+ oop argument = impl_java_dyn_BoundMethodHandle::argument(mh());
-+ const char* err = NULL;
-+ switch (ptype) {
-+ case T_OBJECT:
-+ if (argument != NULL)
-+ // we must implicitly convert from the arg type to the outgoing ptype
-+ err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass, argnum);
-+ break;
-+ case T_ARRAY: case T_VOID:
-+ assert(false, "array, void do not appear here");
-+ default:
-+ if (ptype != T_INT && !is_subword_type(ptype)) {
-+ err = "unexpected parameter type";
-+ break;
-+ }
-+ // check subrange of Integer.value, if necessary
-+ if (argument == NULL || argument->klass() != SystemDictionary::int_klass()) {
-+ err = "bound integer argument must be of type java.lang.Integer";
-+ break;
-+ }
-+ if (ptype != T_INT) {
-+ int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
-+ jint value = argument->int_field(value_offset);
-+ int vminfo = adapter_subword_vminfo(ptype);
-+ jint subword = truncate_subword_from_vminfo(value, vminfo);
-+ if (value != subword) {
-+ err = "bound subword value does not fit into the subword type";
-+ break;
-+ }
-+ }
-+ break;
-+ case T_FLOAT:
-+ case T_DOUBLE:
-+ case T_LONG:
-+ {
-+ // we must implicitly convert from the unboxed arg type to the outgoing ptype
-+ BasicType argbox = java_lang_boxing_object::basic_type(argument);
-+ if (argbox != ptype) {
-+ err = check_argument_type_change(T_OBJECT, (argument == NULL
-+ ? SystemDictionary::object_klass()
-+ : argument->klass()),
-+ ptype, ptype_klass, argnum);
-+ assert(err != NULL, "this must be an error");
-+ }
-+ break;
-+ }
-+ }
-+
-+ if (err == NULL) {
-+ DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-+ if (direct_to_method) {
-+ assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
-+ assert(slots_pushed <= MethodHandlePushLimit, "");
-+ } else {
-+ int prev_pushes = decode_MethodHandle_stack_pushes(target());
-+ assert(this_pushes == slots_pushed + prev_pushes, "BMH stack motion must be correct");
-+ // do not blow the stack; use a Java-based adapter if this limit is exceeded
-+ if (slots_pushed + prev_pushes > MethodHandlePushLimit)
-+ err = "too many bound parameters";
-+ }
-+ }
-+
-+ if (err != NULL)
-+ { throw_InternalError(err, CHECK); }
-+
-+ // Verify the rest of the method type.
-+ verify_method_type_insertion(java_dyn_MethodHandle::type(mh()),
-+ argnum, ptype_oop,
-+ java_dyn_MethodHandle::type(target()), CHECK);
-+ }
+
+ MethodHandleEntry* me = NULL;
+ if (ptype == T_OBJECT) {
@@ -5603,275 +5630,313 @@ new file mode 100644
+ java_dyn_MethodHandle::set_vmentry(mh(), me);
+}
+
-+void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
-+ jint conversion = impl_java_dyn_AdapterMethodHandle::conversion(mh());
-+ oop argument = impl_java_dyn_AdapterMethodHandle::argument(mh());
-+ int argslot = impl_java_dyn_AdapterMethodHandle::vmargslot(mh());
-+
-+ // adjust the adapter code to the internal EntryKind enumeration:
-+ AdapterKind ak = adapter_conversion_op(conversion);
-+ EntryKind ek = (EntryKind)(MethodHandles::_adapter_mh_first + (int)ak);
-+
-+ if (ak < _adapt_retype_only || ak > _AK_LIMIT)
-+ { throw_InternalError("bad conversion", CHECK); }
-+
-+ // Finalize the vmtarget field (Java initialized it to null).
-+ impl_java_dyn_AdapterMethodHandle::set_vmtarget(mh(), target());
++static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) {
++ char msg[200];
++ jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err);
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg);
++}
++
++void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
++ jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh());
++ int argslot = sun_dyn_AdapterMethodHandle::vmargslot(mh());
++
++ verify_vmargslot(mh, argnum, argslot, CHECK);
++ verify_vmslots(mh, CHECK);
++
++ jint conv_op = adapter_conversion_op(conversion);
++ if (!conv_op_valid(conv_op)) {
++ throw_InternalError_for_bad_conversion(conversion, "unknown conversion op", THREAD);
++ return;
++ }
++ EntryKind ek = adapter_entry_kind(conv_op);
+
+ int stack_move = adapter_conversion_stack_move(conversion);
+ BasicType src = adapter_conversion_src_type(conversion);
+ BasicType dest = adapter_conversion_dest_type(conversion);
+ int vminfo = adapter_conversion_vminfo(conversion); // should be zero
+
-+ if (VerifyMethodHandles) {
-+ verify_vmargslot(mh, argnum, argslot, CHECK);
-+ verify_vmslots(mh, CHECK);
-+
-+ const char* err = NULL;
-+
-+ if (err == NULL) {
-+ if (!java_dyn_MethodHandle::is_instance(target()))
-+ err = "adapter target is not a method handle";
-+ }
-+
-+ if (err == NULL) {
-+ // Check that the correct argument is supplied, but only if it is required.
-+ switch (ak) {
-+ case _adapt_check_cast: // target type of cast
-+ case _adapt_ref_to_prim: // wrapper type from which to unbox
-+ case _adapt_prim_to_ref: // wrapper type to box into
-+ case _adapt_collect_args: // array type to collect into
-+ case _adapt_spread_args: // array type to spread from
-+ if (!java_lang_Class::is_instance(argument)
-+ || java_lang_Class::is_primitive(argument))
-+ { err = "adapter requires argument of type java.lang.Class"; break; }
-+ if (ak == _adapt_collect_args ||
-+ ak == _adapt_spread_args) {
-+ // Make sure it is a suitable collection type. (Array, for now.)
-+ Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument));
-+ if (!ak->oop_is_objArray()) {
-+ { err = "adapter requires argument of type java.lang.Class<Object[]>"; break; }
++ Handle argument(THREAD, sun_dyn_AdapterMethodHandle::argument(mh()));
++ Handle target(THREAD, sun_dyn_AdapterMethodHandle::vmtarget(mh()));
++ Handle src_mtype(THREAD, java_dyn_MethodHandle::type(mh()));
++ Handle dst_mtype(THREAD, java_dyn_MethodHandle::type(target()));
++
++ const char* err = NULL;
++
++ if (err == NULL) {
++ // Check that the correct argument is supplied, but only if it is required.
++ switch (ek) {
++ case _adapter_check_cast: // target type of cast
++ case _adapter_ref_to_prim: // wrapper type from which to unbox
++ case _adapter_prim_to_ref: // wrapper type to box into
++ case _adapter_collect_args: // array type to collect into
++ case _adapter_spread_args: // array type to spread from
++ if (!java_lang_Class::is_instance(argument())
++ || java_lang_Class::is_primitive(argument()))
++ { err = "adapter requires argument of type java.lang.Class"; break; }
++ if (ek == _adapter_collect_args ||
++ ek == _adapter_spread_args) {
++ // Make sure it is a suitable collection type. (Array, for now.)
++ Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument()));
++ if (!ak->oop_is_objArray()) {
++ { err = "adapter requires argument of type java.lang.Class<Object[]>"; break; }
++ }
++ }
++ break;
++ case _adapter_flyby:
++ case _adapter_ricochet:
++ if (!java_dyn_MethodHandle::is_instance(argument()))
++ { err = "MethodHandle adapter argument required"; break; }
++ break;
++ default:
++ if (argument.not_null())
++ { err = "adapter has spurious argument"; break; }
++ break;
++ }
++ }
++
++ if (err == NULL) {
++ // Check that the src/dest types are supplied if needed.
++ switch (ek) {
++ case _adapter_prim_to_prim:
++ if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
++ err = "adapter requires primitive src/dest conversion subfields"; break;
++ }
++ if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
++ !(src == T_FLOAT || src == T_DOUBLE) && (dest == T_FLOAT || dest == T_DOUBLE)) {
++ err = "adapter cannot convert beween floating and fixed-point"; break;
++ }
++ break;
++ case _adapter_ref_to_prim:
++ if (src != T_OBJECT || !is_java_primitive(dest)
++ || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
++ err = "adapter requires primitive dest conversion subfield"; break;
++ }
++ break;
++ case _adapter_prim_to_ref:
++ if (!is_java_primitive(src) || dest != T_OBJECT
++ || argument() != Klass::cast(SystemDictionary::box_klass(src))->java_mirror()) {
++ err = "adapter requires primitive src conversion subfield"; break;
++ }
++ break;
++ case _adapter_swap_args:
++ case _adapter_rot_args:
++ {
++ if (!src || src != dest) {
++ err = "adapter requires src/dest conversion subfields for swap"; break;
++ }
++ int swap_size = type2size[src];
++ oop src_mtype = sun_dyn_AdapterMethodHandle::type(target());
++ oop dest_mtype = sun_dyn_AdapterMethodHandle::type(mh());
++ int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(src_mtype);
++ int src_slot = argslot;
++ int dest_slot = vminfo;
++ bool rotate_up = (src_slot > dest_slot); // upward rotation
++ int src_arg = argnum;
++ int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot);
++ verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
++ if (!(dest_slot >= src_slot + swap_size) &&
++ !(src_slot >= dest_slot + swap_size)) {
++ err = "source, destination slots must be distinct";
++ } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
++ err = "source of swap must be deeper in stack";
++ } else if (ek == _adapter_swap_args) {
++ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, dest_arg),
++ java_dyn_MethodType::ptype(dest_mtype, src_arg),
++ dest_arg);
++ } else if (ek == _adapter_rot_args) {
++ if (rotate_up) {
++ assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
++ // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
++ // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
++ for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
++ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
++ java_dyn_MethodType::ptype(dest_mtype, i-1),
++ i);
++ }
++ } else { // rotate down
++ assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
++ // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
++ // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
++ for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
++ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
++ java_dyn_MethodType::ptype(dest_mtype, i+1),
++ i);
++ }
+ }
+ }
-+ break;
-+ case _adapt_flyby:
-+ case _adapt_ricochet:
-+ if (!java_dyn_MethodHandle::is_instance(argument))
-+ { err = "MethodHandle adapter argument required"; break; }
-+ break;
-+ default:
-+ if (argument != NULL)
-+ { err = "adapter has spurious argument"; break; }
-+ break;
++ if (err == NULL)
++ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, src_arg),
++ java_dyn_MethodType::ptype(dest_mtype, dest_arg),
++ src_arg);
+ }
-+ }
-+
-+ if (err == NULL) {
-+ // Check that the src/dest types are supplied if needed.
-+ switch (ak) {
-+ case _adapt_prim_to_prim:
-+ if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
-+ err = "adapter requires primitive src/dest conversion subfields"; break;
-+ }
-+ if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
-+ !(src == T_FLOAT || src == T_DOUBLE) && (dest == T_FLOAT || dest == T_DOUBLE)) {
-+ err = "adapter cannot convert beween floating and fixed-point"; break;
-+ }
-+ break;
-+ case _adapt_ref_to_prim:
-+ if (src != T_OBJECT || !is_java_primitive(dest)
-+ || argument != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
-+ err = "adapter requires primitive dest conversion subfield"; break;
-+ }
-+ break;
-+ case _adapt_prim_to_ref:
-+ if (!is_java_primitive(src) || dest != T_OBJECT
-+ || argument != Klass::cast(SystemDictionary::box_klass(src))->java_mirror()) {
-+ err = "adapter requires primitive src conversion subfield"; break;
-+ }
-+ break;
-+ case _adapt_swap_args:
-+ case _adapt_rot_args:
-+ {
-+ if (!src || src != dest) {
-+ err = "adapter requires src/dest conversion subfields for swap"; break;
-+ }
-+ int swap_size = type2size[src];
-+ oop src_mtype = impl_java_dyn_AdapterMethodHandle::type(target());
-+ oop dest_mtype = impl_java_dyn_AdapterMethodHandle::type(mh());
-+ int slot_limit = impl_java_dyn_AdapterMethodHandle::vmslots(src_mtype);
-+ int src_slot = argslot;
-+ int dest_slot = vminfo;
-+ bool rotate_up = (src_slot > dest_slot); // upward rotation
-+ int src_arg = argnum;
-+ int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot);
-+ verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
-+ if (!(dest_slot >= src_slot + swap_size) &&
-+ !(src_slot >= dest_slot + swap_size)) {
-+ err = "source, destination slots must be distinct";
-+ } else if (ak == _adapt_swap_args && !(src_slot > dest_slot)) {
-+ err = "source of swap must be deeper in stack";
-+ } else if (ak == _adapt_swap_args) {
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, dest_arg),
-+ java_dyn_MethodType::ptype(dest_mtype, src_arg),
-+ dest_arg);
-+ } else if (ak == _adapt_rot_args) {
-+ if (rotate_up) {
-+ assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
-+ // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
-+ // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
-+ for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
-+ java_dyn_MethodType::ptype(dest_mtype, i-1),
-+ i);
-+ }
-+ } else { // rotate down
-+ assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
-+ // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
-+ // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
-+ for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
-+ java_dyn_MethodType::ptype(dest_mtype, i+1),
-+ i);
-+ }
-+ }
-+ }
-+ if (err == NULL)
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, src_arg),
-+ java_dyn_MethodType::ptype(dest_mtype, dest_arg),
-+ src_arg);
-+ }
-+ break;
-+ case _adapt_collect_args:
-+ case _adapt_spread_args:
-+ {
-+ BasicType coll_type = (ak == _adapt_collect_args) ? dest : src;
-+ BasicType elem_type = (ak == _adapt_collect_args) ? src : dest;
-+ if (coll_type != T_OBJECT || elem_type != T_OBJECT) {
-+ err = "adapter requires src/dest subfields"; break;
-+ // later:
-+ // - consider making coll be a primitive array
-+ // - consider making coll be a heterogeneous collection
-+ }
-+ }
-+ break;
-+ default:
-+ if (src != 0 || dest != 0) {
-+ err = "adapter has spurious src/dest conversion subfields"; break;
-+ }
-+ break;
-+ }
-+ }
-+
-+ if (err == NULL) {
-+ // Check the stack_move subfield.
-+ // It must always report the net change in stack size, positive or negative.
-+ int slots_pushed = stack_move / stack_move_unit();
-+ switch (ak) {
-+ case _adapt_prim_to_prim:
-+ case _adapt_ref_to_prim:
-+ case _adapt_prim_to_ref:
-+ if (slots_pushed != type2size[dest] - type2size[src]) {
-+ err = "wrong stack motion for primitive conversion";
-+ }
-+ break;
-+ case _adapt_dup_args:
-+ if (slots_pushed <= 0) {
-+ err = "adapter requires conversion subfield slots_pushed > 0";
-+ }
-+ break;
-+ case _adapt_drop_args:
-+ if (slots_pushed >= 0) {
-+ err = "adapter requires conversion subfield slots_pushed < 0";
-+ }
-+ break;
-+ case _adapt_collect_args:
-+ if (slots_pushed > 1) {
-+ err = "adapter requires conversion subfield slots_pushed <= 1";
-+ }
-+ break;
-+ case _adapt_spread_args:
-+ if (slots_pushed < -1) {
-+ err = "adapter requires conversion subfield slots_pushed >= -1";
-+ }
-+ break;
-+ default:
-+ if (stack_move != 0) {
-+ err = "adapter has spurious stack_move conversion subfield";
-+ }
-+ break;
-+ }
-+ if (err == NULL && stack_move != slots_pushed * stack_move_unit()) {
-+ err = "stack_move conversion subfield must be multiple of stack_move_unit";
-+ }
-+ }
-+
-+ if (err == NULL) {
-+ // Make sure this adapter does not push too deeply.
-+ int slots_pushed = stack_move / stack_move_unit();
-+ int this_vmslots = java_dyn_MethodHandle::vmslots(mh());
-+ int prev_vmslots = java_dyn_MethodHandle::vmslots(target());
-+ if (slots_pushed != (this_vmslots - prev_vmslots)) {
-+ err = "stack_move inconsistent with previous and current MethodType vmslots";
-+ } else if (slots_pushed > 0) {
-+ // verify stack_move against MethodHandlePushLimit
-+ int prev_pushes = decode_MethodHandle_stack_pushes(target());
-+ // do not blow the stack; use a Java-based adapter if this limit is exceeded
-+ if (slots_pushed + prev_pushes > MethodHandlePushLimit) {
-+ err = "adapter pushes too many parameters";
++ break;
++ case _adapter_collect_args:
++ case _adapter_spread_args:
++ {
++ BasicType coll_type = (ek == _adapter_collect_args) ? dest : src;
++ BasicType elem_type = (ek == _adapter_collect_args) ? src : dest;
++ if (coll_type != T_OBJECT || elem_type != T_OBJECT) {
++ err = "adapter requires src/dest subfields"; break;
++ // later:
++ // - consider making coll be a primitive array
++ // - consider making coll be a heterogeneous collection
+ }
+ }
-+
-+ // While we're at it, check that the stack motion decoder works:
-+ DEBUG_ONLY(int prev_pushes = decode_MethodHandle_stack_pushes(target()));
-+ DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-+ assert(this_pushes == slots_pushed + prev_pushes, "AMH stack motion must be correct");
-+ }
-+
-+ if (err == NULL && vminfo != 0) {
-+ switch (ak) {
-+ case _adapt_swap_args:
-+ case _adapt_rot_args:
-+ break; // OK
-+ default:
-+ err = "vminfo subfield is reserved to the JVM";
++ break;
++ default:
++ if (src != 0 || dest != 0) {
++ err = "adapter has spurious src/dest conversion subfields"; break;
+ }
-+ }
-+
-+ if (err != NULL) { throw_InternalError(err, CHECK); }
-+ }
-+
-+ // Here are the source and destination types, if we need to look at them.
-+ Handle src_mtype, dst_mtype;
++ break;
++ }
++ }
++
++ if (err == NULL) {
++ // Check the stack_move subfield.
++ // It must always report the net change in stack size, positive or negative.
++ int slots_pushed = stack_move / stack_move_unit();
++ switch (ek) {
++ case _adapter_prim_to_prim:
++ case _adapter_ref_to_prim:
++ case _adapter_prim_to_ref:
++ if (slots_pushed != type2size[dest] - type2size[src]) {
++ err = "wrong stack motion for primitive conversion";
++ }
++ break;
++ case _adapter_dup_args:
++ if (slots_pushed <= 0) {
++ err = "adapter requires conversion subfield slots_pushed > 0";
++ }
++ break;
++ case _adapter_drop_args:
++ if (slots_pushed >= 0) {
++ err = "adapter requires conversion subfield slots_pushed < 0";
++ }
++ break;
++ case _adapter_collect_args:
++ if (slots_pushed > 1) {
++ err = "adapter requires conversion subfield slots_pushed <= 1";
++ }
++ break;
++ case _adapter_spread_args:
++ if (slots_pushed < -1) {
++ err = "adapter requires conversion subfield slots_pushed >= -1";
++ }
++ break;
++ default:
++ if (stack_move != 0) {
++ err = "adapter has spurious stack_move conversion subfield";
++ }
++ break;
++ }
++ if (err == NULL && stack_move != slots_pushed * stack_move_unit()) {
++ err = "stack_move conversion subfield must be multiple of stack_move_unit";
++ }
++ }
++
++ if (err == NULL) {
++ // Make sure this adapter does not push too deeply.
++ int slots_pushed = stack_move / stack_move_unit();
++ int this_vmslots = java_dyn_MethodHandle::vmslots(mh());
++ int prev_vmslots = java_dyn_MethodHandle::vmslots(target());
++ if (slots_pushed != (this_vmslots - prev_vmslots)) {
++ err = "stack_move inconsistent with previous and current MethodType vmslots";
++ } else if (slots_pushed > 0) {
++ // verify stack_move against MethodHandlePushLimit
++ int prev_pushes = decode_MethodHandle_stack_pushes(target());
++ // do not blow the stack; use a Java-based adapter if this limit is exceeded
++ if (slots_pushed + prev_pushes > MethodHandlePushLimit) {
++ err = "adapter pushes too many parameters";
++ }
++ }
++
++ // While we're at it, check that the stack motion decoder works:
++ DEBUG_ONLY(int prev_pushes = decode_MethodHandle_stack_pushes(target()));
++ DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
++ assert(this_pushes == slots_pushed + prev_pushes, "AMH stack motion must be correct");
++ }
++
++ if (err == NULL && vminfo != 0) {
++ switch (ek) {
++ case _adapter_swap_args:
++ case _adapter_rot_args:
++ break; // OK
++ default:
++ err = "vminfo subfield is reserved to the JVM";
++ }
++ }
++
++ // Do additional ad hoc checks.
++ if (err == NULL) {
++ switch (ek) {
++ case _adapter_retype_only:
++ err = check_method_type_passthrough(src_mtype(), dst_mtype());
++ break;
++
++ case _adapter_check_cast:
++ {
++ // The actual value being checked must be a reference:
++ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype(), argnum),
++ object_java_mirror(), argnum);
++ if (err != NULL) break;
++
++ // The output of the cast must fit with the destination argument:
++ Handle cast_class = argument;
++ err = check_method_type_conversion(src_mtype(),
++ argnum, cast_class(),
++ dst_mtype());
++ }
++ break;
++
++ // %%% TO DO: continue in remaining cases to verify src/dst_mtype if VerifyMethodHandles
++ }
++ }
++
++ if (err != NULL) {
++ throw_InternalError_for_bad_conversion(conversion, err, THREAD);
++ return;
++ }
++
++}
++
++void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
++ oop argument = sun_dyn_AdapterMethodHandle::argument(mh());
++ int argslot = sun_dyn_AdapterMethodHandle::vmargslot(mh());
++ jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh());
++ jint conv_op = adapter_conversion_op(conversion);
++
++ // adjust the adapter code to the internal EntryKind enumeration:
++ EntryKind ek_orig = adapter_entry_kind(conv_op);
++ EntryKind ek_opt = ek_orig; // may be optimized
++
++ // Finalize the vmtarget field (Java initialized it to null).
++ if (!java_dyn_MethodHandle::is_instance(target())) {
++ throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD);
++ return;
++ }
++ sun_dyn_AdapterMethodHandle::set_vmtarget(mh(), target());
++
+ if (VerifyMethodHandles) {
-+ src_mtype = Handle(THREAD, java_dyn_MethodHandle::type(mh()));
-+ dst_mtype = Handle(THREAD, java_dyn_MethodHandle::type(target()));
-+ }
++ verify_AdapterMethodHandle(mh, argnum, CHECK);
++ }
++
++ int stack_move = adapter_conversion_stack_move(conversion);
++ BasicType src = adapter_conversion_src_type(conversion);
++ BasicType dest = adapter_conversion_dest_type(conversion);
++ int vminfo = adapter_conversion_vminfo(conversion); // should be zero
++
++ const char* err = NULL;
+
+ // Now it's time to finish the case analysis and pick a MethodHandleEntry.
-+ switch (ak) {
-+ case _adapt_retype_only:
-+ if (VerifyMethodHandles) {
-+ verify_method_type_passthrough(src_mtype(), dst_mtype(), CHECK);
-+ }
++ switch (ek_orig) {
++ case _adapter_retype_only:
++ case _adapter_check_cast:
++ case _adapter_dup_args:
++ case _adapter_drop_args:
++ // these work fine via general case code
+ break;
+
-+ case _adapt_check_cast:
-+ if (VerifyMethodHandles) {
-+ // The actual value being checked must be a reference:
-+ verify_argument_type_change(java_dyn_MethodType::ptype(src_mtype(), argnum),
-+ object_java_mirror(), argnum, CHECK);
-+ // The output of the cast must fit with the destination argument:
-+ oop cast_class = argument;
-+ verify_method_type_conversion(src_mtype(),
-+ argnum, cast_class,
-+ dst_mtype(), CHECK);
-+ }
-+ break;
-+
-+ // %%% TO DO: continue in remaining cases to verify src/dst_mtype if VerifyMethodHandles
-+
-+ case _adapt_prim_to_prim:
++ case _adapter_prim_to_prim:
+ {
+ // Non-subword cases are {int,float,long,double} -> {int,float,long,double}.
+ // And, the {float,double} -> {int,long} cases must be handled by Java.
@@ -5879,24 +5944,24 @@ new file mode 100644
+ case 1 *4+ 1:
+ assert(src == T_INT || is_subword_type(src), "source is not float");
+ // Subword-related cases are int -> {boolean,byte,char,short}.
-+ ek = _adapter_opt_i2i;
++ ek_opt = _adapter_opt_i2i;
+ vminfo = adapter_subword_vminfo(dest);
+ break;
+ case 2 *4+ 1:
+ if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) {
-+ ek = _adapter_opt_l2i;
++ ek_opt = _adapter_opt_l2i;
+ vminfo = adapter_subword_vminfo(dest);
+ } else if (src == T_DOUBLE && dest == T_FLOAT) {
-+ ek = _adapter_opt_d2f;
++ ek_opt = _adapter_opt_d2f;
+ } else {
+ assert(false, "");
+ }
+ break;
+ case 1 *4+ 2:
+ if (src == T_INT && dest == T_LONG) {
-+ ek = _adapter_opt_i2l;
++ ek_opt = _adapter_opt_i2l;
+ } else if (src == T_FLOAT && dest == T_DOUBLE) {
-+ ek = _adapter_opt_f2d;
++ ek_opt = _adapter_opt_f2d;
+ } else {
+ assert(false, "");
+ }
@@ -5908,15 +5973,15 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapt_ref_to_prim:
++ case _adapter_ref_to_prim:
+ {
+ switch (type2size[dest]) {
+ case 1:
-+ ek = _adapter_opt_a2i;
++ ek_opt = _adapter_opt_unboxi;
+ vminfo = adapter_subword_vminfo(dest);
+ break;
+ case 2:
-+ ek = _adapter_opt_a2l;
++ ek_opt = _adapter_opt_unboxl;
+ break;
+ default:
+ assert(false, "");
@@ -5925,26 +5990,26 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapt_prim_to_ref:
++ case _adapter_prim_to_ref:
+ goto throw_not_impl; // allocates, hence could block
+
-+ case _adapt_swap_args:
-+ case _adapt_rot_args:
++ case _adapter_swap_args:
++ case _adapter_rot_args:
+ {
+ int swap_slots = type2size[src];
-+ oop mtype = impl_java_dyn_AdapterMethodHandle::type(mh());
-+ int slot_limit = impl_java_dyn_AdapterMethodHandle::vmslots(mtype);
++ oop mtype = sun_dyn_AdapterMethodHandle::type(mh());
++ int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mtype);
+ int src_slot = argslot;
+ int dest_slot = vminfo;
-+ int rotate = (ak == _adapt_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
++ int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
+ switch (swap_slots) {
+ case 1:
-+ ek = (!rotate ? _adapter_opt_swap_1 :
-+ rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
++ ek_opt = (!rotate ? _adapter_opt_swap_1 :
++ rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
+ break;
+ case 2:
-+ ek = (!rotate ? _adapter_opt_swap_2 :
-+ rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
++ ek_opt = (!rotate ? _adapter_opt_swap_2 :
++ rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
+ break;
+ default:
+ assert(false, "");
@@ -5953,15 +6018,10 @@ new file mode 100644
+ }
+ break;
+
-+ case _adapt_dup_args:
-+ case _adapt_drop_args:
-+ // these work fine via general case code
-+ break;
-+
-+ case _adapt_collect_args:
++ case _adapter_collect_args:
+ goto throw_not_impl; // allocates, hence could block
+
-+ case _adapt_spread_args:
++ case _adapter_spread_args:
+ {
+ // vminfo will be the required length of the array
+ int slots_pushed = stack_move / stack_move_unit();
@@ -5969,62 +6029,56 @@ new file mode 100644
+ assert(array_size >= 0, "");
+ vminfo = array_size;
+ switch (array_size) {
-+ case 0: ek = _adapt_opt_spread_0; break;
-+ case 1: ek = _adapt_opt_spread_1; break;
-+ default: ek = _adapt_opt_spread_more; break;
++ case 0: ek_opt = _adapter_opt_spread_0; break;
++ case 1: ek_opt = _adapter_opt_spread_1; break;
++ default: ek_opt = _adapter_opt_spread_more; break;
+ }
-+ if ((vminfo & _CONV_VMINFO_MASK) != vminfo)
++ if ((vminfo & CONV_VMINFO_MASK) != vminfo)
+ goto throw_not_impl; // overflow
+ }
+ break;
+
-+ case _adapt_flyby:
-+ case _adapt_ricochet:
++ case _adapter_flyby:
++ case _adapter_ricochet:
+ goto throw_not_impl; // runs Java code, hence could block
++
++ default:
++ // should have failed much earlier; must be a missing case here
++ assert(false, "incomplete switch");
++ // and fall through:
+
+ throw_not_impl:
+ // FIXME: these adapters are NYI
-+ throw_InternalError(adapter_entry_name(ak), CHECK);
++ err = "adapter not yet implemented in the JVM";
++ break;
++ }
++
++ if (err != NULL) {
++ throw_InternalError_for_bad_conversion(conversion, err, THREAD);
+ return;
+ }
+
+ // Rebuild the conversion value; maybe parts of it were changed.
-+ jint new_conversion = (((int)ak << _CONV_OP_SHIFT) |
-+ (src << _CONV_SRC_TYPE_SHIFT) |
-+ (dest << _CONV_DEST_TYPE_SHIFT) |
-+ (stack_move << _CONV_STACK_MOVE_SHIFT) |
-+ (vminfo << _CONV_VMINFO_SHIFT) );
-+
-+ // Take it apart again, just to make sure:
-+ assert(adapter_conversion_op(new_conversion) == ak, "");
-+ assert(adapter_conversion_vminfo(new_conversion) == vminfo, "");
-+ assert(adapter_conversion_src_type(new_conversion) == src, "");
-+ assert(adapter_conversion_dest_type(new_conversion) == dest, "");
-+ assert(adapter_conversion_stack_move(new_conversion) == stack_move, "");
++ jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo);
+
+ // Finalize the conversion field. (Note that it is final to Java code.)
-+ impl_java_dyn_AdapterMethodHandle::set_conversion(mh(), new_conversion);
++ sun_dyn_AdapterMethodHandle::set_conversion(mh(), new_conversion);
+
+ // Done!
-+ java_dyn_MethodHandle::set_vmentry(mh(), entry(ek));
++ java_dyn_MethodHandle::set_vmentry(mh(), entry(ek_opt));
+
+ // There should be enough memory barriers on exit from native methods
+ // to ensure that the MH is fully initialized to all threads before
+ // Java code can publish it in global data structures.
+}
+
-+// %%% move this into reflection.cpp:
-+static bool is_same_package_member(klassOop current_class, klassOop field_class, TRAPS) {
-+ instanceKlass* k1 = instanceKlass::cast(current_class);
-+ instanceKlass* k2 = instanceKlass::cast(field_class);
-+ if (!k1->is_same_class_package(k2->as_klassOop())) return false;
-+
-+}
-+
+//
-+// Here are the native methods on impl.java.dyn.MethodHandleImpl.
++// Here are the native methods on sun.dyn.MethodHandleImpl.
+// They are the private interface between this JVM and the HotSpot-specific
+// Java code that implements JSR 292 method handles.
++//
++// Note: We use a JVM_ENTRY macro to define each of these, for this is the way
++// that intrinsic (non-JNI) native methods are defined in HotSpot.
+//
+
+// direct method handles for invokestatic or invokespecial
@@ -6034,17 +6088,17 @@ new file mode 100644
+ ResourceMark rm; // for error messages
+
+ // This is the guy we are initializing:
-+ if (mh_jh == NULL) { throw_InternalError(CHECK); }
++ if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
+ Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
+
+ // Early returns out of this method leave the DMH in an unfinished state.
+ assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
+
+ // which method are we really talking about?
-+ if (target_jh == NULL) { throw_InternalError(CHECK); }
++ if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
+ oop target_oop = JNIHandles::resolve_non_null(target_jh);
-+ if (impl_java_dyn_MemberName::is_instance(target_oop) &&
-+ impl_java_dyn_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) {
++ if (sun_dyn_MemberName::is_instance(target_oop) &&
++ sun_dyn_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) {
+ Handle mname(THREAD, target_oop);
+ MethodHandles::resolve_MemberName(mname, CHECK);
+ target_oop = mname(); // in case of GC
@@ -6054,7 +6108,7 @@ new file mode 100644
+ methodHandle m(THREAD,
+ MethodHandles::decode_method(target_oop,
+ receiver_limit, decode_flags));
-+ if (m.is_null()) { throw_InternalError("no such method", CHECK); }
++ if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
+
+ // The trusted Java code that calls this method should already have performed
+ // access checks on behalf of the given caller. But, we can verify this.
@@ -6067,14 +6121,14 @@ new file mode 100644
+ klassOop reference_klass = m->method_holder(); // OK approximation
+ if (receiver_limit != NULL && receiver_limit != reference_klass) {
+ if (!Klass::cast(receiver_limit)->is_subtype_of(reference_klass))
-+ throw_InternalError("receiver limit out of bounds", CHECK); // Java code bug
++ THROW_MSG(vmSymbols::java_lang_InternalError(), "receiver limit out of bounds"); // Java code bug
+ reference_klass = receiver_limit;
+ }
+ // Emulate LinkResolver::check_klass_accessability.
+ if (!Reflection::verify_class_access(caller->as_klassOop(),
+ reference_klass,
+ true)) {
-+ throw_InternalError(Klass::cast(m->method_holder())->external_name(), CHECK);
++ THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(m->method_holder())->external_name());
+ }
+ // If there were a bytecode, the next step would be to lookup the method
+ // in the reference class, then then check the method's access bits.
@@ -6088,7 +6142,7 @@ new file mode 100644
+ bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(),
+ reference_klass, THREAD);
+ if (!same_pm) {
-+ throw_InternalError(m->name_and_sig_as_C_string(), CHECK);
++ THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
+ }
+ }
+ }
@@ -6103,22 +6157,25 @@ new file mode 100644
+ ResourceMark rm; // for error messages
+
+ // This is the guy we are initializing:
-+ if (mh_jh == NULL) { throw_InternalError(CHECK); }
++ if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
+ Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
+
+ // Early returns out of this method leave the BMH in an unfinished state.
+ assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
+
-+ if (target_jh == NULL) { throw_InternalError(CHECK); }
++ if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
+ Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
+
+ if (!java_dyn_MethodHandle::is_instance(target())) {
+ // Target object is a reflective method. (%%% Do we need this alternate path?)
+ Untested("init_BMH of non-MH");
-+ if (argnum != 0) { throw_InternalError(CHECK); }
-+ int decode_flags = 0; klassOop receiver_limit = NULL;
-+ methodOop m = MethodHandles::decode_method(target(),
-+ receiver_limit, decode_flags);
++ if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
++ int decode_flags = 0; klassOop receiver_limit_oop = NULL;
++ methodHandle m(THREAD,
++ MethodHandles::decode_method(target(),
++ receiver_limit_oop,
++ decode_flags));
++ KlassHandle receiver_limit(THREAD, receiver_limit_oop);
+ MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
+ receiver_limit,
+ decode_flags,
@@ -6135,8 +6192,9 @@ new file mode 100644
+JVM_ENTRY(void, MHI_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
+ jobject target_jh, int argnum)) {
+ // This is the guy we are initializing:
-+ if (mh_jh == NULL || target_jh == NULL)
-+ { throw_InternalError(CHECK); }
++ if (mh_jh == NULL || target_jh == NULL) {
++ THROW(vmSymbols::java_lang_InternalError());
++ }
+ Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
+ Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
+
@@ -6169,9 +6227,10 @@ new file mode 100644
+
+// debugging and reflection
+JVM_ENTRY(jobject, MHI_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) {
-+ oop mh = JNIHandles::resolve(mh_jh);
-+ if (!java_dyn_MethodHandle::is_instance(mh))
-+ { throw_IllegalArgumentException(THREAD); return NULL; }
++ Handle mh(THREAD, JNIHandles::resolve(mh_jh));
++ if (!java_dyn_MethodHandle::is_instance(mh())) {
++ THROW_NULL(vmSymbols::java_lang_IllegalArgumentException());
++ }
+ oop target = MethodHandles::encode_target(mh, format, CHECK_NULL);
+ return JNIHandles::make_local(THREAD, target);
+}
@@ -6199,34 +6258,35 @@ new file mode 100644
+ template(MethodHandles,ETF_DIRECT_HANDLE) \
+ template(MethodHandles,ETF_METHOD_NAME) \
+ template(MethodHandles,ETF_REFLECT_METHOD) \
-+ template(impl_java_dyn_MemberName,MN_IS_METHOD) \
-+ template(impl_java_dyn_MemberName,MN_IS_CONSTRUCTOR) \
-+ template(impl_java_dyn_MemberName,MN_IS_FIELD) \
-+ template(impl_java_dyn_MemberName,MN_IS_TYPE) \
-+ template(impl_java_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \
-+ template(impl_java_dyn_MemberName,MN_SEARCH_INTERFACES) \
-+ template(impl_java_dyn_MemberName,VM_INDEX_UNINITIALIZED) \
-+ template(impl_java_dyn_AdapterMethodHandle,RETYPE_ONLY) \
-+ template(impl_java_dyn_AdapterMethodHandle,CHECK_CAST) \
-+ template(impl_java_dyn_AdapterMethodHandle,PRIM_TO_PRIM) \
-+ template(impl_java_dyn_AdapterMethodHandle,REF_TO_PRIM) \
-+ template(impl_java_dyn_AdapterMethodHandle,PRIM_TO_REF) \
-+ template(impl_java_dyn_AdapterMethodHandle,SWAP_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,ROT_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,DUP_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,DROP_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,COLLECT_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,SPREAD_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,FLYBY) \
-+ template(impl_java_dyn_AdapterMethodHandle,RICOCHET) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_OP_MASK) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_VMINFO_MASK) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_VMINFO_SHIFT) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_OP_SHIFT) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \
++ template(sun_dyn_MemberName,MN_IS_METHOD) \
++ template(sun_dyn_MemberName,MN_IS_CONSTRUCTOR) \
++ template(sun_dyn_MemberName,MN_IS_FIELD) \
++ template(sun_dyn_MemberName,MN_IS_TYPE) \
++ template(sun_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \
++ template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \
++ template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \
++ template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \
++ template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \
++ template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
++ template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \
++ template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_REF) \
++ template(sun_dyn_AdapterMethodHandle,OP_SWAP_ARGS) \
++ template(sun_dyn_AdapterMethodHandle,OP_ROT_ARGS) \
++ template(sun_dyn_AdapterMethodHandle,OP_DUP_ARGS) \
++ template(sun_dyn_AdapterMethodHandle,OP_DROP_ARGS) \
++ template(sun_dyn_AdapterMethodHandle,OP_COLLECT_ARGS) \
++ template(sun_dyn_AdapterMethodHandle,OP_SPREAD_ARGS) \
++ template(sun_dyn_AdapterMethodHandle,OP_FLYBY) \
++ template(sun_dyn_AdapterMethodHandle,OP_RICOCHET) \
++ template(sun_dyn_AdapterMethodHandle,CONV_OP_LIMIT) \
++ template(sun_dyn_AdapterMethodHandle,CONV_OP_MASK) \
++ template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_MASK) \
++ template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_SHIFT) \
++ template(sun_dyn_AdapterMethodHandle,CONV_OP_SHIFT) \
++ template(sun_dyn_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \
++ template(sun_dyn_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \
++ template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \
++ template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \
+ /*end*/
+
+#define ONE_PLUS(scope,value) 1+
@@ -6239,7 +6299,7 @@ new file mode 100644
+#undef ONE_PLUS
+#undef VALUE_COMMA
+#undef STRING_NULL
-+#undef EACH_NAMED_CON
++#undef EACH_NAMED_CON
+#endif
+
+JVM_ENTRY(jint, MHI_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
@@ -6263,7 +6323,7 @@ new file mode 100644
+
+// void init(MemberName self, AccessibleObject ref)
+JVM_ENTRY(void, MHI_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
-+ if (mname_jh == NULL || target_jh == NULL) { throw_InternalError(CHECK); }
++ if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
+ Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
+ oop target_oop = JNIHandles::resolve_non_null(target_jh);
+ MethodHandles::init_MemberName(mname(), target_oop);
@@ -6272,7 +6332,7 @@ new file mode 100644
+
+// void expand(MemberName self)
+JVM_ENTRY(void, MHI_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
-+ if (mname_jh == NULL) { throw_InternalError(CHECK); }
++ if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
+ Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
+ MethodHandles::expand_MemberName(mname, 0, CHECK);
+}
@@ -6280,7 +6340,7 @@ new file mode 100644
+
+// void resolve(MemberName self, Class<?> caller)
+JVM_ENTRY(void, MHI_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
-+ if (mname_jh == NULL) { throw_InternalError(CHECK); }
++ if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
+ Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
+ // %%% take caller into account!
+ MethodHandles::resolve_MemberName(mname, CHECK);
@@ -6334,7 +6394,7 @@ new file mode 100644
+
+#define LANG "Ljava/lang/"
+#define JDYN "Ljava/dyn/"
-+#define IDYN "Limpl/java/dyn/"
++#define IDYN "Lsun/dyn/"
+
+#define OBJ LANG"Object;"
+#define CLS LANG"Class;"
@@ -6350,7 +6410,7 @@ new file mode 100644
+#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 impl.java.dyn.MethodHandleNatives.
++// These are the native methods on sun.dyn.MethodHandleNatives.
+static JNINativeMethod methods[] = {
+ // void init(MemberName self, AccessibleObject ref)
+ {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHI_init_AMH)},
@@ -6398,7 +6458,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/vm/prims/methodHandles.hpp
-@@ -0,0 +1,417 @@
+@@ -0,0 +1,435 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -6432,31 +6492,6 @@ new file mode 100644
+ // in java.dyn and java.dyn.hotspot.
+ // See also javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}.
+ public:
-+ enum AdapterKind {
-+ // these constants must align with a set of values in impl/java/dyn/AMH.java:
-+ _adapt_retype_only = 0x0, // no argument changes; straight retype
-+ _adapt_check_cast = 0x1, // ref-to-ref conversion; requires a Class argument
-+ _adapt_prim_to_prim = 0x2, // converts from one primitive to another
-+ _adapt_ref_to_prim = 0x3, // unboxes a wrapper to produce a primitive
-+ _adapt_prim_to_ref = 0x4, // boxes a primitive into a wrapper (NYI)
-+ _adapt_swap_args = 0x5, // permutes arguments (NYI)
-+ _adapt_rot_args = 0x6, // permutes arguments (NYI)
-+ _adapt_dup_args = 0x7, // duplicates one or more arguments (at TOS)
-+ _adapt_drop_args = 0x8, // remove one or more argument slots
-+ _adapt_collect_args = 0x9, // combine one or more arguments into a varargs (NYI)
-+ _adapt_spread_args = 0xA, // expand in place a varargs array (of known size)
-+ _adapt_flyby = 0xB, // operate first on reified argument list (NYI)
-+ _adapt_ricochet = 0xC, // run an adapter chain on the return value (NYI)
-+ _AK_LIMIT
-+ };
-+ enum { // format of AMH.conversion field
-+ _CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
-+ _CONV_VMINFO_SHIFT = 0, // position of bits in CONV_VMINFO_MASK
-+ _CONV_OP_SHIFT = 8, // position of bits in CONV_OP_MASK
-+ _CONV_DEST_TYPE_SHIFT = 12, // byte 3 has the target BasicType (if needed)
-+ _CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed)
-+ _CONV_STACK_MOVE_SHIFT = 20 // high 12 bits give signed SP change
-+ };
+ enum EntryKind {
+ _check_mtype, // how a caller calls a MH
+ _wrong_method_type, // what happens when there is a type mismatch
@@ -6471,8 +6506,21 @@ new file mode 100644
+ _bound_int_direct_mh,
+ _bound_long_direct_mh,
+
-+ _adapter_mh_first, // adapter sequence goes here...
-+ _adapter_mh_last = _adapter_mh_first + (_AK_LIMIT - 1),
++ _adapter_mh_first, // adapter sequence goes here...
++ _adapter_retype_only = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY,
++ _adapter_check_cast = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_CHECK_CAST,
++ _adapter_prim_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM,
++ _adapter_ref_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM,
++ _adapter_prim_to_ref = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF,
++ _adapter_swap_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS,
++ _adapter_rot_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_ROT_ARGS,
++ _adapter_dup_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_DUP_ARGS,
++ _adapter_drop_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_DROP_ARGS,
++ _adapter_collect_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS,
++ _adapter_spread_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS,
++ _adapter_flyby = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_FLYBY,
++ _adapter_ricochet = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RICOCHET,
++ _adapter_mh_last = _adapter_mh_first + sun_dyn_AdapterMethodHandle::CONV_OP_LIMIT - 1,
+
+ // Optimized adapter types
+
@@ -6494,13 +6542,13 @@ new file mode 100644
+ // conversion between floating point and integer type is handled by Java
+
+ // reference to primitive:
-+ _adapter_opt_a2i,
-+ _adapter_opt_a2l,
++ _adapter_opt_unboxi,
++ _adapter_opt_unboxl,
+
+ // spreading (array length cases 0, 1, >=2)
-+ _adapt_opt_spread_0,
-+ _adapt_opt_spread_1,
-+ _adapt_opt_spread_more,
++ _adapter_opt_spread_0,
++ _adapter_opt_spread_1,
++ _adapter_opt_spread_more,
+
+ _EK_LIMIT,
+ _EK_FIRST = 0
@@ -6511,11 +6559,23 @@ new file mode 100644
+ static void set_enabled(bool z);
+
+ private:
++ enum { // import sun_dyn_AdapterMethodHandle::CONV_OP_*
++ CONV_OP_LIMIT = sun_dyn_AdapterMethodHandle::CONV_OP_LIMIT,
++ CONV_OP_MASK = sun_dyn_AdapterMethodHandle::CONV_OP_MASK,
++ CONV_VMINFO_MASK = sun_dyn_AdapterMethodHandle::CONV_VMINFO_MASK,
++ CONV_VMINFO_SHIFT = sun_dyn_AdapterMethodHandle::CONV_VMINFO_SHIFT,
++ CONV_OP_SHIFT = sun_dyn_AdapterMethodHandle::CONV_OP_SHIFT,
++ CONV_DEST_TYPE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_DEST_TYPE_SHIFT,
++ CONV_SRC_TYPE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_SRC_TYPE_SHIFT,
++ CONV_STACK_MOVE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_STACK_MOVE_SHIFT,
++ CONV_STACK_MOVE_MASK = sun_dyn_AdapterMethodHandle::CONV_STACK_MOVE_MASK
++ };
++
+ static bool _enabled;
+ static MethodHandleEntry* _entries[_EK_LIMIT];
+ static const char* _entry_names[_EK_LIMIT+1];
+ static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; }
-+ static bool ak_valid(AdapterKind ak) { return (uint)ak < (uint)_AK_LIMIT; }
++ static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; }
+
+ public:
+ static bool have_entry(EntryKind ek) { return ek_valid(ek) && _entries[ek] != NULL; }
@@ -6523,8 +6583,8 @@ new file mode 100644
+ return _entries[ek]; }
+ static const char* entry_name(EntryKind ek) { assert(ek_valid(ek), "oob");
+ return _entry_names[ek]; }
-+ static const char* adapter_entry_name(AdapterKind ak) { assert(ak_valid(ak), "oob");
-+ return entry_name(EntryKind(_adapter_mh_first + (int)ak)); }
++ static EntryKind adapter_entry_kind(int op) { assert(conv_op_valid(op), "oob");
++ return EntryKind(_adapter_mh_first + op); }
+
+ static void init_entry(EntryKind ek, MethodHandleEntry* me) {
+ assert(ek_valid(ek), "oob");
@@ -6532,29 +6592,36 @@ new file mode 100644
+ _entries[ek] = me;
+ }
+
-+ static jint adapter_conversion(AdapterKind ak, BasicType src, BasicType dest,
++ static jint adapter_conversion(int conv_op, BasicType src, BasicType dest,
+ int stack_move = 0, int vminfo = 0) {
-+ return (((int)ak << _CONV_OP_SHIFT)
-+ | (src << _CONV_SRC_TYPE_SHIFT)
-+ | (dest << _CONV_DEST_TYPE_SHIFT)
-+ | (stack_move << _CONV_STACK_MOVE_SHIFT)
-+ | (vminfo << _CONV_VMINFO_SHIFT)
-+ );
-+ }
-+ static AdapterKind adapter_conversion_op(jint conv) {
-+ return (AdapterKind)((conv >> _CONV_OP_SHIFT) & 0xF);
++ assert(conv_op_valid(conv_op), "oob");
++ jint conv = ((conv_op << CONV_OP_SHIFT)
++ | (src << CONV_SRC_TYPE_SHIFT)
++ | (dest << CONV_DEST_TYPE_SHIFT)
++ | (stack_move << CONV_STACK_MOVE_SHIFT)
++ | (vminfo << CONV_VMINFO_SHIFT)
++ );
++ assert(adapter_conversion_op(conv) == conv_op, "decode conv_op");
++ assert(adapter_conversion_src_type(conv) == src, "decode src");
++ assert(adapter_conversion_dest_type(conv) == dest, "decode dest");
++ assert(adapter_conversion_stack_move(conv) == stack_move, "decode stack_move");
++ assert(adapter_conversion_vminfo(conv) == vminfo, "decode vminfo");
++ return conv;
++ }
++ static int adapter_conversion_op(jint conv) {
++ return ((conv >> CONV_OP_SHIFT) & 0xF);
+ }
+ static BasicType adapter_conversion_src_type(jint conv) {
-+ return (BasicType)((conv >> _CONV_SRC_TYPE_SHIFT) & 0xF);
++ return (BasicType)((conv >> CONV_SRC_TYPE_SHIFT) & 0xF);
+ }
+ static BasicType adapter_conversion_dest_type(jint conv) {
-+ return (BasicType)((conv >> _CONV_DEST_TYPE_SHIFT) & 0xF);
++ return (BasicType)((conv >> CONV_DEST_TYPE_SHIFT) & 0xF);
+ }
+ static int adapter_conversion_stack_move(jint conv) {
-+ return (conv >> _CONV_STACK_MOVE_SHIFT);
++ return (conv >> CONV_STACK_MOVE_SHIFT);
+ }
+ static int adapter_conversion_vminfo(jint conv) {
-+ return (conv >> _CONV_VMINFO_SHIFT) & _CONV_VMINFO_MASK;
++ return (conv >> CONV_VMINFO_SHIFT) & CONV_VMINFO_MASK;
+ }
+
+ // Offset in words that the interpreter stack pointer moves when an argument is pushed.
@@ -6563,18 +6630,18 @@ new file mode 100644
+ return frame::interpreter_frame_expression_stack_direction() * Interpreter::stackElementWords();
+ }
+
-+ enum { _CONV_VMINFO_SIGN_FLAG = 0x80 };
++ enum { CONV_VMINFO_SIGN_FLAG = 0x80 };
+ static int adapter_subword_vminfo(BasicType dest) {
+ if (dest == T_BOOLEAN) return (BitsPerInt - 1);
+ if (dest == T_CHAR) return (BitsPerInt - 16);
-+ if (dest == T_BYTE) return (BitsPerInt - 8) | _CONV_VMINFO_SIGN_FLAG;
-+ if (dest == T_SHORT) return (BitsPerInt - 16) | _CONV_VMINFO_SIGN_FLAG;
++ if (dest == T_BYTE) return (BitsPerInt - 8) | CONV_VMINFO_SIGN_FLAG;
++ if (dest == T_SHORT) return (BitsPerInt - 16) | CONV_VMINFO_SIGN_FLAG;
+ return 0; // case T_INT
+ }
+ // Here is the transformation the i2i adapter must perform:
+ static int truncate_subword_from_vminfo(jint value, int vminfo) {
+ jint tem = value << vminfo;
-+ if ((vminfo & _CONV_VMINFO_SIGN_FLAG) != 0) {
++ if ((vminfo & CONV_VMINFO_SIGN_FLAG) != 0) {
+ return (jint)tem >> vminfo;
+ } else {
+ return (juint)tem >> vminfo;
@@ -6631,7 +6698,7 @@ new file mode 100644
+ _dmf_binds_argument = 0x10,
+ _DMF_BOUND_MASK = (_dmf_binds_argument*2 - _dmf_binds_method),
+ _dmf_adapter_lsb = 0x20,
-+ _DMF_ADAPTER_MASK = (_dmf_adapter_lsb << _AK_LIMIT) - _dmf_adapter_lsb
++ _DMF_ADAPTER_MASK = (_dmf_adapter_lsb << CONV_OP_LIMIT) - _dmf_adapter_lsb
+ };
+ static methodOop decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result);
+ enum {
@@ -6645,52 +6712,41 @@ new file mode 100644
+ ETF_METHOD_NAME = 2, // ultimate method as MemberName
+ ETF_REFLECT_METHOD = 3 // ultimate method as java.lang.reflect object (sans refClass)
+ };
-+ static int get_named_constant(int which, oop name_box, TRAPS);
-+ static oop encode_target(oop mh, int format, TRAPS); // report vmtarget (to Java code)
++ static int get_named_constant(int which, Handle name_box, TRAPS);
++ static oop encode_target(Handle mh, int format, TRAPS); // report vmtarget (to Java code)
+ static bool class_cast_needed(klassOop src, klassOop dst);
+
-+ static void verify_vmslots(Handle mh, TRAPS);
-+ static void verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS);
-+ static void verify_method_type_change(oop src_mtype, int src_beg, int src_end,
-+ int insert_argnum, oop insert_type,
-+ int change_argnum, oop change_type,
-+ int delete_argnum,
-+ oop dst_mtype, int dst_beg, int dst_end,
-+ TRAPS);
-+ static void verify_argument_type_change(oop src_type, oop dst_type,
-+ int argnum, TRAPS);
-+ static void verify_method_type_insertion(oop src_mtype,
-+ int insert_argnum, oop insert_type,
-+ oop dst_mtype, TRAPS) {
++ private:
++ // These checkers operate on a pair of whole MethodTypes:
++ static const char* check_method_type_change(oop src_mtype, int src_beg, int src_end,
++ int insert_argnum, oop insert_type,
++ int change_argnum, oop change_type,
++ int delete_argnum,
++ oop dst_mtype, int dst_beg, int dst_end);
++ static const char* check_method_type_insertion(oop src_mtype,
++ int insert_argnum, oop insert_type,
++ oop dst_mtype) {
+ oop no_ref = NULL;
-+ verify_method_type_change(src_mtype, 0, -1,
-+ insert_argnum, insert_type,
-+ -1, no_ref, -1, dst_mtype, 0, -1, THREAD);
-+ }
-+ static void verify_method_type_conversion(oop src_mtype,
-+ int change_argnum, oop change_type,
-+ oop dst_mtype, TRAPS) {
++ return check_method_type_change(src_mtype, 0, -1,
++ insert_argnum, insert_type,
++ -1, no_ref, -1, dst_mtype, 0, -1);
++ }
++ static const char* check_method_type_conversion(oop src_mtype,
++ int change_argnum, oop change_type,
++ oop dst_mtype) {
+ oop no_ref = NULL;
-+ verify_method_type_change(src_mtype, 0, -1, -1, no_ref,
-+ change_argnum, change_type,
-+ -1, dst_mtype, 0, -1, THREAD);
-+ }
-+ static void verify_method_type_passthrough(oop src_mtype, oop dst_mtype, TRAPS) {
++ return check_method_type_change(src_mtype, 0, -1, -1, no_ref,
++ change_argnum, change_type,
++ -1, dst_mtype, 0, -1);
++ }
++ static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype) {
+ oop no_ref = NULL;
-+ verify_method_type_change(src_mtype, 0, -1,
-+ -1, no_ref, -1, no_ref, -1,
-+ dst_mtype, 0, -1, THREAD);
-+ }
-+
-+ static void verify_method_type(methodHandle m, oop mtype,
-+ bool has_bound_oop,
-+ klassOop bound_oop_type,
-+ TRAPS);
-+
-+ static void verify_method_signature(methodHandle m, Handle mtype,
-+ int first_ptype_pos,
-+ KlassHandle insert_ptype, TRAPS);
-+
++ return check_method_type_change(src_mtype, 0, -1,
++ -1, no_ref, -1, no_ref, -1,
++ dst_mtype, 0, -1);
++ }
++
++ // These checkers operate on pairs of argument or return types:
+ static const char* check_argument_type_change(BasicType src_type, klassOop src_klass,
+ BasicType dst_type, klassOop dst_klass,
+ int argnum);
@@ -6713,8 +6769,28 @@ new file mode 100644
+ return check_argument_type_change(src_type, src_klass, dst_type, dst_klass, -1);
+ }
+
-+ static const char* check_method_receiver(methodHandle m, klassOop passed_recv_type);
-+
++ static const char* check_method_receiver(methodOop m, klassOop passed_recv_type);
++
++ // These verifiers can block, and will throw an error if the checking fails:
++ static void verify_vmslots(Handle mh, TRAPS);
++ static void verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS);
++
++ static void verify_method_type(methodHandle m, Handle mtype,
++ bool has_bound_oop,
++ KlassHandle bound_oop_type,
++ TRAPS);
++
++ static void verify_method_signature(methodHandle m, Handle mtype,
++ int first_ptype_pos,
++ KlassHandle insert_ptype, TRAPS);
++
++ static void verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS);
++ static void verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
++ bool direct_to_method, TRAPS);
++ static void verify_BoundMethodHandle_with_receiver(Handle mh, methodHandle m, TRAPS);
++ static void verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS);
++
++ public:
+
+ // Fill in the fields of a DirectMethodHandle mh. (MH.type must be pre-filled.)
+ static void init_DirectMethodHandle(Handle mh, methodHandle method, bool do_dispatch, TRAPS);
@@ -6722,8 +6798,8 @@ new file mode 100644
+ // Fill in the fields of a BoundMethodHandle mh. (MH.type, BMH.argument must be pre-filled.)
+ static void init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS);
+ static void init_BoundMethodHandle_with_receiver(Handle mh,
-+ methodOop original_m_oop,
-+ klassOop receiver_limit_oop,
++ methodHandle original_m,
++ KlassHandle receiver_limit,
+ int decode_flags,
+ TRAPS);
+
@@ -6735,9 +6811,11 @@ new file mode 100644
+#endif
+
+ private:
-+ static methodOop dispatch_decoded_method(methodOop m, klassOop receiver_limit, int decode_flags,
-+ klassOop receiver_klass,
-+ TRAPS);
++ static methodHandle dispatch_decoded_method(methodHandle m,
++ KlassHandle receiver_limit,
++ int decode_flags,
++ KlassHandle receiver_klass,
++ TRAPS);
+
+ static bool same_basic_type_for_arguments(BasicType src, BasicType dst,
+ bool for_return = false);
@@ -6838,7 +6916,7 @@ diff --git a/src/share/vm/prims/nativeLo
if (strstr(jni_name, "Java_sun_misc_Unsafe_registerNatives") != NULL) {
return CAST_FROM_FN_PTR(address, JVM_RegisterUnsafeMethods);
}
-+ if (strstr(jni_name, "Java_impl_java_dyn_MethodHandleNatives_registerNatives") != NULL) {
++ if (strstr(jni_name, "Java_sun_dyn_MethodHandleNatives_registerNatives") != NULL) {
+ return CAST_FROM_FN_PTR(address, JVM_RegisterMethodHandleMethods);
+ }
if (strstr(jni_name, "Java_sun_misc_Perf_registerNatives") != NULL) {
@@ -6968,7 +7046,7 @@ diff --git a/src/share/vm/runtime/shared
diff --git a/src/share/vm/runtime/sharedRuntime.hpp b/src/share/vm/runtime/sharedRuntime.hpp
--- a/src/share/vm/runtime/sharedRuntime.hpp
+++ b/src/share/vm/runtime/sharedRuntime.hpp
-@@ -209,6 +209,27 @@
+@@ -209,10 +209,32 @@
static char* generate_class_cast_message(JavaThread* thr, const char* name);
/**
@@ -6996,7 +7074,12 @@ diff --git a/src/share/vm/runtime/shared
* Fill in the "X cannot be cast to a Y" message for ClassCastException
*
* @param name the name of the class of the object attempted to be cast
-@@ -221,7 +242,8 @@
+ * @param klass the name of the target klass attempt
++ * @param gripe the specific kind of problem being reported
+ * @return the dynamically allocated exception message (must be freed
+ * by the caller using a resource mark)
+ *
+@@ -221,7 +243,8 @@
* The caller (or one of it's callers) must use a ResourceMark
* in order to correctly free the result.
*/
@@ -7064,6 +7147,19 @@ diff --git a/src/share/vm/utilities/acce
+ af._flags = flags;
+ return af;
+}
+diff --git a/src/share/vm/utilities/exceptions.hpp b/src/share/vm/utilities/exceptions.hpp
+--- a/src/share/vm/utilities/exceptions.hpp
++++ b/src/share/vm/utilities/exceptions.hpp
+@@ -237,6 +237,9 @@
+ #define THROW_ARG_0(name, signature, arg) THROW_ARG_(name, signature, arg, 0)
+ #define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0)
+
++#define THROW_NULL(name) THROW_(name, NULL)
++#define THROW_MSG_NULL(name, message) THROW_MSG_(name, message, NULL)
++
+ // The CATCH macro checks that no exception has been thrown by a function; it is used at
+ // call sites about which is statically known that the callee cannot throw an exception
+ // even though it is declared with TRAPS.
diff --git a/src/share/vm/utilities/globalDefinitions.hpp b/src/share/vm/utilities/globalDefinitions.hpp
--- a/src/share/vm/utilities/globalDefinitions.hpp
+++ b/src/share/vm/utilities/globalDefinitions.hpp
--- a/meth.patch Tue Apr 07 01:55:20 2009 -0700
+++ b/meth.patch Wed Apr 08 02:52:08 2009 -0700
@@ -481,29 +481,6 @@ diff --git a/src/cpu/x86/vm/interpreter_
}
-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
-@@ -135,7 +135,8 @@
- verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame");
- if (arg_slots.is_register()) {
- Label L_ok, L_bad;
-- __ cmpptr(arg_slots.as_register(), NULL_WORD);
-+ intptr_t zero = 0;
-+ __ cmpptr(arg_slots.as_register(), zero);
- __ jcc(Assembler::greater, L_bad);
- __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
- __ jcc(Assembler::zero, L_ok);
-@@ -220,7 +221,8 @@
- }
- if (arg_slots.is_register()) {
- Label L_ok, L_bad;
-- __ cmpptr(arg_slots.as_register(), NULL_WORD);
-+ intptr_t zero = 0;
-+ __ cmpptr(arg_slots.as_register(), zero);
- __ jcc(Assembler::less, L_bad);
- __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
- __ jcc(Assembler::zero, L_ok);
diff --git a/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/src/cpu/x86/vm/stubGenerator_x86_64.cpp
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp
@@ -570,27 +547,3 @@ diff --git a/src/share/vm/interpreter/te
static address throw_WrongMethodType_entry() { return _throw_WrongMethodType_entry; }
static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; }
static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; }
-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
-@@ -875,7 +875,7 @@
- #ifdef ASSERT
- // Make sure the pointer chase works.
- address p = (address) m();
-- for (int* pchase = method_type_offsets_chain(); (*pchase) != -1; pchase++) {
-+ for (jint* pchase = method_type_offsets_chain(); (*pchase) != -1; pchase++) {
- p = *(address*)(p + (*pchase));
- }
- assert((oop)p == method_type(), "pointer chase is correct");
-diff --git a/src/share/vm/oops/methodOop.hpp b/src/share/vm/oops/methodOop.hpp
---- a/src/share/vm/oops/methodOop.hpp
-+++ b/src/share/vm/oops/methodOop.hpp
-@@ -532,7 +532,7 @@
- TRAPS);
- // these operate only on invoke methods:
- oop method_handle_type() const;
-- static jint* method_type_offsets_chain();
-+ static jint* method_type_offsets_chain(); // series of pointer-offsets, terminated by -1
- // presize interpreter frames for extra interpreter stack entries, if needed
- static int extra_stack_entries() { return EnableMethodHandles ? (int)MethodHandlePushLimit : 0; }
- static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize()
--- a/meth.proj.patch Tue Apr 07 01:55:20 2009 -0700
+++ b/meth.proj.patch Wed Apr 08 02:52:08 2009 -0700
@@ -1067,7 +1067,7 @@ new file mode 100644
+dist.javadoc.dir=${dist.dir}/javadoc
+excludes=java/dyn/Anonymous*.java,java/dyn/*ConstantPool*.java,jdk/java/dyn/Anonymous*.java,links/**
+file.reference.test-classes=build/test/classes
-+includes=java/dyn/**,jdk/java/dyn/**,impl/java/dyn/**
++includes=java/dyn/**,jdk/java/dyn/**,sun/dyn/**
+#includes=**
+jar.compress=true
+javac.classpath=
@@ -1725,7 +1725,7 @@ new file mode 100644
+package jdk.java.dyn;
+
+import java.dyn.*;
-+import impl.java.dyn.util.*;
++import sun.dyn.util.*;
+import java.lang.reflect.Method;
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
@@ -1813,7 +1813,7 @@ new file mode 100644
+package jdk.java.dyn;
+
+import java.dyn.*;
-+import impl.java.dyn.util.MethodHandleInvoker;
++import sun.dyn.util.MethodHandleInvoker;
+
+import org.junit.*;
+//import static org.junit.Assert.*;
@@ -1988,8 +1988,8 @@ new file mode 100644
+
+package jdk.java.dyn;
+
-+import impl.java.dyn.MemberName;
-+import impl.java.dyn.util.Wrappers;
++import sun.dyn.MemberName;
++import sun.dyn.util.Wrappers;
+import java.dyn.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
@@ -2624,7 +2624,7 @@ new file mode 100644
+
+package jdk.java.dyn;
+
-+import impl.java.dyn.MemberName;
++import sun.dyn.MemberName;
+import java.dyn.MethodType;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
--- a/series Tue Apr 07 01:55:20 2009 -0700
+++ b/series Wed Apr 08 02:52:08 2009 -0700
@@ -7,7 +7,6 @@ meth-subtype-6813212.patch #-/meth
meth-subtype-6813212.patch #-/meth #+05f8c84c5daa
meth-minor-6814659.patch #-/meth #+05f8c84c5daa
meth-6655638.patch #-/meth #+05f8c84c5daa
-meth-6655638.03.patch #-/meth #+05f8c84c5daa
meth.patch #-/meth #+05f8c84c5daa
indy.patch #-/indy #+05f8c84c5daa
--- a/meth-6655638.03.patch Tue Apr 07 01:55:20 2009 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2554 +0,0 @@
-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
-@@ -29,6 +29,9 @@
-
- address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
- address interpreted_entry) {
-+ // Just before the actual machine code entry point, allocate space
-+ // for a MethodHandleEntry::Data record, so that we can manage everything
-+ // from one base pointer.
- __ align(wordSize);
- address target = __ pc() + sizeof(Data);
- while (__ pc() < target) {
-@@ -98,7 +101,7 @@
- // fetch the MethodType from the method handle into rax (the 'check' register)
- {
- Register tem = rbx_method;
-- for (int* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
-+ for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
- __ movptr(rax_mtype, Address(tem, *pchase));
- tem = rax_mtype; // in case there is another indirection
- }
-@@ -121,30 +124,18 @@
- // Helper to insert argument slots into the stack.
- // arg_slots must be a multiple of stack_move_unit() and <= 0
- void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
-- RegisterOrConstant arg_slots,
-- int arg_mask,
-- Register rax_argslot,
-- Register rbx_temp, Register rdx_temp) {
-+ RegisterOrConstant arg_slots,
-+ int arg_mask,
-+ Register rax_argslot,
-+ Register rbx_temp, Register rdx_temp) {
- assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
- (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
-
-- int constant_arg_slots = 0;
-- if (arg_slots.is_constant()) {
-- constant_arg_slots = arg_slots.as_constant() / stack_move_unit();
-- } else {
-- assert(arg_mask == _INSERT_NO_MASK,
-- "cannot specify arg_mask with non-constant slot count");
--#ifdef _LP64
-- // clean high bits of stack motion register (was loaded as an int)
-- __ movslq(arg_slots.as_register(), arg_slots.as_register());
--#endif
-- }
--
- #ifdef ASSERT
- verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame");
- if (arg_slots.is_register()) {
- Label L_ok, L_bad;
-- __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
-+ __ cmpptr(arg_slots.as_register(), NULL_WORD);
- __ jcc(Assembler::greater, L_bad);
- __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
- __ jcc(Assembler::zero, L_ok);
-@@ -157,6 +148,13 @@
- }
- #endif //ASSERT
-
-+#ifdef _LP64
-+ if (arg_slots.is_register()) {
-+ // clean high bits of stack motion register (was loaded as an int)
-+ __ movslq(arg_slots.as_register(), arg_slots.as_register());
-+ }
-+#endif
-+
- // Make space on the stack for the inserted argument(s).
- // Then pull down everything shallower than rax_argslot.
- // The stacked return address gets pulled down with everything else.
-@@ -181,7 +179,10 @@
- // Now move the argslot down, to point to the opened-up space.
- __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
-
-- if (TaggedStackInterpreter) {
-+ if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) {
-+ // The caller has specified a bitmask of tags to put into the opened space.
-+ // This only works when the arg_slots value is an assembly-time constant.
-+ int constant_arg_slots = arg_slots.as_constant() / stack_move_unit();
- int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();
- for (int slot = 0; slot < constant_arg_slots; slot++) {
- BasicType slot_type = ((arg_mask & (1 << slot)) == 0 ? T_OBJECT : T_INT);
-@@ -219,7 +220,7 @@
- }
- if (arg_slots.is_register()) {
- Label L_ok, L_bad;
-- __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
-+ __ cmpptr(arg_slots.as_register(), NULL_WORD);
- __ jcc(Assembler::less, L_bad);
- __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
- __ jcc(Assembler::zero, L_ok);
-@@ -272,7 +273,7 @@
- intptr_t* entry_sp,
- intptr_t* saved_sp) {
- // called as a leaf from native code: do not block the JVM!
-- printf("MH %s %p %p %d\n", adaptername, mh, entry_sp, entry_sp - saved_sp);
-+ printf("MH %s "PTR_FORMAT" "PTR_FORMAT" "INTX_FORMAT"\n", adaptername, mh, entry_sp, entry_sp - saved_sp);
- }
- #endif //PRODUCT
-
-@@ -283,7 +284,7 @@
- // as set up by generate_method_handle_interpreter_entry():
- // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
- // - rcx: receiver method handle
-- // - rax: method handle type (already checked at call site, then unused)
-+ // - rax: method handle type (only used by the check_mtype entry point)
- // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
- // - rdx: garbage temp, can blow away
-
-@@ -322,10 +323,6 @@
- address interp_entry = __ pc();
- if (UseCompressedOops) __ unimplemented("UseCompressedOops");
-
-- AdapterKind ak = _adapt_retype_only;
-- if ((int)ek > (int)_adapter_mh_first)
-- ak = AdapterKind((int)ek - (int)_adapter_mh_first);
--
- #ifndef PRODUCT
- if (TraceMethodHandles) {
- __ push(rax); __ push(rbx); __ push(rcx); __ push(rdx); __ push(rsi); __ push(rdi);
-@@ -409,7 +406,7 @@
-
- // get receiver klass
- Register rax_klass = rax_argslot;
-- __ movl(rax_klass, Address(rcx_recv, oopDesc::klass_offset_in_bytes()));
-+ __ load_klass(rax_klass, rcx_recv);
- __ verify_oop(rax_klass);
-
- // get target methodOop & entry point
-@@ -442,7 +439,7 @@
-
- // get receiver klass
- Register rax_klass = rax_argslot;
-- __ movl(rax_klass, Address(rcx_recv, oopDesc::klass_offset_in_bytes()));
-+ __ load_klass(rax_klass, rcx_recv);
- __ verify_oop(rax_klass);
-
- Register rcx_temp = rcx_recv;
-@@ -526,7 +523,7 @@
- }
- break;
-
-- case _adapter_mh_first+_adapt_retype_only:
-+ case _adapter_retype_only:
- // immediately jump to the next MH layer:
- __ movptr(rcx_recv, rcx_mh_vmtarget);
- __ verify_oop(rcx_recv);
-@@ -535,7 +532,7 @@
- // It is also OK when a return type narrows.
- break;
-
-- case _adapter_mh_first+_adapt_check_cast:
-+ case _adapter_check_cast:
- {
- // temps:
- Register rbx_klass = rbx_temp; // interesting AMH data
-@@ -556,7 +553,7 @@
- __ movptr(rdx_temp, vmarg);
- __ testl(rdx_temp, rdx_temp);
- __ jcc(Assembler::zero, done); // no cast if null
-- __ movl(rdx_temp, Address(rdx_temp, oopDesc::klass_offset_in_bytes()));
-+ __ load_klass(rdx_temp, rdx_temp);
-
- // live at this point:
- // - rbx_klass: klass required by the target method
-@@ -576,8 +573,8 @@
- }
- break;
-
-- case _adapter_mh_first+_adapt_prim_to_prim:
-- case _adapter_mh_first+_adapt_ref_to_prim:
-+ case _adapter_prim_to_prim:
-+ case _adapter_ref_to_prim:
- // handled completely by optimized cases
- __ stop("init_AdapterMethodHandle should not issue this");
- break;
-@@ -585,7 +582,7 @@
- case _adapter_opt_i2i: // optimized subcase of adapt_prim_to_prim
- //case _adapter_opt_f2i: // optimized subcase of adapt_prim_to_prim
- case _adapter_opt_l2i: // optimized subcase of adapt_prim_to_prim
-- case _adapter_opt_a2i: // optimized subcase of adapt_ref_to_prim
-+ case _adapter_opt_unboxi: // optimized subcase of adapt_ref_to_prim
- {
- // perform an in-place conversion to int or an int subword
- __ movl(rax_argslot, rcx_amh_vmargslot);
-@@ -605,7 +602,7 @@
- __ movl(rdx_temp, vmarg);
- }
- break;
-- case _adapter_opt_a2i:
-+ case _adapter_opt_unboxi:
- {
- // Load the value up from the heap.
- __ movptr(rdx_temp, vmarg);
-@@ -633,7 +630,7 @@
- {
- Register rbx_vminfo = rbx_temp;
- __ movl(rbx_vminfo, rcx_amh_conversion);
-- assert(_CONV_VMINFO_SHIFT == 0, "preshifted");
-+ assert(CONV_VMINFO_SHIFT == 0, "preshifted");
-
- // get the new MH:
- __ movptr(rcx_recv, rcx_mh_vmtarget);
-@@ -644,7 +641,7 @@
- __ xchgl(rcx, rbx_vminfo); // free rcx for shifts
- __ shll(rdx_temp /*, rcx*/);
- Label zero_extend, done;
-- __ testl(rcx, _CONV_VMINFO_SIGN_FLAG);
-+ __ testl(rcx, CONV_VMINFO_SIGN_FLAG);
- __ jcc(Assembler::zero, zero_extend);
-
- // this path is taken for int->byte, int->short
-@@ -664,7 +661,7 @@
- break;
-
- case _adapter_opt_i2l: // optimized subcase of adapt_prim_to_prim
-- case _adapter_opt_a2l: // optimized subcase of adapt_ref_to_prim
-+ case _adapter_opt_unboxl: // optimized subcase of adapt_ref_to_prim
- {
- // perform an in-place int-to-long or ref-to-long conversion
- __ movl(rax_argslot, rcx_amh_vmargslot);
-@@ -684,7 +681,7 @@
- __ movl(vmarg2, rdx_temp); // store second word
- }
- break;
-- case _adapter_opt_a2l:
-+ case _adapter_opt_unboxl:
- {
- // Load the value up from the heap.
- __ movptr(rdx_temp, vmarg1);
-@@ -759,12 +756,12 @@
- }
- break;
-
-- case _adapter_mh_first+_adapt_prim_to_ref:
-+ case _adapter_prim_to_ref:
- __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
- break;
-
-- case _adapter_mh_first+_adapt_swap_args:
-- case _adapter_mh_first+_adapt_rot_args:
-+ case _adapter_swap_args:
-+ case _adapter_rot_args:
- // handled completely by optimized cases
- __ stop("init_AdapterMethodHandle should not issue this");
- break;
-@@ -797,8 +794,8 @@
- // 'vminfo' is the second
- Register rbx_destslot = rbx_temp;
- __ movl(rbx_destslot, rcx_amh_conversion);
-- assert(_CONV_VMINFO_SHIFT == 0, "preshifted");
-- __ andl(rbx_destslot, _CONV_VMINFO_MASK);
-+ assert(CONV_VMINFO_SHIFT == 0, "preshifted");
-+ __ andl(rbx_destslot, CONV_VMINFO_MASK);
- __ lea(rbx_destslot, __ argument_address(rbx_destslot));
- DEBUG_ONLY(verify_argslot(_masm, rbx_destslot, "swap point must fall within current frame"));
-
-@@ -881,7 +878,7 @@
- }
- break;
-
-- case _adapter_mh_first+_adapt_dup_args:
-+ case _adapter_dup_args:
- {
- // 'argslot' is the position of the first argument to duplicate
- __ movl(rax_argslot, rcx_amh_vmargslot);
-@@ -890,7 +887,7 @@
- // 'stack_move' is negative number of words to duplicate
- Register rdx_stack_move = rdx_temp;
- __ movl(rdx_stack_move, rcx_amh_conversion);
-- __ sarl(rdx_stack_move, _CONV_STACK_MOVE_SHIFT);
-+ __ sarl(rdx_stack_move, CONV_STACK_MOVE_SHIFT);
-
- int argslot0_num = 0;
- Address argslot0 = __ argument_address(RegisterOrConstant(argslot0_num));
-@@ -941,7 +938,7 @@
- }
- break;
-
-- case _adapter_mh_first+_adapt_drop_args:
-+ case _adapter_drop_args:
- {
- // 'argslot' is the position of the first argument to nuke
- __ movl(rax_argslot, rcx_amh_vmargslot);
-@@ -953,7 +950,7 @@
- // 'stack_move' is number of words to drop
- Register rdi_stack_move = rdi;
- __ movl(rdi_stack_move, rcx_amh_conversion);
-- __ sarl(rdi_stack_move, _CONV_STACK_MOVE_SHIFT);
-+ __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
- remove_arg_slots(_masm, rdi_stack_move,
- rax_argslot, rbx_temp, rdx_temp);
-
-@@ -964,24 +961,24 @@
- }
- break;
-
-- case _adapter_mh_first+_adapt_collect_args:
-+ case _adapter_collect_args:
- __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
- break;
-
-- case _adapter_mh_first+_adapt_spread_args:
-+ case _adapter_spread_args:
- // handled completely by optimized cases
- __ stop("init_AdapterMethodHandle should not issue this");
- break;
-
-- case _adapt_opt_spread_0:
-- case _adapt_opt_spread_1:
-- case _adapt_opt_spread_more:
-+ case _adapter_opt_spread_0:
-+ case _adapter_opt_spread_1:
-+ case _adapter_opt_spread_more:
- {
- // spread an array out into a group of arguments
- int length_constant = -1;
- switch (ek) {
-- case _adapt_opt_spread_0: length_constant = 0; break;
-- case _adapt_opt_spread_1: length_constant = 1; break;
-+ case _adapter_opt_spread_0: length_constant = 0; break;
-+ case _adapter_opt_spread_1: length_constant = 1; break;
- }
-
- // find the address of the array argument
-@@ -1010,7 +1007,7 @@
- __ jcc(Assembler::zero, skip_array_check);
- }
- __ null_check(rsi_array, oopDesc::klass_offset_in_bytes());
-- __ movl(rdx_array_klass, Address(rsi_array, oopDesc::klass_offset_in_bytes()));
-+ __ load_klass(rdx_array_klass, rsi_array);
-
- // Check the array type.
- Register rbx_klass = rbx_temp;
-@@ -1029,8 +1026,8 @@
- } else {
- Register rbx_vminfo = rbx_temp;
- __ movl(rbx_vminfo, rcx_amh_conversion);
-- assert(_CONV_VMINFO_SHIFT == 0, "preshifted");
-- __ andl(rbx_vminfo, _CONV_VMINFO_MASK);
-+ assert(CONV_VMINFO_SHIFT == 0, "preshifted");
-+ __ andl(rbx_vminfo, CONV_VMINFO_MASK);
- __ cmpl(rbx_vminfo, Address(rsi_array, length_offset));
- }
- __ jcc(Assembler::notEqual, bad_array_length);
-@@ -1044,7 +1041,7 @@
- // 'stack_move' is negative number of words to insert
- Register rdi_stack_move = rdi;
- __ movl(rdi_stack_move, rcx_amh_conversion);
-- __ sarl(rdi_stack_move, _CONV_STACK_MOVE_SHIFT);
-+ __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
- Register rsi_temp = rsi_array; // spill this
- insert_arg_slots(_masm, rdi_stack_move, -1,
- rax_argslot, rbx_temp, rsi_temp);
-@@ -1120,8 +1117,8 @@
- }
- break;
-
-- case _adapter_mh_first+_adapt_flyby:
-- case _adapter_mh_first+_adapt_ricochet:
-+ case _adapter_flyby:
-+ case _adapter_ricochet:
- __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
- break;
-
-diff --git a/src/share/vm/classfile/javaClasses.hpp b/src/share/vm/classfile/javaClasses.hpp
---- a/src/share/vm/classfile/javaClasses.hpp
-+++ b/src/share/vm/classfile/javaClasses.hpp
-@@ -151,6 +151,12 @@
- // Conversion
- static klassOop as_klassOop(oop java_class);
- static BasicType as_BasicType(oop java_class, klassOop* reference_klass = NULL);
-+ static BasicType as_BasicType(oop java_class, KlassHandle* reference_klass) {
-+ klassOop refk_oop = NULL;
-+ BasicType result = as_BasicType(java_class, &refk_oop);
-+ (*reference_klass) = KlassHandle(refk_oop);
-+ return result;
-+ }
- static symbolOop as_signature(oop java_class, bool intern_if_not_found, TRAPS);
- static void print_signature(oop java_class, outputStream *st);
- // Testing
-@@ -896,25 +902,26 @@
-
- // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
- enum {
-- RETYPE_ONLY = 0x000, // no argument changes; straight retype
-- CHECK_CAST = 0x100, // ref-to-ref conversion; requires a Class argument
-- PRIM_TO_PRIM = 0x200, // converts from one primitive to another
-- REF_TO_PRIM = 0x300, // unboxes a wrapper to produce a primitive
-- PRIM_TO_REF = 0x400, // boxes a primitive into a wrapper (NYI)
-- SWAP_ARGS = 0x500, // swap arguments (vminfo is 2nd arg)
-- ROT_ARGS = 0x600, // rotate arguments (vminfo is displaced arg)
-- DUP_ARGS = 0x700, // duplicates one or more arguments (at TOS)
-- DROP_ARGS = 0x800, // remove one or more argument slots
-- COLLECT_ARGS = 0x900, // combine one or more arguments into a varargs (NYI)
-- SPREAD_ARGS = 0xA00, // expand in place a varargs array (of known size)
-- FLYBY = 0xB00, // operate first on reified argument list (NYI)
-- RICOCHET = 0xC00, // run an adapter chain on the return value (NYI)
-+ OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
-+ OP_CHECK_CAST = 0x1, // ref-to-ref conversion; requires a Class argument
-+ OP_PRIM_TO_PRIM = 0x2, // converts from one primitive to another
-+ OP_REF_TO_PRIM = 0x3, // unboxes a wrapper to produce a primitive
-+ OP_PRIM_TO_REF = 0x4, // boxes a primitive into a wrapper (NYI)
-+ OP_SWAP_ARGS = 0x5, // swap arguments (vminfo is 2nd arg)
-+ OP_ROT_ARGS = 0x6, // rotate arguments (vminfo is displaced arg)
-+ OP_DUP_ARGS = 0x7, // duplicates one or more arguments (at TOS)
-+ OP_DROP_ARGS = 0x8, // remove one or more argument slots
-+ OP_COLLECT_ARGS = 0x9, // combine one or more arguments into a varargs (NYI)
-+ OP_SPREAD_ARGS = 0xA, // expand in place a varargs array (of known size)
-+ OP_FLYBY = 0xB, // operate first on reified argument list (NYI)
-+ OP_RICOCHET = 0xC, // run an adapter chain on the return value (NYI)
-+ CONV_OP_LIMIT = 0xD, // limit of CONV_OP enumeration
-
-- CONV_OP_MASK = 0xF00, // byte 3 contains the conversion op field
-+ CONV_OP_MASK = 0xF00, // this nybble contains the conversion op field
- CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
- CONV_VMINFO_SHIFT = 0, // position of bits in CONV_VMINFO_MASK
- CONV_OP_SHIFT = 8, // position of bits in CONV_OP_MASK
-- CONV_DEST_TYPE_SHIFT = 12, // byte 3 has the adapter BasicType (if needed)
-+ CONV_DEST_TYPE_SHIFT = 12, // byte 2 has the adapter BasicType (if needed)
- CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed)
- CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change
- CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1
-diff --git a/src/share/vm/includeDB_core b/src/share/vm/includeDB_core
---- a/src/share/vm/includeDB_core
-+++ b/src/share/vm/includeDB_core
-@@ -2817,6 +2817,7 @@
- methodHandles.hpp frame.inline.hpp
- methodHandles.hpp globals.hpp
- methodHandles.hpp interfaceSupport.hpp
-+methodHandles.hpp javaClasses.hpp
- methodHandles.hpp vmSymbols.hpp
-
- methodHandles.cpp allocation.inline.hpp
-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
-@@ -47,19 +47,19 @@
- "bound_long_direct",
-
- // starting at _adapter_mh_first:
-- "adapt_retype_only", // these are for AMH...
-- "adapt_check_cast",
-- "adapt_prim_to_prim",
-- "adapt_ref_to_prim",
-- "adapt_prim_to_ref",
-- "adapt_swap_args",
-- "adapt_rot_args",
-- "adapt_dup_args",
-- "adapt_drop_args",
-- "adapt_collect_args",
-- "adapt_spread_args",
-- "adapt_flyby",
-- "adapt_ricochet",
-+ "adapter_retype_only", // these are for AMH...
-+ "adapter_check_cast",
-+ "adapter_prim_to_prim",
-+ "adapter_ref_to_prim",
-+ "adapter_prim_to_ref",
-+ "adapter_swap_args",
-+ "adapter_rot_args",
-+ "adapter_dup_args",
-+ "adapter_drop_args",
-+ "adapter_collect_args",
-+ "adapter_spread_args",
-+ "adapter_flyby",
-+ "adapter_ricochet",
-
- // optimized adapter types:
- "adapter_swap_args/1",
-@@ -68,16 +68,16 @@
- "adapter_rot_args/1,down",
- "adapter_rot_args/2,up",
- "adapter_rot_args/2,down",
-- "adapt_prim_to_prim/i2i",
-- "adapt_prim_to_prim/l2i",
-- "adapt_prim_to_prim/d2f",
-- "adapt_prim_to_prim/i2l",
-- "adapt_prim_to_prim/f2d",
-- "adapt_prim_to_prim/a2i",
-- "adapt_prim_to_prim/a2l",
-- "adapt_spread_args/0",
-- "adapt_spread_args/1",
-- "adapt_spread_args/more",
-+ "adapter_prim_to_prim/i2i",
-+ "adapter_prim_to_prim/l2i",
-+ "adapter_prim_to_prim/d2f",
-+ "adapter_prim_to_prim/i2l",
-+ "adapter_prim_to_prim/f2d",
-+ "adapter_ref_to_prim/unboxi",
-+ "adapter_ref_to_prim/unboxl",
-+ "adapter_spread_args/0",
-+ "adapter_spread_args/1",
-+ "adapter_spread_args/more",
-
- NULL
- };
-@@ -86,8 +86,9 @@
- bool MethodHandles::spot_check_entry_names() {
- assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), "");
- assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), "");
-- assert(!strcmp(adapter_entry_name(_adapt_retype_only), "adapt_retype_only"), "");
-- assert(!strcmp(adapter_entry_name(_adapt_ricochet), "adapt_ricochet"), "");
-+ assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), "");
-+ assert(!strcmp(entry_name(_adapter_ricochet), "adapter_ricochet"), "");
-+ assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), "");
- return true;
- }
- #endif
-@@ -99,6 +100,11 @@
- }
- }
-
-+// Note: A method which does not have a TRAPS argument cannot block in the GC
-+// or throw exceptions. Such methods are used in this file to do something quick
-+// and local, like parse a data structure. For speed, such methods work on plain
-+// oops, not handles. Trapping methods uniformly operate on handles.
-+
- methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
- klassOop& receiver_limit_result, int& decode_flags_result) {
- if (vmtarget == NULL) return NULL;
-@@ -183,8 +189,8 @@
- assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
- for (oop amh = mh;;) {
- // Adapter MHs can be stacked to convert several arguments.
-- AdapterKind ak = adapter_conversion_op(impl_java_dyn_AdapterMethodHandle::conversion(amh));
-- decode_flags_result |= (_dmf_adapter_lsb << ak);
-+ int conv_op = adapter_conversion_op(impl_java_dyn_AdapterMethodHandle::conversion(amh));
-+ decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK;
- oop target = java_dyn_MethodHandle::vmtarget(amh);
- if (target == NULL) return NULL;
- klassOop tk = target->klass();
-@@ -299,26 +305,6 @@
- }
-
-
--static void throw_IllegalArgumentException(TRAPS) {
-- THROW(vmSymbols::java_lang_IllegalArgumentException());
-- ShouldNotReachHere();
--}
--
--static void throw_IllegalArgumentException(const char* message, TRAPS) {
-- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message);
-- ShouldNotReachHere();
--}
--
--static void throw_InternalError(const char* message, TRAPS) {
-- THROW_MSG(vmSymbols::java_lang_InternalError(), message);
-- ShouldNotReachHere();
--}
--
--static void throw_InternalError(TRAPS) {
-- THROW(vmSymbols::java_lang_InternalError());
-- ShouldNotReachHere();
--}
--
- // MemberName support
-
- // import impl_java_dyn_MemberName.*
-@@ -352,7 +338,7 @@
-
- void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) {
- int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD)
-- | (jushort) m->access_flags().as_short());
-+ | (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ));
- oop vmtarget = m;
- int vmindex = methodOopDesc::invalid_vtable_index; // implies no info yet
- if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound())
-@@ -364,7 +350,7 @@
- }
-
- void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) {
-- int flags = (IS_FIELD | (jushort) mods.as_short());
-+ int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ));
- oop vmtarget = field_holder;
- int vmindex = offset; // implies no info yet
- assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex");
-@@ -405,18 +391,21 @@
- oop type_str = impl_java_dyn_MemberName::type(mname());
- int flags = impl_java_dyn_MemberName::flags(mname());
-
-- if (defc_oop == NULL || name_str == NULL || type_str == NULL)
-- { throw_IllegalArgumentException("nothing to resolve", CHECK); }
-+ if (defc_oop == NULL || name_str == NULL || type_str == NULL) {
-+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve");
-+ }
- klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop);
- defc_oop = NULL; // safety
-+ if (defc_klassOop == NULL) return; // a primitive; no resolution possible
- if (!Klass::cast(defc_klassOop)->oop_is_instance()) {
- if (!Klass::cast(defc_klassOop)->oop_is_array()) return;
- defc_klassOop = SystemDictionary::object_klass();
- }
- instanceKlassHandle defc(THREAD, defc_klassOop);
- defc_klassOop = NULL; // safety
-- if (defc.is_null())
-- { throw_InternalError("primitive class", CHECK); }
-+ if (defc.is_null()) {
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class");
-+ }
- defc->link_class(CHECK);
-
- // convert the external string name to an internal symbol
-@@ -439,7 +428,7 @@
- type_sym = java_lang_String::as_symbol_or_null(type_str);
- }
- } else {
-- throw_InternalError("unrecognized type", CHECK);
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized type");
- }
- if (type_sym != NULL)
- type = symbolHandle(THREAD, type_sym);
-@@ -486,9 +475,10 @@
- } else {
- vmtarget = result.resolved_klass()->as_klassOop();
- }
-+ int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
- impl_java_dyn_MemberName::set_vmtarget(mname(), vmtarget);
- impl_java_dyn_MemberName::set_vmindex(mname(), vmindex);
-- impl_java_dyn_MemberName::set_modifiers(mname(), m->access_flags().as_short());
-+ impl_java_dyn_MemberName::set_modifiers(mname(), mods);
- DEBUG_ONLY(int junk; klassOop junk2);
- assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
- "properly stored for later decoding");
-@@ -514,9 +504,10 @@
- methodHandle m = result.resolved_method();
- oop vmtarget = m();
- int vmindex = methodOopDesc::nonvirtual_vtable_index;
-+ int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
- impl_java_dyn_MemberName::set_vmtarget(mname(), vmtarget);
- impl_java_dyn_MemberName::set_vmindex(mname(), vmindex);
-- impl_java_dyn_MemberName::set_modifiers(mname(), m->access_flags().as_short());
-+ impl_java_dyn_MemberName::set_modifiers(mname(), mods);
- DEBUG_ONLY(int junk; klassOop junk2);
- assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
- "properly stored for later decoding");
-@@ -531,14 +522,15 @@
- if (sel_klass.is_null()) return;
- oop vmtarget = sel_klass->as_klassOop();
- int vmindex = fd.offset();
-+ int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS);
- if (vmindex == VM_INDEX_UNINITIALIZED) break; // should not happen
- impl_java_dyn_MemberName::set_vmtarget(mname(), vmtarget);
- impl_java_dyn_MemberName::set_vmindex(mname(), vmindex);
-- impl_java_dyn_MemberName::set_modifiers(mname(), fd.access_flags().as_short());
-+ impl_java_dyn_MemberName::set_modifiers(mname(), mods);
- return;
- }
- }
-- throw_InternalError("unrecognized MemberName format", THREAD);
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
- }
-
- // Conversely, a member name which is only initialized from JVM internals
-@@ -549,8 +541,9 @@
- assert(impl_java_dyn_MemberName::is_instance(mname()), "");
- oop vmtarget = impl_java_dyn_MemberName::vmtarget(mname());
- int vmindex = impl_java_dyn_MemberName::vmindex(mname());
-- if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED)
-- { throw_IllegalArgumentException("nothing to expand", CHECK); }
-+ if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) {
-+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
-+ }
-
- bool have_defc = (impl_java_dyn_MemberName::clazz(mname()) != NULL);
- bool have_name = (impl_java_dyn_MemberName::name(mname()) != NULL);
-@@ -617,7 +610,7 @@
- return;
- }
- }
-- throw_InternalError("unrecognized MemberName format", THREAD);
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
- }
-
- int MethodHandles::find_MemberNames(klassOop k,
-@@ -734,10 +727,10 @@
- // Decode the vmtarget field of a method handle.
- // Sanitize out methodOops, klassOops, and any other non-Java data.
- // This is for debugging and reflection.
--oop MethodHandles::encode_target(oop mh, int format, TRAPS) {
-- assert(java_dyn_MethodHandle::is_instance(mh), "must be a MH");
-+oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
-+ assert(java_dyn_MethodHandle::is_instance(mh()), "must be a MH");
- if (format == ETF_HANDLE_OR_METHOD_NAME) {
-- oop target = java_dyn_MethodHandle::vmtarget(mh);
-+ oop target = java_dyn_MethodHandle::vmtarget(mh());
- if (target == NULL) {
- return NULL; // unformed MH
- }
-@@ -747,7 +740,7 @@
- }
- }
- if (format == ETF_DIRECT_HANDLE) {
-- oop target = mh;
-+ oop target = mh();
- for (;;) {
- if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
- return target;
-@@ -764,7 +757,7 @@
- // - DMH can have klassOop for dispatched (non-static) invoke
- klassOop receiver_limit = NULL;
- int decode_flags = 0;
-- methodOop m = decode_MethodHandle(mh, receiver_limit, decode_flags);
-+ methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags);
- if (m == NULL) return NULL;
- switch (format) {
- case ETF_REFLECT_METHOD:
-@@ -791,8 +784,9 @@
- }
-
- // Unknown format code.
-- throw_IllegalArgumentException(THREAD);
-- return NULL;
-+ char msg[50];
-+ jio_snprintf(msg, sizeof(msg), "unknown getTarget format=%d", format);
-+ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg);
- }
-
- bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) {
-@@ -843,8 +837,8 @@
- return false;
- }
-
--const char* MethodHandles::check_method_receiver(methodHandle m,
-- klassOop passed_recv_type) {
-+const char* MethodHandles::check_method_receiver(methodOop m,
-+ klassOop passed_recv_type) {
- assert(!m->is_static(), "caller resp.");
- if (passed_recv_type == NULL)
- return "receiver type is primitive";
-@@ -860,10 +854,10 @@
- // of the given method type 'mtype'.
- // It takes a TRAPS argument because it must perform symbol lookups.
- void MethodHandles::verify_method_signature(methodHandle m,
-- Handle mtype,
-- int first_ptype_pos,
-- KlassHandle insert_ptype,
-- TRAPS) {
-+ Handle mtype,
-+ int first_ptype_pos,
-+ KlassHandle insert_ptype,
-+ TRAPS) {
- objArrayHandle ptypes(THREAD, java_dyn_MethodType::ptypes(mtype()));
- int pnum = first_ptype_pos;
- int pmax = ptypes->length();
-@@ -919,22 +913,17 @@
- }
-
- if (err != NULL) {
-- throw_InternalError(err, CHECK);
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), err);
- }
- }
-
- // Main routine for verifying the MethodHandle.type of a proposed
- // direct or bound-direct method handle.
- void MethodHandles::verify_method_type(methodHandle m,
-- oop mtype_oop,
-- bool has_bound_recv,
-- klassOop bound_recv_type_oop,
-- TRAPS) {
-- Handle mtype(THREAD, mtype_oop);
-- KlassHandle bound_recv_type(THREAD, bound_recv_type_oop);
--
-- mtype_oop = NULL; bound_recv_type_oop = NULL; // better safe than sorry
--
-+ Handle mtype,
-+ bool has_bound_recv,
-+ KlassHandle bound_recv_type,
-+ TRAPS) {
- bool m_needs_receiver = !m->is_static();
-
- const char* err = NULL;
-@@ -951,9 +940,9 @@
- if (ptypes->length() < first_ptype_pos)
- { err = "receiver argument is missing"; goto die; }
- if (first_ptype_pos == -1)
-- err = check_method_receiver(m, bound_recv_type->as_klassOop());
-+ err = check_method_receiver(m(), bound_recv_type->as_klassOop());
- else
-- err = check_method_receiver(m, java_lang_Class::as_klassOop(ptypes->obj_at(0)));
-+ err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(0)));
- if (err != NULL) goto die;
- }
-
-@@ -962,14 +951,15 @@
- return;
-
- die:
-- throw_InternalError(err, CHECK);
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), err);
- }
-
- void MethodHandles::verify_vmslots(Handle mh, TRAPS) {
- // Verify vmslots.
- int check_slots = argument_slot_count(java_dyn_MethodHandle::type(mh()));
-- if (java_dyn_MethodHandle::vmslots(mh()) != check_slots)
-- { throw_InternalError("bad vmslots in BMH", CHECK); }
-+ if (java_dyn_MethodHandle::vmslots(mh()) != check_slots) {
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH");
-+ }
- }
-
- void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
-@@ -980,7 +970,7 @@
- size_t msglen = strlen(fmt) + 3*11 + 1;
- char* msg = NEW_RESOURCE_ARRAY(char, msglen);
- jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
-- throw_InternalError(msg, CHECK);
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
- }
- }
-
-@@ -988,12 +978,12 @@
- // Apart from the advertised changes, caller method type X must
- // be able to invoke the callee method Y type with no violations
- // of type integrity.
--void MethodHandles::verify_method_type_change(oop src_mtype, int src_beg, int src_end,
-- int insert_argnum, oop insert_type,
-- int change_argnum, oop change_type,
-- int delete_argnum,
-- oop dst_mtype, int dst_beg, int dst_end,
-- TRAPS) {
-+// Return NULL if all is well, else a short error message.
-+const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end,
-+ int insert_argnum, oop insert_type,
-+ int change_argnum, oop change_type,
-+ int delete_argnum,
-+ oop dst_mtype, int dst_beg, int dst_end) {
- objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype);
- objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype);
-
-@@ -1050,31 +1040,23 @@
-
- // Compare the two argument types.
- if (src_type != dst_type) {
-- if (src_type == NULL) err = "not enough arguments";
-- if (dst_type == NULL) err = "too many arguments";
-- if (err == NULL)
-- err = check_argument_type_change(src_type, dst_type, dst_idx);
-- if (err != NULL) break;
-+ if (src_type == NULL) return "not enough arguments";
-+ if (dst_type == NULL) return "too many arguments";
-+ err = check_argument_type_change(src_type, dst_type, dst_idx);
-+ if (err != NULL) return err;
- }
- }
-
-- if (err == NULL) {
-- // Now compare return types also.
-- oop src_rtype = java_dyn_MethodType::rtype(src_mtype);
-- oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype);
-- if (src_rtype != dst_rtype) {
-- err = check_return_type_change(dst_rtype, src_rtype); // note reversal!
-- }
-+ // Now compare return types also.
-+ oop src_rtype = java_dyn_MethodType::rtype(src_mtype);
-+ oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype);
-+ if (src_rtype != dst_rtype) {
-+ err = check_return_type_change(dst_rtype, src_rtype); // note reversal!
-+ if (err != NULL) return err;
- }
-
-- if (err != NULL) { throw_InternalError(err, CHECK); }
--}
--
--// Handy wrapper for check_argument_type_change, to verify one src/dest pair.
--void MethodHandles::verify_argument_type_change(oop src_type, oop dst_type,
-- int argnum, TRAPS) {
-- const char* err = check_argument_type_change(src_type, dst_type, argnum);
-- if (err != NULL) { throw_InternalError(err, CHECK); }
-+ assert(err == NULL, "");
-+ return NULL; // all is well
- }
-
-
-@@ -1176,33 +1158,33 @@
- return -99; // oob slot, or splitting a double-slot arg
- }
-
--methodOop MethodHandles::dispatch_decoded_method(methodOop m,
-- klassOop receiver_limit,
-- int decode_flags,
-- klassOop receiver_klass,
-- TRAPS) {
-+methodHandle MethodHandles::dispatch_decoded_method(methodHandle m,
-+ KlassHandle receiver_limit,
-+ int decode_flags,
-+ KlassHandle receiver_klass,
-+ TRAPS) {
- assert((decode_flags & ~_DMF_DIRECT_MASK) == 0, "must be direct method reference");
- assert((decode_flags & _dmf_has_receiver) != 0, "must have a receiver or first reference argument");
-
- if (!m->is_static() &&
-- (receiver_klass == NULL || !Klass::cast(receiver_klass)->is_subtype_of(m->method_holder())))
-+ (receiver_klass.is_null() || !receiver_klass->is_subtype_of(m->method_holder())))
- // given type does not match class of method, or receiver is null!
- // caller should have checked this, but let's be extra careful...
-- return NULL;
-+ return methodHandle();
-
-- if (receiver_limit != NULL &&
-- (receiver_klass != NULL && !Klass::cast(receiver_klass)->is_subtype_of(receiver_limit)))
-+ if (receiver_limit.not_null() &&
-+ (receiver_klass.not_null() && !receiver_klass->is_subtype_of(receiver_limit())))
- // given type is not limited to the receiver type
- // note that a null receiver can match any reference value, for a static method
-- return NULL;
-+ return methodHandle();
-
- if (!(decode_flags & MethodHandles::_dmf_does_dispatch)) {
- // pre-dispatched or static method (null receiver is OK for static)
- return m;
-
-- } else if (receiver_klass == NULL) {
-+ } else if (receiver_klass.is_null()) {
- // null receiver value; cannot dispatch
-- return NULL;
-+ return methodHandle();
-
- } else if (!(decode_flags & MethodHandles::_dmf_from_interface)) {
- // perform virtual dispatch
-@@ -1212,37 +1194,45 @@
- // receiver_klass might be an arrayKlassOop but all vtables start at
- // the same place. The cast is to avoid virtual call and assertion.
- // See also LinkResolver::runtime_resolve_virtual_method.
-- instanceKlass* inst = (instanceKlass*)Klass::cast(receiver_klass);
-+ instanceKlass* inst = (instanceKlass*)Klass::cast(receiver_klass());
- DEBUG_ONLY(inst->verify_vtable_index(vtable_index));
-- return inst->method_at_vtable(vtable_index);
-+ methodOop m_oop = inst->method_at_vtable(vtable_index);
-+ return methodHandle(THREAD, m_oop);
-
- } else {
- // perform interface dispatch
-- int itable_index = klassItable::compute_itable_index(m);
-+ int itable_index = klassItable::compute_itable_index(m());
- guarantee(itable_index >= 0, "valid itable index");
-- instanceKlass* inst = instanceKlass::cast(receiver_klass);
-- return inst->method_at_itable(m->method_holder(), itable_index, THREAD);
-+ instanceKlass* inst = instanceKlass::cast(receiver_klass());
-+ methodOop m_oop = inst->method_at_itable(m->method_holder(), itable_index, THREAD);
-+ return methodHandle(THREAD, m_oop);
-+ }
-+}
-+
-+void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) {
-+ // Verify type.
-+ Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
-+ verify_method_type(m, mtype, false, KlassHandle(), CHECK);
-+
-+ // Verify vmslots.
-+ if (java_dyn_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH");
- }
- }
-
- void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_dispatch, TRAPS) {
- // Check arguments.
- if (mh.is_null() || m.is_null() ||
-- (!do_dispatch && m->is_abstract()))
-- { throw_InternalError(CHECK); }
-+ (!do_dispatch && m->is_abstract())) {
-+ THROW(vmSymbols::java_lang_InternalError());
-+ }
-
- java_dyn_MethodHandle::init_vmslots(mh());
-
-- // The privileged code which invokes this routine should not make
-- // a mistake about types, but it's better to verify.
- if (VerifyMethodHandles) {
-- // Verify type.
-- verify_method_type(m, java_dyn_MethodHandle::type(mh()),
-- false, NULL, CHECK);
--
-- // Verify vmslots.
-- if (java_dyn_MethodHandle::vmslots(mh()) != m->size_of_parameters())
-- { throw_InternalError("bad vmslots in DMH", CHECK); }
-+ // The privileged code which invokes this routine should not make
-+ // a mistake about types, but it's better to verify.
-+ verify_DirectMethodHandle(mh, m, CHECK);
- }
-
- // Finally, after safety checks are done, link to the target method.
-@@ -1295,7 +1285,7 @@
- me = MethodHandles::entry(MethodHandles::_invokevirtual_mh);
- }
-
-- if (me == NULL) { throw_InternalError(CHECK); }
-+ if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
-
- impl_java_dyn_DirectMethodHandle::set_vmtarget(mh(), vmtarget);
- impl_java_dyn_DirectMethodHandle::set_vmindex(mh(), vmindex);
-@@ -1312,48 +1302,56 @@
- java_dyn_MethodHandle::set_vmentry(mh(), me);
- }
-
-+void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh,
-+ methodHandle m,
-+ TRAPS) {
-+ // Verify type.
-+ oop receiver = impl_java_dyn_BoundMethodHandle::argument(mh());
-+ Handle mtype(THREAD, java_dyn_MethodHandle::type(mh()));
-+ KlassHandle bound_recv_type;
-+ if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass());
-+ verify_method_type(m, mtype, true, bound_recv_type, CHECK);
-+
-+ int receiver_pos = m->size_of_parameters() - 1;
-+
-+ // Verify MH.vmargslot, which should point at the bound receiver.
-+ verify_vmargslot(mh, -1, impl_java_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
-+ //verify_vmslots(mh, CHECK);
-+
-+ // Verify vmslots.
-+ if (java_dyn_MethodHandle::vmslots(mh()) != receiver_pos) {
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)");
-+ }
-+}
-+
- // Initialize a BMH with a receiver bound directly to a methodOop.
- void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh,
-- methodOop original_m_oop,
-- klassOop receiver_limit_oop,
-- int decode_flags,
-- TRAPS) {
-+ methodHandle original_m,
-+ KlassHandle receiver_limit,
-+ int decode_flags,
-+ TRAPS) {
- // Check arguments.
-- if (mh.is_null() || original_m_oop == NULL)
-- { throw_InternalError(CHECK); }
-+ if (mh.is_null() || original_m.is_null()) {
-+ THROW(vmSymbols::java_lang_InternalError());
-+ }
-
-- oop arg_oop = impl_java_dyn_BoundMethodHandle::argument(mh());
-- methodOop m_oop = dispatch_decoded_method(original_m_oop,
-- receiver_limit_oop, decode_flags,
-- (arg_oop == NULL ? klassOop(NULL) : arg_oop->klass()),
-- CHECK);
-- // do not use bare oops after this point:
-- original_m_oop = NULL; receiver_limit_oop = NULL; arg_oop = NULL;
--
-- if (m_oop == NULL) { throw_InternalError(CHECK); }
-- methodHandle m(THREAD, m_oop); m_oop = NULL;
--
-- if (m->is_abstract())
-- THROW(vmSymbols::java_lang_AbstractMethodError());
-+ KlassHandle receiver_klass;
-+ {
-+ oop receiver_oop = impl_java_dyn_BoundMethodHandle::argument(mh());
-+ if (receiver_oop != NULL)
-+ receiver_klass = KlassHandle(THREAD, receiver_oop->klass());
-+ }
-+ methodHandle m = dispatch_decoded_method(original_m,
-+ receiver_limit, decode_flags,
-+ receiver_klass,
-+ CHECK);
-+ if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); }
-+ if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
-
- java_dyn_MethodHandle::init_vmslots(mh());
-
- if (VerifyMethodHandles) {
-- // Verify type.
-- oop receiver = impl_java_dyn_BoundMethodHandle::argument(mh());
-- verify_method_type(m, java_dyn_MethodHandle::type(mh()),
-- true, (receiver == NULL ? klassOop(NULL) : receiver->klass()),
-- CHECK);
--
-- int receiver_pos = m->size_of_parameters() - 1;
--
-- // Verify MH.vmargslot, which should point at the bound receiver.
-- verify_vmargslot(mh, -1, impl_java_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
-- //verify_vmslots(mh, CHECK);
--
-- // Verify vmslots.
-- if (java_dyn_MethodHandle::vmslots(mh()) != receiver_pos)
-- { throw_InternalError("bad vmslots in BMH (receiver)", CHECK); }
-+ verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
- }
-
- impl_java_dyn_BoundMethodHandle::set_vmtarget(mh(), m());
-@@ -1366,10 +1364,96 @@
- java_dyn_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
- }
-
-+void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
-+ bool direct_to_method, TRAPS) {
-+ Handle ptype_handle(THREAD,
-+ java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum));
-+ KlassHandle ptype_klass;
-+ BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass);
-+ int slots_pushed = type2size[ptype];
-+
-+ oop argument = impl_java_dyn_BoundMethodHandle::argument(mh());
-+
-+ const char* err = NULL;
-+
-+ switch (ptype) {
-+ case T_OBJECT:
-+ if (argument != NULL)
-+ // we must implicitly convert from the arg type to the outgoing ptype
-+ err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass(), argnum);
-+ break;
-+
-+ case T_ARRAY: case T_VOID:
-+ assert(false, "array, void do not appear here");
-+ default:
-+ if (ptype != T_INT && !is_subword_type(ptype)) {
-+ err = "unexpected parameter type";
-+ break;
-+ }
-+ // check subrange of Integer.value, if necessary
-+ if (argument == NULL || argument->klass() != SystemDictionary::int_klass()) {
-+ err = "bound integer argument must be of type java.lang.Integer";
-+ break;
-+ }
-+ if (ptype != T_INT) {
-+ int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
-+ jint value = argument->int_field(value_offset);
-+ int vminfo = adapter_subword_vminfo(ptype);
-+ jint subword = truncate_subword_from_vminfo(value, vminfo);
-+ if (value != subword) {
-+ err = "bound subword value does not fit into the subword type";
-+ break;
-+ }
-+ }
-+ break;
-+ case T_FLOAT:
-+ case T_DOUBLE:
-+ case T_LONG:
-+ {
-+ // we must implicitly convert from the unboxed arg type to the outgoing ptype
-+ BasicType argbox = java_lang_boxing_object::basic_type(argument);
-+ if (argbox != ptype) {
-+ err = check_argument_type_change(T_OBJECT, (argument == NULL
-+ ? SystemDictionary::object_klass()
-+ : argument->klass()),
-+ ptype, ptype_klass(), argnum);
-+ assert(err != NULL, "this must be an error");
-+ }
-+ break;
-+ }
-+ }
-+
-+ if (err == NULL) {
-+ DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-+ if (direct_to_method) {
-+ assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
-+ assert(slots_pushed <= MethodHandlePushLimit, "");
-+ } else {
-+ int prev_pushes = decode_MethodHandle_stack_pushes(target());
-+ assert(this_pushes == slots_pushed + prev_pushes, "BMH stack motion must be correct");
-+ // do not blow the stack; use a Java-based adapter if this limit is exceeded
-+ if (slots_pushed + prev_pushes > MethodHandlePushLimit)
-+ err = "too many bound parameters";
-+ }
-+ }
-+
-+ if (err == NULL) {
-+ // Verify the rest of the method type.
-+ err = check_method_type_insertion(java_dyn_MethodHandle::type(mh()),
-+ argnum, ptype_handle(),
-+ java_dyn_MethodHandle::type(target()));
-+ }
-+
-+ if (err != NULL) {
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), err);
-+ }
-+}
-+
- void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
- // Check arguments.
-- if (mh.is_null() || target.is_null() || !java_dyn_MethodHandle::is_instance(target()))
-- { throw_InternalError(CHECK); }
-+ if (mh.is_null() || target.is_null() || !java_dyn_MethodHandle::is_instance(target())) {
-+ THROW(vmSymbols::java_lang_InternalError());
-+ }
-
- java_dyn_MethodHandle::init_vmslots(mh());
-
-@@ -1387,13 +1471,14 @@
- if (OptimizeMethodHandles &&
- target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
- (argnum == 0 || impl_java_dyn_DirectMethodHandle::vmindex(target()) < 0)) {
-- int decode_flags = 0; klassOop receiver_limit = NULL;
-- methodHandle m(THREAD, decode_method(target(), receiver_limit, decode_flags));
-- if (m.is_null()) { throw_InternalError("DMH failed to decode", CHECK); }
-+ int decode_flags = 0; klassOop receiver_limit_oop = NULL;
-+ methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags));
-+ if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
- DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - 1); // pos. of 1st arg.
- assert(impl_java_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
- if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
-- init_BoundMethodHandle_with_receiver(mh, m(),
-+ KlassHandle receiver_limit(THREAD, receiver_limit_oop);
-+ init_BoundMethodHandle_with_receiver(mh, m,
- receiver_limit, decode_flags,
- CHECK);
- return;
-@@ -1409,84 +1494,14 @@
- if (!direct_to_method)
- impl_java_dyn_BoundMethodHandle::set_vmtarget(mh(), target());
-
-+ if (VerifyMethodHandles) {
-+ verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK);
-+ }
-+
- // Next question: Is this a ref, int, or long bound value?
-- oop target_mtype = java_dyn_MethodHandle::type(target());
-- klassOop ptype_klass = NULL;
-- oop ptype_oop = java_dyn_MethodType::ptype(target_mtype, argnum);
-- BasicType ptype = java_lang_Class::as_BasicType(ptype_oop, &ptype_klass);
-- assert(ptype != T_ARRAY && ptype != T_VOID, "does not appear here");
-+ oop ptype_oop = java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum);
-+ BasicType ptype = java_lang_Class::as_BasicType(ptype_oop);
- int slots_pushed = type2size[ptype];
-- if (VerifyMethodHandles) {
-- oop argument = impl_java_dyn_BoundMethodHandle::argument(mh());
-- const char* err = NULL;
-- switch (ptype) {
-- case T_OBJECT:
-- if (argument != NULL)
-- // we must implicitly convert from the arg type to the outgoing ptype
-- err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass, argnum);
-- break;
-- case T_ARRAY: case T_VOID:
-- assert(false, "array, void do not appear here");
-- default:
-- if (ptype != T_INT && !is_subword_type(ptype)) {
-- err = "unexpected parameter type";
-- break;
-- }
-- // check subrange of Integer.value, if necessary
-- if (argument == NULL || argument->klass() != SystemDictionary::int_klass()) {
-- err = "bound integer argument must be of type java.lang.Integer";
-- break;
-- }
-- if (ptype != T_INT) {
-- int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
-- jint value = argument->int_field(value_offset);
-- int vminfo = adapter_subword_vminfo(ptype);
-- jint subword = truncate_subword_from_vminfo(value, vminfo);
-- if (value != subword) {
-- err = "bound subword value does not fit into the subword type";
-- break;
-- }
-- }
-- break;
-- case T_FLOAT:
-- case T_DOUBLE:
-- case T_LONG:
-- {
-- // we must implicitly convert from the unboxed arg type to the outgoing ptype
-- BasicType argbox = java_lang_boxing_object::basic_type(argument);
-- if (argbox != ptype) {
-- err = check_argument_type_change(T_OBJECT, (argument == NULL
-- ? SystemDictionary::object_klass()
-- : argument->klass()),
-- ptype, ptype_klass, argnum);
-- assert(err != NULL, "this must be an error");
-- }
-- break;
-- }
-- }
--
-- if (err == NULL) {
-- DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-- if (direct_to_method) {
-- assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
-- assert(slots_pushed <= MethodHandlePushLimit, "");
-- } else {
-- int prev_pushes = decode_MethodHandle_stack_pushes(target());
-- assert(this_pushes == slots_pushed + prev_pushes, "BMH stack motion must be correct");
-- // do not blow the stack; use a Java-based adapter if this limit is exceeded
-- if (slots_pushed + prev_pushes > MethodHandlePushLimit)
-- err = "too many bound parameters";
-- }
-- }
--
-- if (err != NULL)
-- { throw_InternalError(err, CHECK); }
--
-- // Verify the rest of the method type.
-- verify_method_type_insertion(java_dyn_MethodHandle::type(mh()),
-- argnum, ptype_oop,
-- java_dyn_MethodHandle::type(target()), CHECK);
-- }
-
- MethodHandleEntry* me = NULL;
- if (ptype == T_OBJECT) {
-@@ -1506,275 +1521,313 @@
- java_dyn_MethodHandle::set_vmentry(mh(), me);
- }
-
--void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
-+static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) {
-+ char msg[200];
-+ jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err);
-+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg);
-+}
-+
-+void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
- jint conversion = impl_java_dyn_AdapterMethodHandle::conversion(mh());
-- oop argument = impl_java_dyn_AdapterMethodHandle::argument(mh());
- int argslot = impl_java_dyn_AdapterMethodHandle::vmargslot(mh());
-
-- // adjust the adapter code to the internal EntryKind enumeration:
-- AdapterKind ak = adapter_conversion_op(conversion);
-- EntryKind ek = (EntryKind)(MethodHandles::_adapter_mh_first + (int)ak);
-+ verify_vmargslot(mh, argnum, argslot, CHECK);
-+ verify_vmslots(mh, CHECK);
-
-- if (ak < _adapt_retype_only || ak > _AK_LIMIT)
-- { throw_InternalError("bad conversion", CHECK); }
--
-- // Finalize the vmtarget field (Java initialized it to null).
-- impl_java_dyn_AdapterMethodHandle::set_vmtarget(mh(), target());
-+ jint conv_op = adapter_conversion_op(conversion);
-+ if (!conv_op_valid(conv_op)) {
-+ throw_InternalError_for_bad_conversion(conversion, "unknown conversion op", THREAD);
-+ return;
-+ }
-+ EntryKind ek = adapter_entry_kind(conv_op);
-
- int stack_move = adapter_conversion_stack_move(conversion);
- BasicType src = adapter_conversion_src_type(conversion);
- BasicType dest = adapter_conversion_dest_type(conversion);
- int vminfo = adapter_conversion_vminfo(conversion); // should be zero
-
-- if (VerifyMethodHandles) {
-- verify_vmargslot(mh, argnum, argslot, CHECK);
-- verify_vmslots(mh, CHECK);
-+ Handle argument(THREAD, impl_java_dyn_AdapterMethodHandle::argument(mh()));
-+ Handle target(THREAD, impl_java_dyn_AdapterMethodHandle::vmtarget(mh()));
-+ Handle src_mtype(THREAD, java_dyn_MethodHandle::type(mh()));
-+ Handle dst_mtype(THREAD, java_dyn_MethodHandle::type(target()));
-
-- const char* err = NULL;
-+ const char* err = NULL;
-
-- if (err == NULL) {
-- if (!java_dyn_MethodHandle::is_instance(target()))
-- err = "adapter target is not a method handle";
-+ if (err == NULL) {
-+ // Check that the correct argument is supplied, but only if it is required.
-+ switch (ek) {
-+ case _adapter_check_cast: // target type of cast
-+ case _adapter_ref_to_prim: // wrapper type from which to unbox
-+ case _adapter_prim_to_ref: // wrapper type to box into
-+ case _adapter_collect_args: // array type to collect into
-+ case _adapter_spread_args: // array type to spread from
-+ if (!java_lang_Class::is_instance(argument())
-+ || java_lang_Class::is_primitive(argument()))
-+ { err = "adapter requires argument of type java.lang.Class"; break; }
-+ if (ek == _adapter_collect_args ||
-+ ek == _adapter_spread_args) {
-+ // Make sure it is a suitable collection type. (Array, for now.)
-+ Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument()));
-+ if (!ak->oop_is_objArray()) {
-+ { err = "adapter requires argument of type java.lang.Class<Object[]>"; break; }
-+ }
-+ }
-+ break;
-+ case _adapter_flyby:
-+ case _adapter_ricochet:
-+ if (!java_dyn_MethodHandle::is_instance(argument()))
-+ { err = "MethodHandle adapter argument required"; break; }
-+ break;
-+ default:
-+ if (argument.not_null())
-+ { err = "adapter has spurious argument"; break; }
-+ break;
- }
-+ }
-
-- if (err == NULL) {
-- // Check that the correct argument is supplied, but only if it is required.
-- switch (ak) {
-- case _adapt_check_cast: // target type of cast
-- case _adapt_ref_to_prim: // wrapper type from which to unbox
-- case _adapt_prim_to_ref: // wrapper type to box into
-- case _adapt_collect_args: // array type to collect into
-- case _adapt_spread_args: // array type to spread from
-- if (!java_lang_Class::is_instance(argument)
-- || java_lang_Class::is_primitive(argument))
-- { err = "adapter requires argument of type java.lang.Class"; break; }
-- if (ak == _adapt_collect_args ||
-- ak == _adapt_spread_args) {
-- // Make sure it is a suitable collection type. (Array, for now.)
-- Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument));
-- if (!ak->oop_is_objArray()) {
-- { err = "adapter requires argument of type java.lang.Class<Object[]>"; break; }
-+ if (err == NULL) {
-+ // Check that the src/dest types are supplied if needed.
-+ switch (ek) {
-+ case _adapter_prim_to_prim:
-+ if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
-+ err = "adapter requires primitive src/dest conversion subfields"; break;
-+ }
-+ if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
-+ !(src == T_FLOAT || src == T_DOUBLE) && (dest == T_FLOAT || dest == T_DOUBLE)) {
-+ err = "adapter cannot convert beween floating and fixed-point"; break;
-+ }
-+ break;
-+ case _adapter_ref_to_prim:
-+ if (src != T_OBJECT || !is_java_primitive(dest)
-+ || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
-+ err = "adapter requires primitive dest conversion subfield"; break;
-+ }
-+ break;
-+ case _adapter_prim_to_ref:
-+ if (!is_java_primitive(src) || dest != T_OBJECT
-+ || argument() != Klass::cast(SystemDictionary::box_klass(src))->java_mirror()) {
-+ err = "adapter requires primitive src conversion subfield"; break;
-+ }
-+ break;
-+ case _adapter_swap_args:
-+ case _adapter_rot_args:
-+ {
-+ if (!src || src != dest) {
-+ err = "adapter requires src/dest conversion subfields for swap"; break;
-+ }
-+ int swap_size = type2size[src];
-+ oop src_mtype = impl_java_dyn_AdapterMethodHandle::type(target());
-+ oop dest_mtype = impl_java_dyn_AdapterMethodHandle::type(mh());
-+ int slot_limit = impl_java_dyn_AdapterMethodHandle::vmslots(src_mtype);
-+ int src_slot = argslot;
-+ int dest_slot = vminfo;
-+ bool rotate_up = (src_slot > dest_slot); // upward rotation
-+ int src_arg = argnum;
-+ int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot);
-+ verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
-+ if (!(dest_slot >= src_slot + swap_size) &&
-+ !(src_slot >= dest_slot + swap_size)) {
-+ err = "source, destination slots must be distinct";
-+ } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
-+ err = "source of swap must be deeper in stack";
-+ } else if (ek == _adapter_swap_args) {
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, dest_arg),
-+ java_dyn_MethodType::ptype(dest_mtype, src_arg),
-+ dest_arg);
-+ } else if (ek == _adapter_rot_args) {
-+ if (rotate_up) {
-+ assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
-+ // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
-+ // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
-+ for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
-+ java_dyn_MethodType::ptype(dest_mtype, i-1),
-+ i);
-+ }
-+ } else { // rotate down
-+ assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
-+ // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
-+ // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
-+ for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
-+ java_dyn_MethodType::ptype(dest_mtype, i+1),
-+ i);
-+ }
- }
- }
-- break;
-- case _adapt_flyby:
-- case _adapt_ricochet:
-- if (!java_dyn_MethodHandle::is_instance(argument))
-- { err = "MethodHandle adapter argument required"; break; }
-- break;
-- default:
-- if (argument != NULL)
-- { err = "adapter has spurious argument"; break; }
-- break;
-+ if (err == NULL)
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, src_arg),
-+ java_dyn_MethodType::ptype(dest_mtype, dest_arg),
-+ src_arg);
-+ }
-+ break;
-+ case _adapter_collect_args:
-+ case _adapter_spread_args:
-+ {
-+ BasicType coll_type = (ek == _adapter_collect_args) ? dest : src;
-+ BasicType elem_type = (ek == _adapter_collect_args) ? src : dest;
-+ if (coll_type != T_OBJECT || elem_type != T_OBJECT) {
-+ err = "adapter requires src/dest subfields"; break;
-+ // later:
-+ // - consider making coll be a primitive array
-+ // - consider making coll be a heterogeneous collection
-+ }
-+ }
-+ break;
-+ default:
-+ if (src != 0 || dest != 0) {
-+ err = "adapter has spurious src/dest conversion subfields"; break;
-+ }
-+ break;
-+ }
-+ }
-+
-+ if (err == NULL) {
-+ // Check the stack_move subfield.
-+ // It must always report the net change in stack size, positive or negative.
-+ int slots_pushed = stack_move / stack_move_unit();
-+ switch (ek) {
-+ case _adapter_prim_to_prim:
-+ case _adapter_ref_to_prim:
-+ case _adapter_prim_to_ref:
-+ if (slots_pushed != type2size[dest] - type2size[src]) {
-+ err = "wrong stack motion for primitive conversion";
-+ }
-+ break;
-+ case _adapter_dup_args:
-+ if (slots_pushed <= 0) {
-+ err = "adapter requires conversion subfield slots_pushed > 0";
-+ }
-+ break;
-+ case _adapter_drop_args:
-+ if (slots_pushed >= 0) {
-+ err = "adapter requires conversion subfield slots_pushed < 0";
-+ }
-+ break;
-+ case _adapter_collect_args:
-+ if (slots_pushed > 1) {
-+ err = "adapter requires conversion subfield slots_pushed <= 1";
-+ }
-+ break;
-+ case _adapter_spread_args:
-+ if (slots_pushed < -1) {
-+ err = "adapter requires conversion subfield slots_pushed >= -1";
-+ }
-+ break;
-+ default:
-+ if (stack_move != 0) {
-+ err = "adapter has spurious stack_move conversion subfield";
-+ }
-+ break;
-+ }
-+ if (err == NULL && stack_move != slots_pushed * stack_move_unit()) {
-+ err = "stack_move conversion subfield must be multiple of stack_move_unit";
-+ }
-+ }
-+
-+ if (err == NULL) {
-+ // Make sure this adapter does not push too deeply.
-+ int slots_pushed = stack_move / stack_move_unit();
-+ int this_vmslots = java_dyn_MethodHandle::vmslots(mh());
-+ int prev_vmslots = java_dyn_MethodHandle::vmslots(target());
-+ if (slots_pushed != (this_vmslots - prev_vmslots)) {
-+ err = "stack_move inconsistent with previous and current MethodType vmslots";
-+ } else if (slots_pushed > 0) {
-+ // verify stack_move against MethodHandlePushLimit
-+ int prev_pushes = decode_MethodHandle_stack_pushes(target());
-+ // do not blow the stack; use a Java-based adapter if this limit is exceeded
-+ if (slots_pushed + prev_pushes > MethodHandlePushLimit) {
-+ err = "adapter pushes too many parameters";
- }
- }
-
-- if (err == NULL) {
-- // Check that the src/dest types are supplied if needed.
-- switch (ak) {
-- case _adapt_prim_to_prim:
-- if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
-- err = "adapter requires primitive src/dest conversion subfields"; break;
-- }
-- if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
-- !(src == T_FLOAT || src == T_DOUBLE) && (dest == T_FLOAT || dest == T_DOUBLE)) {
-- err = "adapter cannot convert beween floating and fixed-point"; break;
-- }
-- break;
-- case _adapt_ref_to_prim:
-- if (src != T_OBJECT || !is_java_primitive(dest)
-- || argument != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
-- err = "adapter requires primitive dest conversion subfield"; break;
-- }
-- break;
-- case _adapt_prim_to_ref:
-- if (!is_java_primitive(src) || dest != T_OBJECT
-- || argument != Klass::cast(SystemDictionary::box_klass(src))->java_mirror()) {
-- err = "adapter requires primitive src conversion subfield"; break;
-- }
-- break;
-- case _adapt_swap_args:
-- case _adapt_rot_args:
-- {
-- if (!src || src != dest) {
-- err = "adapter requires src/dest conversion subfields for swap"; break;
-- }
-- int swap_size = type2size[src];
-- oop src_mtype = impl_java_dyn_AdapterMethodHandle::type(target());
-- oop dest_mtype = impl_java_dyn_AdapterMethodHandle::type(mh());
-- int slot_limit = impl_java_dyn_AdapterMethodHandle::vmslots(src_mtype);
-- int src_slot = argslot;
-- int dest_slot = vminfo;
-- bool rotate_up = (src_slot > dest_slot); // upward rotation
-- int src_arg = argnum;
-- int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot);
-- verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
-- if (!(dest_slot >= src_slot + swap_size) &&
-- !(src_slot >= dest_slot + swap_size)) {
-- err = "source, destination slots must be distinct";
-- } else if (ak == _adapt_swap_args && !(src_slot > dest_slot)) {
-- err = "source of swap must be deeper in stack";
-- } else if (ak == _adapt_swap_args) {
-- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, dest_arg),
-- java_dyn_MethodType::ptype(dest_mtype, src_arg),
-- dest_arg);
-- } else if (ak == _adapt_rot_args) {
-- if (rotate_up) {
-- assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
-- // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
-- // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
-- for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
-- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
-- java_dyn_MethodType::ptype(dest_mtype, i-1),
-- i);
-- }
-- } else { // rotate down
-- assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
-- // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
-- // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
-- for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
-- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i),
-- java_dyn_MethodType::ptype(dest_mtype, i+1),
-- i);
-- }
-- }
-- }
-- if (err == NULL)
-- err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, src_arg),
-- java_dyn_MethodType::ptype(dest_mtype, dest_arg),
-- src_arg);
-- }
-- break;
-- case _adapt_collect_args:
-- case _adapt_spread_args:
-- {
-- BasicType coll_type = (ak == _adapt_collect_args) ? dest : src;
-- BasicType elem_type = (ak == _adapt_collect_args) ? src : dest;
-- if (coll_type != T_OBJECT || elem_type != T_OBJECT) {
-- err = "adapter requires src/dest subfields"; break;
-- // later:
-- // - consider making coll be a primitive array
-- // - consider making coll be a heterogeneous collection
-- }
-- }
-- break;
-- default:
-- if (src != 0 || dest != 0) {
-- err = "adapter has spurious src/dest conversion subfields"; break;
-- }
-- break;
-- }
-- }
--
-- if (err == NULL) {
-- // Check the stack_move subfield.
-- // It must always report the net change in stack size, positive or negative.
-- int slots_pushed = stack_move / stack_move_unit();
-- switch (ak) {
-- case _adapt_prim_to_prim:
-- case _adapt_ref_to_prim:
-- case _adapt_prim_to_ref:
-- if (slots_pushed != type2size[dest] - type2size[src]) {
-- err = "wrong stack motion for primitive conversion";
-- }
-- break;
-- case _adapt_dup_args:
-- if (slots_pushed <= 0) {
-- err = "adapter requires conversion subfield slots_pushed > 0";
-- }
-- break;
-- case _adapt_drop_args:
-- if (slots_pushed >= 0) {
-- err = "adapter requires conversion subfield slots_pushed < 0";
-- }
-- break;
-- case _adapt_collect_args:
-- if (slots_pushed > 1) {
-- err = "adapter requires conversion subfield slots_pushed <= 1";
-- }
-- break;
-- case _adapt_spread_args:
-- if (slots_pushed < -1) {
-- err = "adapter requires conversion subfield slots_pushed >= -1";
-- }
-- break;
-- default:
-- if (stack_move != 0) {
-- err = "adapter has spurious stack_move conversion subfield";
-- }
-- break;
-- }
-- if (err == NULL && stack_move != slots_pushed * stack_move_unit()) {
-- err = "stack_move conversion subfield must be multiple of stack_move_unit";
-- }
-- }
--
-- if (err == NULL) {
-- // Make sure this adapter does not push too deeply.
-- int slots_pushed = stack_move / stack_move_unit();
-- int this_vmslots = java_dyn_MethodHandle::vmslots(mh());
-- int prev_vmslots = java_dyn_MethodHandle::vmslots(target());
-- if (slots_pushed != (this_vmslots - prev_vmslots)) {
-- err = "stack_move inconsistent with previous and current MethodType vmslots";
-- } else if (slots_pushed > 0) {
-- // verify stack_move against MethodHandlePushLimit
-- int prev_pushes = decode_MethodHandle_stack_pushes(target());
-- // do not blow the stack; use a Java-based adapter if this limit is exceeded
-- if (slots_pushed + prev_pushes > MethodHandlePushLimit) {
-- err = "adapter pushes too many parameters";
-- }
-- }
--
-- // While we're at it, check that the stack motion decoder works:
-- DEBUG_ONLY(int prev_pushes = decode_MethodHandle_stack_pushes(target()));
-- DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-- assert(this_pushes == slots_pushed + prev_pushes, "AMH stack motion must be correct");
-- }
--
-- if (err == NULL && vminfo != 0) {
-- switch (ak) {
-- case _adapt_swap_args:
-- case _adapt_rot_args:
-- break; // OK
-- default:
-- err = "vminfo subfield is reserved to the JVM";
-- }
-- }
--
-- if (err != NULL) { throw_InternalError(err, CHECK); }
-+ // While we're at it, check that the stack motion decoder works:
-+ DEBUG_ONLY(int prev_pushes = decode_MethodHandle_stack_pushes(target()));
-+ DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-+ assert(this_pushes == slots_pushed + prev_pushes, "AMH stack motion must be correct");
- }
-
-- // Here are the source and destination types, if we need to look at them.
-- Handle src_mtype, dst_mtype;
-- if (VerifyMethodHandles) {
-- src_mtype = Handle(THREAD, java_dyn_MethodHandle::type(mh()));
-- dst_mtype = Handle(THREAD, java_dyn_MethodHandle::type(target()));
-+ if (err == NULL && vminfo != 0) {
-+ switch (ek) {
-+ case _adapter_swap_args:
-+ case _adapter_rot_args:
-+ break; // OK
-+ default:
-+ err = "vminfo subfield is reserved to the JVM";
-+ }
- }
-
-+ // Do additional ad hoc checks.
-+ if (err == NULL) {
-+ switch (ek) {
-+ case _adapter_retype_only:
-+ err = check_method_type_passthrough(src_mtype(), dst_mtype());
-+ break;
-+
-+ case _adapter_check_cast:
-+ {
-+ // The actual value being checked must be a reference:
-+ err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype(), argnum),
-+ object_java_mirror(), argnum);
-+ if (err != NULL) break;
-+
-+ // The output of the cast must fit with the destination argument:
-+ Handle cast_class = argument;
-+ err = check_method_type_conversion(src_mtype(),
-+ argnum, cast_class(),
-+ dst_mtype());
-+ }
-+ break;
-+
-+ // %%% TO DO: continue in remaining cases to verify src/dst_mtype if VerifyMethodHandles
-+ }
-+ }
-+
-+ if (err != NULL) {
-+ throw_InternalError_for_bad_conversion(conversion, err, THREAD);
-+ return;
-+ }
-+
-+}
-+
-+void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
-+ oop argument = impl_java_dyn_AdapterMethodHandle::argument(mh());
-+ int argslot = impl_java_dyn_AdapterMethodHandle::vmargslot(mh());
-+ jint conversion = impl_java_dyn_AdapterMethodHandle::conversion(mh());
-+ jint conv_op = adapter_conversion_op(conversion);
-+
-+ // adjust the adapter code to the internal EntryKind enumeration:
-+ EntryKind ek_orig = adapter_entry_kind(conv_op);
-+ EntryKind ek_opt = ek_orig; // may be optimized
-+
-+ // Finalize the vmtarget field (Java initialized it to null).
-+ if (!java_dyn_MethodHandle::is_instance(target())) {
-+ throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD);
-+ return;
-+ }
-+ impl_java_dyn_AdapterMethodHandle::set_vmtarget(mh(), target());
-+
-+ if (VerifyMethodHandles) {
-+ verify_AdapterMethodHandle(mh, argnum, CHECK);
-+ }
-+
-+ int stack_move = adapter_conversion_stack_move(conversion);
-+ BasicType src = adapter_conversion_src_type(conversion);
-+ BasicType dest = adapter_conversion_dest_type(conversion);
-+ int vminfo = adapter_conversion_vminfo(conversion); // should be zero
-+
-+ const char* err = NULL;
-+
- // Now it's time to finish the case analysis and pick a MethodHandleEntry.
-- switch (ak) {
-- case _adapt_retype_only:
-- if (VerifyMethodHandles) {
-- verify_method_type_passthrough(src_mtype(), dst_mtype(), CHECK);
-- }
-+ switch (ek_orig) {
-+ case _adapter_retype_only:
-+ case _adapter_check_cast:
-+ case _adapter_dup_args:
-+ case _adapter_drop_args:
-+ // these work fine via general case code
- break;
-
-- case _adapt_check_cast:
-- if (VerifyMethodHandles) {
-- // The actual value being checked must be a reference:
-- verify_argument_type_change(java_dyn_MethodType::ptype(src_mtype(), argnum),
-- object_java_mirror(), argnum, CHECK);
-- // The output of the cast must fit with the destination argument:
-- oop cast_class = argument;
-- verify_method_type_conversion(src_mtype(),
-- argnum, cast_class,
-- dst_mtype(), CHECK);
-- }
-- break;
--
-- // %%% TO DO: continue in remaining cases to verify src/dst_mtype if VerifyMethodHandles
--
-- case _adapt_prim_to_prim:
-+ case _adapter_prim_to_prim:
- {
- // Non-subword cases are {int,float,long,double} -> {int,float,long,double}.
- // And, the {float,double} -> {int,long} cases must be handled by Java.
-@@ -1782,24 +1835,24 @@
- case 1 *4+ 1:
- assert(src == T_INT || is_subword_type(src), "source is not float");
- // Subword-related cases are int -> {boolean,byte,char,short}.
-- ek = _adapter_opt_i2i;
-+ ek_opt = _adapter_opt_i2i;
- vminfo = adapter_subword_vminfo(dest);
- break;
- case 2 *4+ 1:
- if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) {
-- ek = _adapter_opt_l2i;
-+ ek_opt = _adapter_opt_l2i;
- vminfo = adapter_subword_vminfo(dest);
- } else if (src == T_DOUBLE && dest == T_FLOAT) {
-- ek = _adapter_opt_d2f;
-+ ek_opt = _adapter_opt_d2f;
- } else {
- assert(false, "");
- }
- break;
- case 1 *4+ 2:
- if (src == T_INT && dest == T_LONG) {
-- ek = _adapter_opt_i2l;
-+ ek_opt = _adapter_opt_i2l;
- } else if (src == T_FLOAT && dest == T_DOUBLE) {
-- ek = _adapter_opt_f2d;
-+ ek_opt = _adapter_opt_f2d;
- } else {
- assert(false, "");
- }
-@@ -1811,15 +1864,15 @@
- }
- break;
-
-- case _adapt_ref_to_prim:
-+ case _adapter_ref_to_prim:
- {
- switch (type2size[dest]) {
- case 1:
-- ek = _adapter_opt_a2i;
-+ ek_opt = _adapter_opt_unboxi;
- vminfo = adapter_subword_vminfo(dest);
- break;
- case 2:
-- ek = _adapter_opt_a2l;
-+ ek_opt = _adapter_opt_unboxl;
- break;
- default:
- assert(false, "");
-@@ -1828,26 +1881,26 @@
- }
- break;
-
-- case _adapt_prim_to_ref:
-+ case _adapter_prim_to_ref:
- goto throw_not_impl; // allocates, hence could block
-
-- case _adapt_swap_args:
-- case _adapt_rot_args:
-+ case _adapter_swap_args:
-+ case _adapter_rot_args:
- {
- int swap_slots = type2size[src];
- oop mtype = impl_java_dyn_AdapterMethodHandle::type(mh());
- int slot_limit = impl_java_dyn_AdapterMethodHandle::vmslots(mtype);
- int src_slot = argslot;
- int dest_slot = vminfo;
-- int rotate = (ak == _adapt_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
-+ int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
- switch (swap_slots) {
- case 1:
-- ek = (!rotate ? _adapter_opt_swap_1 :
-- rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
-+ ek_opt = (!rotate ? _adapter_opt_swap_1 :
-+ rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
- break;
- case 2:
-- ek = (!rotate ? _adapter_opt_swap_2 :
-- rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
-+ ek_opt = (!rotate ? _adapter_opt_swap_2 :
-+ rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
- break;
- default:
- assert(false, "");
-@@ -1856,15 +1909,10 @@
- }
- break;
-
-- case _adapt_dup_args:
-- case _adapt_drop_args:
-- // these work fine via general case code
-- break;
--
-- case _adapt_collect_args:
-+ case _adapter_collect_args:
- goto throw_not_impl; // allocates, hence could block
-
-- case _adapt_spread_args:
-+ case _adapter_spread_args:
- {
- // vminfo will be the required length of the array
- int slots_pushed = stack_move / stack_move_unit();
-@@ -1872,44 +1920,43 @@
- assert(array_size >= 0, "");
- vminfo = array_size;
- switch (array_size) {
-- case 0: ek = _adapt_opt_spread_0; break;
-- case 1: ek = _adapt_opt_spread_1; break;
-- default: ek = _adapt_opt_spread_more; break;
-+ case 0: ek_opt = _adapter_opt_spread_0; break;
-+ case 1: ek_opt = _adapter_opt_spread_1; break;
-+ default: ek_opt = _adapter_opt_spread_more; break;
- }
-- if ((vminfo & _CONV_VMINFO_MASK) != vminfo)
-+ if ((vminfo & CONV_VMINFO_MASK) != vminfo)
- goto throw_not_impl; // overflow
- }
- break;
-
-- case _adapt_flyby:
-- case _adapt_ricochet:
-+ case _adapter_flyby:
-+ case _adapter_ricochet:
- goto throw_not_impl; // runs Java code, hence could block
-
-+ default:
-+ // should have failed much earlier; must be a missing case here
-+ assert(false, "incomplete switch");
-+ // and fall through:
-+
- throw_not_impl:
- // FIXME: these adapters are NYI
-- throw_InternalError(adapter_entry_name(ak), CHECK);
-+ err = "adapter not yet implemented in the JVM";
-+ break;
-+ }
-+
-+ if (err != NULL) {
-+ throw_InternalError_for_bad_conversion(conversion, err, THREAD);
- return;
- }
-
- // Rebuild the conversion value; maybe parts of it were changed.
-- jint new_conversion = (((int)ak << _CONV_OP_SHIFT) |
-- (src << _CONV_SRC_TYPE_SHIFT) |
-- (dest << _CONV_DEST_TYPE_SHIFT) |
-- (stack_move << _CONV_STACK_MOVE_SHIFT) |
-- (vminfo << _CONV_VMINFO_SHIFT) );
--
-- // Take it apart again, just to make sure:
-- assert(adapter_conversion_op(new_conversion) == ak, "");
-- assert(adapter_conversion_vminfo(new_conversion) == vminfo, "");
-- assert(adapter_conversion_src_type(new_conversion) == src, "");
-- assert(adapter_conversion_dest_type(new_conversion) == dest, "");
-- assert(adapter_conversion_stack_move(new_conversion) == stack_move, "");
-+ jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo);
-
- // Finalize the conversion field. (Note that it is final to Java code.)
- impl_java_dyn_AdapterMethodHandle::set_conversion(mh(), new_conversion);
-
- // Done!
-- java_dyn_MethodHandle::set_vmentry(mh(), entry(ek));
-+ java_dyn_MethodHandle::set_vmentry(mh(), entry(ek_opt));
-
- // There should be enough memory barriers on exit from native methods
- // to ensure that the MH is fully initialized to all threads before
-@@ -1929,6 +1976,9 @@
- // They are the private interface between this JVM and the HotSpot-specific
- // Java code that implements JSR 292 method handles.
- //
-+// Note: We use a JVM_ENTRY macro to define each of these, for this is the way
-+// that intrinsic (non-JNI) native methods are defined in HotSpot.
-+//
-
- // direct method handles for invokestatic or invokespecial
- // void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller);
-@@ -1937,14 +1987,14 @@
- ResourceMark rm; // for error messages
-
- // This is the guy we are initializing:
-- if (mh_jh == NULL) { throw_InternalError(CHECK); }
-+ if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
- Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
-
- // Early returns out of this method leave the DMH in an unfinished state.
- assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
-
- // which method are we really talking about?
-- if (target_jh == NULL) { throw_InternalError(CHECK); }
-+ if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
- oop target_oop = JNIHandles::resolve_non_null(target_jh);
- if (impl_java_dyn_MemberName::is_instance(target_oop) &&
- impl_java_dyn_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) {
-@@ -1957,7 +2007,7 @@
- methodHandle m(THREAD,
- MethodHandles::decode_method(target_oop,
- receiver_limit, decode_flags));
-- if (m.is_null()) { throw_InternalError("no such method", CHECK); }
-+ if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
-
- // The trusted Java code that calls this method should already have performed
- // access checks on behalf of the given caller. But, we can verify this.
-@@ -1970,14 +2020,14 @@
- klassOop reference_klass = m->method_holder(); // OK approximation
- if (receiver_limit != NULL && receiver_limit != reference_klass) {
- if (!Klass::cast(receiver_limit)->is_subtype_of(reference_klass))
-- throw_InternalError("receiver limit out of bounds", CHECK); // Java code bug
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), "receiver limit out of bounds"); // Java code bug
- reference_klass = receiver_limit;
- }
- // Emulate LinkResolver::check_klass_accessability.
- if (!Reflection::verify_class_access(caller->as_klassOop(),
- reference_klass,
- true)) {
-- throw_InternalError(Klass::cast(m->method_holder())->external_name(), CHECK);
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(m->method_holder())->external_name());
- }
- // If there were a bytecode, the next step would be to lookup the method
- // in the reference class, then then check the method's access bits.
-@@ -1991,7 +2041,7 @@
- bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(),
- reference_klass, THREAD);
- if (!same_pm) {
-- throw_InternalError(m->name_and_sig_as_C_string(), CHECK);
-+ THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
- }
- }
- }
-@@ -2006,22 +2056,25 @@
- ResourceMark rm; // for error messages
-
- // This is the guy we are initializing:
-- if (mh_jh == NULL) { throw_InternalError(CHECK); }
-+ if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
- Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
-
- // Early returns out of this method leave the BMH in an unfinished state.
- assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
-
-- if (target_jh == NULL) { throw_InternalError(CHECK); }
-+ if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
- Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
-
- if (!java_dyn_MethodHandle::is_instance(target())) {
- // Target object is a reflective method. (%%% Do we need this alternate path?)
- Untested("init_BMH of non-MH");
-- if (argnum != 0) { throw_InternalError(CHECK); }
-- int decode_flags = 0; klassOop receiver_limit = NULL;
-- methodOop m = MethodHandles::decode_method(target(),
-- receiver_limit, decode_flags);
-+ if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
-+ int decode_flags = 0; klassOop receiver_limit_oop = NULL;
-+ methodHandle m(THREAD,
-+ MethodHandles::decode_method(target(),
-+ receiver_limit_oop,
-+ decode_flags));
-+ KlassHandle receiver_limit(THREAD, receiver_limit_oop);
- MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
- receiver_limit,
- decode_flags,
-@@ -2038,8 +2091,9 @@
- JVM_ENTRY(void, MHI_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
- jobject target_jh, int argnum)) {
- // This is the guy we are initializing:
-- if (mh_jh == NULL || target_jh == NULL)
-- { throw_InternalError(CHECK); }
-+ if (mh_jh == NULL || target_jh == NULL) {
-+ THROW(vmSymbols::java_lang_InternalError());
-+ }
- Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
- Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
-
-@@ -2072,9 +2126,10 @@
-
- // debugging and reflection
- JVM_ENTRY(jobject, MHI_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) {
-- oop mh = JNIHandles::resolve(mh_jh);
-- if (!java_dyn_MethodHandle::is_instance(mh))
-- { throw_IllegalArgumentException(THREAD); return NULL; }
-+ Handle mh(THREAD, JNIHandles::resolve(mh_jh));
-+ if (!java_dyn_MethodHandle::is_instance(mh())) {
-+ THROW_NULL(vmSymbols::java_lang_IllegalArgumentException());
-+ }
- oop target = MethodHandles::encode_target(mh, format, CHECK_NULL);
- return JNIHandles::make_local(THREAD, target);
- }
-@@ -2109,19 +2164,20 @@
- template(impl_java_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \
- template(impl_java_dyn_MemberName,MN_SEARCH_INTERFACES) \
- template(impl_java_dyn_MemberName,VM_INDEX_UNINITIALIZED) \
-- template(impl_java_dyn_AdapterMethodHandle,RETYPE_ONLY) \
-- template(impl_java_dyn_AdapterMethodHandle,CHECK_CAST) \
-- template(impl_java_dyn_AdapterMethodHandle,PRIM_TO_PRIM) \
-- template(impl_java_dyn_AdapterMethodHandle,REF_TO_PRIM) \
-- template(impl_java_dyn_AdapterMethodHandle,PRIM_TO_REF) \
-- template(impl_java_dyn_AdapterMethodHandle,SWAP_ARGS) \
-- template(impl_java_dyn_AdapterMethodHandle,ROT_ARGS) \
-- template(impl_java_dyn_AdapterMethodHandle,DUP_ARGS) \
-- template(impl_java_dyn_AdapterMethodHandle,DROP_ARGS) \
-- template(impl_java_dyn_AdapterMethodHandle,COLLECT_ARGS) \
-- template(impl_java_dyn_AdapterMethodHandle,SPREAD_ARGS) \
-- template(impl_java_dyn_AdapterMethodHandle,FLYBY) \
-- template(impl_java_dyn_AdapterMethodHandle,RICOCHET) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_CHECK_CAST) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_PRIM_TO_REF) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_SWAP_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_ROT_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_DUP_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_DROP_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_COLLECT_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_SPREAD_ARGS) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_FLYBY) \
-+ template(impl_java_dyn_AdapterMethodHandle,OP_RICOCHET) \
-+ template(impl_java_dyn_AdapterMethodHandle,CONV_OP_LIMIT) \
- template(impl_java_dyn_AdapterMethodHandle,CONV_OP_MASK) \
- template(impl_java_dyn_AdapterMethodHandle,CONV_VMINFO_MASK) \
- template(impl_java_dyn_AdapterMethodHandle,CONV_VMINFO_SHIFT) \
-@@ -2166,7 +2222,7 @@
-
- // void init(MemberName self, AccessibleObject ref)
- JVM_ENTRY(void, MHI_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
-- if (mname_jh == NULL || target_jh == NULL) { throw_InternalError(CHECK); }
-+ if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
- Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
- oop target_oop = JNIHandles::resolve_non_null(target_jh);
- MethodHandles::init_MemberName(mname(), target_oop);
-@@ -2175,7 +2231,7 @@
-
- // void expand(MemberName self)
- JVM_ENTRY(void, MHI_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
-- if (mname_jh == NULL) { throw_InternalError(CHECK); }
-+ if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
- Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
- MethodHandles::expand_MemberName(mname, 0, CHECK);
- }
-@@ -2183,7 +2239,7 @@
-
- // void resolve(MemberName self, Class<?> caller)
- JVM_ENTRY(void, MHI_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
-- if (mname_jh == NULL) { throw_InternalError(CHECK); }
-+ if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
- Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
- // %%% take caller into account!
- MethodHandles::resolve_MemberName(mname, CHECK);
-diff --git a/src/share/vm/prims/methodHandles.hpp b/src/share/vm/prims/methodHandles.hpp
---- a/src/share/vm/prims/methodHandles.hpp
-+++ b/src/share/vm/prims/methodHandles.hpp
-@@ -31,31 +31,6 @@
- // in java.dyn and java.dyn.hotspot.
- // See also javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}.
- public:
-- enum AdapterKind {
-- // these constants must align with a set of values in impl/java/dyn/AMH.java:
-- _adapt_retype_only = 0x0, // no argument changes; straight retype
-- _adapt_check_cast = 0x1, // ref-to-ref conversion; requires a Class argument
-- _adapt_prim_to_prim = 0x2, // converts from one primitive to another
-- _adapt_ref_to_prim = 0x3, // unboxes a wrapper to produce a primitive
-- _adapt_prim_to_ref = 0x4, // boxes a primitive into a wrapper (NYI)
-- _adapt_swap_args = 0x5, // permutes arguments (NYI)
-- _adapt_rot_args = 0x6, // permutes arguments (NYI)
-- _adapt_dup_args = 0x7, // duplicates one or more arguments (at TOS)
-- _adapt_drop_args = 0x8, // remove one or more argument slots
-- _adapt_collect_args = 0x9, // combine one or more arguments into a varargs (NYI)
-- _adapt_spread_args = 0xA, // expand in place a varargs array (of known size)
-- _adapt_flyby = 0xB, // operate first on reified argument list (NYI)
-- _adapt_ricochet = 0xC, // run an adapter chain on the return value (NYI)
-- _AK_LIMIT
-- };
-- enum { // format of AMH.conversion field
-- _CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
-- _CONV_VMINFO_SHIFT = 0, // position of bits in CONV_VMINFO_MASK
-- _CONV_OP_SHIFT = 8, // position of bits in CONV_OP_MASK
-- _CONV_DEST_TYPE_SHIFT = 12, // byte 3 has the target BasicType (if needed)
-- _CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed)
-- _CONV_STACK_MOVE_SHIFT = 20 // high 12 bits give signed SP change
-- };
- enum EntryKind {
- _check_mtype, // how a caller calls a MH
- _wrong_method_type, // what happens when there is a type mismatch
-@@ -70,8 +45,21 @@
- _bound_int_direct_mh,
- _bound_long_direct_mh,
-
-- _adapter_mh_first, // adapter sequence goes here...
-- _adapter_mh_last = _adapter_mh_first + (_AK_LIMIT - 1),
-+ _adapter_mh_first, // adapter sequence goes here...
-+ _adapter_retype_only = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_RETYPE_ONLY,
-+ _adapter_check_cast = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_CHECK_CAST,
-+ _adapter_prim_to_prim = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM,
-+ _adapter_ref_to_prim = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_REF_TO_PRIM,
-+ _adapter_prim_to_ref = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_PRIM_TO_REF,
-+ _adapter_swap_args = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_SWAP_ARGS,
-+ _adapter_rot_args = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_ROT_ARGS,
-+ _adapter_dup_args = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_DUP_ARGS,
-+ _adapter_drop_args = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_DROP_ARGS,
-+ _adapter_collect_args = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_COLLECT_ARGS,
-+ _adapter_spread_args = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_SPREAD_ARGS,
-+ _adapter_flyby = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_FLYBY,
-+ _adapter_ricochet = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::OP_RICOCHET,
-+ _adapter_mh_last = _adapter_mh_first + impl_java_dyn_AdapterMethodHandle::CONV_OP_LIMIT - 1,
-
- // Optimized adapter types
-
-@@ -93,13 +81,13 @@
- // conversion between floating point and integer type is handled by Java
-
- // reference to primitive:
-- _adapter_opt_a2i,
-- _adapter_opt_a2l,
-+ _adapter_opt_unboxi,
-+ _adapter_opt_unboxl,
-
- // spreading (array length cases 0, 1, >=2)
-- _adapt_opt_spread_0,
-- _adapt_opt_spread_1,
-- _adapt_opt_spread_more,
-+ _adapter_opt_spread_0,
-+ _adapter_opt_spread_1,
-+ _adapter_opt_spread_more,
-
- _EK_LIMIT,
- _EK_FIRST = 0
-@@ -110,11 +98,23 @@
- static void set_enabled(bool z);
-
- private:
-+ enum { // import impl_java_dyn_AdapterMethodHandle::CONV_OP_*
-+ CONV_OP_LIMIT = impl_java_dyn_AdapterMethodHandle::CONV_OP_LIMIT,
-+ CONV_OP_MASK = impl_java_dyn_AdapterMethodHandle::CONV_OP_MASK,
-+ CONV_VMINFO_MASK = impl_java_dyn_AdapterMethodHandle::CONV_VMINFO_MASK,
-+ CONV_VMINFO_SHIFT = impl_java_dyn_AdapterMethodHandle::CONV_VMINFO_SHIFT,
-+ CONV_OP_SHIFT = impl_java_dyn_AdapterMethodHandle::CONV_OP_SHIFT,
-+ CONV_DEST_TYPE_SHIFT = impl_java_dyn_AdapterMethodHandle::CONV_DEST_TYPE_SHIFT,
-+ CONV_SRC_TYPE_SHIFT = impl_java_dyn_AdapterMethodHandle::CONV_SRC_TYPE_SHIFT,
-+ CONV_STACK_MOVE_SHIFT = impl_java_dyn_AdapterMethodHandle::CONV_STACK_MOVE_SHIFT,
-+ CONV_STACK_MOVE_MASK = impl_java_dyn_AdapterMethodHandle::CONV_STACK_MOVE_MASK
-+ };
-+
- static bool _enabled;
- static MethodHandleEntry* _entries[_EK_LIMIT];
- static const char* _entry_names[_EK_LIMIT+1];
- static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; }
-- static bool ak_valid(AdapterKind ak) { return (uint)ak < (uint)_AK_LIMIT; }
-+ static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; }
-
- public:
- static bool have_entry(EntryKind ek) { return ek_valid(ek) && _entries[ek] != NULL; }
-@@ -122,8 +122,8 @@
- return _entries[ek]; }
- static const char* entry_name(EntryKind ek) { assert(ek_valid(ek), "oob");
- return _entry_names[ek]; }
-- static const char* adapter_entry_name(AdapterKind ak) { assert(ak_valid(ak), "oob");
-- return entry_name(EntryKind(_adapter_mh_first + (int)ak)); }
-+ static EntryKind adapter_entry_kind(int op) { assert(conv_op_valid(op), "oob");
-+ return EntryKind(_adapter_mh_first + op); }
-
- static void init_entry(EntryKind ek, MethodHandleEntry* me) {
- assert(ek_valid(ek), "oob");
-@@ -131,29 +131,36 @@
- _entries[ek] = me;
- }
-
-- static jint adapter_conversion(AdapterKind ak, BasicType src, BasicType dest,
-+ static jint adapter_conversion(int conv_op, BasicType src, BasicType dest,
- int stack_move = 0, int vminfo = 0) {
-- return (((int)ak << _CONV_OP_SHIFT)
-- | (src << _CONV_SRC_TYPE_SHIFT)
-- | (dest << _CONV_DEST_TYPE_SHIFT)
-- | (stack_move << _CONV_STACK_MOVE_SHIFT)
-- | (vminfo << _CONV_VMINFO_SHIFT)
-- );
-+ assert(conv_op_valid(conv_op), "oob");
-+ jint conv = ((conv_op << CONV_OP_SHIFT)
-+ | (src << CONV_SRC_TYPE_SHIFT)
-+ | (dest << CONV_DEST_TYPE_SHIFT)
-+ | (stack_move << CONV_STACK_MOVE_SHIFT)
-+ | (vminfo << CONV_VMINFO_SHIFT)
-+ );
-+ assert(adapter_conversion_op(conv) == conv_op, "decode conv_op");
-+ assert(adapter_conversion_src_type(conv) == src, "decode src");
-+ assert(adapter_conversion_dest_type(conv) == dest, "decode dest");
-+ assert(adapter_conversion_stack_move(conv) == stack_move, "decode stack_move");
-+ assert(adapter_conversion_vminfo(conv) == vminfo, "decode vminfo");
-+ return conv;
- }
-- static AdapterKind adapter_conversion_op(jint conv) {
-- return (AdapterKind)((conv >> _CONV_OP_SHIFT) & 0xF);
-+ static int adapter_conversion_op(jint conv) {
-+ return ((conv >> CONV_OP_SHIFT) & 0xF);
- }
- static BasicType adapter_conversion_src_type(jint conv) {
-- return (BasicType)((conv >> _CONV_SRC_TYPE_SHIFT) & 0xF);
-+ return (BasicType)((conv >> CONV_SRC_TYPE_SHIFT) & 0xF)