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/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 |
OLD | NEW |