| 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 2777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2788 // v0: result parameter for PerformGC, if any | 2788 // v0: result parameter for PerformGC, if any |
| 2789 // s0: number of arguments including receiver (C callee-saved) | 2789 // s0: number of arguments including receiver (C callee-saved) |
| 2790 // s1: pointer to the first argument (C callee-saved) | 2790 // s1: pointer to the first argument (C callee-saved) |
| 2791 // s2: pointer to builtin function (C callee-saved) | 2791 // s2: pointer to builtin function (C callee-saved) |
| 2792 | 2792 |
| 2793 Isolate* isolate = masm->isolate(); | 2793 Isolate* isolate = masm->isolate(); |
| 2794 | 2794 |
| 2795 if (do_gc) { | 2795 if (do_gc) { |
| 2796 // Move result passed in v0 into a0 to call PerformGC. | 2796 // Move result passed in v0 into a0 to call PerformGC. |
| 2797 __ mov(a0, v0); | 2797 __ mov(a0, v0); |
| 2798 __ PrepareCallCFunction(1, 0, a1); | 2798 __ PrepareCallCFunction(2, 0, a1); |
| 2799 __ CallCFunction(ExternalReference::perform_gc_function(isolate), 1, 0); | 2799 __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 2800 __ CallCFunction(ExternalReference::perform_gc_function(isolate), 2, 0); |
| 2800 } | 2801 } |
| 2801 | 2802 |
| 2802 ExternalReference scope_depth = | 2803 ExternalReference scope_depth = |
| 2803 ExternalReference::heap_always_allocate_scope_depth(isolate); | 2804 ExternalReference::heap_always_allocate_scope_depth(isolate); |
| 2804 if (always_allocate) { | 2805 if (always_allocate) { |
| 2805 __ li(a0, Operand(scope_depth)); | 2806 __ li(a0, Operand(scope_depth)); |
| 2806 __ lw(a1, MemOperand(a0)); | 2807 __ lw(a1, MemOperand(a0)); |
| 2807 __ Addu(a1, a1, Operand(1)); | 2808 __ Addu(a1, a1, Operand(1)); |
| 2808 __ sw(a1, MemOperand(a0)); | 2809 __ sw(a1, MemOperand(a0)); |
| 2809 } | 2810 } |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3401 ASSERT(kind() == Code::LOAD_IC); | 3402 ASSERT(kind() == Code::LOAD_IC); |
| 3402 // ----------- S t a t e ------------- | 3403 // ----------- S t a t e ------------- |
| 3403 // -- a2 : name | 3404 // -- a2 : name |
| 3404 // -- ra : return address | 3405 // -- ra : return address |
| 3405 // -- a0 : receiver | 3406 // -- a0 : receiver |
| 3406 // -- sp[0] : receiver | 3407 // -- sp[0] : receiver |
| 3407 // ----------------------------------- | 3408 // ----------------------------------- |
| 3408 receiver = a0; | 3409 receiver = a0; |
| 3409 } | 3410 } |
| 3410 | 3411 |
| 3411 StubCompiler::GenerateLoadStringLength(masm, receiver, a3, t0, &miss, | 3412 StubCompiler::GenerateLoadStringLength(masm, receiver, a3, t0, &miss); |
| 3412 support_wrapper_); | |
| 3413 | 3413 |
| 3414 __ bind(&miss); | 3414 __ bind(&miss); |
| 3415 StubCompiler::TailCallBuiltin( | 3415 StubCompiler::TailCallBuiltin( |
| 3416 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); | 3416 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); |
| 3417 } | 3417 } |
| 3418 | 3418 |
| 3419 | 3419 |
| 3420 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { | 3420 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { |
| 3421 // This accepts as a receiver anything JSArray::SetElementsLength accepts | 3421 // This accepts as a receiver anything JSArray::SetElementsLength accepts |
| 3422 // (currently anything except for external arrays which means anything with | 3422 // (currently anything except for external arrays which means anything with |
| (...skipping 2431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5854 Register scratch3, | 5854 Register scratch3, |
| 5855 Register scratch4, | 5855 Register scratch4, |
| 5856 Label* slow) { | 5856 Label* slow) { |
| 5857 // First check if the argument is already a string. | 5857 // First check if the argument is already a string. |
| 5858 Label not_string, done; | 5858 Label not_string, done; |
| 5859 __ JumpIfSmi(arg, ¬_string); | 5859 __ JumpIfSmi(arg, ¬_string); |
| 5860 __ GetObjectType(arg, scratch1, scratch1); | 5860 __ GetObjectType(arg, scratch1, scratch1); |
| 5861 __ Branch(&done, lt, scratch1, Operand(FIRST_NONSTRING_TYPE)); | 5861 __ Branch(&done, lt, scratch1, Operand(FIRST_NONSTRING_TYPE)); |
| 5862 | 5862 |
| 5863 // Check the number to string cache. | 5863 // Check the number to string cache. |
| 5864 Label not_cached; | |
| 5865 __ bind(¬_string); | 5864 __ bind(¬_string); |
| 5866 // Puts the cached result into scratch1. | 5865 // Puts the cached result into scratch1. |
| 5867 NumberToStringStub::GenerateLookupNumberStringCache(masm, | 5866 NumberToStringStub::GenerateLookupNumberStringCache(masm, |
| 5868 arg, | 5867 arg, |
| 5869 scratch1, | 5868 scratch1, |
| 5870 scratch2, | 5869 scratch2, |
| 5871 scratch3, | 5870 scratch3, |
| 5872 scratch4, | 5871 scratch4, |
| 5873 ¬_cached); | 5872 slow); |
| 5874 __ mov(arg, scratch1); | 5873 __ mov(arg, scratch1); |
| 5875 __ sw(arg, MemOperand(sp, stack_offset)); | 5874 __ sw(arg, MemOperand(sp, stack_offset)); |
| 5876 __ jmp(&done); | |
| 5877 | |
| 5878 // Check if the argument is a safe string wrapper. | |
| 5879 __ bind(¬_cached); | |
| 5880 __ JumpIfSmi(arg, slow); | |
| 5881 __ GetObjectType(arg, scratch1, scratch2); // map -> scratch1. | |
| 5882 __ Branch(slow, ne, scratch2, Operand(JS_VALUE_TYPE)); | |
| 5883 __ lbu(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset)); | |
| 5884 __ li(scratch4, 1 << Map::kStringWrapperSafeForDefaultValueOf); | |
| 5885 __ And(scratch2, scratch2, scratch4); | |
| 5886 __ Branch(slow, ne, scratch2, Operand(scratch4)); | |
| 5887 __ lw(arg, FieldMemOperand(arg, JSValue::kValueOffset)); | |
| 5888 __ sw(arg, MemOperand(sp, stack_offset)); | |
| 5889 | |
| 5890 __ bind(&done); | 5875 __ bind(&done); |
| 5891 } | 5876 } |
| 5892 | 5877 |
| 5893 | 5878 |
| 5894 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 5879 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { |
| 5895 ASSERT(state_ == CompareIC::SMI); | 5880 ASSERT(state_ == CompareIC::SMI); |
| 5896 Label miss; | 5881 Label miss; |
| 5897 __ Or(a2, a1, a0); | 5882 __ Or(a2, a1, a0); |
| 5898 __ JumpIfNotSmi(a2, &miss); | 5883 __ JumpIfNotSmi(a2, &miss); |
| 5899 | 5884 |
| (...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6976 __ mov(sp, s5); | 6961 __ mov(sp, s5); |
| 6977 } | 6962 } |
| 6978 | 6963 |
| 6979 // Also pop ra to get Ret(0). | 6964 // Also pop ra to get Ret(0). |
| 6980 __ MultiPop(kSavedRegs | ra.bit()); | 6965 __ MultiPop(kSavedRegs | ra.bit()); |
| 6981 __ Ret(); | 6966 __ Ret(); |
| 6982 } | 6967 } |
| 6983 | 6968 |
| 6984 | 6969 |
| 6985 template<class T> | 6970 template<class T> |
| 6986 static void CreateArrayDispatch(MacroAssembler* masm) { | 6971 static void CreateArrayDispatch(MacroAssembler* masm, |
| 6987 int last_index = GetSequenceIndexFromFastElementsKind( | 6972 AllocationSiteOverrideMode mode) { |
| 6988 TERMINAL_FAST_ELEMENTS_KIND); | 6973 if (mode == DISABLE_ALLOCATION_SITES) { |
| 6989 for (int i = 0; i <= last_index; ++i) { | 6974 T stub(GetInitialFastElementsKind(), |
| 6990 Label next; | 6975 CONTEXT_CHECK_REQUIRED, |
| 6991 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 6976 mode); |
| 6992 __ Branch(&next, ne, a3, Operand(kind)); | |
| 6993 T stub(kind); | |
| 6994 __ TailCallStub(&stub); | 6977 __ TailCallStub(&stub); |
| 6995 __ bind(&next); | 6978 } else if (mode == DONT_OVERRIDE) { |
| 6979 int last_index = GetSequenceIndexFromFastElementsKind( |
| 6980 TERMINAL_FAST_ELEMENTS_KIND); |
| 6981 for (int i = 0; i <= last_index; ++i) { |
| 6982 Label next; |
| 6983 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 6984 __ Branch(&next, ne, a3, Operand(kind)); |
| 6985 T stub(kind); |
| 6986 __ TailCallStub(&stub); |
| 6987 __ bind(&next); |
| 6988 } |
| 6989 |
| 6990 // If we reached this point there is a problem. |
| 6991 __ Abort(kUnexpectedElementsKindInArrayConstructor); |
| 6992 } else { |
| 6993 UNREACHABLE(); |
| 6996 } | 6994 } |
| 6997 | |
| 6998 // If we reached this point there is a problem. | |
| 6999 __ Abort(kUnexpectedElementsKindInArrayConstructor); | |
| 7000 } | 6995 } |
| 7001 | 6996 |
| 7002 | 6997 |
| 7003 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { | 6998 static void CreateArrayDispatchOneArgument(MacroAssembler* masm, |
| 7004 // a2 - type info cell | 6999 AllocationSiteOverrideMode mode) { |
| 7005 // a3 - kind | 7000 // a2 - type info cell (if mode != DISABLE_ALLOCATION_SITES) |
| 7001 // a3 - kind (if mode != DISABLE_ALLOCATION_SITES) |
| 7006 // a0 - number of arguments | 7002 // a0 - number of arguments |
| 7007 // a1 - constructor? | 7003 // a1 - constructor? |
| 7008 // sp[0] - last argument | 7004 // sp[0] - last argument |
| 7009 ASSERT(FAST_SMI_ELEMENTS == 0); | 7005 Label normal_sequence; |
| 7010 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 7006 if (mode == DONT_OVERRIDE) { |
| 7011 ASSERT(FAST_ELEMENTS == 2); | 7007 ASSERT(FAST_SMI_ELEMENTS == 0); |
| 7012 ASSERT(FAST_HOLEY_ELEMENTS == 3); | 7008 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 7013 ASSERT(FAST_DOUBLE_ELEMENTS == 4); | 7009 ASSERT(FAST_ELEMENTS == 2); |
| 7014 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); | 7010 ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 7011 ASSERT(FAST_DOUBLE_ELEMENTS == 4); |
| 7012 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); |
| 7015 | 7013 |
| 7016 // is the low bit set? If so, we are holey and that is good. | 7014 // is the low bit set? If so, we are holey and that is good. |
| 7017 Label normal_sequence; | 7015 __ And(at, a3, Operand(1)); |
| 7018 __ And(at, a3, Operand(1)); | 7016 __ Branch(&normal_sequence, ne, at, Operand(zero_reg)); |
| 7019 __ Branch(&normal_sequence, ne, at, Operand(zero_reg)); | 7017 } |
| 7020 | 7018 |
| 7021 // look at the first argument | 7019 // look at the first argument |
| 7022 __ lw(t1, MemOperand(sp, 0)); | 7020 __ lw(t1, MemOperand(sp, 0)); |
| 7023 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); | 7021 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); |
| 7024 | 7022 |
| 7025 // We are going to create a holey array, but our kind is non-holey. | 7023 if (mode == DISABLE_ALLOCATION_SITES) { |
| 7026 // Fix kind and retry (only if we have an allocation site in the cell). | 7024 ElementsKind initial = GetInitialFastElementsKind(); |
| 7027 __ Addu(a3, a3, Operand(1)); | 7025 ElementsKind holey_initial = GetHoleyElementsKind(initial); |
| 7028 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | |
| 7029 __ Branch(&normal_sequence, eq, a2, Operand(at)); | |
| 7030 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); | |
| 7031 __ lw(t1, FieldMemOperand(t1, 0)); | |
| 7032 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | |
| 7033 __ Branch(&normal_sequence, ne, t1, Operand(at)); | |
| 7034 | 7026 |
| 7035 // Save the resulting elements kind in type info | 7027 ArraySingleArgumentConstructorStub stub_holey(holey_initial, |
| 7036 __ SmiTag(a3); | 7028 CONTEXT_CHECK_REQUIRED, |
| 7037 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); | 7029 DISABLE_ALLOCATION_SITES); |
| 7038 __ sw(a3, FieldMemOperand(t1, AllocationSite::kTransitionInfoOffset)); | 7030 __ TailCallStub(&stub_holey); |
| 7039 __ SmiUntag(a3); | |
| 7040 | 7031 |
| 7041 __ bind(&normal_sequence); | 7032 __ bind(&normal_sequence); |
| 7042 int last_index = GetSequenceIndexFromFastElementsKind( | 7033 ArraySingleArgumentConstructorStub stub(initial, |
| 7043 TERMINAL_FAST_ELEMENTS_KIND); | 7034 CONTEXT_CHECK_REQUIRED, |
| 7044 for (int i = 0; i <= last_index; ++i) { | 7035 DISABLE_ALLOCATION_SITES); |
| 7045 Label next; | |
| 7046 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | |
| 7047 __ Branch(&next, ne, a3, Operand(kind)); | |
| 7048 ArraySingleArgumentConstructorStub stub(kind); | |
| 7049 __ TailCallStub(&stub); | 7036 __ TailCallStub(&stub); |
| 7050 __ bind(&next); | 7037 } else if (mode == DONT_OVERRIDE) { |
| 7038 // We are going to create a holey array, but our kind is non-holey. |
| 7039 // Fix kind and retry (only if we have an allocation site in the cell). |
| 7040 __ Addu(a3, a3, Operand(1)); |
| 7041 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
| 7042 |
| 7043 if (FLAG_debug_code) { |
| 7044 __ lw(t1, FieldMemOperand(t1, 0)); |
| 7045 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
| 7046 __ Assert(eq, kExpectedAllocationSiteInCell, t1, Operand(at)); |
| 7047 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
| 7048 } |
| 7049 |
| 7050 // Save the resulting elements kind in type info |
| 7051 __ SmiTag(a3); |
| 7052 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
| 7053 __ sw(a3, FieldMemOperand(t1, AllocationSite::kTransitionInfoOffset)); |
| 7054 __ SmiUntag(a3); |
| 7055 |
| 7056 __ bind(&normal_sequence); |
| 7057 int last_index = GetSequenceIndexFromFastElementsKind( |
| 7058 TERMINAL_FAST_ELEMENTS_KIND); |
| 7059 for (int i = 0; i <= last_index; ++i) { |
| 7060 Label next; |
| 7061 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 7062 __ Branch(&next, ne, a3, Operand(kind)); |
| 7063 ArraySingleArgumentConstructorStub stub(kind); |
| 7064 __ TailCallStub(&stub); |
| 7065 __ bind(&next); |
| 7066 } |
| 7067 |
| 7068 // If we reached this point there is a problem. |
| 7069 __ Abort(kUnexpectedElementsKindInArrayConstructor); |
| 7070 } else { |
| 7071 UNREACHABLE(); |
| 7051 } | 7072 } |
| 7052 | |
| 7053 // If we reached this point there is a problem. | |
| 7054 __ Abort(kUnexpectedElementsKindInArrayConstructor); | |
| 7055 } | 7073 } |
| 7056 | 7074 |
| 7057 | 7075 |
| 7058 template<class T> | 7076 template<class T> |
| 7059 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { | 7077 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { |
| 7078 ElementsKind initial_kind = GetInitialFastElementsKind(); |
| 7079 ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind); |
| 7080 |
| 7060 int to_index = GetSequenceIndexFromFastElementsKind( | 7081 int to_index = GetSequenceIndexFromFastElementsKind( |
| 7061 TERMINAL_FAST_ELEMENTS_KIND); | 7082 TERMINAL_FAST_ELEMENTS_KIND); |
| 7062 for (int i = 0; i <= to_index; ++i) { | 7083 for (int i = 0; i <= to_index; ++i) { |
| 7063 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 7084 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 7064 T stub(kind); | 7085 T stub(kind); |
| 7065 stub.GetCode(isolate)->set_is_pregenerated(true); | 7086 stub.GetCode(isolate)->set_is_pregenerated(true); |
| 7066 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { | 7087 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE || |
| 7088 (!FLAG_track_allocation_sites && |
| 7089 (kind == initial_kind || kind == initial_holey_kind))) { |
| 7067 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); | 7090 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); |
| 7068 stub1.GetCode(isolate)->set_is_pregenerated(true); | 7091 stub1.GetCode(isolate)->set_is_pregenerated(true); |
| 7069 } | 7092 } |
| 7070 } | 7093 } |
| 7071 } | 7094 } |
| 7072 | 7095 |
| 7073 | 7096 |
| 7074 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 7097 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 7075 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 7098 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
| 7076 isolate); | 7099 isolate); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 7089 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); | 7112 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); |
| 7090 stubh1.GetCode(isolate)->set_is_pregenerated(true); | 7113 stubh1.GetCode(isolate)->set_is_pregenerated(true); |
| 7091 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); | 7114 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); |
| 7092 stubh2.GetCode(isolate)->set_is_pregenerated(true); | 7115 stubh2.GetCode(isolate)->set_is_pregenerated(true); |
| 7093 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); | 7116 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); |
| 7094 stubh3.GetCode(isolate)->set_is_pregenerated(true); | 7117 stubh3.GetCode(isolate)->set_is_pregenerated(true); |
| 7095 } | 7118 } |
| 7096 } | 7119 } |
| 7097 | 7120 |
| 7098 | 7121 |
| 7122 void ArrayConstructorStub::GenerateDispatchToArrayStub( |
| 7123 MacroAssembler* masm, |
| 7124 AllocationSiteOverrideMode mode) { |
| 7125 if (argument_count_ == ANY) { |
| 7126 Label not_zero_case, not_one_case; |
| 7127 __ And(at, a0, a0); |
| 7128 __ Branch(¬_zero_case, ne, at, Operand(zero_reg)); |
| 7129 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); |
| 7130 |
| 7131 __ bind(¬_zero_case); |
| 7132 __ Branch(¬_one_case, gt, a0, Operand(1)); |
| 7133 CreateArrayDispatchOneArgument(masm, mode); |
| 7134 |
| 7135 __ bind(¬_one_case); |
| 7136 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
| 7137 } else if (argument_count_ == NONE) { |
| 7138 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); |
| 7139 } else if (argument_count_ == ONE) { |
| 7140 CreateArrayDispatchOneArgument(masm, mode); |
| 7141 } else if (argument_count_ == MORE_THAN_ONE) { |
| 7142 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
| 7143 } else { |
| 7144 UNREACHABLE(); |
| 7145 } |
| 7146 } |
| 7147 |
| 7148 |
| 7099 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 7149 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 7100 // ----------- S t a t e ------------- | 7150 // ----------- S t a t e ------------- |
| 7101 // -- a0 : argc (only if argument_count_ == ANY) | 7151 // -- a0 : argc (only if argument_count_ == ANY) |
| 7102 // -- a1 : constructor | 7152 // -- a1 : constructor |
| 7103 // -- a2 : type info cell | 7153 // -- a2 : type info cell |
| 7104 // -- sp[0] : return address | 7154 // -- sp[0] : return address |
| 7105 // -- sp[4] : last argument | 7155 // -- sp[4] : last argument |
| 7106 // ----------------------------------- | 7156 // ----------------------------------- |
| 7107 if (FLAG_debug_code) { | 7157 if (FLAG_debug_code) { |
| 7108 // The array construct code is only set for the global and natives | 7158 // The array construct code is only set for the global and natives |
| (...skipping 13 matching lines...) Expand all Loading... |
| 7122 Label okay_here; | 7172 Label okay_here; |
| 7123 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); | 7173 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); |
| 7124 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 7174 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 7125 __ Branch(&okay_here, eq, a2, Operand(at)); | 7175 __ Branch(&okay_here, eq, a2, Operand(at)); |
| 7126 __ lw(a3, FieldMemOperand(a2, 0)); | 7176 __ lw(a3, FieldMemOperand(a2, 0)); |
| 7127 __ Assert(eq, kExpectedPropertyCellInRegisterA2, | 7177 __ Assert(eq, kExpectedPropertyCellInRegisterA2, |
| 7128 a3, Operand(cell_map)); | 7178 a3, Operand(cell_map)); |
| 7129 __ bind(&okay_here); | 7179 __ bind(&okay_here); |
| 7130 } | 7180 } |
| 7131 | 7181 |
| 7132 Label no_info, switch_ready; | 7182 Label no_info; |
| 7133 // Get the elements kind and case on that. | 7183 // Get the elements kind and case on that. |
| 7134 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 7184 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 7135 __ Branch(&no_info, eq, a2, Operand(at)); | 7185 __ Branch(&no_info, eq, a2, Operand(at)); |
| 7136 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); | 7186 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); |
| 7137 | 7187 |
| 7138 // The type cell may have undefined in its value. | 7188 // If the type cell is undefined, or contains anything other than an |
| 7139 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 7189 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
| 7140 __ Branch(&no_info, eq, a3, Operand(at)); | |
| 7141 | |
| 7142 // The type cell has either an AllocationSite or a JSFunction. | |
| 7143 __ lw(t0, FieldMemOperand(a3, 0)); | 7190 __ lw(t0, FieldMemOperand(a3, 0)); |
| 7144 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 7191 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
| 7145 __ Branch(&no_info, ne, t0, Operand(at)); | 7192 __ Branch(&no_info, ne, t0, Operand(at)); |
| 7146 | 7193 |
| 7147 __ lw(a3, FieldMemOperand(a3, AllocationSite::kTransitionInfoOffset)); | 7194 __ lw(a3, FieldMemOperand(a3, AllocationSite::kTransitionInfoOffset)); |
| 7148 __ SmiUntag(a3); | 7195 __ SmiUntag(a3); |
| 7149 __ jmp(&switch_ready); | 7196 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
| 7197 |
| 7150 __ bind(&no_info); | 7198 __ bind(&no_info); |
| 7151 __ li(a3, Operand(GetInitialFastElementsKind())); | 7199 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
| 7152 __ bind(&switch_ready); | |
| 7153 | |
| 7154 if (argument_count_ == ANY) { | |
| 7155 Label not_zero_case, not_one_case; | |
| 7156 __ And(at, a0, a0); | |
| 7157 __ Branch(¬_zero_case, ne, at, Operand(zero_reg)); | |
| 7158 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm); | |
| 7159 | |
| 7160 __ bind(¬_zero_case); | |
| 7161 __ Branch(¬_one_case, gt, a0, Operand(1)); | |
| 7162 CreateArrayDispatchOneArgument(masm); | |
| 7163 | |
| 7164 __ bind(¬_one_case); | |
| 7165 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm); | |
| 7166 } else if (argument_count_ == NONE) { | |
| 7167 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm); | |
| 7168 } else if (argument_count_ == ONE) { | |
| 7169 CreateArrayDispatchOneArgument(masm); | |
| 7170 } else if (argument_count_ == MORE_THAN_ONE) { | |
| 7171 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm); | |
| 7172 } else { | |
| 7173 UNREACHABLE(); | |
| 7174 } | |
| 7175 } | 7200 } |
| 7176 | 7201 |
| 7177 | 7202 |
| 7178 void InternalArrayConstructorStub::GenerateCase( | 7203 void InternalArrayConstructorStub::GenerateCase( |
| 7179 MacroAssembler* masm, ElementsKind kind) { | 7204 MacroAssembler* masm, ElementsKind kind) { |
| 7180 Label not_zero_case, not_one_case; | 7205 Label not_zero_case, not_one_case; |
| 7181 Label normal_sequence; | 7206 Label normal_sequence; |
| 7182 | 7207 |
| 7183 __ Branch(¬_zero_case, ne, a0, Operand(zero_reg)); | 7208 __ Branch(¬_zero_case, ne, a0, Operand(zero_reg)); |
| 7184 InternalArrayNoArgumentConstructorStub stub0(kind); | 7209 InternalArrayNoArgumentConstructorStub stub0(kind); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7256 __ bind(&fast_elements_case); | 7281 __ bind(&fast_elements_case); |
| 7257 GenerateCase(masm, FAST_ELEMENTS); | 7282 GenerateCase(masm, FAST_ELEMENTS); |
| 7258 } | 7283 } |
| 7259 | 7284 |
| 7260 | 7285 |
| 7261 #undef __ | 7286 #undef __ |
| 7262 | 7287 |
| 7263 } } // namespace v8::internal | 7288 } } // namespace v8::internal |
| 7264 | 7289 |
| 7265 #endif // V8_TARGET_ARCH_MIPS | 7290 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |