hotspot/src/share/vm/classfile/systemDictionary.cpp
changeset 7114 65d21c4c6337
parent 7104 0c8b519af363
child 7397 5b173b4ca846
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Sat Oct 30 12:19:07 2010 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Sat Oct 30 13:08:23 2010 -0700
@@ -2555,7 +2555,9 @@
 }
 
 Handle SystemDictionary::find_bootstrap_method(methodHandle caller_method, int caller_bci,
-                                               int cache_index, TRAPS) {
+                                               int cache_index,
+                                               Handle& argument_info_result,
+                                               TRAPS) {
   Handle empty;
 
   constantPoolHandle pool;
@@ -2569,7 +2571,7 @@
   constantTag tag = pool->tag_at(constant_pool_index);
 
   if (tag.is_invoke_dynamic()) {
-    // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type]
+    // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments
     // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry.
     int bsm_index = pool->invoke_dynamic_bootstrap_method_ref_index_at(constant_pool_index);
     if (bsm_index != 0) {
@@ -2585,9 +2587,38 @@
         tty->print_cr("bootstrap method for "PTR_FORMAT" at %d retrieved as "PTR_FORMAT":",
                       (intptr_t) caller_method(), caller_bci, (intptr_t) bsm_oop);
       }
-      assert(bsm_oop->is_oop()
-             && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane");
-      return Handle(THREAD, bsm_oop);
+      assert(bsm_oop->is_oop(), "must be sane");
+      // caller must verify that it is of type MethodHandle
+      Handle bsm(THREAD, bsm_oop);
+      bsm_oop = NULL;  // safety
+
+      // Extract the optional static arguments.
+      Handle argument_info;  // either null, or one arg, or Object[]{arg...}
+      int argc = pool->invoke_dynamic_argument_count_at(constant_pool_index);
+      if (TraceInvokeDynamic) {
+        tty->print_cr("find_bootstrap_method: [%d/%d] CONSTANT_InvokeDynamic: %d[%d]",
+                      constant_pool_index, cache_index, bsm_index, argc);
+      }
+      if (argc > 0) {
+        objArrayHandle arg_array;
+        if (argc > 1) {
+          objArrayOop arg_array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), argc, CHECK_(empty));
+          arg_array = objArrayHandle(THREAD, arg_array_oop);
+          argument_info = arg_array;
+        }
+        for (int arg_i = 0; arg_i < argc; arg_i++) {
+          int arg_index = pool->invoke_dynamic_argument_index_at(constant_pool_index, arg_i);
+          oop arg_oop = pool->resolve_possibly_cached_constant_at(arg_index, CHECK_(empty));
+          if (arg_array.is_null()) {
+            argument_info = Handle(THREAD, arg_oop);
+          } else {
+            arg_array->obj_at_put(arg_i, arg_oop);
+          }
+        }
+      }
+
+      argument_info_result = argument_info;  // return argument_info to caller
+      return bsm;
     }
     // else null BSM; fall through
   } else if (tag.is_name_and_type()) {
@@ -2600,14 +2631,14 @@
   // Fall through to pick up the per-class bootstrap method.
   // This mechanism may go away in the PFD.
   assert(AllowTransitionalJSR292, "else the verifier should have stopped us already");
+  argument_info_result = empty;  // return no argument_info to caller
   oop bsm_oop = instanceKlass::cast(caller_method->method_holder())->bootstrap_method();
   if (bsm_oop != NULL) {
     if (TraceMethodHandles) {
       tty->print_cr("bootstrap method for "PTR_FORMAT" registered as "PTR_FORMAT":",
                     (intptr_t) caller_method(), (intptr_t) bsm_oop);
     }
-    assert(bsm_oop->is_oop()
-           && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane");
+    assert(bsm_oop->is_oop(), "must be sane");
     return Handle(THREAD, bsm_oop);
   }