// ------------------------------------------------------------------
// ciObjectFactory::create_new_object
//
// Create a new ciObject from a Metadata*.
//
// Implementation note: this functionality could be virtual behavior
// of the oop itself.  For now, we explicitly marshal the object.
ciMetadata* ciObjectFactory::create_new_object(Metadata* o) {
  EXCEPTION_CONTEXT;

  if (o->is_klass()) {
    KlassHandle h_k(THREAD, (Klass*)o);
    Klass* k = (Klass*)o;
    if (k->oop_is_instance()) {
      return new (arena()) ciInstanceKlass(h_k);
    } else if (k->oop_is_objArray()) {
      return new (arena()) ciObjArrayKlass(h_k);
    } else if (k->oop_is_typeArray()) {
      return new (arena()) ciTypeArrayKlass(h_k);
    }
  } else if (o->is_method()) {
    methodHandle h_m(THREAD, (Method*)o);
    return new (arena()) ciMethod(h_m);
  } else if (o->is_methodData()) {
    // Hold methodHandle alive - might not be necessary ???
    methodHandle h_m(THREAD, ((MethodData*)o)->method());
    return new (arena()) ciMethodData((MethodData*)o);
  }

  // The oop is of some type not supported by the compiler interface.
  ShouldNotReachHere();
  return NULL;
}
Example #2
0
void klassKlass::oop_verify_on(oop obj, outputStream* st) {
  Klass::oop_verify_on(obj, st);
  guarantee(obj->is_perm(),                      "should be in permspace");
  guarantee(obj->is_klass(),                     "should be klass");

  Klass* k = Klass::cast(klassOop(obj));
  if (k->super() != NULL) {
    guarantee(k->super()->is_perm(),             "should be in permspace");
    guarantee(k->super()->is_klass(),            "should be klass");
  }
  klassOop ko = k->secondary_super_cache();
  if( ko != NULL ) {
    guarantee(ko->is_perm(),                     "should be in permspace");
    guarantee(ko->is_klass(),                    "should be klass");
  }
  for( uint i = 0; i < primary_super_limit(); i++ ) {
    oop ko = k->adr_primary_supers()[i]; // Cannot use normal accessor because it asserts
    if( ko != NULL ) {
      guarantee(ko->is_perm(),                   "should be in permspace");
      guarantee(ko->is_klass(),                  "should be klass");
    }
  }

  if (k->java_mirror() != NULL || (k->oop_is_instance() && instanceKlass::cast(klassOop(obj))->is_loaded())) {
    guarantee(k->java_mirror() != NULL,          "should be allocated");
    guarantee(k->java_mirror()->is_perm(),       "should be in permspace");
    guarantee(k->java_mirror()->is_instance(),   "should be instance");
  }
  if (k->name() != NULL) {
    guarantee(Universe::heap()->is_in_permanent(k->name()),
              "should be in permspace");
    guarantee(k->name()->is_symbol(), "should be symbol");
  }
}
void Dictionary::verify() {
  guarantee(number_of_entries() >= 0, "Verify of system dictionary failed");

  int element_count = 0;
  for (int index = 0; index < table_size(); index++) {
    for (DictionaryEntry* probe = bucket(index);
                          probe != NULL;
                          probe = probe->next()) {
      Klass* e = probe->klass();
      ClassLoaderData* loader_data = probe->loader_data();
      guarantee(e->oop_is_instance(),
                              "Verify of system dictionary failed");
      // class loader must be present;  a null class loader is the
      // boostrap loader
      guarantee(loader_data != NULL || DumpSharedSpaces ||
                loader_data->class_loader() == NULL ||
                loader_data->class_loader()->is_instance(),
                "checking type of class_loader");
      e->verify();
      probe->verify_protection_domain_set();
      element_count++;
    }
  }
  guarantee(number_of_entries() == element_count,
            "Verify of system dictionary failed");
  debug_only(verify_lookup_length((double)number_of_entries() / table_size()));

  _pd_cache_table->verify();
}
void InstanceMirrorKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
  InstanceKlass::oop_pc_follow_contents(obj, cm);

  // Follow the klass field in the mirror.
  Klass* klass = java_lang_Class::as_Klass(obj);
  if (klass != NULL) {
    // An anonymous class doesn't have its own class loader, so the call
    // to follow_klass will mark and push its java mirror instead of the
    // class loader. When handling the java mirror for an anonymous class
    // we need to make sure its class loader data is claimed, this is done
    // by calling follow_class_loader explicitly. For non-anonymous classes
    // the call to follow_class_loader is made when the class loader itself
    // is handled.
    if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
      PSParallelCompact::follow_class_loader(cm, klass->class_loader_data());
    } else {
      PSParallelCompact::follow_klass(cm, klass);
    }
  } else {
    // If klass is NULL then this a mirror for a primitive type.
    // We don't have to follow them, since they are handled as strong
    // roots in Universe::oops_do.
    assert(java_lang_Class::is_primitive(obj), "Sanity check");
  }

  PSParallelCompact::MarkAndPushClosure cl(cm);
  oop_oop_iterate_statics<true>(obj, &cl);
}
void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
  for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
    if (k->oop_is_instance()) {
      f(InstanceKlass::cast(k));
    }
    assert(k != k->next_link(), "no loops!");
  }
}
void ClassLoaderData::loaded_classes_do(KlassClosure* klass_closure) {
  // Lock to avoid classes being modified/added/removed during iteration
  MutexLockerEx ml(metaspace_lock(),  Mutex::_no_safepoint_check_flag);
  for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
    // Do not filter ArrayKlass oops here...
    if (k->oop_is_array() || (k->oop_is_instance() && InstanceKlass::cast(k)->is_loaded())) {
      klass_closure->do_klass(k);
    }
  }
}
// ------------------------------------------------------------------
// ciObjectFactory::create_new_metadata
//
// Create a new ciMetadata from a Metadata*.
//
// Implementation note: in order to keep Metadata live, an auxiliary ciObject
// is used, which points to it's holder.
ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) {
  EXCEPTION_CONTEXT;

  // Hold metadata from unloading by keeping it's holder alive.
  if (_initialized && o->is_klass()) {
    Klass* holder = ((Klass*)o);
    if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) {
      // Though ciInstanceKlass records class loader oop, it's not enough to keep
      // VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
      // It is enough to record a ciObject, since cached elements are never removed
      // during ciObjectFactory lifetime. ciObjectFactory itself is created for
      // every compilation and lives for the whole duration of the compilation.
      ciObject* h = get(holder->klass_holder());
    }
  }

  if (o->is_klass()) {
    KlassHandle h_k(THREAD, (Klass*)o);
    Klass* k = (Klass*)o;
    if (k->oop_is_instance()) {
      return new (arena()) ciInstanceKlass(h_k);
    } else if (k->oop_is_objArray()) {
      return new (arena()) ciObjArrayKlass(h_k);
    } else if (k->oop_is_typeArray()) {
      return new (arena()) ciTypeArrayKlass(h_k);
    }
  } else if (o->is_method()) {
    methodHandle h_m(THREAD, (Method*)o);
    ciEnv *env = CURRENT_THREAD_ENV;
    ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder());
    return new (arena()) ciMethod(h_m, holder);
  } else if (o->is_methodData()) {
    // Hold methodHandle alive - might not be necessary ???
    methodHandle h_m(THREAD, ((MethodData*)o)->method());
    return new (arena()) ciMethodData((MethodData*)o);
  }

  // The Metadata* is of some type not supported by the compiler interface.
  ShouldNotReachHere();
  return NULL;
}
Example #8
0
object_type ClassifyObjectClosure::classify_object(oop obj, bool count) {
  object_type type = unknown_type;

  Klass* k = obj->blueprint();

  if (k->as_klassOop() == SystemDictionary::Object_klass()) {
    tty->print_cr("Found the class!");
  }

  if (count) {
    k->set_alloc_count(k->alloc_count() + 1);
  }

  if (obj->is_instance()) {
    if (k->oop_is_instanceRef()) {
      type = instanceRef_type;
    } else {
      type = instance_type;
    }
  } else if (obj->is_typeArray()) {
    type = typeArray_type;
  } else if (obj->is_objArray()) {
    type = objArray_type;
  } else if (obj->is_symbol()) {
    type = symbol_type;
  } else if (obj->is_klass()) {
    Klass* k = ((klassOop)obj)->klass_part();
    if (k->oop_is_instance()) {
      type = instanceKlass_type;
    } else {
      type = klass_type;
    }
  } else if (obj->is_method()) {
    type = method_type;
  } else if (obj->is_constMethod()) {
    type = constMethod_type;
  } else if (obj->is_methodData()) {
    ShouldNotReachHere();
  } else if (obj->is_constantPool()) {
    type = constantPool_type;
  } else if (obj->is_constantPoolCache()) {
    type = constantPoolCache_type;
  } else if (obj->is_compiledICHolder()) {
    type = compiledICHolder_type;
  } else {
    ShouldNotReachHere();
  }

  assert(type != unknown_type, "found object of unknown type.");
  return type;
}
// Walk all methods in the class list and assign a fingerprint.
// so that this part of the ConstMethod* is read only.
static void calculate_fingerprints() {
  for (int i = 0; i < _global_klass_objects->length(); i++) {
    Klass* k = _global_klass_objects->at(i);
    if (k->oop_is_instance()) {
      InstanceKlass* ik = InstanceKlass::cast(k);
      for (int i = 0; i < ik->methods()->length(); i++) {
        Method* m = ik->methods()->at(i);
        Fingerprinter fp(m);
        // The side effect of this call sets method's fingerprint field.
        fp.fingerprint();
      }
    }
  }
}
Method* ConstantPoolCacheEntry::method_if_resolved(constantPoolHandle cpool) {
  // Decode the action of set_method and set_interface_call
  Bytecodes::Code invoke_code = bytecode_1();
  if (invoke_code != (Bytecodes::Code)0) {
    Metadata* f1 = f1_ord();
    if (f1 != NULL) {
      switch (invoke_code) {
      case Bytecodes::_invokeinterface:
        assert(f1->is_klass(), "");
        return klassItable::method_for_itable_index((Klass*)f1, f2_as_index());
      case Bytecodes::_invokestatic:
      case Bytecodes::_invokespecial:
        assert(!has_appendix(), "");
      case Bytecodes::_invokehandle:
      case Bytecodes::_invokedynamic:
        assert(f1->is_method(), "");
        return (Method*)f1;
      }
    }
  }
  invoke_code = bytecode_2();
  if (invoke_code != (Bytecodes::Code)0) {
    switch (invoke_code) {
    case Bytecodes::_invokevirtual:
      if (is_vfinal()) {
        // invokevirtual
        Method* m = f2_as_vfinal_method();
        assert(m->is_method(), "");
        return m;
      } else {
        int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index());
        if (cpool->tag_at(holder_index).is_klass()) {
          Klass* klass = cpool->resolved_klass_at(holder_index);
          if (!klass->oop_is_instance())
            klass = SystemDictionary::Object_klass();
          return InstanceKlass::cast(klass)->method_at_vtable(f2_as_index());
        }
      }
      break;
    }
  }
  return NULL;
}
  // Unevolving classes may point to methods of the evolving class directly
  // from their constantpool caches and vtables/itables. Fix this. 
  static void adjust_cpool_cache_and_vtable(klassOop k_oop, oop loader) {
    Klass *k = k_oop->klass_part();
    if (k->oop_is_instance()) {
      instanceKlass *ik = (instanceKlass *) k;
      bool previous_version; 

      if (java_core_class_name(ik->name()->as_utf8())) return;

      // By this time we have already replaced the constantpool pointer in the evolving
      // class itself. However, we need to fix the entries in the old constantpool, which
      // is still referenced by active old methods of this class.
      constantPoolCacheOop cp_cache = (k_oop == _evolving_koop) ? 
                _old_constants->cache() : ik->constants()->cache();
      
      do {

        if (cp_cache != NULL) {
          cp_cache->adjust_method_entries(_old_methods, _new_methods);
        }

        // Fix vtable (this is needed for the evolving class itself and its subclasses).
        if (ik->vtable_length() > 0 && ik->is_subclass_of(_evolving_koop)) {
          ik->vtable()->adjust_entries(_old_methods, _new_methods);         
        }
        // Fix itable, if it exists.
        if (ik->itable_length() > 0) {
          ik->itable()->adjust_method_entries(_old_methods, _new_methods);
        }

        // Previous version methods could be still on stack so adjust entries
        // in all previous versions.
        if (ik->has_previous_version()) {
          ik = (instanceKlass *)(ik->previous_version())->klass_part();
          cp_cache = ik->constants()->cache();
          previous_version = true;
        } else {
          previous_version = false;
        }
      } while (previous_version);
    }
  }
// Assumes the vtable is in first slot in object.
static void patch_klass_vtables(void** vtbl_list, void* new_vtable_start) {
  int n = _global_klass_objects->length();
  for (int i = 0; i < n; i++) {
    Klass* obj = _global_klass_objects->at(i);
    // Note oop_is_instance() is a virtual call.  After patching vtables
    // all virtual calls on the dummy vtables will restore the original!
    if (obj->oop_is_instance()) {
      InstanceKlass* ik = InstanceKlass::cast(obj);
      *(void**)ik = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, ik);
      ConstantPool* cp = ik->constants();
      *(void**)cp = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, cp);
      for (int j = 0; j < ik->methods()->length(); j++) {
        Method* m = ik->methods()->at(j);
        *(void**)m = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, m);
      }
    } else {
      // Array klasses
      Klass* k = obj;
      *(void**)k = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, k);
    }
  }
}
// ------------------------------------------------------------------
// ciFieldLayout::fill_in_instance_fields
//
// Set up the instance fields in this ciFieldLayout.
void ciFieldLayout::fill_in_instance_fields(GrowableArray<BasicType>* fieldtypes,
					    GrowableArray<int>* fieldoffsets, 
					    GrowableArray<int>* aflags,
					    int& pos,
					    klassOop current) {
  Klass* k = current->klass_part();
  assert(k->oop_is_instance(), "must be instanceKlass");
  instanceKlass* ik = (instanceKlass*)k;
  klassOop super = k->super();
  if (super) {
    fill_in_instance_fields(fieldtypes, fieldoffsets, aflags, pos, super);
  }

  // Fill in this klass's instance fields.
  typeArrayOop field_list = ik->fields();
  constantPoolOop cpool = ik->constants();
  uint num_fields = field_list->length();

  for (uint i = 0; i < num_fields; i += instanceKlass::next_offset) {
    AccessFlags flags;
    flags.set_flags(field_list->short_at(i + instanceKlass::access_flags_offset));
   
    if (!flags.is_static()) {
      // This is an instance field.  Add it to our list.
      int field_offset = ik->offset_from_fields( i );
      // Add the type to our list.
      symbolOop type_sym = cpool->symbol_at(field_list->short_at(i+
                           instanceKlass::signature_index_offset));
      BasicType field_type; 
      field_type = type2field[FieldType::basic_type(type_sym)];
      fieldtypes->at_put_grow(pos, field_type, T_VOID);
      aflags->at_put_grow(pos, flags.as_int(), 0);
      // The field offset we set here includes the header_size
      fieldoffsets->at_put_grow(pos, field_offset, 0);
      pos++;
    }
  }
}
Example #14
0
inline instanceKlass* klassVtable::ik() const {
  Klass* k = _klass()->klass_part();
  assert(k->oop_is_instance(), "not an instanceKlass");
  return (instanceKlass*)k;
}
Example #15
0
// ------------------------------------------------------------------
// ciObjectFactory::create_new_object
//
// Create a new ciObject from an oop.
//
// Implementation note: this functionality could be virtual behavior
// of the oop itself.  For now, we explicitly marshal the object.
ciObject* ciObjectFactory::create_new_object(oop o) {
  EXCEPTION_CONTEXT;

  if (o->is_symbol()) {
    symbolHandle h_o(THREAD, (symbolOop)o);
    assert(vmSymbols::find_sid(h_o()) == vmSymbols::NO_SID, "");
    return new (arena()) ciSymbol(h_o, vmSymbols::NO_SID);
  } else if (o->is_klass()) {
    KlassHandle h_k(THREAD, (klassOop)o);
    Klass* k = ((klassOop)o)->klass_part();
    if (k->oop_is_instance()) {
      return new (arena()) ciInstanceKlass(h_k);
    } else if (k->oop_is_objArray()) {
      return new (arena()) ciObjArrayKlass(h_k);
    } else if (k->oop_is_typeArray()) {
      return new (arena()) ciTypeArrayKlass(h_k);
    } else if (k->oop_is_method()) {
      return new (arena()) ciMethodKlass(h_k);
    } else if (k->oop_is_symbol()) {
      return new (arena()) ciSymbolKlass(h_k);
    } else if (k->oop_is_klass()) {
      if (k->oop_is_objArrayKlass()) {
        return new (arena()) ciObjArrayKlassKlass(h_k);
      } else if (k->oop_is_typeArrayKlass()) {
        return new (arena()) ciTypeArrayKlassKlass(h_k);
      } else if (k->oop_is_instanceKlass()) {
        return new (arena()) ciInstanceKlassKlass(h_k);
      } else {
        assert(o == Universe::klassKlassObj(), "bad klassKlass");
        return new (arena()) ciKlassKlass(h_k);
      }
    }
  } else if (o->is_method()) {
    methodHandle h_m(THREAD, (methodOop)o);
    return new (arena()) ciMethod(h_m);
  } else if (o->is_methodData()) {
    methodDataHandle h_md(THREAD, (methodDataOop)o);
    return new (arena()) ciMethodData(h_md);
  } else if (o->is_instance()) {
    instanceHandle h_i(THREAD, (instanceOop)o);
    if (java_dyn_CallSite::is_instance(o))
      return new (arena()) ciCallSite(h_i);
    else if (java_dyn_MethodHandle::is_instance(o))
      return new (arena()) ciMethodHandle(h_i);
    else
      return new (arena()) ciInstance(h_i);
  } else if (o->is_objArray()) {
    objArrayHandle h_oa(THREAD, (objArrayOop)o);
    return new (arena()) ciObjArray(h_oa);
  } else if (o->is_typeArray()) {
    typeArrayHandle h_ta(THREAD, (typeArrayOop)o);
    return new (arena()) ciTypeArray(h_ta);
  } else if (o->is_constantPoolCache()) {
    constantPoolCacheHandle h_cpc(THREAD, (constantPoolCacheOop) o);
    return new (arena()) ciCPCache(h_cpc);
  }

  // The oop is of some type not supported by the compiler interface.
  ShouldNotReachHere();
  return NULL;
}