1 /*
   2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2020 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #ifndef SHARE_MEMORY_METASPACE_MSFREEBLOCKS_HPP
  27 #define SHARE_MEMORY_METASPACE_MSFREEBLOCKS_HPP
  28 
  29 #include "memory/allocation.hpp"
  30 
  31 #include "memory/metaspace/msBinList.hpp"
  32 #include "memory/metaspace/msBlockTree.hpp"
  33 #include "memory/metaspace/msCounter.hpp"
  34 
  35 #include "utilities/debug.hpp"
  36 #include "utilities/globalDefinitions.hpp"
  37 
  38 class outputStream;
  39 
  40 namespace metaspace {
  41 
  42 // Class FreeBlocks manages deallocated blocks in Metaspace.
  43 //
  44 // In Metaspace, allocated memory blocks may be release prematurely. This is
  45 //  uncommon (otherwise an arena-based allocation scheme would not make sense).
  46 //  It can happen e.g. when class loading fails or when bytecode gets rewritten.
  47 //
  48 // All these released blocks should be reused, so they are collected. Since these
  49 //  blocks are embedded into chunks which are still in use by a live arena,
  50 //  we cannot just give these blocks to anyone; only the owner of this arena can
  51 //  reuse these blocks. Therefore these blocks are kept at arena-level.
  52 //
  53 // The structure to manage these released blocks at arena level is class FreeBlocks.
  54 //
  55 // FreeBlocks is optimized toward the typical size and number of deallocated
  56 //  blocks. The vast majority of them (about 90%) are below 16 words in size,
  57 //  but there is a significant portion of memory blocks much larger than that,
  58 //  leftover space from retired chunks, see MetaspaceArena::retire_current_chunk().
  59 //
  60 // Since the vast majority of blocks are small or very small, FreeBlocks consists
  61 //  internally of two separate structures to keep very small blocks and other blocks.
  62 //  Very small blocks are kept in a bin list (see binlist.hpp) and larger blocks in
  63 //  a BST (see blocktree.hpp).
  64 
  65 class FreeBlocks : public CHeapObj<mtMetaspace> {
  66 
  67   // _small_blocks takes care of small to very small blocks.
  68   BinList32 _small_blocks;
  69 
  70   // A BST for larger blocks, only for blocks which are too large
  71   // to fit into _smallblocks.
  72   BlockTree _tree;
  73 
  74   // Cutoff point: blocks larger than this size are kept in the
  75   // tree, blocks smaller than or equal to this size in the bin list.
  76   const size_t MaxSmallBlocksWordSize = BinList32::MaxWordSize;
  77 
  78 public:
  79 
  80   // Smallest blocks we can keep in this structure.
  81   const static size_t MinWordSize = BinList32::MinWordSize;
  82 
  83   // Add a block to the deallocation management.
  84   void add_block(MetaWord* p, size_t word_size);
  85 
  86   // Retrieve a block of at least requested_word_size.
  87   MetaWord* remove_block(size_t requested_word_size);
  88 
  89 #ifdef ASSERT
  90   void verify() const {
  91     _tree.verify();
  92     _small_blocks.verify();
  93   };
  94 #endif
  95 
  96   // Returns number of blocks.
  97   int count() const {
  98     return _small_blocks.count() + _tree.count();
  99   }
 100 
 101   // Returns total size, in words, of all elements.
 102   size_t total_size() const {
 103     return _small_blocks.total_size() + _tree.total_size();
 104   }
 105 
 106   // Returns true if empty.
 107   bool is_empty() const {
 108     return _small_blocks.is_empty() && _tree.is_empty();
 109   }
 110 
 111 };
 112 
 113 } // namespace metaspace
 114 
 115 #endif // SHARE_MEMORY_METASPACE_MSFREEBLOCKS_HPP