Пример #1
0
// ------------------------------------------------------------------
// ciInstance::field_value_by_offset
//
// Constant value of a field at the specified offset.
ciConstant ciInstance::field_value_by_offset(int field_offset) {
  ciInstanceKlass* ik = klass()->as_instance_klass();
  ciField* field = ik->get_field_by_offset(field_offset, false);
  if (field == NULL)
    return ciConstant();  // T_ILLEGAL
  return field_value(field);
}
Пример #2
0
// ------------------------------------------------------------------
// ciInstance::field_value
//
// Constant value of a field.
ciConstant ciInstance::field_value(ciField* field) {
  assert(is_loaded() &&
         field->holder()->is_loaded() &&
         klass()->is_subclass_of(field->holder()),
         "invalid access");
  VM_ENTRY_MARK;
  ciConstant result;
  oop obj = get_oop();
  assert(obj != NULL, "bad oop");
  BasicType field_btype = field->type()->basic_type();
  int offset = field->offset();

  switch(field_btype) {
  case T_BYTE:
    return ciConstant(field_btype, obj->byte_field(offset));
    break;
  case T_CHAR:
    return ciConstant(field_btype, obj->char_field(offset));
    break;
  case T_SHORT:
    return ciConstant(field_btype, obj->short_field(offset));
    break;
  case T_BOOLEAN:
    return ciConstant(field_btype, obj->bool_field(offset));
    break;
  case T_INT:
    return ciConstant(field_btype, obj->int_field(offset));
    break;
  case T_FLOAT:
    return ciConstant(obj->float_field(offset));
    break;
  case T_DOUBLE:
    return ciConstant(obj->double_field(offset));
    break;
  case T_LONG:
    return ciConstant(obj->long_field(offset));
    break;
  case T_OBJECT:
  case T_ARRAY:
    {
      oop o = obj->obj_field(offset);

      // A field will be "constant" if it is known always to be
      // a non-null reference to an instance of a particular class,
      // or to a particular array.  This can happen even if the instance
      // or array is not perm.  In such a case, an "unloaded" ciArray
      // or ciInstance is created.  The compiler may be able to use
      // information about the object's class (which is exact) or length.

      if (o == NULL) {
        return ciConstant(field_btype, ciNullObject::make());
      } else {
        return ciConstant(field_btype, CURRENT_ENV->get_object(o));
      }
    }
  }
  ShouldNotReachHere();
  // to shut up the compiler
  return ciConstant();
}
Пример #3
0
void ciField::initialize_from(fieldDescriptor* fd) {
  // Get the flags, offset, and canonical holder of the field.
  _flags = ciFlags(fd->access_flags());
  _offset = fd->offset();
  _holder = CURRENT_ENV->get_object(fd->field_holder())->as_instance_klass();

  // Check to see if the field is constant.
  if (_holder->is_initialized() && this->is_final()) {
    if (!this->is_static()) {
      // A field can be constant if it's a final static field or if it's
      // a final non-static field of a trusted class ({java,sun}.dyn).
      if (trust_final_non_static_fields(_holder)) {
        _is_constant = true;
        return;
      }
      _is_constant = false;
      return;
    }

    // This field just may be constant.  The only cases where it will
    // not be constant are:
    //
    // 1. The field holds a non-perm-space oop.  The field is, strictly
    //    speaking, constant but we cannot embed non-perm-space oops into
    //    generated code.  For the time being we need to consider the
    //    field to be not constant.
    // 2. The field is a *special* static&final field whose value
    //    may change.  The three examples are java.lang.System.in,
    //    java.lang.System.out, and java.lang.System.err.

    klassOop k = _holder->get_klassOop();
    assert( SystemDictionary::System_klass() != NULL, "Check once per vm");
    if( k == SystemDictionary::System_klass() ) {
      // Check offsets for case 2: System.in, System.out, or System.err
      if( _offset == java_lang_System::in_offset_in_bytes()  ||
          _offset == java_lang_System::out_offset_in_bytes() ||
          _offset == java_lang_System::err_offset_in_bytes() ) {
        _is_constant = false;
        return;
      }
    }

    _is_constant = true;
    switch(type()->basic_type()) {
    case T_BYTE:
      _constant_value = ciConstant(type()->basic_type(), k->byte_field(_offset));
      break;
    case T_CHAR:
      _constant_value = ciConstant(type()->basic_type(), k->char_field(_offset));
      break;
    case T_SHORT:
      _constant_value = ciConstant(type()->basic_type(), k->short_field(_offset));
      break;
    case T_BOOLEAN:
      _constant_value = ciConstant(type()->basic_type(), k->bool_field(_offset));
      break;
    case T_INT:
      _constant_value = ciConstant(type()->basic_type(), k->int_field(_offset));
      break;
    case T_FLOAT:
      _constant_value = ciConstant(k->float_field(_offset));
      break;
    case T_DOUBLE:
      _constant_value = ciConstant(k->double_field(_offset));
      break;
    case T_LONG:
      _constant_value = ciConstant(k->long_field(_offset));
      break;
    case T_OBJECT:
    case T_ARRAY:
      {
        oop o = k->obj_field(_offset);

        // A field will be "constant" if it is known always to be
        // a non-null reference to an instance of a particular class,
        // or to a particular array.  This can happen even if the instance
        // or array is not perm.  In such a case, an "unloaded" ciArray
        // or ciInstance is created.  The compiler may be able to use
        // information about the object's class (which is exact) or length.

        if (o == NULL) {
          _constant_value = ciConstant(type()->basic_type(), ciNullObject::make());
        } else {
          _constant_value = ciConstant(type()->basic_type(), CURRENT_ENV->get_object(o));
          assert(_constant_value.as_object() == CURRENT_ENV->get_object(o), "check interning");
        }
      }
    }
  } else {
    _is_constant = false;
  }
}
Пример #4
0
// ------------------------------------------------------------------
// ciInstance::field_value_impl
ciConstant ciInstance::field_value_impl(BasicType field_btype, int offset) {
  Handle obj = get_oop();
  assert(!obj.is_null(), "bad oop");
  switch(field_btype) {
    case T_BYTE:    return ciConstant(field_btype, obj->byte_field(offset));
    case T_CHAR:    return ciConstant(field_btype, obj->char_field(offset));
    case T_SHORT:   return ciConstant(field_btype, obj->short_field(offset));
    case T_BOOLEAN: return ciConstant(field_btype, obj->bool_field(offset));
    case T_INT:     return ciConstant(field_btype, obj->int_field(offset));
    case T_FLOAT:   return ciConstant(obj->float_field(offset));
    case T_DOUBLE:  return ciConstant(obj->double_field(offset));
    case T_LONG:    return ciConstant(obj->long_field(offset));
    case T_OBJECT:  // fall through
    case T_ARRAY: {
      oop o = obj->obj_field(offset);

      // A field will be "constant" if it is known always to be
      // a non-null reference to an instance of a particular class,
      // or to a particular array.  This can happen even if the instance
      // or array is not perm.  In such a case, an "unloaded" ciArray
      // or ciInstance is created.  The compiler may be able to use
      // information about the object's class (which is exact) or length.

      if (o == NULL) {
        return ciConstant(field_btype, ciNullObject::make());
      } else {
        return ciConstant(field_btype, CURRENT_ENV->get_object(o));
      }
    }
  }
  fatal("no field value: %s", type2name(field_btype));
  return ciConstant();
}