| 1 | /* | 
|---|
| 2 | * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. | 
|---|
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
|---|
| 4 | * | 
|---|
| 5 | * This code is free software; you can redistribute it and/or modify it | 
|---|
| 6 | * under the terms of the GNU General Public License version 2 only, as | 
|---|
| 7 | * published by the Free Software Foundation. | 
|---|
| 8 | * | 
|---|
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT | 
|---|
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|---|
| 11 | * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|---|
| 12 | * version 2 for more details (a copy is included in the LICENSE file that | 
|---|
| 13 | * accompanied this code). | 
|---|
| 14 | * | 
|---|
| 15 | * You should have received a copy of the GNU General Public License version | 
|---|
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, | 
|---|
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
|---|
| 18 | * | 
|---|
| 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
|---|
| 20 | * or visit www.oracle.com if you need additional information or have any | 
|---|
| 21 | * questions. | 
|---|
| 22 | * | 
|---|
| 23 | */ | 
|---|
| 24 |  | 
|---|
| 25 | #include "precompiled.hpp" | 
|---|
| 26 | #include "classfile/javaClasses.hpp" | 
|---|
| 27 | #include "classfile/moduleEntry.hpp" | 
|---|
| 28 | #include "classfile/systemDictionary.hpp" | 
|---|
| 29 | #include "classfile/vmSymbols.hpp" | 
|---|
| 30 | #include "gc/shared/collectedHeap.inline.hpp" | 
|---|
| 31 | #include "jvmtifiles/jvmti.h" | 
|---|
| 32 | #include "memory/metaspaceClosure.hpp" | 
|---|
| 33 | #include "memory/resourceArea.hpp" | 
|---|
| 34 | #include "memory/universe.hpp" | 
|---|
| 35 | #include "oops/arrayKlass.hpp" | 
|---|
| 36 | #include "oops/arrayOop.hpp" | 
|---|
| 37 | #include "oops/instanceKlass.hpp" | 
|---|
| 38 | #include "oops/objArrayOop.hpp" | 
|---|
| 39 | #include "oops/oop.inline.hpp" | 
|---|
| 40 | #include "runtime/handles.inline.hpp" | 
|---|
| 41 |  | 
|---|
| 42 | int ArrayKlass::static_size(int ) { | 
|---|
| 43 | // size of an array klass object | 
|---|
| 44 | assert(header_size <= InstanceKlass::header_size(), "bad header size"); | 
|---|
| 45 | // If this assert fails, see comments in base_create_array_klass. | 
|---|
| 46 | header_size = InstanceKlass::header_size(); | 
|---|
| 47 | int vtable_len = Universe::base_vtable_size(); | 
|---|
| 48 | int size = header_size + vtable_len; | 
|---|
| 49 | return align_metadata_size(size); | 
|---|
| 50 | } | 
|---|
| 51 |  | 
|---|
| 52 |  | 
|---|
| 53 | InstanceKlass* ArrayKlass::java_super() const { | 
|---|
| 54 | if (super() == NULL)  return NULL;  // bootstrap case | 
|---|
| 55 | // Array klasses have primary supertypes which are not reported to Java. | 
|---|
| 56 | // Example super chain:  String[][] -> Object[][] -> Object[] -> Object | 
|---|
| 57 | return SystemDictionary::Object_klass(); | 
|---|
| 58 | } | 
|---|
| 59 |  | 
|---|
| 60 |  | 
|---|
| 61 | oop ArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) { | 
|---|
| 62 | ShouldNotReachHere(); | 
|---|
| 63 | return NULL; | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined | 
|---|
| 67 | Klass* ArrayKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { | 
|---|
| 68 | // There are no fields in an array klass but look to the super class (Object) | 
|---|
| 69 | assert(super(), "super klass must be present"); | 
|---|
| 70 | return super()->find_field(name, sig, fd); | 
|---|
| 71 | } | 
|---|
| 72 |  | 
|---|
| 73 | Method* ArrayKlass::uncached_lookup_method(const Symbol* name, | 
|---|
| 74 | const Symbol* signature, | 
|---|
| 75 | OverpassLookupMode overpass_mode, | 
|---|
| 76 | PrivateLookupMode private_mode) const { | 
|---|
| 77 | // There are no methods in an array klass but the super class (Object) has some | 
|---|
| 78 | assert(super(), "super klass must be present"); | 
|---|
| 79 | // Always ignore overpass methods in superclasses, although technically the | 
|---|
| 80 | // super klass of an array, (j.l.Object) should not have | 
|---|
| 81 | // any overpass methods present. | 
|---|
| 82 | return super()->uncached_lookup_method(name, signature, Klass::skip_overpass, private_mode); | 
|---|
| 83 | } | 
|---|
| 84 |  | 
|---|
| 85 | ArrayKlass::ArrayKlass(Symbol* name, KlassID id) : | 
|---|
| 86 | Klass(id), | 
|---|
| 87 | _dimension(1), | 
|---|
| 88 | _higher_dimension(NULL), | 
|---|
| 89 | _lower_dimension(NULL) { | 
|---|
| 90 | // Arrays don't add any new methods, so their vtable is the same size as | 
|---|
| 91 | // the vtable of klass Object. | 
|---|
| 92 | set_vtable_length(Universe::base_vtable_size()); | 
|---|
| 93 | set_name(name); | 
|---|
| 94 | set_super(Universe::is_bootstrapping() ? NULL : SystemDictionary::Object_klass()); | 
|---|
| 95 | set_layout_helper(Klass::_lh_neutral_value); | 
|---|
| 96 | set_is_cloneable(); // All arrays are considered to be cloneable (See JLS 20.1.5) | 
|---|
| 97 | JFR_ONLY(INIT_ID(this);) | 
|---|
| 98 | } | 
|---|
| 99 |  | 
|---|
| 100 |  | 
|---|
| 101 | // Initialization of vtables and mirror object is done separatly from base_create_array_klass, | 
|---|
| 102 | // since a GC can happen. At this point all instance variables of the ArrayKlass must be setup. | 
|---|
| 103 | void ArrayKlass::complete_create_array_klass(ArrayKlass* k, Klass* super_klass, ModuleEntry* module_entry, TRAPS) { | 
|---|
| 104 | k->initialize_supers(super_klass, NULL, CHECK); | 
|---|
| 105 | k->vtable().initialize_vtable(false, CHECK); | 
|---|
| 106 |  | 
|---|
| 107 | // During bootstrapping, before java.base is defined, the module_entry may not be present yet. | 
|---|
| 108 | // These classes will be put on a fixup list and their module fields will be patched once | 
|---|
| 109 | // java.base is defined. | 
|---|
| 110 | assert((module_entry != NULL) || ((module_entry == NULL) && !ModuleEntryTable::javabase_defined()), | 
|---|
| 111 | "module entry not available post "JAVA_BASE_NAME " definition"); | 
|---|
| 112 | oop module = (module_entry != NULL) ? module_entry->module() : (oop)NULL; | 
|---|
| 113 | java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), Handle(THREAD, module), Handle(), CHECK); | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|
| 116 | GrowableArray<Klass*>* ArrayKlass::compute_secondary_supers(int , | 
|---|
| 117 | Array<InstanceKlass*>* transitive_interfaces) { | 
|---|
| 118 | // interfaces = { cloneable_klass, serializable_klass }; | 
|---|
| 119 | assert(num_extra_slots == 0, "sanity of primitive array type"); | 
|---|
| 120 | assert(transitive_interfaces == NULL, "sanity"); | 
|---|
| 121 | // Must share this for correct bootstrapping! | 
|---|
| 122 | set_secondary_supers(Universe::the_array_interfaces_array()); | 
|---|
| 123 | return NULL; | 
|---|
| 124 | } | 
|---|
| 125 |  | 
|---|
| 126 | objArrayOop ArrayKlass::allocate_arrayArray(int n, int length, TRAPS) { | 
|---|
| 127 | check_array_allocation_length(length, arrayOopDesc::max_array_length(T_ARRAY), CHECK_0); | 
|---|
| 128 | int size = objArrayOopDesc::object_size(length); | 
|---|
| 129 | Klass* k = array_klass(n+dimension(), CHECK_0); | 
|---|
| 130 | ArrayKlass* ak = ArrayKlass::cast(k); | 
|---|
| 131 | objArrayOop o = (objArrayOop)Universe::heap()->array_allocate(ak, size, length, | 
|---|
| 132 | /* do_zero */ true, CHECK_0); | 
|---|
| 133 | // initialization to NULL not necessary, area already cleared | 
|---|
| 134 | return o; | 
|---|
| 135 | } | 
|---|
| 136 |  | 
|---|
| 137 | void ArrayKlass::array_klasses_do(void f(Klass* k, TRAPS), TRAPS) { | 
|---|
| 138 | Klass* k = this; | 
|---|
| 139 | // Iterate over this array klass and all higher dimensions | 
|---|
| 140 | while (k != NULL) { | 
|---|
| 141 | f(k, CHECK); | 
|---|
| 142 | k = ArrayKlass::cast(k)->higher_dimension(); | 
|---|
| 143 | } | 
|---|
| 144 | } | 
|---|
| 145 |  | 
|---|
| 146 | void ArrayKlass::array_klasses_do(void f(Klass* k)) { | 
|---|
| 147 | Klass* k = this; | 
|---|
| 148 | // Iterate over this array klass and all higher dimensions | 
|---|
| 149 | while (k != NULL) { | 
|---|
| 150 | f(k); | 
|---|
| 151 | k = ArrayKlass::cast(k)->higher_dimension(); | 
|---|
| 152 | } | 
|---|
| 153 | } | 
|---|
| 154 |  | 
|---|
| 155 | // JVM support | 
|---|
| 156 |  | 
|---|
| 157 | jint ArrayKlass::compute_modifier_flags(TRAPS) const { | 
|---|
| 158 | return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; | 
|---|
| 159 | } | 
|---|
| 160 |  | 
|---|
| 161 | // JVMTI support | 
|---|
| 162 |  | 
|---|
| 163 | jint ArrayKlass::jvmti_class_status() const { | 
|---|
| 164 | return JVMTI_CLASS_STATUS_ARRAY; | 
|---|
| 165 | } | 
|---|
| 166 |  | 
|---|
| 167 | void ArrayKlass::metaspace_pointers_do(MetaspaceClosure* it) { | 
|---|
| 168 | Klass::metaspace_pointers_do(it); | 
|---|
| 169 |  | 
|---|
| 170 | ResourceMark rm; | 
|---|
| 171 | log_trace(cds)( "Iter(ArrayKlass): %p (%s)", this, external_name()); | 
|---|
| 172 |  | 
|---|
| 173 | // need to cast away volatile | 
|---|
| 174 | it->push((Klass**)&_higher_dimension); | 
|---|
| 175 | it->push((Klass**)&_lower_dimension); | 
|---|
| 176 | } | 
|---|
| 177 |  | 
|---|
| 178 | void ArrayKlass::remove_unshareable_info() { | 
|---|
| 179 | Klass::remove_unshareable_info(); | 
|---|
| 180 | if (_higher_dimension != NULL) { | 
|---|
| 181 | ArrayKlass *ak = ArrayKlass::cast(higher_dimension()); | 
|---|
| 182 | ak->remove_unshareable_info(); | 
|---|
| 183 | } | 
|---|
| 184 | } | 
|---|
| 185 |  | 
|---|
| 186 | void ArrayKlass::remove_java_mirror() { | 
|---|
| 187 | Klass::remove_java_mirror(); | 
|---|
| 188 | if (_higher_dimension != NULL) { | 
|---|
| 189 | ArrayKlass *ak = ArrayKlass::cast(higher_dimension()); | 
|---|
| 190 | ak->remove_java_mirror(); | 
|---|
| 191 | } | 
|---|
| 192 | } | 
|---|
| 193 |  | 
|---|
| 194 | void ArrayKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) { | 
|---|
| 195 | assert(loader_data == ClassLoaderData::the_null_class_loader_data(), "array classes belong to null loader"); | 
|---|
| 196 | Klass::restore_unshareable_info(loader_data, protection_domain, CHECK); | 
|---|
| 197 | // Klass recreates the component mirror also | 
|---|
| 198 |  | 
|---|
| 199 | if (_higher_dimension != NULL) { | 
|---|
| 200 | ArrayKlass *ak = ArrayKlass::cast(higher_dimension()); | 
|---|
| 201 | ak->restore_unshareable_info(loader_data, protection_domain, CHECK); | 
|---|
| 202 | } | 
|---|
| 203 | } | 
|---|
| 204 |  | 
|---|
| 205 | // Printing | 
|---|
| 206 |  | 
|---|
| 207 | void ArrayKlass::print_on(outputStream* st) const { | 
|---|
| 208 | assert(is_klass(), "must be klass"); | 
|---|
| 209 | Klass::print_on(st); | 
|---|
| 210 | } | 
|---|
| 211 |  | 
|---|
| 212 | void ArrayKlass::print_value_on(outputStream* st) const { | 
|---|
| 213 | assert(is_klass(), "must be klass"); | 
|---|
| 214 | for(int index = 0; index < dimension(); index++) { | 
|---|
| 215 | st->print( "[]"); | 
|---|
| 216 | } | 
|---|
| 217 | } | 
|---|
| 218 |  | 
|---|
| 219 | void ArrayKlass::oop_print_on(oop obj, outputStream* st) { | 
|---|
| 220 | assert(obj->is_array(), "must be array"); | 
|---|
| 221 | Klass::oop_print_on(obj, st); | 
|---|
| 222 | st->print_cr( " - length: %d", arrayOop(obj)->length()); | 
|---|
| 223 | } | 
|---|
| 224 |  | 
|---|
| 225 |  | 
|---|
| 226 | // Verification | 
|---|
| 227 |  | 
|---|
| 228 | void ArrayKlass::verify_on(outputStream* st) { | 
|---|
| 229 | Klass::verify_on(st); | 
|---|
| 230 | } | 
|---|
| 231 |  | 
|---|
| 232 | void ArrayKlass::oop_verify_on(oop obj, outputStream* st) { | 
|---|
| 233 | guarantee(obj->is_array(), "must be array"); | 
|---|
| 234 | arrayOop a = arrayOop(obj); | 
|---|
| 235 | guarantee(a->length() >= 0, "array with negative length?"); | 
|---|
| 236 | } | 
|---|
| 237 |  | 
|---|