< prev index next >
src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp
Print this page
rev 50637 : [mq]: JDK-8205336.patch
rev 50638 : [mq]: JDK-8205336-01.patch
*** 22,32 ****
--- 22,34 ----
*
*/
#include "precompiled.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
+ #include "gc/shared/collectedHeap.hpp"
#include "runtime/jniHandles.hpp"
+ #include "runtime/thread.hpp"
#define __ masm->
void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register dst, Address src, Register tmp1, Register tmp_thread) {
*** 119,123 ****
--- 121,231 ----
// If mask changes we need to ensure that the inverse is still encodable as an immediate
STATIC_ASSERT(JNIHandles::weak_tag_mask == 1);
__ andr(obj, obj, ~JNIHandles::weak_tag_mask);
__ ldr(obj, Address(obj, 0)); // *obj
}
+
+ // Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes.
+ void BarrierSetAssembler::tlab_allocate(MacroAssembler* masm, Register obj,
+ Register var_size_in_bytes,
+ int con_size_in_bytes,
+ Register t1,
+ Register t2,
+ Label& slow_case) {
+ assert_different_registers(obj, t2);
+ assert_different_registers(obj, var_size_in_bytes);
+ Register end = t2;
+
+ // verify_tlab();
+
+ __ ldr(obj, Address(rthread, JavaThread::tlab_top_offset()));
+ if (var_size_in_bytes == noreg) {
+ __ lea(end, Address(obj, con_size_in_bytes));
+ } else {
+ __ lea(end, Address(obj, var_size_in_bytes));
+ }
+ __ ldr(rscratch1, Address(rthread, JavaThread::tlab_end_offset()));
+ __ cmp(end, rscratch1);
+ __ br(Assembler::HI, slow_case);
+
+ // update the tlab top pointer
+ __ str(end, Address(rthread, JavaThread::tlab_top_offset()));
+
+ // recover var_size_in_bytes if necessary
+ if (var_size_in_bytes == end) {
+ __ sub(var_size_in_bytes, var_size_in_bytes, obj);
+ }
+ // verify_tlab();
+ }
+
+ // Defines obj, preserves var_size_in_bytes
+ void BarrierSetAssembler::eden_allocate(MacroAssembler* masm, Register obj,
+ Register var_size_in_bytes,
+ int con_size_in_bytes,
+ Register t1,
+ Label& slow_case) {
+ assert_different_registers(obj, var_size_in_bytes, t1);
+ if (!Universe::heap()->supports_inline_contig_alloc()) {
+ __ b(slow_case);
+ } else {
+ Register end = t1;
+ Register heap_end = rscratch2;
+ Label retry;
+ __ bind(retry);
+ {
+ unsigned long offset;
+ __ adrp(rscratch1, ExternalAddress((address) Universe::heap()->end_addr()), offset);
+ __ ldr(heap_end, Address(rscratch1, offset));
+ }
+
+ ExternalAddress heap_top((address) Universe::heap()->top_addr());
+
+ // Get the current top of the heap
+ {
+ unsigned long offset;
+ __ adrp(rscratch1, heap_top, offset);
+ // Use add() here after ARDP, rather than lea().
+ // lea() does not generate anything if its offset is zero.
+ // However, relocs expect to find either an ADD or a load/store
+ // insn after an ADRP. add() always generates an ADD insn, even
+ // for add(Rn, Rn, 0).
+ __ add(rscratch1, rscratch1, offset);
+ __ ldaxr(obj, rscratch1);
+ }
+
+ // Adjust it my the size of our new object
+ if (var_size_in_bytes == noreg) {
+ __ lea(end, Address(obj, con_size_in_bytes));
+ } else {
+ __ lea(end, Address(obj, var_size_in_bytes));
+ }
+
+ // if end < obj then we wrapped around high memory
+ __ cmp(end, obj);
+ __ br(Assembler::LO, slow_case);
+
+ __ cmp(end, heap_end);
+ __ br(Assembler::HI, slow_case);
+
+ // If heap_top hasn't been changed by some other thread, update it.
+ __ stlxr(rscratch2, end, rscratch1);
+ __ cbnzw(rscratch2, retry);
+
+ incr_allocated_bytes(masm, var_size_in_bytes, con_size_in_bytes, t1);
+ }
+ }
+
+ void BarrierSetAssembler::incr_allocated_bytes(MacroAssembler* masm,
+ Register var_size_in_bytes,
+ int con_size_in_bytes,
+ Register t1) {
+ assert(t1->is_valid(), "need temp reg");
+
+ __ ldr(t1, Address(rthread, in_bytes(JavaThread::allocated_bytes_offset())));
+ if (var_size_in_bytes->is_valid()) {
+ __ add(t1, t1, var_size_in_bytes);
+ } else {
+ __ add(t1, t1, con_size_in_bytes);
+ }
+ __ str(t1, Address(rthread, in_bytes(JavaThread::allocated_bytes_offset())));
+ }
+
< prev index next >