src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp

changeset 4128
f81a7c0c618d
parent 4037
da91efe96a93
child 4993
746b070f5022
     1.1 --- a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Mon Oct 01 13:29:11 2012 +0200
     1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Wed Oct 03 08:08:52 2012 -0700
     1.3 @@ -121,103 +121,12 @@
     1.4  
     1.5  // We get passed the space_top value to prevent us from traversing into
     1.6  // the old_gen promotion labs, which cannot be safely parsed.
     1.7 -void CardTableExtension::scavenge_contents(ObjectStartArray* start_array,
     1.8 -                                           MutableSpace* sp,
     1.9 -                                           HeapWord* space_top,
    1.10 -                                           PSPromotionManager* pm)
    1.11 -{
    1.12 -  assert(start_array != NULL && sp != NULL && pm != NULL, "Sanity");
    1.13 -  assert(start_array->covered_region().contains(sp->used_region()),
    1.14 -         "ObjectStartArray does not cover space");
    1.15  
    1.16 -  if (sp->not_empty()) {
    1.17 -    oop* sp_top = (oop*)space_top;
    1.18 -    oop* prev_top = NULL;
    1.19 -    jbyte* current_card = byte_for(sp->bottom());
    1.20 -    jbyte* end_card     = byte_for(sp_top - 1);    // sp_top is exclusive
    1.21 -    // scan card marking array
    1.22 -    while (current_card <= end_card) {
    1.23 -      jbyte value = *current_card;
    1.24 -      // skip clean cards
    1.25 -      if (card_is_clean(value)) {
    1.26 -        current_card++;
    1.27 -      } else {
    1.28 -        // we found a non-clean card
    1.29 -        jbyte* first_nonclean_card = current_card++;
    1.30 -        oop* bottom = (oop*)addr_for(first_nonclean_card);
    1.31 -        // find object starting on card
    1.32 -        oop* bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom);
    1.33 -        // bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom);
    1.34 -        assert(bottom_obj <= bottom, "just checking");
    1.35 -        // make sure we don't scan oops we already looked at
    1.36 -        if (bottom < prev_top) bottom = prev_top;
    1.37 -        // figure out when to stop scanning
    1.38 -        jbyte* first_clean_card;
    1.39 -        oop* top;
    1.40 -        bool restart_scanning;
    1.41 -        do {
    1.42 -          restart_scanning = false;
    1.43 -          // find a clean card
    1.44 -          while (current_card <= end_card) {
    1.45 -            value = *current_card;
    1.46 -            if (card_is_clean(value)) break;
    1.47 -            current_card++;
    1.48 -          }
    1.49 -          // check if we reached the end, if so we are done
    1.50 -          if (current_card >= end_card) {
    1.51 -            first_clean_card = end_card + 1;
    1.52 -            current_card++;
    1.53 -            top = sp_top;
    1.54 -          } else {
    1.55 -            // we have a clean card, find object starting on that card
    1.56 -            first_clean_card = current_card++;
    1.57 -            top = (oop*)addr_for(first_clean_card);
    1.58 -            oop* top_obj = (oop*)start_array->object_start((HeapWord*)top);
    1.59 -            // top_obj = (oop*)start_array->object_start((HeapWord*)top);
    1.60 -            assert(top_obj <= top, "just checking");
    1.61 -            if (oop(top_obj)->is_objArray() || oop(top_obj)->is_typeArray()) {
    1.62 -              // an arrayOop is starting on the clean card - since we do exact store
    1.63 -              // checks for objArrays we are done
    1.64 -            } else {
    1.65 -              // otherwise, it is possible that the object starting on the clean card
    1.66 -              // spans the entire card, and that the store happened on a later card.
    1.67 -              // figure out where the object ends
    1.68 -              top = top_obj + oop(top_obj)->size();
    1.69 -              jbyte* top_card = CardTableModRefBS::byte_for(top - 1);   // top is exclusive
    1.70 -              if (top_card > first_clean_card) {
    1.71 -                // object ends a different card
    1.72 -                current_card = top_card + 1;
    1.73 -                if (card_is_clean(*top_card)) {
    1.74 -                  // the ending card is clean, we are done
    1.75 -                  first_clean_card = top_card;
    1.76 -                } else {
    1.77 -                  // the ending card is not clean, continue scanning at start of do-while
    1.78 -                  restart_scanning = true;
    1.79 -                }
    1.80 -              } else {
    1.81 -                // object ends on the clean card, we are done.
    1.82 -                assert(first_clean_card == top_card, "just checking");
    1.83 -              }
    1.84 -            }
    1.85 -          }
    1.86 -        } while (restart_scanning);
    1.87 -        // we know which cards to scan, now clear them
    1.88 -        while (first_nonclean_card < first_clean_card) {
    1.89 -          *first_nonclean_card++ = clean_card;
    1.90 -        }
    1.91 -        // scan oops in objects
    1.92 -        do {
    1.93 -          oop(bottom_obj)->push_contents(pm);
    1.94 -          bottom_obj += oop(bottom_obj)->size();
    1.95 -          assert(bottom_obj <= sp_top, "just checking");
    1.96 -        } while (bottom_obj < top);
    1.97 -        pm->drain_stacks_cond_depth();
    1.98 -        // remember top oop* scanned
    1.99 -        prev_top = top;
   1.100 -      }
   1.101 -    }
   1.102 -  }
   1.103 -}
   1.104 +// Do not call this method if the space is empty.
   1.105 +// It is a waste to start tasks and get here only to
   1.106 +// do no work.  If this method needs to be called
   1.107 +// when the space is empty, fix the calculation of
   1.108 +// end_card to allow sp_top == sp->bottom().
   1.109  
   1.110  void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_array,
   1.111                                                      MutableSpace* sp,
   1.112 @@ -228,10 +137,11 @@
   1.113    int ssize = 128; // Naked constant!  Work unit = 64k.
   1.114    int dirty_card_count = 0;
   1.115  
   1.116 +  // It is a waste to get here if empty.
   1.117 +  assert(sp->bottom() < sp->top(), "Should not be called if empty");
   1.118    oop* sp_top = (oop*)space_top;
   1.119 -  oop* sp_last = sp->bottom() == space_top ? sp_top : sp_top - 1;
   1.120    jbyte* start_card = byte_for(sp->bottom());
   1.121 -  jbyte* end_card   = byte_for(sp_last) + 1;
   1.122 +  jbyte* end_card   = byte_for(sp_top - 1) + 1;
   1.123    oop* last_scanned = NULL; // Prevent scanning objects more than once
   1.124    // The width of the stripe ssize*stripe_total must be
   1.125    // consistent with the number of stripes so that the complete slice
   1.126 @@ -255,6 +165,16 @@
   1.127      HeapWord* slice_start = addr_for(worker_start_card);
   1.128      HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card));
   1.129  
   1.130 +#ifdef ASSERT
   1.131 +    if (GCWorkerDelayMillis > 0) {
   1.132 +      // Delay 1 worker so that it proceeds after all the work
   1.133 +      // has been completed.
   1.134 +      if (stripe_number < 2) {
   1.135 +        os::sleep(Thread::current(), GCWorkerDelayMillis, false);
   1.136 +      }
   1.137 +    }
   1.138 +#endif
   1.139 +
   1.140      // If there are not objects starting within the chunk, skip it.
   1.141      if (!start_array->object_starts_in_range(slice_start, slice_end)) {
   1.142        continue;

mercurial