| 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 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 void CompileGraph(); | 360 void CompileGraph(); |
| 361 | 361 |
| 362 void VisitBlocks(); | 362 void VisitBlocks(); |
| 363 | 363 |
| 364 // Bail out of the flow graph compiler. Does not return to the caller. | 364 // Bail out of the flow graph compiler. Does not return to the caller. |
| 365 void Bailout(const char* reason); | 365 void Bailout(const char* reason); |
| 366 | 366 |
| 367 // Returns 'true' if regular code generation should be skipped. | 367 // Returns 'true' if regular code generation should be skipped. |
| 368 bool TryIntrinsify(); | 368 bool TryIntrinsify(); |
| 369 | 369 |
| 370 void GenerateAssertAssignable(TokenPosition token_pos, |
| 371 intptr_t deopt_id, |
| 372 const AbstractType& dst_type, |
| 373 const String& dst_name, |
| 374 LocationSummary* locs); |
| 375 |
| 376 // DBC emits calls very differently from all other architectures due to its |
| 377 // interpreted nature. |
| 378 #if !defined(TARGET_ARCH_DBC) |
| 370 void GenerateRuntimeCall(TokenPosition token_pos, | 379 void GenerateRuntimeCall(TokenPosition token_pos, |
| 371 intptr_t deopt_id, | 380 intptr_t deopt_id, |
| 372 const RuntimeEntry& entry, | 381 const RuntimeEntry& entry, |
| 373 intptr_t argument_count, | 382 intptr_t argument_count, |
| 374 LocationSummary* locs); | 383 LocationSummary* locs); |
| 375 | 384 |
| 376 void GenerateCall(TokenPosition token_pos, | 385 void GenerateCall(TokenPosition token_pos, |
| 377 const StubEntry& stub_entry, | 386 const StubEntry& stub_entry, |
| 378 RawPcDescriptors::Kind kind, | 387 RawPcDescriptors::Kind kind, |
| 379 LocationSummary* locs); | 388 LocationSummary* locs); |
| 380 | 389 |
| 381 void GenerateDartCall(intptr_t deopt_id, | 390 void GenerateDartCall(intptr_t deopt_id, |
| 382 TokenPosition token_pos, | 391 TokenPosition token_pos, |
| 383 const StubEntry& stub_entry, | 392 const StubEntry& stub_entry, |
| 384 RawPcDescriptors::Kind kind, | 393 RawPcDescriptors::Kind kind, |
| 385 LocationSummary* locs); | 394 LocationSummary* locs); |
| 386 void GenerateStaticDartCall(intptr_t deopt_id, | 395 void GenerateStaticDartCall(intptr_t deopt_id, |
| 387 TokenPosition token_pos, | 396 TokenPosition token_pos, |
| 388 const StubEntry& stub_entry, | 397 const StubEntry& stub_entry, |
| 389 RawPcDescriptors::Kind kind, | 398 RawPcDescriptors::Kind kind, |
| 390 LocationSummary* locs, | 399 LocationSummary* locs, |
| 391 const Function& target); | 400 const Function& target); |
| 392 | 401 |
| 393 void GenerateAssertAssignable(TokenPosition token_pos, | |
| 394 intptr_t deopt_id, | |
| 395 const AbstractType& dst_type, | |
| 396 const String& dst_name, | |
| 397 LocationSummary* locs); | |
| 398 | |
| 399 void GenerateInstanceOf(TokenPosition token_pos, | 402 void GenerateInstanceOf(TokenPosition token_pos, |
| 400 intptr_t deopt_id, | 403 intptr_t deopt_id, |
| 401 const AbstractType& type, | 404 const AbstractType& type, |
| 402 bool negate_result, | 405 bool negate_result, |
| 403 LocationSummary* locs); | 406 LocationSummary* locs); |
| 404 | 407 |
| 405 void GenerateInstanceCall(intptr_t deopt_id, | 408 void GenerateInstanceCall(intptr_t deopt_id, |
| 406 TokenPosition token_pos, | 409 TokenPosition token_pos, |
| 407 intptr_t argument_count, | 410 intptr_t argument_count, |
| 408 LocationSummary* locs, | 411 LocationSummary* locs, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 419 void GenerateNumberTypeCheck(Register kClassIdReg, | 422 void GenerateNumberTypeCheck(Register kClassIdReg, |
| 420 const AbstractType& type, | 423 const AbstractType& type, |
| 421 Label* is_instance_lbl, | 424 Label* is_instance_lbl, |
| 422 Label* is_not_instance_lbl); | 425 Label* is_not_instance_lbl); |
| 423 void GenerateStringTypeCheck(Register kClassIdReg, | 426 void GenerateStringTypeCheck(Register kClassIdReg, |
| 424 Label* is_instance_lbl, | 427 Label* is_instance_lbl, |
| 425 Label* is_not_instance_lbl); | 428 Label* is_not_instance_lbl); |
| 426 void GenerateListTypeCheck(Register kClassIdReg, | 429 void GenerateListTypeCheck(Register kClassIdReg, |
| 427 Label* is_instance_lbl); | 430 Label* is_instance_lbl); |
| 428 | 431 |
| 429 void EmitComment(Instruction* instr); | |
| 430 | |
| 431 bool NeedsEdgeCounter(TargetEntryInstr* block); | |
| 432 | |
| 433 void EmitEdgeCounter(intptr_t edge_id); | |
| 434 | |
| 435 void EmitOptimizedInstanceCall(const StubEntry& stub_entry, | 432 void EmitOptimizedInstanceCall(const StubEntry& stub_entry, |
| 436 const ICData& ic_data, | 433 const ICData& ic_data, |
| 437 intptr_t argument_count, | 434 intptr_t argument_count, |
| 438 intptr_t deopt_id, | 435 intptr_t deopt_id, |
| 439 TokenPosition token_pos, | 436 TokenPosition token_pos, |
| 440 LocationSummary* locs); | 437 LocationSummary* locs); |
| 441 | 438 |
| 442 void EmitInstanceCall(const StubEntry& stub_entry, | 439 void EmitInstanceCall(const StubEntry& stub_entry, |
| 443 const ICData& ic_data, | 440 const ICData& ic_data, |
| 444 intptr_t argument_count, | 441 intptr_t argument_count, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 | 479 |
| 483 Condition EmitEqualityRegConstCompare(Register reg, | 480 Condition EmitEqualityRegConstCompare(Register reg, |
| 484 const Object& obj, | 481 const Object& obj, |
| 485 bool needs_number_check, | 482 bool needs_number_check, |
| 486 TokenPosition token_pos); | 483 TokenPosition token_pos); |
| 487 Condition EmitEqualityRegRegCompare(Register left, | 484 Condition EmitEqualityRegRegCompare(Register left, |
| 488 Register right, | 485 Register right, |
| 489 bool needs_number_check, | 486 bool needs_number_check, |
| 490 TokenPosition token_pos); | 487 TokenPosition token_pos); |
| 491 | 488 |
| 489 bool NeedsEdgeCounter(TargetEntryInstr* block); |
| 490 |
| 491 void EmitEdgeCounter(intptr_t edge_id); |
| 492 #endif // !defined(TARGET_ARCH_DBC) |
| 493 |
| 492 void EmitTrySync(Instruction* instr, intptr_t try_index); | 494 void EmitTrySync(Instruction* instr, intptr_t try_index); |
| 493 | 495 |
| 496 void EmitComment(Instruction* instr); |
| 497 |
| 494 intptr_t StackSize() const; | 498 intptr_t StackSize() const; |
| 495 | 499 |
| 496 // Returns assembler label associated with the given block entry. | 500 // Returns assembler label associated with the given block entry. |
| 497 Label* GetJumpLabel(BlockEntryInstr* block_entry) const; | 501 Label* GetJumpLabel(BlockEntryInstr* block_entry) const; |
| 498 bool WasCompacted(BlockEntryInstr* block_entry) const; | 502 bool WasCompacted(BlockEntryInstr* block_entry) const; |
| 499 | 503 |
| 500 // Returns the label of the fall-through of the current block. | 504 // Returns the label of the fall-through of the current block. |
| 501 Label* NextNonEmptyLabel() const; | 505 Label* NextNonEmptyLabel() const; |
| 502 | 506 |
| 503 // Returns true if there is a next block after the current one in | 507 // Returns true if there is a next block after the current one in |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 intptr_t deopt_id, | 634 intptr_t deopt_id, |
| 631 TokenPosition token_pos, | 635 TokenPosition token_pos, |
| 632 LocationSummary* locs); | 636 LocationSummary* locs); |
| 633 | 637 |
| 634 void EmitUnoptimizedStaticCall(intptr_t argument_count, | 638 void EmitUnoptimizedStaticCall(intptr_t argument_count, |
| 635 intptr_t deopt_id, | 639 intptr_t deopt_id, |
| 636 TokenPosition token_pos, | 640 TokenPosition token_pos, |
| 637 LocationSummary* locs, | 641 LocationSummary* locs, |
| 638 const ICData& ic_data); | 642 const ICData& ic_data); |
| 639 | 643 |
| 644 // DBC handles type tests differently from all other architectures due |
| 645 // to its interpreted nature. |
| 646 #if !defined(TARGET_ARCH_DBC) |
| 640 // Type checking helper methods. | 647 // Type checking helper methods. |
| 641 void CheckClassIds(Register class_id_reg, | 648 void CheckClassIds(Register class_id_reg, |
| 642 const GrowableArray<intptr_t>& class_ids, | 649 const GrowableArray<intptr_t>& class_ids, |
| 643 Label* is_instance_lbl, | 650 Label* is_instance_lbl, |
| 644 Label* is_not_instance_lbl); | 651 Label* is_not_instance_lbl); |
| 645 | 652 |
| 646 RawSubtypeTestCache* GenerateInlineInstanceof(TokenPosition token_pos, | 653 RawSubtypeTestCache* GenerateInlineInstanceof(TokenPosition token_pos, |
| 647 const AbstractType& type, | 654 const AbstractType& type, |
| 648 Label* is_instance_lbl, | 655 Label* is_instance_lbl, |
| 649 Label* is_not_instance_lbl); | 656 Label* is_not_instance_lbl); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 Register temp_reg, | 690 Register temp_reg, |
| 684 Label* is_instance_lbl, | 691 Label* is_instance_lbl, |
| 685 Label* is_not_instance_lbl); | 692 Label* is_not_instance_lbl); |
| 686 | 693 |
| 687 // Returns true if checking against this type is a direct class id comparison. | 694 // Returns true if checking against this type is a direct class id comparison. |
| 688 bool TypeCheckAsClassEquality(const AbstractType& type); | 695 bool TypeCheckAsClassEquality(const AbstractType& type); |
| 689 | 696 |
| 690 void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false); | 697 void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false); |
| 691 | 698 |
| 692 void CopyParameters(); | 699 void CopyParameters(); |
| 700 #endif // !defined(TARGET_ARCH_DBC) |
| 693 | 701 |
| 694 void GenerateInlinedGetter(intptr_t offset); | 702 void GenerateInlinedGetter(intptr_t offset); |
| 695 void GenerateInlinedSetter(intptr_t offset); | 703 void GenerateInlinedSetter(intptr_t offset); |
| 696 | 704 |
| 697 // Perform a greedy local register allocation. Consider all registers free. | 705 // Perform a greedy local register allocation. Consider all registers free. |
| 698 void AllocateRegistersLocally(Instruction* instr); | 706 void AllocateRegistersLocally(Instruction* instr); |
| 699 | 707 |
| 700 // Map a block number in a forward iteration into the block number in the | 708 // Map a block number in a forward iteration into the block number in the |
| 701 // corresponding reverse iteration. Used to obtain an index into | 709 // corresponding reverse iteration. Used to obtain an index into |
| 702 // block_order for reverse iterations. | 710 // block_order for reverse iterations. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 715 | 723 |
| 716 intptr_t GetOptimizationThreshold() const; | 724 intptr_t GetOptimizationThreshold() const; |
| 717 | 725 |
| 718 StackmapTableBuilder* stackmap_table_builder() { | 726 StackmapTableBuilder* stackmap_table_builder() { |
| 719 if (stackmap_table_builder_ == NULL) { | 727 if (stackmap_table_builder_ == NULL) { |
| 720 stackmap_table_builder_ = new StackmapTableBuilder(); | 728 stackmap_table_builder_ = new StackmapTableBuilder(); |
| 721 } | 729 } |
| 722 return stackmap_table_builder_; | 730 return stackmap_table_builder_; |
| 723 } | 731 } |
| 724 | 732 |
| 725 #if defined(DEBUG) | 733 // TODO(vegorov) re-enable frame state tracking on DBC. It is |
| 734 // currently disabled because it relies on LocationSummaries and |
| 735 // we don't use them during unoptimized compilation on DBC. |
| 736 #if defined(DEBUG) && !defined(TARGET_ARCH_DBC) |
| 726 void FrameStateUpdateWith(Instruction* instr); | 737 void FrameStateUpdateWith(Instruction* instr); |
| 727 void FrameStatePush(Definition* defn); | 738 void FrameStatePush(Definition* defn); |
| 728 void FrameStatePop(intptr_t count); | 739 void FrameStatePop(intptr_t count); |
| 729 bool FrameStateIsSafeToCall(); | 740 bool FrameStateIsSafeToCall(); |
| 730 void FrameStateClear(); | 741 void FrameStateClear(); |
| 731 #endif | 742 #endif |
| 732 | 743 |
| 733 // This struct contains either function or code, the other one being NULL. | 744 // This struct contains either function or code, the other one being NULL. |
| 734 class StaticCallsStruct : public ZoneAllocated { | 745 class StaticCallsStruct : public ZoneAllocated { |
| 735 public: | 746 public: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 const GrowableArray<const Function*>& inline_id_to_function_; | 818 const GrowableArray<const Function*>& inline_id_to_function_; |
| 808 const GrowableArray<TokenPosition>& inline_id_to_token_pos_; | 819 const GrowableArray<TokenPosition>& inline_id_to_token_pos_; |
| 809 const GrowableArray<intptr_t>& caller_inline_id_; | 820 const GrowableArray<intptr_t>& caller_inline_id_; |
| 810 | 821 |
| 811 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); | 822 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); |
| 812 }; | 823 }; |
| 813 | 824 |
| 814 } // namespace dart | 825 } // namespace dart |
| 815 | 826 |
| 816 #endif // VM_FLOW_GRAPH_COMPILER_H_ | 827 #endif // VM_FLOW_GRAPH_COMPILER_H_ |
| OLD | NEW |