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
|