225 // . the default policy 226 static ReferencePolicy* _default_soft_ref_policy; 227 // . the "clear all" policy 228 static ReferencePolicy* _always_clear_soft_ref_policy; 229 // . the current policy below is either one of the above 230 ReferencePolicy* _current_soft_ref_policy; 231 232 // The discovered ref lists themselves 233 234 // The active MT'ness degree of the queues below 235 uint _num_q; 236 // The maximum MT'ness degree of the queues below 237 uint _max_num_q; 238 239 // Master array of discovered oops 240 DiscoveredList* _discovered_refs; 241 242 // Arrays of lists of oops, one per thread (pointers into master array above) 243 DiscoveredList* _discoveredSoftRefs; 244 DiscoveredList* _discoveredWeakRefs; 245 DiscoveredList* _discoveredFinalRefs; 246 DiscoveredList* _discoveredPhantomRefs; 247 DiscoveredList* _discoveredCleanerRefs; 248 249 public: 250 static int number_of_subclasses_of_ref() { return (REF_CLEANER - REF_OTHER); } 251 252 uint num_q() { return _num_q; } 253 uint max_num_q() { return _max_num_q; } 254 void set_active_mt_degree(uint v) { _num_q = v; } 255 256 DiscoveredList* discovered_refs() { return _discovered_refs; } 257 258 ReferencePolicy* setup_policy(bool always_clear) { 259 _current_soft_ref_policy = always_clear ? 260 _always_clear_soft_ref_policy : _default_soft_ref_policy; 261 _current_soft_ref_policy->setup(); // snapshot the policy threshold 262 return _current_soft_ref_policy; 263 } 264 265 // Process references with a certain reachability level. 266 void process_discovered_reflist(DiscoveredList refs_lists[], 267 ReferencePolicy* policy, 268 bool clear_referent, 269 BoolObjectClosure* is_alive, 270 OopClosure* keep_alive, 271 VoidClosure* complete_gc, 272 AbstractRefProcTaskExecutor* task_executor); 273 274 void process_phaseJNI(BoolObjectClosure* is_alive, 275 OopClosure* keep_alive, 276 VoidClosure* complete_gc); 277 278 // Work methods used by the method process_discovered_reflist 279 // Phase1: keep alive all those referents that are otherwise 280 // dead but which must be kept alive by policy (and their closure). 281 void process_phase1(DiscoveredList& refs_list, 282 ReferencePolicy* policy, 283 BoolObjectClosure* is_alive, 284 OopClosure* keep_alive, 285 VoidClosure* complete_gc); 286 // Phase2: remove all those references whose referents are 287 // reachable. 288 inline void process_phase2(DiscoveredList& refs_list, 289 BoolObjectClosure* is_alive, 290 OopClosure* keep_alive, 291 VoidClosure* complete_gc) { 292 if (discovery_is_atomic()) { 293 // complete_gc is ignored in this case for this phase 294 pp2_work(refs_list, is_alive, keep_alive); 295 } else { 296 assert(complete_gc != NULL, "Error"); 297 pp2_work_concurrent_discovery(refs_list, is_alive, 298 keep_alive, complete_gc); 299 } 300 } 301 // Work methods in support of process_phase2 302 void pp2_work(DiscoveredList& refs_list, 303 BoolObjectClosure* is_alive, 304 OopClosure* keep_alive); 305 void pp2_work_concurrent_discovery( 306 DiscoveredList& refs_list, 307 BoolObjectClosure* is_alive, 308 OopClosure* keep_alive, 309 VoidClosure* complete_gc); 310 // Phase3: process the referents by either clearing them 311 // or keeping them alive (and their closure) 312 void process_phase3(DiscoveredList& refs_list, 313 bool clear_referent, 314 BoolObjectClosure* is_alive, 315 OopClosure* keep_alive, 316 VoidClosure* complete_gc); 317 318 // Enqueue references with a certain reachability level 319 void enqueue_discovered_reflist(DiscoveredList& refs_list, HeapWord* pending_list_addr); 320 321 // "Preclean" all the discovered reference lists 322 // by removing references with strongly reachable referents. 323 // The first argument is a predicate on an oop that indicates 324 // its (strong) reachability and the second is a closure that 325 // may be used to incrementalize or abort the precleaning process. 326 // The caller is responsible for taking care of potential 327 // interference with concurrent operations on these lists 328 // (or predicates involved) by other threads. Currently 329 // only used by the CMS collector. 330 void preclean_discovered_references(BoolObjectClosure* is_alive, 331 OopClosure* keep_alive, 332 VoidClosure* complete_gc, 333 YieldClosure* yield, 334 GCTimer* gc_timer); 335 336 // Returns the name of the discovered reference list 337 // occupying the i / _num_q slot. 338 const char* list_name(uint i); 339 340 void enqueue_discovered_reflists(HeapWord* pending_list_addr, AbstractRefProcTaskExecutor* task_executor); 341 342 protected: 343 // "Preclean" the given discovered reference list 344 // by removing references with strongly reachable referents. 345 // Currently used in support of CMS only. 346 void preclean_discovered_reflist(DiscoveredList& refs_list, 347 BoolObjectClosure* is_alive, 348 OopClosure* keep_alive, 349 VoidClosure* complete_gc, 350 YieldClosure* yield); 351 352 // round-robin mod _num_q (not: _not_ mode _max_num_q) 353 uint next_id() { 354 uint id = _next_id; 355 if (++_next_id == _num_q) { 356 _next_id = 0; 357 } 358 return id; 359 } 360 DiscoveredList* get_discovered_list(ReferenceType rt); 361 inline void add_to_discovered_list_mt(DiscoveredList& refs_list, oop obj, 362 HeapWord* discovered_addr); 363 364 void clear_discovered_references(DiscoveredList& refs_list); 365 366 // Calculate the number of jni handles. 367 size_t count_jni_refs(); 368 369 void log_reflist_counts(DiscoveredList ref_lists[], size_t total_count) PRODUCT_RETURN; 370 | 225 // . the default policy 226 static ReferencePolicy* _default_soft_ref_policy; 227 // . the "clear all" policy 228 static ReferencePolicy* _always_clear_soft_ref_policy; 229 // . the current policy below is either one of the above 230 ReferencePolicy* _current_soft_ref_policy; 231 232 // The discovered ref lists themselves 233 234 // The active MT'ness degree of the queues below 235 uint _num_q; 236 // The maximum MT'ness degree of the queues below 237 uint _max_num_q; 238 239 // Master array of discovered oops 240 DiscoveredList* _discovered_refs; 241 242 // Arrays of lists of oops, one per thread (pointers into master array above) 243 DiscoveredList* _discoveredSoftRefs; 244 DiscoveredList* _discoveredWeakRefs; 245 DiscoveredList* _discoveredEphemerons; 246 DiscoveredList* _discoveredFinalRefs; 247 DiscoveredList* _discoveredPhantomRefs; 248 249 public: 250 static int number_of_subclasses_of_ref() { return (REF_PHANTOM - REF_OTHER); } 251 252 uint num_q() { return _num_q; } 253 uint max_num_q() { return _max_num_q; } 254 void set_active_mt_degree(uint v) { _num_q = v; } 255 256 DiscoveredList* discovered_refs() { return _discovered_refs; } 257 258 ReferencePolicy* setup_policy(bool always_clear) { 259 _current_soft_ref_policy = always_clear ? 260 _always_clear_soft_ref_policy : _default_soft_ref_policy; 261 _current_soft_ref_policy->setup(); // snapshot the policy threshold 262 return _current_soft_ref_policy; 263 } 264 265 // Process references with a certain reachability level. 266 void process_discovered_reflist(DiscoveredList refs_lists[], 267 ReferencePolicy* policy, 268 bool clear_referent, 269 BoolObjectClosure* is_alive, 270 OopClosure* keep_alive, 271 VoidClosure* complete_gc, 272 AbstractRefProcTaskExecutor* task_executor); 273 274 // Balance ephemerons queues if needed 275 void balance_discovered_ephemerons(AbstractRefProcTaskExecutor* task_executor); 276 277 // Process ephemerons, phase2 278 void process_discovered_ephemerons_ph2(BoolObjectClosure* is_alive, 279 OopClosure* keep_alive, 280 VoidClosure* complete_gc, 281 AbstractRefProcTaskExecutor* task_executor); 282 283 // Process ephemerons, phase3 284 void process_discovered_ephemerons_ph3(BoolObjectClosure* is_alive, 285 OopClosure* keep_alive, 286 VoidClosure* complete_gc, 287 AbstractRefProcTaskExecutor* task_executor); 288 289 void process_phaseJNI(BoolObjectClosure* is_alive, 290 OopClosure* keep_alive, 291 VoidClosure* complete_gc); 292 293 // Work methods used by the method process_discovered_reflist 294 // Phase1: keep alive all those referents that are otherwise 295 // dead but which must be kept alive by policy (and their closure). 296 void process_phase1(DiscoveredList& refs_list, 297 ReferencePolicy* policy, 298 BoolObjectClosure* is_alive, 299 OopClosure* keep_alive, 300 VoidClosure* complete_gc); 301 // Phase2: remove all those references whose referents are 302 // reachable. Return true if any ephemerons were removed. 303 inline bool process_phase2(DiscoveredList& refs_list, 304 bool has_ephemerons, 305 BoolObjectClosure* is_alive, 306 OopClosure* keep_alive, 307 VoidClosure* complete_gc) { 308 if (has_ephemerons) { 309 assert(complete_gc != NULL, "Error"); 310 if (discovery_is_atomic()) { 311 return pp2_ephemerons_work(refs_list, is_alive, keep_alive, complete_gc); 312 } else { 313 return pp2_ephemerons_work_concurrent_discovery(refs_list, is_alive, 314 keep_alive, complete_gc); 315 } 316 } else { 317 if (discovery_is_atomic()) { 318 // complete_gc is ignored in this case for this phase 319 pp2_work(refs_list, is_alive, keep_alive); 320 } else { 321 assert(complete_gc != NULL, "Error"); 322 pp2_work_concurrent_discovery(refs_list, is_alive, 323 keep_alive, complete_gc); 324 } 325 return false; 326 } 327 } 328 // Work methods in support of process_phase2 329 void pp2_work(DiscoveredList& refs_list, 330 BoolObjectClosure* is_alive, 331 OopClosure* keep_alive); 332 void pp2_work_concurrent_discovery( 333 DiscoveredList& refs_list, 334 BoolObjectClosure* is_alive, 335 OopClosure* keep_alive, 336 VoidClosure* complete_gc); 337 bool pp2_ephemerons_work( 338 DiscoveredList& refs_list, 339 BoolObjectClosure* is_alive, 340 OopClosure* keep_alive, 341 VoidClosure* complete_gc); 342 bool pp2_ephemerons_work_concurrent_discovery( 343 DiscoveredList& refs_list, 344 BoolObjectClosure* is_alive, 345 OopClosure* keep_alive, 346 VoidClosure* complete_gc); 347 // Phase3: process the referents by either clearing them 348 // or keeping them alive (and their closure) 349 void process_phase3(DiscoveredList& refs_list, 350 bool clear_referent, 351 bool has_ephemerons, 352 BoolObjectClosure* is_alive, 353 OopClosure* keep_alive, 354 VoidClosure* complete_gc); 355 356 // Enqueue references with a certain reachability level 357 void enqueue_discovered_reflist(DiscoveredList& refs_list, HeapWord* pending_list_addr); 358 359 // "Preclean" all the discovered reference lists 360 // by removing references with strongly reachable referents. 361 // The first argument is a predicate on an oop that indicates 362 // its (strong) reachability and the second is a closure that 363 // may be used to incrementalize or abort the precleaning process. 364 // The caller is responsible for taking care of potential 365 // interference with concurrent operations on these lists 366 // (or predicates involved) by other threads. Currently 367 // only used by the CMS collector. 368 void preclean_discovered_references(BoolObjectClosure* is_alive, 369 OopClosure* keep_alive, 370 VoidClosure* complete_gc, 371 YieldClosure* yield, 372 GCTimer* gc_timer); 373 374 // Returns the name of the discovered reference list 375 // occupying the i / _num_q slot. 376 const char* list_name(uint i); 377 378 void enqueue_discovered_reflists(HeapWord* pending_list_addr, AbstractRefProcTaskExecutor* task_executor); 379 380 protected: 381 // "Preclean" the given discovered reference list 382 // by removing references with strongly reachable referents. 383 // Currently used in support of CMS only. 384 void preclean_discovered_reflist(DiscoveredList& refs_list, 385 BoolObjectClosure* is_alive, 386 OopClosure* keep_alive, 387 VoidClosure* complete_gc, 388 YieldClosure* yield); 389 // The same as above, but specialized for ephemerons and returns true 390 // if any ephemerons were removed from the list. 391 bool preclean_discovered_ephemerons_reflist( 392 DiscoveredList& refs_list, 393 BoolObjectClosure* is_alive, 394 OopClosure* keep_alive, 395 VoidClosure* complete_gc, 396 YieldClosure* yield); 397 398 // round-robin mod _num_q (not: _not_ mode _max_num_q) 399 uint next_id() { 400 uint id = _next_id; 401 if (++_next_id == _num_q) { 402 _next_id = 0; 403 } 404 return id; 405 } 406 DiscoveredList* get_discovered_list(ReferenceType rt); 407 inline void add_to_discovered_list_mt(DiscoveredList& refs_list, oop obj, 408 HeapWord* discovered_addr); 409 410 void clear_discovered_references(DiscoveredList& refs_list); 411 412 // Calculate the number of jni handles. 413 size_t count_jni_refs(); 414 415 void log_reflist_counts(DiscoveredList ref_lists[], size_t total_count) PRODUCT_RETURN; 416 |