// ------------------------------------------------------------------
// ciInstanceKlass::ciInstanceKlass
//
// Loaded instance klass.
ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
  ciKlass(h_k)
{
  assert(get_Klass()->oop_is_instance(), "wrong type");
  assert(get_instanceKlass()->is_loaded(), "must be at least loaded");
  InstanceKlass* ik = get_instanceKlass();

  AccessFlags access_flags = ik->access_flags();
  _flags = ciFlags(access_flags);
  _has_finalizer = access_flags.has_finalizer();
  _has_subklass = ik->subklass() != NULL;
  _init_state = ik->init_state();
  _nonstatic_field_size = ik->nonstatic_field_size();
  _has_nonstatic_fields = ik->has_nonstatic_fields();
  _has_default_methods = ik->has_default_methods();
  _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
  _has_injected_fields = -1;
  _implementor = NULL; // we will fill these lazily

  Thread *thread = Thread::current();
  if (ciObjectFactory::is_initialized()) {
    _loader = JNIHandles::make_local(thread, ik->class_loader());
    _protection_domain = JNIHandles::make_local(thread,
                                                ik->protection_domain());
    _is_shared = false;
  } else {
    Handle h_loader(thread, ik->class_loader());
    Handle h_protection_domain(thread, ik->protection_domain());
    _loader = JNIHandles::make_global(h_loader);
    _protection_domain = JNIHandles::make_global(h_protection_domain);
    _is_shared = true;
  }

  // Lazy fields get filled in only upon request.
  _super  = NULL;
  _java_mirror = NULL;

  if (is_shared()) {
    if (h_k() != SystemDictionary::Object_klass()) {
      super();
    }
    //compute_nonstatic_fields();  // done outside of constructor
  }

  _field_cache = NULL;
}
Пример #2
0
// ------------------------------------------------------------------
// ciInstanceKlass::ciInstanceKlass
//
// Loaded instance klass.
ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : ciKlass(h_k) {
  assert(get_Klass()->oop_is_instance(), "wrong type");
  instanceKlass* ik = get_instanceKlass();

  AccessFlags access_flags = ik->access_flags();
  _flags = ciFlags(access_flags);
  _has_finalizer = access_flags.has_finalizer();
  _has_subklass = ik->subklass() != NULL;
  _is_initialized = ik->is_initialized();
  _is_being_initialized = ik->is_being_initialized();
  _size_helper = ik->size_helper();
  _nonstatic_field_size = ik->nonstatic_field_size();

  _checked_implementor = false;
  _implementor = NULL;

  Thread *thread = Thread::current();
  if (ciObjectFactory::shared_is_initialized()) {
    _loader = JNIHandles::make_local(thread, ik->class_loader());
    _protection_domain = JNIHandles::make_local(thread,
                                                ik->protection_domain());
    _is_shared = false;
  } else {
    Handle h_loader(thread, ik->class_loader());
    Handle h_protection_domain(thread, ik->protection_domain());
    _loader = JNIHandles::make_global(h_loader, false);
    _protection_domain = JNIHandles::make_global(h_protection_domain, false);
    _is_shared = true;
  }
  
  // Lazy fields get filled in only upon request.
  _super  = NULL;
  _java_mirror = NULL;

  if (_is_shared) {
    if (h_k() != SystemDictionary::object_klass()) {
      super();
    }
    java_mirror();
  }

  _field_cache = NULL;
}
Пример #3
0
// ------------------------------------------------------------------
// ciMethod::ciMethod
//
// Loaded method.
ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) {
  assert(h_m() != NULL, "no null method");

  // These fields are always filled in in loaded methods.
  _flags = ciFlags(h_m()->access_flags());

  // Easy to compute, so fill them in now.
  _max_stack          = h_m()->max_stack();
  _max_locals         = h_m()->max_locals();
  _code_size          = h_m()->code_size();
  _intrinsic_id       = h_m()->intrinsic_id();
  _handler_count      = h_m()->exception_table_length();
  _uses_monitors      = h_m()->access_flags().has_monitor_bytecodes();
  _balanced_monitors  = !_uses_monitors || h_m()->access_flags().is_monitor_matching();
  _is_c1_compilable   = !h_m()->is_not_c1_compilable();
  _is_c2_compilable   = !h_m()->is_not_c2_compilable();
  // Lazy fields, filled in on demand.  Require allocation.
  _code               = NULL;
  _exception_handlers = NULL;
  _liveness           = NULL;
  _method_blocks = NULL;
#if defined(COMPILER2) || defined(SHARK)
  _flow               = NULL;
  _bcea               = NULL;
#endif // COMPILER2 || SHARK

  ciEnv *env = CURRENT_ENV;
  if (env->jvmti_can_hotswap_or_post_breakpoint() && can_be_compiled()) {
    // 6328518 check hotswap conditions under the right lock.
    MutexLocker locker(Compile_lock);
    if (Dependencies::check_evol_method(h_m()) != NULL) {
      _is_c1_compilable = false;
      _is_c2_compilable = false;
    }
  } else {
    CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
  }

  if (h_m()->method_holder()->is_linked()) {
    _can_be_statically_bound = h_m()->can_be_statically_bound();
  } else {
    // Have to use a conservative value in this case.
    _can_be_statically_bound = false;
  }

  // Adjust the definition of this condition to be more useful:
  // %%% take these conditions into account in vtable generation
  if (!_can_be_statically_bound && h_m()->is_private())
    _can_be_statically_bound = true;
  if (_can_be_statically_bound && h_m()->is_abstract())
    _can_be_statically_bound = false;

  // generating _signature may allow GC and therefore move m.
  // These fields are always filled in.
  _name = env->get_symbol(h_m()->name());
  _holder = env->get_instance_klass(h_m()->method_holder());
  ciSymbol* sig_symbol = env->get_symbol(h_m()->signature());
  constantPoolHandle cpool = h_m()->constants();
  _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol);
  _method_data = NULL;
  // Take a snapshot of these values, so they will be commensurate with the MDO.
  if (ProfileInterpreter || TieredCompilation) {
    int invcnt = h_m()->interpreter_invocation_count();
    // if the value overflowed report it as max int
    _interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ;
    _interpreter_throwout_count   = h_m()->interpreter_throwout_count();
  } else {
    _interpreter_invocation_count = 0;
    _interpreter_throwout_count = 0;
  }
  if (_interpreter_invocation_count == 0)
    _interpreter_invocation_count = 1;
  _instructions_size = -1;
#ifdef ASSERT
  if (ReplayCompiles) {
    ciReplay::initialize(this);
  }
#endif
}
Пример #4
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;
  }
}