< prev index next >

src/hotspot/share/oops/arrayKlass.cpp

Print this page
@@ -24,10 +24,11 @@
  
  #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"

@@ -35,15 +36,17 @@
  #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() : _dimension() {
+ 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

@@ -86,15 +89,37 @@
    // 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),
+ 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) {
+   _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());

@@ -103,11 +128,10 @@
    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();

@@ -116,11 +140,20 @@
    // 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);
+ 
+   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");

@@ -182,10 +215,27 @@
    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;
  }

@@ -221,11 +271,11 @@
  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();
+     ObjArrayKlass *ak = higher_dimension();
      log_array_class_load(ak);
      ak->restore_unshareable_info(loader_data, protection_domain, CHECK);
    }
  }
  

@@ -281,9 +331,10 @@
  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 >