9e4fc568a6
Reviewed-by: shade, rehn, dholmes
102 lines
3.5 KiB
C++
102 lines
3.5 KiB
C++
/*
|
|
* Copyright (c) 2023 Red Hat Inc. All rights reserved.
|
|
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
|
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*
|
|
*/
|
|
|
|
#include "precompiled.hpp"
|
|
#include "runtime/os.hpp"
|
|
#include "runtime/trimNativeHeap.hpp"
|
|
#include "utilities/globalDefinitions.hpp"
|
|
#include "utilities/ostream.hpp"
|
|
#include "testutils.hpp"
|
|
#include "unittest.hpp"
|
|
|
|
using ::testing::HasSubstr;
|
|
|
|
// Check the state of the trimmer via print_state; returns the suspend count
|
|
static int check_trim_state() {
|
|
char buf [1024];
|
|
stringStream ss(buf, sizeof(buf));
|
|
NativeHeapTrimmer::print_state(&ss);
|
|
if (NativeHeapTrimmer::enabled()) {
|
|
assert(TrimNativeHeapInterval > 0, "Sanity");
|
|
EXPECT_THAT(buf, HasSubstr("Periodic native trim enabled"));
|
|
|
|
const char* s = ::strstr(buf, "Trims performed");
|
|
EXPECT_NOT_NULL(s);
|
|
|
|
uint64_t num_trims = 0;
|
|
int suspend_count = 0;
|
|
int stopped = 0;
|
|
EXPECT_EQ(::sscanf(s, "Trims performed: " UINT64_FORMAT ", current suspend count: %d, stopped: %d",
|
|
&num_trims, &suspend_count, &stopped), 3);
|
|
|
|
// Number of trims we can reasonably expect should be limited
|
|
const double fudge_factor = 1.5;
|
|
const uint64_t elapsed_ms = (uint64_t)(os::elapsedTime() * fudge_factor * 1000.0);
|
|
const uint64_t max_num_trims = (elapsed_ms / TrimNativeHeapInterval) + 1;
|
|
EXPECT_LE(num_trims, max_num_trims);
|
|
|
|
// We should not be stopped
|
|
EXPECT_EQ(stopped, 0);
|
|
|
|
// Suspend count must not underflow
|
|
EXPECT_GE(suspend_count, 0);
|
|
return suspend_count;
|
|
|
|
} else {
|
|
EXPECT_THAT(buf, HasSubstr("Periodic native trim disabled"));
|
|
EXPECT_THAT(buf, Not(HasSubstr("Trims performed")));
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
TEST_VM(os, TrimNative) {
|
|
|
|
if (!NativeHeapTrimmer::enabled()) {
|
|
return;
|
|
}
|
|
|
|
// Try recursive pausing. This tests that we are able to pause, that pauses stack,
|
|
// and that stacking works within the same thread.
|
|
int c1 = 0, c2 = 0, c3 = 0;
|
|
{
|
|
NativeHeapTrimmer::SuspendMark sm1("Test1");
|
|
c1 = check_trim_state();
|
|
{
|
|
NativeHeapTrimmer::SuspendMark sm2("Test2");
|
|
c2 = check_trim_state();
|
|
{
|
|
NativeHeapTrimmer::SuspendMark sm3("Test3");
|
|
c3 = check_trim_state();
|
|
}
|
|
}
|
|
}
|
|
// We also check the state: the suspend count should go up. But since we don't know
|
|
// whether concurrent code will have increased the suspend count too, this is fuzzy and
|
|
// we must avoid intermittent false positives.
|
|
EXPECT_GT(c2, c1);
|
|
EXPECT_GT(c3, c2);
|
|
}
|