251 // rsp += size;
252 __ lea(rdx_temp, Address(rax_argslot, -wordSize)); // source pointer for copy
253 {
254 Label loop;
255 __ bind(loop);
256 // pull one word up each time through the loop
257 __ movptr(rbx_temp, Address(rdx_temp, 0));
258 __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
259 __ addptr(rdx_temp, -wordSize);
260 __ cmpptr(rdx_temp, rsp);
261 __ jcc(Assembler::greaterEqual, loop);
262 }
263
264 // Now move the argslot up, to point to the just-copied block.
265 __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr));
266 // And adjust the argslot address to point at the deletion point.
267 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
268 }
269
270 #ifndef PRODUCT
271 void trace_method_handle_stub(const char* adaptername,
272 oopDesc* mh,
273 intptr_t* entry_sp,
274 intptr_t* saved_sp,
275 intptr_t* saved_bp) {
276 // called as a leaf from native code: do not block the JVM!
277 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
278 intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
279 printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
280 adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
281 if (last_sp != saved_sp)
282 printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
283 }
284 #endif //PRODUCT
285
286 // Generate an "entry" field for a method handle.
287 // This determines how the method handle will respond to calls.
288 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
289 // Here is the register state during an interpreted call,
290 // as set up by generate_method_handle_interpreter_entry():
291 // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
292 // - rcx: receiver method handle
293 // - rax: method handle type (only used by the check_mtype entry point)
294 // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
295 // - rdx: garbage temp, can blow away
296
297 Register rcx_recv = rcx;
298 Register rax_argslot = rax;
299 Register rbx_temp = rbx;
300 Register rdx_temp = rdx;
301
302 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
|
251 // rsp += size;
252 __ lea(rdx_temp, Address(rax_argslot, -wordSize)); // source pointer for copy
253 {
254 Label loop;
255 __ bind(loop);
256 // pull one word up each time through the loop
257 __ movptr(rbx_temp, Address(rdx_temp, 0));
258 __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
259 __ addptr(rdx_temp, -wordSize);
260 __ cmpptr(rdx_temp, rsp);
261 __ jcc(Assembler::greaterEqual, loop);
262 }
263
264 // Now move the argslot up, to point to the just-copied block.
265 __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr));
266 // And adjust the argslot address to point at the deletion point.
267 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
268 }
269
270 #ifndef PRODUCT
271 extern "C" void print_method_handle(oopDesc* mh);
272 void trace_method_handle_stub(const char* adaptername,
273 oopDesc* mh,
274 intptr_t* entry_sp,
275 intptr_t* saved_sp,
276 intptr_t* saved_bp) {
277 // called as a leaf from native code: do not block the JVM!
278 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
279 intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
280 printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
281 adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
282 if (last_sp != saved_sp)
283 printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
284 if (Verbose) print_method_handle(mh);
285 }
286 #endif //PRODUCT
287
288 // Generate an "entry" field for a method handle.
289 // This determines how the method handle will respond to calls.
290 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
291 // Here is the register state during an interpreted call,
292 // as set up by generate_method_handle_interpreter_entry():
293 // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
294 // - rcx: receiver method handle
295 // - rax: method handle type (only used by the check_mtype entry point)
296 // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
297 // - rdx: garbage temp, can blow away
298
299 Register rcx_recv = rcx;
300 Register rax_argslot = rax;
301 Register rbx_temp = rbx;
302 Register rdx_temp = rdx;
303
304 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
|