< prev index next >
src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp
Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 SAP SE. 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
* under the terms of the GNU General Public License version 2 only, as
@@ -127,11 +127,11 @@
};
class LoaderTreeNode : public ResourceObj {
- // We walk the CLDG and, for each CLD which is non-unsafe_anonymous, add
+ // We walk the CLDG and, for each CLD which is findable, add
// a tree node.
// To add a node we need its parent node; if the parent node does not yet
// exist - because we have not yet encountered the CLD for the parent loader -
// we add a preliminary empty LoaderTreeNode for it. This preliminary node
// just contains the loader oop and nothing else. Once we encounter the CLD of
@@ -147,10 +147,13 @@
int _num_classes;
LoadedClassInfo* _anon_classes;
int _num_anon_classes;
+ LoadedClassInfo* _hidden_weak_classes;
+ int _num_hidden_weak_classes;
+
// In default view, similar tree nodes (same loader class, same name or no name)
// are folded into each other to make the output more readable.
// _num_folded contains the number of nodes which have been folded into this
// one.
int _num_folded;
@@ -175,10 +178,11 @@
// e.g. "+--- jdk.internal.reflect.DelegatingClassLoader"
st->print("+%.*s", BranchTracker::twig_len, "----------");
if (_cld->is_the_null_class_loader_data()) {
st->print(" <bootstrap>");
} else {
+ assert(!_cld->has_class_mirror_holder(), "_cld must be the primary cld");
if (loader_name != NULL) {
st->print(" \"%s\",", loader_name->as_C_string());
}
st->print(" %s", loader_klass != NULL ? loader_klass->external_name() : "??");
if (_num_folded > 0) {
@@ -218,11 +222,11 @@
}
if (print_classes) {
if (_classes != NULL) {
for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) {
- // Non-unsafe anonymous classes should live in the primary CLD of its loader
+ // Weak-hidden and unsafe anonymous classes should not live in the primary CLD of their loaders.
assert(lci->_cld == _cld, "must be");
branchtracker.print(st);
if (lci == _classes) { // first iteration
st->print("%*s ", indentation, "Classes:");
@@ -256,20 +260,49 @@
st->print("%*s ", indentation, "Unsafe Anonymous Classes:");
} else {
st->print("%*s ", indentation, "");
}
st->print("%s", lci->_klass->external_name());
- // For unsafe anonymous classes, also print CLD if verbose. Should be a different one than the primary CLD.
+ // For unsafe anonymous classes, also print CLD if verbose. Should
+ // be a different one than the primary CLD.
+ assert(lci->_cld != _cld, "must be");
+ if (verbose) {
+ st->print(" (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld));
+ }
+ st->cr();
+ }
+ branchtracker.print(st);
+ st->print("%*s ", indentation, "");
+ st->print_cr("(%u unsafe anonymous class%s)", _num_anon_classes,
+ (_num_anon_classes == 1) ? "" : "es");
+
+ // Empty line
+ branchtracker.print(st);
+ st->cr();
+ }
+
+ if (_hidden_weak_classes != NULL) {
+ for (LoadedClassInfo* lci = _hidden_weak_classes; lci; lci = lci->_next) {
+ branchtracker.print(st);
+ if (lci == _hidden_weak_classes) { // first iteration
+ st->print("%*s ", indentation, "Weak Hidden Classes:");
+ } else {
+ st->print("%*s ", indentation, "");
+ }
+ st->print("%s", lci->_klass->external_name());
+ // For weak hidden classes, also print CLD if verbose. Should be a
+ // different one than the primary CLD.
assert(lci->_cld != _cld, "must be");
if (verbose) {
st->print(" (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld));
}
st->cr();
}
branchtracker.print(st);
st->print("%*s ", indentation, "");
- st->print_cr("(%u unsafe anonymous class%s)", _num_anon_classes, (_num_anon_classes == 1) ? "" : "es");
+ st->print_cr("(%u weak hidden class%s)", _num_hidden_weak_classes,
+ (_num_hidden_weak_classes == 1) ? "" : "es");
// Empty line
branchtracker.print(st);
st->cr();
}
@@ -299,10 +332,11 @@
public:
LoaderTreeNode(const oop loader_oop)
: _loader_oop(loader_oop), _cld(NULL), _child(NULL), _next(NULL),
_classes(NULL), _num_classes(0), _anon_classes(NULL), _num_anon_classes(0),
+ _hidden_weak_classes(NULL), _num_hidden_weak_classes(0),
_num_folded(0)
{}
void set_cld(const ClassLoaderData* cld) {
_cld = cld;
@@ -317,19 +351,29 @@
assert(info->_next == NULL, "must be");
info->_next = _next;
_next = info;
}
- void add_classes(LoadedClassInfo* first_class, int num_classes, bool is_unsafe_anonymous) {
- LoadedClassInfo** p_list_to_add_to = is_unsafe_anonymous ? &_anon_classes : &_classes;
+ void add_classes(LoadedClassInfo* first_class, int num_classes, bool has_class_mirror_holder) {
+ LoadedClassInfo** p_list_to_add_to;
+ bool is_hidden = first_class->_klass->is_hidden();
+ if (has_class_mirror_holder) {
+ p_list_to_add_to = is_hidden ? &_hidden_weak_classes : &_anon_classes;
+ } else {
+ p_list_to_add_to = &_classes;
+ }
// Search tail.
while ((*p_list_to_add_to) != NULL) {
p_list_to_add_to = &(*p_list_to_add_to)->_next;
}
*p_list_to_add_to = first_class;
- if (is_unsafe_anonymous) {
+ if (has_class_mirror_holder) {
+ if (is_hidden) {
+ _num_hidden_weak_classes += num_classes;
+ } else {
_num_anon_classes += num_classes;
+ }
} else {
_num_classes += num_classes;
}
}
@@ -419,11 +463,11 @@
static void fill_in_classes(LoaderTreeNode* info, const ClassLoaderData* cld) {
assert(info != NULL && cld != NULL, "must be");
LoadedClassCollectClosure lccc(cld);
const_cast<ClassLoaderData*>(cld)->classes_do(&lccc);
if (lccc._num_classes > 0) {
- info->add_classes(lccc._list, lccc._num_classes, cld->is_unsafe_anonymous());
+ info->add_classes(lccc._list, lccc._num_classes, cld->has_class_mirror_holder());
}
}
LoaderTreeNode* find_node_or_add_empty_node(oop loader_oop) {
@@ -479,11 +523,11 @@
LoaderTreeNode* info = find_node_or_add_empty_node(loader_oop);
assert(info != NULL, "must be");
// Update CLD in node, but only if this is the primary CLD for this loader.
- if (cld->is_unsafe_anonymous() == false) {
+ if (cld->has_class_mirror_holder() == false) {
assert(info->cld() == NULL, "there should be only one primary CLD per loader");
info->set_cld(cld);
}
// Add classes.
< prev index next >