hotspot/src/share/vm/gc/parallel/psVirtualspace.cpp
author tschatzl
Thu, 28 Jan 2016 13:30:12 +0100
changeset 35877 a2a62511d0f8
parent 35061 be6025ebffea
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
/*
30291
54cdc5c1a9cb 8068352: Move virtualspace.* out of src/share/vm/runtime to memory directory
coleenp
parents: 29798
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: 2105
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2105
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: 2105
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: 30291
diff changeset
    26
#include "gc/parallel/psVirtualspace.hpp"
30291
54cdc5c1a9cb 8068352: Move virtualspace.* out of src/share/vm/runtime to memory directory
coleenp
parents: 29798
diff changeset
    27
#include "memory/virtualspace.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "runtime/os.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
// PSVirtualSpace
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
PSVirtualSpace::PSVirtualSpace(ReservedSpace rs, size_t alignment) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
  _alignment(alignment)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
  set_reserved(rs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  set_committed(reserved_low_addr(), reserved_low_addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  DEBUG_ONLY(verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
PSVirtualSpace::PSVirtualSpace(ReservedSpace rs) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  _alignment(os::vm_page_size())
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  set_reserved(rs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  set_committed(reserved_low_addr(), reserved_low_addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  DEBUG_ONLY(verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// Deprecated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
PSVirtualSpace::PSVirtualSpace(): _alignment(os::vm_page_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
// Deprecated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
bool PSVirtualSpace::initialize(ReservedSpace rs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
                                size_t commit_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  set_reserved(rs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  set_committed(reserved_low_addr(), reserved_low_addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  // Commit to initial size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  assert(commit_size <= rs.size(), "commit_size too big");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  bool result = commit_size > 0 ? expand_by(commit_size) : true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  DEBUG_ONLY(verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
PSVirtualSpace::~PSVirtualSpace() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  release();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
bool PSVirtualSpace::contains(void* p) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  char* const cp = (char*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  return cp >= committed_low_addr() && cp < committed_high_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
void PSVirtualSpace::release() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
    76
  // This may not release memory it didn't reserve.
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
    77
  // Use rs.release() to release the underlying memory instead.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  _reserved_low_addr = _reserved_high_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  _committed_low_addr = _committed_high_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  _special = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
1911
b7cfe7eb809c 6783381: NUMA allocator: don't pretouch eden space with UseNUMA
iveresov
parents: 1217
diff changeset
    83
bool PSVirtualSpace::expand_by(size_t bytes) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  assert(is_aligned(bytes), "arg not aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  if (uncommitted_size() < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  char* const base_addr = committed_high_addr();
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10565
diff changeset
    92
  bool result = special() ||
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10565
diff changeset
    93
         os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    _committed_high_addr += bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
bool PSVirtualSpace::shrink_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  assert(is_aligned(bytes), "arg not aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  if (committed_size() < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  char* const base_addr = committed_high_addr() - bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  bool result = special() || os::uncommit_memory(base_addr, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    _committed_high_addr -= bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  return result;
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  assert(is_aligned(bytes), "arg not aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  assert(grows_up(), "this space must grow up");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  assert(other_space->grows_down(), "other space must grow down");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  assert(reserved_high_addr() == other_space->reserved_low_addr(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
         "spaces not contiguous");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  assert(special() == other_space->special(), "one space is special, the other is not");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  size_t bytes_needed = bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  // First use the uncommitted region in this space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  if (tmp_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
    if (expand_by(tmp_bytes)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
      bytes_needed -= tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
      return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  // Next take from the uncommitted region in the other space, and commit it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  if (tmp_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    char* const commit_base = committed_high_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    if (other_space->special() ||
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10565
diff changeset
   146
        os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
      // Reduce the reserved region in the other space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
                                other_space->reserved_high_addr(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
                                other_space->special());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
      // Grow both reserved and committed in this space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      _reserved_high_addr += tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      _committed_high_addr += tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
      bytes_needed -= tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      return bytes - bytes_needed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  // Finally take from the already committed region in the other space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  tmp_bytes = bytes_needed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  if (tmp_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    // Reduce both committed and reserved in the other space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    other_space->set_committed(other_space->committed_low_addr() + tmp_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
                               other_space->committed_high_addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
                              other_space->reserved_high_addr(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
                              other_space->special());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    // Grow both reserved and committed in this space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    _reserved_high_addr += tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    _committed_high_addr += tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  return bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
bool PSVirtualSpace::is_aligned(size_t value, size_t align) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  const size_t tmp_value = value + align - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  const size_t mask = ~(align - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  return (tmp_value & mask) == value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
bool PSVirtualSpace::is_aligned(size_t value) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  return is_aligned(value, alignment());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
bool PSVirtualSpace::is_aligned(char* value) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  return is_aligned((size_t)value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
void PSVirtualSpace::verify() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  assert(is_aligned(alignment(), os::vm_page_size()), "bad alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  assert(is_aligned(reserved_low_addr()), "bad reserved_low_addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  assert(is_aligned(reserved_high_addr()), "bad reserved_high_addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  assert(is_aligned(committed_low_addr()), "bad committed_low_addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  assert(is_aligned(committed_high_addr()), "bad committed_high_addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  // Reserved region must be non-empty or both addrs must be 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  assert(reserved_low_addr() < reserved_high_addr() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
         reserved_low_addr() == NULL && reserved_high_addr() == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
         "bad reserved addrs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  assert(committed_low_addr() <= committed_high_addr(), "bad committed addrs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  if (grows_up()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    assert(reserved_low_addr() == committed_low_addr(), "bad low addrs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    assert(reserved_high_addr() >= committed_high_addr(), "bad high addrs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    assert(reserved_high_addr() == committed_high_addr(), "bad high addrs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    assert(reserved_low_addr() <= committed_low_addr(), "bad low addrs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
#endif // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 25468
diff changeset
   220
               p2i(low_boundary()), p2i(high()), p2i(high_boundary()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
                                                 size_t alignment) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  PSVirtualSpace(alignment)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  set_reserved(rs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  set_committed(reserved_high_addr(), reserved_high_addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  DEBUG_ONLY(verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  set_reserved(rs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  set_committed(reserved_high_addr(), reserved_high_addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  DEBUG_ONLY(verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
1911
b7cfe7eb809c 6783381: NUMA allocator: don't pretouch eden space with UseNUMA
iveresov
parents: 1217
diff changeset
   238
bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  assert(is_aligned(bytes), "arg not aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  if (uncommitted_size() < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  char* const base_addr = committed_low_addr() - bytes;
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10565
diff changeset
   247
  bool result = special() ||
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10565
diff changeset
   248
         os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
    _committed_low_addr -= bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
bool PSVirtualSpaceHighToLow::shrink_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  assert(is_aligned(bytes), "arg not aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  if (committed_size() < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  char* const base_addr = committed_low_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  bool result = special() || os::uncommit_memory(base_addr, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
    _committed_low_addr += bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
size_t PSVirtualSpaceHighToLow::expand_into(PSVirtualSpace* other_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
                                            size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  assert(is_aligned(bytes), "arg not aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  assert(grows_down(), "this space must grow down");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  assert(other_space->grows_up(), "other space must grow up");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  assert(reserved_low_addr() == other_space->reserved_high_addr(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
         "spaces not contiguous");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  assert(special() == other_space->special(), "one space is special in memory, the other is not");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  size_t bytes_needed = bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  // First use the uncommitted region in this space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  if (tmp_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
    if (expand_by(tmp_bytes)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
      bytes_needed -= tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
      return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  // Next take from the uncommitted region in the other space, and commit it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  if (tmp_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    char* const commit_base = committed_low_addr() - tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    if (other_space->special() ||
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10565
diff changeset
   301
        os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
      // Reduce the reserved region in the other space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
      other_space->set_reserved(other_space->reserved_low_addr(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
                                other_space->reserved_high_addr() - tmp_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
                                other_space->special());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      // Grow both reserved and committed in this space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
      _reserved_low_addr -= tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
      _committed_low_addr -= tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
      bytes_needed -= tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
      return bytes - bytes_needed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  // Finally take from the already committed region in the other space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  tmp_bytes = bytes_needed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  if (tmp_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    // Reduce both committed and reserved in the other space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
    other_space->set_committed(other_space->committed_low_addr(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
                               other_space->committed_high_addr() - tmp_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
    other_space->set_reserved(other_space->reserved_low_addr(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
                              other_space->reserved_high_addr() - tmp_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
                              other_space->special());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    // Grow both reserved and committed in this space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    _reserved_low_addr -= tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
    _committed_low_addr -= tmp_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  return bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
PSVirtualSpaceHighToLow::print_space_boundaries_on(outputStream* st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  st->print_cr(" (" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT "]",
29798
451c73fdf690 8076071: parallelScavenge: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC needs to be removed from source files
david
parents: 25468
diff changeset
   337
               p2i(high_boundary()), p2i(low()), p2i(low_boundary()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
}