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

Side by Side Diff: src/ic/mips/ic-mips.cc

Issue 858893002: MIPS: Add fast-path OOB support to KeyedLoadIC_Generic. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « no previous file | src/ic/mips64/ic-mips64.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 5
6 #include "src/v8.h" 6 #include "src/v8.h"
7 7
8 #if V8_TARGET_ARCH_MIPS 8 #if V8_TARGET_ARCH_MIPS
9 9
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // In the case that the object is a value-wrapper object, 153 // In the case that the object is a value-wrapper object,
154 // we enter the runtime system to make sure that indexing into string 154 // we enter the runtime system to make sure that indexing into string
155 // objects work as intended. 155 // objects work as intended.
156 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); 156 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE);
157 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 157 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
158 __ Branch(slow, lt, scratch, Operand(JS_OBJECT_TYPE)); 158 __ Branch(slow, lt, scratch, Operand(JS_OBJECT_TYPE));
159 } 159 }
160 160
161 161
162 // Loads an indexed element from a fast case array. 162 // Loads an indexed element from a fast case array.
163 // If not_fast_array is NULL, doesn't perform the elements map check.
164 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, 163 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
165 Register key, Register elements, 164 Register key, Register elements,
166 Register scratch1, Register scratch2, 165 Register scratch1, Register scratch2,
167 Register result, Label* not_fast_array, 166 Register result, Label* slow) {
168 Label* out_of_range) {
169 // Register use: 167 // Register use:
170 // 168 //
171 // receiver - holds the receiver on entry. 169 // receiver - holds the receiver on entry.
172 // Unchanged unless 'result' is the same register. 170 // Unchanged unless 'result' is the same register.
173 // 171 //
174 // key - holds the smi key on entry. 172 // key - holds the smi key on entry.
175 // Unchanged unless 'result' is the same register. 173 // Unchanged unless 'result' is the same register.
176 // 174 //
177 // elements - holds the elements of the receiver on exit.
178 //
179 // result - holds the result on exit if the load succeeded. 175 // result - holds the result on exit if the load succeeded.
180 // Allowed to be the the same as 'receiver' or 'key'. 176 // Allowed to be the the same as 'receiver' or 'key'.
181 // Unchanged on bailout so 'receiver' and 'key' can be safely 177 // Unchanged on bailout so 'receiver' and 'key' can be safely
182 // used by further computation. 178 // used by further computation.
183 // 179 //
184 // Scratch registers: 180 // Scratch registers:
185 // 181 //
186 // scratch1 - used to hold elements map and elements length. 182 // elements - holds the elements of the receiver and its prototypes.
187 // Holds the elements map if not_fast_array branch is taken.
188 // 183 //
189 // scratch2 - used to hold the loaded value. 184 // scratch1 - used to hold elements length, bit fields, base addresses.
185 //
186 // scratch2 - used to hold maps, prototypes, and the loaded value.
187 Label check_prototypes, check_next_prototype;
188 Label done, in_bounds, return_undefined;
190 189
191 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 190 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
192 if (not_fast_array != NULL) { 191 __ AssertFastElements(elements);
193 // Check that the object is in fast mode (not dictionary).
194 __ lw(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset));
195 __ LoadRoot(at, Heap::kFixedArrayMapRootIndex);
196 __ Branch(not_fast_array, ne, scratch1, Operand(at));
197 } else {
198 __ AssertFastElements(elements);
199 }
200 192
201 // Check that the key (index) is within bounds. 193 // Check that the key (index) is within bounds.
202 __ lw(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset)); 194 __ lw(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
203 __ Branch(out_of_range, hs, key, Operand(scratch1)); 195 __ Branch(&in_bounds, lo, key, Operand(scratch1));
196 // Out-of-bounds. Check the prototype chain to see if we can just return
197 // 'undefined'.
198 // Negative keys can't take the fast OOB path.
199 __ Branch(slow, lt, key, Operand(zero_reg));
200 __ bind(&check_prototypes);
201 __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
202 __ bind(&check_next_prototype);
203 __ lw(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
204 // scratch2: current prototype
205 __ LoadRoot(at, Heap::kNullValueRootIndex);
206 __ Branch(&return_undefined, eq, scratch2, Operand(at));
207 __ lw(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
208 __ lw(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
209 // elements: elements of current prototype
210 // scratch2: map of current prototype
211 __ lbu(scratch1, FieldMemOperand(scratch2, Map::kInstanceTypeOffset));
212 __ Branch(slow, lo, scratch1, Operand(JS_OBJECT_TYPE));
213 __ lbu(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset));
214 __ And(at, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) |
215 (1 << Map::kHasIndexedInterceptor)));
216 __ Branch(slow, ne, at, Operand(zero_reg));
217 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
218 __ Branch(slow, ne, elements, Operand(at));
219 __ Branch(&check_next_prototype);
204 220
221 __ bind(&return_undefined);
222 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
223 __ Branch(&done);
224
225 __ bind(&in_bounds);
205 // Fast case: Do the load. 226 // Fast case: Do the load.
206 __ Addu(scratch1, elements, 227 __ Addu(scratch1, elements,
207 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 228 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
208 // The key is a smi. 229 // The key is a smi.
209 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); 230 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
210 __ sll(at, key, kPointerSizeLog2 - kSmiTagSize); 231 __ sll(at, key, kPointerSizeLog2 - kSmiTagSize);
211 __ addu(at, at, scratch1); 232 __ addu(at, at, scratch1);
212 __ lw(scratch2, MemOperand(at)); 233 __ lw(scratch2, MemOperand(at));
213 234
214 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 235 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
215 // In case the loaded value is the_hole we have to consult GetProperty 236 // In case the loaded value is the_hole we have to check the prototype chain.
216 // to ensure the prototype chain is searched. 237 __ Branch(&check_prototypes, eq, scratch2, Operand(at));
217 __ Branch(out_of_range, eq, scratch2, Operand(at)); 238 __ Move(result, scratch2);
218 __ mov(result, scratch2); 239 __ bind(&done);
219 } 240 }
220 241
221 242
222 // Checks whether a key is an array index string or a unique name. 243 // Checks whether a key is an array index string or a unique name.
223 // Falls through if a key is a unique name. 244 // Falls through if a key is a unique name.
224 static void GenerateKeyNameCheck(MacroAssembler* masm, Register key, 245 static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
225 Register map, Register hash, 246 Register map, Register hash,
226 Label* index_string, Label* not_unique) { 247 Label* index_string, Label* not_unique) {
227 // The key is not a smi. 248 // The key is not a smi.
228 Label unique; 249 Label unique;
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 __ bind(&index_smi); 492 __ bind(&index_smi);
472 // Now the key is known to be a smi. This place is also jumped to from below 493 // Now the key is known to be a smi. This place is also jumped to from below
473 // where a numeric string is converted to a smi. 494 // where a numeric string is converted to a smi.
474 495
475 GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3, 496 GenerateKeyedLoadReceiverCheck(masm, receiver, a0, a3,
476 Map::kHasIndexedInterceptor, &slow); 497 Map::kHasIndexedInterceptor, &slow);
477 498
478 // Check the receiver's map to see if it has fast elements. 499 // Check the receiver's map to see if it has fast elements.
479 __ CheckFastElements(a0, a3, &check_number_dictionary); 500 __ CheckFastElements(a0, a3, &check_number_dictionary);
480 501
481 GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, NULL, &slow); 502 GenerateFastArrayLoad(masm, receiver, key, a0, a3, t0, v0, &slow);
482 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, t0, a3); 503 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, t0, a3);
483 __ Ret(); 504 __ Ret();
484 505
485 __ bind(&check_number_dictionary); 506 __ bind(&check_number_dictionary);
486 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset)); 507 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
487 __ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset)); 508 __ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset));
488 509
489 // Check whether the elements is a number dictionary. 510 // Check whether the elements is a number dictionary.
490 // a3: elements map 511 // a3: elements map
491 // t0: elements 512 // t0: elements
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 patcher.ChangeBranchCondition(ne); 1046 patcher.ChangeBranchCondition(ne);
1026 } else { 1047 } else {
1027 DCHECK(Assembler::IsBne(branch_instr)); 1048 DCHECK(Assembler::IsBne(branch_instr));
1028 patcher.ChangeBranchCondition(eq); 1049 patcher.ChangeBranchCondition(eq);
1029 } 1050 }
1030 } 1051 }
1031 } 1052 }
1032 } // namespace v8::internal 1053 } // namespace v8::internal
1033 1054
1034 #endif // V8_TARGET_ARCH_MIPS 1055 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/ic/mips64/ic-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698