4258 // Note: monitorenter & exit are symmetric routines; which is reflected
4259 // in the assembly code structure as well
4260 //
4261 // Stack layout:
4262 //
4263 // [expressions ] <--- rsp = expression stack top
4264 // ..
4265 // [expressions ]
4266 // [monitor entry] <--- monitor block top = expression stack bot
4267 // ..
4268 // [monitor entry]
4269 // [frame data ] <--- monitor block bot
4270 // ...
4271 // [saved rbp ] <--- rbp
4272 void TemplateTable::monitorenter() {
4273 transition(atos, vtos);
4274
4275 // check for NULL object
4276 __ null_check(rax);
4277
4278 // We need to preemptively evacuate the object, because we later compare
4279 // it to objects in the BasicObjectLock list, and we might get false negatives
4280 // if another thread evacuates the object in the meantime. See acmp.
4281 oopDesc::bs()->interpreter_write_barrier(_masm, rax);
4282
4283 const Address monitor_block_top(
4284 rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
4285 const Address monitor_block_bot(
4286 rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
4287 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
4288
4289 Label allocated;
4290
4291 Register rtop = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
4292 Register rbot = LP64_ONLY(c_rarg2) NOT_LP64(rbx);
4293 Register rmon = LP64_ONLY(c_rarg1) NOT_LP64(rdx);
4294
4295 // initialize entry pointer
4296 __ xorl(rmon, rmon); // points to free slot or NULL
4297
4298 // find a free slot in the monitor block (result in rmon)
4299 {
4300 Label entry, loop, exit;
4301 __ movptr(rtop, monitor_block_top); // points to current entry,
4302 // starting with top-most entry
4303 __ lea(rbot, monitor_block_bot); // points to word before bottom
4304 // of monitor block
4305 __ jmpb_if_possible(entry);
4306
4307 __ bind(loop);
4308 // check if current entry is used
4309 __ cmpptr(Address(rtop, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD);
4310 // if not used then remember entry in rmon
4311 __ cmovptr(Assembler::equal, rmon, rtop); // cmov => cmovptr
4312 // check if current entry is for same object
4313 __ movptr(rscratch1, Address(rtop, BasicObjectLock::obj_offset_in_bytes()));
4314 __ shenandoah_store_addr_check(rscratch1); // Invariant
4315 oopDesc::bs()->interpreter_read_barrier(_masm, rscratch1);
4316 __ cmpptr(rax, rscratch1);
4317 // if same object then stop searching
4318 __ jccb(Assembler::equal, exit);
4319 // otherwise advance to next entry
4320 __ addptr(rtop, entry_size);
4321 __ bind(entry);
4322 // check if bottom reached
4323 __ cmpptr(rtop, rbot);
4324 // if not at bottom then check this entry
4325 __ jcc(Assembler::notEqual, loop);
4326 __ bind(exit);
4327 }
4328
4329 __ testptr(rmon, rmon); // check if a slot has been found
4330 __ jcc(Assembler::notZero, allocated); // if found, continue with that one
4331
4332 // allocate one if there's no free slot
4333 {
4334 Label entry, loop;
4335 // 1. compute new pointers // rsp: old expression stack top
4336 __ movptr(rmon, monitor_block_bot); // rmon: old expression stack bottom
4364 // store object
4365 __ shenandoah_store_addr_check(rax); // Invariant
4366 __ movptr(Address(rmon, BasicObjectLock::obj_offset_in_bytes()), rax);
4367 __ lock_object(rmon);
4368
4369 // check to make sure this monitor doesn't cause stack overflow after locking
4370 __ save_bcp(); // in case of exception
4371 __ generate_stack_overflow_check(0);
4372
4373 // The bcp has already been incremented. Just need to dispatch to
4374 // next instruction.
4375 __ dispatch_next(vtos);
4376 }
4377
4378 void TemplateTable::monitorexit() {
4379 transition(atos, vtos);
4380
4381 // check for NULL object
4382 __ null_check(rax);
4383
4384 // We need to preemptively evacuate the object, because we later compare
4385 // it to objects in the BasicObjectLock list, and we might get false negatives
4386 // if another thread evacuates the object in the meantime. See acmp.
4387 oopDesc::bs()->interpreter_write_barrier(_masm, rax);
4388
4389 const Address monitor_block_top(
4390 rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
4391 const Address monitor_block_bot(
4392 rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
4393 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
4394
4395 Register rtop = LP64_ONLY(c_rarg1) NOT_LP64(rdx);
4396 Register rbot = LP64_ONLY(c_rarg2) NOT_LP64(rbx);
4397
4398 Label found;
4399
4400 // find matching slot
4401 {
4402 Label entry, loop;
4403 __ movptr(rtop, monitor_block_top); // points to current entry,
4404 // starting with top-most entry
4405 __ lea(rbot, monitor_block_bot); // points to word before bottom
4406 // of monitor block
4407 __ jmpb_if_possible(entry);
4408
4409 __ bind(loop);
4410 // check if current entry is for same object
4411 __ movptr(rscratch1, Address(rtop, BasicObjectLock::obj_offset_in_bytes()));
4412 __ shenandoah_store_addr_check(rscratch1); // Invariant
4413 oopDesc::bs()->interpreter_read_barrier(_masm, rscratch1);
4414 __ cmpptr(rax, rscratch1);
4415 // if same object then stop searching
4416 __ jcc(Assembler::equal, found);
4417 // otherwise advance to next entry
4418 __ addptr(rtop, entry_size);
4419 __ bind(entry);
4420 // check if bottom reached
4421 __ cmpptr(rtop, rbot);
4422 // if not at bottom then check this entry
4423 __ jcc(Assembler::notEqual, loop);
4424 }
4425
4426 // error handling. Unlocking was not block-structured
4427 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
4428 InterpreterRuntime::throw_illegal_monitor_state_exception));
4429 __ should_not_reach_here();
4430
4431 // call run-time routine
4432 __ bind(found);
4433 __ push_ptr(rax); // make sure object is on stack (contract with oopMaps)
4434 __ unlock_object(rtop);
|
4258 // Note: monitorenter & exit are symmetric routines; which is reflected
4259 // in the assembly code structure as well
4260 //
4261 // Stack layout:
4262 //
4263 // [expressions ] <--- rsp = expression stack top
4264 // ..
4265 // [expressions ]
4266 // [monitor entry] <--- monitor block top = expression stack bot
4267 // ..
4268 // [monitor entry]
4269 // [frame data ] <--- monitor block bot
4270 // ...
4271 // [saved rbp ] <--- rbp
4272 void TemplateTable::monitorenter() {
4273 transition(atos, vtos);
4274
4275 // check for NULL object
4276 __ null_check(rax);
4277
4278 oopDesc::bs()->interpreter_write_barrier(_masm, rax);
4279
4280 const Address monitor_block_top(
4281 rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
4282 const Address monitor_block_bot(
4283 rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
4284 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
4285
4286 Label allocated;
4287
4288 Register rtop = LP64_ONLY(c_rarg3) NOT_LP64(rcx);
4289 Register rbot = LP64_ONLY(c_rarg2) NOT_LP64(rbx);
4290 Register rmon = LP64_ONLY(c_rarg1) NOT_LP64(rdx);
4291
4292 // initialize entry pointer
4293 __ xorl(rmon, rmon); // points to free slot or NULL
4294
4295 // find a free slot in the monitor block (result in rmon)
4296 {
4297 Label entry, loop, exit;
4298 __ movptr(rtop, monitor_block_top); // points to current entry,
4299 // starting with top-most entry
4300 __ lea(rbot, monitor_block_bot); // points to word before bottom
4301 // of monitor block
4302 __ jmpb_if_possible(entry);
4303
4304 __ bind(loop);
4305 // check if current entry is used
4306 __ cmpptr(Address(rtop, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL_WORD);
4307 // if not used then remember entry in rmon
4308 __ cmovptr(Assembler::equal, rmon, rtop); // cmov => cmovptr
4309 // check if current entry is for same object
4310 __ shenandoah_lock_check(rtop); // Invariant
4311 __ cmpptr(rax, Address(rtop, BasicObjectLock::obj_offset_in_bytes()));
4312 // if same object then stop searching
4313 __ jccb(Assembler::equal, exit);
4314 // otherwise advance to next entry
4315 __ addptr(rtop, entry_size);
4316 __ bind(entry);
4317 // check if bottom reached
4318 __ cmpptr(rtop, rbot);
4319 // if not at bottom then check this entry
4320 __ jcc(Assembler::notEqual, loop);
4321 __ bind(exit);
4322 }
4323
4324 __ testptr(rmon, rmon); // check if a slot has been found
4325 __ jcc(Assembler::notZero, allocated); // if found, continue with that one
4326
4327 // allocate one if there's no free slot
4328 {
4329 Label entry, loop;
4330 // 1. compute new pointers // rsp: old expression stack top
4331 __ movptr(rmon, monitor_block_bot); // rmon: old expression stack bottom
4359 // store object
4360 __ shenandoah_store_addr_check(rax); // Invariant
4361 __ movptr(Address(rmon, BasicObjectLock::obj_offset_in_bytes()), rax);
4362 __ lock_object(rmon);
4363
4364 // check to make sure this monitor doesn't cause stack overflow after locking
4365 __ save_bcp(); // in case of exception
4366 __ generate_stack_overflow_check(0);
4367
4368 // The bcp has already been incremented. Just need to dispatch to
4369 // next instruction.
4370 __ dispatch_next(vtos);
4371 }
4372
4373 void TemplateTable::monitorexit() {
4374 transition(atos, vtos);
4375
4376 // check for NULL object
4377 __ null_check(rax);
4378
4379 oopDesc::bs()->interpreter_write_barrier(_masm, rax);
4380
4381 const Address monitor_block_top(
4382 rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
4383 const Address monitor_block_bot(
4384 rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
4385 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
4386
4387 Register rtop = LP64_ONLY(c_rarg1) NOT_LP64(rdx);
4388 Register rbot = LP64_ONLY(c_rarg2) NOT_LP64(rbx);
4389
4390 Label found;
4391
4392 // find matching slot
4393 {
4394 Label entry, loop;
4395 __ movptr(rtop, monitor_block_top); // points to current entry,
4396 // starting with top-most entry
4397 __ lea(rbot, monitor_block_bot); // points to word before bottom
4398 // of monitor block
4399 __ jmpb_if_possible(entry);
4400
4401 __ bind(loop);
4402 // check if current entry is for same object
4403 __ shenandoah_lock_check(rtop); // Invariant
4404 __ cmpptr(rax, Address(rtop, BasicObjectLock::obj_offset_in_bytes()));
4405 // if same object then stop searching
4406 __ jcc(Assembler::equal, found);
4407 // otherwise advance to next entry
4408 __ addptr(rtop, entry_size);
4409 __ bind(entry);
4410 // check if bottom reached
4411 __ cmpptr(rtop, rbot);
4412 // if not at bottom then check this entry
4413 __ jcc(Assembler::notEqual, loop);
4414 }
4415
4416 // error handling. Unlocking was not block-structured
4417 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
4418 InterpreterRuntime::throw_illegal_monitor_state_exception));
4419 __ should_not_reach_here();
4420
4421 // call run-time routine
4422 __ bind(found);
4423 __ push_ptr(rax); // make sure object is on stack (contract with oopMaps)
4424 __ unlock_object(rtop);
|