| 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_PIPELINE_H_ | 5 #ifndef V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
| 6 #define V8_INTERPRETER_BYTECODE_PIPELINE_H_ | 6 #define V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
| 7 | 7 |
| 8 #include "src/base/compiler-specific.h" | 8 #include "src/base/compiler-specific.h" |
| 9 #include "src/globals.h" | 9 #include "src/globals.h" |
| 10 #include "src/interpreter/bytecode-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 position_type_ = PositionType::kExpression; | 88 position_type_ = PositionType::kExpression; |
| 89 source_position_ = source_position; | 89 source_position_ = source_position; |
| 90 } | 90 } |
| 91 | 91 |
| 92 // Forces an instance into an expression position. | 92 // Forces an instance into an expression position. |
| 93 void ForceExpressionPosition(int source_position) { | 93 void ForceExpressionPosition(int source_position) { |
| 94 position_type_ = PositionType::kExpression; | 94 position_type_ = PositionType::kExpression; |
| 95 source_position_ = source_position; | 95 source_position_ = source_position; |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Clones a source position. The current instance is expected to be | |
| 99 // invalid. | |
| 100 void Clone(const BytecodeSourceInfo& other) { | |
| 101 DCHECK(!is_valid()); | |
| 102 position_type_ = other.position_type_; | |
| 103 source_position_ = other.source_position_; | |
| 104 } | |
| 105 | |
| 106 int source_position() const { | 98 int source_position() const { |
| 107 DCHECK(is_valid()); | 99 DCHECK(is_valid()); |
| 108 return source_position_; | 100 return source_position_; |
| 109 } | 101 } |
| 110 | 102 |
| 111 bool is_statement() const { | 103 bool is_statement() const { |
| 112 return position_type_ == PositionType::kStatement; | 104 return position_type_ == PositionType::kStatement; |
| 113 } | 105 } |
| 114 bool is_expression() const { | 106 bool is_expression() const { |
| 115 return position_type_ == PositionType::kExpression; | 107 return position_type_ == PositionType::kExpression; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 135 enum class PositionType : uint8_t { kNone, kExpression, kStatement }; | 127 enum class PositionType : uint8_t { kNone, kExpression, kStatement }; |
| 136 | 128 |
| 137 PositionType position_type_; | 129 PositionType position_type_; |
| 138 int source_position_; | 130 int source_position_; |
| 139 }; | 131 }; |
| 140 | 132 |
| 141 // A container for a generated bytecode, it's operands, and source information. | 133 // A container for a generated bytecode, it's operands, and source information. |
| 142 // These must be allocated by a BytecodeNodeAllocator instance. | 134 // These must be allocated by a BytecodeNodeAllocator instance. |
| 143 class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) { | 135 class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) { |
| 144 public: | 136 public: |
| 145 INLINE(BytecodeNode(const Bytecode bytecode, | 137 INLINE(BytecodeNode(Bytecode bytecode, |
| 146 BytecodeSourceInfo* source_info = nullptr)) | 138 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
| 147 : bytecode_(bytecode), | 139 : bytecode_(bytecode), |
| 148 operand_count_(0), | 140 operand_count_(0), |
| 149 operand_scale_(OperandScale::kSingle) { | 141 operand_scale_(OperandScale::kSingle), |
| 142 source_info_(source_info) { |
| 150 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 143 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
| 151 AttachSourceInfo(source_info); | |
| 152 } | 144 } |
| 153 | 145 |
| 154 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, | 146 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, |
| 155 BytecodeSourceInfo* source_info = nullptr)) | 147 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
| 156 : bytecode_(bytecode), | 148 : bytecode_(bytecode), |
| 157 operand_count_(1), | 149 operand_count_(1), |
| 158 operand_scale_(OperandScale::kSingle) { | 150 operand_scale_(OperandScale::kSingle), |
| 151 source_info_(source_info) { |
| 159 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 152 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
| 160 SetOperand(0, operand0); | 153 SetOperand(0, operand0); |
| 161 AttachSourceInfo(source_info); | |
| 162 } | 154 } |
| 163 | 155 |
| 164 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, | 156 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 165 uint32_t operand1, | 157 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
| 166 BytecodeSourceInfo* source_info = nullptr)) | |
| 167 : bytecode_(bytecode), | 158 : bytecode_(bytecode), |
| 168 operand_count_(2), | 159 operand_count_(2), |
| 169 operand_scale_(OperandScale::kSingle) { | 160 operand_scale_(OperandScale::kSingle), |
| 161 source_info_(source_info) { |
| 170 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 162 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
| 171 SetOperand(0, operand0); | 163 SetOperand(0, operand0); |
| 172 SetOperand(1, operand1); | 164 SetOperand(1, operand1); |
| 173 AttachSourceInfo(source_info); | |
| 174 } | 165 } |
| 175 | 166 |
| 176 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, | 167 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 177 uint32_t operand1, uint32_t operand2, | 168 uint32_t operand2, |
| 178 BytecodeSourceInfo* source_info = nullptr)) | 169 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
| 179 : bytecode_(bytecode), | 170 : bytecode_(bytecode), |
| 180 operand_count_(3), | 171 operand_count_(3), |
| 181 operand_scale_(OperandScale::kSingle) { | 172 operand_scale_(OperandScale::kSingle), |
| 173 source_info_(source_info) { |
| 182 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 174 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
| 183 SetOperand(0, operand0); | 175 SetOperand(0, operand0); |
| 184 SetOperand(1, operand1); | 176 SetOperand(1, operand1); |
| 185 SetOperand(2, operand2); | 177 SetOperand(2, operand2); |
| 186 AttachSourceInfo(source_info); | |
| 187 } | 178 } |
| 188 | 179 |
| 189 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, | 180 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 190 uint32_t operand1, uint32_t operand2, uint32_t operand3, | 181 uint32_t operand2, uint32_t operand3, |
| 191 BytecodeSourceInfo* source_info = nullptr)) | 182 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
| 192 : bytecode_(bytecode), | 183 : bytecode_(bytecode), |
| 193 operand_count_(4), | 184 operand_count_(4), |
| 194 operand_scale_(OperandScale::kSingle) { | 185 operand_scale_(OperandScale::kSingle), |
| 186 source_info_(source_info) { |
| 195 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 187 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
| 196 SetOperand(0, operand0); | 188 SetOperand(0, operand0); |
| 197 SetOperand(1, operand1); | 189 SetOperand(1, operand1); |
| 198 SetOperand(2, operand2); | 190 SetOperand(2, operand2); |
| 199 SetOperand(3, operand3); | 191 SetOperand(3, operand3); |
| 200 AttachSourceInfo(source_info); | |
| 201 } | 192 } |
| 202 | 193 |
| 203 BytecodeNode(const BytecodeNode& other); | |
| 204 BytecodeNode& operator=(const BytecodeNode& other); | |
| 205 | |
| 206 // Replace the bytecode of this node with |bytecode| and keep the operands. | 194 // Replace the bytecode of this node with |bytecode| and keep the operands. |
| 207 void replace_bytecode(Bytecode bytecode) { | 195 void replace_bytecode(Bytecode bytecode) { |
| 208 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_), | 196 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_), |
| 209 Bytecodes::NumberOfOperands(bytecode)); | 197 Bytecodes::NumberOfOperands(bytecode)); |
| 210 bytecode_ = bytecode; | 198 bytecode_ = bytecode; |
| 211 } | 199 } |
| 200 |
| 212 void set_bytecode(Bytecode bytecode) { | 201 void set_bytecode(Bytecode bytecode) { |
| 213 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | 202 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); |
| 214 bytecode_ = bytecode; | 203 bytecode_ = bytecode; |
| 215 operand_count_ = 0; | 204 operand_count_ = 0; |
| 216 operand_scale_ = OperandScale::kSingle; | 205 operand_scale_ = OperandScale::kSingle; |
| 217 } | 206 } |
| 207 |
| 218 void set_bytecode(Bytecode bytecode, uint32_t operand0) { | 208 void set_bytecode(Bytecode bytecode, uint32_t operand0) { |
| 219 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1); | 209 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1); |
| 220 bytecode_ = bytecode; | 210 bytecode_ = bytecode; |
| 221 operand_count_ = 1; | 211 operand_count_ = 1; |
| 222 operand_scale_ = OperandScale::kSingle; | 212 operand_scale_ = OperandScale::kSingle; |
| 223 SetOperand(0, operand0); | 213 SetOperand(0, operand0); |
| 224 } | 214 } |
| 215 |
| 225 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1) { | 216 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1) { |
| 226 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2); | 217 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2); |
| 227 bytecode_ = bytecode; | 218 bytecode_ = bytecode; |
| 228 operand_count_ = 2; | 219 operand_count_ = 2; |
| 229 operand_scale_ = OperandScale::kSingle; | 220 operand_scale_ = OperandScale::kSingle; |
| 230 SetOperand(0, operand0); | 221 SetOperand(0, operand0); |
| 231 SetOperand(1, operand1); | 222 SetOperand(1, operand1); |
| 232 } | 223 } |
| 224 |
| 233 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | 225 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
| 234 uint32_t operand2) { | 226 uint32_t operand2) { |
| 235 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); | 227 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); |
| 236 bytecode_ = bytecode; | 228 bytecode_ = bytecode; |
| 237 operand_count_ = 3; | 229 operand_count_ = 3; |
| 238 operand_scale_ = OperandScale::kSingle; | 230 operand_scale_ = OperandScale::kSingle; |
| 239 SetOperand(0, operand0); | 231 SetOperand(0, operand0); |
| 240 SetOperand(1, operand1); | 232 SetOperand(1, operand1); |
| 241 SetOperand(2, operand2); | 233 SetOperand(2, operand2); |
| 242 } | 234 } |
| 243 | 235 |
| 244 // Clone |other|. | |
| 245 void Clone(const BytecodeNode* const other); | |
| 246 | |
| 247 // Print to stream |os|. | 236 // Print to stream |os|. |
| 248 void Print(std::ostream& os) const; | 237 void Print(std::ostream& os) const; |
| 249 | 238 |
| 250 // Transform to a node representing |new_bytecode| which has one | 239 // Transform to a node representing |new_bytecode| which has one |
| 251 // operand more than the current bytecode. | 240 // operand more than the current bytecode. |
| 252 void Transform(Bytecode new_bytecode, uint32_t extra_operand) { | 241 void Transform(Bytecode new_bytecode, uint32_t extra_operand) { |
| 253 DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode), | 242 DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode), |
| 254 Bytecodes::NumberOfOperands(bytecode()) + 1); | 243 Bytecodes::NumberOfOperands(bytecode()) + 1); |
| 255 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 || | 244 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 || |
| 256 Bytecodes::GetOperandType(new_bytecode, 0) == | 245 Bytecodes::GetOperandType(new_bytecode, 0) == |
| 257 Bytecodes::GetOperandType(bytecode(), 0)); | 246 Bytecodes::GetOperandType(bytecode(), 0)); |
| 258 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 || | 247 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 || |
| 259 Bytecodes::GetOperandType(new_bytecode, 1) == | 248 Bytecodes::GetOperandType(new_bytecode, 1) == |
| 260 Bytecodes::GetOperandType(bytecode(), 1)); | 249 Bytecodes::GetOperandType(bytecode(), 1)); |
| 261 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 || | 250 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 || |
| 262 Bytecodes::GetOperandType(new_bytecode, 2) == | 251 Bytecodes::GetOperandType(new_bytecode, 2) == |
| 263 Bytecodes::GetOperandType(bytecode(), 2)); | 252 Bytecodes::GetOperandType(bytecode(), 2)); |
| 264 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4); | 253 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4); |
| 265 | 254 |
| 266 bytecode_ = new_bytecode; | 255 bytecode_ = new_bytecode; |
| 267 operand_count_++; | 256 operand_count_++; |
| 268 SetOperand(operand_count() - 1, extra_operand); | 257 SetOperand(operand_count() - 1, extra_operand); |
| 269 } | 258 } |
| 270 | 259 |
| 271 // Updates the operand at |operand_index| to |operand|. | |
| 272 void UpdateOperand(int operand_index, uint32_t operand) { | |
| 273 DCHECK_LE(operand_index, Bytecodes::NumberOfOperands(bytecode())); | |
| 274 operands_[operand_index] = operand; | |
| 275 if ((Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index) && | |
| 276 Bytecodes::ScaleForSignedOperand(operand) != operand_scale_) || | |
| 277 (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), operand_index) && | |
| 278 Bytecodes::ScaleForUnsignedOperand(operand) != operand_scale_)) { | |
| 279 UpdateScale(); | |
| 280 } | |
| 281 } | |
| 282 | |
| 283 Bytecode bytecode() const { return bytecode_; } | 260 Bytecode bytecode() const { return bytecode_; } |
| 284 | 261 |
| 285 uint32_t operand(int i) const { | 262 uint32_t operand(int i) const { |
| 286 DCHECK_LT(i, operand_count()); | 263 DCHECK_LT(i, operand_count()); |
| 287 return operands_[i]; | 264 return operands_[i]; |
| 288 } | 265 } |
| 289 const uint32_t* operands() const { return operands_; } | 266 const uint32_t* operands() const { return operands_; } |
| 290 | 267 |
| 291 int operand_count() const { return operand_count_; } | 268 int operand_count() const { return operand_count_; } |
| 292 OperandScale operand_scale() const { return operand_scale_; } | 269 OperandScale operand_scale() const { return operand_scale_; } |
| 293 | 270 |
| 294 const BytecodeSourceInfo& source_info() const { return source_info_; } | 271 const BytecodeSourceInfo& source_info() const { return source_info_; } |
| 295 BytecodeSourceInfo* source_info_ptr() { return &source_info_; } | 272 void set_source_info(BytecodeSourceInfo source_info) { |
| 273 source_info_ = source_info; |
| 274 } |
| 296 | 275 |
| 297 bool operator==(const BytecodeNode& other) const; | 276 bool operator==(const BytecodeNode& other) const; |
| 298 bool operator!=(const BytecodeNode& other) const { return !(*this == other); } | 277 bool operator!=(const BytecodeNode& other) const { return !(*this == other); } |
| 299 | 278 |
| 300 private: | 279 private: |
| 301 INLINE(void AttachSourceInfo(BytecodeSourceInfo* source_info)) { | |
| 302 if (source_info && source_info->is_valid()) { | |
| 303 // Statement positions need to be emitted immediately. Expression | |
| 304 // positions can be pushed back until a bytecode is found that can | |
| 305 // throw (if expression position filtering is turned on). We only | |
| 306 // invalidate the existing source position information if it is used. | |
| 307 if (source_info->is_statement() || | |
| 308 !FLAG_ignition_filter_expression_positions || | |
| 309 !Bytecodes::IsWithoutExternalSideEffects(bytecode())) { | |
| 310 source_info_.Clone(*source_info); | |
| 311 source_info->set_invalid(); | |
| 312 } | |
| 313 } | |
| 314 } | |
| 315 | |
| 316 INLINE(void UpdateScaleForOperand(int operand_index, uint32_t operand)) { | 280 INLINE(void UpdateScaleForOperand(int operand_index, uint32_t operand)) { |
| 317 if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) { | 281 if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) { |
| 318 operand_scale_ = | 282 operand_scale_ = |
| 319 std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand)); | 283 std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand)); |
| 320 } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), | 284 } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), |
| 321 operand_index)) { | 285 operand_index)) { |
| 322 operand_scale_ = | 286 operand_scale_ = |
| 323 std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand)); | 287 std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand)); |
| 324 } | 288 } |
| 325 } | 289 } |
| 326 | 290 |
| 327 INLINE(void SetOperand(int operand_index, uint32_t operand)) { | 291 INLINE(void SetOperand(int operand_index, uint32_t operand)) { |
| 328 operands_[operand_index] = operand; | 292 operands_[operand_index] = operand; |
| 329 UpdateScaleForOperand(operand_index, operand); | 293 UpdateScaleForOperand(operand_index, operand); |
| 330 } | 294 } |
| 331 | 295 |
| 332 void UpdateScale() { | |
| 333 operand_scale_ = OperandScale::kSingle; | |
| 334 for (int i = 0; i < operand_count(); i++) { | |
| 335 UpdateScaleForOperand(i, operands_[i]); | |
| 336 } | |
| 337 } | |
| 338 | |
| 339 Bytecode bytecode_; | 296 Bytecode bytecode_; |
| 340 uint32_t operands_[Bytecodes::kMaxOperands]; | 297 uint32_t operands_[Bytecodes::kMaxOperands]; |
| 341 int operand_count_; | 298 int operand_count_; |
| 342 OperandScale operand_scale_; | 299 OperandScale operand_scale_; |
| 343 BytecodeSourceInfo source_info_; | 300 BytecodeSourceInfo source_info_; |
| 344 }; | 301 }; |
| 345 | 302 |
| 346 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 303 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| 347 const BytecodeSourceInfo& info); | 304 const BytecodeSourceInfo& info); |
| 348 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 305 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| 349 const BytecodeNode& node); | 306 const BytecodeNode& node); |
| 350 | 307 |
| 351 } // namespace interpreter | 308 } // namespace interpreter |
| 352 } // namespace internal | 309 } // namespace internal |
| 353 } // namespace v8 | 310 } // namespace v8 |
| 354 | 311 |
| 355 #endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_ | 312 #endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
| OLD | NEW |