/*
 * Copyright (C) 2011 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.
 */

#ifndef ART_SRC_STACK_H_
#define ART_SRC_STACK_H_

#include "dex_file.h"
#include "heap.h"
#include "jni.h"
#include "macros.h"
#include "oat/runtime/context.h"
#include "trace.h"

#include <stdint.h>

namespace art {

class Method;
class Object;
class ShadowFrame;
class ScopedJniThreadState;
class Thread;

jobject GetThreadStack(const ScopedJniThreadState&, Thread*);

class ShadowFrame {
 public:
  // Number of references contained within this shadow frame
  uint32_t NumberOfReferences() const {
    return number_of_references_;
  }

  void SetNumberOfReferences(uint32_t number_of_references) {
    number_of_references_ = number_of_references;
  }

  // Caller dex pc
  uint32_t GetDexPC() const {
    return dex_pc_;
  }

  void SetDexPC(uint32_t dex_pc) {
    dex_pc_ = dex_pc;
  }

  // Link to previous shadow frame or NULL
  ShadowFrame* GetLink() const {
    return link_;
  }

  void SetLink(ShadowFrame* frame) {
    DCHECK_NE(this, frame);
    link_ = frame;
  }

  Object* GetReference(size_t i) const {
    DCHECK_LT(i, number_of_references_);
    return references_[i];
  }

  void SetReference(size_t i, Object* object) {
    DCHECK_LT(i, number_of_references_);
    references_[i] = object;
  }

  Method* GetMethod() const {
    DCHECK_NE(method_, static_cast<void*>(NULL));
    return method_;
  }

  void SetMethod(Method* method) {
    DCHECK_NE(method, static_cast<void*>(NULL));
    method_ = method;
  }

  bool Contains(Object** shadow_frame_entry) const {
    return ((&references_[0] <= shadow_frame_entry) &&
            (shadow_frame_entry <= (&references_[number_of_references_ - 1])));
  }

  void VisitRoots(Heap::RootVisitor* visitor, void* arg) {
    size_t num_refs = NumberOfReferences();
    for (size_t j = 0; j < num_refs; j++) {
      Object* object = GetReference(j);
      if (object != NULL) {
        visitor(object, arg);
      }
    }
  }

  // Offset of link within shadow frame
  static size_t LinkOffset() {
    return OFFSETOF_MEMBER(ShadowFrame, link_);
  }

  // Offset of method within shadow frame
  static size_t MethodOffset() {
    return OFFSETOF_MEMBER(ShadowFrame, method_);
  }

  // Offset of dex pc within shadow frame
  static size_t DexPCOffset() {
    return OFFSETOF_MEMBER(ShadowFrame, dex_pc_);
  }

  // Offset of length within shadow frame
  static size_t NumberOfReferencesOffset() {
    return OFFSETOF_MEMBER(ShadowFrame, number_of_references_);
  }

  // Offset of references within shadow frame
  static size_t ReferencesOffset() {
    return OFFSETOF_MEMBER(ShadowFrame, references_);
  }

 private:
  // ShadowFrame should be allocated by the generated code directly.
  // We should not create new shadow stack in the runtime support function.
  ~ShadowFrame() {}

  uint32_t number_of_references_;
  ShadowFrame* link_;
  Method* method_;
  uint32_t dex_pc_;
  Object* references_[];

  DISALLOW_IMPLICIT_CONSTRUCTORS(ShadowFrame);
};

// The managed stack is used to record fragments of managed code stacks. Managed code stacks
// may either be shadow frames or lists of frames using fixed frame sizes. Transition records are
// necessary for transitions between code using different frame layouts and transitions into native
// code.
class PACKED ManagedStack {
 public:
  ManagedStack() : link_(NULL), top_shadow_frame_(NULL),
                   top_quick_frame_(NULL), top_quick_frame_pc_(0) {}
  void PushManagedStackFragment(ManagedStack* fragment);
  void PopManagedStackFragment(const ManagedStack& record);

  ManagedStack* GetLink() const {
    return link_;
  }

  Method** GetTopQuickFrame() const {
    return top_quick_frame_;
  }

  void SetTopQuickFrame(Method** top) {
    top_quick_frame_ = top;
  }

  uintptr_t GetTopQuickFramePc() const {
    return top_quick_frame_pc_;
  }

  void SetTopQuickFramePc(uintptr_t pc) {
    top_quick_frame_pc_ = pc;
  }

  static size_t TopQuickFrameOffset() {
    return OFFSETOF_MEMBER(ManagedStack, top_quick_frame_);
  }

  static size_t TopQuickFramePcOffset() {
    return OFFSETOF_MEMBER(ManagedStack, top_quick_frame_pc_);
  }

  ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame) {
    ShadowFrame* old_frame = top_shadow_frame_;
    top_shadow_frame_ = new_top_frame;
    new_top_frame->SetLink(old_frame);
    return old_frame;
  }

  ShadowFrame* PopShadowFrame() {
    CHECK(top_shadow_frame_ != NULL);
    ShadowFrame* frame = top_shadow_frame_;
    top_shadow_frame_ = frame->GetLink();
    return frame;
  }

  ShadowFrame* GetTopShadowFrame() const {
    return top_shadow_frame_;
  }

  static size_t TopShadowFrameOffset() {
    return OFFSETOF_MEMBER(ManagedStack, top_shadow_frame_);
  }

  size_t NumShadowFrameReferences() const;

  bool ShadowFramesContain(Object** shadow_frame_entry) const;

 private:
  ManagedStack* link_;
  ShadowFrame* top_shadow_frame_;
  Method** top_quick_frame_;
  uintptr_t top_quick_frame_pc_;
};

class StackVisitor {
 protected:
  StackVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack,
               Context* context = NULL) :
    stack_start_(stack), trace_stack_(trace_stack), cur_shadow_frame_(NULL), cur_quick_frame_(NULL),
    cur_quick_frame_pc_(0), num_frames_(0), cur_depth_(0), context_(context) {}

 public:
  virtual ~StackVisitor() {}

  // Return 'true' if we should continue to visit more frames, 'false' to stop.
  virtual bool VisitFrame() = 0;

  void WalkStack(bool include_transitions = false);

  Method* GetMethod() const {
    if (cur_shadow_frame_ != NULL) {
      return cur_shadow_frame_->GetMethod();
    } else if (cur_quick_frame_ != NULL) {
      return *cur_quick_frame_;
    } else {
      return NULL;
    }
  }

  bool IsShadowFrame() const {
    return cur_shadow_frame_ != NULL;
  }

  uintptr_t LoadCalleeSave(int num, size_t frame_size) const {
    // Callee saves are held at the top of the frame
    Method* method = GetMethod();
    DCHECK(method != NULL);
    byte* save_addr =
        reinterpret_cast<byte*>(cur_quick_frame_) + frame_size - ((num + 1) * kPointerSize);
#if defined(__i386__)
    save_addr -= kPointerSize;  // account for return address
#endif
    return *reinterpret_cast<uintptr_t*>(save_addr);
  }

  uint32_t GetDexPc() const;

  // Gets the height of the stack in the managed stack frames, including transitions.
  size_t GetFrameHeight() {
    return GetNumFrames() - cur_depth_;
  }

  // Get a frame ID where 0 is a special value.
  size_t GetFrameId() {
    return GetFrameHeight() + 1;
  }

  size_t GetNumFrames() {
    if (num_frames_ == 0) {
      num_frames_ = ComputeNumFrames();
    }
    return num_frames_;
  }

  uint32_t GetVReg(Method* m, int vreg) const;

  void SetVReg(Method* m, int vreg, uint32_t new_value);

  uintptr_t GetGPR(uint32_t reg) const;

  uint32_t GetVReg(const DexFile::CodeItem* code_item, uint32_t core_spills,
                   uint32_t fp_spills, size_t frame_size, int vreg) const {
    int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg);
    byte* vreg_addr = reinterpret_cast<byte*>(GetCurrentQuickFrame()) + offset;
    return *reinterpret_cast<uint32_t*>(vreg_addr);
  }

  uintptr_t GetReturnPc() const;

  void SetReturnPc(uintptr_t new_ret_pc);

  /*
   * Return sp-relative offset for a Dalvik virtual register, compiler
   * spill or Method* in bytes using Method*.
   * Note that (reg >= 0) refers to a Dalvik register, (reg == -2)
   * denotes Method* and (reg <= -3) denotes a compiler temp.
   *
   *     +------------------------+
   *     | IN[ins-1]              |  {Note: resides in caller's frame}
   *     |       .                |
   *     | IN[0]                  |
   *     | caller's Method*       |
   *     +========================+  {Note: start of callee's frame}
   *     | core callee-save spill |  {variable sized}
   *     +------------------------+
   *     | fp callee-save spill   |
   *     +------------------------+
   *     | filler word            |  {For compatibility, if V[locals-1] used as wide
   *     +------------------------+
   *     | V[locals-1]            |
   *     | V[locals-2]            |
   *     |      .                 |
   *     |      .                 |  ... (reg == 2)
   *     | V[1]                   |  ... (reg == 1)
   *     | V[0]                   |  ... (reg == 0) <---- "locals_start"
   *     +------------------------+
   *     | Compiler temps         |  ... (reg == -2)
   *     |                        |  ... (reg == -3)
   *     |                        |  ... (reg == -4)
   *     +------------------------+
   *     | stack alignment padding|  {0 to (kStackAlignWords-1) of padding}
   *     +------------------------+
   *     | OUT[outs-1]            |
   *     | OUT[outs-2]            |
   *     |       .                |
   *     | OUT[0]                 |
   *     | curMethod*             |  ... (reg == -1) <<== sp, 16-byte aligned
   *     +========================+
   */
  static int GetVRegOffset(const DexFile::CodeItem* code_item,
                    uint32_t core_spills, uint32_t fp_spills,
                    size_t frame_size, int reg) {
    DCHECK_EQ(frame_size & (kStackAlignment - 1), 0U);
    int num_spills = __builtin_popcount(core_spills) + __builtin_popcount(fp_spills) + 1; // Filler.
    int num_ins = code_item->ins_size_;
    int num_regs = code_item->registers_size_ - num_ins;
    int locals_start = frame_size - ((num_spills + num_regs) * sizeof(uint32_t));
    if (reg == -2) {
      return 0;  // Method*
    } else if (reg <= -3) {
      return locals_start - ((reg + 1) * sizeof(uint32_t));  // Compiler temp.
    } else if (reg < num_regs) {
      return locals_start + (reg * sizeof(uint32_t));        // Dalvik local reg.
    } else {
      return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + sizeof(uint32_t); // Dalvik in.
    }
  }

  uintptr_t GetCurrentQuickFramePc() const {
    return cur_quick_frame_pc_;
  }

  Method** GetCurrentQuickFrame() const {
    return cur_quick_frame_;
  }

  ShadowFrame* GetCurrentShadowFrame() const {
    return cur_shadow_frame_;
  }

 private:
  size_t ComputeNumFrames() const;

  TraceStackFrame GetTraceStackFrame(uint32_t depth) const {
    return trace_stack_->at(trace_stack_->size() - depth - 1);
  }

  void SanityCheckFrame();

  const ManagedStack* const stack_start_;
  const std::vector<TraceStackFrame>* const trace_stack_;
  ShadowFrame* cur_shadow_frame_;
  Method** cur_quick_frame_;
  uintptr_t cur_quick_frame_pc_;
  // Lazily computed, number of frames in the stack.
  size_t num_frames_;
  // Depth of the frame we're currently at.
  size_t cur_depth_;
 protected:
  Context* const context_;
};

static inline uintptr_t AdjustQuickFramePcForDexPcComputation(uintptr_t pc) {
  // Quick methods record a mapping from quick PCs to Dex PCs at the beginning of the code for
  // each dex instruction. When walking the stack, the return PC will be set to the instruction
  // following call which will likely be the start of the next dex instruction. Adjust the PC
  // for these cases by 2 bytes in case the return PC also has the thumb bit set.
  if (pc > 0) { pc -= 2; }
  return pc;
}

}  // namespace art

#endif  // ART_SRC_STACK_H_
