| 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/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
| 9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
| 10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 }; | 204 }; |
| 205 | 205 |
| 206 | 206 |
| 207 // Helper class for a try-finally control scope. It can record intercepted | 207 // Helper class for a try-finally control scope. It can record intercepted |
| 208 // control-flow commands that cause entry into a finally-block, and re-apply | 208 // control-flow commands that cause entry into a finally-block, and re-apply |
| 209 // them after again leaving that block. Special tokens are used to identify | 209 // them after again leaving that block. Special tokens are used to identify |
| 210 // paths going through the finally-block to dispatch after leaving the block. | 210 // paths going through the finally-block to dispatch after leaving the block. |
| 211 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { | 211 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { |
| 212 public: | 212 public: |
| 213 explicit DeferredCommands(AstGraphBuilder* owner) | 213 explicit DeferredCommands(AstGraphBuilder* owner) |
| 214 : owner_(owner), deferred_(owner->zone()) {} | 214 : owner_(owner), deferred_(owner->local_zone()) {} |
| 215 | 215 |
| 216 // One recorded control-flow command. | 216 // One recorded control-flow command. |
| 217 struct Entry { | 217 struct Entry { |
| 218 Command command; // The command type being applied on this path. | 218 Command command; // The command type being applied on this path. |
| 219 Statement* statement; // The target statement for the command or {NULL}. | 219 Statement* statement; // The target statement for the command or {NULL}. |
| 220 Node* token; // A token identifying this particular path. | 220 Node* token; // A token identifying this particular path. |
| 221 }; | 221 }; |
| 222 | 222 |
| 223 // Records a control-flow command while entering the finally-block. This also | 223 // Records a control-flow command while entering the finally-block. This also |
| 224 // generates a new dispatch token that identifies one particular path. | 224 // generates a new dispatch token that identifies one particular path. |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 | 423 |
| 424 private: | 424 private: |
| 425 AstGraphBuilder* builder_; | 425 AstGraphBuilder* builder_; |
| 426 Node* frame_state_before_; | 426 Node* frame_state_before_; |
| 427 }; | 427 }; |
| 428 | 428 |
| 429 | 429 |
| 430 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, | 430 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, |
| 431 JSGraph* jsgraph, LoopAssignmentAnalysis* loop, | 431 JSGraph* jsgraph, LoopAssignmentAnalysis* loop, |
| 432 JSTypeFeedbackTable* js_type_feedback) | 432 JSTypeFeedbackTable* js_type_feedback) |
| 433 : local_zone_(local_zone), | 433 : isolate_(info->isolate()), |
| 434 local_zone_(local_zone), |
| 434 info_(info), | 435 info_(info), |
| 435 jsgraph_(jsgraph), | 436 jsgraph_(jsgraph), |
| 436 environment_(nullptr), | 437 environment_(nullptr), |
| 437 ast_context_(nullptr), | 438 ast_context_(nullptr), |
| 438 globals_(0, local_zone), | 439 globals_(0, local_zone), |
| 439 execution_control_(nullptr), | 440 execution_control_(nullptr), |
| 440 execution_context_(nullptr), | 441 execution_context_(nullptr), |
| 441 try_catch_nesting_level_(0), | 442 try_catch_nesting_level_(0), |
| 442 try_nesting_level_(0), | 443 try_nesting_level_(0), |
| 443 input_buffer_size_(0), | 444 input_buffer_size_(0), |
| 444 input_buffer_(nullptr), | 445 input_buffer_(nullptr), |
| 445 exit_controls_(local_zone), | 446 exit_controls_(local_zone), |
| 446 loop_assignment_analysis_(loop), | 447 loop_assignment_analysis_(loop), |
| 447 state_values_cache_(jsgraph), | 448 state_values_cache_(jsgraph), |
| 448 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), | 449 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), |
| 449 local_zone), | 450 local_zone), |
| 450 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 451 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
| 451 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, | 452 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, |
| 452 info->scope()->num_stack_slots(), info->shared_info(), | 453 info->scope()->num_stack_slots(), info->shared_info(), |
| 453 CALL_MAINTAINS_NATIVE_CONTEXT)), | 454 CALL_MAINTAINS_NATIVE_CONTEXT)), |
| 454 js_type_feedback_(js_type_feedback) { | 455 js_type_feedback_(js_type_feedback) { |
| 455 InitializeAstVisitor(info->isolate(), local_zone); | 456 InitializeAstVisitor(info->isolate()); |
| 456 } | 457 } |
| 457 | 458 |
| 458 | 459 |
| 459 Node* AstGraphBuilder::GetFunctionClosureForContext() { | 460 Node* AstGraphBuilder::GetFunctionClosureForContext() { |
| 460 Scope* closure_scope = current_scope()->ClosureScope(); | 461 Scope* closure_scope = current_scope()->ClosureScope(); |
| 461 if (closure_scope->is_script_scope() || | 462 if (closure_scope->is_script_scope() || |
| 462 closure_scope->is_module_scope()) { | 463 closure_scope->is_module_scope()) { |
| 463 // Contexts nested in the native context have a canonical empty function as | 464 // Contexts nested in the native context have a canonical empty function as |
| 464 // their closure, not the anonymous closure containing the global code. | 465 // their closure, not the anonymous closure containing the global code. |
| 465 // Pass a SMI sentinel and let the runtime look up the empty function. | 466 // Pass a SMI sentinel and let the runtime look up the empty function. |
| (...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 // dispatch to the correct continuation point after the statements in the | 1440 // dispatch to the correct continuation point after the statements in the |
| 1440 // finally-block have been evaluated. | 1441 // finally-block have been evaluated. |
| 1441 // | 1442 // |
| 1442 // The try-finally construct can enter the finally-block in three ways: | 1443 // The try-finally construct can enter the finally-block in three ways: |
| 1443 // 1. By exiting the try-block normally, falling through at the end. | 1444 // 1. By exiting the try-block normally, falling through at the end. |
| 1444 // 2. By exiting the try-block with a function-local control flow transfer | 1445 // 2. By exiting the try-block with a function-local control flow transfer |
| 1445 // (i.e. through break/continue/return statements). | 1446 // (i.e. through break/continue/return statements). |
| 1446 // 3. By exiting the try-block with a thrown exception. | 1447 // 3. By exiting the try-block with a thrown exception. |
| 1447 Node* fallthrough_result = jsgraph()->TheHoleConstant(); | 1448 Node* fallthrough_result = jsgraph()->TheHoleConstant(); |
| 1448 ControlScope::DeferredCommands* commands = | 1449 ControlScope::DeferredCommands* commands = |
| 1449 new (zone()) ControlScope::DeferredCommands(this); | 1450 new (local_zone()) ControlScope::DeferredCommands(this); |
| 1450 | 1451 |
| 1451 // Evaluate the try-block inside a control scope. This simulates a handler | 1452 // Evaluate the try-block inside a control scope. This simulates a handler |
| 1452 // that is intercepting all control commands. | 1453 // that is intercepting all control commands. |
| 1453 try_control.BeginTry(); | 1454 try_control.BeginTry(); |
| 1454 { | 1455 { |
| 1455 ControlScopeForFinally scope(this, commands, &try_control); | 1456 ControlScopeForFinally scope(this, commands, &try_control); |
| 1456 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); | 1457 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); |
| 1457 environment()->Push(current_context()); | 1458 environment()->Push(current_context()); |
| 1458 Visit(stmt->try_block()); | 1459 Visit(stmt->try_block()); |
| 1459 environment()->Pop(); | 1460 environment()->Pop(); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1715 Node* literal = NewNode(op, literals_array, literal_index, constants); | 1716 Node* literal = NewNode(op, literals_array, literal_index, constants); |
| 1716 PrepareFrameState(literal, expr->CreateLiteralId(), | 1717 PrepareFrameState(literal, expr->CreateLiteralId(), |
| 1717 OutputFrameStateCombine::Push()); | 1718 OutputFrameStateCombine::Push()); |
| 1718 | 1719 |
| 1719 // The object is expected on the operand stack during computation of the | 1720 // The object is expected on the operand stack during computation of the |
| 1720 // property values and is the value of the entire expression. | 1721 // property values and is the value of the entire expression. |
| 1721 environment()->Push(literal); | 1722 environment()->Push(literal); |
| 1722 | 1723 |
| 1723 // Create nodes to store computed values into the literal. | 1724 // Create nodes to store computed values into the literal. |
| 1724 int property_index = 0; | 1725 int property_index = 0; |
| 1725 AccessorTable accessor_table(zone()); | 1726 AccessorTable accessor_table(local_zone()); |
| 1726 for (; property_index < expr->properties()->length(); property_index++) { | 1727 for (; property_index < expr->properties()->length(); property_index++) { |
| 1727 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1728 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1728 if (property->is_computed_name()) break; | 1729 if (property->is_computed_name()) break; |
| 1729 if (property->IsCompileTimeValue()) continue; | 1730 if (property->IsCompileTimeValue()) continue; |
| 1730 | 1731 |
| 1731 Literal* key = property->key()->AsLiteral(); | 1732 Literal* key = property->key()->AsLiteral(); |
| 1732 switch (property->kind()) { | 1733 switch (property->kind()) { |
| 1733 case ObjectLiteral::Property::CONSTANT: | 1734 case ObjectLiteral::Property::CONSTANT: |
| 1734 UNREACHABLE(); | 1735 UNREACHABLE(); |
| 1735 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1736 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3010 } else if (ast_context()->IsEffect()) { | 3011 } else if (ast_context()->IsEffect()) { |
| 3011 environment()->Pop(); | 3012 environment()->Pop(); |
| 3012 } else if (ast_context()->IsTest()) { | 3013 } else if (ast_context()->IsTest()) { |
| 3013 environment()->Poke(0, jsgraph()->FalseConstant()); | 3014 environment()->Poke(0, jsgraph()->FalseConstant()); |
| 3014 } | 3015 } |
| 3015 compare_if.End(); | 3016 compare_if.End(); |
| 3016 ast_context()->ReplaceValue(); | 3017 ast_context()->ReplaceValue(); |
| 3017 } | 3018 } |
| 3018 | 3019 |
| 3019 | 3020 |
| 3020 Isolate* AstGraphBuilder::isolate() const { return info()->isolate(); } | |
| 3021 | |
| 3022 | |
| 3023 LanguageMode AstGraphBuilder::language_mode() const { | 3021 LanguageMode AstGraphBuilder::language_mode() const { |
| 3024 return info()->language_mode(); | 3022 return info()->language_mode(); |
| 3025 } | 3023 } |
| 3026 | 3024 |
| 3027 | 3025 |
| 3028 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair( | 3026 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair( |
| 3029 FeedbackVectorSlot slot) const { | 3027 FeedbackVectorSlot slot) const { |
| 3030 return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot); | 3028 return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot); |
| 3031 } | 3029 } |
| 3032 | 3030 |
| (...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4287 // Phi does not exist yet, introduce one. | 4285 // Phi does not exist yet, introduce one. |
| 4288 value = NewPhi(inputs, value, control); | 4286 value = NewPhi(inputs, value, control); |
| 4289 value->ReplaceInput(inputs - 1, other); | 4287 value->ReplaceInput(inputs - 1, other); |
| 4290 } | 4288 } |
| 4291 return value; | 4289 return value; |
| 4292 } | 4290 } |
| 4293 | 4291 |
| 4294 } // namespace compiler | 4292 } // namespace compiler |
| 4295 } // namespace internal | 4293 } // namespace internal |
| 4296 } // namespace v8 | 4294 } // namespace v8 |
| OLD | NEW |