< prev index next > src/hotspot/share/oops/arrayKlass.cpp
Print this page
#include "cds/aotMetaspace.hpp"
#include "cds/cdsConfig.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/moduleEntry.hpp"
+ #include "classfile/symbolTable.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "jvmtifiles/jvmti.h"
#include "memory/metaspaceClosure.hpp"
#include "memory/universe.hpp"
#include "oops/arrayKlass.inline.hpp"
#include "oops/arrayOop.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
! ArrayKlass::ArrayKlass() : _dimension() {
assert(CDSConfig::is_dumping_static_archive() || CDSConfig::is_using_archive(), "only for CDS");
}
int ArrayKlass::static_size(int header_size) {
// size of an array klass object
#include "memory/universe.hpp"
#include "oops/arrayKlass.inline.hpp"
#include "oops/arrayOop.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klass.inline.hpp"
+ #include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
+ #include "oops/refArrayKlass.hpp"
#include "runtime/handles.inline.hpp"
! ArrayKlass::ArrayKlass() : _properties() {
assert(CDSConfig::is_dumping_static_archive() || CDSConfig::is_using_archive(), "only for CDS");
}
int ArrayKlass::static_size(int header_size) {
// size of an array klass object
// super klass of an array, (j.l.Object) should not have
// any overpass methods present.
return super()->uncached_lookup_method(name, signature, OverpassLookupMode::skip, private_mode);
}
! ArrayKlass::ArrayKlass(int n, Symbol* name, KlassKind kind) :
! Klass(kind),
_dimension(n),
_higher_dimension(nullptr),
! _lower_dimension(nullptr) {
// Arrays don't add any new methods, so their vtable is the same size as
// the vtable of klass Object.
set_vtable_length(Universe::base_vtable_size());
set_name(name);
set_super(Universe::is_bootstrapping() ? nullptr : vmClasses::Object_klass());
// super klass of an array, (j.l.Object) should not have
// any overpass methods present.
return super()->uncached_lookup_method(name, signature, OverpassLookupMode::skip, private_mode);
}
! static markWord calc_prototype_header(Klass::KlassKind kind, ArrayProperties props) {
! switch (kind) {
+ case Klass::KlassKind::TypeArrayKlassKind:
+ return markWord::prototype();
+
+ case Klass::KlassKind::FlatArrayKlassKind:
+ return markWord::flat_array_prototype(props.is_null_restricted());
+
+ case Klass::KlassKind::ObjArrayKlassKind:
+ case Klass::KlassKind::RefArrayKlassKind:
+ if (props.is_null_restricted()) {
+ return markWord::null_free_array_prototype();
+ } else {
+ return markWord::prototype();
+ }
+
+ default:
+ ShouldNotReachHere();
+ };
+ }
+
+ ArrayKlass::ArrayKlass(int n, Symbol* name, KlassKind kind, ArrayProperties props)
+ : Klass(kind, calc_prototype_header(kind, props)),
_dimension(n),
_higher_dimension(nullptr),
! _lower_dimension(nullptr),
+ _properties(props) {
// Arrays don't add any new methods, so their vtable is the same size as
// the vtable of klass Object.
set_vtable_length(Universe::base_vtable_size());
set_name(name);
set_super(Universe::is_bootstrapping() ? nullptr : vmClasses::Object_klass());
set_is_cloneable_fast();
JFR_ONLY(INIT_ID(this);)
log_array_class_load(this);
}
-
// Initialization of vtables and mirror object is done separately from base_create_array_klass,
// since a GC can happen. At this point all instance variables of the ArrayKlass must be setup.
void ArrayKlass::complete_create_array_klass(ArrayKlass* k, Klass* super_klass, ModuleEntry* module_entry, TRAPS) {
k->initialize_supers(super_klass, nullptr, CHECK);
k->vtable().initialize_vtable();
// These classes will be put on a fixup list and their module fields will be patched once
// java.base is defined.
assert((module_entry != nullptr) || ((module_entry == nullptr) && !ModuleEntryTable::javabase_defined()),
"module entry not available post " JAVA_BASE_NAME " definition");
oop module_oop = (module_entry != nullptr) ? module_entry->module_oop() : (oop)nullptr;
! java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), Handle(THREAD, module_oop), Handle(), Handle(), CHECK);
}
ArrayKlass* ArrayKlass::array_klass(int n, TRAPS) {
assert(dimension() <= n, "check order of chain");
// These classes will be put on a fixup list and their module fields will be patched once
// java.base is defined.
assert((module_entry != nullptr) || ((module_entry == nullptr) && !ModuleEntryTable::javabase_defined()),
"module entry not available post " JAVA_BASE_NAME " definition");
oop module_oop = (module_entry != nullptr) ? module_entry->module_oop() : (oop)nullptr;
!
+ if (k->is_refined_objArray_klass()) {
+ assert(super_klass != nullptr, "Must be");
+ assert(k->super() != nullptr, "Must be");
+ assert(k->super() == super_klass, "Must be");
+ Handle mirror(THREAD, super_klass->java_mirror());
+ k->set_java_mirror(mirror);
+ } else {
+ java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), Handle(THREAD, module_oop), Handle(), Handle(), CHECK);
+ }
}
ArrayKlass* ArrayKlass::array_klass(int n, TRAPS) {
assert(dimension() <= n, "check order of chain");
set_secondary_supers(Universe::the_array_interfaces_array(),
Universe::the_array_interfaces_bitmap());
return nullptr;
}
+ oop ArrayKlass::component_mirror() const {
+ return java_lang_Class::component_mirror(java_mirror());
+ }
+
+ ArrayProperties ArrayKlass::array_properties_from_layout(LayoutKind lk) {
+ switch(lk) {
+ case LayoutKind::NULL_FREE_ATOMIC_FLAT:
+ return ArrayProperties::Default().with_null_restricted();
+ case LayoutKind::NULL_FREE_NON_ATOMIC_FLAT:
+ return ArrayProperties::Default().with_null_restricted().with_non_atomic();
+ case LayoutKind::NULLABLE_ATOMIC_FLAT:
+ return ArrayProperties::Default();
+ default:
+ ShouldNotReachHere();
+ }
+ }
+
// JVMTI support
jint ArrayKlass::jvmti_class_status() const {
return JVMTI_CLASS_STATUS_ARRAY;
}
void ArrayKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
// Klass recreates the component mirror also
if (_higher_dimension != nullptr) {
! ArrayKlass *ak = higher_dimension();
log_array_class_load(ak);
ak->restore_unshareable_info(loader_data, protection_domain, CHECK);
}
}
void ArrayKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
// Klass recreates the component mirror also
if (_higher_dimension != nullptr) {
! ObjArrayKlass *ak = higher_dimension();
log_array_class_load(ak);
ak->restore_unshareable_info(loader_data, protection_domain, CHECK);
}
}
void ArrayKlass::verify_on(outputStream* st) {
Klass::verify_on(st);
}
void ArrayKlass::oop_verify_on(oop obj, outputStream* st) {
+ Klass::oop_verify_on(obj, st);
guarantee(obj->is_array(), "must be array");
arrayOop a = arrayOop(obj);
guarantee(a->length() >= 0, "array with negative length?");
}
< prev index next >