v8: upgrade to 3.20.17
[platform/upstream/nodejs.git] / deps / v8 / src / optimizing-compiler-thread.cc
index 21ef237..337ddd4 100644 (file)
@@ -60,12 +60,25 @@ void OptimizingCompilerThread::Run() {
       OS::Sleep(FLAG_parallel_recompilation_delay);
     }
 
-    if (Acquire_Load(&stop_thread_)) {
-      stop_semaphore_->Signal();
-      if (FLAG_trace_parallel_recompilation) {
-        time_spent_total_ = OS::Ticks() - epoch;
-      }
-      return;
+    switch (static_cast<StopFlag>(Acquire_Load(&stop_thread_))) {
+      case CONTINUE:
+        break;
+      case STOP:
+        if (FLAG_trace_parallel_recompilation) {
+          time_spent_total_ = OS::Ticks() - epoch;
+        }
+        stop_semaphore_->Signal();
+        return;
+      case FLUSH:
+        // The main thread is blocked, waiting for the stop semaphore.
+        { AllowHandleDereference allow_handle_dereference;
+          FlushInputQueue(true);
+        }
+        Release_Store(&queue_length_, static_cast<AtomicWord>(0));
+        Release_Store(&stop_thread_, static_cast<AtomicWord>(CONTINUE));
+        stop_semaphore_->Signal();
+        // Return to start of consumer loop.
+        continue;
     }
 
     int64_t compiling_start = 0;
@@ -82,7 +95,9 @@ void OptimizingCompilerThread::Run() {
 
 void OptimizingCompilerThread::CompileNext() {
   OptimizingCompiler* optimizing_compiler = NULL;
-  input_queue_.Dequeue(&optimizing_compiler);
+  bool result = input_queue_.Dequeue(&optimizing_compiler);
+  USE(result);
+  ASSERT(result);
   Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(-1));
 
   // The function may have already been optimized by OSR.  Simply continue.
@@ -102,26 +117,61 @@ void OptimizingCompilerThread::CompileNext() {
 }
 
 
+void OptimizingCompilerThread::FlushInputQueue(bool restore_function_code) {
+  OptimizingCompiler* optimizing_compiler;
+  // The optimizing compiler is allocated in the CompilationInfo's zone.
+  while (input_queue_.Dequeue(&optimizing_compiler)) {
+    // This should not block, since we have one signal on the input queue
+    // semaphore corresponding to each element in the input queue.
+    input_queue_semaphore_->Wait();
+    CompilationInfo* info = optimizing_compiler->info();
+    if (restore_function_code) {
+      Handle<JSFunction> function = info->closure();
+      function->ReplaceCode(function->shared()->code());
+    }
+    delete info;
+  }
+}
+
+
+void OptimizingCompilerThread::FlushOutputQueue(bool restore_function_code) {
+  OptimizingCompiler* optimizing_compiler;
+  // The optimizing compiler is allocated in the CompilationInfo's zone.
+  while (output_queue_.Dequeue(&optimizing_compiler)) {
+    CompilationInfo* info = optimizing_compiler->info();
+    if (restore_function_code) {
+      Handle<JSFunction> function = info->closure();
+      function->ReplaceCode(function->shared()->code());
+    }
+    delete info;
+  }
+}
+
+
+void OptimizingCompilerThread::Flush() {
+  ASSERT(!IsOptimizerThread());
+  Release_Store(&stop_thread_, static_cast<AtomicWord>(FLUSH));
+  input_queue_semaphore_->Signal();
+  stop_semaphore_->Wait();
+  FlushOutputQueue(true);
+}
+
+
 void OptimizingCompilerThread::Stop() {
   ASSERT(!IsOptimizerThread());
-  Release_Store(&stop_thread_, static_cast<AtomicWord>(true));
+  Release_Store(&stop_thread_, static_cast<AtomicWord>(STOP));
   input_queue_semaphore_->Signal();
   stop_semaphore_->Wait();
 
   if (FLAG_parallel_recompilation_delay != 0) {
     // Barrier when loading queue length is not necessary since the write
     // happens in CompileNext on the same thread.
+    // This is used only for testing.
     while (NoBarrier_Load(&queue_length_) > 0) CompileNext();
     InstallOptimizedFunctions();
   } else {
-    OptimizingCompiler* optimizing_compiler;
-    // The optimizing compiler is allocated in the CompilationInfo's zone.
-    while (input_queue_.Dequeue(&optimizing_compiler)) {
-      delete optimizing_compiler->info();
-    }
-    while (output_queue_.Dequeue(&optimizing_compiler)) {
-      delete optimizing_compiler->info();
-    }
+    FlushInputQueue(false);
+    FlushOutputQueue(false);
   }
 
   if (FLAG_trace_parallel_recompilation) {