Chromium Code Reviews| 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/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, | 372 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, |
| 373 JSGraph* jsgraph, LoopAssignmentAnalysis* loop) | 373 JSGraph* jsgraph, LoopAssignmentAnalysis* loop) |
| 374 : local_zone_(local_zone), | 374 : local_zone_(local_zone), |
| 375 info_(info), | 375 info_(info), |
| 376 jsgraph_(jsgraph), | 376 jsgraph_(jsgraph), |
| 377 environment_(nullptr), | 377 environment_(nullptr), |
| 378 ast_context_(nullptr), | 378 ast_context_(nullptr), |
| 379 globals_(0, local_zone), | 379 globals_(0, local_zone), |
| 380 execution_control_(nullptr), | 380 execution_control_(nullptr), |
| 381 execution_context_(nullptr), | 381 execution_context_(nullptr), |
| 382 function_context_(nullptr), | |
| 383 input_buffer_size_(0), | 382 input_buffer_size_(0), |
| 384 input_buffer_(nullptr), | 383 input_buffer_(nullptr), |
| 385 exit_control_(nullptr), | 384 exit_control_(nullptr), |
| 386 loop_assignment_analysis_(loop) { | 385 loop_assignment_analysis_(loop) { |
| 387 InitializeAstVisitor(info->isolate(), local_zone); | 386 InitializeAstVisitor(info->isolate(), local_zone); |
| 388 } | 387 } |
| 389 | 388 |
| 390 | 389 |
| 391 Node* AstGraphBuilder::GetFunctionClosure() { | 390 Node* AstGraphBuilder::GetFunctionClosure() { |
| 392 if (!function_closure_.is_set()) { | 391 if (!function_closure_.is_set()) { |
| 393 const Operator* op = | 392 const Operator* op = |
| 394 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); | 393 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); |
| 395 Node* node = NewNode(op, graph()->start()); | 394 Node* node = NewNode(op, graph()->start()); |
| 396 function_closure_.set(node); | 395 function_closure_.set(node); |
| 397 } | 396 } |
| 398 return function_closure_.get(); | 397 return function_closure_.get(); |
| 399 } | 398 } |
| 400 | 399 |
| 401 | 400 |
| 402 Node* AstGraphBuilder::GetFunctionContext() { | 401 Node* AstGraphBuilder::GetFunctionContext() { return function_context_.get(); } |
| 403 DCHECK(function_context_ != nullptr); | |
| 404 return function_context_; | |
| 405 } | |
| 406 | 402 |
| 407 | 403 |
| 408 Node* AstGraphBuilder::NewOuterContextParam() { | 404 Node* AstGraphBuilder::NewOuterContextParam() { |
| 409 // Parameter (arity + 1) is special for the outer context of the function | 405 // Parameter (arity + 1) is special for the outer context of the function |
| 410 const Operator* op = common()->Parameter(info()->num_parameters() + 1); | 406 const Operator* op = common()->Parameter(info()->num_parameters() + 1); |
| 411 return NewNode(op, graph()->start()); | 407 return NewNode(op, graph()->start()); |
| 412 } | 408 } |
| 413 | 409 |
| 414 | 410 |
| 415 Node* AstGraphBuilder::NewCurrentContextOsrValue() { | 411 Node* AstGraphBuilder::NewCurrentContextOsrValue() { |
| 416 // TODO(titzer): use a real OSR value here; a parameter works by accident. | 412 // TODO(titzer): use a real OSR value here; a parameter works by accident. |
| 417 // Parameter (arity + 1) is special for the outer context of the function | 413 // Parameter (arity + 1) is special for the outer context of the function |
| 418 const Operator* op = common()->Parameter(info()->num_parameters() + 1); | 414 const Operator* op = common()->Parameter(info()->num_parameters() + 1); |
| 419 return NewNode(op, graph()->start()); | 415 return NewNode(op, graph()->start()); |
| 420 } | 416 } |
| 421 | 417 |
| 422 | 418 |
| 423 bool AstGraphBuilder::CreateGraph() { | 419 bool AstGraphBuilder::CreateGraph(bool constant_context) { |
| 424 Scope* scope = info()->scope(); | 420 Scope* scope = info()->scope(); |
| 425 DCHECK(graph() != NULL); | 421 DCHECK(graph() != NULL); |
| 426 | 422 |
| 427 // Set up the basic structure of the graph. | 423 // Set up the basic structure of the graph. |
| 428 int parameter_count = info()->num_parameters(); | 424 int parameter_count = info()->num_parameters(); |
| 429 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); | 425 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); |
| 430 | 426 |
| 431 // Initialize control scope. | 427 // Initialize control scope. |
| 432 ControlScope control(this, 0); | 428 ControlScope control(this, 0); |
| 433 | 429 |
| 434 // Initialize the top-level environment. | 430 // Initialize the top-level environment. |
| 435 Environment env(this, scope, graph()->start()); | 431 Environment env(this, scope, graph()->start()); |
| 436 set_environment(&env); | 432 set_environment(&env); |
| 437 | 433 |
| 438 if (info()->is_osr()) { | 434 if (info()->is_osr()) { |
| 439 // Use OSR normal entry as the start of the top-level environment. | 435 // Use OSR normal entry as the start of the top-level environment. |
| 440 // It will be replaced with {Dead} after typing and optimizations. | 436 // It will be replaced with {Dead} after typing and optimizations. |
| 441 NewNode(common()->OsrNormalEntry()); | 437 NewNode(common()->OsrNormalEntry()); |
| 442 } | 438 } |
| 443 | 439 |
| 444 // Initialize the incoming context. | 440 // Initialize the incoming context. |
| 445 function_context_ = NewOuterContextParam(); | 441 if (constant_context) { |
|
Michael Starzinger
2015/02/18 17:37:32
nit: Can we move this logic into GetFunctionContex
titzer
2015/02/19 09:53:04
As discussed in person, I've moved this into Creat
| |
| 446 ContextScope incoming(this, scope, function_context_); | 442 function_context_.set(jsgraph()->HeapConstant(info()->context())); |
| 443 } else { | |
| 444 function_context_.set(NewOuterContextParam()); | |
| 445 } | |
| 446 ContextScope incoming(this, scope, function_context_.get()); | |
| 447 | 447 |
| 448 // Build receiver check for sloppy mode if necessary. | 448 // Build receiver check for sloppy mode if necessary. |
| 449 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? | 449 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
| 450 Node* original_receiver = env.Lookup(scope->receiver()); | 450 Node* original_receiver = env.Lookup(scope->receiver()); |
| 451 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 451 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
| 452 env.Bind(scope->receiver(), patched_receiver); | 452 env.Bind(scope->receiver(), patched_receiver); |
| 453 | 453 |
| 454 bool ok; | 454 bool ok; |
| 455 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 455 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 456 if (heap_slots > 0) { | 456 if (heap_slots > 0) { |
| 457 // Push a new inner context scope for the function. | 457 // Push a new inner context scope for the function. |
| 458 Node* closure = GetFunctionClosure(); | 458 Node* closure = GetFunctionClosure(); |
| 459 Node* inner_context = BuildLocalFunctionContext(function_context_, closure); | 459 Node* inner_context = |
| 460 BuildLocalFunctionContext(function_context_.get(), closure); | |
| 460 ContextScope top_context(this, scope, inner_context); | 461 ContextScope top_context(this, scope, inner_context); |
| 461 ok = CreateGraphBody(); | 462 ok = CreateGraphBody(); |
| 462 } else { | 463 } else { |
| 463 // Simply use the outer function context in building the graph. | 464 // Simply use the outer function context in building the graph. |
| 464 ok = CreateGraphBody(); | 465 ok = CreateGraphBody(); |
| 465 } | 466 } |
| 466 | 467 |
| 467 // Finish the basic structure of the graph. | 468 // Finish the basic structure of the graph. |
| 468 if (ok) { | 469 if (ok) { |
| 469 environment()->UpdateControlDependency(exit_control()); | 470 environment()->UpdateControlDependency(exit_control()); |
| (...skipping 2564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3034 | 3035 |
| 3035 // Resurrect a dead environment by copying the contents of the other one and | 3036 // Resurrect a dead environment by copying the contents of the other one and |
| 3036 // placing a singleton merge as the new control dependency. | 3037 // placing a singleton merge as the new control dependency. |
| 3037 if (this->IsMarkedAsUnreachable()) { | 3038 if (this->IsMarkedAsUnreachable()) { |
| 3038 Node* other_control = other->control_dependency_; | 3039 Node* other_control = other->control_dependency_; |
| 3039 Node* inputs[] = {other_control}; | 3040 Node* inputs[] = {other_control}; |
| 3040 control_dependency_ = | 3041 control_dependency_ = |
| 3041 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); | 3042 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); |
| 3042 effect_dependency_ = other->effect_dependency_; | 3043 effect_dependency_ = other->effect_dependency_; |
| 3043 values_ = other->values_; | 3044 values_ = other->values_; |
| 3045 contexts_ = other->contexts_; | |
| 3044 return; | 3046 return; |
| 3045 } | 3047 } |
| 3046 | 3048 |
| 3047 // Create a merge of the control dependencies of both environments and update | 3049 // Create a merge of the control dependencies of both environments and update |
| 3048 // the current environment's control dependency accordingly. | 3050 // the current environment's control dependency accordingly. |
| 3049 Node* control = builder_->MergeControl(this->GetControlDependency(), | 3051 Node* control = builder_->MergeControl(this->GetControlDependency(), |
| 3050 other->GetControlDependency()); | 3052 other->GetControlDependency()); |
| 3051 UpdateControlDependency(control); | 3053 UpdateControlDependency(control); |
| 3052 | 3054 |
| 3053 // Create a merge of the effect dependencies of both environments and update | 3055 // Create a merge of the effect dependencies of both environments and update |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3207 // Phi does not exist yet, introduce one. | 3209 // Phi does not exist yet, introduce one. |
| 3208 value = NewPhi(inputs, value, control); | 3210 value = NewPhi(inputs, value, control); |
| 3209 value->ReplaceInput(inputs - 1, other); | 3211 value->ReplaceInput(inputs - 1, other); |
| 3210 } | 3212 } |
| 3211 return value; | 3213 return value; |
| 3212 } | 3214 } |
| 3213 | 3215 |
| 3214 } // namespace compiler | 3216 } // namespace compiler |
| 3215 } // namespace internal | 3217 } // namespace internal |
| 3216 } // namespace v8 | 3218 } // namespace v8 |
| OLD | NEW |