223 lines
10 KiB
Diff
223 lines
10 KiB
Diff
Date: Thu, 8 Jun 2023 19:52:36 +0800
|
|
Subject: [PATCH 55/59] Fix jmap heapdump symbols when the class is loaded from dynamicCDS' jsa
|
|
|
|
---
|
|
.../sun/jvm/hotspot/memory/SymbolTable.java | 16 +++++++-
|
|
.../utilities/OffsetCompactHashTable.java | 39 +++++++++++++++++++
|
|
.../src/share/vm/classfile/symbolTable.cpp | 16 ++------
|
|
.../src/share/vm/classfile/symbolTable.hpp | 15 +++++++
|
|
hotspot/src/share/vm/runtime/vmStructs.cpp | 16 +++++++-
|
|
5 files changed, 86 insertions(+), 16 deletions(-)
|
|
create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/OffsetCompactHashTable.java
|
|
|
|
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java
|
|
index 7510d08bf..015415fab 100644
|
|
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java
|
|
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java
|
|
@@ -44,15 +44,21 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
|
|
private static synchronized void initialize(TypeDataBase db) {
|
|
Type type = db.lookupType("SymbolTable");
|
|
theTableField = type.getAddressField("_the_table");
|
|
+ dynamicSharedTableField = type.getAddressField("_dynamic_shared_table");
|
|
}
|
|
|
|
// Fields
|
|
private static AddressField theTableField;
|
|
+ private static AddressField dynamicSharedTableField;
|
|
+ private OffsetCompactHashTable dynamicSharedTable;
|
|
|
|
// Accessors
|
|
public static SymbolTable getTheTable() {
|
|
Address tmp = theTableField.getValue();
|
|
- return (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
|
|
+ SymbolTable table = (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
|
|
+ Address dynamicShared = dynamicSharedTableField.getStaticFieldAddress();
|
|
+ table.dynamicSharedTable = (OffsetCompactHashTable)VMObjectFactory.newObject(OffsetCompactHashTable.class, dynamicShared);
|
|
+ return table;
|
|
}
|
|
|
|
public SymbolTable(Address addr) {
|
|
@@ -77,14 +83,20 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
|
|
table. */
|
|
public Symbol probe(byte[] name) {
|
|
long hashValue = hashSymbol(name);
|
|
+
|
|
+ Symbol sym = null;
|
|
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
|
|
if (e.hash() == hashValue) {
|
|
- Symbol sym = Symbol.create(e.literalValue());
|
|
+ sym = Symbol.create(e.literalValue());
|
|
if (sym.equals(name)) {
|
|
return sym;
|
|
}
|
|
}
|
|
}
|
|
+ if(sym == null && dynamicSharedTable != null) {
|
|
+ sym = dynamicSharedTable.probe(name, hashValue);
|
|
+ return sym;
|
|
+ }
|
|
return null;
|
|
}
|
|
|
|
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/OffsetCompactHashTable.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/OffsetCompactHashTable.java
|
|
new file mode 100644
|
|
index 000000000..42c72d0c3
|
|
--- /dev/null
|
|
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/OffsetCompactHashTable.java
|
|
@@ -0,0 +1,39 @@
|
|
+/*
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved.
|
|
+ */
|
|
+
|
|
+package sun.jvm.hotspot.utilities;
|
|
+
|
|
+import java.util.*;
|
|
+import sun.jvm.hotspot.debugger.*;
|
|
+import sun.jvm.hotspot.oops.*;
|
|
+import sun.jvm.hotspot.types.*;
|
|
+import sun.jvm.hotspot.runtime.*;
|
|
+import sun.jvm.hotspot.utilities.*;
|
|
+
|
|
+public class OffsetCompactHashTable extends CompactHashTable {
|
|
+ static {
|
|
+ VM.registerVMInitializedObserver(new Observer() {
|
|
+ public void update(Observable o, Object data) {
|
|
+ initialize(VM.getVM().getTypeDataBase());
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+
|
|
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
|
+ Type type = db.lookupType("SymbolOffsetCompactHashtable");
|
|
+ baseAddressField = type.getAddressField("_base_address");
|
|
+ bucketCountField = type.getCIntegerField("_bucket_count");
|
|
+ entryCountField = type.getCIntegerField("_entry_count");
|
|
+ bucketsField = type.getAddressField("_buckets");
|
|
+ entriesField = type.getAddressField("_entries");
|
|
+ uintSize = db.lookupType("u4").getSize();
|
|
+ }
|
|
+
|
|
+ public OffsetCompactHashTable(Address addr) {
|
|
+ super(addr);
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+
|
|
diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp
|
|
index 6a2d8077f..06da1e40e 100644
|
|
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp
|
|
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp
|
|
@@ -44,18 +44,10 @@
|
|
|
|
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
|
|
|
-inline bool symbol_equals_compact_hashtable_entry(Symbol* value, const char* key, int len) {
|
|
- if (value->equals(key, len)) {
|
|
- return true;
|
|
- } else {
|
|
- return false;
|
|
- }
|
|
-}
|
|
-
|
|
-static OffsetCompactHashtable<
|
|
+OffsetCompactHashtable<
|
|
const char*, Symbol*,
|
|
symbol_equals_compact_hashtable_entry
|
|
-> _dynamic_shared_table;
|
|
+> SymbolTable::_dynamic_shared_table;
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
@@ -254,7 +246,6 @@ Symbol* SymbolTable::lookup_shared(const char* name,
|
|
// always uses the same original hash code.
|
|
hash = java_lang_String::hash_code((const jbyte*)name, len);
|
|
}
|
|
-
|
|
sym = _dynamic_shared_table.lookup(name, hash, len);
|
|
}
|
|
return sym;
|
|
diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp
|
|
index 96eb173d1..f861e161f 100644
|
|
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp
|
|
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp
|
|
@@ -75,11 +75,25 @@ class TempNewSymbol : public StackObj {
|
|
operator Symbol*() { return _temp; }
|
|
};
|
|
|
|
+inline bool symbol_equals_compact_hashtable_entry(Symbol* value, const char* key, int len) {
|
|
+ if (value->equals(key, len)) {
|
|
+ return true;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
class SymbolTable : public RehashableHashtable<Symbol*, mtSymbol> {
|
|
friend class VMStructs;
|
|
friend class ClassFileParser;
|
|
|
|
private:
|
|
+ // The dynamic shared table
|
|
+ static OffsetCompactHashtable<
|
|
+ const char*, Symbol*,
|
|
+ symbol_equals_compact_hashtable_entry
|
|
+ > _dynamic_shared_table;
|
|
+
|
|
// The symbol table
|
|
static SymbolTable* _the_table;
|
|
|
|
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
|
|
index 5d1cf2b8e..744c43e02 100644
|
|
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
|
|
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
|
|
@@ -23,6 +23,7 @@
|
|
*/
|
|
|
|
#include "precompiled.hpp"
|
|
+#include "classfile/symbolTable.hpp"
|
|
#include "classfile/dictionary.hpp"
|
|
#include "classfile/javaClasses.hpp"
|
|
#include "classfile/loaderConstraints.hpp"
|
|
@@ -252,6 +253,8 @@ typedef Hashtable<Klass*, mtClass> KlassHashtable;
|
|
typedef HashtableEntry<Klass*, mtClass> KlassHashtableEntry;
|
|
typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
|
|
|
+typedef OffsetCompactHashtable<const char*, Symbol*, symbol_equals_compact_hashtable_entry> SymbolOffsetCompactHashtable;
|
|
+
|
|
//--------------------------------------------------------------------------------
|
|
// VM_STRUCTS
|
|
//
|
|
@@ -628,9 +631,19 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
|
/***************/ \
|
|
/* SymbolTable */ \
|
|
/***************/ \
|
|
- \
|
|
+ static_field(SymbolTable, _dynamic_shared_table, SymbolOffsetCompactHashtable) \
|
|
static_field(SymbolTable, _the_table, SymbolTable*) \
|
|
\
|
|
+ /********************************/ \
|
|
+ /* SymbolOffsetCompactHashtable */ \
|
|
+ /********************************/ \
|
|
+ \
|
|
+ nonstatic_field(SymbolOffsetCompactHashtable, _base_address, address) \
|
|
+ nonstatic_field(SymbolOffsetCompactHashtable, _entry_count, u4) \
|
|
+ nonstatic_field(SymbolOffsetCompactHashtable, _bucket_count, u4) \
|
|
+ nonstatic_field(SymbolOffsetCompactHashtable, _buckets, u4*) \
|
|
+ nonstatic_field(SymbolOffsetCompactHashtable, _entries, u4*) \
|
|
+ \
|
|
/***************/ \
|
|
/* StringTable */ \
|
|
/***************/ \
|
|
@@ -1574,6 +1587,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
|
declare_type(KlassTwoOopHashtable, KlassHashtable) \
|
|
declare_type(Dictionary, KlassTwoOopHashtable) \
|
|
declare_type(PlaceholderTable, SymbolTwoOopHashtable) \
|
|
+ declare_toplevel_type(SymbolOffsetCompactHashtable) \
|
|
declare_toplevel_type(BasicHashtableEntry<mtInternal>) \
|
|
declare_type(IntptrHashtableEntry, BasicHashtableEntry<mtInternal>) \
|
|
declare_type(DictionaryEntry, KlassHashtableEntry) \
|
|
--
|
|
2.22.0
|
|
|