psCompactionManager.hpp 6.4 KB
Newer Older
D
duke 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/*
 * Copyright 2005-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

//
// psPromotionManager is used by a single thread to manage object survival
// during a scavenge. The promotion manager contains thread local data only.
//
// NOTE! Be carefull when allocating the stacks on cheap. If you are going
// to use a promotion manager in more than one thread, the stacks MUST be
// on cheap. This can lead to memory leaks, though, as they are not auto
// deallocated.
//
// FIX ME FIX ME Add a destructor, and don't rely on the user to drain/flush/deallocate!
//

// Move to some global location
#define HAS_BEEN_MOVED 0x1501d01d
// End move to some global location


class MutableSpace;
class PSOldGen;
class ParCompactionManager;
class ObjectStartArray;
class ParallelCompactData;
class ParMarkBitMap;

// Move to it's own file if this works out.

class ParCompactionManager : public CHeapObj {
  friend class ParallelTaskTerminator;
  friend class ParMarkBitMap;
  friend class PSParallelCompact;
55
  friend class StealRegionCompactionTask;
D
duke 已提交
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
  friend class UpdateAndFillClosure;
  friend class RefProcTaskExecutor;

 public:

// ------------------------  Don't putback if not needed
  // Actions that the compaction manager should take.
  enum Action {
    Update,
    Copy,
    UpdateAndCopy,
    CopyAndUpdate,
    VerifyUpdate,
    ResetObjects,
    NotValid
  };
// ------------------------  End don't putback if not needed

 private:
75 76 77 78 79 80 81 82
  static ParCompactionManager** _manager_array;
  static OopTaskQueueSet*       _stack_array;
  static ObjectStartArray*      _start_array;
  static RegionTaskQueueSet*    _region_array;
  static PSOldGen*              _old_gen;

  OopTaskQueue                  _marking_stack;
  GrowableArray<oop>*           _overflow_stack;
D
duke 已提交
83
  // Is there a way to reuse the _marking_stack for the
84
  // saving empty regions?  For now just create a different
D
duke 已提交
85 86
  // type of TaskQueue.

87 88
#ifdef USE_RegionTaskQueueWithOverflow
  RegionTaskQueueWithOverflow   _region_stack;
D
duke 已提交
89
#else
90 91
  RegionTaskQueue               _region_stack;
  GrowableArray<size_t>*        _region_overflow_stack;
D
duke 已提交
92 93 94
#endif

#if 1  // does this happen enough to need a per thread stack?
95
  GrowableArray<Klass*>*        _revisit_klass_stack;
D
duke 已提交
96 97 98 99 100 101 102
#endif
  static ParMarkBitMap* _mark_bitmap;

  Action _action;

  static PSOldGen* old_gen()             { return _old_gen; }
  static ObjectStartArray* start_array() { return _start_array; }
103
  static OopTaskQueueSet* stack_array()  { return _stack_array; }
D
duke 已提交
104 105 106 107 108

  static void initialize(ParMarkBitMap* mbm);

 protected:
  // Array of tasks.  Needed by the ParallelTaskTerminator.
109 110 111 112 113
  static RegionTaskQueueSet* region_array()      { return _region_array; }
  OopTaskQueue*  marking_stack()                 { return &_marking_stack; }
  GrowableArray<oop>* overflow_stack()           { return _overflow_stack; }
#ifdef USE_RegionTaskQueueWithOverflow
  RegionTaskQueueWithOverflow* region_stack()    { return &_region_stack; }
D
duke 已提交
114
#else
115 116 117 118
  RegionTaskQueue*  region_stack()               { return &_region_stack; }
  GrowableArray<size_t>* region_overflow_stack() {
    return _region_overflow_stack;
  }
D
duke 已提交
119 120 121 122 123 124 125 126
#endif

  // Pushes onto the marking stack.  If the marking stack is full,
  // pushes onto the overflow stack.
  void stack_push(oop obj);
  // Do not implement an equivalent stack_pop.  Deal with the
  // marking stack and overflow stack directly.

127 128 129
  // Pushes onto the region stack.  If the region stack is full,
  // pushes onto the region overflow stack.
  void region_stack_push(size_t region_index);
D
duke 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
 public:

  Action action() { return _action; }
  void set_action(Action v) { _action = v; }

  inline static ParCompactionManager* manager_array(int index);

  ParCompactionManager();
  ~ParCompactionManager();

  void allocate_stacks();
  void deallocate_stacks();
  ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }

  // Take actions in preparation for a compaction.
  static void reset();

  // void drain_stacks();

  bool should_update();
  bool should_copy();
  bool should_verify_only();
  bool should_reset_only();

#if 1
  // Probably stays as a growable array
  GrowableArray<Klass*>* revisit_klass_stack() { return _revisit_klass_stack; }
#endif

  // Save oop for later processing.  Must not fail.
  void save_for_scanning(oop m);
  // Get a oop for scanning.  If returns null, no oop were found.
  oop retrieve_for_scanning();

164 165 166 167
  // Save region for later processing.  Must not fail.
  void save_for_processing(size_t region_index);
  // Get a region for processing.  If returns null, no region were found.
  bool retrieve_for_processing(size_t& region_index);
D
duke 已提交
168 169 170 171 172 173 174 175

  // Access function for compaction managers
  static ParCompactionManager* gc_thread_compaction_manager(int index);

  static bool steal(int queue_num, int* seed, Task& t) {
    return stack_array()->steal(queue_num, seed, t);
  }

176 177
  static bool steal(int queue_num, int* seed, RegionTask& t) {
    return region_array()->steal(queue_num, seed, t);
D
duke 已提交
178 179 180 181 182 183
  }

  // Process tasks remaining on any stack
  void drain_marking_stacks(OopClosure *blk);

  // Process tasks remaining on any stack
184
  void drain_region_stacks();
D
duke 已提交
185 186

  // Process tasks remaining on any stack
187
  void drain_region_overflow_stack();
D
duke 已提交
188 189 190 191 192 193 194 195 196 197 198 199 200

  // Debugging support
#ifdef ASSERT
  bool stacks_have_been_allocated();
#endif
};

inline ParCompactionManager* ParCompactionManager::manager_array(int index) {
  assert(_manager_array != NULL, "access of NULL manager_array");
  assert(index >= 0 && index <= (int)ParallelGCThreads,
    "out of range manager_array access");
  return _manager_array[index];
}