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 7a3c80f7b5797ef7337d12f0b7197dd6dea09711..e0986ebd7d54a4b6925cde3c0d3a19e5b6d1711f 100644 |
| --- a/src/arm/stub-cache-arm.cc |
| +++ b/src/arm/stub-cache-arm.cc |
| @@ -3084,52 +3084,59 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
| } |
| -MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { |
| +MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) { |
| // ----------- S t a t e ------------- |
| // -- lr : return address |
| // -- r0 : key |
| // -- r1 : receiver |
| // ----------------------------------- |
| - Label miss; |
| - |
| - // Check that the receiver isn't a smi. |
| - __ tst(r1, Operand(kSmiTagMask)); |
| - __ b(eq, &miss); |
| - |
| - // Check that the map matches. |
| - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| - __ cmp(r2, Operand(Handle<Map>(receiver->map()))); |
| - __ b(ne, &miss); |
| - |
| - // Check that the key is a smi. |
| - __ tst(r0, Operand(kSmiTagMask)); |
| - __ b(ne, &miss); |
| + KeyedLoadIC keyed_load_ic(isolate()); |
|
Mads Ager (chromium)
2011/05/10 13:38:06
Isn't this called from a KeyedLoadIC instance? Can
danno
2011/05/11 14:20:19
Done.
|
| + MaybeObject* maybe_stub = |
| + keyed_load_ic.ComputeMonomorphicBuiltinFastElementStub( |
|
Mads Ager (chromium)
2011/05/10 13:38:06
Are any of these stubs actually builtin? This is t
danno
2011/05/11 14:20:19
Done.
|
| + receiver_map->instance_type() == JS_ARRAY_TYPE); |
| + Code* stub; |
| + if (!maybe_stub->To(&stub)) return maybe_stub; |
| + __ DispatchMap(r1, |
| + r2, |
| + Handle<Map>(receiver_map), |
| + Handle<Code>(stub), |
| + false); |
|
Mads Ager (chromium)
2011/05/10 13:38:06
Creating an enum for this would make this call sit
danno
2011/05/11 14:20:19
Really good idea. Mind if I do that in another CL?
|
| + |
| + Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
| + __ Jump(ic, RelocInfo::CODE_TARGET); |
| - // Get the elements array. |
| - __ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset)); |
| - __ AssertFastElements(r2); |
| + // Return the generated code. |
| + return GetCode(NORMAL, NULL); |
| +} |
| - // Check that the key is within bounds. |
| - __ ldr(r3, FieldMemOperand(r2, FixedArray::kLengthOffset)); |
| - __ cmp(r0, Operand(r3)); |
| - __ b(hs, &miss); |
| - // Load the result and make sure it's not the hole. |
| - __ add(r3, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| - ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
| - __ ldr(r4, |
| - MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| - __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| - __ cmp(r4, ip); |
| - __ b(eq, &miss); |
| - __ mov(r0, r4); |
| - __ Ret(); |
| +MaybeObject* KeyedLoadStubCompiler::CompileLoadMegamorphic( |
| + MapList* receiver_maps, |
| + CodeList* handler_ics) { |
| + // ----------- S t a t e ------------- |
| + // -- lr : return address |
| + // -- r0 : key |
| + // -- r1 : receiver |
| + // ----------------------------------- |
| + Label miss; |
| + __ JumpIfSmi(r1, &miss); |
| + |
| + int receiver_count = receiver_maps->length(); |
| + for (int current = 0; current < receiver_count; ++current) { |
| + // Check map and tail call if there's a match |
| + __ DispatchMap(r1, |
| + r2, |
| + Handle<Map>(receiver_maps->at(current)), |
| + Handle<Code>(handler_ics->at(current)), |
| + true); |
| + } |
| __ bind(&miss); |
| - GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| + Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
| + __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); |
| // Return the generated code. |
| - return GetCode(NORMAL, NULL); |
| + return GetCode(NORMAL, NULL, MEGAMORPHIC); |
| } |
| @@ -3171,73 +3178,64 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
| } |
| -MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( |
| - JSObject* receiver) { |
| +MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( |
| + Map* receiver_map) { |
| // ----------- S t a t e ------------- |
| // -- r0 : value |
| // -- r1 : key |
| // -- r2 : receiver |
| // -- lr : return address |
| // -- r3 : scratch |
| - // -- r4 : scratch (elements) |
| // ----------------------------------- |
| - Label miss; |
| - |
| - Register value_reg = r0; |
| - Register key_reg = r1; |
| - Register receiver_reg = r2; |
| - Register scratch = r3; |
| - Register elements_reg = r4; |
| - |
| - // Check that the receiver isn't a smi. |
| - __ tst(receiver_reg, Operand(kSmiTagMask)); |
| - __ b(eq, &miss); |
| - |
| - // Check that the map matches. |
| - __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
| - __ cmp(scratch, Operand(Handle<Map>(receiver->map()))); |
| - __ b(ne, &miss); |
| + KeyedStoreIC keyed_store_ic(isolate()); |
|
Mads Ager (chromium)
2011/05/10 13:38:06
I would prefer passing in the actual stub here and
danno
2011/05/11 14:20:19
Done.
|
| + MaybeObject* maybe_stub = |
| + keyed_store_ic.ComputeMonomorphicBuiltinFastElementStub( |
| + receiver_map->instance_type() == JS_ARRAY_TYPE); |
| + Code* stub; |
| + if (!maybe_stub->To(&stub)) return maybe_stub; |
| + __ DispatchMap(r2, |
| + r3, |
| + Handle<Map>(receiver_map), |
| + Handle<Code>(stub), |
| + false); |
| + |
| + Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| + __ Jump(ic, RelocInfo::CODE_TARGET); |
| - // Check that the key is a smi. |
| - __ tst(key_reg, Operand(kSmiTagMask)); |
| - __ b(ne, &miss); |
| + // Return the generated code. |
| + return GetCode(NORMAL, NULL); |
| +} |
| - // Get the elements array and make sure it is a fast element array, not 'cow'. |
| - __ ldr(elements_reg, |
| - FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
| - __ ldr(scratch, FieldMemOperand(elements_reg, HeapObject::kMapOffset)); |
| - __ cmp(scratch, Operand(Handle<Map>(factory()->fixed_array_map()))); |
| - __ b(ne, &miss); |
| - // Check that the key is within bounds. |
| - if (receiver->IsJSArray()) { |
| - __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
| - } else { |
| - __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
| +MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic( |
| + MapList* receiver_maps, |
| + CodeList* handler_ics) { |
| + // ----------- S t a t e ------------- |
| + // -- r0 : value |
| + // -- r1 : key |
| + // -- r2 : receiver |
| + // -- lr : return address |
| + // -- r3 : scratch |
| + // ----------------------------------- |
| + Label miss; |
| + __ JumpIfSmi(r2, &miss); |
| + |
| + int receiver_count = receiver_maps->length(); |
| + for (int current = 0; current < receiver_count; ++current) { |
| + // Check map and tail call if there's a match |
| + __ DispatchMap(r2, |
| + r3, |
| + Handle<Map>(receiver_maps->at(current)), |
| + Handle<Code>(handler_ics->at(current)), |
| + true); |
| } |
| - // Compare smis. |
| - __ cmp(key_reg, scratch); |
| - __ b(hs, &miss); |
| - |
| - __ add(scratch, |
| - elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| - ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
| - __ str(value_reg, |
| - MemOperand(scratch, key_reg, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| - __ RecordWrite(scratch, |
| - Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize), |
| - receiver_reg , elements_reg); |
| - |
| - // value_reg (r0) is preserved. |
| - // Done. |
| - __ Ret(); |
| __ bind(&miss); |
| - Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); |
| - __ Jump(ic, RelocInfo::CODE_TARGET); |
| + Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| + __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); |
| // Return the generated code. |
| - return GetCode(NORMAL, NULL); |
| + return GetCode(NORMAL, NULL, MEGAMORPHIC); |
| } |
| @@ -3385,6 +3383,62 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
| } |
| +MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad( |
| + JSObject*receiver, ExternalArrayType array_type) { |
| + // ----------- S t a t e ------------- |
| + // -- lr : return address |
| + // -- r0 : key |
| + // -- r1 : receiver |
| + // ----------------------------------- |
| + KeyedLoadIC load_ic(isolate()); |
| + MaybeObject* maybe_stub = |
| + load_ic.ComputeMonomorphicBuiltinExternalArrayStub(array_type); |
| + Code* stub; |
| + if (!maybe_stub->To(&stub)) return maybe_stub; |
| + __ DispatchMap(r1, |
| + r2, |
| + Handle<Map>(receiver->map()), |
| + Handle<Code>(stub), |
| + false); |
| + |
| + Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
| + __ Jump(ic, RelocInfo::CODE_TARGET); |
| + |
| + // Return the generated code. |
| + return GetCode(); |
| +} |
| + |
| + |
| +MaybeObject* ExternalArrayStoreStubCompiler::CompileStore( |
| + JSObject* receiver, ExternalArrayType array_type) { |
| + // ----------- S t a t e ------------- |
| + // -- r0 : value |
| + // -- r1 : name |
| + // -- r2 : receiver |
| + // -- lr : return address |
| + // ----------------------------------- |
| + KeyedStoreIC store_ic(isolate()); |
| + MaybeObject* maybe_stub = |
| + store_ic.ComputeMonomorphicBuiltinExternalArrayStub(array_type); |
| + Code* stub; |
| + if (!maybe_stub->To(&stub)) return maybe_stub; |
| + __ DispatchMap(r2, |
| + r3, |
| + Handle<Map>(receiver->map()), |
| + Handle<Code>(stub), |
| + false); |
| + |
| + Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
| + __ Jump(ic, RelocInfo::CODE_TARGET); |
| + |
| + return GetCode(); |
| +} |
| + |
| + |
| +#undef __ |
| +#define __ ACCESS_MASM(masm) |
| + |
| + |
| static bool IsElementTypeSigned(ExternalArrayType array_type) { |
| switch (array_type) { |
| case kExternalByteArray: |
| @@ -3404,30 +3458,21 @@ static bool IsElementTypeSigned(ExternalArrayType array_type) { |
| } |
| -MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
| - JSObject* receiver_object, |
| - ExternalArrayType array_type, |
| - Code::Flags flags) { |
| +void KeyedLoadStubCompiler::GenerateLoadExternalArray( |
| + MacroAssembler* masm, |
| + ExternalArrayType array_type) { |
| // ---------- S t a t e -------------- |
| // -- lr : return address |
| // -- r0 : key |
| // -- r1 : receiver |
| // ----------------------------------- |
| - Label slow, failed_allocation; |
| + Label miss_force_generic, slow, failed_allocation; |
| Register key = r0; |
| Register receiver = r1; |
| - // Check that the object isn't a smi |
| - __ JumpIfSmi(receiver, &slow); |
| - |
| // Check that the key is a smi. |
| - __ JumpIfNotSmi(key, &slow); |
| - |
| - // Make sure that we've got the right map. |
| - __ ldr(r2, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| - __ cmp(r2, Operand(Handle<Map>(receiver_object->map()))); |
| - __ b(ne, &slow); |
| + __ JumpIfNotSmi(key, &miss_force_generic); |
| __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
| // r3: elements array |
| @@ -3436,7 +3481,7 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
| __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset)); |
| __ cmp(ip, Operand(key, ASR, kSmiTagSize)); |
| // Unsigned comparison catches both negative and too-large values. |
| - __ b(lo, &slow); |
| + __ b(lo, &miss_force_generic); |
| __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); |
| // r3: base pointer of external storage |
| @@ -3573,12 +3618,12 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
| __ bind(&box_int_0); |
| // Integer does not have leading zeros. |
| - GenerateUInt2Double(masm(), hiword, loword, r4, 0); |
| + GenerateUInt2Double(masm, hiword, loword, r4, 0); |
| __ b(&done); |
| __ bind(&box_int_1); |
| // Integer has one leading zero. |
| - GenerateUInt2Double(masm(), hiword, loword, r4, 1); |
| + GenerateUInt2Double(masm, hiword, loword, r4, 1); |
| __ bind(&done); |
| @@ -3700,7 +3745,7 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
| // Slow case, key and receiver still in r0 and r1. |
| __ bind(&slow); |
| __ IncrementCounter( |
| - masm()->isolate()->counters()->keyed_load_external_array_slow(), |
| + masm->isolate()->counters()->keyed_load_external_array_slow(), |
| 1, r2, r3); |
| // ---------- S t a t e -------------- |
| @@ -3713,21 +3758,23 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( |
| __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
| - return GetCode(flags); |
| + __ bind(&miss_force_generic); |
| + Code* stub = masm->isolate()->builtins()->builtin( |
| + Builtins::kKeyedLoadIC_MissForceGeneric); |
| + __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); |
| } |
| -MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( |
| - JSObject* receiver_object, |
| - ExternalArrayType array_type, |
| - Code::Flags flags) { |
| +void KeyedStoreStubCompiler::GenerateStoreExternalArray( |
| + MacroAssembler* masm, |
| + ExternalArrayType array_type) { |
| // ---------- S t a t e -------------- |
| // -- r0 : value |
| // -- r1 : key |
| // -- r2 : receiver |
| // -- lr : return address |
| // ----------------------------------- |
| - Label slow, check_heap_number; |
| + Label slow, check_heap_number, miss_force_generic; |
| // Register usage. |
| Register value = r0; |
| @@ -3735,25 +3782,17 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( |
| Register receiver = r2; |
| // r3 mostly holds the elements array or the destination external array. |
| - // Check that the object isn't a smi. |
| - __ JumpIfSmi(receiver, &slow); |
| - |
| - // Make sure that we've got the right map. |
| - __ ldr(r3, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| - __ cmp(r3, Operand(Handle<Map>(receiver_object->map()))); |
| - __ b(ne, &slow); |
| - |
| __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
|
Mads Ager (chromium)
2011/05/10 13:38:06
Have you always checked that the receiver is not a
danno
2011/05/11 14:20:19
Yes, this stub is always tail-called by other stub
|
| // Check that the key is a smi. |
| - __ JumpIfNotSmi(key, &slow); |
| + __ JumpIfNotSmi(key, &miss_force_generic); |
| // Check that the index is in range |
| __ SmiUntag(r4, key); |
| __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset)); |
| __ cmp(r4, ip); |
| // Unsigned comparison catches both negative and too-large values. |
| - __ b(hs, &slow); |
| + __ b(hs, &miss_force_generic); |
| // Handle both smis and HeapNumbers in the fast path. Go to the |
| // runtime for all other kinds of values. |
| @@ -3791,7 +3830,7 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( |
| break; |
| case kExternalFloatArray: |
| // Perform int-to-float conversion and store to memory. |
| - StoreIntAsFloat(masm(), r3, r4, r5, r6, r7, r9); |
| + StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); |
| break; |
| case kExternalDoubleArray: |
| __ add(r3, r3, Operand(r4, LSL, 3)); |
| @@ -3803,7 +3842,7 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( |
| destination = FloatingPointHelper::kCoreRegisters; |
| } |
| FloatingPointHelper::ConvertIntToDouble( |
| - masm(), r5, destination, |
| + masm, r5, destination, |
| d0, r6, r7, // These are: double_dst, dst1, dst2. |
| r4, s2); // These are: scratch2, single_scratch. |
| if (destination == FloatingPointHelper::kVFPRegisters) { |
| @@ -4030,28 +4069,133 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( |
| } |
| } |
| - // Slow case: call runtime. |
| + // Slow case, key and receiver still in r0 and r1. |
| __ bind(&slow); |
| + __ IncrementCounter( |
| + masm->isolate()->counters()->keyed_load_external_array_slow(), |
| + 1, r2, r3); |
| + |
| + // ---------- S t a t e -------------- |
| + // -- lr : return address |
| + // -- r0 : key |
| + // -- r1 : receiver |
| + // ----------------------------------- |
| + Handle<Code> slow_ic = |
| + masm->isolate()->builtins()->KeyedStoreIC_Slow(); |
| + __ Jump(slow_ic, RelocInfo::CODE_TARGET); |
| + |
| + // Miss case, call the runtime. |
| + __ bind(&miss_force_generic); |
| - // Entry registers are intact. |
| // ---------- S t a t e -------------- |
| - // -- r0 : value |
| - // -- r1 : key |
| - // -- r2 : receiver |
| // -- lr : return address |
| + // -- r0 : key |
| + // -- r1 : receiver |
| // ----------------------------------- |
| - // Push receiver, key and value for runtime call. |
| - __ Push(r2, r1, r0); |
| + Handle<Code> miss_ic = |
| + masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| + __ Jump(miss_ic, RelocInfo::CODE_TARGET); |
| +} |
| + |
| - __ mov(r1, Operand(Smi::FromInt(NONE))); // PropertyAttributes |
| - __ mov(r0, Operand(Smi::FromInt( |
| - Code::ExtractExtraICStateFromFlags(flags) & kStrictMode))); |
| - __ Push(r1, r0); |
| +void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { |
| + // ----------- S t a t e ------------- |
| + // -- lr : return address |
| + // -- r0 : key |
| + // -- r1 : receiver |
| + // ----------------------------------- |
| + Label miss_force_generic; |
| + |
| + // Check that the key is a smi. |
| + __ tst(r0, Operand(kSmiTagMask)); |
| + __ b(ne, &miss_force_generic); |
| + |
| + // Get the elements array. |
| + __ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset)); |
| + __ AssertFastElements(r2); |
| + |
| + // Check that the key is within bounds. |
| + __ ldr(r3, FieldMemOperand(r2, FixedArray::kLengthOffset)); |
| + __ cmp(r0, Operand(r3)); |
| + __ b(hs, &miss_force_generic); |
| + |
| + // Load the result and make sure it's not the hole. |
| + __ add(r3, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| + ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
| + __ ldr(r4, |
| + MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| + __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| + __ cmp(r4, ip); |
| + __ b(eq, &miss_force_generic); |
| + __ mov(r0, r4); |
| + __ Ret(); |
| + |
| + __ bind(&miss_force_generic); |
| + Code* stub = masm->isolate()->builtins()->builtin( |
| + Builtins::kKeyedLoadIC_MissForceGeneric); |
| + __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); |
| +} |
| + |
| + |
| +void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm, |
| + bool is_js_array) { |
| + // ----------- S t a t e ------------- |
| + // -- r0 : value |
| + // -- r1 : key |
| + // -- r2 : receiver |
| + // -- lr : return address |
| + // -- r3 : scratch |
| + // -- r4 : scratch (elements) |
| + // ----------------------------------- |
| + Label miss_force_generic; |
| + |
| + Register value_reg = r0; |
| + Register key_reg = r1; |
| + Register receiver_reg = r2; |
| + Register scratch = r3; |
| + Register elements_reg = r4; |
| + |
| + // Check that the key is a smi. |
| + __ tst(key_reg, Operand(kSmiTagMask)); |
| + __ b(ne, &miss_force_generic); |
| + |
| + // Get the elements array and make sure it is a fast element array, not 'cow'. |
| + __ ldr(elements_reg, |
| + FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
| + __ ldr(scratch, FieldMemOperand(elements_reg, HeapObject::kMapOffset)); |
| + Handle<Map> map = |
| + Handle<Map>(masm->isolate()->factory()->fixed_array_map()); |
| + __ cmp(scratch, Operand(map)); |
| + __ b(ne, &miss_force_generic); |
| + |
| + // Check that the key is within bounds. |
| + if (is_js_array) { |
| + __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
| + } else { |
| + __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
| + } |
| + // Compare smis. |
| + __ cmp(key_reg, scratch); |
| + __ b(hs, &miss_force_generic); |
| + |
| + __ add(scratch, |
| + elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| + ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
| + __ str(value_reg, |
| + MemOperand(scratch, key_reg, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| + __ RecordWrite(scratch, |
| + Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize), |
| + receiver_reg , elements_reg); |
| - __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
| + // value_reg (r0) is preserved. |
| + // Done. |
| + __ Ret(); |
| - return GetCode(flags); |
| + __ bind(&miss_force_generic); |
| + Handle<Code> ic = |
| + masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| + __ Jump(ic, RelocInfo::CODE_TARGET); |
| } |