| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_FLOW_GRAPH_COMPILER_H_ | 5 #ifndef VM_FLOW_GRAPH_COMPILER_H_ |
| 6 #define VM_FLOW_GRAPH_COMPILER_H_ | 6 #define VM_FLOW_GRAPH_COMPILER_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/code_descriptors.h" | 10 #include "vm/code_descriptors.h" |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 212 |
| 213 DISALLOW_COPY_AND_ASSIGN(SlowPathCode); | 213 DISALLOW_COPY_AND_ASSIGN(SlowPathCode); |
| 214 }; | 214 }; |
| 215 | 215 |
| 216 | 216 |
| 217 class MegamorphicSlowPath : public SlowPathCode { | 217 class MegamorphicSlowPath : public SlowPathCode { |
| 218 public: | 218 public: |
| 219 MegamorphicSlowPath(const ICData& ic_data, | 219 MegamorphicSlowPath(const ICData& ic_data, |
| 220 intptr_t argument_count, | 220 intptr_t argument_count, |
| 221 intptr_t deopt_id, | 221 intptr_t deopt_id, |
| 222 intptr_t token_pos, | 222 TokenDescriptor token_pos, |
| 223 LocationSummary* locs, | 223 LocationSummary* locs, |
| 224 intptr_t try_index) | 224 intptr_t try_index) |
| 225 : SlowPathCode(), | 225 : SlowPathCode(), |
| 226 ic_data_(ic_data), | 226 ic_data_(ic_data), |
| 227 argument_count_(argument_count), | 227 argument_count_(argument_count), |
| 228 deopt_id_(deopt_id), | 228 deopt_id_(deopt_id), |
| 229 token_pos_(token_pos), | 229 token_pos_(token_pos), |
| 230 locs_(locs), | 230 locs_(locs), |
| 231 try_index_(try_index) {} | 231 try_index_(try_index) {} |
| 232 virtual ~MegamorphicSlowPath() {} | 232 virtual ~MegamorphicSlowPath() {} |
| 233 | 233 |
| 234 private: | 234 private: |
| 235 virtual void EmitNativeCode(FlowGraphCompiler* comp); | 235 virtual void EmitNativeCode(FlowGraphCompiler* comp); |
| 236 | 236 |
| 237 const ICData& ic_data_; | 237 const ICData& ic_data_; |
| 238 intptr_t argument_count_; | 238 intptr_t argument_count_; |
| 239 intptr_t deopt_id_; | 239 intptr_t deopt_id_; |
| 240 intptr_t token_pos_; | 240 TokenDescriptor token_pos_; |
| 241 LocationSummary* locs_; | 241 LocationSummary* locs_; |
| 242 const intptr_t try_index_; // For try/catch ranges. | 242 const intptr_t try_index_; // For try/catch ranges. |
| 243 | 243 |
| 244 DISALLOW_COPY_AND_ASSIGN(MegamorphicSlowPath); | 244 DISALLOW_COPY_AND_ASSIGN(MegamorphicSlowPath); |
| 245 }; | 245 }; |
| 246 | 246 |
| 247 | 247 |
| 248 struct CidTarget { | 248 struct CidTarget { |
| 249 intptr_t cid; | 249 intptr_t cid; |
| 250 Function* target; | 250 Function* target; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 void CompileGraph(); | 358 void CompileGraph(); |
| 359 | 359 |
| 360 void VisitBlocks(); | 360 void VisitBlocks(); |
| 361 | 361 |
| 362 // Bail out of the flow graph compiler. Does not return to the caller. | 362 // Bail out of the flow graph compiler. Does not return to the caller. |
| 363 void Bailout(const char* reason); | 363 void Bailout(const char* reason); |
| 364 | 364 |
| 365 // Returns 'true' if regular code generation should be skipped. | 365 // Returns 'true' if regular code generation should be skipped. |
| 366 bool TryIntrinsify(); | 366 bool TryIntrinsify(); |
| 367 | 367 |
| 368 void GenerateRuntimeCall(intptr_t token_pos, | 368 void GenerateRuntimeCall(TokenDescriptor token_pos, |
| 369 intptr_t deopt_id, | 369 intptr_t deopt_id, |
| 370 const RuntimeEntry& entry, | 370 const RuntimeEntry& entry, |
| 371 intptr_t argument_count, | 371 intptr_t argument_count, |
| 372 LocationSummary* locs); | 372 LocationSummary* locs); |
| 373 | 373 |
| 374 void GenerateCall(intptr_t token_pos, | 374 void GenerateCall(TokenDescriptor token_pos, |
| 375 const StubEntry& stub_entry, | 375 const StubEntry& stub_entry, |
| 376 RawPcDescriptors::Kind kind, | 376 RawPcDescriptors::Kind kind, |
| 377 LocationSummary* locs); | 377 LocationSummary* locs); |
| 378 | 378 |
| 379 void GenerateDartCall(intptr_t deopt_id, | 379 void GenerateDartCall(intptr_t deopt_id, |
| 380 intptr_t token_pos, | 380 TokenDescriptor token_pos, |
| 381 const StubEntry& stub_entry, | 381 const StubEntry& stub_entry, |
| 382 RawPcDescriptors::Kind kind, | 382 RawPcDescriptors::Kind kind, |
| 383 LocationSummary* locs); | 383 LocationSummary* locs); |
| 384 | 384 |
| 385 void GenerateAssertAssignable(intptr_t token_pos, | 385 void GenerateAssertAssignable(TokenDescriptor token_pos, |
| 386 intptr_t deopt_id, | 386 intptr_t deopt_id, |
| 387 const AbstractType& dst_type, | 387 const AbstractType& dst_type, |
| 388 const String& dst_name, | 388 const String& dst_name, |
| 389 LocationSummary* locs); | 389 LocationSummary* locs); |
| 390 | 390 |
| 391 void GenerateInstanceOf(intptr_t token_pos, | 391 void GenerateInstanceOf(TokenDescriptor token_pos, |
| 392 intptr_t deopt_id, | 392 intptr_t deopt_id, |
| 393 const AbstractType& type, | 393 const AbstractType& type, |
| 394 bool negate_result, | 394 bool negate_result, |
| 395 LocationSummary* locs); | 395 LocationSummary* locs); |
| 396 | 396 |
| 397 void GenerateInstanceCall(intptr_t deopt_id, | 397 void GenerateInstanceCall(intptr_t deopt_id, |
| 398 intptr_t token_pos, | 398 TokenDescriptor token_pos, |
| 399 intptr_t argument_count, | 399 intptr_t argument_count, |
| 400 LocationSummary* locs, | 400 LocationSummary* locs, |
| 401 const ICData& ic_data); | 401 const ICData& ic_data); |
| 402 | 402 |
| 403 void GenerateStaticCall(intptr_t deopt_id, | 403 void GenerateStaticCall(intptr_t deopt_id, |
| 404 intptr_t token_pos, | 404 TokenDescriptor token_pos, |
| 405 const Function& function, | 405 const Function& function, |
| 406 intptr_t argument_count, | 406 intptr_t argument_count, |
| 407 const Array& argument_names, | 407 const Array& argument_names, |
| 408 LocationSummary* locs, | 408 LocationSummary* locs, |
| 409 const ICData& ic_data); | 409 const ICData& ic_data); |
| 410 | 410 |
| 411 void GenerateNumberTypeCheck(Register kClassIdReg, | 411 void GenerateNumberTypeCheck(Register kClassIdReg, |
| 412 const AbstractType& type, | 412 const AbstractType& type, |
| 413 Label* is_instance_lbl, | 413 Label* is_instance_lbl, |
| 414 Label* is_not_instance_lbl); | 414 Label* is_not_instance_lbl); |
| 415 void GenerateStringTypeCheck(Register kClassIdReg, | 415 void GenerateStringTypeCheck(Register kClassIdReg, |
| 416 Label* is_instance_lbl, | 416 Label* is_instance_lbl, |
| 417 Label* is_not_instance_lbl); | 417 Label* is_not_instance_lbl); |
| 418 void GenerateListTypeCheck(Register kClassIdReg, | 418 void GenerateListTypeCheck(Register kClassIdReg, |
| 419 Label* is_instance_lbl); | 419 Label* is_instance_lbl); |
| 420 | 420 |
| 421 void EmitComment(Instruction* instr); | 421 void EmitComment(Instruction* instr); |
| 422 | 422 |
| 423 bool NeedsEdgeCounter(TargetEntryInstr* block); | 423 bool NeedsEdgeCounter(TargetEntryInstr* block); |
| 424 | 424 |
| 425 void EmitEdgeCounter(intptr_t edge_id); | 425 void EmitEdgeCounter(intptr_t edge_id); |
| 426 | 426 |
| 427 void EmitOptimizedInstanceCall(const StubEntry& stub_entry, | 427 void EmitOptimizedInstanceCall(const StubEntry& stub_entry, |
| 428 const ICData& ic_data, | 428 const ICData& ic_data, |
| 429 intptr_t argument_count, | 429 intptr_t argument_count, |
| 430 intptr_t deopt_id, | 430 intptr_t deopt_id, |
| 431 intptr_t token_pos, | 431 TokenDescriptor token_pos, |
| 432 LocationSummary* locs); | 432 LocationSummary* locs); |
| 433 | 433 |
| 434 void EmitInstanceCall(const StubEntry& stub_entry, | 434 void EmitInstanceCall(const StubEntry& stub_entry, |
| 435 const ICData& ic_data, | 435 const ICData& ic_data, |
| 436 intptr_t argument_count, | 436 intptr_t argument_count, |
| 437 intptr_t deopt_id, | 437 intptr_t deopt_id, |
| 438 intptr_t token_pos, | 438 TokenDescriptor token_pos, |
| 439 LocationSummary* locs); | 439 LocationSummary* locs); |
| 440 | 440 |
| 441 void EmitPolymorphicInstanceCall(const ICData& ic_data, | 441 void EmitPolymorphicInstanceCall(const ICData& ic_data, |
| 442 intptr_t argument_count, | 442 intptr_t argument_count, |
| 443 const Array& argument_names, | 443 const Array& argument_names, |
| 444 intptr_t deopt_id, | 444 intptr_t deopt_id, |
| 445 intptr_t token_pos, | 445 TokenDescriptor token_pos, |
| 446 LocationSummary* locs); | 446 LocationSummary* locs); |
| 447 | 447 |
| 448 // Pass a value for try-index where block is not available (e.g. slow path). | 448 // Pass a value for try-index where block is not available (e.g. slow path). |
| 449 void EmitMegamorphicInstanceCall( | 449 void EmitMegamorphicInstanceCall( |
| 450 const ICData& ic_data, | 450 const ICData& ic_data, |
| 451 intptr_t argument_count, | 451 intptr_t argument_count, |
| 452 intptr_t deopt_id, | 452 intptr_t deopt_id, |
| 453 intptr_t token_pos, | 453 TokenDescriptor token_pos, |
| 454 LocationSummary* locs, | 454 LocationSummary* locs, |
| 455 intptr_t try_index = CatchClauseNode::kInvalidTryIndex); | 455 intptr_t try_index = CatchClauseNode::kInvalidTryIndex); |
| 456 | 456 |
| 457 void EmitSwitchableInstanceCall(const ICData& ic_data, | 457 void EmitSwitchableInstanceCall(const ICData& ic_data, |
| 458 intptr_t argument_count, | 458 intptr_t argument_count, |
| 459 intptr_t deopt_id, | 459 intptr_t deopt_id, |
| 460 intptr_t token_pos, | 460 TokenDescriptor token_pos, |
| 461 LocationSummary* locs); | 461 LocationSummary* locs); |
| 462 | 462 |
| 463 void EmitTestAndCall(const ICData& ic_data, | 463 void EmitTestAndCall(const ICData& ic_data, |
| 464 intptr_t arg_count, | 464 intptr_t arg_count, |
| 465 const Array& arg_names, | 465 const Array& arg_names, |
| 466 Label* failed, | 466 Label* failed, |
| 467 Label* match_found, | 467 Label* match_found, |
| 468 intptr_t deopt_id, | 468 intptr_t deopt_id, |
| 469 intptr_t token_index, | 469 TokenDescriptor token_index, |
| 470 LocationSummary* locs); | 470 LocationSummary* locs); |
| 471 | 471 |
| 472 Condition EmitEqualityRegConstCompare(Register reg, | 472 Condition EmitEqualityRegConstCompare(Register reg, |
| 473 const Object& obj, | 473 const Object& obj, |
| 474 bool needs_number_check, | 474 bool needs_number_check, |
| 475 intptr_t token_pos); | 475 TokenDescriptor token_pos); |
| 476 Condition EmitEqualityRegRegCompare(Register left, | 476 Condition EmitEqualityRegRegCompare(Register left, |
| 477 Register right, | 477 Register right, |
| 478 bool needs_number_check, | 478 bool needs_number_check, |
| 479 intptr_t token_pos); | 479 TokenDescriptor token_pos); |
| 480 | 480 |
| 481 void EmitTrySync(Instruction* instr, intptr_t try_index); | 481 void EmitTrySync(Instruction* instr, intptr_t try_index); |
| 482 | 482 |
| 483 intptr_t StackSize() const; | 483 intptr_t StackSize() const; |
| 484 | 484 |
| 485 // Returns assembler label associated with the given block entry. | 485 // Returns assembler label associated with the given block entry. |
| 486 Label* GetJumpLabel(BlockEntryInstr* block_entry) const; | 486 Label* GetJumpLabel(BlockEntryInstr* block_entry) const; |
| 487 bool WasCompacted(BlockEntryInstr* block_entry) const; | 487 bool WasCompacted(BlockEntryInstr* block_entry) const; |
| 488 | 488 |
| 489 // Returns the label of the fall-through of the current block. | 489 // Returns the label of the fall-through of the current block. |
| 490 Label* NextNonEmptyLabel() const; | 490 Label* NextNonEmptyLabel() const; |
| 491 | 491 |
| 492 // Returns true if there is a next block after the current one in | 492 // Returns true if there is a next block after the current one in |
| 493 // the block order and if it is the given block. | 493 // the block order and if it is the given block. |
| 494 bool CanFallThroughTo(BlockEntryInstr* block_entry) const; | 494 bool CanFallThroughTo(BlockEntryInstr* block_entry) const; |
| 495 | 495 |
| 496 // Return true-, false- and fall-through label for a branch instruction. | 496 // Return true-, false- and fall-through label for a branch instruction. |
| 497 BranchLabels CreateBranchLabels(BranchInstr* branch) const; | 497 BranchLabels CreateBranchLabels(BranchInstr* branch) const; |
| 498 | 498 |
| 499 void AddExceptionHandler(intptr_t try_index, | 499 void AddExceptionHandler(intptr_t try_index, |
| 500 intptr_t outer_try_index, | 500 intptr_t outer_try_index, |
| 501 intptr_t pc_offset, | 501 intptr_t pc_offset, |
| 502 const Array& handler_types, | 502 const Array& handler_types, |
| 503 bool needs_stacktrace); | 503 bool needs_stacktrace); |
| 504 void SetNeedsStacktrace(intptr_t try_index); | 504 void SetNeedsStacktrace(intptr_t try_index); |
| 505 void AddCurrentDescriptor(RawPcDescriptors::Kind kind, | 505 void AddCurrentDescriptor(RawPcDescriptors::Kind kind, |
| 506 intptr_t deopt_id, | 506 intptr_t deopt_id, |
| 507 intptr_t token_pos); | 507 TokenDescriptor token_pos); |
| 508 | 508 |
| 509 void RecordSafepoint(LocationSummary* locs); | 509 void RecordSafepoint(LocationSummary* locs); |
| 510 | 510 |
| 511 Label* AddDeoptStub(intptr_t deopt_id, | 511 Label* AddDeoptStub(intptr_t deopt_id, |
| 512 ICData::DeoptReasonId reason, | 512 ICData::DeoptReasonId reason, |
| 513 uint32_t flags = 0); | 513 uint32_t flags = 0); |
| 514 | 514 |
| 515 void AddDeoptIndexAtCall(intptr_t deopt_id, intptr_t token_pos); | 515 void AddDeoptIndexAtCall(intptr_t deopt_id, TokenDescriptor token_pos); |
| 516 | 516 |
| 517 void AddSlowPathCode(SlowPathCode* slow_path); | 517 void AddSlowPathCode(SlowPathCode* slow_path); |
| 518 | 518 |
| 519 void FinalizeExceptionHandlers(const Code& code); | 519 void FinalizeExceptionHandlers(const Code& code); |
| 520 void FinalizePcDescriptors(const Code& code); | 520 void FinalizePcDescriptors(const Code& code); |
| 521 RawArray* CreateDeoptInfo(Assembler* assembler); | 521 RawArray* CreateDeoptInfo(Assembler* assembler); |
| 522 void FinalizeStackmaps(const Code& code); | 522 void FinalizeStackmaps(const Code& code); |
| 523 void FinalizeVarDescriptors(const Code& code); | 523 void FinalizeVarDescriptors(const Code& code); |
| 524 void FinalizeStaticCallTargetsTable(const Code& code); | 524 void FinalizeStaticCallTargetsTable(const Code& code); |
| 525 | 525 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 void EmitInstructionPrologue(Instruction* instr); | 598 void EmitInstructionPrologue(Instruction* instr); |
| 599 void EmitInstructionEpilogue(Instruction* instr); | 599 void EmitInstructionEpilogue(Instruction* instr); |
| 600 | 600 |
| 601 // Emit code to load a Value into register 'dst'. | 601 // Emit code to load a Value into register 'dst'. |
| 602 void LoadValue(Register dst, Value* value); | 602 void LoadValue(Register dst, Value* value); |
| 603 | 603 |
| 604 void EmitOptimizedStaticCall(const Function& function, | 604 void EmitOptimizedStaticCall(const Function& function, |
| 605 const Array& arguments_descriptor, | 605 const Array& arguments_descriptor, |
| 606 intptr_t argument_count, | 606 intptr_t argument_count, |
| 607 intptr_t deopt_id, | 607 intptr_t deopt_id, |
| 608 intptr_t token_pos, | 608 TokenDescriptor token_pos, |
| 609 LocationSummary* locs); | 609 LocationSummary* locs); |
| 610 | 610 |
| 611 void EmitUnoptimizedStaticCall(intptr_t argument_count, | 611 void EmitUnoptimizedStaticCall(intptr_t argument_count, |
| 612 intptr_t deopt_id, | 612 intptr_t deopt_id, |
| 613 intptr_t token_pos, | 613 TokenDescriptor token_pos, |
| 614 LocationSummary* locs, | 614 LocationSummary* locs, |
| 615 const ICData& ic_data); | 615 const ICData& ic_data); |
| 616 | 616 |
| 617 // Type checking helper methods. | 617 // Type checking helper methods. |
| 618 void CheckClassIds(Register class_id_reg, | 618 void CheckClassIds(Register class_id_reg, |
| 619 const GrowableArray<intptr_t>& class_ids, | 619 const GrowableArray<intptr_t>& class_ids, |
| 620 Label* is_instance_lbl, | 620 Label* is_instance_lbl, |
| 621 Label* is_not_instance_lbl); | 621 Label* is_not_instance_lbl); |
| 622 | 622 |
| 623 RawSubtypeTestCache* GenerateInlineInstanceof(intptr_t token_pos, | 623 RawSubtypeTestCache* GenerateInlineInstanceof(TokenDescriptor token_pos, |
| 624 const AbstractType& type, | 624 const AbstractType& type, |
| 625 Label* is_instance_lbl, | 625 Label* is_instance_lbl, |
| 626 Label* is_not_instance_lbl); | 626 Label* is_not_instance_lbl); |
| 627 | 627 |
| 628 RawSubtypeTestCache* GenerateInstantiatedTypeWithArgumentsTest( | 628 RawSubtypeTestCache* GenerateInstantiatedTypeWithArgumentsTest( |
| 629 intptr_t token_pos, | 629 TokenDescriptor token_pos, |
| 630 const AbstractType& dst_type, | 630 const AbstractType& dst_type, |
| 631 Label* is_instance_lbl, | 631 Label* is_instance_lbl, |
| 632 Label* is_not_instance_lbl); | 632 Label* is_not_instance_lbl); |
| 633 | 633 |
| 634 bool GenerateInstantiatedTypeNoArgumentsTest(intptr_t token_pos, | 634 bool GenerateInstantiatedTypeNoArgumentsTest(TokenDescriptor token_pos, |
| 635 const AbstractType& dst_type, | 635 const AbstractType& dst_type, |
| 636 Label* is_instance_lbl, | 636 Label* is_instance_lbl, |
| 637 Label* is_not_instance_lbl); | 637 Label* is_not_instance_lbl); |
| 638 | 638 |
| 639 RawSubtypeTestCache* GenerateUninstantiatedTypeTest( | 639 RawSubtypeTestCache* GenerateUninstantiatedTypeTest( |
| 640 intptr_t token_pos, | 640 TokenDescriptor token_pos, |
| 641 const AbstractType& dst_type, | 641 const AbstractType& dst_type, |
| 642 Label* is_instance_lbl, | 642 Label* is_instance_lbl, |
| 643 Label* is_not_instance_label); | 643 Label* is_not_instance_label); |
| 644 | 644 |
| 645 RawSubtypeTestCache* GenerateSubtype1TestCacheLookup( | 645 RawSubtypeTestCache* GenerateSubtype1TestCacheLookup( |
| 646 intptr_t token_pos, | 646 TokenDescriptor token_pos, |
| 647 const Class& type_class, | 647 const Class& type_class, |
| 648 Label* is_instance_lbl, | 648 Label* is_instance_lbl, |
| 649 Label* is_not_instance_lbl); | 649 Label* is_not_instance_lbl); |
| 650 | 650 |
| 651 enum TypeTestStubKind { | 651 enum TypeTestStubKind { |
| 652 kTestTypeOneArg, | 652 kTestTypeOneArg, |
| 653 kTestTypeTwoArgs, | 653 kTestTypeTwoArgs, |
| 654 kTestTypeThreeArgs, | 654 kTestTypeThreeArgs, |
| 655 }; | 655 }; |
| 656 | 656 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 Array& inlined_code_intervals_; | 781 Array& inlined_code_intervals_; |
| 782 const GrowableArray<const Function*>& inline_id_to_function_; | 782 const GrowableArray<const Function*>& inline_id_to_function_; |
| 783 const GrowableArray<intptr_t>& caller_inline_id_; | 783 const GrowableArray<intptr_t>& caller_inline_id_; |
| 784 | 784 |
| 785 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); | 785 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); |
| 786 }; | 786 }; |
| 787 | 787 |
| 788 } // namespace dart | 788 } // namespace dart |
| 789 | 789 |
| 790 #endif // VM_FLOW_GRAPH_COMPILER_H_ | 790 #endif // VM_FLOW_GRAPH_COMPILER_H_ |
| OLD | NEW |