< prev index next >

src/share/vm/gc/shared/referenceProcessor.cpp

Print this page
rev 10256 : imported patch 8150302


 322     return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
 323   } else {
 324     return enqueue_discovered_ref_helper<oop>(this, task_executor);
 325   }
 326 }
 327 
 328 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
 329                                                     HeapWord* pending_list_addr) {
 330   // Given a list of refs linked through the "discovered" field
 331   // (java.lang.ref.Reference.discovered), self-loop their "next" field
 332   // thus distinguishing them from active References, then
 333   // prepend them to the pending list.
 334   //
 335   // The Java threads will see the Reference objects linked together through
 336   // the discovered field. Instead of trying to do the write barrier updates
 337   // in all places in the reference processor where we manipulate the discovered
 338   // field we make sure to do the barrier here where we anyway iterate through
 339   // all linked Reference objects. Note that it is important to not dirty any
 340   // cards during reference processing since this will cause card table
 341   // verification to fail for G1.
 342   log_develop_trace(gc, ref)("ReferenceProcessor::enqueue_discovered_reflist list " INTPTR_FORMAT, p2i(refs_list.head()));
 343 
 344   oop obj = NULL;
 345   oop next_d = refs_list.head();
 346   // Walk down the list, self-looping the next field
 347   // so that the References are not considered active.
 348   while (obj != next_d) {
 349     obj = next_d;
 350     assert(obj->is_instance(), "should be an instance object");
 351     assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
 352     next_d = java_lang_ref_Reference::discovered(obj);
 353     log_develop_trace(gc, ref)("        obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, p2i(obj), p2i(next_d));
 354     assert(java_lang_ref_Reference::next(obj) == NULL,
 355            "Reference not active; should not be discovered");
 356     // Self-loop next, so as to make Ref not active.
 357     java_lang_ref_Reference::set_next_raw(obj, obj);
 358     if (next_d != obj) {
 359       oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
 360     } else {
 361       // This is the last object.
 362       // Swap refs_list into pending_list_addr and


 485   // Decide which softly reachable refs should be kept alive.
 486   while (iter.has_next()) {
 487     iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
 488     bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
 489     if (referent_is_dead &&
 490         !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {
 491       log_develop_trace(gc, ref)("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
 492                                  p2i(iter.obj()), iter.obj()->klass()->internal_name());
 493       // Remove Reference object from list
 494       iter.remove();
 495       // keep the referent around
 496       iter.make_referent_alive();
 497       iter.move_to_next();
 498     } else {
 499       iter.next();
 500     }
 501   }
 502   // Close the reachable set
 503   complete_gc->do_void();
 504   log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT " discovered Refs by policy, from list " INTPTR_FORMAT,
 505                              iter.removed(), iter.processed(), p2i(refs_list.head()));
 506     }
 507 
 508 // Traverse the list and remove any Refs that are not active, or
 509 // whose referents are either alive or NULL.
 510 void
 511 ReferenceProcessor::pp2_work(DiscoveredList&    refs_list,
 512                              BoolObjectClosure* is_alive,
 513                              OopClosure*        keep_alive) {
 514   assert(discovery_is_atomic(), "Error");
 515   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
 516   while (iter.has_next()) {
 517     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
 518     DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());)
 519     assert(next == NULL, "Should not discover inactive Reference");
 520     if (iter.is_referent_alive()) {
 521       log_develop_trace(gc, ref)("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
 522                                  p2i(iter.obj()), iter.obj()->klass()->internal_name());
 523       // The referent is reachable after all.
 524       // Remove Reference object from list.
 525       iter.remove();
 526       // Update the referent pointer as necessary: Note that this
 527       // should not entail any recursive marking because the
 528       // referent must already have been traversed.
 529       iter.make_referent_alive();
 530       iter.move_to_next();
 531     } else {
 532       iter.next();
 533     }
 534   }
 535   NOT_PRODUCT(
 536     if (iter.processed() > 0) {
 537       log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
 538         " Refs in discovered list " INTPTR_FORMAT,
 539         iter.removed(), iter.processed(), p2i(refs_list.head()));
 540     }
 541   )
 542 }
 543 
 544 void
 545 ReferenceProcessor::pp2_work_concurrent_discovery(DiscoveredList&    refs_list,
 546                                                   BoolObjectClosure* is_alive,
 547                                                   OopClosure*        keep_alive,
 548                                                   VoidClosure*       complete_gc) {
 549   assert(!discovery_is_atomic(), "Error");
 550   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
 551   while (iter.has_next()) {
 552     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
 553     HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
 554     oop next = java_lang_ref_Reference::next(iter.obj());
 555     if ((iter.referent() == NULL || iter.is_referent_alive() ||
 556          next != NULL)) {
 557       assert(next->is_oop_or_null(), "Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next));
 558       // Remove Reference object from list
 559       iter.remove();
 560       // Trace the cohorts
 561       iter.make_referent_alive();
 562       if (UseCompressedOops) {
 563         keep_alive->do_oop((narrowOop*)next_addr);
 564       } else {
 565         keep_alive->do_oop((oop*)next_addr);
 566       }
 567       iter.move_to_next();
 568     } else {
 569       iter.next();
 570     }
 571   }
 572   // Now close the newly reachable set
 573   complete_gc->do_void();
 574   NOT_PRODUCT(
 575     if (iter.processed() > 0) {
 576       log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
 577         " Refs in discovered list " INTPTR_FORMAT,
 578         iter.removed(), iter.processed(), p2i(refs_list.head()));
 579     }
 580   )
 581 }
 582 
 583 // Traverse the list and process the referents, by either
 584 // clearing them or keeping them (and their reachable
 585 // closure) alive.
 586 void
 587 ReferenceProcessor::process_phase3(DiscoveredList&    refs_list,
 588                                    bool               clear_referent,
 589                                    BoolObjectClosure* is_alive,
 590                                    OopClosure*        keep_alive,
 591                                    VoidClosure*       complete_gc) {
 592   ResourceMark rm;
 593   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
 594   while (iter.has_next()) {
 595     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
 596     if (clear_referent) {
 597       // NULL out referent pointer
 598       iter.clear_referent();


1181       // Keep alive its cohort.
1182       iter.make_referent_alive();
1183       if (UseCompressedOops) {
1184         narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
1185         keep_alive->do_oop(next_addr);
1186       } else {
1187         oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
1188         keep_alive->do_oop(next_addr);
1189       }
1190       iter.move_to_next();
1191     } else {
1192       iter.next();
1193     }
1194   }
1195   // Close the reachable set
1196   complete_gc->do_void();
1197 
1198   NOT_PRODUCT(
1199     if (iter.processed() > 0) {
1200       log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " Refs out of " SIZE_FORMAT " Refs in discovered list " INTPTR_FORMAT,
1201         iter.removed(), iter.processed(), p2i(refs_list.head()));
1202     }
1203   )
1204 }
1205 
1206 const char* ReferenceProcessor::list_name(uint i) {
1207    assert(i <= _max_num_q * number_of_subclasses_of_ref(),
1208           "Out of bounds index");
1209 
1210    int j = i / _max_num_q;
1211    switch (j) {
1212      case 0: return "SoftRef";
1213      case 1: return "WeakRef";
1214      case 2: return "FinalRef";
1215      case 3: return "PhantomRef";
1216    }
1217    ShouldNotReachHere();
1218    return NULL;
1219 }
1220 


 322     return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
 323   } else {
 324     return enqueue_discovered_ref_helper<oop>(this, task_executor);
 325   }
 326 }
 327 
 328 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
 329                                                     HeapWord* pending_list_addr) {
 330   // Given a list of refs linked through the "discovered" field
 331   // (java.lang.ref.Reference.discovered), self-loop their "next" field
 332   // thus distinguishing them from active References, then
 333   // prepend them to the pending list.
 334   //
 335   // The Java threads will see the Reference objects linked together through
 336   // the discovered field. Instead of trying to do the write barrier updates
 337   // in all places in the reference processor where we manipulate the discovered
 338   // field we make sure to do the barrier here where we anyway iterate through
 339   // all linked Reference objects. Note that it is important to not dirty any
 340   // cards during reference processing since this will cause card table
 341   // verification to fail for G1.
 342   log_develop_trace(gc, ref)("ReferenceProcessor::enqueue_discovered_reflist list " INTPTR_FORMAT, p2i(&refs_list));
 343 
 344   oop obj = NULL;
 345   oop next_d = refs_list.head();
 346   // Walk down the list, self-looping the next field
 347   // so that the References are not considered active.
 348   while (obj != next_d) {
 349     obj = next_d;
 350     assert(obj->is_instance(), "should be an instance object");
 351     assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
 352     next_d = java_lang_ref_Reference::discovered(obj);
 353     log_develop_trace(gc, ref)("        obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, p2i(obj), p2i(next_d));
 354     assert(java_lang_ref_Reference::next(obj) == NULL,
 355            "Reference not active; should not be discovered");
 356     // Self-loop next, so as to make Ref not active.
 357     java_lang_ref_Reference::set_next_raw(obj, obj);
 358     if (next_d != obj) {
 359       oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
 360     } else {
 361       // This is the last object.
 362       // Swap refs_list into pending_list_addr and


 485   // Decide which softly reachable refs should be kept alive.
 486   while (iter.has_next()) {
 487     iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
 488     bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
 489     if (referent_is_dead &&
 490         !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {
 491       log_develop_trace(gc, ref)("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
 492                                  p2i(iter.obj()), iter.obj()->klass()->internal_name());
 493       // Remove Reference object from list
 494       iter.remove();
 495       // keep the referent around
 496       iter.make_referent_alive();
 497       iter.move_to_next();
 498     } else {
 499       iter.next();
 500     }
 501   }
 502   // Close the reachable set
 503   complete_gc->do_void();
 504   log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT " discovered Refs by policy, from list " INTPTR_FORMAT,
 505                              iter.removed(), iter.processed(), p2i(&refs_list));
 506     }
 507 
 508 // Traverse the list and remove any Refs that are not active, or
 509 // whose referents are either alive or NULL.
 510 void
 511 ReferenceProcessor::pp2_work(DiscoveredList&    refs_list,
 512                              BoolObjectClosure* is_alive,
 513                              OopClosure*        keep_alive) {
 514   assert(discovery_is_atomic(), "Error");
 515   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
 516   while (iter.has_next()) {
 517     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
 518     DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());)
 519     assert(next == NULL, "Should not discover inactive Reference");
 520     if (iter.is_referent_alive()) {
 521       log_develop_trace(gc, ref)("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
 522                                  p2i(iter.obj()), iter.obj()->klass()->internal_name());
 523       // The referent is reachable after all.
 524       // Remove Reference object from list.
 525       iter.remove();
 526       // Update the referent pointer as necessary: Note that this
 527       // should not entail any recursive marking because the
 528       // referent must already have been traversed.
 529       iter.make_referent_alive();
 530       iter.move_to_next();
 531     } else {
 532       iter.next();
 533     }
 534   }
 535   NOT_PRODUCT(
 536     if (iter.processed() > 0) {
 537       log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
 538         " Refs in discovered list " INTPTR_FORMAT,
 539         iter.removed(), iter.processed(), p2i(&refs_list));
 540     }
 541   )
 542 }
 543 
 544 void
 545 ReferenceProcessor::pp2_work_concurrent_discovery(DiscoveredList&    refs_list,
 546                                                   BoolObjectClosure* is_alive,
 547                                                   OopClosure*        keep_alive,
 548                                                   VoidClosure*       complete_gc) {
 549   assert(!discovery_is_atomic(), "Error");
 550   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
 551   while (iter.has_next()) {
 552     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
 553     HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
 554     oop next = java_lang_ref_Reference::next(iter.obj());
 555     if ((iter.referent() == NULL || iter.is_referent_alive() ||
 556          next != NULL)) {
 557       assert(next->is_oop_or_null(), "Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next));
 558       // Remove Reference object from list
 559       iter.remove();
 560       // Trace the cohorts
 561       iter.make_referent_alive();
 562       if (UseCompressedOops) {
 563         keep_alive->do_oop((narrowOop*)next_addr);
 564       } else {
 565         keep_alive->do_oop((oop*)next_addr);
 566       }
 567       iter.move_to_next();
 568     } else {
 569       iter.next();
 570     }
 571   }
 572   // Now close the newly reachable set
 573   complete_gc->do_void();
 574   NOT_PRODUCT(
 575     if (iter.processed() > 0) {
 576       log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
 577         " Refs in discovered list " INTPTR_FORMAT,
 578         iter.removed(), iter.processed(), p2i(&refs_list));
 579     }
 580   )
 581 }
 582 
 583 // Traverse the list and process the referents, by either
 584 // clearing them or keeping them (and their reachable
 585 // closure) alive.
 586 void
 587 ReferenceProcessor::process_phase3(DiscoveredList&    refs_list,
 588                                    bool               clear_referent,
 589                                    BoolObjectClosure* is_alive,
 590                                    OopClosure*        keep_alive,
 591                                    VoidClosure*       complete_gc) {
 592   ResourceMark rm;
 593   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
 594   while (iter.has_next()) {
 595     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
 596     if (clear_referent) {
 597       // NULL out referent pointer
 598       iter.clear_referent();


1181       // Keep alive its cohort.
1182       iter.make_referent_alive();
1183       if (UseCompressedOops) {
1184         narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
1185         keep_alive->do_oop(next_addr);
1186       } else {
1187         oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
1188         keep_alive->do_oop(next_addr);
1189       }
1190       iter.move_to_next();
1191     } else {
1192       iter.next();
1193     }
1194   }
1195   // Close the reachable set
1196   complete_gc->do_void();
1197 
1198   NOT_PRODUCT(
1199     if (iter.processed() > 0) {
1200       log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " Refs out of " SIZE_FORMAT " Refs in discovered list " INTPTR_FORMAT,
1201         iter.removed(), iter.processed(), p2i(&refs_list));
1202     }
1203   )
1204 }
1205 
1206 const char* ReferenceProcessor::list_name(uint i) {
1207    assert(i <= _max_num_q * number_of_subclasses_of_ref(),
1208           "Out of bounds index");
1209 
1210    int j = i / _max_num_q;
1211    switch (j) {
1212      case 0: return "SoftRef";
1213      case 1: return "WeakRef";
1214      case 2: return "FinalRef";
1215      case 3: return "PhantomRef";
1216    }
1217    ShouldNotReachHere();
1218    return NULL;
1219 }
1220 
< prev index next >