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

Side by Side Diff: src/arm/codegen-arm.cc

Issue 118226: Simplify the processing of deferred code in the code generator. Our... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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
« no previous file with comments | « no previous file | src/arm/codegen-arm-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 23 matching lines...) Expand all
34 #include "register-allocator-inl.h" 34 #include "register-allocator-inl.h"
35 #include "runtime.h" 35 #include "runtime.h"
36 #include "scopes.h" 36 #include "scopes.h"
37 37
38 38
39 namespace v8 { 39 namespace v8 {
40 namespace internal { 40 namespace internal {
41 41
42 #define __ ACCESS_MASM(masm_) 42 #define __ ACCESS_MASM(masm_)
43 43
44 // -------------------------------------------------------------------------
45 // Platform-specific DeferredCode functions.
46
47 void DeferredCode::SaveRegisters() {
48 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
49 int action = registers_[i];
50 if (action == kPush) {
51 __ push(RegisterAllocator::ToRegister(i));
52 } else if (action != kIgnore && (action & kSyncedFlag) == 0) {
53 __ str(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
54 }
55 }
56 }
57
58
59 void DeferredCode::RestoreRegisters() {
60 // Restore registers in reverse order due to the stack.
61 for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) {
62 int action = registers_[i];
63 if (action == kPush) {
64 __ pop(RegisterAllocator::ToRegister(i));
65 } else if (action != kIgnore) {
66 action &= ~kSyncedFlag;
67 __ ldr(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
68 }
69 }
70 }
71
44 72
45 // ------------------------------------------------------------------------- 73 // -------------------------------------------------------------------------
46 // CodeGenState implementation. 74 // CodeGenState implementation.
47 75
48 CodeGenState::CodeGenState(CodeGenerator* owner) 76 CodeGenState::CodeGenState(CodeGenerator* owner)
49 : owner_(owner), 77 : owner_(owner),
50 typeof_state_(NOT_INSIDE_TYPEOF), 78 typeof_state_(NOT_INSIDE_TYPEOF),
51 true_target_(NULL), 79 true_target_(NULL),
52 false_target_(NULL), 80 false_target_(NULL),
53 previous_(NULL) { 81 previous_(NULL) {
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 virtual void Generate(); 797 virtual void Generate();
770 798
771 private: 799 private:
772 Token::Value op_; 800 Token::Value op_;
773 int value_; 801 int value_;
774 bool reversed_; 802 bool reversed_;
775 OverwriteMode overwrite_mode_; 803 OverwriteMode overwrite_mode_;
776 }; 804 };
777 805
778 806
779 #undef __
780 #define __ ACCESS_MASM(masm)
781
782
783 void DeferredInlineSmiOperation::Generate() { 807 void DeferredInlineSmiOperation::Generate() {
784 MacroAssembler* masm = cgen()->masm();
785 enter()->Bind();
786 VirtualFrame::SpilledScope spilled_scope;
787
788 switch (op_) { 808 switch (op_) {
789 case Token::ADD: { 809 case Token::ADD: {
810 // Revert optimistic add.
790 if (reversed_) { 811 if (reversed_) {
791 // revert optimistic add
792 __ sub(r0, r0, Operand(Smi::FromInt(value_))); 812 __ sub(r0, r0, Operand(Smi::FromInt(value_)));
793 __ mov(r1, Operand(Smi::FromInt(value_))); 813 __ mov(r1, Operand(Smi::FromInt(value_)));
794 } else { 814 } else {
795 // revert optimistic add
796 __ sub(r1, r0, Operand(Smi::FromInt(value_))); 815 __ sub(r1, r0, Operand(Smi::FromInt(value_)));
797 __ mov(r0, Operand(Smi::FromInt(value_))); 816 __ mov(r0, Operand(Smi::FromInt(value_)));
798 } 817 }
799 break; 818 break;
800 } 819 }
801 820
802 case Token::SUB: { 821 case Token::SUB: {
822 // Revert optimistic sub.
803 if (reversed_) { 823 if (reversed_) {
804 // revert optimistic sub
805 __ rsb(r0, r0, Operand(Smi::FromInt(value_))); 824 __ rsb(r0, r0, Operand(Smi::FromInt(value_)));
806 __ mov(r1, Operand(Smi::FromInt(value_))); 825 __ mov(r1, Operand(Smi::FromInt(value_)));
807 } else { 826 } else {
808 __ add(r1, r0, Operand(Smi::FromInt(value_))); 827 __ add(r1, r0, Operand(Smi::FromInt(value_)));
809 __ mov(r0, Operand(Smi::FromInt(value_))); 828 __ mov(r0, Operand(Smi::FromInt(value_)));
810 } 829 }
811 break; 830 break;
812 } 831 }
813 832
814 case Token::BIT_OR: 833 case Token::BIT_OR:
815 case Token::BIT_XOR: 834 case Token::BIT_XOR:
816 case Token::BIT_AND: { 835 case Token::BIT_AND: {
817 if (reversed_) { 836 if (reversed_) {
818 __ mov(r1, Operand(Smi::FromInt(value_))); 837 __ mov(r1, Operand(Smi::FromInt(value_)));
819 } else { 838 } else {
820 __ mov(r1, Operand(r0)); 839 __ mov(r1, Operand(r0));
821 __ mov(r0, Operand(Smi::FromInt(value_))); 840 __ mov(r0, Operand(Smi::FromInt(value_)));
822 } 841 }
823 break; 842 break;
824 } 843 }
825 844
826 case Token::SHL: 845 case Token::SHL:
827 case Token::SHR: 846 case Token::SHR:
828 case Token::SAR: { 847 case Token::SAR: {
829 if (!reversed_) { 848 if (!reversed_) {
830 __ mov(r1, Operand(r0)); 849 __ mov(r1, Operand(r0));
831 __ mov(r0, Operand(Smi::FromInt(value_))); 850 __ mov(r0, Operand(Smi::FromInt(value_)));
832 } else { 851 } else {
833 UNREACHABLE(); // should have been handled in SmiOperation 852 UNREACHABLE(); // Should have been handled in SmiOperation.
834 } 853 }
835 break; 854 break;
836 } 855 }
837 856
838 default: 857 default:
839 // other cases should have been handled before this point. 858 // Other cases should have been handled before this point.
840 UNREACHABLE(); 859 UNREACHABLE();
841 break; 860 break;
842 } 861 }
843 862
844 GenericBinaryOpStub igostub(op_, overwrite_mode_); 863 GenericBinaryOpStub stub(op_, overwrite_mode_);
845 Result arg0 = cgen()->allocator()->Allocate(r1); 864 __ CallStub(&stub);
846 ASSERT(arg0.is_valid());
847 Result arg1 = cgen()->allocator()->Allocate(r0);
848 ASSERT(arg1.is_valid());
849 cgen()->frame()->CallStub(&igostub, &arg0, &arg1);
850 exit_.Jump();
851 } 865 }
852 866
853 867
854 #undef __
855 #define __ ACCESS_MASM(masm_)
856
857
858 void CodeGenerator::SmiOperation(Token::Value op, 868 void CodeGenerator::SmiOperation(Token::Value op,
859 Handle<Object> value, 869 Handle<Object> value,
860 bool reversed, 870 bool reversed,
861 OverwriteMode mode) { 871 OverwriteMode mode) {
862 VirtualFrame::SpilledScope spilled_scope; 872 VirtualFrame::SpilledScope spilled_scope;
863 // NOTE: This is an attempt to inline (a bit) more of the code for 873 // NOTE: This is an attempt to inline (a bit) more of the code for
864 // some possible smi operations (like + and -) when (at least) one 874 // some possible smi operations (like + and -) when (at least) one
865 // of the operands is a literal smi. With this optimization, the 875 // of the operands is a literal smi. With this optimization, the
866 // performance of the system is increased by ~15%, and the generated 876 // performance of the system is increased by ~15%, and the generated
867 // code size is increased by ~1% (measured on a combination of 877 // code size is increased by ~1% (measured on a combination of
868 // different benchmarks). 878 // different benchmarks).
869 879
870 // sp[0] : operand 880 // sp[0] : operand
871 881
872 int int_value = Smi::cast(*value)->value(); 882 int int_value = Smi::cast(*value)->value();
873 883
874 JumpTarget exit; 884 JumpTarget exit;
875 frame_->EmitPop(r0); 885 frame_->EmitPop(r0);
876 886
877 switch (op) { 887 switch (op) {
878 case Token::ADD: { 888 case Token::ADD: {
879 DeferredCode* deferred = 889 DeferredCode* deferred =
880 new DeferredInlineSmiOperation(op, int_value, reversed, mode); 890 new DeferredInlineSmiOperation(op, int_value, reversed, mode);
881 891
882 __ add(r0, r0, Operand(value), SetCC); 892 __ add(r0, r0, Operand(value), SetCC);
883 deferred->enter()->Branch(vs); 893 deferred->Branch(vs);
884 __ tst(r0, Operand(kSmiTagMask)); 894 __ tst(r0, Operand(kSmiTagMask));
885 deferred->enter()->Branch(ne); 895 deferred->Branch(ne);
886 deferred->BindExit(); 896 deferred->BindExit();
887 break; 897 break;
888 } 898 }
889 899
890 case Token::SUB: { 900 case Token::SUB: {
891 DeferredCode* deferred = 901 DeferredCode* deferred =
892 new DeferredInlineSmiOperation(op, int_value, reversed, mode); 902 new DeferredInlineSmiOperation(op, int_value, reversed, mode);
893 903
894 if (!reversed) { 904 if (reversed) {
905 __ rsb(r0, r0, Operand(value), SetCC);
906 } else {
895 __ sub(r0, r0, Operand(value), SetCC); 907 __ sub(r0, r0, Operand(value), SetCC);
896 } else {
897 __ rsb(r0, r0, Operand(value), SetCC);
898 } 908 }
899 deferred->enter()->Branch(vs); 909 deferred->Branch(vs);
900 __ tst(r0, Operand(kSmiTagMask)); 910 __ tst(r0, Operand(kSmiTagMask));
901 deferred->enter()->Branch(ne); 911 deferred->Branch(ne);
902 deferred->BindExit(); 912 deferred->BindExit();
903 break; 913 break;
904 } 914 }
905 915
906 case Token::BIT_OR: 916 case Token::BIT_OR:
907 case Token::BIT_XOR: 917 case Token::BIT_XOR:
908 case Token::BIT_AND: { 918 case Token::BIT_AND: {
909 DeferredCode* deferred = 919 DeferredCode* deferred =
910 new DeferredInlineSmiOperation(op, int_value, reversed, mode); 920 new DeferredInlineSmiOperation(op, int_value, reversed, mode);
911 __ tst(r0, Operand(kSmiTagMask)); 921 __ tst(r0, Operand(kSmiTagMask));
912 deferred->enter()->Branch(ne); 922 deferred->Branch(ne);
913 switch (op) { 923 switch (op) {
914 case Token::BIT_OR: __ orr(r0, r0, Operand(value)); break; 924 case Token::BIT_OR: __ orr(r0, r0, Operand(value)); break;
915 case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break; 925 case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break;
916 case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break; 926 case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break;
917 default: UNREACHABLE(); 927 default: UNREACHABLE();
918 } 928 }
919 deferred->BindExit(); 929 deferred->BindExit();
920 break; 930 break;
921 } 931 }
922 932
923 case Token::SHL: 933 case Token::SHL:
924 case Token::SHR: 934 case Token::SHR:
925 case Token::SAR: { 935 case Token::SAR: {
926 if (reversed) { 936 if (reversed) {
927 __ mov(ip, Operand(value)); 937 __ mov(ip, Operand(value));
928 frame_->EmitPush(ip); 938 frame_->EmitPush(ip);
929 frame_->EmitPush(r0); 939 frame_->EmitPush(r0);
930 GenericBinaryOperation(op, mode); 940 GenericBinaryOperation(op, mode);
931 941
932 } else { 942 } else {
933 int shift_value = int_value & 0x1f; // least significant 5 bits 943 int shift_value = int_value & 0x1f; // least significant 5 bits
934 DeferredCode* deferred = 944 DeferredCode* deferred =
935 new DeferredInlineSmiOperation(op, shift_value, false, mode); 945 new DeferredInlineSmiOperation(op, shift_value, false, mode);
936 __ tst(r0, Operand(kSmiTagMask)); 946 __ tst(r0, Operand(kSmiTagMask));
937 deferred->enter()->Branch(ne); 947 deferred->Branch(ne);
938 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); // remove tags 948 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); // remove tags
939 switch (op) { 949 switch (op) {
940 case Token::SHL: { 950 case Token::SHL: {
941 __ mov(r2, Operand(r2, LSL, shift_value)); 951 __ mov(r2, Operand(r2, LSL, shift_value));
942 // check that the *unsigned* result fits in a smi 952 // check that the *unsigned* result fits in a smi
943 __ add(r3, r2, Operand(0x40000000), SetCC); 953 __ add(r3, r2, Operand(0x40000000), SetCC);
944 deferred->enter()->Branch(mi); 954 deferred->Branch(mi);
945 break; 955 break;
946 } 956 }
947 case Token::SHR: { 957 case Token::SHR: {
948 // LSR by immediate 0 means shifting 32 bits. 958 // LSR by immediate 0 means shifting 32 bits.
949 if (shift_value != 0) { 959 if (shift_value != 0) {
950 __ mov(r2, Operand(r2, LSR, shift_value)); 960 __ mov(r2, Operand(r2, LSR, shift_value));
951 } 961 }
952 // check that the *unsigned* result fits in a smi 962 // check that the *unsigned* result fits in a smi
953 // neither of the two high-order bits can be set: 963 // neither of the two high-order bits can be set:
954 // - 0x80000000: high bit would be lost when smi tagging 964 // - 0x80000000: high bit would be lost when smi tagging
955 // - 0x40000000: this number would convert to negative when 965 // - 0x40000000: this number would convert to negative when
956 // smi tagging these two cases can only happen with shifts 966 // smi tagging these two cases can only happen with shifts
957 // by 0 or 1 when handed a valid smi 967 // by 0 or 1 when handed a valid smi
958 __ and_(r3, r2, Operand(0xc0000000), SetCC); 968 __ and_(r3, r2, Operand(0xc0000000), SetCC);
959 deferred->enter()->Branch(ne); 969 deferred->Branch(ne);
960 break; 970 break;
961 } 971 }
962 case Token::SAR: { 972 case Token::SAR: {
963 if (shift_value != 0) { 973 if (shift_value != 0) {
964 // ASR by immediate 0 means shifting 32 bits. 974 // ASR by immediate 0 means shifting 32 bits.
965 __ mov(r2, Operand(r2, ASR, shift_value)); 975 __ mov(r2, Operand(r2, ASR, shift_value));
966 } 976 }
967 break; 977 break;
968 } 978 }
969 default: UNREACHABLE(); 979 default: UNREACHABLE();
(...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after
2663 set_comment("[ DeferredObjectLiteral"); 2673 set_comment("[ DeferredObjectLiteral");
2664 } 2674 }
2665 2675
2666 virtual void Generate(); 2676 virtual void Generate();
2667 2677
2668 private: 2678 private:
2669 ObjectLiteral* node_; 2679 ObjectLiteral* node_;
2670 }; 2680 };
2671 2681
2672 2682
2673 #undef __
2674 #define __ ACCESS_MASM(masm)
2675
2676
2677 void DeferredObjectLiteral::Generate() { 2683 void DeferredObjectLiteral::Generate() {
2678 MacroAssembler* masm = cgen()->masm();
2679 // Argument is passed in r1. 2684 // Argument is passed in r1.
2680 enter()->Bind();
2681 VirtualFrame::SpilledScope spilled_scope;
2682 2685
2683 // If the entry is undefined we call the runtime system to compute 2686 // If the entry is undefined we call the runtime system to compute
2684 // the literal. 2687 // the literal.
2685
2686 VirtualFrame* frame = cgen()->frame();
2687 // Literal array (0). 2688 // Literal array (0).
2688 frame->EmitPush(r1); 2689 __ push(r1);
2689 // Literal index (1). 2690 // Literal index (1).
2690 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); 2691 __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
2691 frame->EmitPush(r0); 2692 __ push(r0);
2692 // Constant properties (2). 2693 // Constant properties (2).
2693 __ mov(r0, Operand(node_->constant_properties())); 2694 __ mov(r0, Operand(node_->constant_properties()));
2694 frame->EmitPush(r0); 2695 __ push(r0);
2695 Result boilerplate = 2696 __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
2696 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); 2697 __ mov(r2, Operand(r0));
2697 __ mov(r2, Operand(boilerplate.reg()));
2698 // Result is returned in r2. 2698 // Result is returned in r2.
2699 exit_.Jump();
2700 } 2699 }
2701 2700
2702 2701
2703 #undef __
2704 #define __ ACCESS_MASM(masm_)
2705
2706
2707 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { 2702 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
2708 #ifdef DEBUG 2703 #ifdef DEBUG
2709 int original_height = frame_->height(); 2704 int original_height = frame_->height();
2710 #endif 2705 #endif
2711 VirtualFrame::SpilledScope spilled_scope; 2706 VirtualFrame::SpilledScope spilled_scope;
2712 Comment cmnt(masm_, "[ ObjectLiteral"); 2707 Comment cmnt(masm_, "[ ObjectLiteral");
2713 2708
2714 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(node); 2709 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(node);
2715 2710
2716 // Retrieve the literal array and check the allocated entry. 2711 // Retrieve the literal array and check the allocated entry.
2717 2712
2718 // Load the function of this activation. 2713 // Load the function of this activation.
2719 __ ldr(r1, frame_->Function()); 2714 __ ldr(r1, frame_->Function());
2720 2715
2721 // Load the literals array of the function. 2716 // Load the literals array of the function.
2722 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); 2717 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
2723 2718
2724 // Load the literal at the ast saved index. 2719 // Load the literal at the ast saved index.
2725 int literal_offset = 2720 int literal_offset =
2726 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2721 FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
2727 __ ldr(r2, FieldMemOperand(r1, literal_offset)); 2722 __ ldr(r2, FieldMemOperand(r1, literal_offset));
2728 2723
2729 // Check whether we need to materialize the object literal boilerplate. 2724 // Check whether we need to materialize the object literal boilerplate.
2730 // If so, jump to the deferred code. 2725 // If so, jump to the deferred code.
2731 __ cmp(r2, Operand(Factory::undefined_value())); 2726 __ cmp(r2, Operand(Factory::undefined_value()));
2732 deferred->enter()->Branch(eq); 2727 deferred->Branch(eq);
2733 deferred->BindExit(); 2728 deferred->BindExit();
2734 2729
2735 // Push the object literal boilerplate. 2730 // Push the object literal boilerplate.
2736 frame_->EmitPush(r2); 2731 frame_->EmitPush(r2);
2737 2732
2738 // Clone the boilerplate object. 2733 // Clone the boilerplate object.
2739 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; 2734 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate;
2740 if (node->depth() == 1) { 2735 if (node->depth() == 1) {
2741 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; 2736 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate;
2742 } 2737 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2800 set_comment("[ DeferredArrayLiteral"); 2795 set_comment("[ DeferredArrayLiteral");
2801 } 2796 }
2802 2797
2803 virtual void Generate(); 2798 virtual void Generate();
2804 2799
2805 private: 2800 private:
2806 ArrayLiteral* node_; 2801 ArrayLiteral* node_;
2807 }; 2802 };
2808 2803
2809 2804
2810 #undef __
2811 #define __ ACCESS_MASM(masm)
2812
2813
2814 void DeferredArrayLiteral::Generate() { 2805 void DeferredArrayLiteral::Generate() {
2815 MacroAssembler* masm = cgen()->masm();
2816 // Argument is passed in r1. 2806 // Argument is passed in r1.
2817 enter()->Bind();
2818 VirtualFrame::SpilledScope spilled_scope;
2819 2807
2820 // If the entry is undefined we call the runtime system to computed 2808 // If the entry is undefined we call the runtime system to computed
2821 // the literal. 2809 // the literal.
2822
2823 VirtualFrame* frame = cgen()->frame();
2824 // Literal array (0). 2810 // Literal array (0).
2825 frame->EmitPush(r1); 2811 __ push(r1);
2826 // Literal index (1). 2812 // Literal index (1).
2827 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); 2813 __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
2828 frame->EmitPush(r0); 2814 __ push(r0);
2829 // Constant properties (2). 2815 // Constant properties (2).
2830 __ mov(r0, Operand(node_->literals())); 2816 __ mov(r0, Operand(node_->literals()));
2831 frame->EmitPush(r0); 2817 __ push(r0);
2832 Result boilerplate = 2818 __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
2833 frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3); 2819 __ mov(r2, Operand(r0));
2834 __ mov(r2, Operand(boilerplate.reg()));
2835 // Result is returned in r2. 2820 // Result is returned in r2.
2836 exit_.Jump();
2837 } 2821 }
2838 2822
2839 2823
2840 #undef __
2841 #define __ ACCESS_MASM(masm_)
2842
2843
2844 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 2824 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
2845 #ifdef DEBUG 2825 #ifdef DEBUG
2846 int original_height = frame_->height(); 2826 int original_height = frame_->height();
2847 #endif 2827 #endif
2848 VirtualFrame::SpilledScope spilled_scope; 2828 VirtualFrame::SpilledScope spilled_scope;
2849 Comment cmnt(masm_, "[ ArrayLiteral"); 2829 Comment cmnt(masm_, "[ ArrayLiteral");
2850 2830
2851 DeferredArrayLiteral* deferred = new DeferredArrayLiteral(node); 2831 DeferredArrayLiteral* deferred = new DeferredArrayLiteral(node);
2852 2832
2853 // Retrieve the literal array and check the allocated entry. 2833 // Retrieve the literal array and check the allocated entry.
2854 2834
2855 // Load the function of this activation. 2835 // Load the function of this activation.
2856 __ ldr(r1, frame_->Function()); 2836 __ ldr(r1, frame_->Function());
2857 2837
2858 // Load the literals array of the function. 2838 // Load the literals array of the function.
2859 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); 2839 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
2860 2840
2861 // Load the literal at the ast saved index. 2841 // Load the literal at the ast saved index.
2862 int literal_offset = 2842 int literal_offset =
2863 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2843 FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
2864 __ ldr(r2, FieldMemOperand(r1, literal_offset)); 2844 __ ldr(r2, FieldMemOperand(r1, literal_offset));
2865 2845
2866 // Check whether we need to materialize the object literal boilerplate. 2846 // Check whether we need to materialize the object literal boilerplate.
2867 // If so, jump to the deferred code. 2847 // If so, jump to the deferred code.
2868 __ cmp(r2, Operand(Factory::undefined_value())); 2848 __ cmp(r2, Operand(Factory::undefined_value()));
2869 deferred->enter()->Branch(eq); 2849 deferred->Branch(eq);
2870 deferred->BindExit(); 2850 deferred->BindExit();
2871 2851
2872 // Push the object literal boilerplate. 2852 // Push the object literal boilerplate.
2873 frame_->EmitPush(r2); 2853 frame_->EmitPush(r2);
2874 2854
2875 // Clone the boilerplate object. 2855 // Clone the boilerplate object.
2876 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; 2856 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate;
2877 if (node->depth() == 1) { 2857 if (node->depth() == 1) {
2878 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; 2858 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate;
2879 } 2859 }
(...skipping 2330 matching lines...) Expand 10 before | Expand all | Expand 10 after
5210 __ mov(r2, Operand(0)); 5190 __ mov(r2, Operand(0));
5211 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5191 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5212 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5192 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
5213 RelocInfo::CODE_TARGET); 5193 RelocInfo::CODE_TARGET);
5214 } 5194 }
5215 5195
5216 5196
5217 #undef __ 5197 #undef __
5218 5198
5219 } } // namespace v8::internal 5199 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/codegen-arm-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698