8212108: SafepointSynchronizer never ending counter (big enough)
Reviewed-by: dholmes, eosterlund
--- a/src/hotspot/share/code/dependencyContext.hpp Fri Nov 23 10:51:59 2018 +0100
+++ b/src/hotspot/share/code/dependencyContext.hpp Fri Nov 23 10:43:18 2018 +0100
@@ -118,13 +118,13 @@
// Safepoints are forbidden during DC lifetime. GC can invalidate
// _dependency_context_addr if it relocates the holder
// (e.g. CallSiteContext Java object).
- int _safepoint_counter;
+ uint64_t _safepoint_counter;
DependencyContext(intptr_t* addr) : _dependency_context_addr(addr),
- _safepoint_counter(SafepointSynchronize::_safepoint_counter) {}
+ _safepoint_counter(SafepointSynchronize::safepoint_counter()) {}
~DependencyContext() {
- assert(_safepoint_counter == SafepointSynchronize::_safepoint_counter, "safepoint happened");
+ assert(_safepoint_counter == SafepointSynchronize::safepoint_counter(), "safepoint happened");
}
#else
DependencyContext(intptr_t* addr) : _dependency_context_addr(addr) {}
--- a/src/hotspot/share/jfr/metadata/metadata.xml Fri Nov 23 10:51:59 2018 +0100
+++ b/src/hotspot/share/jfr/metadata/metadata.xml Fri Nov 23 10:43:18 2018 +0100
@@ -67,7 +67,7 @@
<Event name="BiasedLockRevocation" category="Java Application" label="Biased Lock Revocation" description="Revoked bias of object" thread="true"
stackTrace="true">
<Field type="Class" name="lockClass" label="Lock Class" description="Class of object whose biased lock was revoked" />
- <Field type="int" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
<Field type="Thread" name="previousOwner" label="Previous Owner" description="Thread owning the bias before revocation" />
</Event>
@@ -80,7 +80,7 @@
thread="true" stackTrace="true">
<Field type="Class" name="revokedClass" label="Revoked Class" description="Class whose biased locks were revoked" />
<Field type="boolean" name="disableBiasing" label="Disable Further Biasing" description="Whether further biasing for instances of this class will be allowed" />
- <Field type="int" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
</Event>
<Event name="ReservedStackActivation" category="Java Virtual Machine, Runtime" label="Reserved Stack Activation"
@@ -519,14 +519,14 @@
</Event>
<Event name="SafepointBegin" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Begin" description="Safepointing begin" thread="true">
- <Field type="int" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
<Field type="int" name="totalThreadCount" label="Total Threads" description="The total number of threads at the start of safe point" />
<Field type="int" name="jniCriticalThreadCount" label="JNI Critical Threads" description="The number of threads in JNI critical sections" />
</Event>
<Event name="SafepointStateSynchronization" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint State Synchronization" description="Synchronize run state of threads"
thread="true">
- <Field type="int" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
<Field type="int" name="initialThreadCount" label="Initial Threads" description="The number of threads running at the beginning of state check" />
<Field type="int" name="runningThreadCount" label="Running Threads" description="The number of threads still running" />
<Field type="int" name="iterations" label="Iterations" description="Number of state check iterations" />
@@ -534,23 +534,23 @@
<Event name="SafepointWaitBlocked" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Wait Blocked" description="Safepointing begin waiting on running threads to block"
thread="true">
- <Field type="int" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
<Field type="int" name="runningThreadCount" label="Running Threads" description="The number running of threads wait for safe point" />
</Event>
<Event name="SafepointCleanup" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Cleanup" description="Safepointing begin running cleanup tasks"
thread="true">
- <Field type="int" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
</Event>
<Event name="SafepointCleanupTask" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Cleanup Task" description="Safepointing begin running cleanup tasks"
thread="true">
- <Field type="int" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
<Field type="string" name="name" label="Task Name" description="The task name" />
</Event>
<Event name="SafepointEnd" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint End" description="Safepointing end" thread="true">
- <Field type="int" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
</Event>
<Event name="ExecuteVMOperation" category="Java Virtual Machine, Runtime" label="VM Operation" description="Execution of a VM Operation" thread="true">
@@ -559,7 +559,7 @@
<Field type="boolean" name="blocking" label="Caller Blocked" description="If the calling thread was blocked until the operation was complete" />
<Field type="Thread" name="caller" label="Caller" transition="from"
description="Thread requesting operation. If non-blocking, will be set to 0 indicating thread is unknown" />
- <Field type="int" name="safepointId" label="Safepoint Identifier" description="The safepoint (if any) under which this operation was completed"
+ <Field type="ulong" name="safepointId" label="Safepoint Identifier" description="The safepoint (if any) under which this operation was completed"
relation="SafepointId" />
</Event>
--- a/src/hotspot/share/runtime/safepoint.cpp Fri Nov 23 10:51:59 2018 +0100
+++ b/src/hotspot/share/runtime/safepoint.cpp Fri Nov 23 10:43:18 2018 +0100
@@ -141,7 +141,7 @@
SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
volatile int SafepointSynchronize::_waiting_to_block = 0;
-volatile int SafepointSynchronize::_safepoint_counter = 0;
+volatile uint64_t SafepointSynchronize::_safepoint_counter = 0;
int SafepointSynchronize::_current_jni_active_count = 0;
long SafepointSynchronize::_end_of_last_safepoint = 0;
int SafepointSynchronize::_defer_thr_suspend_loop_count = 4000;
--- a/src/hotspot/share/runtime/safepoint.hpp Fri Nov 23 10:51:59 2018 +0100
+++ b/src/hotspot/share/runtime/safepoint.hpp Fri Nov 23 10:43:18 2018 +0100
@@ -101,11 +101,11 @@
// safepoint. The fact that Threads_lock is held throughout each pair of
// increments (at the beginning and end of each safepoint) guarantees
// race freedom.
-public:
- static volatile int _safepoint_counter;
+ static volatile uint64_t _safepoint_counter;
+
private:
- static long _end_of_last_safepoint; // Time of last safepoint in milliseconds
- static julong _coalesced_vmop_count; // coalesced vmop count
+ static long _end_of_last_safepoint; // Time of last safepoint in milliseconds
+ static julong _coalesced_vmop_count; // coalesced vmop count
// Statistics
static void begin_statistics(int nof_threads, int nof_running);
@@ -132,9 +132,9 @@
static void check_for_lazy_critical_native(JavaThread *thread, JavaThreadState state);
// Query
- inline static bool is_at_safepoint() { return _state == _synchronized; }
- inline static bool is_synchronizing() { return _state == _synchronizing; }
- inline static int safepoint_counter() { return _safepoint_counter; }
+ inline static bool is_at_safepoint() { return _state == _synchronized; }
+ inline static bool is_synchronizing() { return _state == _synchronizing; }
+ inline static uint64_t safepoint_counter() { return _safepoint_counter; }
inline static void increment_jni_active_count() {
assert_locked_or_safepoint(Safepoint_lock);
@@ -176,8 +176,17 @@
// Assembly support
static address address_of_state() { return (address)&_state; }
- static address safepoint_counter_addr() { return (address)&_safepoint_counter; }
-
+ // Only used for making sure that no safepoint has happened in
+ // JNI_FastGetField. Therefore only the low 32-bits are needed
+ // even if this is a 64-bit counter.
+ static address safepoint_counter_addr() {
+#ifdef VM_LITTLE_ENDIAN
+ return (address)&_safepoint_counter;
+#else /* BIG */
+ // Return pointer to the 32 LSB:
+ return (address) (((uint32_t*)(&_safepoint_counter)) + 1);
+#endif
+ }
};
// Some helper assert macros for safepoint checks.
--- a/test/jdk/jdk/jfr/event/runtime/TestBiasedLockRevocationEvents.java Fri Nov 23 10:51:59 2018 +0100
+++ b/test/jdk/jdk/jfr/event/runtime/TestBiasedLockRevocationEvents.java Fri Nov 23 10:43:18 2018 +0100
@@ -275,13 +275,13 @@
List<RecordedEvent> events = Events.fromRecording(recording);
// Determine which safepoints included single and bulk revocation VM operations
- Set<Integer> vmOperationsSingle = new HashSet<>();
- Set<Integer> vmOperationsBulk = new HashSet<>();
+ Set<Long> vmOperationsSingle = new HashSet<>();
+ Set<Long> vmOperationsBulk = new HashSet<>();
for (RecordedEvent event : events) {
if (event.getEventType().getName().equals(EventNames.ExecuteVMOperation)) {
String operation = event.getValue("operation");
- Integer safepointId = event.getValue("safepointId");
+ Long safepointId = event.getValue("safepointId");
if (operation.equals("RevokeBias")) {
vmOperationsSingle.add(safepointId);
@@ -297,14 +297,14 @@
// Match all revoke events to a corresponding VMOperation event
for (RecordedEvent event : events) {
if (event.getEventType().getName().equals(EventNames.BiasedLockRevocation)) {
- Integer safepointId = event.getValue("safepointId");
+ Long safepointId = event.getValue("safepointId");
String lockClass = ((RecordedClass)event.getValue("lockClass")).getName();
if (lockClass.equals(MyLock.class.getName())) {
Asserts.assertTrue(vmOperationsSingle.contains(safepointId));
revokeCount++;
}
} else if (event.getEventType().getName().equals(EventNames.BiasedLockClassRevocation)) {
- Integer safepointId = event.getValue("safepointId");
+ Long safepointId = event.getValue("safepointId");
String lockClass = ((RecordedClass)event.getValue("revokedClass")).getName();
if (lockClass.toString().equals(MyLock.class.getName())) {
Asserts.assertTrue(vmOperationsBulk.contains(safepointId));
--- a/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java Fri Nov 23 10:51:59 2018 +0100
+++ b/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java Fri Nov 23 10:43:18 2018 +0100
@@ -84,9 +84,9 @@
}
// Collect all events grouped by safepoint id
- SortedMap<Integer, Set<String>> safepointIds = new TreeMap<>();
+ SortedMap<Long, Set<String>> safepointIds = new TreeMap<>();
for (RecordedEvent event : Events.fromRecording(recording)) {
- Integer safepointId = event.getValue("safepointId");
+ Long safepointId = event.getValue("safepointId");
if (!safepointIds.containsKey(safepointId)) {
safepointIds.put(safepointId, new HashSet<>());
}