Mercurial > hg > truffle
diff src/share/vm/classfile/loaderConstraints.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | d2a62e0f25eb |
children | 070d523b96a7 |
line wrap: on
line diff
--- a/src/share/vm/classfile/loaderConstraints.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/classfile/loaderConstraints.cpp Sat Sep 01 13:25:18 2012 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.inline.hpp" #include "classfile/loaderConstraints.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" @@ -30,16 +31,20 @@ #include "runtime/safepoint.hpp" #include "utilities/hashtable.inline.hpp" +void LoaderConstraintEntry::set_loader(int i, oop p) { + set_loader_data(i, ClassLoaderData::class_loader_data(p)); +} + LoaderConstraintTable::LoaderConstraintTable(int nof_buckets) - : Hashtable<klassOop, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {}; + : Hashtable<Klass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {}; LoaderConstraintEntry* LoaderConstraintTable::new_entry( unsigned int hash, Symbol* name, - klassOop klass, int num_loaders, + Klass* klass, int num_loaders, int max_loaders) { LoaderConstraintEntry* entry; - entry = (LoaderConstraintEntry*)Hashtable<klassOop, mtClass>::new_entry(hash, klass); + entry = (LoaderConstraintEntry*)Hashtable<Klass*, mtClass>::new_entry(hash, klass); entry->set_name(name); entry->set_num_loaders(num_loaders); entry->set_max_loaders(max_loaders); @@ -49,27 +54,21 @@ void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) { // decrement name refcount before freeing entry->name()->decrement_refcount(); - Hashtable<klassOop, mtClass>::free_entry(entry); + Hashtable<Klass*, mtClass>::free_entry(entry); } - -void LoaderConstraintTable::oops_do(OopClosure* f) { +// Enhanced Class Redefinition support +void LoaderConstraintTable::classes_do(KlassClosure* f) { for (int index = 0; index < table_size(); index++) { for (LoaderConstraintEntry* probe = bucket(index); probe != NULL; probe = probe->next()) { if (probe->klass() != NULL) { - f->do_oop((oop*)probe->klass_addr()); + f->do_klass(probe->klass()); } - for (int n = 0; n < probe->num_loaders(); n++) { - if (probe->loader(n) != NULL) { - f->do_oop(probe->loader_addr(n)); } } } - } -} - // The loaderConstraintTable must always be accessed with the // SystemDictionary lock held. This is true even for readers as @@ -81,12 +80,14 @@ unsigned int hash = compute_hash(name); int index = hash_to_index(hash); LoaderConstraintEntry** pp = bucket_addr(index); + ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader()); + while (*pp) { LoaderConstraintEntry* p = *pp; if (p->hash() == hash) { if (p->name() == name) { for (int i = p->num_loaders() - 1; i >= 0; i--) { - if (p->loader(i) == loader()) { + if (p->loader_data(i) == loader_data) { return pp; } } @@ -98,16 +99,17 @@ } -void LoaderConstraintTable::purge_loader_constraints(BoolObjectClosure* is_alive) { +void LoaderConstraintTable::purge_loader_constraints() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); // Remove unloaded entries from constraint table for (int index = 0; index < table_size(); index++) { LoaderConstraintEntry** p = bucket_addr(index); while(*p) { LoaderConstraintEntry* probe = *p; - klassOop klass = probe->klass(); + Klass* klass = probe->klass(); // Remove klass that is no longer alive - if (klass != NULL && !is_alive->do_object_b(klass)) { + if (klass != NULL && + klass->class_loader_data()->is_unloading()) { probe->set_klass(NULL); if (TraceLoaderConstraints) { ResourceMark rm; @@ -116,19 +118,18 @@ probe->name()->as_C_string()); for (int i = 0; i < probe->num_loaders(); i++) { tty->print_cr("[ [%d]: %s", i, - SystemDictionary::loader_name(probe->loader(i))); + SystemDictionary::loader_name(probe->loader_data(i))); } } } // Remove entries no longer alive from loader array int n = 0; while (n < probe->num_loaders()) { - if (probe->loader(n) != NULL) { - if (!is_alive->do_object_b(probe->loader(n))) { + if (probe->loader_data(n)->is_unloading()) { if (TraceLoaderConstraints) { ResourceMark rm; tty->print_cr("[Purging loader %s from constraint for name %s", - SystemDictionary::loader_name(probe->loader(n)), + SystemDictionary::loader_name(probe->loader_data(n)), probe->name()->as_C_string() ); } @@ -136,22 +137,21 @@ // Compact array int num = probe->num_loaders() - 1; probe->set_num_loaders(num); - probe->set_loader(n, probe->loader(num)); - probe->set_loader(num, NULL); + probe->set_loader_data(n, probe->loader_data(num)); + probe->set_loader_data(num, NULL); if (TraceLoaderConstraints) { ResourceMark rm; tty->print_cr("[New loader list:"); for (int i = 0; i < probe->num_loaders(); i++) { tty->print_cr("[ [%d]: %s", i, - SystemDictionary::loader_name(probe->loader(i))); + SystemDictionary::loader_name(probe->loader_data(i))); } } continue; // current element replaced, so restart without // incrementing n } - } n++; } // Check whether entry should be purged @@ -169,12 +169,9 @@ } else { #ifdef ASSERT if (probe->klass() != NULL) { - assert(is_alive->do_object_b(probe->klass()), "klass should be live"); - } - for (n = 0; n < probe->num_loaders(); n++) { - if (probe->loader(n) != NULL) { - assert(is_alive->do_object_b(probe->loader(n)), "loader should be live"); - } + ClassLoaderData* loader_data = + probe->klass()->class_loader_data(); + assert(!loader_data->is_unloading(), "klass should be live"); } #endif // Go to next entry @@ -185,14 +182,14 @@ } bool LoaderConstraintTable::add_entry(Symbol* class_name, - klassOop klass1, Handle class_loader1, - klassOop klass2, Handle class_loader2) { + Klass* klass1, Handle class_loader1, + Klass* klass2, Handle class_loader2) { int failure_code = 0; // encode different reasons for failing if (klass1 != NULL && klass2 != NULL && klass1 != klass2) { failure_code = 1; } else { - klassOop klass = klass1 != NULL ? klass1 : klass2; + Klass* klass = klass1 != NULL ? klass1 : klass2; LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, class_loader1); @@ -224,7 +221,7 @@ int index = hash_to_index(hash); LoaderConstraintEntry* p; p = new_entry(hash, class_name, klass, 2, 2); - p->set_loaders(NEW_C_HEAP_ARRAY(oop, 2, mtClass)); + p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass)); p->set_loader(0, class_loader1()); p->set_loader(1, class_loader2()); p->set_klass(klass); @@ -319,11 +316,11 @@ } } -klassOop LoaderConstraintTable::find_constrained_klass(Symbol* name, +Klass* LoaderConstraintTable::find_constrained_klass(Symbol* name, Handle loader) { LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); if (p != NULL && p->klass() != NULL) { - if (Klass::cast(p->klass())->oop_is_instance() && !instanceKlass::cast(p->klass())->is_loaded()) { + if (Klass::cast(p->klass())->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) { // Only return fully loaded classes. Classes found through the // constraints might still be in the process of loading. return NULL; @@ -340,10 +337,10 @@ int nfree) { if (p->max_loaders() - p->num_loaders() < nfree) { int n = nfree + p->num_loaders(); - oop* new_loaders = NEW_C_HEAP_ARRAY(oop, n, mtClass); - memcpy(new_loaders, p->loaders(), sizeof(oop) * p->num_loaders()); + ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass); + memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders()); p->set_max_loaders(n); - FREE_C_HEAP_ARRAY(oop, p->loaders(), mtClass); + FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders(), mtClass); p->set_loaders(new_loaders); } } @@ -351,7 +348,7 @@ void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p, Handle loader, - klassOop klass) { + Klass* klass) { ensure_loader_constraint_capacity(p, 1); int num = p->num_loaders(); p->set_loader(num, loader()); @@ -376,7 +373,7 @@ void LoaderConstraintTable::merge_loader_constraints( LoaderConstraintEntry** pp1, LoaderConstraintEntry** pp2, - klassOop klass) { + Klass* klass) { // make sure *pp1 has higher capacity if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) { LoaderConstraintEntry** tmp = pp2; @@ -391,7 +388,7 @@ for (int i = 0; i < p2->num_loaders(); i++) { int num = p1->num_loaders(); - p1->set_loader(num, p2->loader(i)); + p1->set_loader_data(num, p2->loader_data(i)); p1->set_num_loaders(num + 1); } @@ -403,7 +400,7 @@ for (int i = 0; i < p1->num_loaders(); i++) { tty->print_cr("[ [%d]: %s", i, - SystemDictionary::loader_name(p1->loader(i))); + SystemDictionary::loader_name(p1->loader_data(i))); } if (p1->klass() == NULL) { tty->print_cr("[... and setting class object]"); @@ -439,33 +436,33 @@ probe != NULL; probe = probe->next()) { if (probe->klass() != NULL) { - instanceKlass* ik = instanceKlass::cast(probe->klass()); + InstanceKlass* ik = InstanceKlass::cast(probe->klass()); guarantee(ik->name() == probe->name(), "name should match"); Symbol* name = ik->name(); - Handle loader(thread, ik->class_loader()); - unsigned int d_hash = dictionary->compute_hash(name, loader); + ClassLoaderData* loader_data = ik->class_loader_data(); + unsigned int d_hash = dictionary->compute_hash(name, loader_data); int d_index = dictionary->hash_to_index(d_hash); - klassOop k = dictionary->find_class(d_index, d_hash, name, loader); + Klass* k = dictionary->find_class(d_index, d_hash, name, loader_data); if (k != NULL) { // We found the class in the system dictionary, so we should - // make sure that the klassOop matches what we already have. + // make sure that the Klass* matches what we already have. guarantee(k == probe->klass(), "klass should be in dictionary"); } else { // If we don't find the class in the system dictionary, it // has to be in the placeholders table. - unsigned int p_hash = placeholders->compute_hash(name, loader); + unsigned int p_hash = placeholders->compute_hash(name, loader_data); int p_index = placeholders->hash_to_index(p_hash); PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash, - name, loader); + name, loader_data); - // The instanceKlass might not be on the entry, so the only + // The InstanceKlass might not be on the entry, so the only // thing we can check here is whether we were successful in // finding the class in the placeholders table. guarantee(entry != NULL, "klass should be in the placeholders"); } } for (int n = 0; n< probe->num_loaders(); n++) { - guarantee(probe->loader(n)->is_oop_or_null(), "should be oop"); + assert(ClassLoaderDataGraph::contains_loader_data(probe->loader_data(n)), "The loader is missing"); } } } @@ -487,7 +484,7 @@ probe->name()->print(); tty->print(" , loaders:"); for (int n = 0; n < probe->num_loaders(); n++) { - probe->loader(n)->print_value(); + probe->loader_data(n)->print_value(); tty->print(", "); } tty->cr();