189 pop(c_rarg3);
190 } else {
191 mov(c_rarg1, arg1);
192 mov(c_rarg2, arg2);
193 mov(c_rarg3, arg3);
194 }
195 #else
196 push(arg3);
197 push(arg2);
198 push(arg1);
199 #endif // _LP64
200 return call_RT(oop_result1, metadata_result, entry, 3);
201 }
202
203
204 // Implementation of StubFrame
205
206 class StubFrame: public StackObj {
207 private:
208 StubAssembler* _sasm;
209
210 public:
211 StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments);
212 void load_argument(int offset_in_words, Register reg);
213
214 ~StubFrame();
215 };
216
217 void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
218 set_info(name, must_gc_arguments);
219 enter();
220 }
221
222 void StubAssembler::epilogue() {
223 leave();
224 ret(0);
225 }
226
227 #define __ _sasm->
228
229 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
230 _sasm = sasm;
231 __ prologue(name, must_gc_arguments);
232 }
233
234 // load parameters that were stored with LIR_Assembler::store_parameter
235 // Note: offsets for store_parameter and load_argument must match
236 void StubFrame::load_argument(int offset_in_words, Register reg) {
237 __ load_parameter(offset_in_words, reg);
238 }
239
240
241 StubFrame::~StubFrame() {
242 __ epilogue();
243 }
244
245 #undef __
246
247
248 // Implementation of Runtime1
249
250 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
251 const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2;
252
253 // Stack layout for saving/restoring all the registers needed during a runtime
254 // call (this includes deoptimization)
255 // Note: note that users of this frame may well have arguments to some runtime
256 // while these values are on the stack. These positions neglect those arguments
257 // but the code in save_live_registers will take the argument count into
258 // account.
259 //
260 #ifdef _LP64
261 #define SLOT2(x) x,
262 #define SLOT_PER_WORD 2
615
616 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
617 bool save_fpu_registers = true) {
618 __ save_live_registers_no_oop_map(save_fpu_registers);
619 return generate_oop_map(sasm, num_rt_args, save_fpu_registers);
620 }
621
622 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
623 __ restore_live_registers(restore_fpu_registers);
624 }
625
626 static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) {
627 sasm->restore_live_registers_except_rax(restore_fpu_registers);
628 }
629
630
631 void Runtime1::initialize_pd() {
632 // nothing to do
633 }
634
635
636 // Target: the entry point of the method that creates and posts the exception oop.
637 // has_argument: true if the exception needs arguments (passed on the stack because
638 // registers must be preserved).
639 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
640 // Preserve all registers.
641 int num_rt_args = has_argument ? (2 + 1) : 1;
642 OopMap* oop_map = save_live_registers(sasm, num_rt_args);
643
644 // Now all registers are saved and can be used freely.
645 // Verify that no old value is used accidentally.
646 __ invalidate_registers(true, true, true, true, true, true);
647
648 // Registers used by this stub.
649 const Register temp_reg = rbx;
650
651 // Load arguments for exception that are passed as arguments into the stub.
652 if (has_argument) {
653 #ifdef _LP64
654 __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord));
1292 __ pop(rcx);
1293 __ pop(rsi);
1294 __ pop(rdi);
1295 __ ret(0);
1296
1297 __ bind(miss);
1298 __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result
1299 __ pop(rax);
1300 __ pop(rcx);
1301 __ pop(rsi);
1302 __ pop(rdi);
1303 __ ret(0);
1304 }
1305 break;
1306
1307 case monitorenter_nofpu_id:
1308 save_fpu_registers = false;
1309 // fall through
1310 case monitorenter_id:
1311 {
1312 StubFrame f(sasm, "monitorenter", dont_gc_arguments);
1313 OopMap* map = save_live_registers(sasm, 3, save_fpu_registers);
1314
1315 // Called with store_parameter and not C abi
1316
1317 f.load_argument(1, rax); // rax,: object
1318 f.load_argument(0, rbx); // rbx,: lock address
1319
1320 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), rax, rbx);
1321
1322 oop_maps = new OopMapSet();
1323 oop_maps->add_gc_map(call_offset, map);
1324 restore_live_registers(sasm, save_fpu_registers);
1325 }
1326 break;
1327
1328 case monitorexit_nofpu_id:
1329 save_fpu_registers = false;
1330 // fall through
1331 case monitorexit_id:
1332 {
|
189 pop(c_rarg3);
190 } else {
191 mov(c_rarg1, arg1);
192 mov(c_rarg2, arg2);
193 mov(c_rarg3, arg3);
194 }
195 #else
196 push(arg3);
197 push(arg2);
198 push(arg1);
199 #endif // _LP64
200 return call_RT(oop_result1, metadata_result, entry, 3);
201 }
202
203
204 // Implementation of StubFrame
205
206 class StubFrame: public StackObj {
207 private:
208 StubAssembler* _sasm;
209 bool _use_pop_on_epilog;
210
211 public:
212 StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments, bool use_pop_on_epilog = false);
213 void load_argument(int offset_in_words, Register reg);
214
215 ~StubFrame();
216 };
217
218 void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
219 set_info(name, must_gc_arguments);
220 enter();
221 }
222
223 void StubAssembler::epilogue(bool use_pop) {
224 use_pop ? pop(rbp) : leave();
225 ret(0);
226 }
227
228 #define __ _sasm->
229
230 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments, bool use_pop_on_epilog) {
231 _sasm = sasm;
232 _use_pop_on_epilog = use_pop_on_epilog;
233 __ prologue(name, must_gc_arguments);
234 }
235
236 // load parameters that were stored with LIR_Assembler::store_parameter
237 // Note: offsets for store_parameter and load_argument must match
238 void StubFrame::load_argument(int offset_in_words, Register reg) {
239 __ load_parameter(offset_in_words, reg);
240 }
241
242
243 StubFrame::~StubFrame() {
244 __ epilogue(_use_pop_on_epilog);
245 }
246
247 #undef __
248
249
250 // Implementation of Runtime1
251
252 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
253 const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2;
254
255 // Stack layout for saving/restoring all the registers needed during a runtime
256 // call (this includes deoptimization)
257 // Note: note that users of this frame may well have arguments to some runtime
258 // while these values are on the stack. These positions neglect those arguments
259 // but the code in save_live_registers will take the argument count into
260 // account.
261 //
262 #ifdef _LP64
263 #define SLOT2(x) x,
264 #define SLOT_PER_WORD 2
617
618 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
619 bool save_fpu_registers = true) {
620 __ save_live_registers_no_oop_map(save_fpu_registers);
621 return generate_oop_map(sasm, num_rt_args, save_fpu_registers);
622 }
623
624 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
625 __ restore_live_registers(restore_fpu_registers);
626 }
627
628 static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) {
629 sasm->restore_live_registers_except_rax(restore_fpu_registers);
630 }
631
632
633 void Runtime1::initialize_pd() {
634 // nothing to do
635 }
636
637 uint Runtime1::runtime_blob_current_thread_offset(frame f) {
638 return r15_off / 2;
639 }
640
641 // Target: the entry point of the method that creates and posts the exception oop.
642 // has_argument: true if the exception needs arguments (passed on the stack because
643 // registers must be preserved).
644 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
645 // Preserve all registers.
646 int num_rt_args = has_argument ? (2 + 1) : 1;
647 OopMap* oop_map = save_live_registers(sasm, num_rt_args);
648
649 // Now all registers are saved and can be used freely.
650 // Verify that no old value is used accidentally.
651 __ invalidate_registers(true, true, true, true, true, true);
652
653 // Registers used by this stub.
654 const Register temp_reg = rbx;
655
656 // Load arguments for exception that are passed as arguments into the stub.
657 if (has_argument) {
658 #ifdef _LP64
659 __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord));
1297 __ pop(rcx);
1298 __ pop(rsi);
1299 __ pop(rdi);
1300 __ ret(0);
1301
1302 __ bind(miss);
1303 __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result
1304 __ pop(rax);
1305 __ pop(rcx);
1306 __ pop(rsi);
1307 __ pop(rdi);
1308 __ ret(0);
1309 }
1310 break;
1311
1312 case monitorenter_nofpu_id:
1313 save_fpu_registers = false;
1314 // fall through
1315 case monitorenter_id:
1316 {
1317 StubFrame f(sasm, "monitorenter", dont_gc_arguments, true /* use_pop_on_epilog */);
1318 OopMap* map = save_live_registers(sasm, 3, save_fpu_registers);
1319
1320 // Called with store_parameter and not C abi
1321
1322 f.load_argument(1, rax); // rax,: object
1323 f.load_argument(0, rbx); // rbx,: lock address
1324
1325 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), rax, rbx);
1326
1327 oop_maps = new OopMapSet();
1328 oop_maps->add_gc_map(call_offset, map);
1329 restore_live_registers(sasm, save_fpu_registers);
1330 }
1331 break;
1332
1333 case monitorexit_nofpu_id:
1334 save_fpu_registers = false;
1335 // fall through
1336 case monitorexit_id:
1337 {
|