diff --git a/BUILD.gn b/BUILD.gn index 4d0e338555..3eebcfe8ce 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -893,8 +893,8 @@ source_set("v8_base") { "src/objects-printer.cc", "src/objects.cc", "src/objects.h", - "src/optimizing-compiler-thread.cc", - "src/optimizing-compiler-thread.h", + "src/optimizing-compile-dispatcher.cc", + "src/optimizing-compile-dispatcher.h", "src/ostreams.cc", "src/ostreams.h", "src/parser.cc", diff --git a/src/compiler.cc b/src/compiler.cc index 00a228238f..9502311960 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -819,7 +819,7 @@ static bool GetOptimizedCodeNow(CompilationInfo* info) { static bool GetOptimizedCodeLater(CompilationInfo* info) { Isolate* isolate = info->isolate(); - if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) { + if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) { if (FLAG_trace_concurrent_recompilation) { PrintF(" ** Compilation queue full, will retry optimizing "); info->closure()->ShortPrint(); @@ -840,7 +840,7 @@ static bool GetOptimizedCodeLater(CompilationInfo* info) { OptimizedCompileJob* job = new (info->zone()) OptimizedCompileJob(info); OptimizedCompileJob::Status status = job->CreateGraph(); if (status != OptimizedCompileJob::SUCCEEDED) return false; - isolate->optimizing_compiler_thread()->QueueForOptimization(job); + isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); if (FLAG_trace_concurrent_recompilation) { PrintF(" ** Queued "); diff --git a/src/compiler.h b/src/compiler.h index fb91a9e2f5..f9acb66c08 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -372,12 +372,10 @@ class CompilationInfo { } void AbortDueToDependencyChange() { - DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); aborted_due_to_dependency_change_ = true; } bool HasAbortedDueToDependencyChange() const { - DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); return aborted_due_to_dependency_change_; } diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h index 26ec7f900a..7d8669bf61 100644 --- a/src/cpu-profiler.h +++ b/src/cpu-profiler.h @@ -11,7 +11,7 @@ #include "src/circular-queue.h" #include "src/compiler.h" #include "src/sampler.h" -#include "src/unbound-queue.h" +#include "src/unbound-queue-inl.h" namespace v8 { namespace internal { diff --git a/src/debug.cc b/src/debug.cc index 854b507c47..25407a746f 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -1843,7 +1843,7 @@ void Debug::PrepareForBreakPoints() { // functions as debugging does not work with optimized code. if (!has_break_points_) { if (isolate_->concurrent_recompilation_enabled()) { - isolate_->optimizing_compiler_thread()->Flush(); + isolate_->optimizing_compile_dispatcher()->Flush(); } Deoptimizer::DeoptimizeAll(isolate_); diff --git a/src/execution.cc b/src/execution.cc index 7ae67410e4..e281bac5fa 100644 --- a/src/execution.cc +++ b/src/execution.cc @@ -677,7 +677,7 @@ Object* StackGuard::HandleInterrupts() { if (CheckAndClearInterrupt(INSTALL_CODE)) { DCHECK(isolate_->concurrent_recompilation_enabled()); - isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions(); + isolate_->optimizing_compile_dispatcher()->InstallOptimizedFunctions(); } if (CheckAndClearInterrupt(API_INTERRUPT)) { diff --git a/src/flag-definitions.h b/src/flag-definitions.h index e48dd9f788..def2dec73e 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -364,9 +364,6 @@ DEFINE_BOOL(optimize_for_in, true, "optimize functions containing for-in loops") DEFINE_BOOL(concurrent_recompilation, true, "optimizing hot functions asynchronously on a separate thread") -DEFINE_BOOL(job_based_recompilation, true, - "post tasks to v8::Platform instead of using a thread for " - "concurrent recompilation") DEFINE_BOOL(trace_concurrent_recompilation, false, "track concurrent recompilation") DEFINE_INT(concurrent_recompilation_queue_length, 8, diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 274d9ef0c2..0a458d7acf 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -430,7 +430,7 @@ void Heap::GarbageCollectionPrologue() { store_buffer()->GCPrologue(); if (isolate()->concurrent_osr_enabled()) { - isolate()->optimizing_compiler_thread()->AgeBufferedOsrJobs(); + isolate()->optimizing_compile_dispatcher()->AgeBufferedOsrJobs(); } if (new_space_.IsAtMaximumCapacity()) { @@ -767,7 +767,7 @@ void Heap::CollectAllAvailableGarbage(const char* gc_reason) { if (isolate()->concurrent_recompilation_enabled()) { // The optimizing compiler may be unnecessarily holding on to memory. DisallowHeapAllocation no_recursive_gc; - isolate()->optimizing_compiler_thread()->Flush(); + isolate()->optimizing_compile_dispatcher()->Flush(); } isolate()->ClearSerializerData(); mark_compact_collector()->SetFlags(kMakeHeapIterableMask | @@ -885,7 +885,7 @@ int Heap::NotifyContextDisposed(bool dependant_context) { } if (isolate()->concurrent_recompilation_enabled()) { // Flush the queued recompilation tasks. - isolate()->optimizing_compiler_thread()->Flush(); + isolate()->optimizing_compile_dispatcher()->Flush(); } AgeInlineCaches(); set_retained_maps(ArrayList::cast(empty_fixed_array())); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 7649dae047..0ea1bd59bd 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -3475,7 +3475,6 @@ HBasicBlock* HGraph::CreateBasicBlock() { void HGraph::FinalizeUniqueness() { DisallowHeapAllocation no_gc; - DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); for (int i = 0; i < blocks()->length(); ++i) { for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { it.Current()->FinalizeUniqueness(); diff --git a/src/isolate.cc b/src/isolate.cc index 927972d822..9a9403a79f 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -1736,7 +1736,7 @@ Isolate::Isolate(bool enable_serializer) heap_profiler_(NULL), function_entry_hook_(NULL), deferred_handles_head_(NULL), - optimizing_compiler_thread_(NULL), + optimizing_compile_dispatcher_(NULL), stress_deopt_count_(0), next_optimization_id_(0), #if TRACE_MAPS @@ -1833,9 +1833,9 @@ void Isolate::Deinit() { FreeThreadResources(); if (concurrent_recompilation_enabled()) { - optimizing_compiler_thread_->Stop(); - delete optimizing_compiler_thread_; - optimizing_compiler_thread_ = NULL; + optimizing_compile_dispatcher_->Stop(); + delete optimizing_compile_dispatcher_; + optimizing_compile_dispatcher_ = NULL; } if (heap_.mark_compact_collector()->sweeping_in_progress()) { @@ -2133,9 +2133,8 @@ bool Isolate::Init(Deserializer* des) { if (FLAG_trace_hydrogen || FLAG_trace_hydrogen_stubs) { PrintF("Concurrent recompilation has been disabled for tracing.\n"); - } else if (OptimizingCompilerThread::Enabled(max_available_threads_)) { - optimizing_compiler_thread_ = new OptimizingCompilerThread(this); - optimizing_compiler_thread_->Start(); + } else if (OptimizingCompileDispatcher::Enabled(max_available_threads_)) { + optimizing_compile_dispatcher_ = new OptimizingCompileDispatcher(this); } // Initialize runtime profiler before deserialization, because collections may diff --git a/src/isolate.h b/src/isolate.h index e8576f5940..85d25ed93e 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -19,7 +19,7 @@ #include "src/handles.h" #include "src/hashmap.h" #include "src/heap/heap.h" -#include "src/optimizing-compiler-thread.h" +#include "src/optimizing-compile-dispatcher.h" #include "src/regexp-stack.h" #include "src/runtime/runtime.h" #include "src/runtime-profiler.h" @@ -1028,20 +1028,20 @@ class Isolate { bool concurrent_recompilation_enabled() { // Thread is only available with flag enabled. - DCHECK(optimizing_compiler_thread_ == NULL || + DCHECK(optimizing_compile_dispatcher_ == NULL || FLAG_concurrent_recompilation); - return optimizing_compiler_thread_ != NULL; + return optimizing_compile_dispatcher_ != NULL; } bool concurrent_osr_enabled() const { // Thread is only available with flag enabled. - DCHECK(optimizing_compiler_thread_ == NULL || + DCHECK(optimizing_compile_dispatcher_ == NULL || FLAG_concurrent_recompilation); - return optimizing_compiler_thread_ != NULL && FLAG_concurrent_osr; + return optimizing_compile_dispatcher_ != NULL && FLAG_concurrent_osr; } - OptimizingCompilerThread* optimizing_compiler_thread() { - return optimizing_compiler_thread_; + OptimizingCompileDispatcher* optimizing_compile_dispatcher() { + return optimizing_compile_dispatcher_; } int id() const { return static_cast(id_); } @@ -1329,7 +1329,7 @@ class Isolate { #endif DeferredHandles* deferred_handles_head_; - OptimizingCompilerThread* optimizing_compiler_thread_; + OptimizingCompileDispatcher* optimizing_compile_dispatcher_; // Counts deopt points if deopt_every_n_times is enabled. unsigned int stress_deopt_count_; @@ -1350,7 +1350,7 @@ class Isolate { friend class ExecutionAccess; friend class HandleScopeImplementer; - friend class OptimizingCompilerThread; + friend class OptimizingCompileDispatcher; friend class SweeperThread; friend class ThreadManager; friend class Simulator; diff --git a/src/objects.cc b/src/objects.cc index 20d7f9029b..bb10a9b1c2 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -9708,7 +9708,7 @@ void JSFunction::AttemptConcurrentOptimization() { return; } if (isolate->concurrent_osr_enabled() && - isolate->optimizing_compiler_thread()->IsQueuedForOSR(this)) { + isolate->optimizing_compile_dispatcher()->IsQueuedForOSR(this)) { // Do not attempt regular recompilation if we already queued this for OSR. // TODO(yangguo): This is necessary so that we don't install optimized // code on a function that is already optimized, since OSR and regular diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compile-dispatcher.cc similarity index 55% rename from src/optimizing-compiler-thread.cc rename to src/optimizing-compile-dispatcher.cc index eda4f5ca9d..8445dc15a0 100644 --- a/src/optimizing-compiler-thread.cc +++ b/src/optimizing-compile-dispatcher.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/optimizing-compiler-thread.h" +#include "src/optimizing-compile-dispatcher.h" #include "src/v8.h" @@ -10,7 +10,6 @@ #include "src/full-codegen.h" #include "src/hydrogen.h" #include "src/isolate.h" -#include "src/v8threads.h" namespace v8 { namespace internal { @@ -40,12 +39,13 @@ void DisposeOptimizedCompileJob(OptimizedCompileJob* job, } // namespace -class OptimizingCompilerThread::CompileTask : public v8::Task { +class OptimizingCompileDispatcher::CompileTask : public v8::Task { public: explicit CompileTask(Isolate* isolate) : isolate_(isolate) { - OptimizingCompilerThread* thread = isolate_->optimizing_compiler_thread(); - base::LockGuard lock_guard(&thread->ref_count_mutex_); - ++thread->ref_count_; + OptimizingCompileDispatcher* dispatcher = + isolate_->optimizing_compile_dispatcher(); + base::LockGuard lock_guard(&dispatcher->ref_count_mutex_); + ++dispatcher->ref_count_; } virtual ~CompileTask() {} @@ -57,20 +57,21 @@ class OptimizingCompilerThread::CompileTask : public v8::Task { DisallowHandleAllocation no_handles; DisallowHandleDereference no_deref; - OptimizingCompilerThread* thread = isolate_->optimizing_compiler_thread(); + OptimizingCompileDispatcher* dispatcher = + isolate_->optimizing_compile_dispatcher(); { TimerEventScope timer(isolate_); - if (thread->recompilation_delay_ != 0) { - base::OS::Sleep(thread->recompilation_delay_); + if (dispatcher->recompilation_delay_ != 0) { + base::OS::Sleep(dispatcher->recompilation_delay_); } - thread->CompileNext(thread->NextInput(true)); + dispatcher->CompileNext(dispatcher->NextInput(true)); } { - base::LockGuard lock_guard(&thread->ref_count_mutex_); - if (--thread->ref_count_ == 0) { - thread->ref_count_zero_.NotifyOne(); + base::LockGuard lock_guard(&dispatcher->ref_count_mutex_); + if (--dispatcher->ref_count_ == 0) { + dispatcher->ref_count_zero_.NotifyOne(); } } } @@ -81,7 +82,7 @@ class OptimizingCompilerThread::CompileTask : public v8::Task { }; -OptimizingCompilerThread::~OptimizingCompilerThread() { +OptimizingCompileDispatcher::~OptimizingCompileDispatcher() { #ifdef DEBUG { base::LockGuard lock_guard(&ref_count_mutex_); @@ -101,65 +102,7 @@ OptimizingCompilerThread::~OptimizingCompilerThread() { } -void OptimizingCompilerThread::Run() { -#ifdef DEBUG - { base::LockGuard lock_guard(&thread_id_mutex_); - thread_id_ = ThreadId::Current().ToInteger(); - } -#endif - DisallowHeapAllocation no_allocation; - DisallowHandleAllocation no_handles; - DisallowHandleDereference no_deref; - - if (job_based_recompilation_) { - return; - } - - base::ElapsedTimer total_timer; - if (tracing_enabled_) total_timer.Start(); - - while (true) { - input_queue_semaphore_.Wait(); - TimerEventScope timer(isolate_); - - if (recompilation_delay_ != 0) { - base::OS::Sleep(recompilation_delay_); - } - - switch (static_cast(base::Acquire_Load(&stop_thread_))) { - case CONTINUE: - break; - case STOP: - if (tracing_enabled_) { - time_spent_total_ = total_timer.Elapsed(); - } - stop_semaphore_.Signal(); - return; - case FLUSH: - // The main thread is blocked, waiting for the stop semaphore. - { AllowHandleDereference allow_handle_dereference; - FlushInputQueue(true); - } - base::Release_Store(&stop_thread_, - static_cast(CONTINUE)); - stop_semaphore_.Signal(); - // Return to start of consumer loop. - continue; - } - - base::ElapsedTimer compiling_timer; - if (tracing_enabled_) compiling_timer.Start(); - - CompileNext(NextInput()); - - if (tracing_enabled_) { - time_spent_compiling_ += compiling_timer.Elapsed(); - } - } -} - - -OptimizedCompileJob* OptimizingCompilerThread::NextInput( +OptimizedCompileJob* OptimizingCompileDispatcher::NextInput( bool check_if_flushing) { base::LockGuard access_input_queue_(&input_queue_mutex_); if (input_queue_length_ == 0) return NULL; @@ -168,7 +111,7 @@ OptimizedCompileJob* OptimizingCompilerThread::NextInput( input_queue_shift_ = InputQueueIndex(1); input_queue_length_--; if (check_if_flushing) { - if (static_cast(base::Acquire_Load(&stop_thread_)) != CONTINUE) { + if (static_cast(base::Acquire_Load(&mode_)) == FLUSH) { if (!job->info()->is_osr()) { AllowHandleDereference allow_handle_dereference; DisposeOptimizedCompileJob(job, true); @@ -180,31 +123,29 @@ OptimizedCompileJob* OptimizingCompilerThread::NextInput( } -void OptimizingCompilerThread::CompileNext(OptimizedCompileJob* job) { +void OptimizingCompileDispatcher::CompileNext(OptimizedCompileJob* job) { if (!job) return; // The function may have already been optimized by OSR. Simply continue. OptimizedCompileJob::Status status = job->OptimizeGraph(); - USE(status); // Prevent an unused-variable error in release mode. + USE(status); // Prevent an unused-variable error in release mode. DCHECK(status != OptimizedCompileJob::FAILED); // The function may have already been optimized by OSR. Simply continue. // Use a mutex to make sure that functions marked for install // are always also queued. - if (job_based_recompilation_) output_queue_mutex_.Lock(); - output_queue_.Enqueue(job); - if (job_based_recompilation_) output_queue_mutex_.Unlock(); + base::LockGuard access_output_queue_(&output_queue_mutex_); + output_queue_.push(job); isolate_->stack_guard()->RequestInstallCode(); } -void OptimizingCompilerThread::FlushInputQueue(bool restore_function_code) { - OptimizedCompileJob* job; - while ((job = NextInput())) { - DCHECK(!job_based_recompilation_); - // 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(); +void OptimizingCompileDispatcher::FlushOutputQueue(bool restore_function_code) { + base::LockGuard access_output_queue_(&output_queue_mutex_); + while (!output_queue_.empty()) { + OptimizedCompileJob* job = output_queue_.front(); + output_queue_.pop(); + // OSR jobs are dealt with separately. if (!job->info()->is_osr()) { DisposeOptimizedCompileJob(job, restore_function_code); @@ -213,18 +154,7 @@ void OptimizingCompilerThread::FlushInputQueue(bool restore_function_code) { } -void OptimizingCompilerThread::FlushOutputQueue(bool restore_function_code) { - OptimizedCompileJob* job; - while (output_queue_.Dequeue(&job)) { - // OSR jobs are dealt with separately. - if (!job->info()->is_osr()) { - DisposeOptimizedCompileJob(job, restore_function_code); - } - } -} - - -void OptimizingCompilerThread::FlushOsrBuffer(bool restore_function_code) { +void OptimizingCompileDispatcher::FlushOsrBuffer(bool restore_function_code) { for (int i = 0; i < osr_buffer_capacity_; i++) { if (osr_buffer_[i] != NULL) { DisposeOptimizedCompileJob(osr_buffer_[i], restore_function_code); @@ -234,37 +164,29 @@ void OptimizingCompilerThread::FlushOsrBuffer(bool restore_function_code) { } -void OptimizingCompilerThread::Flush() { - DCHECK(!IsOptimizerThread()); - base::Release_Store(&stop_thread_, static_cast(FLUSH)); +void OptimizingCompileDispatcher::Flush() { + base::Release_Store(&mode_, static_cast(FLUSH)); if (FLAG_block_concurrent_recompilation) Unblock(); - if (!job_based_recompilation_) { - input_queue_semaphore_.Signal(); - stop_semaphore_.Wait(); - } else { + { base::LockGuard lock_guard(&ref_count_mutex_); while (ref_count_ > 0) ref_count_zero_.Wait(&ref_count_mutex_); - base::Release_Store(&stop_thread_, static_cast(CONTINUE)); + base::Release_Store(&mode_, static_cast(COMPILE)); } FlushOutputQueue(true); if (FLAG_concurrent_osr) FlushOsrBuffer(true); - if (tracing_enabled_) { + if (FLAG_trace_concurrent_recompilation) { PrintF(" ** Flushed concurrent recompilation queues.\n"); } } -void OptimizingCompilerThread::Stop() { - DCHECK(!IsOptimizerThread()); - base::Release_Store(&stop_thread_, static_cast(STOP)); +void OptimizingCompileDispatcher::Stop() { + base::Release_Store(&mode_, static_cast(FLUSH)); if (FLAG_block_concurrent_recompilation) Unblock(); - if (!job_based_recompilation_) { - input_queue_semaphore_.Signal(); - stop_semaphore_.Wait(); - } else { + { base::LockGuard lock_guard(&ref_count_mutex_); while (ref_count_ > 0) ref_count_zero_.Wait(&ref_count_mutex_); - base::Release_Store(&stop_thread_, static_cast(CONTINUE)); + base::Release_Store(&mode_, static_cast(COMPILE)); } if (recompilation_delay_ != 0) { @@ -273,32 +195,25 @@ void OptimizingCompilerThread::Stop() { while (input_queue_length_ > 0) CompileNext(NextInput()); InstallOptimizedFunctions(); } else { - FlushInputQueue(false); FlushOutputQueue(false); } if (FLAG_concurrent_osr) FlushOsrBuffer(false); - if (tracing_enabled_) { - double percentage = time_spent_compiling_.PercentOf(time_spent_total_); - if (job_based_recompilation_) percentage = 100.0; - PrintF(" ** Compiler thread did %.2f%% useful work\n", percentage); - } - - if ((FLAG_trace_osr || tracing_enabled_) && FLAG_concurrent_osr) { + if ((FLAG_trace_osr || FLAG_trace_concurrent_recompilation) && + FLAG_concurrent_osr) { PrintF("[COSR hit rate %d / %d]\n", osr_hits_, osr_attempts_); } - - Join(); } -void OptimizingCompilerThread::InstallOptimizedFunctions() { - DCHECK(!IsOptimizerThread()); +void OptimizingCompileDispatcher::InstallOptimizedFunctions() { HandleScope handle_scope(isolate_); - OptimizedCompileJob* job; - while (output_queue_.Dequeue(&job)) { + base::LockGuard access_output_queue_(&output_queue_mutex_); + while (!output_queue_.empty()) { + OptimizedCompileJob* job = output_queue_.front(); + output_queue_.pop(); CompilationInfo* info = job->info(); Handle function(*info->closure()); if (info->is_osr()) { @@ -315,7 +230,7 @@ void OptimizingCompilerThread::InstallOptimizedFunctions() { BackEdgeTable::RemoveStackCheck(code, offset); } else { if (function->IsOptimized()) { - if (tracing_enabled_) { + if (FLAG_trace_concurrent_recompilation) { PrintF(" ** Aborting compilation for "); function->ShortPrint(); PrintF(" as it has already been optimized.\n"); @@ -323,17 +238,17 @@ void OptimizingCompilerThread::InstallOptimizedFunctions() { DisposeOptimizedCompileJob(job, false); } else { Handle code = Compiler::GetConcurrentlyOptimizedCode(job); - function->ReplaceCode( - code.is_null() ? function->shared()->code() : *code); + function->ReplaceCode(code.is_null() ? function->shared()->code() + : *code); } } } } -void OptimizingCompilerThread::QueueForOptimization(OptimizedCompileJob* job) { +void OptimizingCompileDispatcher::QueueForOptimization( + OptimizedCompileJob* job) { DCHECK(IsQueueAvailable()); - DCHECK(!IsOptimizerThread()); CompilationInfo* info = job->info(); if (info->is_osr()) { osr_attempts_++; @@ -354,36 +269,27 @@ void OptimizingCompilerThread::QueueForOptimization(OptimizedCompileJob* job) { } if (FLAG_block_concurrent_recompilation) { blocked_jobs_++; - } else if (job_based_recompilation_) { + } else { V8::GetCurrentPlatform()->CallOnBackgroundThread( new CompileTask(isolate_), v8::Platform::kShortRunningTask); - } else { - input_queue_semaphore_.Signal(); } } -void OptimizingCompilerThread::Unblock() { - DCHECK(!IsOptimizerThread()); +void OptimizingCompileDispatcher::Unblock() { while (blocked_jobs_ > 0) { - if (job_based_recompilation_) { - V8::GetCurrentPlatform()->CallOnBackgroundThread( - new CompileTask(isolate_), v8::Platform::kShortRunningTask); - } else { - input_queue_semaphore_.Signal(); - } + V8::GetCurrentPlatform()->CallOnBackgroundThread( + new CompileTask(isolate_), v8::Platform::kShortRunningTask); blocked_jobs_--; } } -OptimizedCompileJob* OptimizingCompilerThread::FindReadyOSRCandidate( +OptimizedCompileJob* OptimizingCompileDispatcher::FindReadyOSRCandidate( Handle function, BailoutId osr_ast_id) { - DCHECK(!IsOptimizerThread()); for (int i = 0; i < osr_buffer_capacity_; i++) { OptimizedCompileJob* current = osr_buffer_[i]; - if (current != NULL && - current->IsWaitingForInstall() && + if (current != NULL && current->IsWaitingForInstall() && current->info()->HasSameOsrEntry(function, osr_ast_id)) { osr_hits_++; osr_buffer_[i] = NULL; @@ -394,9 +300,8 @@ OptimizedCompileJob* OptimizingCompilerThread::FindReadyOSRCandidate( } -bool OptimizingCompilerThread::IsQueuedForOSR(Handle function, - BailoutId osr_ast_id) { - DCHECK(!IsOptimizerThread()); +bool OptimizingCompileDispatcher::IsQueuedForOSR(Handle function, + BailoutId osr_ast_id) { for (int i = 0; i < osr_buffer_capacity_; i++) { OptimizedCompileJob* current = osr_buffer_[i]; if (current != NULL && @@ -408,8 +313,7 @@ bool OptimizingCompilerThread::IsQueuedForOSR(Handle function, } -bool OptimizingCompilerThread::IsQueuedForOSR(JSFunction* function) { - DCHECK(!IsOptimizerThread()); +bool OptimizingCompileDispatcher::IsQueuedForOSR(JSFunction* function) { for (int i = 0; i < osr_buffer_capacity_; i++) { OptimizedCompileJob* current = osr_buffer_[i]; if (current != NULL && *current->info()->closure() == function) { @@ -420,8 +324,7 @@ bool OptimizingCompilerThread::IsQueuedForOSR(JSFunction* function) { } -void OptimizingCompilerThread::AddToOsrBuffer(OptimizedCompileJob* job) { - DCHECK(!IsOptimizerThread()); +void OptimizingCompileDispatcher::AddToOsrBuffer(OptimizedCompileJob* job) { // Find the next slot that is empty or has a stale job. OptimizedCompileJob* stale = NULL; while (true) { @@ -444,20 +347,5 @@ void OptimizingCompilerThread::AddToOsrBuffer(OptimizedCompileJob* job) { osr_buffer_[osr_buffer_cursor_] = job; osr_buffer_cursor_ = (osr_buffer_cursor_ + 1) % osr_buffer_capacity_; } - - -#ifdef DEBUG -bool OptimizingCompilerThread::IsOptimizerThread(Isolate* isolate) { - return isolate->concurrent_recompilation_enabled() && - isolate->optimizing_compiler_thread()->IsOptimizerThread(); } - - -bool OptimizingCompilerThread::IsOptimizerThread() { - base::LockGuard lock_guard(&thread_id_mutex_); - return ThreadId::Current().ToInteger() == thread_id_; -} -#endif - - -} } // namespace v8::internal +} // namespace v8::internal diff --git a/src/optimizing-compiler-thread.h b/src/optimizing-compile-dispatcher.h similarity index 71% rename from src/optimizing-compiler-thread.h rename to src/optimizing-compile-dispatcher.h index 7d60d9bf74..822bb40b31 100644 --- a/src/optimizing-compiler-thread.h +++ b/src/optimizing-compile-dispatcher.h @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_OPTIMIZING_COMPILER_THREAD_H_ -#define V8_OPTIMIZING_COMPILER_THREAD_H_ +#ifndef V8_OPTIMIZING_COMPILE_DISPATCHER_H_ +#define V8_OPTIMIZING_COMPILE_DISPATCHER_H_ + +#include #include "src/base/atomicops.h" #include "src/base/platform/condition-variable.h" #include "src/base/platform/mutex.h" #include "src/base/platform/platform.h" -#include "src/base/platform/time.h" #include "src/flags.h" #include "src/list.h" -#include "src/unbound-queue-inl.h" namespace v8 { namespace internal { @@ -21,16 +21,10 @@ class HOptimizedGraphBuilder; class OptimizedCompileJob; class SharedFunctionInfo; -class OptimizingCompilerThread : public base::Thread { +class OptimizingCompileDispatcher { public: - explicit OptimizingCompilerThread(Isolate* isolate) - : Thread(Options("OptimizingCompilerThread")), -#ifdef DEBUG - thread_id_(0), -#endif - isolate_(isolate), - stop_semaphore_(0), - input_queue_semaphore_(0), + explicit OptimizingCompileDispatcher(Isolate* isolate) + : isolate_(isolate), input_queue_capacity_(FLAG_concurrent_recompilation_queue_length), input_queue_length_(0), input_queue_shift_(0), @@ -40,11 +34,8 @@ class OptimizingCompilerThread : public base::Thread { osr_attempts_(0), blocked_jobs_(0), ref_count_(0), - tracing_enabled_(FLAG_trace_concurrent_recompilation), - job_based_recompilation_(FLAG_job_based_recompilation), recompilation_delay_(FLAG_concurrent_recompilation_delay) { - base::NoBarrier_Store(&stop_thread_, - static_cast(CONTINUE)); + base::NoBarrier_Store(&mode_, static_cast(COMPILE)); input_queue_ = NewArray(input_queue_capacity_); if (FLAG_concurrent_osr) { // Allocate and mark OSR buffer slots as empty. @@ -53,7 +44,7 @@ class OptimizingCompilerThread : public base::Thread { } } - ~OptimizingCompilerThread(); + ~OptimizingCompileDispatcher(); void Run(); void Stop(); @@ -83,17 +74,11 @@ class OptimizingCompilerThread : public base::Thread { return (FLAG_concurrent_recompilation && max_available > 1); } -#ifdef DEBUG - static bool IsOptimizerThread(Isolate* isolate); - bool IsOptimizerThread(); -#endif - private: class CompileTask; - enum StopFlag { CONTINUE, STOP, FLUSH }; + enum ModeFlag { COMPILE, FLUSH }; - void FlushInputQueue(bool restore_function_code); void FlushOutputQueue(bool restore_function_code); void FlushOsrBuffer(bool restore_function_code); void CompileNext(OptimizedCompileJob* job); @@ -110,14 +95,7 @@ class OptimizingCompilerThread : public base::Thread { return result; } -#ifdef DEBUG - int thread_id_; - base::Mutex thread_id_mutex_; -#endif - Isolate* isolate_; - base::Semaphore stop_semaphore_; - base::Semaphore input_queue_semaphore_; // Circular queue of incoming recompilation tasks (including OSR). OptimizedCompileJob** input_queue_; @@ -127,7 +105,7 @@ class OptimizingCompilerThread : public base::Thread { base::Mutex input_queue_mutex_; // Queue of recompilation tasks ready to be installed (excluding OSR). - UnboundQueue output_queue_; + std::queue output_queue_; // Used for job based recompilation which has multiple producers on // different threads. base::Mutex output_queue_mutex_; @@ -137,9 +115,7 @@ class OptimizingCompilerThread : public base::Thread { int osr_buffer_capacity_; int osr_buffer_cursor_; - volatile base::AtomicWord stop_thread_; - base::TimeDelta time_spent_compiling_; - base::TimeDelta time_spent_total_; + volatile base::AtomicWord mode_; int osr_hits_; int osr_attempts_; @@ -150,17 +126,14 @@ class OptimizingCompilerThread : public base::Thread { base::Mutex ref_count_mutex_; base::ConditionVariable ref_count_zero_; - // Copies of FLAG_trace_concurrent_recompilation, - // FLAG_concurrent_recompilation_delay and - // FLAG_job_based_recompilation that will be used from the background thread. + // Copy of FLAG_concurrent_recompilation_delay that will be used from the + // background thread. // // Since flags might get modified while the background thread is running, it // is not safe to access them directly. - bool tracing_enabled_; - bool job_based_recompilation_; int recompilation_delay_; }; +} +} // namespace v8::internal -} } // namespace v8::internal - -#endif // V8_OPTIMIZING_COMPILER_THREAD_H_ +#endif // V8_OPTIMIZING_COMPILE_DISPATCHER_H_ diff --git a/src/runtime/runtime-compiler.cc b/src/runtime/runtime-compiler.cc index d8512fdfb5..16175803f0 100644 --- a/src/runtime/runtime-compiler.cc +++ b/src/runtime/runtime-compiler.cc @@ -232,8 +232,9 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { // Gate the OSR entry with a stack check. BackEdgeTable::AddStackCheck(caller_code, pc_offset); // Poll already queued compilation jobs. - OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread(); - if (thread->IsQueuedForOSR(function, ast_id)) { + OptimizingCompileDispatcher* dispatcher = + isolate->optimizing_compile_dispatcher(); + if (dispatcher->IsQueuedForOSR(function, ast_id)) { if (FLAG_trace_osr) { PrintF("[OSR - Still waiting for queued: "); function->PrintName(); @@ -242,7 +243,7 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { return NULL; } - job = thread->FindReadyOSRCandidate(function, ast_id); + job = dispatcher->FindReadyOSRCandidate(function, ast_id); } if (job != NULL) { @@ -324,7 +325,7 @@ RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) { return isolate->StackOverflow(); } - isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); + isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions(); return (function->IsOptimized()) ? function->code() : function->shared()->code(); } diff --git a/src/runtime/runtime-test.cc b/src/runtime/runtime-test.cc index 6a812da822..9a59d9c436 100644 --- a/src/runtime/runtime-test.cc +++ b/src/runtime/runtime-test.cc @@ -175,7 +175,7 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) { if (isolate->concurrent_recompilation_enabled() && sync_with_compiler_thread) { while (function->IsInOptimizationQueue()) { - isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); + isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions(); base::OS::Sleep(50); } } @@ -200,7 +200,7 @@ RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) { DCHECK(args.length() == 0); RUNTIME_ASSERT(FLAG_block_concurrent_recompilation); RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled()); - isolate->optimizing_compiler_thread()->Unblock(); + isolate->optimizing_compile_dispatcher()->Unblock(); return isolate->heap()->undefined_value(); } diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index 31890fa713..c3a1c611d6 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -780,8 +780,8 @@ '../../src/objects-printer.cc', '../../src/objects.cc', '../../src/objects.h', - '../../src/optimizing-compiler-thread.cc', - '../../src/optimizing-compiler-thread.h', + '../../src/optimizing-compile-dispatcher.cc', + '../../src/optimizing-compile-dispatcher.h', '../../src/ostreams.cc', '../../src/ostreams.h', '../../src/parser.cc',