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 c154f9add4be1d8b722a7c0161b7650bac417e87..0cc48fd53ddd2c34c69c03b50e8b555660416e7a 100644 |
| --- a/src/arm/stub-cache-arm.cc |
| +++ b/src/arm/stub-cache-arm.cc |
| @@ -437,91 +437,62 @@ static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| } |
| +void BaseStoreStubCompiler::GenerateNegativeHolderLookup( |
| + MacroAssembler* masm, |
| + Handle<JSObject> holder, |
| + Register holder_reg, |
| + Handle<Name> name, |
| + Label* miss) { |
| + if (holder->IsJSGlobalObject()) { |
| + GenerateCheckPropertyCell( |
| + masm, |
|
ulan
2013/07/09 08:08:39
Nit: arguments fit in one or two lines.
Toon Verwaest
2013/07/09 08:22:26
Done.
|
| + Handle<GlobalObject>::cast(holder), |
| + name, |
| + scratch1(), |
| + miss); |
| + } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
| + GenerateDictionaryNegativeLookup( |
| + masm, miss, holder_reg, name, scratch1(), scratch2()); |
| + } |
| +} |
| + |
| + |
| // Generate StoreTransition code, value is passed in r0 register. |
| // When leaving generated code after success, the receiver_reg and name_reg |
| // may be clobbered. Upon branch to miss_label, the receiver and name |
| // registers have their original values. |
| -void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| - Handle<JSObject> object, |
| - LookupResult* lookup, |
| - Handle<Map> transition, |
| - Handle<Name> name, |
| - Register receiver_reg, |
| - Register name_reg, |
| - Register value_reg, |
| - Register scratch1, |
| - Register scratch2, |
| - Register scratch3, |
| - Label* miss_label, |
| - Label* miss_restore_name, |
| - Label* slow) { |
| +void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| + Handle<JSObject> object, |
| + LookupResult* lookup, |
| + Handle<Map> transition, |
| + Handle<Name> name, |
| + Register receiver_reg, |
| + Register storage_reg, |
| + Register value_reg, |
| + Register scratch1, |
| + Register scratch2, |
| + Register scratch3, |
| + Label* miss_label, |
|
ulan
2013/07/09 08:08:39
Can we use "miss" instead of "miss_label"?
Toon Verwaest
2013/07/09 08:22:26
I'll let this as cleanup for later, given that it'
|
| + Label* slow) { |
| // r0 : value |
| Label exit; |
| - // Check that the map of the object hasn't changed. |
| - __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, |
| - DO_SMI_CHECK); |
| - |
| - // Perform global security token check if needed. |
| - if (object->IsJSGlobalProxy()) { |
| - __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); |
| - } |
| - |
| int descriptor = transition->LastAdded(); |
| DescriptorArray* descriptors = transition->instance_descriptors(); |
| PropertyDetails details = descriptors->GetDetails(descriptor); |
| Representation representation = details.representation(); |
| ASSERT(!representation.IsNone()); |
| - // Ensure no transitions to deprecated maps are followed. |
| - __ CheckMapDeprecated(transition, scratch1, miss_label); |
| - |
| - // Check that we are allowed to write this. |
| - if (object->GetPrototype()->IsJSObject()) { |
| - JSObject* holder; |
| - // holder == object indicates that no property was found. |
| - if (lookup->holder() != *object) { |
| - holder = lookup->holder(); |
| - } else { |
| - // Find the top object. |
| - holder = *object; |
| - do { |
| - holder = JSObject::cast(holder->GetPrototype()); |
| - } while (holder->GetPrototype()->IsJSObject()); |
| - } |
| - Register holder_reg = CheckPrototypes( |
| - object, receiver_reg, Handle<JSObject>(holder), name_reg, |
| - scratch1, scratch2, name, miss_restore_name, SKIP_RECEIVER); |
| - // If no property was found, and the holder (the last object in the |
| - // prototype chain) is in slow mode, we need to do a negative lookup on the |
| - // holder. |
| - if (lookup->holder() == *object) { |
| - if (holder->IsJSGlobalObject()) { |
| - GenerateCheckPropertyCell( |
| - masm, |
| - Handle<GlobalObject>(GlobalObject::cast(holder)), |
| - name, |
| - scratch1, |
| - miss_restore_name); |
| - } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
| - GenerateDictionaryNegativeLookup( |
| - masm, miss_restore_name, holder_reg, name, scratch1, scratch2); |
| - } |
| - } |
| - } |
| - |
| - Register storage_reg = name_reg; |
| - |
| if (details.type() == CONSTANT_FUNCTION) { |
| Handle<HeapObject> constant( |
| HeapObject::cast(descriptors->GetValue(descriptor))); |
| __ LoadHeapObject(scratch1, constant); |
| __ cmp(value_reg, scratch1); |
| - __ b(ne, miss_restore_name); |
| + __ b(ne, miss_label); |
| } else if (FLAG_track_fields && representation.IsSmi()) { |
| - __ JumpIfNotSmi(value_reg, miss_restore_name); |
| + __ JumpIfNotSmi(value_reg, miss_label); |
| } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| - __ JumpIfSmi(value_reg, miss_restore_name); |
| + __ JumpIfSmi(value_reg, miss_label); |
| } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| Label do_store, heap_number; |
| __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); |
| @@ -535,7 +506,7 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| __ bind(&heap_number); |
| __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, |
| - miss_restore_name, DONT_DO_SMI_CHECK); |
| + miss_label, DONT_DO_SMI_CHECK); |
| __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
| __ bind(&do_store); |
| @@ -566,8 +537,7 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| __ mov(scratch1, Operand(transition)); |
| __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
| - // Update the write barrier for the map field and pass the now unused |
| - // name_reg as scratch register. |
| + // Update the write barrier for the map field. |
| __ RecordWriteField(receiver_reg, |
| HeapObject::kMapOffset, |
| scratch1, |
| @@ -608,15 +578,12 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| __ JumpIfSmi(value_reg, &exit); |
| // Update the write barrier for the array address. |
| - // Pass the now unused name_reg as a scratch register. |
| if (!FLAG_track_double_fields || !representation.IsDouble()) { |
| - __ mov(name_reg, value_reg); |
| - } else { |
| - ASSERT(storage_reg.is(name_reg)); |
| + __ mov(storage_reg, value_reg); |
| } |
| __ RecordWriteField(receiver_reg, |
| offset, |
| - name_reg, |
| + storage_reg, |
| scratch1, |
| kLRHasNotBeenSaved, |
| kDontSaveFPRegs, |
| @@ -640,15 +607,12 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| __ JumpIfSmi(value_reg, &exit); |
| // Update the write barrier for the array address. |
| - // Ok to clobber receiver_reg and name_reg, since we return. |
| if (!FLAG_track_double_fields || !representation.IsDouble()) { |
| - __ mov(name_reg, value_reg); |
| - } else { |
| - ASSERT(storage_reg.is(name_reg)); |
| + __ mov(storage_reg, value_reg); |
| } |
| __ RecordWriteField(scratch1, |
| offset, |
| - name_reg, |
| + storage_reg, |
| receiver_reg, |
| kLRHasNotBeenSaved, |
| kDontSaveFPRegs, |
| @@ -668,27 +632,18 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| // When leaving generated code after success, the receiver_reg and name_reg |
| // may be clobbered. Upon branch to miss_label, the receiver and name |
| // registers have their original values. |
| -void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| - Handle<JSObject> object, |
| - LookupResult* lookup, |
| - Register receiver_reg, |
| - Register name_reg, |
| - Register value_reg, |
| - Register scratch1, |
| - Register scratch2, |
| - Label* miss_label) { |
| +void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm, |
| + Handle<JSObject> object, |
| + LookupResult* lookup, |
| + Register receiver_reg, |
| + Register name_reg, |
| + Register value_reg, |
| + Register scratch1, |
| + Register scratch2, |
| + Label* miss_label) { |
| // r0 : value |
| Label exit; |
| - // Check that the map of the object hasn't changed. |
| - __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, |
| - DO_SMI_CHECK); |
| - |
| - // Perform global security token check if needed. |
| - if (object->IsJSGlobalProxy()) { |
| - __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); |
| - } |
| - |
| // Stub never generated for non-global objects that require access |
| // checks. |
| ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| @@ -1342,7 +1297,8 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| } |
| -void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, |
| +void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, |
| + Label* success, |
| Label* miss) { |
| if (!miss->is_unused()) { |
| __ b(success); |
| @@ -1352,6 +1308,18 @@ void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, |
| } |
| +void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, |
| + Label* success, |
| + Label* miss) { |
| + if (!miss->is_unused()) { |
| + __ b(success); |
| + __ bind(miss); |
|
ulan
2013/07/09 08:08:39
Using GenerateRestoreName instead these two lines
Toon Verwaest
2013/07/09 08:22:26
Done.
|
| + __ mov(this->name(), Operand(name)); |
| + TailCallBuiltin(masm(), MissBuiltin(kind())); |
| + } |
| +} |
| + |
| + |
| Register BaseLoadStubCompiler::CallbackHandlerFrontend( |
| Handle<JSObject> object, |
| Register object_reg, |
| @@ -1394,7 +1362,7 @@ Register BaseLoadStubCompiler::CallbackHandlerFrontend( |
| __ b(ne, &miss); |
| } |
| - HandlerFrontendFooter(success, &miss); |
| + HandlerFrontendFooter(name, success, &miss); |
| return reg; |
| } |
| @@ -1415,7 +1383,7 @@ void BaseLoadStubCompiler::NonexistentHandlerFrontend( |
| GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); |
| } |
| - HandlerFrontendFooter(success, &miss); |
| + HandlerFrontendFooter(name, success, &miss); |
| } |
| @@ -2824,34 +2792,30 @@ Handle<Code> CallStubCompiler::CompileCallGlobal( |
| Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| - Handle<Name> name, |
| Handle<JSObject> object, |
| Handle<JSObject> holder, |
| + Handle<Name> name, |
| Handle<ExecutableAccessorInfo> callback) { |
| - Label miss; |
| - // Check that the maps haven't changed. |
| - __ JumpIfSmi(receiver(), &miss); |
| - CheckPrototypes(object, receiver(), holder, |
| - scratch1(), scratch2(), scratch3(), name, &miss); |
| + Label success; |
| + HandlerFrontend(object, receiver(), holder, name, &success); |
| + __ bind(&success); |
| // Stub never generated for non-global objects that require access checks. |
| ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| __ push(receiver()); // receiver |
| __ mov(ip, Operand(callback)); // callback info |
| - __ Push(ip, this->name(), value()); |
| + __ push(ip); |
| + __ mov(ip, Operand(name)); |
| + __ Push(ip, value()); |
| // Do tail-call to the runtime system. |
| ExternalReference store_callback_property = |
| ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
| __ TailCallExternalReference(store_callback_property, 4, 1); |
| - // Handle store cache miss. |
| - __ bind(&miss); |
| - TailCallBuiltin(masm(), MissBuiltin(kind())); |
| - |
| // Return the generated code. |
| - return GetICCode(kind(), Code::CALLBACKS, name); |
| + return GetCode(kind(), Code::CALLBACKS, name); |
| } |
| @@ -3105,7 +3069,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| __ b(eq, &miss); |
| } |
| - HandlerFrontendFooter(&success, &miss); |
| + HandlerFrontendFooter(name, &success, &miss); |
| __ bind(&success); |
| Counters* counters = isolate()->counters(); |
| @@ -3118,7 +3082,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| } |
| -Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
| +Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( |
| MapHandleList* receiver_maps, |
| CodeHandleList* handlers, |
| Handle<Name> name, |