src/share/vm/memory/metaspace.cpp

changeset 9064
ea0367ce6726
parent 9063
777ace6655eb
child 9122
024be04bb151
child 9301
d47844b56aaf
     1.1 --- a/src/share/vm/memory/metaspace.cpp	Mon Dec 25 00:08:23 2017 -0500
     1.2 +++ b/src/share/vm/memory/metaspace.cpp	Wed Jan 03 03:17:10 2018 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -154,7 +154,7 @@
    1.11  
    1.12    // Map a size to a list index assuming that there are lists
    1.13    // for special, small, medium, and humongous chunks.
    1.14 -  static ChunkIndex list_index(size_t size);
    1.15 +  ChunkIndex list_index(size_t size);
    1.16  
    1.17    // Remove the chunk from its freelist.  It is
    1.18    // expected to be on one of the _free_chunks[] lists.
    1.19 @@ -1752,7 +1752,11 @@
    1.20    st->print_cr("Sum free chunk total " SIZE_FORMAT "  count " SIZE_FORMAT,
    1.21                  sum_free_chunks(), sum_free_chunks_count());
    1.22  }
    1.23 +
    1.24  ChunkList* ChunkManager::free_chunks(ChunkIndex index) {
    1.25 +  assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex,
    1.26 +         err_msg("Bad index: %d", (int)index));
    1.27 +
    1.28    return &_free_chunks[index];
    1.29  }
    1.30  
    1.31 @@ -1864,7 +1868,7 @@
    1.32    }
    1.33  
    1.34    assert((word_size <= chunk->word_size()) ||
    1.35 -         list_index(chunk->word_size() == HumongousIndex),
    1.36 +         (list_index(chunk->word_size()) == HumongousIndex),
    1.37           "Non-humongous variable sized chunk");
    1.38    if (TraceMetadataChunkAllocation) {
    1.39      size_t list_count;
    1.40 @@ -2358,22 +2362,18 @@
    1.41  }
    1.42  
    1.43  ChunkIndex ChunkManager::list_index(size_t size) {
    1.44 -  switch (size) {
    1.45 -    case SpecializedChunk:
    1.46 -      assert(SpecializedChunk == ClassSpecializedChunk,
    1.47 -             "Need branch for ClassSpecializedChunk");
    1.48 -      return SpecializedIndex;
    1.49 -    case SmallChunk:
    1.50 -    case ClassSmallChunk:
    1.51 -      return SmallIndex;
    1.52 -    case MediumChunk:
    1.53 -    case ClassMediumChunk:
    1.54 -      return MediumIndex;
    1.55 -    default:
    1.56 -      assert(size > MediumChunk || size > ClassMediumChunk,
    1.57 -             "Not a humongous chunk");
    1.58 -      return HumongousIndex;
    1.59 +  if (free_chunks(SpecializedIndex)->size() == size) {
    1.60 +    return SpecializedIndex;
    1.61    }
    1.62 +  if (free_chunks(SmallIndex)->size() == size) {
    1.63 +    return SmallIndex;
    1.64 +  }
    1.65 +  if (free_chunks(MediumIndex)->size() == size) {
    1.66 +    return MediumIndex;
    1.67 +  }
    1.68 +
    1.69 +  assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk");
    1.70 +  return HumongousIndex;
    1.71  }
    1.72  
    1.73  void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
    1.74 @@ -2395,7 +2395,7 @@
    1.75  
    1.76    // Find the correct list and and set the current
    1.77    // chunk for that list.
    1.78 -  ChunkIndex index = ChunkManager::list_index(new_chunk->word_size());
    1.79 +  ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size());
    1.80  
    1.81    if (index != HumongousIndex) {
    1.82      retire_current_chunk();
    1.83 @@ -4031,4 +4031,40 @@
    1.84    SpaceManagerTest::test_adjust_initial_chunk_size();
    1.85  }
    1.86  
    1.87 +// The following test is placed here instead of a gtest / unittest file
    1.88 +// because the ChunkManager class is only available in this file.
    1.89 +void ChunkManager_test_list_index() {
    1.90 +  ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk);
    1.91 +
    1.92 +  // Test previous bug where a query for a humongous class metachunk,
    1.93 +  // incorrectly matched the non-class medium metachunk size.
    1.94 +  {
    1.95 +    assert(MediumChunk > ClassMediumChunk, "Precondition for test");
    1.96 +
    1.97 +    ChunkIndex index = manager.list_index(MediumChunk);
    1.98 +
    1.99 +    assert(index == HumongousIndex,
   1.100 +           err_msg("Requested size is larger than ClassMediumChunk,"
   1.101 +           " so should return HumongousIndex. Got index: %d", (int)index));
   1.102 +  }
   1.103 +
   1.104 +  // Check the specified sizes as well.
   1.105 +  {
   1.106 +    ChunkIndex index = manager.list_index(ClassSpecializedChunk);
   1.107 +    assert(index == SpecializedIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
   1.108 +  }
   1.109 +  {
   1.110 +    ChunkIndex index = manager.list_index(ClassSmallChunk);
   1.111 +    assert(index == SmallIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
   1.112 +  }
   1.113 +  {
   1.114 +    ChunkIndex index = manager.list_index(ClassMediumChunk);
   1.115 +    assert(index == MediumIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
   1.116 +  }
   1.117 +  {
   1.118 +    ChunkIndex index = manager.list_index(ClassMediumChunk + 1);
   1.119 +    assert(index == HumongousIndex, err_msg("Wrong index returned. Got index: %d", (int)index));
   1.120 +  }
   1.121 +}
   1.122 +
   1.123  #endif

mercurial