< prev index next >

src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp

Print this page




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


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




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


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


< prev index next >