products/sources/formale sprachen/Java/openjdk-20-36_src/test/hotspot/gtest/nmt image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: test_nmtpreinit.cpp   Sprache: C

/*
 * Copyright (c) 2021, 2022 SAP SE. All rights reserved.
 * Copyright (c) 2021, 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 "memory/allocation.hpp"
#include "runtime/os.hpp"
#include "services/memTracker.hpp"
#include "services/nmtPreInit.hpp"
#include "utilities/debug.hpp"
#include "utilities/ostream.hpp"
#include "unittest.hpp"

// convenience log. switch on if debugging tests. Don't use tty, plain stdio only.
//#define LOG(...) { printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
#define LOG(...)


// This tests the ability of the NMT pre-init system to deal with various combinations
// of pre- and post-init-allocations.

// The tests consist of two phases:
// 1) before NMT initialization (pre-NMT-init) we allocate and reallocate a bunch of
//    blocks via os::malloc() and os::realloc(), and free some of them via os::free()
// 2) after NMT initialization, we reallocate some more, then free all of them.
//
// The intent is to check that blocks allocated in pre-init phase and potentially realloced
// in pre-init phase are handled correctly if further realloc'ed or free'd post-init.

// We manage to run tests in different phases with this technique:
// - for the pre-init phase, we start the tests in the constructor of a global object; that constructor will
//   run as part of the dyn. C++ initialization of the gtestlauncher binary. Since the gtestlauncher links
//   *statically* against the libjvm, gtestlauncher and libjvm initialization fold into one and are the same.
// - for the post-init phase, we just start it inside a TEST_VM scope, which needs to create the VM for
//   us. So inside that scope VM initialization ran and with it the NMT initialization.
// To be sure, we assert those assumptions.

// Some shorts to save writing out the flags every time
static void* os_malloc(size_t s)              { return os::malloc(s, mtTest); }
static void* os_realloc(void* old, size_t s)  { return os::realloc(old, s, mtTest); }

static void log_state() {
  // Don't use tty! the only safe thing to use at all times is stringStream.
  char tmp[256];
  stringStream ss(tmp, sizeof(tmp));
  NMTPreInit::print_state(&ss);
  LOG("%s", tmp);
}

class TestAllocations {
  void* p1, *p2, *p3, *p4;
public:
  TestAllocations() {
    test_pre();
  }
  void test_pre() {
    // Note that this part will run every time a gtestlauncher execs (so, for every TEST_OTHER_VM).
    assert(!MemTracker::is_initialized(),
           "This should be run in pre-init phase (as part of C++ dyn. initialization)");
    LOG("corner cases, pre-init (%d)", os::current_process_id());
    log_state();

    p1 = os_malloc(100);                 // normal allocation
    os::free(os_malloc(0));              // 0-sized allocation, should be free-able
    p2 = os_realloc(os_malloc(10), 20);  // realloc, growing
    p3 = os_realloc(os_malloc(20), 10);  // realloc, shrinking
    p4 = os_realloc(NULL, 10);           // realloc with NULL pointer
    os_realloc(os_realloc(os_malloc(20), 0), 30);  // realloc to size 0 and back up again
    os::free(os_malloc(20));             // malloc, free
    os::free(os_realloc(os_malloc(20), 30));  // malloc, realloc, free
    os::free(NULL);                      // free(null)
    DEBUG_ONLY(NMTPreInit::verify();)

    // This should result in a fatal native oom error from NMT preinit with a clear error message.
    // It should not result in a SEGV or anything similar. Unfortunately difficult to test
    // automatically.
    // Uncomment to test manually.

    // case 1: overflow
    // os_malloc(SIZE_MAX);

    // case 2: failing malloc
    // os_malloc(SIZE_MAX - M);

    // case 3: overflow in realloc
    // void* p = os_malloc(10);
    // p = os_realloc(p, SIZE_MAX);

    // case 4: failing realloc
    // void* p = os_malloc(10);
    // p = os_realloc(p, SIZE_MAX - M);

    log_state();
  }
  void test_post() {
    assert(MemTracker::is_initialized(),
           "This should be run in post-init phase (from inside a TEST_VM test)");
    LOG("corner cases, post-init (%d)", os::current_process_id());
    log_state();

    p1 = os_realloc(p1, 140);  // realloc from pre-init-phase, growing
    p2 = os_realloc(p2, 150);  // realloc from pre-init-phase, growing
    p3 = os_realloc(p3, 50);   // realloc from pre-init-phase, growing
    p4 = os_realloc(p4, 8);    // realloc from pre-init-phase, shrinking
    DEBUG_ONLY(NMTPreInit::verify();)

    log_state();
  }
  void free_all() {
    assert(MemTracker::is_initialized(),
           "This should be run in post-init phase (from inside a TEST_VM test)");
    LOG("corner cases, free-all (%d)", os::current_process_id());
    log_state();

    os::free(p1); os::free(p2); os::free(p3); os::free(p4);
    DEBUG_ONLY(NMTPreInit::verify();)

    log_state();
  }
};

static TestAllocations g_test_allocations;

TEST_VM(NMTPreInit, pre_to_post_allocs) {
  g_test_allocations.test_post();
  g_test_allocations.free_all();
}

¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.


Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff