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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
}
Beispiel #10
0
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();
  }
}