8257641: Shenandoah: Query is_at_shenandoah_safepoint() from control thread should return false

Reviewed-by: shade
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
index 3a109a2..90d809b 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
@@ -122,6 +122,7 @@
   friend class ShenandoahGCSession;
   friend class ShenandoahGCStateResetter;
   friend class ShenandoahParallelObjectIterator;
+  friend class ShenandoahSafepoint;
 // ---------- Locks that guard important data structures in Heap
 //
 private:
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp
index 2f4fde1..c095075 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp
@@ -147,9 +147,15 @@
   static inline bool is_at_shenandoah_safepoint() {
     if (!SafepointSynchronize::is_at_safepoint()) return false;
 
+    Thread* const thr = Thread::current();
+    // Shenandoah GC specific safepoints are scheduled by control thread.
+    // So if we are enter here from control thread, then we are definitely not
+    // at Shenandoah safepoint, but at something else.
+    if (thr == ShenandoahHeap::heap()->control_thread()) return false;
+
     // This is not VM thread, cannot see what VM thread is doing,
     // so pretend this is a proper Shenandoah safepoint
-    if (!Thread::current()->is_VM_thread()) return true;
+    if (!thr->is_VM_thread()) return true;
 
     // Otherwise check we are at proper operation type
     VM_Operation* vm_op = VMThread::vm_operation();