src/share/vm/classfile/dictionary.cpp
Print this page
rev 5310 : imported patch ioi_original_patch
rev 5311 : imported patch cleanup
@@ -36,20 +36,20 @@
Dictionary::Dictionary(int table_size)
: TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry)) {
_current_class_index = 0;
_current_class_entry = NULL;
- _pd_cache_table = new ProtectionDomainCacheTable(137);
+ _pd_cache_table = new ProtectionDomainCacheTable(ProtectionDomainCacheSize);
};
Dictionary::Dictionary(int table_size, HashtableBucket<mtClass>* t,
int number_of_entries)
: TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry), t, number_of_entries) {
_current_class_index = 0;
_current_class_entry = NULL;
- _pd_cache_table = new ProtectionDomainCacheTable(137);
+ _pd_cache_table = new ProtectionDomainCacheTable(ProtectionDomainCacheSize);
};
ProtectionDomainCacheEntry* Dictionary::cache_get(oop protection_domain) {
return _pd_cache_table->get(protection_domain);
}
@@ -200,34 +200,28 @@
return class_was_unloaded;
}
void Dictionary::always_strong_oops_do(OopClosure* blk) {
- // This code is not multi-thread safe, but it should be called only
- // by GC thread.
- static int scan_generation = 0;
- scan_generation++;
- if (scan_generation == 0) {
- // Wrapped around 32-bit. Never use 0 -- it's the initial value of
- // ProtectionDomainCacheEntry::_scan_generation.
- scan_generation = 1;
- }
-
- // Follow all system classes and temporary placeholders in dictionary
+ // Follow all system classes and temporary placeholders in dictionary; only
+ // protection domain oops contain references into the heap. In a first
+ // pass over the system dictionary determine which need to be treated as
+ // strongly reachable and mark them as such.
for (int index = 0; index < table_size(); index++) {
for (DictionaryEntry *probe = bucket(index);
probe != NULL;
probe = probe->next()) {
Klass* e = probe->klass();
ClassLoaderData* loader_data = probe->loader_data();
if (is_strongly_reachable(loader_data, e)) {
- probe->set_strongly_reachable(scan_generation);
+ probe->set_strongly_reachable();
}
}
}
-
- _pd_cache_table->always_strong_oops_do(blk, scan_generation);
+ // then iterate over the protection domain cache to apply the closure on the
+ // previously marked ones.
+ _pd_cache_table->always_strong_oops_do(blk);
}
void Dictionary::always_strong_classes_do(KlassClosure* closure) {
// Follow all system classes and temporary placeholders in dictionary
@@ -286,10 +280,12 @@
}
}
}
void Dictionary::oops_do(OopClosure* f) {
+ // only the protection domain oops contain references into the heap. Iterate
+ // over all of them.
_pd_cache_table->oops_do(f);
}
void Dictionary::methods_do(void f(Method*)) {
for (int index = 0; index < table_size(); index++) {
@@ -470,17 +466,62 @@
probe->oops_do(f);
}
}
}
+uint ProtectionDomainCacheTable::bucket_size() {
+ return sizeof(ProtectionDomainCacheEntry);
+}
-void ProtectionDomainCacheTable::always_strong_oops_do(OopClosure* f, int gen) {
+#ifndef PRODUCT
+void ProtectionDomainCacheTable::print() {
+ tty->print_cr("Protection domain cache table (table_size=%d, classes=%d)",
+ table_size(), number_of_entries());
for (int index = 0; index < table_size(); index++) {
for (ProtectionDomainCacheEntry* probe = bucket(index);
probe != NULL;
probe = probe->next()) {
- if (probe->is_strongly_reachable(gen)) {
+ probe->print();
+ }
+ }
+}
+
+void ProtectionDomainCacheEntry::print() {
+ tty->print_cr("entry "PTR_FORMAT" value "PTR_FORMAT" refcount %d strongly_reachable %d next "PTR_FORMAT,
+ this, literal(), refcount(), _strongly_reachable, next());
+}
+#endif
+
+void ProtectionDomainCacheTable::verify() {
+ int element_count = 0;
+ for (int index = 0; index < table_size(); index++) {
+ for (ProtectionDomainCacheEntry* probe = bucket(index);
+ probe != NULL;
+ probe = probe->next()) {
+ probe->verify();
+ element_count++;
+ }
+ }
+ guarantee(number_of_entries() == element_count,
+ "Verify of protection domain cache table failed");
+ debug_only(verify_lookup_length((double)number_of_entries() / table_size()));
+}
+
+void ProtectionDomainCacheEntry::verify() {
+ guarantee(literal()->is_oop(), "must be an oop");
+ guarantee(_refcount >= 0, "must be");
+}
+
+void ProtectionDomainCacheTable::always_strong_oops_do(OopClosure* f) {
+ // the caller marked the protection domain cache entries that we need to apply
+ // the closure on. Only process them.
+ for (int index = 0; index < table_size(); index++) {
+ for (ProtectionDomainCacheEntry* probe = bucket(index);
+ probe != NULL;
+ probe = probe->next()) {
+ if (probe->is_strongly_reachable()) {
+ probe->reset_strongly_reachable();
probe->oops_do(f);
}
}
}
}
@@ -620,15 +661,16 @@
tty->print(", loader ");
loader_data->print_value();
tty->cr();
}
}
+ tty->cr();
+ _pd_cache_table->print();
}
#endif
-
void Dictionary::verify() {
guarantee(number_of_entries() >= 0, "Verify of system dictionary failed");
int element_count = 0;
for (int index = 0; index < table_size(); index++) {
@@ -651,7 +693,9 @@
}
}
guarantee(number_of_entries() == element_count,
"Verify of system dictionary failed");
debug_only(verify_lookup_length((double)number_of_entries() / table_size()));
+
+ _pd_cache_table->verify();
}