6964458: Reimplement class meta-data storage to use native memory

Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes

Co-authored-by: Stefan Karlsson <stefan.karlsson@oracle.com>
Co-authored-by: Mikael Gerdin <mikael.gerdin@oracle.com>
Co-authored-by: Tom Rodriguez <tom.rodriguez@oracle.com>
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
This commit is contained in:
Jon Masamitsu 2012-09-01 13:25:18 -04:00 committed by Coleen Phillimore
parent 36eee7c8c8
commit 5c58d27aac
853 changed files with 26124 additions and 82956 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -55,7 +55,7 @@ enum SH_process_strong_roots_tasks {
SharedHeap::SharedHeap(CollectorPolicy* policy_) :
CollectedHeap(),
_collector_policy(policy_),
_perm_gen(NULL), _rem_set(NULL),
_rem_set(NULL),
_strong_roots_parity(0),
_process_strong_tasks(new SubTasksDone(SH_PS_NumElements)),
_workers(NULL)
@ -100,15 +100,6 @@ void SharedHeap::set_par_threads(uint t) {
_process_strong_tasks->set_n_threads(t);
}
class AssertIsPermClosure: public OopClosure {
public:
virtual void do_oop(oop* p) {
assert((*p) == NULL || (*p)->is_perm(), "Referent should be perm.");
}
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
};
static AssertIsPermClosure assert_is_perm_closure;
#ifdef ASSERT
class AssertNonScavengableClosure: public OopClosure {
public:
@ -143,12 +134,13 @@ SharedHeap::StrongRootsScope::~StrongRootsScope() {
}
void SharedHeap::process_strong_roots(bool activate_scope,
bool collecting_perm_gen,
bool is_scavenging,
ScanningOption so,
OopClosure* roots,
CodeBlobClosure* code_roots,
OopsInGenClosure* perm_blk) {
KlassClosure* klass_closure) {
StrongRootsScope srs(this, activate_scope);
// General strong roots.
assert(_strong_roots_parity != 0, "must have called prologue code");
// _n_termination for _process_strong_tasks should be set up stream
@ -157,8 +149,6 @@ void SharedHeap::process_strong_roots(bool activate_scope,
// is executing in another GC worker.
if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
Universe::oops_do(roots);
// Consider perm-gen discovered lists to be strong.
perm_gen()->ref_processor()->weak_oops_do(roots);
}
// Global (strong) JNI handles
if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
@ -181,40 +171,32 @@ void SharedHeap::process_strong_roots(bool activate_scope,
if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
if (so & SO_AllClasses) {
SystemDictionary::oops_do(roots);
ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
} else if (so & SO_SystemClasses) {
SystemDictionary::always_strong_oops_do(roots);
ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
} else {
ShouldNotReachHere2("We should always have selected either SO_AllClasses or SO_SystemClasses");
}
}
if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
if (so & SO_Strings || (!collecting_perm_gen && !JavaObjectsInPerm)) {
if (so & SO_Strings) {
StringTable::oops_do(roots);
}
if (JavaObjectsInPerm) {
// Verify the string table contents are in the perm gen
NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
}
}
if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
if (so & SO_CodeCache) {
// (Currently, CMSCollector uses this to do intermediate-strength collections.)
assert(collecting_perm_gen, "scanning all of code cache");
assert(code_roots != NULL, "must supply closure for code cache");
if (code_roots != NULL) {
CodeCache::blobs_do(code_roots);
}
} else if (so & (SO_SystemClasses|SO_AllClasses)) {
if (!collecting_perm_gen) {
// If we are collecting from class statics, but we are not going to
// visit all of the CodeCache, collect from the non-perm roots if any.
// This makes the code cache function temporarily as a source of strong
// roots for oops, until the next major collection.
//
// If collecting_perm_gen is true, we require that this phase will call
// CodeCache::do_unloading. This will kill off nmethods with expired
// weak references, such as stale invokedynamic targets.
if (is_scavenging) {
// We only visit parts of the CodeCache when scavenging.
CodeCache::scavenge_root_nmethods_do(code_roots);
} else {
// CMSCollector uses this to do intermediate-strength collections.
// We scan the entire code cache, since CodeCache::do_unloading is not called.
CodeCache::blobs_do(code_roots);
}
}
// Verify that the code cache contents are not subject to
@ -223,11 +205,6 @@ void SharedHeap::process_strong_roots(bool activate_scope,
DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
}
if (!collecting_perm_gen) {
// All threads perform this; coordination is handled internally.
rem_set()->younger_refs_iterate(perm_gen(), perm_blk);
}
_process_strong_tasks->all_tasks_completed();
}
@ -238,33 +215,6 @@ public:
};
static AlwaysTrueClosure always_true;
class SkipAdjustingSharedStrings: public OopClosure {
OopClosure* _clo;
public:
SkipAdjustingSharedStrings(OopClosure* clo) : _clo(clo) {}
virtual void do_oop(oop* p) {
oop o = (*p);
if (!o->is_shared_readwrite()) {
_clo->do_oop(p);
}
}
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
};
// Unmarked shared Strings in the StringTable (which got there due to
// being in the constant pools of as-yet unloaded shared classes) were
// not marked and therefore did not have their mark words preserved.
// These entries are also deliberately not purged from the string
// table during unloading of unmarked strings. If an identity hash
// code was computed for any of these objects, it will not have been
// cleared to zero during the forwarding process or by the
// RecursiveAdjustSharedObjectClosure, and will be confused by the
// adjusting process as a forwarding pointer. We need to skip
// forwarding StringTable entries which contain unmarked shared
// Strings. Actually, since shared strings won't be moving, we can
// just skip adjusting any shared entries in the string table.
void SharedHeap::process_weak_roots(OopClosure* root_closure,
CodeBlobClosure* code_roots,
OopClosure* non_root_closure) {
@ -272,13 +222,8 @@ void SharedHeap::process_weak_roots(OopClosure* root_closure,
JNIHandles::weak_oops_do(&always_true, root_closure);
CodeCache::blobs_do(code_roots);
if (UseSharedSpaces && !DumpSharedSpaces) {
SkipAdjustingSharedStrings skip_closure(root_closure);
StringTable::oops_do(&skip_closure);
} else {
StringTable::oops_do(root_closure);
}
}
void SharedHeap::set_barrier_set(BarrierSet* bs) {
_barrier_set = bs;
@ -290,9 +235,7 @@ void SharedHeap::post_initialize() {
ref_processing_init();
}
void SharedHeap::ref_processing_init() {
perm_gen()->ref_processor_init();
}
void SharedHeap::ref_processing_init() {}
// Some utilities.
void SharedHeap::print_size_transition(outputStream* out,