hotspot/src/share/vm/memory/collectorPolicy.cpp
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 1 489c9b5090e2
child 186 32e6c95f8d9b
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_collectorPolicy.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
// CollectorPolicy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
void CollectorPolicy::initialize_flags() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
  if (PermSize > MaxPermSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
    MaxPermSize = PermSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
  PermSize = align_size_down(PermSize, min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
  MaxPermSize = align_size_up(MaxPermSize, max_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  MinPermHeapExpansion = align_size_down(MinPermHeapExpansion, min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  MaxPermHeapExpansion = align_size_down(MaxPermHeapExpansion, min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  assert(PermSize    % min_alignment() == 0, "permanent space alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  assert(MaxPermSize % max_alignment() == 0, "maximum permanent space alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  assert(SharedReadOnlySize % max_alignment() == 0, "read-only space alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  assert(SharedReadWriteSize % max_alignment() == 0, "read-write space alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  assert(SharedMiscDataSize % max_alignment() == 0, "misc-data space alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  if (PermSize < M) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    vm_exit_during_initialization("Too small initial permanent heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
void CollectorPolicy::initialize_size_info() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  // User inputs from -mx and ms are aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  _initial_heap_byte_size = align_size_up(Arguments::initial_heap_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
                                          min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  _min_heap_byte_size = align_size_up(Arguments::min_heap_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
                                          min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  _max_heap_byte_size = align_size_up(MaxHeapSize, max_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  // Check validity of heap parameters from launcher
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  if (_initial_heap_byte_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    _initial_heap_byte_size = NewSize + OldSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    Universe::check_alignment(_initial_heap_byte_size, min_alignment(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
                            "initial heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  if (_min_heap_byte_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    _min_heap_byte_size = NewSize + OldSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
    Universe::check_alignment(_min_heap_byte_size, min_alignment(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
                            "initial heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  // Check heap parameter properties
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  if (_initial_heap_byte_size < M) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    vm_exit_during_initialization("Too small initial heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  // Check heap parameter properties
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  if (_min_heap_byte_size < M) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    vm_exit_during_initialization("Too small minimum heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  if (_initial_heap_byte_size <= NewSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
     // make sure there is at least some room in old space
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    vm_exit_during_initialization("Too small initial heap for new size specified");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  if (_max_heap_byte_size < _min_heap_byte_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  if (_initial_heap_byte_size < _min_heap_byte_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  if (_max_heap_byte_size < _initial_heap_byte_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
void CollectorPolicy::initialize_perm_generation(PermGen::Name pgnm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  _permanent_generation =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    new PermanentGenerationSpec(pgnm, PermSize, MaxPermSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
                                SharedReadOnlySize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
                                SharedReadWriteSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
                                SharedMiscDataSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
                                SharedMiscCodeSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  if (_permanent_generation == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    vm_exit_during_initialization("Unable to allocate gen spec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
                                           int max_covered_regions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  switch (rem_set_name()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  case GenRemSet::CardTable: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
    if (barrier_set_name() != BarrierSet::CardTableModRef)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
      vm_exit_during_initialization("Mismatch between RS and BS.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    CardTableRS* res = new CardTableRS(whole_heap, max_covered_regions);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    guarantee(false, "unrecognized GenRemSet::Name");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
// GenCollectorPolicy methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
                                                size_t init_promo_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
                                                size_t init_survivor_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  _size_policy = new AdaptiveSizePolicy(init_eden_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
                                        init_promo_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
                                        init_survivor_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
                                        max_gc_minor_pause_sec,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
                                        GCTimeRatio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
size_t GenCollectorPolicy::compute_max_alignment() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  // The card marking array and the offset arrays for old generations are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  // committed in os pages as well. Make sure they are entirely full (to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  // byte entry and the os page size is 4096, the maximum heap size should
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  // be 512*4096 = 2MB aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  // Parallel GC does its own alignment of the generations to avoid requiring a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  // large page (256M on some platforms) for the permanent generation.  The
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  // other collectors should also be updated to do their own alignment and then
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  // this use of lcm() should be removed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  if (UseLargePages && !UseParallelGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
      // in presence of large pages we have to make sure that our
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      // alignment is large page aware
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      alignment = lcm(os::large_page_size(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  return alignment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
void GenCollectorPolicy::initialize_flags() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  // All sizes must be multiples of the generation granularity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  set_min_alignment((uintx) Generation::GenGrain);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  set_max_alignment(compute_max_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  assert(max_alignment() >= min_alignment() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
         max_alignment() % min_alignment() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
         "invalid alignment constraints");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  CollectorPolicy::initialize_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  // All generational heaps have a youngest gen; handle those flags here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  // Adjust max size parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  if (NewSize > MaxNewSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    MaxNewSize = NewSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  NewSize = align_size_down(NewSize, min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  MaxNewSize = align_size_down(MaxNewSize, min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  // Check validity of heap flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  assert(NewSize     % min_alignment() == 0, "eden space alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  assert(MaxNewSize  % min_alignment() == 0, "survivor space alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  if (NewSize < 3*min_alignment()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
     // make sure there room for eden and two survivor spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    vm_exit_during_initialization("Too small new size specified");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  if (SurvivorRatio < 1 || NewRatio < 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    vm_exit_during_initialization("Invalid heap ratio specified");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
void TwoGenerationCollectorPolicy::initialize_flags() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  GenCollectorPolicy::initialize_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  OldSize = align_size_down(OldSize, min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  if (NewSize + OldSize > MaxHeapSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    MaxHeapSize = NewSize + OldSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  always_do_update_barrier = UseConcMarkSweepGC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  BlockOffsetArrayUseUnallocatedBlock =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
      BlockOffsetArrayUseUnallocatedBlock || ParallelGCThreads > 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  // Check validity of heap flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  assert(OldSize     % min_alignment() == 0, "old space alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  assert(MaxHeapSize % max_alignment() == 0, "maximum heap alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
void GenCollectorPolicy::initialize_size_info() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  CollectorPolicy::initialize_size_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  // Minimum sizes of the generations may be different than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  // the initial sizes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  if (!FLAG_IS_DEFAULT(NewSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
    _min_gen0_size = NewSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
    _min_gen0_size = align_size_down(_min_heap_byte_size / (NewRatio+1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
                                     min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    // We bound the minimum size by NewSize below (since it historically
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    // would have been NewSize and because the NewRatio calculation could
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    // yield a size that is too small) and bound it by MaxNewSize above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    // This is not always best.  The NewSize calculated by CMS (which has
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    // a fixed minimum of 16m) can sometimes be "too" large.  Consider
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    // the case where -Xmx32m.  The CMS calculated NewSize would be about
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
    // half the entire heap which seems too large.  But the counter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    // example is seen when the client defaults for NewRatio are used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    // An initial young generation size of 640k was observed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
    // with -Xmx128m -XX:MaxNewSize=32m when NewSize was not used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
    // as a lower bound as with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
    // _min_gen0_size = MIN2(_min_gen0_size, MaxNewSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
    // and 640k seemed too small a young generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
    _min_gen0_size = MIN2(MAX2(_min_gen0_size, NewSize), MaxNewSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  // Parameters are valid, compute area sizes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  size_t max_new_size = align_size_down(_max_heap_byte_size / (NewRatio+1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
                                        min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  max_new_size = MIN2(MAX2(max_new_size, _min_gen0_size), MaxNewSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  // desired_new_size is used to set the initial size.  The
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  // initial size must be greater than the minimum size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  size_t desired_new_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
    align_size_down(_initial_heap_byte_size / (NewRatio+1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
                  min_alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  size_t new_size = MIN2(MAX2(desired_new_size, _min_gen0_size), max_new_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  _initial_gen0_size = new_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  _max_gen0_size = max_new_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
void TwoGenerationCollectorPolicy::initialize_size_info() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  GenCollectorPolicy::initialize_size_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  // Minimum sizes of the generations may be different than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  // the initial sizes.  An inconsistently is permitted here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  // in the total size that can be specified explicitly by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  // command line specification of OldSize and NewSize and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  // also a command line specification of -Xms.  Issue a warning
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  // but allow the values to pass.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  if (!FLAG_IS_DEFAULT(OldSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    _min_gen1_size = OldSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
    // The generation minimums and the overall heap mimimum should
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
    // be within one heap alignment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
    if ((_min_gen1_size + _min_gen0_size + max_alignment()) <
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
         _min_heap_byte_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
      warning("Inconsistency between minimum heap size and minimum "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
        "generation sizes: using min heap = " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
        _min_heap_byte_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    _min_gen1_size = _min_heap_byte_size - _min_gen0_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  _initial_gen1_size = _initial_heap_byte_size - _initial_gen0_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  _max_gen1_size = _max_heap_byte_size - _max_gen0_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
                                        bool is_tlab,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
                                        bool* gc_overhead_limit_was_exceeded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  GenCollectedHeap *gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  debug_only(gch->check_for_valid_allocation_state());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  HeapWord* result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  // Loop until the allocation is satisified,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  // or unsatisfied after GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  for (int try_count = 1; /* return or throw */; try_count += 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    HandleMark hm; // discard any handles allocated in each iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    // First allocation attempt is lock-free.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    Generation *gen0 = gch->get_gen(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    assert(gen0->supports_inline_contig_alloc(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
      "Otherwise, must do alloc within heap lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    if (gen0->should_allocate(size, is_tlab)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
      result = gen0->par_allocate(size, is_tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
      if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
        assert(gch->is_in_reserved(result), "result not in heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
        return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    unsigned int gc_count_before;  // read inside the Heap_lock locked region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
      MutexLocker ml(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
      if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
        gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
                      " attempting locked slow path allocation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
      // Note that only large objects get a shot at being
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
      // allocated in later generations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
      bool first_only = ! should_try_older_generation_allocation(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
      result = gch->attempt_allocation(size, is_tlab, first_only);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
      if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
        assert(gch->is_in_reserved(result), "result not in heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
        return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
      // There are NULL's returned for different circumstances below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
      // In general gc_overhead_limit_was_exceeded should be false so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
      // set it so here and reset it to true only if the gc time
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
      // limit is being exceeded as checked below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
      *gc_overhead_limit_was_exceeded = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
      if (GC_locker::is_active_and_needs_gc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
        if (is_tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
          return NULL;  // Caller will retry allocating individual object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
        if (!gch->is_maximal_no_gc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
          // Try and expand heap to satisfy request
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
          result = expand_heap_and_allocate(size, is_tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
          // result could be null if we are out of space
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
          if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
            return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
        // If this thread is not in a jni critical section, we stall
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
        // the requestor until the critical section has cleared and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
        // GC allowed. When the critical section clears, a GC is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
        // initiated by the last thread exiting the critical section; so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
        // we retry the allocation sequence from the beginning of the loop,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
        // rather than causing more, now probably unnecessary, GC attempts.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
        JavaThread* jthr = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
        if (!jthr->in_critical()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
          MutexUnlocker mul(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
          // Wait for JNI critical section to be exited
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
          GC_locker::stall_until_clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
          continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
          if (CheckJNICalls) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
            fatal("Possible deadlock due to allocating while"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
                  " in jni critical section");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
          return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
      // Read the gc count while the heap lock is held.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
      gc_count_before = Universe::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
    // Allocation has failed and a collection is about
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    // to be done.  If the gc time limit was exceeded the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
    // last time a collection was done, return NULL so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
    // that an out-of-memory will be thrown.  Clear
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
    // gc_time_limit_exceeded so that subsequent attempts
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
    // at a collection will be made.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
    if (size_policy()->gc_time_limit_exceeded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
      *gc_overhead_limit_was_exceeded = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
      size_policy()->set_gc_time_limit_exceeded(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
    VM_GenCollectForAllocation op(size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
                                  is_tlab,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
                                  gc_count_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
    VMThread::execute(&op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
    if (op.prologue_succeeded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
      result = op.result();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
      if (op.gc_locked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
         assert(result == NULL, "must be NULL if gc_locked() is true");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
         continue;  // retry and/or stall as necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
      assert(result == NULL || gch->is_in_reserved(result),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
             "result not in heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
      return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
    // Give a warning if we seem to be looping forever.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
    if ((QueuedAllocationWarningCount > 0) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
        (try_count % QueuedAllocationWarningCount == 0)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
          warning("TwoGenerationCollectorPolicy::mem_allocate_work retries %d times \n\t"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
                  " size=%d %s", try_count, size, is_tlab ? "(TLAB)" : "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
                                                       bool   is_tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  GenCollectedHeap *gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  HeapWord* result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  for (int i = number_of_generations() - 1; i >= 0 && result == NULL; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    Generation *gen = gch->get_gen(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    if (gen->should_allocate(size, is_tlab)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
      result = gen->expand_and_allocate(size, is_tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  assert(result == NULL || gch->is_in_reserved(result), "result not in heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
                                                        bool   is_tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  GenCollectedHeap *gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  GCCauseSetter x(gch, GCCause::_allocation_failure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  HeapWord* result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  assert(size != 0, "Precondition violated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  if (GC_locker::is_active_and_needs_gc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    // GC locker is active; instead of a collection we will attempt
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
    // to expand the heap, if there's room for expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
    if (!gch->is_maximal_no_gc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
      result = expand_heap_and_allocate(size, is_tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
    return result;   // could be null if we are out of space
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  } else if (!gch->incremental_collection_will_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    // The gc_prologues have not executed yet.  The value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
    // for incremental_collection_will_fail() is the remanent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
    // of the last collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    // Do an incremental collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
    gch->do_collection(false            /* full */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
                       false            /* clear_all_soft_refs */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
                       size             /* size */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
                       is_tlab          /* is_tlab */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
                       number_of_generations() - 1 /* max_level */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
    // Try a full collection; see delta for bug id 6266275
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
    // for the original code and why this has been simplified
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
    // with from-space allocation criteria modified and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    // such allocation moved out of the safepoint path.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
    gch->do_collection(true             /* full */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
                       false            /* clear_all_soft_refs */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
                       size             /* size */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
                       is_tlab          /* is_tlab */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
                       number_of_generations() - 1 /* max_level */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  result = gch->attempt_allocation(size, is_tlab, false /*first_only*/);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    assert(gch->is_in_reserved(result), "result not in heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  // OK, collection failed, try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  result = expand_heap_and_allocate(size, is_tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  // If we reach this point, we're really out of memory. Try every trick
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  // we can to reclaim memory. Force collection of soft references. Force
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  // a complete compaction of the heap. Any additional methods for finding
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  // free memory should be here, especially if they are expensive. If this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  // attempt fails, an OOM exception will be thrown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
    IntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    gch->do_collection(true             /* full */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
                       true             /* clear_all_soft_refs */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
                       size             /* size */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
                       is_tlab          /* is_tlab */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
                       number_of_generations() - 1 /* max_level */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  result = gch->attempt_allocation(size, is_tlab, false /* first_only */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    assert(gch->is_in_reserved(result), "result not in heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  // What else?  We might try synchronous finalization later.  If the total
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  // space available is large enough for the allocation, then a more
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  // complete compaction phase than we've tried so far might be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
  // appropriate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
size_t GenCollectorPolicy::large_typearray_limit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  return FastAllocateSizeLimit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
// Return true if any of the following is true:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
// . the allocation won't fit into the current young gen heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
// . gc locker is occupied (jni critical section)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
// . heap memory is tight -- the most recent previous collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
//   was a full collection because a partial collection (would
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
//   have) failed and is likely to fail again
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
bool GenCollectorPolicy::should_try_older_generation_allocation(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
        size_t word_size) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  size_t gen0_capacity = gch->get_gen(0)->capacity_before_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  return    (word_size > heap_word_size(gen0_capacity))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
         || (GC_locker::is_active_and_needs_gc())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
         || (   gch->last_incremental_collection_failed()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
             && gch->incremental_collection_will_fail());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
// MarkSweepPolicy methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
MarkSweepPolicy::MarkSweepPolicy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  initialize_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
void MarkSweepPolicy::initialize_generations() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  initialize_perm_generation(PermGen::MarkSweepCompact);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  _generations = new GenerationSpecPtr[number_of_generations()];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  if (_generations == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
    vm_exit_during_initialization("Unable to allocate gen spec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  if (UseParNewGC && ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
    _generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    _generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  _generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_gen1_size, _max_gen1_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  if (_generations[0] == NULL || _generations[1] == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
    vm_exit_during_initialization("Unable to allocate gen spec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
void MarkSweepPolicy::initialize_gc_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  // initialize the policy counters - 2 collectors, 3 generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  if (UseParNewGC && ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
    _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
    _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
}