| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/compiler/ast-loop-assignment-analyzer.h" | 9 #include "src/compiler/ast-loop-assignment-analyzer.h" |
| 10 #include "src/compiler/control-builders.h" | 10 #include "src/compiler/control-builders.h" |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 BreakableStatement* target_; | 354 BreakableStatement* target_; |
| 355 LoopBuilder* control_; | 355 LoopBuilder* control_; |
| 356 }; | 356 }; |
| 357 | 357 |
| 358 | 358 |
| 359 // Control scope implementation for a TryCatchStatement. | 359 // Control scope implementation for a TryCatchStatement. |
| 360 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { | 360 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { |
| 361 public: | 361 public: |
| 362 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchStatement* stmt, | 362 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchStatement* stmt, |
| 363 TryCatchBuilder* control) | 363 TryCatchBuilder* control) |
| 364 : ControlScope(owner), | 364 : ControlScope(owner), control_(control) { |
| 365 control_(control), | |
| 366 outer_prediction_(owner->try_catch_prediction_) { | |
| 367 builder()->try_nesting_level_++; // Increment nesting. | 365 builder()->try_nesting_level_++; // Increment nesting. |
| 368 builder()->try_catch_prediction_ = stmt->catch_prediction(); | |
| 369 } | 366 } |
| 370 ~ControlScopeForCatch() { | 367 ~ControlScopeForCatch() { |
| 371 builder()->try_nesting_level_--; // Decrement nesting. | 368 builder()->try_nesting_level_--; // Decrement nesting. |
| 372 builder()->try_catch_prediction_ = outer_prediction_; | |
| 373 } | 369 } |
| 374 | 370 |
| 375 protected: | 371 protected: |
| 376 bool Execute(Command cmd, Statement* target, Node** value) override { | 372 bool Execute(Command cmd, Statement* target, Node** value) override { |
| 377 switch (cmd) { | 373 switch (cmd) { |
| 378 case CMD_THROW: | 374 case CMD_THROW: |
| 379 control_->Throw(*value); | 375 control_->Throw(*value); |
| 380 return true; | 376 return true; |
| 381 case CMD_BREAK: | 377 case CMD_BREAK: |
| 382 case CMD_CONTINUE: | 378 case CMD_CONTINUE: |
| 383 case CMD_RETURN: | 379 case CMD_RETURN: |
| 384 break; | 380 break; |
| 385 } | 381 } |
| 386 return false; | 382 return false; |
| 387 } | 383 } |
| 388 | 384 |
| 389 private: | 385 private: |
| 390 TryCatchBuilder* control_; | 386 TryCatchBuilder* control_; |
| 391 HandlerTable::CatchPrediction outer_prediction_; | |
| 392 }; | 387 }; |
| 393 | 388 |
| 394 | 389 |
| 395 // Control scope implementation for a TryFinallyStatement. | 390 // Control scope implementation for a TryFinallyStatement. |
| 396 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { | 391 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { |
| 397 public: | 392 public: |
| 398 ControlScopeForFinally(AstGraphBuilder* owner, TryFinallyStatement* stmt, | 393 ControlScopeForFinally(AstGraphBuilder* owner, TryFinallyStatement* stmt, |
| 399 DeferredCommands* commands, TryFinallyBuilder* control) | 394 DeferredCommands* commands, TryFinallyBuilder* control) |
| 400 : ControlScope(owner), | 395 : ControlScope(owner), commands_(commands), control_(control) { |
| 401 commands_(commands), | |
| 402 control_(control), | |
| 403 outer_prediction_(owner->try_catch_prediction_) { | |
| 404 builder()->try_nesting_level_++; // Increment nesting. | 396 builder()->try_nesting_level_++; // Increment nesting. |
| 405 builder()->try_catch_prediction_ = stmt->catch_prediction(); | |
| 406 } | 397 } |
| 407 ~ControlScopeForFinally() { | 398 ~ControlScopeForFinally() { |
| 408 builder()->try_nesting_level_--; // Decrement nesting. | 399 builder()->try_nesting_level_--; // Decrement nesting. |
| 409 builder()->try_catch_prediction_ = outer_prediction_; | |
| 410 } | 400 } |
| 411 | 401 |
| 412 protected: | 402 protected: |
| 413 bool Execute(Command cmd, Statement* target, Node** value) override { | 403 bool Execute(Command cmd, Statement* target, Node** value) override { |
| 414 Node* token = commands_->RecordCommand(cmd, target, *value); | 404 Node* token = commands_->RecordCommand(cmd, target, *value); |
| 415 control_->LeaveTry(token, *value); | 405 control_->LeaveTry(token, *value); |
| 416 return true; | 406 return true; |
| 417 } | 407 } |
| 418 | 408 |
| 419 private: | 409 private: |
| 420 DeferredCommands* commands_; | 410 DeferredCommands* commands_; |
| 421 TryFinallyBuilder* control_; | 411 TryFinallyBuilder* control_; |
| 422 HandlerTable::CatchPrediction outer_prediction_; | |
| 423 }; | 412 }; |
| 424 | 413 |
| 425 | 414 |
| 426 // Helper for generating before and after frame states. | 415 // Helper for generating before and after frame states. |
| 427 class AstGraphBuilder::FrameStateBeforeAndAfter { | 416 class AstGraphBuilder::FrameStateBeforeAndAfter { |
| 428 public: | 417 public: |
| 429 FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before) | 418 FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before) |
| 430 : builder_(builder), frame_state_before_(nullptr) { | 419 : builder_(builder), frame_state_before_(nullptr) { |
| 431 frame_state_before_ = id_before == BailoutId::None() | 420 frame_state_before_ = id_before == BailoutId::None() |
| 432 ? builder_->GetEmptyFrameState() | 421 ? builder_->GetEmptyFrameState() |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 : isolate_(info->isolate()), | 471 : isolate_(info->isolate()), |
| 483 local_zone_(local_zone), | 472 local_zone_(local_zone), |
| 484 info_(info), | 473 info_(info), |
| 485 jsgraph_(jsgraph), | 474 jsgraph_(jsgraph), |
| 486 environment_(nullptr), | 475 environment_(nullptr), |
| 487 ast_context_(nullptr), | 476 ast_context_(nullptr), |
| 488 globals_(0, local_zone), | 477 globals_(0, local_zone), |
| 489 execution_control_(nullptr), | 478 execution_control_(nullptr), |
| 490 execution_context_(nullptr), | 479 execution_context_(nullptr), |
| 491 try_nesting_level_(0), | 480 try_nesting_level_(0), |
| 492 try_catch_prediction_(HandlerTable::UNCAUGHT), | |
| 493 input_buffer_size_(0), | 481 input_buffer_size_(0), |
| 494 input_buffer_(nullptr), | 482 input_buffer_(nullptr), |
| 495 exit_controls_(local_zone), | 483 exit_controls_(local_zone), |
| 496 loop_assignment_analysis_(loop), | 484 loop_assignment_analysis_(loop), |
| 497 type_hint_analysis_(type_hint_analysis), | 485 type_hint_analysis_(type_hint_analysis), |
| 498 state_values_cache_(jsgraph), | 486 state_values_cache_(jsgraph), |
| 499 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), | 487 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), |
| 500 local_zone), | 488 local_zone), |
| 501 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 489 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
| 502 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, | 490 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, |
| (...skipping 3647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4150 // Update the current control dependency for control-producing nodes. | 4138 // Update the current control dependency for control-producing nodes. |
| 4151 if (NodeProperties::IsControl(result)) { | 4139 if (NodeProperties::IsControl(result)) { |
| 4152 environment_->UpdateControlDependency(result); | 4140 environment_->UpdateControlDependency(result); |
| 4153 } | 4141 } |
| 4154 // Update the current effect dependency for effect-producing nodes. | 4142 // Update the current effect dependency for effect-producing nodes. |
| 4155 if (result->op()->EffectOutputCount() > 0) { | 4143 if (result->op()->EffectOutputCount() > 0) { |
| 4156 environment_->UpdateEffectDependency(result); | 4144 environment_->UpdateEffectDependency(result); |
| 4157 } | 4145 } |
| 4158 // Add implicit exception continuation for throwing nodes. | 4146 // Add implicit exception continuation for throwing nodes. |
| 4159 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) { | 4147 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) { |
| 4160 // Conservative prediction whether caught locally. | |
| 4161 IfExceptionHint hint = | |
| 4162 ExceptionHintFromCatchPrediction(try_catch_prediction_); | |
| 4163 // Copy the environment for the success continuation. | 4148 // Copy the environment for the success continuation. |
| 4164 Environment* success_env = environment()->CopyForConditional(); | 4149 Environment* success_env = environment()->CopyForConditional(); |
| 4165 const Operator* op = common()->IfException(hint); | 4150 const Operator* op = common()->IfException(); |
| 4166 Node* effect = environment()->GetEffectDependency(); | 4151 Node* effect = environment()->GetEffectDependency(); |
| 4167 Node* on_exception = graph()->NewNode(op, effect, result); | 4152 Node* on_exception = graph()->NewNode(op, effect, result); |
| 4168 environment_->UpdateControlDependency(on_exception); | 4153 environment_->UpdateControlDependency(on_exception); |
| 4169 environment_->UpdateEffectDependency(on_exception); | 4154 environment_->UpdateEffectDependency(on_exception); |
| 4170 execution_control()->ThrowValue(on_exception); | 4155 execution_control()->ThrowValue(on_exception); |
| 4171 set_environment(success_env); | 4156 set_environment(success_env); |
| 4172 } | 4157 } |
| 4173 // Add implicit success continuation for throwing nodes. | 4158 // Add implicit success continuation for throwing nodes. |
| 4174 if (!result->op()->HasProperty(Operator::kNoThrow)) { | 4159 if (!result->op()->HasProperty(Operator::kNoThrow)) { |
| 4175 const Operator* op = common()->IfSuccess(); | 4160 const Operator* op = common()->IfSuccess(); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4390 // Phi does not exist yet, introduce one. | 4375 // Phi does not exist yet, introduce one. |
| 4391 value = NewPhi(inputs, value, control); | 4376 value = NewPhi(inputs, value, control); |
| 4392 value->ReplaceInput(inputs - 1, other); | 4377 value->ReplaceInput(inputs - 1, other); |
| 4393 } | 4378 } |
| 4394 return value; | 4379 return value; |
| 4395 } | 4380 } |
| 4396 | 4381 |
| 4397 } // namespace compiler | 4382 } // namespace compiler |
| 4398 } // namespace internal | 4383 } // namespace internal |
| 4399 } // namespace v8 | 4384 } // namespace v8 |
| OLD | NEW |