mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
212 lines
8.8 KiB
Diff
212 lines
8.8 KiB
Diff
From 4f88dcec830d39452f69d1117729469fdb768a8f Mon Sep 17 00:00:00 2001
|
|
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
|
Date: Sun, 22 Nov 2020 12:05:26 +0100
|
|
Subject: [PATCH 22/34] dcevm15 - fix ResolvedMethodTable
|
|
|
|
---
|
|
src/hotspot/share/classfile/javaClasses.cpp | 5 -
|
|
src/hotspot/share/classfile/javaClasses.hpp | 1 -
|
|
.../share/prims/resolvedMethodTable.cpp | 139 +++++++++++-------
|
|
3 files changed, 84 insertions(+), 61 deletions(-)
|
|
|
|
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
|
|
index 9b086a241f7..9a627786d0f 100644
|
|
--- a/src/hotspot/share/classfile/javaClasses.cpp
|
|
+++ b/src/hotspot/share/classfile/javaClasses.cpp
|
|
@@ -3996,11 +3996,6 @@ void java_lang_invoke_ResolvedMethodName::set_vmholder(oop resolved_method, oop
|
|
resolved_method->obj_field_put(_vmholder_offset, holder);
|
|
}
|
|
|
|
-void java_lang_invoke_ResolvedMethodName::set_vmholder_offset(oop resolved_method, Method* m) {
|
|
- assert(is_instance(resolved_method), "wrong type");
|
|
- resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror());
|
|
-}
|
|
-
|
|
oop java_lang_invoke_ResolvedMethodName::find_resolved_method(const methodHandle& m, TRAPS) {
|
|
const Method* method = m();
|
|
|
|
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
|
|
index 9abf2e1d105..8f5993b7225 100644
|
|
--- a/src/hotspot/share/classfile/javaClasses.hpp
|
|
+++ b/src/hotspot/share/classfile/javaClasses.hpp
|
|
@@ -1107,7 +1107,6 @@ class java_lang_invoke_ResolvedMethodName : AllStatic {
|
|
|
|
static Method* vmtarget(oop resolved_method);
|
|
static void set_vmtarget(oop resolved_method, Method* method);
|
|
- static void set_vmholder_offset(oop resolved_method, Method* method);
|
|
|
|
static void set_vmholder(oop resolved_method, oop holder);
|
|
|
|
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
|
index eb9fcda44f3..d0f1667b967 100644
|
|
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
|
|
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
|
@@ -375,6 +375,67 @@ public:
|
|
}
|
|
};
|
|
|
|
+class AdjustMethodEntriesDcevm : public StackObj {
|
|
+ bool* _trace_name_printed;
|
|
+ GrowableArray<oop>* _oops_to_add;
|
|
+public:
|
|
+ AdjustMethodEntriesDcevm(GrowableArray<oop>* oops_to_add, bool* trace_name_printed) : _trace_name_printed(trace_name_printed), _oops_to_add(oops_to_add) {};
|
|
+ bool operator()(WeakHandle<vm_resolved_method_table_data>* entry) {
|
|
+ oop mem_name = entry->peek();
|
|
+ if (mem_name == NULL) {
|
|
+ // Removed
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
|
+
|
|
+ if (old_method->is_old()) {
|
|
+
|
|
+ InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
|
|
+ Method* newer_method;
|
|
+
|
|
+ // Method* new_method;
|
|
+ if (old_method->is_deleted()) {
|
|
+ newer_method = Universe::throw_no_such_method_error();
|
|
+ } else {
|
|
+ newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
|
|
+
|
|
+ log_debug(redefine, class, update)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
|
+
|
|
+ assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
|
|
+ assert(newer_method != NULL, "method_with_idnum() should not be NULL");
|
|
+ assert(old_method != newer_method, "sanity check");
|
|
+
|
|
+ Thread* thread = Thread::current();
|
|
+ ResolvedMethodTableLookup lookup(thread, method_hash(newer_method), newer_method);
|
|
+ ResolvedMethodGet rmg(thread, newer_method);
|
|
+
|
|
+ if (_local_table->get(thread, lookup, rmg)) {
|
|
+ // old method was already adjusted if new method exists in _the_table
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, newer_method);
|
|
+ java_lang_invoke_ResolvedMethodName::set_vmholder(mem_name, newer_method->method_holder()->java_mirror());
|
|
+
|
|
+ newer_klass->set_has_resolved_methods();
|
|
+ _oops_to_add->append(mem_name);
|
|
+
|
|
+ ResourceMark rm;
|
|
+ if (!(*_trace_name_printed)) {
|
|
+ log_debug(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
|
|
+ *_trace_name_printed = true;
|
|
+ }
|
|
+ log_debug(redefine, class, update, constantpool)
|
|
+ ("ResolvedMethod method update: %s(%s)",
|
|
+ newer_method->name()->as_C_string(), newer_method->signature()->as_C_string());
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+};
|
|
+
|
|
// It is called at safepoint only for RedefineClasses
|
|
void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
|
|
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
|
|
@@ -382,73 +443,41 @@ void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
|
|
AdjustMethodEntries adjust(trace_name_printed);
|
|
_local_table->do_safepoint_scan(adjust);
|
|
}
|
|
-#endif // INCLUDE_JVMTI
|
|
|
|
-// (DCEVM) It is called at safepoint only for RedefineClasses
|
|
+// It is called at safepoint only for RedefineClasses
|
|
void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed) {
|
|
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
|
|
// For each entry in RMT, change to new method
|
|
- GrowableArray<oop>* oops_to_add = new GrowableArray<oop>();
|
|
-
|
|
- for (int i = 0; i < _the_table->table_size(); ++i) {
|
|
- for (ResolvedMethodEntry* entry = _the_table->bucket(i);
|
|
- entry != NULL;
|
|
- entry = entry->next()) {
|
|
-
|
|
- oop mem_name = entry->object_no_keepalive();
|
|
- // except ones removed
|
|
- if (mem_name == NULL) {
|
|
- continue;
|
|
- }
|
|
- Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
|
-
|
|
- if (old_method->is_old()) {
|
|
-
|
|
- InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
|
|
- Method* newer_method;
|
|
-
|
|
- // Method* new_method;
|
|
- if (old_method->is_deleted()) {
|
|
- newer_method = Universe::throw_no_such_method_error();
|
|
- } else {
|
|
- newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
|
|
-
|
|
- log_debug(redefine, class, update)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
|
-
|
|
- assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
|
|
- assert(newer_method != NULL, "method_with_idnum() should not be NULL");
|
|
- assert(old_method != newer_method, "sanity check");
|
|
-
|
|
- if (_the_table->lookup(newer_method) != NULL) {
|
|
- // old method was already adjusted if new method exists in _the_table
|
|
- continue;
|
|
- }
|
|
- }
|
|
+ GrowableArray<oop> oops_to_add(0);
|
|
+ AdjustMethodEntriesDcevm adjust(&oops_to_add, trace_name_printed);
|
|
+ _local_table->do_safepoint_scan(adjust);
|
|
+ Thread* thread = Thread::current();
|
|
+ for (int i = 0; i < oops_to_add.length(); i++) {
|
|
+ oop mem_name = oops_to_add.at(i);
|
|
+ Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
|
|
|
- java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, newer_method);
|
|
- java_lang_invoke_ResolvedMethodName::set_vmholder_offset(mem_name, newer_method);
|
|
+ // The hash table takes ownership of the WeakHandle, even if it's not inserted.
|
|
|
|
- newer_klass->set_has_resolved_methods();
|
|
- oops_to_add->append(mem_name);
|
|
+ ResolvedMethodTableLookup lookup(thread, method_hash(method), method);
|
|
+ ResolvedMethodGet rmg(thread, method);
|
|
|
|
- ResourceMark rm;
|
|
- if (!(*trace_name_printed)) {
|
|
- log_debug(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
|
|
- *trace_name_printed = true;
|
|
- }
|
|
- log_debug(redefine, class, update, constantpool)
|
|
- ("ResolvedMethod method update: %s(%s)",
|
|
- newer_method->name()->as_C_string(), newer_method->signature()->as_C_string());
|
|
+ while (true) {
|
|
+ if (_local_table->get(thread, lookup, rmg)) {
|
|
+ break;
|
|
+ }
|
|
+ WeakHandle<vm_resolved_method_table_data> wh = WeakHandle<vm_resolved_method_table_data>::create(Handle(thread, mem_name));
|
|
+ // The hash table takes ownership of the WeakHandle, even if it's not inserted.
|
|
+ if (_local_table->insert(thread, lookup, wh)) {
|
|
+ log_insert(method);
|
|
+ wh.resolve();
|
|
+ break;
|
|
}
|
|
- }
|
|
- for (int i = 0; i < oops_to_add->length(); i++) {
|
|
- oop mem_name = oops_to_add->at(i);
|
|
- Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
|
- _the_table->basic_add(method, Handle(Thread::current(), mem_name));
|
|
}
|
|
}
|
|
}
|
|
|
|
+#endif // INCLUDE_JVMTI
|
|
+
|
|
// Verification
|
|
class VerifyResolvedMethod : StackObj {
|
|
public:
|
|
--
|
|
2.23.0
|
|
|