--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Sat Jul 22 15:54:27 2017 -0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Aug 02 18:06:38 2017 -0700
@@ -46,6 +46,7 @@
#include "memory/heapInspection.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/metadataFactory.hpp"
+#include "memory/metaspaceClosure.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
@@ -1998,6 +1999,49 @@
}
}
+void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
+ Klass::metaspace_pointers_do(it);
+
+ if (log_is_enabled(Trace, cds)) {
+ ResourceMark rm;
+ log_trace(cds)("Iter(InstanceKlass): %p (%s)", this, external_name());
+ }
+
+ it->push(&_annotations);
+ it->push((Klass**)&_array_klasses);
+ it->push(&_constants);
+ it->push(&_inner_classes);
+ it->push(&_array_name);
+#if INCLUDE_JVMTI
+ it->push(&_previous_versions);
+#endif
+ it->push(&_methods);
+ it->push(&_default_methods);
+ it->push(&_local_interfaces);
+ it->push(&_transitive_interfaces);
+ it->push(&_method_ordering);
+ it->push(&_default_vtable_indices);
+ it->push(&_fields);
+
+ if (itable_length() > 0) {
+ itableOffsetEntry* ioe = (itableOffsetEntry*)start_of_itable();
+ int method_table_offset_in_words = ioe->offset()/wordSize;
+ int nof_interfaces = (method_table_offset_in_words - itable_offset_in_words())
+ / itableOffsetEntry::size();
+
+ for (int i = 0; i < nof_interfaces; i ++, ioe ++) {
+ if (ioe->interface_klass() != NULL) {
+ it->push(ioe->interface_klass_addr());
+ itableMethodEntry* ime = ioe->first_method_entry(this);
+ int n = klassItable::method_count_for_interface(ioe->interface_klass());
+ for (int index = 0; index < n; index ++) {
+ it->push(ime[index].method_addr());
+ }
+ }
+ }
+ }
+}
+
void InstanceKlass::remove_unshareable_info() {
Klass::remove_unshareable_info();
@@ -2018,12 +2062,26 @@
constants()->remove_unshareable_info();
- assert(_dep_context == DependencyContext::EMPTY, "dependency context is not shareable");
-
for (int i = 0; i < methods()->length(); i++) {
Method* m = methods()->at(i);
m->remove_unshareable_info();
}
+
+ // These are not allocated from metaspace, but they should should all be empty
+ // during dump time, so we don't need to worry about them in InstanceKlass::metaspace_pointers_do().
+ guarantee(_source_debug_extension == NULL, "must be");
+ guarantee(_oop_map_cache == NULL, "must be");
+ guarantee(_init_thread == NULL, "must be");
+ guarantee(_oop_map_cache == NULL, "must be");
+ guarantee(_jni_ids == NULL, "must be");
+ guarantee(_methods_jmethod_ids == NULL, "must be");
+ guarantee(_dep_context == DependencyContext::EMPTY, "must be");
+ guarantee(_osr_nmethods_head == NULL, "must be");
+
+#if INCLUDE_JVMTI
+ guarantee(_breakpoints == NULL, "must be");
+ guarantee(_previous_versions == NULL, "must be");
+#endif
}
static void restore_unshareable_in_class(Klass* k, TRAPS) {
@@ -3664,11 +3722,15 @@
#if INCLUDE_CDS
JvmtiCachedClassFileData* InstanceKlass::get_archived_class_data() {
- assert(this->is_shared(), "class should be shared");
- if (MetaspaceShared::is_in_shared_space(_cached_class_file)) {
+ if (DumpSharedSpaces) {
return _cached_class_file;
} else {
- return NULL;
+ assert(this->is_shared(), "class should be shared");
+ if (MetaspaceShared::is_in_shared_space(_cached_class_file)) {
+ return _cached_class_file;
+ } else {
+ return NULL;
+ }
}
}
#endif