src/hotspot/cpu/x86/templateTable_x86.cpp
changeset 49368 2ed1c37df3a5
parent 49359 59f6547e151f
child 49449 ef5d5d343e2a
child 56348 f3b0961adb3c
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp	Fri Mar 09 12:03:20 2018 -0500
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp	Thu Feb 08 09:23:49 2018 +0100
@@ -3872,6 +3872,8 @@
 
   Label no_such_interface, no_such_method;
 
+  // Preserve method for throw_AbstractMethodErrorVerbose.
+  __ mov(rcx, rbx);
   // Receiver subtype check against REFC.
   // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
   __ lookup_interface_method(// inputs: rec. class, interface, itable index
@@ -3893,8 +3895,10 @@
   __ subl(rbx, Method::itable_index_max);
   __ negl(rbx);
 
+  // Preserve recvKlass for throw_AbstractMethodErrorVerbose.
+  __ mov(rlocals, rdx);
   __ lookup_interface_method(// inputs: rec. class, interface, itable index
-                             rdx, rax, rbx,
+                             rlocals, rax, rbx,
                              // outputs: method, scan temp. reg
                              rbx, rbcp,
                              no_such_interface);
@@ -3926,8 +3930,19 @@
   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
-  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
-  // the call_VM checks for exception, so we should never return here.
+  // Pass arguments for generating a verbose error message.
+#ifdef _LP64
+  Register recvKlass = c_rarg1;
+  Register method    = c_rarg2;
+  if (recvKlass != rdx) { __ movq(recvKlass, rdx); }
+  if (method != rcx)    { __ movq(method, rcx);    }
+#else
+  Register recvKlass = rdx;
+  Register method    = rcx;
+#endif
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose),
+             recvKlass, method);
+  // The call_VM checks for exception, so we should never return here.
   __ should_not_reach_here();
 
   __ bind(no_such_interface);
@@ -3935,8 +3950,10 @@
   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
-  __ call_VM(noreg, CAST_FROM_FN_PTR(address,
-                   InterpreterRuntime::throw_IncompatibleClassChangeError));
+  // Pass arguments for generating a verbose error message.
+  LP64_ONLY( if (recvKlass != rdx) { __ movq(recvKlass, rdx); } )
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose),
+             recvKlass, rax);
   // the call_VM checks for exception, so we should never return here.
   __ should_not_reach_here();
 }