8081323: ConstantPool::_resolved_references is missing in heap dump
Add resolved_references and init_lock as hidden static field in class so root is found.
Reviewed-by: dholmes, coleenp
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 90ffcf9..1de2213 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -418,6 +418,7 @@
template(getProtectionDomain_name, "getProtectionDomain") \
template(getProtectionDomain_signature, "(Ljava/security/CodeSource;)Ljava/security/ProtectionDomain;") \
template(url_code_signer_array_void_signature, "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \
+ template(resolved_references_name, "<resolved_references>") \
template(referencequeue_null_name, "NULL") \
template(referencequeue_enqueued_name, "ENQUEUED") \
\
@@ -508,6 +509,7 @@
template(class_array_signature, "[Ljava/lang/Class;") \
template(classloader_signature, "Ljava/lang/ClassLoader;") \
template(object_signature, "Ljava/lang/Object;") \
+ template(object_array_signature, "[Ljava/lang/Object;") \
template(class_signature, "Ljava/lang/Class;") \
template(string_signature, "Ljava/lang/String;") \
template(reference_signature, "Ljava/lang/ref/Reference;") \
diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp
index b76435f..7a4d500 100644
--- a/hotspot/src/share/vm/oops/constantPool.cpp
+++ b/hotspot/src/share/vm/oops/constantPool.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -109,6 +109,16 @@
return (objArrayOop)JNIHandles::resolve(_resolved_references);
}
+// Called from outside constant pool resolution where a resolved_reference array
+// may not be present.
+objArrayOop ConstantPool::resolved_references_or_null() const {
+ if (_cache == NULL) {
+ return NULL;
+ } else {
+ return (objArrayOop)JNIHandles::resolve(_resolved_references);
+ }
+}
+
// Create resolved_references array and mapping array for original cp indexes
// The ldc bytecode was rewritten to have the resolved reference array index so need a way
// to map it back for resolving and some unlikely miscellaneous uses.
diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp
index f170dec..0698eb4 100644
--- a/hotspot/src/share/vm/oops/constantPool.hpp
+++ b/hotspot/src/share/vm/oops/constantPool.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -200,6 +200,7 @@
// resolved strings, methodHandles and callsite objects from the constant pool
objArrayOop resolved_references() const;
+ objArrayOop resolved_references_or_null() const;
// mapping resolved object array indexes to cp indexes and back.
int object_to_cp_index(int index) { return _reference_map->at(index); }
int cp_to_object_index(int index);
diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp
index 9086cfb..a62ce91 100644
--- a/hotspot/src/share/vm/services/heapDumper.cpp
+++ b/hotspot/src/share/vm/services/heapDumper.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -815,6 +815,28 @@
for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
if (fldc.access_flags().is_static()) field_count++;
}
+ // Add in resolved_references which is referenced by the cpCache
+ // The resolved_references is an array per InstanceKlass holding the
+ // strings and other oops resolved from the constant pool.
+ oop resolved_references = ikh->constants()->resolved_references_or_null();
+ if (resolved_references != NULL) {
+ field_count++;
+
+ // Add in the resolved_references of the used previous versions of the class
+ // in the case of RedefineClasses
+ InstanceKlass* prev = ikh->previous_versions();
+ while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {
+ field_count++;
+ prev = prev->previous_versions();
+ }
+ }
+
+ // Also provide a pointer to the init_lock if present, so there aren't unreferenced int[0]
+ // arrays.
+ oop init_lock = ikh->init_lock();
+ if (init_lock != NULL) {
+ field_count++;
+ }
writer->write_u2(field_count);
@@ -833,6 +855,29 @@
dump_field_value(writer, sig->byte_at(0), addr);
}
}
+
+ // Add resolved_references for each class that has them
+ if (resolved_references != NULL) {
+ writer->write_symbolID(vmSymbols::resolved_references_name()); // name
+ writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type
+ writer->write_objectID(resolved_references);
+
+ // Also write any previous versions
+ InstanceKlass* prev = ikh->previous_versions();
+ while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {
+ writer->write_symbolID(vmSymbols::resolved_references_name()); // name
+ writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type
+ writer->write_objectID(prev->constants()->resolved_references());
+ prev = prev->previous_versions();
+ }
+ }
+
+ // Add init lock to the end if the class is not yet initialized
+ if (init_lock != NULL) {
+ writer->write_symbolID(vmSymbols::init_lock_name()); // name
+ writer->write_u1(sig2tag(vmSymbols::int_array_signature())); // type
+ writer->write_objectID(init_lock);
+ }
}
// dump the raw values of the instance fields of the given object
@@ -868,7 +913,7 @@
if (!fld.access_flags().is_static()) {
Symbol* sig = fld.signature();
- writer->write_symbolID(fld.name()); // name
+ writer->write_symbolID(fld.name()); // name
writer->write_u1(sig2tag(sig)); // type
}
}
@@ -1758,6 +1803,8 @@
// HPROF_GC_ROOT_JNI_GLOBAL
JNIGlobalsDumper jni_dumper(writer());
JNIHandles::oops_do(&jni_dumper);
+ Universe::oops_do(&jni_dumper); // technically not jni roots, but global roots
+ // for things like preallocated throwable backtraces
check_segment_length();
// HPROF_GC_ROOT_STICKY_CLASS