hotspot/src/share/vm/runtime/sharedRuntime.cpp
changeset 13391 30245956af37
parent 13195 be27e1b6a4b9
child 13396 1b2b5f740ee0
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Mon Jul 23 13:04:59 2012 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Jul 24 10:51:00 2012 -0700
@@ -88,8 +88,6 @@
 RuntimeStub*        SharedRuntime::_resolve_static_call_blob;
 
 DeoptimizationBlob* SharedRuntime::_deopt_blob;
-RicochetBlob*       SharedRuntime::_ricochet_blob;
-
 SafepointBlob*      SharedRuntime::_polling_page_safepoint_handler_blob;
 SafepointBlob*      SharedRuntime::_polling_page_return_handler_blob;
 
@@ -109,7 +107,6 @@
   _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), false);
   _polling_page_return_handler_blob    = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), true);
 
-  generate_ricochet_blob();
   generate_deopt_blob();
 
 #ifdef COMPILER2
@@ -117,33 +114,6 @@
 #endif // COMPILER2
 }
 
-//----------------------------generate_ricochet_blob---------------------------
-void SharedRuntime::generate_ricochet_blob() {
-  if (!EnableInvokeDynamic)  return;  // leave it as a null
-
-  // allocate space for the code
-  ResourceMark rm;
-  // setup code generation tools
-  CodeBuffer buffer("ricochet_blob", 256 LP64_ONLY(+ 256), 256);  // XXX x86 LP64L: 512, 512
-  MacroAssembler* masm = new MacroAssembler(&buffer);
-
-  int bounce_offset = -1, exception_offset = -1, frame_size_in_words = -1;
-  MethodHandles::RicochetFrame::generate_ricochet_blob(masm, &bounce_offset, &exception_offset, &frame_size_in_words);
-
-  // -------------
-  // make sure all code is generated
-  masm->flush();
-
-  // failed to generate?
-  if (bounce_offset < 0 || exception_offset < 0 || frame_size_in_words < 0) {
-    assert(false, "bad ricochet blob");
-    return;
-  }
-
-  _ricochet_blob = RicochetBlob::create(&buffer, bounce_offset, exception_offset, frame_size_in_words);
-}
-
-
 #include <math.h>
 
 #ifndef USDT2
@@ -527,10 +497,6 @@
   if (Interpreter::contains(return_address)) {
     return Interpreter::rethrow_exception_entry();
   }
-  // Ricochet frame unwind code
-  if (SharedRuntime::ricochet_blob() != NULL && SharedRuntime::ricochet_blob()->returns_to_bounce_addr(return_address)) {
-    return SharedRuntime::ricochet_blob()->exception_addr();
-  }
 
   guarantee(blob == NULL || !blob->is_runtime_stub(), "caller should have skipped stub");
   guarantee(!VtableStubs::contains(return_address), "NULL exceptions in vtables should have been handled already!");
@@ -768,13 +734,6 @@
   throw_and_post_jvmti_exception(thread, exception);
 JRT_END
 
-JRT_ENTRY(void, SharedRuntime::throw_WrongMethodTypeException(JavaThread* thread, oopDesc* required, oopDesc* actual))
-  assert(thread == JavaThread::current() && required->is_oop() && actual->is_oop(), "bad args");
-  ResourceMark rm;
-  char* message = SharedRuntime::generate_wrong_method_type_message(thread, required, actual);
-  throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_invoke_WrongMethodTypeException(), message);
-JRT_END
-
 address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
                                                            address pc,
                                                            SharedRuntime::ImplicitExceptionKind exception_kind)
@@ -857,6 +816,12 @@
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
 
+          if (nm->method()->is_method_handle_intrinsic()) {
+            // exception happened inside MH dispatch code, similar to a vtable stub
+            Events::log_exception(thread, "NullPointerException in MH adapter " INTPTR_FORMAT, pc);
+            return StubRoutines::throw_NullPointerException_at_call_entry();
+          }
+
 #ifndef PRODUCT
           _implicit_null_throws++;
 #endif
@@ -1045,16 +1010,17 @@
   assert(!vfst.at_end(), "Java frame must exist");
 
   // Find caller and bci from vframe
-  methodHandle caller (THREAD, vfst.method());
-  int          bci    = vfst.bci();
+  methodHandle caller(THREAD, vfst.method());
+  int          bci   = vfst.bci();
 
   // Find bytecode
   Bytecode_invoke bytecode(caller, bci);
-  bc = bytecode.java_code();
+  bc = bytecode.invoke_code();
   int bytecode_index = bytecode.index();
 
   // Find receiver for non-static call
-  if (bc != Bytecodes::_invokestatic) {
+  if (bc != Bytecodes::_invokestatic &&
+      bc != Bytecodes::_invokedynamic) {
     // This register map must be update since we need to find the receiver for
     // compiled frames. The receiver might be in a register.
     RegisterMap reg_map2(thread);
@@ -1075,25 +1041,32 @@
   }
 
   // Resolve method. This is parameterized by bytecode.
-  constantPoolHandle constants (THREAD, caller->constants());
-  assert (receiver.is_null() || receiver->is_oop(), "wrong receiver");
+  constantPoolHandle constants(THREAD, caller->constants());
+  assert(receiver.is_null() || receiver->is_oop(), "wrong receiver");
   LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_(nullHandle));
 
 #ifdef ASSERT
   // Check that the receiver klass is of the right subtype and that it is initialized for virtual calls
   if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic) {
     assert(receiver.not_null(), "should have thrown exception");
-    KlassHandle receiver_klass (THREAD, receiver->klass());
+    KlassHandle receiver_klass(THREAD, receiver->klass());
     klassOop rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle));
                             // klass is already loaded
-    KlassHandle static_receiver_klass (THREAD, rk);
-    assert(receiver_klass->is_subtype_of(static_receiver_klass()), "actual receiver must be subclass of static receiver klass");
+    KlassHandle static_receiver_klass(THREAD, rk);
+    // Method handle invokes might have been optimized to a direct call
+    // so don't check for the receiver class.
+    // FIXME this weakens the assert too much
+    methodHandle callee = callinfo.selected_method();
+    assert(receiver_klass->is_subtype_of(static_receiver_klass()) ||
+           callee->is_method_handle_intrinsic() ||
+           callee->is_compiled_lambda_form(),
+           "actual receiver must be subclass of static receiver klass");
     if (receiver_klass->oop_is_instance()) {
       if (instanceKlass::cast(receiver_klass())->is_not_initialized()) {
         tty->print_cr("ERROR: Klass not yet initialized!!");
         receiver_klass.print();
       }
-      assert (!instanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized");
+      assert(!instanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized");
     }
   }
 #endif
@@ -1186,8 +1159,10 @@
                                      call_info, CHECK_(methodHandle()));
   methodHandle callee_method = call_info.selected_method();
 
-  assert((!is_virtual && invoke_code == Bytecodes::_invokestatic) ||
-         ( is_virtual && invoke_code != Bytecodes::_invokestatic), "inconsistent bytecode");
+  assert((!is_virtual && invoke_code == Bytecodes::_invokestatic ) ||
+         (!is_virtual && invoke_code == Bytecodes::_invokehandle ) ||
+         (!is_virtual && invoke_code == Bytecodes::_invokedynamic) ||
+         ( is_virtual && invoke_code != Bytecodes::_invokestatic ), "inconsistent bytecode");
 
 #ifndef PRODUCT
   // tracing/debugging/statistics
@@ -1202,16 +1177,17 @@
       (is_optimized) ? "optimized " : "", (is_virtual) ? "virtual" : "static",
       Bytecodes::name(invoke_code));
     callee_method->print_short_name(tty);
-    tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
+    tty->print_cr(" at pc: " INTPTR_FORMAT " to code: " INTPTR_FORMAT, caller_frame.pc(), callee_method->code());
   }
 #endif
 
-  // JSR 292
+  // JSR 292 key invariant:
   // If the resolved method is a MethodHandle invoke target the call
-  // site must be a MethodHandle call site.
-  if (callee_method->is_method_handle_invoke()) {
-    assert(caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
-  }
+  // site must be a MethodHandle call site, because the lambda form might tail-call
+  // leaving the stack in a state unknown to either caller or callee
+  // TODO detune for now but we might need it again
+//  assert(!callee_method->is_compiled_lambda_form() ||
+//         caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
 
   // Compute entry points. This might require generation of C2I converter
   // frames, so we cannot be holding any locks here. Furthermore, the
@@ -1284,7 +1260,6 @@
   assert(stub_frame.is_runtime_frame(), "sanity check");
   frame caller_frame = stub_frame.sender(&reg_map);
   assert(!caller_frame.is_interpreted_frame() && !caller_frame.is_entry_frame(), "unexpected frame");
-  assert(!caller_frame.is_ricochet_frame(), "unexpected frame");
 #endif /* ASSERT */
 
   methodHandle callee_method;
@@ -1320,21 +1295,9 @@
   address   sender_pc = caller_frame.pc();
   CodeBlob* sender_cb = caller_frame.cb();
   nmethod*  sender_nm = sender_cb->as_nmethod_or_null();
-  bool is_mh_invoke_via_adapter = false;  // Direct c2c call or via adapter?
-  if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) {
-    // If the callee_target is set, then we have come here via an i2c
-    // adapter.
-    methodOop callee = thread->callee_target();
-    if (callee != NULL) {
-      assert(callee->is_method(), "sanity");
-      is_mh_invoke_via_adapter = true;
-    }
-  }
 
   if (caller_frame.is_interpreted_frame() ||
-      caller_frame.is_entry_frame()       ||
-      caller_frame.is_ricochet_frame()    ||
-      is_mh_invoke_via_adapter) {
+      caller_frame.is_entry_frame()) {
     methodOop callee = thread->callee_target();
     guarantee(callee != NULL && callee->is_method(), "bad handshake");
     thread->set_vm_result(callee);
@@ -1677,12 +1640,6 @@
   // Get the return PC for the passed caller PC.
   address return_pc = caller_pc + frame::pc_return_offset;
 
-  // Don't fixup method handle call sites as the executed method
-  // handle adapters are doing the required MethodHandle chain work.
-  if (nm->is_method_handle_return(return_pc)) {
-    return;
-  }
-
   // There is a benign race here. We could be attempting to patch to a compiled
   // entry point at the same time the callee is being deoptimized. If that is
   // the case then entry_point may in fact point to a c2i and we'd patch the
@@ -1788,97 +1745,6 @@
   return generate_class_cast_message(objName, targetKlass->external_name());
 }
 
-char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread,
-                                                        oopDesc* required,
-                                                        oopDesc* actual) {
-  if (TraceMethodHandles) {
-    tty->print_cr("WrongMethodType thread="PTR_FORMAT" req="PTR_FORMAT" act="PTR_FORMAT"",
-                  thread, required, actual);
-  }
-  assert(EnableInvokeDynamic, "");
-  oop singleKlass = wrong_method_type_is_for_single_argument(thread, required);
-  char* message = NULL;
-  if (singleKlass != NULL) {
-    const char* objName = "argument or return value";
-    if (actual != NULL) {
-      // be flexible about the junk passed in:
-      klassOop ak = (actual->is_klass()
-                     ? (klassOop)actual
-                     : actual->klass());
-      objName = Klass::cast(ak)->external_name();
-    }
-    Klass* targetKlass = Klass::cast(required->is_klass()
-                                     ? (klassOop)required
-                                     : java_lang_Class::as_klassOop(required));
-    message = generate_class_cast_message(objName, targetKlass->external_name());
-  } else {
-    // %%% need to get the MethodType string, without messing around too much
-    const char* desc = NULL;
-    // Get a signature from the invoke instruction
-    const char* mhName = "method handle";
-    const char* targetType = "the required signature";
-    int targetArity = -1, mhArity = -1;
-    vframeStream vfst(thread, true);
-    if (!vfst.at_end()) {
-      Bytecode_invoke call(vfst.method(), vfst.bci());
-      methodHandle target;
-      {
-        EXCEPTION_MARK;
-        target = call.static_target(THREAD);
-        if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; }
-      }
-      if (target.not_null()
-          && target->is_method_handle_invoke()
-          && required == target->method_handle_type()) {
-        targetType = target->signature()->as_C_string();
-        targetArity = ArgumentCount(target->signature()).size();
-      }
-    }
-    KlassHandle kignore; int dmf_flags = 0;
-    methodHandle actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags);
-    if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver |
-                       MethodHandles::_dmf_does_dispatch |
-                       MethodHandles::_dmf_from_interface)) != 0)
-      actual_method = methodHandle();  // MH does extra binds, drops, etc.
-    bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0);
-    if (actual_method.not_null()) {
-      mhName = actual_method->signature()->as_C_string();
-      mhArity = ArgumentCount(actual_method->signature()).size();
-      if (!actual_method->is_static())  mhArity += 1;
-    } else if (java_lang_invoke_MethodHandle::is_instance(actual)) {
-      oopDesc* mhType = java_lang_invoke_MethodHandle::type(actual);
-      mhArity = java_lang_invoke_MethodType::ptype_count(mhType);
-      stringStream st;
-      java_lang_invoke_MethodType::print_signature(mhType, &st);
-      mhName = st.as_string();
-    }
-    if (targetArity != -1 && targetArity != mhArity) {
-      if (has_receiver && targetArity == mhArity-1)
-        desc = " cannot be called without a receiver argument as ";
-      else
-        desc = " cannot be called with a different arity as ";
-    }
-    message = generate_class_cast_message(mhName, targetType,
-                                          desc != NULL ? desc :
-                                          " cannot be called as ");
-  }
-  if (TraceMethodHandles) {
-    tty->print_cr("WrongMethodType => message=%s", message);
-  }
-  return message;
-}
-
-oop SharedRuntime::wrong_method_type_is_for_single_argument(JavaThread* thr,
-                                                            oopDesc* required) {
-  if (required == NULL)  return NULL;
-  if (required->klass() == SystemDictionary::Class_klass())
-    return required;
-  if (required->is_klass())
-    return Klass::cast(klassOop(required))->java_mirror();
-  return NULL;
-}
-
-
 char* SharedRuntime::generate_class_cast_message(
     const char* objName, const char* targetKlassName, const char* desc) {
   size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1;
@@ -2119,8 +1985,17 @@
 // that allows sharing of adapters for the same calling convention.
 class AdapterFingerPrint : public CHeapObj<mtCode> {
  private:
+  enum {
+    _basic_type_bits = 4,
+    _basic_type_mask = right_n_bits(_basic_type_bits),
+    _basic_types_per_int = BitsPerInt / _basic_type_bits,
+    _compact_int_count = 3
+  };
+  // TO DO:  Consider integrating this with a more global scheme for compressing signatures.
+  // For now, 4 bits per components (plus T_VOID gaps after double/long) is not excessive.
+
   union {
-    int  _compact[3];
+    int  _compact[_compact_int_count];
     int* _fingerprint;
   } _value;
   int _length; // A negative length indicates the fingerprint is in the compact form,
@@ -2129,8 +2004,7 @@
   // Remap BasicTypes that are handled equivalently by the adapters.
   // These are correct for the current system but someday it might be
   // necessary to make this mapping platform dependent.
-  static BasicType adapter_encoding(BasicType in) {
-    assert((~0xf & in) == 0, "must fit in 4 bits");
+  static int adapter_encoding(BasicType in) {
     switch(in) {
       case T_BOOLEAN:
       case T_BYTE:
@@ -2141,6 +2015,8 @@
 
       case T_OBJECT:
       case T_ARRAY:
+        // In other words, we assume that any register good enough for
+        // an int or long is good enough for a managed pointer.
 #ifdef _LP64
         return T_LONG;
 #else
@@ -2165,8 +2041,9 @@
     // The fingerprint is based on the BasicType signature encoded
     // into an array of ints with eight entries per int.
     int* ptr;
-    int len = (total_args_passed + 7) >> 3;
-    if (len <= (int)(sizeof(_value._compact) / sizeof(int))) {
+    int len = (total_args_passed + (_basic_types_per_int-1)) / _basic_types_per_int;
+    if (len <= _compact_int_count) {
+      assert(_compact_int_count == 3, "else change next line");
       _value._compact[0] = _value._compact[1] = _value._compact[2] = 0;
       // Storing the signature encoded as signed chars hits about 98%
       // of the time.
@@ -2182,10 +2059,12 @@
     int sig_index = 0;
     for (int index = 0; index < len; index++) {
       int value = 0;
-      for (int byte = 0; byte < 8; byte++) {
-        if (sig_index < total_args_passed) {
-          value = (value << 4) | adapter_encoding(sig_bt[sig_index++]);
-        }
+      for (int byte = 0; byte < _basic_types_per_int; byte++) {
+        int bt = ((sig_index < total_args_passed)
+                  ? adapter_encoding(sig_bt[sig_index++])
+                  : 0);
+        assert((bt & _basic_type_mask) == bt, "must fit in 4 bits");
+        value = (value << _basic_type_bits) | bt;
       }
       ptr[index] = value;
     }
@@ -2235,6 +2114,7 @@
       return false;
     }
     if (_length < 0) {
+      assert(_compact_int_count == 3, "else change next line");
       return _value._compact[0] == other->_value._compact[0] &&
              _value._compact[1] == other->_value._compact[1] &&
              _value._compact[2] == other->_value._compact[2];
@@ -2531,13 +2411,17 @@
     entry->relocate(B->content_begin());
 #ifndef PRODUCT
     // debugging suppport
-    if (PrintAdapterHandlers) {
-      tty->cr();
-      tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = %s, %d bytes generated)",
+    if (PrintAdapterHandlers || PrintStubCode) {
+      entry->print_adapter_on(tty);
+      tty->print_cr("i2c argument handler #%d for: %s %s (%d bytes generated)",
                     _adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"),
-                    method->signature()->as_C_string(), fingerprint->as_string(), insts_size );
+                    method->signature()->as_C_string(), insts_size);
       tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry());
-      Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + insts_size);
+      if (Verbose || PrintStubCode) {
+        address first_pc = entry->base_address();
+        if (first_pc != NULL)
+          Disassembler::decode(first_pc, first_pc + insts_size);
+      }
     }
 #endif
 
@@ -2561,11 +2445,25 @@
   return entry;
 }
 
+address AdapterHandlerEntry::base_address() {
+  address base = _i2c_entry;
+  if (base == NULL)  base = _c2i_entry;
+  assert(base <= _c2i_entry || _c2i_entry == NULL, "");
+  assert(base <= _c2i_unverified_entry || _c2i_unverified_entry == NULL, "");
+  return base;
+}
+
 void AdapterHandlerEntry::relocate(address new_base) {
-    ptrdiff_t delta = new_base - _i2c_entry;
+  address old_base = base_address();
+  assert(old_base != NULL, "");
+  ptrdiff_t delta = new_base - old_base;
+  if (_i2c_entry != NULL)
     _i2c_entry += delta;
+  if (_c2i_entry != NULL)
     _c2i_entry += delta;
+  if (_c2i_unverified_entry != NULL)
     _c2i_unverified_entry += delta;
+  assert(base_address() == new_base, "");
 }
 
 
@@ -2614,7 +2512,9 @@
   ResourceMark rm;
   nmethod* nm = NULL;
 
-  assert(method->has_native_function(), "must have something valid to call!");
+  assert(method->is_native(), "must be native");
+  assert(method->is_method_handle_intrinsic() ||
+         method->has_native_function(), "must have something valid to call!");
 
   {
     // perform the work while holding the lock, but perform any printing outside the lock
@@ -2651,9 +2551,11 @@
       assert( i==total_args_passed, "" );
       BasicType ret_type = ss.type();
 
-      // Now get the compiled-Java layout as input arguments
-      int comp_args_on_stack;
-      comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
+      // Now get the compiled-Java layout as input (or output) arguments.
+      // NOTE: Stubs for compiled entry points of method handle intrinsics
+      // are just trampolines so the argument registers must be outgoing ones.
+      const bool is_outgoing = method->is_method_handle_intrinsic();
+      int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
 
       // Generate the compiled-to-native wrapper code
       nm = SharedRuntime::generate_native_wrapper(&_masm,
@@ -2939,18 +2841,22 @@
   AdapterHandlerTableIterator iter(_adapters);
   while (iter.has_next()) {
     AdapterHandlerEntry* a = iter.next();
-    if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) {
+    if (b == CodeCache::find_blob(a->get_i2c_entry())) {
       st->print("Adapter for signature: ");
-      st->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
-                   a->fingerprint()->as_string(),
-                   a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry());
-
+      a->print_adapter_on(tty);
       return;
     }
   }
   assert(false, "Should have found handler");
 }
 
+void AdapterHandlerEntry::print_adapter_on(outputStream* st) const {
+  st->print_cr("AHE@" INTPTR_FORMAT ": %s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
+               (intptr_t) this, fingerprint()->as_string(),
+               get_i2c_entry(), get_c2i_entry(), get_c2i_unverified_entry());
+
+}
+
 #ifndef PRODUCT
 
 void AdapterHandlerLibrary::print_statistics() {