8212108: SafepointSynchronizer never ending counter (big enough)
authorrehn
Fri, 23 Nov 2018 10:43:18 +0100
changeset 52672 bbfa1b3aaf7e
parent 52671 600fca45232b
child 52673 61b3b58a1d1d
8212108: SafepointSynchronizer never ending counter (big enough) Reviewed-by: dholmes, eosterlund
src/hotspot/share/code/dependencyContext.hpp
src/hotspot/share/jfr/metadata/metadata.xml
src/hotspot/share/runtime/safepoint.cpp
src/hotspot/share/runtime/safepoint.hpp
test/jdk/jdk/jfr/event/runtime/TestBiasedLockRevocationEvents.java
test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java
--- 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<>());
                 }