66 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
67 Label done;
68 int null_check_offset = -1;
69
70 verify_oop(obj);
71
72 // save object being locked into the BasicObjectLock
73 str(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
74
75 if (UseBiasedLocking) {
76 assert(scratch != noreg, "should have scratch register at this point");
77 null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, done, &slow_case);
78 } else {
79 null_check_offset = offset();
80 }
81
82 // Load object header
83 ldr(hdr, Address(obj, hdr_offset));
84 // and mark it as unlocked
85 orr(hdr, hdr, markOopDesc::unlocked_value);
86 // save unlocked object header into the displaced header location on the stack
87 str(hdr, Address(disp_hdr, 0));
88 // test if object header is still the same (i.e. unlocked), and if so, store the
89 // displaced header address in the object header - if it is not the same, get the
90 // object header instead
91 lea(rscratch2, Address(obj, hdr_offset));
92 cmpxchgptr(hdr, disp_hdr, rscratch2, rscratch1, done, /*fallthough*/NULL);
93 // if the object header was the same, we're done
94 // if the object header was not the same, it is now in the hdr register
95 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
96 //
97 // 1) (hdr & aligned_mask) == 0
98 // 2) sp <= hdr
99 // 3) hdr <= sp + page_size
100 //
101 // these 3 tests can be done by evaluating the following expression:
102 //
103 // (hdr - sp) & (aligned_mask - page_size)
104 //
105 // assuming both the stack pointer and page_size have their least
|
66 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
67 Label done;
68 int null_check_offset = -1;
69
70 verify_oop(obj);
71
72 // save object being locked into the BasicObjectLock
73 str(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
74
75 if (UseBiasedLocking) {
76 assert(scratch != noreg, "should have scratch register at this point");
77 null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false, done, &slow_case);
78 } else {
79 null_check_offset = offset();
80 }
81
82 // Load object header
83 ldr(hdr, Address(obj, hdr_offset));
84 // and mark it as unlocked
85 orr(hdr, hdr, markOopDesc::unlocked_value);
86
87 if (EnableValhalla && !UseBiasedLocking) {
88 // Mask always_locked bit such that we go to the slow path if object is a value type
89 andr(hdr, hdr, ~markOopDesc::biased_lock_bit_in_place);
90 }
91
92 // save unlocked object header into the displaced header location on the stack
93 str(hdr, Address(disp_hdr, 0));
94 // test if object header is still the same (i.e. unlocked), and if so, store the
95 // displaced header address in the object header - if it is not the same, get the
96 // object header instead
97 lea(rscratch2, Address(obj, hdr_offset));
98 cmpxchgptr(hdr, disp_hdr, rscratch2, rscratch1, done, /*fallthough*/NULL);
99 // if the object header was the same, we're done
100 // if the object header was not the same, it is now in the hdr register
101 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
102 //
103 // 1) (hdr & aligned_mask) == 0
104 // 2) sp <= hdr
105 // 3) hdr <= sp + page_size
106 //
107 // these 3 tests can be done by evaluating the following expression:
108 //
109 // (hdr - sp) & (aligned_mask - page_size)
110 //
111 // assuming both the stack pointer and page_size have their least
|