Chromium Code Reviews| 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_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
| 6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 | 104 |
| 105 | 105 |
| 106 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | 106 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
| 107 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | 107 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) |
| 108 #undef FORWARD_DECLARATION | 108 #undef FORWARD_DECLARATION |
| 109 | 109 |
| 110 // Forward declarations. | 110 // Forward declarations. |
| 111 class BindInstr; | 111 class BindInstr; |
| 112 class BranchInstr; | 112 class BranchInstr; |
| 113 class BufferFormatter; | 113 class BufferFormatter; |
| 114 class ComparisonComp; | |
|
Kevin Millikin (Google)
2012/07/19 12:28:05
My high level comment is that we should look for a
srdjan
2012/07/19 15:33:58
I agree.
| |
| 114 class Instruction; | 115 class Instruction; |
| 115 class Value; | 116 class Value; |
| 116 | 117 |
| 117 class Computation : public ZoneAllocated { | 118 class Computation : public ZoneAllocated { |
| 118 public: | 119 public: |
| 119 static const int kNoCid = -1; | 120 static const int kNoCid = -1; |
| 120 | 121 |
| 121 Computation() : cid_(-1), ic_data_(NULL), locs_(NULL) { | 122 Computation() : cid_(-1), ic_data_(NULL), locs_(NULL) { |
| 122 Isolate* isolate = Isolate::Current(); | 123 Isolate* isolate = Isolate::Current(); |
| 123 cid_ = GetNextCid(isolate); | 124 cid_ = GetNextCid(isolate); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 | 157 |
| 157 // Returns structure describing location constraints required | 158 // Returns structure describing location constraints required |
| 158 // to emit native code for this computation. | 159 // to emit native code for this computation. |
| 159 LocationSummary* locs() { | 160 LocationSummary* locs() { |
| 160 if (locs_ == NULL) { | 161 if (locs_ == NULL) { |
| 161 locs_ = MakeLocationSummary(); | 162 locs_ = MakeLocationSummary(); |
| 162 } | 163 } |
| 163 return locs_; | 164 return locs_; |
| 164 } | 165 } |
| 165 | 166 |
| 167 virtual ComparisonComp* AsComparison() { return NULL; } | |
| 168 | |
| 166 // Create a location summary for this computation. | 169 // Create a location summary for this computation. |
| 167 // TODO(fschneider): Temporarily returns NULL for instructions | 170 // TODO(fschneider): Temporarily returns NULL for instructions |
| 168 // that are not yet converted to the location based code generation. | 171 // that are not yet converted to the location based code generation. |
| 169 virtual LocationSummary* MakeLocationSummary() const = 0; | 172 virtual LocationSummary* MakeLocationSummary() const = 0; |
| 170 | 173 |
| 171 // TODO(fschneider): Make EmitNativeCode and locs const. | 174 // TODO(fschneider): Make EmitNativeCode and locs const. |
| 172 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; | 175 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; |
| 173 | 176 |
| 174 static LocationSummary* MakeCallSummary(); | 177 static LocationSummary* MakeCallSummary(); |
| 175 | 178 |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 | 572 |
| 570 private: | 573 private: |
| 571 InstanceCallComp* instance_call_; | 574 InstanceCallComp* instance_call_; |
| 572 | 575 |
| 573 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallComp); | 576 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallComp); |
| 574 }; | 577 }; |
| 575 | 578 |
| 576 | 579 |
| 577 class ComparisonComp : public TemplateComputation<2> { | 580 class ComparisonComp : public TemplateComputation<2> { |
| 578 public: | 581 public: |
| 579 ComparisonComp(Value* left, Value* right) | 582 ComparisonComp(Value* left, Value* right) { |
| 580 : fused_with_branch_(NULL) { | |
| 581 ASSERT(left != NULL); | 583 ASSERT(left != NULL); |
| 582 ASSERT(right != NULL); | 584 ASSERT(right != NULL); |
| 583 inputs_[0] = left; | 585 inputs_[0] = left; |
| 584 inputs_[1] = right; | 586 inputs_[1] = right; |
| 585 } | 587 } |
| 586 | 588 |
| 587 void MarkFusedWithBranch(BranchInstr* branch) { | |
| 588 fused_with_branch_ = branch; | |
| 589 } | |
| 590 | |
| 591 BranchInstr* fused_with_branch() const { | |
| 592 ASSERT(is_fused_with_branch()); | |
| 593 return fused_with_branch_; | |
| 594 } | |
| 595 | |
| 596 bool is_fused_with_branch() const { | |
| 597 return fused_with_branch_ != NULL; | |
| 598 } | |
| 599 | |
| 600 Value* left() const { return inputs_[0]; } | 589 Value* left() const { return inputs_[0]; } |
| 601 Value* right() const { return inputs_[1]; } | 590 Value* right() const { return inputs_[1]; } |
| 602 | 591 |
| 603 private: | 592 virtual ComparisonComp* AsComparison() { return this; } |
| 604 BranchInstr* fused_with_branch_; | 593 |
| 594 virtual Token::Kind kind() const = 0; | |
|
Kevin Millikin (Google)
2012/07/19 12:28:05
I would implement this as a member variable in cla
srdjan
2012/07/19 15:33:58
Done.
| |
| 605 }; | 595 }; |
| 606 | 596 |
| 607 | 597 |
| 608 class StrictCompareComp : public ComparisonComp { | 598 class StrictCompareComp : public ComparisonComp { |
| 609 public: | 599 public: |
| 610 StrictCompareComp(Token::Kind kind, Value* left, Value* right) | 600 StrictCompareComp(Token::Kind kind, Value* left, Value* right) |
| 611 : ComparisonComp(left, right), kind_(kind) { | 601 : ComparisonComp(left, right), kind_(kind) { |
| 612 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); | 602 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); |
| 613 } | 603 } |
| 614 | 604 |
| 615 DECLARE_COMPUTATION(StrictCompare) | 605 DECLARE_COMPUTATION(StrictCompare) |
| 616 | 606 |
| 617 Token::Kind kind() const { return kind_; } | 607 virtual Token::Kind kind() const { return kind_; } |
| 618 | 608 |
| 619 virtual void PrintOperandsTo(BufferFormatter* f) const; | 609 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 620 | 610 |
| 621 private: | 611 private: |
| 622 const Token::Kind kind_; | 612 const Token::Kind kind_; |
| 623 | 613 |
| 624 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 614 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); |
| 625 }; | 615 }; |
| 626 | 616 |
| 627 | 617 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 639 | 629 |
| 640 DECLARE_COMPUTATION(EqualityCompare) | 630 DECLARE_COMPUTATION(EqualityCompare) |
| 641 | 631 |
| 642 intptr_t token_pos() const { return token_pos_; } | 632 intptr_t token_pos() const { return token_pos_; } |
| 643 intptr_t try_index() const { return try_index_; } | 633 intptr_t try_index() const { return try_index_; } |
| 644 | 634 |
| 645 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } | 635 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } |
| 646 intptr_t receiver_class_id() const { return receiver_class_id_; } | 636 intptr_t receiver_class_id() const { return receiver_class_id_; } |
| 647 virtual void PrintOperandsTo(BufferFormatter* f) const; | 637 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 648 | 638 |
| 639 virtual Token::Kind kind() const { return Token::kEQ; } | |
| 640 | |
| 649 private: | 641 private: |
| 650 const intptr_t token_pos_; | 642 const intptr_t token_pos_; |
| 651 const intptr_t try_index_; | 643 const intptr_t try_index_; |
| 652 intptr_t receiver_class_id_; // Set by optimizer. | 644 intptr_t receiver_class_id_; // Set by optimizer. |
| 653 | 645 |
| 654 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); | 646 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); |
| 655 }; | 647 }; |
| 656 | 648 |
| 657 | 649 |
| 658 class RelationalOpComp : public ComparisonComp { | 650 class RelationalOpComp : public ComparisonComp { |
| 659 public: | 651 public: |
| 660 RelationalOpComp(intptr_t token_pos, | 652 RelationalOpComp(intptr_t token_pos, |
| 661 intptr_t try_index, | 653 intptr_t try_index, |
| 662 Token::Kind kind, | 654 Token::Kind kind, |
| 663 Value* left, | 655 Value* left, |
| 664 Value* right) | 656 Value* right) |
| 665 : ComparisonComp(left, right), | 657 : ComparisonComp(left, right), |
| 666 token_pos_(token_pos), | 658 token_pos_(token_pos), |
| 667 try_index_(try_index), | 659 try_index_(try_index), |
| 668 kind_(kind), | 660 kind_(kind), |
| 669 operands_class_id_(kObject) { | 661 operands_class_id_(kObject) { |
| 670 ASSERT(Token::IsRelationalOperator(kind)); | 662 ASSERT(Token::IsRelationalOperator(kind)); |
| 671 } | 663 } |
| 672 | 664 |
| 673 DECLARE_COMPUTATION(RelationalOp) | 665 DECLARE_COMPUTATION(RelationalOp) |
| 674 | 666 |
| 675 intptr_t token_pos() const { return token_pos_; } | 667 intptr_t token_pos() const { return token_pos_; } |
| 676 intptr_t try_index() const { return try_index_; } | 668 intptr_t try_index() const { return try_index_; } |
| 677 Token::Kind kind() const { return kind_; } | 669 virtual Token::Kind kind() const { return kind_; } |
| 678 | 670 |
| 679 // TODO(srdjan): instead of class-id pass an enum that can differentiate | 671 // TODO(srdjan): instead of class-id pass an enum that can differentiate |
| 680 // between boxed and unboxed doubles and integers. | 672 // between boxed and unboxed doubles and integers. |
| 681 void set_operands_class_id(intptr_t value) { | 673 void set_operands_class_id(intptr_t value) { |
| 682 operands_class_id_ = value; | 674 operands_class_id_ = value; |
| 683 } | 675 } |
| 684 | 676 |
| 685 intptr_t operands_class_id() const { return operands_class_id_; } | 677 intptr_t operands_class_id() const { return operands_class_id_; } |
| 686 | 678 |
| 687 virtual void PrintOperandsTo(BufferFormatter* f) const; | 679 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| (...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1733 Isolate* isolate = Isolate::Current(); | 1725 Isolate* isolate = Isolate::Current(); |
| 1734 cid_ = Computation::GetNextCid(isolate); | 1726 cid_ = Computation::GetNextCid(isolate); |
| 1735 ic_data_ = Computation::GetICDataForCid(cid_, isolate); | 1727 ic_data_ = Computation::GetICDataForCid(cid_, isolate); |
| 1736 } | 1728 } |
| 1737 | 1729 |
| 1738 // Unique computation/instruction id, used for deoptimization, e.g. for | 1730 // Unique computation/instruction id, used for deoptimization, e.g. for |
| 1739 // ReturnInstr, ThrowInstr and ReThrowInstr. | 1731 // ReturnInstr, ThrowInstr and ReThrowInstr. |
| 1740 intptr_t cid() const { return cid_; } | 1732 intptr_t cid() const { return cid_; } |
| 1741 | 1733 |
| 1742 const ICData* ic_data() const { return ic_data_; } | 1734 const ICData* ic_data() const { return ic_data_; } |
| 1735 bool HasICData() const { | |
| 1736 return (ic_data() != NULL) && !ic_data()->IsNull(); | |
| 1737 } | |
| 1743 | 1738 |
| 1744 virtual bool IsBlockEntry() const { return false; } | 1739 virtual bool IsBlockEntry() const { return false; } |
| 1745 BlockEntryInstr* AsBlockEntry() { | 1740 BlockEntryInstr* AsBlockEntry() { |
| 1746 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; | 1741 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; |
| 1747 } | 1742 } |
| 1748 virtual bool IsDefinition() const { return false; } | 1743 virtual bool IsDefinition() const { return false; } |
| 1749 virtual Definition* AsDefinition() { return NULL; } | 1744 virtual Definition* AsDefinition() { return NULL; } |
| 1750 | 1745 |
| 1751 virtual intptr_t InputCount() const = 0; | 1746 virtual intptr_t InputCount() const = 0; |
| 1752 virtual Value* InputAt(intptr_t i) const = 0; | 1747 virtual Value* InputAt(intptr_t i) const = 0; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1765 void set_next(Instruction* instr) { | 1760 void set_next(Instruction* instr) { |
| 1766 ASSERT(!IsGraphEntry()); | 1761 ASSERT(!IsGraphEntry()); |
| 1767 ASSERT(!IsReturn()); | 1762 ASSERT(!IsReturn()); |
| 1768 ASSERT(!IsBranch()); | 1763 ASSERT(!IsBranch()); |
| 1769 ASSERT(!IsPhi()); | 1764 ASSERT(!IsPhi()); |
| 1770 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions | 1765 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions |
| 1771 // that do not have a successor. Currently, the graph builder will continue | 1766 // that do not have a successor. Currently, the graph builder will continue |
| 1772 // to append instruction in case of a Throw inside an expression. This | 1767 // to append instruction in case of a Throw inside an expression. This |
| 1773 // condition should be handled in the graph builder | 1768 // condition should be handled in the graph builder |
| 1774 next_ = instr; | 1769 next_ = instr; |
| 1770 if ((instr != NULL) && !instr->IsBlockEntry()) { | |
| 1771 instr->set_previous(this); | |
|
Kevin Millikin (Google)
2012/07/19 12:28:05
I see why you did this, but I think we should avoi
srdjan
2012/07/19 15:33:58
I will avoid it with the better way to construct t
| |
| 1772 } | |
| 1775 } | 1773 } |
| 1776 | 1774 |
| 1777 // Normal instructions can have 0 (inside a block) or 1 (last instruction in | 1775 // Normal instructions can have 0 (inside a block) or 1 (last instruction in |
| 1778 // a block) successors. Branch instruction with >1 successors override this | 1776 // a block) successors. Branch instruction with >1 successors override this |
| 1779 // function. | 1777 // function. |
| 1780 virtual intptr_t SuccessorCount() const; | 1778 virtual intptr_t SuccessorCount() const; |
| 1781 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1779 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 1782 | 1780 |
| 1783 // Discover basic-block structure by performing a recursive depth first | 1781 // Discover basic-block structure by performing a recursive depth first |
| 1784 // traversal of the instruction graph reachable from this instruction. As | 1782 // traversal of the instruction graph reachable from this instruction. As |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2287 const intptr_t try_index_; | 2285 const intptr_t try_index_; |
| 2288 Value* exception_; | 2286 Value* exception_; |
| 2289 Value* stack_trace_; | 2287 Value* stack_trace_; |
| 2290 | 2288 |
| 2291 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); | 2289 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); |
| 2292 }; | 2290 }; |
| 2293 | 2291 |
| 2294 | 2292 |
| 2295 class BranchInstr : public InstructionWithInputs { | 2293 class BranchInstr : public InstructionWithInputs { |
| 2296 public: | 2294 public: |
| 2297 explicit BranchInstr(Value* value) | 2295 BranchInstr(intptr_t token_pos, |
|
Kevin Millikin (Google)
2012/07/19 12:28:05
Indentation is weird.
| |
| 2296 intptr_t try_index, | |
| 2297 Value* left, | |
| 2298 Value* right, | |
| 2299 Token::Kind kind) | |
| 2298 : InstructionWithInputs(), | 2300 : InstructionWithInputs(), |
| 2299 value_(value), | 2301 token_pos_(token_pos), |
| 2302 try_index_(try_index), | |
| 2303 left_(left), | |
| 2304 right_(right), | |
| 2305 kind_(kind), | |
| 2300 true_successor_(NULL), | 2306 true_successor_(NULL), |
| 2301 false_successor_(NULL), | 2307 false_successor_(NULL) { |
| 2302 fused_with_comparison_(NULL), | 2308 ASSERT(left_ != NULL); |
| 2303 is_negated_(false) { } | 2309 ASSERT(right_ != NULL); |
| 2310 ASSERT(Token::IsEqualityOperator(kind) || | |
| 2311 Token::IsRelationalOperator(kind) || | |
| 2312 Token::IsTypeTestOperator(kind)); | |
| 2313 } | |
| 2304 | 2314 |
| 2305 DECLARE_INSTRUCTION(Branch) | 2315 DECLARE_INSTRUCTION(Branch) |
| 2306 | 2316 |
| 2307 Value* value() const { return value_; } | 2317 Value* left() const { return left_; } |
| 2318 Value* right() const { return right_; } | |
| 2319 Token::Kind kind() const { return kind_; } | |
| 2320 void set_kind(Token::Kind kind) { | |
| 2321 ASSERT(Token::IsEqualityOperator(kind) || | |
| 2322 Token::IsRelationalOperator(kind) || | |
| 2323 Token::IsTypeTestOperator(kind)); | |
| 2324 kind_ = kind; | |
| 2325 } | |
| 2326 intptr_t token_pos() const { return token_pos_;} | |
| 2327 intptr_t try_index() const { return try_index_; } | |
| 2328 | |
| 2308 TargetEntryInstr* true_successor() const { return true_successor_; } | 2329 TargetEntryInstr* true_successor() const { return true_successor_; } |
| 2309 TargetEntryInstr* false_successor() const { return false_successor_; } | 2330 TargetEntryInstr* false_successor() const { return false_successor_; } |
| 2310 | 2331 |
| 2311 TargetEntryInstr** true_successor_address() { return &true_successor_; } | 2332 TargetEntryInstr** true_successor_address() { return &true_successor_; } |
| 2312 TargetEntryInstr** false_successor_address() { return &false_successor_; } | 2333 TargetEntryInstr** false_successor_address() { return &false_successor_; } |
| 2313 | 2334 |
| 2314 virtual intptr_t SuccessorCount() const; | 2335 virtual intptr_t SuccessorCount() const; |
| 2315 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 2336 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 2316 | 2337 |
| 2317 virtual void DiscoverBlocks( | 2338 virtual void DiscoverBlocks( |
| 2318 BlockEntryInstr* current_block, | 2339 BlockEntryInstr* current_block, |
| 2319 GrowableArray<BlockEntryInstr*>* preorder, | 2340 GrowableArray<BlockEntryInstr*>* preorder, |
| 2320 GrowableArray<BlockEntryInstr*>* postorder, | 2341 GrowableArray<BlockEntryInstr*>* postorder, |
| 2321 GrowableArray<intptr_t>* parent, | 2342 GrowableArray<intptr_t>* parent, |
| 2322 GrowableArray<BitVector*>* assigned_vars, | 2343 GrowableArray<BitVector*>* assigned_vars, |
| 2323 intptr_t variable_count); | 2344 intptr_t variable_count); |
| 2324 | 2345 |
| 2325 virtual LocationSummary* MakeLocationSummary() const; | 2346 virtual LocationSummary* MakeLocationSummary() const; |
| 2326 | 2347 |
| 2327 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 2348 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 2328 | 2349 |
| 2329 void EmitBranchOnCondition(FlowGraphCompiler* compiler, | 2350 void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 2330 Condition true_condition); | 2351 Condition true_condition); |
| 2331 | 2352 |
| 2332 void MarkFusedWithComparison(ComparisonComp* comp) { | |
| 2333 fused_with_comparison_ = comp; | |
| 2334 } | |
| 2335 | |
| 2336 bool is_fused_with_comparison() const { | |
| 2337 return fused_with_comparison_ != NULL; | |
| 2338 } | |
| 2339 bool is_negated() const { return is_negated_; } | |
| 2340 void set_is_negated(bool value) { is_negated_ = value; } | |
| 2341 | |
| 2342 private: | 2353 private: |
| 2343 Value* value_; | 2354 const intptr_t token_pos_; |
| 2355 const intptr_t try_index_; | |
| 2356 Value* left_; | |
| 2357 Value* right_; | |
| 2358 Token::Kind kind_; | |
| 2344 TargetEntryInstr* true_successor_; | 2359 TargetEntryInstr* true_successor_; |
| 2345 TargetEntryInstr* false_successor_; | 2360 TargetEntryInstr* false_successor_; |
| 2346 ComparisonComp* fused_with_comparison_; | |
| 2347 bool is_negated_; | |
| 2348 | 2361 |
| 2349 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 2362 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
| 2350 }; | 2363 }; |
| 2351 | 2364 |
| 2352 | 2365 |
| 2353 // This class is often passed by value. Add additional fields with caution. | 2366 // This class is often passed by value. Add additional fields with caution. |
| 2354 class MoveOperands : public ValueObject { | 2367 class MoveOperands : public ValueObject { |
| 2355 public: | 2368 public: |
| 2356 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } | 2369 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } |
| 2357 | 2370 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2490 const GrowableArray<BlockEntryInstr*>& block_order_; | 2503 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 2491 | 2504 |
| 2492 private: | 2505 private: |
| 2493 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 2506 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 2494 }; | 2507 }; |
| 2495 | 2508 |
| 2496 | 2509 |
| 2497 } // namespace dart | 2510 } // namespace dart |
| 2498 | 2511 |
| 2499 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 2512 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |