OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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_INTERPRETER_BYTECODE_WRITER_H_ |
| 6 #define V8_INTERPRETER_BYTECODE_WRITER_H_ |
| 7 |
| 8 #include "src/interpreter/bytecode-register-allocator.h" |
| 9 #include "src/interpreter/bytecodes.h" |
| 10 #include "src/zone-containers.h" |
| 11 |
| 12 namespace v8 { |
| 13 namespace internal { |
| 14 namespace interpreter { |
| 15 |
| 16 class BytecodeArrayBuilder; |
| 17 class SourcePositionTableBuilder; |
| 18 class TemporaryRegisterAllocator; |
| 19 |
| 20 class BytecodeNodeAllocator; |
| 21 |
| 22 // Source code position information. |
| 23 class BytecodeSourceInfo final { |
| 24 public: |
| 25 static const int kUninitializedPosition = -1; |
| 26 |
| 27 BytecodeSourceInfo(int position = kUninitializedPosition, |
| 28 bool is_statement = false) |
| 29 : source_position_(position), is_statement_(is_statement) {} |
| 30 |
| 31 // Combine later source info with current. |
| 32 void Update(const BytecodeSourceInfo& entry); |
| 33 |
| 34 int source_position() const { |
| 35 DCHECK(is_valid()); |
| 36 return source_position_; |
| 37 } |
| 38 |
| 39 int is_statement() const { return is_valid() && is_statement_; } |
| 40 |
| 41 bool is_valid() const { return source_position_ != kUninitializedPosition; } |
| 42 void set_invalid() { source_position_ = kUninitializedPosition; } |
| 43 |
| 44 bool operator==(const BytecodeSourceInfo& other) const { |
| 45 return source_position_ == other.source_position_ && |
| 46 is_statement_ == other.is_statement_; |
| 47 } |
| 48 bool operator!=(const BytecodeSourceInfo& other) const { |
| 49 return source_position_ != other.source_position_ || |
| 50 is_statement_ != other.is_statement_; |
| 51 } |
| 52 |
| 53 private: |
| 54 int source_position_; |
| 55 bool is_statement_; |
| 56 |
| 57 DISALLOW_COPY_AND_ASSIGN(BytecodeSourceInfo); |
| 58 }; |
| 59 |
| 60 // A container for a generated bytecode, it's operands, and source information. |
| 61 // These must be allocated by a BytecodeNodeAllocator instance. |
| 62 class BytecodeNode final : ZoneObject { |
| 63 public: |
| 64 // Print to stream. |
| 65 void Print(std::ostream& os); |
| 66 |
| 67 // Return the size when this node is serialized to a bytecode array. |
| 68 size_t Size() const; |
| 69 |
| 70 // Return to node to allocator for re-use. |
| 71 void Release(); |
| 72 |
| 73 Bytecode bytecode() const { return bytecode_; } |
| 74 void set_bytecode(Bytecode bytecode); |
| 75 void set_bytecode(Bytecode bytecode, uint32_t operand0, |
| 76 OperandScale operand_scale); |
| 77 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 78 OperandScale operand_scale); |
| 79 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 80 uint32_t operand2, OperandScale operand_scale); |
| 81 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 82 uint32_t operand2, uint32_t operand3, |
| 83 OperandScale operand_scale); |
| 84 |
| 85 uint32_t* operands() { return operands_; } |
| 86 const uint32_t* operands() const { return operands_; } |
| 87 |
| 88 int operand_count() const { return Bytecodes::NumberOfOperands(bytecode_); } |
| 89 |
| 90 OperandScale operand_scale() const { return operand_scale_; } |
| 91 |
| 92 const BytecodeSourceInfo& source_info() const { return source_info_; } |
| 93 BytecodeSourceInfo& source_info() { return source_info_; } |
| 94 |
| 95 private: |
| 96 static const int kInvalidPosition = kMinInt; |
| 97 static const size_t kMaxOperands = 4; |
| 98 |
| 99 friend class BytecodeNodeAllocator; |
| 100 explicit BytecodeNode(BytecodeNodeAllocator* allocator); |
| 101 |
| 102 Bytecode bytecode_; |
| 103 uint32_t operands_[kMaxOperands]; |
| 104 OperandScale operand_scale_; |
| 105 BytecodeSourceInfo source_info_; |
| 106 BytecodeNodeAllocator* allocator_; |
| 107 BytecodeNode* next_; |
| 108 |
| 109 DISALLOW_COPY_AND_ASSIGN(BytecodeNode); |
| 110 }; |
| 111 |
| 112 // Allocator for BytecodeNodes that zone allocates them when needed |
| 113 // and maintains a freelist to reduce number of allocations and limit |
| 114 // memory use. |
| 115 class BytecodeNodeAllocator final { |
| 116 public: |
| 117 explicit BytecodeNodeAllocator(Zone* zone) |
| 118 : allocation_count_(0), free_list_(nullptr), zone_(zone) {} |
| 119 |
| 120 BytecodeNode* Allocate(); |
| 121 |
| 122 private: |
| 123 friend class BytecodeNode; |
| 124 static const int kMaxDebugAllocations = 8; |
| 125 |
| 126 void Release(BytecodeNode* node); |
| 127 |
| 128 Zone* zone() const { return zone_; } |
| 129 |
| 130 int allocation_count_; |
| 131 BytecodeNode* free_list_; |
| 132 Zone* zone_; |
| 133 |
| 134 DISALLOW_COPY_AND_ASSIGN(BytecodeNodeAllocator); |
| 135 }; |
| 136 |
| 137 // Interface for bytecode writers. |
| 138 class BytecodeWriter { |
| 139 public: |
| 140 virtual ~BytecodeWriter() {} |
| 141 |
| 142 // Flush state for bytecode array offset calculation. Returns the |
| 143 // current size of bytecode array. |
| 144 virtual size_t FlushForOffset() = 0; |
| 145 |
| 146 // Signal end of basic block. |
| 147 virtual void LeaveBasicBlock() = 0; |
| 148 |
| 149 // Write bytecode into pipeline. The callee owns node from here and |
| 150 // the caller should not hold any references to it. |
| 151 virtual void Write(BytecodeNode* node) = 0; |
| 152 }; |
| 153 |
| 154 // Class for emitting bytecode as the final stage of a bytecode writer |
| 155 // chain. |
| 156 class FinalStageBytecodeWriter : public BytecodeWriter { |
| 157 public: |
| 158 FinalStageBytecodeWriter( |
| 159 Zone* zone, SourcePositionTableBuilder* source_position_table_builder); |
| 160 virtual ~FinalStageBytecodeWriter(); |
| 161 |
| 162 size_t FlushForOffset() override; |
| 163 void LeaveBasicBlock() override; |
| 164 void Write(BytecodeNode* node) override; |
| 165 |
| 166 // Get the bytecode vector. |
| 167 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } |
| 168 |
| 169 // Returns the size in bytes of the frame associated with the |
| 170 // bytecode written. |
| 171 int GetMeasuredFrameSize(); |
| 172 |
| 173 private: |
| 174 void EmitBytecode(const BytecodeNode* const node); |
| 175 void UpdateSourcePositionTable(const BytecodeNode* const node); |
| 176 |
| 177 ZoneVector<uint8_t> bytecodes_; |
| 178 int frame_register_count_; |
| 179 SourcePositionTableBuilder* source_position_table_builder_; |
| 180 |
| 181 DISALLOW_COPY_AND_ASSIGN(FinalStageBytecodeWriter); |
| 182 }; |
| 183 |
| 184 } // namespace interpreter |
| 185 } // namespace internal |
| 186 } // namespace v8 |
| 187 |
| 188 #endif // V8_INTERPRETER_BYTECODE_WRITER_H_ |
OLD | NEW |