8024638: Count and expose the amount of committed memory in the metaspaces

Thu, 12 Sep 2013 10:15:54 +0200

author
stefank
date
Thu, 12 Sep 2013 10:15:54 +0200
changeset 5704
c4c768305a8f
parent 5703
d6c266999345
child 5705
335b388c4b28

8024638: Count and expose the amount of committed memory in the metaspaces
Reviewed-by: brutisso, ehelin

src/share/vm/memory/metaspace.cpp file | annotate | diff | comparison | revisions
src/share/vm/memory/metaspace.hpp file | annotate | diff | comparison | revisions
src/share/vm/prims/jni.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/virtualspace.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/virtualspace.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/memory/metaspace.cpp	Thu Sep 12 10:15:30 2013 +0200
     1.2 +++ b/src/share/vm/memory/metaspace.cpp	Thu Sep 12 10:15:54 2013 +0200
     1.3 @@ -291,6 +291,10 @@
     1.4    MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
     1.5    MetaWord* end() const { return (MetaWord*) _virtual_space.high(); }
     1.6  
     1.7 +  size_t reserved_words() const  { return _virtual_space.reserved_size() / BytesPerWord; }
     1.8 +  size_t expanded_words() const  { return _virtual_space.committed_size() / BytesPerWord; }
     1.9 +  size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; }
    1.10 +
    1.11    // address of next available space in _virtual_space;
    1.12    // Accessors
    1.13    VirtualSpaceNode* next() { return _next; }
    1.14 @@ -327,12 +331,10 @@
    1.15  
    1.16    // Allocate a chunk from the virtual space and return it.
    1.17    Metachunk* get_chunk_vs(size_t chunk_word_size);
    1.18 -  Metachunk* get_chunk_vs_with_expand(size_t chunk_word_size);
    1.19  
    1.20    // Expands/shrinks the committed space in a virtual space.  Delegates
    1.21    // to Virtualspace
    1.22    bool expand_by(size_t words, bool pre_touch = false);
    1.23 -  bool shrink_by(size_t words);
    1.24  
    1.25    // In preparation for deleting this node, remove all the chunks
    1.26    // in the node from any freelist.
    1.27 @@ -340,8 +342,6 @@
    1.28  
    1.29  #ifdef ASSERT
    1.30    // Debug support
    1.31 -  static void verify_virtual_space_total();
    1.32 -  static void verify_virtual_space_count();
    1.33    void mangle();
    1.34  #endif
    1.35  
    1.36 @@ -429,8 +429,11 @@
    1.37    bool _is_class;
    1.38    bool can_grow() const { return !is_class() || !UseCompressedClassPointers; }
    1.39  
    1.40 -  // Sum of space in all virtual spaces and number of virtual spaces
    1.41 -  size_t _virtual_space_total;
    1.42 +  // Sum of reserved and committed memory in the virtual spaces
    1.43 +  size_t _reserved_words;
    1.44 +  size_t _committed_words;
    1.45 +
    1.46 +  // Number of virtual spaces
    1.47    size_t _virtual_space_count;
    1.48  
    1.49    ~VirtualSpaceList();
    1.50 @@ -444,7 +447,7 @@
    1.51      _current_virtual_space = v;
    1.52    }
    1.53  
    1.54 -  void link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size);
    1.55 +  void link_vs(VirtualSpaceNode* new_entry);
    1.56  
    1.57    // Get another virtual space and add it to the list.  This
    1.58    // is typically prompted by a failed attempt to allocate a chunk
    1.59 @@ -461,6 +464,8 @@
    1.60                             size_t grow_chunks_by_words,
    1.61                             size_t medium_chunk_bunch);
    1.62  
    1.63 +  bool expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch = false);
    1.64 +
    1.65    // Get the first chunk for a Metaspace.  Used for
    1.66    // special cases such as the boot class loader, reflection
    1.67    // class loader and anonymous class loader.
    1.68 @@ -476,10 +481,15 @@
    1.69    // Allocate the first virtualspace.
    1.70    void initialize(size_t word_size);
    1.71  
    1.72 -  size_t virtual_space_total() { return _virtual_space_total; }
    1.73 -
    1.74 -  void inc_virtual_space_total(size_t v);
    1.75 -  void dec_virtual_space_total(size_t v);
    1.76 +  size_t reserved_words()  { return _reserved_words; }
    1.77 +  size_t reserved_bytes()  { return reserved_words() * BytesPerWord; }
    1.78 +  size_t committed_words() { return _committed_words; }
    1.79 +  size_t committed_bytes() { return committed_words() * BytesPerWord; }
    1.80 +
    1.81 +  void inc_reserved_words(size_t v);
    1.82 +  void dec_reserved_words(size_t v);
    1.83 +  void inc_committed_words(size_t v);
    1.84 +  void dec_committed_words(size_t v);
    1.85    void inc_virtual_space_count();
    1.86    void dec_virtual_space_count();
    1.87  
    1.88 @@ -901,15 +911,6 @@
    1.89    return result;
    1.90  }
    1.91  
    1.92 -// Shrink the virtual space (commit more of the reserved space)
    1.93 -bool VirtualSpaceNode::shrink_by(size_t words) {
    1.94 -  size_t bytes = words * BytesPerWord;
    1.95 -  virtual_space()->shrink_by(bytes);
    1.96 -  return true;
    1.97 -}
    1.98 -
    1.99 -// Add another chunk to the chunk list.
   1.100 -
   1.101  Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
   1.102    assert_lock_strong(SpaceManager::expand_lock());
   1.103    Metachunk* result = take_from_committed(chunk_word_size);
   1.104 @@ -919,23 +920,6 @@
   1.105    return result;
   1.106  }
   1.107  
   1.108 -Metachunk* VirtualSpaceNode::get_chunk_vs_with_expand(size_t chunk_word_size) {
   1.109 -  assert_lock_strong(SpaceManager::expand_lock());
   1.110 -
   1.111 -  Metachunk* new_chunk = get_chunk_vs(chunk_word_size);
   1.112 -
   1.113 -  if (new_chunk == NULL) {
   1.114 -    // Only a small part of the virtualspace is committed when first
   1.115 -    // allocated so committing more here can be expected.
   1.116 -    size_t page_size_words = os::vm_page_size() / BytesPerWord;
   1.117 -    size_t aligned_expand_vs_by_words = align_size_up(chunk_word_size,
   1.118 -                                                    page_size_words);
   1.119 -    expand_by(aligned_expand_vs_by_words, false);
   1.120 -    new_chunk = get_chunk_vs(chunk_word_size);
   1.121 -  }
   1.122 -  return new_chunk;
   1.123 -}
   1.124 -
   1.125  bool VirtualSpaceNode::initialize() {
   1.126  
   1.127    if (!_rs.is_reserved()) {
   1.128 @@ -995,13 +979,22 @@
   1.129    }
   1.130  }
   1.131  
   1.132 -void VirtualSpaceList::inc_virtual_space_total(size_t v) {
   1.133 +void VirtualSpaceList::inc_reserved_words(size_t v) {
   1.134    assert_lock_strong(SpaceManager::expand_lock());
   1.135 -  _virtual_space_total = _virtual_space_total + v;
   1.136 +  _reserved_words = _reserved_words + v;
   1.137  }
   1.138 -void VirtualSpaceList::dec_virtual_space_total(size_t v) {
   1.139 +void VirtualSpaceList::dec_reserved_words(size_t v) {
   1.140    assert_lock_strong(SpaceManager::expand_lock());
   1.141 -  _virtual_space_total = _virtual_space_total - v;
   1.142 +  _reserved_words = _reserved_words - v;
   1.143 +}
   1.144 +
   1.145 +void VirtualSpaceList::inc_committed_words(size_t v) {
   1.146 +  assert_lock_strong(SpaceManager::expand_lock());
   1.147 +  _committed_words = _committed_words + v;
   1.148 +}
   1.149 +void VirtualSpaceList::dec_committed_words(size_t v) {
   1.150 +  assert_lock_strong(SpaceManager::expand_lock());
   1.151 +  _committed_words = _committed_words - v;
   1.152  }
   1.153  
   1.154  void VirtualSpaceList::inc_virtual_space_count() {
   1.155 @@ -1052,7 +1045,8 @@
   1.156        }
   1.157  
   1.158        vsl->purge(chunk_manager());
   1.159 -      dec_virtual_space_total(vsl->reserved()->word_size());
   1.160 +      dec_reserved_words(vsl->reserved_words());
   1.161 +      dec_committed_words(vsl->committed_words());
   1.162        dec_virtual_space_count();
   1.163        purged_vsl = vsl;
   1.164        delete vsl;
   1.165 @@ -1106,7 +1100,8 @@
   1.166                                     _is_class(false),
   1.167                                     _virtual_space_list(NULL),
   1.168                                     _current_virtual_space(NULL),
   1.169 -                                   _virtual_space_total(0),
   1.170 +                                   _reserved_words(0),
   1.171 +                                   _committed_words(0),
   1.172                                     _virtual_space_count(0) {
   1.173    MutexLockerEx cl(SpaceManager::expand_lock(),
   1.174                     Mutex::_no_safepoint_check_flag);
   1.175 @@ -1123,7 +1118,8 @@
   1.176                                     _is_class(true),
   1.177                                     _virtual_space_list(NULL),
   1.178                                     _current_virtual_space(NULL),
   1.179 -                                   _virtual_space_total(0),
   1.180 +                                   _reserved_words(0),
   1.181 +                                   _committed_words(0),
   1.182                                     _virtual_space_count(0) {
   1.183    MutexLockerEx cl(SpaceManager::expand_lock(),
   1.184                     Mutex::_no_safepoint_check_flag);
   1.185 @@ -1133,7 +1129,7 @@
   1.186    _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk);
   1.187    _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
   1.188    assert(succeeded, " VirtualSpaceList initialization should not fail");
   1.189 -  link_vs(class_entry, rs.size()/BytesPerWord);
   1.190 +  link_vs(class_entry);
   1.191  }
   1.192  
   1.193  size_t VirtualSpaceList::free_bytes() {
   1.194 @@ -1156,21 +1152,23 @@
   1.195      delete new_entry;
   1.196      return false;
   1.197    } else {
   1.198 +    assert(new_entry->reserved_words() == vs_word_size, "Must be");
   1.199      // ensure lock-free iteration sees fully initialized node
   1.200      OrderAccess::storestore();
   1.201 -    link_vs(new_entry, vs_word_size);
   1.202 +    link_vs(new_entry);
   1.203      return true;
   1.204    }
   1.205  }
   1.206  
   1.207 -void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size) {
   1.208 +void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry) {
   1.209    if (virtual_space_list() == NULL) {
   1.210        set_virtual_space_list(new_entry);
   1.211    } else {
   1.212      current_virtual_space()->set_next(new_entry);
   1.213    }
   1.214    set_current_virtual_space(new_entry);
   1.215 -  inc_virtual_space_total(vs_word_size);
   1.216 +  inc_reserved_words(new_entry->reserved_words());
   1.217 +  inc_committed_words(new_entry->committed_words());
   1.218    inc_virtual_space_count();
   1.219  #ifdef ASSERT
   1.220    new_entry->mangle();
   1.221 @@ -1181,6 +1179,20 @@
   1.222    }
   1.223  }
   1.224  
   1.225 +bool VirtualSpaceList::expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch) {
   1.226 +  size_t before = node->committed_words();
   1.227 +
   1.228 +  bool result = node->expand_by(word_size, pre_touch);
   1.229 +
   1.230 +  size_t after = node->committed_words();
   1.231 +
   1.232 +  // after and before can be the same if the memory was pre-committed.
   1.233 +  assert(after >= before, "Must be");
   1.234 +  inc_committed_words(after - before);
   1.235 +
   1.236 +  return result;
   1.237 +}
   1.238 +
   1.239  Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
   1.240                                             size_t grow_chunks_by_words,
   1.241                                             size_t medium_chunk_bunch) {
   1.242 @@ -1204,7 +1216,7 @@
   1.243      size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words,
   1.244                                                          page_size_words);
   1.245      bool vs_expanded =
   1.246 -      current_virtual_space()->expand_by(aligned_expand_vs_by_words, false);
   1.247 +      expand_by(current_virtual_space(), aligned_expand_vs_by_words);
   1.248      if (!vs_expanded) {
   1.249        // Should the capacity of the metaspaces be expanded for
   1.250        // this allocation?  If it's the virtual space for classes and is
   1.251 @@ -1215,7 +1227,14 @@
   1.252              MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words);
   1.253          if (grow_vs(grow_vs_words)) {
   1.254            // Got it.  It's on the list now.  Get a chunk from it.
   1.255 -          next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words);
   1.256 +          assert(current_virtual_space()->expanded_words() == 0,
   1.257 +              "New virtuals space nodes should not have expanded");
   1.258 +
   1.259 +          size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words,
   1.260 +                                                              page_size_words);
   1.261 +          // We probably want to expand by aligned_expand_vs_by_words here.
   1.262 +          expand_by(current_virtual_space(), grow_chunks_by_words_aligned);
   1.263 +          next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
   1.264          }
   1.265        } else {
   1.266          // Allocation will fail and induce a GC
   1.267 @@ -1325,7 +1344,7 @@
   1.268    // reserved space, because this is a larger space prereserved for compressed
   1.269    // class pointers.
   1.270    if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) {
   1.271 -    size_t real_allocated = Metaspace::space_list()->virtual_space_total() +
   1.272 +    size_t real_allocated = Metaspace::space_list()->reserved_words() +
   1.273                MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType);
   1.274      if (real_allocated >= MaxMetaspaceSize) {
   1.275        return false;
   1.276 @@ -2615,7 +2634,12 @@
   1.277  
   1.278  size_t MetaspaceAux::reserved_bytes(Metaspace::MetadataType mdtype) {
   1.279    VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
   1.280 -  return list == NULL ? 0 : list->virtual_space_total() * BytesPerWord;
   1.281 +  return list == NULL ? 0 : list->reserved_bytes();
   1.282 +}
   1.283 +
   1.284 +size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) {
   1.285 +  VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
   1.286 +  return list == NULL ? 0 : list->committed_bytes();
   1.287  }
   1.288  
   1.289  size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); }
   1.290 @@ -3357,3 +3381,59 @@
   1.291      class_vsm()->dump(out);
   1.292    }
   1.293  }
   1.294 +
   1.295 +/////////////// Unit tests ///////////////
   1.296 +
   1.297 +#ifndef PRODUCT
   1.298 +
   1.299 +class MetaspaceAuxTest : AllStatic {
   1.300 + public:
   1.301 +  static void test_reserved() {
   1.302 +    size_t reserved = MetaspaceAux::reserved_bytes();
   1.303 +
   1.304 +    assert(reserved > 0, "assert");
   1.305 +
   1.306 +    size_t committed  = MetaspaceAux::committed_bytes();
   1.307 +    assert(committed <= reserved, "assert");
   1.308 +
   1.309 +    size_t reserved_metadata = MetaspaceAux::reserved_bytes(Metaspace::NonClassType);
   1.310 +    assert(reserved_metadata > 0, "assert");
   1.311 +    assert(reserved_metadata <= reserved, "assert");
   1.312 +
   1.313 +    if (UseCompressedClassPointers) {
   1.314 +      size_t reserved_class    = MetaspaceAux::reserved_bytes(Metaspace::ClassType);
   1.315 +      assert(reserved_class > 0, "assert");
   1.316 +      assert(reserved_class < reserved, "assert");
   1.317 +    }
   1.318 +  }
   1.319 +
   1.320 +  static void test_committed() {
   1.321 +    size_t committed = MetaspaceAux::committed_bytes();
   1.322 +
   1.323 +    assert(committed > 0, "assert");
   1.324 +
   1.325 +    size_t reserved  = MetaspaceAux::reserved_bytes();
   1.326 +    assert(committed <= reserved, "assert");
   1.327 +
   1.328 +    size_t committed_metadata = MetaspaceAux::committed_bytes(Metaspace::NonClassType);
   1.329 +    assert(committed_metadata > 0, "assert");
   1.330 +    assert(committed_metadata <= committed, "assert");
   1.331 +
   1.332 +    if (UseCompressedClassPointers) {
   1.333 +      size_t committed_class    = MetaspaceAux::committed_bytes(Metaspace::ClassType);
   1.334 +      assert(committed_class > 0, "assert");
   1.335 +      assert(committed_class < committed, "assert");
   1.336 +    }
   1.337 +  }
   1.338 +
   1.339 +  static void test() {
   1.340 +    test_reserved();
   1.341 +    test_committed();
   1.342 +  }
   1.343 +};
   1.344 +
   1.345 +void MetaspaceAux_test() {
   1.346 +  MetaspaceAuxTest::test();
   1.347 +}
   1.348 +
   1.349 +#endif
     2.1 --- a/src/share/vm/memory/metaspace.hpp	Thu Sep 12 10:15:30 2013 +0200
     2.2 +++ b/src/share/vm/memory/metaspace.hpp	Thu Sep 12 10:15:54 2013 +0200
     2.3 @@ -292,13 +292,18 @@
     2.4    static size_t free_bytes();
     2.5    static size_t free_bytes(Metaspace::MetadataType mdtype);
     2.6  
     2.7 -  // Total capacity in all Metaspaces
     2.8    static size_t reserved_bytes(Metaspace::MetadataType mdtype);
     2.9    static size_t reserved_bytes() {
    2.10      return reserved_bytes(Metaspace::ClassType) +
    2.11             reserved_bytes(Metaspace::NonClassType);
    2.12    }
    2.13  
    2.14 +  static size_t committed_bytes(Metaspace::MetadataType mdtype);
    2.15 +  static size_t committed_bytes() {
    2.16 +    return committed_bytes(Metaspace::ClassType) +
    2.17 +           committed_bytes(Metaspace::NonClassType);
    2.18 +  }
    2.19 +
    2.20    static size_t min_chunk_size_words();
    2.21    static size_t min_chunk_size_bytes() {
    2.22      return min_chunk_size_words() * BytesPerWord;
     3.1 --- a/src/share/vm/prims/jni.cpp	Thu Sep 12 10:15:30 2013 +0200
     3.2 +++ b/src/share/vm/prims/jni.cpp	Thu Sep 12 10:15:54 2013 +0200
     3.3 @@ -5048,12 +5048,16 @@
     3.4  // Forward declaration
     3.5  void TestReservedSpace_test();
     3.6  void TestReserveMemorySpecial_test();
     3.7 +void TestVirtualSpace_test();
     3.8 +void MetaspaceAux_test();
     3.9  
    3.10  void execute_internal_vm_tests() {
    3.11    if (ExecuteInternalVMTests) {
    3.12      tty->print_cr("Running internal VM tests");
    3.13      run_unit_test(TestReservedSpace_test());
    3.14      run_unit_test(TestReserveMemorySpecial_test());
    3.15 +    run_unit_test(TestVirtualSpace_test());
    3.16 +    run_unit_test(MetaspaceAux_test());
    3.17      run_unit_test(GlobalDefinitions::test_globals());
    3.18      run_unit_test(GCTimerAllTest::all());
    3.19      run_unit_test(arrayOopDesc::test_max_array_length());
     4.1 --- a/src/share/vm/runtime/virtualspace.cpp	Thu Sep 12 10:15:30 2013 +0200
     4.2 +++ b/src/share/vm/runtime/virtualspace.cpp	Thu Sep 12 10:15:54 2013 +0200
     4.3 @@ -453,6 +453,42 @@
     4.4    return reserved_size() - committed_size();
     4.5  }
     4.6  
     4.7 +size_t VirtualSpace::actual_committed_size() const {
     4.8 +  // Special VirtualSpaces commit all reserved space up front.
     4.9 +  if (special()) {
    4.10 +    return reserved_size();
    4.11 +  }
    4.12 +
    4.13 +  size_t committed_low    = pointer_delta(_lower_high,  _low_boundary,         sizeof(char));
    4.14 +  size_t committed_middle = pointer_delta(_middle_high, _lower_high_boundary,  sizeof(char));
    4.15 +  size_t committed_high   = pointer_delta(_upper_high,  _middle_high_boundary, sizeof(char));
    4.16 +
    4.17 +#ifdef ASSERT
    4.18 +  size_t lower  = pointer_delta(_lower_high_boundary,  _low_boundary,         sizeof(char));
    4.19 +  size_t middle = pointer_delta(_middle_high_boundary, _lower_high_boundary,  sizeof(char));
    4.20 +  size_t upper  = pointer_delta(_upper_high_boundary,  _middle_high_boundary, sizeof(char));
    4.21 +
    4.22 +  if (committed_high > 0) {
    4.23 +    assert(committed_low == lower, "Must be");
    4.24 +    assert(committed_middle == middle, "Must be");
    4.25 +  }
    4.26 +
    4.27 +  if (committed_middle > 0) {
    4.28 +    assert(committed_low == lower, "Must be");
    4.29 +  }
    4.30 +  if (committed_middle < middle) {
    4.31 +    assert(committed_high == 0, "Must be");
    4.32 +  }
    4.33 +
    4.34 +  if (committed_low < lower) {
    4.35 +    assert(committed_high == 0, "Must be");
    4.36 +    assert(committed_middle == 0, "Must be");
    4.37 +  }
    4.38 +#endif
    4.39 +
    4.40 +  return committed_low + committed_middle + committed_high;
    4.41 +}
    4.42 +
    4.43  
    4.44  bool VirtualSpace::contains(const void* p) const {
    4.45    return low() <= (const char*) p && (const char*) p < high();
    4.46 @@ -910,6 +946,109 @@
    4.47    TestReservedSpace::test_reserved_space();
    4.48  }
    4.49  
    4.50 +#define assert_equals(actual, expected)     \
    4.51 +  assert(actual == expected,                \
    4.52 +    err_msg("Got " SIZE_FORMAT " expected " \
    4.53 +      SIZE_FORMAT, actual, expected));
    4.54 +
    4.55 +#define assert_ge(value1, value2)                  \
    4.56 +  assert(value1 >= value2,                         \
    4.57 +    err_msg("'" #value1 "': " SIZE_FORMAT " '"     \
    4.58 +      #value2 "': " SIZE_FORMAT, value1, value2));
    4.59 +
    4.60 +#define assert_lt(value1, value2)                  \
    4.61 +  assert(value1 < value2,                          \
    4.62 +    err_msg("'" #value1 "': " SIZE_FORMAT " '"     \
    4.63 +      #value2 "': " SIZE_FORMAT, value1, value2));
    4.64 +
    4.65 +
    4.66 +class TestVirtualSpace : AllStatic {
    4.67 + public:
    4.68 +  static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size) {
    4.69 +    size_t granularity = os::vm_allocation_granularity();
    4.70 +    size_t reserve_size_aligned = align_size_up(reserve_size, granularity);
    4.71 +
    4.72 +    ReservedSpace reserved(reserve_size_aligned);
    4.73 +
    4.74 +    assert(reserved.is_reserved(), "Must be");
    4.75 +
    4.76 +    VirtualSpace vs;
    4.77 +    bool initialized = vs.initialize(reserved, 0);
    4.78 +    assert(initialized, "Failed to initialize VirtualSpace");
    4.79 +
    4.80 +    vs.expand_by(commit_size, false);
    4.81 +
    4.82 +    if (vs.special()) {
    4.83 +      assert_equals(vs.actual_committed_size(), reserve_size_aligned);
    4.84 +    } else {
    4.85 +      assert_ge(vs.actual_committed_size(), commit_size);
    4.86 +      // Approximate the commit granularity.
    4.87 +      size_t commit_granularity = UseLargePages ? os::large_page_size() : os::vm_page_size();
    4.88 +      assert_lt(vs.actual_committed_size(), commit_size + commit_granularity);
    4.89 +    }
    4.90 +
    4.91 +    reserved.release();
    4.92 +  }
    4.93 +
    4.94 +  static void test_virtual_space_actual_committed_space_one_large_page() {
    4.95 +    if (!UseLargePages) {
    4.96 +      return;
    4.97 +    }
    4.98 +
    4.99 +    size_t large_page_size = os::large_page_size();
   4.100 +
   4.101 +    ReservedSpace reserved(large_page_size, large_page_size, true, false);
   4.102 +
   4.103 +    assert(reserved.is_reserved(), "Must be");
   4.104 +
   4.105 +    VirtualSpace vs;
   4.106 +    bool initialized = vs.initialize(reserved, 0);
   4.107 +    assert(initialized, "Failed to initialize VirtualSpace");
   4.108 +
   4.109 +    vs.expand_by(large_page_size, false);
   4.110 +
   4.111 +    assert_equals(vs.actual_committed_size(), large_page_size);
   4.112 +
   4.113 +    reserved.release();
   4.114 +  }
   4.115 +
   4.116 +  static void test_virtual_space_actual_committed_space() {
   4.117 +    test_virtual_space_actual_committed_space(4 * K, 0);
   4.118 +    test_virtual_space_actual_committed_space(4 * K, 4 * K);
   4.119 +    test_virtual_space_actual_committed_space(8 * K, 0);
   4.120 +    test_virtual_space_actual_committed_space(8 * K, 4 * K);
   4.121 +    test_virtual_space_actual_committed_space(8 * K, 8 * K);
   4.122 +    test_virtual_space_actual_committed_space(12 * K, 0);
   4.123 +    test_virtual_space_actual_committed_space(12 * K, 4 * K);
   4.124 +    test_virtual_space_actual_committed_space(12 * K, 8 * K);
   4.125 +    test_virtual_space_actual_committed_space(12 * K, 12 * K);
   4.126 +    test_virtual_space_actual_committed_space(64 * K, 0);
   4.127 +    test_virtual_space_actual_committed_space(64 * K, 32 * K);
   4.128 +    test_virtual_space_actual_committed_space(64 * K, 64 * K);
   4.129 +    test_virtual_space_actual_committed_space(2 * M, 0);
   4.130 +    test_virtual_space_actual_committed_space(2 * M, 4 * K);
   4.131 +    test_virtual_space_actual_committed_space(2 * M, 64 * K);
   4.132 +    test_virtual_space_actual_committed_space(2 * M, 1 * M);
   4.133 +    test_virtual_space_actual_committed_space(2 * M, 2 * M);
   4.134 +    test_virtual_space_actual_committed_space(10 * M, 0);
   4.135 +    test_virtual_space_actual_committed_space(10 * M, 4 * K);
   4.136 +    test_virtual_space_actual_committed_space(10 * M, 8 * K);
   4.137 +    test_virtual_space_actual_committed_space(10 * M, 1 * M);
   4.138 +    test_virtual_space_actual_committed_space(10 * M, 2 * M);
   4.139 +    test_virtual_space_actual_committed_space(10 * M, 5 * M);
   4.140 +    test_virtual_space_actual_committed_space(10 * M, 10 * M);
   4.141 +  }
   4.142 +
   4.143 +  static void test_virtual_space() {
   4.144 +    test_virtual_space_actual_committed_space();
   4.145 +    test_virtual_space_actual_committed_space_one_large_page();
   4.146 +  }
   4.147 +};
   4.148 +
   4.149 +void TestVirtualSpace_test() {
   4.150 +  TestVirtualSpace::test_virtual_space();
   4.151 +}
   4.152 +
   4.153  #endif // PRODUCT
   4.154  
   4.155  #endif
     5.1 --- a/src/share/vm/runtime/virtualspace.hpp	Thu Sep 12 10:15:30 2013 +0200
     5.2 +++ b/src/share/vm/runtime/virtualspace.hpp	Thu Sep 12 10:15:54 2013 +0200
     5.3 @@ -183,11 +183,16 @@
     5.4    // Destruction
     5.5    ~VirtualSpace();
     5.6  
     5.7 -  // Testers (all sizes are byte sizes)
     5.8 -  size_t committed_size()   const;
     5.9 -  size_t reserved_size()    const;
    5.10 +  // Reserved memory
    5.11 +  size_t reserved_size() const;
    5.12 +  // Actually committed OS memory
    5.13 +  size_t actual_committed_size() const;
    5.14 +  // Memory used/expanded in this virtual space
    5.15 +  size_t committed_size() const;
    5.16 +  // Memory left to use/expand in this virtual space
    5.17    size_t uncommitted_size() const;
    5.18 -  bool   contains(const void* p)  const;
    5.19 +
    5.20 +  bool   contains(const void* p) const;
    5.21  
    5.22    // Operations
    5.23    // returns true on success, false otherwise

mercurial