/*
 * 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_RUNTIME_OAT_QUICK_METHOD_HEADER_H_
#define ART_RUNTIME_OAT_QUICK_METHOD_HEADER_H_

#include "arch/instruction_set.h"
#include "base/locks.h"
#include "base/macros.h"
#include "base/utils.h"
#include "quick/quick_method_frame_info.h"
#include "stack_map.h"

namespace art {

class ArtMethod;

// Size in bytes of the should_deoptimize flag on stack.
// We just need 4 bytes for our purpose regardless of the architecture. Frame size
// calculation will automatically do alignment for the final frame size.
static constexpr size_t kShouldDeoptimizeFlagSize = 4;

// OatQuickMethodHeader precedes the raw code chunk generated by the compiler.
class PACKED(4) OatQuickMethodHeader {
 public:
  OatQuickMethodHeader(uint32_t code_info_offset = 0) {
    SetCodeInfoOffset(code_info_offset);
  }

  static OatQuickMethodHeader* NterpMethodHeader;

  bool IsNterpMethodHeader() const;

  static bool IsNterpPc(uintptr_t pc) {
    return OatQuickMethodHeader::NterpMethodHeader != nullptr &&
        OatQuickMethodHeader::NterpMethodHeader->Contains(pc);
  }

  static OatQuickMethodHeader* FromCodePointer(const void* code_ptr) {
    uintptr_t code = reinterpret_cast<uintptr_t>(code_ptr);
    uintptr_t header = code - OFFSETOF_MEMBER(OatQuickMethodHeader, code_);
    DCHECK(IsAlignedParam(code, GetInstructionSetAlignment(kRuntimeISA)) ||
           IsAlignedParam(header, GetInstructionSetAlignment(kRuntimeISA)))
        << std::hex << code << " " << std::hex << header;
    return reinterpret_cast<OatQuickMethodHeader*>(header);
  }

  static OatQuickMethodHeader* FromEntryPoint(const void* entry_point) {
    return FromCodePointer(EntryPointToCodePointer(entry_point));
  }

  static size_t InstructionAlignedSize() {
    return RoundUp(sizeof(OatQuickMethodHeader), GetInstructionSetAlignment(kRuntimeISA));
  }

  OatQuickMethodHeader(const OatQuickMethodHeader&) = default;
  OatQuickMethodHeader& operator=(const OatQuickMethodHeader&) = default;

  uintptr_t NativeQuickPcOffset(const uintptr_t pc) const {
    return pc - reinterpret_cast<uintptr_t>(GetEntryPoint());
  }

  ALWAYS_INLINE bool IsOptimized() const {
    uintptr_t code = reinterpret_cast<uintptr_t>(code_);
    DCHECK_NE(data_, 0u) << std::hex << code;          // Probably a padding of native code.
    DCHECK_NE(data_, kInvalidData) << std::hex << code;  // Probably a stub or trampoline.
    return (data_ & kIsCodeInfoMask) != 0;
  }

  ALWAYS_INLINE const uint8_t* GetOptimizedCodeInfoPtr() const {
    uint32_t offset = GetCodeInfoOffset();
    DCHECK_NE(offset, 0u);
    return code_ - offset;
  }

  ALWAYS_INLINE uint8_t* GetOptimizedCodeInfoPtr() {
    uint32_t offset = GetCodeInfoOffset();
    DCHECK_NE(offset, 0u);
    return code_ - offset;
  }

  ALWAYS_INLINE const uint8_t* GetCode() const {
    return code_;
  }

  ALWAYS_INLINE uint32_t GetCodeSize() const {
    return LIKELY(IsOptimized())
        ? CodeInfo::DecodeCodeSize(GetOptimizedCodeInfoPtr())
        : (data_ & kCodeSizeMask);
  }

  ALWAYS_INLINE uint32_t GetCodeInfoOffset() const {
    DCHECK(IsOptimized());
    return data_ & kCodeInfoMask;
  }

  void SetCodeInfoOffset(uint32_t offset) {
    data_ = kIsCodeInfoMask | offset;
    DCHECK_EQ(GetCodeInfoOffset(), offset);
  }

  bool Contains(uintptr_t pc) const {
    // We should not call `Contains` on a stub or trampoline.
    DCHECK_NE(data_, kInvalidData) << std::hex << reinterpret_cast<uintptr_t>(code_);
    // Remove hwasan tag to make comparison below valid. The PC from the stack does not have it.
    uintptr_t code_start = reinterpret_cast<uintptr_t>(HWASanUntag(code_));
    static_assert(kRuntimeISA != InstructionSet::kThumb2, "kThumb2 cannot be a runtime ISA");
    if (kRuntimeISA == InstructionSet::kArm) {
      // On Thumb-2, the pc is offset by one.
      code_start++;
    }
    return code_start <= pc && pc <= (code_start + GetCodeSize());
  }

  const uint8_t* GetEntryPoint() const {
    // When the runtime architecture is ARM, `kRuntimeISA` is set to `kArm`
    // (not `kThumb2`), *but* we always generate code for the Thumb-2
    // instruction set anyway. Thumb-2 requires the entrypoint to be of
    // offset 1.
    static_assert(kRuntimeISA != InstructionSet::kThumb2, "kThumb2 cannot be a runtime ISA");
    return (kRuntimeISA == InstructionSet::kArm)
        ? reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(code_) | 1)
        : code_;
  }

  template <bool kCheckFrameSize = true>
  uint32_t GetFrameSizeInBytes() const {
    uint32_t result = GetFrameInfo().FrameSizeInBytes();
    if (kCheckFrameSize) {
      DCHECK_ALIGNED(result, kStackAlignment);
    }
    return result;
  }

  QuickMethodFrameInfo GetFrameInfo() const {
    DCHECK(IsOptimized());
    return CodeInfo::DecodeFrameInfo(GetOptimizedCodeInfoPtr());
  }

  size_t GetShouldDeoptimizeFlagOffset() const {
    DCHECK(IsOptimized());
    QuickMethodFrameInfo frame_info = GetFrameInfo();
    size_t frame_size = frame_info.FrameSizeInBytes();
    size_t core_spill_size =
        POPCOUNT(frame_info.CoreSpillMask()) * GetBytesPerGprSpillLocation(kRuntimeISA);
    size_t fpu_spill_size =
        POPCOUNT(frame_info.FpSpillMask()) * GetBytesPerFprSpillLocation(kRuntimeISA);
    return frame_size - core_spill_size - fpu_spill_size - kShouldDeoptimizeFlagSize;
  }

  uintptr_t ToNativeQuickPc(ArtMethod* method,
                            const uint32_t dex_pc,
                            bool is_for_catch_handler,
                            bool abort_on_failure = true) const;

  uint32_t ToDexPc(ArtMethod** frame,
                   const uintptr_t pc,
                   bool abort_on_failure = true) const
      REQUIRES_SHARED(Locks::mutator_lock_);

  void SetHasShouldDeoptimizeFlag() {
    DCHECK(!HasShouldDeoptimizeFlag());
    data_ |= kShouldDeoptimizeMask;
  }

  bool HasShouldDeoptimizeFlag() const {
    return (data_ & kShouldDeoptimizeMask) != 0;
  }

 private:
  static constexpr uint32_t kShouldDeoptimizeMask = 0x80000000;
  static constexpr uint32_t kIsCodeInfoMask       = 0x40000000;
  static constexpr uint32_t kCodeInfoMask         = 0x3FFFFFFF;  // If kIsCodeInfoMask is set.
  static constexpr uint32_t kCodeSizeMask         = 0x3FFFFFFF;  // If kIsCodeInfoMask is clear.

  // In order to not confuse a stub with Java-generated code, we prefix each
  // stub with a 0xFFFFFFFF marker.
  static constexpr uint32_t kInvalidData = 0xFFFFFFFF;

  uint32_t data_ = 0u;  // Combination of fields using the above masks.
  uint8_t code_[0];     // The actual method code.
};

}  // namespace art

#endif  // ART_RUNTIME_OAT_QUICK_METHOD_HEADER_H_
