| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 void PostProcessLoopHeader(IterationStatement* stmt); | 102 void PostProcessLoopHeader(IterationStatement* stmt); |
| 103 | 103 |
| 104 bool IsFinished() const { return end_ != NULL; } | 104 bool IsFinished() const { return end_ != NULL; } |
| 105 void AddPhi(HPhi* phi); | 105 void AddPhi(HPhi* phi); |
| 106 void RemovePhi(HPhi* phi); | 106 void RemovePhi(HPhi* phi); |
| 107 void AddInstruction(HInstruction* instr); | 107 void AddInstruction(HInstruction* instr); |
| 108 bool Dominates(HBasicBlock* other) const; | 108 bool Dominates(HBasicBlock* other) const; |
| 109 int LoopNestingDepth() const; | 109 int LoopNestingDepth() const; |
| 110 | 110 |
| 111 void SetInitialEnvironment(HEnvironment* env); | 111 void SetInitialEnvironment(HEnvironment* env); |
| 112 void ClearEnvironment() { | |
| 113 ASSERT(IsFinished()); | |
| 114 ASSERT(end()->SuccessorCount() == 0); | |
| 115 last_environment_ = NULL; | |
| 116 } | |
| 117 bool HasEnvironment() const { return last_environment_ != NULL; } | 112 bool HasEnvironment() const { return last_environment_ != NULL; } |
| 118 void UpdateEnvironment(HEnvironment* env); | 113 void UpdateEnvironment(HEnvironment* env); |
| 119 HBasicBlock* parent_loop_header() const { return parent_loop_header_; } | 114 HBasicBlock* parent_loop_header() const { return parent_loop_header_; } |
| 120 | 115 |
| 121 void set_parent_loop_header(HBasicBlock* block) { | 116 void set_parent_loop_header(HBasicBlock* block) { |
| 122 ASSERT(parent_loop_header_ == NULL); | 117 ASSERT(parent_loop_header_ == NULL); |
| 123 parent_loop_header_ = block; | 118 parent_loop_header_ = block; |
| 124 } | 119 } |
| 125 | 120 |
| 126 bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; } | 121 bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; } |
| 127 | 122 |
| 128 void SetJoinId(BailoutId ast_id); | 123 void SetJoinId(BailoutId ast_id); |
| 129 | 124 |
| 130 void Finish(HControlInstruction* last); | 125 void Finish(HControlInstruction* last); |
| 131 void FinishExit(HControlInstruction* instruction); | 126 void FinishExit(HControlInstruction* instruction); |
| 132 void Goto(HBasicBlock* block, | 127 void Goto(HBasicBlock* block, |
| 133 FunctionState* state = NULL, | 128 FunctionState* state = NULL, |
| 134 bool add_simulate = true); | 129 bool add_simulate = true); |
| 135 void GotoNoSimulate(HBasicBlock* block) { | 130 void GotoNoSimulate(HBasicBlock* block) { |
| 136 Goto(block, NULL, false); | 131 Goto(block, NULL, false); |
| 137 } | 132 } |
| 138 | 133 |
| 139 int PredecessorIndexOf(HBasicBlock* predecessor) const; | 134 int PredecessorIndexOf(HBasicBlock* predecessor) const; |
| 140 void AddSimulate(BailoutId ast_id, | 135 HSimulate* AddSimulate(BailoutId ast_id, |
| 141 RemovableSimulate removable = FIXED_SIMULATE) { | 136 RemovableSimulate removable = FIXED_SIMULATE) { |
| 142 AddInstruction(CreateSimulate(ast_id, removable)); | 137 HSimulate* instr = CreateSimulate(ast_id, removable); |
| 138 AddInstruction(instr); |
| 139 return instr; |
| 143 } | 140 } |
| 144 void AssignCommonDominator(HBasicBlock* other); | 141 void AssignCommonDominator(HBasicBlock* other); |
| 145 void AssignLoopSuccessorDominators(); | 142 void AssignLoopSuccessorDominators(); |
| 146 | 143 |
| 147 void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) { | |
| 148 FinishExit(CreateDeoptimize(has_uses)); | |
| 149 } | |
| 150 | |
| 151 // Add the inlined function exit sequence, adding an HLeaveInlined | 144 // Add the inlined function exit sequence, adding an HLeaveInlined |
| 152 // instruction and updating the bailout environment. | 145 // instruction and updating the bailout environment. |
| 153 void AddLeaveInlined(HValue* return_value, FunctionState* state); | 146 void AddLeaveInlined(HValue* return_value, FunctionState* state); |
| 154 | 147 |
| 155 // If a target block is tagged as an inline function return, all | 148 // If a target block is tagged as an inline function return, all |
| 156 // predecessors should contain the inlined exit sequence: | 149 // predecessors should contain the inlined exit sequence: |
| 157 // | 150 // |
| 158 // LeaveInlined | 151 // LeaveInlined |
| 159 // Simulate (caller's environment) | 152 // Simulate (caller's environment) |
| 160 // Goto (target block) | 153 // Goto (target block) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 175 dominates_loop_successors_ = true; | 168 dominates_loop_successors_ = true; |
| 176 } | 169 } |
| 177 | 170 |
| 178 inline Zone* zone() const; | 171 inline Zone* zone() const; |
| 179 | 172 |
| 180 #ifdef DEBUG | 173 #ifdef DEBUG |
| 181 void Verify(); | 174 void Verify(); |
| 182 #endif | 175 #endif |
| 183 | 176 |
| 184 private: | 177 private: |
| 178 friend class HGraphBuilder; |
| 179 |
| 185 void RegisterPredecessor(HBasicBlock* pred); | 180 void RegisterPredecessor(HBasicBlock* pred); |
| 186 void AddDominatedBlock(HBasicBlock* block); | 181 void AddDominatedBlock(HBasicBlock* block); |
| 187 | 182 |
| 188 HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable); | 183 HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable); |
| 189 HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses); | |
| 190 | 184 |
| 191 int block_id_; | 185 int block_id_; |
| 192 HGraph* graph_; | 186 HGraph* graph_; |
| 193 ZoneList<HPhi*> phis_; | 187 ZoneList<HPhi*> phis_; |
| 194 HInstruction* first_; | 188 HInstruction* first_; |
| 195 HInstruction* last_; | 189 HInstruction* last_; |
| 196 HControlInstruction* end_; | 190 HControlInstruction* end_; |
| 197 HLoopInformation* loop_information_; | 191 HLoopInformation* loop_information_; |
| 198 ZoneList<HBasicBlock*> predecessors_; | 192 ZoneList<HBasicBlock*> predecessors_; |
| 199 HBasicBlock* dominator_; | 193 HBasicBlock* dominator_; |
| (...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1016 new(zone()) I(p1, p2, p3, p4, p5, p6, p7))); | 1010 new(zone()) I(p1, p2, p3, p4, p5, p6, p7))); |
| 1017 } | 1011 } |
| 1018 | 1012 |
| 1019 template<class I, class P1, class P2, class P3, class P4, | 1013 template<class I, class P1, class P2, class P3, class P4, |
| 1020 class P5, class P6, class P7, class P8> | 1014 class P5, class P6, class P7, class P8> |
| 1021 I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) { | 1015 I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) { |
| 1022 return static_cast<I*>(AddInstruction( | 1016 return static_cast<I*>(AddInstruction( |
| 1023 new(zone()) I(p1, p2, p3, p4, p5, p6, p7, p8))); | 1017 new(zone()) I(p1, p2, p3, p4, p5, p6, p7, p8))); |
| 1024 } | 1018 } |
| 1025 | 1019 |
| 1026 void AddSimulate(BailoutId id, | |
| 1027 RemovableSimulate removable = FIXED_SIMULATE); | |
| 1028 | |
| 1029 HReturn* AddReturn(HValue* value); | |
| 1030 | |
| 1031 void IncrementInNoSideEffectsScope() { | 1020 void IncrementInNoSideEffectsScope() { |
| 1032 no_side_effects_scope_count_++; | 1021 no_side_effects_scope_count_++; |
| 1033 } | 1022 } |
| 1034 | 1023 |
| 1035 void DecrementInNoSideEffectsScope() { | 1024 void DecrementInNoSideEffectsScope() { |
| 1036 no_side_effects_scope_count_--; | 1025 no_side_effects_scope_count_--; |
| 1037 } | 1026 } |
| 1038 | 1027 |
| 1039 protected: | 1028 protected: |
| 1040 virtual bool BuildGraph() = 0; | 1029 virtual bool BuildGraph() = 0; |
| 1041 | 1030 |
| 1042 HBasicBlock* CreateBasicBlock(HEnvironment* env); | 1031 HBasicBlock* CreateBasicBlock(HEnvironment* env); |
| 1043 HBasicBlock* CreateLoopHeaderBlock(); | 1032 HBasicBlock* CreateLoopHeaderBlock(); |
| 1044 | 1033 |
| 1034 void Deoptimize(HBasicBlock* continuation); |
| 1035 |
| 1045 HValue* BuildCheckHeapObject(HValue* object); | 1036 HValue* BuildCheckHeapObject(HValue* object); |
| 1046 HValue* BuildCheckMap(HValue* obj, Handle<Map> map); | 1037 HValue* BuildCheckMap(HValue* obj, Handle<Map> map); |
| 1047 | 1038 |
| 1048 // Building common constructs | 1039 // Building common constructs |
| 1049 HInstruction* BuildExternalArrayElementAccess( | 1040 HInstruction* BuildExternalArrayElementAccess( |
| 1050 HValue* external_elements, | 1041 HValue* external_elements, |
| 1051 HValue* checked_key, | 1042 HValue* checked_key, |
| 1052 HValue* val, | 1043 HValue* val, |
| 1053 HValue* dependency, | 1044 HValue* dependency, |
| 1054 ElementsKind elements_kind, | 1045 ElementsKind elements_kind, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 Representation representation = Representation::Tagged()); | 1102 Representation representation = Representation::Tagged()); |
| 1112 | 1103 |
| 1113 HStoreNamedField* AddStoreMapConstant(HValue *object, Handle<Map>); | 1104 HStoreNamedField* AddStoreMapConstant(HValue *object, Handle<Map>); |
| 1114 | 1105 |
| 1115 HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck = NULL); | 1106 HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck = NULL); |
| 1116 | 1107 |
| 1117 HLoadNamedField* AddLoadFixedArrayLength(HValue *object); | 1108 HLoadNamedField* AddLoadFixedArrayLength(HValue *object); |
| 1118 | 1109 |
| 1119 HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin, HValue* context); | 1110 HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin, HValue* context); |
| 1120 | 1111 |
| 1121 enum SoftDeoptimizeMode { | |
| 1122 MUST_EMIT_SOFT_DEOPT, | |
| 1123 CAN_OMIT_SOFT_DEOPT | |
| 1124 }; | |
| 1125 | |
| 1126 void AddSoftDeoptimize(SoftDeoptimizeMode mode = CAN_OMIT_SOFT_DEOPT); | |
| 1127 | |
| 1128 class IfBuilder { | 1112 class IfBuilder { |
| 1129 public: | 1113 public: |
| 1130 explicit IfBuilder(HGraphBuilder* builder, | 1114 explicit IfBuilder(HGraphBuilder* builder, |
| 1131 int position = RelocInfo::kNoPosition); | 1115 int position = RelocInfo::kNoPosition); |
| 1132 IfBuilder(HGraphBuilder* builder, | 1116 IfBuilder(HGraphBuilder* builder, |
| 1133 HIfContinuation* continuation); | 1117 HIfContinuation* continuation); |
| 1134 | 1118 |
| 1135 ~IfBuilder() { | 1119 ~IfBuilder() { |
| 1136 if (!finished_) End(); | 1120 if (!finished_) End(); |
| 1137 } | 1121 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1221 void CaptureContinuation(HIfContinuation* continuation); | 1205 void CaptureContinuation(HIfContinuation* continuation); |
| 1222 | 1206 |
| 1223 void Then(); | 1207 void Then(); |
| 1224 void Else(); | 1208 void Else(); |
| 1225 void End(); | 1209 void End(); |
| 1226 | 1210 |
| 1227 void Deopt(); | 1211 void Deopt(); |
| 1228 void ElseDeopt() { | 1212 void ElseDeopt() { |
| 1229 Else(); | 1213 Else(); |
| 1230 Deopt(); | 1214 Deopt(); |
| 1231 End(); | |
| 1232 } | 1215 } |
| 1233 | 1216 |
| 1234 void Return(HValue* value); | 1217 void Return(HValue* value); |
| 1235 | 1218 |
| 1236 private: | 1219 private: |
| 1237 void AddCompare(HControlInstruction* compare); | 1220 void AddCompare(HControlInstruction* compare); |
| 1238 | 1221 |
| 1239 Zone* zone() { return builder_->zone(); } | 1222 Zone* zone() { return builder_->zone(); } |
| 1240 | 1223 |
| 1241 HGraphBuilder* builder_; | 1224 HGraphBuilder* builder_; |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 HInstruction* BuildGetArrayFunction(HValue* context); | 1404 HInstruction* BuildGetArrayFunction(HValue* context); |
| 1422 | 1405 |
| 1423 private: | 1406 private: |
| 1424 HGraphBuilder(); | 1407 HGraphBuilder(); |
| 1425 CompilationInfo* info_; | 1408 CompilationInfo* info_; |
| 1426 HGraph* graph_; | 1409 HGraph* graph_; |
| 1427 HBasicBlock* current_block_; | 1410 HBasicBlock* current_block_; |
| 1428 int no_side_effects_scope_count_; | 1411 int no_side_effects_scope_count_; |
| 1429 }; | 1412 }; |
| 1430 | 1413 |
| 1414 |
| 1415 template<> |
| 1416 inline HDeoptimize* HGraphBuilder::Add(Deoptimizer::BailoutType type) { |
| 1417 isolate()->counters()->soft_deopts_requested()->Increment(); |
| 1418 if (FLAG_always_opt && type == Deoptimizer::SOFT) return NULL; |
| 1419 if (current_block()->IsDeoptimizing()) return NULL; |
| 1420 HDeoptimize* instr = new(zone()) HDeoptimize(type); |
| 1421 AddInstruction(instr); |
| 1422 isolate()->counters()->soft_deopts_inserted()->Increment(); |
| 1423 current_block()->MarkAsDeoptimizing(); |
| 1424 graph()->set_has_soft_deoptimize(true); |
| 1425 return instr; |
| 1426 } |
| 1427 |
| 1428 |
| 1429 template<> |
| 1430 inline HSimulate* HGraphBuilder::Add(BailoutId id, |
| 1431 RemovableSimulate removable) { |
| 1432 HSimulate* instr = current_block()->CreateSimulate(id, removable); |
| 1433 AddInstruction(instr); |
| 1434 return instr; |
| 1435 } |
| 1436 |
| 1437 template<> |
| 1438 inline HSimulate* HGraphBuilder::Add(BailoutId id) { |
| 1439 return Add<HSimulate>(id, FIXED_SIMULATE); |
| 1440 } |
| 1441 |
| 1442 template<> |
| 1443 inline HReturn* HGraphBuilder::Add(HValue* value) { |
| 1444 HValue* context = environment()->LookupContext(); |
| 1445 int num_parameters = graph()->info()->num_parameters(); |
| 1446 HValue* params = Add<HConstant>(num_parameters); |
| 1447 HReturn* return_instruction = new(graph()->zone()) |
| 1448 HReturn(value, context, params); |
| 1449 current_block()->FinishExit(return_instruction); |
| 1450 return return_instruction; |
| 1451 } |
| 1452 |
| 1453 template<> |
| 1454 inline HReturn* HGraphBuilder::Add(HConstant* p1) { |
| 1455 return Add<HReturn>(static_cast<HValue*>(p1)); |
| 1456 } |
| 1457 |
| 1458 |
| 1431 class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { | 1459 class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { |
| 1432 public: | 1460 public: |
| 1433 // A class encapsulating (lazily-allocated) break and continue blocks for | 1461 // A class encapsulating (lazily-allocated) break and continue blocks for |
| 1434 // a breakable statement. Separated from BreakAndContinueScope so that it | 1462 // a breakable statement. Separated from BreakAndContinueScope so that it |
| 1435 // can have a separate lifetime. | 1463 // can have a separate lifetime. |
| 1436 class BreakAndContinueInfo BASE_EMBEDDED { | 1464 class BreakAndContinueInfo BASE_EMBEDDED { |
| 1437 public: | 1465 public: |
| 1438 explicit BreakAndContinueInfo(BreakableStatement* target, | 1466 explicit BreakAndContinueInfo(BreakableStatement* target, |
| 1439 int drop_extra = 0) | 1467 int drop_extra = 0) |
| 1440 : target_(target), | 1468 : target_(target), |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 void HandlePropertyAssignment(Assignment* expr); | 1762 void HandlePropertyAssignment(Assignment* expr); |
| 1735 void HandleCompoundAssignment(Assignment* expr); | 1763 void HandleCompoundAssignment(Assignment* expr); |
| 1736 void HandlePolymorphicLoadNamedField(Property* expr, | 1764 void HandlePolymorphicLoadNamedField(Property* expr, |
| 1737 HValue* object, | 1765 HValue* object, |
| 1738 SmallMapList* types, | 1766 SmallMapList* types, |
| 1739 Handle<String> name); | 1767 Handle<String> name); |
| 1740 HInstruction* TryLoadPolymorphicAsMonomorphic(Property* expr, | 1768 HInstruction* TryLoadPolymorphicAsMonomorphic(Property* expr, |
| 1741 HValue* object, | 1769 HValue* object, |
| 1742 SmallMapList* types, | 1770 SmallMapList* types, |
| 1743 Handle<String> name); | 1771 Handle<String> name); |
| 1772 |
| 1773 void HandlePolymorphicStoreNamedFieldHelper(HValue* object, |
| 1774 Handle<String> name, |
| 1775 HValue* value, |
| 1776 SmallMapList* types, |
| 1777 int current_type, |
| 1778 int stored_count, |
| 1779 int position); |
| 1780 |
| 1744 void HandlePolymorphicStoreNamedField(BailoutId id, | 1781 void HandlePolymorphicStoreNamedField(BailoutId id, |
| 1745 int position, | 1782 int position, |
| 1746 BailoutId assignment_id, | 1783 BailoutId assignment_id, |
| 1747 HValue* object, | 1784 HValue* object, |
| 1748 HValue* value, | 1785 HValue* value, |
| 1749 HValue* result, | 1786 HValue* result, |
| 1750 SmallMapList* types, | 1787 SmallMapList* types, |
| 1751 Handle<String> name); | 1788 Handle<String> name); |
| 1752 bool TryStorePolymorphicAsMonomorphic(int position, | 1789 bool TryStorePolymorphicAsMonomorphic(int position, |
| 1753 BailoutId assignment_id, | 1790 BailoutId assignment_id, |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2096 EmbeddedVector<char, 64> filename_; | 2133 EmbeddedVector<char, 64> filename_; |
| 2097 HeapStringAllocator string_allocator_; | 2134 HeapStringAllocator string_allocator_; |
| 2098 StringStream trace_; | 2135 StringStream trace_; |
| 2099 int indent_; | 2136 int indent_; |
| 2100 }; | 2137 }; |
| 2101 | 2138 |
| 2102 | 2139 |
| 2103 } } // namespace v8::internal | 2140 } } // namespace v8::internal |
| 2104 | 2141 |
| 2105 #endif // V8_HYDROGEN_H_ | 2142 #endif // V8_HYDROGEN_H_ |
| OLD | NEW |