// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OPTIMIZING_COMPILE_DISPATCHER_H_
#define V8_OPTIMIZING_COMPILE_DISPATCHER_H_

#include <queue>

#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/flags.h"
#include "src/list.h"

namespace v8 {
namespace internal {

class HOptimizedGraphBuilder;
class OptimizedCompileJob;
class SharedFunctionInfo;

class OptimizingCompileDispatcher {
 public:
  explicit OptimizingCompileDispatcher(Isolate* isolate)
      : isolate_(isolate),
        input_queue_capacity_(FLAG_concurrent_recompilation_queue_length),
        input_queue_length_(0),
        input_queue_shift_(0),
        blocked_jobs_(0),
        ref_count_(0),
        recompilation_delay_(FLAG_concurrent_recompilation_delay) {
    base::NoBarrier_Store(&mode_, static_cast<base::AtomicWord>(COMPILE));
    input_queue_ = NewArray<OptimizedCompileJob*>(input_queue_capacity_);
  }

  ~OptimizingCompileDispatcher();

  void Run();
  void Stop();
  void Flush();
  void QueueForOptimization(OptimizedCompileJob* optimizing_compiler);
  void Unblock();
  void InstallOptimizedFunctions();

  inline bool IsQueueAvailable() {
    base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_);
    return input_queue_length_ < input_queue_capacity_;
  }

  static bool Enabled() { return FLAG_concurrent_recompilation; }

 private:
  class CompileTask;

  enum ModeFlag { COMPILE, FLUSH };

  void FlushOutputQueue(bool restore_function_code);
  void CompileNext(OptimizedCompileJob* job);
  OptimizedCompileJob* NextInput(bool check_if_flushing = false);

  inline int InputQueueIndex(int i) {
    int result = (i + input_queue_shift_) % input_queue_capacity_;
    DCHECK_LE(0, result);
    DCHECK_LT(result, input_queue_capacity_);
    return result;
  }

  Isolate* isolate_;

  // Circular queue of incoming recompilation tasks (including OSR).
  OptimizedCompileJob** input_queue_;
  int input_queue_capacity_;
  int input_queue_length_;
  int input_queue_shift_;
  base::Mutex input_queue_mutex_;

  // Queue of recompilation tasks ready to be installed (excluding OSR).
  std::queue<OptimizedCompileJob*> output_queue_;
  // Used for job based recompilation which has multiple producers on
  // different threads.
  base::Mutex output_queue_mutex_;

  volatile base::AtomicWord mode_;

  int blocked_jobs_;

  int ref_count_;
  base::Mutex ref_count_mutex_;
  base::ConditionVariable ref_count_zero_;

  // 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.
  int recompilation_delay_;
};
}  // namespace internal
}  // namespace v8

#endif  // V8_OPTIMIZING_COMPILE_DISPATCHER_H_
