968 // assuming page size is a power of 2, we can merge the two
969 // conditions into a single test:
970 // => ((mark - SP) & (3 - os::pagesize())) == 0
971
972 // (3 - os::pagesize()) cannot be encoded as an ARM immediate operand.
973 // Check independently the low bits and the distance to SP.
974 // -1- test low 2 bits
975 movs(R0, AsmOperand(Rmark, lsl, 30));
976 // -2- test (mark - SP) if the low two bits are 0
977 sub(R0, Rmark, SP, eq);
978 movs(R0, AsmOperand(R0, lsr, exact_log2(os::vm_page_size())), eq);
979 // If still 'eq' then recursive locking OK: store 0 into lock record
980 str(R0, Address(Rlock, mark_offset), eq);
981
982 b(done, eq);
983 }
984
985 bind(slow_case);
986
987 // Call the runtime routine for slow case
988 if (LockingMode == LM_LIGHTWEIGHT) {
989 // Pass oop, not lock, in fast lock case. call_VM wants R1 though.
990 push(R1);
991 mov(R1, Robj);
992 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter_obj), R1);
993 pop(R1);
994 } else {
995 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), Rlock);
996 }
997 bind(done);
998 }
999 }
1000
1001 // Unlocks an object. Used in monitorexit bytecode and remove_activation.
1002 //
1003 // Argument: R0: Points to BasicObjectLock structure for lock
1004 // Throw an IllegalMonitorException if object is not locked by current thread
1005 // Blows volatile registers R0-R3, Rtemp, LR. Calls VM.
1006 void InterpreterMacroAssembler::unlock_object(Register Rlock) {
1007 assert(Rlock == R0, "the first argument");
1008
1009 if (LockingMode == LM_MONITOR) {
1010 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), Rlock);
1011 } else {
1012 Label done, slow_case;
1013
1014 const Register Robj = R2;
1015 const Register Rmark = R3;
1016 assert_different_registers(Robj, Rmark, Rlock, Rtemp);
|
968 // assuming page size is a power of 2, we can merge the two
969 // conditions into a single test:
970 // => ((mark - SP) & (3 - os::pagesize())) == 0
971
972 // (3 - os::pagesize()) cannot be encoded as an ARM immediate operand.
973 // Check independently the low bits and the distance to SP.
974 // -1- test low 2 bits
975 movs(R0, AsmOperand(Rmark, lsl, 30));
976 // -2- test (mark - SP) if the low two bits are 0
977 sub(R0, Rmark, SP, eq);
978 movs(R0, AsmOperand(R0, lsr, exact_log2(os::vm_page_size())), eq);
979 // If still 'eq' then recursive locking OK: store 0 into lock record
980 str(R0, Address(Rlock, mark_offset), eq);
981
982 b(done, eq);
983 }
984
985 bind(slow_case);
986
987 // Call the runtime routine for slow case
988 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), Rlock);
989 bind(done);
990 }
991 }
992
993 // Unlocks an object. Used in monitorexit bytecode and remove_activation.
994 //
995 // Argument: R0: Points to BasicObjectLock structure for lock
996 // Throw an IllegalMonitorException if object is not locked by current thread
997 // Blows volatile registers R0-R3, Rtemp, LR. Calls VM.
998 void InterpreterMacroAssembler::unlock_object(Register Rlock) {
999 assert(Rlock == R0, "the first argument");
1000
1001 if (LockingMode == LM_MONITOR) {
1002 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), Rlock);
1003 } else {
1004 Label done, slow_case;
1005
1006 const Register Robj = R2;
1007 const Register Rmark = R3;
1008 assert_different_registers(Robj, Rmark, Rlock, Rtemp);
|