// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_BACKEND_CODE_GENERATOR_H_
#define V8_COMPILER_BACKEND_CODE_GENERATOR_H_

#include <memory>

#include "src/base/optional.h"
#include "src/codegen/macro-assembler.h"
#include "src/codegen/safepoint-table.h"
#include "src/codegen/source-position-table.h"
#include "src/compiler/backend/gap-resolver.h"
#include "src/compiler/backend/instruction.h"
#include "src/compiler/backend/unwinding-info-writer.h"
#include "src/compiler/osr.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/trap-handler/trap-handler.h"

namespace v8 {
namespace internal {

class OptimizedCompilationInfo;

namespace compiler {

// Forward declarations.
class DeoptimizationExit;
class FrameAccessState;
class Linkage;
class OutOfLineCode;

struct BranchInfo {
  FlagsCondition condition;
  Label* true_label;
  Label* false_label;
  bool fallthru;
};

class InstructionOperandIterator {
 public:
  InstructionOperandIterator(Instruction* instr, size_t pos)
      : instr_(instr), pos_(pos) {}

  Instruction* instruction() const { return instr_; }
  InstructionOperand* Advance() { return instr_->InputAt(pos_++); }

 private:
  Instruction* instr_;
  size_t pos_;
};

enum class DeoptimizationLiteralKind { kObject, kNumber, kString, kInvalid };

// Either a non-null Handle<Object>, a double or a StringConstantBase.
class DeoptimizationLiteral {
 public:
  DeoptimizationLiteral()
      : kind_(DeoptimizationLiteralKind::kInvalid),
        object_(),
        number_(0),
        string_(nullptr) {}
  explicit DeoptimizationLiteral(Handle<Object> object)
      : kind_(DeoptimizationLiteralKind::kObject), object_(object) {
    CHECK(!object_.is_null());
  }
  explicit DeoptimizationLiteral(double number)
      : kind_(DeoptimizationLiteralKind::kNumber), number_(number) {}
  explicit DeoptimizationLiteral(const StringConstantBase* string)
      : kind_(DeoptimizationLiteralKind::kString), string_(string) {}

  Handle<Object> object() const { return object_; }
  const StringConstantBase* string() const { return string_; }

  bool operator==(const DeoptimizationLiteral& other) const {
    return kind_ == other.kind_ && object_.equals(other.object_) &&
           bit_cast<uint64_t>(number_) == bit_cast<uint64_t>(other.number_) &&
           bit_cast<intptr_t>(string_) == bit_cast<intptr_t>(other.string_);
  }

  Handle<Object> Reify(Isolate* isolate) const;

  void Validate() const {
    CHECK_NE(kind_, DeoptimizationLiteralKind::kInvalid);
  }

  DeoptimizationLiteralKind kind() const {
    Validate();
    return kind_;
  }

 private:
  DeoptimizationLiteralKind kind_;

  Handle<Object> object_;
  double number_ = 0;
  const StringConstantBase* string_ = nullptr;
};

// These structs hold pc offsets for generated instructions and is only used
// when tracing for turbolizer is enabled.
struct TurbolizerCodeOffsetsInfo {
  int code_start_register_check = -1;
  int deopt_check = -1;
  int init_poison = -1;
  int blocks_start = -1;
  int out_of_line_code = -1;
  int deoptimization_exits = -1;
  int pools = -1;
  int jump_tables = -1;
};

struct TurbolizerInstructionStartInfo {
  int gap_pc_offset = -1;
  int arch_instr_pc_offset = -1;
  int condition_pc_offset = -1;
};

// Generates native code for a sequence of instructions.
class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
 public:
  explicit CodeGenerator(
      Zone* codegen_zone, Frame* frame, Linkage* linkage,
      InstructionSequence* instructions, OptimizedCompilationInfo* info,
      Isolate* isolate, base::Optional<OsrHelper> osr_helper,
      int start_source_position, JumpOptimizationInfo* jump_opt,
      PoisoningMitigationLevel poisoning_level, const AssemblerOptions& options,
      int32_t builtin_index, size_t max_unoptimized_frame_height,
      size_t max_pushed_argument_count, std::unique_ptr<AssemblerBuffer> = {},
      const char* debug_name = nullptr);

  // Generate native code. After calling AssembleCode, call FinalizeCode to
  // produce the actual code object. If an error occurs during either phase,
  // FinalizeCode returns an empty MaybeHandle.
  void AssembleCode();  // Does not need to run on main thread.
  MaybeHandle<Code> FinalizeCode();

  OwnedVector<byte> GetSourcePositionTable();
  OwnedVector<byte> GetProtectedInstructionsData();

  InstructionSequence* instructions() const { return instructions_; }
  FrameAccessState* frame_access_state() const { return frame_access_state_; }
  const Frame* frame() const { return frame_access_state_->frame(); }
  Isolate* isolate() const { return isolate_; }
  Linkage* linkage() const { return linkage_; }

  Label* GetLabel(RpoNumber rpo) { return &labels_[rpo.ToSize()]; }

  void AddProtectedInstructionLanding(uint32_t instr_offset,
                                      uint32_t landing_offset);

  bool wasm_runtime_exception_support() const;

  SourcePosition start_source_position() const {
    return start_source_position_;
  }

  void AssembleSourcePosition(Instruction* instr);
  void AssembleSourcePosition(SourcePosition source_position);

  // Record a safepoint with the given pointer map.
  void RecordSafepoint(ReferenceMap* references,
                       Safepoint::DeoptMode deopt_mode);

  Zone* zone() const { return zone_; }
  TurboAssembler* tasm() { return &tasm_; }
  SafepointTableBuilder* safepoint_table_builder() { return &safepoints_; }
  size_t GetSafepointTableOffset() const { return safepoints_.GetCodeOffset(); }
  size_t GetHandlerTableOffset() const { return handler_table_offset_; }

  const ZoneVector<int>& block_starts() const { return block_starts_; }
  const ZoneVector<TurbolizerInstructionStartInfo>& instr_starts() const {
    return instr_starts_;
  }

  const TurbolizerCodeOffsetsInfo& offsets_info() const {
    return offsets_info_;
  }

  static constexpr int kBinarySearchSwitchMinimalCases = 4;

  // Returns true if an offset should be applied to the given stack check. There
  // are two reasons that this could happen:
  // 1. The optimized frame is smaller than the corresponding deoptimized frames
  //    and an offset must be applied in order to be able to deopt safely.
  // 2. The current function pushes a large number of arguments to the stack.
  //    These are not accounted for by the initial frame setup.
  bool ShouldApplyOffsetToStackCheck(Instruction* instr, uint32_t* offset);
  uint32_t GetStackCheckOffset();

 private:
  GapResolver* resolver() { return &resolver_; }
  SafepointTableBuilder* safepoints() { return &safepoints_; }
  OptimizedCompilationInfo* info() const { return info_; }
  OsrHelper* osr_helper() { return &(*osr_helper_); }

  // Create the FrameAccessState object. The Frame is immutable from here on.
  void CreateFrameAccessState(Frame* frame);

  // Architecture - specific frame finalization.
  void FinishFrame(Frame* frame);

  // Checks if {block} will appear directly after {current_block_} when
  // assembling code, in which case, a fall-through can be used.
  bool IsNextInAssemblyOrder(RpoNumber block) const;

  // Check if a heap object can be materialized by loading from a heap root,
  // which is cheaper on some platforms than materializing the actual heap
  // object constant.
  bool IsMaterializableFromRoot(Handle<HeapObject> object,
                                RootIndex* index_return);

  enum CodeGenResult { kSuccess, kTooManyDeoptimizationBailouts };

  // Assemble instructions for the specified block.
  CodeGenResult AssembleBlock(const InstructionBlock* block);

  // Inserts mask update at the beginning of an instruction block if the
  // predecessor blocks ends with a masking branch.
  void TryInsertBranchPoisoning(const InstructionBlock* block);

  // Initializes the masking register in the prologue of a function.
  void InitializeSpeculationPoison();
  // Reset the masking register during execution of a function.
  void ResetSpeculationPoison();
  // Generates a mask from the pc passed in {kJavaScriptCallCodeStartRegister}.
  void GenerateSpeculationPoisonFromCodeStartRegister();

  // Assemble code for the specified instruction.
  CodeGenResult AssembleInstruction(int instruction_index,
                                    const InstructionBlock* block);
  void AssembleGaps(Instruction* instr);

  // Compute branch info from given instruction. Returns a valid rpo number
  // if the branch is redundant, the returned rpo number point to the target
  // basic block.
  RpoNumber ComputeBranchInfo(BranchInfo* branch, Instruction* instr);

  // Returns true if a instruction is a tail call that needs to adjust the stack
  // pointer before execution. The stack slot index to the empty slot above the
  // adjusted stack pointer is returned in |slot|.
  bool GetSlotAboveSPBeforeTailCall(Instruction* instr, int* slot);

  // Determines how to call helper stubs depending on the code kind.
  StubCallMode DetermineStubCallMode() const;

  CodeGenResult AssembleDeoptimizerCall(DeoptimizationExit* exit);

  // ===========================================================================
  // ============= Architecture-specific code generation methods. ==============
  // ===========================================================================

  CodeGenResult AssembleArchInstruction(Instruction* instr);
  void AssembleArchJump(RpoNumber target);
  void AssembleArchBranch(Instruction* instr, BranchInfo* branch);

  // Generates special branch for deoptimization condition.
  void AssembleArchDeoptBranch(Instruction* instr, BranchInfo* branch);

  void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
  void AssembleArchTrap(Instruction* instr, FlagsCondition condition);
  void AssembleArchBinarySearchSwitchRange(Register input, RpoNumber def_block,
                                           std::pair<int32_t, Label*>* begin,
                                           std::pair<int32_t, Label*>* end);
  void AssembleArchBinarySearchSwitch(Instruction* instr);
  void AssembleArchTableSwitch(Instruction* instr);

  // Generates code that checks whether the {kJavaScriptCallCodeStartRegister}
  // contains the expected pointer to the start of the instruction stream.
  void AssembleCodeStartRegisterCheck();

  void AssembleBranchPoisoning(FlagsCondition condition, Instruction* instr);

  // When entering a code that is marked for deoptimization, rather continuing
  // with its execution, we jump to a lazy compiled code. We need to do this
  // because this code has already been deoptimized and needs to be unlinked
  // from the JS functions referring it.
  void BailoutIfDeoptimized();

  // Generates code to poison the stack pointer and implicit register arguments
  // like the context register and the function register.
  void AssembleRegisterArgumentPoisoning();

  // Generates an architecture-specific, descriptor-specific prologue
  // to set up a stack frame.
  void AssembleConstructFrame();

  // Generates an architecture-specific, descriptor-specific return sequence
  // to tear down a stack frame.
  void AssembleReturn(InstructionOperand* pop);

  void AssembleDeconstructFrame();

  // Generates code to manipulate the stack in preparation for a tail call.
  void AssemblePrepareTailCall();

  // Generates code to pop current frame if it is an arguments adaptor frame.
  void AssemblePopArgumentsAdaptorFrame(Register args_reg, Register scratch1,
                                        Register scratch2, Register scratch3);

  enum PushTypeFlag {
    kImmediatePush = 0x1,
    kRegisterPush = 0x2,
    kStackSlotPush = 0x4,
    kScalarPush = kRegisterPush | kStackSlotPush
  };

  using PushTypeFlags = base::Flags<PushTypeFlag>;

  static bool IsValidPush(InstructionOperand source, PushTypeFlags push_type);

  // Generate a list of moves from an instruction that are candidates to be
  // turned into push instructions on platforms that support them. In general,
  // the list of push candidates are moves to a set of contiguous destination
  // InstructionOperand locations on the stack that don't clobber values that
  // are needed to resolve the gap or use values generated by the gap,
  // i.e. moves that can be hoisted together before the actual gap and assembled
  // together.
  static void GetPushCompatibleMoves(Instruction* instr,
                                     PushTypeFlags push_type,
                                     ZoneVector<MoveOperands*>* pushes);

  class MoveType {
   public:
    enum Type {
      kRegisterToRegister,
      kRegisterToStack,
      kStackToRegister,
      kStackToStack,
      kConstantToRegister,
      kConstantToStack
    };

    // Detect what type of move or swap needs to be performed. Note that these
    // functions do not take into account the representation (Tagged, FP,
    // ...etc).

    static Type InferMove(InstructionOperand* source,
                          InstructionOperand* destination);
    static Type InferSwap(InstructionOperand* source,
                          InstructionOperand* destination);
  };
  // Called before a tail call |instr|'s gap moves are assembled and allows
  // gap-specific pre-processing, e.g. adjustment of the sp for tail calls that
  // need it before gap moves or conversion of certain gap moves into pushes.
  void AssembleTailCallBeforeGap(Instruction* instr,
                                 int first_unused_stack_slot);
  // Called after a tail call |instr|'s gap moves are assembled and allows
  // gap-specific post-processing, e.g. adjustment of the sp for tail calls that
  // need it after gap moves.
  void AssembleTailCallAfterGap(Instruction* instr,
                                int first_unused_stack_slot);

  void FinishCode();
  void MaybeEmitOutOfLineConstantPool();

  void IncrementStackAccessCounter(InstructionOperand* source,
                                   InstructionOperand* destination);

  // ===========================================================================
  // ============== Architecture-specific gap resolver methods. ================
  // ===========================================================================

  // Interface used by the gap resolver to emit moves and swaps.
  void AssembleMove(InstructionOperand* source,
                    InstructionOperand* destination) final;
  void AssembleSwap(InstructionOperand* source,
                    InstructionOperand* destination) final;

  // ===========================================================================
  // =================== Jump table construction methods. ======================
  // ===========================================================================

  class JumpTable;
  // Adds a jump table that is emitted after the actual code.  Returns label
  // pointing to the beginning of the table.  {targets} is assumed to be static
  // or zone allocated.
  Label* AddJumpTable(Label** targets, size_t target_count);
  // Emits a jump table.
  void AssembleJumpTable(Label** targets, size_t target_count);

  // ===========================================================================
  // ================== Deoptimization table construction. =====================
  // ===========================================================================

  void RecordCallPosition(Instruction* instr);
  Handle<DeoptimizationData> GenerateDeoptimizationData();
  int DefineDeoptimizationLiteral(DeoptimizationLiteral literal);
  DeoptimizationEntry const& GetDeoptimizationEntry(Instruction* instr,
                                                    size_t frame_state_offset);
  DeoptimizationExit* BuildTranslation(Instruction* instr, int pc_offset,
                                       size_t frame_state_offset,
                                       OutputFrameStateCombine state_combine);
  void BuildTranslationForFrameStateDescriptor(
      FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
      Translation* translation, OutputFrameStateCombine state_combine);
  void TranslateStateValueDescriptor(StateValueDescriptor* desc,
                                     StateValueList* nested,
                                     Translation* translation,
                                     InstructionOperandIterator* iter);
  void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc,
                                             InstructionOperandIterator* iter,
                                             Translation* translation);
  void AddTranslationForOperand(Translation* translation, Instruction* instr,
                                InstructionOperand* op, MachineType type);
  void MarkLazyDeoptSite();

  void PrepareForDeoptimizationExits(ZoneDeque<DeoptimizationExit*>* exits);
  DeoptimizationExit* AddDeoptimizationExit(Instruction* instr,
                                            size_t frame_state_offset);

  // ===========================================================================

  struct HandlerInfo {
    Label* handler;
    int pc_offset;
  };

  friend class OutOfLineCode;
  friend class CodeGeneratorTester;

  Zone* zone_;
  Isolate* isolate_;
  FrameAccessState* frame_access_state_;
  Linkage* const linkage_;
  InstructionSequence* const instructions_;
  UnwindingInfoWriter unwinding_info_writer_;
  OptimizedCompilationInfo* const info_;
  Label* const labels_;
  Label return_label_;
  RpoNumber current_block_;
  SourcePosition start_source_position_;
  SourcePosition current_source_position_;
  TurboAssembler tasm_;
  GapResolver resolver_;
  SafepointTableBuilder safepoints_;
  ZoneVector<HandlerInfo> handlers_;
  int next_deoptimization_id_ = 0;
  int deopt_exit_start_offset_ = 0;
  int non_lazy_deopt_count_ = 0;
  ZoneDeque<DeoptimizationExit*> deoptimization_exits_;
  ZoneDeque<DeoptimizationLiteral> deoptimization_literals_;
  size_t inlined_function_count_ = 0;
  TranslationBuffer translations_;
  int handler_table_offset_ = 0;
  int last_lazy_deopt_pc_ = 0;

  // Deoptimization exits must be as small as possible, since their count grows
  // with function size. {jump_deoptimization_entry_labels_} is an optimization
  // to that effect, which extracts the (potentially large) instruction
  // sequence for the final jump to the deoptimization entry into a single spot
  // per Code object. All deopt exits can then near-call to this label. Note:
  // not used on all architectures.
  Label jump_deoptimization_entry_labels_[kDeoptimizeKindCount];

  // The maximal combined height of all frames produced upon deoptimization, and
  // the maximal number of pushed arguments for function calls. Applied as an
  // offset to the first stack check of an optimized function.
  const size_t max_unoptimized_frame_height_;
  const size_t max_pushed_argument_count_;

  // kArchCallCFunction could be reached either:
  //   kArchCallCFunction;
  // or:
  //   kArchSaveCallerRegisters;
  //   kArchCallCFunction;
  //   kArchRestoreCallerRegisters;
  // The boolean is used to distinguish the two cases. In the latter case, we
  // also need to decide if FP registers need to be saved, which is controlled
  // by fp_mode_.
  bool caller_registers_saved_;
  SaveFPRegsMode fp_mode_;

  JumpTable* jump_tables_;
  OutOfLineCode* ools_;
  base::Optional<OsrHelper> osr_helper_;
  int osr_pc_offset_;
  int optimized_out_literal_id_;
  SourcePositionTableBuilder source_position_table_builder_;
  ZoneVector<trap_handler::ProtectedInstructionData> protected_instructions_;
  CodeGenResult result_;
  PoisoningMitigationLevel poisoning_level_;
  ZoneVector<int> block_starts_;
  TurbolizerCodeOffsetsInfo offsets_info_;
  ZoneVector<TurbolizerInstructionStartInfo> instr_starts_;

  const char* debug_name_ = nullptr;
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_BACKEND_CODE_GENERATOR_H_
