/*
 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPARALLELCOMPACT_HPP
#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPARALLELCOMPACT_HPP

#include "gc_implementation/parallelScavenge/objectStartArray.hpp"
#include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
#include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
#include "gc_implementation/shared/collectorCounters.hpp"
#include "gc_implementation/shared/markSweep.hpp"
#include "gc_implementation/shared/mutableSpace.hpp"
#include "memory/sharedHeap.hpp"
#include "oops/oop.hpp"

class ParallelScavengeHeap;
class PSAdaptiveSizePolicy;
class PSYoungGen;
class PSOldGen;
class ParCompactionManager;
class ParallelTaskTerminator;
class PSParallelCompact;
class GCTaskManager;
class GCTaskQueue;
class PreGCValues;
class MoveAndUpdateClosure;
class RefProcTaskExecutor;

// The SplitInfo class holds the information needed to 'split' a source region
// so that the live data can be copied to two destination *spaces*.  Normally,
// all the live data in a region is copied to a single destination space (e.g.,
// everything live in a region in eden is copied entirely into the old gen).
// However, when the heap is nearly full, all the live data in eden may not fit
// into the old gen.  Copying only some of the regions from eden to old gen
// requires finding a region that does not contain a partial object (i.e., no
// live object crosses the region boundary) somewhere near the last object that
// does fit into the old gen.  Since it's not always possible to find such a
// region, splitting is necessary for predictable behavior.
//
// A region is always split at the end of the partial object.  This avoids
// additional tests when calculating the new location of a pointer, which is a
// very hot code path.  The partial object and everything to its left will be
// copied to another space (call it dest_space_1).  The live data to the right
// of the partial object will be copied either within the space itself, or to a
// different destination space (distinct from dest_space_1).
//
// Split points are identified during the summary phase, when region
// destinations are computed:  data about the split, including the
// partial_object_size, is recorded in a SplitInfo record and the
// partial_object_size field in the summary data is set to zero.  The zeroing is
// possible (and necessary) since the partial object will move to a different
// destination space than anything to its right, thus the partial object should
// not affect the locations of any objects to its right.
//
// The recorded data is used during the compaction phase, but only rarely:  when
// the partial object on the split region will be copied across a destination
// region boundary.  This test is made once each time a region is filled, and is
// a simple address comparison, so the overhead is negligible (see
// PSParallelCompact::first_src_addr()).
//
// Notes:
//
// Only regions with partial objects are split; a region without a partial
// object does not need any extra bookkeeping.
//
// At most one region is split per space, so the amount of data required is
// constant.
//
// A region is split only when the destination space would overflow.  Once that
// happens, the destination space is abandoned and no other data (even from
// other source spaces) is targeted to that destination space.  Abandoning the
// destination space may leave a somewhat large unused area at the end, if a
// large object caused the overflow.
//
// Future work:
//
// More bookkeeping would be required to continue to use the destination space.
// The most general solution would allow data from regions in two different
// source spaces to be "joined" in a single destination region.  At the very
// least, additional code would be required in next_src_region() to detect the
// join and skip to an out-of-order source region.  If the join region was also
// the last destination region to which a split region was copied (the most
// likely case), then additional work would be needed to get fill_region() to
// stop iteration and switch to a new source region at the right point.  Basic
// idea would be to use a fake value for the top of the source space.  It is
// doable, if a bit tricky.
//
// A simpler (but less general) solution would fill the remainder of the
// destination region with a dummy object and continue filling the next
// destination region.

class SplitInfo
{
public:
  // Return true if this split info is valid (i.e., if a split has been
  // recorded).  The very first region cannot have a partial object and thus is
  // never split, so 0 is the 'invalid' value.
  bool is_valid() const { return _src_region_idx > 0; }

  // Return true if this split holds data for the specified source region.
  inline bool is_split(size_t source_region) const;

  // The index of the split region, the size of the partial object on that
  // region and the destination of the partial object.
  size_t    src_region_idx() const   { return _src_region_idx; }
  size_t    partial_obj_size() const { return _partial_obj_size; }
  HeapWord* destination() const      { return _destination; }

  // The destination count of the partial object referenced by this split
  // (either 1 or 2).  This must be added to the destination count of the
  // remainder of the source region.
  unsigned int destination_count() const { return _destination_count; }

  // If a word within the partial object will be written to the first word of a
  // destination region, this is the address of the destination region;
  // otherwise this is NULL.
  HeapWord* dest_region_addr() const     { return _dest_region_addr; }

  // If a word within the partial object will be written to the first word of a
  // destination region, this is the address of that word within the partial
  // object; otherwise this is NULL.
  HeapWord* first_src_addr() const       { return _first_src_addr; }

  // Record the data necessary to split the region src_region_idx.
  void record(size_t src_region_idx, size_t partial_obj_size,
              HeapWord* destination);

  void clear();

  DEBUG_ONLY(void verify_clear();)

private:
  size_t       _src_region_idx;
  size_t       _partial_obj_size;
  HeapWord*    _destination;
  unsigned int _destination_count;
  HeapWord*    _dest_region_addr;
  HeapWord*    _first_src_addr;
};

inline bool SplitInfo::is_split(size_t region_idx) const
{
  return _src_region_idx == region_idx && is_valid();
}

class SpaceInfo
{
 public:
  MutableSpace* space() const { return _space; }

  // Where the free space will start after the collection.  Valid only after the
  // summary phase completes.
  HeapWord* new_top() const { return _new_top; }

  // Allows new_top to be set.
  HeapWord** new_top_addr() { return &_new_top; }

  // Where the smallest allowable dense prefix ends (used only for perm gen).
  HeapWord* min_dense_prefix() const { return _min_dense_prefix; }

  // Where the dense prefix ends, or the compacted region begins.
  HeapWord* dense_prefix() const { return _dense_prefix; }

  // The start array for the (generation containing the) space, or NULL if there
  // is no start array.
  ObjectStartArray* start_array() const { return _start_array; }

  SplitInfo& split_info() { return _split_info; }

  void set_space(MutableSpace* s)           { _space = s; }
  void set_new_top(HeapWord* addr)          { _new_top = addr; }
  void set_min_dense_prefix(HeapWord* addr) { _min_dense_prefix = addr; }
  void set_dense_prefix(HeapWord* addr)     { _dense_prefix = addr; }
  void set_start_array(ObjectStartArray* s) { _start_array = s; }

  void publish_new_top() const              { _space->set_top(_new_top); }

 private:
  MutableSpace*     _space;
  HeapWord*         _new_top;
  HeapWord*         _min_dense_prefix;
  HeapWord*         _dense_prefix;
  ObjectStartArray* _start_array;
  SplitInfo         _split_info;
};

class ParallelCompactData
{
public:
  // Sizes are in HeapWords, unless indicated otherwise.
  static const size_t Log2RegionSize;
  static const size_t RegionSize;
  static const size_t RegionSizeBytes;

  // Mask for the bits in a size_t to get an offset within a region.
  static const size_t RegionSizeOffsetMask;
  // Mask for the bits in a pointer to get an offset within a region.
  static const size_t RegionAddrOffsetMask;
  // Mask for the bits in a pointer to get the address of the start of a region.
  static const size_t RegionAddrMask;

  class RegionData
  {
  public:
    // Destination address of the region.
    HeapWord* destination() const { return _destination; }

    // The first region containing data destined for this region.
    size_t source_region() const { return _source_region; }

    // The object (if any) starting in this region and ending in a different
    // region that could not be updated during the main (parallel) compaction
    // phase.  This is different from _partial_obj_addr, which is an object that
    // extends onto a source region.  However, the two uses do not overlap in
    // time, so the same field is used to save space.
    HeapWord* deferred_obj_addr() const { return _partial_obj_addr; }

    // The starting address of the partial object extending onto the region.
    HeapWord* partial_obj_addr() const { return _partial_obj_addr; }

    // Size of the partial object extending onto the region (words).
    size_t partial_obj_size() const { return _partial_obj_size; }

    // Size of live data that lies within this region due to objects that start
    // in this region (words).  This does not include the partial object
    // extending onto the region (if any), or the part of an object that extends
    // onto the next region (if any).
    size_t live_obj_size() const { return _dc_and_los & los_mask; }

    // Total live data that lies within the region (words).
    size_t data_size() const { return partial_obj_size() + live_obj_size(); }

    // The destination_count is the number of other regions to which data from
    // this region will be copied.  At the end of the summary phase, the valid
    // values of destination_count are
    //
    // 0 - data from the region will be compacted completely into itself, or the
    //     region is empty.  The region can be claimed and then filled.
    // 1 - data from the region will be compacted into 1 other region; some
    //     data from the region may also be compacted into the region itself.
    // 2 - data from the region will be copied to 2 other regions.
    //
    // During compaction as regions are emptied, the destination_count is
    // decremented (atomically) and when it reaches 0, it can be claimed and
    // then filled.
    //
    // A region is claimed for processing by atomically changing the
    // destination_count to the claimed value (dc_claimed).  After a region has
    // been filled, the destination_count should be set to the completed value
    // (dc_completed).
    inline uint destination_count() const;
    inline uint destination_count_raw() const;

    // The location of the java heap data that corresponds to this region.
    inline HeapWord* data_location() const;

    // The highest address referenced by objects in this region.
    inline HeapWord* highest_ref() const;

    // Whether this region is available to be claimed, has been claimed, or has
    // been completed.
    //
    // Minor subtlety:  claimed() returns true if the region is marked
    // completed(), which is desirable since a region must be claimed before it
    // can be completed.
    bool available() const { return _dc_and_los < dc_one; }
    bool claimed() const   { return _dc_and_los >= dc_claimed; }
    bool completed() const { return _dc_and_los >= dc_completed; }

    // These are not atomic.
    void set_destination(HeapWord* addr)       { _destination = addr; }
    void set_source_region(size_t region)      { _source_region = region; }
    void set_deferred_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; }
    void set_partial_obj_addr(HeapWord* addr)  { _partial_obj_addr = addr; }
    void set_partial_obj_size(size_t words)    {
      _partial_obj_size = (region_sz_t) words;
    }

    inline void set_destination_count(uint count);
    inline void set_live_obj_size(size_t words);
    inline void set_data_location(HeapWord* addr);
    inline void set_completed();
    inline bool claim_unsafe();

    // These are atomic.
    inline void add_live_obj(size_t words);
    inline void set_highest_ref(HeapWord* addr);
    inline void decrement_destination_count();
    inline bool claim();

  private:
    // The type used to represent object sizes within a region.
    typedef uint region_sz_t;

    // Constants for manipulating the _dc_and_los field, which holds both the
    // destination count and live obj size.  The live obj size lives at the
    // least significant end so no masking is necessary when adding.
    static const region_sz_t dc_shift;           // Shift amount.
    static const region_sz_t dc_mask;            // Mask for destination count.
    static const region_sz_t dc_one;             // 1, shifted appropriately.
    static const region_sz_t dc_claimed;         // Region has been claimed.
    static const region_sz_t dc_completed;       // Region has been completed.
    static const region_sz_t los_mask;           // Mask for live obj size.

    HeapWord*            _destination;
    size_t               _source_region;
    HeapWord*            _partial_obj_addr;
    region_sz_t          _partial_obj_size;
    region_sz_t volatile _dc_and_los;
#ifdef ASSERT
    // These enable optimizations that are only partially implemented.  Use
    // debug builds to prevent the code fragments from breaking.
    HeapWord*            _data_location;
    HeapWord*            _highest_ref;
#endif  // #ifdef ASSERT

#ifdef ASSERT
   public:
    uint            _pushed;   // 0 until region is pushed onto a worker's stack
   private:
#endif
  };

public:
  ParallelCompactData();
  bool initialize(MemRegion covered_region);

  size_t region_count() const { return _region_count; }

  // Convert region indices to/from RegionData pointers.
  inline RegionData* region(size_t region_idx) const;
  inline size_t     region(const RegionData* const region_ptr) const;

  // Returns true if the given address is contained within the region
  bool region_contains(size_t region_index, HeapWord* addr);

  void add_obj(HeapWord* addr, size_t len);
  void add_obj(oop p, size_t len) { add_obj((HeapWord*)p, len); }

  // Fill in the regions covering [beg, end) so that no data moves; i.e., the
  // destination of region n is simply the start of region n.  The argument beg
  // must be region-aligned; end need not be.
  void summarize_dense_prefix(HeapWord* beg, HeapWord* end);

  HeapWord* summarize_split_space(size_t src_region, SplitInfo& split_info,
                                  HeapWord* destination, HeapWord* target_end,
                                  HeapWord** target_next);
  bool summarize(SplitInfo& split_info,
                 HeapWord* source_beg, HeapWord* source_end,
                 HeapWord** source_next,
                 HeapWord* target_beg, HeapWord* target_end,
                 HeapWord** target_next);

  void clear();
  void clear_range(size_t beg_region, size_t end_region);
  void clear_range(HeapWord* beg, HeapWord* end) {
    clear_range(addr_to_region_idx(beg), addr_to_region_idx(end));
  }

  // Return the number of words between addr and the start of the region
  // containing addr.
  inline size_t     region_offset(const HeapWord* addr) const;

  // Convert addresses to/from a region index or region pointer.
  inline size_t     addr_to_region_idx(const HeapWord* addr) const;
  inline RegionData* addr_to_region_ptr(const HeapWord* addr) const;
  inline HeapWord*  region_to_addr(size_t region) const;
  inline HeapWord*  region_to_addr(size_t region, size_t offset) const;
  inline HeapWord*  region_to_addr(const RegionData* region) const;

  inline HeapWord*  region_align_down(HeapWord* addr) const;
  inline HeapWord*  region_align_up(HeapWord* addr) const;
  inline bool       is_region_aligned(HeapWord* addr) const;

  // Return the address one past the end of the partial object.
  HeapWord* partial_obj_end(size_t region_idx) const;

  // Return the new location of the object p after the
  // the compaction.
  HeapWord* calc_new_pointer(HeapWord* addr);

  HeapWord* calc_new_pointer(oop p) {
    return calc_new_pointer((HeapWord*) p);
  }

#ifdef  ASSERT
  void verify_clear(const PSVirtualSpace* vspace);
  void verify_clear();
#endif  // #ifdef ASSERT

private:
  bool initialize_region_data(size_t region_size);
  PSVirtualSpace* create_vspace(size_t count, size_t element_size);

private:
  HeapWord*       _region_start;
#ifdef  ASSERT
  HeapWord*       _region_end;
#endif  // #ifdef ASSERT

  PSVirtualSpace* _region_vspace;
  RegionData*     _region_data;
  size_t          _region_count;
};

inline uint
ParallelCompactData::RegionData::destination_count_raw() const
{
  return _dc_and_los & dc_mask;
}

inline uint
ParallelCompactData::RegionData::destination_count() const
{
  return destination_count_raw() >> dc_shift;
}

inline void
ParallelCompactData::RegionData::set_destination_count(uint count)
{
  assert(count <= (dc_completed >> dc_shift), "count too large");
  const region_sz_t live_sz = (region_sz_t) live_obj_size();
  _dc_and_los = (count << dc_shift) | live_sz;
}

inline void ParallelCompactData::RegionData::set_live_obj_size(size_t words)
{
  assert(words <= los_mask, "would overflow");
  _dc_and_los = destination_count_raw() | (region_sz_t)words;
}

inline void ParallelCompactData::RegionData::decrement_destination_count()
{
  assert(_dc_and_los < dc_claimed, "already claimed");
  assert(_dc_and_los >= dc_one, "count would go negative");
  Atomic::add((int)dc_mask, (volatile int*)&_dc_and_los);
}

inline HeapWord* ParallelCompactData::RegionData::data_location() const
{
  DEBUG_ONLY(return _data_location;)
  NOT_DEBUG(return NULL;)
}

inline HeapWord* ParallelCompactData::RegionData::highest_ref() const
{
  DEBUG_ONLY(return _highest_ref;)
  NOT_DEBUG(return NULL;)
}

inline void ParallelCompactData::RegionData::set_data_location(HeapWord* addr)
{
  DEBUG_ONLY(_data_location = addr;)
}

inline void ParallelCompactData::RegionData::set_completed()
{
  assert(claimed(), "must be claimed first");
  _dc_and_los = dc_completed | (region_sz_t) live_obj_size();
}

// MT-unsafe claiming of a region.  Should only be used during single threaded
// execution.
inline bool ParallelCompactData::RegionData::claim_unsafe()
{
  if (available()) {
    _dc_and_los |= dc_claimed;
    return true;
  }
  return false;
}

inline void ParallelCompactData::RegionData::add_live_obj(size_t words)
{
  assert(words <= (size_t)los_mask - live_obj_size(), "overflow");
  Atomic::add((int) words, (volatile int*) &_dc_and_los);
}

inline void ParallelCompactData::RegionData::set_highest_ref(HeapWord* addr)
{
#ifdef ASSERT
  HeapWord* tmp = _highest_ref;
  while (addr > tmp) {
    tmp = (HeapWord*)Atomic::cmpxchg_ptr(addr, &_highest_ref, tmp);
  }
#endif  // #ifdef ASSERT
}

inline bool ParallelCompactData::RegionData::claim()
{
  const int los = (int) live_obj_size();
  const int old = Atomic::cmpxchg(dc_claimed | los,
                                  (volatile int*) &_dc_and_los, los);
  return old == los;
}

inline ParallelCompactData::RegionData*
ParallelCompactData::region(size_t region_idx) const
{
  assert(region_idx <= region_count(), "bad arg");
  return _region_data + region_idx;
}

inline size_t
ParallelCompactData::region(const RegionData* const region_ptr) const
{
  assert(region_ptr >= _region_data, "bad arg");
  assert(region_ptr <= _region_data + region_count(), "bad arg");
  return pointer_delta(region_ptr, _region_data, sizeof(RegionData));
}

inline size_t
ParallelCompactData::region_offset(const HeapWord* addr) const
{
  assert(addr >= _region_start, "bad addr");
  assert(addr <= _region_end, "bad addr");
  return (size_t(addr) & RegionAddrOffsetMask) >> LogHeapWordSize;
}

inline size_t
ParallelCompactData::addr_to_region_idx(const HeapWord* addr) const
{
  assert(addr >= _region_start, "bad addr");
  assert(addr <= _region_end, "bad addr");
  return pointer_delta(addr, _region_start) >> Log2RegionSize;
}

inline ParallelCompactData::RegionData*
ParallelCompactData::addr_to_region_ptr(const HeapWord* addr) const
{
  return region(addr_to_region_idx(addr));
}

inline HeapWord*
ParallelCompactData::region_to_addr(size_t region) const
{
  assert(region <= _region_count, "region out of range");
  return _region_start + (region << Log2RegionSize);
}

inline HeapWord*
ParallelCompactData::region_to_addr(const RegionData* region) const
{
  return region_to_addr(pointer_delta(region, _region_data,
                                      sizeof(RegionData)));
}

inline HeapWord*
ParallelCompactData::region_to_addr(size_t region, size_t offset) const
{
  assert(region <= _region_count, "region out of range");
  assert(offset < RegionSize, "offset too big");  // This may be too strict.
  return region_to_addr(region) + offset;
}

inline HeapWord*
ParallelCompactData::region_align_down(HeapWord* addr) const
{
  assert(addr >= _region_start, "bad addr");
  assert(addr < _region_end + RegionSize, "bad addr");
  return (HeapWord*)(size_t(addr) & RegionAddrMask);
}

inline HeapWord*
ParallelCompactData::region_align_up(HeapWord* addr) const
{
  assert(addr >= _region_start, "bad addr");
  assert(addr <= _region_end, "bad addr");
  return region_align_down(addr + RegionSizeOffsetMask);
}

inline bool
ParallelCompactData::is_region_aligned(HeapWord* addr) const
{
  return region_offset(addr) == 0;
}

// Abstract closure for use with ParMarkBitMap::iterate(), which will invoke the
// do_addr() method.
//
// The closure is initialized with the number of heap words to process
// (words_remaining()), and becomes 'full' when it reaches 0.  The do_addr()
// methods in subclasses should update the total as words are processed.  Since
// only one subclass actually uses this mechanism to terminate iteration, the
// default initial value is > 0.  The implementation is here and not in the
// single subclass that uses it to avoid making is_full() virtual, and thus
// adding a virtual call per live object.

class ParMarkBitMapClosure: public StackObj {
 public:
  typedef ParMarkBitMap::idx_t idx_t;
  typedef ParMarkBitMap::IterationStatus IterationStatus;

 public:
  inline ParMarkBitMapClosure(ParMarkBitMap* mbm, ParCompactionManager* cm,
                              size_t words = max_uintx);

  inline ParCompactionManager* compaction_manager() const;
  inline ParMarkBitMap*        bitmap() const;
  inline size_t                words_remaining() const;
  inline bool                  is_full() const;
  inline HeapWord*             source() const;

  inline void                  set_source(HeapWord* addr);

  virtual IterationStatus do_addr(HeapWord* addr, size_t words) = 0;

 protected:
  inline void decrement_words_remaining(size_t words);

 private:
  ParMarkBitMap* const        _bitmap;
  ParCompactionManager* const _compaction_manager;
  DEBUG_ONLY(const size_t     _initial_words_remaining;) // Useful in debugger.
  size_t                      _words_remaining; // Words left to copy.

 protected:
  HeapWord*                   _source;          // Next addr that would be read.
};

inline
ParMarkBitMapClosure::ParMarkBitMapClosure(ParMarkBitMap* bitmap,
                                           ParCompactionManager* cm,
                                           size_t words):
  _bitmap(bitmap), _compaction_manager(cm)
#ifdef  ASSERT
  , _initial_words_remaining(words)
#endif
{
  _words_remaining = words;
  _source = NULL;
}

inline ParCompactionManager* ParMarkBitMapClosure::compaction_manager() const {
  return _compaction_manager;
}

inline ParMarkBitMap* ParMarkBitMapClosure::bitmap() const {
  return _bitmap;
}

inline size_t ParMarkBitMapClosure::words_remaining() const {
  return _words_remaining;
}

inline bool ParMarkBitMapClosure::is_full() const {
  return words_remaining() == 0;
}

inline HeapWord* ParMarkBitMapClosure::source() const {
  return _source;
}

inline void ParMarkBitMapClosure::set_source(HeapWord* addr) {
  _source = addr;
}

inline void ParMarkBitMapClosure::decrement_words_remaining(size_t words) {
  assert(_words_remaining >= words, "processed too many words");
  _words_remaining -= words;
}

// The UseParallelOldGC collector is a stop-the-world garbage collector that
// does parts of the collection using parallel threads.  The collection includes
// the tenured generation and the young generation.  The permanent generation is
// collected at the same time as the other two generations but the permanent
// generation is collect by a single GC thread.  The permanent generation is
// collected serially because of the requirement that during the processing of a
// klass AAA, any objects reference by AAA must already have been processed.
// This requirement is enforced by a left (lower address) to right (higher
// address) sliding compaction.
//
// There are four phases of the collection.
//
//      - marking phase
//      - summary phase
//      - compacting phase
//      - clean up phase
//
// Roughly speaking these phases correspond, respectively, to
//      - mark all the live objects
//      - calculate the destination of each object at the end of the collection
//      - move the objects to their destination
//      - update some references and reinitialize some variables
//
// These three phases are invoked in PSParallelCompact::invoke_no_policy().  The
// marking phase is implemented in PSParallelCompact::marking_phase() and does a
// complete marking of the heap.  The summary phase is implemented in
// PSParallelCompact::summary_phase().  The move and update phase is implemented
// in PSParallelCompact::compact().
//
// A space that is being collected is divided into regions and with each region
// is associated an object of type ParallelCompactData.  Each region is of a
// fixed size and typically will contain more than 1 object and may have parts
// of objects at the front and back of the region.
//
// region            -----+---------------------+----------
// objects covered   [ AAA  )[ BBB )[ CCC   )[ DDD     )
//
// The marking phase does a complete marking of all live objects in the heap.
// The marking also compiles the size of the data for all live objects covered
// by the region.  This size includes the part of any live object spanning onto
// the region (part of AAA if it is live) from the front, all live objects
// contained in the region (BBB and/or CCC if they are live), and the part of
// any live objects covered by the region that extends off the region (part of
// DDD if it is live).  The marking phase uses multiple GC threads and marking
// is done in a bit array of type ParMarkBitMap.  The marking of the bit map is
// done atomically as is the accumulation of the size of the live objects
// covered by a region.
//
// The summary phase calculates the total live data to the left of each region
// XXX.  Based on that total and the bottom of the space, it can calculate the
// starting location of the live data in XXX.  The summary phase calculates for
// each region XXX quantites such as
//
//      - the amount of live data at the beginning of a region from an object
//        entering the region.
//      - the location of the first live data on the region
//      - a count of the number of regions receiving live data from XXX.
//
// See ParallelCompactData for precise details.  The summary phase also
// calculates the dense prefix for the compaction.  The dense prefix is a
// portion at the beginning of the space that is not moved.  The objects in the
// dense prefix do need to have their object references updated.  See method
// summarize_dense_prefix().
//
// The summary phase is done using 1 GC thread.
//
// The compaction phase moves objects to their new location and updates all
// references in the object.
//
// A current exception is that objects that cross a region boundary are moved
// but do not have their references updated.  References are not updated because
// it cannot easily be determined if the klass pointer KKK for the object AAA
// has been updated.  KKK likely resides in a region to the left of the region
// containing AAA.  These AAA's have there references updated at the end in a
// clean up phase.  See the method PSParallelCompact::update_deferred_objects().
// An alternate strategy is being investigated for this deferral of updating.
//
// Compaction is done on a region basis.  A region that is ready to be filled is
// put on a ready list and GC threads take region off the list and fill them.  A
// region is ready to be filled if it empty of live objects.  Such a region may
// have been initially empty (only contained dead objects) or may have had all
// its live objects copied out already.  A region that compacts into itself is
// also ready for filling.  The ready list is initially filled with empty
// regions and regions compacting into themselves.  There is always at least 1
// region that can be put on the ready list.  The regions are atomically added
// and removed from the ready list.

class PSParallelCompact : AllStatic {
 public:
  // Convenient access to type names.
  typedef ParMarkBitMap::idx_t idx_t;
  typedef ParallelCompactData::RegionData RegionData;

  typedef enum {
    old_space_id, eden_space_id,
    from_space_id, to_space_id, last_space_id
  } SpaceId;

 public:
  // Inline closure decls
  //
  class IsAliveClosure: public BoolObjectClosure {
   public:
    virtual void do_object(oop p);
    virtual bool do_object_b(oop p);
  };

  class KeepAliveClosure: public OopClosure {
   private:
    ParCompactionManager* _compaction_manager;
   protected:
    template <class T> inline void do_oop_work(T* p);
   public:
    KeepAliveClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
    virtual void do_oop(oop* p);
    virtual void do_oop(narrowOop* p);
  };

  // Current unused
  class FollowRootClosure: public OopsInGenClosure {
   private:
    ParCompactionManager* _compaction_manager;
   public:
    FollowRootClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
    virtual void do_oop(oop* p);
    virtual void do_oop(narrowOop* p);
 };

  class FollowStackClosure: public VoidClosure {
   private:
    ParCompactionManager* _compaction_manager;
   public:
    FollowStackClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
    virtual void do_void();
  };

  class AdjustPointerClosure: public OopClosure {
   private:
    bool _is_root;
   public:
    AdjustPointerClosure(bool is_root) : _is_root(is_root) { }
    virtual void do_oop(oop* p);
    virtual void do_oop(narrowOop* p);
    // do not walk from thread stacks to the code cache on this phase
    virtual void do_code_blob(CodeBlob* cb) const { }
  };

  class AdjustKlassClosure : public KlassClosure {
   public:
    void do_klass(Klass* klass);
  };

  friend class KeepAliveClosure;
  friend class FollowStackClosure;
  friend class AdjustPointerClosure;
  friend class AdjustKlassClosure;
  friend class FollowKlassClosure;
  friend class FollowRootClosure;
  friend class InstanceClassLoaderKlass;
  friend class RefProcTaskProxy;

 private:
  static elapsedTimer         _accumulated_time;
  static unsigned int         _total_invocations;
  static unsigned int         _maximum_compaction_gc_num;
  static jlong                _time_of_last_gc;   // ms
  static CollectorCounters*   _counters;
  static ParMarkBitMap        _mark_bitmap;
  static ParallelCompactData  _summary_data;
  static IsAliveClosure       _is_alive_closure;
  static SpaceInfo            _space_info[last_space_id];
  static bool                 _print_phases;
  static AdjustPointerClosure _adjust_root_pointer_closure;
  static AdjustPointerClosure _adjust_pointer_closure;
  static AdjustKlassClosure   _adjust_klass_closure;

  // Reference processing (used in ...follow_contents)
  static ReferenceProcessor*  _ref_processor;

  // Updated location of intArrayKlassObj.
  static Klass* _updated_int_array_klass_obj;

  // Values computed at initialization and used by dead_wood_limiter().
  static double _dwl_mean;
  static double _dwl_std_dev;
  static double _dwl_first_term;
  static double _dwl_adjustment;
#ifdef  ASSERT
  static bool   _dwl_initialized;
#endif  // #ifdef ASSERT

 private:

  static void initialize_space_info();

  // Return true if details about individual phases should be printed.
  static inline bool print_phases();

  // Clear the marking bitmap and summary data that cover the specified space.
  static void clear_data_covering_space(SpaceId id);

  static void pre_compact(PreGCValues* pre_gc_values);
  static void post_compact();

  // Mark live objects
  static void marking_phase(ParCompactionManager* cm,
                            bool maximum_heap_compaction);

  template <class T> static inline void adjust_pointer(T* p, bool is_root);
  static void adjust_root_pointer(oop* p) { adjust_pointer(p, true); }

  template <class T>
  static inline void follow_root(ParCompactionManager* cm, T* p);

  // Compute the dense prefix for the designated space.  This is an experimental
  // implementation currently not used in production.
  static HeapWord* compute_dense_prefix_via_density(const SpaceId id,
                                                    bool maximum_compaction);

  // Methods used to compute the dense prefix.

  // Compute the value of the normal distribution at x = density.  The mean and
  // standard deviation are values saved by initialize_dead_wood_limiter().
  static inline double normal_distribution(double density);

  // Initialize the static vars used by dead_wood_limiter().
  static void initialize_dead_wood_limiter();

  // Return the percentage of space that can be treated as "dead wood" (i.e.,
  // not reclaimed).
  static double dead_wood_limiter(double density, size_t min_percent);

  // Find the first (left-most) region in the range [beg, end) that has at least
  // dead_words of dead space to the left.  The argument beg must be the first
  // region in the space that is not completely live.
  static RegionData* dead_wood_limit_region(const RegionData* beg,
                                            const RegionData* end,
                                            size_t dead_words);

  // Return a pointer to the first region in the range [beg, end) that is not
  // completely full.
  static RegionData* first_dead_space_region(const RegionData* beg,
                                             const RegionData* end);

  // Return a value indicating the benefit or 'yield' if the compacted region
  // were to start (or equivalently if the dense prefix were to end) at the
  // candidate region.  Higher values are better.
  //
  // The value is based on the amount of space reclaimed vs. the costs of (a)
  // updating references in the dense prefix plus (b) copying objects and
  // updating references in the compacted region.
  static inline double reclaimed_ratio(const RegionData* const candidate,
                                       HeapWord* const bottom,
                                       HeapWord* const top,
                                       HeapWord* const new_top);

  // Compute the dense prefix for the designated space.
  static HeapWord* compute_dense_prefix(const SpaceId id,
                                        bool maximum_compaction);

  // Return true if dead space crosses onto the specified Region; bit must be
  // the bit index corresponding to the first word of the Region.
  static inline bool dead_space_crosses_boundary(const RegionData* region,
                                                 idx_t bit);

  // Summary phase utility routine to fill dead space (if any) at the dense
  // prefix boundary.  Should only be called if the the dense prefix is
  // non-empty.
  static void fill_dense_prefix_end(SpaceId id);

  // Clear the summary data source_region field for the specified addresses.
  static void clear_source_region(HeapWord* beg_addr, HeapWord* end_addr);

#ifndef PRODUCT
  // Routines to provoke splitting a young gen space (ParallelOldGCSplitALot).

  // Fill the region [start, start + words) with live object(s).  Only usable
  // for the old and permanent generations.
  static void fill_with_live_objects(SpaceId id, HeapWord* const start,
                                     size_t words);
  // Include the new objects in the summary data.
  static void summarize_new_objects(SpaceId id, HeapWord* start);

  // Add live objects to a survivor space since it's rare that both survivors
  // are non-empty.
  static void provoke_split_fill_survivor(SpaceId id);

  // Add live objects and/or choose the dense prefix to provoke splitting.
  static void provoke_split(bool & maximum_compaction);
#endif

  static void summarize_spaces_quick();
  static void summarize_space(SpaceId id, bool maximum_compaction);
  static void summary_phase(ParCompactionManager* cm, bool maximum_compaction);

  // Adjust addresses in roots.  Does not adjust addresses in heap.
  static void adjust_roots();

  // Move objects to new locations.
  static void compact_perm(ParCompactionManager* cm);
  static void compact();

  // Add available regions to the stack and draining tasks to the task queue.
  static void enqueue_region_draining_tasks(GCTaskQueue* q,
                                            uint parallel_gc_threads);

  // Add dense prefix update tasks to the task queue.
  static void enqueue_dense_prefix_tasks(GCTaskQueue* q,
                                         uint parallel_gc_threads);

  // Add region stealing tasks to the task queue.
  static void enqueue_region_stealing_tasks(
                                       GCTaskQueue* q,
                                       ParallelTaskTerminator* terminator_ptr,
                                       uint parallel_gc_threads);

  // If objects are left in eden after a collection, try to move the boundary
  // and absorb them into the old gen.  Returns true if eden was emptied.
  static bool absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
                                         PSYoungGen* young_gen,
                                         PSOldGen* old_gen);

  // Reset time since last full gc
  static void reset_millis_since_last_gc();

 protected:
#ifdef VALIDATE_MARK_SWEEP
  static GrowableArray<void*>*           _root_refs_stack;
  static GrowableArray<oop> *            _live_oops;
  static GrowableArray<oop> *            _live_oops_moved_to;
  static GrowableArray<size_t>*          _live_oops_size;
  static size_t                          _live_oops_index;
  static size_t                          _live_oops_index_at_perm;
  static GrowableArray<void*>*           _other_refs_stack;
  static GrowableArray<void*>*           _adjusted_pointers;
  static bool                            _pointer_tracking;
  static bool                            _root_tracking;

  // The following arrays are saved since the time of the last GC and
  // assist in tracking down problems where someone has done an errant
  // store into the heap, usually to an oop that wasn't properly
  // handleized across a GC. If we crash or otherwise fail before the
  // next GC, we can query these arrays to find out the object we had
  // intended to do the store to (assuming it is still alive) and the
  // offset within that object. Covered under RecordMarkSweepCompaction.
  static GrowableArray<HeapWord*> *      _cur_gc_live_oops;
  static GrowableArray<HeapWord*> *      _cur_gc_live_oops_moved_to;
  static GrowableArray<size_t>*          _cur_gc_live_oops_size;
  static GrowableArray<HeapWord*> *      _last_gc_live_oops;
  static GrowableArray<HeapWord*> *      _last_gc_live_oops_moved_to;
  static GrowableArray<size_t>*          _last_gc_live_oops_size;
#endif

 public:
  class MarkAndPushClosure: public OopClosure {
   private:
    ParCompactionManager* _compaction_manager;
   public:
    MarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
    virtual void do_oop(oop* p);
    virtual void do_oop(narrowOop* p);
  };

  // The one and only place to start following the classes.
  // Should only be applied to the ClassLoaderData klasses list.
  class FollowKlassClosure : public KlassClosure {
   private:
    MarkAndPushClosure* _mark_and_push_closure;
   public:
    FollowKlassClosure(MarkAndPushClosure* mark_and_push_closure) :
        _mark_and_push_closure(mark_and_push_closure) { }
    void do_klass(Klass* klass);
  };

  PSParallelCompact();

  // Convenient accessor for Universe::heap().
  static ParallelScavengeHeap* gc_heap() {
    return (ParallelScavengeHeap*)Universe::heap();
  }

  static void invoke(bool maximum_heap_compaction);
  static bool invoke_no_policy(bool maximum_heap_compaction);

  static void post_initialize();
  // Perform initialization for PSParallelCompact that requires
  // allocations.  This should be called during the VM initialization
  // at a pointer where it would be appropriate to return a JNI_ENOMEM
  // in the event of a failure.
  static bool initialize();

  // Closure accessors
  static OopClosure* adjust_pointer_closure()      { return (OopClosure*)&_adjust_pointer_closure; }
  static OopClosure* adjust_root_pointer_closure() { return (OopClosure*)&_adjust_root_pointer_closure; }
  static KlassClosure* adjust_klass_closure()      { return (KlassClosure*)&_adjust_klass_closure; }
  static BoolObjectClosure* is_alive_closure()     { return (BoolObjectClosure*)&_is_alive_closure; }

  // Public accessors
  static elapsedTimer* accumulated_time() { return &_accumulated_time; }
  static unsigned int total_invocations() { return _total_invocations; }
  static CollectorCounters* counters()    { return _counters; }

  // Used to add tasks
  static GCTaskManager* const gc_task_manager();
  static Klass* updated_int_array_klass_obj() {
    return _updated_int_array_klass_obj;
  }

  // Marking support
  static inline bool mark_obj(oop obj);
  static inline bool is_marked(oop obj);
  // Check mark and maybe push on marking stack
  template <class T> static inline void mark_and_push(ParCompactionManager* cm,
                                                      T* p);

  static void follow_klass(ParCompactionManager* cm, Klass* klass);
  static void adjust_klass(ParCompactionManager* cm, Klass* klass);

  static void follow_class_loader(ParCompactionManager* cm,
                                  ClassLoaderData* klass);
  static void adjust_class_loader(ParCompactionManager* cm,
                                  ClassLoaderData* klass);

  // Compaction support.
  // Return true if p is in the range [beg_addr, end_addr).
  static inline bool is_in(HeapWord* p, HeapWord* beg_addr, HeapWord* end_addr);
  static inline bool is_in(oop* p, HeapWord* beg_addr, HeapWord* end_addr);

  // Convenience wrappers for per-space data kept in _space_info.
  static inline MutableSpace*     space(SpaceId space_id);
  static inline HeapWord*         new_top(SpaceId space_id);
  static inline HeapWord*         dense_prefix(SpaceId space_id);
  static inline ObjectStartArray* start_array(SpaceId space_id);

  // Move and update the live objects in the specified space.
  static void move_and_update(ParCompactionManager* cm, SpaceId space_id);

  // Process the end of the given region range in the dense prefix.
  // This includes saving any object not updated.
  static void dense_prefix_regions_epilogue(ParCompactionManager* cm,
                                            size_t region_start_index,
                                            size_t region_end_index,
                                            idx_t exiting_object_offset,
                                            idx_t region_offset_start,
                                            idx_t region_offset_end);

  // Update a region in the dense prefix.  For each live object
  // in the region, update it's interior references.  For each
  // dead object, fill it with deadwood. Dead space at the end
  // of a region range will be filled to the start of the next
  // live object regardless of the region_index_end.  None of the
  // objects in the dense prefix move and dead space is dead
  // (holds only dead objects that don't need any processing), so
  // dead space can be filled in any order.
  static void update_and_deadwood_in_dense_prefix(ParCompactionManager* cm,
                                                  SpaceId space_id,
                                                  size_t region_index_start,
                                                  size_t region_index_end);

  // Return the address of the count + 1st live word in the range [beg, end).
  static HeapWord* skip_live_words(HeapWord* beg, HeapWord* end, size_t count);

  // Return the address of the word to be copied to dest_addr, which must be
  // aligned to a region boundary.
  static HeapWord* first_src_addr(HeapWord* const dest_addr,
                                  SpaceId src_space_id,
                                  size_t src_region_idx);

  // Determine the next source region, set closure.source() to the start of the
  // new region return the region index.  Parameter end_addr is the address one
  // beyond the end of source range just processed.  If necessary, switch to a
  // new source space and set src_space_id (in-out parameter) and src_space_top
  // (out parameter) accordingly.
  static size_t next_src_region(MoveAndUpdateClosure& closure,
                                SpaceId& src_space_id,
                                HeapWord*& src_space_top,
                                HeapWord* end_addr);

  // Decrement the destination count for each non-empty source region in the
  // range [beg_region, region(region_align_up(end_addr))).  If the destination
  // count for a region goes to 0 and it needs to be filled, enqueue it.
  static void decrement_destination_counts(ParCompactionManager* cm,
                                           SpaceId src_space_id,
                                           size_t beg_region,
                                           HeapWord* end_addr);

  // Fill a region, copying objects from one or more source regions.
  static void fill_region(ParCompactionManager* cm, size_t region_idx);
  static void fill_and_update_region(ParCompactionManager* cm, size_t region) {
    fill_region(cm, region);
  }

  // Update the deferred objects in the space.
  static void update_deferred_objects(ParCompactionManager* cm, SpaceId id);

  static ParMarkBitMap* mark_bitmap() { return &_mark_bitmap; }
  static ParallelCompactData& summary_data() { return _summary_data; }

  static inline void adjust_pointer(oop* p)       { adjust_pointer(p, false); }
  static inline void adjust_pointer(narrowOop* p) { adjust_pointer(p, false); }

  // Reference Processing
  static ReferenceProcessor* const ref_processor() { return _ref_processor; }

  // Return the SpaceId for the given address.
  static SpaceId space_id(HeapWord* addr);

  // Time since last full gc (in milliseconds).
  static jlong millis_since_last_gc();

#ifdef VALIDATE_MARK_SWEEP
  static void track_adjusted_pointer(void* p, bool isroot);
  static void check_adjust_pointer(void* p);
  static void track_interior_pointers(oop obj);
  static void check_interior_pointers();

  static void reset_live_oop_tracking();
  static void register_live_oop(oop p, size_t size);
  static void validate_live_oop(oop p, size_t size);
  static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top);
  static void compaction_complete();

  // Querying operation of RecordMarkSweepCompaction results.
  // Finds and prints the current base oop and offset for a word
  // within an oop that was live during the last GC. Helpful for
  // tracking down heap stomps.
  static void print_new_location_of_heap_address(HeapWord* q);
#endif  // #ifdef VALIDATE_MARK_SWEEP

#ifndef PRODUCT
  // Debugging support.
  static const char* space_names[last_space_id];
  static void print_region_ranges();
  static void print_dense_prefix_stats(const char* const algorithm,
                                       const SpaceId id,
                                       const bool maximum_compaction,
                                       HeapWord* const addr);
  static void summary_phase_msg(SpaceId dst_space_id,
                                HeapWord* dst_beg, HeapWord* dst_end,
                                SpaceId src_space_id,
                                HeapWord* src_beg, HeapWord* src_end);
#endif  // #ifndef PRODUCT

#ifdef  ASSERT
  // Sanity check the new location of a word in the heap.
  static inline void check_new_location(HeapWord* old_addr, HeapWord* new_addr);
  // Verify that all the regions have been emptied.
  static void verify_complete(SpaceId space_id);
#endif  // #ifdef ASSERT
};

inline bool PSParallelCompact::mark_obj(oop obj) {
  const int obj_size = obj->size();
  if (mark_bitmap()->mark_obj(obj, obj_size)) {
    _summary_data.add_obj(obj, obj_size);
    return true;
  } else {
    return false;
  }
}

inline bool PSParallelCompact::is_marked(oop obj) {
  return mark_bitmap()->is_marked(obj);
}

template <class T>
inline void PSParallelCompact::follow_root(ParCompactionManager* cm, T* p) {
  assert(!Universe::heap()->is_in_reserved(p),
         "roots shouldn't be things within the heap");
#ifdef VALIDATE_MARK_SWEEP
  if (ValidateMarkSweep) {
    guarantee(!_root_refs_stack->contains(p), "should only be in here once");
    _root_refs_stack->push(p);
  }
#endif
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
    if (mark_bitmap()->is_unmarked(obj)) {
      if (mark_obj(obj)) {
        obj->follow_contents(cm);
      }
    }
  }
  cm->follow_marking_stacks();
}

template <class T>
inline void PSParallelCompact::mark_and_push(ParCompactionManager* cm, T* p) {
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
    if (mark_bitmap()->is_unmarked(obj) && mark_obj(obj)) {
      cm->push(obj);
    }
  }
}

template <class T>
inline void PSParallelCompact::adjust_pointer(T* p, bool isroot) {
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop obj     = oopDesc::decode_heap_oop_not_null(heap_oop);
    oop new_obj = (oop)summary_data().calc_new_pointer(obj);
    assert(new_obj != NULL,                    // is forwarding ptr?
           "should be forwarded");
    // Just always do the update unconditionally?
    if (new_obj != NULL) {
      assert(Universe::heap()->is_in_reserved(new_obj),
             "should be in object space");
      oopDesc::encode_store_heap_oop_not_null(p, new_obj);
    }
  }
  VALIDATE_MARK_SWEEP_ONLY(track_adjusted_pointer(p, isroot));
}

template <class T>
inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) {
#ifdef VALIDATE_MARK_SWEEP
  if (ValidateMarkSweep) {
    if (!Universe::heap()->is_in_reserved(p)) {
      _root_refs_stack->push(p);
    } else {
      _other_refs_stack->push(p);
    }
  }
#endif
  mark_and_push(_compaction_manager, p);
}

inline bool PSParallelCompact::print_phases() {
  return _print_phases;
}

inline double PSParallelCompact::normal_distribution(double density) {
  assert(_dwl_initialized, "uninitialized");
  const double squared_term = (density - _dwl_mean) / _dwl_std_dev;
  return _dwl_first_term * exp(-0.5 * squared_term * squared_term);
}

inline bool
PSParallelCompact::dead_space_crosses_boundary(const RegionData* region,
                                               idx_t bit)
{
  assert(bit > 0, "cannot call this for the first bit/region");
  assert(_summary_data.region_to_addr(region) == _mark_bitmap.bit_to_addr(bit),
         "sanity check");

  // Dead space crosses the boundary if (1) a partial object does not extend
  // onto the region, (2) an object does not start at the beginning of the
  // region, and (3) an object does not end at the end of the prior region.
  return region->partial_obj_size() == 0 &&
    !_mark_bitmap.is_obj_beg(bit) &&
    !_mark_bitmap.is_obj_end(bit - 1);
}

inline bool
PSParallelCompact::is_in(HeapWord* p, HeapWord* beg_addr, HeapWord* end_addr) {
  return p >= beg_addr && p < end_addr;
}

inline bool
PSParallelCompact::is_in(oop* p, HeapWord* beg_addr, HeapWord* end_addr) {
  return is_in((HeapWord*)p, beg_addr, end_addr);
}

inline MutableSpace* PSParallelCompact::space(SpaceId id) {
  assert(id < last_space_id, "id out of range");
  return _space_info[id].space();
}

inline HeapWord* PSParallelCompact::new_top(SpaceId id) {
  assert(id < last_space_id, "id out of range");
  return _space_info[id].new_top();
}

inline HeapWord* PSParallelCompact::dense_prefix(SpaceId id) {
  assert(id < last_space_id, "id out of range");
  return _space_info[id].dense_prefix();
}

inline ObjectStartArray* PSParallelCompact::start_array(SpaceId id) {
  assert(id < last_space_id, "id out of range");
  return _space_info[id].start_array();
}

#ifdef ASSERT
inline void
PSParallelCompact::check_new_location(HeapWord* old_addr, HeapWord* new_addr)
{
  assert(old_addr >= new_addr || space_id(old_addr) != space_id(new_addr),
         "must move left or to a different space");
  assert(is_object_aligned((intptr_t)old_addr) && is_object_aligned((intptr_t)new_addr),
         "checking alignment");
}
#endif // ASSERT

class MoveAndUpdateClosure: public ParMarkBitMapClosure {
 public:
  inline MoveAndUpdateClosure(ParMarkBitMap* bitmap, ParCompactionManager* cm,
                              ObjectStartArray* start_array,
                              HeapWord* destination, size_t words);

  // Accessors.
  HeapWord* destination() const         { return _destination; }

  // If the object will fit (size <= words_remaining()), copy it to the current
  // destination, update the interior oops and the start array and return either
  // full (if the closure is full) or incomplete.  If the object will not fit,
  // return would_overflow.
  virtual IterationStatus do_addr(HeapWord* addr, size_t size);

  // Copy enough words to fill this closure, starting at source().  Interior
  // oops and the start array are not updated.  Return full.
  IterationStatus copy_until_full();

  // Copy enough words to fill this closure or to the end of an object,
  // whichever is smaller, starting at source().  Interior oops and the start
  // array are not updated.
  void copy_partial_obj();

 protected:
  // Update variables to indicate that word_count words were processed.
  inline void update_state(size_t word_count);

 protected:
  ObjectStartArray* const _start_array;
  HeapWord*               _destination;         // Next addr to be written.
};

inline
MoveAndUpdateClosure::MoveAndUpdateClosure(ParMarkBitMap* bitmap,
                                           ParCompactionManager* cm,
                                           ObjectStartArray* start_array,
                                           HeapWord* destination,
                                           size_t words) :
  ParMarkBitMapClosure(bitmap, cm, words), _start_array(start_array)
{
  _destination = destination;
}

inline void MoveAndUpdateClosure::update_state(size_t words)
{
  decrement_words_remaining(words);
  _source += words;
  _destination += words;
}

class UpdateOnlyClosure: public ParMarkBitMapClosure {
 private:
  const PSParallelCompact::SpaceId _space_id;
  ObjectStartArray* const          _start_array;

 public:
  UpdateOnlyClosure(ParMarkBitMap* mbm,
                    ParCompactionManager* cm,
                    PSParallelCompact::SpaceId space_id);

  // Update the object.
  virtual IterationStatus do_addr(HeapWord* addr, size_t words);

  inline void do_addr(HeapWord* addr);
};

inline void UpdateOnlyClosure::do_addr(HeapWord* addr)
{
  _start_array->allocate_block(addr);
  oop(addr)->update_contents(compaction_manager());
}

class FillClosure: public ParMarkBitMapClosure
{
public:
  FillClosure(ParCompactionManager* cm, PSParallelCompact::SpaceId space_id) :
    ParMarkBitMapClosure(PSParallelCompact::mark_bitmap(), cm),
    _start_array(PSParallelCompact::start_array(space_id))
  {
    assert(space_id == PSParallelCompact::old_space_id,
           "cannot use FillClosure in the young gen");
  }

  virtual IterationStatus do_addr(HeapWord* addr, size_t size) {
    CollectedHeap::fill_with_objects(addr, size);
    HeapWord* const end = addr + size;
    do {
      _start_array->allocate_block(addr);
      addr += oop(addr)->size();
    } while (addr < end);
    return ParMarkBitMap::incomplete;
  }

private:
  ObjectStartArray* const _start_array;
};

#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPARALLELCOMPACT_HPP
