1/* 2 * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25// This file mirror as much as possible methodHandles_x86.cpp to ease 26// cross platform development for JSR292. 27// Last synchronization: changeset f8c9417e3571 28 29#include "precompiled.hpp" 30#include "classfile/javaClasses.inline.hpp" 31#include "interpreter/interpreter.hpp" 32#include "interpreter/interpreterRuntime.hpp" 33#include "memory/allocation.inline.hpp" 34#include "memory/resourceArea.hpp" 35#include "prims/jvm.h" 36#include "prims/methodHandles.hpp" 37 38#define __ _masm-> 39 40#ifdef PRODUCT 41#define BLOCK_COMMENT(str) /* nothing */ 42#else 43#define BLOCK_COMMENT(str) __ block_comment(str) 44#endif 45 46#define BIND(label) bind(label); BLOCK_COMMENT(#label ":") 47 48void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp1, Register temp2) { 49 if (VerifyMethodHandles) { 50 verify_klass(_masm, klass_reg, temp1, temp2, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), 51 "MH argument is a Class"); 52 } 53 __ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes())); 54} 55 56#ifdef ASSERT 57static int check_nonzero(const char* xname, int x) { 58 assert(x != 0, "%s should be nonzero", xname); 59 return x; 60} 61#define NONZERO(x) check_nonzero(#x, x) 62#else //ASSERT 63#define NONZERO(x) (x) 64#endif //ASSERT 65 66#ifdef ASSERT 67void MethodHandles::verify_klass(MacroAssembler* _masm, 68 Register obj, Register temp1, Register temp2, SystemDictionary::WKID klass_id, 69 const char* error_message) { 70 InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id); 71 Klass* klass = SystemDictionary::well_known_klass(klass_id); 72 Label L_ok, L_bad; 73 BLOCK_COMMENT("verify_klass {"); 74 __ verify_oop(obj); 75 __ cbz(obj, L_bad); 76 __ load_klass(temp1, obj); 77 __ lea(temp2, ExternalAddress((address) klass_addr)); 78 __ ldr(temp2, temp2); // the cmpptr on x86 dereferences the AddressLiteral (not lea) 79 __ cmp(temp1, temp2); 80 __ b(L_ok, eq); 81 intptr_t super_check_offset = klass->super_check_offset(); 82 __ ldr(temp1, Address(temp1, super_check_offset)); 83 __ cmp(temp1, temp2); 84 __ b(L_ok, eq); 85 86 __ bind(L_bad); 87 __ stop(error_message); 88 __ BIND(L_ok); 89 BLOCK_COMMENT("} verify_klass"); 90} 91 92void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) { 93 Label L; 94 BLOCK_COMMENT("verify_ref_kind {"); 95 __ ldr_u32(temp, Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes()))); 96 __ logical_shift_right(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT); 97 __ andr(temp, temp, (unsigned)java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK); 98 __ cmp(temp, ref_kind); 99 __ b(L, eq); 100 { char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal); 101 jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind); 102 if (ref_kind == JVM_REF_invokeVirtual || 103 ref_kind == JVM_REF_invokeSpecial) 104 // could do this for all ref_kinds, but would explode assembly code size 105 trace_method_handle(_masm, buf); 106 __ stop(buf); 107 } 108 BLOCK_COMMENT("} verify_ref_kind"); 109 __ bind(L); 110} 111 112#endif //ASSERT 113 114void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, bool for_compiler_entry) { 115 Label L_no_such_method; 116 __ cbz(Rmethod, L_no_such_method); 117 118 // Note: JVMTI overhead seems small enough compared to invocation 119 // cost and is not worth the complexity or code size overhead of 120 // supporting several variants of each adapter. 121 if (!for_compiler_entry && (JvmtiExport::can_post_interpreter_events())) { 122 // JVMTI events, such as single-stepping, are implemented partly by avoiding running 123 // compiled code in threads for which the event is enabled. Check here for 124 // interp_only_mode if these events CAN be enabled. 125 __ ldr_s32(Rtemp, Address(Rthread, JavaThread::interp_only_mode_offset())); 126#ifdef AARCH64 127 Label L; 128 __ cbz(Rtemp, L); 129 __ indirect_jump(Address(Rmethod, Method::interpreter_entry_offset()), Rtemp); 130 __ bind(L); 131#else 132 __ cmp(Rtemp, 0); 133 __ ldr(PC, Address(Rmethod, Method::interpreter_entry_offset()), ne); 134#endif // AARCH64 135 } 136 const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : 137 Method::from_interpreted_offset(); 138 139 __ indirect_jump(Address(Rmethod, entry_offset), Rtemp); 140 141 __ bind(L_no_such_method); 142 // throw exception 143 __ jump(StubRoutines::throw_AbstractMethodError_entry(), relocInfo::runtime_call_type, Rtemp); 144} 145 146void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, 147 Register recv, Register tmp, 148 bool for_compiler_entry) { 149 BLOCK_COMMENT("jump_to_lambda_form {"); 150 // This is the initial entry point of a lazy method handle. 151 // After type checking, it picks up the invoker from the LambdaForm. 152 assert_different_registers(recv, tmp, Rmethod); 153 154 // Load the invoker, as MH -> MH.form -> LF.vmentry 155 __ load_heap_oop(tmp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()))); 156 __ verify_oop(tmp); 157 158 __ load_heap_oop(tmp, Address(tmp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()))); 159 __ verify_oop(tmp); 160 161 __ load_heap_oop(Rmethod, Address(tmp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()))); 162 __ verify_oop(Rmethod); 163 __ ldr(Rmethod, Address(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()))); 164 165 if (VerifyMethodHandles && !for_compiler_entry) { 166 // make sure recv is already on stack 167 __ ldr(tmp, Address(Rmethod, Method::const_offset())); 168 __ load_sized_value(tmp, 169 Address(tmp, ConstMethod::size_of_parameters_offset()), 170 sizeof(u2), /*is_signed*/ false); 171 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); 172 Label L; 173 __ ldr(tmp, __ receiver_argument_address(Rparams, tmp, tmp)); 174 __ cmp(tmp, recv); 175 __ b(L, eq); 176 __ stop("receiver not on stack"); 177 __ bind(L); 178 } 179 180 jump_from_method_handle(_masm, for_compiler_entry); 181 BLOCK_COMMENT("} jump_to_lambda_form"); 182} 183 184 185// Code generation 186address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm, 187 vmIntrinsics::ID iid) { 188 const bool not_for_compiler_entry = false; // this is the interpreter entry 189 assert(is_signature_polymorphic(iid), "expected invoke iid"); 190 if (iid == vmIntrinsics::_invokeGeneric || 191 iid == vmIntrinsics::_compiledLambdaForm) { 192 // Perhaps surprisingly, the user-visible names, and linkToCallSite, are not directly used. 193 // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod. 194 // They all require an extra argument. 195 __ should_not_reach_here(); // empty stubs make SG sick 196 return NULL; 197 } 198 199 // Rmethod: Method* 200 // Rparams (SP on 32-bit ARM): pointer to parameters 201 // Rsender_sp (R4/R19): sender SP (must preserve; see prepare_to_jump_from_interpreted) 202 // R5_mh: receiver method handle (must load from sp[MethodTypeForm.vmslots]) 203 // R1, R2, Rtemp: garbage temp, blown away 204 205 // Use same name as x86 to ease future merges 206 Register rdx_temp = R2_tmp; 207 Register rdx_param_size = rdx_temp; // size of parameters 208 Register rax_temp = R1_tmp; 209 Register rcx_mh = R5_mh; // MH receiver; dies quickly and is recycled 210 Register rbx_method = Rmethod; // eventual target of this invocation 211 Register rdi_temp = Rtemp; 212 213 // here's where control starts out: 214 __ align(CodeEntryAlignment); 215 address entry_point = __ pc(); 216 217 if (VerifyMethodHandles) { 218 Label L; 219 BLOCK_COMMENT("verify_intrinsic_id {"); 220 __ ldrh(rdi_temp, Address(rbx_method, Method::intrinsic_id_offset_in_bytes())); 221 __ sub_slow(rdi_temp, rdi_temp, (int) iid); 222 __ cbz(rdi_temp, L); 223 if (iid == vmIntrinsics::_linkToVirtual || 224 iid == vmIntrinsics::_linkToSpecial) { 225 // could do this for all kinds, but would explode assembly code size 226 trace_method_handle(_masm, "bad Method*::intrinsic_id"); 227 } 228 __ stop("bad Method*::intrinsic_id"); 229 __ bind(L); 230 BLOCK_COMMENT("} verify_intrinsic_id"); 231 } 232 233 // First task: Find out how big the argument list is. 234 Address rdx_first_arg_addr; 235 int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid); 236 assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic"); 237 if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) { 238 __ ldr(rdx_param_size, Address(rbx_method, Method::const_offset())); 239 __ load_sized_value(rdx_param_size, 240 Address(rdx_param_size, ConstMethod::size_of_parameters_offset()), 241 sizeof(u2), /*is_signed*/ false); 242 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); 243 rdx_first_arg_addr = __ receiver_argument_address(Rparams, rdx_param_size, rdi_temp); 244 } else { 245 DEBUG_ONLY(rdx_param_size = noreg); 246 } 247 248 if (!is_signature_polymorphic_static(iid)) { 249 __ ldr(rcx_mh, rdx_first_arg_addr); 250 DEBUG_ONLY(rdx_param_size = noreg); 251 } 252 253 // rdx_first_arg_addr is live! 254 255 trace_method_handle_interpreter_entry(_masm, iid); 256 257 if (iid == vmIntrinsics::_invokeBasic) { 258 generate_method_handle_dispatch(_masm, iid, rcx_mh, noreg, not_for_compiler_entry); 259 260 } else { 261 // Adjust argument list by popping the trailing MemberName argument. 262 Register rcx_recv = noreg; 263 if (MethodHandles::ref_kind_has_receiver(ref_kind)) { 264 // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack. 265 __ ldr(rcx_recv = rcx_mh, rdx_first_arg_addr); 266 DEBUG_ONLY(rdx_param_size = noreg); 267 } 268 Register rbx_member = rbx_method; // MemberName ptr; incoming method ptr is dead now 269#ifdef AARCH64 270 __ ldr(rbx_member, Address(Rparams, Interpreter::stackElementSize, post_indexed)); 271#else 272 __ pop(rbx_member); 273#endif 274 generate_method_handle_dispatch(_masm, iid, rcx_recv, rbx_member, not_for_compiler_entry); 275 } 276 return entry_point; 277} 278 279void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, 280 vmIntrinsics::ID iid, 281 Register receiver_reg, 282 Register member_reg, 283 bool for_compiler_entry) { 284 assert(is_signature_polymorphic(iid), "expected invoke iid"); 285 // Use same name as x86 to ease future merges 286 Register rbx_method = Rmethod; // eventual target of this invocation 287 // temps used in this code are not used in *either* compiled or interpreted calling sequences 288 Register temp1 = (for_compiler_entry ? saved_last_sp_register() : R1_tmp); 289 Register temp2 = AARCH64_ONLY(R9) NOT_AARCH64(R8); 290 Register temp3 = Rtemp; // R12/R16 291 Register temp4 = AARCH64_ONLY(Rtemp2) NOT_AARCH64(R5); 292 if (for_compiler_entry) { 293 assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : j_rarg0), "only valid assignment"); 294#ifdef AARCH64 295 assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7); 296 assert_different_registers(temp2, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7); 297 assert_different_registers(temp3, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7); 298 assert_different_registers(temp4, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7); 299#else 300 assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3); 301 assert_different_registers(temp2, j_rarg0, j_rarg1, j_rarg2, j_rarg3); 302 assert_different_registers(temp3, j_rarg0, j_rarg1, j_rarg2, j_rarg3); 303 assert_different_registers(temp4, j_rarg0, j_rarg1, j_rarg2, j_rarg3); 304#endif // AARCH64 305 } 306 assert_different_registers(temp1, temp2, temp3, receiver_reg); 307 assert_different_registers(temp1, temp2, temp3, temp4, member_reg); 308 if (!for_compiler_entry) 309 assert_different_registers(temp1, temp2, temp3, temp4, saved_last_sp_register()); // don't trash lastSP 310 311 if (iid == vmIntrinsics::_invokeBasic) { 312 // indirect through MH.form.exactInvoker.vmtarget 313 jump_to_lambda_form(_masm, receiver_reg, temp3, for_compiler_entry); 314 315 } else { 316 // The method is a member invoker used by direct method handles. 317 if (VerifyMethodHandles) { 318 // make sure the trailing argument really is a MemberName (caller responsibility) 319 verify_klass(_masm, member_reg, temp2, temp3, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_invoke_MemberName), 320 "MemberName required for invokeVirtual etc."); 321 } 322 323 Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes())); 324 Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes())); 325 Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())); 326 Address vmtarget_method(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())); 327 328 Register temp1_recv_klass = temp1; 329 if (iid != vmIntrinsics::_linkToStatic) { 330 if (iid == vmIntrinsics::_linkToSpecial) { 331 // Don't actually load the klass; just null-check the receiver. 332 __ null_check(receiver_reg, temp3); 333 } else { 334 // load receiver klass itself 335 __ null_check(receiver_reg, temp3, oopDesc::klass_offset_in_bytes()); 336 __ load_klass(temp1_recv_klass, receiver_reg); 337 __ verify_klass_ptr(temp1_recv_klass); 338 } 339 BLOCK_COMMENT("check_receiver {"); 340 // The receiver for the MemberName must be in receiver_reg. 341 // Check the receiver against the MemberName.clazz 342 if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) { 343 // Did not load it above... 344 __ load_klass(temp1_recv_klass, receiver_reg); 345 __ verify_klass_ptr(temp1_recv_klass); 346 } 347 // Check the receiver against the MemberName.clazz 348 if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) { 349 Label L_ok; 350 Register temp2_defc = temp2; 351 __ load_heap_oop(temp2_defc, member_clazz); 352 load_klass_from_Class(_masm, temp2_defc, temp3, temp4); 353 __ verify_klass_ptr(temp2_defc); 354#ifdef AARCH64 355 // TODO-AARCH64 356 __ b(L_ok); 357#else 358 __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, noreg, L_ok); 359#endif 360 // If we get here, the type check failed! 361 __ stop("receiver class disagrees with MemberName.clazz"); 362 __ bind(L_ok); 363 } 364 BLOCK_COMMENT("} check_receiver"); 365 } 366 if (iid == vmIntrinsics::_linkToSpecial || 367 iid == vmIntrinsics::_linkToStatic) { 368 DEBUG_ONLY(temp1_recv_klass = noreg); // these guys didn't load the recv_klass 369 } 370 371 // Live registers at this point: 372 // member_reg - MemberName that was the extra argument 373 // temp1_recv_klass - klass of stacked receiver, if needed 374 375 Label L_incompatible_class_change_error; 376 switch (iid) { 377 case vmIntrinsics::_linkToSpecial: 378 if (VerifyMethodHandles) { 379 verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); 380 } 381 __ load_heap_oop(Rmethod, member_vmtarget); 382 __ ldr(Rmethod, vmtarget_method); 383 break; 384 385 case vmIntrinsics::_linkToStatic: 386 if (VerifyMethodHandles) { 387 verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); 388 } 389 __ load_heap_oop(Rmethod, member_vmtarget); 390 __ ldr(Rmethod, vmtarget_method); 391 break; 392 break; 393 394 case vmIntrinsics::_linkToVirtual: 395 { 396 // same as TemplateTable::invokevirtual, 397 // minus the CP setup and profiling: 398 399 if (VerifyMethodHandles) { 400 verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3); 401 } 402 403 // pick out the vtable index from the MemberName, and then we can discard it: 404 Register temp2_index = temp2; 405 __ ldr(temp2_index, member_vmindex); 406 407 if (VerifyMethodHandles) { 408 Label L_index_ok; 409 __ cmp(temp2_index, 0); 410 __ b(L_index_ok, ge); 411 __ stop("no virtual index"); 412 __ bind(L_index_ok); 413 } 414 415 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget 416 // at this point. And VerifyMethodHandles has already checked clazz, if needed. 417 418 // get target Method* & entry point 419 __ lookup_virtual_method(temp1_recv_klass, temp2_index, Rmethod); 420 break; 421 } 422 423 case vmIntrinsics::_linkToInterface: 424 { 425 // same as TemplateTable::invokeinterface 426 // (minus the CP setup and profiling, with different argument motion) 427 if (VerifyMethodHandles) { 428 verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3); 429 } 430 431 Register temp3_intf = temp3; 432 __ load_heap_oop(temp3_intf, member_clazz); 433 load_klass_from_Class(_masm, temp3_intf, temp2, temp4); 434 __ verify_klass_ptr(temp3_intf); 435 436 Register rbx_index = rbx_method; 437 __ ldr(rbx_index, member_vmindex); 438 if (VerifyMethodHandles) { 439 Label L; 440 __ cmp(rbx_index, 0); 441 __ b(L, ge); 442 __ stop("invalid vtable index for MH.invokeInterface"); 443 __ bind(L); 444 } 445 446 // given intf, index, and recv klass, dispatch to the implementation method 447 Label L_no_such_interface; 448 __ lookup_interface_method(temp1_recv_klass, temp3_intf, 449 // note: next two args must be the same: 450 rbx_index, rbx_method, 451 temp2, temp4, 452 L_incompatible_class_change_error); 453 break; 454 } 455 456 default: 457 fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)); 458 break; 459 } 460 461 // Live at this point: 462 // Rmethod (target method) 463 // Rsender_sp, Rparams (if interpreted) 464 // register arguments (if compiled) 465 466 // After figuring out which concrete method to call, jump into it. 467 __ verify_method_ptr(Rmethod); 468 jump_from_method_handle(_masm, for_compiler_entry); 469 470 if (iid == vmIntrinsics::_linkToInterface) { 471 __ bind(L_incompatible_class_change_error); 472 __ jump(StubRoutines::throw_IncompatibleClassChangeError_entry(), relocInfo::runtime_call_type, Rtemp); 473 } 474 } 475} 476 477 478#ifndef PRODUCT 479enum { 480 ARG_LIMIT = 255, SLOP = 4, 481 // use this parameter for checking for garbage stack movements: 482 UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP) 483 // the slop defends against false alarms due to fencepost errors 484}; 485 486#ifdef AARCH64 487const int trace_mh_nregs = 32; // R0-R30, PC 488#else 489const int trace_mh_nregs = 15; 490const Register trace_mh_regs[trace_mh_nregs] = 491 {R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, PC}; 492#endif // AARCH64 493 494void trace_method_handle_stub(const char* adaptername, 495 intptr_t* saved_regs, 496 intptr_t* saved_bp, 497 oop mh) { 498 // called as a leaf from native code: do not block the JVM! 499 bool has_mh = (strstr(adaptername, "/static") == NULL && 500 strstr(adaptername, "linkTo") == NULL); // static linkers don't have MH 501 intptr_t* entry_sp = (intptr_t*) &saved_regs[trace_mh_nregs]; // just after the saved regs 502 intptr_t* saved_sp = (intptr_t*) saved_regs[Rsender_sp->encoding()]; // save of Rsender_sp 503 intptr_t* last_sp = (intptr_t*) saved_bp[AARCH64_ONLY(frame::interpreter_frame_stack_top_offset) NOT_AARCH64(frame::interpreter_frame_last_sp_offset)]; 504 intptr_t* base_sp = last_sp; 505 506 intptr_t mh_reg = (intptr_t)saved_regs[R5_mh->encoding()]; 507 const char* mh_reg_name = "R5_mh"; 508 if (!has_mh) mh_reg_name = "R5"; 509 tty->print_cr("MH %s %s=" PTR_FORMAT " sp=(" PTR_FORMAT "+" INTX_FORMAT ") stack_size=" INTX_FORMAT " bp=" PTR_FORMAT, 510 adaptername, mh_reg_name, mh_reg, 511 (intptr_t)entry_sp, (intptr_t)saved_sp - (intptr_t)entry_sp, (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); 512 513 if (last_sp != saved_sp && last_sp != NULL) 514 tty->print_cr("*** last_sp=" INTPTR_FORMAT, p2i(last_sp)); 515 if (Verbose) { 516 tty->print(" reg dump: "); 517 int i; 518 for (i = 0; i < trace_mh_nregs; i++) { 519 if (i > 0 && i % AARCH64_ONLY(2) NOT_AARCH64(4) == 0) 520 tty->print("\n + dump: "); 521#ifdef AARCH64 522 const char* reg_name = (i == trace_mh_nregs-1) ? "pc" : as_Register(i)->name(); 523#else 524 const char* reg_name = trace_mh_regs[i]->name(); 525#endif 526 tty->print(" %s: " INTPTR_FORMAT, reg_name, p2i((void *)saved_regs[i])); 527 } 528 tty->cr(); 529 } 530 531 if (Verbose) { 532 // dump last frame (from JavaThread::print_frame_layout) 533 534 // Note: code is robust but the dumped informationm may not be 535 // 100% correct, particularly with respect to the dumped 536 // "unextended_sp". Getting it right for all trace_method_handle 537 // call paths is not worth the complexity/risk. The correct slot 538 // will be identified by *Rsender_sp anyway in the dump. 539 JavaThread* p = JavaThread::active(); 540 541 ResourceMark rm; 542 PRESERVE_EXCEPTION_MARK; 543 FrameValues values; 544 545 intptr_t* dump_fp = (intptr_t *) saved_bp; 546 address dump_pc = (address) saved_regs[trace_mh_nregs-2]; // LR (with LR,PC last in saved_regs) 547 frame dump_frame((intptr_t *)entry_sp, dump_fp, dump_pc); 548 549 dump_frame.describe(values, 1); 550 // mark Rsender_sp if seems valid 551 if (has_mh) { 552 if ((saved_sp >= entry_sp - UNREASONABLE_STACK_MOVE) && (saved_sp < dump_fp)) { 553 values.describe(-1, saved_sp, "*Rsender_sp"); 554 } 555 } 556 557 // Note: the unextended_sp may not be correct 558 tty->print_cr(" stack layout:"); 559 values.print(p); 560 } 561 if (Verbose) { 562 if (has_mh && oopDesc::is_oop(mh)) { 563 mh->print(); 564 if (java_lang_invoke_MethodHandle::is_instance(mh)) { 565 if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0) 566 java_lang_invoke_MethodHandle::form(mh)->print(); 567 } 568 } 569 } 570} 571 572void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { 573 if (!TraceMethodHandles) return; 574 BLOCK_COMMENT("trace_method_handle {"); 575 // register saving 576 // must correspond to trace_mh_nregs and trace_mh_regs defined above 577 int push_size = __ save_all_registers(); 578 assert(trace_mh_nregs*wordSize == push_size,"saved register count mismatch"); 579 580 __ mov_slow(R0, adaptername); 581 __ mov(R1, SP); // entry_sp (after pushes) 582 __ mov(R2, FP); 583 if (R5_mh != R3) { 584 assert_different_registers(R0, R1, R2, R5_mh); 585 __ mov(R3, R5_mh); 586 } 587 588 __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), R0, R1, R2, R3); 589 590 __ restore_all_registers(); 591 BLOCK_COMMENT("} trace_method_handle"); 592} 593#endif //PRODUCT 594