31 #include "nativeInst_x86.hpp"
32 #include "oops/compiledICHolder.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "prims/jvmtiExport.hpp"
35 #include "register_x86.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/signature.hpp"
38 #include "runtime/vframeArray.hpp"
39 #include "utilities/macros.hpp"
40 #include "vmreg_x86.inline.hpp"
41 #if INCLUDE_ALL_GCS
42 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
43 #endif
44
45
46 // Implementation of StubAssembler
47
48 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
49 // setup registers
50 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions)
51 assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different");
52 assert(oop_result1 != thread && metadata_result != thread, "registers must be different");
53 assert(args_size >= 0, "illegal args_size");
54 bool align_stack = false;
55 #ifdef _LP64
56 // At a method handle call, the stack may not be properly aligned
57 // when returning with an exception.
58 align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id);
59 #endif
60
61 #ifdef _LP64
62 mov(c_rarg0, thread);
63 set_num_rt_args(0); // Nothing on stack
64 #else
65 set_num_rt_args(1 + args_size);
66
67 // push java thread (becomes first argument of C function)
68 get_thread(thread);
69 push(thread);
70 #endif // _LP64
71
93 cmpptr(thread, rax);
94 jcc(Assembler::equal, L);
95 int3();
96 stop("StubAssembler::call_RT: rdi not callee saved?");
97 bind(L);
98 }
99 pop(rax);
100 #endif
101 reset_last_Java_frame(thread, true, align_stack);
102
103 // discard thread and arguments
104 NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
105
106 // check for pending exceptions
107 { Label L;
108 cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
109 jcc(Assembler::equal, L);
110 // exception pending => remove activation and forward to exception handler
111 movptr(rax, Address(thread, Thread::pending_exception_offset()));
112 // make sure that the vm_results are cleared
113 if (oop_result1->is_valid()) {
114 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
115 }
116 if (metadata_result->is_valid()) {
117 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
118 }
119 if (frame_size() == no_frame_size) {
120 leave();
121 jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
122 } else if (_stub_id == Runtime1::forward_exception_id) {
123 should_not_reach_here();
124 } else {
125 jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
126 }
127 bind(L);
128 }
129 // get oop results if there are any and reset the values in the thread
130 if (oop_result1->is_valid()) {
131 get_vm_result(oop_result1, thread);
132 }
133 if (metadata_result->is_valid()) {
134 get_vm_result_2(metadata_result, thread);
135 }
136 return call_offset;
137 }
138
139
140 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) {
141 #ifdef _LP64
142 mov(c_rarg1, arg1);
143 #else
144 push(arg1);
145 #endif // _LP64
146 return call_RT(oop_result1, metadata_result, entry, 1);
147 }
148
149
150 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) {
151 #ifdef _LP64
152 if (c_rarg1 == arg2) {
153 if (c_rarg2 == arg1) {
311 // Tries to smart of about FP registers. In particular we separate
312 // saving and describing the FPU registers for deoptimization since we
313 // have to save the FPU registers twice if we describe them and on P4
314 // saving FPU registers which don't contain anything appears
315 // expensive. The deopt blob is the only thing which needs to
316 // describe FPU registers. In all other cases it should be sufficient
317 // to simply save their current value.
318
319 static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
320 bool save_fpu_registers = true) {
321
322 // In 64bit all the args are in regs so there are no additional stack slots
323 LP64_ONLY(num_rt_args = 0);
324 LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");)
325 int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread
326 sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word );
327
328 // record saved value locations in an OopMap
329 // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread
330 OopMap* map = new OopMap(frame_size_in_slots, 0);
331 map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax->as_VMReg());
332 map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg());
333 map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg());
334 map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg());
335 map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg());
336 map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg());
337 #ifdef _LP64
338 map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args), r8->as_VMReg());
339 map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args), r9->as_VMReg());
340 map->set_callee_saved(VMRegImpl::stack2reg(r10_off + num_rt_args), r10->as_VMReg());
341 map->set_callee_saved(VMRegImpl::stack2reg(r11_off + num_rt_args), r11->as_VMReg());
342 map->set_callee_saved(VMRegImpl::stack2reg(r12_off + num_rt_args), r12->as_VMReg());
343 map->set_callee_saved(VMRegImpl::stack2reg(r13_off + num_rt_args), r13->as_VMReg());
344 map->set_callee_saved(VMRegImpl::stack2reg(r14_off + num_rt_args), r14->as_VMReg());
345 map->set_callee_saved(VMRegImpl::stack2reg(r15_off + num_rt_args), r15->as_VMReg());
346
347 // This is stupid but needed.
348 map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next());
349 map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next());
350 map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next());
351 map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next());
352 map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next());
353 map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next());
354
355 map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args), r8->as_VMReg()->next());
356 map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args), r9->as_VMReg()->next());
357 map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10->as_VMReg()->next());
358 map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11->as_VMReg()->next());
359 map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12->as_VMReg()->next());
360 map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13->as_VMReg()->next());
361 map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14->as_VMReg()->next());
362 map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15->as_VMReg()->next());
363 #endif // _LP64
364
365 if (save_fpu_registers) {
366 if (UseSSE < 2) {
367 int fpu_off = float_regs_as_doubles_off;
368 for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
369 VMReg fpu_name_0 = FrameMap::fpu_regname(n);
370 map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + num_rt_args), fpu_name_0);
371 // %%% This is really a waste but we'll keep things as they were for now
372 if (true) {
373 map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + 1 + num_rt_args), fpu_name_0->next());
374 }
375 fpu_off += 2;
376 }
377 assert(fpu_off == fpu_state_off, "incorrect number of fpu stack slots");
378 }
379
380 if (UseSSE >= 2) {
381 int xmm_off = xmm_regs_as_doubles_off;
382 for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
383 VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
384 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
385 // %%% This is really a waste but we'll keep things as they were for now
386 if (true) {
387 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + 1 + num_rt_args), xmm_name_0->next());
388 }
389 xmm_off += 2;
390 }
391 assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
392
393 } else if (UseSSE == 1) {
394 int xmm_off = xmm_regs_as_doubles_off;
395 for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
396 VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
397 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
398 xmm_off += 2;
399 }
400 assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
401 }
402 }
403
404 return map;
405 }
406
407 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
408 bool save_fpu_registers = true) {
409 __ block_comment("save_live_registers");
410
411 __ pusha(); // integer registers
412
413 // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
414 // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset");
415
416 __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
|
31 #include "nativeInst_x86.hpp"
32 #include "oops/compiledICHolder.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "prims/jvmtiExport.hpp"
35 #include "register_x86.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/signature.hpp"
38 #include "runtime/vframeArray.hpp"
39 #include "utilities/macros.hpp"
40 #include "vmreg_x86.inline.hpp"
41 #if INCLUDE_ALL_GCS
42 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
43 #endif
44
45
46 // Implementation of StubAssembler
47
48 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
49 // setup registers
50 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions)
51 assert(!(oop_result1.is_valid() || metadata_result.is_valid()) || oop_result1 != metadata_result, "registers must be different");
52 assert(oop_result1 != thread && metadata_result != thread, "registers must be different");
53 assert(args_size >= 0, "illegal args_size");
54 bool align_stack = false;
55 #ifdef _LP64
56 // At a method handle call, the stack may not be properly aligned
57 // when returning with an exception.
58 align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id);
59 #endif
60
61 #ifdef _LP64
62 mov(c_rarg0, thread);
63 set_num_rt_args(0); // Nothing on stack
64 #else
65 set_num_rt_args(1 + args_size);
66
67 // push java thread (becomes first argument of C function)
68 get_thread(thread);
69 push(thread);
70 #endif // _LP64
71
93 cmpptr(thread, rax);
94 jcc(Assembler::equal, L);
95 int3();
96 stop("StubAssembler::call_RT: rdi not callee saved?");
97 bind(L);
98 }
99 pop(rax);
100 #endif
101 reset_last_Java_frame(thread, true, align_stack);
102
103 // discard thread and arguments
104 NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
105
106 // check for pending exceptions
107 { Label L;
108 cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
109 jcc(Assembler::equal, L);
110 // exception pending => remove activation and forward to exception handler
111 movptr(rax, Address(thread, Thread::pending_exception_offset()));
112 // make sure that the vm_results are cleared
113 if (oop_result1.is_valid()) {
114 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
115 }
116 if (metadata_result.is_valid()) {
117 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
118 }
119 if (frame_size() == no_frame_size) {
120 leave();
121 jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
122 } else if (_stub_id == Runtime1::forward_exception_id) {
123 should_not_reach_here();
124 } else {
125 jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
126 }
127 bind(L);
128 }
129 // get oop results if there are any and reset the values in the thread
130 if (oop_result1.is_valid()) {
131 get_vm_result(oop_result1, thread);
132 }
133 if (metadata_result.is_valid()) {
134 get_vm_result_2(metadata_result, thread);
135 }
136 return call_offset;
137 }
138
139
140 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) {
141 #ifdef _LP64
142 mov(c_rarg1, arg1);
143 #else
144 push(arg1);
145 #endif // _LP64
146 return call_RT(oop_result1, metadata_result, entry, 1);
147 }
148
149
150 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) {
151 #ifdef _LP64
152 if (c_rarg1 == arg2) {
153 if (c_rarg2 == arg1) {
311 // Tries to smart of about FP registers. In particular we separate
312 // saving and describing the FPU registers for deoptimization since we
313 // have to save the FPU registers twice if we describe them and on P4
314 // saving FPU registers which don't contain anything appears
315 // expensive. The deopt blob is the only thing which needs to
316 // describe FPU registers. In all other cases it should be sufficient
317 // to simply save their current value.
318
319 static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
320 bool save_fpu_registers = true) {
321
322 // In 64bit all the args are in regs so there are no additional stack slots
323 LP64_ONLY(num_rt_args = 0);
324 LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");)
325 int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread
326 sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word );
327
328 // record saved value locations in an OopMap
329 // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread
330 OopMap* map = new OopMap(frame_size_in_slots, 0);
331 map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax.as_VMReg());
332 map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx.as_VMReg());
333 map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx.as_VMReg());
334 map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx.as_VMReg());
335 map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi.as_VMReg());
336 map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi.as_VMReg());
337 #ifdef _LP64
338 map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args), r8.as_VMReg());
339 map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args), r9.as_VMReg());
340 map->set_callee_saved(VMRegImpl::stack2reg(r10_off + num_rt_args), r10.as_VMReg());
341 map->set_callee_saved(VMRegImpl::stack2reg(r11_off + num_rt_args), r11.as_VMReg());
342 map->set_callee_saved(VMRegImpl::stack2reg(r12_off + num_rt_args), r12.as_VMReg());
343 map->set_callee_saved(VMRegImpl::stack2reg(r13_off + num_rt_args), r13.as_VMReg());
344 map->set_callee_saved(VMRegImpl::stack2reg(r14_off + num_rt_args), r14.as_VMReg());
345 map->set_callee_saved(VMRegImpl::stack2reg(r15_off + num_rt_args), r15.as_VMReg());
346
347 // This is stupid but needed.
348 map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax.as_VMReg()->next());
349 map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx.as_VMReg()->next());
350 map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx.as_VMReg()->next());
351 map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx.as_VMReg()->next());
352 map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi.as_VMReg()->next());
353 map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi.as_VMReg()->next());
354
355 map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args), r8.as_VMReg()->next());
356 map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args), r9.as_VMReg()->next());
357 map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10.as_VMReg()->next());
358 map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11.as_VMReg()->next());
359 map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12.as_VMReg()->next());
360 map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13.as_VMReg()->next());
361 map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14.as_VMReg()->next());
362 map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15.as_VMReg()->next());
363 #endif // _LP64
364
365 if (save_fpu_registers) {
366 if (UseSSE < 2) {
367 int fpu_off = float_regs_as_doubles_off;
368 for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
369 VMReg fpu_name_0 = FrameMap::fpu_regname(n);
370 map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + num_rt_args), fpu_name_0);
371 // %%% This is really a waste but we'll keep things as they were for now
372 if (true) {
373 map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + 1 + num_rt_args), fpu_name_0->next());
374 }
375 fpu_off += 2;
376 }
377 assert(fpu_off == fpu_state_off, "incorrect number of fpu stack slots");
378 }
379
380 if (UseSSE >= 2) {
381 int xmm_off = xmm_regs_as_doubles_off;
382 for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
383 VMReg xmm_name_0 = as_XMMRegister(n).as_VMReg();
384 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
385 // %%% This is really a waste but we'll keep things as they were for now
386 if (true) {
387 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + 1 + num_rt_args), xmm_name_0->next());
388 }
389 xmm_off += 2;
390 }
391 assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
392
393 } else if (UseSSE == 1) {
394 int xmm_off = xmm_regs_as_doubles_off;
395 for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
396 VMReg xmm_name_0 = as_XMMRegister(n).as_VMReg();
397 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
398 xmm_off += 2;
399 }
400 assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
401 }
402 }
403
404 return map;
405 }
406
407 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
408 bool save_fpu_registers = true) {
409 __ block_comment("save_live_registers");
410
411 __ pusha(); // integer registers
412
413 // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
414 // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset");
415
416 __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
|