< prev index next >

test/hotspot/gtest/metaspace/test_metaspacearena_stress.cpp

Print this page

  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 #include "precompiled.hpp"
 27 #include "memory/metaspace/chunkManager.hpp"
 28 #include "memory/metaspace/counters.hpp"

 29 #include "memory/metaspace/metaspaceArena.hpp"
 30 #include "memory/metaspace/metaspaceArenaGrowthPolicy.hpp"
 31 #include "memory/metaspace/metaspaceSettings.hpp"
 32 #include "memory/metaspace/metaspaceStatistics.hpp"
 33 #include "runtime/mutexLocker.hpp"
 34 #include "utilities/debug.hpp"
 35 #include "utilities/globalDefinitions.hpp"
 36 //#define LOG_PLEASE
 37 #include "metaspaceGtestCommon.hpp"
 38 #include "metaspaceGtestContexts.hpp"
 39 #include "metaspaceGtestSparseArray.hpp"
 40 
 41 using metaspace::ArenaGrowthPolicy;
 42 using metaspace::ChunkManager;
 43 using metaspace::IntCounter;
 44 using metaspace::MemRangeCounter;
 45 using metaspace::MetaspaceArena;
 46 using metaspace::SizeAtomicCounter;
 47 using metaspace::ArenaStats;
 48 using metaspace::InUseChunkStats;
 49 
 50 // Little randomness helper
 51 static bool fifty_fifty() {
 52   return IntRange(100).random_value() < 50;
 53 }
 54 
 55 // See metaspaceArena.cpp : needed for predicting commit sizes.
 56 namespace metaspace {
 57   extern size_t get_raw_word_size_for_requested_word_size(size_t net_word_size);
 58 }
 59 
 60 // A MetaspaceArenaTestBed contains a single MetaspaceArena and its lock.
 61 // It keeps track of allocations done from this MetaspaceArena.
 62 class MetaspaceArenaTestBed : public CHeapObj<mtInternal> {
 63 
 64   MetaspaceArena* _arena;

 65 

 66   Mutex* _lock;
 67 
 68   const SizeRange _allocation_range;
 69   size_t _size_of_last_failed_allocation;
 70 
 71   // We keep track of all allocations done thru the MetaspaceArena to
 72   // later check for overwriters.
 73   struct allocation_t {
 74     allocation_t* next;
 75     MetaWord* p; // NULL if deallocated
 76     size_t word_size;
 77     void mark() {
 78       mark_range(p, word_size);
 79     }
 80     void verify() const {
 81       if (p != NULL) {
 82         check_marked_range(p, word_size);
 83       }
 84     }
 85   };
 86 
 87   allocation_t* _allocations;
 88 
 89   // We count how much we did allocate and deallocate
 90   MemRangeCounter _alloc_count;

 91   MemRangeCounter _dealloc_count;
 92 
 93   // Check statistics returned by MetaspaceArena::add_to_statistics() against what
 94   // we know we allocated. This is a bit flaky since MetaspaceArena has internal
 95   // overhead.
 96   void verify_arena_statistics() const {
 97 
 98     ArenaStats stats;
 99     _arena->add_to_statistics(&stats);
100     InUseChunkStats in_use_stats = stats.totals();
101 
102     assert(_dealloc_count.total_size() <= _alloc_count.total_size() &&
103            _dealloc_count.count() <= _alloc_count.count(), "Sanity");
104 
105     // Check consistency of stats
106     ASSERT_GE(in_use_stats._word_size, in_use_stats._committed_words);
107     ASSERT_EQ(in_use_stats._committed_words,
108               in_use_stats._used_words + in_use_stats._free_words + in_use_stats._waste_words);
109     ASSERT_GE(in_use_stats._used_words, stats._free_blocks_word_size);
110 
111     // Note: reasons why the outside alloc counter and the inside used counter can differ:
112     // - alignment/padding of allocations
113     // - inside used counter contains blocks in free list
114     // - free block list splinter threshold
115     // - if +MetaspaceGuardAllocations, guard costs
116 
117     // Since what we deallocated may have been given back to us in a following allocation,
118     // we only know fore sure we allocated what we did not give back.
119     const size_t at_least_allocated = _alloc_count.total_size() - _dealloc_count.total_size();
120 
121     // At most we allocated this:
122     const size_t max_word_overhead_per_alloc =
123         4 + (metaspace::Settings::use_allocation_guard() ? 4 : 0);
124     const size_t at_most_allocated = _alloc_count.total_size() + max_word_overhead_per_alloc * _alloc_count.count();



125 
126     ASSERT_LE(at_least_allocated, in_use_stats._used_words - stats._free_blocks_word_size);
127     ASSERT_GE(at_most_allocated, in_use_stats._used_words - stats._free_blocks_word_size);
128 
129   }
130 
131 public:
132 
133   MetaspaceArena* arena() { return _arena; }
134 
135   MetaspaceArenaTestBed(ChunkManager* cm, const ArenaGrowthPolicy* alloc_sequence,
136                         SizeAtomicCounter* used_words_counter, SizeRange allocation_range) :


137     _arena(NULL),
138     _lock(NULL),
139     _allocation_range(allocation_range),
140     _size_of_last_failed_allocation(0),
141     _allocations(NULL),
142     _alloc_count(),
143     _dealloc_count()
144   {
145     _lock = new Mutex(Monitor::nosafepoint, "gtest-MetaspaceArenaTestBed_lock");
146     // Lock during space creation, since this is what happens in the VM too
147     //  (see ClassLoaderData::metaspace_non_null(), which we mimick here).
148     MutexLocker ml(_lock,  Mutex::_no_safepoint_check_flag);
149     _arena = new MetaspaceArena(cm, alloc_sequence, _lock, used_words_counter, "gtest-MetaspaceArenaTestBed-sm");
150   }
151 
152   ~MetaspaceArenaTestBed() {
153 
154     verify_arena_statistics();
155 
156     allocation_t* a = _allocations;
157     while (a != NULL) {
158       allocation_t* b = a->next;
159       a->verify();
160       FREE_C_HEAP_OBJ(a);
161       a = b;
162     }
163 
164     DEBUG_ONLY(_arena->verify();)
165 
166     // Delete MetaspaceArena. That should clean up all metaspace.
167     delete _arena;
168     delete _lock;
169 
170   }
171 
172   size_t words_allocated() const        { return _alloc_count.total_size(); }
173   int num_allocations() const           { return _alloc_count.count(); }
174 
175   size_t size_of_last_failed_allocation() const { return _size_of_last_failed_allocation; }
176 




177   // Allocate a random amount. Return false if the allocation failed.
178   bool checked_random_allocate() {
179     size_t word_size = 1 + _allocation_range.random_value();
180     MetaWord* p = _arena->allocate(word_size);
181     if (p != NULL) {
182       EXPECT_TRUE(is_aligned(p, sizeof(MetaWord)));
183       allocation_t* a = NEW_C_HEAP_OBJ(allocation_t, mtInternal);
184       a->word_size = word_size;
185       a->p = p;
186       a->mark();
187       a->next = _allocations;
188       _allocations = a;
189       _alloc_count.add(word_size);
190       if ((_alloc_count.count() % 20) == 0) {

191         verify_arena_statistics();
192         DEBUG_ONLY(_arena->verify();)
193       }
194       return true;
195     } else {
196       _size_of_last_failed_allocation = word_size;
197     }
198     return false;
199   }
200 
201   // Deallocate a random allocation
202   void checked_random_deallocate() {
203     allocation_t* a = _allocations;
204     while (a && a->p != NULL && os::random() % 10 != 0) {
205       a = a->next;
206     }
207     if (a != NULL && a->p != NULL) {
208       a->verify();
209       _arena->deallocate(a->p, a->word_size);
210       _dealloc_count.add(a->word_size);

212       if ((_dealloc_count.count() % 20) == 0) {
213         verify_arena_statistics();
214         DEBUG_ONLY(_arena->verify();)
215       }
216     }
217   }
218 
219 }; // End: MetaspaceArenaTestBed
220 
221 class MetaspaceArenaTest {
222 
223   MetaspaceGtestContext _context;
224 
225   SizeAtomicCounter _used_words_counter;
226 
227   SparseArray<MetaspaceArenaTestBed*> _testbeds;
228   IntCounter _num_beds;
229 
230   //////// Bed creation, destruction ///////
231 
232   void create_new_test_bed_at(int slotindex, const ArenaGrowthPolicy* growth_policy, SizeRange allocation_range) {
233     DEBUG_ONLY(_testbeds.check_slot_is_null(slotindex));
234     MetaspaceArenaTestBed* bed = new MetaspaceArenaTestBed(&_context.cm(), growth_policy,
235                                                        &_used_words_counter, allocation_range);
236     _testbeds.set_at(slotindex, bed);
237     _num_beds.increment();
238   }
239 
240   void create_random_test_bed_at(int slotindex) {
241     SizeRange allocation_range(1, 100); // randomize too?
242     const ArenaGrowthPolicy* growth_policy = ArenaGrowthPolicy::policy_for_space_type(
243         (fifty_fifty() ? Metaspace::StandardMetaspaceType : Metaspace::ReflectionMetaspaceType),
244          fifty_fifty());
245     create_new_test_bed_at(slotindex, growth_policy, allocation_range);



246    }
247 
248   // Randomly create a random test bed at a random slot, and return its slot index
249   // (returns false if we reached max number of test beds)
250   bool create_random_test_bed() {
251     const int slot = _testbeds.random_null_slot_index();
252     if (slot != -1) {
253       create_random_test_bed_at(slot);
254     }
255     return slot;
256   }
257 
258   // Create test beds for all slots
259   void create_all_test_beds() {
260     for (int slot = 0; slot < _testbeds.size(); slot++) {
261       if (_testbeds.slot_is_null(slot)) {
262         create_random_test_bed_at(slot);
263       }
264     }
265   }
266 
267   void delete_test_bed_at(int slotindex) {
268     DEBUG_ONLY(_testbeds.check_slot_is_not_null(slotindex));
269     MetaspaceArenaTestBed* bed = _testbeds.at(slotindex);
270     delete bed; // This will return all its memory to the chunk manager
271     _testbeds.set_at(slotindex, NULL);
272     _num_beds.decrement();
273   }
274 
275   // Randomly delete a random test bed at a random slot
276   // Return false if there are no test beds to delete.
277   bool delete_random_test_bed() {
278     const int slotindex = _testbeds.random_non_null_slot_index();
279     if (slotindex != -1) {
280       delete_test_bed_at(slotindex);
281       return true;
282     }
283     return false;
284   }
285 
286   // Delete all test beds.
287   void delete_all_test_beds() {
288     for (int slot = _testbeds.first_non_null_slot(); slot != -1; slot = _testbeds.next_non_null_slot(slot)) {
289       delete_test_bed_at(slot);
290     }
291   }
292 
293   //////// Allocating metaspace from test beds ///////
294 
295   bool random_allocate_from_testbed(int slotindex) {
296     DEBUG_ONLY(_testbeds.check_slot_is_not_null(slotindex);)
297     MetaspaceArenaTestBed* bed = _testbeds.at(slotindex);
298     bool success = bed->checked_random_allocate();
299     if (success == false) {
300       // We must have hit a limit.
301       EXPECT_LT(_context.commit_limiter().possible_expansion_words(),
302                 metaspace::get_raw_word_size_for_requested_word_size(bed->size_of_last_failed_allocation()));
303     }
304     return success;
305   }
306 
307   // Allocate multiple times random sizes from a single MetaspaceArena.
308   bool random_allocate_multiple_times_from_testbed(int slotindex, int num_allocations) {
309     bool success = true;
310     int n = 0;
311     while (success && n < num_allocations) {
312       success = random_allocate_from_testbed(slotindex);
313       n++;
314     }
315     return success;
316   }
317 
318   // Allocate multiple times random sizes from a single random MetaspaceArena.
319   bool random_allocate_random_times_from_random_testbed() {
320     int slot = _testbeds.random_non_null_slot_index();
321     bool success = false;
322     if (slot != -1) {

  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 #include "precompiled.hpp"
 27 #include "memory/metaspace/chunkManager.hpp"
 28 #include "memory/metaspace/counters.hpp"
 29 #include "memory/metaspace/metaspaceAlignment.hpp"
 30 #include "memory/metaspace/metaspaceArena.hpp"
 31 #include "memory/metaspace/metaspaceArenaGrowthPolicy.hpp"
 32 #include "memory/metaspace/metaspaceSettings.hpp"
 33 #include "memory/metaspace/metaspaceStatistics.hpp"
 34 #include "runtime/mutexLocker.hpp"
 35 #include "utilities/debug.hpp"
 36 #include "utilities/globalDefinitions.hpp"
 37 //#define LOG_PLEASE
 38 #include "metaspaceGtestCommon.hpp"
 39 #include "metaspaceGtestContexts.hpp"
 40 #include "metaspaceGtestSparseArray.hpp"
 41 
 42 using metaspace::ArenaGrowthPolicy;
 43 using metaspace::ChunkManager;
 44 using metaspace::IntCounter;
 45 using metaspace::MemRangeCounter;
 46 using metaspace::MetaspaceArena;
 47 using metaspace::SizeAtomicCounter;
 48 using metaspace::ArenaStats;
 49 using metaspace::InUseChunkStats;
 50 
 51 // Little randomness helper
 52 static bool fifty_fifty() {
 53   return IntRange(100).random_value() < 50;
 54 }
 55 





 56 // A MetaspaceArenaTestBed contains a single MetaspaceArena and its lock.
 57 // It keeps track of allocations done from this MetaspaceArena.
 58 class MetaspaceArenaTestBed : public CHeapObj<mtInternal> {
 59 
 60   const SizeRange _allocation_range;
 61   const int _alignment_words;
 62 
 63   MetaspaceArena* _arena;
 64   Mutex* _lock;


 65   size_t _size_of_last_failed_allocation;
 66 
 67   // We keep track of all allocations done thru the MetaspaceArena to
 68   // later check for overwriters.
 69   struct allocation_t {
 70     allocation_t* next;
 71     MetaWord* p; // NULL if deallocated
 72     size_t word_size;
 73     void mark() {
 74       mark_range(p, word_size);
 75     }
 76     void verify() const {
 77       if (p != NULL) {
 78         check_marked_range(p, word_size);
 79       }
 80     }
 81   };
 82 
 83   allocation_t* _allocations;
 84 
 85   // We count how much we did allocate and deallocate
 86   MemRangeCounter _alloc_count_net; // net used bytes
 87   MemRangeCounter _alloc_count_raw; // net used bytes + internal overhead
 88   MemRangeCounter _dealloc_count;
 89 
 90   // Check statistics returned by MetaspaceArena::add_to_statistics() against what
 91   // we know we allocated. This is a bit flaky since MetaspaceArena has internal
 92   // overhead.
 93   void verify_arena_statistics() const {
 94 
 95     ArenaStats stats;
 96     _arena->add_to_statistics(&stats);
 97     InUseChunkStats in_use_stats = stats.totals();
 98 
 99     assert(_dealloc_count.total_size() <= _alloc_count_net.total_size() &&
100            _dealloc_count.count() <= _alloc_count_net.count(), "Sanity");
101 
102     // Check consistency of stats
103     ASSERT_GE(in_use_stats._word_size, in_use_stats._committed_words);
104     ASSERT_EQ(in_use_stats._committed_words,
105               in_use_stats._used_words + in_use_stats._free_words + in_use_stats._waste_words);
106     ASSERT_GE(in_use_stats._used_words, stats._free_blocks_word_size);
107 
108     // Note: reasons why the outside alloc counter and the inside used counter can differ:
109     // - alignment/padding of allocations
110     // - inside used counter contains blocks in free list
111     // - free block list splinter threshold
112     // - if +MetaspaceGuardAllocations, guard costs
113 
114     // Since what we deallocated may have been given back to us in a following allocation,
115     // we only know fore sure we allocated what we did not give back.
116     const size_t at_least_allocated = _alloc_count_net.total_size() - _dealloc_count.total_size();
117 
118     // At most we allocated this:
119     size_t max_word_overhead_per_alloc = align_up(4, _alignment_words);
120     // Guard fences come as a separate, secondary block
121     if (metaspace::Settings::use_allocation_guard()) {
122       max_word_overhead_per_alloc *= 2;
123     }
124     const size_t at_most_allocated = _alloc_count_raw.total_size() + max_word_overhead_per_alloc * _alloc_count_raw.count();
125 
126     ASSERT_LE(at_least_allocated, in_use_stats._used_words - stats._free_blocks_word_size);
127     ASSERT_GE(at_most_allocated, in_use_stats._used_words - stats._free_blocks_word_size);

128   }
129 
130 public:
131 
132   MetaspaceArena* arena() { return _arena; }
133 
134   MetaspaceArenaTestBed(ChunkManager* cm, const ArenaGrowthPolicy* alloc_sequence, int alignment_words,
135                         SizeAtomicCounter* used_words_counter, SizeRange allocation_range) :
136     _allocation_range(allocation_range),
137     _alignment_words(alignment_words),
138     _arena(NULL),
139     _lock(NULL),

140     _size_of_last_failed_allocation(0),
141     _allocations(NULL),
142     _alloc_count_net(),
143     _dealloc_count()
144   {
145     _lock = new Mutex(Monitor::nosafepoint, "gtest-MetaspaceArenaTestBed_lock");
146     // Lock during space creation, since this is what happens in the VM too
147     //  (see ClassLoaderData::metaspace_non_null(), which we mimick here).
148     MutexLocker ml(_lock,  Mutex::_no_safepoint_check_flag);
149     _arena = new MetaspaceArena(cm, alloc_sequence, alignment_words, _lock, used_words_counter, "gtest-MetaspaceArenaTestBed-sm");
150   }
151 
152   ~MetaspaceArenaTestBed() {
153 
154     verify_arena_statistics();
155 
156     allocation_t* a = _allocations;
157     while (a != NULL) {
158       allocation_t* b = a->next;
159       a->verify();
160       FREE_C_HEAP_OBJ(a);
161       a = b;
162     }
163 
164     DEBUG_ONLY(_arena->verify();)
165 
166     // Delete MetaspaceArena. That should clean up all metaspace.
167     delete _arena;
168     delete _lock;
169 
170   }
171 
172   size_t words_allocated() const        { return _alloc_count_net.total_size(); }
173   int num_allocations() const           { return _alloc_count_net.count(); }
174 
175   size_t size_of_last_failed_allocation() const { return _size_of_last_failed_allocation; }
176 
177   size_t calc_expected_usage_for_allocated_words(size_t word_size) {
178     return metaspace::get_raw_word_size_for_requested_word_size(word_size, _alignment_words);
179   }
180 
181   // Allocate a random amount. Return false if the allocation failed.
182   bool checked_random_allocate() {
183     size_t word_size = 1 + _allocation_range.random_value();
184     MetaWord* p = _arena->allocate(word_size);
185     if (p != NULL) {
186       EXPECT_TRUE(is_aligned(p, _alignment_words * BytesPerWord));
187       allocation_t* a = NEW_C_HEAP_OBJ(allocation_t, mtInternal);
188       a->word_size = word_size;
189       a->p = p;
190       a->mark();
191       a->next = _allocations;
192       _allocations = a;
193       _alloc_count_net.add(word_size);
194       _alloc_count_raw.add(calc_expected_usage_for_allocated_words(word_size));
195       if ((_alloc_count_net.count() % 20) == 0) {
196         verify_arena_statistics();
197         DEBUG_ONLY(_arena->verify();)
198       }
199       return true;
200     } else {
201       _size_of_last_failed_allocation = word_size;
202     }
203     return false;
204   }
205 
206   // Deallocate a random allocation
207   void checked_random_deallocate() {
208     allocation_t* a = _allocations;
209     while (a && a->p != NULL && os::random() % 10 != 0) {
210       a = a->next;
211     }
212     if (a != NULL && a->p != NULL) {
213       a->verify();
214       _arena->deallocate(a->p, a->word_size);
215       _dealloc_count.add(a->word_size);

217       if ((_dealloc_count.count() % 20) == 0) {
218         verify_arena_statistics();
219         DEBUG_ONLY(_arena->verify();)
220       }
221     }
222   }
223 
224 }; // End: MetaspaceArenaTestBed
225 
226 class MetaspaceArenaTest {
227 
228   MetaspaceGtestContext _context;
229 
230   SizeAtomicCounter _used_words_counter;
231 
232   SparseArray<MetaspaceArenaTestBed*> _testbeds;
233   IntCounter _num_beds;
234 
235   //////// Bed creation, destruction ///////
236 
237   void create_new_test_bed_at(int slotindex, const ArenaGrowthPolicy* growth_policy, int alignment_words, SizeRange allocation_range) {
238     DEBUG_ONLY(_testbeds.check_slot_is_null(slotindex));
239     MetaspaceArenaTestBed* bed = new MetaspaceArenaTestBed(&_context.cm(), growth_policy, alignment_words,
240                                                        &_used_words_counter, allocation_range);
241     _testbeds.set_at(slotindex, bed);
242     _num_beds.increment();
243   }
244 
245   void create_random_test_bed_at(int slotindex) {
246     SizeRange allocation_range(1, 100); // randomize too?
247     const ArenaGrowthPolicy* growth_policy = ArenaGrowthPolicy::policy_for_space_type(
248         (fifty_fifty() ? Metaspace::StandardMetaspaceType : Metaspace::ReflectionMetaspaceType),
249          fifty_fifty());
250     const int alignment_bytes =
251         1 << IntRange(metaspace::LogMetaspaceMinimalAlignment,
252                       metaspace::LogMetaspaceMinimalAlignment + 7).random_value(); // zw 8 byte and 1K
253     create_new_test_bed_at(slotindex, growth_policy, alignment_bytes / BytesPerWord, allocation_range);
254    }
255 
256   // Randomly create a random test bed at a random slot, and return its slot index
257   // (returns false if we reached max number of test beds)
258   bool create_random_test_bed() {
259     const int slot = _testbeds.random_null_slot_index();
260     if (slot != -1) {
261       create_random_test_bed_at(slot);
262     }
263     return slot;
264   }
265 









266   void delete_test_bed_at(int slotindex) {
267     DEBUG_ONLY(_testbeds.check_slot_is_not_null(slotindex));
268     MetaspaceArenaTestBed* bed = _testbeds.at(slotindex);
269     delete bed; // This will return all its memory to the chunk manager
270     _testbeds.set_at(slotindex, NULL);
271     _num_beds.decrement();
272   }
273 
274   // Randomly delete a random test bed at a random slot
275   // Return false if there are no test beds to delete.
276   bool delete_random_test_bed() {
277     const int slotindex = _testbeds.random_non_null_slot_index();
278     if (slotindex != -1) {
279       delete_test_bed_at(slotindex);
280       return true;
281     }
282     return false;
283   }
284 
285   // Delete all test beds.
286   void delete_all_test_beds() {
287     for (int slot = _testbeds.first_non_null_slot(); slot != -1; slot = _testbeds.next_non_null_slot(slot)) {
288       delete_test_bed_at(slot);
289     }
290   }
291 
292   //////// Allocating metaspace from test beds ///////
293 
294   bool random_allocate_from_testbed(int slotindex) {
295     DEBUG_ONLY(_testbeds.check_slot_is_not_null(slotindex);)
296     MetaspaceArenaTestBed* bed = _testbeds.at(slotindex);
297     bool success = bed->checked_random_allocate();
298     if (success == false) {
299       // We must have hit a limit.
300       EXPECT_LT(_context.commit_limiter().possible_expansion_words(),
301                 bed->calc_expected_usage_for_allocated_words(bed->size_of_last_failed_allocation()));
302     }
303     return success;
304   }
305 
306   // Allocate multiple times random sizes from a single MetaspaceArena.
307   bool random_allocate_multiple_times_from_testbed(int slotindex, int num_allocations) {
308     bool success = true;
309     int n = 0;
310     while (success && n < num_allocations) {
311       success = random_allocate_from_testbed(slotindex);
312       n++;
313     }
314     return success;
315   }
316 
317   // Allocate multiple times random sizes from a single random MetaspaceArena.
318   bool random_allocate_random_times_from_random_testbed() {
319     int slot = _testbeds.random_non_null_slot_index();
320     bool success = false;
321     if (slot != -1) {
< prev index next >