OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 } | 93 } |
94 | 94 |
95 ~ArrayContextChecker() { | 95 ~ArrayContextChecker() { |
96 checker_.ElseDeopt(); | 96 checker_.ElseDeopt(); |
97 checker_.End(); | 97 checker_.End(); |
98 } | 98 } |
99 private: | 99 private: |
100 IfBuilder checker_; | 100 IfBuilder checker_; |
101 }; | 101 }; |
102 | 102 |
103 enum ArgumentClass { | |
104 NONE, | |
105 SINGLE, | |
106 MULTIPLE | |
107 }; | |
108 | |
109 HValue* BuildArrayConstructor(ElementsKind kind, AllocationSiteMode mode, | |
110 ArgumentClass argument_class); | |
111 HValue* BuildInternalArrayConstructor(ElementsKind kind, | |
112 ArgumentClass argument_class); | |
113 | |
103 private: | 114 private: |
115 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); | |
116 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, | |
117 ElementsKind kind); | |
118 | |
104 SmartArrayPointer<HParameter*> parameters_; | 119 SmartArrayPointer<HParameter*> parameters_; |
105 HValue* arguments_length_; | 120 HValue* arguments_length_; |
106 CompilationInfoWithZone info_; | 121 CompilationInfoWithZone info_; |
107 CodeStubInterfaceDescriptor* descriptor_; | 122 CodeStubInterfaceDescriptor* descriptor_; |
108 HContext* context_; | 123 HContext* context_; |
109 }; | 124 }; |
110 | 125 |
111 | 126 |
112 bool CodeStubGraphBuilderBase::BuildGraph() { | 127 bool CodeStubGraphBuilderBase::BuildGraph() { |
113 // Update the static counter each time a new code stub is generated. | 128 // Update the static counter each time a new code stub is generated. |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 Representation::Tagged(), | 544 Representation::Tagged(), |
530 JSArray::kMapOffset)); | 545 JSArray::kMapOffset)); |
531 return js_array; | 546 return js_array; |
532 } | 547 } |
533 | 548 |
534 | 549 |
535 Handle<Code> TransitionElementsKindStub::GenerateCode() { | 550 Handle<Code> TransitionElementsKindStub::GenerateCode() { |
536 return DoGenerateCode(this); | 551 return DoGenerateCode(this); |
537 } | 552 } |
538 | 553 |
554 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor( | |
555 ElementsKind kind, AllocationSiteMode mode, | |
556 ArgumentClass argument_class) { | |
557 HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor); | |
558 HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell); | |
559 HInstruction* array_function = BuildGetArrayFunction(context()); | |
560 ArrayContextChecker(this, constructor, array_function); | |
561 JSArrayBuilder array_builder(this, kind, property_cell, mode); | |
539 | 562 |
540 template <> | 563 if (argument_class == NONE) { |
Michael Starzinger
2013/05/23 09:16:49
Can we model that as a switch without a default ca
mvstanton
2013/05/23 14:46:05
Cool, didn't think about that good trick. Done.
| |
541 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { | 564 return array_builder.AllocateEmptyArray(); |
542 // ----------- S t a t e ------------- | 565 } else if (argument_class == SINGLE) { |
543 // -- Parameter 1 : type info cell | 566 return BuildArraySingleArgumentConstructor(&array_builder); |
544 // -- Parameter 0 : constructor | 567 } |
545 // ----------------------------------- | 568 |
546 HInstruction* array_function = BuildGetArrayFunction(context()); | 569 ASSERT(argument_class == MULTIPLE); |
547 ArrayContextChecker(this, | 570 return BuildArrayNArgumentsConstructor(&array_builder, kind); |
548 GetParameter(ArrayConstructorStubBase::kConstructor), | |
549 array_function); | |
550 // Get the right map | |
551 // Should be a constant | |
552 JSArrayBuilder array_builder( | |
553 this, | |
554 casted_stub()->elements_kind(), | |
555 GetParameter(ArrayConstructorStubBase::kPropertyCell), | |
556 casted_stub()->mode()); | |
557 return array_builder.AllocateEmptyArray(); | |
558 } | 571 } |
559 | 572 |
560 | 573 |
561 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { | 574 HValue* CodeStubGraphBuilderBase::BuildInternalArrayConstructor( |
562 return DoGenerateCode(this); | 575 ElementsKind kind, ArgumentClass argument_class) { |
576 HValue* constructor = GetParameter( | |
577 InternalArrayConstructorStubBase::kConstructor); | |
578 JSArrayBuilder array_builder(this, kind, constructor); | |
579 | |
580 if (argument_class == NONE) { | |
Michael Starzinger
2013/05/23 09:16:49
Likewise.
mvstanton
2013/05/23 14:46:05
Done.
| |
581 return array_builder.AllocateEmptyArray(); | |
582 } else if (argument_class == SINGLE) { | |
583 return BuildArraySingleArgumentConstructor(&array_builder); | |
584 } | |
585 | |
586 ASSERT(argument_class == MULTIPLE); | |
587 return BuildArrayNArgumentsConstructor(&array_builder, kind); | |
563 } | 588 } |
564 | 589 |
565 | 590 |
566 template <> | 591 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor( |
567 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: | 592 JSArrayBuilder* array_builder) { |
568 BuildCodeStub() { | |
569 HInstruction* array_function = BuildGetArrayFunction(context()); | |
570 ArrayContextChecker(this, | |
571 GetParameter(ArrayConstructorStubBase::kConstructor), | |
572 array_function); | |
573 // Smi check and range check on the input arg. | 593 // Smi check and range check on the input arg. |
574 HValue* constant_one = graph()->GetConstant1(); | 594 HValue* constant_one = graph()->GetConstant1(); |
575 HValue* constant_zero = graph()->GetConstant0(); | 595 HValue* constant_zero = graph()->GetConstant0(); |
576 | 596 |
577 HInstruction* elements = AddInstruction( | 597 HInstruction* elements = AddInstruction( |
578 new(zone()) HArgumentsElements(false)); | 598 new(zone()) HArgumentsElements(false)); |
579 HInstruction* argument = AddInstruction( | 599 HInstruction* argument = AddInstruction( |
580 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero)); | 600 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero)); |
581 | 601 |
582 HConstant* max_alloc_length = | 602 HConstant* max_alloc_length = |
(...skipping 16 matching lines...) Expand all Loading... | |
599 Push(initial_capacity_node); // capacity | 619 Push(initial_capacity_node); // capacity |
600 Push(constant_zero); // length | 620 Push(constant_zero); // length |
601 if_builder.Else(); | 621 if_builder.Else(); |
602 Push(checked_arg); // capacity | 622 Push(checked_arg); // capacity |
603 Push(checked_arg); // length | 623 Push(checked_arg); // length |
604 if_builder.End(); | 624 if_builder.End(); |
605 | 625 |
606 // Figure out total size | 626 // Figure out total size |
607 HValue* length = Pop(); | 627 HValue* length = Pop(); |
608 HValue* capacity = Pop(); | 628 HValue* capacity = Pop(); |
609 | 629 return array_builder->AllocateArray(capacity, length, true); |
610 JSArrayBuilder array_builder( | |
611 this, | |
612 casted_stub()->elements_kind(), | |
613 GetParameter(ArrayConstructorStubBase::kPropertyCell), | |
614 casted_stub()->mode()); | |
615 return array_builder.AllocateArray(capacity, length, true); | |
616 } | 630 } |
617 | 631 |
618 | 632 |
619 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { | 633 HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor( |
620 return DoGenerateCode(this); | 634 JSArrayBuilder* array_builder, ElementsKind kind) { |
621 } | |
622 | |
623 | |
624 template <> | |
625 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { | |
626 HInstruction* array_function = BuildGetArrayFunction(context()); | |
627 ArrayContextChecker(this, | |
628 GetParameter(ArrayConstructorStubBase::kConstructor), | |
629 array_function); | |
630 ElementsKind kind = casted_stub()->elements_kind(); | |
631 HValue* length = GetArgumentsLength(); | |
632 | |
633 JSArrayBuilder array_builder( | |
634 this, | |
635 kind, | |
636 GetParameter(ArrayConstructorStubBase::kPropertyCell), | |
637 casted_stub()->mode()); | |
638 | |
639 // We need to fill with the hole if it's a smi array in the multi-argument | 635 // We need to fill with the hole if it's a smi array in the multi-argument |
640 // case because we might have to bail out while copying arguments into | 636 // case because we might have to bail out while copying arguments into |
641 // the array because they aren't compatible with a smi array. | 637 // the array because they aren't compatible with a smi array. |
642 // If it's a double array, no problem, and if it's fast then no | 638 // If it's a double array, no problem, and if it's fast then no |
643 // problem either because doubles are boxed. | 639 // problem either because doubles are boxed. |
640 HValue* length = GetArgumentsLength(); | |
644 bool fill_with_hole = IsFastSmiElementsKind(kind); | 641 bool fill_with_hole = IsFastSmiElementsKind(kind); |
645 HValue* new_object = array_builder.AllocateArray(length, | 642 HValue* new_object = array_builder->AllocateArray(length, |
646 length, | 643 length, |
647 fill_with_hole); | 644 fill_with_hole); |
648 HValue* elements = array_builder.GetElementsLocation(); | 645 HValue* elements = array_builder->GetElementsLocation(); |
649 ASSERT(elements != NULL); | 646 ASSERT(elements != NULL); |
650 | 647 |
651 // Now populate the elements correctly. | 648 // Now populate the elements correctly. |
652 LoopBuilder builder(this, | 649 LoopBuilder builder(this, |
653 context(), | 650 context(), |
654 LoopBuilder::kPostIncrement); | 651 LoopBuilder::kPostIncrement); |
655 HValue* start = graph()->GetConstant0(); | 652 HValue* start = graph()->GetConstant0(); |
656 HValue* key = builder.BeginBody(start, length, Token::LT); | 653 HValue* key = builder.BeginBody(start, length, Token::LT); |
657 HInstruction* argument_elements = AddInstruction( | 654 HInstruction* argument_elements = AddInstruction( |
658 new(zone()) HArgumentsElements(false)); | 655 new(zone()) HArgumentsElements(false)); |
659 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt( | 656 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt( |
660 argument_elements, length, key)); | 657 argument_elements, length, key)); |
661 | 658 |
662 // Checks to prevent incompatible stores | 659 // Checks to prevent incompatible stores |
663 if (IsFastSmiElementsKind(kind)) { | 660 if (IsFastSmiElementsKind(kind)) { |
664 AddInstruction(new(zone()) HCheckSmi(argument)); | 661 AddInstruction(new(zone()) HCheckSmi(argument)); |
665 } | 662 } |
666 | 663 |
667 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind)); | 664 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind)); |
668 builder.EndBody(); | 665 builder.EndBody(); |
669 return new_object; | 666 return new_object; |
670 } | 667 } |
671 | 668 |
672 | 669 |
670 template <> | |
671 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { | |
672 ElementsKind kind = casted_stub()->elements_kind(); | |
673 AllocationSiteMode mode = casted_stub()->mode(); | |
674 return BuildArrayConstructor(kind, mode, NONE); | |
675 } | |
676 | |
677 | |
678 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { | |
679 return DoGenerateCode(this); | |
680 } | |
681 | |
682 | |
683 template <> | |
684 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: | |
685 BuildCodeStub() { | |
686 ElementsKind kind = casted_stub()->elements_kind(); | |
687 AllocationSiteMode mode = casted_stub()->mode(); | |
688 return BuildArrayConstructor(kind, mode, SINGLE); | |
689 } | |
690 | |
691 | |
692 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { | |
693 return DoGenerateCode(this); | |
694 } | |
695 | |
696 | |
697 template <> | |
698 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { | |
699 ElementsKind kind = casted_stub()->elements_kind(); | |
700 AllocationSiteMode mode = casted_stub()->mode(); | |
701 return BuildArrayConstructor(kind, mode, MULTIPLE); | |
702 } | |
703 | |
704 | |
673 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { | 705 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { |
674 return DoGenerateCode(this); | 706 return DoGenerateCode(this); |
675 } | 707 } |
676 | 708 |
677 | 709 |
678 template <> | 710 template <> |
711 HValue* CodeStubGraphBuilder<InternalArrayNoArgumentConstructorStub>:: | |
712 BuildCodeStub() { | |
713 ElementsKind kind = casted_stub()->elements_kind(); | |
714 return BuildInternalArrayConstructor(kind, NONE); | |
715 } | |
716 | |
717 | |
718 Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode() { | |
719 return DoGenerateCode(this); | |
720 } | |
721 | |
722 | |
723 template <> | |
724 HValue* CodeStubGraphBuilder<InternalArraySingleArgumentConstructorStub>:: | |
725 BuildCodeStub() { | |
726 ElementsKind kind = casted_stub()->elements_kind(); | |
727 return BuildInternalArrayConstructor(kind, SINGLE); | |
728 } | |
729 | |
730 | |
731 Handle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode() { | |
732 return DoGenerateCode(this); | |
733 } | |
734 | |
735 | |
736 template <> | |
737 HValue* CodeStubGraphBuilder<InternalArrayNArgumentsConstructorStub>:: | |
738 BuildCodeStub() { | |
739 ElementsKind kind = casted_stub()->elements_kind(); | |
740 return BuildInternalArrayConstructor(kind, MULTIPLE); | |
741 } | |
742 | |
743 | |
744 Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode() { | |
745 return DoGenerateCode(this); | |
746 } | |
747 | |
748 | |
749 template <> | |
679 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeUninitializedStub() { | 750 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeUninitializedStub() { |
680 CompareNilICStub* stub = casted_stub(); | 751 CompareNilICStub* stub = casted_stub(); |
681 HIfContinuation continuation; | 752 HIfContinuation continuation; |
682 Handle<Map> sentinel_map(graph()->isolate()->heap()->meta_map()); | 753 Handle<Map> sentinel_map(graph()->isolate()->heap()->meta_map()); |
683 BuildCompareNil(GetParameter(0), stub->GetKind(), | 754 BuildCompareNil(GetParameter(0), stub->GetKind(), |
684 stub->GetTypes(), sentinel_map, | 755 stub->GetTypes(), sentinel_map, |
685 RelocInfo::kNoPosition, &continuation); | 756 RelocInfo::kNoPosition, &continuation); |
686 IfBuilder if_nil(this, &continuation); | 757 IfBuilder if_nil(this, &continuation); |
687 if_nil.Then(); | 758 if_nil.Then(); |
688 if (continuation.IsFalseReachable()) { | 759 if (continuation.IsFalseReachable()) { |
689 if_nil.Else(); | 760 if_nil.Else(); |
690 if_nil.Return(graph()->GetConstantSmi0()); | 761 if_nil.Return(graph()->GetConstantSmi0()); |
691 } | 762 } |
692 if_nil.End(); | 763 if_nil.End(); |
693 return continuation.IsTrueReachable() | 764 return continuation.IsTrueReachable() |
694 ? graph()->GetConstantSmi1() | 765 ? graph()->GetConstantSmi1() |
695 : graph()->GetConstantUndefined(); | 766 : graph()->GetConstantUndefined(); |
696 } | 767 } |
697 | 768 |
698 | 769 |
699 Handle<Code> CompareNilICStub::GenerateCode() { | 770 Handle<Code> CompareNilICStub::GenerateCode() { |
700 return DoGenerateCode(this); | 771 return DoGenerateCode(this); |
701 } | 772 } |
702 | 773 |
703 } } // namespace v8::internal | 774 } } // namespace v8::internal |
OLD | NEW |