| 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 |