8171157: Convert ObjectMonitor_test to GTest
Summary: Migration of the ObjectMonitor test to GTest. Two GTests were actually created, one for ObjectMonitor and one for ObjectSynchronizer.
Reviewed-by: dcubed, hseigel
Contributed-by: patricio.chilano.mateo@oracle.com
--- a/src/hotspot/share/runtime/objectMonitor.cpp Fri Jul 27 14:20:07 2018 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.cpp Fri Jul 27 16:29:36 2018 -0400
@@ -2354,10 +2354,6 @@
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 @@
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
--- a/src/hotspot/share/runtime/objectMonitor.hpp Fri Jul 27 14:20:07 2018 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.hpp Fri Jul 27 16:29:36 2018 -0400
@@ -103,11 +103,11 @@
// 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 @@
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);
--- a/src/hotspot/share/runtime/synchronizer.cpp Fri Jul 27 14:20:07 2018 +0530
+++ b/src/hotspot/share/runtime/synchronizer.cpp Fri Jul 27 16:29:36 2018 -0400
@@ -1906,52 +1906,20 @@
//------------------------------------------------------------------------------
// 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;
-
- if (verbose) {
- tty->print_cr("INFO: sizeof(SharedGlobals)=" SIZE_FORMAT,
- sizeof(SharedGlobals));
- }
-
- uint offset_stwRandom = (uint)(addr_stwRandom - addr_begin);
- if (verbose) tty->print_cr("INFO: offset(stwRandom)=%u", offset_stwRandom);
-
- uint offset_hcSequence = (uint)(addr_hcSequence - addr_begin);
- if (verbose) {
- tty->print_cr("INFO: offset(_hcSequence)=%u", offset_hcSequence);
- }
+u_char* ObjectSynchronizer::get_gvars_addr() {
+ return (u_char*)&GVars;
+}
- 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)++;
- }
+u_char* ObjectSynchronizer::get_gvars_hcSequence_addr() {
+ return (u_char*)&GVars.hcSequence;
+}
- 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)++;
- }
+size_t ObjectSynchronizer::get_gvars_size() {
+ return sizeof(SharedGlobals);
+}
- 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
--- a/src/hotspot/share/runtime/synchronizer.hpp Fri Jul 27 14:20:07 2018 +0530
+++ b/src/hotspot/share/runtime/synchronizer.hpp Fri Jul 27 16:29:36 2018 -0400
@@ -153,12 +153,11 @@
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 @@
// 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
--- a/src/hotspot/share/utilities/internalVMTests.cpp Fri Jul 27 14:20:07 2018 +0530
+++ b/src/hotspot/share/utilities/internalVMTests.cpp Fri Jul 27 16:29:36 2018 -0400
@@ -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 @@
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");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/runtime/test_objectMonitor.cpp Fri Jul 27 16:29:36 2018 -0400
@@ -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.";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/runtime/test_synchronizer.cpp Fri Jul 27 16:29:36 2018 -0400
@@ -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.";
+ }
+}