ciSymbol* ciObjectFactory::get_symbol(Symbol* key) {
  vmSymbols::SID sid = vmSymbols::find_sid(key);
  if (sid != vmSymbols::NO_SID) {
    // do not pollute the main cache with it
    return vm_symbol_at(sid);
  }

  assert(vmSymbols::find_sid(key) == vmSymbols::NO_SID, "");
  ciSymbol* s = new (arena()) ciSymbol(key, vmSymbols::NO_SID);
  _symbols->push(s);
  return s;
}
void ciObjectFactory::init_shared_objects() {

  _next_ident = 1;  // start numbering CI objects at 1

  {
    // Create the shared symbols, but not in _shared_ci_metadata.
    int i;
    for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) {
      Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i);
      assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping");
      ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i);
      init_ident_of(sym);
      _shared_ci_symbols[i] = sym;
    }
#ifdef ASSERT
    for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) {
      Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i);
      ciSymbol* sym = vm_symbol_at((vmSymbols::SID) i);
      assert(sym->get_symbol() == vmsym, "oop must match");
    }
    assert(ciSymbol::void_class_signature()->get_symbol() == vmSymbols::void_class_signature(), "spot check");
#endif
  }

  _ci_metadata = new (_arena) GrowableArray<ciMetadata*>(_arena, 64, 0, NULL);

  for (int i = T_BOOLEAN; i <= T_CONFLICT; i++) {
    BasicType t = (BasicType)i;
    if (type2name(t) != NULL && t != T_OBJECT && t != T_ARRAY && t != T_NARROWOOP && t != T_NARROWKLASS) {
      ciType::_basic_types[t] = new (_arena) ciType(t);
      init_ident_of(ciType::_basic_types[t]);
    }
  }

  ciEnv::_null_object_instance = new (_arena) ciNullObject();
  init_ident_of(ciEnv::_null_object_instance);

#define WK_KLASS_DEFN(name, ignore_s, opt)                              \
  if (SystemDictionary::name() != NULL) \
    ciEnv::_##name = get_metadata(SystemDictionary::name())->as_instance_klass();

  WK_KLASSES_DO(WK_KLASS_DEFN)
#undef WK_KLASS_DEFN

  for (int len = -1; len != _ci_metadata->length(); ) {
    len = _ci_metadata->length();
    for (int i2 = 0; i2 < len; i2++) {
      ciMetadata* obj = _ci_metadata->at(i2);
      assert (obj->is_metadata(), "what else would it be?");
      if (obj->is_loaded() && obj->is_instance_klass()) {
        obj->as_instance_klass()->compute_nonstatic_fields();
      }
    }
  }

  ciEnv::_unloaded_cisymbol = ciObjectFactory::get_symbol(vmSymbols::dummy_symbol());
  // Create dummy InstanceKlass and ObjArrayKlass object and assign them idents
  ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL);
  init_ident_of(ciEnv::_unloaded_ciinstance_klass);
  ciEnv::_unloaded_ciobjarrayklass = new (_arena) ciObjArrayKlass(ciEnv::_unloaded_cisymbol, ciEnv::_unloaded_ciinstance_klass, 1);
  init_ident_of(ciEnv::_unloaded_ciobjarrayklass);
  assert(ciEnv::_unloaded_ciobjarrayklass->is_obj_array_klass(), "just checking");

  get_metadata(Universe::boolArrayKlassObj());
  get_metadata(Universe::charArrayKlassObj());
  get_metadata(Universe::singleArrayKlassObj());
  get_metadata(Universe::doubleArrayKlassObj());
  get_metadata(Universe::byteArrayKlassObj());
  get_metadata(Universe::shortArrayKlassObj());
  get_metadata(Universe::intArrayKlassObj());
  get_metadata(Universe::longArrayKlassObj());



  assert(_non_perm_count == 0, "no shared non-perm objects");

  // The shared_ident_limit is the first ident number that will
  // be used for non-shared objects.  That is, numbers less than
  // this limit are permanently assigned to shared CI objects,
  // while the higher numbers are recycled afresh by each new ciEnv.

  _shared_ident_limit = _next_ident;
  _shared_ci_metadata = _ci_metadata;
}
예제 #3
0
// ------------------------------------------------------------------
// ciObjectFactory::get
//
// Get the ciObject corresponding to some oop.  If the ciObject has
// already been created, it is returned.  Otherwise, a new ciObject
// is created.
ciObject* ciObjectFactory::get(oop key) {
  ASSERT_IN_VM;

#ifdef ASSERT
  if (CIObjectFactoryVerify) {
    oop last = NULL;
    for (int j = 0; j< _ci_objects->length(); j++) {
      oop o = _ci_objects->at(j)->get_oop();
      assert(last < o, "out of order");
      last = o;
    }
  }
#endif // ASSERT
  int len = _ci_objects->length();
  int index = find(key, _ci_objects);
#ifdef ASSERT
  if (CIObjectFactoryVerify) {
    for (int i=0; i<_ci_objects->length(); i++) {
      if (_ci_objects->at(i)->get_oop() == key) {
        assert(index == i, " bad lookup");
      }
    }
  }
#endif
  if (!is_found_at(index, key, _ci_objects)) {
    // Check in the non-perm area before putting it in the list.
    NonPermObject* &bucket = find_non_perm(key);
    if (bucket != NULL) {
      return bucket->object();
    }

    // Check in the shared symbol area before putting it in the list.
    if (key->is_symbol()) {
      vmSymbols::SID sid = vmSymbols::find_sid((symbolOop)key);
      if (sid != vmSymbols::NO_SID) {
        // do not pollute the main cache with it
        return vm_symbol_at(sid);
      }
    }

    // The ciObject does not yet exist.  Create it and insert it
    // into the cache.
    Handle keyHandle(key);
    ciObject* new_object = create_new_object(keyHandle());
    assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
    init_ident_of(new_object);
    if (!new_object->is_perm()) {
      // Not a perm-space object.
      insert_non_perm(bucket, keyHandle(), new_object);
      return new_object;
    }
    if (len != _ci_objects->length()) {
      // creating the new object has recursively entered new objects
      // into the table.  We need to recompute our index.
      index = find(keyHandle(), _ci_objects);
    }
    assert(!is_found_at(index, keyHandle(), _ci_objects), "no double insert");
    insert(index, new_object, _ci_objects);
    return new_object;
  }
  return _ci_objects->at(index);
}