Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp
64438 views
1
/*
2
* Copyright (c) 2021 SAP SE. All rights reserved.
3
* Copyright (c) 2021, Oracle and/or its affiliates. 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
#include "precompiled.hpp"
26
#include "jvm_io.h"
27
#include "memory/allocation.hpp"
28
#include "runtime/os.hpp"
29
#include "services/nmtPreInit.hpp"
30
#include "utilities/debug.hpp"
31
#include "utilities/ostream.hpp"
32
#include "unittest.hpp"
33
34
#if INCLUDE_NMT
35
36
// This tests the NMTPreInitAllocationTable hash table used to store C-heap allocations before NMT initialization ran.
37
38
static size_t small_random_nonzero_size() {
39
// We keep the sizes random but not too random; the more regular the sizes, the
40
// more regular the malloc return pointers and the better we see how our hash
41
// function copes in the NMT preinit lu table.
42
switch (os::random() % 4) {
43
case 0: return 0x10;
44
case 1: return 0x42;
45
case 2: return 0x20;
46
case 3: return 0x80;
47
}
48
return 1;
49
}
50
51
//#define VERBOSE
52
53
static void print_and_check_table(NMTPreInitAllocationTable& table, int expected_num_entries) {
54
char tmp[256];
55
stringStream ss(tmp, sizeof(tmp));
56
char expected[256];
57
jio_snprintf(expected, sizeof(expected), "entries: %d", expected_num_entries);
58
table.print_state(&ss);
59
EXPECT_EQ(::strncmp(tmp, expected, strlen(expected)), 0);
60
#ifdef VERBOSE
61
tty->print_raw(tmp);
62
tty->cr();
63
#endif
64
DEBUG_ONLY(table.verify();)
65
}
66
67
TEST_VM(NMTPreInit, stress_test_map) {
68
NMTPreInitAllocationTable table;
69
const int num_allocs = 32 * K; // about factor 100 more than normally expected
70
NMTPreInitAllocation** allocations = NEW_C_HEAP_ARRAY(NMTPreInitAllocation*, num_allocs, mtTest);
71
72
// Fill table with allocations
73
for (int i = 0; i < num_allocs; i++) {
74
NMTPreInitAllocation* a = NMTPreInitAllocation::do_alloc(small_random_nonzero_size());
75
table.add(a);
76
allocations[i] = a;
77
}
78
79
print_and_check_table(table, num_allocs);
80
81
// look them all up
82
for (int i = 0; i < num_allocs; i++) {
83
const NMTPreInitAllocation* a = table.find(allocations[i]->payload());
84
ASSERT_EQ(a, allocations[i]);
85
}
86
87
// Randomly realloc
88
for (int j = 0; j < num_allocs/2; j++) {
89
int pos = os::random() % num_allocs;
90
NMTPreInitAllocation* a1 = allocations[pos];
91
NMTPreInitAllocation* a2 = table.find_and_remove(a1->payload());
92
ASSERT_EQ(a1, a2);
93
NMTPreInitAllocation* a3 = NMTPreInitAllocation::do_reallocate(a2, small_random_nonzero_size());
94
table.add(a3);
95
allocations[pos] = a3;
96
}
97
98
print_and_check_table(table, num_allocs);
99
100
// look them all up
101
for (int i = 0; i < num_allocs; i++) {
102
const NMTPreInitAllocation* a = table.find(allocations[i]->payload());
103
ASSERT_EQ(a, allocations[i]);
104
}
105
106
// free all
107
for (int i = 0; i < num_allocs; i++) {
108
NMTPreInitAllocation* a = table.find_and_remove(allocations[i]->payload());
109
ASSERT_EQ(a, allocations[i]);
110
NMTPreInitAllocation::do_free(a);
111
allocations[i] = NULL;
112
}
113
114
print_and_check_table(table, 0);
115
116
FREE_C_HEAP_ARRAY(NMTPreInitAllocation*, allocations);
117
}
118
119
#ifdef ASSERT
120
// Test that we will assert if the lookup table is seriously over-booked.
121
TEST_VM_ASSERT_MSG(NMTPreInit, assert_on_lu_table_overflow, ".*NMT preinit lookup table degenerated.*") {
122
NMTPreInitAllocationTable table;
123
const int num_allocs = 400 * 1000; // anything above ~250K entries should trigger the assert (note: normal number of entries is ~500)
124
for (int i = 0; i < num_allocs; i++) {
125
NMTPreInitAllocation* a = NMTPreInitAllocation::do_alloc(1);
126
table.add(a);
127
}
128
#ifdef VERBOSE
129
table.print_state(tty);
130
tty->cr();
131
#endif
132
table.verify();
133
}
134
#endif // ASSERT
135
136
#endif // INCLUDE_NMT
137
138