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

Unified Diff: src/ic/arm/ic-arm.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 | « no previous file | src/ic/arm64/ic-arm64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/arm/ic-arm.cc
diff --git a/src/ic/arm/ic-arm.cc b/src/ic/arm/ic-arm.cc
index 70a5d84e93384e47729d71ea8c68286e49f47f9e..4ca8aa72e7a571a2b1c85372e5064845a7882adf 100644
--- a/src/ic/arm/ic-arm.cc
+++ b/src/ic/arm/ic-arm.cc
@@ -158,12 +158,10 @@ 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.
static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
Register key, Register elements,
Register scratch1, Register scratch2,
- Register result, Label* not_fast_array,
- Label* out_of_range) {
+ Register result, Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
@@ -172,8 +170,6 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
// key - holds the smi key on entry.
// Unchanged unless 'result' is the same register.
//
- // elements - holds the elements of the receiver on exit.
- //
// 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
@@ -181,34 +177,59 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
//
// Scratch registers:
//
- // scratch1 - used to hold elements map and elements length.
- // Holds the elements map if not_fast_array branch is taken.
+ // elements - holds the elements of the receiver and its prototypes.
+ //
+ // scratch1 - used to hold elements length, bit fields, base addresses.
//
- // scratch2 - used to hold the loaded value.
+ // scratch2 - used to hold maps, prototypes, and the loaded value.
+ Label check_prototypes, check_next_prototype;
+ Label done, in_bounds, return_undefined;
__ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- if (not_fast_array != NULL) {
- // Check that the object is in fast mode and writable.
- __ ldr(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset));
- __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
- __ cmp(scratch1, ip);
- __ b(ne, not_fast_array);
- } else {
- __ AssertFastElements(elements);
- }
+ __ AssertFastElements(elements);
+
// Check that the key (index) is within bounds.
__ ldr(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
__ cmp(key, Operand(scratch1));
- __ b(hs, out_of_range);
+ __ b(lo, &in_bounds);
+ // Out-of-bounds. Check the prototype chain to see if we can just return
+ // 'undefined'.
+ __ cmp(key, Operand(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
+ __ CompareRoot(scratch2, Heap::kNullValueRootIndex);
+ __ b(eq, &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));
+ __ tst(scratch1, Operand((1 << Map::kIsAccessCheckNeeded) |
+ (1 << Map::kHasIndexedInterceptor)));
+ __ b(ne, slow);
+ __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
+ __ b(ne, slow);
+ __ jmp(&check_next_prototype);
+
+ __ bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ jmp(&done);
+
+ __ bind(&in_bounds);
// Fast case: Do the load.
__ add(scratch1, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ ldr(scratch2, MemOperand::PointerAddressFromSmiKey(scratch1, key));
- __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
- __ cmp(scratch2, ip);
- // In case the loaded value is the_hole we have to consult GetProperty
- // to ensure the prototype chain is searched.
- __ b(eq, out_of_range);
+ __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex);
+ // In case the loaded value is the_hole we have to check the prototype chain.
+ __ b(eq, &check_prototypes);
__ mov(result, scratch2);
+ __ bind(&done);
}
@@ -468,7 +489,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(r0, r3, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, NULL, &slow);
+ GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r4, r3);
__ Ret();
« no previous file with comments | « no previous file | src/ic/arm64/ic-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698