Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/test/hotspot/gtest/nmt/test_nmtpreinit.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 "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"
32
33
// convenience log. switch on if debugging tests. Don't use tty, plain stdio only.
34
//#define LOG(...) { printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
35
#define LOG(...)
36
37
38
// This tests the ability of the NMT pre-init system to deal with various combinations
39
// of pre- and post-init-allocations.
40
41
// The tests consist of two phases:
42
// 1) before NMT initialization (pre-NMT-init) we allocate and reallocate a bunch of
43
// blocks via os::malloc() and os::realloc(), and free some of them via os::free()
44
// 2) after NMT initialization, we reallocate some more, then free all of them.
45
//
46
// The intent is to check that blocks allocated in pre-init phase and potentially realloced
47
// in pre-init phase are handled correctly if further realloc'ed or free'd post-init.
48
49
// We manage to run tests in different phases with this technique:
50
// - for the pre-init phase, we start the tests in the constructor of a global object; that constructor will
51
// run as part of the dyn. C++ initialization of the gtestlauncher binary. Since the gtestlauncher links
52
// *statically* against the libjvm, gtestlauncher and libjvm initialization fold into one and are the same.
53
// - for the post-init phase, we just start it inside a TEST_VM scope, which needs to create the VM for
54
// us. So inside that scope VM initialization ran and with it the NMT initialization.
55
// To be sure, we assert those assumptions.
56
57
#if INCLUDE_NMT
58
59
// Some shorts to save writing out the flags every time
60
static void* os_malloc(size_t s) { return os::malloc(s, mtTest); }
61
static void* os_realloc(void* old, size_t s) { return os::realloc(old, s, mtTest); }
62
63
static void log_state() {
64
// Don't use tty! the only safe thing to use at all times is stringStream.
65
char tmp[256];
66
stringStream ss(tmp, sizeof(tmp));
67
NMTPreInit::print_state(&ss);
68
LOG("%s", tmp);
69
}
70
71
class TestAllocations {
72
void* p1, *p2, *p3, *p4;
73
public:
74
TestAllocations() {
75
test_pre();
76
}
77
void test_pre() {
78
// Note that this part will run every time a gtestlauncher execs (so, for every TEST_OTHER_VM).
79
assert(NMTPreInit::in_preinit_phase(),
80
"This should be run in pre-init phase (as part of C++ dyn. initialization)");
81
LOG("corner cases, pre-init (%d)", os::current_process_id());
82
log_state();
83
84
p1 = os_malloc(100); // normal allocation
85
os::free(os_malloc(0)); // 0-sized allocation, should be free-able
86
p2 = os_realloc(os_malloc(10), 20); // realloc, growing
87
p3 = os_realloc(os_malloc(20), 10); // realloc, shrinking
88
p4 = os_realloc(NULL, 10); // realloc with NULL pointer
89
os_realloc(os_realloc(os_malloc(20), 0), 30); // realloc to size 0 and back up again
90
os::free(os_malloc(20)); // malloc, free
91
os::free(os_realloc(os_malloc(20), 30)); // malloc, realloc, free
92
os::free(NULL); // free(null)
93
DEBUG_ONLY(NMTPreInit::verify();)
94
95
log_state();
96
}
97
void test_post() {
98
assert(NMTPreInit::in_preinit_phase() == false,
99
"This should be run in post-init phase (from inside a TEST_VM test)");
100
LOG("corner cases, post-init (%d)", os::current_process_id());
101
log_state();
102
103
p1 = os_realloc(p1, 140); // realloc from pre-init-phase, growing
104
p2 = os_realloc(p2, 150); // realloc from pre-init-phase, growing
105
p3 = os_realloc(p3, 50); // realloc from pre-init-phase, growing
106
p4 = os_realloc(p4, 8); // realloc from pre-init-phase, shrinking
107
DEBUG_ONLY(NMTPreInit::verify();)
108
109
log_state();
110
}
111
void free_all() {
112
assert(NMTPreInit::in_preinit_phase() == false,
113
"This should be run in post-init phase (from inside a TEST_VM test)");
114
LOG("corner cases, free-all (%d)", os::current_process_id());
115
log_state();
116
117
os::free(p1); os::free(p2); os::free(p3); os::free(p4);
118
DEBUG_ONLY(NMTPreInit::verify();)
119
120
log_state();
121
}
122
};
123
124
static TestAllocations g_test_allocations;
125
126
TEST_VM(NMTPreInit, pre_to_post_allocs) {
127
g_test_allocations.test_post();
128
g_test_allocations.free_all();
129
}
130
131
#endif // INCLUDE_NMT
132
133