%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/baseline/
Upload File :
Create Path :
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/baseline/baseline-compiler.h

// Copyright 2021 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_BASELINE_BASELINE_COMPILER_H_
#define V8_BASELINE_BASELINE_COMPILER_H_

// TODO(v8:11421): Remove #if once baseline compiler is ported to other
// architectures.
#include "src/flags/flags.h"
#if ENABLE_SPARKPLUG

#include "src/base/logging.h"
#include "src/base/pointer-with-payload.h"
#include "src/base/threaded-list.h"
#include "src/base/vlq.h"
#include "src/baseline/baseline-assembler.h"
#include "src/execution/local-isolate.h"
#include "src/handles/handles.h"
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/interpreter/bytecode-register.h"
#include "src/interpreter/interpreter-intrinsics.h"
#include "src/logging/counters.h"
#include "src/objects/map.h"
#include "src/objects/tagged-index.h"

namespace v8 {
namespace internal {

class BytecodeArray;

namespace baseline {

class BytecodeOffsetTableBuilder {
 public:
  void AddPosition(size_t pc_offset) {
    size_t pc_diff = pc_offset - previous_pc_;
    DCHECK_GE(pc_diff, 0);
    DCHECK_LE(pc_diff, std::numeric_limits<uint32_t>::max());
    base::VLQEncodeUnsigned(&bytes_, static_cast<uint32_t>(pc_diff));
    previous_pc_ = pc_offset;
  }

  template <typename IsolateT>
  Handle<ByteArray> ToBytecodeOffsetTable(IsolateT* isolate);

  void Reserve(size_t size) { bytes_.reserve(size); }

 private:
  size_t previous_pc_ = 0;
  std::vector<uint8_t> bytes_;
};

class BaselineCompiler {
 public:
  explicit BaselineCompiler(LocalIsolate* local_isolate,
                            Handle<SharedFunctionInfo> shared_function_info,
                            Handle<BytecodeArray> bytecode);

  void GenerateCode();
  MaybeHandle<Code> Build(LocalIsolate* local_isolate);
  static int EstimateInstructionSize(Tagged<BytecodeArray> bytecode);

 private:
  void Prologue();
  void PrologueFillFrame();
  void PrologueHandleOptimizationState(Register feedback_vector);

  void PreVisitSingleBytecode();
  void VisitSingleBytecode();

  void VerifyFrame();
  void VerifyFrameSize();

  // Register operands.
  interpreter::Register RegisterOperand(int operand_index);
  void LoadRegister(Register output, int operand_index);
  void StoreRegister(int operand_index, Register value);
  void StoreRegisterPair(int operand_index, Register val0, Register val1);

  // Constant pool operands.
  template <typename Type>
  Handle<Type> Constant(int operand_index);
  Tagged<Smi> ConstantSmi(int operand_index);
  template <typename Type>
  void LoadConstant(Register output, int operand_index);

  // Immediate value operands.
  uint32_t Uint(int operand_index);
  int32_t Int(int operand_index);
  uint32_t Index(int operand_index);
  uint32_t Flag8(int operand_index);
  uint32_t Flag16(int operand_index);
  uint32_t RegisterCount(int operand_index);
  Tagged<TaggedIndex> IndexAsTagged(int operand_index);
  Tagged<TaggedIndex> UintAsTagged(int operand_index);
  Tagged<Smi> IndexAsSmi(int operand_index);
  Tagged<Smi> IntAsSmi(int operand_index);
  Tagged<Smi> Flag8AsSmi(int operand_index);
  Tagged<Smi> Flag16AsSmi(int operand_index);

  // Jump helpers.
  Label* NewLabel();
  Label* BuildForwardJumpLabel();
  enum StackCheckBehavior {
    kEnableStackCheck,
    kDisableStackCheck,
  };
  void UpdateInterruptBudgetAndJumpToLabel(
      int weight, Label* label, Label* skip_interrupt_label,
      StackCheckBehavior stack_check_behavior);
  void JumpIfRoot(RootIndex root);
  void JumpIfNotRoot(RootIndex root);

  // Feedback vector.
  MemOperand FeedbackVector();
  void LoadFeedbackVector(Register output);
  void LoadClosureFeedbackArray(Register output);

  // Position mapping.
  void AddPosition();

  // Misc. helpers.

  void UpdateMaxCallArgs(int max_call_args) {
    max_call_args_ = std::max(max_call_args_, max_call_args);
  }

  // Select the root boolean constant based on the jump in the given
  // `jump_func` -- the function should jump to the given label if we want to
  // select "true", otherwise it should fall through.
  void SelectBooleanConstant(
      Register output, std::function<void(Label*, Label::Distance)> jump_func);

  // Jumps based on calling ToBoolean on kInterpreterAccumulatorRegister.
  void JumpIfToBoolean(bool do_jump_if_true, Label* label,
                       Label::Distance distance = Label::kFar);

  // Call helpers.
  template <Builtin kBuiltin, typename... Args>
  void CallBuiltin(Args... args);
  template <typename... Args>
  void CallRuntime(Runtime::FunctionId function, Args... args);

  template <Builtin kBuiltin, typename... Args>
  void TailCallBuiltin(Args... args);

  template <ConvertReceiverMode kMode, typename... Args>
  void BuildCall(uint32_t slot, uint32_t arg_count, Args... args);

#ifdef V8_TRACE_UNOPTIMIZED
  void TraceBytecode(Runtime::FunctionId function_id);
#endif

  // Single bytecode visitors.
#define DECLARE_VISITOR(name, ...) void Visit##name();
  BYTECODE_LIST(DECLARE_VISITOR)
#undef DECLARE_VISITOR

  // Intrinsic call visitors.
#define DECLARE_VISITOR(name, ...) \
  void VisitIntrinsic##name(interpreter::RegisterList args);
  INTRINSICS_LIST(DECLARE_VISITOR)
#undef DECLARE_VISITOR

  const interpreter::BytecodeArrayIterator& iterator() { return iterator_; }

  LocalIsolate* local_isolate_;
  RuntimeCallStats* stats_;
  Handle<SharedFunctionInfo> shared_function_info_;
  Handle<HeapObject> interpreter_data_;
  Handle<BytecodeArray> bytecode_;
  MacroAssembler masm_;
  BaselineAssembler basm_;
  interpreter::BytecodeArrayIterator iterator_;
  BytecodeOffsetTableBuilder bytecode_offset_table_builder_;
  Zone zone_;

  int max_call_args_ = 0;

  // Mark location as a jump target reachable via indirect branches, required
  // for CFI.
  enum class MarkAsIndirectJumpTarget { kNo, kYes };

  struct BaselineLabelPointer : base::PointerWithPayload<Label, bool, 1> {
    void MarkAsIndirectJumpTarget() { SetPayload(true); }
    bool IsIndirectJumpTarget() const { return GetPayload(); }
  };

  Label* EnsureLabel(
      int i, MarkAsIndirectJumpTarget mark = MarkAsIndirectJumpTarget::kNo) {
    if (labels_[i].GetPointer() == nullptr) {
      labels_[i].SetPointer(zone_.New<Label>());
    }
    if (mark == MarkAsIndirectJumpTarget::kYes) {
      labels_[i].MarkAsIndirectJumpTarget();
    }
    return labels_[i].GetPointer();
  }

  BaselineLabelPointer* labels_;

#ifdef DEBUG
  friend class SaveAccumulatorScope;

  struct EffectState {
    bool may_have_deopted = false;
    bool accumulator_on_stack = false;
    bool safe_to_skip = false;

    void MayDeopt() {
      DCHECK(!accumulator_on_stack);
      may_have_deopted = true;
    }

    void CheckEffect() { DCHECK(!may_have_deopted || safe_to_skip); }

    void clear() {
      DCHECK(!accumulator_on_stack);
      *this = EffectState();
    }
  } effect_state_;
#endif
};

class SaveAccumulatorScope final {
 public:
  SaveAccumulatorScope(BaselineCompiler* compiler,
                       BaselineAssembler* assembler);

  ~SaveAccumulatorScope();

 private:
#ifdef DEBUG
  BaselineCompiler* compiler_;
#endif
  BaselineAssembler* assembler_;
};

}  // namespace baseline
}  // namespace internal
}  // namespace v8

#endif  // ENABLE_SPARKPLUG

#endif  // V8_BASELINE_BASELINE_COMPILER_H_

Zerion Mini Shell 1.0