Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/g1/satbQueue.cpp @ 23027:2e5e058881f4
8075466: SATB queue pre-filter verify found reclaimed humongous object
Summary: Removed pre-filter verify, and made filtering more careful.
Reviewed-by: brutisso, tschatzl
author | kbarrett |
---|---|
date | Wed, 15 Apr 2015 16:37:57 -0400 |
parents | c2844108a708 |
children | b5d14ef905b5 |
comparison
equal
deleted
inserted
replaced
23026:b7c8142a9e0b | 23027:2e5e058881f4 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2015, 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. |
33 #include "runtime/vmThread.hpp" | 33 #include "runtime/vmThread.hpp" |
34 | 34 |
35 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC | 35 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
36 | 36 |
37 void ObjPtrQueue::flush() { | 37 void ObjPtrQueue::flush() { |
38 // The buffer might contain refs into the CSet. We have to filter it | 38 // Filter now to possibly save work later. If filtering empties the |
39 // first before we flush it, otherwise we might end up with an | 39 // buffer then flush_impl can deallocate the buffer. |
40 // enqueued buffer with refs into the CSet which breaks our invariants. | |
41 filter(); | 40 filter(); |
42 flush_impl(); | 41 flush_impl(); |
43 } | 42 } |
44 | 43 |
45 // This method removes entries from an SATB buffer that will not be | 44 // Return true if a SATB buffer entry refers to an object that |
46 // useful to the concurrent marking threads. An entry is removed if it | 45 // requires marking. |
47 // satisfies one of the following conditions: | 46 // |
48 // | 47 // The entry must point into the G1 heap. In particular, it must not |
49 // * it points to an object outside the G1 heap (G1's concurrent | 48 // be a NULL pointer. NULL pointers are pre-filtered and never |
50 // marking only visits objects inside the G1 heap), | 49 // inserted into a SATB buffer. |
51 // * it points to an object that has been allocated since marking | 50 // |
52 // started (according to SATB those objects do not need to be | 51 // An entry that is below the NTAMS pointer for the containing heap |
53 // visited during marking), or | 52 // region requires marking. Such an entry must point to a valid object. |
54 // * it points to an object that has already been marked (no need to | 53 // |
55 // process it again). | 54 // An entry that is at least the NTAMS pointer for the containing heap |
56 // | 55 // region might be any of the following, none of which should be marked. |
57 // The rest of the entries will be retained and are compacted towards | 56 // |
58 // the top of the buffer. Note that, because we do not allow old | 57 // * A reference to an object allocated since marking started. |
59 // regions in the CSet during marking, all objects on the CSet regions | 58 // According to SATB, such objects are implicitly kept live and do |
60 // are young (eden or survivors) and therefore implicitly live. So any | 59 // not need to be dealt with via SATB buffer processing. |
61 // references into the CSet will be removed during filtering. | 60 // |
61 // * A reference to a young generation object. Young objects are | |
62 // handled separately and are not marked by concurrent marking. | |
63 // | |
64 // * A stale reference to a young generation object. If a young | |
65 // generation object reference is recorded and not filtered out | |
66 // before being moved by a young collection, the reference becomes | |
67 // stale. | |
68 // | |
69 // * A stale reference to an eagerly reclaimed humongous object. If a | |
70 // humongous object is recorded and then reclaimed, the reference | |
71 // becomes stale. | |
72 // | |
73 // The stale reference cases are implicitly handled by the NTAMS | |
74 // comparison. Because of the possibility of stale references, buffer | |
75 // processing must be somewhat circumspect and not assume entries | |
76 // in an unfiltered buffer refer to valid objects. | |
77 | |
78 inline bool requires_marking(const void* entry, G1CollectedHeap* heap) { | |
79 // Includes rejection of NULL pointers. | |
80 assert(heap->is_in_reserved(entry), | |
81 err_msg("Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry))); | |
82 | |
83 HeapRegion* region = heap->heap_region_containing_raw(entry); | |
84 assert(region != NULL, err_msg("No region for " PTR_FORMAT, p2i(entry))); | |
85 if (entry >= region->next_top_at_mark_start()) { | |
86 return false; | |
87 } | |
88 | |
89 assert(((oop)entry)->is_oop(true /* ignore mark word */), | |
90 err_msg("Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry))); | |
91 | |
92 return true; | |
93 } | |
94 | |
95 // This method removes entries from a SATB buffer that will not be | |
96 // useful to the concurrent marking threads. Entries are retained if | |
97 // they require marking and are not already marked. Retained entries | |
98 // are compacted toward the top of the buffer. | |
62 | 99 |
63 void ObjPtrQueue::filter() { | 100 void ObjPtrQueue::filter() { |
64 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | 101 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
65 void** buf = _buf; | 102 void** buf = _buf; |
66 size_t sz = _sz; | 103 size_t sz = _sz; |
78 | 115 |
79 while (i > _index) { | 116 while (i > _index) { |
80 assert(i > 0, "we should have at least one more entry to process"); | 117 assert(i > 0, "we should have at least one more entry to process"); |
81 i -= oopSize; | 118 i -= oopSize; |
82 debug_only(entries += 1;) | 119 debug_only(entries += 1;) |
83 oop* p = (oop*) &buf[byte_index_to_index((int) i)]; | 120 void** p = &buf[byte_index_to_index((int) i)]; |
84 oop obj = *p; | 121 void* entry = *p; |
85 // NULL the entry so that unused parts of the buffer contain NULLs | 122 // NULL the entry so that unused parts of the buffer contain NULLs |
86 // at the end. If we are going to retain it we will copy it to its | 123 // at the end. If we are going to retain it we will copy it to its |
87 // final place. If we have retained all entries we have visited so | 124 // final place. If we have retained all entries we have visited so |
88 // far, we'll just end up copying it to the same place. | 125 // far, we'll just end up copying it to the same place. |
89 *p = NULL; | 126 *p = NULL; |
90 | 127 |
91 bool retain = g1h->is_obj_ill(obj); | 128 if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) { |
92 if (retain) { | |
93 assert(new_index > 0, "we should not have already filled up the buffer"); | 129 assert(new_index > 0, "we should not have already filled up the buffer"); |
94 new_index -= oopSize; | 130 new_index -= oopSize; |
95 assert(new_index >= i, | 131 assert(new_index >= i, |
96 "new_index should never be below i, as we alwaysr compact 'up'"); | 132 "new_index should never be below i, as we alwaysr compact 'up'"); |
97 oop* new_p = (oop*) &buf[byte_index_to_index((int) new_index)]; | 133 void** new_p = &buf[byte_index_to_index((int) new_index)]; |
98 assert(new_p >= p, "the destination location should never be below " | 134 assert(new_p >= p, "the destination location should never be below " |
99 "the source as we always compact 'up'"); | 135 "the source as we always compact 'up'"); |
100 assert(*new_p == NULL, | 136 assert(*new_p == NULL, |
101 "we should have already cleared the destination location"); | 137 "we should have already cleared the destination location"); |
102 *new_p = obj; | 138 *new_p = entry; |
103 debug_only(retained += 1;) | 139 debug_only(retained += 1;) |
104 } | 140 } |
105 } | 141 } |
106 | 142 |
107 #ifdef ASSERT | 143 #ifdef ASSERT |
184 "index: "SIZE_FORMAT" sz: "SIZE_FORMAT, | 220 "index: "SIZE_FORMAT" sz: "SIZE_FORMAT, |
185 name, buf, index, sz); | 221 name, buf, index, sz); |
186 } | 222 } |
187 #endif // PRODUCT | 223 #endif // PRODUCT |
188 | 224 |
189 #ifdef ASSERT | |
190 void ObjPtrQueue::verify_oops_in_buffer() { | |
191 if (_buf == NULL) return; | |
192 for (size_t i = _index; i < _sz; i += oopSize) { | |
193 oop obj = (oop)_buf[byte_index_to_index((int)i)]; | |
194 assert(obj != NULL && obj->is_oop(true /* ignore mark word */), | |
195 "Not an oop"); | |
196 } | |
197 } | |
198 #endif | |
199 | |
200 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | 225 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away |
201 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | 226 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
202 #endif // _MSC_VER | 227 #endif // _MSC_VER |
203 | 228 |
204 SATBMarkQueueSet::SATBMarkQueueSet() : | 229 SATBMarkQueueSet::SATBMarkQueueSet() : |
214 _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC); | 239 _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC); |
215 } | 240 } |
216 } | 241 } |
217 | 242 |
218 void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) { | 243 void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) { |
219 DEBUG_ONLY(t->satb_mark_queue().verify_oops_in_buffer();) | |
220 t->satb_mark_queue().handle_zero_index(); | 244 t->satb_mark_queue().handle_zero_index(); |
221 } | 245 } |
222 | 246 |
223 #ifdef ASSERT | 247 #ifdef ASSERT |
224 void SATBMarkQueueSet::dump_active_states(bool expected_active) { | 248 void SATBMarkQueueSet::dump_active_states(bool expected_active) { |