--- a/indy.patch Fri Apr 03 15:15:37 2009 -0700
+++ b/indy.patch Mon Apr 06 03:27:56 2009 -0700
@@ -666,7 +666,7 @@ diff --git a/src/cpu/x86/vm/templateTabl
__ bind(resolved);
}
-@@ -2884,9 +2889,14 @@
+@@ -2884,12 +2889,17 @@
}
@@ -681,7 +681,11 @@ diff --git a/src/cpu/x86/vm/templateTabl
+ const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
const bool is_invokespecial = code == Bytecodes::_invokespecial;
- const bool load_receiver = code != Bytecodes::_invokestatic;
+- const bool load_receiver = code != Bytecodes::_invokestatic;
++ const bool load_receiver = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
+ const bool receiver_null_check = is_invokespecial;
+ const bool save_flags = is_invokeinterface || is_invokevirtual;
+ // setup registers & access constant pool cache
@@ -2897,6 +2907,9 @@
const Register flags = rdx;
assert_different_registers(method, index, recv, flags);
@@ -760,7 +764,7 @@ diff --git a/src/cpu/x86/vm/templateTabl
// rax,: Interface
// rbx,: index
-@@ -3102,6 +3125,83 @@
+@@ -3102,6 +3125,84 @@
__ should_not_reach_here();
}
@@ -787,17 +791,9 @@ diff --git a/src/cpu/x86/vm/templateTabl
+
+ if (ProfileInterpreter) {
+ Label L;
-+ __ movl(rdx, Address(rcx, 0));
-+ __ testl(rdx, rdx);
-+ __ jcc(Assembler::zero, L);
-+
-+ // Get receiver klass into rdx
-+ __ movl(rdx, Address(rdx, oopDesc::klass_offset_in_bytes()));
-+ __ verify_oop(rdx);
-+ __ bind(L);
-+
++ // %%% should make a type profile for any invokedynamic that takes a ref argument
+ // profile this call
-+ __ profile_virtual_call(rdx, rsi, rdi, true);
++ __ profile_call(rsi);
+ }
+
+ Label handle_unlinked_site;
@@ -812,31 +808,40 @@ diff --git a/src/cpu/x86/vm/templateTabl
+ __ bind(handle_unlinked_site);
+ __ pop(rcx); // remove return address pushed by prepare_invoke
+
++ // box stacked arguments into an array for the bootstrap method
+ address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::bootstrap_invokedynamic);
-+ // squish stacked arguments together on stack, preceded by call site
-+ // return bootstrap method as a handle in rcx
+ __ restore_bcp(); // rsi must be correct for call_VM
+ __ call_VM(rax, entry, rax);
-+ __ movl(rdi, rax); // protect MH from prepare_invoke
++ __ movl(rdi, rax); // protect bootstrap MH from prepare_invoke
+
+ // recompute return address
+ __ restore_bcp(); // rsi must be correct for prepare_invoke
-+ prepare_invoke(rax, rbx, -byte_no);
++ prepare_invoke(rax, rbx, -byte_no); // smashes rcx, rdx
+ // rax: CallSite object (f1)
+ // rbx: unused (f2)
-+ // rcx: receiver address (now holds arglist)
++ // rdi: bootstrap MH
+ // rdx: flags
+
-+ // save SP now, before we add the bootstrap call to the stack
++ // now load up the arglist, which has been neatly boxed
++ __ get_thread(rcx);
++ __ movptr(rdx, Address(rcx, JavaThread::vm_result_2_offset()));
++ __ movptr(Address(rcx, JavaThread::vm_result_2_offset()), NULL_WORD);
++ __ verify_oop(rdx);
++ // rdx = arglist
++
++ // save SP now, before we add the bootstrap call to the stack
++ // We must preserve a fiction that the original arguments are outgoing,
++ // because the return sequence will reset the stack to this point
++ // and then pop all those arguments. It seems error-prone to use
++ // a different argument list size just for bootstrapping.
+ __ prepare_to_jump_from_interpreted();
+
-+ // let's play adapter
-+ __ pop(rbx); // return value
++ // Now let's play adapter, pushing the real arguments on the stack.
++ __ pop(rbx); // return PC
+ __ push(rdi); // boot MH
+ __ push(rax); // call site
-+ __ movptr(rcx, Address(rcx, 0));
-+ __ push(rcx); // arglist
-+ __ push(rbx); // return value
++ __ push(rdx); // arglist
++ __ push(rbx); // return PC, again
+ __ mov(rcx, rdi);
+ __ jump_to_method_handle_entry(rcx, rdx);
+}
@@ -2128,7 +2133,7 @@ diff --git a/src/share/vm/interpreter/in
diff --git a/src/share/vm/interpreter/interpreterRuntime.cpp b/src/share/vm/interpreter/interpreterRuntime.cpp
--- a/src/share/vm/interpreter/interpreterRuntime.cpp
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp
-@@ -681,6 +681,131 @@
+@@ -681,6 +681,133 @@
IRT_END
@@ -2200,7 +2205,11 @@ diff --git a/src/share/vm/interpreter/in
+ call_site_name,
+ mh_invdyn,
+ CHECK);
-+ pool->cache()->entry_at(site_index)->set_dynamic_call(call_site(), 0);
++
++ // In the secondary entry, the f1 field is the call site, and the f2 (index)
++ // field is some data about the invoke site.
++ int extra_data = 0;
++ pool->cache()->entry_at(site_index)->set_dynamic_call(call_site(), extra_data);
+}
+IRT_END
+
@@ -2229,7 +2238,6 @@ diff --git a/src/share/vm/interpreter/in
+ if (!java_lang_Class::is_primitive(ptype)) {
+ arg = *(oop*) slot_addr;
+ } else {
-+ assert(i > 0, "first argument is always an oop");
+ BasicType bt = java_lang_Class::primitive_type(ptype);
+ assert(frame::interpreter_frame_expression_stack_direction() < 0, "else reconsider this code");
+ jvalue value;
@@ -2244,14 +2252,13 @@ diff --git a/src/share/vm/interpreter/in
+ arg_array->obj_at_put(i, arg);
+ }
+
-+ // return the argument array by storing it down over the first argument:
-+ assert(nargs > 0, "always a first argument");
-+ *fr.interpreter_frame_tos_at(tos_offset - 1) = (intptr_t) arg_array();
-+
+ // now find the bootstrap method
+ oop bootstrap_mh_oop = instanceKlass::cast(fr.interpreter_frame_method()->method_holder())->bootstrap_method();
-+ assert(bootstrap_mh_oop != NULL, "must already be determined");
++ assert(bootstrap_mh_oop != NULL, "resolve_invokedynamic ensures a BSM");
++
++ // return the bootstrap method and argument array via vm_result/_2
+ thread->set_vm_result(bootstrap_mh_oop);
++ thread->set_vm_result_2(arg_array());
+}
+IRT_END
+
@@ -3120,7 +3127,7 @@ diff --git a/src/share/vm/oops/cpCacheOo
}
-+void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, int index) {
++void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, int extra_data) {
+ methodOop method = (methodOop) impl_java_dyn_CallSiteImpl::vmmethod(call_site());
+ assert(method->is_method(), "must be initialized properly");
+ int param_size = method->size_of_parameters();
@@ -3130,7 +3137,7 @@ diff --git a/src/share/vm/oops/cpCacheOo
+ // racing threads might be trying to install their own favorites
+ set_f1(call_site());
+ }
-+ set_f2(index);
++ set_f2(extra_data);
+ set_flags(as_flags(as_TosState(method->result_type()), method->is_final_method(), false, false, false, true) | param_size);
+ // do not do set_bytecode on a secondary CP cache entry
+ //set_bytecode_1(Bytecodes::_invokedynamic);
@@ -3180,7 +3187,7 @@ diff --git a/src/share/vm/oops/cpCacheOo
+ void set_dynamic_call(
+ Handle call_site, // Resolved java.dyn.CallSite (f1)
-+ int index // index (unused f2)
++ int extra_data // (f2)
+ );
+
void set_parameter_size(int value) {
@@ -3355,6 +3362,30 @@ diff --git a/src/share/vm/oops/instanceK
if (ik->generic_signature() != NULL) {
st->print(BULLET"generic signature: ");
ik->generic_signature()->print_value_on(st);
+diff --git a/src/share/vm/oops/methodDataOop.cpp b/src/share/vm/oops/methodDataOop.cpp
+--- a/src/share/vm/oops/methodDataOop.cpp
++++ b/src/share/vm/oops/methodDataOop.cpp
+@@ -442,6 +442,8 @@
+ case Bytecodes::_invokevirtual:
+ case Bytecodes::_invokeinterface:
+ return VirtualCallData::static_cell_count();
++ case Bytecodes::_invokedynamic:
++ return CounterData::static_cell_count();
+ case Bytecodes::_ret:
+ return RetData::static_cell_count();
+ case Bytecodes::_ifeq:
+@@ -570,6 +572,11 @@
+ cell_count = VirtualCallData::static_cell_count();
+ tag = DataLayout::virtual_call_data_tag;
+ break;
++ case Bytecodes::_invokedynamic:
++ // %%% should make a type profile for any invokedynamic that takes a ref argument
++ cell_count = CounterData::static_cell_count();
++ tag = DataLayout::counter_data_tag;
++ break;
+ case Bytecodes::_ret:
+ cell_count = RetData::static_cell_count();
+ tag = DataLayout::ret_data_tag;
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
@@ -3397,6 +3428,29 @@ diff --git a/src/share/vm/opto/doCall.cp
assert(dest_method->will_link(method()->holder(), klass, bc()), "dest_method: typeflow responsibility");
return false;
+diff --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp
+--- a/src/share/vm/prims/jvm.cpp
++++ b/src/share/vm/prims/jvm.cpp
+@@ -2212,6 +2212,9 @@
+ case JVM_CONSTANT_InterfaceMethodref:
+ case JVM_CONSTANT_Methodref:
+ return cp->uncached_name_ref_at(cp_index)->as_utf8();
++ case JVM_CONSTANT_NameAndType:
++ // for invokedynamic
++ return cp->nt_name_ref_at(cp_index)->as_utf8();
+ default:
+ fatal("JVM_GetCPMethodNameUTF: illegal constant");
+ }
+@@ -2229,6 +2232,9 @@
+ case JVM_CONSTANT_InterfaceMethodref:
+ case JVM_CONSTANT_Methodref:
+ return cp->uncached_signature_ref_at(cp_index)->as_utf8();
++ case JVM_CONSTANT_NameAndType:
++ // for invokedynamic
++ return cp->nt_signature_ref_at(cp_index)->as_utf8();
+ default:
+ fatal("JVM_GetCPMethodSignatureUTF: illegal constant");
+ }
diff --git a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
--- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
+++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
@@ -3440,7 +3494,7 @@ diff --git a/src/share/vm/prims/methodHa
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
-@@ -2231,6 +2231,16 @@
+@@ -2232,6 +2232,16 @@
JVM_END
@@ -3457,7 +3511,7 @@ diff --git a/src/share/vm/prims/methodHa
/// JVM_RegisterMethodHandleMethods
#define ADR "J"
-@@ -2249,6 +2259,7 @@
+@@ -2250,6 +2260,7 @@
#define AMH IDYN"AdapterMethodHandle;"
#define BMH IDYN"BoundMethodHandle;"
#define DMH IDYN"DirectMethodHandle;"
@@ -3465,7 +3519,7 @@ diff --git a/src/share/vm/prims/methodHa
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
-@@ -2263,6 +2274,7 @@
+@@ -2264,6 +2275,7 @@
{CC"init", CC"("MEM""OBJ")V", FN_PTR(MHI_init_Mem)},
{CC"expand", CC"("MEM")V", FN_PTR(MHI_expand_Mem)},
{CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHI_resolve_Mem)},
--- a/indy.txt Fri Apr 03 15:15:37 2009 -0700
+++ b/indy.txt Mon Apr 06 03:27:56 2009 -0700
@@ -4,4 +4,13 @@ http://bugs.sun.com/bugdatabase/view_bug
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6655646
Features:
-- enabled via -XX:+InvokeDynamic
+- enabled via -XX:+EnableInvokeDynamic
+
+Notes:
+
+If you get an error like this:
+ Exception in thread "main" java.lang.VerifyError: (class: Foo, method: ...) Illegal instruction found at offset 39
+then you need a JDK with a patch to the old verifier plugin, see ../jdk/indy.verify.patch
+As a workaround, use this JVM flag to turn off the (unpatched) verifier:
+ -Xverify:none
+or else put your classes on the BCP: -Xbootclasspath/a:my/classes:my.jar
--- a/meth.patch Fri Apr 03 15:15:37 2009 -0700
+++ b/meth.patch Mon Apr 06 03:27:56 2009 -0700
@@ -591,6 +591,17 @@ diff --git a/src/share/vm/oops/methodOop
// 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()
+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
+@@ -409,6 +409,7 @@
+ { throw_IllegalArgumentException("nothing to resolve", CHECK); }
+ 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();
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
--- a/series Fri Apr 03 15:15:37 2009 -0700
+++ b/series Mon Apr 06 03:27:56 2009 -0700
@@ -11,10 +11,10 @@ meth.patch #-/meth
indy.patch #-/indy #+05f8c84c5daa
-annot.patch #-/annot #+d1605aabd0a1 #+jdk7-b30 #-testable
-#inti.patch #-/inti #+d1605aabd0a1 #+jdk7-b30 #-buildable
-callcc.patch #-/callcc #+d1605aabd0a1 #+jdk7-b30 #-testable
-tailc.patch #-/tailc #+a268411445d9 #+jdk7-b45 #-testable
+annot.patch #-/annot #+d1605aabd0a1 #+jdk7-b30 #-testable
+inti.patch #-/inti #+d1605aabd0a1 #+jdk7-b30 #-buildable
+callcc.patch #-/callcc #+d1605aabd0a1 #+jdk7-b30 #-testable
+tailc.patch #-/tailc #+a268411445d9 #+jdk7-b45 #-testable
meth.proj.patch #-/meth #+projects
anonk.proj.patch #-/anonk #+projects