• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_MAGLEV_MAGLEV_CODE_GEN_STATE_H_
6 #define V8_MAGLEV_MAGLEV_CODE_GEN_STATE_H_
7 
8 #include "src/codegen/assembler.h"
9 #include "src/codegen/label.h"
10 #include "src/codegen/macro-assembler.h"
11 #include "src/codegen/safepoint-table.h"
12 #include "src/common/globals.h"
13 #include "src/compiler/backend/instruction.h"
14 #include "src/compiler/js-heap-broker.h"
15 #include "src/maglev/maglev-compilation-unit.h"
16 #include "src/maglev/maglev-ir.h"
17 
18 namespace v8 {
19 namespace internal {
20 namespace maglev {
21 
22 class InterpreterFrameState;
23 
24 class DeferredCodeInfo {
25  public:
26   virtual void Generate(MaglevCodeGenState* code_gen_state,
27                         Label* return_label) = 0;
28   Label deferred_code_label;
29   Label return_label;
30 };
31 
32 class MaglevCodeGenState {
33  public:
MaglevCodeGenState(MaglevCompilationUnit * compilation_unit,SafepointTableBuilder * safepoint_table_builder)34   MaglevCodeGenState(MaglevCompilationUnit* compilation_unit,
35                      SafepointTableBuilder* safepoint_table_builder)
36       : compilation_unit_(compilation_unit),
37         safepoint_table_builder_(safepoint_table_builder),
38         masm_(isolate(), CodeObjectRequired::kNo) {}
39 
SetVregSlots(int slots)40   void SetVregSlots(int slots) { vreg_slots_ = slots; }
41 
PushDeferredCode(DeferredCodeInfo * deferred_code)42   void PushDeferredCode(DeferredCodeInfo* deferred_code) {
43     deferred_code_.push_back(deferred_code);
44   }
deferred_code()45   const std::vector<DeferredCodeInfo*>& deferred_code() const {
46     return deferred_code_;
47   }
PushEagerDeopt(EagerDeoptInfo * info)48   void PushEagerDeopt(EagerDeoptInfo* info) { eager_deopts_.push_back(info); }
PushLazyDeopt(LazyDeoptInfo * info)49   void PushLazyDeopt(LazyDeoptInfo* info) { lazy_deopts_.push_back(info); }
eager_deopts()50   const std::vector<EagerDeoptInfo*>& eager_deopts() const {
51     return eager_deopts_;
52   }
lazy_deopts()53   const std::vector<LazyDeoptInfo*>& lazy_deopts() const {
54     return lazy_deopts_;
55   }
56   inline void DefineSafepointStackSlots(
57       SafepointTableBuilder::Safepoint& safepoint) const;
58 
native_context()59   compiler::NativeContextRef native_context() const {
60     return broker()->target_native_context();
61   }
isolate()62   Isolate* isolate() const { return compilation_unit_->isolate(); }
parameter_count()63   int parameter_count() const { return compilation_unit_->parameter_count(); }
register_count()64   int register_count() const { return compilation_unit_->register_count(); }
bytecode_analysis()65   const compiler::BytecodeAnalysis& bytecode_analysis() const {
66     return compilation_unit_->bytecode_analysis();
67   }
broker()68   compiler::JSHeapBroker* broker() const { return compilation_unit_->broker(); }
bytecode()69   const compiler::BytecodeArrayRef& bytecode() const {
70     return compilation_unit_->bytecode();
71   }
graph_labeller()72   MaglevGraphLabeller* graph_labeller() const {
73     return compilation_unit_->graph_labeller();
74   }
masm()75   MacroAssembler* masm() { return &masm_; }
vreg_slots()76   int vreg_slots() const { return vreg_slots_; }
safepoint_table_builder()77   SafepointTableBuilder* safepoint_table_builder() const {
78     return safepoint_table_builder_;
79   }
compilation_unit()80   MaglevCompilationUnit* compilation_unit() const { return compilation_unit_; }
81 
82   // TODO(v8:7700): Clean up after all code paths are supported.
set_found_unsupported_code_paths(bool val)83   void set_found_unsupported_code_paths(bool val) {
84     found_unsupported_code_paths_ = val;
85   }
found_unsupported_code_paths()86   bool found_unsupported_code_paths() const {
87     return found_unsupported_code_paths_;
88   }
89 
90  private:
91   MaglevCompilationUnit* const compilation_unit_;
92   SafepointTableBuilder* const safepoint_table_builder_;
93 
94   MacroAssembler masm_;
95   std::vector<DeferredCodeInfo*> deferred_code_;
96   std::vector<EagerDeoptInfo*> eager_deopts_;
97   std::vector<LazyDeoptInfo*> lazy_deopts_;
98   int vreg_slots_ = 0;
99 
100   // Allow marking some codegen paths as unsupported, so that we can test maglev
101   // incrementally.
102   // TODO(v8:7700): Clean up after all code paths are supported.
103   bool found_unsupported_code_paths_ = false;
104 };
105 
106 // Some helpers for codegen.
107 // TODO(leszeks): consider moving this to a separate header.
108 
GetFramePointerOffsetForStackSlot(int index)109 inline constexpr int GetFramePointerOffsetForStackSlot(int index) {
110   return StandardFrameConstants::kExpressionsOffset -
111          index * kSystemPointerSize;
112 }
113 
GetFramePointerOffsetForStackSlot(const compiler::AllocatedOperand & operand)114 inline int GetFramePointerOffsetForStackSlot(
115     const compiler::AllocatedOperand& operand) {
116   return GetFramePointerOffsetForStackSlot(operand.index());
117 }
118 
GetSafepointIndexForStackSlot(int i)119 inline int GetSafepointIndexForStackSlot(int i) {
120   // Safepoint tables also contain slots for all fixed frame slots (both
121   // above and below the fp).
122   return StandardFrameConstants::kFixedSlotCount + i;
123 }
124 
GetStackSlot(int index)125 inline MemOperand GetStackSlot(int index) {
126   return MemOperand(rbp, GetFramePointerOffsetForStackSlot(index));
127 }
128 
GetStackSlot(const compiler::AllocatedOperand & operand)129 inline MemOperand GetStackSlot(const compiler::AllocatedOperand& operand) {
130   return GetStackSlot(operand.index());
131 }
132 
ToRegister(const compiler::InstructionOperand & operand)133 inline Register ToRegister(const compiler::InstructionOperand& operand) {
134   return compiler::AllocatedOperand::cast(operand).GetRegister();
135 }
136 
ToRegister(const ValueLocation & location)137 inline Register ToRegister(const ValueLocation& location) {
138   return ToRegister(location.operand());
139 }
140 
ToMemOperand(const compiler::InstructionOperand & operand)141 inline MemOperand ToMemOperand(const compiler::InstructionOperand& operand) {
142   return GetStackSlot(compiler::AllocatedOperand::cast(operand));
143 }
144 
ToMemOperand(const ValueLocation & location)145 inline MemOperand ToMemOperand(const ValueLocation& location) {
146   return ToMemOperand(location.operand());
147 }
148 
DefineSafepointStackSlots(SafepointTableBuilder::Safepoint & safepoint)149 inline void MaglevCodeGenState::DefineSafepointStackSlots(
150     SafepointTableBuilder::Safepoint& safepoint) const {
151   DCHECK_EQ(compilation_unit()->stack_value_repr().size(), vreg_slots());
152   int stack_slot = 0;
153   for (ValueRepresentation repr : compilation_unit()->stack_value_repr()) {
154     if (repr == ValueRepresentation::kTagged) {
155       safepoint.DefineTaggedStackSlot(
156           GetSafepointIndexForStackSlot(stack_slot));
157     }
158     stack_slot++;
159   }
160 }
161 
162 }  // namespace maglev
163 }  // namespace internal
164 }  // namespace v8
165 
166 #endif  // V8_MAGLEV_MAGLEV_CODE_GEN_STATE_H_
167