hotspot/src/share/vm/oops/cpCache.cpp
changeset 13929 8da0dc50a6e4
parent 13740 ae6179641137
child 14391 df0a1573d5bd
child 14393 93a4dcdbebfd
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Fri Sep 28 14:36:20 2012 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Mon Oct 01 14:50:10 2012 -0700
@@ -244,21 +244,23 @@
 
 
 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
-                                               methodHandle adapter, Handle appendix,
+                                               methodHandle adapter,
+                                               Handle appendix, Handle method_type,
                                                objArrayHandle resolved_references) {
-  set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, resolved_references);
+  set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, method_type, resolved_references);
 }
 
 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
-                                              methodHandle adapter, Handle appendix,
+                                              methodHandle adapter,
+                                              Handle appendix, Handle method_type,
                                               objArrayHandle resolved_references) {
-  set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, resolved_references);
+  set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, method_type, resolved_references);
 }
 
 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
                                                       Bytecodes::Code invoke_code,
                                                       methodHandle adapter,
-                                                      Handle appendix,
+                                                      Handle appendix, Handle method_type,
                                                       objArrayHandle resolved_references) {
   // NOTE: This CPCE can be the subject of data races.
   // There are three words to update: flags, refs[f2], f1 (in that order).
@@ -274,18 +276,21 @@
     return;
   }
 
-  bool has_appendix = appendix.not_null();
+  const bool has_appendix    = appendix.not_null();
+  const bool has_method_type = method_type.not_null();
 
   // Write the flags.
   set_method_flags(as_TosState(adapter->result_type()),
-                   ((has_appendix ?  1 : 0) << has_appendix_shift) |
-                   (                 1      << is_final_shift),
+                   ((has_appendix    ? 1 : 0) << has_appendix_shift   ) |
+                   ((has_method_type ? 1 : 0) << has_method_type_shift) |
+                   (                   1      << is_final_shift       ),
                    adapter->size_of_parameters());
 
   if (TraceInvokeDynamic) {
-    tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method="PTR_FORMAT" ",
+    tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
                   invoke_code,
-                  (intptr_t)appendix(), (has_appendix ? "" : " (unused)"),
+                  (intptr_t)appendix(),    (has_appendix    ? "" : " (unused)"),
+                  (intptr_t)method_type(), (has_method_type ? "" : " (unused)"),
                   (intptr_t)adapter());
     adapter->print();
     if (has_appendix)  appendix()->print();
@@ -310,17 +315,26 @@
   // This allows us to create fewer method oops, while keeping type safety.
   //
 
+  // Store appendix, if any.
   if (has_appendix) {
-    int ref_index = f2_as_index();
-    assert(ref_index >= 0 && ref_index < resolved_references->length(), "oob");
-    assert(resolved_references->obj_at(ref_index) == NULL, "init just once");
-    resolved_references->obj_at_put(ref_index, appendix());
+    const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
+    assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
+    assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
+    resolved_references->obj_at_put(appendix_index, appendix());
+  }
+
+  // Store MethodType, if any.
+  if (has_method_type) {
+    const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
+    assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
+    assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
+    resolved_references->obj_at_put(method_type_index, method_type());
   }
 
   release_set_f1(adapter());  // This must be the last one to set (see NOTE above)!
 
-    // The interpreter assembly code does not check byte_2,
-    // but it is used by is_resolved, method_if_resolved, etc.
+  // The interpreter assembly code does not check byte_2,
+  // but it is used by is_resolved, method_if_resolved, etc.
   set_bytecode_1(invoke_code);
   NOT_PRODUCT(verify(tty));
   if (TraceInvokeDynamic) {
@@ -376,7 +390,16 @@
 oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
   if (is_f1_null() || !has_appendix())
     return NULL;
-  int ref_index = f2_as_index();
+  const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
+  objArrayOop resolved_references = cpool->resolved_references();
+  return resolved_references->obj_at(ref_index);
+}
+
+
+oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
+  if (is_f1_null() || !has_method_type())
+    return NULL;
+  const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
   objArrayOop resolved_references = cpool->resolved_references();
   return resolved_references->obj_at(ref_index);
 }
@@ -513,13 +536,23 @@
   for (int i = 0; i < length(); i++) {
     ConstantPoolCacheEntry* e = entry_at(i);
     int original_index = inverse_index_map[i];
-      e->initialize_entry(original_index);
+    e->initialize_entry(original_index);
     assert(entry_at(i) == e, "sanity");
-    }
+  }
   for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
-    int cpci = invokedynamic_references_map[ref];
-    if (cpci >= 0)
+    const int cpci = invokedynamic_references_map[ref];
+    if (cpci >= 0) {
+#ifdef ASSERT
+      // invokedynamic and invokehandle have more entries; check if they
+      // all point to the same constant pool cache entry.
+      for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
+        const int cpci_next = invokedynamic_references_map[ref + entry];
+        assert(cpci == cpci_next, err_msg_res("%d == %d", cpci, cpci_next));
+      }
+#endif
       entry_at(cpci)->initialize_resolved_reference_index(ref);
+      ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1;  // skip extra entries
+    }
   }
 }