1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/ppc/vm/methodHandles_ppc.cpp Fri Aug 02 16:46:45 2013 +0200 1.3 @@ -0,0 +1,540 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +#include "precompiled.hpp" 1.30 +#include "asm/macroAssembler.inline.hpp" 1.31 +#include "interpreter/interpreter.hpp" 1.32 +#include "memory/allocation.inline.hpp" 1.33 +#include "prims/methodHandles.hpp" 1.34 + 1.35 +#define __ _masm-> 1.36 + 1.37 +#ifdef PRODUCT 1.38 +#define BLOCK_COMMENT(str) // nothing 1.39 +#define STOP(error) stop(error) 1.40 +#else 1.41 +#define BLOCK_COMMENT(str) __ block_comment(str) 1.42 +#define STOP(error) block_comment(error); __ stop(error) 1.43 +#endif 1.44 + 1.45 +#define BIND(label) bind(label); BLOCK_COMMENT(#label ":") 1.46 + 1.47 +// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant. 1.48 +inline static RegisterOrConstant constant(int value) { 1.49 + return RegisterOrConstant(value); 1.50 +} 1.51 + 1.52 +void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) { 1.53 + if (VerifyMethodHandles) 1.54 + verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), temp_reg, temp2_reg, 1.55 + "MH argument is a Class"); 1.56 + __ ld(klass_reg, java_lang_Class::klass_offset_in_bytes(), klass_reg); 1.57 +} 1.58 + 1.59 +#ifdef ASSERT 1.60 +static int check_nonzero(const char* xname, int x) { 1.61 + assert(x != 0, err_msg("%s should be nonzero", xname)); 1.62 + return x; 1.63 +} 1.64 +#define NONZERO(x) check_nonzero(#x, x) 1.65 +#else //ASSERT 1.66 +#define NONZERO(x) (x) 1.67 +#endif //ASSERT 1.68 + 1.69 +#ifdef ASSERT 1.70 +void MethodHandles::verify_klass(MacroAssembler* _masm, 1.71 + Register obj_reg, SystemDictionary::WKID klass_id, 1.72 + Register temp_reg, Register temp2_reg, 1.73 + const char* error_message) { 1.74 + Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id); 1.75 + KlassHandle klass = SystemDictionary::well_known_klass(klass_id); 1.76 + Label L_ok, L_bad; 1.77 + BLOCK_COMMENT("verify_klass {"); 1.78 + __ verify_oop(obj_reg); 1.79 + __ cmpdi(CCR0, obj_reg, 0); 1.80 + __ beq(CCR0, L_bad); 1.81 + __ load_klass(temp_reg, obj_reg); 1.82 + __ load_const_optimized(temp2_reg, (address) klass_addr); 1.83 + __ ld(temp2_reg, 0, temp2_reg); 1.84 + __ cmpd(CCR0, temp_reg, temp2_reg); 1.85 + __ beq(CCR0, L_ok); 1.86 + __ ld(temp_reg, klass->super_check_offset(), temp_reg); 1.87 + __ cmpd(CCR0, temp_reg, temp2_reg); 1.88 + __ beq(CCR0, L_ok); 1.89 + __ BIND(L_bad); 1.90 + __ stop(error_message); 1.91 + __ BIND(L_ok); 1.92 + BLOCK_COMMENT("} verify_klass"); 1.93 +} 1.94 + 1.95 +void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) { 1.96 + Label L; 1.97 + BLOCK_COMMENT("verify_ref_kind {"); 1.98 + __ load_sized_value(temp, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes()), member_reg, 1.99 + sizeof(u4), /*is_signed*/ false); 1.100 + // assert(sizeof(u4) == sizeof(java.lang.invoke.MemberName.flags), ""); 1.101 + __ srwi( temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT); 1.102 + __ andi(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK); 1.103 + __ cmpwi(CCR1, temp, ref_kind); 1.104 + __ beq(CCR1, L); 1.105 + { char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal); 1.106 + jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind); 1.107 + if (ref_kind == JVM_REF_invokeVirtual || 1.108 + ref_kind == JVM_REF_invokeSpecial) 1.109 + // could do this for all ref_kinds, but would explode assembly code size 1.110 + trace_method_handle(_masm, buf); 1.111 + __ stop(buf); 1.112 + } 1.113 + BLOCK_COMMENT("} verify_ref_kind"); 1.114 + __ BIND(L); 1.115 +} 1.116 + 1.117 +#endif // ASSERT 1.118 + 1.119 +void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp, 1.120 + bool for_compiler_entry) { 1.121 + assert(method == R19_method, "interpreter calling convention"); 1.122 + assert_different_registers(method, target, temp); 1.123 + 1.124 + if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) { 1.125 + Label run_compiled_code; 1.126 + // JVMTI events, such as single-stepping, are implemented partly by avoiding running 1.127 + // compiled code in threads for which the event is enabled. Check here for 1.128 + // interp_only_mode if these events CAN be enabled. 1.129 + __ verify_thread(); 1.130 + __ lwz(temp, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread); 1.131 + __ cmplwi(CCR0, temp, 0); 1.132 + __ beq(CCR0, run_compiled_code); 1.133 + __ ld(target, in_bytes(Method::interpreter_entry_offset()), R19_method); 1.134 + __ mtctr(target); 1.135 + __ bctr(); 1.136 + __ BIND(run_compiled_code); 1.137 + } 1.138 + 1.139 + const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : 1.140 + Method::from_interpreted_offset(); 1.141 + __ ld(target, in_bytes(entry_offset), R19_method); 1.142 + __ mtctr(target); 1.143 + __ bctr(); 1.144 +} 1.145 + 1.146 + 1.147 +void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, 1.148 + Register recv, Register method_temp, 1.149 + Register temp2, Register temp3, 1.150 + bool for_compiler_entry) { 1.151 + BLOCK_COMMENT("jump_to_lambda_form {"); 1.152 + // This is the initial entry point of a lazy method handle. 1.153 + // After type checking, it picks up the invoker from the LambdaForm. 1.154 + assert_different_registers(recv, method_temp, temp2); // temp3 is only passed on 1.155 + assert(method_temp == R19_method, "required register for loading method"); 1.156 + 1.157 + // Load the invoker, as MH -> MH.form -> LF.vmentry 1.158 + __ verify_oop(recv); 1.159 + __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv); 1.160 + __ verify_oop(method_temp); 1.161 + __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp); 1.162 + __ verify_oop(method_temp); 1.163 + // the following assumes that a Method* is normally compressed in the vmtarget field: 1.164 + __ ld(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), method_temp); 1.165 + 1.166 + if (VerifyMethodHandles && !for_compiler_entry) { 1.167 + // make sure recv is already on stack 1.168 + __ ld(temp2, in_bytes(Method::const_offset()), method_temp); 1.169 + __ load_sized_value(temp2, in_bytes(ConstMethod::size_of_parameters_offset()), temp2, 1.170 + sizeof(u2), /*is_signed*/ false); 1.171 + // assert(sizeof(u2) == sizeof(ConstMethod::_size_of_parameters), ""); 1.172 + Label L; 1.173 + __ ld(temp2, __ argument_offset(temp2, temp2, 0), R17_tos); 1.174 + __ cmpd(CCR1, temp2, recv); 1.175 + __ beq(CCR1, L); 1.176 + __ stop("receiver not on stack"); 1.177 + __ BIND(L); 1.178 + } 1.179 + 1.180 + jump_from_method_handle(_masm, method_temp, temp2, temp3, for_compiler_entry); 1.181 + BLOCK_COMMENT("} jump_to_lambda_form"); 1.182 +} 1.183 + 1.184 + 1.185 + 1.186 +// Code generation 1.187 +address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm, 1.188 + vmIntrinsics::ID iid) { 1.189 + const bool not_for_compiler_entry = false; // this is the interpreter entry 1.190 + assert(is_signature_polymorphic(iid), "expected invoke iid"); 1.191 + if (iid == vmIntrinsics::_invokeGeneric || 1.192 + iid == vmIntrinsics::_compiledLambdaForm) { 1.193 + // Perhaps surprisingly, the symbolic references visible to Java are not directly used. 1.194 + // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod. 1.195 + // They all allow an appendix argument. 1.196 + __ stop("Should not reach here"); // empty stubs make SG sick 1.197 + return NULL; 1.198 + } 1.199 + 1.200 + Register argbase = R17_tos; // parameter (preserved) 1.201 + Register argslot = R3; 1.202 + Register temp1 = R6; 1.203 + Register param_size = R7; 1.204 + 1.205 + // here's where control starts out: 1.206 + __ align(CodeEntryAlignment); 1.207 + address entry_point = __ pc(); 1.208 + 1.209 + if (VerifyMethodHandles) { 1.210 + Label L; 1.211 + BLOCK_COMMENT("verify_intrinsic_id {"); 1.212 + __ load_sized_value(temp1, Method::intrinsic_id_offset_in_bytes(), R19_method, 1.213 + sizeof(u1), /*is_signed*/ false); 1.214 + // assert(sizeof(u1) == sizeof(Method::_intrinsic_id), ""); 1.215 + __ cmpwi(CCR1, temp1, (int) iid); 1.216 + __ beq(CCR1, L); 1.217 + if (iid == vmIntrinsics::_linkToVirtual || 1.218 + iid == vmIntrinsics::_linkToSpecial) { 1.219 + // could do this for all kinds, but would explode assembly code size 1.220 + trace_method_handle(_masm, "bad Method*:intrinsic_id"); 1.221 + } 1.222 + __ stop("bad Method*::intrinsic_id"); 1.223 + __ BIND(L); 1.224 + BLOCK_COMMENT("} verify_intrinsic_id"); 1.225 + } 1.226 + 1.227 + // First task: Find out how big the argument list is. 1.228 + int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid); 1.229 + assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic"); 1.230 + if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) { 1.231 + __ ld(param_size, in_bytes(Method::const_offset()), R19_method); 1.232 + __ load_sized_value(param_size, in_bytes(ConstMethod::size_of_parameters_offset()), param_size, 1.233 + sizeof(u2), /*is_signed*/ false); 1.234 + // assert(sizeof(u2) == sizeof(ConstMethod::_size_of_parameters), ""); 1.235 + } else { 1.236 + DEBUG_ONLY(param_size = noreg); 1.237 + } 1.238 + 1.239 + Register tmp_mh = noreg; 1.240 + if (!is_signature_polymorphic_static(iid)) { 1.241 + __ ld(tmp_mh = temp1, __ argument_offset(param_size, param_size, 0), argbase); 1.242 + DEBUG_ONLY(param_size = noreg); 1.243 + } 1.244 + 1.245 + if (TraceMethodHandles) { 1.246 + if (tmp_mh != noreg) 1.247 + __ mr(R23_method_handle, tmp_mh); // make stub happy 1.248 + trace_method_handle_interpreter_entry(_masm, iid); 1.249 + } 1.250 + 1.251 + if (iid == vmIntrinsics::_invokeBasic) { 1.252 + generate_method_handle_dispatch(_masm, iid, tmp_mh, noreg, not_for_compiler_entry); 1.253 + 1.254 + } else { 1.255 + // Adjust argument list by popping the trailing MemberName argument. 1.256 + Register tmp_recv = noreg; 1.257 + if (MethodHandles::ref_kind_has_receiver(ref_kind)) { 1.258 + // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack. 1.259 + __ ld(tmp_recv = temp1, __ argument_offset(param_size, param_size, 0), argbase); 1.260 + DEBUG_ONLY(param_size = noreg); 1.261 + } 1.262 + Register R19_member = R19_method; // MemberName ptr; incoming method ptr is dead now 1.263 + __ ld(R19_member, RegisterOrConstant((intptr_t)8), argbase); 1.264 + __ add(argbase, Interpreter::stackElementSize, argbase); 1.265 + generate_method_handle_dispatch(_masm, iid, tmp_recv, R19_member, not_for_compiler_entry); 1.266 + } 1.267 + 1.268 + return entry_point; 1.269 +} 1.270 + 1.271 +void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, 1.272 + vmIntrinsics::ID iid, 1.273 + Register receiver_reg, 1.274 + Register member_reg, 1.275 + bool for_compiler_entry) { 1.276 + assert(is_signature_polymorphic(iid), "expected invoke iid"); 1.277 + Register temp1 = (for_compiler_entry ? R21_tmp1 : R7); 1.278 + Register temp2 = (for_compiler_entry ? R22_tmp2 : R8); 1.279 + Register temp3 = (for_compiler_entry ? R23_tmp3 : R9); 1.280 + Register temp4 = (for_compiler_entry ? R24_tmp4 : R10); 1.281 + if (receiver_reg != noreg) assert_different_registers(temp1, temp2, temp3, temp4, receiver_reg); 1.282 + if (member_reg != noreg) assert_different_registers(temp1, temp2, temp3, temp4, member_reg); 1.283 + 1.284 + if (iid == vmIntrinsics::_invokeBasic) { 1.285 + // indirect through MH.form.vmentry.vmtarget 1.286 + jump_to_lambda_form(_masm, receiver_reg, R19_method, temp1, temp2, for_compiler_entry); 1.287 + } else { 1.288 + // The method is a member invoker used by direct method handles. 1.289 + if (VerifyMethodHandles) { 1.290 + // make sure the trailing argument really is a MemberName (caller responsibility) 1.291 + verify_klass(_masm, member_reg, SystemDictionary::WK_KLASS_ENUM_NAME(MemberName_klass), 1.292 + temp1, temp2, 1.293 + "MemberName required for invokeVirtual etc."); 1.294 + } 1.295 + 1.296 + Register temp1_recv_klass = temp1; 1.297 + if (iid != vmIntrinsics::_linkToStatic) { 1.298 + __ verify_oop(receiver_reg); 1.299 + if (iid == vmIntrinsics::_linkToSpecial) { 1.300 + // Don't actually load the klass; just null-check the receiver. 1.301 + __ null_check_throw(receiver_reg, 0, temp1, StubRoutines::throw_NullPointerException_at_call_entry()); 1.302 + } else { 1.303 + // load receiver klass itself 1.304 + __ null_check_throw(receiver_reg, oopDesc::klass_offset_in_bytes(), 1.305 + temp1, StubRoutines::throw_NullPointerException_at_call_entry()); 1.306 + __ load_klass(temp1_recv_klass, receiver_reg); 1.307 + __ verify_klass_ptr(temp1_recv_klass); 1.308 + } 1.309 + BLOCK_COMMENT("check_receiver {"); 1.310 + // The receiver for the MemberName must be in receiver_reg. 1.311 + // Check the receiver against the MemberName.clazz 1.312 + if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) { 1.313 + // Did not load it above... 1.314 + __ load_klass(temp1_recv_klass, receiver_reg); 1.315 + __ verify_klass_ptr(temp1_recv_klass); 1.316 + } 1.317 + if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) { 1.318 + Label L_ok; 1.319 + Register temp2_defc = temp2; 1.320 + __ load_heap_oop_not_null(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg); 1.321 + load_klass_from_Class(_masm, temp2_defc, temp3, temp4); 1.322 + __ verify_klass_ptr(temp2_defc); 1.323 + __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, L_ok); 1.324 + // If we get here, the type check failed! 1.325 + __ stop("receiver class disagrees with MemberName.clazz"); 1.326 + __ BIND(L_ok); 1.327 + } 1.328 + BLOCK_COMMENT("} check_receiver"); 1.329 + } 1.330 + if (iid == vmIntrinsics::_linkToSpecial || 1.331 + iid == vmIntrinsics::_linkToStatic) { 1.332 + DEBUG_ONLY(temp1_recv_klass = noreg); // these guys didn't load the recv_klass 1.333 + } 1.334 + 1.335 + // Live registers at this point: 1.336 + // member_reg - MemberName that was the trailing argument 1.337 + // temp1_recv_klass - klass of stacked receiver, if needed 1.338 + // O5_savedSP - interpreter linkage (if interpreted) 1.339 + // O0..O5 - compiler arguments (if compiled) 1.340 + 1.341 + Label L_incompatible_class_change_error; 1.342 + switch (iid) { 1.343 + case vmIntrinsics::_linkToSpecial: 1.344 + if (VerifyMethodHandles) { 1.345 + verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp2); 1.346 + } 1.347 + __ ld(R19_method, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), member_reg); 1.348 + break; 1.349 + 1.350 + case vmIntrinsics::_linkToStatic: 1.351 + if (VerifyMethodHandles) { 1.352 + verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp2); 1.353 + } 1.354 + __ ld(R19_method, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()), member_reg); 1.355 + break; 1.356 + 1.357 + case vmIntrinsics::_linkToVirtual: 1.358 + { 1.359 + // same as TemplateTable::invokevirtual, 1.360 + // minus the CP setup and profiling: 1.361 + 1.362 + if (VerifyMethodHandles) { 1.363 + verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp2); 1.364 + } 1.365 + 1.366 + // pick out the vtable index from the MemberName, and then we can discard it: 1.367 + Register temp2_index = temp2; 1.368 + __ ld(temp2_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()), member_reg); 1.369 + 1.370 + if (VerifyMethodHandles) { 1.371 + Label L_index_ok; 1.372 + __ cmpdi(CCR1, temp2_index, 0); 1.373 + __ bge(CCR1, L_index_ok); 1.374 + __ stop("no virtual index"); 1.375 + __ BIND(L_index_ok); 1.376 + } 1.377 + 1.378 + // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget 1.379 + // at this point. And VerifyMethodHandles has already checked clazz, if needed. 1.380 + 1.381 + // get target Method* & entry point 1.382 + __ lookup_virtual_method(temp1_recv_klass, temp2_index, R19_method); 1.383 + break; 1.384 + } 1.385 + 1.386 + case vmIntrinsics::_linkToInterface: 1.387 + { 1.388 + // same as TemplateTable::invokeinterface 1.389 + // (minus the CP setup and profiling, with different argument motion) 1.390 + if (VerifyMethodHandles) { 1.391 + verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp2); 1.392 + } 1.393 + 1.394 + Register temp2_intf = temp2; 1.395 + __ load_heap_oop_not_null(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg); 1.396 + load_klass_from_Class(_masm, temp2_intf, temp3, temp4); 1.397 + __ verify_klass_ptr(temp2_intf); 1.398 + 1.399 + Register vtable_index = R19_method; 1.400 + __ ld(vtable_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()), member_reg); 1.401 + if (VerifyMethodHandles) { 1.402 + Label L_index_ok; 1.403 + __ cmpdi(CCR1, vtable_index, 0); 1.404 + __ bge(CCR1, L_index_ok); 1.405 + __ stop("invalid vtable index for MH.invokeInterface"); 1.406 + __ BIND(L_index_ok); 1.407 + } 1.408 + 1.409 + // given intf, index, and recv klass, dispatch to the implementation method 1.410 + __ lookup_interface_method(temp1_recv_klass, temp2_intf, 1.411 + // note: next two args must be the same: 1.412 + vtable_index, R19_method, 1.413 + temp3, temp4, 1.414 + L_incompatible_class_change_error); 1.415 + break; 1.416 + } 1.417 + 1.418 + default: 1.419 + fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); 1.420 + break; 1.421 + } 1.422 + 1.423 + // Live at this point: 1.424 + // R19_method 1.425 + // O5_savedSP (if interpreted) 1.426 + 1.427 + // After figuring out which concrete method to call, jump into it. 1.428 + // Note that this works in the interpreter with no data motion. 1.429 + // But the compiled version will require that rcx_recv be shifted out. 1.430 + __ verify_method_ptr(R19_method); 1.431 + jump_from_method_handle(_masm, R19_method, temp1, temp2, for_compiler_entry); 1.432 + 1.433 + if (iid == vmIntrinsics::_linkToInterface) { 1.434 + __ BIND(L_incompatible_class_change_error); 1.435 + __ load_const_optimized(temp1, StubRoutines::throw_IncompatibleClassChangeError_entry()); 1.436 + __ mtctr(temp1); 1.437 + __ bctr(); 1.438 + } 1.439 + } 1.440 +} 1.441 + 1.442 +#ifndef PRODUCT 1.443 +void trace_method_handle_stub(const char* adaptername, 1.444 + oopDesc* mh, 1.445 + intptr_t* entry_sp, 1.446 + intptr_t* saved_regs) { 1.447 + 1.448 + bool has_mh = (strstr(adaptername, "/static") == NULL && 1.449 + strstr(adaptername, "linkTo") == NULL); // static linkers don't have MH 1.450 + const char* mh_reg_name = has_mh ? "R23_method_handle" : "G23"; 1.451 + tty->print_cr("MH %s %s="INTPTR_FORMAT " sp=" INTPTR_FORMAT, 1.452 + adaptername, mh_reg_name, (intptr_t) mh, entry_sp); 1.453 + 1.454 + if (Verbose) { 1.455 + tty->print_cr("Registers:"); 1.456 + const int abi_offset = frame::abi_112_size / 8; 1.457 + for (int i = R3->encoding(); i <= R13->encoding(); i++) { 1.458 + Register r = as_Register(i); 1.459 + int count = i - R3->encoding(); 1.460 + // The registers are stored in reverse order on the stack (by save_volatile_gprs(R1_SP, abi_112_size)). 1.461 + tty->print("%3s=" PTR_FORMAT, r->name(), saved_regs[abi_offset + count]); 1.462 + if ((count + 1) % 4 == 0) { 1.463 + tty->cr(); 1.464 + } else { 1.465 + tty->print(", "); 1.466 + } 1.467 + } 1.468 + tty->cr(); 1.469 + 1.470 + { 1.471 + // dumping last frame with frame::describe 1.472 + 1.473 + JavaThread* p = JavaThread::active(); 1.474 + 1.475 + ResourceMark rm; 1.476 + PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here 1.477 + FrameValues values; 1.478 + 1.479 + // Note: We want to allow trace_method_handle from any call site. 1.480 + // While trace_method_handle creates a frame, it may be entered 1.481 + // without a PC on the stack top (e.g. not just after a call). 1.482 + // Walking that frame could lead to failures due to that invalid PC. 1.483 + // => carefully detect that frame when doing the stack walking 1.484 + 1.485 + // Current C frame 1.486 + frame cur_frame = os::current_frame(); 1.487 + 1.488 + // Robust search of trace_calling_frame (independant of inlining). 1.489 + // Assumes saved_regs comes from a pusha in the trace_calling_frame. 1.490 + assert(cur_frame.sp() < saved_regs, "registers not saved on stack ?"); 1.491 + frame trace_calling_frame = os::get_sender_for_C_frame(&cur_frame); 1.492 + while (trace_calling_frame.fp() < saved_regs) { 1.493 + trace_calling_frame = os::get_sender_for_C_frame(&trace_calling_frame); 1.494 + } 1.495 + 1.496 + // safely create a frame and call frame::describe 1.497 + intptr_t *dump_sp = trace_calling_frame.sender_sp(); 1.498 + 1.499 + frame dump_frame = frame(dump_sp); 1.500 + dump_frame.describe(values, 1); 1.501 + 1.502 + values.describe(-1, saved_regs, "raw top of stack"); 1.503 + 1.504 + tty->print_cr("Stack layout:"); 1.505 + values.print(p); 1.506 + } 1.507 + 1.508 + if (has_mh && mh->is_oop()) { 1.509 + mh->print(); 1.510 + if (java_lang_invoke_MethodHandle::is_instance(mh)) { 1.511 + if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0) 1.512 + java_lang_invoke_MethodHandle::form(mh)->print(); 1.513 + } 1.514 + } 1.515 + } 1.516 +} 1.517 + 1.518 +void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { 1.519 + if (!TraceMethodHandles) return; 1.520 + 1.521 + BLOCK_COMMENT("trace_method_handle {"); 1.522 + 1.523 + int nbytes_save = 10 * 8; // 10 volatile gprs 1.524 + __ save_LR_CR(R0); 1.525 + __ mr(R0, R1_SP); // saved_sp 1.526 + assert(Assembler::is_simm(-nbytes_save, 16), "Overwriting R0"); 1.527 + // push_frame_abi112 only uses R0 if nbytes_save is wider than 16 bit 1.528 + __ push_frame_abi112(nbytes_save, R0); 1.529 + __ save_volatile_gprs(R1_SP, frame::abi_112_size); // Except R0. 1.530 + 1.531 + __ load_const(R3_ARG1, (address)adaptername); 1.532 + __ mr(R4_ARG2, R23_method_handle); 1.533 + __ mr(R5_ARG3, R0); // saved_sp 1.534 + __ mr(R6_ARG4, R1_SP); 1.535 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub)); 1.536 + 1.537 + __ restore_volatile_gprs(R1_SP, 112); // except R0 1.538 + __ pop_frame(); 1.539 + __ restore_LR_CR(R0); 1.540 + 1.541 + BLOCK_COMMENT("} trace_method_handle"); 1.542 +} 1.543 +#endif // PRODUCT