src/share/vm/memory/metaspace.cpp

changeset 5771
b960c9df4f11
parent 5770
9361de86a50f
child 5774
03f493ce3a71
     1.1 --- a/src/share/vm/memory/metaspace.cpp	Fri Sep 20 11:00:38 2013 +0200
     1.2 +++ b/src/share/vm/memory/metaspace.cpp	Sat Sep 21 10:09:42 2013 +0200
     1.3 @@ -23,6 +23,7 @@
     1.4   */
     1.5  #include "precompiled.hpp"
     1.6  #include "gc_interface/collectedHeap.hpp"
     1.7 +#include "memory/allocation.hpp"
     1.8  #include "memory/binaryTreeDictionary.hpp"
     1.9  #include "memory/freeList.hpp"
    1.10  #include "memory/collectorPolicy.hpp"
    1.11 @@ -111,7 +112,7 @@
    1.12  // Has three lists of free chunks, and a total size and
    1.13  // count that includes all three
    1.14  
    1.15 -class ChunkManager VALUE_OBJ_CLASS_SPEC {
    1.16 +class ChunkManager : public CHeapObj<mtInternal> {
    1.17  
    1.18    // Free list of chunks of different sizes.
    1.19    //   SpecializedChunk
    1.20 @@ -158,7 +159,12 @@
    1.21  
    1.22   public:
    1.23  
    1.24 -  ChunkManager() : _free_chunks_total(0), _free_chunks_count(0) {}
    1.25 +  ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size)
    1.26 +      : _free_chunks_total(0), _free_chunks_count(0) {
    1.27 +    _free_chunks[SpecializedIndex].set_size(specialized_size);
    1.28 +    _free_chunks[SmallIndex].set_size(small_size);
    1.29 +    _free_chunks[MediumIndex].set_size(medium_size);
    1.30 +  }
    1.31  
    1.32    // add or delete (return) a chunk to the global freelist.
    1.33    Metachunk* chunk_freelist_allocate(size_t word_size);
    1.34 @@ -219,7 +225,7 @@
    1.35    void locked_print_free_chunks(outputStream* st);
    1.36    void locked_print_sum_free_chunks(outputStream* st);
    1.37  
    1.38 -  void print_on(outputStream* st);
    1.39 +  void print_on(outputStream* st) const;
    1.40  };
    1.41  
    1.42  // Used to manage the free list of Metablocks (a block corresponds
    1.43 @@ -276,11 +282,6 @@
    1.44    // VirtualSpace
    1.45    Metachunk* first_chunk() { return (Metachunk*) bottom(); }
    1.46  
    1.47 -  void inc_container_count();
    1.48 -#ifdef ASSERT
    1.49 -  uint container_count_slow();
    1.50 -#endif
    1.51 -
    1.52   public:
    1.53  
    1.54    VirtualSpaceNode(size_t byte_size);
    1.55 @@ -314,8 +315,10 @@
    1.56    void inc_top(size_t word_size) { _top += word_size; }
    1.57  
    1.58    uintx container_count() { return _container_count; }
    1.59 +  void inc_container_count();
    1.60    void dec_container_count();
    1.61  #ifdef ASSERT
    1.62 +  uint container_count_slow();
    1.63    void verify_container_count();
    1.64  #endif
    1.65  
    1.66 @@ -421,8 +424,6 @@
    1.67    VirtualSpaceNode* _virtual_space_list;
    1.68    // virtual space currently being used for allocations
    1.69    VirtualSpaceNode* _current_virtual_space;
    1.70 -  // Free chunk list for all other metadata
    1.71 -  ChunkManager      _chunk_manager;
    1.72  
    1.73    // Can this virtual list allocate >1 spaces?  Also, used to determine
    1.74    // whether to allocate unlimited small chunks in this virtual space
    1.75 @@ -475,7 +476,6 @@
    1.76      return _current_virtual_space;
    1.77    }
    1.78  
    1.79 -  ChunkManager* chunk_manager() { return &_chunk_manager; }
    1.80    bool is_class() const { return _is_class; }
    1.81  
    1.82    // Allocate the first virtualspace.
    1.83 @@ -494,14 +494,7 @@
    1.84    void dec_virtual_space_count();
    1.85  
    1.86    // Unlink empty VirtualSpaceNodes and free it.
    1.87 -  void purge();
    1.88 -
    1.89 -  // Used and capacity in the entire list of virtual spaces.
    1.90 -  // These are global values shared by all Metaspaces
    1.91 -  size_t capacity_words_sum();
    1.92 -  size_t capacity_bytes_sum() { return capacity_words_sum() * BytesPerWord; }
    1.93 -  size_t used_words_sum();
    1.94 -  size_t used_bytes_sum() { return used_words_sum() * BytesPerWord; }
    1.95 +  void purge(ChunkManager* chunk_manager);
    1.96  
    1.97    bool contains(const void *ptr);
    1.98  
    1.99 @@ -582,18 +575,12 @@
   1.100    // Type of metadata allocated.
   1.101    Metaspace::MetadataType _mdtype;
   1.102  
   1.103 -  // Chunk related size
   1.104 -  size_t _medium_chunk_bunch;
   1.105 -
   1.106    // List of chunks in use by this SpaceManager.  Allocations
   1.107    // are done from the current chunk.  The list is used for deallocating
   1.108    // chunks when the SpaceManager is freed.
   1.109    Metachunk* _chunks_in_use[NumberOfInUseLists];
   1.110    Metachunk* _current_chunk;
   1.111  
   1.112 -  // Virtual space where allocation comes from.
   1.113 -  VirtualSpaceList* _vs_list;
   1.114 -
   1.115    // Number of small chunks to allocate to a manager
   1.116    // If class space manager, small chunks are unlimited
   1.117    static uint const _small_chunk_limit;
   1.118 @@ -626,7 +613,9 @@
   1.119    }
   1.120  
   1.121    Metaspace::MetadataType mdtype() { return _mdtype; }
   1.122 -  VirtualSpaceList* vs_list() const    { return _vs_list; }
   1.123 +
   1.124 +  VirtualSpaceList* vs_list()   const { return Metaspace::get_space_list(_mdtype); }
   1.125 +  ChunkManager* chunk_manager() const { return Metaspace::get_chunk_manager(_mdtype); }
   1.126  
   1.127    Metachunk* current_chunk() const { return _current_chunk; }
   1.128    void set_current_chunk(Metachunk* v) {
   1.129 @@ -648,18 +637,19 @@
   1.130  
   1.131   public:
   1.132    SpaceManager(Metaspace::MetadataType mdtype,
   1.133 -               Mutex* lock,
   1.134 -               VirtualSpaceList* vs_list);
   1.135 +               Mutex* lock);
   1.136    ~SpaceManager();
   1.137  
   1.138    enum ChunkMultiples {
   1.139      MediumChunkMultiple = 4
   1.140    };
   1.141  
   1.142 +  bool is_class() { return _mdtype == Metaspace::ClassType; }
   1.143 +
   1.144    // Accessors
   1.145    size_t specialized_chunk_size() { return SpecializedChunk; }
   1.146 -  size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; }
   1.147 -  size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; }
   1.148 +  size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; }
   1.149 +  size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; }
   1.150    size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; }
   1.151  
   1.152    size_t allocated_blocks_words() const { return _allocated_blocks_words; }
   1.153 @@ -762,7 +752,7 @@
   1.154    _container_count++;
   1.155    assert(_container_count == container_count_slow(),
   1.156           err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT
   1.157 -                 "container_count_slow() " SIZE_FORMAT,
   1.158 +                 " container_count_slow() " SIZE_FORMAT,
   1.159                   _container_count, container_count_slow()));
   1.160  }
   1.161  
   1.162 @@ -775,7 +765,7 @@
   1.163  void VirtualSpaceNode::verify_container_count() {
   1.164    assert(_container_count == container_count_slow(),
   1.165      err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT
   1.166 -            "container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow()));
   1.167 +            " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow()));
   1.168  }
   1.169  #endif
   1.170  
   1.171 @@ -1020,7 +1010,7 @@
   1.172  // Walk the list of VirtualSpaceNodes and delete
   1.173  // nodes with a 0 container_count.  Remove Metachunks in
   1.174  // the node from their respective freelists.
   1.175 -void VirtualSpaceList::purge() {
   1.176 +void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
   1.177    assert_lock_strong(SpaceManager::expand_lock());
   1.178    // Don't use a VirtualSpaceListIterator because this
   1.179    // list is being changed and a straightforward use of an iterator is not safe.
   1.180 @@ -1042,7 +1032,7 @@
   1.181          prev_vsl->set_next(vsl->next());
   1.182        }
   1.183  
   1.184 -      vsl->purge(chunk_manager());
   1.185 +      vsl->purge(chunk_manager);
   1.186        dec_reserved_words(vsl->reserved_words());
   1.187        dec_committed_words(vsl->committed_words());
   1.188        dec_virtual_space_count();
   1.189 @@ -1064,36 +1054,6 @@
   1.190  #endif
   1.191  }
   1.192  
   1.193 -size_t VirtualSpaceList::used_words_sum() {
   1.194 -  size_t allocated_by_vs = 0;
   1.195 -  VirtualSpaceListIterator iter(virtual_space_list());
   1.196 -  while (iter.repeat()) {
   1.197 -    VirtualSpaceNode* vsl = iter.get_next();
   1.198 -    // Sum used region [bottom, top) in each virtualspace
   1.199 -    allocated_by_vs += vsl->used_words_in_vs();
   1.200 -  }
   1.201 -  assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(),
   1.202 -    err_msg("Total in free chunks " SIZE_FORMAT
   1.203 -            " greater than total from virtual_spaces " SIZE_FORMAT,
   1.204 -            allocated_by_vs, chunk_manager()->free_chunks_total_words()));
   1.205 -  size_t used =
   1.206 -    allocated_by_vs - chunk_manager()->free_chunks_total_words();
   1.207 -  return used;
   1.208 -}
   1.209 -
   1.210 -// Space available in all MetadataVirtualspaces allocated
   1.211 -// for metadata.  This is the upper limit on the capacity
   1.212 -// of chunks allocated out of all the MetadataVirtualspaces.
   1.213 -size_t VirtualSpaceList::capacity_words_sum() {
   1.214 -  size_t capacity = 0;
   1.215 -  VirtualSpaceListIterator iter(virtual_space_list());
   1.216 -  while (iter.repeat()) {
   1.217 -    VirtualSpaceNode* vsl = iter.get_next();
   1.218 -    capacity += vsl->capacity_words_in_vs();
   1.219 -  }
   1.220 -  return capacity;
   1.221 -}
   1.222 -
   1.223  VirtualSpaceList::VirtualSpaceList(size_t word_size ) :
   1.224                                     _is_class(false),
   1.225                                     _virtual_space_list(NULL),
   1.226 @@ -1104,10 +1064,6 @@
   1.227    MutexLockerEx cl(SpaceManager::expand_lock(),
   1.228                     Mutex::_no_safepoint_check_flag);
   1.229    bool initialization_succeeded = grow_vs(word_size);
   1.230 -
   1.231 -  _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
   1.232 -  _chunk_manager.free_chunks(SmallIndex)->set_size(SmallChunk);
   1.233 -  _chunk_manager.free_chunks(MediumIndex)->set_size(MediumChunk);
   1.234    assert(initialization_succeeded,
   1.235      " VirtualSpaceList initialization should not fail");
   1.236  }
   1.237 @@ -1123,9 +1079,6 @@
   1.238                     Mutex::_no_safepoint_check_flag);
   1.239    VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs);
   1.240    bool succeeded = class_entry->initialize();
   1.241 -  _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
   1.242 -  _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk);
   1.243 -  _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
   1.244    assert(succeeded, " VirtualSpaceList initialization should not fail");
   1.245    link_vs(class_entry);
   1.246  }
   1.247 @@ -1195,15 +1148,8 @@
   1.248                                             size_t grow_chunks_by_words,
   1.249                                             size_t medium_chunk_bunch) {
   1.250  
   1.251 -  // Get a chunk from the chunk freelist
   1.252 -  Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words);
   1.253 -
   1.254 -  if (next != NULL) {
   1.255 -    next->container()->inc_container_count();
   1.256 -  } else {
   1.257 -    // Allocate a chunk out of the current virtual space.
   1.258 -    next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
   1.259 -  }
   1.260 +  // Allocate a chunk out of the current virtual space.
   1.261 +  Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
   1.262  
   1.263    if (next == NULL) {
   1.264      // Not enough room in current virtual space.  Try to commit
   1.265 @@ -1537,15 +1483,15 @@
   1.266        if (dummy_chunk == NULL) {
   1.267          break;
   1.268        }
   1.269 -      vsl->chunk_manager()->chunk_freelist_deallocate(dummy_chunk);
   1.270 +      sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk);
   1.271  
   1.272        if (TraceMetadataChunkAllocation && Verbose) {
   1.273          gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ",
   1.274                                 sm->sum_count_in_chunks_in_use());
   1.275          dummy_chunk->print_on(gclog_or_tty);
   1.276          gclog_or_tty->print_cr("  Free chunks total %d  count %d",
   1.277 -                               vsl->chunk_manager()->free_chunks_total_words(),
   1.278 -                               vsl->chunk_manager()->free_chunks_count());
   1.279 +                               sm->chunk_manager()->free_chunks_total_words(),
   1.280 +                               sm->chunk_manager()->free_chunks_count());
   1.281        }
   1.282      }
   1.283    } else {
   1.284 @@ -1797,6 +1743,8 @@
   1.285    // work.
   1.286    chunk->set_is_free(false);
   1.287  #endif
   1.288 +  chunk->container()->inc_container_count();
   1.289 +
   1.290    slow_locked_verify();
   1.291    return chunk;
   1.292  }
   1.293 @@ -1831,9 +1779,9 @@
   1.294    return chunk;
   1.295  }
   1.296  
   1.297 -void ChunkManager::print_on(outputStream* out) {
   1.298 +void ChunkManager::print_on(outputStream* out) const {
   1.299    if (PrintFLSStatistics != 0) {
   1.300 -    humongous_dictionary()->report_statistics();
   1.301 +    const_cast<ChunkManager *>(this)->humongous_dictionary()->report_statistics();
   1.302    }
   1.303  }
   1.304  
   1.305 @@ -1980,8 +1928,8 @@
   1.306      }
   1.307    }
   1.308  
   1.309 -  vs_list()->chunk_manager()->locked_print_free_chunks(st);
   1.310 -  vs_list()->chunk_manager()->locked_print_sum_free_chunks(st);
   1.311 +  chunk_manager()->locked_print_free_chunks(st);
   1.312 +  chunk_manager()->locked_print_sum_free_chunks(st);
   1.313  }
   1.314  
   1.315  size_t SpaceManager::calc_chunk_size(size_t word_size) {
   1.316 @@ -2085,9 +2033,7 @@
   1.317  }
   1.318  
   1.319  SpaceManager::SpaceManager(Metaspace::MetadataType mdtype,
   1.320 -                           Mutex* lock,
   1.321 -                           VirtualSpaceList* vs_list) :
   1.322 -  _vs_list(vs_list),
   1.323 +                           Mutex* lock) :
   1.324    _mdtype(mdtype),
   1.325    _allocated_blocks_words(0),
   1.326    _allocated_chunks_words(0),
   1.327 @@ -2173,9 +2119,7 @@
   1.328    MutexLockerEx fcl(SpaceManager::expand_lock(),
   1.329                      Mutex::_no_safepoint_check_flag);
   1.330  
   1.331 -  ChunkManager* chunk_manager = vs_list()->chunk_manager();
   1.332 -
   1.333 -  chunk_manager->slow_locked_verify();
   1.334 +  chunk_manager()->slow_locked_verify();
   1.335  
   1.336    dec_total_from_size_metrics();
   1.337  
   1.338 @@ -2189,8 +2133,8 @@
   1.339  
   1.340    // Have to update before the chunks_in_use lists are emptied
   1.341    // below.
   1.342 -  chunk_manager->inc_free_chunks_total(allocated_chunks_words(),
   1.343 -                                       sum_count_in_chunks_in_use());
   1.344 +  chunk_manager()->inc_free_chunks_total(allocated_chunks_words(),
   1.345 +                                         sum_count_in_chunks_in_use());
   1.346  
   1.347    // Add all the chunks in use by this space manager
   1.348    // to the global list of free chunks.
   1.349 @@ -2205,11 +2149,11 @@
   1.350                               chunk_size_name(i));
   1.351      }
   1.352      Metachunk* chunks = chunks_in_use(i);
   1.353 -    chunk_manager->return_chunks(i, chunks);
   1.354 +    chunk_manager()->return_chunks(i, chunks);
   1.355      set_chunks_in_use(i, NULL);
   1.356      if (TraceMetadataChunkAllocation && Verbose) {
   1.357        gclog_or_tty->print_cr("updated freelist count %d %s",
   1.358 -                             chunk_manager->free_chunks(i)->count(),
   1.359 +                             chunk_manager()->free_chunks(i)->count(),
   1.360                               chunk_size_name(i));
   1.361      }
   1.362      assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
   1.363 @@ -2246,16 +2190,16 @@
   1.364                     humongous_chunks->word_size(), HumongousChunkGranularity));
   1.365      Metachunk* next_humongous_chunks = humongous_chunks->next();
   1.366      humongous_chunks->container()->dec_container_count();
   1.367 -    chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks);
   1.368 +    chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks);
   1.369      humongous_chunks = next_humongous_chunks;
   1.370    }
   1.371    if (TraceMetadataChunkAllocation && Verbose) {
   1.372      gclog_or_tty->print_cr("");
   1.373      gclog_or_tty->print_cr("updated dictionary count %d %s",
   1.374 -                     chunk_manager->humongous_dictionary()->total_count(),
   1.375 +                     chunk_manager()->humongous_dictionary()->total_count(),
   1.376                       chunk_size_name(HumongousIndex));
   1.377    }
   1.378 -  chunk_manager->slow_locked_verify();
   1.379 +  chunk_manager()->slow_locked_verify();
   1.380  }
   1.381  
   1.382  const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
   1.383 @@ -2344,9 +2288,7 @@
   1.384      gclog_or_tty->print("SpaceManager::add_chunk: %d) ",
   1.385                          sum_count_in_chunks_in_use());
   1.386      new_chunk->print_on(gclog_or_tty);
   1.387 -    if (vs_list() != NULL) {
   1.388 -      vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty);
   1.389 -    }
   1.390 +    chunk_manager()->locked_print_free_chunks(gclog_or_tty);
   1.391    }
   1.392  }
   1.393  
   1.394 @@ -2362,10 +2304,14 @@
   1.395  
   1.396  Metachunk* SpaceManager::get_new_chunk(size_t word_size,
   1.397                                         size_t grow_chunks_by_words) {
   1.398 -
   1.399 -  Metachunk* next = vs_list()->get_new_chunk(word_size,
   1.400 -                                             grow_chunks_by_words,
   1.401 -                                             medium_chunk_bunch());
   1.402 +  // Get a chunk from the chunk freelist
   1.403 +  Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words);
   1.404 +
   1.405 +  if (next == NULL) {
   1.406 +    next = vs_list()->get_new_chunk(word_size,
   1.407 +                                    grow_chunks_by_words,
   1.408 +                                    medium_chunk_bunch());
   1.409 +  }
   1.410  
   1.411    if (TraceMetadataHumongousAllocation && next != NULL &&
   1.412        SpaceManager::is_humongous(next->word_size())) {
   1.413 @@ -2645,13 +2591,12 @@
   1.414  size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); }
   1.415  
   1.416  size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) {
   1.417 -  VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
   1.418 -  if (list == NULL) {
   1.419 +  ChunkManager* chunk_manager = Metaspace::get_chunk_manager(mdtype);
   1.420 +  if (chunk_manager == NULL) {
   1.421      return 0;
   1.422    }
   1.423 -  ChunkManager* chunk = list->chunk_manager();
   1.424 -  chunk->slow_verify();
   1.425 -  return chunk->free_chunks_total_words();
   1.426 +  chunk_manager->slow_verify();
   1.427 +  return chunk_manager->free_chunks_total_words();
   1.428  }
   1.429  
   1.430  size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) {
   1.431 @@ -2802,9 +2747,9 @@
   1.432  }
   1.433  
   1.434  void MetaspaceAux::verify_free_chunks() {
   1.435 -  Metaspace::space_list()->chunk_manager()->verify();
   1.436 +  Metaspace::chunk_manager_metadata()->verify();
   1.437    if (Metaspace::using_class_space()) {
   1.438 -    Metaspace::class_space_list()->chunk_manager()->verify();
   1.439 +    Metaspace::chunk_manager_class()->verify();
   1.440    }
   1.441  }
   1.442  
   1.443 @@ -2875,6 +2820,9 @@
   1.444  VirtualSpaceList* Metaspace::_space_list = NULL;
   1.445  VirtualSpaceList* Metaspace::_class_space_list = NULL;
   1.446  
   1.447 +ChunkManager* Metaspace::_chunk_manager_metadata = NULL;
   1.448 +ChunkManager* Metaspace::_chunk_manager_class = NULL;
   1.449 +
   1.450  #define VIRTUALSPACEMULTIPLIER 2
   1.451  
   1.452  #ifdef _LP64
   1.453 @@ -2982,6 +2930,7 @@
   1.454           err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize));
   1.455    assert(using_class_space(), "Must be using class space");
   1.456    _class_space_list = new VirtualSpaceList(rs);
   1.457 +  _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk);
   1.458  }
   1.459  
   1.460  #endif
   1.461 @@ -3007,6 +2956,7 @@
   1.462      // remainder is the misc code and data chunks.
   1.463      cds_total = FileMapInfo::shared_spaces_size();
   1.464      _space_list = new VirtualSpaceList(cds_total/wordSize);
   1.465 +    _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk);
   1.466  
   1.467  #ifdef _LP64
   1.468      // Set the compressed klass pointer base so that decoding of these pointers works
   1.469 @@ -3074,15 +3024,30 @@
   1.470      size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size();
   1.471      // Initialize the list of virtual spaces.
   1.472      _space_list = new VirtualSpaceList(word_size);
   1.473 +    _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk);
   1.474    }
   1.475  }
   1.476  
   1.477 +Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype,
   1.478 +                                               size_t chunk_word_size,
   1.479 +                                               size_t chunk_bunch) {
   1.480 +  // Get a chunk from the chunk freelist
   1.481 +  Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size);
   1.482 +  if (chunk != NULL) {
   1.483 +    return chunk;
   1.484 +  }
   1.485 +
   1.486 +  return get_space_list(mdtype)->get_initialization_chunk(chunk_word_size, chunk_bunch);
   1.487 +}
   1.488 +
   1.489  void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
   1.490  
   1.491    assert(space_list() != NULL,
   1.492      "Metadata VirtualSpaceList has not been initialized");
   1.493 -
   1.494 -  _vsm = new SpaceManager(NonClassType, lock, space_list());
   1.495 +  assert(chunk_manager_metadata() != NULL,
   1.496 +    "Metadata ChunkManager has not been initialized");
   1.497 +
   1.498 +  _vsm = new SpaceManager(NonClassType, lock);
   1.499    if (_vsm == NULL) {
   1.500      return;
   1.501    }
   1.502 @@ -3091,11 +3056,13 @@
   1.503    vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size);
   1.504  
   1.505    if (using_class_space()) {
   1.506 -    assert(class_space_list() != NULL,
   1.507 -      "Class VirtualSpaceList has not been initialized");
   1.508 +  assert(class_space_list() != NULL,
   1.509 +    "Class VirtualSpaceList has not been initialized");
   1.510 +  assert(chunk_manager_class() != NULL,
   1.511 +    "Class ChunkManager has not been initialized");
   1.512  
   1.513      // Allocate SpaceManager for classes.
   1.514 -    _class_vsm = new SpaceManager(ClassType, lock, class_space_list());
   1.515 +    _class_vsm = new SpaceManager(ClassType, lock);
   1.516      if (_class_vsm == NULL) {
   1.517        return;
   1.518      }
   1.519 @@ -3104,9 +3071,9 @@
   1.520    MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
   1.521  
   1.522    // Allocate chunk for metadata objects
   1.523 -  Metachunk* new_chunk =
   1.524 -     space_list()->get_initialization_chunk(word_size,
   1.525 -                                            vsm()->medium_chunk_bunch());
   1.526 +  Metachunk* new_chunk = get_initialization_chunk(NonClassType,
   1.527 +                                                  word_size,
   1.528 +                                                  vsm()->medium_chunk_bunch());
   1.529    assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks");
   1.530    if (new_chunk != NULL) {
   1.531      // Add to this manager's list of chunks in use and current_chunk().
   1.532 @@ -3115,9 +3082,9 @@
   1.533  
   1.534    // Allocate chunk for class metadata objects
   1.535    if (using_class_space()) {
   1.536 -    Metachunk* class_chunk =
   1.537 -       class_space_list()->get_initialization_chunk(class_word_size,
   1.538 -                                                    class_vsm()->medium_chunk_bunch());
   1.539 +    Metachunk* class_chunk = get_initialization_chunk(ClassType,
   1.540 +                                                      class_word_size,
   1.541 +                                                      class_vsm()->medium_chunk_bunch());
   1.542      if (class_chunk != NULL) {
   1.543        class_vsm()->add_chunk(class_chunk, true);
   1.544      }
   1.545 @@ -3334,12 +3301,16 @@
   1.546    }
   1.547  }
   1.548  
   1.549 +void Metaspace::purge(MetadataType mdtype) {
   1.550 +  get_space_list(mdtype)->purge(get_chunk_manager(mdtype));
   1.551 +}
   1.552 +
   1.553  void Metaspace::purge() {
   1.554    MutexLockerEx cl(SpaceManager::expand_lock(),
   1.555                     Mutex::_no_safepoint_check_flag);
   1.556 -  space_list()->purge();
   1.557 +  purge(NonClassType);
   1.558    if (using_class_space()) {
   1.559 -    class_space_list()->purge();
   1.560 +    purge(ClassType);
   1.561    }
   1.562  }
   1.563  

mercurial