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

Unified Diff: src/ic/x64/ic-x64.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/ia32/ic-ia32.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/x64/ic-x64.cc
diff --git a/src/ic/x64/ic-x64.cc b/src/ic/x64/ic-x64.cc
index 2709a8571884fb73eadb9b746e6d09cb81cb599d..b2b0f8d20064334978a3db790475842d3a926541 100644
--- a/src/ic/x64/ic-x64.cc
+++ b/src/ic/x64/ic-x64.cc
@@ -168,11 +168,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 scratch, Register result,
- Label* not_fast_array, Label* out_of_range) {
+ Label* slow) {
// Register use:
//
// receiver - holds the receiver on entry.
@@ -181,8 +180,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
@@ -190,32 +187,58 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
//
// Scratch registers:
//
- // scratch - used to hold elements of the receiver and the loaded value.
+ // elements - holds the elements of the receiver and its prototypes.
+ //
+ // scratch - used to hold maps, prototypes, and the loaded value.
+ Label check_prototypes, check_next_prototype;
+ Label done, in_bounds, return_undefined;
__ movp(elements, FieldOperand(receiver, JSObject::kElementsOffset));
- if (not_fast_array != NULL) {
- // Check that the object is in fast mode and writable.
- __ CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
- Heap::kFixedArrayMapRootIndex);
- __ j(not_equal, not_fast_array);
- } else {
- __ AssertFastElements(elements);
- }
+ __ AssertFastElements(elements);
// Check that the key (index) is within bounds.
__ SmiCompare(key, FieldOperand(elements, FixedArray::kLengthOffset));
// Unsigned comparison rejects negative indices.
- __ j(above_equal, out_of_range);
+ __ j(below, &in_bounds);
+
+ // Out-of-bounds. Check the prototype chain to see if we can just return
+ // 'undefined'.
+ __ SmiCompare(key, Smi::FromInt(0));
+ __ j(less, slow); // Negative keys can't take the fast OOB path.
+ __ bind(&check_prototypes);
+ __ movp(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
+ __ bind(&check_next_prototype);
+ __ movp(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
+ // scratch: current prototype
+ __ CompareRoot(scratch, Heap::kNullValueRootIndex);
+ __ j(equal, &return_undefined);
+ __ movp(elements, FieldOperand(scratch, JSObject::kElementsOffset));
+ __ movp(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
+ // elements: elements of current prototype
+ // scratch: map of current prototype
+ __ CmpInstanceType(scratch, JS_OBJECT_TYPE);
+ __ j(below, slow);
+ __ testb(FieldOperand(scratch, Map::kBitFieldOffset),
+ Immediate((1 << Map::kIsAccessCheckNeeded) |
+ (1 << Map::kHasIndexedInterceptor)));
+ __ j(not_zero, slow);
+ __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
+ __ j(not_equal, slow);
+ __ jmp(&check_next_prototype);
+
+ __ bind(&return_undefined);
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+ __ jmp(&done);
+
+ __ bind(&in_bounds);
// Fast case: Do the load.
SmiIndex index = masm->SmiToIndex(scratch, key, kPointerSizeLog2);
__ movp(scratch, FieldOperand(elements, index.reg, index.scale,
FixedArray::kHeaderSize));
__ CompareRoot(scratch, Heap::kTheHoleValueRootIndex);
- // In case the loaded value is the_hole we have to consult GetProperty
- // to ensure the prototype chain is searched.
- __ j(equal, out_of_range);
- if (!result.is(scratch)) {
- __ movp(result, scratch);
- }
+ // In case the loaded value is the_hole we have to check the prototype chain.
+ __ j(equal, &check_prototypes);
+ __ Move(result, scratch);
+ __ bind(&done);
}
@@ -273,7 +296,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(rax, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, rax, rbx, rax, NULL, &slow);
+ GenerateFastArrayLoad(masm, receiver, key, rax, rbx, rax, &slow);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
__ ret(0);
« no previous file with comments | « src/ic/ia32/ic-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698