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_LEFTOVERBINS_HPP
  27 #define SHARE_MEMORY_METASPACE_LEFTOVERBINS_HPP
  28 
  29 #include "memory/allocation.hpp"
  30 
  31 #include "memory/metaspace/counter.hpp"
  32 #include "memory/metaspace/binlist.hpp"
  33 #include "memory/metaspace/blocktree.hpp"
  34 
  35 #include "utilities/debug.hpp"
  36 #include "utilities/globalDefinitions.hpp"
  37 
  38 
  39 class outputStream;
  40 
  41 namespace metaspace {
  42 
  43 // Class FreeBlocks manages deallocated blocks in Metaspace.
  44 //
  45 // In Metaspace, allocated memory blocks may be release prematurely. This is
  46 //  uncommon (otherwise an arena-based allocation scheme would not make sense).
  47 //  It can happen e.g. when class loading fails or when bytecode gets rewritten.
  48 //
  49 // All these released blocks should be reused, so they are collected. Since these
  50 //  blocks are embedded into chunks which are still in use by a live arena,
  51 //  we cannot just give these blocks to anyone; only the owner of this arena can
  52 //  reuse these blocks. Therefore these blocks are kept at arena-level.
  53 //
  54 // The structure to manage these released blocks at arena level is class FreeBlocks.
  55 //
  56 // FreeBlocks is optimized toward the typical size and number of deallocated
  57 //  blocks. The vast majority of them (about 90%) are below 16 words in size,
  58 //  but there is a significant portion of memory blocks much larger than that,
  59 //  leftover space from retired chunks, see MetaspaceArena::retire_current_chunk().
  60 //
  61 // Since the vast majority of blocks are small or very small, FreeBlocks consists
  62 //  internally of two separate structures to keep very small blocks and other blocks.
  63 //  Very small blocks are kept in a bin list (see binlist.hpp) and larger blocks in
  64 //  a BST (see blocktree.hpp).
  65 
  66 class FreeBlocks : public CHeapObj<mtMetaspace> {
  67 
  68   typedef BinList32 SmallBlocksType;
  69 
  70   // _small_blocks takes care of small to very small blocks.
  71   SmallBlocksType _small_blocks;
  72 
  73   // A BST for larger blocks.
  74   BlockTree _tree;
  75 
  76   static const size_t splinter_threshold = 0;// 0x100;
  77 
  78 public:
  79 
  80   const static size_t minimal_word_size = SmallBlocksType::minimal_word_size;
  81 
  82   // Add a block to the deallocation management.
  83   void add_block(MetaWord* p, size_t word_size);
  84 
  85   // Retrieve a block of at least requested_word_size.
  86   MetaWord* get_block(size_t requested_word_size);
  87 
  88 #ifdef ASSERT
  89   void verify() const {
  90     _tree.verify();
  91     _small_blocks.verify();
  92   };
  93 #endif
  94 
  95   // Returns number of blocks.
  96   int count() const {
  97     return _small_blocks.count() + _tree.count();
  98   }
  99 
 100   // Returns total size, in words, of all elements.
 101   size_t total_size() const {
 102     return _small_blocks.total_size() + _tree.total_size();
 103   }
 104 
 105   // Returns true if empty.
 106   bool is_empty() const {
 107     return _small_blocks.is_empty() && _tree.is_empty();
 108   }
 109 
 110 };
 111 
 112 
 113 
 114 
 115 } // namespace metaspace
 116 
 117 #endif // SHARE_MEMORY_METASPACE_CHUNKMANAGER_HPP