| 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 2747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2758 bool do_gc, | 2758 bool do_gc, |
| 2759 bool always_allocate) { | 2759 bool always_allocate) { |
| 2760 // r0: result parameter for PerformGC, if any | 2760 // r0: result parameter for PerformGC, if any |
| 2761 // r4: number of arguments including receiver (C callee-saved) | 2761 // r4: number of arguments including receiver (C callee-saved) |
| 2762 // r5: pointer to builtin function (C callee-saved) | 2762 // r5: pointer to builtin function (C callee-saved) |
| 2763 // r6: pointer to the first argument (C callee-saved) | 2763 // r6: pointer to the first argument (C callee-saved) |
| 2764 Isolate* isolate = masm->isolate(); | 2764 Isolate* isolate = masm->isolate(); |
| 2765 | 2765 |
| 2766 if (do_gc) { | 2766 if (do_gc) { |
| 2767 // Passing r0. | 2767 // Passing r0. |
| 2768 __ PrepareCallCFunction(1, 0, r1); | 2768 __ PrepareCallCFunction(2, 0, r1); |
| 2769 __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 2769 __ CallCFunction(ExternalReference::perform_gc_function(isolate), | 2770 __ CallCFunction(ExternalReference::perform_gc_function(isolate), |
| 2770 1, 0); | 2771 2, 0); |
| 2771 } | 2772 } |
| 2772 | 2773 |
| 2773 ExternalReference scope_depth = | 2774 ExternalReference scope_depth = |
| 2774 ExternalReference::heap_always_allocate_scope_depth(isolate); | 2775 ExternalReference::heap_always_allocate_scope_depth(isolate); |
| 2775 if (always_allocate) { | 2776 if (always_allocate) { |
| 2776 __ mov(r0, Operand(scope_depth)); | 2777 __ mov(r0, Operand(scope_depth)); |
| 2777 __ ldr(r1, MemOperand(r0)); | 2778 __ ldr(r1, MemOperand(r0)); |
| 2778 __ add(r1, r1, Operand(1)); | 2779 __ add(r1, r1, Operand(1)); |
| 2779 __ str(r1, MemOperand(r0)); | 2780 __ str(r1, MemOperand(r0)); |
| 2780 } | 2781 } |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3368 ASSERT(kind() == Code::LOAD_IC); | 3369 ASSERT(kind() == Code::LOAD_IC); |
| 3369 // ----------- S t a t e ------------- | 3370 // ----------- S t a t e ------------- |
| 3370 // -- r2 : name | 3371 // -- r2 : name |
| 3371 // -- lr : return address | 3372 // -- lr : return address |
| 3372 // -- r0 : receiver | 3373 // -- r0 : receiver |
| 3373 // -- sp[0] : receiver | 3374 // -- sp[0] : receiver |
| 3374 // ----------------------------------- | 3375 // ----------------------------------- |
| 3375 receiver = r0; | 3376 receiver = r0; |
| 3376 } | 3377 } |
| 3377 | 3378 |
| 3378 StubCompiler::GenerateLoadStringLength(masm, receiver, r3, r4, &miss, | 3379 StubCompiler::GenerateLoadStringLength(masm, receiver, r3, r4, &miss); |
| 3379 support_wrapper_); | |
| 3380 | 3380 |
| 3381 __ bind(&miss); | 3381 __ bind(&miss); |
| 3382 StubCompiler::TailCallBuiltin( | 3382 StubCompiler::TailCallBuiltin( |
| 3383 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); | 3383 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); |
| 3384 } | 3384 } |
| 3385 | 3385 |
| 3386 | 3386 |
| 3387 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { | 3387 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { |
| 3388 // This accepts as a receiver anything JSArray::SetElementsLength accepts | 3388 // This accepts as a receiver anything JSArray::SetElementsLength accepts |
| 3389 // (currently anything except for external arrays which means anything with | 3389 // (currently anything except for external arrays which means anything with |
| (...skipping 2393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5783 Register scratch3, | 5783 Register scratch3, |
| 5784 Register scratch4, | 5784 Register scratch4, |
| 5785 Label* slow) { | 5785 Label* slow) { |
| 5786 // First check if the argument is already a string. | 5786 // First check if the argument is already a string. |
| 5787 Label not_string, done; | 5787 Label not_string, done; |
| 5788 __ JumpIfSmi(arg, ¬_string); | 5788 __ JumpIfSmi(arg, ¬_string); |
| 5789 __ CompareObjectType(arg, scratch1, scratch1, FIRST_NONSTRING_TYPE); | 5789 __ CompareObjectType(arg, scratch1, scratch1, FIRST_NONSTRING_TYPE); |
| 5790 __ b(lt, &done); | 5790 __ b(lt, &done); |
| 5791 | 5791 |
| 5792 // Check the number to string cache. | 5792 // Check the number to string cache. |
| 5793 Label not_cached; | |
| 5794 __ bind(¬_string); | 5793 __ bind(¬_string); |
| 5795 // Puts the cached result into scratch1. | 5794 // Puts the cached result into scratch1. |
| 5796 NumberToStringStub::GenerateLookupNumberStringCache(masm, | 5795 NumberToStringStub::GenerateLookupNumberStringCache(masm, |
| 5797 arg, | 5796 arg, |
| 5798 scratch1, | 5797 scratch1, |
| 5799 scratch2, | 5798 scratch2, |
| 5800 scratch3, | 5799 scratch3, |
| 5801 scratch4, | 5800 scratch4, |
| 5802 ¬_cached); | 5801 slow); |
| 5803 __ mov(arg, scratch1); | 5802 __ mov(arg, scratch1); |
| 5804 __ str(arg, MemOperand(sp, stack_offset)); | 5803 __ str(arg, MemOperand(sp, stack_offset)); |
| 5805 __ jmp(&done); | |
| 5806 | |
| 5807 // Check if the argument is a safe string wrapper. | |
| 5808 __ bind(¬_cached); | |
| 5809 __ JumpIfSmi(arg, slow); | |
| 5810 __ CompareObjectType( | |
| 5811 arg, scratch1, scratch2, JS_VALUE_TYPE); // map -> scratch1. | |
| 5812 __ b(ne, slow); | |
| 5813 __ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset)); | |
| 5814 __ and_(scratch2, | |
| 5815 scratch2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); | |
| 5816 __ cmp(scratch2, | |
| 5817 Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); | |
| 5818 __ b(ne, slow); | |
| 5819 __ ldr(arg, FieldMemOperand(arg, JSValue::kValueOffset)); | |
| 5820 __ str(arg, MemOperand(sp, stack_offset)); | |
| 5821 | |
| 5822 __ bind(&done); | 5804 __ bind(&done); |
| 5823 } | 5805 } |
| 5824 | 5806 |
| 5825 | 5807 |
| 5826 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 5808 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { |
| 5827 ASSERT(state_ == CompareIC::SMI); | 5809 ASSERT(state_ == CompareIC::SMI); |
| 5828 Label miss; | 5810 Label miss; |
| 5829 __ orr(r2, r1, r0); | 5811 __ orr(r2, r1, r0); |
| 5830 __ JumpIfNotSmi(r2, &miss); | 5812 __ JumpIfNotSmi(r2, &miss); |
| 5831 | 5813 |
| (...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6848 if (frame_alignment > kPointerSize) { | 6830 if (frame_alignment > kPointerSize) { |
| 6849 __ mov(sp, r5); | 6831 __ mov(sp, r5); |
| 6850 } | 6832 } |
| 6851 | 6833 |
| 6852 // Also pop pc to get Ret(0). | 6834 // Also pop pc to get Ret(0). |
| 6853 __ ldm(ia_w, sp, kSavedRegs | pc.bit()); | 6835 __ ldm(ia_w, sp, kSavedRegs | pc.bit()); |
| 6854 } | 6836 } |
| 6855 | 6837 |
| 6856 | 6838 |
| 6857 template<class T> | 6839 template<class T> |
| 6858 static void CreateArrayDispatch(MacroAssembler* masm) { | 6840 static void CreateArrayDispatch(MacroAssembler* masm, |
| 6859 int last_index = GetSequenceIndexFromFastElementsKind( | 6841 AllocationSiteOverrideMode mode) { |
| 6860 TERMINAL_FAST_ELEMENTS_KIND); | 6842 if (mode == DISABLE_ALLOCATION_SITES) { |
| 6861 for (int i = 0; i <= last_index; ++i) { | 6843 T stub(GetInitialFastElementsKind(), |
| 6862 Label next; | 6844 CONTEXT_CHECK_REQUIRED, |
| 6863 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 6845 mode); |
| 6864 __ cmp(r3, Operand(kind)); | |
| 6865 __ b(ne, &next); | |
| 6866 T stub(kind); | |
| 6867 __ TailCallStub(&stub); | 6846 __ TailCallStub(&stub); |
| 6868 __ bind(&next); | 6847 } else if (mode == DONT_OVERRIDE) { |
| 6848 int last_index = GetSequenceIndexFromFastElementsKind( |
| 6849 TERMINAL_FAST_ELEMENTS_KIND); |
| 6850 for (int i = 0; i <= last_index; ++i) { |
| 6851 Label next; |
| 6852 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 6853 __ cmp(r3, Operand(kind)); |
| 6854 __ b(ne, &next); |
| 6855 T stub(kind); |
| 6856 __ TailCallStub(&stub); |
| 6857 __ bind(&next); |
| 6858 } |
| 6859 |
| 6860 // If we reached this point there is a problem. |
| 6861 __ Abort(kUnexpectedElementsKindInArrayConstructor); |
| 6862 } else { |
| 6863 UNREACHABLE(); |
| 6869 } | 6864 } |
| 6870 | |
| 6871 // If we reached this point there is a problem. | |
| 6872 __ Abort(kUnexpectedElementsKindInArrayConstructor); | |
| 6873 } | 6865 } |
| 6874 | 6866 |
| 6875 | 6867 |
| 6876 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { | 6868 static void CreateArrayDispatchOneArgument(MacroAssembler* masm, |
| 6877 // r2 - type info cell | 6869 AllocationSiteOverrideMode mode) { |
| 6878 // r3 - kind | 6870 // r2 - type info cell (if mode != DISABLE_ALLOCATION_SITES) |
| 6871 // r3 - kind (if mode != DISABLE_ALLOCATION_SITES) |
| 6879 // r0 - number of arguments | 6872 // r0 - number of arguments |
| 6880 // r1 - constructor? | 6873 // r1 - constructor? |
| 6881 // sp[0] - last argument | 6874 // sp[0] - last argument |
| 6882 ASSERT(FAST_SMI_ELEMENTS == 0); | 6875 Label normal_sequence; |
| 6883 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 6876 if (mode == DONT_OVERRIDE) { |
| 6884 ASSERT(FAST_ELEMENTS == 2); | 6877 ASSERT(FAST_SMI_ELEMENTS == 0); |
| 6885 ASSERT(FAST_HOLEY_ELEMENTS == 3); | 6878 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 6886 ASSERT(FAST_DOUBLE_ELEMENTS == 4); | 6879 ASSERT(FAST_ELEMENTS == 2); |
| 6887 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); | 6880 ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 6881 ASSERT(FAST_DOUBLE_ELEMENTS == 4); |
| 6882 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); |
| 6888 | 6883 |
| 6889 // is the low bit set? If so, we are holey and that is good. | 6884 // is the low bit set? If so, we are holey and that is good. |
| 6890 __ tst(r3, Operand(1)); | 6885 __ tst(r3, Operand(1)); |
| 6891 Label normal_sequence; | 6886 __ b(ne, &normal_sequence); |
| 6892 __ b(ne, &normal_sequence); | 6887 } |
| 6893 | 6888 |
| 6894 // look at the first argument | 6889 // look at the first argument |
| 6895 __ ldr(r5, MemOperand(sp, 0)); | 6890 __ ldr(r5, MemOperand(sp, 0)); |
| 6896 __ cmp(r5, Operand::Zero()); | 6891 __ cmp(r5, Operand::Zero()); |
| 6897 __ b(eq, &normal_sequence); | 6892 __ b(eq, &normal_sequence); |
| 6898 | 6893 |
| 6899 // We are going to create a holey array, but our kind is non-holey. | 6894 if (mode == DISABLE_ALLOCATION_SITES) { |
| 6900 // Fix kind and retry (only if we have an allocation site in the cell). | 6895 ElementsKind initial = GetInitialFastElementsKind(); |
| 6901 __ add(r3, r3, Operand(1)); | 6896 ElementsKind holey_initial = GetHoleyElementsKind(initial); |
| 6902 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); | |
| 6903 __ b(eq, &normal_sequence); | |
| 6904 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); | |
| 6905 __ ldr(r5, FieldMemOperand(r5, 0)); | |
| 6906 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); | |
| 6907 __ b(ne, &normal_sequence); | |
| 6908 | 6897 |
| 6909 // Save the resulting elements kind in type info | 6898 ArraySingleArgumentConstructorStub stub_holey(holey_initial, |
| 6910 __ SmiTag(r3); | 6899 CONTEXT_CHECK_REQUIRED, |
| 6911 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); | 6900 DISABLE_ALLOCATION_SITES); |
| 6912 __ str(r3, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset)); | 6901 __ TailCallStub(&stub_holey); |
| 6913 __ SmiUntag(r3); | |
| 6914 | 6902 |
| 6915 __ bind(&normal_sequence); | 6903 __ bind(&normal_sequence); |
| 6916 int last_index = GetSequenceIndexFromFastElementsKind( | 6904 ArraySingleArgumentConstructorStub stub(initial, |
| 6917 TERMINAL_FAST_ELEMENTS_KIND); | 6905 CONTEXT_CHECK_REQUIRED, |
| 6918 for (int i = 0; i <= last_index; ++i) { | 6906 DISABLE_ALLOCATION_SITES); |
| 6919 Label next; | |
| 6920 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | |
| 6921 __ cmp(r3, Operand(kind)); | |
| 6922 __ b(ne, &next); | |
| 6923 ArraySingleArgumentConstructorStub stub(kind); | |
| 6924 __ TailCallStub(&stub); | 6907 __ TailCallStub(&stub); |
| 6925 __ bind(&next); | 6908 } else if (mode == DONT_OVERRIDE) { |
| 6909 // We are going to create a holey array, but our kind is non-holey. |
| 6910 // Fix kind and retry (only if we have an allocation site in the cell). |
| 6911 __ add(r3, r3, Operand(1)); |
| 6912 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); |
| 6913 |
| 6914 if (FLAG_debug_code) { |
| 6915 __ ldr(r5, FieldMemOperand(r5, 0)); |
| 6916 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); |
| 6917 __ Assert(eq, kExpectedAllocationSiteInCell); |
| 6918 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); |
| 6919 } |
| 6920 |
| 6921 // Save the resulting elements kind in type info |
| 6922 __ SmiTag(r3); |
| 6923 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); |
| 6924 __ str(r3, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset)); |
| 6925 __ SmiUntag(r3); |
| 6926 |
| 6927 __ bind(&normal_sequence); |
| 6928 int last_index = GetSequenceIndexFromFastElementsKind( |
| 6929 TERMINAL_FAST_ELEMENTS_KIND); |
| 6930 for (int i = 0; i <= last_index; ++i) { |
| 6931 Label next; |
| 6932 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 6933 __ cmp(r3, Operand(kind)); |
| 6934 __ b(ne, &next); |
| 6935 ArraySingleArgumentConstructorStub stub(kind); |
| 6936 __ TailCallStub(&stub); |
| 6937 __ bind(&next); |
| 6938 } |
| 6939 |
| 6940 // If we reached this point there is a problem. |
| 6941 __ Abort(kUnexpectedElementsKindInArrayConstructor); |
| 6942 } else { |
| 6943 UNREACHABLE(); |
| 6926 } | 6944 } |
| 6927 | |
| 6928 // If we reached this point there is a problem. | |
| 6929 __ Abort(kUnexpectedElementsKindInArrayConstructor); | |
| 6930 } | 6945 } |
| 6931 | 6946 |
| 6932 | 6947 |
| 6933 template<class T> | 6948 template<class T> |
| 6934 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { | 6949 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { |
| 6950 ElementsKind initial_kind = GetInitialFastElementsKind(); |
| 6951 ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind); |
| 6952 |
| 6935 int to_index = GetSequenceIndexFromFastElementsKind( | 6953 int to_index = GetSequenceIndexFromFastElementsKind( |
| 6936 TERMINAL_FAST_ELEMENTS_KIND); | 6954 TERMINAL_FAST_ELEMENTS_KIND); |
| 6937 for (int i = 0; i <= to_index; ++i) { | 6955 for (int i = 0; i <= to_index; ++i) { |
| 6938 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 6956 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 6939 T stub(kind); | 6957 T stub(kind); |
| 6940 stub.GetCode(isolate)->set_is_pregenerated(true); | 6958 stub.GetCode(isolate)->set_is_pregenerated(true); |
| 6941 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { | 6959 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE || |
| 6960 (!FLAG_track_allocation_sites && |
| 6961 (kind == initial_kind || kind == initial_holey_kind))) { |
| 6942 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); | 6962 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); |
| 6943 stub1.GetCode(isolate)->set_is_pregenerated(true); | 6963 stub1.GetCode(isolate)->set_is_pregenerated(true); |
| 6944 } | 6964 } |
| 6945 } | 6965 } |
| 6946 } | 6966 } |
| 6947 | 6967 |
| 6948 | 6968 |
| 6949 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 6969 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 6950 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 6970 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
| 6951 isolate); | 6971 isolate); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6964 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); | 6984 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); |
| 6965 stubh1.GetCode(isolate)->set_is_pregenerated(true); | 6985 stubh1.GetCode(isolate)->set_is_pregenerated(true); |
| 6966 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); | 6986 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); |
| 6967 stubh2.GetCode(isolate)->set_is_pregenerated(true); | 6987 stubh2.GetCode(isolate)->set_is_pregenerated(true); |
| 6968 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); | 6988 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); |
| 6969 stubh3.GetCode(isolate)->set_is_pregenerated(true); | 6989 stubh3.GetCode(isolate)->set_is_pregenerated(true); |
| 6970 } | 6990 } |
| 6971 } | 6991 } |
| 6972 | 6992 |
| 6973 | 6993 |
| 6994 void ArrayConstructorStub::GenerateDispatchToArrayStub( |
| 6995 MacroAssembler* masm, |
| 6996 AllocationSiteOverrideMode mode) { |
| 6997 if (argument_count_ == ANY) { |
| 6998 Label not_zero_case, not_one_case; |
| 6999 __ tst(r0, r0); |
| 7000 __ b(ne, ¬_zero_case); |
| 7001 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); |
| 7002 |
| 7003 __ bind(¬_zero_case); |
| 7004 __ cmp(r0, Operand(1)); |
| 7005 __ b(gt, ¬_one_case); |
| 7006 CreateArrayDispatchOneArgument(masm, mode); |
| 7007 |
| 7008 __ bind(¬_one_case); |
| 7009 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
| 7010 } else if (argument_count_ == NONE) { |
| 7011 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); |
| 7012 } else if (argument_count_ == ONE) { |
| 7013 CreateArrayDispatchOneArgument(masm, mode); |
| 7014 } else if (argument_count_ == MORE_THAN_ONE) { |
| 7015 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
| 7016 } else { |
| 7017 UNREACHABLE(); |
| 7018 } |
| 7019 } |
| 7020 |
| 7021 |
| 6974 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 7022 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 6975 // ----------- S t a t e ------------- | 7023 // ----------- S t a t e ------------- |
| 6976 // -- r0 : argc (only if argument_count_ == ANY) | 7024 // -- r0 : argc (only if argument_count_ == ANY) |
| 6977 // -- r1 : constructor | 7025 // -- r1 : constructor |
| 6978 // -- r2 : type info cell | 7026 // -- r2 : type info cell |
| 6979 // -- sp[0] : return address | 7027 // -- sp[0] : return address |
| 6980 // -- sp[4] : last argument | 7028 // -- sp[4] : last argument |
| 6981 // ----------------------------------- | 7029 // ----------------------------------- |
| 6982 if (FLAG_debug_code) { | 7030 if (FLAG_debug_code) { |
| 6983 // The array construct code is only set for the global and natives | 7031 // The array construct code is only set for the global and natives |
| (...skipping 11 matching lines...) Expand all Loading... |
| 6995 Label okay_here; | 7043 Label okay_here; |
| 6996 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); | 7044 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); |
| 6997 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); | 7045 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 6998 __ b(eq, &okay_here); | 7046 __ b(eq, &okay_here); |
| 6999 __ ldr(r3, FieldMemOperand(r2, 0)); | 7047 __ ldr(r3, FieldMemOperand(r2, 0)); |
| 7000 __ cmp(r3, Operand(cell_map)); | 7048 __ cmp(r3, Operand(cell_map)); |
| 7001 __ Assert(eq, kExpectedPropertyCellInRegisterEbx); | 7049 __ Assert(eq, kExpectedPropertyCellInRegisterEbx); |
| 7002 __ bind(&okay_here); | 7050 __ bind(&okay_here); |
| 7003 } | 7051 } |
| 7004 | 7052 |
| 7005 Label no_info, switch_ready; | 7053 Label no_info; |
| 7006 // Get the elements kind and case on that. | 7054 // Get the elements kind and case on that. |
| 7007 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); | 7055 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 7008 __ b(eq, &no_info); | 7056 __ b(eq, &no_info); |
| 7009 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); | 7057 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); |
| 7010 | 7058 |
| 7011 // The type cell may have undefined in its value. | 7059 // If the type cell is undefined, or contains anything other than an |
| 7012 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); | 7060 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
| 7013 __ b(eq, &no_info); | |
| 7014 | |
| 7015 // The type cell has either an AllocationSite or a JSFunction | |
| 7016 __ ldr(r4, FieldMemOperand(r3, 0)); | 7061 __ ldr(r4, FieldMemOperand(r3, 0)); |
| 7017 __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex); | 7062 __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex); |
| 7018 __ b(ne, &no_info); | 7063 __ b(ne, &no_info); |
| 7019 | 7064 |
| 7020 __ ldr(r3, FieldMemOperand(r3, AllocationSite::kTransitionInfoOffset)); | 7065 __ ldr(r3, FieldMemOperand(r3, AllocationSite::kTransitionInfoOffset)); |
| 7021 __ SmiUntag(r3); | 7066 __ SmiUntag(r3); |
| 7022 __ jmp(&switch_ready); | 7067 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
| 7068 |
| 7023 __ bind(&no_info); | 7069 __ bind(&no_info); |
| 7024 __ mov(r3, Operand(GetInitialFastElementsKind())); | 7070 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
| 7025 __ bind(&switch_ready); | |
| 7026 | |
| 7027 if (argument_count_ == ANY) { | |
| 7028 Label not_zero_case, not_one_case; | |
| 7029 __ tst(r0, r0); | |
| 7030 __ b(ne, ¬_zero_case); | |
| 7031 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm); | |
| 7032 | |
| 7033 __ bind(¬_zero_case); | |
| 7034 __ cmp(r0, Operand(1)); | |
| 7035 __ b(gt, ¬_one_case); | |
| 7036 CreateArrayDispatchOneArgument(masm); | |
| 7037 | |
| 7038 __ bind(¬_one_case); | |
| 7039 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm); | |
| 7040 } else if (argument_count_ == NONE) { | |
| 7041 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm); | |
| 7042 } else if (argument_count_ == ONE) { | |
| 7043 CreateArrayDispatchOneArgument(masm); | |
| 7044 } else if (argument_count_ == MORE_THAN_ONE) { | |
| 7045 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm); | |
| 7046 } else { | |
| 7047 UNREACHABLE(); | |
| 7048 } | |
| 7049 } | 7071 } |
| 7050 | 7072 |
| 7051 | 7073 |
| 7052 void InternalArrayConstructorStub::GenerateCase( | 7074 void InternalArrayConstructorStub::GenerateCase( |
| 7053 MacroAssembler* masm, ElementsKind kind) { | 7075 MacroAssembler* masm, ElementsKind kind) { |
| 7054 Label not_zero_case, not_one_case; | 7076 Label not_zero_case, not_one_case; |
| 7055 Label normal_sequence; | 7077 Label normal_sequence; |
| 7056 | 7078 |
| 7057 __ tst(r0, r0); | 7079 __ tst(r0, r0); |
| 7058 __ b(ne, ¬_zero_case); | 7080 __ b(ne, ¬_zero_case); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7132 __ bind(&fast_elements_case); | 7154 __ bind(&fast_elements_case); |
| 7133 GenerateCase(masm, FAST_ELEMENTS); | 7155 GenerateCase(masm, FAST_ELEMENTS); |
| 7134 } | 7156 } |
| 7135 | 7157 |
| 7136 | 7158 |
| 7137 #undef __ | 7159 #undef __ |
| 7138 | 7160 |
| 7139 } } // namespace v8::internal | 7161 } } // namespace v8::internal |
| 7140 | 7162 |
| 7141 #endif // V8_TARGET_ARCH_ARM | 7163 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |