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 |