< 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 ****
/*
! * Copyright (c) 2018, 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
--- 1,7 ----
/*
! * 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,137 ****
};
class LoaderTreeNode : public ResourceObj {
! // We walk the CLDG and, for each CLD which is non-unsafe_anonymous, 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
--- 127,137 ----
};
class LoaderTreeNode : public ResourceObj {
! // 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,156 ****
--- 147,159 ----
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,184 ****
--- 178,188 ----
// 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,228 ****
}
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
assert(lci->_cld == _cld, "must be");
branchtracker.print(st);
if (lci == _classes) { // first iteration
st->print("%*s ", indentation, "Classes:");
--- 222,232 ----
}
if (print_classes) {
if (_classes != NULL) {
for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) {
! // 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,275 ****
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.
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();
}
--- 260,308 ----
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.
! 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 weak hidden class%s)", _num_hidden_weak_classes,
! (_num_hidden_weak_classes == 1) ? "" : "es");
// Empty line
branchtracker.print(st);
st->cr();
}
*** 299,308 ****
--- 332,342 ----
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,335 ****
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;
// 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) {
_num_anon_classes += num_classes;
} else {
_num_classes += num_classes;
}
}
--- 351,379 ----
assert(info->_next == NULL, "must be");
info->_next = _next;
_next = info;
}
! 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 (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,429 ****
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());
}
}
LoaderTreeNode* find_node_or_add_empty_node(oop loader_oop) {
--- 463,473 ----
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->has_class_mirror_holder());
}
}
LoaderTreeNode* find_node_or_add_empty_node(oop loader_oop) {
*** 479,489 ****
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) {
assert(info->cld() == NULL, "there should be only one primary CLD per loader");
info->set_cld(cld);
}
// Add classes.
--- 523,533 ----
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->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 >