161 __ sub(var_size_in_bytes, var_size_in_bytes, obj);
162 }
163 // verify_tlab();
164 }
165
166 // Defines obj, preserves var_size_in_bytes
167 void BarrierSetAssembler::eden_allocate(MacroAssembler* masm, Register obj,
168 Register var_size_in_bytes,
169 int con_size_in_bytes,
170 Register t1,
171 Label& slow_case) {
172 assert_different_registers(obj, var_size_in_bytes, t1);
173 if (!Universe::heap()->supports_inline_contig_alloc()) {
174 __ b(slow_case);
175 } else {
176 Register end = t1;
177 Register heap_end = rscratch2;
178 Label retry;
179 __ bind(retry);
180 {
181 unsigned long offset;
182 __ adrp(rscratch1, ExternalAddress((address) Universe::heap()->end_addr()), offset);
183 __ ldr(heap_end, Address(rscratch1, offset));
184 }
185
186 ExternalAddress heap_top((address) Universe::heap()->top_addr());
187
188 // Get the current top of the heap
189 {
190 unsigned long offset;
191 __ adrp(rscratch1, heap_top, offset);
192 // Use add() here after ARDP, rather than lea().
193 // lea() does not generate anything if its offset is zero.
194 // However, relocs expect to find either an ADD or a load/store
195 // insn after an ADRP. add() always generates an ADD insn, even
196 // for add(Rn, Rn, 0).
197 __ add(rscratch1, rscratch1, offset);
198 __ ldaxr(obj, rscratch1);
199 }
200
201 // Adjust it my the size of our new object
202 if (var_size_in_bytes == noreg) {
203 __ lea(end, Address(obj, con_size_in_bytes));
204 } else {
205 __ lea(end, Address(obj, var_size_in_bytes));
206 }
207
208 // if end < obj then we wrapped around high memory
209 __ cmp(end, obj);
210 __ br(Assembler::LO, slow_case);
|
161 __ sub(var_size_in_bytes, var_size_in_bytes, obj);
162 }
163 // verify_tlab();
164 }
165
166 // Defines obj, preserves var_size_in_bytes
167 void BarrierSetAssembler::eden_allocate(MacroAssembler* masm, Register obj,
168 Register var_size_in_bytes,
169 int con_size_in_bytes,
170 Register t1,
171 Label& slow_case) {
172 assert_different_registers(obj, var_size_in_bytes, t1);
173 if (!Universe::heap()->supports_inline_contig_alloc()) {
174 __ b(slow_case);
175 } else {
176 Register end = t1;
177 Register heap_end = rscratch2;
178 Label retry;
179 __ bind(retry);
180 {
181 uint64_t offset;
182 __ adrp(rscratch1, ExternalAddress((address) Universe::heap()->end_addr()), offset);
183 __ ldr(heap_end, Address(rscratch1, offset));
184 }
185
186 ExternalAddress heap_top((address) Universe::heap()->top_addr());
187
188 // Get the current top of the heap
189 {
190 uint64_t offset;
191 __ adrp(rscratch1, heap_top, offset);
192 // Use add() here after ARDP, rather than lea().
193 // lea() does not generate anything if its offset is zero.
194 // However, relocs expect to find either an ADD or a load/store
195 // insn after an ADRP. add() always generates an ADD insn, even
196 // for add(Rn, Rn, 0).
197 __ add(rscratch1, rscratch1, offset);
198 __ ldaxr(obj, rscratch1);
199 }
200
201 // Adjust it my the size of our new object
202 if (var_size_in_bytes == noreg) {
203 __ lea(end, Address(obj, con_size_in_bytes));
204 } else {
205 __ lea(end, Address(obj, var_size_in_bytes));
206 }
207
208 // if end < obj then we wrapped around high memory
209 __ cmp(end, obj);
210 __ br(Assembler::LO, slow_case);
|