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

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

Issue 949743002: [turbofan] Variable liveness analysis for deopt (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address review comments Created 5 years, 9 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/liveness-analyzer.h » ('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"
11 #include "src/compiler/liveness-analyzer.h"
11 #include "src/compiler/machine-operator.h" 12 #include "src/compiler/machine-operator.h"
12 #include "src/compiler/node-matchers.h" 13 #include "src/compiler/node-matchers.h"
13 #include "src/compiler/node-properties.h" 14 #include "src/compiler/node-properties.h"
14 #include "src/compiler/operator-properties.h" 15 #include "src/compiler/operator-properties.h"
15 #include "src/compiler/state-values-utils.h" 16 #include "src/compiler/state-values-utils.h"
16 #include "src/full-codegen.h" 17 #include "src/full-codegen.h"
17 #include "src/parser.h" 18 #include "src/parser.h"
18 #include "src/scopes.h" 19 #include "src/scopes.h"
19 20
20 namespace v8 { 21 namespace v8 {
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 environment_(nullptr), 388 environment_(nullptr),
388 ast_context_(nullptr), 389 ast_context_(nullptr),
389 globals_(0, local_zone), 390 globals_(0, local_zone),
390 execution_control_(nullptr), 391 execution_control_(nullptr),
391 execution_context_(nullptr), 392 execution_context_(nullptr),
392 try_nesting_level_(0), 393 try_nesting_level_(0),
393 input_buffer_size_(0), 394 input_buffer_size_(0),
394 input_buffer_(nullptr), 395 input_buffer_(nullptr),
395 exit_control_(nullptr), 396 exit_control_(nullptr),
396 loop_assignment_analysis_(loop), 397 loop_assignment_analysis_(loop),
397 state_values_cache_(jsgraph) { 398 state_values_cache_(jsgraph),
399 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()),
400 local_zone) {
398 InitializeAstVisitor(info->isolate(), local_zone); 401 InitializeAstVisitor(info->isolate(), local_zone);
399 } 402 }
400 403
401 404
402 Node* AstGraphBuilder::GetFunctionClosure() { 405 Node* AstGraphBuilder::GetFunctionClosure() {
403 if (!function_closure_.is_set()) { 406 if (!function_closure_.is_set()) {
404 const Operator* op = 407 const Operator* op =
405 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); 408 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex);
406 Node* node = NewNode(op, graph()->start()); 409 Node* node = NewNode(op, graph()->start());
407 function_closure_.set(node); 410 function_closure_.set(node);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 ContextScope top_context(this, scope, inner_context); 476 ContextScope top_context(this, scope, inner_context);
474 CreateGraphBody(stack_check); 477 CreateGraphBody(stack_check);
475 } else { 478 } else {
476 // Simply use the outer function context in building the graph. 479 // Simply use the outer function context in building the graph.
477 CreateGraphBody(stack_check); 480 CreateGraphBody(stack_check);
478 } 481 }
479 482
480 // Finish the basic structure of the graph. 483 // Finish the basic structure of the graph.
481 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); 484 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control()));
482 485
486 // Compute local variable liveness information and use it to relax
487 // frame states.
488 ClearNonLiveSlotsInFrameStates();
489
483 // Failures indicated by stack overflow. 490 // Failures indicated by stack overflow.
484 return !HasStackOverflow(); 491 return !HasStackOverflow();
485 } 492 }
486 493
487 494
488 void AstGraphBuilder::CreateGraphBody(bool stack_check) { 495 void AstGraphBuilder::CreateGraphBody(bool stack_check) {
489 Scope* scope = info()->scope(); 496 Scope* scope = info()->scope();
490 497
491 // Build the arguments object if it is used. 498 // Build the arguments object if it is used.
492 BuildArgumentsObject(scope->arguments()); 499 BuildArgumentsObject(scope->arguments());
(...skipping 30 matching lines...) Expand all
523 // TODO(mstarzinger): Only traces implicit return. 530 // TODO(mstarzinger): Only traces implicit return.
524 Node* return_value = jsgraph()->UndefinedConstant(); 531 Node* return_value = jsgraph()->UndefinedConstant();
525 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); 532 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value);
526 } 533 }
527 534
528 // Return 'undefined' in case we can fall off the end. 535 // Return 'undefined' in case we can fall off the end.
529 BuildReturn(jsgraph()->UndefinedConstant()); 536 BuildReturn(jsgraph()->UndefinedConstant());
530 } 537 }
531 538
532 539
540 void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() {
541 if (!FLAG_analyze_environment_liveness) return;
542
543 NonLiveFrameStateSlotReplacer replacer(
544 &state_values_cache_, jsgraph()->UndefinedConstant(),
545 liveness_analyzer()->local_count(), local_zone());
546 Variable* arguments = info()->scope()->arguments();
547 if (arguments != nullptr && arguments->IsStackAllocated()) {
548 replacer.MarkPermanentlyLive(arguments->index());
549 }
550 liveness_analyzer()->Run(&replacer);
551 if (FLAG_trace_environment_liveness) {
552 OFStream os(stdout);
553 liveness_analyzer()->Print(os);
554 }
555 }
556
557
533 // Left-hand side can only be a property, a global or a variable slot. 558 // Left-hand side can only be a property, a global or a variable slot.
534 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 559 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
535 560
536 561
537 // Determine the left-hand side kind of an assignment. 562 // Determine the left-hand side kind of an assignment.
538 static LhsKind DetermineLhsKind(Expression* expr) { 563 static LhsKind DetermineLhsKind(Expression* expr) {
539 Property* property = expr->AsProperty(); 564 Property* property = expr->AsProperty();
540 DCHECK(expr->IsValidReferenceExpression()); 565 DCHECK(expr->IsValidReferenceExpression());
541 LhsKind lhs_kind = 566 LhsKind lhs_kind =
542 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) 567 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName())
543 ? NAMED_PROPERTY 568 ? NAMED_PROPERTY
544 : KEYED_PROPERTY; 569 : KEYED_PROPERTY;
545 return lhs_kind; 570 return lhs_kind;
546 } 571 }
547 572
548 573
549 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, 574 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
550 Scope* scope, 575 Scope* scope,
551 Node* control_dependency) 576 Node* control_dependency)
552 : builder_(builder), 577 : builder_(builder),
553 parameters_count_(scope->num_parameters() + 1), 578 parameters_count_(scope->num_parameters() + 1),
554 locals_count_(scope->num_stack_slots()), 579 locals_count_(scope->num_stack_slots()),
580 liveness_block_(builder_->liveness_analyzer()->NewBlock()),
555 values_(builder_->local_zone()), 581 values_(builder_->local_zone()),
556 contexts_(builder_->local_zone()), 582 contexts_(builder_->local_zone()),
557 control_dependency_(control_dependency), 583 control_dependency_(control_dependency),
558 effect_dependency_(control_dependency), 584 effect_dependency_(control_dependency),
559 parameters_node_(nullptr), 585 parameters_node_(nullptr),
560 locals_node_(nullptr), 586 locals_node_(nullptr),
561 stack_node_(nullptr) { 587 stack_node_(nullptr) {
562 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); 588 DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
563 589
564 // Bind the receiver variable. 590 // Bind the receiver variable.
565 Node* receiver = builder->graph()->NewNode(common()->Parameter(0), 591 Node* receiver = builder->graph()->NewNode(common()->Parameter(0),
566 builder->graph()->start()); 592 builder->graph()->start());
567 values()->push_back(receiver); 593 values()->push_back(receiver);
568 594
569 // Bind all parameter variables. The parameter indices are shifted by 1 595 // Bind all parameter variables. The parameter indices are shifted by 1
570 // (receiver is parameter index -1 but environment index 0). 596 // (receiver is parameter index -1 but environment index 0).
571 for (int i = 0; i < scope->num_parameters(); ++i) { 597 for (int i = 0; i < scope->num_parameters(); ++i) {
572 Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1), 598 Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1),
573 builder->graph()->start()); 599 builder->graph()->start());
574 values()->push_back(parameter); 600 values()->push_back(parameter);
575 } 601 }
576 602
577 // Bind all local variables to undefined. 603 // Bind all local variables to undefined.
578 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); 604 Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
579 values()->insert(values()->end(), locals_count(), undefined_constant); 605 values()->insert(values()->end(), locals_count(), undefined_constant);
580 } 606 }
581 607
582 608
583 AstGraphBuilder::Environment::Environment( 609 AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy)
584 const AstGraphBuilder::Environment* copy)
585 : builder_(copy->builder_), 610 : builder_(copy->builder_),
586 parameters_count_(copy->parameters_count_), 611 parameters_count_(copy->parameters_count_),
587 locals_count_(copy->locals_count_), 612 locals_count_(copy->locals_count_),
588 values_(copy->zone()), 613 values_(copy->zone()),
589 contexts_(copy->zone()), 614 contexts_(copy->zone()),
590 control_dependency_(copy->control_dependency_), 615 control_dependency_(copy->control_dependency_),
591 effect_dependency_(copy->effect_dependency_), 616 effect_dependency_(copy->effect_dependency_),
592 parameters_node_(copy->parameters_node_), 617 parameters_node_(copy->parameters_node_),
593 locals_node_(copy->locals_node_), 618 locals_node_(copy->locals_node_),
594 stack_node_(copy->stack_node_) { 619 stack_node_(copy->stack_node_) {
595 const size_t kStackEstimate = 7; // optimum from experimentation! 620 const size_t kStackEstimate = 7; // optimum from experimentation!
596 values_.reserve(copy->values_.size() + kStackEstimate); 621 values_.reserve(copy->values_.size() + kStackEstimate);
597 values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end()); 622 values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end());
598 contexts_.reserve(copy->contexts_.size()); 623 contexts_.reserve(copy->contexts_.size());
599 contexts_.insert(contexts_.begin(), copy->contexts_.begin(), 624 contexts_.insert(contexts_.begin(), copy->contexts_.begin(),
600 copy->contexts_.end()); 625 copy->contexts_.end());
626
627 if (FLAG_analyze_environment_liveness) {
628 // Split the liveness blocks.
629 copy->liveness_block_ =
630 builder_->liveness_analyzer()->NewBlock(copy->liveness_block());
631 liveness_block_ =
632 builder_->liveness_analyzer()->NewBlock(copy->liveness_block());
633 }
601 } 634 }
602 635
603 636
637 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) {
638 DCHECK(variable->IsStackAllocated());
639 if (variable->IsParameter()) {
640 // The parameter indices are shifted by 1 (receiver is parameter
641 // index -1 but environment index 0).
642 values()->at(variable->index() + 1) = node;
643 } else {
644 DCHECK(variable->IsStackLocal());
645 values()->at(variable->index() + parameters_count_) = node;
646 if (FLAG_analyze_environment_liveness) {
647 liveness_block()->Bind(variable->index());
648 }
649 }
650 }
651
652
653 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) {
654 DCHECK(variable->IsStackAllocated());
655 if (variable->IsParameter()) {
656 // The parameter indices are shifted by 1 (receiver is parameter
657 // index -1 but environment index 0).
658 return values()->at(variable->index() + 1);
659 } else {
660 DCHECK(variable->IsStackLocal());
661 if (FLAG_analyze_environment_liveness) {
662 liveness_block()->Lookup(variable->index());
663 }
664 return values()->at(variable->index() + parameters_count_);
665 }
666 }
667
668
669 void AstGraphBuilder::Environment::MarkAllLocalsLive() {
670 if (FLAG_analyze_environment_liveness) {
671 for (int i = 0; i < locals_count_; i++) {
672 liveness_block()->Lookup(i);
673 }
674 }
675 }
676
677
678 AstGraphBuilder::Environment*
679 AstGraphBuilder::Environment::CopyAndShareLiveness() {
680 Environment* env = new (zone()) Environment(this);
681 if (FLAG_analyze_environment_liveness) {
682 env->liveness_block_ = liveness_block();
683 }
684 return env;
685 }
686
687
604 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, 688 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
605 int offset, int count) { 689 int offset, int count) {
606 bool should_update = false; 690 bool should_update = false;
607 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); 691 Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
608 if (*state_values == NULL || (*state_values)->InputCount() != count) { 692 if (*state_values == NULL || (*state_values)->InputCount() != count) {
609 should_update = true; 693 should_update = true;
610 } else { 694 } else {
611 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); 695 DCHECK(static_cast<size_t>(offset + count) <= values()->size());
612 for (int i = 0; i < count; i++) { 696 for (int i = 0; i < count; i++) {
613 if ((*state_values)->InputAt(i) != env_values[i]) { 697 if ((*state_values)->InputAt(i) != env_values[i]) {
(...skipping 21 matching lines...) Expand all
635 BailoutId ast_id, OutputFrameStateCombine combine) { 719 BailoutId ast_id, OutputFrameStateCombine combine) {
636 if (!FLAG_turbo_deoptimization) return nullptr; 720 if (!FLAG_turbo_deoptimization) return nullptr;
637 721
638 UpdateStateValues(&parameters_node_, 0, parameters_count()); 722 UpdateStateValues(&parameters_node_, 0, parameters_count());
639 UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count()); 723 UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count());
640 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), 724 UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
641 stack_height()); 725 stack_height());
642 726
643 const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine); 727 const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine);
644 728
645 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_, 729 Node* result = graph()->NewNode(op, parameters_node_, locals_node_,
646 builder()->current_context(), 730 stack_node_, builder()->current_context(),
647 builder()->jsgraph()->UndefinedConstant()); 731 builder()->jsgraph()->UndefinedConstant());
732 if (FLAG_analyze_environment_liveness) {
733 liveness_block()->Checkpoint(result);
734 }
735 return result;
648 } 736 }
649 737
650 738
651 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, 739 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
652 Expression::Context kind) 740 Expression::Context kind)
653 : kind_(kind), owner_(own), outer_(own->ast_context()) { 741 : kind_(kind), owner_(own), outer_(own->ast_context()) {
654 owner()->set_ast_context(this); // Push. 742 owner()->set_ast_context(this); // Push.
655 #ifdef DEBUG 743 #ifdef DEBUG
656 original_height_ = environment()->stack_height(); 744 original_height_ = environment()->stack_height();
657 #endif 745 #endif
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 1414
1327 // TODO(mstarzinger): Remove bailout once everything works. 1415 // TODO(mstarzinger): Remove bailout once everything works.
1328 if (!FLAG_turbo_exceptions) SetStackOverflow(); 1416 if (!FLAG_turbo_exceptions) SetStackOverflow();
1329 } 1417 }
1330 1418
1331 1419
1332 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 1420 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
1333 // TODO(turbofan): Do we really need a separate reloc-info for this? 1421 // TODO(turbofan): Do we really need a separate reloc-info for this?
1334 Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0)); 1422 Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0));
1335 PrepareFrameState(node, stmt->DebugBreakId()); 1423 PrepareFrameState(node, stmt->DebugBreakId());
1424 environment()->MarkAllLocalsLive();
1336 } 1425 }
1337 1426
1338 1427
1339 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 1428 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
1340 Node* context = current_context(); 1429 Node* context = current_context();
1341 1430
1342 // Build a new shared function info if we cannot find one in the baseline 1431 // Build a new shared function info if we cannot find one in the baseline
1343 // code. We also have a stack overflow if the recursive compilation did. 1432 // code. We also have a stack overflow if the recursive compilation did.
1344 expr->InitializeSharedInfo(handle(info()->shared_info()->code())); 1433 expr->InitializeSharedInfo(handle(info()->shared_info()->code()));
1345 Handle<SharedFunctionInfo> shared_info = expr->shared_info(); 1434 Handle<SharedFunctionInfo> shared_info = expr->shared_info();
(...skipping 1821 matching lines...) Expand 10 before | Expand all | Expand 10 after
3167 DCHECK(contexts_.size() <= other->contexts_.size()); 3256 DCHECK(contexts_.size() <= other->contexts_.size());
3168 3257
3169 // Nothing to do if the other environment is dead. 3258 // Nothing to do if the other environment is dead.
3170 if (other->IsMarkedAsUnreachable()) return; 3259 if (other->IsMarkedAsUnreachable()) return;
3171 3260
3172 // Resurrect a dead environment by copying the contents of the other one and 3261 // Resurrect a dead environment by copying the contents of the other one and
3173 // placing a singleton merge as the new control dependency. 3262 // placing a singleton merge as the new control dependency.
3174 if (this->IsMarkedAsUnreachable()) { 3263 if (this->IsMarkedAsUnreachable()) {
3175 Node* other_control = other->control_dependency_; 3264 Node* other_control = other->control_dependency_;
3176 Node* inputs[] = {other_control}; 3265 Node* inputs[] = {other_control};
3266 liveness_block_ = other->liveness_block_;
3177 control_dependency_ = 3267 control_dependency_ =
3178 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); 3268 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
3179 effect_dependency_ = other->effect_dependency_; 3269 effect_dependency_ = other->effect_dependency_;
3180 values_ = other->values_; 3270 values_ = other->values_;
3181 // TODO(titzer): make context stack heights match. 3271 // TODO(titzer): make context stack heights match.
3182 size_t min = std::min(contexts_.size(), other->contexts_.size()); 3272 size_t min = std::min(contexts_.size(), other->contexts_.size());
3183 contexts_ = other->contexts_; 3273 contexts_ = other->contexts_;
3184 contexts_.resize(min, nullptr); 3274 contexts_.resize(min, nullptr);
3185 return; 3275 return;
3186 } 3276 }
3187 3277
3278 // Record the merge for the local variable liveness calculation.
3279 // Unfortunately, we have to mirror the logic in the MergeControl method:
3280 // connect before merge or loop, or create a new merge otherwise.
3281 if (FLAG_analyze_environment_liveness) {
3282 if (GetControlDependency()->opcode() != IrOpcode::kLoop &&
3283 GetControlDependency()->opcode() != IrOpcode::kMerge) {
3284 liveness_block_ =
3285 builder_->liveness_analyzer()->NewBlock(liveness_block());
3286 }
3287 liveness_block()->AddPredecessor(other->liveness_block());
3288 }
3289
3188 // Create a merge of the control dependencies of both environments and update 3290 // Create a merge of the control dependencies of both environments and update
3189 // the current environment's control dependency accordingly. 3291 // the current environment's control dependency accordingly.
3190 Node* control = builder_->MergeControl(this->GetControlDependency(), 3292 Node* control = builder_->MergeControl(this->GetControlDependency(),
3191 other->GetControlDependency()); 3293 other->GetControlDependency());
3192 UpdateControlDependency(control); 3294 UpdateControlDependency(control);
3193 3295
3194 // Create a merge of the effect dependencies of both environments and update 3296 // Create a merge of the effect dependencies of both environments and update
3195 // the current environment's effect dependency accordingly. 3297 // the current environment's effect dependency accordingly.
3196 Node* effect = builder_->MergeEffect(this->GetEffectDependency(), 3298 Node* effect = builder_->MergeEffect(this->GetEffectDependency(),
3197 other->GetEffectDependency(), control); 3299 other->GetEffectDependency(), control);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
3348 // Phi does not exist yet, introduce one. 3450 // Phi does not exist yet, introduce one.
3349 value = NewPhi(inputs, value, control); 3451 value = NewPhi(inputs, value, control);
3350 value->ReplaceInput(inputs - 1, other); 3452 value->ReplaceInput(inputs - 1, other);
3351 } 3453 }
3352 return value; 3454 return value;
3353 } 3455 }
3354 3456
3355 } // namespace compiler 3457 } // namespace compiler
3356 } // namespace internal 3458 } // namespace internal
3357 } // namespace v8 3459 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/liveness-analyzer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698