Fri, 10 Oct 2014 15:51:58 +0200
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
1 /*
2 * Copyright (c) 2001, 2014, 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_G1_G1OOPCLOSURES_HPP
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP
28 #include "memory/iterator.hpp"
30 class HeapRegion;
31 class G1CollectedHeap;
32 class G1RemSet;
33 class ConcurrentMark;
34 class DirtyCardToOopClosure;
35 class CMBitMap;
36 class CMMarkStack;
37 class G1ParScanThreadState;
38 class CMTask;
39 class ReferenceProcessor;
41 // A class that scans oops in a given heap region (much as OopsInGenClosure
42 // scans oops in a generation.)
43 class OopsInHeapRegionClosure: public ExtendedOopClosure {
44 protected:
45 HeapRegion* _from;
46 public:
47 void set_region(HeapRegion* from) { _from = from; }
48 };
50 class G1ParClosureSuper : public OopsInHeapRegionClosure {
51 protected:
52 G1CollectedHeap* _g1;
53 G1ParScanThreadState* _par_scan_state;
54 uint _worker_id;
55 public:
56 // Initializes the instance, leaving _par_scan_state uninitialized. Must be done
57 // later using the set_par_scan_thread_state() method.
58 G1ParClosureSuper(G1CollectedHeap* g1);
59 G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state);
60 bool apply_to_weak_ref_discovered_field() { return true; }
62 void set_par_scan_thread_state(G1ParScanThreadState* par_scan_state);
63 };
65 class G1ParPushHeapRSClosure : public G1ParClosureSuper {
66 public:
67 G1ParPushHeapRSClosure(G1CollectedHeap* g1,
68 G1ParScanThreadState* par_scan_state):
69 G1ParClosureSuper(g1, par_scan_state) { }
71 template <class T> void do_oop_nv(T* p);
72 virtual void do_oop(oop* p) { do_oop_nv(p); }
73 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
74 };
76 class G1ParScanClosure : public G1ParClosureSuper {
77 public:
78 G1ParScanClosure(G1CollectedHeap* g1, ReferenceProcessor* rp) :
79 G1ParClosureSuper(g1) {
80 assert(_ref_processor == NULL, "sanity");
81 _ref_processor = rp;
82 }
84 template <class T> void do_oop_nv(T* p);
85 virtual void do_oop(oop* p) { do_oop_nv(p); }
86 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
87 };
89 // Add back base class for metadata
90 class G1ParCopyHelper : public G1ParClosureSuper {
91 protected:
92 Klass* _scanned_klass;
93 ConcurrentMark* _cm;
95 // Mark the object if it's not already marked. This is used to mark
96 // objects pointed to by roots that are guaranteed not to move
97 // during the GC (i.e., non-CSet objects). It is MT-safe.
98 void mark_object(oop obj);
100 // Mark the object if it's not already marked. This is used to mark
101 // objects pointed to by roots that have been forwarded during a
102 // GC. It is MT-safe.
103 void mark_forwarded_object(oop from_obj, oop to_obj);
104 public:
105 G1ParCopyHelper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state);
107 void set_scanned_klass(Klass* k) { _scanned_klass = k; }
108 template <class T> void do_klass_barrier(T* p, oop new_obj);
109 };
111 template <G1Barrier barrier, G1Mark do_mark_object>
112 class G1ParCopyClosure : public G1ParCopyHelper {
113 private:
114 template <class T> void do_oop_work(T* p);
116 public:
117 G1ParCopyClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state,
118 ReferenceProcessor* rp) :
119 G1ParCopyHelper(g1, par_scan_state) {
120 assert(_ref_processor == NULL, "sanity");
121 }
123 template <class T> void do_oop_nv(T* p) { do_oop_work(p); }
124 virtual void do_oop(oop* p) { do_oop_nv(p); }
125 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
127 G1CollectedHeap* g1() { return _g1; };
128 G1ParScanThreadState* pss() { return _par_scan_state; }
129 ReferenceProcessor* rp() { return _ref_processor; };
130 };
132 typedef G1ParCopyClosure<G1BarrierNone, G1MarkNone> G1ParScanExtRootClosure;
133 typedef G1ParCopyClosure<G1BarrierNone, G1MarkFromRoot> G1ParScanAndMarkExtRootClosure;
134 typedef G1ParCopyClosure<G1BarrierNone, G1MarkPromotedFromRoot> G1ParScanAndMarkWeakExtRootClosure;
135 // We use a separate closure to handle references during evacuation
136 // failure processing.
138 typedef G1ParCopyClosure<G1BarrierEvac, G1MarkNone> G1ParScanHeapEvacFailureClosure;
140 class FilterIntoCSClosure: public ExtendedOopClosure {
141 G1CollectedHeap* _g1;
142 OopClosure* _oc;
143 DirtyCardToOopClosure* _dcto_cl;
144 public:
145 FilterIntoCSClosure( DirtyCardToOopClosure* dcto_cl,
146 G1CollectedHeap* g1,
147 OopClosure* oc) :
148 _dcto_cl(dcto_cl), _g1(g1), _oc(oc) { }
150 template <class T> void do_oop_nv(T* p);
151 virtual void do_oop(oop* p) { do_oop_nv(p); }
152 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
153 bool apply_to_weak_ref_discovered_field() { return true; }
154 };
156 class FilterOutOfRegionClosure: public ExtendedOopClosure {
157 HeapWord* _r_bottom;
158 HeapWord* _r_end;
159 OopClosure* _oc;
160 public:
161 FilterOutOfRegionClosure(HeapRegion* r, OopClosure* oc);
162 template <class T> void do_oop_nv(T* p);
163 virtual void do_oop(oop* p) { do_oop_nv(p); }
164 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
165 bool apply_to_weak_ref_discovered_field() { return true; }
166 };
168 // Closure for iterating over object fields during concurrent marking
169 class G1CMOopClosure : public MetadataAwareOopClosure {
170 protected:
171 ConcurrentMark* _cm;
172 private:
173 G1CollectedHeap* _g1h;
174 CMTask* _task;
175 public:
176 G1CMOopClosure(G1CollectedHeap* g1h, ConcurrentMark* cm, CMTask* task);
177 template <class T> void do_oop_nv(T* p);
178 virtual void do_oop( oop* p) { do_oop_nv(p); }
179 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
180 };
182 // Closure to scan the root regions during concurrent marking
183 class G1RootRegionScanClosure : public MetadataAwareOopClosure {
184 private:
185 G1CollectedHeap* _g1h;
186 ConcurrentMark* _cm;
187 uint _worker_id;
188 public:
189 G1RootRegionScanClosure(G1CollectedHeap* g1h, ConcurrentMark* cm,
190 uint worker_id) :
191 _g1h(g1h), _cm(cm), _worker_id(worker_id) { }
192 template <class T> void do_oop_nv(T* p);
193 virtual void do_oop( oop* p) { do_oop_nv(p); }
194 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
195 };
197 // Closure that applies the given two closures in sequence.
198 // Used by the RSet refinement code (when updating RSets
199 // during an evacuation pause) to record cards containing
200 // pointers into the collection set.
202 class G1Mux2Closure : public ExtendedOopClosure {
203 OopClosure* _c1;
204 OopClosure* _c2;
205 public:
206 G1Mux2Closure(OopClosure *c1, OopClosure *c2);
207 template <class T> void do_oop_nv(T* p);
208 virtual void do_oop(oop* p) { do_oop_nv(p); }
209 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
210 };
212 // A closure that returns true if it is actually applied
213 // to a reference
215 class G1TriggerClosure : public ExtendedOopClosure {
216 bool _triggered;
217 public:
218 G1TriggerClosure();
219 bool triggered() const { return _triggered; }
220 template <class T> void do_oop_nv(T* p);
221 virtual void do_oop(oop* p) { do_oop_nv(p); }
222 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
223 };
225 // A closure which uses a triggering closure to determine
226 // whether to apply an oop closure.
228 class G1InvokeIfNotTriggeredClosure: public ExtendedOopClosure {
229 G1TriggerClosure* _trigger_cl;
230 OopClosure* _oop_cl;
231 public:
232 G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t, OopClosure* oc);
233 template <class T> void do_oop_nv(T* p);
234 virtual void do_oop(oop* p) { do_oop_nv(p); }
235 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
236 };
238 class G1UpdateRSOrPushRefOopClosure: public ExtendedOopClosure {
239 G1CollectedHeap* _g1;
240 G1RemSet* _g1_rem_set;
241 HeapRegion* _from;
242 OopsInHeapRegionClosure* _push_ref_cl;
243 bool _record_refs_into_cset;
244 uint _worker_i;
246 public:
247 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
248 G1RemSet* rs,
249 OopsInHeapRegionClosure* push_ref_cl,
250 bool record_refs_into_cset,
251 uint worker_i = 0);
253 void set_from(HeapRegion* from) {
254 assert(from != NULL, "from region must be non-NULL");
255 _from = from;
256 }
258 bool self_forwarded(oop obj) {
259 bool result = (obj->is_forwarded() && (obj->forwardee()== obj));
260 return result;
261 }
263 bool apply_to_weak_ref_discovered_field() { return true; }
265 template <class T> void do_oop_nv(T* p);
266 virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
267 virtual void do_oop(oop* p) { do_oop_nv(p); }
268 };
270 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP