179
180 // r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
181 // rmethod: Method*
182 // r3: argument locator (parameter slot count, added to rsp)
183 // r1: used as temp to hold mh or receiver
184 // r0, r11: garbage temps, blown away
185 Register argp = r3; // argument list ptr, live on error paths
186 Register temp = r0;
187 Register mh = r1; // MH receiver; dies quickly and is recycled
188
189 // here's where control starts out:
190 __ align(CodeEntryAlignment);
191 address entry_point = __ pc();
192
193 if (VerifyMethodHandles) {
194 assert(Method::intrinsic_id_size_in_bytes() == 2, "assuming Method::_intrinsic_id is u2");
195
196 Label L;
197 BLOCK_COMMENT("verify_intrinsic_id {");
198 __ ldrh(rscratch1, Address(rmethod, Method::intrinsic_id_offset_in_bytes()));
199 __ cmp(rscratch1, (int) iid);
200 __ br(Assembler::EQ, L);
201 if (iid == vmIntrinsics::_linkToVirtual ||
202 iid == vmIntrinsics::_linkToSpecial) {
203 // could do this for all kinds, but would explode assembly code size
204 trace_method_handle(_masm, "bad Method*::intrinsic_id");
205 }
206 __ hlt(0);
207 __ bind(L);
208 BLOCK_COMMENT("} verify_intrinsic_id");
209 }
210
211 // First task: Find out how big the argument list is.
212 Address r3_first_arg_addr;
213 int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
214 assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
215 if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
216 __ ldr(argp, Address(rmethod, Method::const_offset()));
217 __ load_sized_value(argp,
218 Address(argp, ConstMethod::size_of_parameters_offset()),
219 sizeof(u2), /*is_signed*/ false);
|
179
180 // r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
181 // rmethod: Method*
182 // r3: argument locator (parameter slot count, added to rsp)
183 // r1: used as temp to hold mh or receiver
184 // r0, r11: garbage temps, blown away
185 Register argp = r3; // argument list ptr, live on error paths
186 Register temp = r0;
187 Register mh = r1; // MH receiver; dies quickly and is recycled
188
189 // here's where control starts out:
190 __ align(CodeEntryAlignment);
191 address entry_point = __ pc();
192
193 if (VerifyMethodHandles) {
194 assert(Method::intrinsic_id_size_in_bytes() == 2, "assuming Method::_intrinsic_id is u2");
195
196 Label L;
197 BLOCK_COMMENT("verify_intrinsic_id {");
198 __ ldrh(rscratch1, Address(rmethod, Method::intrinsic_id_offset_in_bytes()));
199 __ subs(zr, rscratch1, (int) iid);
200 __ br(Assembler::EQ, L);
201 if (iid == vmIntrinsics::_linkToVirtual ||
202 iid == vmIntrinsics::_linkToSpecial) {
203 // could do this for all kinds, but would explode assembly code size
204 trace_method_handle(_masm, "bad Method*::intrinsic_id");
205 }
206 __ hlt(0);
207 __ bind(L);
208 BLOCK_COMMENT("} verify_intrinsic_id");
209 }
210
211 // First task: Find out how big the argument list is.
212 Address r3_first_arg_addr;
213 int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
214 assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
215 if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
216 __ ldr(argp, Address(rmethod, Method::const_offset()));
217 __ load_sized_value(argp,
218 Address(argp, ConstMethod::size_of_parameters_offset()),
219 sizeof(u2), /*is_signed*/ false);
|