collectorPolicy.hpp 10.6 KB
Newer Older
D
duke 已提交
1
/*
X
xdono 已提交
2
 * Copyright 2001-2008 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
 * 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.
 *
 */

// This class (or more correctly, subtypes of this class)
// are used to define global garbage collector attributes.
// This includes initialization of generations and any other
// shared resources they may need.
//
// In general, all flag adjustment and validation should be
// done in initialize_flags(), which is called prior to
// initialize_size_info().
//
// This class is not fully developed yet. As more collector(s)
// are added, it is expected that we will come across further
// behavior that requires global attention. The correct place
// to deal with those issues is this class.

// Forward declarations.
class GenCollectorPolicy;
class TwoGenerationCollectorPolicy;
42
class AdaptiveSizePolicy;
D
duke 已提交
43 44
#ifndef SERIALGC
class ConcurrentMarkSweepPolicy;
45
class G1CollectorPolicy;
D
duke 已提交
46
#endif // SERIALGC
47

D
duke 已提交
48 49 50 51 52 53 54 55 56 57 58 59
class GCPolicyCounters;
class PermanentGenerationSpec;
class MarkSweepPolicy;

class CollectorPolicy : public CHeapObj {
 protected:
  PermanentGenerationSpec *_permanent_generation;
  GCPolicyCounters* _gc_policy_counters;

  // Requires that the concrete subclass sets the alignment constraints
  // before calling.
  virtual void initialize_flags();
60
  virtual void initialize_size_info();
D
duke 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  // Initialize "_permanent_generation" to a spec for the given kind of
  // Perm Gen.
  void initialize_perm_generation(PermGen::Name pgnm);

  size_t _initial_heap_byte_size;
  size_t _max_heap_byte_size;
  size_t _min_heap_byte_size;

  size_t _min_alignment;
  size_t _max_alignment;

  CollectorPolicy() :
    _min_alignment(1),
    _max_alignment(1),
    _initial_heap_byte_size(0),
    _max_heap_byte_size(0),
    _min_heap_byte_size(0)
  {}

 public:
  void set_min_alignment(size_t align)         { _min_alignment = align; }
  size_t min_alignment()                       { return _min_alignment; }
  void set_max_alignment(size_t align)         { _max_alignment = align; }
  size_t max_alignment()                       { return _max_alignment; }

  size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
87
  void set_initial_heap_byte_size(size_t v) { _initial_heap_byte_size = v; }
D
duke 已提交
88
  size_t max_heap_byte_size()     { return _max_heap_byte_size; }
89
  void set_max_heap_byte_size(size_t v) { _max_heap_byte_size = v; }
D
duke 已提交
90
  size_t min_heap_byte_size()     { return _min_heap_byte_size; }
91
  void set_min_heap_byte_size(size_t v) { _min_heap_byte_size = v; }
D
duke 已提交
92 93 94 95 96

  enum Name {
    CollectorPolicyKind,
    TwoGenerationCollectorPolicyKind,
    ConcurrentMarkSweepPolicyKind,
97 98
    ASConcurrentMarkSweepPolicyKind,
    G1CollectorPolicyKind
D
duke 已提交
99 100 101
  };

  // Identification methods.
102
  virtual GenCollectorPolicy*           as_generation_policy()            { return NULL; }
D
duke 已提交
103 104 105 106
  virtual TwoGenerationCollectorPolicy* as_two_generation_policy()        { return NULL; }
  virtual MarkSweepPolicy*              as_mark_sweep_policy()            { return NULL; }
#ifndef SERIALGC
  virtual ConcurrentMarkSweepPolicy*    as_concurrent_mark_sweep_policy() { return NULL; }
107
  virtual G1CollectorPolicy*            as_g1_policy()                    { return NULL; }
D
duke 已提交
108 109 110 111 112 113 114
#endif // SERIALGC
  // Note that these are not virtual.
  bool is_generation_policy()            { return as_generation_policy() != NULL; }
  bool is_two_generation_policy()        { return as_two_generation_policy() != NULL; }
  bool is_mark_sweep_policy()            { return as_mark_sweep_policy() != NULL; }
#ifndef SERIALGC
  bool is_concurrent_mark_sweep_policy() { return as_concurrent_mark_sweep_policy() != NULL; }
115
  bool is_g1_policy()                    { return as_g1_policy() != NULL; }
D
duke 已提交
116 117
#else  // SERIALGC
  bool is_concurrent_mark_sweep_policy() { return false; }
118
  bool is_g1_policy()                    { return false; }
D
duke 已提交
119 120
#endif // SERIALGC

121

D
duke 已提交
122 123 124 125 126 127 128 129 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 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
  virtual PermanentGenerationSpec *permanent_generation() {
    assert(_permanent_generation != NULL, "Sanity check");
    return _permanent_generation;
  }

  virtual BarrierSet::Name barrier_set_name() = 0;
  virtual GenRemSet::Name  rem_set_name() = 0;

  // Create the remembered set (to cover the given reserved region,
  // allowing breaking up into at most "max_covered_regions").
  virtual GenRemSet* create_rem_set(MemRegion reserved,
                                    int max_covered_regions);

  // This method controls how a collector satisfies a request
  // for a block of memory.  "gc_time_limit_was_exceeded" will
  // be set to true if the adaptive size policy determine that
  // an excessive amount of time is being spent doing collections
  // and caused a NULL to be returned.  If a NULL is not returned,
  // "gc_time_limit_was_exceeded" has an undefined meaning.
  virtual HeapWord* mem_allocate_work(size_t size,
                                      bool is_tlab,
                                      bool* gc_overhead_limit_was_exceeded) = 0;

  // This method controls how a collector handles one or more
  // of its generations being fully allocated.
  virtual HeapWord *satisfy_failed_allocation(size_t size, bool is_tlab) = 0;
  // Performace Counter support
  GCPolicyCounters* counters()     { return _gc_policy_counters; }

  // Create the jstat counters for the GC policy.  By default, policy's
  // don't have associated counters, and we complain if this is invoked.
  virtual void initialize_gc_policy_counters() {
    ShouldNotReachHere();
  }

  virtual CollectorPolicy::Name kind() {
    return CollectorPolicy::CollectorPolicyKind;
  }

  // Returns true if a collector has eden space with soft end.
  virtual bool has_soft_ended_eden() {
    return false;
  }

};

class GenCollectorPolicy : public CollectorPolicy {
 protected:
  size_t _min_gen0_size;
  size_t _initial_gen0_size;
  size_t _max_gen0_size;

  GenerationSpec **_generations;

  // The sizing of the different generations in the heap are controlled
  // by a sizing policy.
  AdaptiveSizePolicy* _size_policy;

  // Return true if an allocation should be attempted in the older
  // generation if it fails in the younger generation.  Return
  // false, otherwise.
  virtual bool should_try_older_generation_allocation(size_t word_size) const;

  void initialize_flags();
  void initialize_size_info();

  // Try to allocate space by expanding the heap.
  virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);

  // compute max heap alignment
  size_t compute_max_alignment();

194 195 196 197 198 199 200 201
 // Scale the base_size by NewRation according to
 //     result = base_size / (NewRatio + 1)
 // and align by min_alignment()
 size_t scale_by_NewRatio_aligned(size_t base_size);

 // Bound the value by the given maximum minus the
 // min_alignment.
 size_t bound_minus_alignment(size_t desired_size, size_t maximum_size);
D
duke 已提交
202 203

 public:
204 205 206 207 208 209 210 211
  // Accessors
  size_t min_gen0_size() { return _min_gen0_size; }
  void set_min_gen0_size(size_t v) { _min_gen0_size = v; }
  size_t initial_gen0_size() { return _initial_gen0_size; }
  void set_initial_gen0_size(size_t v) { _initial_gen0_size = v; }
  size_t max_gen0_size() { return _max_gen0_size; }
  void set_max_gen0_size(size_t v) { _max_gen0_size = v; }

D
duke 已提交
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
  virtual int number_of_generations() = 0;

  virtual GenerationSpec **generations()       {
    assert(_generations != NULL, "Sanity check");
    return _generations;
  }

  virtual GenCollectorPolicy* as_generation_policy() { return this; }

  virtual void initialize_generations() = 0;

  virtual void initialize_all() {
    initialize_flags();
    initialize_size_info();
    initialize_generations();
  }

  HeapWord* mem_allocate_work(size_t size,
                              bool is_tlab,
                              bool* gc_overhead_limit_was_exceeded);

  HeapWord *satisfy_failed_allocation(size_t size, bool is_tlab);

  // The size that defines a "large array".
  virtual size_t large_typearray_limit();

  // Adaptive size policy
  AdaptiveSizePolicy* size_policy() { return _size_policy; }
  virtual void initialize_size_policy(size_t init_eden_size,
                                      size_t init_promo_size,
                                      size_t init_survivor_size);

};


// All of hotspot's current collectors are subtypes of this
// class. Currently, these collectors all use the same gen[0],
// but have different gen[1] types. If we add another subtype
// of CollectorPolicy, this class should be broken out into
// its own file.

class TwoGenerationCollectorPolicy : public GenCollectorPolicy {
 protected:
  size_t _min_gen1_size;
  size_t _initial_gen1_size;
  size_t _max_gen1_size;

  void initialize_flags();
  void initialize_size_info();
  void initialize_generations()                { ShouldNotReachHere(); }

 public:
264 265 266 267 268 269 270 271
  // Accessors
  size_t min_gen1_size() { return _min_gen1_size; }
  void set_min_gen1_size(size_t v) { _min_gen1_size = v; }
  size_t initial_gen1_size() { return _initial_gen1_size; }
  void set_initial_gen1_size(size_t v) { _initial_gen1_size = v; }
  size_t max_gen1_size() { return _max_gen1_size; }
  void set_max_gen1_size(size_t v) { _max_gen1_size = v; }

D
duke 已提交
272 273 274 275 276 277 278 279 280 281
  // Inherited methods
  TwoGenerationCollectorPolicy* as_two_generation_policy() { return this; }

  int number_of_generations()                  { return 2; }
  BarrierSet::Name barrier_set_name()          { return BarrierSet::CardTableModRef; }
  GenRemSet::Name rem_set_name()               { return GenRemSet::CardTable; }

  virtual CollectorPolicy::Name kind() {
    return CollectorPolicy::TwoGenerationCollectorPolicyKind;
  }
282 283 284 285

  // Returns true is gen0 sizes were adjusted
  bool adjust_gen0_sizes(size_t* gen0_size_ptr, size_t* gen1_size_ptr,
                               size_t heap_size, size_t min_gen1_size);
D
duke 已提交
286 287 288 289 290 291 292 293 294 295 296 297 298
};

class MarkSweepPolicy : public TwoGenerationCollectorPolicy {
 protected:
  void initialize_generations();

 public:
  MarkSweepPolicy();

  MarkSweepPolicy* as_mark_sweep_policy() { return this; }

  void initialize_gc_policy_counters();
};