8171157: Convert ObjectMonitor_test to GTest

Migration of the ObjectMonitor test to GTest. Two GTests were actually created, one for ObjectMonitor and one for ObjectSynchronizer.

Reviewed-by: dcubed, hseigel
This commit is contained in:
Patricio Chilano Mateo 2018-07-27 16:29:36 -04:00 committed by Daniel D. Daugherty
parent c1bbdfaa2c
commit 2d1029c256
7 changed files with 140 additions and 124 deletions

View File

@ -2354,10 +2354,6 @@ void ObjectMonitor::DeferredInitialize() {
SETKNOB(FastHSSEC);
#undef SETKNOB
if (Knob_Verbose) {
sanity_checks();
}
if (os::is_MP()) {
BackOffMask = (1 << Knob_SpinBackOff) - 1;
if (Knob_ReportSettings) {
@ -2376,70 +2372,3 @@ void ObjectMonitor::DeferredInitialize() {
InitDone = 1;
}
void ObjectMonitor::sanity_checks() {
int error_cnt = 0;
int warning_cnt = 0;
bool verbose = Knob_Verbose != 0 NOT_PRODUCT(|| VerboseInternalVMTests);
if (verbose) {
tty->print_cr("INFO: sizeof(ObjectMonitor)=" SIZE_FORMAT,
sizeof(ObjectMonitor));
tty->print_cr("INFO: sizeof(PaddedEnd<ObjectMonitor>)=" SIZE_FORMAT,
sizeof(PaddedEnd<ObjectMonitor>));
}
uint cache_line_size = VM_Version::L1_data_cache_line_size();
if (verbose) {
tty->print_cr("INFO: L1_data_cache_line_size=%u", cache_line_size);
}
ObjectMonitor dummy;
u_char *addr_begin = (u_char*)&dummy;
u_char *addr_header = (u_char*)&dummy._header;
u_char *addr_owner = (u_char*)&dummy._owner;
uint offset_header = (uint)(addr_header - addr_begin);
if (verbose) tty->print_cr("INFO: offset(_header)=%u", offset_header);
uint offset_owner = (uint)(addr_owner - addr_begin);
if (verbose) tty->print_cr("INFO: offset(_owner)=%u", offset_owner);
if ((uint)(addr_header - addr_begin) != 0) {
tty->print_cr("ERROR: offset(_header) must be zero (0).");
error_cnt++;
}
if (cache_line_size != 0) {
// We were able to determine the L1 data cache line size so
// do some cache line specific sanity checks
if ((offset_owner - offset_header) < cache_line_size) {
tty->print_cr("WARNING: the _header and _owner fields are closer "
"than a cache line which permits false sharing.");
warning_cnt++;
}
if ((sizeof(PaddedEnd<ObjectMonitor>) % cache_line_size) != 0) {
tty->print_cr("WARNING: PaddedEnd<ObjectMonitor> size is not a "
"multiple of a cache line which permits false sharing.");
warning_cnt++;
}
}
ObjectSynchronizer::sanity_checks(verbose, cache_line_size, &error_cnt,
&warning_cnt);
if (verbose || error_cnt != 0 || warning_cnt != 0) {
tty->print_cr("INFO: error_cnt=%d", error_cnt);
tty->print_cr("INFO: warning_cnt=%d", warning_cnt);
}
guarantee(error_cnt == 0,
"Fatal error(s) found in ObjectMonitor::sanity_checks()");
}
#ifndef PRODUCT
void ObjectMonitor_test() {
ObjectMonitor::sanity_checks();
}
#endif

View File

@ -103,11 +103,11 @@ class ObjectWaiter : public StackObj {
// coherency misses. There is no single optimal layout for both
// single-threaded and multi-threaded environments.
//
// - See ObjectMonitor::sanity_checks() for how critical restrictions are
// enforced and advisory recommendations are reported.
// - See TEST_VM(ObjectMonitor, sanity) gtest for how critical restrictions are
// enforced.
// - Adjacent ObjectMonitors should be separated by enough space to avoid
// false sharing. This is handled by the ObjectMonitor allocation code
// in synchronizer.cpp. Also see ObjectSynchronizer::sanity_checks().
// in synchronizer.cpp. Also see TEST_VM(SynchronizerTest, sanity) gtest.
//
// Futures notes:
// - Separating _owner from the <remaining_fields> by enough space to
@ -294,8 +294,6 @@ class ObjectMonitor {
bool check(TRAPS); // true if the thread owns the monitor.
void check_slow(TRAPS);
void clear();
static void sanity_checks(); // public for -XX:+ExecuteInternalVMTests
// in PRODUCT for -XX:SyncKnobs=Verbose=1
void enter(TRAPS);
void exit(bool not_suspended, TRAPS);

View File

@ -1906,52 +1906,20 @@ const char* ObjectSynchronizer::inflate_cause_name(const InflateCause cause) {
//------------------------------------------------------------------------------
// Debugging code
void ObjectSynchronizer::sanity_checks(const bool verbose,
const uint cache_line_size,
int *error_cnt_ptr,
int *warning_cnt_ptr) {
u_char *addr_begin = (u_char*)&GVars;
u_char *addr_stwRandom = (u_char*)&GVars.stwRandom;
u_char *addr_hcSequence = (u_char*)&GVars.hcSequence;
u_char* ObjectSynchronizer::get_gvars_addr() {
return (u_char*)&GVars;
}
if (verbose) {
tty->print_cr("INFO: sizeof(SharedGlobals)=" SIZE_FORMAT,
sizeof(SharedGlobals));
}
u_char* ObjectSynchronizer::get_gvars_hcSequence_addr() {
return (u_char*)&GVars.hcSequence;
}
uint offset_stwRandom = (uint)(addr_stwRandom - addr_begin);
if (verbose) tty->print_cr("INFO: offset(stwRandom)=%u", offset_stwRandom);
size_t ObjectSynchronizer::get_gvars_size() {
return sizeof(SharedGlobals);
}
uint offset_hcSequence = (uint)(addr_hcSequence - addr_begin);
if (verbose) {
tty->print_cr("INFO: offset(_hcSequence)=%u", offset_hcSequence);
}
if (cache_line_size != 0) {
// We were able to determine the L1 data cache line size so
// do some cache line specific sanity checks
if (offset_stwRandom < cache_line_size) {
tty->print_cr("WARNING: the SharedGlobals.stwRandom field is closer "
"to the struct beginning than a cache line which permits "
"false sharing.");
(*warning_cnt_ptr)++;
}
if ((offset_hcSequence - offset_stwRandom) < cache_line_size) {
tty->print_cr("WARNING: the SharedGlobals.stwRandom and "
"SharedGlobals.hcSequence fields are closer than a cache "
"line which permits false sharing.");
(*warning_cnt_ptr)++;
}
if ((sizeof(SharedGlobals) - offset_hcSequence) < cache_line_size) {
tty->print_cr("WARNING: the SharedGlobals.hcSequence field is closer "
"to the struct end than a cache line which permits false "
"sharing.");
(*warning_cnt_ptr)++;
}
}
u_char* ObjectSynchronizer::get_gvars_stwRandom_addr() {
return (u_char*)&GVars.stwRandom;
}
#ifndef PRODUCT

View File

@ -153,12 +153,11 @@ class ObjectSynchronizer : AllStatic {
static void thread_local_used_oops_do(Thread* thread, OopClosure* f);
// debugging
static void sanity_checks(const bool verbose,
const unsigned int cache_line_size,
int *error_cnt_ptr, int *warning_cnt_ptr);
static int verify_objmon_isinpool(ObjectMonitor *addr) PRODUCT_RETURN0;
private:
friend class SynchronizerTest;
enum { _BLOCKSIZE = 128 };
// global list of blocks of monitors
static PaddedEnd<ObjectMonitor> * volatile gBlockList;
@ -177,6 +176,11 @@ class ObjectSynchronizer : AllStatic {
// Process oops in monitors on the given list
static void list_oops_do(ObjectMonitor* list, OopClosure* f);
// Support for SynchronizerTest access to GVars fields:
static u_char* get_gvars_addr();
static u_char* get_gvars_hcSequence_addr();
static size_t get_gvars_size();
static u_char* get_gvars_stwRandom_addr();
};
// ObjectLocker enforced balanced locking and can never thrown an

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018, 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
@ -47,7 +47,6 @@ void InternalVMTests::run() {
run_unit_test(TestVirtualSpace_test);
run_unit_test(TestMetaspaceUtils_test);
run_unit_test(GCTimer_test);
run_unit_test(ObjectMonitor_test);
// These tests require the "C" locale to correctly parse decimal values
const char* orig_locale = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018, 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/objectMonitor.hpp"
#include "runtime/vm_version.hpp"
#include "unittest.hpp"
TEST_VM(ObjectMonitor, sanity) {
EXPECT_EQ(0, ObjectMonitor::header_offset_in_bytes()) << "Offset for _header must be zero.";
uint cache_line_size = VM_Version::L1_data_cache_line_size();
if (cache_line_size != 0) {
// We were able to determine the L1 data cache line size so
// do some cache line specific sanity checks
EXPECT_EQ((size_t) 0, sizeof (PaddedEnd<ObjectMonitor>) % cache_line_size)
<< "PaddedEnd<ObjectMonitor> size is not a "
<< "multiple of a cache line which permits false sharing. "
<< "sizeof(PaddedEnd<ObjectMonitor>) = "
<< sizeof (PaddedEnd<ObjectMonitor>)
<< "; cache_line_size = " << cache_line_size;
EXPECT_GE((size_t) ObjectMonitor::owner_offset_in_bytes(), cache_line_size)
<< "the _header and _owner fields are closer "
<< "than a cache line which permits false sharing.";
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2018, 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/synchronizer.hpp"
#include "runtime/vm_version.hpp"
#include "unittest.hpp"
class SynchronizerTest : public ::testing::Test {
public:
static u_char* get_gvars_addr() { return ObjectSynchronizer::get_gvars_addr(); }
static u_char* get_gvars_hcSequence_addr() { return ObjectSynchronizer::get_gvars_hcSequence_addr(); }
static size_t get_gvars_size() { return ObjectSynchronizer::get_gvars_size(); }
static u_char* get_gvars_stwRandom_addr() { return ObjectSynchronizer::get_gvars_stwRandom_addr(); }
};
TEST_VM(SynchronizerTest, sanity) {
uint cache_line_size = VM_Version::L1_data_cache_line_size();
if (cache_line_size != 0) {
// We were able to determine the L1 data cache line size so
// do some cache line specific sanity checks
u_char *addr_begin = SynchronizerTest::get_gvars_addr();
u_char *addr_stwRandom = SynchronizerTest::get_gvars_stwRandom_addr();
u_char *addr_hcSequence = SynchronizerTest::get_gvars_hcSequence_addr();
size_t gvars_size = SynchronizerTest::get_gvars_size();
uint offset_stwRandom = (uint) (addr_stwRandom - addr_begin);
uint offset_hcSequence = (uint) (addr_hcSequence - addr_begin);
uint offset_hcSequence_stwRandom = offset_hcSequence - offset_stwRandom;
uint offset_hcSequence_struct_end = (uint) gvars_size - offset_hcSequence;
EXPECT_GE(offset_stwRandom, cache_line_size)
<< "the SharedGlobals.stwRandom field is closer "
<< "to the struct beginning than a cache line which permits "
<< "false sharing.";
EXPECT_GE(offset_hcSequence_stwRandom, cache_line_size)
<< "the SharedGlobals.stwRandom and "
<< "SharedGlobals.hcSequence fields are closer than a cache "
<< "line which permits false sharing.";
EXPECT_GE(offset_hcSequence_struct_end, cache_line_size)
<< "the SharedGlobals.hcSequence field is closer "
<< "to the struct end than a cache line which permits false "
<< "sharing.";
}
}