1 /*
   2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_MEMORY_METASPACE_CHUNKMANAGER_HPP
  26 #define SHARE_MEMORY_METASPACE_CHUNKMANAGER_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "memory/metaspace/chunkLevel.hpp"
  30 #include "memory/metaspace/counter.hpp"
  31 #include "memory/metaspace/metachunk.hpp"
  32 
  33 namespace metaspace {
  34 
  35 class VirtualSpaceList;
  36 class ChunkManagerStatistics;
  37 
  38 // class ChunkManager
  39 //
  40 // The ChunkManager has a central role. Callers request chunks from it.
  41 // It keeps the freelists for chunks. If the freelist is exhausted it
  42 // allocates new chunks from a connected VirtualSpaceList.
  43 //
  44 class ChunkManager : public CHeapObj<mtInternal> {
  45 
  46   // A chunk manager is connected to a virtual space list which is used
  47   // to allocate new root chunks when no free chunks are found.
  48   VirtualSpaceList* const _vslist;
  49 
  50   // Name
  51   const char* const _name;
  52 
  53   // Freelist
  54   MetachunkList _chunks [chklvl::NUM_CHUNK_LEVELS];
  55 
  56   // Total size, in words, of all chunks combined.
  57   SizeCounter _total_word_size;
  58 
  59   // Returns true if this manager contains the given chunk. Slow (walks free list) and
  60   // only needed for verifications.
  61   DEBUG_ONLY(bool contains_chunk(Metachunk* metachunk) const;)
  62 
  63   // Given a chunk we are about to handout to the caller, make sure it is committed
  64   // according to constants::committed_words_on_fresh_chunks.
  65   // May fail if we hit the commit limit.
  66   static bool commit_chunk_before_handout(Metachunk* c);
  67 
  68   // Return a single chunk to the freelist and adjust accounting. No merge is attempted.
  69   void return_chunk_simple(Metachunk* c);
  70 
  71   // Take a single chunk from the given freelist and adjust counters. Returns NULL
  72   // if there is no fitting chunk for this level.
  73   Metachunk* remove_first_chunk_at_level(chklvl_t l);
  74 
  75 
  76   // Given a chunk which must be outside of a freelist and must be free, split it to
  77   // meet a target level and return it. Splinters are added to the freelist.
  78   Metachunk* split_chunk_and_add_splinters(Metachunk* c, chklvl_t target_level);
  79 
  80 public:
  81 
  82   // Creates a chunk manager with a given name (which is for debug purposes only)
  83   // and an associated space list which will be used to request new chunks from
  84   // (see get_chunk())
  85   ChunkManager(const char* name, VirtualSpaceList* space_list);
  86 
  87   // Get a chunk and be smart about it.
  88   // - 1) Attempt to find a free chunk of exactly the pref_level level
  89   // - 2) Failing that, attempt to find a chunk smaller or equal the minimal level.
  90   // - 3) Failing that, attempt to find a free chunk of larger size and split it.
  91   // - 4) Failing that, attempt to allocate a new chunk from the connected virtual space.
  92   // - Failing that, give up and return NULL.
  93   // Note: this is not guaranteed to return a *committed* chunk. The chunk manager will
  94   //   attempt to commit the returned chunk according to constants::committed_words_on_fresh_chunks;
  95   //   but this may fail if we hit a commit limit. In that case, a partly uncommitted chunk
  96   //   will be returned, and the commit is attempted again when we allocate from the chunk's
  97   //   uncommitted area. See also Metachunk::allocate.
  98   Metachunk* get_chunk(chklvl_t min_level, chklvl_t pref_level);
  99 
 100   // Return a single chunk to the ChunkManager and adjust accounting. May merge chunk
 101   //  with neighbors.
 102   // Happens after a Classloader was unloaded and releases its metaspace chunks.
 103   // !! Note: this may invalidate the chunk. Do not access the chunk after
 104   //    this function returns !!
 105   void return_chunk(Metachunk* c);
 106 
 107   // Uncommit payload area of free chunks. Will be called during Metaspace GC.
 108   void uncommit_free_chunks();
 109 
 110   // Run verifications. slow=true: verify chunk-internal integrity too.
 111   DEBUG_ONLY(void verify(bool slow) const;)
 112 
 113   // Returns the name of this chunk manager.
 114   const char* name() const                  { return _name; }
 115 
 116   // Returns number of words in all free chunks.
 117   size_t total_word_size() const            { return _total_word_size.get(); }
 118 
 119   // Update statistics.
 120   void add_to_statistics(ChunkManagerStatistics* out) const;
 121 
 122 private:
 123 
 124   static ChunkManager* _chunkmanager_class;
 125   static ChunkManager* _chunkmanager_nonclass;
 126 
 127 public:
 128 
 129   static ChunkManager* chunkmanager_class() { return _chunkmanager_class; }
 130   static ChunkManager* chunkmanager_nonclass() { return _chunkmanager_nonclass; }
 131 
 132   static void set_chunkmanager_class(ChunkManager* cm);
 133   static void set_chunkmanager_nonclass(ChunkManager* cm);
 134 
 135 };
 136 
 137 } // namespace metaspace
 138 
 139 #endif // SHARE_MEMORY_METASPACE_CHUNKMANAGER_HPP