< prev index next >

src/hotspot/cpu/arm/macroAssembler_arm.cpp

Print this page
rev 49916 : 8201786: Modularize interpreter GC barriers: leftovers for ARM32
Reviewed-by: enevill

*** 29,38 **** --- 29,39 ---- #include "ci/ciEnv.hpp" #include "code/nativeInst.hpp" #include "compiler/disassembler.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" + #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" #include "oops/klass.inline.hpp"
*** 2124,2338 **** void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2) { assert_different_registers(value, tmp1, tmp2); Label done, not_weak; cbz(value, done); // Use NULL as-is. STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u); tbz(value, 0, not_weak); // Test for jweak tag. // Resolve jweak. ! ldr(value, Address(value, -JNIHandles::weak_tag_value)); ! verify_oop(value); ! #if INCLUDE_ALL_GCS ! if (UseG1GC) { ! g1_write_barrier_pre(noreg, // store_addr ! noreg, // new_val ! value, // pre_val ! tmp1, // tmp1 ! tmp2); // tmp2 ! } ! #endif // INCLUDE_ALL_GCS b(done); bind(not_weak); // Resolve (untagged) jobject. ! ldr(value, Address(value)); verify_oop(value); bind(done); } ////////////////////////////////////////////////////////////////////////////////// - #if INCLUDE_ALL_GCS - - // G1 pre-barrier. - // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR). - // If store_addr != noreg, then previous value is loaded from [store_addr]; - // in such case store_addr and new_val registers are preserved; - // otherwise pre_val register is preserved. - void MacroAssembler::g1_write_barrier_pre(Register store_addr, - Register new_val, - Register pre_val, - Register tmp1, - Register tmp2) { - Label done; - Label runtime; - - if (store_addr != noreg) { - assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg); - } else { - assert (new_val == noreg, "should be"); - assert_different_registers(pre_val, tmp1, tmp2, noreg); - } - - Address in_progress(Rthread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset())); - Address index(Rthread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset())); - Address buffer(Rthread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset())); - - // Is marking active? - assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code"); - ldrb(tmp1, in_progress); - cbz(tmp1, done); - - // Do we need to load the previous value? - if (store_addr != noreg) { - load_heap_oop(pre_val, Address(store_addr, 0)); - } - - // Is the previous value null? - cbz(pre_val, done); - - // Can we store original value in the thread's buffer? - // Is index == 0? - // (The index field is typed as size_t.) - - ldr(tmp1, index); // tmp1 := *index_adr - ldr(tmp2, buffer); - - subs(tmp1, tmp1, wordSize); // tmp1 := tmp1 - wordSize - b(runtime, lt); // If negative, goto runtime - - str(tmp1, index); // *index_adr := tmp1 - - // Record the previous value - str(pre_val, Address(tmp2, tmp1)); - b(done); - - bind(runtime); - - // save the live input values - #ifdef AARCH64 - if (store_addr != noreg) { - raw_push(store_addr, new_val); - } else { - raw_push(pre_val, ZR); - } - #else - if (store_addr != noreg) { - // avoid raw_push to support any ordering of store_addr and new_val - push(RegisterSet(store_addr) | RegisterSet(new_val)); - } else { - push(pre_val); - } - #endif // AARCH64 - - if (pre_val != R0) { - mov(R0, pre_val); - } - mov(R1, Rthread); - - call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), R0, R1); - - #ifdef AARCH64 - if (store_addr != noreg) { - raw_pop(store_addr, new_val); - } else { - raw_pop(pre_val, ZR); - } - #else - if (store_addr != noreg) { - pop(RegisterSet(store_addr) | RegisterSet(new_val)); - } else { - pop(pre_val); - } - #endif // AARCH64 - - bind(done); - } - - // G1 post-barrier. - // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR). - void MacroAssembler::g1_write_barrier_post(Register store_addr, - Register new_val, - Register tmp1, - Register tmp2, - Register tmp3) { - - Address queue_index(Rthread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset())); - Address buffer(Rthread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset())); - - BarrierSet* bs = BarrierSet::barrier_set(); - CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs); - CardTable* ct = ctbs->card_table(); - Label done; - Label runtime; - - // Does store cross heap regions? - - eor(tmp1, store_addr, new_val); - #ifdef AARCH64 - logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes); - cbz(tmp1, done); - #else - movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes)); - b(done, eq); - #endif - - // crosses regions, storing NULL? - - cbz(new_val, done); - - // storing region crossing non-NULL, is card already dirty? - const Register card_addr = tmp1; - assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code"); - - mov_address(tmp2, (address)ct->byte_map_base(), symbolic_Relocation::card_table_reference); - add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTable::card_shift)); - - ldrb(tmp2, Address(card_addr)); - cmp(tmp2, (int)G1CardTable::g1_young_card_val()); - b(done, eq); - - membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2); - - assert(CardTable::dirty_card_val() == 0, "adjust this code"); - ldrb(tmp2, Address(card_addr)); - cbz(tmp2, done); - - // storing a region crossing, non-NULL oop, card is clean. - // dirty card and log. - - strb(zero_register(tmp2), Address(card_addr)); - - ldr(tmp2, queue_index); - ldr(tmp3, buffer); - - subs(tmp2, tmp2, wordSize); - b(runtime, lt); // go to runtime if now negative - - str(tmp2, queue_index); - - str(card_addr, Address(tmp3, tmp2)); - b(done); - - bind(runtime); - - if (card_addr != R0) { - mov(R0, card_addr); - } - mov(R1, Rthread); - call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), R0, R1); - - bind(done); - } - - #endif // INCLUDE_ALL_GCS - - ////////////////////////////////////////////////////////////////////////////////// - #ifdef AARCH64 void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed) { switch (size_in_bytes) { case 8: ldr(dst, src); break; --- 2125,2157 ---- void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2) { + BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); + assert_different_registers(value, tmp1, tmp2); Label done, not_weak; cbz(value, done); // Use NULL as-is. STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u); tbz(value, 0, not_weak); // Test for jweak tag. + // Resolve jweak. ! bs->load_at(this, IN_ROOT | ON_PHANTOM_OOP_REF, T_OBJECT, ! value, Address(value, -JNIHandles::weak_tag_value), tmp1, tmp2, noreg); b(done); bind(not_weak); // Resolve (untagged) jobject. ! bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT, ! value, Address(value, 0), tmp1, tmp2, noreg); verify_oop(value); bind(done); } ////////////////////////////////////////////////////////////////////////////////// #ifdef AARCH64 void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed) { switch (size_in_bytes) { case 8: ldr(dst, src); break;
*** 2871,2912 **** } #endif // AARCH64 ! void MacroAssembler::load_heap_oop(Register dst, Address src) { ! #ifdef AARCH64 ! if (UseCompressedOops) { ! ldr_w(dst, src); ! decode_heap_oop(dst); ! return; ! } ! #endif // AARCH64 ! ldr(dst, src); } // Blows src and flags. ! void MacroAssembler::store_heap_oop(Register src, Address dst) { ! #ifdef AARCH64 ! if (UseCompressedOops) { ! assert(!dst.uses(src), "not enough registers"); ! encode_heap_oop(src); ! str_w(src, dst); ! return; } - #endif // AARCH64 - str(src, dst); } ! void MacroAssembler::store_heap_oop_null(Register src, Address dst) { ! #ifdef AARCH64 ! if (UseCompressedOops) { ! str_w(src, dst); ! return; } - #endif // AARCH64 - str(src, dst); } #ifdef AARCH64 --- 2690,2732 ---- } #endif // AARCH64 ! void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1, Register tmp2, Register tmp3, DecoratorSet decorators) { ! access_load_at(T_OBJECT, IN_HEAP | decorators, src, dst, tmp1, tmp2, tmp3); } // Blows src and flags. ! void MacroAssembler::store_heap_oop(Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, DecoratorSet decorators) { ! access_store_at(T_OBJECT, IN_HEAP | decorators, obj, new_val, tmp1, tmp2, tmp3, false); ! } ! ! void MacroAssembler::store_heap_oop_null(Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, DecoratorSet decorators) { ! access_store_at(T_OBJECT, IN_HEAP, obj, new_val, tmp1, tmp2, tmp3, true); ! } ! ! void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators, ! Address src, Register dst, Register tmp1, Register tmp2, Register tmp3) { ! BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); ! bool as_raw = (decorators & AS_RAW) != 0; ! if (as_raw) { ! bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1, tmp2, tmp3); ! } else { ! bs->load_at(this, decorators, type, dst, src, tmp1, tmp2, tmp3); } } ! void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators, ! Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, bool is_null) { ! BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); ! bool as_raw = (decorators & AS_RAW) != 0; ! if (as_raw) { ! bs->BarrierSetAssembler::store_at(this, decorators, type, obj, new_val, tmp1, tmp2, tmp3, is_null); ! } else { ! bs->store_at(this, decorators, type, obj, new_val, tmp1, tmp2, tmp3, is_null); } } #ifdef AARCH64
< prev index next >