Thu, 20 Sep 2012 09:52:56 -0700
7190666: G1: assert(_unused == 0) failed: Inconsistency in PLAB stats
Summary: Reset the fields in ParGCAllocBuffer, that are used for accumulating values for the ResizePLAB sensors in PLABStats, to zero after flushing the values to the PLABStats fields. Flush PLABStats values only when retiring the final allocation buffers prior to disposing of a G1ParScanThreadState object, rather than when retiring every allocation buffer.
Reviewed-by: jwilhelm, jmasa, ysr
1 /*
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.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_HPP
26 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_HPP
28 #include "gc_interface/collectedHeap.hpp"
29 #include "memory/universe.hpp"
30 #include "oops/markOop.hpp"
31 #include "oops/oop.hpp"
32 #include "runtime/timer.hpp"
33 #include "utilities/growableArray.hpp"
34 #include "utilities/stack.hpp"
35 #include "utilities/taskqueue.hpp"
37 class ReferenceProcessor;
38 class DataLayout;
40 // MarkSweep takes care of global mark-compact garbage collection for a
41 // GenCollectedHeap using a four-phase pointer forwarding algorithm. All
42 // generations are assumed to support marking; those that can also support
43 // compaction.
44 //
45 // Class unloading will only occur when a full gc is invoked.
47 // If VALIDATE_MARK_SWEEP is defined, the -XX:+ValidateMarkSweep flag will
48 // be operational, and will provide slow but comprehensive self-checks within
49 // the GC. This is not enabled by default in product or release builds,
50 // since the extra call to track_adjusted_pointer() in _adjust_pointer()
51 // would be too much overhead, and would disturb performance measurement.
52 // However, debug builds are sometimes way too slow to run GC tests!
53 #ifdef ASSERT
54 #define VALIDATE_MARK_SWEEP 1
55 #endif
56 #ifdef VALIDATE_MARK_SWEEP
57 #define VALIDATE_MARK_SWEEP_ONLY(code) code
58 #else
59 #define VALIDATE_MARK_SWEEP_ONLY(code)
60 #endif
62 // declared at end
63 class PreservedMark;
65 class MarkSweep : AllStatic {
66 //
67 // Inline closure decls
68 //
69 class FollowRootClosure: public OopsInGenClosure {
70 public:
71 virtual void do_oop(oop* p);
72 virtual void do_oop(narrowOop* p);
73 };
75 class MarkAndPushClosure: public OopClosure {
76 public:
77 virtual void do_oop(oop* p);
78 virtual void do_oop(narrowOop* p);
79 };
81 // The one and only place to start following the classes.
82 // Should only be applied to the ClassLoaderData klasses list.
83 class FollowKlassClosure : public KlassClosure {
84 public:
85 void do_klass(Klass* klass);
86 };
87 class AdjustKlassClosure : public KlassClosure {
88 public:
89 void do_klass(Klass* klass);
90 };
92 class FollowStackClosure: public VoidClosure {
93 public:
94 virtual void do_void();
95 };
97 class AdjustPointerClosure: public OopsInGenClosure {
98 private:
99 bool _is_root;
100 public:
101 AdjustPointerClosure(bool is_root) : _is_root(is_root) {}
102 virtual void do_oop(oop* p);
103 virtual void do_oop(narrowOop* p);
104 };
106 // Used for java/lang/ref handling
107 class IsAliveClosure: public BoolObjectClosure {
108 public:
109 virtual void do_object(oop p);
110 virtual bool do_object_b(oop p);
111 };
113 class KeepAliveClosure: public OopClosure {
114 protected:
115 template <class T> void do_oop_work(T* p);
116 public:
117 virtual void do_oop(oop* p);
118 virtual void do_oop(narrowOop* p);
119 };
121 //
122 // Friend decls
123 //
124 friend class AdjustPointerClosure;
125 friend class KeepAliveClosure;
126 friend class VM_MarkSweep;
127 friend void marksweep_init();
129 //
130 // Vars
131 //
132 protected:
133 // Total invocations of a MarkSweep collection
134 static unsigned int _total_invocations;
136 // Traversal stacks used during phase1
137 static Stack<oop, mtGC> _marking_stack;
138 static Stack<ObjArrayTask, mtGC> _objarray_stack;
140 // Space for storing/restoring mark word
141 static Stack<markOop, mtGC> _preserved_mark_stack;
142 static Stack<oop, mtGC> _preserved_oop_stack;
143 static size_t _preserved_count;
144 static size_t _preserved_count_max;
145 static PreservedMark* _preserved_marks;
147 // Reference processing (used in ...follow_contents)
148 static ReferenceProcessor* _ref_processor;
150 #ifdef VALIDATE_MARK_SWEEP
151 static GrowableArray<void*>* _root_refs_stack;
152 static GrowableArray<oop> * _live_oops;
153 static GrowableArray<oop> * _live_oops_moved_to;
154 static GrowableArray<size_t>* _live_oops_size;
155 static size_t _live_oops_index;
156 static size_t _live_oops_index_at_perm;
157 static GrowableArray<void*>* _other_refs_stack;
158 static GrowableArray<void*>* _adjusted_pointers;
159 static bool _pointer_tracking;
160 static bool _root_tracking;
162 // The following arrays are saved since the time of the last GC and
163 // assist in tracking down problems where someone has done an errant
164 // store into the heap, usually to an oop that wasn't properly
165 // handleized across a GC. If we crash or otherwise fail before the
166 // next GC, we can query these arrays to find out the object we had
167 // intended to do the store to (assuming it is still alive) and the
168 // offset within that object. Covered under RecordMarkSweepCompaction.
169 static GrowableArray<HeapWord*> * _cur_gc_live_oops;
170 static GrowableArray<HeapWord*> * _cur_gc_live_oops_moved_to;
171 static GrowableArray<size_t>* _cur_gc_live_oops_size;
172 static GrowableArray<HeapWord*> * _last_gc_live_oops;
173 static GrowableArray<HeapWord*> * _last_gc_live_oops_moved_to;
174 static GrowableArray<size_t>* _last_gc_live_oops_size;
175 #endif
177 // Non public closures
178 static KeepAliveClosure keep_alive;
180 // Debugging
181 static void trace(const char* msg) PRODUCT_RETURN;
183 public:
184 // Public closures
185 static IsAliveClosure is_alive;
186 static FollowRootClosure follow_root_closure;
187 static CodeBlobToOopClosure follow_code_root_closure; // => follow_root_closure
188 static MarkAndPushClosure mark_and_push_closure;
189 static FollowKlassClosure follow_klass_closure;
190 static FollowStackClosure follow_stack_closure;
191 static AdjustPointerClosure adjust_root_pointer_closure;
192 static AdjustPointerClosure adjust_pointer_closure;
193 static AdjustKlassClosure adjust_klass_closure;
195 // Accessors
196 static unsigned int total_invocations() { return _total_invocations; }
198 // Reference Processing
199 static ReferenceProcessor* const ref_processor() { return _ref_processor; }
201 // Call backs for marking
202 static void mark_object(oop obj);
203 // Mark pointer and follow contents. Empty marking stack afterwards.
204 template <class T> static inline void follow_root(T* p);
206 // Check mark and maybe push on marking stack
207 template <class T> static void mark_and_push(T* p);
209 static inline void push_objarray(oop obj, size_t index);
211 static void follow_stack(); // Empty marking stack.
213 static void follow_klass(Klass* klass);
214 static void adjust_klass(Klass* klass);
216 static void follow_class_loader(ClassLoaderData* cld);
217 static void adjust_class_loader(ClassLoaderData* cld);
219 static void preserve_mark(oop p, markOop mark);
220 // Save the mark word so it can be restored later
221 static void adjust_marks(); // Adjust the pointers in the preserved marks table
222 static void restore_marks(); // Restore the marks that we saved in preserve_mark
224 template <class T> static inline void adjust_pointer(T* p, bool isroot);
226 static void adjust_root_pointer(oop* p) { adjust_pointer(p, true); }
227 static void adjust_pointer(oop* p) { adjust_pointer(p, false); }
228 static void adjust_pointer(narrowOop* p) { adjust_pointer(p, false); }
230 #ifdef VALIDATE_MARK_SWEEP
231 static void track_adjusted_pointer(void* p, bool isroot);
232 static void check_adjust_pointer(void* p);
233 static void track_interior_pointers(oop obj);
234 static void check_interior_pointers();
236 static void reset_live_oop_tracking();
237 static void register_live_oop(oop p, size_t size);
238 static void validate_live_oop(oop p, size_t size);
239 static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top);
240 static void compaction_complete();
242 // Querying operation of RecordMarkSweepCompaction results.
243 // Finds and prints the current base oop and offset for a word
244 // within an oop that was live during the last GC. Helpful for
245 // tracking down heap stomps.
246 static void print_new_location_of_heap_address(HeapWord* q);
247 #endif
248 };
250 class PreservedMark VALUE_OBJ_CLASS_SPEC {
251 private:
252 oop _obj;
253 markOop _mark;
255 public:
256 void init(oop obj, markOop mark) {
257 _obj = obj;
258 _mark = mark;
259 }
261 void adjust_pointer() {
262 MarkSweep::adjust_pointer(&_obj);
263 }
265 void restore() {
266 _obj->set_mark(_mark);
267 }
268 };
270 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_HPP