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" |
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/full-codegen.h" | 16 #include "src/full-codegen.h" |
16 #include "src/parser.h" | 17 #include "src/parser.h" |
17 #include "src/scopes.h" | 18 #include "src/scopes.h" |
18 | 19 |
19 namespace v8 { | 20 namespace v8 { |
20 namespace internal { | 21 namespace internal { |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 jsgraph_(jsgraph), | 387 jsgraph_(jsgraph), |
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), |
398 liveness_analyzer_(new (local_zone) LivenessAnalyzer( | |
399 static_cast<size_t>(info->scope()->num_stack_slots()), local_zone)) { | |
397 InitializeAstVisitor(info->isolate(), local_zone); | 400 InitializeAstVisitor(info->isolate(), local_zone); |
398 } | 401 } |
399 | 402 |
400 | 403 |
401 Node* AstGraphBuilder::GetFunctionClosure() { | 404 Node* AstGraphBuilder::GetFunctionClosure() { |
402 if (!function_closure_.is_set()) { | 405 if (!function_closure_.is_set()) { |
403 const Operator* op = | 406 const Operator* op = |
404 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); | 407 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); |
405 Node* node = NewNode(op, graph()->start()); | 408 Node* node = NewNode(op, graph()->start()); |
406 function_closure_.set(node); | 409 function_closure_.set(node); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 | 520 |
518 // Emit tracing call if requested to do so. | 521 // Emit tracing call if requested to do so. |
519 if (FLAG_trace) { | 522 if (FLAG_trace) { |
520 // TODO(mstarzinger): Only traces implicit return. | 523 // TODO(mstarzinger): Only traces implicit return. |
521 Node* return_value = jsgraph()->UndefinedConstant(); | 524 Node* return_value = jsgraph()->UndefinedConstant(); |
522 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); | 525 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); |
523 } | 526 } |
524 | 527 |
525 // Return 'undefined' in case we can fall off the end. | 528 // Return 'undefined' in case we can fall off the end. |
526 BuildReturn(jsgraph()->UndefinedConstant()); | 529 BuildReturn(jsgraph()->UndefinedConstant()); |
530 | |
531 // Finish the basic structure of the graph. | |
532 environment()->UpdateControlDependency(exit_control()); | |
533 graph()->SetEnd(NewNode(common()->End())); | |
Michael Starzinger
2015/03/01 21:00:56
This duplicates the end node, please don't do this
Jarin
2015/03/16 21:30:12
Great catch, bad rebase. Done.
| |
534 | |
535 // Compute local variable liveness information and use it to relax | |
536 // frame states. | |
537 RelaxFrameStatesWithLiveness(); | |
Michael Starzinger
2015/03/01 21:00:56
Rather move this call into CreateGraph() a few lin
Jarin
2015/03/16 21:30:12
Done.
| |
527 } | 538 } |
528 | 539 |
529 | 540 |
541 void AstGraphBuilder::RelaxFrameStatesWithLiveness() { | |
542 if (!FLAG_analyze_environment_liveness) return; | |
543 | |
544 FrameStateRelaxer relaxer(jsgraph(), jsgraph()->UndefinedConstant(), | |
545 liveness_analyzer()->local_count(), local_zone()); | |
546 Variable* arguments = info()->scope()->arguments(); | |
547 if (arguments != nullptr && arguments->IsStackAllocated()) { | |
548 relaxer.Blacklist(arguments->index()); | |
titzer
2015/02/27 21:09:55
Maybe "MarkPermanentlyLive(int index)" as a better
Jarin
2015/03/16 21:30:12
Done.
| |
549 } | |
550 liveness_analyzer()->Run(&relaxer); | |
551 if (FLAG_trace_environment_liveness) { | |
552 OFStream os(stdout); | |
553 liveness_analyzer()->Print(os); | |
554 } | |
555 } | |
556 | |
557 | |
530 // 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. |
531 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 559 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
532 | 560 |
533 | 561 |
534 // Determine the left-hand side kind of an assignment. | 562 // Determine the left-hand side kind of an assignment. |
535 static LhsKind DetermineLhsKind(Expression* expr) { | 563 static LhsKind DetermineLhsKind(Expression* expr) { |
536 Property* property = expr->AsProperty(); | 564 Property* property = expr->AsProperty(); |
537 DCHECK(expr->IsValidReferenceExpression()); | 565 DCHECK(expr->IsValidReferenceExpression()); |
538 LhsKind lhs_kind = | 566 LhsKind lhs_kind = |
539 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) | 567 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) |
540 ? NAMED_PROPERTY | 568 ? NAMED_PROPERTY |
541 : KEYED_PROPERTY; | 569 : KEYED_PROPERTY; |
542 return lhs_kind; | 570 return lhs_kind; |
543 } | 571 } |
544 | 572 |
545 | 573 |
546 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, | 574 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, |
547 Scope* scope, | 575 Scope* scope, |
548 Node* control_dependency) | 576 Node* control_dependency) |
549 : builder_(builder), | 577 : builder_(builder), |
550 parameters_count_(scope->num_parameters() + 1), | 578 parameters_count_(scope->num_parameters() + 1), |
551 locals_count_(scope->num_stack_slots()), | 579 locals_count_(scope->num_stack_slots()), |
580 liveness_block_(builder_->liveness_analyzer()->New()), | |
552 values_(builder_->local_zone()), | 581 values_(builder_->local_zone()), |
553 contexts_(builder_->local_zone()), | 582 contexts_(builder_->local_zone()), |
554 control_dependency_(control_dependency), | 583 control_dependency_(control_dependency), |
555 effect_dependency_(control_dependency), | 584 effect_dependency_(control_dependency), |
556 parameters_node_(nullptr), | 585 parameters_node_(nullptr), |
557 locals_node_(nullptr), | 586 locals_node_(nullptr), |
558 stack_node_(nullptr) { | 587 stack_node_(nullptr) { |
559 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); | 588 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); |
560 | 589 |
561 // Bind the receiver variable. | 590 // Bind the receiver variable. |
562 Node* receiver = builder->graph()->NewNode(common()->Parameter(0), | 591 Node* receiver = builder->graph()->NewNode(common()->Parameter(0), |
563 builder->graph()->start()); | 592 builder->graph()->start()); |
564 values()->push_back(receiver); | 593 values()->push_back(receiver); |
565 | 594 |
566 // Bind all parameter variables. The parameter indices are shifted by 1 | 595 // Bind all parameter variables. The parameter indices are shifted by 1 |
567 // (receiver is parameter index -1 but environment index 0). | 596 // (receiver is parameter index -1 but environment index 0). |
568 for (int i = 0; i < scope->num_parameters(); ++i) { | 597 for (int i = 0; i < scope->num_parameters(); ++i) { |
569 Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1), | 598 Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1), |
570 builder->graph()->start()); | 599 builder->graph()->start()); |
571 values()->push_back(parameter); | 600 values()->push_back(parameter); |
572 } | 601 } |
573 | 602 |
574 // Bind all local variables to undefined. | 603 // Bind all local variables to undefined. |
575 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 604 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
576 values()->insert(values()->end(), locals_count(), undefined_constant); | 605 values()->insert(values()->end(), locals_count(), undefined_constant); |
577 } | 606 } |
578 | 607 |
579 | 608 |
580 AstGraphBuilder::Environment::Environment( | 609 AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy) |
581 const AstGraphBuilder::Environment* copy) | |
582 : builder_(copy->builder_), | 610 : builder_(copy->builder_), |
583 parameters_count_(copy->parameters_count_), | 611 parameters_count_(copy->parameters_count_), |
584 locals_count_(copy->locals_count_), | 612 locals_count_(copy->locals_count_), |
585 values_(copy->zone()), | 613 values_(copy->zone()), |
586 contexts_(copy->zone()), | 614 contexts_(copy->zone()), |
587 control_dependency_(copy->control_dependency_), | 615 control_dependency_(copy->control_dependency_), |
588 effect_dependency_(copy->effect_dependency_), | 616 effect_dependency_(copy->effect_dependency_), |
589 parameters_node_(copy->parameters_node_), | 617 parameters_node_(copy->parameters_node_), |
590 locals_node_(copy->locals_node_), | 618 locals_node_(copy->locals_node_), |
591 stack_node_(copy->stack_node_) { | 619 stack_node_(copy->stack_node_) { |
592 const size_t kStackEstimate = 7; // optimum from experimentation! | 620 const size_t kStackEstimate = 7; // optimum from experimentation! |
593 values_.reserve(copy->values_.size() + kStackEstimate); | 621 values_.reserve(copy->values_.size() + kStackEstimate); |
594 values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end()); | 622 values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end()); |
595 contexts_.reserve(copy->contexts_.size()); | 623 contexts_.reserve(copy->contexts_.size()); |
596 contexts_.insert(contexts_.begin(), copy->contexts_.begin(), | 624 contexts_.insert(contexts_.begin(), copy->contexts_.begin(), |
597 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()->New(copy->liveness_block()); | |
631 liveness_block_ = | |
632 builder_->liveness_analyzer()->New(copy->liveness_block()); | |
633 } | |
598 } | 634 } |
599 | 635 |
600 | 636 |
637 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) { | |
638 DCHECK(variable->IsStackAllocated()); | |
639 if (variable->IsParameter()) { | |
640 values()->at(variable->index() + 1) = node; | |
641 } else { | |
642 DCHECK(variable->IsStackLocal()); | |
643 values()->at(variable->index() + parameters_count_) = node; | |
644 if (FLAG_analyze_environment_liveness) { | |
645 liveness_block()->Bind(variable->index()); | |
646 } | |
647 } | |
648 } | |
649 | |
650 | |
651 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) { | |
652 DCHECK(variable->IsStackAllocated()); | |
653 if (variable->IsParameter()) { | |
654 return values()->at(variable->index() + 1); | |
655 } else { | |
656 DCHECK(variable->IsStackLocal()); | |
657 if (FLAG_analyze_environment_liveness) { | |
658 liveness_block()->Lookup(variable->index()); | |
659 } | |
660 return values()->at(variable->index() + parameters_count_); | |
661 } | |
662 } | |
663 | |
664 | |
665 void AstGraphBuilder::Environment::MakeAllLocalsLive() { | |
titzer
2015/02/27 21:09:55
Make -> Mark?
Jarin
2015/03/16 21:30:12
Done.
| |
666 if (FLAG_analyze_environment_liveness) { | |
667 for (int i = 0; i < locals_count_; i++) { | |
668 liveness_block()->Lookup(i); | |
669 } | |
670 } | |
671 } | |
672 | |
673 | |
674 AstGraphBuilder::Environment* AstGraphBuilder::Environment::Snapshot() { | |
Michael Starzinger
2015/03/02 10:56:34
nit: How about s/Snapshot/CopyAndShareLiveness/ he
Jarin
2015/03/16 21:30:12
Done.
| |
675 Environment* env = new (zone()) Environment(this); | |
676 if (FLAG_analyze_environment_liveness) { | |
677 env->liveness_block_ = liveness_block(); | |
678 } | |
679 return env; | |
680 } | |
681 | |
682 | |
601 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 683 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
602 int offset, int count) { | 684 int offset, int count) { |
603 bool should_update = false; | 685 bool should_update = false; |
604 Node** env_values = (count == 0) ? NULL : &values()->at(offset); | 686 Node** env_values = (count == 0) ? NULL : &values()->at(offset); |
605 if (*state_values == NULL || (*state_values)->InputCount() != count) { | 687 if (*state_values == NULL || (*state_values)->InputCount() != count) { |
606 should_update = true; | 688 should_update = true; |
607 } else { | 689 } else { |
608 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); | 690 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); |
609 for (int i = 0; i < count; i++) { | 691 for (int i = 0; i < count; i++) { |
610 if ((*state_values)->InputAt(i) != env_values[i]) { | 692 if ((*state_values)->InputAt(i) != env_values[i]) { |
(...skipping 11 matching lines...) Expand all Loading... | |
622 | 704 |
623 Node* AstGraphBuilder::Environment::Checkpoint( | 705 Node* AstGraphBuilder::Environment::Checkpoint( |
624 BailoutId ast_id, OutputFrameStateCombine combine) { | 706 BailoutId ast_id, OutputFrameStateCombine combine) { |
625 UpdateStateValues(¶meters_node_, 0, parameters_count()); | 707 UpdateStateValues(¶meters_node_, 0, parameters_count()); |
626 UpdateStateValues(&locals_node_, parameters_count(), locals_count()); | 708 UpdateStateValues(&locals_node_, parameters_count(), locals_count()); |
627 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), | 709 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), |
628 stack_height()); | 710 stack_height()); |
629 | 711 |
630 const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine); | 712 const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine); |
631 | 713 |
632 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_, | 714 Node* result = graph()->NewNode(op, parameters_node_, locals_node_, |
633 builder()->current_context(), | 715 stack_node_, builder()->current_context(), |
634 builder()->jsgraph()->UndefinedConstant()); | 716 builder()->jsgraph()->UndefinedConstant()); |
717 if (FLAG_analyze_environment_liveness) { | |
718 liveness_block()->Checkpoint(result); | |
719 } | |
720 return result; | |
635 } | 721 } |
636 | 722 |
637 | 723 |
638 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, | 724 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, |
639 Expression::Context kind) | 725 Expression::Context kind) |
640 : kind_(kind), owner_(own), outer_(own->ast_context()) { | 726 : kind_(kind), owner_(own), outer_(own->ast_context()) { |
641 owner()->set_ast_context(this); // Push. | 727 owner()->set_ast_context(this); // Push. |
642 #ifdef DEBUG | 728 #ifdef DEBUG |
643 original_height_ = environment()->stack_height(); | 729 original_height_ = environment()->stack_height(); |
644 #endif | 730 #endif |
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1284 | 1370 |
1285 // TODO(mstarzinger): Remove bailout once everything works. | 1371 // TODO(mstarzinger): Remove bailout once everything works. |
1286 if (!FLAG_turbo_exceptions) SetStackOverflow(); | 1372 if (!FLAG_turbo_exceptions) SetStackOverflow(); |
1287 } | 1373 } |
1288 | 1374 |
1289 | 1375 |
1290 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1376 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
1291 // TODO(turbofan): Do we really need a separate reloc-info for this? | 1377 // TODO(turbofan): Do we really need a separate reloc-info for this? |
1292 Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0)); | 1378 Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0)); |
1293 PrepareFrameState(node, stmt->DebugBreakId()); | 1379 PrepareFrameState(node, stmt->DebugBreakId()); |
1380 environment()->MakeAllLocalsLive(); | |
1294 } | 1381 } |
1295 | 1382 |
1296 | 1383 |
1297 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 1384 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
1298 Node* context = current_context(); | 1385 Node* context = current_context(); |
1299 | 1386 |
1300 // Build a new shared function info if we cannot find one in the baseline | 1387 // Build a new shared function info if we cannot find one in the baseline |
1301 // code. We also have a stack overflow if the recursive compilation did. | 1388 // code. We also have a stack overflow if the recursive compilation did. |
1302 expr->InitializeSharedInfo(handle(info()->shared_info()->code())); | 1389 expr->InitializeSharedInfo(handle(info()->shared_info()->code())); |
1303 Handle<SharedFunctionInfo> shared_info = expr->shared_info(); | 1390 Handle<SharedFunctionInfo> shared_info = expr->shared_info(); |
(...skipping 1748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3052 DCHECK(contexts_.size() <= other->contexts_.size()); | 3139 DCHECK(contexts_.size() <= other->contexts_.size()); |
3053 | 3140 |
3054 // Nothing to do if the other environment is dead. | 3141 // Nothing to do if the other environment is dead. |
3055 if (other->IsMarkedAsUnreachable()) return; | 3142 if (other->IsMarkedAsUnreachable()) return; |
3056 | 3143 |
3057 // Resurrect a dead environment by copying the contents of the other one and | 3144 // Resurrect a dead environment by copying the contents of the other one and |
3058 // placing a singleton merge as the new control dependency. | 3145 // placing a singleton merge as the new control dependency. |
3059 if (this->IsMarkedAsUnreachable()) { | 3146 if (this->IsMarkedAsUnreachable()) { |
3060 Node* other_control = other->control_dependency_; | 3147 Node* other_control = other->control_dependency_; |
3061 Node* inputs[] = {other_control}; | 3148 Node* inputs[] = {other_control}; |
3149 liveness_block_ = other->liveness_block_; | |
3062 control_dependency_ = | 3150 control_dependency_ = |
3063 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); | 3151 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); |
3064 effect_dependency_ = other->effect_dependency_; | 3152 effect_dependency_ = other->effect_dependency_; |
3065 values_ = other->values_; | 3153 values_ = other->values_; |
3066 // TODO(titzer): make context stack heights match. | 3154 // TODO(titzer): make context stack heights match. |
3067 size_t min = std::min(contexts_.size(), other->contexts_.size()); | 3155 size_t min = std::min(contexts_.size(), other->contexts_.size()); |
3068 contexts_ = other->contexts_; | 3156 contexts_ = other->contexts_; |
3069 contexts_.resize(min, nullptr); | 3157 contexts_.resize(min, nullptr); |
3070 return; | 3158 return; |
3071 } | 3159 } |
3072 | 3160 |
3161 // Record the merge for the local variable liveness calculation. | |
3162 // Unfortunately, we have to mirror the logic in the MergeControl method: | |
3163 // connect before merge or loop, or create a new merge otherwise. | |
3164 if (FLAG_analyze_environment_liveness) { | |
3165 if (GetControlDependency()->opcode() != IrOpcode::kLoop && | |
3166 GetControlDependency()->opcode() != IrOpcode::kMerge) { | |
3167 liveness_block_ = builder_->liveness_analyzer()->New(liveness_block()); | |
3168 } | |
3169 liveness_block()->AddPredecessor(other->liveness_block()); | |
3170 } | |
3171 | |
3073 // Create a merge of the control dependencies of both environments and update | 3172 // Create a merge of the control dependencies of both environments and update |
3074 // the current environment's control dependency accordingly. | 3173 // the current environment's control dependency accordingly. |
3075 Node* control = builder_->MergeControl(this->GetControlDependency(), | 3174 Node* control = builder_->MergeControl(this->GetControlDependency(), |
3076 other->GetControlDependency()); | 3175 other->GetControlDependency()); |
3077 UpdateControlDependency(control); | 3176 UpdateControlDependency(control); |
3078 | 3177 |
3079 // Create a merge of the effect dependencies of both environments and update | 3178 // Create a merge of the effect dependencies of both environments and update |
3080 // the current environment's effect dependency accordingly. | 3179 // the current environment's effect dependency accordingly. |
3081 Node* effect = builder_->MergeEffect(this->GetEffectDependency(), | 3180 Node* effect = builder_->MergeEffect(this->GetEffectDependency(), |
3082 other->GetEffectDependency(), control); | 3181 other->GetEffectDependency(), control); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3233 // Phi does not exist yet, introduce one. | 3332 // Phi does not exist yet, introduce one. |
3234 value = NewPhi(inputs, value, control); | 3333 value = NewPhi(inputs, value, control); |
3235 value->ReplaceInput(inputs - 1, other); | 3334 value->ReplaceInput(inputs - 1, other); |
3236 } | 3335 } |
3237 return value; | 3336 return value; |
3238 } | 3337 } |
3239 | 3338 |
3240 } // namespace compiler | 3339 } // namespace compiler |
3241 } // namespace internal | 3340 } // namespace internal |
3242 } // namespace v8 | 3341 } // namespace v8 |
OLD | NEW |