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

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

Issue 890543002: [turbofan] Fix OSR compilations of for-in. (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
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/machine-operator.h" 10 #include "src/compiler/machine-operator.h"
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 have_no_properties.Then(); 695 have_no_properties.Then();
696 // Pop obj and skip loop. 696 // Pop obj and skip loop.
697 environment()->Pop(); 697 environment()->Pop();
698 have_no_properties.Else(); 698 have_no_properties.Else();
699 { 699 {
700 // Construct the rest of the environment. 700 // Construct the rest of the environment.
701 environment()->Push(cache_type); 701 environment()->Push(cache_type);
702 environment()->Push(cache_array); 702 environment()->Push(cache_array);
703 environment()->Push(cache_length); 703 environment()->Push(cache_length);
704 environment()->Push(jsgraph()->ZeroConstant()); 704 environment()->Push(jsgraph()->ZeroConstant());
705 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 705
706 LoopBuilder for_loop(this); 706 // Build the actual loop body.
707 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), 707 BuildForInBody(stmt);
708 IsOsrLoopEntry(stmt));
709 // Check loop termination condition.
710 Node* index = environment()->Peek(0);
711 Node* exit_cond =
712 NewNode(javascript()->LessThan(), index, cache_length);
713 // TODO(jarin): provide real bailout id.
714 PrepareFrameState(exit_cond, BailoutId::None());
715 for_loop.BreakUnless(exit_cond);
716 // TODO(dcarney): this runtime call should be a handful of
717 // simplified instructions that
718 // basically produce
719 // value = array[index]
720 environment()->Push(obj);
721 environment()->Push(cache_array);
722 environment()->Push(cache_type);
723 environment()->Push(index);
724 Node* pair = ProcessArguments(
725 javascript()->CallRuntime(Runtime::kForInNext, 4), 4);
726 Node* value = NewNode(common()->Projection(0), pair);
727 Node* should_filter = NewNode(common()->Projection(1), pair);
728 environment()->Push(value);
729 {
730 // Test if FILTER_KEY needs to be called.
731 IfBuilder test_should_filter(this);
732 Node* should_filter_cond =
733 NewNode(javascript()->StrictEqual(), should_filter,
734 jsgraph()->TrueConstant());
735 test_should_filter.If(should_filter_cond);
736 test_should_filter.Then();
737 value = environment()->Pop();
738 Node* builtins = BuildLoadBuiltinsObject();
739 Node* function = BuildLoadObjectField(
740 builtins,
741 JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
742 // Callee.
743 environment()->Push(function);
744 // Receiver.
745 environment()->Push(obj);
746 // Args.
747 environment()->Push(value);
748 // result is either the string key or Smi(0) indicating the property
749 // is gone.
750 Node* res = ProcessArguments(
751 javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS), 3);
752 // TODO(jarin): provide real bailout id.
753 PrepareFrameState(res, BailoutId::None());
754 Node* property_missing = NewNode(javascript()->StrictEqual(), res,
755 jsgraph()->ZeroConstant());
756 {
757 IfBuilder is_property_missing(this);
758 is_property_missing.If(property_missing);
759 is_property_missing.Then();
760 // Inc counter and continue.
761 Node* index_inc =
762 NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
763 // TODO(jarin): provide real bailout id.
764 PrepareFrameState(index_inc, BailoutId::None());
765 environment()->Poke(0, index_inc);
766 for_loop.Continue();
767 is_property_missing.Else();
768 is_property_missing.End();
769 }
770 // Replace 'value' in environment.
771 environment()->Push(res);
772 test_should_filter.Else();
773 test_should_filter.End();
774 }
775 value = environment()->Pop();
776 // Bind value and do loop body.
777 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId());
778 VisitIterationBody(stmt, &for_loop, 5);
779 for_loop.EndBody();
780 // Inc counter and continue.
781 Node* index_inc =
782 NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
783 // TODO(jarin): provide real bailout id.
784 PrepareFrameState(index_inc, BailoutId::None());
785 environment()->Poke(0, index_inc);
786 for_loop.EndLoop();
787 environment()->Drop(5);
788 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
789 } 708 }
790 have_no_properties.End(); 709 have_no_properties.End();
791 } 710 }
792 is_null.End(); 711 is_null.End();
793 } 712 }
794 is_undefined.End(); 713 is_undefined.End();
795 } 714 }
796 715
797 716
717 void AstGraphBuilder::BuildForInBody(ForInStatement* stmt) {
Michael Starzinger 2015/01/29 15:08:10 nit: Same TODO as in line 646 applies to this func
titzer 2015/01/29 16:51:11 Done.
718 LoopBuilder for_loop(this);
719 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
720
721 // These stack values are renamed in the case of OSR, so reload them
722 // from the environment.
723 Node* index = environment()->Peek(0);
724 Node* cache_length = environment()->Peek(1);
725 Node* cache_array = environment()->Peek(2);
726 Node* cache_type = environment()->Peek(3);
727 Node* obj = environment()->Peek(4);
728
729 // Check loop termination condition.
730 Node* exit_cond = NewNode(javascript()->LessThan(), index, cache_length);
731 // TODO(jarin): provide real bailout id.
732 PrepareFrameState(exit_cond, BailoutId::None());
733 for_loop.BreakUnless(exit_cond);
734 Node* pair = NewNode(javascript()->CallRuntime(Runtime::kForInNext, 4), obj,
735 cache_array, cache_type, index);
736 Node* value = NewNode(common()->Projection(0), pair);
737 Node* should_filter = NewNode(common()->Projection(1), pair);
738 environment()->Push(value);
739 {
740 // Test if FILTER_KEY needs to be called.
741 IfBuilder test_should_filter(this);
742 Node* should_filter_cond = NewNode(
743 javascript()->StrictEqual(), should_filter, jsgraph()->TrueConstant());
744 test_should_filter.If(should_filter_cond);
745 test_should_filter.Then();
746 value = environment()->Pop();
747 Node* builtins = BuildLoadBuiltinsObject();
748 Node* function = BuildLoadObjectField(
749 builtins,
750 JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
751 // Callee.
752 environment()->Push(function);
753 // Receiver.
754 environment()->Push(obj);
755 // Args.
756 environment()->Push(value);
757 // result is either the string key or Smi(0) indicating the property
758 // is gone.
759 Node* res = ProcessArguments(
760 javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS), 3);
761 // TODO(jarin): provide real bailout id.
762 PrepareFrameState(res, BailoutId::None());
763 Node* property_missing =
764 NewNode(javascript()->StrictEqual(), res, jsgraph()->ZeroConstant());
765 {
766 IfBuilder is_property_missing(this);
767 is_property_missing.If(property_missing);
768 is_property_missing.Then();
769 // Inc counter and continue.
770 Node* index_inc =
771 NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
772 // TODO(jarin): provide real bailout id.
773 PrepareFrameState(index_inc, BailoutId::None());
774 environment()->Poke(0, index_inc);
775 for_loop.Continue();
776 is_property_missing.Else();
777 is_property_missing.End();
778 }
779 // Replace 'value' in environment.
780 environment()->Push(res);
781 test_should_filter.Else();
782 test_should_filter.End();
783 }
784 value = environment()->Pop();
785 // Bind value and do loop body.
786 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId());
787 VisitIterationBody(stmt, &for_loop, 5);
788 for_loop.EndBody();
789 // Inc counter and continue.
790 Node* index_inc =
791 NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
792 // TODO(jarin): provide real bailout id.
793 PrepareFrameState(index_inc, BailoutId::None());
794 environment()->Poke(0, index_inc);
795 for_loop.EndLoop();
796 environment()->Drop(5);
797 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
798 }
799
800
798 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { 801 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
799 LoopBuilder for_loop(this); 802 LoopBuilder for_loop(this);
800 VisitForEffect(stmt->assign_iterator()); 803 VisitForEffect(stmt->assign_iterator());
801 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); 804 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
802 VisitForEffect(stmt->next_result()); 805 VisitForEffect(stmt->next_result());
803 VisitForTest(stmt->result_done()); 806 VisitForTest(stmt->result_done());
804 Node* condition = environment()->Pop(); 807 Node* condition = environment()->Pop();
805 for_loop.BreakWhen(condition); 808 for_loop.BreakWhen(condition);
806 VisitForEffect(stmt->assign_each()); 809 VisitForEffect(stmt->assign_each());
807 VisitIterationBody(stmt, &for_loop, 0); 810 VisitIterationBody(stmt, &for_loop, 0);
(...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 2439
2437 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( 2440 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
2438 IterationStatement* stmt) { 2441 IterationStatement* stmt) {
2439 if (loop_assignment_analysis_ == NULL) return NULL; 2442 if (loop_assignment_analysis_ == NULL) return NULL;
2440 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); 2443 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
2441 } 2444 }
2442 2445
2443 } // namespace compiler 2446 } // namespace compiler
2444 } // namespace internal 2447 } // namespace internal
2445 } // namespace v8 2448 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698