Assembler::Address2 MemoryAddress::address_2_for(jint address_offset) { if (!has_address_register()) { // Try to do direct access jint fixed_offset; if (has_fixed_offset(fixed_offset)) { jint offset = fixed_offset + base_offset() + address_offset; if (-(1 << 12) < offset && offset < (1 << 12)) { return Assembler::imm_index(fixed_register(), offset); } } create_and_initialize_address_register(); } GUARANTEE(has_address_register(), "We must have address register by now"); int xbase_offset = // base_offset or 0 address_register_includes_base_offset() ? 0 : base_offset(); if (address_offset == 0 && xbase_offset != 0) { // Update the address_register so that it includes the base_offset set_address_register_includes_base_offset(); return Assembler::imm_index(address_register(), xbase_offset, Assembler::pre_indexed); } else { return Assembler::imm_index(address_register(), address_offset + xbase_offset); } }
void MemoryAddress::prepare_preindexed_address(jint address_offset, Assembler::Register& reg, jint& offset){ offset = 0; if (!has_address_register()) { // Try to do direct access jint fixed_offset; if (has_fixed_offset(fixed_offset)) { offset = fixed_offset + base_offset() + address_offset; reg = fixed_register(); return; } create_and_initialize_address_register(); } GUARANTEE(has_address_register(), "We must have address register by now"); reg = address_register(); int xbase_offset = // base_offset or 0 address_register_includes_base_offset() ? 0 : base_offset(); if (address_offset == 0 && xbase_offset != 0) { // Update the address_register so that it includes the base_offset set_address_register_includes_base_offset(); code_generator()->add(address_register(), address_register(), xbase_offset); offset = 0; } else { offset = (address_offset + xbase_offset); } }
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); }
Assembler::Address5 MemoryAddress::address_5_for(jint address_offset) { if (!has_address_register()) { // Try to do direct access jint fixed_offset; if (has_fixed_offset(fixed_offset)) { const jint offset = fixed_offset + base_offset() + address_offset; if (-(1 << 10) < offset && offset < (1 << 10)) { return Assembler::imm_index5(fixed_register(), offset); } } create_and_initialize_address_register(); } GUARANTEE(has_address_register(), "We must have address register by now"); const int xbase_offset = // base_offset or 0 address_register_includes_base_offset() ? 0 : base_offset(); return Assembler::imm_index5(address_register(), address_offset + xbase_offset); }
BinaryAssembler::Address HeapAddress::address_for(jint address_offset) { // use the address register if available if (has_address_register()) { GUARANTEE(address_offset == lo_offset(), "the address register holds the address for the low offset"); return BinaryAssembler::Address(address_register()); } // return the computed address return compute_address_for(address_offset); }
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(); }
Assembler::Address3 MemoryAddress::address_3_for(jint address_offset) { if (!has_address_register()) { jint fixed_offset; if (has_fixed_offset(fixed_offset)) { jint offset = fixed_offset + base_offset() + address_offset; if (-(1 << 8) < offset && offset < (1 << 8)) { return Assembler::imm_index3(fixed_register(), offset); } } // We have to allocate an address register and fill it in create_and_initialize_address_register(); } GUARANTEE(has_address_register(), "We must have address register by now"); if (!address_register_includes_base_offset()) { address_offset += base_offset(); } // Unlike Address2, we have nothing to gain by using pre_indexed mode. // This is not used for modifying objects, longs, or doubles. return Assembler::imm_index3(address_register(), address_offset); }
void MemoryAddress::prepare_indexed_address(jint address_offset, Assembler::Register& reg, jint& offset){ if (!has_address_register()) { jint fixed_offset; if (has_fixed_offset(fixed_offset)) { offset = fixed_offset + base_offset() + address_offset; reg = fixed_register(); return; } // We have to allocate an address register and fill it in create_and_initialize_address_register(); } GUARANTEE(has_address_register(), "We must have address register by now"); offset = address_offset; if (!address_register_includes_base_offset()) { offset += base_offset(); } reg = address_register(); return; }
HeapAddress::~HeapAddress() { GUARANTEE(!has_address_register(), "address register must be cleared and deallocated"); }
MemoryAddress::~MemoryAddress() { // dereference any allocated address registers if (has_address_register()) { RegisterAllocator::dereference(address_register()); } }
void HeapAddress::write_barrier_prolog() { // We must have an address register if (!has_address_register()) { create_and_initialize_address_register(); } }