Exemple #1
0
void Value::assign_register() {
  if (in_register()) {
    return;
  }

#if ENABLE_ARM_VFP
  if (stack_type() == T_FLOAT) {
    set_register(RegisterAllocator::allocate_float_register());
  } else if (stack_type() == T_DOUBLE) {
    set_vfp_double_register(RegisterAllocator::allocate_double_register());
  } else
#endif
  {
    if (!is_two_word()) {
      set_register(RegisterAllocator::allocate());
    } else {
      // NOTE: avoid doing this: set_registers(allocate(), allocate());
      // The order of parameter list evaluation is undefined in C, and
      // on linux/i386 and solaris/sparc the orders are opposite. The following
      // code forces the same order, so AOT generator will generate exact
      // same code on both Linux and Solaris hosts.
      Assembler::Register hi  = RegisterAllocator::allocate();
      Assembler::Register low = RegisterAllocator::allocate();
      set_registers(low, hi);
    }
  }
}
Exemple #2
0
void HeapAddress::write_barrier_prolog() {
  GUARANTEE(stack_type() == T_OBJECT, "write barrier should not be updated for non-object stores");

  // allocate an address register for the write barrier implementation
  set_address_register(RegisterAllocator::allocate());

  // compute the effective address and store it in the address register
  BinaryAssembler::Address address = compute_address_for(lo_offset());
  code_generator()->leal(address_register(), address);
}
Exemple #3
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();
}
Exemple #4
0
RawLocation::Actions 
RawLocation::do_conform_to(int my_index, RawLocation* other, int other_index, 
                           RawLocation::Actions allowed_actions) {
  // make sure object registers and locations have object values 
  if (other->stack_type() == T_OBJECT && stack_type() != T_OBJECT) {
    // Conformance code makes it so that this is no longer necessary.
    SHOULD_NOT_REACH_HERE();

#if NOT_CURRENTLY_USED
    // if we clear an cached object location there's no need to clear
    // any registers, since the register cache (due to type conflicts) is 
    // guaranteed never to be used again
    if (other.is_flushed() || other.is_cached()) {
      code_generator()->clear_object_location(index());
    } else {
      GUARANTEE(other.is_changed(), "only case left");
      Value other_value(other.type());
      other.read_value(other_value);
      Oop::Raw null_obj;      
      code_generator()->move(other_value, &null_obj);
    }
    return;
#endif
  }
  // compute the merge action
  const Actions required_actions = merge_actions(other);

  const Actions actions = required_actions & allowed_actions;

  // handle loads/stores from/to locations
  if (actions & LOC_LOAD)  {
    other->update_cache(other_index);
  }
  if (actions & LOC_STORE) {
    write_changes(my_index);
  }
  
  // handle register stores
  if (actions & REG_STORE && other->in_register()) {
    // declare & read values for both source and destination
    const Value this_value (this,  my_index   );
    const Value other_value(other, other_index);

    // do the register store 
    if (!other->is_register_identical_to(my_index, this, other_index)) {
      code_generator()->move(other_value, this_value);
    }
  }

  return required_actions & ~allowed_actions;
}
Exemple #5
0
bool RawLocation::is_register_identical_to(int my_index, RawLocation* other,
                                           int other_index) {
  GUARANTEE(in_register(), "must be in register");

  // if the the other location isn't in a register we're not identical
  if (!other->in_register()) {
    return false;
  }

  // make sure the types match
  GUARANTEE(stack_type() == other->stack_type(), "types must match");

  const Value this_value (this,  my_index);
  const Value other_value(other, other_index);

  return this_value.lo_register() == other_value.lo_register() &&
    (!this_value.use_two_registers() ||
         this_value.hi_register() == other_value.hi_register() );
}
Exemple #6
0
void Value::assign_register() {
  if (in_register()) return;

  switch(stack_type()) {
    case T_OBJECT : // fall through
    case T_ARRAY  : // fall through
    case T_INT    : set_register(RegisterAllocator::allocate());
                    break;
    case T_LONG   : set_registers(RegisterAllocator::allocate(), RegisterAllocator::allocate());
                    break;
#if ENABLE_ARM_VFP
    case T_FLOAT  : set_register(RegisterAllocator::allocate_float_register());
                    break;
    case T_DOUBLE : set_vfp_double_register(RegisterAllocator::allocate_double_register());
                    break;
#else  // !ENABLE_ARM_VFP
    case T_FLOAT  : // fall through
    case T_DOUBLE : set_register(RegisterAllocator::allocate_float_register());
                    break;
#endif  // ENABLE_ARM_VFP
    default       : SHOULD_NOT_REACH_HERE();
                    break;
  }
}