8212200: assert when shared java.lang.Object is redefined by JVMTI agent

Reviewed-by: dholmes, jiangli, hseigel, lfoltan, sspitsyn
This commit is contained in:
Ioi Lam 2018-10-17 15:57:10 -07:00
parent 02966a7b67
commit 93395f6a9e
11 changed files with 375 additions and 43 deletions

View file

@ -67,7 +67,7 @@
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayKlass.hpp"
#include "prims/jvmtiEnvBase.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/resolvedMethodTable.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/arguments.hpp"
@ -1489,8 +1489,7 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle
!search_only_bootloader_append,
"Attempt to load a class outside of boot loader's module path");
// Search the shared system dictionary for classes preloaded into the
// shared spaces.
// Search for classes in the CDS archive.
InstanceKlass* k = NULL;
{
#if INCLUDE_CDS
@ -1958,7 +1957,7 @@ void SystemDictionary::initialize(TRAPS) {
// Allocate private object used as system class loader lock
_system_loader_lock_obj = oopFactory::new_intArray(0, CHECK);
// Initialize basic classes
resolve_preloaded_classes(CHECK);
resolve_well_known_classes(CHECK);
}
// Compact table of directions on the initialization of klasses:
@ -1971,6 +1970,19 @@ static const short wk_init_info[] = {
0
};
#ifdef ASSERT
bool SystemDictionary::is_well_known_klass(Symbol* class_name) {
int sid;
for (int i = 0; (sid = wk_init_info[i]) != 0; i++) {
Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
if (class_name == symbol) {
return true;
}
}
return false;
}
#endif
bool SystemDictionary::resolve_wk_klass(WKID id, TRAPS) {
assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
int sid = wk_init_info[id - FIRST_WKID];
@ -2002,8 +2014,8 @@ void SystemDictionary::resolve_wk_klasses_until(WKID limit_id, WKID &start_id, T
start_id = limit_id;
}
void SystemDictionary::resolve_preloaded_classes(TRAPS) {
assert(WK_KLASS(Object_klass) == NULL, "preloaded classes should only be initialized once");
void SystemDictionary::resolve_well_known_classes(TRAPS) {
assert(WK_KLASS(Object_klass) == NULL, "well-known classes should only be initialized once");
// Create the ModuleEntry for java.base. This call needs to be done here,
// after vmSymbols::initialize() is called but before any classes are pre-loaded.
@ -2071,7 +2083,8 @@ void SystemDictionary::resolve_preloaded_classes(TRAPS) {
WKID jsr292_group_end = WK_KLASS_ENUM_NAME(VolatileCallSite_klass);
resolve_wk_klasses_until(jsr292_group_start, scan, CHECK);
resolve_wk_klasses_through(jsr292_group_end, scan, CHECK);
resolve_wk_klasses_until(NOT_JVMCI(WKID_LIMIT) JVMCI_ONLY(FIRST_JVMCI_WKID), scan, CHECK);
WKID last = NOT_JVMCI(WKID_LIMIT) JVMCI_ONLY(FIRST_JVMCI_WKID);
resolve_wk_klasses_until(last, scan, CHECK);
_box_klasses[T_BOOLEAN] = WK_KLASS(Boolean_klass);
_box_klasses[T_CHAR] = WK_KLASS(Character_klass);
@ -2088,6 +2101,17 @@ void SystemDictionary::resolve_preloaded_classes(TRAPS) {
Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature());
_has_checkPackageAccess = (method != NULL);
}
#ifdef ASSERT
if (UseSharedSpaces) {
assert(JvmtiExport::is_early_phase(),
"All well known classes must be resolved in JVMTI early phase");
for (int i = FIRST_WKID; i < last; i++) {
InstanceKlass* k = _well_known_klasses[i];
assert(k->is_shared(), "must not be replaced by JVMTI class file load hook");
}
}
#endif
}
// Tells if a given klass is a box (wrapper class, such as java.lang.Integer).