| 1 | /* |
| 2 | * Copyright (c) 2014, 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 | #ifndef SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP |
| 26 | #define SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP |
| 27 | |
| 28 | #include "oops/klass.hpp" |
| 29 | #include "classfile/dictionary.hpp" |
| 30 | #include "classfile/packageEntry.hpp" |
| 31 | #include "classfile/systemDictionary.hpp" |
| 32 | #include "memory/filemap.hpp" |
| 33 | |
| 34 | |
| 35 | /*=============================================================================== |
| 36 | |
| 37 | Handling of the classes in the AppCDS archive |
| 38 | |
| 39 | To ensure safety and to simplify the implementation, archived classes are |
| 40 | "segregated" into 2 types. The following rules describe how they |
| 41 | are stored and looked up. |
| 42 | |
| 43 | [1] Category of archived classes |
| 44 | |
| 45 | There are 2 disjoint groups of classes stored in the AppCDS archive: |
| 46 | |
| 47 | BUILTIN: These classes may be defined ONLY by the BOOT/PLATFORM/APP |
| 48 | loaders. |
| 49 | |
| 50 | UNREGISTERED: These classes may be defined ONLY by a ClassLoader |
| 51 | instance that's not listed above (using fingerprint matching) |
| 52 | |
| 53 | [2] How classes from different categories are specified in the classlist: |
| 54 | |
| 55 | Starting from JDK9, each class in the classlist may be specified with |
| 56 | these keywords: "id", "super", "interfaces", "loader" and "source". |
| 57 | |
| 58 | |
| 59 | BUILTIN Only the "id" keyword may be (optionally) specified. All other |
| 60 | keywords are forbidden. |
| 61 | |
| 62 | The named class is looked up from the jimage and from |
| 63 | Xbootclasspath/a and CLASSPATH. |
| 64 | |
| 65 | UNREGISTERED: The "id", "super", and "source" keywords must all be |
| 66 | specified. |
| 67 | |
| 68 | The "interfaces" keyword must be specified if the class implements |
| 69 | one or more local interfaces. The "interfaces" keyword must not be |
| 70 | specified if the class does not implement local interfaces. |
| 71 | |
| 72 | The named class is looked up from the location specified in the |
| 73 | "source" keyword. |
| 74 | |
| 75 | Example classlist: |
| 76 | |
| 77 | # BUILTIN |
| 78 | java/lang/Object id: 0 |
| 79 | java/lang/Cloneable id: 1 |
| 80 | java/lang/String |
| 81 | |
| 82 | # UNREGISTERED |
| 83 | Bar id: 3 super: 0 interfaces: 1 source: /foo.jar |
| 84 | |
| 85 | |
| 86 | [3] Identifying the category of archived classes |
| 87 | |
| 88 | BUILTIN: (C->shared_classpath_index() >= 0) |
| 89 | UNREGISTERED: (C->shared_classpath_index() == UNREGISTERED_INDEX (-9999)) |
| 90 | |
| 91 | [4] Lookup of archived classes at run time: |
| 92 | |
| 93 | (a) BUILTIN loaders: |
| 94 | |
| 95 | search _builtin_dictionary |
| 96 | |
| 97 | (b) UNREGISTERED loaders: |
| 98 | |
| 99 | search _unregistered_dictionary for an entry that matches the |
| 100 | (name, clsfile_len, clsfile_crc32). |
| 101 | |
| 102 | ===============================================================================*/ |
| 103 | #define UNREGISTERED_INDEX -9999 |
| 104 | |
| 105 | class ClassFileStream; |
| 106 | class DumpTimeSharedClassInfo; |
| 107 | class DumpTimeSharedClassTable; |
| 108 | class RunTimeSharedClassInfo; |
| 109 | class RunTimeSharedDictionary; |
| 110 | |
| 111 | class SystemDictionaryShared: public SystemDictionary { |
| 112 | friend class ExcludeDumpTimeSharedClasses; |
| 113 | public: |
| 114 | enum { |
| 115 | FROM_FIELD_IS_PROTECTED = 1 << 0, |
| 116 | FROM_IS_ARRAY = 1 << 1, |
| 117 | FROM_IS_OBJECT = 1 << 2 |
| 118 | }; |
| 119 | |
| 120 | private: |
| 121 | // These _shared_xxxs arrays are used to initialize the java.lang.Package and |
| 122 | // java.security.ProtectionDomain objects associated with each shared class. |
| 123 | // |
| 124 | // See SystemDictionaryShared::init_security_info for more info. |
| 125 | static objArrayOop _shared_protection_domains; |
| 126 | static objArrayOop _shared_jar_urls; |
| 127 | static objArrayOop _shared_jar_manifests; |
| 128 | |
| 129 | static InstanceKlass* load_shared_class_for_builtin_loader( |
| 130 | Symbol* class_name, |
| 131 | Handle class_loader, |
| 132 | TRAPS); |
| 133 | static Handle get_package_name(Symbol* class_name, TRAPS); |
| 134 | |
| 135 | |
| 136 | // Package handling: |
| 137 | // |
| 138 | // 1. For named modules in the runtime image |
| 139 | // BOOT classes: Reuses the existing JVM_GetSystemPackage(s) interfaces |
| 140 | // to get packages in named modules for shared classes. |
| 141 | // Package for non-shared classes in named module is also |
| 142 | // handled using JVM_GetSystemPackage(s). |
| 143 | // |
| 144 | // APP classes: VM calls ClassLoaders.AppClassLoader::definePackage(String, Module) |
| 145 | // to define package for shared app classes from named |
| 146 | // modules. |
| 147 | // |
| 148 | // PLATFORM classes: VM calls ClassLoaders.PlatformClassLoader::definePackage(String, Module) |
| 149 | // to define package for shared platform classes from named |
| 150 | // modules. |
| 151 | // |
| 152 | // 2. For unnamed modules |
| 153 | // BOOT classes: Reuses the existing JVM_GetSystemPackage(s) interfaces to |
| 154 | // get packages for shared boot classes in unnamed modules. |
| 155 | // |
| 156 | // APP classes: VM calls ClassLoaders.AppClassLoader::defineOrCheckPackage() |
| 157 | // with with the manifest and url from archived data. |
| 158 | // |
| 159 | // PLATFORM classes: No package is defined. |
| 160 | // |
| 161 | // The following two define_shared_package() functions are used to define |
| 162 | // package for shared APP and PLATFORM classes. |
| 163 | static void define_shared_package(Symbol* class_name, |
| 164 | Handle class_loader, |
| 165 | Handle manifest, |
| 166 | Handle url, |
| 167 | TRAPS); |
| 168 | static void define_shared_package(Symbol* class_name, |
| 169 | Handle class_loader, |
| 170 | ModuleEntry* mod_entry, |
| 171 | TRAPS); |
| 172 | |
| 173 | static Handle get_shared_jar_manifest(int shared_path_index, TRAPS); |
| 174 | static Handle get_shared_jar_url(int shared_path_index, TRAPS); |
| 175 | static Handle get_protection_domain_from_classloader(Handle class_loader, |
| 176 | Handle url, TRAPS); |
| 177 | static Handle get_shared_protection_domain(Handle class_loader, |
| 178 | int shared_path_index, |
| 179 | Handle url, |
| 180 | TRAPS); |
| 181 | static Handle get_shared_protection_domain(Handle class_loader, |
| 182 | ModuleEntry* mod, TRAPS); |
| 183 | static Handle init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS); |
| 184 | |
| 185 | static void atomic_set_array_index(objArrayOop array, int index, oop o) { |
| 186 | // Benign race condition: array.obj_at(index) may already be filled in. |
| 187 | // The important thing here is that all threads pick up the same result. |
| 188 | // It doesn't matter which racing thread wins, as long as only one |
| 189 | // result is used by all threads, and all future queries. |
| 190 | array->atomic_compare_exchange_oop(index, o, NULL); |
| 191 | } |
| 192 | |
| 193 | static oop shared_protection_domain(int index); |
| 194 | static void atomic_set_shared_protection_domain(int index, oop pd) { |
| 195 | atomic_set_array_index(_shared_protection_domains, index, pd); |
| 196 | } |
| 197 | static void allocate_shared_protection_domain_array(int size, TRAPS); |
| 198 | static oop shared_jar_url(int index); |
| 199 | static void atomic_set_shared_jar_url(int index, oop url) { |
| 200 | atomic_set_array_index(_shared_jar_urls, index, url); |
| 201 | } |
| 202 | static void allocate_shared_jar_url_array(int size, TRAPS); |
| 203 | static oop shared_jar_manifest(int index); |
| 204 | static void atomic_set_shared_jar_manifest(int index, oop man) { |
| 205 | atomic_set_array_index(_shared_jar_manifests, index, man); |
| 206 | } |
| 207 | static void allocate_shared_jar_manifest_array(int size, TRAPS); |
| 208 | static InstanceKlass* acquire_class_for_current_thread( |
| 209 | InstanceKlass *ik, |
| 210 | Handle class_loader, |
| 211 | Handle protection_domain, |
| 212 | const ClassFileStream* cfs, |
| 213 | TRAPS); |
| 214 | static DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k); |
| 215 | static void write_dictionary(RunTimeSharedDictionary* dictionary, |
| 216 | bool is_builtin, |
| 217 | bool is_static_archive = true); |
| 218 | static bool is_jfr_event_class(InstanceKlass *k); |
| 219 | static void warn_excluded(InstanceKlass* k, const char* reason); |
| 220 | static bool should_be_excluded(InstanceKlass* k); |
| 221 | |
| 222 | DEBUG_ONLY(static bool _no_class_loading_should_happen;) |
| 223 | public: |
| 224 | static InstanceKlass* find_builtin_class(Symbol* class_name); |
| 225 | |
| 226 | static const RunTimeSharedClassInfo* find_record(RunTimeSharedDictionary* dict, Symbol* name); |
| 227 | |
| 228 | static bool has_platform_or_app_classes(); |
| 229 | |
| 230 | // Called by PLATFORM/APP loader only |
| 231 | static InstanceKlass* find_or_load_shared_class(Symbol* class_name, |
| 232 | Handle class_loader, |
| 233 | TRAPS); |
| 234 | |
| 235 | |
| 236 | static void allocate_shared_data_arrays(int size, TRAPS); |
| 237 | static void oops_do(OopClosure* f); |
| 238 | |
| 239 | // Check if sharing is supported for the class loader. |
| 240 | static bool is_sharing_possible(ClassLoaderData* loader_data); |
| 241 | static bool is_shared_class_visible_for_classloader(InstanceKlass* ik, |
| 242 | Handle class_loader, |
| 243 | const char* pkg_string, |
| 244 | Symbol* pkg_name, |
| 245 | PackageEntry* pkg_entry, |
| 246 | ModuleEntry* mod_entry, |
| 247 | TRAPS); |
| 248 | static PackageEntry* get_package_entry(Symbol* pkg, |
| 249 | ClassLoaderData *loader_data) { |
| 250 | if (loader_data != NULL) { |
| 251 | PackageEntryTable* pkgEntryTable = loader_data->packages(); |
| 252 | return pkgEntryTable->lookup_only(pkg); |
| 253 | } |
| 254 | return NULL; |
| 255 | } |
| 256 | |
| 257 | static bool add_unregistered_class(InstanceKlass* k, TRAPS); |
| 258 | static InstanceKlass* dump_time_resolve_super_or_fail(Symbol* child_name, |
| 259 | Symbol* class_name, |
| 260 | Handle class_loader, |
| 261 | Handle protection_domain, |
| 262 | bool is_superclass, |
| 263 | TRAPS); |
| 264 | |
| 265 | static void init_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN; |
| 266 | static void remove_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN; |
| 267 | |
| 268 | static Dictionary* boot_loader_dictionary() { |
| 269 | return ClassLoaderData::the_null_class_loader_data()->dictionary(); |
| 270 | } |
| 271 | |
| 272 | static void update_shared_entry(InstanceKlass* klass, int id); |
| 273 | static void set_shared_class_misc_info(InstanceKlass* k, ClassFileStream* cfs); |
| 274 | |
| 275 | static InstanceKlass* lookup_from_stream(Symbol* class_name, |
| 276 | Handle class_loader, |
| 277 | Handle protection_domain, |
| 278 | const ClassFileStream* st, |
| 279 | TRAPS); |
| 280 | // "verification_constraints" are a set of checks performed by |
| 281 | // VerificationType::is_reference_assignable_from when verifying a shared class during |
| 282 | // dump time. |
| 283 | // |
| 284 | // With AppCDS, it is possible to override archived classes by calling |
| 285 | // ClassLoader.defineClass() directly. SystemDictionary::load_shared_class() already |
| 286 | // ensures that you cannot load a shared class if its super type(s) are changed. However, |
| 287 | // we need an additional check to ensure that the verification_constraints did not change |
| 288 | // between dump time and runtime. |
| 289 | static bool add_verification_constraint(InstanceKlass* k, Symbol* name, |
| 290 | Symbol* from_name, bool from_field_is_protected, |
| 291 | bool from_is_array, bool from_is_object) NOT_CDS_RETURN_(false); |
| 292 | static void check_verification_constraints(InstanceKlass* klass, |
| 293 | TRAPS) NOT_CDS_RETURN; |
| 294 | static bool is_builtin(InstanceKlass* k) { |
| 295 | return (k->shared_classpath_index() != UNREGISTERED_INDEX); |
| 296 | } |
| 297 | static void check_excluded_classes(); |
| 298 | static void validate_before_archiving(InstanceKlass* k); |
| 299 | static bool is_excluded_class(InstanceKlass* k); |
| 300 | static void dumptime_classes_do(class MetaspaceClosure* it); |
| 301 | static size_t estimate_size_for_archive(); |
| 302 | static void write_to_archive(bool is_static_archive = true); |
| 303 | static void (class SerializeClosure* soc, |
| 304 | bool is_static_archive = true); |
| 305 | static void print() { return print_on(tty); } |
| 306 | static void print_on(outputStream* st) NOT_CDS_RETURN; |
| 307 | static void print_table_statistics(outputStream* st) NOT_CDS_RETURN; |
| 308 | static bool empty_dumptime_table() NOT_CDS_RETURN_(true); |
| 309 | |
| 310 | DEBUG_ONLY(static bool no_class_loading_should_happen() {return _no_class_loading_should_happen;}) |
| 311 | |
| 312 | #ifdef ASSERT |
| 313 | class NoClassLoadingMark: public StackObj { |
| 314 | public: |
| 315 | NoClassLoadingMark() { |
| 316 | assert(!_no_class_loading_should_happen, "must not be nested" ); |
| 317 | _no_class_loading_should_happen = true; |
| 318 | } |
| 319 | ~NoClassLoadingMark() { |
| 320 | _no_class_loading_should_happen = false; |
| 321 | } |
| 322 | }; |
| 323 | #endif |
| 324 | |
| 325 | }; |
| 326 | |
| 327 | #endif // SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP |
| 328 | |