| 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 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 if (!function_closure_.is_set()) { | 476 if (!function_closure_.is_set()) { |
| 477 const Operator* op = common()->Parameter( | 477 const Operator* op = common()->Parameter( |
| 478 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); | 478 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); |
| 479 Node* node = NewNode(op, graph()->start()); | 479 Node* node = NewNode(op, graph()->start()); |
| 480 function_closure_.set(node); | 480 function_closure_.set(node); |
| 481 } | 481 } |
| 482 return function_closure_.get(); | 482 return function_closure_.get(); |
| 483 } | 483 } |
| 484 | 484 |
| 485 | 485 |
| 486 void AstGraphBuilder::CreateFunctionContext(bool constant_context) { | 486 Node* AstGraphBuilder::GetFunctionContext() { |
| 487 function_context_.set(constant_context | 487 if (!function_context_.is_set()) { |
| 488 ? jsgraph()->HeapConstant(info()->context()) | 488 const Operator* op = common()->Parameter( |
| 489 : NewOuterContextParam()); | 489 info()->num_parameters_including_this(), "%context"); |
| 490 Node* node = NewNode(op, graph()->start()); |
| 491 function_context_.set(node); |
| 492 } |
| 493 return function_context_.get(); |
| 490 } | 494 } |
| 491 | 495 |
| 492 | 496 |
| 493 Node* AstGraphBuilder::NewOuterContextParam() { | 497 bool AstGraphBuilder::CreateGraph(bool stack_check) { |
| 494 // Parameter (arity + 1) is special for the outer context of the function | |
| 495 const Operator* op = | |
| 496 common()->Parameter(info()->num_parameters_including_this(), "%context"); | |
| 497 return NewNode(op, graph()->start()); | |
| 498 } | |
| 499 | |
| 500 | |
| 501 Node* AstGraphBuilder::NewCurrentContextOsrValue() { | |
| 502 // TODO(titzer): use a real OSR value here; a parameter works by accident. | |
| 503 // Parameter (arity + 1) is special for the outer context of the function | |
| 504 const Operator* op = common()->Parameter( | |
| 505 info()->num_parameters_including_this(), "%osr-context"); | |
| 506 return NewNode(op, graph()->start()); | |
| 507 } | |
| 508 | |
| 509 | |
| 510 bool AstGraphBuilder::CreateGraph(bool constant_context, bool stack_check) { | |
| 511 Scope* scope = info()->scope(); | 498 Scope* scope = info()->scope(); |
| 512 DCHECK(graph() != NULL); | 499 DCHECK(graph() != NULL); |
| 513 | 500 |
| 514 // Set up the basic structure of the graph. | 501 // Set up the basic structure of the graph. |
| 515 int parameter_count = info()->num_parameters(); | 502 int parameter_count = info()->num_parameters(); |
| 516 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); | 503 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); |
| 517 | 504 |
| 518 // Initialize the top-level environment. | 505 // Initialize the top-level environment. |
| 519 Environment env(this, scope, graph()->start()); | 506 Environment env(this, scope, graph()->start()); |
| 520 set_environment(&env); | 507 set_environment(&env); |
| 521 | 508 |
| 522 if (info()->is_osr()) { | 509 if (info()->is_osr()) { |
| 523 // Use OSR normal entry as the start of the top-level environment. | 510 // Use OSR normal entry as the start of the top-level environment. |
| 524 // It will be replaced with {Dead} after typing and optimizations. | 511 // It will be replaced with {Dead} after typing and optimizations. |
| 525 NewNode(common()->OsrNormalEntry()); | 512 NewNode(common()->OsrNormalEntry()); |
| 526 } | 513 } |
| 527 | 514 |
| 528 // Initialize the incoming context. | 515 // Initialize the incoming context. |
| 529 CreateFunctionContext(constant_context); | 516 ContextScope incoming(this, scope, GetFunctionContext()); |
| 530 ContextScope incoming(this, scope, function_context_.get()); | |
| 531 | 517 |
| 532 // Initialize control scope. | 518 // Initialize control scope. |
| 533 ControlScope control(this); | 519 ControlScope control(this); |
| 534 | 520 |
| 535 // Build receiver check for sloppy mode if necessary. | 521 // Build receiver check for sloppy mode if necessary. |
| 536 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? | 522 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
| 537 Node* patched_receiver = nullptr; | 523 Node* patched_receiver = nullptr; |
| 538 if (scope->has_this_declaration()) { | 524 if (scope->has_this_declaration()) { |
| 539 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start()); | 525 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start()); |
| 540 patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 526 patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
| 541 if (scope->receiver()->IsStackAllocated()) { | 527 if (scope->receiver()->IsStackAllocated()) { |
| 542 env.Bind(scope->receiver(), patched_receiver); | 528 env.Bind(scope->receiver(), patched_receiver); |
| 543 } | 529 } |
| 544 } | 530 } |
| 545 | 531 |
| 546 // Build function context only if there are context allocated variables. | 532 // Build function context only if there are context allocated variables. |
| 547 if (info()->num_heap_slots() > 0) { | 533 if (info()->num_heap_slots() > 0) { |
| 548 // Push a new inner context scope for the function. | 534 // Push a new inner context scope for the function. |
| 549 Node* inner_context = | 535 Node* inner_context = |
| 550 BuildLocalFunctionContext(function_context_.get(), patched_receiver); | 536 BuildLocalFunctionContext(GetFunctionContext(), patched_receiver); |
| 551 ContextScope top_context(this, scope, inner_context); | 537 ContextScope top_context(this, scope, inner_context); |
| 552 CreateGraphBody(stack_check); | 538 CreateGraphBody(stack_check); |
| 553 } else { | 539 } else { |
| 554 // Simply use the outer function context in building the graph. | 540 // Simply use the outer function context in building the graph. |
| 555 CreateGraphBody(stack_check); | 541 CreateGraphBody(stack_check); |
| 556 } | 542 } |
| 557 | 543 |
| 558 // Finish the basic structure of the graph. | 544 // Finish the basic structure of the graph. |
| 559 DCHECK_NE(0u, exit_controls_.size()); | 545 DCHECK_NE(0u, exit_controls_.size()); |
| 560 int const input_count = static_cast<int>(exit_controls_.size()); | 546 int const input_count = static_cast<int>(exit_controls_.size()); |
| (...skipping 3062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3623 Node* global = BuildLoadGlobalObject(); | 3609 Node* global = BuildLoadGlobalObject(); |
| 3624 Node* builtins = | 3610 Node* builtins = |
| 3625 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); | 3611 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); |
| 3626 return builtins; | 3612 return builtins; |
| 3627 } | 3613 } |
| 3628 | 3614 |
| 3629 | 3615 |
| 3630 Node* AstGraphBuilder::BuildLoadGlobalObject() { | 3616 Node* AstGraphBuilder::BuildLoadGlobalObject() { |
| 3631 const Operator* load_op = | 3617 const Operator* load_op = |
| 3632 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); | 3618 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); |
| 3633 return NewNode(load_op, function_context_.get()); | 3619 return NewNode(load_op, GetFunctionContext()); |
| 3634 } | 3620 } |
| 3635 | 3621 |
| 3636 | 3622 |
| 3637 Node* AstGraphBuilder::BuildLoadGlobalProxy() { | 3623 Node* AstGraphBuilder::BuildLoadGlobalProxy() { |
| 3638 Node* global = BuildLoadGlobalObject(); | 3624 Node* global = BuildLoadGlobalObject(); |
| 3639 Node* proxy = | 3625 Node* proxy = |
| 3640 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset); | 3626 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset); |
| 3641 return proxy; | 3627 return proxy; |
| 3642 } | 3628 } |
| 3643 | 3629 |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4084 // Rename all the contexts in the environment. | 4070 // Rename all the contexts in the environment. |
| 4085 // The innermost context is the OSR value, and the outer contexts are | 4071 // The innermost context is the OSR value, and the outer contexts are |
| 4086 // reconstructed by dynamically walking up the context chain. | 4072 // reconstructed by dynamically walking up the context chain. |
| 4087 Node* osr_context = nullptr; | 4073 Node* osr_context = nullptr; |
| 4088 const Operator* op = | 4074 const Operator* op = |
| 4089 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); | 4075 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); |
| 4090 int last = static_cast<int>(contexts()->size() - 1); | 4076 int last = static_cast<int>(contexts()->size() - 1); |
| 4091 for (int i = last; i >= 0; i--) { | 4077 for (int i = last; i >= 0; i--) { |
| 4092 Node* val = contexts()->at(i); | 4078 Node* val = contexts()->at(i); |
| 4093 if (!IrOpcode::IsConstantOpcode(val->opcode())) { | 4079 if (!IrOpcode::IsConstantOpcode(val->opcode())) { |
| 4094 osr_context = (i == last) ? builder_->NewCurrentContextOsrValue() | 4080 osr_context = (i == last) ? builder_->GetFunctionContext() |
| 4095 : graph->NewNode(op, osr_context, osr_context, | 4081 : graph->NewNode(op, osr_context, osr_context, |
| 4096 osr_loop_entry); | 4082 osr_loop_entry); |
| 4097 contexts()->at(i) = builder_->MergeValue(val, osr_context, control); | 4083 contexts()->at(i) = builder_->MergeValue(val, osr_context, control); |
| 4098 } else { | 4084 } else { |
| 4099 osr_context = val; | 4085 osr_context = val; |
| 4100 } | 4086 } |
| 4101 } | 4087 } |
| 4102 } | 4088 } |
| 4103 } | 4089 } |
| 4104 | 4090 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4171 // Phi does not exist yet, introduce one. | 4157 // Phi does not exist yet, introduce one. |
| 4172 value = NewPhi(inputs, value, control); | 4158 value = NewPhi(inputs, value, control); |
| 4173 value->ReplaceInput(inputs - 1, other); | 4159 value->ReplaceInput(inputs - 1, other); |
| 4174 } | 4160 } |
| 4175 return value; | 4161 return value; |
| 4176 } | 4162 } |
| 4177 | 4163 |
| 4178 } // namespace compiler | 4164 } // namespace compiler |
| 4179 } // namespace internal | 4165 } // namespace internal |
| 4180 } // namespace v8 | 4166 } // namespace v8 |
| OLD | NEW |