// Copyright (c) 2016, 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_HEAP_SAFEPOINT_H_
#define RUNTIME_VM_HEAP_SAFEPOINT_H_

#include "vm/globals.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/thread.h"
#include "vm/thread_registry.h"
#include "vm/thread_stack_resource.h"

namespace dart {

class ThreadBarrier;

// A stack based scope that can be used to perform an operation after getting
// all threads to a safepoint. At the end of the operation all the threads are
// resumed.
class SafepointOperationScope : public ThreadStackResource {
 protected:
  SafepointOperationScope(Thread* T, SafepointLevel level);
  ~SafepointOperationScope();

 private:
  SafepointLevel level_;

  DISALLOW_COPY_AND_ASSIGN(SafepointOperationScope);
};

// Gets all mutators to a safepoint where GC is allowed.
class GcSafepointOperationScope : public SafepointOperationScope {
 public:
  explicit GcSafepointOperationScope(Thread* T)
      : SafepointOperationScope(T, SafepointLevel::kGC) {}
  ~GcSafepointOperationScope() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(GcSafepointOperationScope);
};

// Gets all mutators to a safepoint where GC and Deopt is allowed.
class DeoptSafepointOperationScope : public SafepointOperationScope {
 public:
  explicit DeoptSafepointOperationScope(Thread* T)
      : SafepointOperationScope(T, SafepointLevel::kGCAndDeopt) {}
  ~DeoptSafepointOperationScope() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(DeoptSafepointOperationScope);
};

// Gets all mutators to a safepoint where GC, Deopt and Reload is allowed.
class ReloadSafepointOperationScope : public SafepointOperationScope {
 public:
  explicit ReloadSafepointOperationScope(Thread* T)
      : SafepointOperationScope(T, SafepointLevel::kGCAndDeoptAndReload) {}
  ~ReloadSafepointOperationScope() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ReloadSafepointOperationScope);
};

// A stack based scope that can be used to perform an operation after getting
// all threads to a safepoint. At the end of the operation all the threads are
// resumed. Allocations in the scope will force heap growth.
class ForceGrowthSafepointOperationScope : public ThreadStackResource {
 public:
  ForceGrowthSafepointOperationScope(Thread* T, SafepointLevel level);
  ~ForceGrowthSafepointOperationScope();

 private:
  SafepointLevel level_;
  bool current_growth_controller_state_;

  DISALLOW_COPY_AND_ASSIGN(ForceGrowthSafepointOperationScope);
};

// Subclasses of SafepointTask are able to run on thread blocked at a safepoint.
class SafepointTask : public ThreadPool::Task,
                      public IntrusiveDListEntry<SafepointTask> {
 protected:
  SafepointTask(IsolateGroup* isolate_group,
                ThreadBarrier* barrier,
                Thread::TaskKind kind)
      : isolate_group_(isolate_group), barrier_(barrier), kind_(kind) {}

 public:
  virtual ~SafepointTask();

  void Run();
  void RunBlockedAtSafepoint();
  void RunMain();
  virtual void RunEnteredIsolateGroup() = 0;

 protected:
  IsolateGroup* isolate_group_;
  ThreadBarrier* barrier_;
  Thread::TaskKind kind_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SafepointTask);
};

// Implements handling of safepoint operations for all threads in an
// IsolateGroup.
class SafepointHandler {
 public:
  explicit SafepointHandler(IsolateGroup* I);
  ~SafepointHandler();

  void EnterSafepointUsingLock(Thread* T);
  void ExitSafepointUsingLock(Thread* T);
  void BlockForSafepoint(Thread* T);

  // The innermost safepoint operation this thread owns
  //
  // Returns `SafepointLevel::kNone` if the current thread doesn't own any
  // safepoint. Otherwise returns the innermost safepoint level of the current
  // thread.
  //
  // * Will return SafepointLevel::kDeoptAndGC for
  //
  //   DeoptSafepointOperationScope sp;
  //
  // * Will return SafepointLevel::kGC for
  //
  //   DeoptSafepointOperationScope sp1;
  //   GcSafepointOperationScope sp2;
  //
  SafepointLevel InnermostSafepointOperation(
      const Thread* current_thread) const;

  bool AnySafepointInProgressLocked() {
    for (intptr_t level = 0; level < SafepointLevel::kNumLevels; ++level) {
      if (handlers_[level]->SafepointInProgress()) {
        return true;
      }
    }
    return false;
  }

  void RunTasks(IntrusiveDList<SafepointTask>* tasks);

 private:
  class LevelHandler {
   public:
    LevelHandler(IsolateGroup* isolate_group, SafepointLevel level)
        : isolate_group_(isolate_group), level_(level) {}

    bool SafepointInProgress() const {
      ASSERT(threads_lock()->IsOwnedByCurrentThread());
      ASSERT((operation_count_ > 0) == (owner_ != nullptr));
      return ((operation_count_ > 0) && (owner_ != nullptr));
    }
    void SetSafepointInProgress(Thread* T) {
      ASSERT(threads_lock()->IsOwnedByCurrentThread());
      ASSERT(owner_ == nullptr);
      ASSERT(operation_count_ == 0);
      operation_count_ = 1;
      owner_ = T;
    }
    void ResetSafepointInProgress(Thread* T) {
      ASSERT(threads_lock()->IsOwnedByCurrentThread());
      ASSERT(owner_ == T);
      ASSERT(operation_count_ == 1);
      ASSERT(num_threads_not_parked_ == 0);
      operation_count_ = 0;
      owner_ = nullptr;
    }
    void NotifyWeAreParked(Thread* T);

    IsolateGroup* isolate_group() const { return isolate_group_; }
    Monitor* threads_lock() const {
      return isolate_group_->thread_registry()->threads_lock();
    }

   private:
    friend class SafepointHandler;

    // Helper methods for [SafepointThreads]
    void NotifyThreadsToGetToSafepointLevel(
        Thread* T,
        MallocGrowableArray<Dart_Port>* oob_isolates);
    void WaitUntilThreadsReachedSafepointLevel();

    // Helper methods for [ResumeThreads]
    void NotifyThreadsToContinue(Thread* T);

    IsolateGroup* isolate_group_;
    SafepointLevel level_;

    // Monitor used by thread initiating a safepoint operation to track threads
    // not at a safepoint and wait for these threads to reach a safepoint.
    Monitor parked_lock_;

    // If a safepoint operation is currently in progress, this field contains
    // the thread that initiated the safepoint operation, otherwise it is
    // nullptr.
    std::atomic<Thread*> owner_ = nullptr;

    // The number of nested safepoint operations currently held.
    std::atomic<int32_t> operation_count_ = 0;

    // Count the number of threads the currently in-progress safepoint operation
    // is waiting for to check-in.
    int32_t num_threads_not_parked_ = 0;
  };

  void SafepointThreads(Thread* T, SafepointLevel level);
  void ResumeThreads(Thread* T, SafepointLevel level);

  // Helper methods for [SafepointThreads]
  void AssertWeOwnLowerLevelSafepoints(Thread* T, SafepointLevel level);
  void AssertWeDoNotOwnLowerLevelSafepoints(Thread* T, SafepointLevel level);
  void AcquireLowerLevelSafepoints(Thread* T, SafepointLevel level);

  // Helper methods for [ResumeThreads]
  void ReleaseLowerLevelSafepoints(Thread* T, SafepointLevel level);

  void EnterSafepointLocked(Thread* T, MonitorLocker* tl, SafepointLevel level);
  void ExitSafepointLocked(Thread* T, MonitorLocker* tl, SafepointLevel level);

  IsolateGroup* isolate_group() const { return isolate_group_; }
  Monitor* threads_lock() const {
    return isolate_group_->thread_registry()->threads_lock();
  }

  IsolateGroup* isolate_group_;

  LevelHandler* handlers_[SafepointLevel::kNumLevels];
  IntrusiveDList<SafepointTask> tasks_;

  friend class Isolate;
  friend class IsolateGroup;
  friend class SafepointOperationScope;
  friend class ForceGrowthSafepointOperationScope;
  friend class HeapIterationScope;
};

/*
 * Set of StackResource classes to track thread execution state transitions:
 *
 * kThreadInGenerated transitioning to
 *   ==> kThreadInVM:
 *       - set_execution_state(kThreadInVM).
 *       - block if safepoint is requested.
 *   ==> kThreadInNative:
 *       - set_execution_state(kThreadInNative).
 *       - EnterSafepoint().
 *   ==> kThreadInBlockedState:
 *       - Invalid transition
 *
 * kThreadInVM transitioning to
 *   ==> kThreadInGenerated
 *       - set_execution_state(kThreadInGenerated).
 *   ==> kThreadInNative
 *       - set_execution_state(kThreadInNative).
 *       - EnterSafepoint.
 *   ==> kThreadInBlockedState
 *       - set_execution_state(kThreadInBlockedState).
 *       - EnterSafepoint.
 *
 * kThreadInNative transitioning to
 *   ==> kThreadInGenerated
 *       - ExitSafepoint.
 *       - set_execution_state(kThreadInGenerated).
 *   ==> kThreadInVM
 *       - ExitSafepoint.
 *       - set_execution_state(kThreadInVM).
 *   ==> kThreadInBlocked
 *       - Invalid transition.
 *
 * kThreadInBlocked transitioning to
 *   ==> kThreadInVM
 *       - ExitSafepoint.
 *       - set_execution_state(kThreadInVM).
 *   ==> kThreadInNative
 *       - Invalid transition.
 *   ==> kThreadInGenerated
 *       - Invalid transition.
 */
class TransitionSafepointState : public ThreadStackResource {
 public:
  explicit TransitionSafepointState(Thread* T) : ThreadStackResource(T) {}
  ~TransitionSafepointState() {}

  SafepointHandler* handler() const {
    ASSERT(thread()->isolate() != nullptr);
    ASSERT(thread()->isolate()->safepoint_handler() != nullptr);
    return thread()->isolate()->safepoint_handler();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TransitionSafepointState);
};

// TransitionGeneratedToVM is used to transition the safepoint state of a
// thread from "running generated code" to "running vm code" and ensures
// that the state is reverted back to "running generated code" when
// exiting the scope/frame.
class TransitionGeneratedToVM : public TransitionSafepointState {
 public:
  explicit TransitionGeneratedToVM(Thread* T) : TransitionSafepointState(T) {
    ASSERT(T == Thread::Current());
    ASSERT(T->execution_state() == Thread::kThreadInGenerated);
    T->set_execution_state(Thread::kThreadInVM);
    // Fast check to see if a safepoint is requested or not.
    // We do the more expensive operation of blocking the thread
    // only if a safepoint is requested.
    if (T->IsSafepointRequested()) {
      T->BlockForSafepoint();
    }
  }

  ~TransitionGeneratedToVM() {
    ASSERT(thread()->execution_state() == Thread::kThreadInVM);
    thread()->set_execution_state(Thread::kThreadInGenerated);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TransitionGeneratedToVM);
};

// TransitionGeneratedToNative is used to transition the safepoint state of a
// thread from "running generated code" to "running native code" and ensures
// that the state is reverted back to "running generated code" when
// exiting the scope/frame.
class TransitionGeneratedToNative : public TransitionSafepointState {
 public:
  explicit TransitionGeneratedToNative(Thread* T)
      : TransitionSafepointState(T) {
    // Native code is considered to be at a safepoint and so we mark it
    // accordingly.
    ASSERT(T->execution_state() == Thread::kThreadInGenerated);
    T->set_execution_state(Thread::kThreadInNative);
    T->EnterSafepointToNative();
  }

  ~TransitionGeneratedToNative() {
    // We are returning to generated code and so we are not at a safepoint
    // anymore.
    ASSERT(thread()->execution_state() == Thread::kThreadInNative);
    thread()->ExitSafepointFromNative();
    thread()->set_execution_state(Thread::kThreadInGenerated);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TransitionGeneratedToNative);
};

// TransitionVMToBlocked is used to transition the safepoint state of a
// thread from "running vm code" to "blocked on a monitor" and ensures
// that the state is reverted back to "running vm code" when
// exiting the scope/frame.
class TransitionVMToBlocked : public TransitionSafepointState {
 public:
  explicit TransitionVMToBlocked(Thread* T) : TransitionSafepointState(T) {
    ASSERT(T->CanAcquireSafepointLocks());
    // A thread blocked on a monitor is considered to be at a safepoint.
    ASSERT(T->execution_state() == Thread::kThreadInVM);
    T->set_execution_state(Thread::kThreadInBlockedState);
    T->EnterSafepoint();
  }

  ~TransitionVMToBlocked() {
    // We are returning to vm code and so we are not at a safepoint anymore.
    ASSERT(thread()->execution_state() == Thread::kThreadInBlockedState);
    thread()->ExitSafepoint();
    thread()->set_execution_state(Thread::kThreadInVM);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TransitionVMToBlocked);
};

// TransitionVMToNative is used to transition the safepoint state of a
// thread from "running vm code" to "running native code" and ensures
// that the state is reverted back to "running vm code" when
// exiting the scope/frame.
class TransitionVMToNative : public TransitionSafepointState {
 public:
  explicit TransitionVMToNative(Thread* T) : TransitionSafepointState(T) {
    // A thread running native code is considered to be at a safepoint.
    ASSERT(T->execution_state() == Thread::kThreadInVM);
    T->set_execution_state(Thread::kThreadInNative);
    T->EnterSafepoint();
  }

  ~TransitionVMToNative() {
    // We are returning to vm code and so we are not at a safepoint anymore.
    ASSERT(thread()->execution_state() == Thread::kThreadInNative);
    thread()->ExitSafepointFromNative();
    thread()->set_execution_state(Thread::kThreadInVM);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TransitionVMToNative);
};

// TransitionVMToGenerated is used to transition the safepoint state of a
// thread from "running vm code" to "running generated code" and ensures
// that the state is reverted back to "running vm code" when
// exiting the scope/frame.
class TransitionVMToGenerated : public TransitionSafepointState {
 public:
  explicit TransitionVMToGenerated(Thread* T) : TransitionSafepointState(T) {
    ASSERT(T == Thread::Current());
    ASSERT(T->execution_state() == Thread::kThreadInVM);
    T->set_execution_state(Thread::kThreadInGenerated);
  }

  ~TransitionVMToGenerated() {
    ASSERT(thread()->execution_state() == Thread::kThreadInGenerated);
    thread()->set_execution_state(Thread::kThreadInVM);
    // Fast check to see if a safepoint is requested or not.
    if (thread()->IsSafepointRequested()) {
      thread()->BlockForSafepoint();
    }
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TransitionVMToGenerated);
};

// TransitionNativeToVM is used to transition the safepoint state of a
// thread from "running native code" to "running vm code" and ensures
// that the state is reverted back to "running native code" when
// exiting the scope/frame.
class TransitionNativeToVM : public TransitionSafepointState {
 public:
  explicit TransitionNativeToVM(Thread* T) : TransitionSafepointState(T) {
    // We are about to execute vm code and so we are not at a safepoint anymore.
    ASSERT(T->execution_state() == Thread::kThreadInNative);
    if (T->no_callback_scope_depth() == 0) {
      T->ExitSafepointFromNative();
    }
    T->set_execution_state(Thread::kThreadInVM);
  }

  ~TransitionNativeToVM() {
    // We are returning to native code and so we are at a safepoint.
    ASSERT(thread()->execution_state() == Thread::kThreadInVM);
    thread()->set_execution_state(Thread::kThreadInNative);
    if (thread()->no_callback_scope_depth() == 0) {
      thread()->EnterSafepointToNative();
    }
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TransitionNativeToVM);
};

// TransitionToGenerated is used to transition the safepoint state of a
// thread from "running vm code" or "running native code" to
// "running generated code" and ensures that the state is reverted back
// to "running vm code" or "running native code" when exiting the
// scope/frame.
class TransitionToGenerated : public TransitionSafepointState {
 public:
  explicit TransitionToGenerated(Thread* T)
      : TransitionSafepointState(T), execution_state_(T->execution_state()) {
    ASSERT(T == Thread::Current());
    ASSERT((execution_state_ == Thread::kThreadInVM) ||
           (execution_state_ == Thread::kThreadInNative));
    if (execution_state_ == Thread::kThreadInNative) {
      T->ExitSafepoint();
    }
    T->set_execution_state(Thread::kThreadInGenerated);
  }

  ~TransitionToGenerated() {
    ASSERT(thread()->execution_state() == Thread::kThreadInGenerated);
    if (execution_state_ == Thread::kThreadInNative) {
      thread()->set_execution_state(Thread::kThreadInNative);
      thread()->EnterSafepoint();
    } else {
      ASSERT(execution_state_ == Thread::kThreadInVM);
      thread()->set_execution_state(Thread::kThreadInVM);
    }
  }

 private:
  uint32_t execution_state_;
  DISALLOW_COPY_AND_ASSIGN(TransitionToGenerated);
};

// TransitionToVM is used to transition the safepoint state of a
// thread from "running native code" to "running vm code"
// and ensures that the state is reverted back to "running native code"
// when exiting the scope/frame.
// This transition helper is mainly used in the error path of the
// Dart API implementations where we sometimes do not have an explicit
// transition set up.
class TransitionToVM : public TransitionSafepointState {
 public:
  explicit TransitionToVM(Thread* T)
      : TransitionSafepointState(T), execution_state_(T->execution_state()) {
    ASSERT(T == Thread::Current());
    ASSERT((execution_state_ == Thread::kThreadInVM) ||
           (execution_state_ == Thread::kThreadInNative));
    if (execution_state_ == Thread::kThreadInNative) {
      T->ExitSafepointFromNative();
      T->set_execution_state(Thread::kThreadInVM);
    }
    ASSERT(T->execution_state() == Thread::kThreadInVM);
  }

  ~TransitionToVM() {
    ASSERT(thread()->execution_state() == Thread::kThreadInVM);
    if (execution_state_ == Thread::kThreadInNative) {
      thread()->set_execution_state(Thread::kThreadInNative);
      thread()->EnterSafepoint();
    }
  }

 private:
  uint32_t execution_state_;
  DISALLOW_COPY_AND_ASSIGN(TransitionToVM);
};

// TransitionToNative is used to transition the safepoint state of a
// thread from "running VM code" to "running native code"
// and ensures that the state is reverted back to the initial state
// when exiting the scope/frame.
class TransitionToNative : public TransitionSafepointState {
 public:
  explicit TransitionToNative(Thread* T)
      : TransitionSafepointState(T), execution_state_(T->execution_state()) {
    ASSERT(T == Thread::Current());
    ASSERT((execution_state_ == Thread::kThreadInVM) ||
           (execution_state_ == Thread::kThreadInNative));
    if (execution_state_ == Thread::kThreadInVM) {
      T->set_execution_state(Thread::kThreadInNative);
      T->EnterSafepointToNative();
    }
    ASSERT(T->execution_state() == Thread::kThreadInNative);
  }

  ~TransitionToNative() {
    ASSERT(thread()->execution_state() == Thread::kThreadInNative);
    if (execution_state_ == Thread::kThreadInVM) {
      thread()->ExitSafepointFromNative();
      thread()->set_execution_state(Thread::kThreadInVM);
    }
  }

 private:
  uint32_t execution_state_;
  DISALLOW_COPY_AND_ASSIGN(TransitionToNative);
};

}  // namespace dart

#endif  // RUNTIME_VM_HEAP_SAFEPOINT_H_
