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 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 AddStore(js_array, HObjectAccess::ForMap(), map); | 529 AddStore(js_array, HObjectAccess::ForMap(), map); |
515 | 530 |
516 return js_array; | 531 return js_array; |
517 } | 532 } |
518 | 533 |
519 | 534 |
520 Handle<Code> TransitionElementsKindStub::GenerateCode() { | 535 Handle<Code> TransitionElementsKindStub::GenerateCode() { |
521 return DoGenerateCode(this); | 536 return DoGenerateCode(this); |
522 } | 537 } |
523 | 538 |
| 539 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor( |
| 540 ElementsKind kind, AllocationSiteMode mode, |
| 541 ArgumentClass argument_class) { |
| 542 HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor); |
| 543 HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell); |
| 544 HInstruction* array_function = BuildGetArrayFunction(context()); |
| 545 ArrayContextChecker(this, constructor, array_function); |
| 546 JSArrayBuilder array_builder(this, kind, property_cell, mode); |
524 | 547 |
525 template <> | 548 HValue* result = NULL; |
526 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { | 549 switch (argument_class) { |
527 // ----------- S t a t e ------------- | 550 case NONE: |
528 // -- Parameter 1 : type info cell | 551 result = array_builder.AllocateEmptyArray(); |
529 // -- Parameter 0 : constructor | 552 break; |
530 // ----------------------------------- | 553 case SINGLE: |
531 HInstruction* array_function = BuildGetArrayFunction(context()); | 554 result = BuildArraySingleArgumentConstructor(&array_builder); |
532 ArrayContextChecker(this, | 555 break; |
533 GetParameter(ArrayConstructorStubBase::kConstructor), | 556 case MULTIPLE: |
534 array_function); | 557 result = BuildArrayNArgumentsConstructor(&array_builder, kind); |
535 // Get the right map | 558 break; |
536 // Should be a constant | 559 } |
537 JSArrayBuilder array_builder( | 560 return result; |
538 this, | |
539 casted_stub()->elements_kind(), | |
540 GetParameter(ArrayConstructorStubBase::kPropertyCell), | |
541 casted_stub()->mode()); | |
542 return array_builder.AllocateEmptyArray(); | |
543 } | 561 } |
544 | 562 |
545 | 563 |
546 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { | 564 HValue* CodeStubGraphBuilderBase::BuildInternalArrayConstructor( |
547 return DoGenerateCode(this); | 565 ElementsKind kind, ArgumentClass argument_class) { |
| 566 HValue* constructor = GetParameter( |
| 567 InternalArrayConstructorStubBase::kConstructor); |
| 568 JSArrayBuilder array_builder(this, kind, constructor); |
| 569 |
| 570 HValue* result = NULL; |
| 571 switch (argument_class) { |
| 572 case NONE: |
| 573 result = array_builder.AllocateEmptyArray(); |
| 574 break; |
| 575 case SINGLE: |
| 576 result = BuildArraySingleArgumentConstructor(&array_builder); |
| 577 break; |
| 578 case MULTIPLE: |
| 579 result = BuildArrayNArgumentsConstructor(&array_builder, kind); |
| 580 break; |
| 581 } |
| 582 return result; |
548 } | 583 } |
549 | 584 |
550 | 585 |
551 template <> | 586 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor( |
552 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: | 587 JSArrayBuilder* array_builder) { |
553 BuildCodeStub() { | |
554 HInstruction* array_function = BuildGetArrayFunction(context()); | |
555 ArrayContextChecker(this, | |
556 GetParameter(ArrayConstructorStubBase::kConstructor), | |
557 array_function); | |
558 // Smi check and range check on the input arg. | 588 // Smi check and range check on the input arg. |
559 HValue* constant_one = graph()->GetConstant1(); | 589 HValue* constant_one = graph()->GetConstant1(); |
560 HValue* constant_zero = graph()->GetConstant0(); | 590 HValue* constant_zero = graph()->GetConstant0(); |
561 | 591 |
562 HInstruction* elements = AddInstruction( | 592 HInstruction* elements = AddInstruction( |
563 new(zone()) HArgumentsElements(false)); | 593 new(zone()) HArgumentsElements(false)); |
564 HInstruction* argument = AddInstruction( | 594 HInstruction* argument = AddInstruction( |
565 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero)); | 595 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero)); |
566 | 596 |
567 HConstant* max_alloc_length = | 597 HConstant* max_alloc_length = |
(...skipping 10 matching lines...) Expand all Loading... |
578 Push(initial_capacity_node); // capacity | 608 Push(initial_capacity_node); // capacity |
579 Push(constant_zero); // length | 609 Push(constant_zero); // length |
580 if_builder.Else(); | 610 if_builder.Else(); |
581 Push(checked_arg); // capacity | 611 Push(checked_arg); // capacity |
582 Push(checked_arg); // length | 612 Push(checked_arg); // length |
583 if_builder.End(); | 613 if_builder.End(); |
584 | 614 |
585 // Figure out total size | 615 // Figure out total size |
586 HValue* length = Pop(); | 616 HValue* length = Pop(); |
587 HValue* capacity = Pop(); | 617 HValue* capacity = Pop(); |
588 | 618 return array_builder->AllocateArray(capacity, length, true); |
589 JSArrayBuilder array_builder( | |
590 this, | |
591 casted_stub()->elements_kind(), | |
592 GetParameter(ArrayConstructorStubBase::kPropertyCell), | |
593 casted_stub()->mode()); | |
594 return array_builder.AllocateArray(capacity, length, true); | |
595 } | 619 } |
596 | 620 |
597 | 621 |
598 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { | 622 HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor( |
599 return DoGenerateCode(this); | 623 JSArrayBuilder* array_builder, ElementsKind kind) { |
600 } | |
601 | |
602 | |
603 template <> | |
604 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { | |
605 HInstruction* array_function = BuildGetArrayFunction(context()); | |
606 ArrayContextChecker(this, | |
607 GetParameter(ArrayConstructorStubBase::kConstructor), | |
608 array_function); | |
609 ElementsKind kind = casted_stub()->elements_kind(); | |
610 HValue* length = GetArgumentsLength(); | |
611 | |
612 JSArrayBuilder array_builder( | |
613 this, | |
614 kind, | |
615 GetParameter(ArrayConstructorStubBase::kPropertyCell), | |
616 casted_stub()->mode()); | |
617 | |
618 // We need to fill with the hole if it's a smi array in the multi-argument | 624 // We need to fill with the hole if it's a smi array in the multi-argument |
619 // case because we might have to bail out while copying arguments into | 625 // case because we might have to bail out while copying arguments into |
620 // the array because they aren't compatible with a smi array. | 626 // the array because they aren't compatible with a smi array. |
621 // If it's a double array, no problem, and if it's fast then no | 627 // If it's a double array, no problem, and if it's fast then no |
622 // problem either because doubles are boxed. | 628 // problem either because doubles are boxed. |
| 629 HValue* length = GetArgumentsLength(); |
623 bool fill_with_hole = IsFastSmiElementsKind(kind); | 630 bool fill_with_hole = IsFastSmiElementsKind(kind); |
624 HValue* new_object = array_builder.AllocateArray(length, | 631 HValue* new_object = array_builder->AllocateArray(length, |
625 length, | 632 length, |
626 fill_with_hole); | 633 fill_with_hole); |
627 HValue* elements = array_builder.GetElementsLocation(); | 634 HValue* elements = array_builder->GetElementsLocation(); |
628 ASSERT(elements != NULL); | 635 ASSERT(elements != NULL); |
629 | 636 |
630 // Now populate the elements correctly. | 637 // Now populate the elements correctly. |
631 LoopBuilder builder(this, | 638 LoopBuilder builder(this, |
632 context(), | 639 context(), |
633 LoopBuilder::kPostIncrement); | 640 LoopBuilder::kPostIncrement); |
634 HValue* start = graph()->GetConstant0(); | 641 HValue* start = graph()->GetConstant0(); |
635 HValue* key = builder.BeginBody(start, length, Token::LT); | 642 HValue* key = builder.BeginBody(start, length, Token::LT); |
636 HInstruction* argument_elements = AddInstruction( | 643 HInstruction* argument_elements = AddInstruction( |
637 new(zone()) HArgumentsElements(false)); | 644 new(zone()) HArgumentsElements(false)); |
638 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt( | 645 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt( |
639 argument_elements, length, key)); | 646 argument_elements, length, key)); |
640 | 647 |
641 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind)); | 648 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind)); |
642 builder.EndBody(); | 649 builder.EndBody(); |
643 return new_object; | 650 return new_object; |
644 } | 651 } |
645 | 652 |
646 | 653 |
| 654 template <> |
| 655 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { |
| 656 ElementsKind kind = casted_stub()->elements_kind(); |
| 657 AllocationSiteMode mode = casted_stub()->mode(); |
| 658 return BuildArrayConstructor(kind, mode, NONE); |
| 659 } |
| 660 |
| 661 |
| 662 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { |
| 663 return DoGenerateCode(this); |
| 664 } |
| 665 |
| 666 |
| 667 template <> |
| 668 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: |
| 669 BuildCodeStub() { |
| 670 ElementsKind kind = casted_stub()->elements_kind(); |
| 671 AllocationSiteMode mode = casted_stub()->mode(); |
| 672 return BuildArrayConstructor(kind, mode, SINGLE); |
| 673 } |
| 674 |
| 675 |
| 676 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { |
| 677 return DoGenerateCode(this); |
| 678 } |
| 679 |
| 680 |
| 681 template <> |
| 682 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { |
| 683 ElementsKind kind = casted_stub()->elements_kind(); |
| 684 AllocationSiteMode mode = casted_stub()->mode(); |
| 685 return BuildArrayConstructor(kind, mode, MULTIPLE); |
| 686 } |
| 687 |
| 688 |
647 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { | 689 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { |
648 return DoGenerateCode(this); | 690 return DoGenerateCode(this); |
649 } | 691 } |
650 | 692 |
651 | 693 |
652 template <> | 694 template <> |
| 695 HValue* CodeStubGraphBuilder<InternalArrayNoArgumentConstructorStub>:: |
| 696 BuildCodeStub() { |
| 697 ElementsKind kind = casted_stub()->elements_kind(); |
| 698 return BuildInternalArrayConstructor(kind, NONE); |
| 699 } |
| 700 |
| 701 |
| 702 Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode() { |
| 703 return DoGenerateCode(this); |
| 704 } |
| 705 |
| 706 |
| 707 template <> |
| 708 HValue* CodeStubGraphBuilder<InternalArraySingleArgumentConstructorStub>:: |
| 709 BuildCodeStub() { |
| 710 ElementsKind kind = casted_stub()->elements_kind(); |
| 711 return BuildInternalArrayConstructor(kind, SINGLE); |
| 712 } |
| 713 |
| 714 |
| 715 Handle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode() { |
| 716 return DoGenerateCode(this); |
| 717 } |
| 718 |
| 719 |
| 720 template <> |
| 721 HValue* CodeStubGraphBuilder<InternalArrayNArgumentsConstructorStub>:: |
| 722 BuildCodeStub() { |
| 723 ElementsKind kind = casted_stub()->elements_kind(); |
| 724 return BuildInternalArrayConstructor(kind, MULTIPLE); |
| 725 } |
| 726 |
| 727 |
| 728 Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode() { |
| 729 return DoGenerateCode(this); |
| 730 } |
| 731 |
| 732 |
| 733 template <> |
653 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() { | 734 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() { |
654 CompareNilICStub* stub = casted_stub(); | 735 CompareNilICStub* stub = casted_stub(); |
655 HIfContinuation continuation; | 736 HIfContinuation continuation; |
656 Handle<Map> sentinel_map(graph()->isolate()->heap()->meta_map()); | 737 Handle<Map> sentinel_map(graph()->isolate()->heap()->meta_map()); |
657 BuildCompareNil(GetParameter(0), stub->GetKind(), | 738 BuildCompareNil(GetParameter(0), stub->GetKind(), |
658 stub->GetTypes(), sentinel_map, | 739 stub->GetTypes(), sentinel_map, |
659 RelocInfo::kNoPosition, &continuation); | 740 RelocInfo::kNoPosition, &continuation); |
660 IfBuilder if_nil(this, &continuation); | 741 IfBuilder if_nil(this, &continuation); |
661 if_nil.Then(); | 742 if_nil.Then(); |
662 if (continuation.IsFalseReachable()) { | 743 if (continuation.IsFalseReachable()) { |
(...skipping 25 matching lines...) Expand all Loading... |
688 return graph()->GetConstant0(); | 769 return graph()->GetConstant0(); |
689 } | 770 } |
690 | 771 |
691 | 772 |
692 Handle<Code> ToBooleanStub::GenerateCode() { | 773 Handle<Code> ToBooleanStub::GenerateCode() { |
693 return DoGenerateCode(this); | 774 return DoGenerateCode(this); |
694 } | 775 } |
695 | 776 |
696 | 777 |
697 } } // namespace v8::internal | 778 } } // namespace v8::internal |
OLD | NEW |