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

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 14576005: Adapt hydrogen-based Array constructor to also support InternalArray and function call (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Refactoring and restored flag for now Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698