Chromium Code Reviews| Index: src/arm/stub-cache-arm.cc |
| diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc |
| index 3350c56c163762f4464dabd0e153685116b6e973..0a822fd202bae4f46de53162e8f6aff4edd48eaf 100644 |
| --- a/src/arm/stub-cache-arm.cc |
| +++ b/src/arm/stub-cache-arm.cc |
| @@ -423,7 +423,7 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, |
| // registers have their original values. |
| void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| Handle<JSObject> object, |
| - int index, |
| + LookupResult* lookup, |
| Handle<Map> transition, |
| Handle<Name> name, |
| Register receiver_reg, |
| @@ -436,16 +436,6 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| // r0 : value |
| Label exit; |
| - LookupResult lookup(masm->isolate()); |
| - object->Lookup(*name, &lookup); |
| - if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { |
| - // In sloppy mode, we could just return the value and be done. However, we |
| - // might be in strict mode, where we have to throw. Since we cannot tell, |
| - // go into slow case unconditionally. |
| - __ jmp(miss_label); |
| - return; |
| - } |
| - |
| // Check that the map of the object hasn't changed. |
| CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS |
| : REQUIRE_EXACT_MAP; |
| @@ -460,8 +450,9 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| // Check that we are allowed to write this. |
| if (!transition.is_null() && object->GetPrototype()->IsJSObject()) { |
| JSObject* holder; |
| - if (lookup.IsFound()) { |
| - holder = lookup.holder(); |
| + // holder == object indicates that no property was found. |
| + if (lookup->holder() != *object) { |
| + holder = lookup->holder(); |
| } else { |
| // Find the top object. |
| holder = *object; |
| @@ -469,8 +460,19 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| holder = JSObject::cast(holder->GetPrototype()); |
| } while (holder->GetPrototype()->IsJSObject()); |
| } |
| - CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg, |
| - scratch1, scratch2, name, miss_restore_name); |
| + Register holder_reg = CheckPrototypes( |
| + object, receiver_reg, Handle<JSObject>(holder), name_reg, |
| + scratch1, scratch2, name, miss_restore_name); |
| + // If no property was found, and the holder (the last object in the |
| + // prototype chain) is is slow mode, we need to do a negative lookup on the |
|
rossberg
2013/03/25 12:08:09
"is is" -> "is in" (same for other back-ends)
Toon Verwaest
2013/03/25 12:36:21
Done.
|
| + // holder. |
| + if (lookup->holder() == *object && |
| + !holder->HasFastProperties() && |
| + !holder->IsJSGlobalProxy() && |
| + !holder->IsJSGlobalObject()) { |
| + GenerateDictionaryNegativeLookup( |
| + masm, miss_restore_name, holder_reg, name, scratch1, scratch2); |
| + } |
| } |
| // Stub never generated for non-global objects that require access |
| @@ -492,6 +494,7 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| return; |
| } |
| + int index; |
| if (!transition.is_null()) { |
| // Update the map of the object. |
| __ mov(scratch1, Operand(transition)); |
| @@ -507,6 +510,10 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| kDontSaveFPRegs, |
| OMIT_REMEMBERED_SET, |
| OMIT_SMI_CHECK); |
| + index = transition->instance_descriptors()->GetFieldIndex( |
| + transition->LastAdded()); |
| + } else { |
| + index = lookup->GetFieldIndex().field_index(); |
| } |
| // Adjust for the number of properties stored in the object. Even in the |