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

Unified Diff: src/ic/arm64/ic-arm64.cc

Issue 852313002: Add fast-path OOB support to KeyedLoadIC_Generic (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix negative indices 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic/arm/ic-arm.cc ('k') | src/ic/ia32/ic-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/arm64/ic-arm64.cc
diff --git a/src/ic/arm64/ic-arm64.cc b/src/ic/arm64/ic-arm64.cc
index a01015c1864c559523435b06d213760625e6ad3c..2c1642bba77731bc7b38b9210beb619a83274acc 100644
--- a/src/ic/arm64/ic-arm64.cc
+++ b/src/ic/arm64/ic-arm64.cc
@@ -151,63 +151,77 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
// Loads an indexed element from a fast case array.
-// If not_fast_array is NULL, doesn't perform the elements map check.
//
-// receiver - holds the receiver on entry.
-// Unchanged unless 'result' is the same register.
+// receiver - holds the receiver on entry.
+// Unchanged unless 'result' is the same register.
//
-// key - holds the smi key on entry.
-// Unchanged unless 'result' is the same register.
+// key - holds the smi key on entry.
+// Unchanged unless 'result' is the same register.
//
-// elements - holds the elements of the receiver on exit.
+// elements - holds the elements of the receiver and its prototypes. Clobbered.
//
-// elements_map - holds the elements map on exit if the not_fast_array branch is
-// taken. Otherwise, this is used as a scratch register.
-//
-// result - holds the result on exit if the load succeeded.
-// Allowed to be the the same as 'receiver' or 'key'.
-// Unchanged on bailout so 'receiver' and 'key' can be safely
-// used by further computation.
+// result - holds the result on exit if the load succeeded.
+// Allowed to be the the same as 'receiver' or 'key'.
+// Unchanged on bailout so 'receiver' and 'key' can be safely
+// used by further computation.
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
- Register elements_map, Register scratch2,
- Register result, Label* not_fast_array,
- Label* slow) {
- DCHECK(!AreAliased(receiver, key, elements, elements_map, scratch2));
+ Register scratch1, Register scratch2,
+ Register result, Label* slow) {
+ DCHECK(!AreAliased(receiver, key, elements, scratch1, scratch2));
+
+ Label check_prototypes, check_next_prototype;
+ Label done, in_bounds, return_undefined;
// Check for fast array.
__ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- if (not_fast_array != NULL) {
- // Check that the object is in fast mode and writable.
- __ Ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
- __ JumpIfNotRoot(elements_map, Heap::kFixedArrayMapRootIndex,
- not_fast_array);
- } else {
- __ AssertFastElements(elements);
- }
-
- // The elements_map register is only used for the not_fast_array path, which
- // was handled above. From this point onward it is a scratch register.
- Register scratch1 = elements_map;
+ __ AssertFastElements(elements);
// Check that the key (index) is within bounds.
__ Ldr(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
__ Cmp(key, scratch1);
- __ B(hs, slow);
-
+ __ B(lo, &in_bounds);
+
+ // Out of bounds. Check the prototype chain to see if we can just return
+ // 'undefined'.
+ __ Cmp(key, Operand(Smi::FromInt(0)));
+ __ B(lt, slow); // Negative keys can't take the fast OOB path.
+ __ Bind(&check_prototypes);
+ __ Ldr(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
+ __ Bind(&check_next_prototype);
+ __ Ldr(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
+ // scratch2: current prototype
+ __ JumpIfRoot(scratch2, Heap::kNullValueRootIndex, &return_undefined);
+ __ Ldr(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
+ __ Ldr(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
+ // elements: elements of current prototype
+ // scratch2: map of current prototype
+ __ CompareInstanceType(scratch2, scratch1, JS_OBJECT_TYPE);
+ __ B(lo, slow);
+ __ Ldrb(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset));
+ __ Tbnz(scratch1, Map::kIsAccessCheckNeeded, slow);
+ __ Tbnz(scratch1, Map::kHasIndexedInterceptor, slow);
+ __ JumpIfNotRoot(elements, Heap::kEmptyFixedArrayRootIndex, slow);
+ __ B(&check_next_prototype);
+
+ __ Bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ B(&done);
+
+ __ Bind(&in_bounds);
// Fast case: Do the load.
__ Add(scratch1, elements, FixedArray::kHeaderSize - kHeapObjectTag);
__ SmiUntag(scratch2, key);
__ Ldr(scratch2, MemOperand(scratch1, scratch2, LSL, kPointerSizeLog2));
- // In case the loaded value is the_hole we have to consult GetProperty
- // to ensure the prototype chain is searched.
- __ JumpIfRoot(scratch2, Heap::kTheHoleValueRootIndex, slow);
+ // In case the loaded value is the_hole we have to check the prototype chain.
+ __ JumpIfRoot(scratch2, Heap::kTheHoleValueRootIndex, &check_prototypes);
// Move the value to the result register.
// 'result' can alias with 'receiver' or 'key' but these two must be
// preserved if we jump to 'slow'.
__ Mov(result, scratch2);
+ __ Bind(&done);
}
@@ -480,7 +494,7 @@ static void GenerateKeyedLoadWithSmiKey(MacroAssembler* masm, Register key,
__ CheckFastElements(scratch1, scratch2, &check_number_dictionary);
GenerateFastArrayLoad(masm, receiver, key, scratch3, scratch2, scratch1,
- result, NULL, slow);
+ result, slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1,
scratch1, scratch2);
__ Ret();
« no previous file with comments | « src/ic/arm/ic-arm.cc ('k') | src/ic/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698