/*
 * 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_COMPILER_JNI_QUICK_CALLING_CONVENTION_H_
#define ART_COMPILER_JNI_QUICK_CALLING_CONVENTION_H_

#include "base/arena_object.h"
#include "base/array_ref.h"
#include "base/enums.h"
#include "dex/primitive.h"
#include "handle_scope.h"
#include "thread.h"
#include "utils/managed_register.h"

namespace art {

enum class InstructionSet;

// Top-level abstraction for different calling conventions.
class CallingConvention : public DeletableArenaObject<kArenaAllocCallingConvention> {
 public:
  bool IsReturnAReference() const { return shorty_[0] == 'L'; }

  Primitive::Type GetReturnType() const {
    return Primitive::GetType(shorty_[0]);
  }

  size_t SizeOfReturnValue() const {
    size_t result = Primitive::ComponentSize(Primitive::GetType(shorty_[0]));
    if (result >= 1 && result < 4) {
      result = 4;
    }
    return result;
  }

  // Register that holds result of this method invocation.
  virtual ManagedRegister ReturnRegister() = 0;

  // Iterator interface

  // Place iterator at start of arguments. The displacement is applied to
  // frame offset methods to account for frames which may be on the stack
  // below the one being iterated over.
  virtual void ResetIterator(FrameOffset displacement) {
    displacement_ = displacement;
    itr_slots_ = 0;
    itr_args_ = 0;
    itr_refs_ = 0;
    itr_longs_and_doubles_ = 0;
    itr_float_and_doubles_ = 0;
  }

  FrameOffset GetDisplacement() const {
    return displacement_;
  }

  PointerSize GetFramePointerSize() const {
    return frame_pointer_size_;
  }

  virtual ~CallingConvention() {}

 protected:
  CallingConvention(bool is_static,
                    bool is_synchronized,
                    const char* shorty,
                    PointerSize frame_pointer_size)
      : itr_slots_(0), itr_refs_(0), itr_args_(0), itr_longs_and_doubles_(0),
        itr_float_and_doubles_(0), displacement_(0),
        frame_pointer_size_(frame_pointer_size),
        handle_scope_pointer_size_(sizeof(StackReference<mirror::Object>)),
        is_static_(is_static), is_synchronized_(is_synchronized),
        shorty_(shorty) {
    num_args_ = (is_static ? 0 : 1) + strlen(shorty) - 1;
    num_ref_args_ = is_static ? 0 : 1;  // The implicit this pointer.
    num_float_or_double_args_ = 0;
    num_long_or_double_args_ = 0;
    for (size_t i = 1; i < strlen(shorty); i++) {
      char ch = shorty_[i];
      switch (ch) {
      case 'L':
        num_ref_args_++;
        break;
      case 'J':
        num_long_or_double_args_++;
        break;
      case 'D':
        num_long_or_double_args_++;
        num_float_or_double_args_++;
        break;
      case 'F':
        num_float_or_double_args_++;
        break;
      }
    }
  }

  bool IsStatic() const {
    return is_static_;
  }
  bool IsSynchronized() const {
    return is_synchronized_;
  }
  bool IsParamALongOrDouble(unsigned int param) const {
    DCHECK_LT(param, NumArgs());
    if (IsStatic()) {
      param++;  // 0th argument must skip return value at start of the shorty
    } else if (param == 0) {
      return false;  // this argument
    }
    char ch = shorty_[param];
    return (ch == 'J' || ch == 'D');
  }
  bool IsParamAFloatOrDouble(unsigned int param) const {
    DCHECK_LT(param, NumArgs());
    if (IsStatic()) {
      param++;  // 0th argument must skip return value at start of the shorty
    } else if (param == 0) {
      return false;  // this argument
    }
    char ch = shorty_[param];
    return (ch == 'F' || ch == 'D');
  }
  bool IsParamADouble(unsigned int param) const {
    DCHECK_LT(param, NumArgs());
    if (IsStatic()) {
      param++;  // 0th argument must skip return value at start of the shorty
    } else if (param == 0) {
      return false;  // this argument
    }
    return shorty_[param] == 'D';
  }
  bool IsParamALong(unsigned int param) const {
    DCHECK_LT(param, NumArgs());
    if (IsStatic()) {
      param++;  // 0th argument must skip return value at start of the shorty
    } else if (param == 0) {
      return false;  // this argument
    }
    return shorty_[param] == 'J';
  }
  bool IsParamAReference(unsigned int param) const {
    DCHECK_LT(param, NumArgs());
    if (IsStatic()) {
      param++;  // 0th argument must skip return value at start of the shorty
    } else if (param == 0) {
      return true;  // this argument
    }
    return shorty_[param] == 'L';
  }
  size_t NumArgs() const {
    return num_args_;
  }
  // Implicit argument count: 1 for instance functions, 0 for static functions.
  // (The implicit argument is only relevant to the shorty, i.e.
  // the 0th arg is not in the shorty if it's implicit).
  size_t NumImplicitArgs() const {
    return IsStatic() ? 0 : 1;
  }
  size_t NumLongOrDoubleArgs() const {
    return num_long_or_double_args_;
  }
  size_t NumFloatOrDoubleArgs() const {
    return num_float_or_double_args_;
  }
  size_t NumReferenceArgs() const {
    return num_ref_args_;
  }
  size_t ParamSize(unsigned int param) const {
    DCHECK_LT(param, NumArgs());
    if (IsStatic()) {
      param++;  // 0th argument must skip return value at start of the shorty
    } else if (param == 0) {
      return sizeof(mirror::HeapReference<mirror::Object>);  // this argument
    }
    size_t result = Primitive::ComponentSize(Primitive::GetType(shorty_[param]));
    if (result >= 1 && result < 4) {
      result = 4;
    }
    return result;
  }
  const char* GetShorty() const {
    return shorty_.c_str();
  }
  // The slot number for current calling_convention argument.
  // Note that each slot is 32-bit. When the current argument is bigger
  // than 32 bits, return the first slot number for this argument.
  unsigned int itr_slots_;
  // The number of references iterated past.
  unsigned int itr_refs_;
  // The argument number along argument list for current argument.
  unsigned int itr_args_;
  // Number of longs and doubles seen along argument list.
  unsigned int itr_longs_and_doubles_;
  // Number of float and doubles seen along argument list.
  unsigned int itr_float_and_doubles_;
  // Space for frames below this on the stack.
  FrameOffset displacement_;
  // The size of a pointer.
  const PointerSize frame_pointer_size_;
  // The size of a reference entry within the handle scope.
  const size_t handle_scope_pointer_size_;

 private:
  const bool is_static_;
  const bool is_synchronized_;
  std::string shorty_;
  size_t num_args_;
  size_t num_ref_args_;
  size_t num_float_or_double_args_;
  size_t num_long_or_double_args_;
};

// Abstraction for managed code's calling conventions
// | { Incoming stack args } |
// | { Prior Method* }       | <-- Prior SP
// | { Return address }      |
// | { Callee saves }        |
// | { Spills ... }          |
// | { Outgoing stack args } |
// | { Method* }             | <-- SP
class ManagedRuntimeCallingConvention : public CallingConvention {
 public:
  static std::unique_ptr<ManagedRuntimeCallingConvention> Create(ArenaAllocator* allocator,
                                                                 bool is_static,
                                                                 bool is_synchronized,
                                                                 const char* shorty,
                                                                 InstructionSet instruction_set);

  // Offset of Method within the managed frame.
  FrameOffset MethodStackOffset() {
    return FrameOffset(0u);
  }

  // Register that holds the incoming method argument
  virtual ManagedRegister MethodRegister() = 0;

  // Iterator interface
  bool HasNext();
  virtual void Next();
  bool IsCurrentParamAReference();
  bool IsCurrentParamAFloatOrDouble();
  bool IsCurrentParamADouble();
  bool IsCurrentParamALong();
  bool IsCurrentParamALongOrDouble() {
    return IsCurrentParamALong() || IsCurrentParamADouble();
  }
  bool IsCurrentArgExplicit();  // ie a non-implict argument such as this
  bool IsCurrentArgPossiblyNull();
  size_t CurrentParamSize();
  virtual bool IsCurrentParamInRegister() = 0;
  virtual bool IsCurrentParamOnStack() = 0;
  virtual ManagedRegister CurrentParamRegister() = 0;
  virtual FrameOffset CurrentParamStackOffset() = 0;

  virtual ~ManagedRuntimeCallingConvention() {}

 protected:
  ManagedRuntimeCallingConvention(bool is_static,
                                  bool is_synchronized,
                                  const char* shorty,
                                  PointerSize frame_pointer_size)
      : CallingConvention(is_static, is_synchronized, shorty, frame_pointer_size) {}
};

// Abstraction for JNI calling conventions
// | { Incoming stack args }         | <-- Prior SP
// | { Return address }              |
// | { Callee saves }                |     ([1])
// | { Return value spill }          |     (live on return slow paths)
// | { Local Ref. Table State }      |
// | { Stack Indirect Ref. Table     |
// |   num. refs./link }             |     (here to prior SP is frame size)
// | { Method* }                     | <-- Anchor SP written to thread
// | { Outgoing stack args }         | <-- SP at point of call
// | Native frame                    |
//
// [1] We must save all callee saves here to enable any exception throws to restore
// callee saves for frames above this one.
class JniCallingConvention : public CallingConvention {
 public:
  static std::unique_ptr<JniCallingConvention> Create(ArenaAllocator* allocator,
                                                      bool is_static,
                                                      bool is_synchronized,
                                                      bool is_critical_native,
                                                      const char* shorty,
                                                      InstructionSet instruction_set);

  // Size of frame excluding space for outgoing args (its assumed Method* is
  // always at the bottom of a frame, but this doesn't work for outgoing
  // native args). Includes alignment.
  virtual size_t FrameSize() const = 0;
  // Size of outgoing frame, i.e. stack arguments, @CriticalNative return PC if needed, alignment.
  // -- Arguments that are passed via registers are excluded from this size.
  virtual size_t OutFrameSize() const = 0;
  // Number of references in stack indirect reference table
  size_t ReferenceCount() const;
  // Location where the segment state of the local indirect reference table is saved
  FrameOffset SavedLocalReferenceCookieOffset() const;
  // Location where the return value of a call can be squirreled if another
  // call is made following the native call
  FrameOffset ReturnValueSaveLocation() const;
  // Register that holds result if it is integer.
  virtual ManagedRegister IntReturnRegister() = 0;
  // Whether the compiler needs to ensure zero-/sign-extension of a small result type
  virtual bool RequiresSmallResultTypeExtension() const = 0;

  // Callee save registers to spill prior to native code (which may clobber)
  virtual ArrayRef<const ManagedRegister> CalleeSaveRegisters() const = 0;

  // Spill mask values
  virtual uint32_t CoreSpillMask() const = 0;
  virtual uint32_t FpSpillMask() const = 0;

  // An extra scratch register live after the call
  virtual ManagedRegister ReturnScratchRegister() const = 0;

  // Iterator interface
  bool HasNext();
  virtual void Next();
  bool IsCurrentParamAReference();
  bool IsCurrentParamAFloatOrDouble();
  bool IsCurrentParamADouble();
  bool IsCurrentParamALong();
  bool IsCurrentParamALongOrDouble() {
    return IsCurrentParamALong() || IsCurrentParamADouble();
  }
  bool IsCurrentParamJniEnv();
  size_t CurrentParamSize() const;
  virtual bool IsCurrentParamInRegister() = 0;
  virtual bool IsCurrentParamOnStack() = 0;
  virtual ManagedRegister CurrentParamRegister() = 0;
  virtual FrameOffset CurrentParamStackOffset() = 0;

  // Iterator interface extension for JNI
  FrameOffset CurrentParamHandleScopeEntryOffset();

  // Position of handle scope and interior fields
  FrameOffset HandleScopeOffset() const {
    return FrameOffset(this->displacement_.Int32Value() + static_cast<size_t>(frame_pointer_size_));
    // above Method reference
  }

  FrameOffset HandleScopeLinkOffset() const {
    return FrameOffset(HandleScopeOffset().Int32Value() +
                       HandleScope::LinkOffset(frame_pointer_size_));
  }

  FrameOffset HandleScopeNumRefsOffset() const {
    return FrameOffset(HandleScopeOffset().Int32Value() +
                       HandleScope::NumberOfReferencesOffset(frame_pointer_size_));
  }

  FrameOffset HandleReferencesOffset() const {
    return FrameOffset(HandleScopeOffset().Int32Value() +
                       HandleScope::ReferencesOffset(frame_pointer_size_));
  }

  virtual ~JniCallingConvention() {}

  bool IsCriticalNative() const {
    return is_critical_native_;
  }

  // Does the transition have a method pointer in the stack frame?
  bool SpillsMethod() const {
    // Exclude method pointer for @CriticalNative methods for optimization speed.
    return !IsCriticalNative();
  }

  // Hidden argument register, used to pass the method pointer for @CriticalNative call.
  virtual ManagedRegister HiddenArgumentRegister() const = 0;

  // Whether to use tail call (used only for @CriticalNative).
  virtual bool UseTailCall() const = 0;

  // Whether the return type is small. Used for RequiresSmallResultTypeExtension()
  // on architectures that require the sign/zero extension.
  bool HasSmallReturnType() const {
    Primitive::Type return_type = GetReturnType();
    return return_type == Primitive::kPrimByte ||
           return_type == Primitive::kPrimShort ||
           return_type == Primitive::kPrimBoolean ||
           return_type == Primitive::kPrimChar;
  }

 protected:
  // Named iterator positions
  enum IteratorPos {
    kJniEnv = 0,
    kObjectOrClass = 1
  };

  JniCallingConvention(bool is_static,
                       bool is_synchronized,
                       bool is_critical_native,
                       const char* shorty,
                       PointerSize frame_pointer_size)
      : CallingConvention(is_static, is_synchronized, shorty, frame_pointer_size),
        is_critical_native_(is_critical_native) {}

 protected:
  size_t NumberOfExtraArgumentsForJni() const;

  // Does the transition have a StackHandleScope?
  bool HasHandleScope() const {
    // Exclude HandleScope for @CriticalNative methods for optimization speed.
    return !IsCriticalNative();
  }

  // Does the transition have a local reference segment state?
  bool HasLocalReferenceSegmentState() const {
    // Exclude local reference segment states for @CriticalNative methods for optimization speed.
    return !IsCriticalNative();
  }

  // Does the transition back spill the return value in the stack frame?
  bool SpillsReturnValue() const {
    // Exclude return value for @CriticalNative methods for optimization speed.
    return !IsCriticalNative();
  }

  // Are there extra JNI arguments (JNIEnv* and maybe jclass)?
  bool HasExtraArgumentsForJni() const {
    // @CriticalNative jni implementations exclude both JNIEnv* and the jclass/jobject parameters.
    return !IsCriticalNative();
  }

  // Has a JNIEnv* parameter implicitly?
  bool HasJniEnv() const {
    // Exclude "JNIEnv*" parameter for @CriticalNative methods.
    return HasExtraArgumentsForJni();
  }

  // Has a 'jclass' parameter implicitly?
  bool HasSelfClass() const;

  // Returns the position of itr_args_, fixed up by removing the offset of extra JNI arguments.
  unsigned int GetIteratorPositionWithinShorty() const;

  // Is the current argument (at the iterator) an extra argument for JNI?
  bool IsCurrentArgExtraForJni() const;

  const bool is_critical_native_;

 private:
  // Shorthand for switching on the switch value but only IF there are extra JNI arguments.
  //
  // Puts the case value into return_value.
  // * (switch_value == kJniEnv) => case_jni_env
  // * (switch_value == kObjectOrClass) => case_object_or_class
  //
  // Returns false otherwise (or if there are no extra JNI arguments).
  bool SwitchExtraJniArguments(size_t switch_value,
                               bool case_jni_env,
                               bool case_object_or_class,
                               /* out parameters */
                               bool* return_value) const;
};

}  // namespace art

#endif  // ART_COMPILER_JNI_QUICK_CALLING_CONVENTION_H_
