| 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 "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
| 10 #include "src/interpreter/bytecodes.h" | 10 #include "src/interpreter/bytecodes.h" |
| 11 #include "src/interpreter/constant-array-builder.h" | 11 #include "src/interpreter/constant-array-builder.h" |
| 12 #include "src/interpreter/handler-table-builder.h" | 12 #include "src/interpreter/handler-table-builder.h" |
| 13 #include "src/interpreter/register-translator.h" | |
| 14 #include "src/interpreter/source-position-table.h" | 13 #include "src/interpreter/source-position-table.h" |
| 15 #include "src/zone-containers.h" | 14 #include "src/zone-containers.h" |
| 16 | 15 |
| 17 namespace v8 { | 16 namespace v8 { |
| 18 namespace internal { | 17 namespace internal { |
| 19 | 18 |
| 20 class Isolate; | 19 class Isolate; |
| 21 | 20 |
| 22 namespace interpreter { | 21 namespace interpreter { |
| 23 | 22 |
| 24 class BytecodeLabel; | 23 class BytecodeLabel; |
| 25 class Register; | 24 class Register; |
| 26 | 25 |
| 27 class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover { | 26 class BytecodeArrayBuilder final : public ZoneObject { |
| 28 public: | 27 public: |
| 29 BytecodeArrayBuilder(Isolate* isolate, Zone* zone, int parameter_count, | 28 BytecodeArrayBuilder(Isolate* isolate, Zone* zone, int parameter_count, |
| 30 int context_count, int locals_count, | 29 int context_count, int locals_count, |
| 31 FunctionLiteral* literal = nullptr); | 30 FunctionLiteral* literal = nullptr); |
| 32 ~BytecodeArrayBuilder(); | 31 ~BytecodeArrayBuilder(); |
| 33 | 32 |
| 34 Handle<BytecodeArray> ToBytecodeArray(); | 33 Handle<BytecodeArray> ToBytecodeArray(); |
| 35 | 34 |
| 36 // Get the number of parameters expected by function. | 35 // Get the number of parameters expected by function. |
| 37 int parameter_count() const { | 36 int parameter_count() const { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 59 | 58 |
| 60 // Returns the number of fixed and temporary registers. | 59 // Returns the number of fixed and temporary registers. |
| 61 int fixed_and_temporary_register_count() const { | 60 int fixed_and_temporary_register_count() const { |
| 62 return fixed_register_count() + temporary_register_count(); | 61 return fixed_register_count() + temporary_register_count(); |
| 63 } | 62 } |
| 64 | 63 |
| 65 int temporary_register_count() const { | 64 int temporary_register_count() const { |
| 66 return temporary_register_allocator()->allocation_count(); | 65 return temporary_register_allocator()->allocation_count(); |
| 67 } | 66 } |
| 68 | 67 |
| 69 // Returns the number of registers used for translating wide | |
| 70 // register operands into byte sized register operands. | |
| 71 int translation_register_count() const { | |
| 72 return RegisterTranslator::RegisterCountAdjustment( | |
| 73 fixed_and_temporary_register_count(), parameter_count()); | |
| 74 } | |
| 75 | |
| 76 Register Parameter(int parameter_index) const; | 68 Register Parameter(int parameter_index) const; |
| 77 | 69 |
| 78 // Return true if the register |reg| represents a parameter or a | 70 // Return true if the register |reg| represents a parameter or a |
| 79 // local. | 71 // local. |
| 80 bool RegisterIsParameterOrLocal(Register reg) const; | 72 bool RegisterIsParameterOrLocal(Register reg) const; |
| 81 | 73 |
| 82 // Returns true if the register |reg| is a live temporary register. | 74 // Returns true if the register |reg| is a live temporary register. |
| 83 bool TemporaryRegisterIsLive(Register reg) const; | 75 bool TemporaryRegisterIsLive(Register reg) const; |
| 84 | 76 |
| 85 // Constant loads to accumulator. | 77 // Constant loads to accumulator. |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 Zone* zone() const { return zone_; } | 261 Zone* zone() const { return zone_; } |
| 270 TemporaryRegisterAllocator* temporary_register_allocator() { | 262 TemporaryRegisterAllocator* temporary_register_allocator() { |
| 271 return &temporary_allocator_; | 263 return &temporary_allocator_; |
| 272 } | 264 } |
| 273 const TemporaryRegisterAllocator* temporary_register_allocator() const { | 265 const TemporaryRegisterAllocator* temporary_register_allocator() const { |
| 274 return &temporary_allocator_; | 266 return &temporary_allocator_; |
| 275 } | 267 } |
| 276 | 268 |
| 277 void EnsureReturn(); | 269 void EnsureReturn(); |
| 278 | 270 |
| 271 static OperandScale OperandSizesToScale( |
| 272 OperandSize size0, OperandSize size1 = OperandSize::kByte, |
| 273 OperandSize size2 = OperandSize::kByte, |
| 274 OperandSize size3 = OperandSize::kByte); |
| 275 |
| 276 static OperandSize SizeForRegisterOperand(Register reg); |
| 277 static OperandSize SizeForSignedOperand(int value); |
| 278 static OperandSize SizeForUnsignedOperand(int value); |
| 279 static OperandSize SizeForUnsignedOperand(size_t value); |
| 280 |
| 281 static uint32_t RegisterOperand(Register reg); |
| 282 static Register RegisterFromOperand(uint32_t operand); |
| 283 static uint32_t SignedOperand(int value, OperandSize size); |
| 284 static uint32_t UnsignedOperand(int value); |
| 285 static uint32_t UnsignedOperand(size_t value); |
| 286 |
| 279 private: | 287 private: |
| 280 class PreviousBytecodeHelper; | 288 class PreviousBytecodeHelper; |
| 281 friend class BytecodeRegisterAllocator; | 289 friend class BytecodeRegisterAllocator; |
| 282 | 290 |
| 283 static Bytecode BytecodeForBinaryOperation(Token::Value op); | 291 static Bytecode BytecodeForBinaryOperation(Token::Value op); |
| 284 static Bytecode BytecodeForCountOperation(Token::Value op); | 292 static Bytecode BytecodeForCountOperation(Token::Value op); |
| 285 static Bytecode BytecodeForCompareOperation(Token::Value op); | 293 static Bytecode BytecodeForCompareOperation(Token::Value op); |
| 286 static Bytecode BytecodeForWideOperands(Bytecode bytecode); | |
| 287 static Bytecode BytecodeForStoreIC(LanguageMode language_mode); | 294 static Bytecode BytecodeForStoreIC(LanguageMode language_mode); |
| 288 static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode); | 295 static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode); |
| 289 static Bytecode BytecodeForLoadGlobal(TypeofMode typeof_mode); | 296 static Bytecode BytecodeForLoadGlobal(TypeofMode typeof_mode); |
| 290 static Bytecode BytecodeForStoreGlobal(LanguageMode language_mode); | 297 static Bytecode BytecodeForStoreGlobal(LanguageMode language_mode); |
| 291 static Bytecode BytecodeForStoreLookupSlot(LanguageMode language_mode); | 298 static Bytecode BytecodeForStoreLookupSlot(LanguageMode language_mode); |
| 292 static Bytecode BytecodeForCreateArguments(CreateArgumentsType type); | 299 static Bytecode BytecodeForCreateArguments(CreateArgumentsType type); |
| 293 static Bytecode BytecodeForDelete(LanguageMode language_mode); | 300 static Bytecode BytecodeForDelete(LanguageMode language_mode); |
| 294 static Bytecode BytecodeForCall(TailCallMode tail_call_mode); | 301 static Bytecode BytecodeForCall(TailCallMode tail_call_mode); |
| 295 | 302 |
| 296 static bool FitsInIdx8Operand(int value); | |
| 297 static bool FitsInIdx8Operand(size_t value); | |
| 298 static bool FitsInImm8Operand(int value); | |
| 299 static bool FitsInIdx16Operand(int value); | |
| 300 static bool FitsInIdx16Operand(size_t value); | |
| 301 static bool FitsInReg8Operand(Register value); | |
| 302 static bool FitsInReg8OperandUntranslated(Register value); | |
| 303 static bool FitsInReg16Operand(Register value); | |
| 304 static bool FitsInReg16OperandUntranslated(Register value); | |
| 305 | |
| 306 // RegisterMover interface. | |
| 307 void MoveRegisterUntranslated(Register from, Register to) override; | |
| 308 | |
| 309 static Bytecode GetJumpWithConstantOperand(Bytecode jump_smi8_operand); | 303 static Bytecode GetJumpWithConstantOperand(Bytecode jump_smi8_operand); |
| 310 static Bytecode GetJumpWithConstantWideOperand(Bytecode jump_smi8_operand); | |
| 311 static Bytecode GetJumpWithToBoolean(Bytecode jump_smi8_operand); | 304 static Bytecode GetJumpWithToBoolean(Bytecode jump_smi8_operand); |
| 312 | 305 |
| 313 template <size_t N> | 306 template <size_t N> |
| 314 INLINE(void Output(Bytecode bytecode, uint32_t(&operands)[N])); | 307 INLINE(void Output(Bytecode bytecode, uint32_t (&operands)[N], |
| 315 void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | 308 OperandScale operand_scale = OperandScale::kSingle)); |
| 316 uint32_t operand2, uint32_t operand3); | |
| 317 void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | |
| 318 uint32_t operand2); | |
| 319 void Output(Bytecode bytecode, uint32_t operand0, uint32_t operand1); | |
| 320 void Output(Bytecode bytecode, uint32_t operand0); | |
| 321 void Output(Bytecode bytecode); | 309 void Output(Bytecode bytecode); |
| 310 void OutputScaled(Bytecode bytecode, OperandScale operand_scale, |
| 311 uint32_t operand0, uint32_t operand1, uint32_t operand2, |
| 312 uint32_t operand3); |
| 313 void OutputScaled(Bytecode bytecode, OperandScale operand_scale, |
| 314 uint32_t operand0, uint32_t operand1, uint32_t operand2); |
| 315 void OutputScaled(Bytecode bytecode, OperandScale operand_scale, |
| 316 uint32_t operand0, uint32_t operand1); |
| 317 void OutputScaled(Bytecode bytecode, OperandScale operand_scale, |
| 318 uint32_t operand0); |
| 322 | 319 |
| 323 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode, | 320 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode, |
| 324 BytecodeLabel* label); | 321 BytecodeLabel* label); |
| 325 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target, | 322 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target, |
| 326 const ZoneVector<uint8_t>::iterator& jump_location); | 323 const ZoneVector<uint8_t>::iterator& jump_location); |
| 327 void PatchIndirectJumpWith8BitOperand( | 324 void PatchIndirectJumpWith8BitOperand( |
| 328 const ZoneVector<uint8_t>::iterator& jump_location, int delta); | 325 const ZoneVector<uint8_t>::iterator& jump_location, int delta); |
| 329 void PatchIndirectJumpWith16BitOperand( | 326 void PatchIndirectJumpWith16BitOperand( |
| 330 const ZoneVector<uint8_t>::iterator& jump_location, int delta); | 327 const ZoneVector<uint8_t>::iterator& jump_location, int delta); |
| 328 void PatchIndirectJumpWith32BitOperand( |
| 329 const ZoneVector<uint8_t>::iterator& jump_location, int delta); |
| 331 | 330 |
| 332 void LeaveBasicBlock(); | 331 void LeaveBasicBlock(); |
| 333 | 332 |
| 334 bool OperandIsValid(Bytecode bytecode, int operand_index, | 333 bool OperandIsValid(Bytecode bytecode, OperandScale operand_scale, |
| 335 uint32_t operand_value) const; | 334 int operand_index, uint32_t operand_value) const; |
| 336 bool RegisterIsValid(Register reg, OperandType reg_type) const; | 335 bool RegisterIsValid(Register reg, OperandSize reg_size) const; |
| 337 | 336 |
| 338 bool LastBytecodeInSameBlock() const; | 337 bool LastBytecodeInSameBlock() const; |
| 339 bool NeedToBooleanCast(); | 338 bool NeedToBooleanCast(); |
| 340 bool IsRegisterInAccumulator(Register reg); | 339 bool IsRegisterInAccumulator(Register reg); |
| 341 | 340 |
| 342 // Set position for return. | 341 // Set position for return. |
| 343 void SetReturnPosition(); | 342 void SetReturnPosition(); |
| 344 | 343 |
| 345 // Gets a constant pool entry for the |object|. | 344 // Gets a constant pool entry for the |object|. |
| 346 size_t GetConstantPoolEntry(Handle<Object> object); | 345 size_t GetConstantPoolEntry(Handle<Object> object); |
| 347 | 346 |
| 348 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } | 347 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } |
| 349 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; } | 348 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; } |
| 350 Isolate* isolate() const { return isolate_; } | 349 Isolate* isolate() const { return isolate_; } |
| 351 ConstantArrayBuilder* constant_array_builder() { | 350 ConstantArrayBuilder* constant_array_builder() { |
| 352 return &constant_array_builder_; | 351 return &constant_array_builder_; |
| 353 } | 352 } |
| 354 const ConstantArrayBuilder* constant_array_builder() const { | 353 const ConstantArrayBuilder* constant_array_builder() const { |
| 355 return &constant_array_builder_; | 354 return &constant_array_builder_; |
| 356 } | 355 } |
| 357 HandlerTableBuilder* handler_table_builder() { | 356 HandlerTableBuilder* handler_table_builder() { |
| 358 return &handler_table_builder_; | 357 return &handler_table_builder_; |
| 359 } | 358 } |
| 360 SourcePositionTableBuilder* source_position_table_builder() { | 359 SourcePositionTableBuilder* source_position_table_builder() { |
| 361 return &source_position_table_builder_; | 360 return &source_position_table_builder_; |
| 362 } | 361 } |
| 363 RegisterTranslator* register_translator() { return ®ister_translator_; } | |
| 364 | 362 |
| 365 Isolate* isolate_; | 363 Isolate* isolate_; |
| 366 Zone* zone_; | 364 Zone* zone_; |
| 367 ZoneVector<uint8_t> bytecodes_; | 365 ZoneVector<uint8_t> bytecodes_; |
| 368 bool bytecode_generated_; | 366 bool bytecode_generated_; |
| 369 ConstantArrayBuilder constant_array_builder_; | 367 ConstantArrayBuilder constant_array_builder_; |
| 370 HandlerTableBuilder handler_table_builder_; | 368 HandlerTableBuilder handler_table_builder_; |
| 371 SourcePositionTableBuilder source_position_table_builder_; | 369 SourcePositionTableBuilder source_position_table_builder_; |
| 372 size_t last_block_end_; | 370 size_t last_block_end_; |
| 373 size_t last_bytecode_start_; | 371 size_t last_bytecode_start_; |
| 374 bool exit_seen_in_block_; | 372 bool exit_seen_in_block_; |
| 375 int unbound_jumps_; | 373 int unbound_jumps_; |
| 376 int parameter_count_; | 374 int parameter_count_; |
| 377 int local_register_count_; | 375 int local_register_count_; |
| 378 int context_register_count_; | 376 int context_register_count_; |
| 379 int return_position_; | 377 int return_position_; |
| 380 TemporaryRegisterAllocator temporary_allocator_; | 378 TemporaryRegisterAllocator temporary_allocator_; |
| 381 RegisterTranslator register_translator_; | |
| 382 | 379 |
| 383 DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder); | 380 DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder); |
| 384 }; | 381 }; |
| 385 | 382 |
| 386 | 383 |
| 387 // A label representing a branch target in a bytecode array. When a | 384 // A label representing a branch target in a bytecode array. When a |
| 388 // label is bound, it represents a known position in the bytecode | 385 // label is bound, it represents a known position in the bytecode |
| 389 // array. For labels that are forward references there can be at most | 386 // array. For labels that are forward references there can be at most |
| 390 // one reference whilst it is unbound. | 387 // one reference whilst it is unbound. |
| 391 class BytecodeLabel final { | 388 class BytecodeLabel final { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 422 size_t offset_; | 419 size_t offset_; |
| 423 | 420 |
| 424 friend class BytecodeArrayBuilder; | 421 friend class BytecodeArrayBuilder; |
| 425 }; | 422 }; |
| 426 | 423 |
| 427 } // namespace interpreter | 424 } // namespace interpreter |
| 428 } // namespace internal | 425 } // namespace internal |
| 429 } // namespace v8 | 426 } // namespace v8 |
| 430 | 427 |
| 431 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 428 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
| OLD | NEW |