psCompactionManager.hpp 6.5 KB
Newer Older
D
duke 已提交
1
/*
X
xdono 已提交
2
 * Copyright 2005-2009 Sun Microsystems, Inc.  All Rights Reserved.
D
duke 已提交
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
 * 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;
Y
ysr 已提交
96
  GrowableArray<DataLayout*>*   _revisit_mdo_stack;
D
duke 已提交
97 98 99 100 101 102 103
#endif
  static ParMarkBitMap* _mark_bitmap;

  Action _action;

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

  static void initialize(ParMarkBitMap* mbm);

 protected:
  // Array of tasks.  Needed by the ParallelTaskTerminator.
110 111 112 113 114
  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 已提交
115
#else
116 117 118 119
  RegionTaskQueue*  region_stack()               { return &_region_stack; }
  GrowableArray<size_t>* region_overflow_stack() {
    return _region_overflow_stack;
  }
D
duke 已提交
120 121 122 123 124 125 126 127
#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.

128 129 130
  // 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 已提交
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
 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; }
Y
ysr 已提交
158
  GrowableArray<DataLayout*>* revisit_mdo_stack() { return _revisit_mdo_stack; }
D
duke 已提交
159 160 161 162 163 164 165
#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();

166 167 168 169
  // 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 已提交
170 171 172 173 174 175 176 177

  // 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);
  }

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

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

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

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

  // 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];
}