comparison src/share/vm/memory/sharedHeap.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 441e946dc1af
children d0aa87f04bd5
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
53 }; 53 };
54 54
55 SharedHeap::SharedHeap(CollectorPolicy* policy_) : 55 SharedHeap::SharedHeap(CollectorPolicy* policy_) :
56 CollectedHeap(), 56 CollectedHeap(),
57 _collector_policy(policy_), 57 _collector_policy(policy_),
58 _perm_gen(NULL), _rem_set(NULL), 58 _rem_set(NULL),
59 _strong_roots_parity(0), 59 _strong_roots_parity(0),
60 _process_strong_tasks(new SubTasksDone(SH_PS_NumElements)), 60 _process_strong_tasks(new SubTasksDone(SH_PS_NumElements)),
61 _workers(NULL) 61 _workers(NULL)
62 { 62 {
63 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { 63 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
98 assert(t == 0 || !UseSerialGC, "Cannot have parallel threads"); 98 assert(t == 0 || !UseSerialGC, "Cannot have parallel threads");
99 _n_par_threads = t; 99 _n_par_threads = t;
100 _process_strong_tasks->set_n_threads(t); 100 _process_strong_tasks->set_n_threads(t);
101 } 101 }
102 102
103 class AssertIsPermClosure: public OopClosure {
104 public:
105 virtual void do_oop(oop* p) {
106 assert((*p) == NULL || (*p)->is_perm(), "Referent should be perm.");
107 }
108 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
109 };
110 static AssertIsPermClosure assert_is_perm_closure;
111
112 #ifdef ASSERT 103 #ifdef ASSERT
113 class AssertNonScavengableClosure: public OopClosure { 104 class AssertNonScavengableClosure: public OopClosure {
114 public: 105 public:
115 virtual void do_oop(oop* p) { 106 virtual void do_oop(oop* p) {
116 assert(!Universe::heap()->is_in_partial_collection(*p), 107 assert(!Universe::heap()->is_in_partial_collection(*p),
141 SharedHeap::StrongRootsScope::~StrongRootsScope() { 132 SharedHeap::StrongRootsScope::~StrongRootsScope() {
142 // nothing particular 133 // nothing particular
143 } 134 }
144 135
145 void SharedHeap::process_strong_roots(bool activate_scope, 136 void SharedHeap::process_strong_roots(bool activate_scope,
146 bool collecting_perm_gen, 137 bool is_scavenging,
147 ScanningOption so, 138 ScanningOption so,
148 OopClosure* roots, 139 OopClosure* roots,
149 CodeBlobClosure* code_roots, 140 CodeBlobClosure* code_roots,
150 OopsInGenClosure* perm_blk) { 141 KlassClosure* klass_closure) {
151 StrongRootsScope srs(this, activate_scope); 142 StrongRootsScope srs(this, activate_scope);
143
152 // General strong roots. 144 // General strong roots.
153 assert(_strong_roots_parity != 0, "must have called prologue code"); 145 assert(_strong_roots_parity != 0, "must have called prologue code");
154 // _n_termination for _process_strong_tasks should be set up stream 146 // _n_termination for _process_strong_tasks should be set up stream
155 // in a method not running in a GC worker. Otherwise the GC worker 147 // in a method not running in a GC worker. Otherwise the GC worker
156 // could be trying to change the termination condition while the task 148 // could be trying to change the termination condition while the task
157 // is executing in another GC worker. 149 // is executing in another GC worker.
158 if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) { 150 if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
159 Universe::oops_do(roots); 151 Universe::oops_do(roots);
160 // Consider perm-gen discovered lists to be strong.
161 perm_gen()->ref_processor()->weak_oops_do(roots);
162 } 152 }
163 // Global (strong) JNI handles 153 // Global (strong) JNI handles
164 if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do)) 154 if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
165 JNIHandles::oops_do(roots); 155 JNIHandles::oops_do(roots);
166 // All threads execute this; the individual threads are task groups. 156 // All threads execute this; the individual threads are task groups.
179 JvmtiExport::oops_do(roots); 169 JvmtiExport::oops_do(roots);
180 170
181 if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) { 171 if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
182 if (so & SO_AllClasses) { 172 if (so & SO_AllClasses) {
183 SystemDictionary::oops_do(roots); 173 SystemDictionary::oops_do(roots);
174 ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
184 } else if (so & SO_SystemClasses) { 175 } else if (so & SO_SystemClasses) {
185 SystemDictionary::always_strong_oops_do(roots); 176 SystemDictionary::always_strong_oops_do(roots);
177 ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
178 } else {
179 ShouldNotReachHere2("We should always have selected either SO_AllClasses or SO_SystemClasses");
186 } 180 }
187 } 181 }
188 182
189 if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) { 183 if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
190 if (so & SO_Strings || (!collecting_perm_gen && !JavaObjectsInPerm)) { 184 if (so & SO_Strings) {
191 StringTable::oops_do(roots); 185 StringTable::oops_do(roots);
192 }
193 if (JavaObjectsInPerm) {
194 // Verify the string table contents are in the perm gen
195 NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
196 } 186 }
197 } 187 }
198 188
199 if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) { 189 if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
200 if (so & SO_CodeCache) { 190 if (so & SO_CodeCache) {
201 // (Currently, CMSCollector uses this to do intermediate-strength collections.)
202 assert(collecting_perm_gen, "scanning all of code cache");
203 assert(code_roots != NULL, "must supply closure for code cache"); 191 assert(code_roots != NULL, "must supply closure for code cache");
204 if (code_roots != NULL) { 192
193 if (is_scavenging) {
194 // We only visit parts of the CodeCache when scavenging.
195 CodeCache::scavenge_root_nmethods_do(code_roots);
196 } else {
197 // CMSCollector uses this to do intermediate-strength collections.
198 // We scan the entire code cache, since CodeCache::do_unloading is not called.
205 CodeCache::blobs_do(code_roots); 199 CodeCache::blobs_do(code_roots);
206 }
207 } else if (so & (SO_SystemClasses|SO_AllClasses)) {
208 if (!collecting_perm_gen) {
209 // If we are collecting from class statics, but we are not going to
210 // visit all of the CodeCache, collect from the non-perm roots if any.
211 // This makes the code cache function temporarily as a source of strong
212 // roots for oops, until the next major collection.
213 //
214 // If collecting_perm_gen is true, we require that this phase will call
215 // CodeCache::do_unloading. This will kill off nmethods with expired
216 // weak references, such as stale invokedynamic targets.
217 CodeCache::scavenge_root_nmethods_do(code_roots);
218 } 200 }
219 } 201 }
220 // Verify that the code cache contents are not subject to 202 // Verify that the code cache contents are not subject to
221 // movement by a scavenging collection. 203 // movement by a scavenging collection.
222 DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, /*do_marking=*/ false)); 204 DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, /*do_marking=*/ false));
223 DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); 205 DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
224 } 206 }
225 207
226 if (!collecting_perm_gen) {
227 // All threads perform this; coordination is handled internally.
228
229 rem_set()->younger_refs_iterate(perm_gen(), perm_blk);
230 }
231 _process_strong_tasks->all_tasks_completed(); 208 _process_strong_tasks->all_tasks_completed();
232 } 209 }
233 210
234 class AlwaysTrueClosure: public BoolObjectClosure { 211 class AlwaysTrueClosure: public BoolObjectClosure {
235 public: 212 public:
236 void do_object(oop p) { ShouldNotReachHere(); } 213 void do_object(oop p) { ShouldNotReachHere(); }
237 bool do_object_b(oop p) { return true; } 214 bool do_object_b(oop p) { return true; }
238 }; 215 };
239 static AlwaysTrueClosure always_true; 216 static AlwaysTrueClosure always_true;
240 217
241 class SkipAdjustingSharedStrings: public OopClosure {
242 OopClosure* _clo;
243 public:
244 SkipAdjustingSharedStrings(OopClosure* clo) : _clo(clo) {}
245
246 virtual void do_oop(oop* p) {
247 oop o = (*p);
248 if (!o->is_shared_readwrite()) {
249 _clo->do_oop(p);
250 }
251 }
252 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
253 };
254
255 // Unmarked shared Strings in the StringTable (which got there due to
256 // being in the constant pools of as-yet unloaded shared classes) were
257 // not marked and therefore did not have their mark words preserved.
258 // These entries are also deliberately not purged from the string
259 // table during unloading of unmarked strings. If an identity hash
260 // code was computed for any of these objects, it will not have been
261 // cleared to zero during the forwarding process or by the
262 // RecursiveAdjustSharedObjectClosure, and will be confused by the
263 // adjusting process as a forwarding pointer. We need to skip
264 // forwarding StringTable entries which contain unmarked shared
265 // Strings. Actually, since shared strings won't be moving, we can
266 // just skip adjusting any shared entries in the string table.
267
268 void SharedHeap::process_weak_roots(OopClosure* root_closure, 218 void SharedHeap::process_weak_roots(OopClosure* root_closure,
269 CodeBlobClosure* code_roots, 219 CodeBlobClosure* code_roots,
270 OopClosure* non_root_closure) { 220 OopClosure* non_root_closure) {
271 // Global (weak) JNI handles 221 // Global (weak) JNI handles
272 JNIHandles::weak_oops_do(&always_true, root_closure); 222 JNIHandles::weak_oops_do(&always_true, root_closure);
273 223
274 CodeCache::blobs_do(code_roots); 224 CodeCache::blobs_do(code_roots);
275 if (UseSharedSpaces && !DumpSharedSpaces) {
276 SkipAdjustingSharedStrings skip_closure(root_closure);
277 StringTable::oops_do(&skip_closure);
278 } else {
279 StringTable::oops_do(root_closure); 225 StringTable::oops_do(root_closure);
280 } 226 }
281 }
282 227
283 void SharedHeap::set_barrier_set(BarrierSet* bs) { 228 void SharedHeap::set_barrier_set(BarrierSet* bs) {
284 _barrier_set = bs; 229 _barrier_set = bs;
285 // Cached barrier set for fast access in oops 230 // Cached barrier set for fast access in oops
286 oopDesc::set_bs(bs); 231 oopDesc::set_bs(bs);
288 233
289 void SharedHeap::post_initialize() { 234 void SharedHeap::post_initialize() {
290 ref_processing_init(); 235 ref_processing_init();
291 } 236 }
292 237
293 void SharedHeap::ref_processing_init() { 238 void SharedHeap::ref_processing_init() {}
294 perm_gen()->ref_processor_init();
295 }
296 239
297 // Some utilities. 240 // Some utilities.
298 void SharedHeap::print_size_transition(outputStream* out, 241 void SharedHeap::print_size_transition(outputStream* out,
299 size_t bytes_before, 242 size_t bytes_before,
300 size_t bytes_after, 243 size_t bytes_after,