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

Unified Diff: src/ic/ia32/ic-ia32.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/arm64/ic-arm64.cc ('k') | src/ic/x64/ic-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/ia32/ic-ia32.cc
diff --git a/src/ic/ia32/ic-ia32.cc b/src/ic/ia32/ic-ia32.cc
index 9822f26ced7efbc2f994653d52e5a5f8aea29e3e..bdaa1f4a995063868117141f898e047722a668cb 100644
--- a/src/ic/ia32/ic-ia32.cc
+++ b/src/ic/ia32/ic-ia32.cc
@@ -169,40 +169,65 @@ 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 scratch,
- Register result, Label* not_fast_array,
- Label* out_of_range) {
+ Register scratch2, Register result,
+ Label* slow) {
// Register use:
// receiver - holds the receiver and is unchanged.
// key - holds the key and is unchanged (must be a smi).
// Scratch registers:
// scratch - used to hold elements of the receiver and the loaded value.
+ // scratch2 - holds maps and prototypes during prototype chain check.
// result - holds the result on exit if the load succeeds and
// we fall through.
+ Label check_prototypes, check_next_prototype;
+ Label done, in_bounds, return_undefined;
__ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset));
- if (not_fast_array != NULL) {
- // Check that the object is in fast mode and writable.
- __ CheckMap(scratch, masm->isolate()->factory()->fixed_array_map(),
- not_fast_array, DONT_DO_SMI_CHECK);
- } else {
- __ AssertFastElements(scratch);
- }
+ __ AssertFastElements(scratch);
+
// Check that the key (index) is within bounds.
__ cmp(key, FieldOperand(scratch, FixedArray::kLengthOffset));
- __ 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'.
+ __ cmp(key, 0);
+ __ j(less, slow); // Negative keys can't take the fast OOB path.
+ __ bind(&check_prototypes);
+ __ mov(scratch2, FieldOperand(receiver, HeapObject::kMapOffset));
+ __ bind(&check_next_prototype);
+ __ mov(scratch2, FieldOperand(scratch2, Map::kPrototypeOffset));
+ // scratch2: current prototype
+ __ cmp(scratch2, masm->isolate()->factory()->null_value());
+ __ j(equal, &return_undefined);
+ __ mov(scratch, FieldOperand(scratch2, JSObject::kElementsOffset));
+ __ mov(scratch2, FieldOperand(scratch2, HeapObject::kMapOffset));
+ // scratch: elements of current prototype
+ // scratch2: map of current prototype
+ __ CmpInstanceType(scratch2, JS_OBJECT_TYPE);
+ __ j(below, slow);
+ __ test_b(
+ FieldOperand(scratch2, Map::kBitFieldOffset),
+ (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor));
+ __ j(not_zero, slow);
+ __ cmp(scratch, masm->isolate()->factory()->empty_fixed_array());
+ __ j(not_equal, slow);
+ __ jmp(&check_next_prototype);
+
+ __ bind(&return_undefined);
+ __ mov(result, masm->isolate()->factory()->undefined_value());
+ __ jmp(&done);
+
+ __ bind(&in_bounds);
// Fast case: Do the load.
STATIC_ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0));
__ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize));
__ cmp(scratch, Immediate(masm->isolate()->factory()->the_hole_value()));
- // 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)) {
- __ mov(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);
}
@@ -327,7 +352,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// Check the receiver's map to see if it has fast elements.
__ CheckFastElements(eax, &check_number_dictionary);
- GenerateFastArrayLoad(masm, receiver, key, eax, eax, NULL, &slow);
+ GenerateFastArrayLoad(masm, receiver, key, eax, ebx, eax, &slow);
Isolate* isolate = masm->isolate();
Counters* counters = isolate->counters();
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
« no previous file with comments | « src/ic/arm64/ic-arm64.cc ('k') | src/ic/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698