26
#include "precompiled.hpp"
27
#include "asm/macroAssembler.hpp"
28
#include "classfile/javaClasses.inline.hpp"
29
#include "classfile/vmClasses.hpp"
30
#include "interpreter/interpreter.hpp"
31
#include "interpreter/interpreterRuntime.hpp"
32
#include "memory/allocation.inline.hpp"
33
#include "prims/jvmtiExport.hpp"
34
#include "prims/methodHandles.hpp"
35
#include "runtime/flags/flagSetting.hpp"
36
#include "runtime/frame.inline.hpp"
37
#include "runtime/stubRoutines.hpp"
42
#define BLOCK_COMMENT(str)
44
#define BLOCK_COMMENT(str) __ block_comment(str)
47
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
49
void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg) {
50
if (VerifyMethodHandles)
51
verify_klass(_masm, klass_reg, VM_CLASS_ID(java_lang_Class),
52
"MH argument is a Class");
53
__ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
57
static int check_nonzero(const char* xname, int x) {
58
assert(x != 0, "%s should be nonzero", xname);
61
#define NONZERO(x) check_nonzero(#x, x)
67
void MethodHandles::verify_klass(MacroAssembler* _masm,
68
Register obj, vmClassID klass_id,
69
const char* error_message) {
70
InstanceKlass** klass_addr = vmClasses::klass_addr_at(klass_id);
71
Klass* klass = vmClasses::klass_at(klass_id);
72
Register temp = rscratch2;
73
Register temp2 = rscratch1;
75
BLOCK_COMMENT("verify_klass {");
78
__ push(RegSet::of(temp, temp2), sp);
79
__ load_klass(temp, obj);
80
__ cmpptr(temp, ExternalAddress((address) klass_addr));
81
__ br(Assembler::EQ, L_ok);
82
intptr_t super_check_offset = klass->super_check_offset();
83
__ ldr(temp, Address(temp, super_check_offset));
84
__ cmpptr(temp, ExternalAddress((address) klass_addr));
85
__ br(Assembler::EQ, L_ok);
86
__ pop(RegSet::of(temp, temp2), sp);
88
__ stop(error_message);
90
__ pop(RegSet::of(temp, temp2), sp);
91
BLOCK_COMMENT("} verify_klass");
94
void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) { }
98
void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
99
bool for_compiler_entry) {
100
assert(method == rmethod, "interpreter calling convention");
101
Label L_no_such_method;
102
__ cbz(rmethod, L_no_such_method);
103
__ verify_method_ptr(method);
105
if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
106
Label run_compiled_code;
111
__ ldrw(rscratch1, Address(rthread, JavaThread::interp_only_mode_offset()));
112
__ cbzw(rscratch1, run_compiled_code);
113
__ ldr(rscratch1, Address(method, Method::interpreter_entry_offset()));
115
__ BIND(run_compiled_code);
118
const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
119
Method::from_interpreted_offset();
120
__ ldr(rscratch1,Address(method, entry_offset));
122
__ bind(L_no_such_method);
123
__ far_jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry()));
126
void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
127
Register recv, Register method_temp,
129
bool for_compiler_entry) {
130
BLOCK_COMMENT("jump_to_lambda_form {");
133
assert_different_registers(recv, method_temp, temp2);
134
assert(recv != noreg, "required register");
135
assert(method_temp == rmethod, "required register for loading method");
139
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset())), temp2, rscratch2);
140
__ verify_oop(method_temp);
141
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset())), temp2, rscratch2);
142
__ verify_oop(method_temp);
143
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset())), temp2, rscratch2);
144
__ verify_oop(method_temp);
145
__ access_load_at(T_ADDRESS, IN_HEAP, method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())), noreg, noreg);
147
if (VerifyMethodHandles && !for_compiler_entry) {
149
__ ldr(temp2, Address(method_temp, Method::const_offset()));
150
__ load_sized_value(temp2,
151
Address(temp2, ConstMethod::size_of_parameters_offset()),
155
__ ldr(rscratch1, __ argument_address(temp2, -1));
156
__ cmpoop(recv, rscratch1);
157
__ br(Assembler::EQ, L);
158
__ ldr(r0, __ argument_address(temp2, -1));
163
jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
164
BLOCK_COMMENT("} jump_to_lambda_form");
168
address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm,
169
vmIntrinsics::ID iid) {
170
const bool not_for_compiler_entry = false;
171
assert(is_signature_polymorphic(iid), "expected invoke iid");
172
if (iid == vmIntrinsics::_invokeGeneric ||
173
iid == vmIntrinsics::_compiledLambdaForm) {
183
if (iid == vmIntrinsics::_linkToNative) {
198
__ align(CodeEntryAlignment);
199
address entry_point = __ pc();
201
if (VerifyMethodHandles) {
202
assert(Method::intrinsic_id_size_in_bytes() == 2, "assuming Method::_intrinsic_id is u2");
205
BLOCK_COMMENT("verify_intrinsic_id {");
206
__ ldrh(rscratch1, Address(rmethod, Method::intrinsic_id_offset()));
207
__ subs(zr, rscratch1, (int) iid);
208
__ br(Assembler::EQ, L);
209
if (iid == vmIntrinsics::_linkToVirtual ||
210
iid == vmIntrinsics::_linkToSpecial) {
212
trace_method_handle(_masm, "bad Method*::intrinsic_id");
216
BLOCK_COMMENT("} verify_intrinsic_id");
220
Address r3_first_arg_addr;
221
int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
222
assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
223
if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
224
__ ldr(argp, Address(rmethod, Method::const_offset()));
225
__ load_sized_value(argp,
226
Address(argp, ConstMethod::size_of_parameters_offset()),
229
r3_first_arg_addr = __ argument_address(argp, -1);
231
DEBUG_ONLY(argp = noreg);
234
if (!is_signature_polymorphic_static(iid)) {
235
__ ldr(mh, r3_first_arg_addr);
236
DEBUG_ONLY(argp = noreg);
241
trace_method_handle_interpreter_entry(_masm, iid);
242
if (iid == vmIntrinsics::_invokeBasic) {
243
generate_method_handle_dispatch(_masm, iid, mh, noreg, not_for_compiler_entry);
247
Register recv = noreg;
248
if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
250
__ ldr(recv = r2, r3_first_arg_addr);
252
DEBUG_ONLY(argp = noreg);
253
Register rmember = rmethod;
255
generate_method_handle_dispatch(_masm, iid, recv, rmember, not_for_compiler_entry);
261
void MethodHandles::jump_to_native_invoker(MacroAssembler* _masm, Register nep_reg, Register temp_target) {
262
BLOCK_COMMENT("jump_to_native_invoker {");
263
assert_different_registers(nep_reg, temp_target);
264
assert(nep_reg != noreg, "required register");
267
__ verify_oop(nep_reg);
268
__ access_load_at(T_ADDRESS, IN_HEAP, temp_target,
269
Address(nep_reg, NONZERO(jdk_internal_foreign_abi_NativeEntryPoint::downcall_stub_address_offset_in_bytes())),
273
BLOCK_COMMENT("} jump_to_native_invoker");
277
void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
278
vmIntrinsics::ID iid,
279
Register receiver_reg,
281
bool for_compiler_entry) {
282
assert(is_signature_polymorphic(iid), "expected invoke iid");
284
Register temp1 = r10;
285
Register temp2 = r11;
286
Register temp3 = r14;
287
if (for_compiler_entry) {
288
assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic || iid == vmIntrinsics::_linkToNative ? noreg : j_rarg0), "only valid assignment");
289
assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
290
assert_different_registers(temp2, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
291
assert_different_registers(temp3, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
294
assert_different_registers(temp1, temp2, temp3, receiver_reg);
295
assert_different_registers(temp1, temp2, temp3, member_reg);
297
if (iid == vmIntrinsics::_invokeBasic) {
299
jump_to_lambda_form(_masm, receiver_reg, rmethod, temp1, for_compiler_entry);
301
} else if (iid == vmIntrinsics::_linkToNative) {
302
assert(for_compiler_entry, "only compiler entry is supported");
303
jump_to_native_invoker(_masm, member_reg, temp1);
306
if (VerifyMethodHandles) {
308
verify_klass(_masm, member_reg, VM_CLASS_ID(java_lang_invoke_MemberName),
309
"MemberName required for invokeVirtual etc.");
312
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset()));
313
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset()));
314
Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset()));
315
Address vmtarget_method( rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
317
Register temp1_recv_klass = temp1;
318
if (iid != vmIntrinsics::_linkToStatic) {
319
__ verify_oop(receiver_reg);
320
if (iid == vmIntrinsics::_linkToSpecial) {
322
__ null_check(receiver_reg);
325
__ load_klass(temp1_recv_klass, receiver_reg);
326
__ verify_klass_ptr(temp1_recv_klass);
328
BLOCK_COMMENT("check_receiver {");
331
if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) {
333
__ load_klass(temp1_recv_klass, receiver_reg);
334
__ verify_klass_ptr(temp1_recv_klass);
336
if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
338
Register temp2_defc = temp2;
339
__ load_heap_oop(temp2_defc, member_clazz, temp3, rscratch2);
340
load_klass_from_Class(_masm, temp2_defc);
341
__ verify_klass_ptr(temp2_defc);
342
__ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, L_ok);
348
BLOCK_COMMENT("} check_receiver");
350
if (iid == vmIntrinsics::_linkToSpecial ||
351
iid == vmIntrinsics::_linkToStatic) {
352
DEBUG_ONLY(temp1_recv_klass = noreg);
361
Label L_incompatible_class_change_error;
363
case vmIntrinsics::_linkToSpecial:
364
if (VerifyMethodHandles) {
365
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
367
__ load_heap_oop(rmethod, member_vmtarget, temp3, rscratch2);
368
__ access_load_at(T_ADDRESS, IN_HEAP, rmethod, vmtarget_method, noreg, noreg);
371
case vmIntrinsics::_linkToStatic:
372
if (VerifyMethodHandles) {
373
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
375
__ load_heap_oop(rmethod, member_vmtarget, temp3, rscratch2);
376
__ access_load_at(T_ADDRESS, IN_HEAP, rmethod, vmtarget_method, noreg, noreg);
379
case vmIntrinsics::_linkToVirtual:
384
if (VerifyMethodHandles) {
385
verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
389
Register temp2_index = temp2;
390
__ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg, noreg);
392
if (VerifyMethodHandles) {
394
__ cmpw(temp2_index, 0U);
395
__ br(Assembler::GE, L_index_ok);
404
__ lookup_virtual_method(temp1_recv_klass, temp2_index, rmethod);
408
case vmIntrinsics::_linkToInterface:
412
if (VerifyMethodHandles) {
413
verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
416
Register temp3_intf = temp3;
417
__ load_heap_oop(temp3_intf, member_clazz, temp2, rscratch2);
418
load_klass_from_Class(_masm, temp3_intf);
419
__ verify_klass_ptr(temp3_intf);
421
Register rindex = rmethod;
422
__ access_load_at(T_ADDRESS, IN_HEAP, rindex, member_vmindex, noreg, noreg);
423
if (VerifyMethodHandles) {
426
__ br(Assembler::GE, L);
432
__ lookup_interface_method(temp1_recv_klass, temp3_intf,
436
L_incompatible_class_change_error);
441
fatal("unexpected intrinsic %d: %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid));
450
__ verify_method_ptr(rmethod);
451
jump_from_method_handle(_masm, rmethod, temp1, for_compiler_entry);
452
if (iid == vmIntrinsics::_linkToInterface) {
453
__ bind(L_incompatible_class_change_error);
454
__ far_jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
460
void trace_method_handle_stub(const char* adaptername,
462
intptr_t* saved_regs,
463
intptr_t* entry_sp) { }
468
struct MethodHandleStubArguments {
469
const char* adaptername;
471
intptr_t* saved_regs;
474
void trace_method_handle_stub_wrapper(MethodHandleStubArguments* args) { }
476
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { }