comparison src/share/vm/gc_implementation/g1/concurrentMark.cpp @ 3975:1847b501ae74

7068215: G1: Print reference processing time during remark Summary: Displays the elapsed time taken to perform reference processing during remark as part of the PrintGCDetails output. Reviewed-by: ysr
author johnc
date Wed, 21 Sep 2011 10:04:45 -0700
parents 20213c8a3c40
children 5cc33133bc6d
comparison
equal deleted inserted replaced
3974:114e52976463 3975:1847b501ae74
2161 } 2161 }
2162 2162
2163 void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { 2163 void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
2164 ResourceMark rm; 2164 ResourceMark rm;
2165 HandleMark hm; 2165 HandleMark hm;
2166 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 2166
2167 ReferenceProcessor* rp = g1h->ref_processor(); 2167 G1CollectedHeap* g1h = G1CollectedHeap::heap();
2168 2168
2169 // See the comment in G1CollectedHeap::ref_processing_init() 2169 // Is alive closure.
2170 // about how reference processing currently works in G1. 2170 G1CMIsAliveClosure g1_is_alive(g1h);
2171 2171
2172 // Process weak references. 2172 // Inner scope to exclude the cleaning of the string and symbol
2173 rp->setup_policy(clear_all_soft_refs); 2173 // tables from the displayed time.
2174 assert(_markStack.isEmpty(), "mark stack should be empty"); 2174 {
2175 2175 bool verbose = PrintGC && PrintGCDetails;
2176 G1CMIsAliveClosure g1_is_alive(g1h); 2176 if (verbose) {
2177 G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap()); 2177 gclog_or_tty->put(' ');
2178 G1CMDrainMarkingStackClosure 2178 }
2179 g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive); 2179 TraceTime t("GC ref-proc", verbose, false, gclog_or_tty);
2180 // We use the work gang from the G1CollectedHeap and we utilize all 2180
2181 // the worker threads. 2181 ReferenceProcessor* rp = g1h->ref_processor();
2182 int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1; 2182
2183 active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1); 2183 // See the comment in G1CollectedHeap::ref_processing_init()
2184 2184 // about how reference processing currently works in G1.
2185 G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(), 2185
2186 g1h->workers(), active_workers); 2186 // Process weak references.
2187 2187 rp->setup_policy(clear_all_soft_refs);
2188 2188 assert(_markStack.isEmpty(), "mark stack should be empty");
2189 if (rp->processing_is_mt()) { 2189
2190 // Set the degree of MT here. If the discovery is done MT, there 2190 G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
2191 // may have been a different number of threads doing the discovery 2191 G1CMDrainMarkingStackClosure
2192 // and a different number of discovered lists may have Ref objects. 2192 g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
2193 // That is OK as long as the Reference lists are balanced (see 2193
2194 // balance_all_queues() and balance_queues()). 2194 // We use the work gang from the G1CollectedHeap and we utilize all
2195 rp->set_active_mt_degree(active_workers); 2195 // the worker threads.
2196 2196 int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1;
2197 rp->process_discovered_references(&g1_is_alive, 2197 active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1);
2198
2199 G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(),
2200 g1h->workers(), active_workers);
2201
2202 if (rp->processing_is_mt()) {
2203 // Set the degree of MT here. If the discovery is done MT, there
2204 // may have been a different number of threads doing the discovery
2205 // and a different number of discovered lists may have Ref objects.
2206 // That is OK as long as the Reference lists are balanced (see
2207 // balance_all_queues() and balance_queues()).
2208 rp->set_active_mt_degree(active_workers);
2209
2210 rp->process_discovered_references(&g1_is_alive,
2198 &g1_keep_alive, 2211 &g1_keep_alive,
2199 &g1_drain_mark_stack, 2212 &g1_drain_mark_stack,
2200 &par_task_executor); 2213 &par_task_executor);
2201 2214
2202 // The work routines of the parallel keep_alive and drain_marking_stack 2215 // The work routines of the parallel keep_alive and drain_marking_stack
2203 // will set the has_overflown flag if we overflow the global marking 2216 // will set the has_overflown flag if we overflow the global marking
2204 // stack. 2217 // stack.
2205 } else { 2218 } else {
2206 rp->process_discovered_references(&g1_is_alive, 2219 rp->process_discovered_references(&g1_is_alive,
2207 &g1_keep_alive, 2220 &g1_keep_alive,
2208 &g1_drain_mark_stack, 2221 &g1_drain_mark_stack,
2209 NULL); 2222 NULL);
2210 2223 }
2211 } 2224
2212 2225 assert(_markStack.overflow() || _markStack.isEmpty(),
2213 assert(_markStack.overflow() || _markStack.isEmpty(), 2226 "mark stack should be empty (unless it overflowed)");
2214 "mark stack should be empty (unless it overflowed)"); 2227 if (_markStack.overflow()) {
2215 if (_markStack.overflow()) { 2228 // Should have been done already when we tried to push an
2216 // Should have been done already when we tried to push an 2229 // entry on to the global mark stack. But let's do it again.
2217 // entry on to the global mark stack. But let's do it again. 2230 set_has_overflown();
2218 set_has_overflown(); 2231 }
2219 } 2232
2220 2233 if (rp->processing_is_mt()) {
2221 if (rp->processing_is_mt()) { 2234 assert(rp->num_q() == active_workers, "why not");
2222 assert(rp->num_q() == active_workers, "why not"); 2235 rp->enqueue_discovered_references(&par_task_executor);
2223 rp->enqueue_discovered_references(&par_task_executor); 2236 } else {
2224 } else { 2237 rp->enqueue_discovered_references();
2225 rp->enqueue_discovered_references(); 2238 }
2226 } 2239
2227 2240 rp->verify_no_references_recorded();
2228 rp->verify_no_references_recorded(); 2241 assert(!rp->discovery_enabled(), "should have been disabled");
2229 assert(!rp->discovery_enabled(), "should have been disabled"); 2242 }
2230 2243
2231 // Now clean up stale oops in StringTable 2244 // Now clean up stale oops in StringTable
2232 StringTable::unlink(&g1_is_alive); 2245 StringTable::unlink(&g1_is_alive);
2233 // Clean up unreferenced symbols in symbol table. 2246 // Clean up unreferenced symbols in symbol table.
2234 SymbolTable::unlink(); 2247 SymbolTable::unlink();