hotspot/src/share/vm/gc/parallel/adjoiningGenerations.cpp
author tschatzl
Thu, 28 Jan 2016 13:30:12 +0100
changeset 35877 a2a62511d0f8
parent 35061 be6025ebffea
child 37242 91e5f98fff6f
permissions -rw-r--r--
8146987: Improve Parallel GC Full GC by caching results of live_words_in_range() Summary: A large part of time in the parallel scavenge collector is spent finding out the amount of live words within memory ranges to find out where to move an object to. Try to incrementally calculate this value. Reviewed-by: tschatzl, mgerdin, jmasa Contributed-by: ray alex <sky1young@gmail.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 24941
diff changeset
     2
 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
1
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
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 24941
diff changeset
    26
#include "gc/parallel/adjoiningGenerations.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 24941
diff changeset
    27
#include "gc/parallel/adjoiningVirtualSpaces.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 24941
diff changeset
    28
#include "gc/parallel/generationSizer.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 24941
diff changeset
    29
#include "gc/parallel/parallelScavengeHeap.hpp"
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
    30
#include "logging/log.hpp"
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
    31
#include "memory/resourceArea.hpp"
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
    32
#include "utilities/ostream.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
// If boundary moving is being used, create the young gen and old
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
// gen with ASPSYoungGen and ASPSOldGen, respectively.  Revert to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
// the old behavior otherwise (with PSYoungGen and PSOldGen).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
AdjoiningGenerations::AdjoiningGenerations(ReservedSpace old_young_rs,
21561
c619b1cb4554 8016309: assert(eden_size > 0 && survivor_size > 0) failed: just checking
jwilhelm
parents: 13728
diff changeset
    39
                                           GenerationSizer* policy,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
                                           size_t alignment) :
24941
4ebbe176a7b1 8042298: Remove the names gen0 and gen1 from the GC code
jwilhelm
parents: 24092
diff changeset
    41
  _virtual_spaces(old_young_rs, policy->min_old_size(),
4ebbe176a7b1 8042298: Remove the names gen0 and gen1 from the GC code
jwilhelm
parents: 24092
diff changeset
    42
                  policy->min_young_size(), alignment) {
4ebbe176a7b1 8042298: Remove the names gen0 and gen1 from the GC code
jwilhelm
parents: 24092
diff changeset
    43
  size_t init_low_byte_size = policy->initial_old_size();
4ebbe176a7b1 8042298: Remove the names gen0 and gen1 from the GC code
jwilhelm
parents: 24092
diff changeset
    44
  size_t min_low_byte_size = policy->min_old_size();
4ebbe176a7b1 8042298: Remove the names gen0 and gen1 from the GC code
jwilhelm
parents: 24092
diff changeset
    45
  size_t max_low_byte_size = policy->max_old_size();
4ebbe176a7b1 8042298: Remove the names gen0 and gen1 from the GC code
jwilhelm
parents: 24092
diff changeset
    46
  size_t init_high_byte_size = policy->initial_young_size();
4ebbe176a7b1 8042298: Remove the names gen0 and gen1 from the GC code
jwilhelm
parents: 24092
diff changeset
    47
  size_t min_high_byte_size = policy->min_young_size();
4ebbe176a7b1 8042298: Remove the names gen0 and gen1 from the GC code
jwilhelm
parents: 24092
diff changeset
    48
  size_t max_high_byte_size = policy->max_young_size();
21561
c619b1cb4554 8016309: assert(eden_size > 0 && survivor_size > 0) failed: just checking
jwilhelm
parents: 13728
diff changeset
    49
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  assert(min_low_byte_size <= init_low_byte_size &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
         init_low_byte_size <= max_low_byte_size, "Parameter check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  assert(min_high_byte_size <= init_high_byte_size &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
         init_high_byte_size <= max_high_byte_size, "Parameter check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  // Create the generations differently based on the option to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  // move the boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  if (UseAdaptiveGCBoundary) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
    // Initialize the adjoining virtual spaces.  Then pass the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    // a virtual to each generation for initialization of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    // generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    // Does the actual creation of the virtual spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    _virtual_spaces.initialize(max_low_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
                               init_low_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
                               init_high_byte_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    // Place the young gen at the high end.  Passes in the virtual space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    _young_gen = new ASPSYoungGen(_virtual_spaces.high(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
                                  _virtual_spaces.high()->committed_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
                                  min_high_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
                                  _virtual_spaces.high_byte_size_limit());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    // Place the old gen at the low end. Passes in the virtual space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
    _old_gen = new ASPSOldGen(_virtual_spaces.low(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
                              _virtual_spaces.low()->committed_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
                              min_low_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
                              _virtual_spaces.low_byte_size_limit(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
                              "old", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    young_gen()->initialize_work();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    assert(young_gen()->reserved().byte_size() <= young_gen()->gen_size_limit(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
     "Consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    assert(old_young_rs.size() >= young_gen()->gen_size_limit(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
     "Consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
    old_gen()->initialize_work("old", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
    assert(old_gen()->reserved().byte_size() <= old_gen()->gen_size_limit(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
     "Consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    assert(old_young_rs.size() >= old_gen()->gen_size_limit(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
     "Consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    // Layout the reserved space for the generations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    ReservedSpace old_rs   =
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
      virtual_spaces()->reserved_space().first_part(max_low_byte_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    ReservedSpace heap_rs  =
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
      virtual_spaces()->reserved_space().last_part(max_low_byte_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    ReservedSpace young_rs = heap_rs.first_part(max_high_byte_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    assert(young_rs.size() == heap_rs.size(), "Didn't reserve all of the heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    // Create the generations.  Virtual spaces are not passed in.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    _young_gen = new PSYoungGen(init_high_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
                                min_high_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
                                max_high_byte_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
    _old_gen = new PSOldGen(init_low_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
                            min_low_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
                            max_low_byte_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
                            "old", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    // The virtual spaces are created by the initialization of the gens.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    _young_gen->initialize(young_rs, alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    assert(young_gen()->gen_size_limit() == young_rs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
      "Consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    _old_gen->initialize(old_rs, alignment, "old", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    assert(old_gen()->gen_size_limit() == old_rs.size(), "Consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
size_t AdjoiningGenerations::reserved_byte_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  return virtual_spaces()->reserved_space().size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   122
void log_before_expansion(bool old, size_t expand_in_bytes, size_t change_in_bytes, size_t max_size) {
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   123
  LogHandle(heap, ergo) log;
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   124
  if (!log.is_debug()) {
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   125
   return;
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   126
  }
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   127
  log.debug("Before expansion of %s gen with boundary move", old ? "old" : "young");
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   128
  log.debug("  Requested change: " SIZE_FORMAT_HEX "  Attempted change: " SIZE_FORMAT_HEX,
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   129
                        expand_in_bytes, change_in_bytes);
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   130
  ResourceMark rm;
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   131
  ParallelScavengeHeap::heap()->print_on(log.debug_stream());
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   132
  log.debug("  PS%sGen max size: " SIZE_FORMAT "K", old ? "Old" : "Young", max_size/K);
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   133
}
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   134
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   135
void log_after_expansion(bool old, size_t max_size) {
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   136
  LogHandle(heap, ergo) log;
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   137
  if (!log.is_debug()) {
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   138
   return;
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   139
  }
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   140
  log.debug("After expansion of %s gen with boundary move", old ? "old" : "young");
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   141
  ResourceMark rm;
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   142
  ParallelScavengeHeap::heap()->print_on(log.debug_stream());
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   143
  log.debug("  PS%sGen max size: " SIZE_FORMAT "K", old ? "Old" : "Young", max_size/K);
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   144
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
// Make checks on the current sizes of the generations and
22551
9bf46d16dcc6 8025856: Fix typos in the GC code
jwilhelm
parents: 22234
diff changeset
   147
// the constraints on the sizes of the generations.  Push
9bf46d16dcc6 8025856: Fix typos in the GC code
jwilhelm
parents: 22234
diff changeset
   148
// up the boundary within the constraints.  A partial
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
// push can occur.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
void AdjoiningGenerations::request_old_gen_expansion(size_t expand_in_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  assert_lock_strong(ExpandHeap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  // These sizes limit the amount the boundaries can move.  Effectively,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  // the generation says how much it is willing to yield to the other
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  // generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  const size_t young_gen_available = young_gen()->available_for_contraction();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  const size_t old_gen_available = old_gen()->available_for_expansion();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  const size_t alignment = virtual_spaces()->alignment();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  size_t change_in_bytes = MIN3(young_gen_available,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
                                old_gen_available,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
                                align_size_up_(expand_in_bytes, alignment));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  if (change_in_bytes == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   170
  log_before_expansion(true, expand_in_bytes, change_in_bytes, old_gen()->max_gen_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  // Move the boundary between the generations up (smaller young gen).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  if (virtual_spaces()->adjust_boundary_up(change_in_bytes)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
    young_gen()->reset_after_change();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    old_gen()->reset_after_change();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  // The total reserved for the generations should match the sum
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  // of the two even if the boundary is moving.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  assert(reserved_byte_size() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
         old_gen()->max_gen_size() + young_gen()->max_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
         "Space is missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  young_gen()->space_invariants();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  old_gen()->space_invariants();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   186
  log_after_expansion(true, old_gen()->max_gen_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
// See comments on request_old_gen_expansion()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
bool AdjoiningGenerations::request_young_gen_expansion(size_t expand_in_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  // If eden is not empty, the boundary can be moved but no advantage
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  // can be made of the move since eden cannot be moved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  if (!young_gen()->eden_space()->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  bool result = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  const size_t young_gen_available = young_gen()->available_for_expansion();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  const size_t old_gen_available = old_gen()->available_for_contraction();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  const size_t alignment = virtual_spaces()->alignment();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  size_t change_in_bytes = MIN3(young_gen_available,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
                                old_gen_available,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
                                align_size_up_(expand_in_bytes, alignment));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  if (change_in_bytes == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   212
  log_before_expansion(false, expand_in_bytes, change_in_bytes, young_gen()->max_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  // Move the boundary between the generations down (smaller old gen).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  MutexLocker x(ExpandHeap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  if (virtual_spaces()->adjust_boundary_down(change_in_bytes)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    young_gen()->reset_after_change();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
    old_gen()->reset_after_change();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
    result = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  // The total reserved for the generations should match the sum
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  // of the two even if the boundary is moving.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  assert(reserved_byte_size() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
         old_gen()->max_gen_size() + young_gen()->max_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
         "Space is missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  young_gen()->space_invariants();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  old_gen()->space_invariants();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 30764
diff changeset
   230
  log_after_expansion(false, young_gen()->max_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
// Additional space is needed in the old generation.  Try to move the boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
// up to meet the need.  Moves boundary up only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
void AdjoiningGenerations::adjust_boundary_for_old_gen_needs(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  size_t desired_free_space) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  // Stress testing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  if (PSAdaptiveSizePolicyResizeVirtualSpaceAlot == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
    MutexLocker x(ExpandHeap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
    request_old_gen_expansion(virtual_spaces()->alignment() * 3 / 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  // Expand only if the entire generation is already committed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  if (old_gen()->virtual_space()->uncommitted_size() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
    if (old_gen()->free_in_bytes() < desired_free_space) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
      MutexLocker x(ExpandHeap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
      request_old_gen_expansion(desired_free_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
// See comment on adjust_boundary_for_old_gen_needss().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
// Adjust boundary down only.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
void AdjoiningGenerations::adjust_boundary_for_young_gen_needs(size_t eden_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
    size_t survivor_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  // Stress testing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  if (PSAdaptiveSizePolicyResizeVirtualSpaceAlot == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    request_young_gen_expansion(virtual_spaces()->alignment() * 3 / 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    eden_size = young_gen()->eden_space()->capacity_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  // Expand only if the entire generation is already committed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  if (young_gen()->virtual_space()->uncommitted_size() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    size_t desired_size = eden_size + 2 * survivor_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    const size_t committed = young_gen()->virtual_space()->committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    if (desired_size > committed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
      request_young_gen_expansion(desired_size - committed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
}