/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "base/logging.h"  // For VLOG_IS_ON.
#include "base/mutex.h"
#include "callee_save_frame.h"
#include "interpreter/interpreter.h"
#include "obj_ptr-inl.h"  // TODO: Find the other include that isn't complete, and clean this up.
#include "quick_exception_handler.h"
#include "runtime.h"
#include "thread.h"

namespace art {

NO_RETURN static void artDeoptimizeImpl(Thread* self, DeoptimizationKind kind, bool single_frame)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  Runtime::Current()->IncrementDeoptimizationCount(kind);
  if (VLOG_IS_ON(deopt)) {
    if (single_frame) {
      // Deopt logging will be in DeoptimizeSingleFrame. It is there to take advantage of the
      // specialized visitor that will show whether a method is Quick or Shadow.
    } else {
      LOG(INFO) << "Deopting:";
      self->Dump(LOG_STREAM(INFO));
    }
  }

  self->AssertHasDeoptimizationContext();
  QuickExceptionHandler exception_handler(self, true);
  if (single_frame) {
    exception_handler.DeoptimizeSingleFrame(kind);
  } else {
    exception_handler.DeoptimizeStack();
  }
  uintptr_t return_pc = exception_handler.UpdateInstrumentationStack();
  if (exception_handler.IsFullFragmentDone()) {
    exception_handler.DoLongJump(true);
  } else {
    exception_handler.DeoptimizePartialFragmentFixup(return_pc);
    // We cannot smash the caller-saves, as we need the ArtMethod in a parameter register that would
    // be caller-saved. This has the downside that we cannot track incorrect register usage down the
    // line.
    exception_handler.DoLongJump(false);
  }
}

extern "C" NO_RETURN void artDeoptimize(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) {
  ScopedQuickEntrypointChecks sqec(self);
  artDeoptimizeImpl(self, DeoptimizationKind::kFullFrame, false);
}

// This is called directly from compiled code by an HDeoptimize.
extern "C" NO_RETURN void artDeoptimizeFromCompiledCode(DeoptimizationKind kind, Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  ScopedQuickEntrypointChecks sqec(self);
  // Before deoptimizing to interpreter, we must push the deoptimization context.
  JValue return_value;
  return_value.SetJ(0);  // we never deoptimize from compiled code with an invoke result.
  self->PushDeoptimizationContext(return_value,
                                  /* is_reference= */ false,
                                  self->GetException(),
                                  /* from_code= */ true,
                                  DeoptimizationMethodType::kDefault);
  artDeoptimizeImpl(self, kind, true);
}

}  // namespace art
