diff src/share/vm/oops/constantPoolOop.cpp @ 6266:1d7922586cf6

7023639: JSR 292 method handle invocation needs a fast path for compiled code 6984705: JSR 292 method handle creation should not go through JNI Summary: remove assembly code for JDK 7 chained method handles Reviewed-by: jrose, twisti, kvn, mhaupt Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author twisti
date Tue, 24 Jul 2012 10:51:00 -0700
parents f457154eee8b
children 957c266d8bc5
line wrap: on
line diff
--- a/src/share/vm/oops/constantPoolOop.cpp	Mon Jul 23 13:04:59 2012 -0700
+++ b/src/share/vm/oops/constantPoolOop.cpp	Tue Jul 24 10:51:00 2012 -0700
@@ -267,25 +267,61 @@
 
 
 methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool,
-                                                   int which, Bytecodes::Code invoke_code) {
+                                                   int which) {
   assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here");
   if (cpool->cache() == NULL)  return NULL;  // nothing to load yet
-  int cache_index = which - CPCACHE_INDEX_TAG;
+  int cache_index = get_cpcache_index(which);
   if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
     if (PrintMiscellaneous && (Verbose||WizardMode)) {
-      tty->print_cr("bad operand %d for %d in:", which, invoke_code); cpool->print();
+      tty->print_cr("bad operand %d in:", which); cpool->print();
     }
     return NULL;
   }
   ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
-  if (invoke_code != Bytecodes::_illegal)
-    return e->get_method_if_resolved(invoke_code, cpool);
-  Bytecodes::Code bc;
-  if ((bc = e->bytecode_1()) != (Bytecodes::Code)0)
-    return e->get_method_if_resolved(bc, cpool);
-  if ((bc = e->bytecode_2()) != (Bytecodes::Code)0)
-    return e->get_method_if_resolved(bc, cpool);
-  return NULL;
+  return e->method_if_resolved(cpool);
+}
+
+
+bool constantPoolOopDesc::has_appendix_at_if_loaded(constantPoolHandle cpool, int which) {
+  if (cpool->cache() == NULL)  return false;  // nothing to load yet
+  // XXX Is there a simpler way to get to the secondary entry?
+  ConstantPoolCacheEntry* e;
+  if (constantPoolCacheOopDesc::is_secondary_index(which)) {
+    e = cpool->cache()->secondary_entry_at(which);
+  } else {
+    int cache_index = get_cpcache_index(which);
+    if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
+      if (PrintMiscellaneous && (Verbose||WizardMode)) {
+        tty->print_cr("bad operand %d in:", which); cpool->print();
+      }
+      return false;
+    }
+    e = cpool->cache()->entry_at(cache_index);
+  }
+  return e->has_appendix();
+}
+
+
+oop constantPoolOopDesc::appendix_at_if_loaded(constantPoolHandle cpool, int which) {
+  if (cpool->cache() == NULL)  return NULL;  // nothing to load yet
+  // XXX Is there a simpler way to get to the secondary entry?
+  ConstantPoolCacheEntry* e;
+  if (constantPoolCacheOopDesc::is_secondary_index(which)) {
+    e = cpool->cache()->secondary_entry_at(which);
+  } else {
+    int cache_index = get_cpcache_index(which);
+    if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
+      if (PrintMiscellaneous && (Verbose||WizardMode)) {
+        tty->print_cr("bad operand %d in:", which); cpool->print();
+      }
+      return NULL;
+    }
+    e = cpool->cache()->entry_at(cache_index);
+  }
+  if (!e->has_appendix()) {
+    return NULL;
+  }
+  return e->f1_as_instance();
 }
 
 
@@ -481,7 +517,7 @@
   if (cache_index >= 0) {
     assert(index == _no_index_sentinel, "only one kind of index at a time");
     ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
-    result_oop = cpc_entry->f1();
+    result_oop = cpc_entry->f1_as_instance();
     if (result_oop != NULL) {
       return decode_exception_from_f1(result_oop, THREAD);
       // That was easy...
@@ -553,12 +589,7 @@
                       index, this_oop->method_type_index_at(index),
                       signature->as_C_string());
       KlassHandle klass(THREAD, this_oop->pool_holder());
-      bool ignore_is_on_bcp = false;
-      Handle value = SystemDictionary::find_method_handle_type(signature,
-                                                               klass,
-                                                               false,
-                                                               ignore_is_on_bcp,
-                                                               THREAD);
+      Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
       if (HAS_PENDING_EXCEPTION) {
         throw_exception = Handle(THREAD, PENDING_EXCEPTION);
         CLEAR_PENDING_EXCEPTION;
@@ -608,7 +639,7 @@
     result_oop = NULL;  // safety
     ObjectLocker ol(this_oop, THREAD);
     ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
-    result_oop = cpc_entry->f1();
+    result_oop = cpc_entry->f1_as_instance();
     // Benign race condition:  f1 may already be filled in while we were trying to lock.
     // The important thing here is that all threads pick up the same result.
     // It doesn't matter which racing thread wins, as long as only one
@@ -627,6 +658,45 @@
   }
 }
 
+
+oop constantPoolOopDesc::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS) {
+  assert(this_oop->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool");
+
+  Handle bsm;
+  int argc;
+  {
+    // 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.
+    // It is accompanied by the optional arguments.
+    int bsm_index = this_oop->invoke_dynamic_bootstrap_method_ref_index_at(index);
+    oop bsm_oop = this_oop->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL);
+    if (!java_lang_invoke_MethodHandle::is_instance(bsm_oop)) {
+      THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "BSM not an MethodHandle");
+    }
+
+    // Extract the optional static arguments.
+    argc = this_oop->invoke_dynamic_argument_count_at(index);
+    if (argc == 0)  return bsm_oop;
+
+    bsm = Handle(THREAD, bsm_oop);
+  }
+
+  objArrayHandle info;
+  {
+    objArrayOop info_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1+argc, CHECK_NULL);
+    info = objArrayHandle(THREAD, info_oop);
+  }
+
+  info->obj_at_put(0, bsm());
+  for (int i = 0; i < argc; i++) {
+    int arg_index = this_oop->invoke_dynamic_argument_index_at(index, i);
+    oop arg_oop = this_oop->resolve_possibly_cached_constant_at(arg_index, CHECK_NULL);
+    info->obj_at_put(1+i, arg_oop);
+  }
+
+  return info();
+}
+
 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
   oop str = NULL;
   CPSlot entry = this_oop->slot_at(which);