< prev index next >

src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp

Print this page




 129 
 130 class LoaderTreeNode : public ResourceObj {
 131 
 132   // We walk the CLDG and, for each CLD which is findable, add
 133   // a tree node.
 134   // To add a node we need its parent node; if the parent node does not yet
 135   // exist - because we have not yet encountered the CLD for the parent loader -
 136   // we add a preliminary empty LoaderTreeNode for it. This preliminary node
 137   // just contains the loader oop and nothing else. Once we encounter the CLD of
 138   // this parent loader, we fill in all the other details.
 139 
 140   const oop _loader_oop;
 141   const ClassLoaderData* _cld;
 142 
 143   LoaderTreeNode* _child;
 144   LoaderTreeNode* _next;
 145 
 146   LoadedClassInfo* _classes;
 147   int _num_classes;
 148 
 149   LoadedClassInfo* _anon_classes;
 150   int _num_anon_classes;
 151 
 152   LoadedClassInfo* _hidden_classes;
 153   int _num_hidden_classes;
 154 
 155   // In default view, similar tree nodes (same loader class, same name or no name)
 156   // are folded into each other to make the output more readable.
 157   // _num_folded contains the number of nodes which have been folded into this
 158   // one.
 159   int _num_folded;
 160 
 161   void print_with_childs(outputStream* st, BranchTracker& branchtracker,
 162       bool print_classes, bool verbose) const {
 163 
 164     ResourceMark rm;
 165 
 166     if (_cld == NULL) {
 167       // Not sure how this could happen: we added a preliminary node for a parent but then never encountered
 168       // its CLD?
 169       return;
 170     }
 171 


 207       st->cr();
 208 
 209       const int indentation = 18;
 210 
 211       if (verbose) {
 212         branchtracker.print(st);
 213         st->print_cr("%*s " PTR_FORMAT, indentation, "Loader Oop:", p2i(_loader_oop));
 214         branchtracker.print(st);
 215         st->print_cr("%*s " PTR_FORMAT, indentation, "Loader Data:", p2i(_cld));
 216         branchtracker.print(st);
 217         st->print_cr("%*s " PTR_FORMAT, indentation, "Loader Klass:", p2i(loader_klass));
 218 
 219         // Empty line
 220         branchtracker.print(st);
 221         st->cr();
 222       }
 223 
 224       if (print_classes) {
 225         if (_classes != NULL) {
 226           for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) {
 227             // non-strong hidden and unsafe anonymous classes should not live in the primary CLD of their loaders.

 228             assert(lci->_cld == _cld, "must be");
 229 
 230             branchtracker.print(st);
 231             if (lci == _classes) { // first iteration
 232               st->print("%*s ", indentation, "Classes:");
 233             } else {
 234               st->print("%*s ", indentation, "");
 235             }
 236             st->print("%s", lci->_klass->external_name());
 237 
 238             // Special treatment for generated core reflection accessor classes: print invocation target.
 239             if (ReflectionAccessorImplKlassHelper::is_generated_accessor(lci->_klass)) {
 240               st->print(" (invokes: ");
 241               ReflectionAccessorImplKlassHelper::print_invocation_target(st, lci->_klass);
 242               st->print(")");
 243             }
 244 
 245             st->cr();
 246           }
 247           branchtracker.print(st);
 248           st->print("%*s ", indentation, "");
 249           st->print_cr("(%u class%s)", _num_classes, (_num_classes == 1) ? "" : "es");
 250 
 251           // Empty line
 252           branchtracker.print(st);
 253           st->cr();
 254         }
 255 
 256         if (_anon_classes != NULL) {
 257           for (LoadedClassInfo* lci = _anon_classes; lci; lci = lci->_next) {
 258             branchtracker.print(st);
 259             if (lci == _anon_classes) { // first iteration
 260               st->print("%*s ", indentation, "Unsafe Anonymous Classes:");
 261             } else {
 262               st->print("%*s ", indentation, "");
 263             }
 264             st->print("%s", lci->_klass->external_name());
 265             // For unsafe anonymous classes, also print CLD if verbose. Should
 266             // be a different one than the primary CLD.
 267             assert(lci->_cld != _cld, "must be");
 268             if (verbose) {
 269               st->print("  (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld));
 270             }
 271             st->cr();
 272           }
 273           branchtracker.print(st);
 274           st->print("%*s ", indentation, "");
 275           st->print_cr("(%u unsafe anonymous class%s)", _num_anon_classes,
 276                        (_num_anon_classes == 1) ? "" : "es");
 277 
 278           // Empty line
 279           branchtracker.print(st);
 280           st->cr();
 281         }
 282 
 283         if (_hidden_classes != NULL) {
 284           for (LoadedClassInfo* lci = _hidden_classes; lci; lci = lci->_next) {
 285             branchtracker.print(st);
 286             if (lci == _hidden_classes) { // first iteration
 287               st->print("%*s ", indentation, "Hidden Classes:");
 288             } else {
 289               st->print("%*s ", indentation, "");
 290             }
 291             st->print("%s", lci->_klass->external_name());
 292             // For non-strong hidden classes, also print CLD if verbose. Should be a
 293             // different one than the primary CLD.
 294             assert(lci->_cld != _cld, "must be");
 295             if (verbose) {
 296               st->print("  (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld));
 297             }
 298             st->cr();
 299           }
 300           branchtracker.print(st);
 301           st->print("%*s ", indentation, "");
 302           st->print_cr("(%u hidden class%s)", _num_hidden_classes,


 316     while (c != NULL) {
 317       c->print_with_childs(st, branchtracker, print_classes, verbose);
 318       c = c->_next;
 319     }
 320 
 321   }
 322 
 323   // Helper: Attempt to fold this node into the target node. If success, returns true.
 324   // Folding can be done if both nodes are leaf nodes and they refer to the same loader class
 325   // and they have the same name or no name (note: leaf check is done by caller).
 326   bool can_fold_into(LoaderTreeNode* target_node) const {
 327     assert(is_leaf() && target_node->is_leaf(), "must be leaf");
 328     return _cld->class_loader_klass() == target_node->_cld->class_loader_klass() &&
 329            _cld->name() == target_node->_cld->name();
 330   }
 331 
 332 public:
 333 
 334   LoaderTreeNode(const oop loader_oop)
 335     : _loader_oop(loader_oop), _cld(NULL), _child(NULL), _next(NULL),
 336       _classes(NULL), _num_classes(0), _anon_classes(NULL), _num_anon_classes(0),
 337       _hidden_classes(NULL), _num_hidden_classes(0),
 338       _num_folded(0)
 339     {}
 340 
 341   void set_cld(const ClassLoaderData* cld) {
 342     _cld = cld;
 343   }
 344 
 345   void add_child(LoaderTreeNode* info) {
 346     info->_next = _child;
 347     _child = info;
 348   }
 349 
 350   void add_sibling(LoaderTreeNode* info) {
 351     assert(info->_next == NULL, "must be");
 352     info->_next = _next;
 353     _next = info;
 354   }
 355 
 356   void add_classes(LoadedClassInfo* first_class, int num_classes, bool has_class_mirror_holder) {
 357     LoadedClassInfo** p_list_to_add_to;
 358     bool is_hidden = first_class->_klass->is_hidden();
 359     if (has_class_mirror_holder) {
 360       p_list_to_add_to = is_hidden ? &_hidden_classes : &_anon_classes;
 361     } else {
 362       p_list_to_add_to = &_classes;
 363     }
 364     // Search tail.
 365     while ((*p_list_to_add_to) != NULL) {
 366       p_list_to_add_to = &(*p_list_to_add_to)->_next;
 367     }
 368     *p_list_to_add_to = first_class;
 369     if (has_class_mirror_holder) {
 370       if (is_hidden) {
 371         _num_hidden_classes += num_classes;
 372       } else {
 373         _num_anon_classes += num_classes;
 374       }
 375     } else {
 376       _num_classes += num_classes;
 377     }
 378   }
 379 
 380   const ClassLoaderData* cld() const {
 381     return _cld;
 382   }
 383 
 384   const oop loader_oop() const {
 385     return _loader_oop;
 386   }
 387 
 388   LoaderTreeNode* find(const oop loader_oop) {
 389     LoaderTreeNode* result = NULL;
 390     if (_loader_oop == loader_oop) {
 391       result = this;
 392     } else {
 393       LoaderTreeNode* c = _child;
 394       while (c != NULL && result == NULL) {




 129 
 130 class LoaderTreeNode : public ResourceObj {
 131 
 132   // We walk the CLDG and, for each CLD which is findable, add
 133   // a tree node.
 134   // To add a node we need its parent node; if the parent node does not yet
 135   // exist - because we have not yet encountered the CLD for the parent loader -
 136   // we add a preliminary empty LoaderTreeNode for it. This preliminary node
 137   // just contains the loader oop and nothing else. Once we encounter the CLD of
 138   // this parent loader, we fill in all the other details.
 139 
 140   const oop _loader_oop;
 141   const ClassLoaderData* _cld;
 142 
 143   LoaderTreeNode* _child;
 144   LoaderTreeNode* _next;
 145 
 146   LoadedClassInfo* _classes;
 147   int _num_classes;
 148 



 149   LoadedClassInfo* _hidden_classes;
 150   int _num_hidden_classes;
 151 
 152   // In default view, similar tree nodes (same loader class, same name or no name)
 153   // are folded into each other to make the output more readable.
 154   // _num_folded contains the number of nodes which have been folded into this
 155   // one.
 156   int _num_folded;
 157 
 158   void print_with_childs(outputStream* st, BranchTracker& branchtracker,
 159       bool print_classes, bool verbose) const {
 160 
 161     ResourceMark rm;
 162 
 163     if (_cld == NULL) {
 164       // Not sure how this could happen: we added a preliminary node for a parent but then never encountered
 165       // its CLD?
 166       return;
 167     }
 168 


 204       st->cr();
 205 
 206       const int indentation = 18;
 207 
 208       if (verbose) {
 209         branchtracker.print(st);
 210         st->print_cr("%*s " PTR_FORMAT, indentation, "Loader Oop:", p2i(_loader_oop));
 211         branchtracker.print(st);
 212         st->print_cr("%*s " PTR_FORMAT, indentation, "Loader Data:", p2i(_cld));
 213         branchtracker.print(st);
 214         st->print_cr("%*s " PTR_FORMAT, indentation, "Loader Klass:", p2i(loader_klass));
 215 
 216         // Empty line
 217         branchtracker.print(st);
 218         st->cr();
 219       }
 220 
 221       if (print_classes) {
 222         if (_classes != NULL) {
 223           for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) {
 224             // non-strong hidden and unsafe anonymous classes should not live in
 225             // the primary CLD of their loaders.
 226             assert(lci->_cld == _cld, "must be");
 227 
 228             branchtracker.print(st);
 229             if (lci == _classes) { // first iteration
 230               st->print("%*s ", indentation, "Classes:");
 231             } else {
 232               st->print("%*s ", indentation, "");
 233             }
 234             st->print("%s", lci->_klass->external_name());
 235 
 236             // Special treatment for generated core reflection accessor classes: print invocation target.
 237             if (ReflectionAccessorImplKlassHelper::is_generated_accessor(lci->_klass)) {
 238               st->print(" (invokes: ");
 239               ReflectionAccessorImplKlassHelper::print_invocation_target(st, lci->_klass);
 240               st->print(")");
 241             }
 242 
 243             st->cr();
 244           }
 245           branchtracker.print(st);
 246           st->print("%*s ", indentation, "");
 247           st->print_cr("(%u class%s)", _num_classes, (_num_classes == 1) ? "" : "es");
 248 
 249           // Empty line
 250           branchtracker.print(st);
 251           st->cr();
 252         }
 253 



























 254         if (_hidden_classes != NULL) {
 255           for (LoadedClassInfo* lci = _hidden_classes; lci; lci = lci->_next) {
 256             branchtracker.print(st);
 257             if (lci == _hidden_classes) { // first iteration
 258               st->print("%*s ", indentation, "Hidden Classes:");
 259             } else {
 260               st->print("%*s ", indentation, "");
 261             }
 262             st->print("%s", lci->_klass->external_name());
 263             // For non-strong hidden classes, also print CLD if verbose. Should be a
 264             // different one than the primary CLD.
 265             assert(lci->_cld != _cld, "must be");
 266             if (verbose) {
 267               st->print("  (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld));
 268             }
 269             st->cr();
 270           }
 271           branchtracker.print(st);
 272           st->print("%*s ", indentation, "");
 273           st->print_cr("(%u hidden class%s)", _num_hidden_classes,


 287     while (c != NULL) {
 288       c->print_with_childs(st, branchtracker, print_classes, verbose);
 289       c = c->_next;
 290     }
 291 
 292   }
 293 
 294   // Helper: Attempt to fold this node into the target node. If success, returns true.
 295   // Folding can be done if both nodes are leaf nodes and they refer to the same loader class
 296   // and they have the same name or no name (note: leaf check is done by caller).
 297   bool can_fold_into(LoaderTreeNode* target_node) const {
 298     assert(is_leaf() && target_node->is_leaf(), "must be leaf");
 299     return _cld->class_loader_klass() == target_node->_cld->class_loader_klass() &&
 300            _cld->name() == target_node->_cld->name();
 301   }
 302 
 303 public:
 304 
 305   LoaderTreeNode(const oop loader_oop)
 306     : _loader_oop(loader_oop), _cld(NULL), _child(NULL), _next(NULL),
 307       _classes(NULL), _num_classes(0), _hidden_classes(NULL),
 308       _num_hidden_classes(0), _num_folded(0)

 309     {}
 310 
 311   void set_cld(const ClassLoaderData* cld) {
 312     _cld = cld;
 313   }
 314 
 315   void add_child(LoaderTreeNode* info) {
 316     info->_next = _child;
 317     _child = info;
 318   }
 319 
 320   void add_sibling(LoaderTreeNode* info) {
 321     assert(info->_next == NULL, "must be");
 322     info->_next = _next;
 323     _next = info;
 324   }
 325 
 326   void add_classes(LoadedClassInfo* first_class, int num_classes, bool has_class_mirror_holder) {
 327     LoadedClassInfo** p_list_to_add_to;
 328     bool is_hidden = first_class->_klass->is_hidden();
 329     if (has_class_mirror_holder) {
 330       p_list_to_add_to = &_hidden_classes;
 331     } else {
 332       p_list_to_add_to = &_classes;
 333     }
 334     // Search tail.
 335     while ((*p_list_to_add_to) != NULL) {
 336       p_list_to_add_to = &(*p_list_to_add_to)->_next;
 337     }
 338     *p_list_to_add_to = first_class;
 339     if (has_class_mirror_holder) {

 340       _num_hidden_classes += num_classes;



 341     } else {
 342       _num_classes += num_classes;
 343     }
 344   }
 345 
 346   const ClassLoaderData* cld() const {
 347     return _cld;
 348   }
 349 
 350   const oop loader_oop() const {
 351     return _loader_oop;
 352   }
 353 
 354   LoaderTreeNode* find(const oop loader_oop) {
 355     LoaderTreeNode* result = NULL;
 356     if (_loader_oop == loader_oop) {
 357       result = this;
 358     } else {
 359       LoaderTreeNode* c = _child;
 360       while (c != NULL && result == NULL) {


< prev index next >