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 |