2
* Copyright (c) 2023 Red Hat Inc. All rights reserved.
3
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
4
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
5
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7
* This code is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License version 2 only, as
9
* published by the Free Software Foundation.
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
27
#include "precompiled.hpp"
28
#include "runtime/os.hpp"
29
#include "runtime/trimNativeHeap.hpp"
30
#include "utilities/globalDefinitions.hpp"
31
#include "utilities/ostream.hpp"
32
#include "testutils.hpp"
33
#include "unittest.hpp"
35
using ::testing::HasSubstr;
37
// Check the state of the trimmer via print_state; returns the suspend count
38
static int check_trim_state() {
40
stringStream ss(buf, sizeof(buf));
41
NativeHeapTrimmer::print_state(&ss);
42
if (NativeHeapTrimmer::enabled()) {
43
assert(TrimNativeHeapInterval > 0, "Sanity");
44
EXPECT_THAT(buf, HasSubstr("Periodic native trim enabled"));
46
const char* s = ::strstr(buf, "Trims performed");
49
uint64_t num_trims = 0;
50
int suspend_count = 0;
52
EXPECT_EQ(::sscanf(s, "Trims performed: " UINT64_FORMAT ", current suspend count: %d, stopped: %d",
53
&num_trims, &suspend_count, &stopped), 3);
55
// Number of trims we can reasonably expect should be limited
56
const double fudge_factor = 1.5;
57
const uint64_t elapsed_ms = (uint64_t)(os::elapsedTime() * fudge_factor * 1000.0);
58
const uint64_t max_num_trims = (elapsed_ms / TrimNativeHeapInterval) + 1;
59
EXPECT_LE(num_trims, max_num_trims);
61
// We should not be stopped
62
EXPECT_EQ(stopped, 0);
64
// Suspend count must not underflow
65
EXPECT_GE(suspend_count, 0);
69
EXPECT_THAT(buf, HasSubstr("Periodic native trim disabled"));
70
EXPECT_THAT(buf, Not(HasSubstr("Trims performed")));
75
TEST_VM(os, TrimNative) {
77
if (!NativeHeapTrimmer::enabled()) {
81
// Try recursive pausing. This tests that we are able to pause, that pauses stack,
82
// and that stacking works within the same thread.
83
int c1 = 0, c2 = 0, c3 = 0;
85
NativeHeapTrimmer::SuspendMark sm1("Test1");
86
c1 = check_trim_state();
88
NativeHeapTrimmer::SuspendMark sm2("Test2");
89
c2 = check_trim_state();
91
NativeHeapTrimmer::SuspendMark sm3("Test3");
92
c3 = check_trim_state();
96
// We also check the state: the suspend count should go up. But since we don't know
97
// whether concurrent code will have increased the suspend count too, this is fuzzy and
98
// we must avoid intermittent false positives.