2134 "Dead object referenced by a not dead object"); |
2134 "Dead object referenced by a not dead object"); |
2135 } |
2135 } |
2136 }; |
2136 }; |
2137 |
2137 |
2138 class VerifyObjsInRegionClosure: public ObjectClosure { |
2138 class VerifyObjsInRegionClosure: public ObjectClosure { |
|
2139 private: |
2139 G1CollectedHeap* _g1h; |
2140 G1CollectedHeap* _g1h; |
2140 size_t _live_bytes; |
2141 size_t _live_bytes; |
2141 HeapRegion *_hr; |
2142 HeapRegion *_hr; |
|
2143 bool _use_prev_marking; |
2142 public: |
2144 public: |
2143 VerifyObjsInRegionClosure(HeapRegion *hr) : _live_bytes(0), _hr(hr) { |
2145 // use_prev_marking == true -> use "prev" marking information, |
|
2146 // use_prev_marking == false -> use "next" marking information |
|
2147 VerifyObjsInRegionClosure(HeapRegion *hr, bool use_prev_marking) |
|
2148 : _live_bytes(0), _hr(hr), _use_prev_marking(use_prev_marking) { |
2144 _g1h = G1CollectedHeap::heap(); |
2149 _g1h = G1CollectedHeap::heap(); |
2145 } |
2150 } |
2146 void do_object(oop o) { |
2151 void do_object(oop o) { |
2147 VerifyLivenessOopClosure isLive(_g1h); |
2152 VerifyLivenessOopClosure isLive(_g1h); |
2148 assert(o != NULL, "Huh?"); |
2153 assert(o != NULL, "Huh?"); |
2149 if (!_g1h->is_obj_dead(o)) { |
2154 if (!_g1h->is_obj_dead_cond(o, _use_prev_marking)) { |
2150 o->oop_iterate(&isLive); |
2155 o->oop_iterate(&isLive); |
2151 if (!_hr->obj_allocated_since_prev_marking(o)) |
2156 if (!_hr->obj_allocated_since_prev_marking(o)) |
2152 _live_bytes += (o->size() * HeapWordSize); |
2157 _live_bytes += (o->size() * HeapWordSize); |
2153 } |
2158 } |
2154 } |
2159 } |
2183 } |
2188 } |
2184 } |
2189 } |
2185 }; |
2190 }; |
2186 |
2191 |
2187 class VerifyRegionClosure: public HeapRegionClosure { |
2192 class VerifyRegionClosure: public HeapRegionClosure { |
2188 public: |
2193 private: |
2189 bool _allow_dirty; |
2194 bool _allow_dirty; |
2190 bool _par; |
2195 bool _par; |
2191 VerifyRegionClosure(bool allow_dirty, bool par = false) |
2196 bool _use_prev_marking; |
2192 : _allow_dirty(allow_dirty), _par(par) {} |
2197 public: |
|
2198 // use_prev_marking == true -> use "prev" marking information, |
|
2199 // use_prev_marking == false -> use "next" marking information |
|
2200 VerifyRegionClosure(bool allow_dirty, bool par, bool use_prev_marking) |
|
2201 : _allow_dirty(allow_dirty), _par(par), |
|
2202 _use_prev_marking(use_prev_marking) {} |
2193 bool doHeapRegion(HeapRegion* r) { |
2203 bool doHeapRegion(HeapRegion* r) { |
2194 guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue, |
2204 guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue, |
2195 "Should be unclaimed at verify points."); |
2205 "Should be unclaimed at verify points."); |
2196 if (!r->continuesHumongous()) { |
2206 if (!r->continuesHumongous()) { |
2197 VerifyObjsInRegionClosure not_dead_yet_cl(r); |
2207 VerifyObjsInRegionClosure not_dead_yet_cl(r, _use_prev_marking); |
2198 r->verify(_allow_dirty); |
2208 r->verify(_allow_dirty, _use_prev_marking); |
2199 r->object_iterate(¬_dead_yet_cl); |
2209 r->object_iterate(¬_dead_yet_cl); |
2200 guarantee(r->max_live_bytes() >= not_dead_yet_cl.live_bytes(), |
2210 guarantee(r->max_live_bytes() >= not_dead_yet_cl.live_bytes(), |
2201 "More live objects than counted in last complete marking."); |
2211 "More live objects than counted in last complete marking."); |
2202 } |
2212 } |
2203 return false; |
2213 return false; |
2206 |
2216 |
2207 class VerifyRootsClosure: public OopsInGenClosure { |
2217 class VerifyRootsClosure: public OopsInGenClosure { |
2208 private: |
2218 private: |
2209 G1CollectedHeap* _g1h; |
2219 G1CollectedHeap* _g1h; |
2210 bool _failures; |
2220 bool _failures; |
2211 |
2221 bool _use_prev_marking; |
2212 public: |
2222 public: |
2213 VerifyRootsClosure() : |
2223 // use_prev_marking == true -> use "prev" marking information, |
2214 _g1h(G1CollectedHeap::heap()), _failures(false) { } |
2224 // use_prev_marking == false -> use "next" marking information |
|
2225 VerifyRootsClosure(bool use_prev_marking) : |
|
2226 _g1h(G1CollectedHeap::heap()), _failures(false), |
|
2227 _use_prev_marking(use_prev_marking) { } |
2215 |
2228 |
2216 bool failures() { return _failures; } |
2229 bool failures() { return _failures; } |
2217 |
2230 |
2218 void do_oop(narrowOop* p) { |
2231 void do_oop(narrowOop* p) { |
2219 guarantee(false, "NYI"); |
2232 guarantee(false, "NYI"); |
2220 } |
2233 } |
2221 |
2234 |
2222 void do_oop(oop* p) { |
2235 void do_oop(oop* p) { |
2223 oop obj = *p; |
2236 oop obj = *p; |
2224 if (obj != NULL) { |
2237 if (obj != NULL) { |
2225 if (_g1h->is_obj_dead(obj)) { |
2238 if (_g1h->is_obj_dead_cond(obj, _use_prev_marking)) { |
2226 gclog_or_tty->print_cr("Root location "PTR_FORMAT" " |
2239 gclog_or_tty->print_cr("Root location "PTR_FORMAT" " |
2227 "points to dead obj "PTR_FORMAT, p, (void*) obj); |
2240 "points to dead obj "PTR_FORMAT, p, (void*) obj); |
2228 obj->print_on(gclog_or_tty); |
2241 obj->print_on(gclog_or_tty); |
2229 _failures = true; |
2242 _failures = true; |
2230 } |
2243 } |
2236 |
2249 |
2237 class G1ParVerifyTask: public AbstractGangTask { |
2250 class G1ParVerifyTask: public AbstractGangTask { |
2238 private: |
2251 private: |
2239 G1CollectedHeap* _g1h; |
2252 G1CollectedHeap* _g1h; |
2240 bool _allow_dirty; |
2253 bool _allow_dirty; |
|
2254 bool _use_prev_marking; |
2241 |
2255 |
2242 public: |
2256 public: |
2243 G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty) : |
2257 // use_prev_marking == true -> use "prev" marking information, |
|
2258 // use_prev_marking == false -> use "next" marking information |
|
2259 G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty, |
|
2260 bool use_prev_marking) : |
2244 AbstractGangTask("Parallel verify task"), |
2261 AbstractGangTask("Parallel verify task"), |
2245 _g1h(g1h), _allow_dirty(allow_dirty) { } |
2262 _g1h(g1h), _allow_dirty(allow_dirty), |
|
2263 _use_prev_marking(use_prev_marking) { } |
2246 |
2264 |
2247 void work(int worker_i) { |
2265 void work(int worker_i) { |
2248 HandleMark hm; |
2266 HandleMark hm; |
2249 VerifyRegionClosure blk(_allow_dirty, true); |
2267 VerifyRegionClosure blk(_allow_dirty, true, _use_prev_marking); |
2250 _g1h->heap_region_par_iterate_chunked(&blk, worker_i, |
2268 _g1h->heap_region_par_iterate_chunked(&blk, worker_i, |
2251 HeapRegion::ParVerifyClaimValue); |
2269 HeapRegion::ParVerifyClaimValue); |
2252 } |
2270 } |
2253 }; |
2271 }; |
2254 |
2272 |
2255 void G1CollectedHeap::verify(bool allow_dirty, bool silent) { |
2273 void G1CollectedHeap::verify(bool allow_dirty, bool silent) { |
|
2274 verify(allow_dirty, silent, /* use_prev_marking */ true); |
|
2275 } |
|
2276 |
|
2277 void G1CollectedHeap::verify(bool allow_dirty, |
|
2278 bool silent, |
|
2279 bool use_prev_marking) { |
2256 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { |
2280 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { |
2257 if (!silent) { gclog_or_tty->print("roots "); } |
2281 if (!silent) { gclog_or_tty->print("roots "); } |
2258 VerifyRootsClosure rootsCl; |
2282 VerifyRootsClosure rootsCl(use_prev_marking); |
2259 process_strong_roots(false, |
2283 process_strong_roots(false, |
2260 SharedHeap::SO_AllClasses, |
2284 SharedHeap::SO_AllClasses, |
2261 &rootsCl, |
2285 &rootsCl, |
2262 &rootsCl); |
2286 &rootsCl); |
2263 rem_set()->invalidate(perm_gen()->used_region(), false); |
2287 rem_set()->invalidate(perm_gen()->used_region(), false); |
2264 if (!silent) { gclog_or_tty->print("heapRegions "); } |
2288 if (!silent) { gclog_or_tty->print("heapRegions "); } |
2265 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
2289 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
2266 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), |
2290 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), |
2267 "sanity check"); |
2291 "sanity check"); |
2268 |
2292 |
2269 G1ParVerifyTask task(this, allow_dirty); |
2293 G1ParVerifyTask task(this, allow_dirty, use_prev_marking); |
2270 int n_workers = workers()->total_workers(); |
2294 int n_workers = workers()->total_workers(); |
2271 set_par_threads(n_workers); |
2295 set_par_threads(n_workers); |
2272 workers()->run_task(&task); |
2296 workers()->run_task(&task); |
2273 set_par_threads(0); |
2297 set_par_threads(0); |
2274 |
2298 |
2278 reset_heap_region_claim_values(); |
2302 reset_heap_region_claim_values(); |
2279 |
2303 |
2280 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), |
2304 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), |
2281 "sanity check"); |
2305 "sanity check"); |
2282 } else { |
2306 } else { |
2283 VerifyRegionClosure blk(allow_dirty); |
2307 VerifyRegionClosure blk(allow_dirty, false, use_prev_marking); |
2284 _hrs->iterate(&blk); |
2308 _hrs->iterate(&blk); |
2285 } |
2309 } |
2286 if (!silent) gclog_or_tty->print("remset "); |
2310 if (!silent) gclog_or_tty->print("remset "); |
2287 rem_set()->verify(); |
2311 rem_set()->verify(); |
2288 guarantee(!rootsCl.failures(), "should not have had failures"); |
2312 guarantee(!rootsCl.failures(), "should not have had failures"); |