< prev index next >

src/share/vm/runtime/thread.cpp

Print this page

        

@@ -95,10 +95,11 @@
 #endif
 #ifdef TARGET_OS_FAMILY_bsd
 # include "os_bsd.inline.hpp"
 #endif
 #if INCLUDE_ALL_GCS
+#include "gc_implementation/shenandoah/shenandoahControlThread.hpp"
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
 #include "gc_implementation/parallelScavenge/pcTasks.hpp"
 #endif // INCLUDE_ALL_GCS
 #ifdef COMPILER1

@@ -299,12 +300,45 @@
     assert(this == _real_malloc_address ||
            this == (void*) align_size_up((intptr_t) _real_malloc_address, markOopDesc::biased_lock_alignment),
            "bug in forced alignment of thread objects");
   }
 #endif /* ASSERT */
+
+  _oom_during_evac = 0;
+#if INCLUDE_ALL_GCS
+  _gc_state = _gc_state_global;
+  _worker_id = (uint)(-1); // Actually, ShenandoahWorkerSession::INVALID_WORKER_ID, but avoid dependencies.
+  _force_satb_flush = false;
+#endif
+}
+
+void Thread::set_oom_during_evac(bool oom) {
+  if (oom) {
+    _oom_during_evac |= 1;
+  } else {
+    _oom_during_evac &= ~1;
+  }
+}
+
+bool Thread::is_oom_during_evac() const {
+  return (_oom_during_evac & 1) == 1;
 }
 
+#ifdef ASSERT
+void Thread::set_evac_allowed(bool evac_allowed) {
+  if (evac_allowed) {
+    _oom_during_evac |= 2;
+  } else {
+    _oom_during_evac &= ~2;
+  }
+}
+
+bool Thread::is_evac_allowed() const {
+  return (_oom_during_evac & 2) == 2;
+}
+#endif
+
 void Thread::initialize_thread_local_storage() {
   // Note: Make sure this method only calls
   // non-blocking operations. Otherwise, it might not work
   // with the thread-startup/safepoint interaction.
 

@@ -1503,17 +1537,18 @@
 }
 
 #if INCLUDE_ALL_GCS
 SATBMarkQueueSet JavaThread::_satb_mark_queue_set;
 DirtyCardQueueSet JavaThread::_dirty_card_queue_set;
+char Thread::_gc_state_global = 0;
 #endif // INCLUDE_ALL_GCS
 
 JavaThread::JavaThread(bool is_attaching_via_jni) :
   Thread()
 #if INCLUDE_ALL_GCS
   , _satb_mark_queue(&_satb_mark_queue_set),
-  _dirty_card_queue(&_dirty_card_queue_set)
+    _dirty_card_queue(&_dirty_card_queue_set)
 #endif // INCLUDE_ALL_GCS
 {
   initialize();
   if (is_attaching_via_jni) {
     _jni_attach_state = _attaching_via_jni;

@@ -1566,11 +1601,11 @@
 
 JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
   Thread()
 #if INCLUDE_ALL_GCS
   , _satb_mark_queue(&_satb_mark_queue_set),
-  _dirty_card_queue(&_dirty_card_queue_set)
+    _dirty_card_queue(&_dirty_card_queue_set)
 #endif // INCLUDE_ALL_GCS
 {
   if (TraceThreadEvents) {
     tty->print_cr("creating thread %p", this);
   }

@@ -1919,13 +1954,16 @@
 #if INCLUDE_ALL_GCS
   // We must flush the G1-related buffers before removing a thread
   // from the list of active threads. We must do this after any deferred
   // card marks have been flushed (above) so that any entries that are
   // added to the thread's dirty card queue as a result are not lost.
-  if (UseG1GC) {
+  if (UseG1GC || (UseShenandoahGC)) {
     flush_barrier_queues();
   }
+  if (UseShenandoahGC && UseTLAB && gclab().is_initialized()) {
+    gclab().make_parsable(true);
+  }
 #endif // INCLUDE_ALL_GCS
 
   // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
   Threads::remove(this);
 }

@@ -1955,10 +1993,31 @@
 
   DirtyCardQueue& dirty_queue = dirty_card_queue();
   // The dirty card queue should have been constructed with its
   // active field set to true.
   assert(dirty_queue.is_active(), "dirty card queue should be active");
+
+  _gc_state = _gc_state_global;
+}
+
+void JavaThread::set_gc_state(char in_prog) {
+  _gc_state = in_prog;
+}
+
+void JavaThread::set_gc_state_all_threads(char in_prog) {
+  assert_locked_or_safepoint(Threads_lock);
+  _gc_state_global = in_prog;
+  for (JavaThread* t = Threads::first(); t != NULL; t = t->next()) {
+    t->set_gc_state(in_prog);
+  }
+}
+
+void JavaThread::set_force_satb_flush_all_threads(bool value) {
+  assert_locked_or_safepoint(Threads_lock);
+  for (JavaThread* t = Threads::first(); t != NULL; t = t->next()) {
+    t->set_force_satb_flush(value);
+  }
 }
 #endif // INCLUDE_ALL_GCS
 
 void JavaThread::cleanup_failed_attach_current_thread() {
   if (get_thread_profiler() != NULL) {

@@ -1985,13 +2044,16 @@
   if (UseTLAB) {
     tlab().make_parsable(true);  // retire TLAB, if any
   }
 
 #if INCLUDE_ALL_GCS
-  if (UseG1GC) {
+  if (UseG1GC || (UseShenandoahGC)) {
     flush_barrier_queues();
   }
+  if (UseShenandoahGC && UseTLAB && gclab().is_initialized()) {
+    gclab().make_parsable(true);
+  }
 #endif // INCLUDE_ALL_GCS
 
   Threads::remove(this);
   delete this;
 }

@@ -3288,10 +3350,17 @@
 #endif
 
 // All JavaThreads
 #define ALL_JAVA_THREADS(X) for (JavaThread* X = _thread_list; X; X = X->next())
 
+void Threads::java_threads_do(ThreadClosure* tc) {
+  assert_locked_or_safepoint(Threads_lock);
+  ALL_JAVA_THREADS(p) {
+    tc->do_thread(p);
+  }
+}
+
 // All JavaThreads + all non-JavaThreads (i.e., every thread in the system)
 void Threads::threads_do(ThreadClosure* tc) {
   assert_locked_or_safepoint(Threads_lock);
   // ALL_JAVA_THREADS iterates through all JavaThreads
   ALL_JAVA_THREADS(p) {

@@ -3599,13 +3668,15 @@
 
 #if INCLUDE_ALL_GCS
   // Support for ConcurrentMarkSweep. This should be cleaned up
   // and better encapsulated. The ugly nested if test would go away
   // once things are properly refactored. XXX YSR
-  if (UseConcMarkSweepGC || UseG1GC) {
+  if (UseConcMarkSweepGC || UseG1GC || UseShenandoahGC) {
     if (UseConcMarkSweepGC) {
       ConcurrentMarkSweepThread::makeSurrogateLockerThread(THREAD);
+    } else if (UseShenandoahGC) {
+      ShenandoahControlThread::makeSurrogateLockerThread(THREAD);
     } else {
       ConcurrentMarkThread::makeSurrogateLockerThread(THREAD);
     }
     if (HAS_PENDING_EXCEPTION) {
       vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));

@@ -4190,11 +4261,12 @@
   // turn off parallelism in process_roots while active_workers
   // is being used for parallelism elsewhere.
   bool is_par = sh->n_par_threads() > 0;
   assert(!is_par ||
          (SharedHeap::heap()->n_par_threads() ==
-          SharedHeap::heap()->workers()->active_workers()), "Mismatch");
+          SharedHeap::heap()->workers()->active_workers()
+          || UseShenandoahGC), "Mismatch");
   int cp = SharedHeap::heap()->strong_roots_parity();
   ALL_JAVA_THREADS(p) {
     if (p->claim_oops_do(is_par, cp)) {
       p->oops_do(f, cld_f, cf);
     }
< prev index next >