Path: blob/master/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp
64438 views
/*1* Copyright (c) 2021 SAP SE. All rights reserved.2* Copyright (c) 2021, 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324#include "precompiled.hpp"25#include "jvm_io.h"26#include "memory/allocation.hpp"27#include "runtime/os.hpp"28#include "services/nmtPreInit.hpp"29#include "utilities/debug.hpp"30#include "utilities/ostream.hpp"31#include "unittest.hpp"3233#if INCLUDE_NMT3435// This tests the NMTPreInitAllocationTable hash table used to store C-heap allocations before NMT initialization ran.3637static size_t small_random_nonzero_size() {38// We keep the sizes random but not too random; the more regular the sizes, the39// more regular the malloc return pointers and the better we see how our hash40// function copes in the NMT preinit lu table.41switch (os::random() % 4) {42case 0: return 0x10;43case 1: return 0x42;44case 2: return 0x20;45case 3: return 0x80;46}47return 1;48}4950//#define VERBOSE5152static void print_and_check_table(NMTPreInitAllocationTable& table, int expected_num_entries) {53char tmp[256];54stringStream ss(tmp, sizeof(tmp));55char expected[256];56jio_snprintf(expected, sizeof(expected), "entries: %d", expected_num_entries);57table.print_state(&ss);58EXPECT_EQ(::strncmp(tmp, expected, strlen(expected)), 0);59#ifdef VERBOSE60tty->print_raw(tmp);61tty->cr();62#endif63DEBUG_ONLY(table.verify();)64}6566TEST_VM(NMTPreInit, stress_test_map) {67NMTPreInitAllocationTable table;68const int num_allocs = 32 * K; // about factor 100 more than normally expected69NMTPreInitAllocation** allocations = NEW_C_HEAP_ARRAY(NMTPreInitAllocation*, num_allocs, mtTest);7071// Fill table with allocations72for (int i = 0; i < num_allocs; i++) {73NMTPreInitAllocation* a = NMTPreInitAllocation::do_alloc(small_random_nonzero_size());74table.add(a);75allocations[i] = a;76}7778print_and_check_table(table, num_allocs);7980// look them all up81for (int i = 0; i < num_allocs; i++) {82const NMTPreInitAllocation* a = table.find(allocations[i]->payload());83ASSERT_EQ(a, allocations[i]);84}8586// Randomly realloc87for (int j = 0; j < num_allocs/2; j++) {88int pos = os::random() % num_allocs;89NMTPreInitAllocation* a1 = allocations[pos];90NMTPreInitAllocation* a2 = table.find_and_remove(a1->payload());91ASSERT_EQ(a1, a2);92NMTPreInitAllocation* a3 = NMTPreInitAllocation::do_reallocate(a2, small_random_nonzero_size());93table.add(a3);94allocations[pos] = a3;95}9697print_and_check_table(table, num_allocs);9899// look them all up100for (int i = 0; i < num_allocs; i++) {101const NMTPreInitAllocation* a = table.find(allocations[i]->payload());102ASSERT_EQ(a, allocations[i]);103}104105// free all106for (int i = 0; i < num_allocs; i++) {107NMTPreInitAllocation* a = table.find_and_remove(allocations[i]->payload());108ASSERT_EQ(a, allocations[i]);109NMTPreInitAllocation::do_free(a);110allocations[i] = NULL;111}112113print_and_check_table(table, 0);114115FREE_C_HEAP_ARRAY(NMTPreInitAllocation*, allocations);116}117118#ifdef ASSERT119// Test that we will assert if the lookup table is seriously over-booked.120TEST_VM_ASSERT_MSG(NMTPreInit, assert_on_lu_table_overflow, ".*NMT preinit lookup table degenerated.*") {121NMTPreInitAllocationTable table;122const int num_allocs = 400 * 1000; // anything above ~250K entries should trigger the assert (note: normal number of entries is ~500)123for (int i = 0; i < num_allocs; i++) {124NMTPreInitAllocation* a = NMTPreInitAllocation::do_alloc(1);125table.add(a);126}127#ifdef VERBOSE128table.print_state(tty);129tty->cr();130#endif131table.verify();132}133#endif // ASSERT134135#endif // INCLUDE_NMT136137138