307 lines
13 KiB
Diff
307 lines
13 KiB
Diff
|
|
From b35f73bec878c712e9fed512361b5fa424dc3fda Mon Sep 17 00:00:00 2001
|
||
|
|
Date: Thu, 21 Sep 2023 15:15:17 +0800
|
||
|
|
Subject: add make-Appcds-jsa-rw-region-deterministic
|
||
|
|
|
||
|
|
---
|
||
|
|
.../share/vm/classfile/classFileParser.hpp | 1 +
|
||
|
|
.../share/vm/classfile/classLoaderData.hpp | 2 +-
|
||
|
|
.../src/share/vm/classfile/defaultMethods.cpp | 6 +++-
|
||
|
|
hotspot/src/share/vm/classfile/dictionary.cpp | 6 +++-
|
||
|
|
hotspot/src/share/vm/classfile/dictionary.hpp | 2 +-
|
||
|
|
.../share/vm/classfile/systemDictionary.cpp | 24 ++++++++++++++--
|
||
|
|
.../share/vm/classfile/systemDictionary.hpp | 2 +-
|
||
|
|
.../src/share/vm/memory/metaspaceShared.cpp | 28 +++++++++++--------
|
||
|
|
hotspot/src/share/vm/runtime/mutex.cpp | 2 +-
|
||
|
|
hotspot/src/share/vm/runtime/os.cpp | 5 +++-
|
||
|
|
hotspot/src/share/vm/runtime/os.hpp | 2 +-
|
||
|
|
hotspot/src/share/vm/runtime/synchronizer.cpp | 2 +-
|
||
|
|
12 files changed, 59 insertions(+), 23 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
|
||
|
|
index 1900f0abf..dda7c92d9 100644
|
||
|
|
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
|
||
|
|
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
|
||
|
|
@@ -42,6 +42,7 @@ class FieldLayoutInfo;
|
||
|
|
// The bytes describing the class file structure is read from a Stream object
|
||
|
|
|
||
|
|
class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||
|
|
+ friend class SystemDictionary;
|
||
|
|
private:
|
||
|
|
bool _need_verify;
|
||
|
|
bool _relax_verify;
|
||
|
|
diff --git a/hotspot/src/share/vm/classfile/classLoaderData.hpp b/hotspot/src/share/vm/classfile/classLoaderData.hpp
|
||
|
|
index 7155257ed..0bb2e1000 100644
|
||
|
|
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp
|
||
|
|
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp
|
||
|
|
@@ -211,7 +211,6 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||
|
|
JFR_ONLY(DEFINE_TRACE_ID_FIELD;)
|
||
|
|
|
||
|
|
void set_next(ClassLoaderData* next) { _next = next; }
|
||
|
|
- ClassLoaderData* next() const { return _next; }
|
||
|
|
|
||
|
|
ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies);
|
||
|
|
~ClassLoaderData();
|
||
|
|
@@ -238,6 +237,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||
|
|
void clear_claimed() { _claimed = 0; }
|
||
|
|
bool claimed() const { return _claimed == 1; }
|
||
|
|
bool claim();
|
||
|
|
+ ClassLoaderData* next() const { return _next; }
|
||
|
|
|
||
|
|
bool is_alive(BoolObjectClosure* is_alive_closure) const;
|
||
|
|
|
||
|
|
diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp
|
||
|
|
index 196622aed..0becb35ed 100644
|
||
|
|
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp
|
||
|
|
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp
|
||
|
|
@@ -909,7 +909,11 @@ static void switchover_constant_pool(BytecodeConstantPool* bpool,
|
||
|
|
if (new_methods->length() > 0) {
|
||
|
|
ConstantPool* cp = bpool->create_constant_pool(CHECK);
|
||
|
|
if (cp != klass->constants()) {
|
||
|
|
- klass->class_loader_data()->add_to_deallocate_list(klass->constants());
|
||
|
|
+ ClassLoaderData* loader_data = klass->class_loader_data();
|
||
|
|
+ while (DumpSharedSpaces && loader_data->next() != NULL) {
|
||
|
|
+ loader_data = loader_data->next();
|
||
|
|
+ }
|
||
|
|
+ loader_data->add_to_deallocate_list(klass->constants());
|
||
|
|
klass->set_constants(cp);
|
||
|
|
cp->set_pool_holder(klass);
|
||
|
|
|
||
|
|
diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp
|
||
|
|
index d41372ecc..530c3fdfb 100644
|
||
|
|
--- a/hotspot/src/share/vm/classfile/dictionary.cpp
|
||
|
|
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp
|
||
|
|
@@ -196,7 +196,7 @@ void Dictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {
|
||
|
|
_pd_cache_table->roots_oops_do(strong, weak);
|
||
|
|
}
|
||
|
|
|
||
|
|
-void Dictionary::remove_classes_in_error_state() {
|
||
|
|
+void Dictionary::remove_classes_in_error_state(void f(Klass*)) {
|
||
|
|
assert(DynamicDumpSharedSpaces || DumpSharedSpaces, "supported only when dumping");
|
||
|
|
DictionaryEntry* probe = NULL;
|
||
|
|
for (int index = 0; index < table_size(); index++) {
|
||
|
|
@@ -209,6 +209,7 @@ void Dictionary::remove_classes_in_error_state() {
|
||
|
|
_current_class_entry = NULL;
|
||
|
|
}
|
||
|
|
free_entry(probe);
|
||
|
|
+ f(ik);
|
||
|
|
ResourceMark rm;
|
||
|
|
tty->print_cr("Preload Warning: Removed error class: %s", ik->external_name());
|
||
|
|
continue;
|
||
|
|
@@ -420,6 +421,9 @@ void Dictionary::add_protection_domain(int index, unsigned int hash,
|
||
|
|
instanceKlassHandle klass,
|
||
|
|
ClassLoaderData* loader_data, Handle protection_domain,
|
||
|
|
TRAPS) {
|
||
|
|
+ if (DumpSharedSpaces) {
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
Symbol* klass_name = klass->name();
|
||
|
|
DictionaryEntry* entry = get_entry(index, hash, klass_name, loader_data);
|
||
|
|
|
||
|
|
diff --git a/hotspot/src/share/vm/classfile/dictionary.hpp b/hotspot/src/share/vm/classfile/dictionary.hpp
|
||
|
|
index 9ed0defb8..8a88fa2e4 100644
|
||
|
|
--- a/hotspot/src/share/vm/classfile/dictionary.hpp
|
||
|
|
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp
|
||
|
|
@@ -103,7 +103,7 @@ public:
|
||
|
|
void methods_do(void f(Method*));
|
||
|
|
|
||
|
|
void unlink(BoolObjectClosure* is_alive);
|
||
|
|
- void remove_classes_in_error_state();
|
||
|
|
+ void remove_classes_in_error_state(void f(Klass*));
|
||
|
|
|
||
|
|
// Classes loaded by the bootstrap loader are always strongly reachable.
|
||
|
|
// If we're not doing class unloading, all classes are strongly reachable.
|
||
|
|
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp
|
||
|
|
index 9089a762d..c8f66e830 100644
|
||
|
|
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp
|
||
|
|
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp
|
||
|
|
@@ -1170,6 +1170,26 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
|
||
|
|
parsed_name,
|
||
|
|
verify,
|
||
|
|
THREAD);
|
||
|
|
+ if (DumpSharedSpaces && k.is_null()) {
|
||
|
|
+ if (loader_data) {
|
||
|
|
+ ClassLoaderData* cld = loader_data;
|
||
|
|
+ while (cld->next() != NULL)
|
||
|
|
+ cld = cld->next();
|
||
|
|
+ ConstantPool* cp = parser._cp;
|
||
|
|
+ if (cp) {
|
||
|
|
+ cld->add_to_deallocate_list(cp);
|
||
|
|
+ }
|
||
|
|
+ Array<Method*>* m = parser._methods;
|
||
|
|
+ if (m) {
|
||
|
|
+ for (int i = 0; i < m->length(); i++) {
|
||
|
|
+ Method* method = m->at(i);
|
||
|
|
+ if (method != NULL) {
|
||
|
|
+ cld->add_to_deallocate_list(method);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
const char* pkg = "java/";
|
||
|
|
size_t pkglen = strlen(pkg);
|
||
|
|
if (!HAS_PENDING_EXCEPTION &&
|
||
|
|
@@ -2036,8 +2056,8 @@ void SystemDictionary::methods_do(void f(Method*)) {
|
||
|
|
invoke_method_table()->methods_do(f);
|
||
|
|
}
|
||
|
|
|
||
|
|
-void SystemDictionary::remove_classes_in_error_state() {
|
||
|
|
- dictionary()->remove_classes_in_error_state();
|
||
|
|
+void SystemDictionary::remove_classes_in_error_state(void f(Klass*)) {
|
||
|
|
+ dictionary()->remove_classes_in_error_state(f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ----------------------------------------------------------------------------
|
||
|
|
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp
|
||
|
|
index cfc15c20e..e39c1de62 100644
|
||
|
|
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp
|
||
|
|
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp
|
||
|
|
@@ -347,7 +347,7 @@ public:
|
||
|
|
static bool do_unloading(BoolObjectClosure* is_alive, bool clean_alive = true);
|
||
|
|
|
||
|
|
// Used by DumpSharedSpaces only to remove classes that failed verification
|
||
|
|
- static void remove_classes_in_error_state();
|
||
|
|
+ static void remove_classes_in_error_state(void f(Klass*));
|
||
|
|
|
||
|
|
static int calculate_systemdictionary_size(int loadedclasses);
|
||
|
|
|
||
|
|
diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp
|
||
|
|
index b31d0a3fb..e6bd39d85 100644
|
||
|
|
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp
|
||
|
|
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp
|
||
|
|
@@ -216,6 +216,10 @@ static void patch_deallocate_meta_vtables(void** vtbl_list, void* new_vtable_sta
|
||
|
|
((ConstantPool*)m)->remove_unshareable_info();
|
||
|
|
*(void**)m = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, m);
|
||
|
|
}
|
||
|
|
+ else if (m->is_method()) {
|
||
|
|
+ ((Method*)m)->remove_unshareable_info();
|
||
|
|
+ *(void**)m = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, m);
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
@@ -442,6 +446,7 @@ public:
|
||
|
|
_md_vs.initialize(md_rs, SharedMiscDataSize);
|
||
|
|
_mc_vs.initialize(mc_rs, SharedMiscCodeSize);
|
||
|
|
_class_promote_order = class_promote_order;
|
||
|
|
+ _global_klass_objects = new GrowableArray<Klass*>(1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
|
||
|
|
@@ -465,13 +470,6 @@ void VM_PopulateDumpSharedSpace::doit() {
|
||
|
|
SystemDictionary::invoke_method_table()->number_of_entries() == 0,
|
||
|
|
"invoke method table is not saved");
|
||
|
|
|
||
|
|
- // At this point, many classes have been loaded.
|
||
|
|
- // Gather systemDictionary classes in a global array and do everything to
|
||
|
|
- // that so we don't have to walk the SystemDictionary again.
|
||
|
|
- _global_klass_objects = new GrowableArray<Klass*>(1000);
|
||
|
|
- Universe::basic_type_classes_do(collect_classes);
|
||
|
|
- SystemDictionary::classes_do(collect_classes);
|
||
|
|
-
|
||
|
|
tty->print_cr("Number of classes %d", _global_klass_objects->length());
|
||
|
|
{
|
||
|
|
int num_type_array = 0, num_obj_array = 0, num_inst = 0;
|
||
|
|
@@ -702,7 +700,7 @@ void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) {
|
||
|
|
|
||
|
|
// record error message, remove error state, and continue to dump jsa file
|
||
|
|
tty->print_cr("Please remove the unverifiable classes from your class list and try again");
|
||
|
|
- SystemDictionary::remove_classes_in_error_state();
|
||
|
|
+ SystemDictionary::remove_classes_in_error_state(collect_classes);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy the dependencies from C_HEAP-alloced GrowableArrays to RO-alloced
|
||
|
|
@@ -785,6 +783,9 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
|
||
|
|
// Rewrite and link classes
|
||
|
|
tty->print_cr("Rewriting and linking classes ...");
|
||
|
|
|
||
|
|
+ // Create here because link_and_cleanup_shared_classes need the _global_klass_objects
|
||
|
|
+ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
||
|
|
+ VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
|
||
|
|
// Link any classes which got missed. This would happen if we have loaded classes that
|
||
|
|
// were not explicitly specified in the classlist. E.g., if an interface implemented by class K
|
||
|
|
// fails verification, all other interfaces that were not specified in the classlist but
|
||
|
|
@@ -792,10 +793,13 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
|
||
|
|
link_and_cleanup_shared_classes(CATCH);
|
||
|
|
tty->print_cr("Rewriting and linking classes: done");
|
||
|
|
|
||
|
|
- // Create and dump the shared spaces. Everything so far is loaded
|
||
|
|
- // with the null class loader.
|
||
|
|
- ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
||
|
|
- VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
|
||
|
|
+ // At this point, many classes have been loaded.
|
||
|
|
+ // Gather systemDictionary classes in a global array and do everything to
|
||
|
|
+ // that so we don't have to walk the SystemDictionary again.
|
||
|
|
+ Universe::basic_type_classes_do(collect_classes);
|
||
|
|
+ SystemDictionary::classes_do(collect_classes);
|
||
|
|
+
|
||
|
|
+ // Dump the shared spaces.
|
||
|
|
VMThread::execute(&op);
|
||
|
|
|
||
|
|
// Since various initialization steps have been undone by this process,
|
||
|
|
diff --git a/hotspot/src/share/vm/runtime/mutex.cpp b/hotspot/src/share/vm/runtime/mutex.cpp
|
||
|
|
index 92bd50662..b1159d02e 100644
|
||
|
|
--- a/hotspot/src/share/vm/runtime/mutex.cpp
|
||
|
|
+++ b/hotspot/src/share/vm/runtime/mutex.cpp
|
||
|
|
@@ -276,7 +276,7 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||
|
|
// Useful for spin loops as the compiler can't optimize it away.
|
||
|
|
|
||
|
|
static inline jint MarsagliaXORV (jint x) {
|
||
|
|
- if (x == 0) x = 1|os::random() ;
|
||
|
|
+ if (x == 0) x = 1|os::random(DumpSharedSpaces) ;
|
||
|
|
x ^= x << 6;
|
||
|
|
x ^= ((unsigned)x) >> 21;
|
||
|
|
x ^= x << 7 ;
|
||
|
|
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
|
||
|
|
index 43d66e85e..ff35e8b3a 100644
|
||
|
|
--- a/hotspot/src/share/vm/runtime/os.cpp
|
||
|
|
+++ b/hotspot/src/share/vm/runtime/os.cpp
|
||
|
|
@@ -770,7 +770,7 @@ void os::init_random(long initval) {
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
-long os::random() {
|
||
|
|
+long os::random(bool skip) {
|
||
|
|
/* standard, well-known linear congruential random generator with
|
||
|
|
* next_rand = (16807*seed) mod (2**31-1)
|
||
|
|
* see
|
||
|
|
@@ -801,6 +801,9 @@ long os::random() {
|
||
|
|
lo &= m;
|
||
|
|
++lo;
|
||
|
|
}
|
||
|
|
+ if (skip) {
|
||
|
|
+ return lo;
|
||
|
|
+ }
|
||
|
|
return (_rand_seed = lo);
|
||
|
|
}
|
||
|
|
|
||
|
|
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
|
||
|
|
index 988977b17..07beeed8c 100644
|
||
|
|
--- a/hotspot/src/share/vm/runtime/os.hpp
|
||
|
|
+++ b/hotspot/src/share/vm/runtime/os.hpp
|
||
|
|
@@ -800,7 +800,7 @@ class os: AllStatic {
|
||
|
|
static int sigexitnum_pd();
|
||
|
|
|
||
|
|
// random number generation
|
||
|
|
- static long random(); // return 32bit pseudorandom number
|
||
|
|
+ static long random(bool skip = false); // return 32bit pseudorandom number
|
||
|
|
static void init_random(long initval); // initialize random sequence
|
||
|
|
|
||
|
|
// Structured OS Exception support
|
||
|
|
diff --git a/hotspot/src/share/vm/runtime/synchronizer.cpp b/hotspot/src/share/vm/runtime/synchronizer.cpp
|
||
|
|
index 8400bff11..e83ecd1d2 100644
|
||
|
|
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp
|
||
|
|
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp
|
||
|
|
@@ -1657,7 +1657,7 @@ void ObjectSynchronizer::deflate_idle_monitors() {
|
||
|
|
|
||
|
|
// TODO: Add objectMonitor leak detection.
|
||
|
|
// Audit/inventory the objectMonitors -- make sure they're all accounted for.
|
||
|
|
- GVars.stwRandom = os::random() ;
|
||
|
|
+ GVars.stwRandom = os::random(DumpSharedSpaces) ;
|
||
|
|
GVars.stwCycle ++ ;
|
||
|
|
}
|
||
|
|
|
||
|
|
--
|
||
|
|
2.22.0
|
||
|
|
|