comparison src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp @ 20804:7848fc12602b

Merge with jdk8u40-b25
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Tue, 07 Apr 2015 14:58:49 +0200
parents 52b4284cb496 eec72fa4b108
children dd9cc155639c
comparison
equal deleted inserted replaced
20184:84105dcdb05b 20804:7848fc12602b
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_INLINE_HPP 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_INLINE_HPP
27 27
28 #include "gc_implementation/g1/concurrentMark.inline.hpp" 28 #include "gc_implementation/g1/concurrentMark.inline.hpp"
29 #include "gc_implementation/g1/g1CollectedHeap.hpp" 29 #include "gc_implementation/g1/g1CollectedHeap.hpp"
30 #include "gc_implementation/g1/g1OopClosures.hpp" 30 #include "gc_implementation/g1/g1OopClosures.hpp"
31 #include "gc_implementation/g1/g1ParScanThreadState.inline.hpp"
31 #include "gc_implementation/g1/g1RemSet.hpp" 32 #include "gc_implementation/g1/g1RemSet.hpp"
32 #include "gc_implementation/g1/g1RemSet.inline.hpp" 33 #include "gc_implementation/g1/g1RemSet.inline.hpp"
33 #include "gc_implementation/g1/heapRegionRemSet.hpp" 34 #include "gc_implementation/g1/heapRegionRemSet.hpp"
35 #include "memory/iterator.inline.hpp"
36 #include "runtime/prefetch.inline.hpp"
34 37
35 /* 38 /*
36 * This really ought to be an inline function, but apparently the C++ 39 * This really ought to be an inline function, but apparently the C++
37 * compiler sometimes sees fit to ignore inline declarations. Sigh. 40 * compiler sometimes sees fit to ignore inline declarations. Sigh.
38 */ 41 */
39 42
40 template <class T> 43 template <class T>
41 inline void FilterIntoCSClosure::do_oop_nv(T* p) { 44 inline void FilterIntoCSClosure::do_oop_nv(T* p) {
42 T heap_oop = oopDesc::load_heap_oop(p); 45 T heap_oop = oopDesc::load_heap_oop(p);
43 if (!oopDesc::is_null(heap_oop) && 46 if (!oopDesc::is_null(heap_oop) &&
44 _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) { 47 _g1->is_in_cset_or_humongous(oopDesc::decode_heap_oop_not_null(heap_oop))) {
45 _oc->do_oop(p); 48 _oc->do_oop(p);
46 } 49 }
47 } 50 }
48 51
49 template <class T> 52 template <class T>
62 inline void G1ParScanClosure::do_oop_nv(T* p) { 65 inline void G1ParScanClosure::do_oop_nv(T* p) {
63 T heap_oop = oopDesc::load_heap_oop(p); 66 T heap_oop = oopDesc::load_heap_oop(p);
64 67
65 if (!oopDesc::is_null(heap_oop)) { 68 if (!oopDesc::is_null(heap_oop)) {
66 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); 69 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
67 if (_g1->in_cset_fast_test(obj)) { 70 G1CollectedHeap::in_cset_state_t state = _g1->in_cset_state(obj);
71 if (state == G1CollectedHeap::InCSet) {
68 // We're not going to even bother checking whether the object is 72 // We're not going to even bother checking whether the object is
69 // already forwarded or not, as this usually causes an immediate 73 // already forwarded or not, as this usually causes an immediate
70 // stall. We'll try to prefetch the object (for write, given that 74 // stall. We'll try to prefetch the object (for write, given that
71 // we might need to install the forwarding reference) and we'll 75 // we might need to install the forwarding reference) and we'll
72 // get back to it when pop it from the queue 76 // get back to it when pop it from the queue
81 obj->forwardee() == oopDesc::load_decode_heap_oop(p)), 85 obj->forwardee() == oopDesc::load_decode_heap_oop(p)),
82 "p should still be pointing to obj or to its forwardee"); 86 "p should still be pointing to obj or to its forwardee");
83 87
84 _par_scan_state->push_on_queue(p); 88 _par_scan_state->push_on_queue(p);
85 } else { 89 } else {
90 if (state == G1CollectedHeap::IsHumongous) {
91 _g1->set_humongous_is_live(obj);
92 }
86 _par_scan_state->update_rs(_from, p, _worker_id); 93 _par_scan_state->update_rs(_from, p, _worker_id);
87 } 94 }
88 } 95 }
89 } 96 }
90 97
92 inline void G1ParPushHeapRSClosure::do_oop_nv(T* p) { 99 inline void G1ParPushHeapRSClosure::do_oop_nv(T* p) {
93 T heap_oop = oopDesc::load_heap_oop(p); 100 T heap_oop = oopDesc::load_heap_oop(p);
94 101
95 if (!oopDesc::is_null(heap_oop)) { 102 if (!oopDesc::is_null(heap_oop)) {
96 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); 103 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
97 if (_g1->in_cset_fast_test(obj)) { 104 if (_g1->is_in_cset_or_humongous(obj)) {
98 Prefetch::write(obj->mark_addr(), 0); 105 Prefetch::write(obj->mark_addr(), 0);
99 Prefetch::read(obj->mark_addr(), (HeapWordSize*2)); 106 Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
100 107
101 // Place on the references queue 108 // Place on the references queue
102 _par_scan_state->push_on_queue(p); 109 _par_scan_state->push_on_queue(p);
110 } else {
111 assert(!_g1->obj_in_cs(obj), "checking");
103 } 112 }
104 } 113 }
105 } 114 }
106 115
107 template <class T> 116 template <class T>
108 inline void G1CMOopClosure::do_oop_nv(T* p) { 117 inline void G1CMOopClosure::do_oop_nv(T* p) {
109 assert(_g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
110 assert(!_g1h->is_on_master_free_list(
111 _g1h->heap_region_containing((HeapWord*) p)), "invariant");
112
113 oop obj = oopDesc::load_decode_heap_oop(p); 118 oop obj = oopDesc::load_decode_heap_oop(p);
114 if (_cm->verbose_high()) { 119 if (_cm->verbose_high()) {
115 gclog_or_tty->print_cr("[%u] we're looking at location " 120 gclog_or_tty->print_cr("[%u] we're looking at location "
116 "*"PTR_FORMAT" = "PTR_FORMAT, 121 "*"PTR_FORMAT" = "PTR_FORMAT,
117 _task->worker_id(), p2i(p), p2i((void*) obj)); 122 _task->worker_id(), p2i(p), p2i((void*) obj));
123 inline void G1RootRegionScanClosure::do_oop_nv(T* p) { 128 inline void G1RootRegionScanClosure::do_oop_nv(T* p) {
124 T heap_oop = oopDesc::load_heap_oop(p); 129 T heap_oop = oopDesc::load_heap_oop(p);
125 if (!oopDesc::is_null(heap_oop)) { 130 if (!oopDesc::is_null(heap_oop)) {
126 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); 131 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
127 HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj); 132 HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj);
128 if (hr != NULL) { 133 _cm->grayRoot(obj, obj->size(), _worker_id, hr);
129 _cm->grayRoot(obj, obj->size(), _worker_id, hr);
130 }
131 } 134 }
132 } 135 }
133 136
134 template <class T> 137 template <class T>
135 inline void G1Mux2Closure::do_oop_nv(T* p) { 138 inline void G1Mux2Closure::do_oop_nv(T* p) {
152 } 155 }
153 156
154 template <class T> 157 template <class T>
155 inline void G1UpdateRSOrPushRefOopClosure::do_oop_nv(T* p) { 158 inline void G1UpdateRSOrPushRefOopClosure::do_oop_nv(T* p) {
156 oop obj = oopDesc::load_decode_heap_oop(p); 159 oop obj = oopDesc::load_decode_heap_oop(p);
160 if (obj == NULL) {
161 return;
162 }
157 #ifdef ASSERT 163 #ifdef ASSERT
158 // can't do because of races 164 // can't do because of races
159 // assert(obj == NULL || obj->is_oop(), "expected an oop"); 165 // assert(obj == NULL || obj->is_oop(), "expected an oop");
160 166
161 // Do the safe subset of is_oop 167 // Do the safe subset of is_oop
162 if (obj != NULL) {
163 #ifdef CHECK_UNHANDLED_OOPS 168 #ifdef CHECK_UNHANDLED_OOPS
164 oopDesc* o = obj.obj(); 169 oopDesc* o = obj.obj();
165 #else 170 #else
166 oopDesc* o = obj; 171 oopDesc* o = obj;
167 #endif // CHECK_UNHANDLED_OOPS 172 #endif // CHECK_UNHANDLED_OOPS
168 assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned"); 173 assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
169 assert(Universe::heap()->is_in_reserved(obj), "must be in heap"); 174 assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
170 }
171 #endif // ASSERT 175 #endif // ASSERT
172 176
173 assert(_from != NULL, "from region must be non-NULL"); 177 assert(_from != NULL, "from region must be non-NULL");
174 assert(_from->is_in_reserved(p), "p is not in from"); 178 assert(_from->is_in_reserved(p), "p is not in from");
175 179
176 HeapRegion* to = _g1->heap_region_containing(obj); 180 HeapRegion* to = _g1->heap_region_containing(obj);
177 if (to != NULL && _from != to) { 181 if (_from == to) {
178 // The _record_refs_into_cset flag is true during the RSet 182 // Normally this closure should only be called with cross-region references.
179 // updating part of an evacuation pause. It is false at all 183 // But since Java threads are manipulating the references concurrently and we
180 // other times: 184 // reload the values things may have changed.
181 // * rebuilding the rembered sets after a full GC 185 return;
182 // * during concurrent refinement. 186 }
183 // * updating the remembered sets of regions in the collection 187 // The _record_refs_into_cset flag is true during the RSet
184 // set in the event of an evacuation failure (when deferred 188 // updating part of an evacuation pause. It is false at all
185 // updates are enabled). 189 // other times:
186 190 // * rebuilding the remembered sets after a full GC
187 if (_record_refs_into_cset && to->in_collection_set()) { 191 // * during concurrent refinement.
188 // We are recording references that point into the collection 192 // * updating the remembered sets of regions in the collection
189 // set and this particular reference does exactly that... 193 // set in the event of an evacuation failure (when deferred
190 // If the referenced object has already been forwarded 194 // updates are enabled).
191 // to itself, we are handling an evacuation failure and 195
192 // we have already visited/tried to copy this object 196 if (_record_refs_into_cset && to->in_collection_set()) {
193 // there is no need to retry. 197 // We are recording references that point into the collection
194 if (!self_forwarded(obj)) { 198 // set and this particular reference does exactly that...
195 assert(_push_ref_cl != NULL, "should not be null"); 199 // If the referenced object has already been forwarded
196 // Push the reference in the refs queue of the G1ParScanThreadState 200 // to itself, we are handling an evacuation failure and
197 // instance for this worker thread. 201 // we have already visited/tried to copy this object
198 _push_ref_cl->do_oop(p); 202 // there is no need to retry.
199 } 203 if (!self_forwarded(obj)) {
200 204 assert(_push_ref_cl != NULL, "should not be null");
201 // Deferred updates to the CSet are either discarded (in the normal case), 205 // Push the reference in the refs queue of the G1ParScanThreadState
202 // or processed (if an evacuation failure occurs) at the end 206 // instance for this worker thread.
203 // of the collection. 207 _push_ref_cl->do_oop(p);
204 // See G1RemSet::cleanup_after_oops_into_collection_set_do(). 208 }
205 return; 209
206 } 210 // Deferred updates to the CSet are either discarded (in the normal case),
207 211 // or processed (if an evacuation failure occurs) at the end
212 // of the collection.
213 // See G1RemSet::cleanup_after_oops_into_collection_set_do().
214 } else {
208 // We either don't care about pushing references that point into the 215 // We either don't care about pushing references that point into the
209 // collection set (i.e. we're not during an evacuation pause) _or_ 216 // collection set (i.e. we're not during an evacuation pause) _or_
210 // the reference doesn't point into the collection set. Either way 217 // the reference doesn't point into the collection set. Either way
211 // we add the reference directly to the RSet of the region containing 218 // we add the reference directly to the RSet of the region containing
212 // the referenced object. 219 // the referenced object.