void HeapAddress::write_barrier_epilog() { GUARANTEE(has_address_register(), "write barrier must have an address register"); GUARANTEE(base_offset() == 0 || address_register_includes_base_offset() , "write_barrier_epilog() must follow address_2_for(0)"); // This is almost always the last thing we do with an address, so it // is okay to steal its temporary register. This saves us one or two // instructions in many cases. Assembler::Register dst = address_register(); clear_address_register(); #if ENABLE_ARM_V7 if (UseHandlers) { if (RegisterAllocator::references(dst) > 1) { Assembler::Register tmp = RegisterAllocator::allocate(); code_generator()->mov(tmp, dst); code_generator()->hbl(CodeGenerator::write_barrier_handler_r0 + (int)tmp); RegisterAllocator::dereference(tmp); } else { code_generator()->hbl(CodeGenerator::write_barrier_handler_r0 + (int)dst); } } else #endif { Assembler::Register tmp1 = RegisterAllocator::allocate(); Assembler::Register tmp2 = RegisterAllocator::allocate(); Assembler::Register tmp3 = Assembler::r12; code_generator()->oop_write_barrier(dst, tmp1, tmp2, tmp3, false); RegisterAllocator::dereference(tmp1); RegisterAllocator::dereference(tmp2); } RegisterAllocator::dereference(dst); }
void HeapAddress::write_barrier_epilog() { GUARANTEE(has_address_register(), "write barrier must have an address register"); // allocate the necessary temporary registers Assembler::Register tmp0; GUARANTEE(base_offset() == 0 || address_register_includes_base_offset(), "write_barrier_epilog() must follow address_2_for(0)"); // This is almost always the last thing we do with an address, so it // is okay to steal its temporary register. This saves us one or two // instructions in many cases. tmp0 = address_register(); clear_address_register(); Assembler::Register tmp1 = RegisterAllocator::allocate(); Assembler::Register tmp2 = RegisterAllocator::allocate(); Assembler::Register tmp3 = RegisterAllocator::allocate(); // update the write barrier code_generator()->oop_write_barrier(tmp0, tmp1, tmp2, tmp3, false); // dereference the allocated registers RegisterAllocator::dereference(tmp0); RegisterAllocator::dereference(tmp1); RegisterAllocator::dereference(tmp2); RegisterAllocator::dereference(tmp3); }
void HeapAddress::write_barrier_epilog() { GUARANTEE(stack_type() == T_OBJECT, "write barrier should not be updated for non-object stores"); GUARANTEE(has_address_register(), "cannot update write barrier without proper register"); // update the bit vector code_generator()->shrl(address_register(), LogBytesPerWord); code_generator()->bts(BinaryAssembler::Address((int) _bitvector_base), address_register()); // dereference the allocated register and clear the cache RegisterAllocator::dereference(address_register()); clear_address_register(); }