29
#include "precompiled.hpp"
30
#include "classfile/javaClasses.inline.hpp"
31
#include "classfile/vmClasses.hpp"
32
#include "interpreter/interpreter.hpp"
33
#include "interpreter/interpreterRuntime.hpp"
35
#include "logging/log.hpp"
36
#include "logging/logStream.hpp"
37
#include "memory/allocation.inline.hpp"
38
#include "memory/resourceArea.hpp"
39
#include "prims/jvmtiExport.hpp"
40
#include "prims/methodHandles.hpp"
41
#include "runtime/frame.inline.hpp"
42
#include "runtime/stubRoutines.hpp"
43
#include "utilities/preserveException.hpp"
48
#define BLOCK_COMMENT(str)
50
#define BLOCK_COMMENT(str) __ block_comment(str)
53
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
55
void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp1, Register temp2) {
56
if (VerifyMethodHandles) {
57
verify_klass(_masm, klass_reg, temp1, temp2, VM_CLASS_ID(java_lang_Class),
58
"MH argument is a Class");
60
__ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
64
static int check_nonzero(const char* xname, int x) {
65
assert(x != 0, "%s should be nonzero", xname);
68
#define NONZERO(x) check_nonzero(#x, x)
74
void MethodHandles::verify_klass(MacroAssembler* _masm,
75
Register obj, Register temp1, Register temp2, vmClassID klass_id,
76
const char* error_message) {
77
InstanceKlass** klass_addr = vmClasses::klass_addr_at(klass_id);
78
Klass* klass = vmClasses::klass_at(klass_id);
80
BLOCK_COMMENT("verify_klass {");
83
__ load_klass(temp1, obj);
84
__ lea(temp2, ExternalAddress((address) klass_addr));
88
intptr_t super_check_offset = klass->super_check_offset();
89
__ ldr(temp1, Address(temp1, super_check_offset));
94
__ stop(error_message);
96
BLOCK_COMMENT("} verify_klass");
99
void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {
101
BLOCK_COMMENT("verify_ref_kind {");
102
__ ldr_u32(temp, Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset())));
103
__ logical_shift_right(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT);
104
__ andr(temp, temp, (unsigned)java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK);
105
__ cmp(temp, ref_kind);
107
{ char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal);
108
jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind);
109
if (ref_kind == JVM_REF_invokeVirtual ||
110
ref_kind == JVM_REF_invokeSpecial)
112
trace_method_handle(_masm, buf);
115
BLOCK_COMMENT("} verify_ref_kind");
121
void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, bool for_compiler_entry) {
122
Label L_no_such_method;
123
__ cbz(Rmethod, L_no_such_method);
128
if (!for_compiler_entry && (JvmtiExport::can_post_interpreter_events())) {
132
__ ldr_s32(Rtemp, Address(Rthread, JavaThread::interp_only_mode_offset()));
134
__ ldr(PC, Address(Rmethod, Method::interpreter_entry_offset()), ne);
136
const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
137
Method::from_interpreted_offset();
139
__ indirect_jump(Address(Rmethod, entry_offset), Rtemp);
141
__ bind(L_no_such_method);
143
__ jump(StubRoutines::throw_AbstractMethodError_entry(), relocInfo::runtime_call_type, Rtemp);
146
void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
147
Register recv, Register tmp,
148
bool for_compiler_entry) {
149
BLOCK_COMMENT("jump_to_lambda_form {");
152
assert_different_registers(recv, tmp, Rmethod);
155
__ load_heap_oop(tmp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset())));
158
__ load_heap_oop(tmp, Address(tmp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset())));
161
__ load_heap_oop(Rmethod, Address(tmp, NONZERO(java_lang_invoke_MemberName::method_offset())));
162
__ verify_oop(Rmethod);
163
__ access_load_at(T_ADDRESS, IN_HEAP, Address(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())), Rmethod, noreg, noreg, noreg);
165
if (VerifyMethodHandles && !for_compiler_entry) {
167
__ ldr(tmp, Address(Rmethod, Method::const_offset()));
168
__ load_sized_value(tmp,
169
Address(tmp, ConstMethod::size_of_parameters_offset()),
173
__ ldr(tmp, __ receiver_argument_address(Rparams, tmp, tmp));
174
__ cmpoop(tmp, recv);
176
__ stop("receiver not on stack");
180
jump_from_method_handle(_masm, for_compiler_entry);
181
BLOCK_COMMENT("} jump_to_lambda_form");
186
address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm,
187
vmIntrinsics::ID iid) {
188
const bool not_for_compiler_entry = false;
189
assert(is_signature_polymorphic(iid), "expected invoke iid");
190
if (iid == vmIntrinsics::_invokeGeneric ||
191
iid == vmIntrinsics::_compiledLambdaForm ||
192
iid == vmIntrinsics::_linkToNative) {
196
__ should_not_reach_here();
207
Register rdx_temp = R2_tmp;
208
Register rdx_param_size = rdx_temp;
209
Register rax_temp = R1_tmp;
210
Register rcx_mh = R5_mh;
211
Register rbx_method = Rmethod;
212
Register rdi_temp = Rtemp;
215
__ align(CodeEntryAlignment);
216
address entry_point = __ pc();
218
if (VerifyMethodHandles) {
220
BLOCK_COMMENT("verify_intrinsic_id {");
221
__ ldrh(rdi_temp, Address(rbx_method, Method::intrinsic_id_offset()));
222
__ sub_slow(rdi_temp, rdi_temp, (int) iid);
224
if (iid == vmIntrinsics::_linkToVirtual ||
225
iid == vmIntrinsics::_linkToSpecial) {
227
trace_method_handle(_masm, "bad Method*::intrinsic_id");
229
__ stop("bad Method*::intrinsic_id");
231
BLOCK_COMMENT("} verify_intrinsic_id");
235
Address rdx_first_arg_addr;
236
int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
237
assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
238
if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
239
__ ldr(rdx_param_size, Address(rbx_method, Method::const_offset()));
240
__ load_sized_value(rdx_param_size,
241
Address(rdx_param_size, ConstMethod::size_of_parameters_offset()),
244
rdx_first_arg_addr = __ receiver_argument_address(Rparams, rdx_param_size, rdi_temp);
246
DEBUG_ONLY(rdx_param_size = noreg);
249
if (!is_signature_polymorphic_static(iid)) {
250
__ ldr(rcx_mh, rdx_first_arg_addr);
251
DEBUG_ONLY(rdx_param_size = noreg);
256
trace_method_handle_interpreter_entry(_masm, iid);
258
if (iid == vmIntrinsics::_invokeBasic) {
259
generate_method_handle_dispatch(_masm, iid, rcx_mh, noreg, not_for_compiler_entry);
263
Register rcx_recv = noreg;
264
if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
266
__ ldr(rcx_recv = rcx_mh, rdx_first_arg_addr);
267
DEBUG_ONLY(rdx_param_size = noreg);
269
Register rbx_member = rbx_method;
271
generate_method_handle_dispatch(_masm, iid, rcx_recv, rbx_member, not_for_compiler_entry);
276
void MethodHandles::jump_to_native_invoker(MacroAssembler* _masm, Register nep_reg, Register temp_target) {
277
BLOCK_COMMENT("jump_to_native_invoker {");
278
__ stop("Should not reach here");
279
BLOCK_COMMENT("} jump_to_native_invoker");
282
void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
283
vmIntrinsics::ID iid,
284
Register receiver_reg,
286
bool for_compiler_entry) {
287
assert(is_signature_polymorphic(iid), "expected invoke iid");
289
Register rbx_method = Rmethod;
291
Register temp1 = (for_compiler_entry ? saved_last_sp_register() : R1_tmp);
293
Register temp3 = Rtemp;
295
if (for_compiler_entry) {
296
assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : j_rarg0), "only valid assignment");
297
assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3);
298
assert_different_registers(temp2, j_rarg0, j_rarg1, j_rarg2, j_rarg3);
299
assert_different_registers(temp3, j_rarg0, j_rarg1, j_rarg2, j_rarg3);
300
assert_different_registers(temp4, j_rarg0, j_rarg1, j_rarg2, j_rarg3);
302
assert_different_registers(temp1, temp2, temp3, receiver_reg);
303
assert_different_registers(temp1, temp2, temp3, temp4, member_reg);
304
if (!for_compiler_entry)
305
assert_different_registers(temp1, temp2, temp3, temp4, saved_last_sp_register());
307
if (iid == vmIntrinsics::_invokeBasic) {
309
jump_to_lambda_form(_masm, receiver_reg, temp3, for_compiler_entry);
311
} else if (iid == vmIntrinsics::_linkToNative) {
312
assert(for_compiler_entry, "only compiler entry is supported");
313
jump_to_native_invoker(_masm, member_reg, temp1);
316
if (VerifyMethodHandles) {
318
verify_klass(_masm, member_reg, temp2, temp3, VM_CLASS_ID(java_lang_invoke_MemberName),
319
"MemberName required for invokeVirtual etc.");
322
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset()));
323
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset()));
324
Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::method_offset()));
325
Address vmtarget_method(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
327
Register temp1_recv_klass = temp1;
328
if (iid != vmIntrinsics::_linkToStatic) {
329
if (iid == vmIntrinsics::_linkToSpecial) {
331
__ null_check(receiver_reg, temp3);
334
__ load_klass(temp1_recv_klass, receiver_reg);
335
__ verify_klass_ptr(temp1_recv_klass);
337
BLOCK_COMMENT("check_receiver {");
340
if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) {
342
__ load_klass(temp1_recv_klass, receiver_reg);
343
__ verify_klass_ptr(temp1_recv_klass);
346
if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
348
Register temp2_defc = temp2;
349
__ load_heap_oop(temp2_defc, member_clazz);
350
load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
351
__ verify_klass_ptr(temp2_defc);
352
__ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, noreg, L_ok);
354
__ stop("receiver class disagrees with MemberName.clazz");
357
BLOCK_COMMENT("} check_receiver");
359
if (iid == vmIntrinsics::_linkToSpecial ||
360
iid == vmIntrinsics::_linkToStatic) {
361
DEBUG_ONLY(temp1_recv_klass = noreg);
368
Label L_incompatible_class_change_error;
370
case vmIntrinsics::_linkToSpecial:
371
if (VerifyMethodHandles) {
372
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
374
__ load_heap_oop(Rmethod, member_vmtarget);
375
__ access_load_at(T_ADDRESS, IN_HEAP, vmtarget_method, Rmethod, noreg, noreg, noreg);
378
case vmIntrinsics::_linkToStatic:
379
if (VerifyMethodHandles) {
380
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
382
__ load_heap_oop(Rmethod, member_vmtarget);
383
__ access_load_at(T_ADDRESS, IN_HEAP, vmtarget_method, Rmethod, noreg, noreg, noreg);
387
case vmIntrinsics::_linkToVirtual:
392
if (VerifyMethodHandles) {
393
verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
397
Register temp2_index = temp2;
398
__ access_load_at(T_ADDRESS, IN_HEAP, member_vmindex, temp2_index, noreg, noreg, noreg);
400
if (VerifyMethodHandles) {
402
__ cmp(temp2_index, 0);
403
__ b(L_index_ok, ge);
404
__ stop("no virtual index");
412
__ lookup_virtual_method(temp1_recv_klass, temp2_index, Rmethod);
416
case vmIntrinsics::_linkToInterface:
420
if (VerifyMethodHandles) {
421
verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
424
Register temp3_intf = temp3;
425
__ load_heap_oop(temp3_intf, member_clazz);
426
load_klass_from_Class(_masm, temp3_intf, temp2, temp4);
427
__ verify_klass_ptr(temp3_intf);
429
Register rbx_index = rbx_method;
430
__ access_load_at(T_ADDRESS, IN_HEAP, member_vmindex, rbx_index, noreg, noreg, noreg);
431
if (VerifyMethodHandles) {
433
__ cmp(rbx_index, 0);
435
__ stop("invalid vtable index for MH.invokeInterface");
440
__ lookup_interface_method(temp1_recv_klass, temp3_intf,
442
rbx_index, rbx_method,
444
L_incompatible_class_change_error);
449
fatal("unexpected intrinsic %d: %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid));
459
__ verify_method_ptr(Rmethod);
460
jump_from_method_handle(_masm, for_compiler_entry);
462
if (iid == vmIntrinsics::_linkToInterface) {
463
__ bind(L_incompatible_class_change_error);
464
__ jump(StubRoutines::throw_IncompatibleClassChangeError_entry(), relocInfo::runtime_call_type, Rtemp);
472
ARG_LIMIT = 255, SLOP = 4,
474
UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
478
const int trace_mh_nregs = 15;
479
const Register trace_mh_regs[trace_mh_nregs] =
480
{R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, PC};
482
void trace_method_handle_stub(const char* adaptername,
483
intptr_t* saved_regs,
487
bool has_mh = (strstr(adaptername, "/static") == nullptr &&
488
strstr(adaptername, "linkTo") == nullptr);
489
intptr_t* entry_sp = (intptr_t*) &saved_regs[trace_mh_nregs];
490
intptr_t* saved_sp = (intptr_t*) saved_regs[Rsender_sp->encoding()];
491
intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
492
intptr_t* base_sp = last_sp;
494
intptr_t mh_reg = (intptr_t)saved_regs[R5_mh->encoding()];
495
const char* mh_reg_name = "R5_mh";
499
log_info(methodhandles)("MH %s %s=" PTR_FORMAT " sp=(" PTR_FORMAT "+" INTX_FORMAT ") stack_size=" INTX_FORMAT " bp=" PTR_FORMAT,
500
adaptername, mh_reg_name, mh_reg,
501
(intptr_t)entry_sp, (intptr_t)saved_sp - (intptr_t)entry_sp, (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
503
if (last_sp != saved_sp && last_sp != nullptr) {
504
log_info(methodhandles)("*** last_sp=" INTPTR_FORMAT, p2i(last_sp));
506
LogTarget(Trace, methodhandles) lt;
507
if (lt.is_enabled()) {
510
ls.print(" reg dump: ");
512
for (i = 0; i < trace_mh_nregs; i++) {
513
if (i > 0 && i % 4 == 0)
514
ls.print("\n + dump: ");
515
const char* reg_name = trace_mh_regs[i]->name();
516
ls.print(" %s: " INTPTR_FORMAT, reg_name, p2i((void*)saved_regs[i]));
528
JavaThread* p = JavaThread::active();
531
PreserveExceptionMark pem(Thread::current());
534
intptr_t* dump_fp = (intptr_t *) saved_bp;
535
address dump_pc = (address) saved_regs[trace_mh_nregs-2];
536
frame dump_frame((intptr_t *)entry_sp, dump_fp, dump_pc);
538
dump_frame.describe(values, 1);
541
if ((saved_sp >= entry_sp - UNREASONABLE_STACK_MOVE) && (saved_sp < dump_fp)) {
542
values.describe(-1, saved_sp, "*Rsender_sp");
547
ls.print_cr(" stack layout:");
548
values.print_on(p, &ls);
551
if (has_mh && oopDesc::is_oop(mh)) {
553
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
554
java_lang_invoke_MethodHandle::form(mh)->print_on(&ls);
560
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
561
if (!log_is_enabled(Info, methodhandles)) return;
562
BLOCK_COMMENT("trace_method_handle {");
565
int push_size = __ save_all_registers();
566
assert(trace_mh_nregs*wordSize == push_size,"saved register count mismatch");
568
__ mov_slow(R0, adaptername);
572
assert_different_registers(R0, R1, R2, R5_mh);
576
__ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), R0, R1, R2, R3);
578
__ restore_all_registers();
579
BLOCK_COMMENT("} trace_method_handle");