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

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 23451057: MIPS: Bugfix: array constructors that expect a type feedback cell that points to an AllocationSite … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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 | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 6950 matching lines...) Expand 10 before | Expand all | Expand 10 after
6961 __ mov(sp, s5); 6961 __ mov(sp, s5);
6962 } 6962 }
6963 6963
6964 // Also pop ra to get Ret(0). 6964 // Also pop ra to get Ret(0).
6965 __ MultiPop(kSavedRegs | ra.bit()); 6965 __ MultiPop(kSavedRegs | ra.bit());
6966 __ Ret(); 6966 __ Ret();
6967 } 6967 }
6968 6968
6969 6969
6970 template<class T> 6970 template<class T>
6971 static void CreateArrayDispatch(MacroAssembler* masm) { 6971 static void CreateArrayDispatch(MacroAssembler* masm,
6972 int last_index = GetSequenceIndexFromFastElementsKind( 6972 AllocationSiteOverrideMode mode) {
6973 TERMINAL_FAST_ELEMENTS_KIND); 6973 if (mode == DISABLE_ALLOCATION_SITES) {
6974 for (int i = 0; i <= last_index; ++i) { 6974 T stub(GetInitialFastElementsKind(),
6975 Label next; 6975 CONTEXT_CHECK_REQUIRED,
6976 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 6976 mode);
6977 __ Branch(&next, ne, a3, Operand(kind));
6978 T stub(kind);
6979 __ TailCallStub(&stub); 6977 __ TailCallStub(&stub);
6980 __ 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();
6981 } 6994 }
6982
6983 // If we reached this point there is a problem.
6984 __ Abort(kUnexpectedElementsKindInArrayConstructor);
6985 } 6995 }
6986 6996
6987 6997
6988 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { 6998 static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
6989 // a2 - type info cell 6999 AllocationSiteOverrideMode mode) {
6990 // a3 - kind 7000 // a2 - type info cell (if mode != DISABLE_ALLOCATION_SITES)
7001 // a3 - kind (if mode != DISABLE_ALLOCATION_SITES)
6991 // a0 - number of arguments 7002 // a0 - number of arguments
6992 // a1 - constructor? 7003 // a1 - constructor?
6993 // sp[0] - last argument 7004 // sp[0] - last argument
6994 ASSERT(FAST_SMI_ELEMENTS == 0); 7005 Label normal_sequence;
6995 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 7006 if (mode == DONT_OVERRIDE) {
6996 ASSERT(FAST_ELEMENTS == 2); 7007 ASSERT(FAST_SMI_ELEMENTS == 0);
6997 ASSERT(FAST_HOLEY_ELEMENTS == 3); 7008 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
6998 ASSERT(FAST_DOUBLE_ELEMENTS == 4); 7009 ASSERT(FAST_ELEMENTS == 2);
6999 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);
7000 7013
7001 // 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.
7002 Label normal_sequence; 7015 __ And(at, a3, Operand(1));
7003 __ And(at, a3, Operand(1)); 7016 __ Branch(&normal_sequence, ne, at, Operand(zero_reg));
7004 __ Branch(&normal_sequence, ne, at, Operand(zero_reg)); 7017 }
7005 7018
7006 // look at the first argument 7019 // look at the first argument
7007 __ lw(t1, MemOperand(sp, 0)); 7020 __ lw(t1, MemOperand(sp, 0));
7008 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); 7021 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg));
7009 7022
7010 // We are going to create a holey array, but our kind is non-holey. 7023 if (mode == DISABLE_ALLOCATION_SITES) {
7011 // Fix kind and retry (only if we have an allocation site in the cell). 7024 ElementsKind initial = GetInitialFastElementsKind();
7012 __ Addu(a3, a3, Operand(1)); 7025 ElementsKind holey_initial = GetHoleyElementsKind(initial);
7013 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
7014 __ Branch(&normal_sequence, eq, a2, Operand(at));
7015 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset));
7016 __ lw(t1, FieldMemOperand(t1, 0));
7017 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
7018 __ Branch(&normal_sequence, ne, t1, Operand(at));
7019 7026
7020 // Save the resulting elements kind in type info 7027 ArraySingleArgumentConstructorStub stub_holey(holey_initial,
7021 __ SmiTag(a3); 7028 CONTEXT_CHECK_REQUIRED,
7022 __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); 7029 DISABLE_ALLOCATION_SITES);
7023 __ sw(a3, FieldMemOperand(t1, AllocationSite::kTransitionInfoOffset)); 7030 __ TailCallStub(&stub_holey);
7024 __ SmiUntag(a3);
7025 7031
7026 __ bind(&normal_sequence); 7032 __ bind(&normal_sequence);
7027 int last_index = GetSequenceIndexFromFastElementsKind( 7033 ArraySingleArgumentConstructorStub stub(initial,
7028 TERMINAL_FAST_ELEMENTS_KIND); 7034 CONTEXT_CHECK_REQUIRED,
7029 for (int i = 0; i <= last_index; ++i) { 7035 DISABLE_ALLOCATION_SITES);
7030 Label next;
7031 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7032 __ Branch(&next, ne, a3, Operand(kind));
7033 ArraySingleArgumentConstructorStub stub(kind);
7034 __ TailCallStub(&stub); 7036 __ TailCallStub(&stub);
7035 __ 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();
7036 } 7072 }
7037
7038 // If we reached this point there is a problem.
7039 __ Abort(kUnexpectedElementsKindInArrayConstructor);
7040 } 7073 }
7041 7074
7042 7075
7043 template<class T> 7076 template<class T>
7044 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
7045 int to_index = GetSequenceIndexFromFastElementsKind( 7081 int to_index = GetSequenceIndexFromFastElementsKind(
7046 TERMINAL_FAST_ELEMENTS_KIND); 7082 TERMINAL_FAST_ELEMENTS_KIND);
7047 for (int i = 0; i <= to_index; ++i) { 7083 for (int i = 0; i <= to_index; ++i) {
7048 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 7084 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7049 T stub(kind); 7085 T stub(kind);
7050 stub.GetCode(isolate)->set_is_pregenerated(true); 7086 stub.GetCode(isolate)->set_is_pregenerated(true);
7051 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))) {
7052 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); 7090 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
7053 stub1.GetCode(isolate)->set_is_pregenerated(true); 7091 stub1.GetCode(isolate)->set_is_pregenerated(true);
7054 } 7092 }
7055 } 7093 }
7056 } 7094 }
7057 7095
7058 7096
7059 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { 7097 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
7060 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( 7098 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
7061 isolate); 7099 isolate);
(...skipping 12 matching lines...) Expand all
7074 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); 7112 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
7075 stubh1.GetCode(isolate)->set_is_pregenerated(true); 7113 stubh1.GetCode(isolate)->set_is_pregenerated(true);
7076 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); 7114 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
7077 stubh2.GetCode(isolate)->set_is_pregenerated(true); 7115 stubh2.GetCode(isolate)->set_is_pregenerated(true);
7078 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); 7116 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
7079 stubh3.GetCode(isolate)->set_is_pregenerated(true); 7117 stubh3.GetCode(isolate)->set_is_pregenerated(true);
7080 } 7118 }
7081 } 7119 }
7082 7120
7083 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(&not_zero_case, ne, at, Operand(zero_reg));
7129 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
7130
7131 __ bind(&not_zero_case);
7132 __ Branch(&not_one_case, gt, a0, Operand(1));
7133 CreateArrayDispatchOneArgument(masm, mode);
7134
7135 __ bind(&not_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
7084 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 7149 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
7085 // ----------- S t a t e ------------- 7150 // ----------- S t a t e -------------
7086 // -- a0 : argc (only if argument_count_ == ANY) 7151 // -- a0 : argc (only if argument_count_ == ANY)
7087 // -- a1 : constructor 7152 // -- a1 : constructor
7088 // -- a2 : type info cell 7153 // -- a2 : type info cell
7089 // -- sp[0] : return address 7154 // -- sp[0] : return address
7090 // -- sp[4] : last argument 7155 // -- sp[4] : last argument
7091 // ----------------------------------- 7156 // -----------------------------------
7092 if (FLAG_debug_code) { 7157 if (FLAG_debug_code) {
7093 // 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
7107 Label okay_here; 7172 Label okay_here;
7108 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); 7173 Handle<Map> cell_map = masm->isolate()->factory()->cell_map();
7109 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 7174 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
7110 __ Branch(&okay_here, eq, a2, Operand(at)); 7175 __ Branch(&okay_here, eq, a2, Operand(at));
7111 __ lw(a3, FieldMemOperand(a2, 0)); 7176 __ lw(a3, FieldMemOperand(a2, 0));
7112 __ Assert(eq, kExpectedPropertyCellInRegisterA2, 7177 __ Assert(eq, kExpectedPropertyCellInRegisterA2,
7113 a3, Operand(cell_map)); 7178 a3, Operand(cell_map));
7114 __ bind(&okay_here); 7179 __ bind(&okay_here);
7115 } 7180 }
7116 7181
7117 Label no_info, switch_ready; 7182 Label no_info;
7118 // Get the elements kind and case on that. 7183 // Get the elements kind and case on that.
7119 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 7184 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
7120 __ Branch(&no_info, eq, a2, Operand(at)); 7185 __ Branch(&no_info, eq, a2, Operand(at));
7121 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); 7186 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset));
7122 7187
7123 // The type cell may have undefined in its value. 7188 // If the type cell is undefined, or contains anything other than an
7124 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 7189 // AllocationSite, call an array constructor that doesn't use AllocationSites.
7125 __ Branch(&no_info, eq, a3, Operand(at));
7126
7127 // The type cell has either an AllocationSite or a JSFunction.
7128 __ lw(t0, FieldMemOperand(a3, 0)); 7190 __ lw(t0, FieldMemOperand(a3, 0));
7129 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); 7191 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
7130 __ Branch(&no_info, ne, t0, Operand(at)); 7192 __ Branch(&no_info, ne, t0, Operand(at));
7131 7193
7132 __ lw(a3, FieldMemOperand(a3, AllocationSite::kTransitionInfoOffset)); 7194 __ lw(a3, FieldMemOperand(a3, AllocationSite::kTransitionInfoOffset));
7133 __ SmiUntag(a3); 7195 __ SmiUntag(a3);
7134 __ jmp(&switch_ready); 7196 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
7197
7135 __ bind(&no_info); 7198 __ bind(&no_info);
7136 __ li(a3, Operand(GetInitialFastElementsKind())); 7199 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
7137 __ bind(&switch_ready);
7138
7139 if (argument_count_ == ANY) {
7140 Label not_zero_case, not_one_case;
7141 __ And(at, a0, a0);
7142 __ Branch(&not_zero_case, ne, at, Operand(zero_reg));
7143 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
7144
7145 __ bind(&not_zero_case);
7146 __ Branch(&not_one_case, gt, a0, Operand(1));
7147 CreateArrayDispatchOneArgument(masm);
7148
7149 __ bind(&not_one_case);
7150 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
7151 } else if (argument_count_ == NONE) {
7152 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
7153 } else if (argument_count_ == ONE) {
7154 CreateArrayDispatchOneArgument(masm);
7155 } else if (argument_count_ == MORE_THAN_ONE) {
7156 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
7157 } else {
7158 UNREACHABLE();
7159 }
7160 } 7200 }
7161 7201
7162 7202
7163 void InternalArrayConstructorStub::GenerateCase( 7203 void InternalArrayConstructorStub::GenerateCase(
7164 MacroAssembler* masm, ElementsKind kind) { 7204 MacroAssembler* masm, ElementsKind kind) {
7165 Label not_zero_case, not_one_case; 7205 Label not_zero_case, not_one_case;
7166 Label normal_sequence; 7206 Label normal_sequence;
7167 7207
7168 __ Branch(&not_zero_case, ne, a0, Operand(zero_reg)); 7208 __ Branch(&not_zero_case, ne, a0, Operand(zero_reg));
7169 InternalArrayNoArgumentConstructorStub stub0(kind); 7209 InternalArrayNoArgumentConstructorStub stub0(kind);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
7241 __ bind(&fast_elements_case); 7281 __ bind(&fast_elements_case);
7242 GenerateCase(masm, FAST_ELEMENTS); 7282 GenerateCase(masm, FAST_ELEMENTS);
7243 } 7283 }
7244 7284
7245 7285
7246 #undef __ 7286 #undef __
7247 7287
7248 } } // namespace v8::internal 7288 } } // namespace v8::internal
7249 7289
7250 #endif // V8_TARGET_ARCH_MIPS 7290 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698