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
83 // 3) hdr <= rsp + page_size
84 //
133 // if the object header was not pointing to the displaced header,
134 // we do unlocking via runtime call
135 jcc(Assembler::notEqual, slow_case);
136 // done
137 bind(done);
138 }
139
140
141 // Defines obj, preserves var_size_in_bytes
142 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
143 if (UseTLAB) {
144 tlab_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
145 } else {
146 eden_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
147 }
148 }
149
150
151 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
152 assert_different_registers(obj, klass, len);
153 if (UseBiasedLocking && !len->is_valid()) {
154 assert_different_registers(obj, klass, len, t1, t2);
155 movptr(t1, Address(klass, Klass::prototype_header_offset()));
156 movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1);
157 } else {
158 // This assumes that all prototype bits fit in an int32_t
159 movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
160 }
161 #ifdef _LP64
162 if (UseCompressedClassPointers) { // Take care not to kill klass
163 movptr(t1, klass);
164 encode_klass_not_null(t1);
165 movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
166 } else
167 #endif
168 {
169 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
170 }
171
172 if (len->is_valid()) {
173 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
|
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 if (EnableValhalla && !UseBiasedLocking) {
66 // Mask always_locked bit such that we go to the slow path if object is a value type
67 andptr(hdr, ~markOopDesc::biased_lock_bit_in_place);
68 }
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
87 // 3) hdr <= rsp + page_size
88 //
137 // if the object header was not pointing to the displaced header,
138 // we do unlocking via runtime call
139 jcc(Assembler::notEqual, slow_case);
140 // done
141 bind(done);
142 }
143
144
145 // Defines obj, preserves var_size_in_bytes
146 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
147 if (UseTLAB) {
148 tlab_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
149 } else {
150 eden_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
151 }
152 }
153
154
155 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
156 assert_different_registers(obj, klass, len);
157 if ((UseBiasedLocking || EnableValhalla) && !len->is_valid()) {
158 // Need to copy markOopDesc::always_locked_pattern for values.
159 assert_different_registers(obj, klass, len, t1, t2);
160 movptr(t1, Address(klass, Klass::prototype_header_offset()));
161 movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1);
162 } else {
163 // This assumes that all prototype bits fit in an int32_t
164 movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
165 }
166 #ifdef _LP64
167 if (UseCompressedClassPointers) { // Take care not to kill klass
168 movptr(t1, klass);
169 encode_klass_not_null(t1);
170 movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
171 } else
172 #endif
173 {
174 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
175 }
176
177 if (len->is_valid()) {
178 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
|