Path: blob/master/test/hotspot/gtest/nmt/test_nmtpreinit.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 "memory/allocation.hpp"26#include "runtime/os.hpp"27#include "services/nmtPreInit.hpp"28#include "utilities/debug.hpp"29#include "utilities/ostream.hpp"30#include "unittest.hpp"3132// convenience log. switch on if debugging tests. Don't use tty, plain stdio only.33//#define LOG(...) { printf(__VA_ARGS__); printf("\n"); fflush(stdout); }34#define LOG(...)353637// This tests the ability of the NMT pre-init system to deal with various combinations38// of pre- and post-init-allocations.3940// The tests consist of two phases:41// 1) before NMT initialization (pre-NMT-init) we allocate and reallocate a bunch of42// blocks via os::malloc() and os::realloc(), and free some of them via os::free()43// 2) after NMT initialization, we reallocate some more, then free all of them.44//45// The intent is to check that blocks allocated in pre-init phase and potentially realloced46// in pre-init phase are handled correctly if further realloc'ed or free'd post-init.4748// We manage to run tests in different phases with this technique:49// - for the pre-init phase, we start the tests in the constructor of a global object; that constructor will50// run as part of the dyn. C++ initialization of the gtestlauncher binary. Since the gtestlauncher links51// *statically* against the libjvm, gtestlauncher and libjvm initialization fold into one and are the same.52// - for the post-init phase, we just start it inside a TEST_VM scope, which needs to create the VM for53// us. So inside that scope VM initialization ran and with it the NMT initialization.54// To be sure, we assert those assumptions.5556#if INCLUDE_NMT5758// Some shorts to save writing out the flags every time59static void* os_malloc(size_t s) { return os::malloc(s, mtTest); }60static void* os_realloc(void* old, size_t s) { return os::realloc(old, s, mtTest); }6162static void log_state() {63// Don't use tty! the only safe thing to use at all times is stringStream.64char tmp[256];65stringStream ss(tmp, sizeof(tmp));66NMTPreInit::print_state(&ss);67LOG("%s", tmp);68}6970class TestAllocations {71void* p1, *p2, *p3, *p4;72public:73TestAllocations() {74test_pre();75}76void test_pre() {77// Note that this part will run every time a gtestlauncher execs (so, for every TEST_OTHER_VM).78assert(NMTPreInit::in_preinit_phase(),79"This should be run in pre-init phase (as part of C++ dyn. initialization)");80LOG("corner cases, pre-init (%d)", os::current_process_id());81log_state();8283p1 = os_malloc(100); // normal allocation84os::free(os_malloc(0)); // 0-sized allocation, should be free-able85p2 = os_realloc(os_malloc(10), 20); // realloc, growing86p3 = os_realloc(os_malloc(20), 10); // realloc, shrinking87p4 = os_realloc(NULL, 10); // realloc with NULL pointer88os_realloc(os_realloc(os_malloc(20), 0), 30); // realloc to size 0 and back up again89os::free(os_malloc(20)); // malloc, free90os::free(os_realloc(os_malloc(20), 30)); // malloc, realloc, free91os::free(NULL); // free(null)92DEBUG_ONLY(NMTPreInit::verify();)9394log_state();95}96void test_post() {97assert(NMTPreInit::in_preinit_phase() == false,98"This should be run in post-init phase (from inside a TEST_VM test)");99LOG("corner cases, post-init (%d)", os::current_process_id());100log_state();101102p1 = os_realloc(p1, 140); // realloc from pre-init-phase, growing103p2 = os_realloc(p2, 150); // realloc from pre-init-phase, growing104p3 = os_realloc(p3, 50); // realloc from pre-init-phase, growing105p4 = os_realloc(p4, 8); // realloc from pre-init-phase, shrinking106DEBUG_ONLY(NMTPreInit::verify();)107108log_state();109}110void free_all() {111assert(NMTPreInit::in_preinit_phase() == false,112"This should be run in post-init phase (from inside a TEST_VM test)");113LOG("corner cases, free-all (%d)", os::current_process_id());114log_state();115116os::free(p1); os::free(p2); os::free(p3); os::free(p4);117DEBUG_ONLY(NMTPreInit::verify();)118119log_state();120}121};122123static TestAllocations g_test_allocations;124125TEST_VM(NMTPreInit, pre_to_post_allocs) {126g_test_allocations.test_post();127g_test_allocations.free_all();128}129130#endif // INCLUDE_NMT131132133