Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/shared/markSweep.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 | e861d44e0c9c |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 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. |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "compiler/compileBroker.hpp" | 26 #include "compiler/compileBroker.hpp" |
27 #include "gc_implementation/shared/markSweep.inline.hpp" | 27 #include "gc_implementation/shared/markSweep.inline.hpp" |
28 #include "gc_interface/collectedHeap.inline.hpp" | 28 #include "gc_interface/collectedHeap.inline.hpp" |
29 #include "oops/methodDataOop.hpp" | 29 #include "oops/methodData.hpp" |
30 #include "oops/objArrayKlass.inline.hpp" | 30 #include "oops/objArrayKlass.inline.hpp" |
31 #include "oops/oop.inline.hpp" | 31 #include "oops/oop.inline.hpp" |
32 | 32 |
33 unsigned int MarkSweep::_total_invocations = 0; | |
34 | |
33 Stack<oop, mtGC> MarkSweep::_marking_stack; | 35 Stack<oop, mtGC> MarkSweep::_marking_stack; |
34 Stack<DataLayout*, mtGC> MarkSweep::_revisit_mdo_stack; | |
35 Stack<Klass*, mtGC> MarkSweep::_revisit_klass_stack; | |
36 Stack<ObjArrayTask, mtGC> MarkSweep::_objarray_stack; | 36 Stack<ObjArrayTask, mtGC> MarkSweep::_objarray_stack; |
37 | 37 |
38 Stack<oop, mtGC> MarkSweep::_preserved_oop_stack; | 38 Stack<oop, mtGC> MarkSweep::_preserved_oop_stack; |
39 Stack<markOop, mtGC> MarkSweep::_preserved_mark_stack; | 39 Stack<markOop, mtGC> MarkSweep::_preserved_mark_stack; |
40 size_t MarkSweep::_preserved_count = 0; | 40 size_t MarkSweep::_preserved_count = 0; |
60 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops = NULL; | 60 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops = NULL; |
61 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops_moved_to = NULL; | 61 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops_moved_to = NULL; |
62 GrowableArray<size_t> * MarkSweep::_last_gc_live_oops_size = NULL; | 62 GrowableArray<size_t> * MarkSweep::_last_gc_live_oops_size = NULL; |
63 #endif | 63 #endif |
64 | 64 |
65 void MarkSweep::revisit_weak_klass_link(Klass* k) { | |
66 _revisit_klass_stack.push(k); | |
67 } | |
68 | |
69 void MarkSweep::follow_weak_klass_links() { | |
70 // All klasses on the revisit stack are marked at this point. | |
71 // Update and follow all subklass, sibling and implementor links. | |
72 if (PrintRevisitStats) { | |
73 gclog_or_tty->print_cr("#classes in system dictionary = %d", | |
74 SystemDictionary::number_of_classes()); | |
75 gclog_or_tty->print_cr("Revisit klass stack size = " SIZE_FORMAT, | |
76 _revisit_klass_stack.size()); | |
77 } | |
78 while (!_revisit_klass_stack.is_empty()) { | |
79 Klass* const k = _revisit_klass_stack.pop(); | |
80 k->follow_weak_klass_links(&is_alive, &keep_alive); | |
81 } | |
82 follow_stack(); | |
83 } | |
84 | |
85 void MarkSweep::revisit_mdo(DataLayout* p) { | |
86 _revisit_mdo_stack.push(p); | |
87 } | |
88 | |
89 void MarkSweep::follow_mdo_weak_refs() { | |
90 // All strongly reachable oops have been marked at this point; | |
91 // we can visit and clear any weak references from MDO's which | |
92 // we memoized during the strong marking phase. | |
93 assert(_marking_stack.is_empty(), "Marking stack should be empty"); | |
94 if (PrintRevisitStats) { | |
95 gclog_or_tty->print_cr("#classes in system dictionary = %d", | |
96 SystemDictionary::number_of_classes()); | |
97 gclog_or_tty->print_cr("Revisit MDO stack size = " SIZE_FORMAT, | |
98 _revisit_mdo_stack.size()); | |
99 } | |
100 while (!_revisit_mdo_stack.is_empty()) { | |
101 _revisit_mdo_stack.pop()->follow_weak_refs(&is_alive); | |
102 } | |
103 follow_stack(); | |
104 } | |
105 | |
106 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; | 65 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; |
107 CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true); | 66 CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true); |
108 | 67 |
109 void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); } | 68 void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); } |
110 void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); } | 69 void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); } |
111 | 70 |
112 MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure; | 71 MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure; |
113 | 72 MarkSweep::FollowKlassClosure MarkSweep::follow_klass_closure; |
114 void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { assert(*p == NULL || (*p)->is_oop(), ""); mark_and_push(p); } | 73 MarkSweep::AdjustKlassClosure MarkSweep::adjust_klass_closure; |
74 | |
75 void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); } | |
115 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); } | 76 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); } |
77 | |
78 void MarkSweep::FollowKlassClosure::do_klass(Klass* klass) { | |
79 klass->oops_do(&MarkSweep::mark_and_push_closure); | |
80 } | |
81 void MarkSweep::AdjustKlassClosure::do_klass(Klass* klass) { | |
82 klass->oops_do(&MarkSweep::adjust_pointer_closure); | |
83 } | |
84 | |
85 void MarkSweep::follow_klass(Klass* klass) { | |
86 ClassLoaderData* cld = klass->class_loader_data(); | |
87 assert(cld->has_defined(klass), "inconsistency!"); | |
88 | |
89 // The actual processing of the klass is done when we | |
90 // traverse the list of Klasses in the class loader data. | |
91 MarkSweep::follow_class_loader(cld); | |
92 } | |
93 | |
94 void MarkSweep::adjust_klass(Klass* klass) { | |
95 ClassLoaderData* cld = klass->class_loader_data(); | |
96 assert(cld->has_defined(klass), "inconsistency!"); | |
97 | |
98 // The actual processing of the klass is done when we | |
99 // traverse the list of Klasses in the class loader data. | |
100 MarkSweep::adjust_class_loader(cld); | |
101 } | |
102 | |
103 void MarkSweep::follow_class_loader(ClassLoaderData* cld) { | |
104 cld->oops_do(&MarkSweep::mark_and_push_closure, &MarkSweep::follow_klass_closure, true); | |
105 } | |
106 | |
107 void MarkSweep::adjust_class_loader(ClassLoaderData* cld) { | |
108 cld->oops_do(&MarkSweep::adjust_root_pointer_closure, &MarkSweep::adjust_klass_closure, true); | |
109 } | |
110 | |
116 | 111 |
117 void MarkSweep::follow_stack() { | 112 void MarkSweep::follow_stack() { |
118 do { | 113 do { |
119 while (!_marking_stack.is_empty()) { | 114 while (!_marking_stack.is_empty()) { |
120 oop obj = _marking_stack.pop(); | 115 oop obj = _marking_stack.pop(); |
122 obj->follow_contents(); | 117 obj->follow_contents(); |
123 } | 118 } |
124 // Process ObjArrays one at a time to avoid marking stack bloat. | 119 // Process ObjArrays one at a time to avoid marking stack bloat. |
125 if (!_objarray_stack.is_empty()) { | 120 if (!_objarray_stack.is_empty()) { |
126 ObjArrayTask task = _objarray_stack.pop(); | 121 ObjArrayTask task = _objarray_stack.pop(); |
127 objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); | 122 objArrayKlass* const k = (objArrayKlass*)task.obj()->klass(); |
128 k->oop_follow_contents(task.obj(), task.index()); | 123 k->oop_follow_contents(task.obj(), task.index()); |
129 } | 124 } |
130 } while (!_marking_stack.is_empty() || !_objarray_stack.is_empty()); | 125 } while (!_marking_stack.is_empty() || !_objarray_stack.is_empty()); |
131 } | 126 } |
132 | 127 |
235 if (ValidateMarkSweep) { | 230 if (ValidateMarkSweep) { |
236 _adjusted_pointers->clear(); | 231 _adjusted_pointers->clear(); |
237 _pointer_tracking = true; | 232 _pointer_tracking = true; |
238 | 233 |
239 AdjusterTracker checker; | 234 AdjusterTracker checker; |
240 obj->oop_iterate(&checker); | 235 obj->oop_iterate_no_header(&checker); |
241 } | 236 } |
242 } | 237 } |
243 | 238 |
244 void MarkSweep::check_interior_pointers() { | 239 void MarkSweep::check_interior_pointers() { |
245 if (ValidateMarkSweep) { | 240 if (ValidateMarkSweep) { |
246 _pointer_tracking = false; | 241 _pointer_tracking = false; |
247 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); | 242 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); |
248 } | 243 } |
249 } | 244 } |
250 | 245 |
251 void MarkSweep::reset_live_oop_tracking(bool at_perm) { | 246 void MarkSweep::reset_live_oop_tracking() { |
252 if (ValidateMarkSweep) { | 247 if (ValidateMarkSweep) { |
253 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); | 248 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); |
254 _live_oops_index = at_perm ? _live_oops_index_at_perm : 0; | 249 _live_oops_index = 0; |
255 } | 250 } |
256 } | 251 } |
257 | 252 |
258 void MarkSweep::register_live_oop(oop p, size_t size) { | 253 void MarkSweep::register_live_oop(oop p, size_t size) { |
259 if (ValidateMarkSweep) { | 254 if (ValidateMarkSweep) { |