21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "c1/c1_MacroAssembler.hpp"
27 #include "c1/c1_Runtime1.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "gc/shared/barrierSet.hpp"
30 #include "gc/shared/barrierSetAssembler.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "interpreter/interpreter.hpp"
33 #include "oops/arrayOop.hpp"
34 #include "oops/markOop.hpp"
35 #include "runtime/basicLock.hpp"
36 #include "runtime/biasedLocking.hpp"
37 #include "runtime/os.hpp"
38 #include "runtime/sharedRuntime.hpp"
39 #include "runtime/stubRoutines.hpp"
40
41 int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case) {
42 const int aligned_mask = BytesPerWord -1;
43 const int hdr_offset = oopDesc::mark_offset_in_bytes();
44 assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
45 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
46 Label done;
47 int null_check_offset = -1;
48
49 verify_oop(obj);
50
51 // save object being locked into the BasicObjectLock
52 movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj);
53
54 if (UseBiasedLocking) {
55 assert(scratch != noreg, "should have scratch register at this point");
56 null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, done, &slow_case);
57 } else {
58 null_check_offset = offset();
59 }
60
61 // Load object header
62 movptr(hdr, Address(obj, hdr_offset));
63 // and mark it as unlocked
64 orptr(hdr, markOopDesc::unlocked_value);
65 // save unlocked object header into the displaced header location on the stack
66 movptr(Address(disp_hdr, 0), hdr);
67 // test if object header is still the same (i.e. unlocked), and if so, store the
68 // displaced header address in the object header - if it is not the same, get the
69 // object header instead
70 MacroAssembler::lock(); // must be immediately before cmpxchg!
71 cmpxchgptr(disp_hdr, Address(obj, hdr_offset));
72 // if the object header was the same, we're done
73 if (PrintBiasedLockingStatistics) {
74 cond_inc32(Assembler::equal,
75 ExternalAddress((address)BiasedLocking::fast_path_entry_count_addr()));
76 }
77 jcc(Assembler::equal, done);
78 // if the object header was not the same, it is now in the hdr register
79 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
80 //
81 // 1) (hdr & aligned_mask) == 0
82 // 2) rsp <= hdr
|
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "c1/c1_MacroAssembler.hpp"
27 #include "c1/c1_Runtime1.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "gc/shared/barrierSet.hpp"
30 #include "gc/shared/barrierSetAssembler.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "interpreter/interpreter.hpp"
33 #include "oops/arrayOop.hpp"
34 #include "oops/markOop.hpp"
35 #include "runtime/basicLock.hpp"
36 #include "runtime/biasedLocking.hpp"
37 #include "runtime/os.hpp"
38 #include "runtime/sharedRuntime.hpp"
39 #include "runtime/stubRoutines.hpp"
40
41 int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case, bool check_always_locked) {
42 const int aligned_mask = BytesPerWord -1;
43 const int hdr_offset = oopDesc::mark_offset_in_bytes();
44 assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
45 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
46 Label done;
47 int null_check_offset = -1;
48
49 verify_oop(obj);
50
51 // save object being locked into the BasicObjectLock
52 movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj);
53
54 if (UseBiasedLocking) {
55 assert(scratch != noreg, "should have scratch register at this point");
56 null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, done, &slow_case);
57 } else {
58 null_check_offset = offset();
59 }
60
61 // Load object header
62 movptr(hdr, Address(obj, hdr_offset));
63 if (check_always_locked) {
64 testl(hdr, markOopDesc::always_locked_pattern);
65 jcc(Assembler::notZero, slow_case);
66 }
67 // and mark it as unlocked
68 orptr(hdr, markOopDesc::unlocked_value);
69 // save unlocked object header into the displaced header location on the stack
70 movptr(Address(disp_hdr, 0), hdr);
71 // test if object header is still the same (i.e. unlocked), and if so, store the
72 // displaced header address in the object header - if it is not the same, get the
73 // object header instead
74 MacroAssembler::lock(); // must be immediately before cmpxchg!
75 cmpxchgptr(disp_hdr, Address(obj, hdr_offset));
76 // if the object header was the same, we're done
77 if (PrintBiasedLockingStatistics) {
78 cond_inc32(Assembler::equal,
79 ExternalAddress((address)BiasedLocking::fast_path_entry_count_addr()));
80 }
81 jcc(Assembler::equal, done);
82 // if the object header was not the same, it is now in the hdr register
83 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
84 //
85 // 1) (hdr & aligned_mask) == 0
86 // 2) rsp <= hdr
|