comparison src/share/vm/gc_interface/collectedHeap.cpp @ 1027:39b01ab7035a

6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning 6889757: G1: enable card mark elision for initializing writes from compiled code (ReduceInitialCardMarks) Summary: Defer the (compiler-elided) card-mark upon a slow-path allocation until after the store and before the next subsequent safepoint; G1 now answers yes to can_elide_tlab_write_barriers(). Reviewed-by: jcoomes, kvn, never
author ysr
date Fri, 16 Oct 2009 02:05:46 -0700
parents 7bb995fbd3c0
children 4ce7240d622c
comparison
equal deleted inserted replaced
1025:1ee412f7fec9 1027:39b01ab7035a
135 } 135 }
136 thread->tlab().fill(obj, obj + size, new_tlab_size); 136 thread->tlab().fill(obj, obj + size, new_tlab_size);
137 return obj; 137 return obj;
138 } 138 }
139 139
140 void CollectedHeap::flush_deferred_store_barrier(JavaThread* thread) {
141 MemRegion deferred = thread->deferred_card_mark();
142 if (!deferred.is_empty()) {
143 {
144 // Verify that the storage points to a parsable object in heap
145 DEBUG_ONLY(oop old_obj = oop(deferred.start());)
146 assert(is_in(old_obj), "Not in allocated heap");
147 assert(!can_elide_initializing_store_barrier(old_obj),
148 "Else should have been filtered in defer_store_barrier()");
149 assert(!is_in_permanent(old_obj), "Sanity: not expected");
150 assert(old_obj->is_oop(true), "Not an oop");
151 assert(old_obj->is_parsable(), "Will not be concurrently parsable");
152 assert(deferred.word_size() == (size_t)(old_obj->size()),
153 "Mismatch: multiple objects?");
154 }
155 BarrierSet* bs = barrier_set();
156 assert(bs->has_write_region_opt(), "No write_region() on BarrierSet");
157 bs->write_region(deferred);
158 // "Clear" the deferred_card_mark field
159 thread->set_deferred_card_mark(MemRegion());
160 }
161 assert(thread->deferred_card_mark().is_empty(), "invariant");
162 }
163
164 // Helper for ReduceInitialCardMarks. For performance,
165 // compiled code may elide card-marks for initializing stores
166 // to a newly allocated object along the fast-path. We
167 // compensate for such elided card-marks as follows:
168 // (a) Generational, non-concurrent collectors, such as
169 // GenCollectedHeap(ParNew,DefNew,Tenured) and
170 // ParallelScavengeHeap(ParallelGC, ParallelOldGC)
171 // need the card-mark if and only if the region is
172 // in the old gen, and do not care if the card-mark
173 // succeeds or precedes the initializing stores themselves,
174 // so long as the card-mark is completed before the next
175 // scavenge. For all these cases, we can do a card mark
176 // at the point at which we do a slow path allocation
177 // in the old gen. For uniformity, however, we end
178 // up using the same scheme (see below) for all three
179 // cases (deferring the card-mark appropriately).
180 // (b) GenCollectedHeap(ConcurrentMarkSweepGeneration) requires
181 // in addition that the card-mark for an old gen allocated
182 // object strictly follow any associated initializing stores.
183 // In these cases, the memRegion remembered below is
184 // used to card-mark the entire region either just before the next
185 // slow-path allocation by this thread or just before the next scavenge or
186 // CMS-associated safepoint, whichever of these events happens first.
187 // (The implicit assumption is that the object has been fully
188 // initialized by this point, a fact that we assert when doing the
189 // card-mark.)
190 // (c) G1CollectedHeap(G1) uses two kinds of write barriers. When a
191 // G1 concurrent marking is in progress an SATB (pre-write-)barrier is
192 // is used to remember the pre-value of any store. Initializing
193 // stores will not need this barrier, so we need not worry about
194 // compensating for the missing pre-barrier here. Turning now
195 // to the post-barrier, we note that G1 needs a RS update barrier
196 // which simply enqueues a (sequence of) dirty cards which may
197 // optionally be refined by the concurrent update threads. Note
198 // that this barrier need only be applied to a non-young write,
199 // but, like in CMS, because of the presence of concurrent refinement
200 // (much like CMS' precleaning), must strictly follow the oop-store.
201 // Thus, using the same protocol for maintaining the intended
202 // invariants turns out, serendepitously, to be the same for all
203 // three collectors/heap types above.
204 //
205 // For each future collector, this should be reexamined with
206 // that specific collector in mind.
207 oop CollectedHeap::defer_store_barrier(JavaThread* thread, oop new_obj) {
208 // If a previous card-mark was deferred, flush it now.
209 flush_deferred_store_barrier(thread);
210 if (can_elide_initializing_store_barrier(new_obj)) {
211 // The deferred_card_mark region should be empty
212 // following the flush above.
213 assert(thread->deferred_card_mark().is_empty(), "Error");
214 } else {
215 // Remember info for the newly deferred store barrier
216 MemRegion deferred = MemRegion((HeapWord*)new_obj, new_obj->size());
217 assert(!deferred.is_empty(), "Error");
218 thread->set_deferred_card_mark(deferred);
219 }
220 return new_obj;
221 }
222
140 size_t CollectedHeap::filler_array_hdr_size() { 223 size_t CollectedHeap::filler_array_hdr_size() {
141 return size_t(arrayOopDesc::header_size(T_INT)); 224 return size_t(arrayOopDesc::header_size(T_INT));
142 } 225 }
143 226
144 size_t CollectedHeap::filler_array_min_size() { 227 size_t CollectedHeap::filler_array_min_size() {
221 words -= cur; 304 words -= cur;
222 } 305 }
223 #endif 306 #endif
224 307
225 fill_with_object_impl(start, words); 308 fill_with_object_impl(start, words);
226 }
227
228 oop CollectedHeap::new_store_barrier(oop new_obj) {
229 // %%% This needs refactoring. (It was imported from the server compiler.)
230 guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported");
231 BarrierSet* bs = this->barrier_set();
232 assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
233 int new_size = new_obj->size();
234 bs->write_region(MemRegion((HeapWord*)new_obj, new_size));
235 return new_obj;
236 } 309 }
237 310
238 HeapWord* CollectedHeap::allocate_new_tlab(size_t size) { 311 HeapWord* CollectedHeap::allocate_new_tlab(size_t size) {
239 guarantee(false, "thread-local allocation buffers not supported"); 312 guarantee(false, "thread-local allocation buffers not supported");
240 return NULL; 313 return NULL;