1 /*
  2  * Copyright (c) 2020, 2022, 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_TESTHELPERS_HPP
 27 #define SHARE_MEMORY_METASPACE_TESTHELPERS_HPP
 28 
 29 #include "memory/allocation.hpp"
 30 #include "memory/metaspace.hpp"
 31 #include "memory/metaspace/commitLimiter.hpp"
 32 #include "memory/metaspace/counters.hpp"
 33 #include "memory/metaspace/metaspaceContext.hpp"
 34 #include "memory/virtualspace.hpp"
 35 #include "utilities/globalDefinitions.hpp"
 36 
 37 // This is just convenience classes for metaspace-related tests
 38 //  (jtreg, via whitebox API, and gtests)
 39 
 40 class ReservedSpace;
 41 class Mutex;
 42 class outputStream;
 43 
 44 namespace metaspace {
 45 
 46 class MetaspaceContext;
 47 class MetaspaceArena;
 48 
 49 // Wraps a MetaspaceTestArena with its own lock for testing purposes.
 50 class MetaspaceTestArena : public CHeapObj<mtInternal> {
 51 
 52   Mutex* const _lock;
 53   MetaspaceArena* const _arena;
 54 
 55 public:
 56 
 57   const MetaspaceArena* arena() const {
 58     return _arena;
 59   }
 60 
 61   MetaspaceTestArena(Mutex* lock, MetaspaceArena* arena);
 62   ~MetaspaceTestArena();
 63 
 64   MetaWord* allocate(size_t word_size);
 65   void deallocate(MetaWord* p, size_t word_size);
 66 
 67 };
 68 
 69 // Wraps an instance of a MetaspaceContext together with some side objects for easy use in test beds (whitebox, gtests)
 70 class MetaspaceTestContext : public CHeapObj<mtInternal> {
 71 
 72   const char* const _name;
 73   const size_t _reserve_limit;
 74   const size_t _commit_limit;
 75 
 76   MetaspaceContext* _context;
 77   CommitLimiter _commit_limiter;
 78   SizeAtomicCounter _used_words_counter;
 79 
 80   // For non-expandable contexts we keep track of the space
 81   // and delete it at destruction time.
 82   ReservedSpace _rs;
 83 
 84 public:
 85 
 86   // Note: limit == 0 means unlimited
 87   // Reserve limit > 0 simulates a non-expandable VirtualSpaceList (like CompressedClassSpace)
 88   // Commit limit > 0 simulates a limit to max committable space (like MaxMetaspaceSize)
 89   MetaspaceTestContext(const char* name, size_t commit_limit = 0, size_t reserve_limit = 0);
 90   ~MetaspaceTestContext();
 91 
 92   // Create an arena, feeding off this area.
 93   MetaspaceTestArena* create_arena(Metaspace::MetaspaceType type);
 94 
 95   void purge_area();
 96 
 97   // Accessors
 98   const CommitLimiter& commit_limiter() const { return _commit_limiter; }
 99   const VirtualSpaceList& vslist() const      { return *(_context->vslist()); }
100   ChunkManager& cm()                          { return *(_context->cm()); }
101 
102   // Returns reserve- and commit limit we run the test with (in the real world,
103   // these would be equivalent to CompressedClassSpaceSize resp MaxMetaspaceSize)
104   size_t reserve_limit() const    { return _reserve_limit == 0 ? max_uintx : 0; }
105   size_t commit_limit() const     { return _commit_limit == 0 ? max_uintx : 0; }
106 
107   // Convenience function to retrieve total committed/used words
108   size_t used_words() const       { return _used_words_counter.get(); }
109   size_t committed_words() const  { return _commit_limiter.committed_words(); }
110 
111   DEBUG_ONLY(void verify() const;)
112 
113   void print_on(outputStream* st) const;
114 
115 };
116 
117 } // namespace metaspace
118 
119 #endif // SHARE_MEMORY_METASPACE_TESTHELPERS_HPP