< prev index next >

src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp

Print this page




 866   mtlr(R0);
 867   BLOCK_COMMENT("} remove_activation");
 868 }
 869 
 870 // Lock object
 871 //
 872 // Registers alive
 873 //   monitor - Address of the BasicObjectLock to be used for locking,
 874 //             which must be initialized with the object to lock.
 875 //   object  - Address of the object to be locked.
 876 //
 877 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
 878   if (UseHeavyMonitors) {
 879     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 880             monitor, /*check_for_exceptions=*/true);
 881   } else {
 882     // template code:
 883     //
 884     // markWord displaced_header = obj->mark().set_unlocked();
 885     // monitor->lock()->set_displaced_header(displaced_header);
 886     // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
 887     //   // We stored the monitor address into the object's mark word.
 888     // } else if (THREAD->is_lock_owned((address)displaced_header))
 889     //   // Simple recursive case.
 890     //   monitor->lock()->set_displaced_header(NULL);
 891     // } else {
 892     //   // Slow path.
 893     //   InterpreterRuntime::monitorenter(THREAD, monitor);
 894     // }
 895 
 896     const Register displaced_header = R7_ARG5;
 897     const Register object_mark_addr = R8_ARG6;
 898     const Register current_header   = R9_ARG7;
 899     const Register tmp              = R10_ARG8;
 900 
 901     Label done;
 902     Label cas_failed, slow_case;
 903 
 904     assert_different_registers(displaced_header, object_mark_addr, current_header, tmp);
 905 
 906     // markWord displaced_header = obj->mark().set_unlocked();
 907 
 908     // Load markWord from object into displaced_header.
 909     ld(displaced_header, oopDesc::mark_offset_in_bytes(), object);
 910 
 911     if (UseBiasedLocking) {
 912       biased_locking_enter(CCR0, object, displaced_header, tmp, current_header, done, &slow_case);
 913     }
 914 
 915     // Set displaced_header to be (markWord of object | UNLOCK_VALUE).
 916     ori(displaced_header, displaced_header, markWord::unlocked_value);
 917 
 918     // monitor->lock()->set_displaced_header(displaced_header);
 919 
 920     // Initialize the box (Must happen before we update the object mark!).
 921     std(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
 922         BasicLock::displaced_header_offset_in_bytes(), monitor);
 923 
 924     // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
 925 
 926     // Store stack address of the BasicObjectLock (this is monitor) into object.
 927     addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
 928 
 929     // Must fence, otherwise, preceding store(s) may float below cmpxchg.
 930     // CmpxchgX sets CCR0 to cmpX(current, displaced).
 931     cmpxchgd(/*flag=*/CCR0,
 932              /*current_value=*/current_header,
 933              /*compare_value=*/displaced_header, /*exchange_value=*/monitor,
 934              /*where=*/object_mark_addr,
 935              MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
 936              MacroAssembler::cmpxchgx_hint_acquire_lock(),
 937              noreg,
 938              &cas_failed,
 939              /*check without membar and ldarx first*/true);
 940 
 941     // If the compare-and-exchange succeeded, then we found an unlocked
 942     // object and we have now locked it.
 943     b(done);
 944     bind(cas_failed);


 980 }
 981 
 982 // Unlocks an object. Used in monitorexit bytecode and remove_activation.
 983 //
 984 // Registers alive
 985 //   monitor - Address of the BasicObjectLock to be used for locking,
 986 //             which must be initialized with the object to lock.
 987 //
 988 // Throw IllegalMonitorException if object is not locked by current thread.
 989 void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) {
 990   if (UseHeavyMonitors) {
 991     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
 992             monitor, check_for_exceptions);
 993   } else {
 994 
 995     // template code:
 996     //
 997     // if ((displaced_header = monitor->displaced_header()) == NULL) {
 998     //   // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
 999     //   monitor->set_obj(NULL);
1000     // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) {
1001     //   // We swapped the unlocked mark in displaced_header into the object's mark word.
1002     //   monitor->set_obj(NULL);
1003     // } else {
1004     //   // Slow path.
1005     //   InterpreterRuntime::monitorexit(THREAD, monitor);
1006     // }
1007 
1008     const Register object           = R7_ARG5;
1009     const Register displaced_header = R8_ARG6;
1010     const Register object_mark_addr = R9_ARG7;
1011     const Register current_header   = R10_ARG8;
1012 
1013     Label free_slot;
1014     Label slow_case;
1015 
1016     assert_different_registers(object, displaced_header, object_mark_addr, current_header);
1017 
1018     if (UseBiasedLocking) {
1019       // The object address from the monitor is in object.
1020       ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor);
1021       assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
1022       biased_locking_exit(CCR0, object, displaced_header, free_slot);
1023     }
1024 
1025     // Test first if we are in the fast recursive case.
1026     ld(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
1027            BasicLock::displaced_header_offset_in_bytes(), monitor);
1028 
1029     // If the displaced header is zero, we have a recursive unlock.
1030     cmpdi(CCR0, displaced_header, 0);
1031     beq(CCR0, free_slot); // recursive unlock
1032 
1033     // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) {
1034     //   // We swapped the unlocked mark in displaced_header into the object's mark word.
1035     //   monitor->set_obj(NULL);
1036 
1037     // If we still have a lightweight lock, unlock the object and be done.
1038 
1039     // The object address from the monitor is in object.
1040     if (!UseBiasedLocking) { ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); }
1041     addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
1042 
1043     // We have the displaced header in displaced_header. If the lock is still
1044     // lightweight, it will contain the monitor address and we'll store the
1045     // displaced header back into the object's mark word.
1046     // CmpxchgX sets CCR0 to cmpX(current, monitor).
1047     cmpxchgd(/*flag=*/CCR0,
1048              /*current_value=*/current_header,
1049              /*compare_value=*/monitor, /*exchange_value=*/displaced_header,
1050              /*where=*/object_mark_addr,
1051              MacroAssembler::MemBarRel,
1052              MacroAssembler::cmpxchgx_hint_release_lock(),
1053              noreg,




 866   mtlr(R0);
 867   BLOCK_COMMENT("} remove_activation");
 868 }
 869 
 870 // Lock object
 871 //
 872 // Registers alive
 873 //   monitor - Address of the BasicObjectLock to be used for locking,
 874 //             which must be initialized with the object to lock.
 875 //   object  - Address of the object to be locked.
 876 //
 877 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
 878   if (UseHeavyMonitors) {
 879     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 880             monitor, /*check_for_exceptions=*/true);
 881   } else {
 882     // template code:
 883     //
 884     // markWord displaced_header = obj->mark().set_unlocked();
 885     // monitor->lock()->set_displaced_header(displaced_header);
 886     // if (Atomic::cmpxchg(/*addr*/obj->mark_addr(), /*cmp*/displaced_header, /*ex=*/monitor) == displaced_header) {
 887     //   // We stored the monitor address into the object's mark word.
 888     // } else if (THREAD->is_lock_owned((address)displaced_header))
 889     //   // Simple recursive case.
 890     //   monitor->lock()->set_displaced_header(NULL);
 891     // } else {
 892     //   // Slow path.
 893     //   InterpreterRuntime::monitorenter(THREAD, monitor);
 894     // }
 895 
 896     const Register displaced_header = R7_ARG5;
 897     const Register object_mark_addr = R8_ARG6;
 898     const Register current_header   = R9_ARG7;
 899     const Register tmp              = R10_ARG8;
 900 
 901     Label done;
 902     Label cas_failed, slow_case;
 903 
 904     assert_different_registers(displaced_header, object_mark_addr, current_header, tmp);
 905 
 906     // markWord displaced_header = obj->mark().set_unlocked();
 907 
 908     // Load markWord from object into displaced_header.
 909     ld(displaced_header, oopDesc::mark_offset_in_bytes(), object);
 910 
 911     if (UseBiasedLocking) {
 912       biased_locking_enter(CCR0, object, displaced_header, tmp, current_header, done, &slow_case);
 913     }
 914 
 915     // Set displaced_header to be (markWord of object | UNLOCK_VALUE).
 916     ori(displaced_header, displaced_header, markWord::unlocked_value);
 917 
 918     // monitor->lock()->set_displaced_header(displaced_header);
 919 
 920     // Initialize the box (Must happen before we update the object mark!).
 921     std(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
 922         BasicLock::displaced_header_offset_in_bytes(), monitor);
 923 
 924     // if (Atomic::cmpxchg(/*addr*/obj->mark_addr(), /*cmp*/displaced_header, /*ex=*/monitor) == displaced_header) {
 925 
 926     // Store stack address of the BasicObjectLock (this is monitor) into object.
 927     addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
 928 
 929     // Must fence, otherwise, preceding store(s) may float below cmpxchg.
 930     // CmpxchgX sets CCR0 to cmpX(current, displaced).
 931     cmpxchgd(/*flag=*/CCR0,
 932              /*current_value=*/current_header,
 933              /*compare_value=*/displaced_header, /*exchange_value=*/monitor,
 934              /*where=*/object_mark_addr,
 935              MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
 936              MacroAssembler::cmpxchgx_hint_acquire_lock(),
 937              noreg,
 938              &cas_failed,
 939              /*check without membar and ldarx first*/true);
 940 
 941     // If the compare-and-exchange succeeded, then we found an unlocked
 942     // object and we have now locked it.
 943     b(done);
 944     bind(cas_failed);


 980 }
 981 
 982 // Unlocks an object. Used in monitorexit bytecode and remove_activation.
 983 //
 984 // Registers alive
 985 //   monitor - Address of the BasicObjectLock to be used for locking,
 986 //             which must be initialized with the object to lock.
 987 //
 988 // Throw IllegalMonitorException if object is not locked by current thread.
 989 void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) {
 990   if (UseHeavyMonitors) {
 991     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
 992             monitor, check_for_exceptions);
 993   } else {
 994 
 995     // template code:
 996     //
 997     // if ((displaced_header = monitor->displaced_header()) == NULL) {
 998     //   // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
 999     //   monitor->set_obj(NULL);
1000     // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) {
1001     //   // We swapped the unlocked mark in displaced_header into the object's mark word.
1002     //   monitor->set_obj(NULL);
1003     // } else {
1004     //   // Slow path.
1005     //   InterpreterRuntime::monitorexit(THREAD, monitor);
1006     // }
1007 
1008     const Register object           = R7_ARG5;
1009     const Register displaced_header = R8_ARG6;
1010     const Register object_mark_addr = R9_ARG7;
1011     const Register current_header   = R10_ARG8;
1012 
1013     Label free_slot;
1014     Label slow_case;
1015 
1016     assert_different_registers(object, displaced_header, object_mark_addr, current_header);
1017 
1018     if (UseBiasedLocking) {
1019       // The object address from the monitor is in object.
1020       ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor);
1021       assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
1022       biased_locking_exit(CCR0, object, displaced_header, free_slot);
1023     }
1024 
1025     // Test first if we are in the fast recursive case.
1026     ld(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
1027            BasicLock::displaced_header_offset_in_bytes(), monitor);
1028 
1029     // If the displaced header is zero, we have a recursive unlock.
1030     cmpdi(CCR0, displaced_header, 0);
1031     beq(CCR0, free_slot); // recursive unlock
1032 
1033     // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) {
1034     //   // We swapped the unlocked mark in displaced_header into the object's mark word.
1035     //   monitor->set_obj(NULL);
1036 
1037     // If we still have a lightweight lock, unlock the object and be done.
1038 
1039     // The object address from the monitor is in object.
1040     if (!UseBiasedLocking) { ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); }
1041     addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
1042 
1043     // We have the displaced header in displaced_header. If the lock is still
1044     // lightweight, it will contain the monitor address and we'll store the
1045     // displaced header back into the object's mark word.
1046     // CmpxchgX sets CCR0 to cmpX(current, monitor).
1047     cmpxchgd(/*flag=*/CCR0,
1048              /*current_value=*/current_header,
1049              /*compare_value=*/monitor, /*exchange_value=*/displaced_header,
1050              /*where=*/object_mark_addr,
1051              MacroAssembler::MemBarRel,
1052              MacroAssembler::cmpxchgx_hint_release_lock(),
1053              noreg,


< prev index next >