// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_COMPILER_JIT_COMPILER_H_
#define RUNTIME_VM_COMPILER_JIT_COMPILER_H_

#include "vm/allocation.h"
#include "vm/compiler/api/deopt_id.h"
#include "vm/growable_array.h"
#include "vm/runtime_entry.h"
#include "vm/thread_pool.h"

namespace dart {

// Forward declarations.
class BackgroundCompilationQueue;
class Class;
class Code;
class CompilationWorkQueue;
class FlowGraph;
class Function;
class IndirectGotoInstr;
class Library;
class ParsedFunction;
class QueueElement;
class Script;
class SequenceNode;

class Compiler : public AllStatic {
 public:
  static constexpr intptr_t kNoOSRDeoptId = DeoptId::kNone;

#if !defined(DART_PRECOMPILED_RUNTIME)
  // Build flow graph for the given function.
  static FlowGraph* BuildFlowGraph(
      Zone* zone,
      ParsedFunction* parsed_function,
      ZoneGrowableArray<const ICData*>* ic_data_array,
      intptr_t osr_id,
      bool optimized);
#endif

  static bool IsBackgroundCompilation();
  // The result for a function may change if debugging gets turned on/off.
  static bool CanOptimizeFunction(Thread* thread, const Function& function);

  // Generates code for given function without optimization and sets its code
  // field.
  //
  // Returns the raw code object if compilation succeeds.  Otherwise returns an
  // ErrorPtr.  Also installs the generated code on the function.
  static ObjectPtr CompileFunction(Thread* thread, const Function& function);

  // Generates unoptimized code if not present, current code is unchanged.
  static ErrorPtr EnsureUnoptimizedCode(Thread* thread,
                                        const Function& function);

  // Generates optimized code for function.
  //
  // Returns the code object if compilation succeeds.  Returns an Error if
  // there is a compilation error.  If optimization fails, but there is no
  // error, returns null.  Any generated code is installed unless we are in
  // OSR mode.
  static ObjectPtr CompileOptimizedFunction(Thread* thread,
                                            const Function& function,
                                            intptr_t osr_id = kNoOSRDeoptId);

  // Generates local var descriptors and sets it in 'code'. Do not call if the
  // local var descriptor already exists.
  static void ComputeLocalVarDescriptors(const Code& code);

  // Eagerly compiles all functions in a class.
  //
  // Returns Error::null() if there is no compilation error.
  static ErrorPtr CompileAllFunctions(const Class& cls);

  // Notify the compiler that background (optimized) compilation has failed
  // because the mutator thread changed the state (e.g., deoptimization,
  // deferred loading). The background compilation may retry to compile
  // the same function later.
  static void AbortBackgroundCompilation(intptr_t deopt_id, const char* msg);
};

// Class to run optimizing compilation in a background thread.
// Current implementation: one task per isolate, it dies with the owning
// isolate.
// No OSR compilation in the background compiler.
class BackgroundCompiler {
 public:
  explicit BackgroundCompiler(IsolateGroup* isolate_group);
  virtual ~BackgroundCompiler();

  static void Stop(IsolateGroup* isolate_group) {
    isolate_group->background_compiler()->Stop();
  }

  // Enqueues a function to be compiled in the background.
  //
  // Return `true` if successful.
  bool EnqueueCompilation(const Function& function);

  void VisitPointers(ObjectPointerVisitor* visitor);

  BackgroundCompilationQueue* function_queue() const { return function_queue_; }
  bool is_running() const { return running_; }

  void Run();

 private:
  friend class NoBackgroundCompilerScope;

  void Stop();
  void StopLocked(Thread* thread, SafepointMonitorLocker* done_locker);
  void Enable();
  void Disable();
  bool IsRunning() { return !done_; }

  IsolateGroup* isolate_group_;

  Monitor monitor_;  // Controls access to the queue and running state.
  BackgroundCompilationQueue* function_queue_;
  bool running_;  // While true, will try to read queue and compile.
  bool done_;     // True if the thread is done.
  int16_t disabled_depth_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(BackgroundCompiler);
};

class NoBackgroundCompilerScope : public StackResource {
 public:
  explicit NoBackgroundCompilerScope(Thread* thread)
      : StackResource(thread), isolate_group_(thread->isolate_group()) {
#if defined(DART_PRECOMPILED_RUNTIME)
    UNREACHABLE();
#else
    isolate_group_->background_compiler()->Disable();
#endif
  }
  ~NoBackgroundCompilerScope() {
#if defined(DART_PRECOMPILED_RUNTIME)
    UNREACHABLE();
#else
    isolate_group_->background_compiler()->Enable();
#endif
  }

 private:
  IsolateGroup* isolate_group_;
};

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_JIT_COMPILER_H_
