2014-08-12 17:29:00 -07:00
|
|
|
/*
|
2019-01-10 15:13:51 -05:00
|
|
|
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
2014-08-12 17:29:00 -07:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-01-10 15:13:51 -05:00
|
|
|
#ifndef SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|
|
|
|
#define SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|
2014-08-12 17:29:00 -07:00
|
|
|
|
2017-11-27 20:21:34 -08:00
|
|
|
#include "oops/klass.hpp"
|
2015-08-18 11:27:23 -07:00
|
|
|
#include "classfile/dictionary.hpp"
|
2017-11-27 20:21:34 -08:00
|
|
|
#include "classfile/systemDictionary.hpp"
|
|
|
|
#include "memory/filemap.hpp"
|
|
|
|
|
|
|
|
|
|
|
|
/*===============================================================================
|
|
|
|
|
|
|
|
Handling of the classes in the AppCDS archive
|
|
|
|
|
|
|
|
To ensure safety and to simplify the implementation, archived classes are
|
2018-11-07 19:40:27 -08:00
|
|
|
"segregated" into 2 types. The following rules describe how they
|
2017-11-27 20:21:34 -08:00
|
|
|
are stored and looked up.
|
|
|
|
|
|
|
|
[1] Category of archived classes
|
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
There are 2 disjoint groups of classes stored in the AppCDS archive:
|
2017-11-27 20:21:34 -08:00
|
|
|
|
|
|
|
BUILTIN: These classes may be defined ONLY by the BOOT/PLATFORM/APP
|
|
|
|
loaders.
|
|
|
|
|
|
|
|
UNREGISTERED: These classes may be defined ONLY by a ClassLoader
|
|
|
|
instance that's not listed above (using fingerprint matching)
|
|
|
|
|
|
|
|
[2] How classes from different categories are specified in the classlist:
|
|
|
|
|
|
|
|
Starting from JDK9, each class in the classlist may be specified with
|
|
|
|
these keywords: "id", "super", "interfaces", "loader" and "source".
|
|
|
|
|
|
|
|
|
|
|
|
BUILTIN Only the "id" keyword may be (optionally) specified. All other
|
|
|
|
keywords are forbidden.
|
|
|
|
|
|
|
|
The named class is looked up from the jimage and from
|
|
|
|
Xbootclasspath/a and CLASSPATH.
|
|
|
|
|
|
|
|
UNREGISTERED: The "id", "super", and "source" keywords must all be
|
|
|
|
specified.
|
|
|
|
|
|
|
|
The "interfaces" keyword must be specified if the class implements
|
|
|
|
one or more local interfaces. The "interfaces" keyword must not be
|
|
|
|
specified if the class does not implement local interfaces.
|
|
|
|
|
|
|
|
The named class is looked up from the location specified in the
|
|
|
|
"source" keyword.
|
|
|
|
|
|
|
|
Example classlist:
|
|
|
|
|
|
|
|
# BUILTIN
|
|
|
|
java/lang/Object id: 0
|
|
|
|
java/lang/Cloneable id: 1
|
|
|
|
java/lang/String
|
|
|
|
|
|
|
|
# UNREGISTERED
|
|
|
|
Bar id: 3 super: 0 interfaces: 1 source: /foo.jar
|
|
|
|
|
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
[3] Identifying the category of archived classes
|
2017-11-27 20:21:34 -08:00
|
|
|
|
|
|
|
BUILTIN: (C->shared_classpath_index() >= 0)
|
2018-11-07 19:40:27 -08:00
|
|
|
UNREGISTERED: (C->shared_classpath_index() == UNREGISTERED_INDEX (-9999))
|
2017-11-27 20:21:34 -08:00
|
|
|
|
|
|
|
[4] Lookup of archived classes at run time:
|
|
|
|
|
|
|
|
(a) BUILTIN loaders:
|
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
search _builtin_dictionary
|
2017-11-27 20:21:34 -08:00
|
|
|
|
|
|
|
(b) UNREGISTERED loaders:
|
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
search _unregistered_dictionary for an entry that matches the
|
|
|
|
(name, clsfile_len, clsfile_crc32).
|
2017-11-27 20:21:34 -08:00
|
|
|
|
|
|
|
===============================================================================*/
|
|
|
|
#define UNREGISTERED_INDEX -9999
|
2015-08-18 11:27:23 -07:00
|
|
|
|
|
|
|
class ClassFileStream;
|
2018-11-07 19:40:27 -08:00
|
|
|
class DumpTimeSharedClassInfo;
|
|
|
|
class DumpTimeSharedClassTable;
|
|
|
|
class RunTimeSharedClassInfo;
|
|
|
|
class RunTimeSharedDictionary;
|
2014-08-12 17:29:00 -07:00
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
class SystemDictionaryShared: public SystemDictionary {
|
2017-11-27 20:21:34 -08:00
|
|
|
public:
|
|
|
|
enum {
|
|
|
|
FROM_FIELD_IS_PROTECTED = 1 << 0,
|
|
|
|
FROM_IS_ARRAY = 1 << 1,
|
|
|
|
FROM_IS_OBJECT = 1 << 2
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
// These _shared_xxxs arrays are used to initialize the java.lang.Package and
|
|
|
|
// java.security.ProtectionDomain objects associated with each shared class.
|
|
|
|
//
|
|
|
|
// See SystemDictionaryShared::init_security_info for more info.
|
|
|
|
static objArrayOop _shared_protection_domains;
|
|
|
|
static objArrayOop _shared_jar_urls;
|
|
|
|
static objArrayOop _shared_jar_manifests;
|
|
|
|
|
|
|
|
static InstanceKlass* load_shared_class_for_builtin_loader(
|
|
|
|
Symbol* class_name,
|
|
|
|
Handle class_loader,
|
|
|
|
TRAPS);
|
|
|
|
static Handle get_package_name(Symbol* class_name, TRAPS);
|
|
|
|
|
|
|
|
|
|
|
|
// Package handling:
|
|
|
|
//
|
|
|
|
// 1. For named modules in the runtime image
|
|
|
|
// BOOT classes: Reuses the existing JVM_GetSystemPackage(s) interfaces
|
|
|
|
// to get packages in named modules for shared classes.
|
|
|
|
// Package for non-shared classes in named module is also
|
|
|
|
// handled using JVM_GetSystemPackage(s).
|
|
|
|
//
|
|
|
|
// APP classes: VM calls ClassLoaders.AppClassLoader::definePackage(String, Module)
|
|
|
|
// to define package for shared app classes from named
|
|
|
|
// modules.
|
|
|
|
//
|
|
|
|
// PLATFORM classes: VM calls ClassLoaders.PlatformClassLoader::definePackage(String, Module)
|
|
|
|
// to define package for shared platform classes from named
|
|
|
|
// modules.
|
|
|
|
//
|
|
|
|
// 2. For unnamed modules
|
|
|
|
// BOOT classes: Reuses the existing JVM_GetSystemPackage(s) interfaces to
|
|
|
|
// get packages for shared boot classes in unnamed modules.
|
|
|
|
//
|
|
|
|
// APP classes: VM calls ClassLoaders.AppClassLoader::defineOrCheckPackage()
|
|
|
|
// with with the manifest and url from archived data.
|
|
|
|
//
|
|
|
|
// PLATFORM classes: No package is defined.
|
|
|
|
//
|
|
|
|
// The following two define_shared_package() functions are used to define
|
|
|
|
// package for shared APP and PLATFORM classes.
|
|
|
|
static void define_shared_package(Symbol* class_name,
|
|
|
|
Handle class_loader,
|
|
|
|
Handle manifest,
|
|
|
|
Handle url,
|
|
|
|
TRAPS);
|
|
|
|
static void define_shared_package(Symbol* class_name,
|
|
|
|
Handle class_loader,
|
|
|
|
ModuleEntry* mod_entry,
|
|
|
|
TRAPS);
|
|
|
|
|
|
|
|
static Handle get_shared_jar_manifest(int shared_path_index, TRAPS);
|
|
|
|
static Handle get_shared_jar_url(int shared_path_index, TRAPS);
|
|
|
|
static Handle get_protection_domain_from_classloader(Handle class_loader,
|
|
|
|
Handle url, TRAPS);
|
|
|
|
static Handle get_shared_protection_domain(Handle class_loader,
|
|
|
|
int shared_path_index,
|
|
|
|
Handle url,
|
|
|
|
TRAPS);
|
|
|
|
static Handle get_shared_protection_domain(Handle class_loader,
|
|
|
|
ModuleEntry* mod, TRAPS);
|
|
|
|
static Handle init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS);
|
|
|
|
|
|
|
|
static void atomic_set_array_index(objArrayOop array, int index, oop o) {
|
|
|
|
// Benign race condition: array.obj_at(index) may already be filled in.
|
|
|
|
// The important thing here is that all threads pick up the same result.
|
|
|
|
// It doesn't matter which racing thread wins, as long as only one
|
|
|
|
// result is used by all threads, and all future queries.
|
|
|
|
array->atomic_compare_exchange_oop(index, o, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static oop shared_protection_domain(int index);
|
|
|
|
static void atomic_set_shared_protection_domain(int index, oop pd) {
|
|
|
|
atomic_set_array_index(_shared_protection_domains, index, pd);
|
|
|
|
}
|
|
|
|
static void allocate_shared_protection_domain_array(int size, TRAPS);
|
|
|
|
static oop shared_jar_url(int index);
|
|
|
|
static void atomic_set_shared_jar_url(int index, oop url) {
|
|
|
|
atomic_set_array_index(_shared_jar_urls, index, url);
|
|
|
|
}
|
|
|
|
static void allocate_shared_jar_url_array(int size, TRAPS);
|
|
|
|
static oop shared_jar_manifest(int index);
|
|
|
|
static void atomic_set_shared_jar_manifest(int index, oop man) {
|
|
|
|
atomic_set_array_index(_shared_jar_manifests, index, man);
|
|
|
|
}
|
|
|
|
static void allocate_shared_jar_manifest_array(int size, TRAPS);
|
|
|
|
static InstanceKlass* acquire_class_for_current_thread(
|
|
|
|
InstanceKlass *ik,
|
|
|
|
Handle class_loader,
|
|
|
|
Handle protection_domain,
|
|
|
|
TRAPS);
|
2018-11-07 19:40:27 -08:00
|
|
|
static DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k);
|
|
|
|
static void write_dictionary(RunTimeSharedDictionary* dictionary, bool is_builtin);
|
|
|
|
static bool is_jfr_event_class(InstanceKlass *k);
|
|
|
|
static void warn_excluded(InstanceKlass* k, const char* reason);
|
|
|
|
|
|
|
|
DEBUG_ONLY(static bool _checked_excluded_classes;)
|
2014-08-12 17:29:00 -07:00
|
|
|
public:
|
2018-11-07 19:40:27 -08:00
|
|
|
static InstanceKlass* find_builtin_class(Symbol* class_name);
|
|
|
|
|
|
|
|
static const RunTimeSharedClassInfo* find_record(RunTimeSharedDictionary* dict, Symbol* name);
|
|
|
|
|
2017-11-27 20:21:34 -08:00
|
|
|
// Called by PLATFORM/APP loader only
|
2017-03-15 10:25:37 -04:00
|
|
|
static InstanceKlass* find_or_load_shared_class(Symbol* class_name,
|
2017-11-27 20:21:34 -08:00
|
|
|
Handle class_loader,
|
|
|
|
TRAPS);
|
|
|
|
|
|
|
|
|
|
|
|
static void allocate_shared_data_arrays(int size, TRAPS);
|
|
|
|
static void oops_do(OopClosure* f);
|
|
|
|
|
|
|
|
// Check if sharing is supported for the class loader.
|
2018-04-18 18:43:04 -04:00
|
|
|
static bool is_sharing_possible(ClassLoaderData* loader_data);
|
2017-11-27 20:21:34 -08:00
|
|
|
static bool is_shared_class_visible_for_classloader(InstanceKlass* ik,
|
|
|
|
Handle class_loader,
|
|
|
|
const char* pkg_string,
|
|
|
|
Symbol* pkg_name,
|
|
|
|
PackageEntry* pkg_entry,
|
|
|
|
ModuleEntry* mod_entry,
|
|
|
|
TRAPS);
|
|
|
|
static PackageEntry* get_package_entry(Symbol* pkg,
|
|
|
|
ClassLoaderData *loader_data) {
|
|
|
|
if (loader_data != NULL) {
|
|
|
|
PackageEntryTable* pkgEntryTable = loader_data->packages();
|
|
|
|
return pkgEntryTable->lookup_only(pkg);
|
|
|
|
}
|
|
|
|
return NULL;
|
8142968: Module System implementation
Initial integration of JEP 200, JEP 260, JEP 261, and JEP 282
Co-authored-by: Alex Buckley <alex.buckley@oracle.com>
Co-authored-by: Jonathan Gibbons <jonathan.gibbons@oracle.com>
Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com>
Co-authored-by: Mandy Chung <mandy.chung@oracle.com>
Co-authored-by: Mark Reinhold <mark.reinhold@oracle.com>
Co-authored-by: Harold Seigel <harold.seigel@oracle.com>
Co-authored-by: Lois Foltan <lois.foltan@oracle.com>
Co-authored-by: Calvin Cheung <calvin.cheung@oracle.com>
Co-authored-by: Christian Tornqvist <christian.tornqvist@oracle.com>
Co-authored-by: Erik Joelsson <erik.joelsson@oracle.com>
Co-authored-by: George Triantafillou <george.triantafillou@oracle.com>
Co-authored-by: Igor Ignatyev <igor.ignatyev@oracle.com>
Co-authored-by: Ioi Lam <ioi.lam@oracle.com>
Co-authored-by: James Laskey <james.laskey@oracle.com>
Co-authored-by: Jean-Francois Denise <jean-francois.denise@oracle.com>
Co-authored-by: Jiangli Zhou <jiangli.zhou@oracle.com>
Co-authored-by: Markus Gronlund <markus.gronlund@oracle.com>
Co-authored-by: Serguei Spitsyn <serguei.spitsyn@oracle.com>
Co-authored-by: Staffan Larsen <staffan.larsen@oracle.com>
Co-authored-by: Sundararajan Athijegannathan <sundararajan.athijegannathan@oracle.com>
Reviewed-by: acorn, ccheung, coleenp, ctornqvi, dholmes, dsimms, gtriantafill, iklam, jiangli, mgronlun, mseledtsov, cjplummer, sspitsyn, stefank, twisti, hseigel, lfoltan, alanb, mchung, dfazunen
2016-03-17 19:04:01 +00:00
|
|
|
}
|
2015-08-18 11:27:23 -07:00
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
static bool add_unregistered_class(InstanceKlass* k, TRAPS);
|
2018-08-07 15:45:07 -07:00
|
|
|
static InstanceKlass* dump_time_resolve_super_or_fail(Symbol* child_name,
|
2015-08-18 11:27:23 -07:00
|
|
|
Symbol* class_name,
|
|
|
|
Handle class_loader,
|
|
|
|
Handle protection_domain,
|
|
|
|
bool is_superclass,
|
2017-11-27 20:21:34 -08:00
|
|
|
TRAPS);
|
2015-08-18 11:27:23 -07:00
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
static void init_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN;
|
|
|
|
static void remove_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN;
|
2017-11-27 20:21:34 -08:00
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
static Dictionary* boot_loader_dictionary() {
|
|
|
|
return ClassLoaderData::the_null_class_loader_data()->dictionary();
|
2017-11-27 20:21:34 -08:00
|
|
|
}
|
2015-08-18 11:27:23 -07:00
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
static void update_shared_entry(InstanceKlass* klass, int id);
|
2018-08-07 15:45:07 -07:00
|
|
|
static void set_shared_class_misc_info(InstanceKlass* k, ClassFileStream* cfs);
|
2017-11-27 20:21:34 -08:00
|
|
|
|
2018-11-07 19:40:27 -08:00
|
|
|
static InstanceKlass* lookup_from_stream(Symbol* class_name,
|
2015-08-18 11:27:23 -07:00
|
|
|
Handle class_loader,
|
|
|
|
Handle protection_domain,
|
2015-12-08 20:04:03 +01:00
|
|
|
const ClassFileStream* st,
|
2017-11-27 20:21:34 -08:00
|
|
|
TRAPS);
|
|
|
|
// "verification_constraints" are a set of checks performed by
|
|
|
|
// VerificationType::is_reference_assignable_from when verifying a shared class during
|
|
|
|
// dump time.
|
|
|
|
//
|
|
|
|
// With AppCDS, it is possible to override archived classes by calling
|
|
|
|
// ClassLoader.defineClass() directly. SystemDictionary::load_shared_class() already
|
|
|
|
// ensures that you cannot load a shared class if its super type(s) are changed. However,
|
|
|
|
// we need an additional check to ensure that the verification_constraints did not change
|
|
|
|
// between dump time and runtime.
|
2018-08-07 15:45:07 -07:00
|
|
|
static bool add_verification_constraint(InstanceKlass* k, Symbol* name,
|
2016-04-06 21:53:44 -07:00
|
|
|
Symbol* from_name, bool from_field_is_protected,
|
2017-11-27 20:21:34 -08:00
|
|
|
bool from_is_array, bool from_is_object) NOT_CDS_RETURN_(false);
|
2017-03-15 10:25:37 -04:00
|
|
|
static void check_verification_constraints(InstanceKlass* klass,
|
2018-11-07 19:40:27 -08:00
|
|
|
TRAPS) NOT_CDS_RETURN;
|
|
|
|
static bool is_builtin(InstanceKlass* k) {
|
|
|
|
return (k->shared_classpath_index() != UNREGISTERED_INDEX);
|
|
|
|
}
|
|
|
|
static bool should_be_excluded(InstanceKlass* k);
|
|
|
|
static void check_excluded_classes();
|
|
|
|
static void validate_before_archiving(InstanceKlass* k);
|
|
|
|
static bool is_excluded_class(InstanceKlass* k);
|
|
|
|
static void dumptime_classes_do(class MetaspaceClosure* it);
|
|
|
|
static void write_to_archive();
|
|
|
|
static void serialize_dictionary_headers(class SerializeClosure* soc);
|
|
|
|
static void print() { return print_on(tty); }
|
|
|
|
static void print_on(outputStream* st) NOT_CDS_RETURN;
|
|
|
|
static void print_table_statistics(outputStream* st) NOT_CDS_RETURN;
|
|
|
|
|
|
|
|
DEBUG_ONLY(static bool checked_excluded_classes() {return _checked_excluded_classes;})
|
2017-08-02 18:06:38 -07:00
|
|
|
};
|
|
|
|
|
2019-01-10 15:13:51 -05:00
|
|
|
#endif // SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|