| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; } | 109 void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; } |
| 110 HBasicBlock* parent_loop_header() const { return parent_loop_header_; } | 110 HBasicBlock* parent_loop_header() const { return parent_loop_header_; } |
| 111 | 111 |
| 112 void set_parent_loop_header(HBasicBlock* block) { | 112 void set_parent_loop_header(HBasicBlock* block) { |
| 113 ASSERT(parent_loop_header_ == NULL); | 113 ASSERT(parent_loop_header_ == NULL); |
| 114 parent_loop_header_ = block; | 114 parent_loop_header_ = block; |
| 115 } | 115 } |
| 116 | 116 |
| 117 bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; } | 117 bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; } |
| 118 | 118 |
| 119 void SetJoinId(int id); | 119 void SetJoinId(int ast_id); |
| 120 | 120 |
| 121 void Finish(HControlInstruction* last); | 121 void Finish(HControlInstruction* last); |
| 122 void FinishExit(HControlInstruction* instruction); | 122 void FinishExit(HControlInstruction* instruction); |
| 123 void Goto(HBasicBlock* block, bool include_stack_check = false); | 123 void Goto(HBasicBlock* block); |
| 124 | 124 |
| 125 int PredecessorIndexOf(HBasicBlock* predecessor) const; | 125 int PredecessorIndexOf(HBasicBlock* predecessor) const; |
| 126 void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); } | 126 void AddSimulate(int ast_id) { AddInstruction(CreateSimulate(ast_id)); } |
| 127 void AssignCommonDominator(HBasicBlock* other); | 127 void AssignCommonDominator(HBasicBlock* other); |
| 128 | 128 |
| 129 void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) { | 129 void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) { |
| 130 FinishExit(CreateDeoptimize(has_uses)); | 130 FinishExit(CreateDeoptimize(has_uses)); |
| 131 } | 131 } |
| 132 | 132 |
| 133 // Add the inlined function exit sequence, adding an HLeaveInlined | 133 // Add the inlined function exit sequence, adding an HLeaveInlined |
| 134 // instruction and updating the bailout environment. | 134 // instruction and updating the bailout environment. |
| 135 void AddLeaveInlined(HValue* return_value, HBasicBlock* target); | 135 void AddLeaveInlined(HValue* return_value, HBasicBlock* target); |
| 136 | 136 |
| 137 // If a target block is tagged as an inline function return, all | 137 // If a target block is tagged as an inline function return, all |
| 138 // predecessors should contain the inlined exit sequence: | 138 // predecessors should contain the inlined exit sequence: |
| 139 // | 139 // |
| 140 // LeaveInlined | 140 // LeaveInlined |
| 141 // Simulate (caller's environment) | 141 // Simulate (caller's environment) |
| 142 // Goto (target block) | 142 // Goto (target block) |
| 143 bool IsInlineReturnTarget() const { return is_inline_return_target_; } | 143 bool IsInlineReturnTarget() const { return is_inline_return_target_; } |
| 144 void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; } | 144 void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; } |
| 145 | 145 |
| 146 bool IsDeoptimizing() const { return is_deoptimizing_; } |
| 147 void MarkAsDeoptimizing() { is_deoptimizing_ = true; } |
| 148 |
| 146 inline Zone* zone(); | 149 inline Zone* zone(); |
| 147 | 150 |
| 148 #ifdef DEBUG | 151 #ifdef DEBUG |
| 149 void Verify(); | 152 void Verify(); |
| 150 #endif | 153 #endif |
| 151 | 154 |
| 152 private: | 155 private: |
| 153 void RegisterPredecessor(HBasicBlock* pred); | 156 void RegisterPredecessor(HBasicBlock* pred); |
| 154 void AddDominatedBlock(HBasicBlock* block); | 157 void AddDominatedBlock(HBasicBlock* block); |
| 155 | 158 |
| 156 HSimulate* CreateSimulate(int id); | 159 HSimulate* CreateSimulate(int ast_id); |
| 157 HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses); | 160 HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses); |
| 158 | 161 |
| 159 int block_id_; | 162 int block_id_; |
| 160 HGraph* graph_; | 163 HGraph* graph_; |
| 161 ZoneList<HPhi*> phis_; | 164 ZoneList<HPhi*> phis_; |
| 162 HInstruction* first_; | 165 HInstruction* first_; |
| 163 HInstruction* last_; | 166 HInstruction* last_; |
| 164 HControlInstruction* end_; | 167 HControlInstruction* end_; |
| 165 HLoopInformation* loop_information_; | 168 HLoopInformation* loop_information_; |
| 166 ZoneList<HBasicBlock*> predecessors_; | 169 ZoneList<HBasicBlock*> predecessors_; |
| 167 HBasicBlock* dominator_; | 170 HBasicBlock* dominator_; |
| 168 ZoneList<HBasicBlock*> dominated_blocks_; | 171 ZoneList<HBasicBlock*> dominated_blocks_; |
| 169 HEnvironment* last_environment_; | 172 HEnvironment* last_environment_; |
| 170 // Outgoing parameter count at block exit, set during lithium translation. | 173 // Outgoing parameter count at block exit, set during lithium translation. |
| 171 int argument_count_; | 174 int argument_count_; |
| 172 // Instruction indices into the lithium code stream. | 175 // Instruction indices into the lithium code stream. |
| 173 int first_instruction_index_; | 176 int first_instruction_index_; |
| 174 int last_instruction_index_; | 177 int last_instruction_index_; |
| 175 ZoneList<int> deleted_phis_; | 178 ZoneList<int> deleted_phis_; |
| 176 HBasicBlock* parent_loop_header_; | 179 HBasicBlock* parent_loop_header_; |
| 177 bool is_inline_return_target_; | 180 bool is_inline_return_target_; |
| 181 bool is_deoptimizing_; |
| 178 }; | 182 }; |
| 179 | 183 |
| 180 | 184 |
| 181 class HLoopInformation: public ZoneObject { | 185 class HLoopInformation: public ZoneObject { |
| 182 public: | 186 public: |
| 183 explicit HLoopInformation(HBasicBlock* loop_header) | 187 explicit HLoopInformation(HBasicBlock* loop_header) |
| 184 : back_edges_(4), loop_header_(loop_header), blocks_(8) { | 188 : back_edges_(4), |
| 189 loop_header_(loop_header), |
| 190 blocks_(8), |
| 191 stack_check_(NULL) { |
| 185 blocks_.Add(loop_header); | 192 blocks_.Add(loop_header); |
| 186 } | 193 } |
| 187 virtual ~HLoopInformation() {} | 194 virtual ~HLoopInformation() {} |
| 188 | 195 |
| 189 const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; } | 196 const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; } |
| 190 const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; } | 197 const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; } |
| 191 HBasicBlock* loop_header() const { return loop_header_; } | 198 HBasicBlock* loop_header() const { return loop_header_; } |
| 192 HBasicBlock* GetLastBackEdge() const; | 199 HBasicBlock* GetLastBackEdge() const; |
| 193 void RegisterBackEdge(HBasicBlock* block); | 200 void RegisterBackEdge(HBasicBlock* block); |
| 194 | 201 |
| 202 HStackCheck* stack_check() const { return stack_check_; } |
| 203 void set_stack_check(HStackCheck* stack_check) { |
| 204 stack_check_ = stack_check; |
| 205 } |
| 206 |
| 195 private: | 207 private: |
| 196 void AddBlock(HBasicBlock* block); | 208 void AddBlock(HBasicBlock* block); |
| 197 | 209 |
| 198 ZoneList<HBasicBlock*> back_edges_; | 210 ZoneList<HBasicBlock*> back_edges_; |
| 199 HBasicBlock* loop_header_; | 211 HBasicBlock* loop_header_; |
| 200 ZoneList<HBasicBlock*> blocks_; | 212 ZoneList<HBasicBlock*> blocks_; |
| 213 HStackCheck* stack_check_; |
| 201 }; | 214 }; |
| 202 | 215 |
| 203 | 216 |
| 204 class HGraph: public ZoneObject { | 217 class HGraph: public ZoneObject { |
| 205 public: | 218 public: |
| 206 explicit HGraph(CompilationInfo* info); | 219 explicit HGraph(CompilationInfo* info); |
| 207 | 220 |
| 208 Isolate* isolate() { return isolate_; } | 221 Isolate* isolate() { return isolate_; } |
| 209 Zone* zone() { return isolate_->zone(); } | 222 Zone* zone() { return isolate_->zone(); } |
| 210 | 223 |
| 211 const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; } | 224 const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; } |
| 212 const ZoneList<HPhi*>* phi_list() const { return phi_list_; } | 225 const ZoneList<HPhi*>* phi_list() const { return phi_list_; } |
| 213 HBasicBlock* entry_block() const { return entry_block_; } | 226 HBasicBlock* entry_block() const { return entry_block_; } |
| 214 HEnvironment* start_environment() const { return start_environment_; } | 227 HEnvironment* start_environment() const { return start_environment_; } |
| 215 | 228 |
| 216 void InitializeInferredTypes(); | 229 void InitializeInferredTypes(); |
| 217 void InsertTypeConversions(); | 230 void InsertTypeConversions(); |
| 218 void InsertRepresentationChanges(); | 231 void InsertRepresentationChanges(); |
| 232 void MarkDeoptimizeOnUndefined(); |
| 219 void ComputeMinusZeroChecks(); | 233 void ComputeMinusZeroChecks(); |
| 220 bool ProcessArgumentsObject(); | 234 bool ProcessArgumentsObject(); |
| 221 void EliminateRedundantPhis(); | 235 void EliminateRedundantPhis(); |
| 222 void EliminateUnreachablePhis(); | 236 void EliminateUnreachablePhis(); |
| 223 void Canonicalize(); | 237 void Canonicalize(); |
| 224 void OrderBlocks(); | 238 void OrderBlocks(); |
| 225 void AssignDominators(); | 239 void AssignDominators(); |
| 240 void ReplaceCheckedValues(); |
| 241 void MarkAsDeoptimizingRecursively(HBasicBlock* block); |
| 226 | 242 |
| 227 // Returns false if there are phi-uses of the arguments-object | 243 // Returns false if there are phi-uses of the arguments-object |
| 228 // which are not supported by the optimizing compiler. | 244 // which are not supported by the optimizing compiler. |
| 229 bool CollectPhis(); | 245 bool CollectPhis(); |
| 230 | 246 |
| 231 Handle<Code> Compile(CompilationInfo* info); | 247 Handle<Code> Compile(CompilationInfo* info); |
| 232 | 248 |
| 233 void set_undefined_constant(HConstant* constant) { | 249 void set_undefined_constant(HConstant* constant) { |
| 234 undefined_constant_.set(constant); | 250 undefined_constant_.set(constant); |
| 235 } | 251 } |
| 236 HConstant* GetConstantUndefined() const { return undefined_constant_.get(); } | 252 HConstant* GetConstantUndefined() const { return undefined_constant_.get(); } |
| 237 HConstant* GetConstant1(); | 253 HConstant* GetConstant1(); |
| 238 HConstant* GetConstantMinus1(); | 254 HConstant* GetConstantMinus1(); |
| 239 HConstant* GetConstantTrue(); | 255 HConstant* GetConstantTrue(); |
| 240 HConstant* GetConstantFalse(); | 256 HConstant* GetConstantFalse(); |
| 257 HConstant* GetConstantHole(); |
| 241 | 258 |
| 242 HBasicBlock* CreateBasicBlock(); | 259 HBasicBlock* CreateBasicBlock(); |
| 243 HArgumentsObject* GetArgumentsObject() const { | 260 HArgumentsObject* GetArgumentsObject() const { |
| 244 return arguments_object_.get(); | 261 return arguments_object_.get(); |
| 245 } | 262 } |
| 246 bool HasArgumentsObject() const { return arguments_object_.is_set(); } | 263 bool HasArgumentsObject() const { return arguments_object_.is_set(); } |
| 247 | 264 |
| 248 void SetArgumentsObject(HArgumentsObject* object) { | 265 void SetArgumentsObject(HArgumentsObject* object) { |
| 249 arguments_object_.set(object); | 266 arguments_object_.set(object); |
| 250 } | 267 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 271 HBasicBlock* loop_header); | 288 HBasicBlock* loop_header); |
| 272 void PostorderLoopBlocks(HLoopInformation* loop, | 289 void PostorderLoopBlocks(HLoopInformation* loop, |
| 273 BitVector* visited, | 290 BitVector* visited, |
| 274 ZoneList<HBasicBlock*>* order, | 291 ZoneList<HBasicBlock*>* order, |
| 275 HBasicBlock* loop_header); | 292 HBasicBlock* loop_header); |
| 276 HConstant* GetConstant(SetOncePointer<HConstant>* pointer, | 293 HConstant* GetConstant(SetOncePointer<HConstant>* pointer, |
| 277 Object* value); | 294 Object* value); |
| 278 | 295 |
| 279 void InsertTypeConversions(HInstruction* instr); | 296 void InsertTypeConversions(HInstruction* instr); |
| 280 void PropagateMinusZeroChecks(HValue* value, BitVector* visited); | 297 void PropagateMinusZeroChecks(HValue* value, BitVector* visited); |
| 298 void RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi); |
| 281 void InsertRepresentationChangeForUse(HValue* value, | 299 void InsertRepresentationChangeForUse(HValue* value, |
| 282 HValue* use_value, | 300 HValue* use_value, |
| 283 int use_index, | 301 int use_index, |
| 284 Representation to); | 302 Representation to); |
| 285 void InsertRepresentationChangesForValue(HValue* value); | 303 void InsertRepresentationChangesForValue(HValue* value); |
| 286 void InferTypes(ZoneList<HValue*>* worklist); | 304 void InferTypes(ZoneList<HValue*>* worklist); |
| 287 void InitializeInferredTypes(int from_inclusive, int to_inclusive); | 305 void InitializeInferredTypes(int from_inclusive, int to_inclusive); |
| 288 void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor); | 306 void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor); |
| 289 | 307 |
| 290 Isolate* isolate_; | 308 Isolate* isolate_; |
| 291 int next_block_id_; | 309 int next_block_id_; |
| 292 HBasicBlock* entry_block_; | 310 HBasicBlock* entry_block_; |
| 293 HEnvironment* start_environment_; | 311 HEnvironment* start_environment_; |
| 294 ZoneList<HBasicBlock*> blocks_; | 312 ZoneList<HBasicBlock*> blocks_; |
| 295 ZoneList<HValue*> values_; | 313 ZoneList<HValue*> values_; |
| 296 ZoneList<HPhi*>* phi_list_; | 314 ZoneList<HPhi*>* phi_list_; |
| 297 SetOncePointer<HConstant> undefined_constant_; | 315 SetOncePointer<HConstant> undefined_constant_; |
| 298 SetOncePointer<HConstant> constant_1_; | 316 SetOncePointer<HConstant> constant_1_; |
| 299 SetOncePointer<HConstant> constant_minus1_; | 317 SetOncePointer<HConstant> constant_minus1_; |
| 300 SetOncePointer<HConstant> constant_true_; | 318 SetOncePointer<HConstant> constant_true_; |
| 301 SetOncePointer<HConstant> constant_false_; | 319 SetOncePointer<HConstant> constant_false_; |
| 320 SetOncePointer<HConstant> constant_hole_; |
| 302 SetOncePointer<HArgumentsObject> arguments_object_; | 321 SetOncePointer<HArgumentsObject> arguments_object_; |
| 303 | 322 |
| 304 DISALLOW_COPY_AND_ASSIGN(HGraph); | 323 DISALLOW_COPY_AND_ASSIGN(HGraph); |
| 305 }; | 324 }; |
| 306 | 325 |
| 307 | 326 |
| 308 Zone* HBasicBlock::zone() { return graph_->zone(); } | 327 Zone* HBasicBlock::zone() { return graph_->zone(); } |
| 309 | 328 |
| 310 | 329 |
| 311 class HEnvironment: public ZoneObject { | 330 class HEnvironment: public ZoneObject { |
| 312 public: | 331 public: |
| 313 enum CompilationPhase { HYDROGEN, LITHIUM }; | |
| 314 | |
| 315 HEnvironment(HEnvironment* outer, | 332 HEnvironment(HEnvironment* outer, |
| 316 Scope* scope, | 333 Scope* scope, |
| 317 Handle<JSFunction> closure); | 334 Handle<JSFunction> closure); |
| 318 | 335 |
| 319 // Simple accessors. | 336 // Simple accessors. |
| 320 Handle<JSFunction> closure() const { return closure_; } | 337 Handle<JSFunction> closure() const { return closure_; } |
| 321 const ZoneList<HValue*>* values() const { return &values_; } | 338 const ZoneList<HValue*>* values() const { return &values_; } |
| 322 const ZoneList<int>* assigned_variables() const { | 339 const ZoneList<int>* assigned_variables() const { |
| 323 return &assigned_variables_; | 340 return &assigned_variables_; |
| 324 } | 341 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 } | 408 } |
| 392 | 409 |
| 393 void SetExpressionStackAt(int index_from_top, HValue* value); | 410 void SetExpressionStackAt(int index_from_top, HValue* value); |
| 394 | 411 |
| 395 HEnvironment* Copy() const; | 412 HEnvironment* Copy() const; |
| 396 HEnvironment* CopyWithoutHistory() const; | 413 HEnvironment* CopyWithoutHistory() const; |
| 397 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const; | 414 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const; |
| 398 | 415 |
| 399 // Create an "inlined version" of this environment, where the original | 416 // Create an "inlined version" of this environment, where the original |
| 400 // environment is the outer environment but the top expression stack | 417 // environment is the outer environment but the top expression stack |
| 401 // elements are moved to an inner environment as parameters. If | 418 // elements are moved to an inner environment as parameters. |
| 402 // is_speculative, the argument values are expected to be PushArgument | |
| 403 // instructions, otherwise they are the actual values. | |
| 404 HEnvironment* CopyForInlining(Handle<JSFunction> target, | 419 HEnvironment* CopyForInlining(Handle<JSFunction> target, |
| 405 FunctionLiteral* function, | 420 FunctionLiteral* function, |
| 406 CompilationPhase compilation_phase, | |
| 407 HConstant* undefined, | 421 HConstant* undefined, |
| 408 CallKind call_kind) const; | 422 CallKind call_kind) const; |
| 409 | 423 |
| 410 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other); | 424 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other); |
| 411 | 425 |
| 412 void ClearHistory() { | 426 void ClearHistory() { |
| 413 pop_count_ = 0; | 427 pop_count_ = 0; |
| 414 push_count_ = 0; | 428 push_count_ = 0; |
| 415 assigned_variables_.Rewind(0); | 429 assigned_variables_.Rewind(0); |
| 416 } | 430 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 // have already been inserted in the instruction stream (or not need to | 491 // have already been inserted in the instruction stream (or not need to |
| 478 // be, e.g., HPhi). Call this function in tail position in the Visit | 492 // be, e.g., HPhi). Call this function in tail position in the Visit |
| 479 // functions for expressions. | 493 // functions for expressions. |
| 480 virtual void ReturnValue(HValue* value) = 0; | 494 virtual void ReturnValue(HValue* value) = 0; |
| 481 | 495 |
| 482 // Add a hydrogen instruction to the instruction stream (recording an | 496 // Add a hydrogen instruction to the instruction stream (recording an |
| 483 // environment simulation if necessary) and then fill this context with | 497 // environment simulation if necessary) and then fill this context with |
| 484 // the instruction as value. | 498 // the instruction as value. |
| 485 virtual void ReturnInstruction(HInstruction* instr, int ast_id) = 0; | 499 virtual void ReturnInstruction(HInstruction* instr, int ast_id) = 0; |
| 486 | 500 |
| 501 // Finishes the current basic block and materialize a boolean for |
| 502 // value context, nothing for effect, generate a branch for test context. |
| 503 // Call this function in tail position in the Visit functions for |
| 504 // expressions. |
| 505 virtual void ReturnControl(HControlInstruction* instr, int ast_id) = 0; |
| 506 |
| 487 void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; } | 507 void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; } |
| 488 bool is_for_typeof() { return for_typeof_; } | 508 bool is_for_typeof() { return for_typeof_; } |
| 489 | 509 |
| 490 protected: | 510 protected: |
| 491 AstContext(HGraphBuilder* owner, Expression::Context kind); | 511 AstContext(HGraphBuilder* owner, Expression::Context kind); |
| 492 virtual ~AstContext(); | 512 virtual ~AstContext(); |
| 493 | 513 |
| 494 HGraphBuilder* owner() const { return owner_; } | 514 HGraphBuilder* owner() const { return owner_; } |
| 495 | 515 |
| 496 inline Zone* zone(); | 516 inline Zone* zone(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 511 | 531 |
| 512 class EffectContext: public AstContext { | 532 class EffectContext: public AstContext { |
| 513 public: | 533 public: |
| 514 explicit EffectContext(HGraphBuilder* owner) | 534 explicit EffectContext(HGraphBuilder* owner) |
| 515 : AstContext(owner, Expression::kEffect) { | 535 : AstContext(owner, Expression::kEffect) { |
| 516 } | 536 } |
| 517 virtual ~EffectContext(); | 537 virtual ~EffectContext(); |
| 518 | 538 |
| 519 virtual void ReturnValue(HValue* value); | 539 virtual void ReturnValue(HValue* value); |
| 520 virtual void ReturnInstruction(HInstruction* instr, int ast_id); | 540 virtual void ReturnInstruction(HInstruction* instr, int ast_id); |
| 541 virtual void ReturnControl(HControlInstruction* instr, int ast_id); |
| 521 }; | 542 }; |
| 522 | 543 |
| 523 | 544 |
| 524 class ValueContext: public AstContext { | 545 class ValueContext: public AstContext { |
| 525 public: | 546 public: |
| 526 explicit ValueContext(HGraphBuilder* owner, ArgumentsAllowedFlag flag) | 547 explicit ValueContext(HGraphBuilder* owner, ArgumentsAllowedFlag flag) |
| 527 : AstContext(owner, Expression::kValue), flag_(flag) { | 548 : AstContext(owner, Expression::kValue), flag_(flag) { |
| 528 } | 549 } |
| 529 virtual ~ValueContext(); | 550 virtual ~ValueContext(); |
| 530 | 551 |
| 531 virtual void ReturnValue(HValue* value); | 552 virtual void ReturnValue(HValue* value); |
| 532 virtual void ReturnInstruction(HInstruction* instr, int ast_id); | 553 virtual void ReturnInstruction(HInstruction* instr, int ast_id); |
| 554 virtual void ReturnControl(HControlInstruction* instr, int ast_id); |
| 533 | 555 |
| 534 bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; } | 556 bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; } |
| 535 | 557 |
| 536 private: | 558 private: |
| 537 ArgumentsAllowedFlag flag_; | 559 ArgumentsAllowedFlag flag_; |
| 538 }; | 560 }; |
| 539 | 561 |
| 540 | 562 |
| 541 class TestContext: public AstContext { | 563 class TestContext: public AstContext { |
| 542 public: | 564 public: |
| 543 TestContext(HGraphBuilder* owner, | 565 TestContext(HGraphBuilder* owner, |
| 566 Expression* condition, |
| 544 HBasicBlock* if_true, | 567 HBasicBlock* if_true, |
| 545 HBasicBlock* if_false) | 568 HBasicBlock* if_false) |
| 546 : AstContext(owner, Expression::kTest), | 569 : AstContext(owner, Expression::kTest), |
| 570 condition_(condition), |
| 547 if_true_(if_true), | 571 if_true_(if_true), |
| 548 if_false_(if_false) { | 572 if_false_(if_false) { |
| 549 } | 573 } |
| 550 | 574 |
| 551 virtual void ReturnValue(HValue* value); | 575 virtual void ReturnValue(HValue* value); |
| 552 virtual void ReturnInstruction(HInstruction* instr, int ast_id); | 576 virtual void ReturnInstruction(HInstruction* instr, int ast_id); |
| 577 virtual void ReturnControl(HControlInstruction* instr, int ast_id); |
| 553 | 578 |
| 554 static TestContext* cast(AstContext* context) { | 579 static TestContext* cast(AstContext* context) { |
| 555 ASSERT(context->IsTest()); | 580 ASSERT(context->IsTest()); |
| 556 return reinterpret_cast<TestContext*>(context); | 581 return reinterpret_cast<TestContext*>(context); |
| 557 } | 582 } |
| 558 | 583 |
| 584 Expression* condition() const { return condition_; } |
| 559 HBasicBlock* if_true() const { return if_true_; } | 585 HBasicBlock* if_true() const { return if_true_; } |
| 560 HBasicBlock* if_false() const { return if_false_; } | 586 HBasicBlock* if_false() const { return if_false_; } |
| 561 | 587 |
| 562 private: | 588 private: |
| 563 // Build the shared core part of the translation unpacking a value into | 589 // Build the shared core part of the translation unpacking a value into |
| 564 // control flow. | 590 // control flow. |
| 565 void BuildBranch(HValue* value); | 591 void BuildBranch(HValue* value); |
| 566 | 592 |
| 593 Expression* condition_; |
| 567 HBasicBlock* if_true_; | 594 HBasicBlock* if_true_; |
| 568 HBasicBlock* if_false_; | 595 HBasicBlock* if_false_; |
| 569 }; | 596 }; |
| 570 | 597 |
| 571 | 598 |
| 572 class FunctionState BASE_EMBEDDED { | 599 class FunctionState BASE_EMBEDDED { |
| 573 public: | 600 public: |
| 574 FunctionState(HGraphBuilder* owner, | 601 FunctionState(HGraphBuilder* owner, |
| 575 CompilationInfo* info, | 602 CompilationInfo* info, |
| 576 TypeFeedbackOracle* oracle); | 603 TypeFeedbackOracle* oracle); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 HBasicBlock* current_block() const { return current_block_; } | 700 HBasicBlock* current_block() const { return current_block_; } |
| 674 void set_current_block(HBasicBlock* block) { current_block_ = block; } | 701 void set_current_block(HBasicBlock* block) { current_block_ = block; } |
| 675 HEnvironment* environment() const { | 702 HEnvironment* environment() const { |
| 676 return current_block()->last_environment(); | 703 return current_block()->last_environment(); |
| 677 } | 704 } |
| 678 | 705 |
| 679 bool inline_bailout() { return inline_bailout_; } | 706 bool inline_bailout() { return inline_bailout_; } |
| 680 | 707 |
| 681 // Adding instructions. | 708 // Adding instructions. |
| 682 HInstruction* AddInstruction(HInstruction* instr); | 709 HInstruction* AddInstruction(HInstruction* instr); |
| 683 void AddSimulate(int id); | 710 void AddSimulate(int ast_id); |
| 684 | 711 |
| 685 // Bailout environment manipulation. | 712 // Bailout environment manipulation. |
| 686 void Push(HValue* value) { environment()->Push(value); } | 713 void Push(HValue* value) { environment()->Push(value); } |
| 687 HValue* Pop() { return environment()->Pop(); } | 714 HValue* Pop() { return environment()->Pop(); } |
| 688 | 715 |
| 689 void Bailout(const char* reason); | 716 void Bailout(const char* reason); |
| 690 | 717 |
| 718 HBasicBlock* CreateJoin(HBasicBlock* first, |
| 719 HBasicBlock* second, |
| 720 int join_id); |
| 721 |
| 691 private: | 722 private: |
| 692 // Type of a member function that generates inline code for a native function. | 723 // Type of a member function that generates inline code for a native function. |
| 693 typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call); | 724 typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call); |
| 694 | 725 |
| 695 // Forward declarations for inner scope classes. | 726 // Forward declarations for inner scope classes. |
| 696 class SubgraphScope; | 727 class SubgraphScope; |
| 697 | 728 |
| 698 static const InlineFunctionGenerator kInlineFunctionGenerators[]; | 729 static const InlineFunctionGenerator kInlineFunctionGenerators[]; |
| 699 | 730 |
| 700 static const int kMaxCallPolymorphism = 4; | 731 static const int kMaxCallPolymorphism = 4; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 | 775 |
| 745 void VisitDelete(UnaryOperation* expr); | 776 void VisitDelete(UnaryOperation* expr); |
| 746 void VisitVoid(UnaryOperation* expr); | 777 void VisitVoid(UnaryOperation* expr); |
| 747 void VisitTypeof(UnaryOperation* expr); | 778 void VisitTypeof(UnaryOperation* expr); |
| 748 void VisitAdd(UnaryOperation* expr); | 779 void VisitAdd(UnaryOperation* expr); |
| 749 void VisitSub(UnaryOperation* expr); | 780 void VisitSub(UnaryOperation* expr); |
| 750 void VisitBitNot(UnaryOperation* expr); | 781 void VisitBitNot(UnaryOperation* expr); |
| 751 void VisitNot(UnaryOperation* expr); | 782 void VisitNot(UnaryOperation* expr); |
| 752 | 783 |
| 753 void VisitComma(BinaryOperation* expr); | 784 void VisitComma(BinaryOperation* expr); |
| 754 void VisitAndOr(BinaryOperation* expr, bool is_logical_and); | 785 void VisitLogicalExpression(BinaryOperation* expr); |
| 755 void VisitCommon(BinaryOperation* expr); | 786 void VisitArithmeticExpression(BinaryOperation* expr); |
| 756 | 787 |
| 757 void PreProcessOsrEntry(IterationStatement* statement); | 788 void PreProcessOsrEntry(IterationStatement* statement); |
| 758 // True iff. we are compiling for OSR and the statement is the entry. | 789 // True iff. we are compiling for OSR and the statement is the entry. |
| 759 bool HasOsrEntryAt(IterationStatement* statement); | 790 bool HasOsrEntryAt(IterationStatement* statement); |
| 760 | 791 void VisitLoopBody(IterationStatement* stmt, |
| 761 HBasicBlock* CreateJoin(HBasicBlock* first, | 792 HBasicBlock* loop_entry, |
| 762 HBasicBlock* second, | 793 BreakAndContinueInfo* break_info); |
| 763 int join_id); | |
| 764 | 794 |
| 765 // Create a back edge in the flow graph. body_exit is the predecessor | 795 // Create a back edge in the flow graph. body_exit is the predecessor |
| 766 // block and loop_entry is the successor block. loop_successor is the | 796 // block and loop_entry is the successor block. loop_successor is the |
| 767 // block where control flow exits the loop normally (e.g., via failure of | 797 // block where control flow exits the loop normally (e.g., via failure of |
| 768 // the condition) and break_block is the block where control flow breaks | 798 // the condition) and break_block is the block where control flow breaks |
| 769 // from the loop. All blocks except loop_entry can be NULL. The return | 799 // from the loop. All blocks except loop_entry can be NULL. The return |
| 770 // value is the new successor block which is the join of loop_successor | 800 // value is the new successor block which is the join of loop_successor |
| 771 // and break_block, or NULL. | 801 // and break_block, or NULL. |
| 772 HBasicBlock* CreateLoop(IterationStatement* statement, | 802 HBasicBlock* CreateLoop(IterationStatement* statement, |
| 773 HBasicBlock* loop_entry, | 803 HBasicBlock* loop_entry, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 788 // test contexts.) | 818 // test contexts.) |
| 789 void VisitForValue(Expression* expr, | 819 void VisitForValue(Expression* expr, |
| 790 ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED); | 820 ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED); |
| 791 void VisitForTypeOf(Expression* expr); | 821 void VisitForTypeOf(Expression* expr); |
| 792 void VisitForEffect(Expression* expr); | 822 void VisitForEffect(Expression* expr); |
| 793 void VisitForControl(Expression* expr, | 823 void VisitForControl(Expression* expr, |
| 794 HBasicBlock* true_block, | 824 HBasicBlock* true_block, |
| 795 HBasicBlock* false_block); | 825 HBasicBlock* false_block); |
| 796 | 826 |
| 797 // Visit an argument subexpression and emit a push to the outgoing | 827 // Visit an argument subexpression and emit a push to the outgoing |
| 798 // arguments. | 828 // arguments. Returns the hydrogen value that was pushed. |
| 799 void VisitArgument(Expression* expr); | 829 HValue* VisitArgument(Expression* expr); |
| 830 |
| 800 void VisitArgumentList(ZoneList<Expression*>* arguments); | 831 void VisitArgumentList(ZoneList<Expression*>* arguments); |
| 801 | 832 |
| 802 // Visit a list of expressions from left to right, each in a value context. | 833 // Visit a list of expressions from left to right, each in a value context. |
| 803 void VisitExpressions(ZoneList<Expression*>* exprs); | 834 void VisitExpressions(ZoneList<Expression*>* exprs); |
| 804 | 835 |
| 805 void AddPhi(HPhi* phi); | 836 void AddPhi(HPhi* phi); |
| 806 | 837 |
| 807 void PushAndAdd(HInstruction* instr); | 838 void PushAndAdd(HInstruction* instr); |
| 808 | 839 |
| 809 // Remove the arguments from the bailout environment and emit instructions | 840 // Remove the arguments from the bailout environment and emit instructions |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 void HandleCompoundAssignment(Assignment* expr); | 891 void HandleCompoundAssignment(Assignment* expr); |
| 861 void HandlePolymorphicStoreNamedField(Assignment* expr, | 892 void HandlePolymorphicStoreNamedField(Assignment* expr, |
| 862 HValue* object, | 893 HValue* object, |
| 863 HValue* value, | 894 HValue* value, |
| 864 ZoneMapList* types, | 895 ZoneMapList* types, |
| 865 Handle<String> name); | 896 Handle<String> name); |
| 866 void HandlePolymorphicCallNamed(Call* expr, | 897 void HandlePolymorphicCallNamed(Call* expr, |
| 867 HValue* receiver, | 898 HValue* receiver, |
| 868 ZoneMapList* types, | 899 ZoneMapList* types, |
| 869 Handle<String> name); | 900 Handle<String> name); |
| 901 void HandleLiteralCompareTypeof(CompareOperation* compare_expr, |
| 902 Expression* expr, |
| 903 Handle<String> check); |
| 904 void HandleLiteralCompareUndefined(CompareOperation* compare_expr, |
| 905 Expression* expr); |
| 870 | 906 |
| 871 HCompareSymbolEq* BuildSymbolCompare(HValue* left, | 907 HStringCharCodeAt* BuildStringCharCodeAt(HValue* context, |
| 872 HValue* right, | 908 HValue* string, |
| 873 Token::Value op); | |
| 874 HStringCharCodeAt* BuildStringCharCodeAt(HValue* string, | |
| 875 HValue* index); | 909 HValue* index); |
| 876 HInstruction* BuildBinaryOperation(BinaryOperation* expr, | 910 HInstruction* BuildBinaryOperation(BinaryOperation* expr, |
| 877 HValue* left, | 911 HValue* left, |
| 878 HValue* right); | 912 HValue* right); |
| 879 HInstruction* BuildBinaryOperation(Token::Value op, | |
| 880 HValue* left, | |
| 881 HValue* right, | |
| 882 TypeInfo info); | |
| 883 HInstruction* BuildIncrement(bool returns_original_input, | 913 HInstruction* BuildIncrement(bool returns_original_input, |
| 884 CountOperation* expr); | 914 CountOperation* expr); |
| 885 HLoadNamedField* BuildLoadNamedField(HValue* object, | 915 HLoadNamedField* BuildLoadNamedField(HValue* object, |
| 886 Property* expr, | 916 Property* expr, |
| 887 Handle<Map> type, | 917 Handle<Map> type, |
| 888 LookupResult* result, | 918 LookupResult* result, |
| 889 bool smi_and_map_check); | 919 bool smi_and_map_check); |
| 890 HInstruction* BuildLoadNamedGeneric(HValue* object, Property* expr); | 920 HInstruction* BuildLoadNamedGeneric(HValue* object, Property* expr); |
| 891 HInstruction* BuildLoadKeyedFastElement(HValue* object, | |
| 892 HValue* key, | |
| 893 Property* expr); | |
| 894 HInstruction* BuildLoadKeyedSpecializedArrayElement(HValue* object, | |
| 895 HValue* key, | |
| 896 Property* expr); | |
| 897 HInstruction* BuildLoadKeyedGeneric(HValue* object, | 921 HInstruction* BuildLoadKeyedGeneric(HValue* object, |
| 898 HValue* key); | 922 HValue* key); |
| 923 HInstruction* BuildExternalArrayElementAccess( |
| 924 HValue* external_elements, |
| 925 HValue* checked_key, |
| 926 HValue* val, |
| 927 JSObject::ElementsKind elements_kind, |
| 928 bool is_store); |
| 899 | 929 |
| 900 HInstruction* BuildLoadKeyed(HValue* obj, | 930 HInstruction* BuildMonomorphicElementAccess(HValue* object, |
| 901 HValue* key, | 931 HValue* key, |
| 902 Property* prop); | 932 HValue* val, |
| 933 Expression* expr, |
| 934 bool is_store); |
| 935 HValue* HandlePolymorphicElementAccess(HValue* object, |
| 936 HValue* key, |
| 937 HValue* val, |
| 938 Expression* prop, |
| 939 int ast_id, |
| 940 int position, |
| 941 bool is_store, |
| 942 bool* has_side_effects); |
| 943 |
| 944 HValue* HandleKeyedElementAccess(HValue* obj, |
| 945 HValue* key, |
| 946 HValue* val, |
| 947 Expression* expr, |
| 948 int ast_id, |
| 949 int position, |
| 950 bool is_store, |
| 951 bool* has_side_effects); |
| 903 | 952 |
| 904 HInstruction* BuildLoadNamed(HValue* object, | 953 HInstruction* BuildLoadNamed(HValue* object, |
| 905 Property* prop, | 954 Property* prop, |
| 906 Handle<Map> map, | 955 Handle<Map> map, |
| 907 Handle<String> name); | 956 Handle<String> name); |
| 908 HInstruction* BuildStoreNamed(HValue* object, | 957 HInstruction* BuildStoreNamed(HValue* object, |
| 909 HValue* value, | 958 HValue* value, |
| 910 Expression* expr); | 959 Expression* expr); |
| 911 HInstruction* BuildStoreNamedField(HValue* object, | 960 HInstruction* BuildStoreNamedField(HValue* object, |
| 912 Handle<String> name, | 961 Handle<String> name, |
| 913 HValue* value, | 962 HValue* value, |
| 914 Handle<Map> type, | 963 Handle<Map> type, |
| 915 LookupResult* lookup, | 964 LookupResult* lookup, |
| 916 bool smi_and_map_check); | 965 bool smi_and_map_check); |
| 917 HInstruction* BuildStoreNamedGeneric(HValue* object, | 966 HInstruction* BuildStoreNamedGeneric(HValue* object, |
| 918 Handle<String> name, | 967 Handle<String> name, |
| 919 HValue* value); | 968 HValue* value); |
| 920 HInstruction* BuildStoreKeyedGeneric(HValue* object, | 969 HInstruction* BuildStoreKeyedGeneric(HValue* object, |
| 921 HValue* key, | 970 HValue* key, |
| 922 HValue* value); | 971 HValue* value); |
| 923 | 972 |
| 924 HInstruction* BuildStoreKeyedFastElement(HValue* object, | |
| 925 HValue* key, | |
| 926 HValue* val, | |
| 927 Expression* expr); | |
| 928 | |
| 929 HInstruction* BuildStoreKeyedSpecializedArrayElement( | |
| 930 HValue* object, | |
| 931 HValue* key, | |
| 932 HValue* val, | |
| 933 Expression* expr); | |
| 934 | |
| 935 HInstruction* BuildStoreKeyed(HValue* object, | |
| 936 HValue* key, | |
| 937 HValue* value, | |
| 938 Expression* assignment); | |
| 939 | |
| 940 HValue* BuildContextChainWalk(Variable* var); | 973 HValue* BuildContextChainWalk(Variable* var); |
| 941 | 974 |
| 942 void AddCheckConstantFunction(Call* expr, | 975 void AddCheckConstantFunction(Call* expr, |
| 943 HValue* receiver, | 976 HValue* receiver, |
| 944 Handle<Map> receiver_map, | 977 Handle<Map> receiver_map, |
| 945 bool smi_and_map_check); | 978 bool smi_and_map_check); |
| 946 | 979 |
| 947 Zone* zone() { return zone_; } | 980 Zone* zone() { return zone_; } |
| 948 | 981 |
| 949 // The translation state of the currently-being-translated function. | 982 // The translation state of the currently-being-translated function. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 void SaveTiming(const char* name, int64_t ticks, unsigned size); | 1076 void SaveTiming(const char* name, int64_t ticks, unsigned size); |
| 1044 static HStatistics* Instance() { | 1077 static HStatistics* Instance() { |
| 1045 static SetOncePointer<HStatistics> instance; | 1078 static SetOncePointer<HStatistics> instance; |
| 1046 if (!instance.is_set()) { | 1079 if (!instance.is_set()) { |
| 1047 instance.set(new HStatistics()); | 1080 instance.set(new HStatistics()); |
| 1048 } | 1081 } |
| 1049 return instance.get(); | 1082 return instance.get(); |
| 1050 } | 1083 } |
| 1051 | 1084 |
| 1052 private: | 1085 private: |
| 1053 | |
| 1054 HStatistics() | 1086 HStatistics() |
| 1055 : timing_(5), | 1087 : timing_(5), |
| 1056 names_(5), | 1088 names_(5), |
| 1057 sizes_(5), | 1089 sizes_(5), |
| 1058 total_(0), | 1090 total_(0), |
| 1059 total_size_(0), | 1091 total_size_(0), |
| 1060 full_code_gen_(0), | 1092 full_code_gen_(0), |
| 1061 source_size_(0) { } | 1093 source_size_(0) { } |
| 1062 | 1094 |
| 1063 List<int64_t> timing_; | 1095 List<int64_t> timing_; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 void PrintLongProperty(const char* name, int64_t value) { | 1199 void PrintLongProperty(const char* name, int64_t value) { |
| 1168 PrintIndent(); | 1200 PrintIndent(); |
| 1169 trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000)); | 1201 trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000)); |
| 1170 } | 1202 } |
| 1171 | 1203 |
| 1172 void PrintBlockProperty(const char* name, int block_id) { | 1204 void PrintBlockProperty(const char* name, int block_id) { |
| 1173 PrintIndent(); | 1205 PrintIndent(); |
| 1174 trace_.Add("%s \"B%d\"\n", name, block_id); | 1206 trace_.Add("%s \"B%d\"\n", name, block_id); |
| 1175 } | 1207 } |
| 1176 | 1208 |
| 1177 void PrintBlockProperty(const char* name, int block_id1, int block_id2) { | |
| 1178 PrintIndent(); | |
| 1179 trace_.Add("%s \"B%d\" \"B%d\"\n", name, block_id1, block_id2); | |
| 1180 } | |
| 1181 | |
| 1182 void PrintIntProperty(const char* name, int value) { | 1209 void PrintIntProperty(const char* name, int value) { |
| 1183 PrintIndent(); | 1210 PrintIndent(); |
| 1184 trace_.Add("%s %d\n", name, value); | 1211 trace_.Add("%s %d\n", name, value); |
| 1185 } | 1212 } |
| 1186 | 1213 |
| 1187 void PrintIndent() { | 1214 void PrintIndent() { |
| 1188 for (int i = 0; i < indent_; i++) { | 1215 for (int i = 0; i < indent_; i++) { |
| 1189 trace_.Add(" "); | 1216 trace_.Add(" "); |
| 1190 } | 1217 } |
| 1191 } | 1218 } |
| 1192 | 1219 |
| 1193 const char* filename_; | 1220 const char* filename_; |
| 1194 HeapStringAllocator string_allocator_; | 1221 HeapStringAllocator string_allocator_; |
| 1195 StringStream trace_; | 1222 StringStream trace_; |
| 1196 int indent_; | 1223 int indent_; |
| 1197 }; | 1224 }; |
| 1198 | 1225 |
| 1199 | 1226 |
| 1200 } } // namespace v8::internal | 1227 } } // namespace v8::internal |
| 1201 | 1228 |
| 1202 #endif // V8_HYDROGEN_H_ | 1229 #endif // V8_HYDROGEN_H_ |
| OLD | NEW |