Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 934293002: [turbofan] Simply context specialization and fix for OSR. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/control-reducer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 void AstGraphBuilder::CreateFunctionContext(bool constant_context) {
403 DCHECK(function_context_ != nullptr); 402 function_context_.set(constant_context
404 return function_context_; 403 ? jsgraph()->HeapConstant(info()->context())
404 : NewOuterContextParam());
405 } 405 }
406 406
407 407
408 Node* AstGraphBuilder::NewOuterContextParam() { 408 Node* AstGraphBuilder::NewOuterContextParam() {
409 // Parameter (arity + 1) is special for the outer context of the function 409 // Parameter (arity + 1) is special for the outer context of the function
410 const Operator* op = common()->Parameter(info()->num_parameters() + 1); 410 const Operator* op = common()->Parameter(info()->num_parameters() + 1);
411 return NewNode(op, graph()->start()); 411 return NewNode(op, graph()->start());
412 } 412 }
413 413
414 414
415 Node* AstGraphBuilder::NewCurrentContextOsrValue() { 415 Node* AstGraphBuilder::NewCurrentContextOsrValue() {
416 // TODO(titzer): use a real OSR value here; a parameter works by accident. 416 // 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 417 // Parameter (arity + 1) is special for the outer context of the function
418 const Operator* op = common()->Parameter(info()->num_parameters() + 1); 418 const Operator* op = common()->Parameter(info()->num_parameters() + 1);
419 return NewNode(op, graph()->start()); 419 return NewNode(op, graph()->start());
420 } 420 }
421 421
422 422
423 bool AstGraphBuilder::CreateGraph() { 423 bool AstGraphBuilder::CreateGraph(bool constant_context) {
424 Scope* scope = info()->scope(); 424 Scope* scope = info()->scope();
425 DCHECK(graph() != NULL); 425 DCHECK(graph() != NULL);
426 426
427 // Set up the basic structure of the graph. 427 // Set up the basic structure of the graph.
428 int parameter_count = info()->num_parameters(); 428 int parameter_count = info()->num_parameters();
429 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); 429 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count)));
430 430
431 // Initialize control scope. 431 // Initialize control scope.
432 ControlScope control(this, 0); 432 ControlScope control(this, 0);
433 433
434 // Initialize the top-level environment. 434 // Initialize the top-level environment.
435 Environment env(this, scope, graph()->start()); 435 Environment env(this, scope, graph()->start());
436 set_environment(&env); 436 set_environment(&env);
437 437
438 if (info()->is_osr()) { 438 if (info()->is_osr()) {
439 // Use OSR normal entry as the start of the top-level environment. 439 // Use OSR normal entry as the start of the top-level environment.
440 // It will be replaced with {Dead} after typing and optimizations. 440 // It will be replaced with {Dead} after typing and optimizations.
441 NewNode(common()->OsrNormalEntry()); 441 NewNode(common()->OsrNormalEntry());
442 } 442 }
443 443
444 // Initialize the incoming context. 444 // Initialize the incoming context.
445 function_context_ = NewOuterContextParam(); 445 CreateFunctionContext(constant_context);
446 ContextScope incoming(this, scope, function_context_); 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 // Build function context only if there are context allocated variables. 454 // Build function context only if there are context allocated variables.
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 CreateGraphBody(); 462 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 CreateGraphBody(); 465 CreateGraphBody();
465 } 466 }
466 467
467 // Finish the basic structure of the graph. 468 // Finish the basic structure of the graph.
468 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); 469 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control()));
469 470
(...skipping 2283 matching lines...) Expand 10 before | Expand all | Expand 10 after
2753 2754
2754 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { 2755 Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
2755 Node* global = BuildLoadGlobalObject(); 2756 Node* global = BuildLoadGlobalObject();
2756 Node* builtins = 2757 Node* builtins =
2757 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); 2758 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
2758 return builtins; 2759 return builtins;
2759 } 2760 }
2760 2761
2761 2762
2762 Node* AstGraphBuilder::BuildLoadGlobalObject() { 2763 Node* AstGraphBuilder::BuildLoadGlobalObject() {
2763 Node* context = GetFunctionContext();
2764 const Operator* load_op = 2764 const Operator* load_op =
2765 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); 2765 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
2766 return NewNode(load_op, context); 2766 return NewNode(load_op, function_context_.get());
2767 } 2767 }
2768 2768
2769 2769
2770 Node* AstGraphBuilder::BuildLoadGlobalProxy() { 2770 Node* AstGraphBuilder::BuildLoadGlobalProxy() {
2771 Node* global = BuildLoadGlobalObject(); 2771 Node* global = BuildLoadGlobalObject();
2772 Node* proxy = 2772 Node* proxy =
2773 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset); 2773 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset);
2774 return proxy; 2774 return proxy;
2775 } 2775 }
2776 2776
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
3016 if (exit_control() != NULL) { 3016 if (exit_control() != NULL) {
3017 exit = MergeControl(exit_control(), exit); 3017 exit = MergeControl(exit_control(), exit);
3018 } 3018 }
3019 environment()->MarkAsUnreachable(); 3019 environment()->MarkAsUnreachable();
3020 set_exit_control(exit); 3020 set_exit_control(exit);
3021 } 3021 }
3022 3022
3023 3023
3024 void AstGraphBuilder::Environment::Merge(Environment* other) { 3024 void AstGraphBuilder::Environment::Merge(Environment* other) {
3025 DCHECK(values_.size() == other->values_.size()); 3025 DCHECK(values_.size() == other->values_.size());
3026 // TODO(titzer): make context stack heights match.
3026 DCHECK(contexts_.size() <= other->contexts_.size()); 3027 DCHECK(contexts_.size() <= other->contexts_.size());
3027 3028
3028 // Nothing to do if the other environment is dead. 3029 // Nothing to do if the other environment is dead.
3029 if (other->IsMarkedAsUnreachable()) return; 3030 if (other->IsMarkedAsUnreachable()) return;
3030 3031
3031 // Resurrect a dead environment by copying the contents of the other one and 3032 // Resurrect a dead environment by copying the contents of the other one and
3032 // placing a singleton merge as the new control dependency. 3033 // placing a singleton merge as the new control dependency.
3033 if (this->IsMarkedAsUnreachable()) { 3034 if (this->IsMarkedAsUnreachable()) {
3034 Node* other_control = other->control_dependency_; 3035 Node* other_control = other->control_dependency_;
3035 Node* inputs[] = {other_control}; 3036 Node* inputs[] = {other_control};
3036 control_dependency_ = 3037 control_dependency_ =
3037 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); 3038 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
3038 effect_dependency_ = other->effect_dependency_; 3039 effect_dependency_ = other->effect_dependency_;
3039 values_ = other->values_; 3040 values_ = other->values_;
3041 // TODO(titzer): make context stack heights match.
3042 size_t min = std::min(contexts_.size(), other->contexts_.size());
3043 contexts_ = other->contexts_;
3044 contexts_.resize(min, nullptr);
3040 return; 3045 return;
3041 } 3046 }
3042 3047
3043 // Create a merge of the control dependencies of both environments and update 3048 // Create a merge of the control dependencies of both environments and update
3044 // the current environment's control dependency accordingly. 3049 // the current environment's control dependency accordingly.
3045 Node* control = builder_->MergeControl(this->GetControlDependency(), 3050 Node* control = builder_->MergeControl(this->GetControlDependency(),
3046 other->GetControlDependency()); 3051 other->GetControlDependency());
3047 UpdateControlDependency(control); 3052 UpdateControlDependency(control);
3048 3053
3049 // Create a merge of the effect dependencies of both environments and update 3054 // Create a merge of the effect dependencies of both environments and update
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
3203 // Phi does not exist yet, introduce one. 3208 // Phi does not exist yet, introduce one.
3204 value = NewPhi(inputs, value, control); 3209 value = NewPhi(inputs, value, control);
3205 value->ReplaceInput(inputs - 1, other); 3210 value->ReplaceInput(inputs - 1, other);
3206 } 3211 }
3207 return value; 3212 return value;
3208 } 3213 }
3209 3214
3210 } // namespace compiler 3215 } // namespace compiler
3211 } // namespace internal 3216 } // namespace internal
3212 } // namespace v8 3217 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/control-reducer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698