OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 5 #ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
6 #define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 6 #define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
7 | 7 |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "src/ast.h" | 10 #include "src/ast.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 | 80 |
81 // Tests. | 81 // Tests. |
82 BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg, | 82 BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg, |
83 LanguageMode language_mode); | 83 LanguageMode language_mode); |
84 | 84 |
85 // Casts | 85 // Casts |
86 BytecodeArrayBuilder& CastAccumulatorToBoolean(); | 86 BytecodeArrayBuilder& CastAccumulatorToBoolean(); |
87 | 87 |
88 // Flow Control. | 88 // Flow Control. |
89 BytecodeArrayBuilder& Bind(BytecodeLabel* label); | 89 BytecodeArrayBuilder& Bind(BytecodeLabel* label); |
| 90 BytecodeArrayBuilder& Bind(const BytecodeLabel& target, BytecodeLabel* label); |
| 91 |
90 BytecodeArrayBuilder& Jump(BytecodeLabel* label); | 92 BytecodeArrayBuilder& Jump(BytecodeLabel* label); |
91 BytecodeArrayBuilder& JumpIfTrue(BytecodeLabel* label); | 93 BytecodeArrayBuilder& JumpIfTrue(BytecodeLabel* label); |
92 BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label); | 94 BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label); |
93 BytecodeArrayBuilder& Return(); | 95 BytecodeArrayBuilder& Return(); |
94 | 96 |
95 BytecodeArrayBuilder& EnterBlock(); | 97 BytecodeArrayBuilder& EnterBlock(); |
96 BytecodeArrayBuilder& LeaveBlock(); | 98 BytecodeArrayBuilder& LeaveBlock(); |
97 | 99 |
| 100 // Accessors |
| 101 Zone* zone() const { return zone_; } |
| 102 |
98 private: | 103 private: |
99 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } | 104 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } |
100 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; } | 105 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; } |
101 Isolate* isolate() const { return isolate_; } | 106 Isolate* isolate() const { return isolate_; } |
102 | 107 |
103 static Bytecode BytecodeForBinaryOperation(Token::Value op); | 108 static Bytecode BytecodeForBinaryOperation(Token::Value op); |
104 static Bytecode BytecodeForCompareOperation(Token::Value op); | 109 static Bytecode BytecodeForCompareOperation(Token::Value op); |
105 static bool FitsInIdxOperand(int value); | 110 static bool FitsInIdxOperand(int value); |
106 static bool FitsInIdxOperand(size_t value); | 111 static bool FitsInIdxOperand(size_t value); |
107 static bool FitsInImm8Operand(int value); | 112 static bool FitsInImm8Operand(int value); |
108 static bool IsJumpWithImm8Operand(Bytecode jump_bytecode); | |
109 static Bytecode GetJumpWithConstantOperand(Bytecode jump_with_smi8_operand); | 113 static Bytecode GetJumpWithConstantOperand(Bytecode jump_with_smi8_operand); |
110 | 114 |
111 template <size_t N> | 115 template <size_t N> |
112 INLINE(void Output(uint8_t(&bytes)[N])); | 116 INLINE(void Output(uint8_t(&bytes)[N])); |
113 void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1, | 117 void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1, |
114 uint8_t operand2); | 118 uint8_t operand2); |
115 void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1); | 119 void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1); |
116 void Output(Bytecode bytecode, uint8_t operand0); | 120 void Output(Bytecode bytecode, uint8_t operand0); |
117 void Output(Bytecode bytecode); | 121 void Output(Bytecode bytecode); |
118 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target, | 122 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target, |
119 ZoneVector<uint8_t>::iterator jump_location); | 123 ZoneVector<uint8_t>::iterator jump_location); |
120 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode, | 124 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode, |
121 BytecodeLabel* label); | 125 BytecodeLabel* label); |
122 | 126 |
123 void EnsureReturn(); | 127 void EnsureReturn(); |
124 | 128 |
125 bool OperandIsValid(Bytecode bytecode, int operand_index, | 129 bool OperandIsValid(Bytecode bytecode, int operand_index, |
126 uint8_t operand_value) const; | 130 uint8_t operand_value) const; |
127 bool LastBytecodeInSameBlock() const; | 131 bool LastBytecodeInSameBlock() const; |
128 | 132 |
129 size_t GetConstantPoolEntry(Handle<Object> object); | 133 size_t GetConstantPoolEntry(Handle<Object> object); |
130 | 134 |
131 // Scope helpers used by TemporaryRegisterScope | 135 // Scope helpers used by TemporaryRegisterScope |
132 int BorrowTemporaryRegister(); | 136 int BorrowTemporaryRegister(); |
133 void ReturnTemporaryRegister(int reg_index); | 137 void ReturnTemporaryRegister(int reg_index); |
134 | 138 |
135 Isolate* isolate_; | 139 Isolate* isolate_; |
| 140 Zone* zone_; |
136 ZoneVector<uint8_t> bytecodes_; | 141 ZoneVector<uint8_t> bytecodes_; |
137 bool bytecode_generated_; | 142 bool bytecode_generated_; |
138 size_t last_block_end_; | 143 size_t last_block_end_; |
139 size_t last_bytecode_start_; | 144 size_t last_bytecode_start_; |
140 bool return_seen_in_block_; | 145 bool return_seen_in_block_; |
141 | 146 |
142 IdentityMap<size_t> constants_map_; | 147 IdentityMap<size_t> constants_map_; |
143 ZoneVector<Handle<Object>> constants_; | 148 ZoneVector<Handle<Object>> constants_; |
144 | 149 |
145 int parameter_count_; | 150 int parameter_count_; |
146 int local_register_count_; | 151 int local_register_count_; |
147 int temporary_register_count_; | 152 int temporary_register_count_; |
148 int temporary_register_next_; | 153 int temporary_register_next_; |
149 | 154 |
150 friend class TemporaryRegisterScope; | 155 friend class TemporaryRegisterScope; |
151 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArrayBuilder); | 156 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArrayBuilder); |
152 }; | 157 }; |
153 | 158 |
154 | 159 |
155 // A label representing a branch target in a bytecode array. When a | 160 // A label representing a branch target in a bytecode array. When a |
156 // label is bound, it represents a known position in the bytecode | 161 // label is bound, it represents a known position in the bytecode |
157 // array. For labels that are forward references there can be at most | 162 // array. For labels that are forward references there can be at most |
158 // one reference whilst it is unbound. | 163 // one reference whilst it is unbound. |
159 class BytecodeLabel final { | 164 class BytecodeLabel final { |
160 public: | 165 public: |
161 BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {} | 166 BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {} |
162 ~BytecodeLabel() { DCHECK(bound_ && offset_ != kInvalidOffset); } | |
163 | 167 |
164 private: | 168 private: |
165 static const size_t kInvalidOffset = static_cast<size_t>(-1); | 169 static const size_t kInvalidOffset = static_cast<size_t>(-1); |
166 | 170 |
167 INLINE(void bind_to(size_t offset)) { | 171 INLINE(void bind_to(size_t offset)) { |
168 DCHECK(!bound_ && offset != kInvalidOffset); | 172 DCHECK(!bound_ && offset != kInvalidOffset); |
169 offset_ = offset; | 173 offset_ = offset; |
170 bound_ = true; | 174 bound_ = true; |
171 } | 175 } |
172 INLINE(void set_referrer(size_t offset)) { | 176 INLINE(void set_referrer(size_t offset)) { |
173 DCHECK(!bound_ && offset != kInvalidOffset); | 177 DCHECK(!bound_ && offset != kInvalidOffset); |
174 offset_ = offset; | 178 offset_ = offset; |
175 } | 179 } |
176 INLINE(size_t offset() const) { return offset_; } | 180 INLINE(size_t offset() const) { return offset_; } |
177 INLINE(bool is_bound() const) { return bound_; } | 181 INLINE(bool is_bound() const) { return bound_; } |
178 INLINE(bool is_forward_target() const) { | 182 INLINE(bool is_forward_target() const) { |
179 return offset() != kInvalidOffset && !is_bound(); | 183 return offset() != kInvalidOffset && !is_bound(); |
180 } | 184 } |
181 | 185 |
182 // There are three states for a label: | 186 // There are three states for a label: |
183 // bound_ offset_ | 187 // bound_ offset_ |
184 // UNSET false kInvalidOffset | 188 // UNSET false kInvalidOffset |
185 // FORWARD_TARGET false Offset of referring jump | 189 // FORWARD_TARGET false Offset of referring jump |
186 // BACKWARD_TARGET true Offset of label in bytecode array when bound | 190 // BACKWARD_TARGET true Offset of label in bytecode array when bound |
187 bool bound_; | 191 bool bound_; |
188 size_t offset_; | 192 size_t offset_; |
189 | 193 |
190 friend class BytecodeArrayBuilder; | 194 friend class BytecodeArrayBuilder; |
191 DISALLOW_COPY_AND_ASSIGN(BytecodeLabel); | |
192 }; | 195 }; |
193 | 196 |
194 | 197 |
195 // A stack-allocated class than allows the instantiator to allocate | 198 // A stack-allocated class than allows the instantiator to allocate |
196 // temporary registers that are cleaned up when scope is closed. | 199 // temporary registers that are cleaned up when scope is closed. |
197 class TemporaryRegisterScope { | 200 class TemporaryRegisterScope { |
198 public: | 201 public: |
199 explicit TemporaryRegisterScope(BytecodeArrayBuilder* builder); | 202 explicit TemporaryRegisterScope(BytecodeArrayBuilder* builder); |
200 ~TemporaryRegisterScope(); | 203 ~TemporaryRegisterScope(); |
201 Register NewRegister(); | 204 Register NewRegister(); |
202 | 205 |
203 private: | 206 private: |
204 void* operator new(size_t size); | 207 void* operator new(size_t size); |
205 void operator delete(void* p); | 208 void operator delete(void* p); |
206 | 209 |
207 BytecodeArrayBuilder* builder_; | 210 BytecodeArrayBuilder* builder_; |
208 int count_; | 211 int count_; |
209 int last_register_index_; | 212 int last_register_index_; |
210 | 213 |
211 DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterScope); | 214 DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterScope); |
212 }; | 215 }; |
213 | 216 |
214 | 217 |
215 } // namespace interpreter | 218 } // namespace interpreter |
216 } // namespace internal | 219 } // namespace internal |
217 } // namespace v8 | 220 } // namespace v8 |
218 | 221 |
219 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 222 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
OLD | NEW |