changeset 35543:0961315f4016

8140659: C1: invokedynamic call patching violates JVMS-6.5.invokedynamic Reviewed-by: roland
author vlivanov
date Fri, 18 Dec 2015 20:23:27 +0300
parents 9dccb7f9f656
children c7ec868d0923
files hotspot/src/share/vm/c1/c1_GraphBuilder.cpp hotspot/src/share/vm/c1/c1_Runtime1.cpp hotspot/src/share/vm/c1/c1_globals.hpp hotspot/src/share/vm/classfile/systemDictionary.cpp hotspot/src/share/vm/interpreter/linkResolver.cpp hotspot/src/share/vm/oops/cpCache.cpp hotspot/src/share/vm/oops/method.cpp hotspot/src/share/vm/prims/methodHandles.cpp
diffstat 8 files changed, 23 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Dec 18 20:23:26 2015 +0300
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Dec 18 20:23:27 2015 +0300
@@ -1748,10 +1748,6 @@
   const Bytecodes::Code bc_raw = stream()->cur_bc_raw();
   assert(declared_signature != NULL, "cannot be null");
 
-  if (!C1PatchInvokeDynamic && Bytecodes::has_optional_appendix(bc_raw) && !will_link) {
-    BAILOUT("unlinked call site (C1PatchInvokeDynamic is off)");
-  }
-
   // we have to make sure the argument size (incl. the receiver)
   // is correct for compilation (the call would fail later during
   // linkage anyway) - was bug (gri 7/28/99)
@@ -1803,8 +1799,7 @@
   // Push appendix argument (MethodType, CallSite, etc.), if one.
   bool patch_for_appendix = false;
   int patching_appendix_arg = 0;
-  if (C1PatchInvokeDynamic &&
-      (Bytecodes::has_optional_appendix(bc_raw) && (!will_link || PatchALot))) {
+  if (Bytecodes::has_optional_appendix(bc_raw) && (!will_link || PatchALot)) {
     Value arg = append(new Constant(new ObjectConstant(compilation()->env()->unloaded_ciinstance()), copy_state_before()));
     apush(arg);
     patch_for_appendix = true;
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Fri Dec 18 20:23:26 2015 +0300
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Fri Dec 18 20:23:27 2015 +0300
@@ -954,20 +954,25 @@
     constantPoolHandle pool(thread, caller_method->constants());
     int index = bytecode.index();
     LinkResolver::resolve_invoke(info, Handle(), pool, index, bc, CHECK);
-    appendix = info.resolved_appendix();
     switch (bc) {
       case Bytecodes::_invokehandle: {
         int cache_index = ConstantPool::decode_cpcache_index(index, true);
         assert(cache_index >= 0 && cache_index < pool->cache()->length(), "unexpected cache index");
-        pool->cache()->entry_at(cache_index)->set_method_handle(pool, info);
+        ConstantPoolCacheEntry* cpce = pool->cache()->entry_at(cache_index);
+        cpce->set_method_handle(pool, info);
+        appendix = info.resolved_appendix();  // just in case somebody already resolved the entry
         break;
       }
       case Bytecodes::_invokedynamic: {
-        pool->invokedynamic_cp_cache_entry_at(index)->set_dynamic_call(pool, info);
+        ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index);
+        cpce->set_dynamic_call(pool, info);
+        appendix = cpce->appendix_if_resolved(pool); // just in case somebody already resolved the entry
         break;
       }
       default: fatal("unexpected bytecode for load_appendix_patching_id");
     }
+    assert(appendix.not_null(), "%s @ %d (%s)",
+           caller_method->name_and_sig_as_C_string(), bci, Bytecodes::name(bc));
   } else {
     ShouldNotReachHere();
   }
--- a/hotspot/src/share/vm/c1/c1_globals.hpp	Fri Dec 18 20:23:26 2015 +0300
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp	Fri Dec 18 20:23:27 2015 +0300
@@ -341,9 +341,6 @@
   develop(bool, PrintCFGToFile, false,                                      \
           "print control flow graph to a separate file during compilation") \
                                                                             \
-  diagnostic(bool, C1PatchInvokeDynamic, true,                              \
-             "Patch invokedynamic appendix not known at compile time")      \
-                                                                            \
 // Read default values for c1 globals
 
 C1_FLAGS(DECLARE_DEVELOPER_FLAG, \
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri Dec 18 20:23:26 2015 +0300
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri Dec 18 20:23:27 2015 +0300
@@ -2386,6 +2386,7 @@
       oop appendix = appendix_box->obj_at(0);
       if (TraceMethodHandles) {
     #ifndef PRODUCT
+        ttyLocker ttyl;
         tty->print("Linked method=" INTPTR_FORMAT ": ", p2i(m));
         m->print();
         if (appendix != NULL) { tty->print("appendix = "); appendix->print(); }
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp	Fri Dec 18 20:23:26 2015 +0300
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp	Fri Dec 18 20:23:27 2015 +0300
@@ -447,6 +447,7 @@
         assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this");
         assert(basic_signature == result->signature(), "predict the result signature");
         if (TraceMethodHandles) {
+          ttyLocker ttyl;
           tty->print("lookup_polymorphic_method => intrinsic ");
           result->print_on(tty);
         }
@@ -479,6 +480,7 @@
                                                             &method_type,
                                                             CHECK_NULL);
       if (TraceMethodHandles) {
+        ttyLocker ttyl;
         tty->print("lookup_polymorphic_method => (via Java) ");
         result->print_on(tty);
         tty->print("  lookup_polymorphic_method => appendix = ");
@@ -1585,10 +1587,11 @@
   }
 
   if (TraceMethodHandles) {
-      ResourceMark rm(THREAD);
-      tty->print_cr("resolve_invokedynamic #%d %s %s",
+    ResourceMark rm(THREAD);
+    tty->print_cr("resolve_invokedynamic #%d %s %s in %s",
                   ConstantPool::decode_invokedynamic_index(index),
-                  method_name->as_C_string(), method_signature->as_C_string());
+                  method_name->as_C_string(), method_signature->as_C_string(),
+                  current_klass->name()->as_C_string());
     tty->print("  BSM info: "); bootstrap_specifier->print();
   }
 
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Fri Dec 18 20:23:26 2015 +0300
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Fri Dec 18 20:23:27 2015 +0300
@@ -306,6 +306,7 @@
                    adapter->size_of_parameters());
 
   if (TraceInvokeDynamic) {
+    ttyLocker ttyl;
     tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method_type=" PTR_FORMAT "%s method=" PTR_FORMAT " ",
                   invoke_code,
                   p2i(appendix()),    (has_appendix    ? "" : " (unused)"),
@@ -357,6 +358,7 @@
   set_bytecode_1(invoke_code);
   NOT_PRODUCT(verify(tty));
   if (TraceInvokeDynamic) {
+    ttyLocker ttyl;
     this->print(tty, 0);
   }
 }
--- a/hotspot/src/share/vm/oops/method.cpp	Fri Dec 18 20:23:26 2015 +0300
+++ b/hotspot/src/share/vm/oops/method.cpp	Fri Dec 18 20:23:27 2015 +0300
@@ -1200,8 +1200,10 @@
   m->set_vtable_index(Method::nonvirtual_vtable_index);
   m->link_method(m, CHECK_(empty));
 
-  if (TraceMethodHandles && (Verbose || WizardMode))
+  if (TraceMethodHandles && (Verbose || WizardMode)) {
+    ttyLocker ttyl;
     m->print_on(tty);
+  }
 
   return m;
 }
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Fri Dec 18 20:23:26 2015 +0300
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Fri Dec 18 20:23:27 2015 +0300
@@ -202,6 +202,7 @@
     assert(m_klass->verify_itable_index(vmindex), "");
     flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
     if (TraceInvokeDynamic) {
+      ttyLocker ttyl;
       ResourceMark rm;
       tty->print_cr("memberName: invokeinterface method_holder::method: %s, itableindex: %d, access_flags:",
             Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
@@ -242,6 +243,7 @@
       m_klass = m_klass_non_interface;
     }
     if (TraceInvokeDynamic) {
+      ttyLocker ttyl;
       ResourceMark rm;
       tty->print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:",
             Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),