607 __ load_mirror(rax, rbx);
608
609 #ifdef ASSERT
610 {
611 Label L;
612 __ testptr(rax, rax);
613 __ jcc(Assembler::notZero, L);
614 __ stop("synchronization object is NULL");
615 __ bind(L);
616 }
617 #endif // ASSERT
618
619 __ bind(done);
620 oopDesc::bs()->interpreter_write_barrier(_masm, rax);
621 }
622
623 // add space for monitor & lock
624 __ subptr(rsp, entry_size); // add space for a monitor entry
625 __ movptr(monitor_block_top, rsp); // set new monitor block top
626 // store object
627 __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax);
628 const Register lockreg = NOT_LP64(rdx) LP64_ONLY(c_rarg1);
629 __ movptr(lockreg, rsp); // object address
630 __ lock_object(lockreg);
631 }
632
633 // Generate a fixed interpreter frame. This is identical setup for
634 // interpreted methods and for native methods hence the shared code.
635 //
636 // Args:
637 // rax: return address
638 // rbx: Method*
639 // r14/rdi: pointer to locals
640 // r13/rsi: sender sp
641 // rdx: cp cache
642 void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
643 // initialize fixed part of activation frame
644 __ push(rax); // save return address
645 __ enter(); // save old & set new rbp
646 __ push(rbcp); // set sender sp
1252 __ movl(t, Address(method, Method::access_flags_offset()));
1253 __ testl(t, JVM_ACC_SYNCHRONIZED);
1254 __ jcc(Assembler::zero, L);
1255 // the code below should be shared with interpreter macro
1256 // assembler implementation
1257 {
1258 Label unlock;
1259 // BasicObjectLock will be first in list, since this is a
1260 // synchronized method. However, need to check that the object
1261 // has not been unlocked by an explicit monitorexit bytecode.
1262 const Address monitor(rbp,
1263 (intptr_t)(frame::interpreter_frame_initial_sp_offset *
1264 wordSize - (int)sizeof(BasicObjectLock)));
1265
1266 const Register regmon = NOT_LP64(rdx) LP64_ONLY(c_rarg1);
1267
1268 // monitor expect in c_rarg1 for slow unlock path
1269 __ lea(regmon, monitor); // address of first monitor
1270
1271 __ movptr(t, Address(regmon, BasicObjectLock::obj_offset_in_bytes()));
1272 __ testptr(t, t);
1273 __ jcc(Assembler::notZero, unlock);
1274
1275 // Entry already unlocked, need to throw exception
1276 __ MacroAssembler::call_VM(noreg,
1277 CAST_FROM_FN_PTR(address,
1278 InterpreterRuntime::throw_illegal_monitor_state_exception));
1279 __ should_not_reach_here();
1280
1281 __ bind(unlock);
1282 __ unlock_object(regmon);
1283 }
1284 __ bind(L);
1285 }
1286
1287 // jvmti support
1288 // Note: This must happen _after_ handling/throwing any exceptions since
1289 // the exception handler code notifies the runtime of method exits
1290 // too. If this happens before, method entry/exit notifications are
1291 // not properly paired (was bug - gri 11/22/99).
|
607 __ load_mirror(rax, rbx);
608
609 #ifdef ASSERT
610 {
611 Label L;
612 __ testptr(rax, rax);
613 __ jcc(Assembler::notZero, L);
614 __ stop("synchronization object is NULL");
615 __ bind(L);
616 }
617 #endif // ASSERT
618
619 __ bind(done);
620 oopDesc::bs()->interpreter_write_barrier(_masm, rax);
621 }
622
623 // add space for monitor & lock
624 __ subptr(rsp, entry_size); // add space for a monitor entry
625 __ movptr(monitor_block_top, rsp); // set new monitor block top
626 // store object
627 __ shenandoah_store_addr_check(rax);
628 __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax);
629 const Register lockreg = NOT_LP64(rdx) LP64_ONLY(c_rarg1);
630 __ movptr(lockreg, rsp); // object address
631 __ lock_object(lockreg);
632 }
633
634 // Generate a fixed interpreter frame. This is identical setup for
635 // interpreted methods and for native methods hence the shared code.
636 //
637 // Args:
638 // rax: return address
639 // rbx: Method*
640 // r14/rdi: pointer to locals
641 // r13/rsi: sender sp
642 // rdx: cp cache
643 void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
644 // initialize fixed part of activation frame
645 __ push(rax); // save return address
646 __ enter(); // save old & set new rbp
647 __ push(rbcp); // set sender sp
1253 __ movl(t, Address(method, Method::access_flags_offset()));
1254 __ testl(t, JVM_ACC_SYNCHRONIZED);
1255 __ jcc(Assembler::zero, L);
1256 // the code below should be shared with interpreter macro
1257 // assembler implementation
1258 {
1259 Label unlock;
1260 // BasicObjectLock will be first in list, since this is a
1261 // synchronized method. However, need to check that the object
1262 // has not been unlocked by an explicit monitorexit bytecode.
1263 const Address monitor(rbp,
1264 (intptr_t)(frame::interpreter_frame_initial_sp_offset *
1265 wordSize - (int)sizeof(BasicObjectLock)));
1266
1267 const Register regmon = NOT_LP64(rdx) LP64_ONLY(c_rarg1);
1268
1269 // monitor expect in c_rarg1 for slow unlock path
1270 __ lea(regmon, monitor); // address of first monitor
1271
1272 __ movptr(t, Address(regmon, BasicObjectLock::obj_offset_in_bytes()));
1273 __ shenandoah_store_addr_check(t); // Invariant
1274 __ testptr(t, t);
1275 __ jcc(Assembler::notZero, unlock);
1276
1277 // Entry already unlocked, need to throw exception
1278 __ MacroAssembler::call_VM(noreg,
1279 CAST_FROM_FN_PTR(address,
1280 InterpreterRuntime::throw_illegal_monitor_state_exception));
1281 __ should_not_reach_here();
1282
1283 __ bind(unlock);
1284 __ unlock_object(regmon);
1285 }
1286 __ bind(L);
1287 }
1288
1289 // jvmti support
1290 // Note: This must happen _after_ handling/throwing any exceptions since
1291 // the exception handler code notifies the runtime of method exits
1292 // too. If this happens before, method entry/exit notifications are
1293 // not properly paired (was bug - gri 11/22/99).
|