// Copyright (c) 2021, 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.

#include "vm/pending_deopts.h"
#include "vm/log.h"
#include "vm/stack_frame.h"
#include "vm/stub_code.h"

namespace dart {

DECLARE_FLAG(bool, trace_deoptimization);

PendingDeopts::PendingDeopts()
    : pending_deopts_(new MallocGrowableArray<PendingLazyDeopt>()) {}
PendingDeopts::~PendingDeopts() {
  delete pending_deopts_;
  pending_deopts_ = nullptr;
}

void PendingDeopts::AddPendingDeopt(uword fp, uword pc) {
  // GrowableArray::Add is not atomic and may be interrupted by a profiler
  // stack walk.
  MallocGrowableArray<PendingLazyDeopt>* old_pending_deopts = pending_deopts_;
  MallocGrowableArray<PendingLazyDeopt>* new_pending_deopts =
      new MallocGrowableArray<PendingLazyDeopt>(old_pending_deopts->length() +
                                                1);
  for (intptr_t i = 0; i < old_pending_deopts->length(); i++) {
    ASSERT((*old_pending_deopts)[i].fp() != fp);
    new_pending_deopts->Add((*old_pending_deopts)[i]);
  }
  PendingLazyDeopt deopt(fp, pc);
  new_pending_deopts->Add(deopt);

  pending_deopts_ = new_pending_deopts;
  delete old_pending_deopts;
}

uword PendingDeopts::FindPendingDeopt(uword fp) {
  for (intptr_t i = 0; i < pending_deopts_->length(); i++) {
    if ((*pending_deopts_)[i].fp() == fp) {
      return (*pending_deopts_)[i].pc();
    }
  }
  FATAL("Missing pending deopt entry");
  return 0;
}

void PendingDeopts::ClearPendingDeoptsBelow(uword fp, ClearReason reason) {
  for (intptr_t i = pending_deopts_->length() - 1; i >= 0; i--) {
    if ((*pending_deopts_)[i].fp() < fp) {
      if (FLAG_trace_deoptimization) {
        switch (reason) {
          case kClearDueToThrow:
            THR_Print(
                "Lazy deopt skipped due to throw for "
                "fp=%" Pp ", pc=%" Pp "\n",
                (*pending_deopts_)[i].fp(), (*pending_deopts_)[i].pc());
            break;
          case kClearDueToDeopt:
            THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n",
                      (*pending_deopts_)[i].fp(), (*pending_deopts_)[i].pc());
            break;
        }
      }
      pending_deopts_->RemoveAt(i);
    }
  }
}

void PendingDeopts::ClearPendingDeoptsAtOrBelow(uword fp, ClearReason reason) {
  ClearPendingDeoptsBelow(fp + kWordSize, reason);
}

uword PendingDeopts::RemapExceptionPCForDeopt(uword program_counter,
                                              uword frame_pointer,
                                              bool* clear_deopt) {
  *clear_deopt = false;
  // Do not attempt to deopt at async exception handler as it doesn't
  // belong to the function code. Async handler never continues execution
  // in the same frame - it either rethrows exception to the caller or
  // tail calls Dart handler, leaving the function frame before the call.
  if (program_counter == StubCode::AsyncExceptionHandler().EntryPoint()) {
    *clear_deopt = true;
    return program_counter;
  }
  // Check if the target frame is scheduled for lazy deopt.
  for (intptr_t i = 0; i < pending_deopts_->length(); i++) {
    if ((*pending_deopts_)[i].fp() == frame_pointer) {
      // Deopt should now resume in the catch handler instead of after the
      // call.
      (*pending_deopts_)[i].set_pc(program_counter);

      // Jump to the deopt stub instead of the catch handler.
      program_counter = StubCode::DeoptimizeLazyFromThrow().EntryPoint();
      if (FLAG_trace_deoptimization) {
        THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n",
                  frame_pointer);

#if defined(DEBUG)
        // Ensure the frame references optimized code.
        ObjectPtr pc_marker = *(reinterpret_cast<ObjectPtr*>(
            frame_pointer + runtime_frame_layout.code_from_fp * kWordSize));
        Code& code = Code::Handle(Code::RawCast(pc_marker));
        ASSERT(code.is_optimized() && !code.is_force_optimized());
#endif
      }
      break;
    }
  }
  return program_counter;
}

}  // namespace dart
