Top


定義場所(file name)

hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp

名前(function name)

void PSParallelCompact::fill_region(ParCompactionManager* cm, size_t region_idx)
{

本体部(body)

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      typedef ParMarkBitMap::IterationStatus IterationStatus;
      const size_t RegionSize = ParallelCompactData::RegionSize;
      ParMarkBitMap* const bitmap = mark_bitmap();
      ParallelCompactData& sd = summary_data();
      RegionData* const region_ptr = sd.region(region_idx);

      // Get the items needed to construct the closure.
      HeapWord* dest_addr = sd.region_to_addr(region_idx);
      SpaceId dest_space_id = space_id(dest_addr);
      ObjectStartArray* start_array = _space_info[dest_space_id].start_array();
      HeapWord* new_top = _space_info[dest_space_id].new_top();
      assert(dest_addr < new_top, "sanity");
      const size_t words = MIN2(pointer_delta(new_top, dest_addr), RegionSize);

      // Get the source region and related info.
      size_t src_region_idx = region_ptr->source_region();
      SpaceId src_space_id = space_id(sd.region_to_addr(src_region_idx));
      HeapWord* src_space_top = _space_info[src_space_id].space()->top();

  {- -------------------------------------------
  (1) 
      ---------------------------------------- -}

      MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words);
      closure.set_source(first_src_addr(dest_addr, src_space_id, src_region_idx));

  {- -------------------------------------------
  (1) 
      ---------------------------------------- -}

      // Adjust src_region_idx to prepare for decrementing destination counts (the
      // destination count is not decremented when a region is copied to itself).
      if (src_region_idx == region_idx) {
        src_region_idx += 1;
      }

  {- -------------------------------------------
  (1) 
      ---------------------------------------- -}

      if (bitmap->is_unmarked(closure.source())) {
        // The first source word is in the middle of an object; copy the remainder
        // of the object or as much as will fit.  The fact that pointer updates were
        // deferred will be noted when the object header is processed.
        HeapWord* const old_src_addr = closure.source();
        closure.copy_partial_obj();
        if (closure.is_full()) {
          decrement_destination_counts(cm, src_space_id, src_region_idx,
                                       closure.source());
          region_ptr->set_deferred_obj_addr(NULL);
          region_ptr->set_completed();
          return;
        }

        HeapWord* const end_addr = sd.region_align_down(closure.source());
        if (sd.region_align_down(old_src_addr) != end_addr) {
          // The partial object was copied from more than one source region.
          decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr);

          // Move to the next source region, possibly switching spaces as well.  All
          // args except end_addr may be modified.
          src_region_idx = next_src_region(closure, src_space_id, src_space_top,
                                           end_addr);
        }
      }

  {- -------------------------------------------
  (1) 
      ---------------------------------------- -}

      do {
        HeapWord* const cur_addr = closure.source();
        HeapWord* const end_addr = MIN2(sd.region_align_up(cur_addr + 1),
                                        src_space_top);
        IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr);

        if (status == ParMarkBitMap::incomplete) {
          // The last obj that starts in the source region does not end in the
          // region.
          assert(closure.source() < end_addr, "sanity");
          HeapWord* const obj_beg = closure.source();
          HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(),
                                           src_space_top);
          HeapWord* const obj_end = bitmap->find_obj_end(obj_beg, range_end);
          if (obj_end < range_end) {
            // The end was found; the entire object will fit.
            status = closure.do_addr(obj_beg, bitmap->obj_size(obj_beg, obj_end));
            assert(status != ParMarkBitMap::would_overflow, "sanity");
          } else {
            // The end was not found; the object will not fit.
            assert(range_end < src_space_top, "obj cannot cross space boundary");
            status = ParMarkBitMap::would_overflow;
          }
        }

        if (status == ParMarkBitMap::would_overflow) {
          // The last object did not fit.  Note that interior oop updates were
          // deferred, then copy enough of the object to fill the region.
          region_ptr->set_deferred_obj_addr(closure.destination());
          status = closure.copy_until_full(); // copies from closure.source()

          decrement_destination_counts(cm, src_space_id, src_region_idx,
                                       closure.source());
          region_ptr->set_completed();
          return;
        }

        if (status == ParMarkBitMap::full) {
          decrement_destination_counts(cm, src_space_id, src_region_idx,
                                       closure.source());
          region_ptr->set_deferred_obj_addr(NULL);
          region_ptr->set_completed();
          return;
        }

        decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr);

        // Move to the next source region, possibly switching spaces as well.  All
        // args except end_addr may be modified.
        src_region_idx = next_src_region(closure, src_space_id, src_space_top,
                                         end_addr);
      } while (true);
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.