Chromium Code Reviews| Index: src/arm/code-stubs-arm.cc |
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc |
| index 355f4e1ce9e11fc899ccef7c232dc62ee5890e99..412ba00fc8828e01ea8ad8710b57ce77f6a6fe35 100644 |
| --- a/src/arm/code-stubs-arm.cc |
| +++ b/src/arm/code-stubs-arm.cc |
| @@ -6677,7 +6677,82 @@ void DirectCEntryStub::GenerateCall(MacroAssembler* masm, |
| } |
| -MaybeObject* StringDictionaryLookupStub::GenerateNegativeLookup( |
| +void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, |
|
Kevin Millikin (Chromium)
2011/10/24 15:55:12
Cannot be wrapped with retry after GC, because it
Vyacheslav Egorov (Chromium)
2011/10/24 16:18:31
You can use create stub in the beginning of the fu
|
| + Label* miss, |
| + Label* done, |
| + Register receiver, |
| + Register properties, |
| + Handle<String> name, |
| + Register scratch0) { |
| + // If names of slots in range from 1 to kProbes - 1 for the hash value are |
| + // not equal to the name and kProbes-th slot is not used (its name is the |
| + // undefined value), it guarantees the hash table doesn't contain the |
| + // property. It's true even if some slots represent deleted properties |
| + // (their names are the null value). |
| + for (int i = 0; i < kInlinedProbes; i++) { |
| + // scratch0 points to properties hash. |
| + // Compute the masked index: (hash + i + i * i) & mask. |
| + Register index = scratch0; |
| + // Capacity is smi 2^n. |
| + __ ldr(index, FieldMemOperand(properties, kCapacityOffset)); |
| + __ sub(index, index, Operand(1)); |
| + __ and_(index, index, Operand( |
| + Smi::FromInt(name->Hash() + StringDictionary::GetProbeOffset(i)))); |
| + |
| + // Scale the index by multiplying by the entry size. |
| + ASSERT(StringDictionary::kEntrySize == 3); |
| + __ add(index, index, Operand(index, LSL, 1)); // index *= 3. |
| + |
| + Register entity_name = scratch0; |
| + // Having undefined at this place means the name is not contained. |
| + ASSERT_EQ(kSmiTagSize, 1); |
| + Register tmp = properties; |
| + __ add(tmp, properties, Operand(index, LSL, 1)); |
| + __ ldr(entity_name, FieldMemOperand(tmp, kElementsStartOffset)); |
| + |
| + ASSERT(!tmp.is(entity_name)); |
| + __ LoadRoot(tmp, Heap::kUndefinedValueRootIndex); |
| + __ cmp(entity_name, tmp); |
| + __ b(eq, done); |
| + |
| + if (i != kInlinedProbes - 1) { |
| + // Stop if found the property. |
| + __ cmp(entity_name, Operand(Handle<String>(name))); |
| + __ b(eq, miss); |
| + |
| + // Check if the entry name is not a symbol. |
| + __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); |
| + __ ldrb(entity_name, |
| + FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); |
| + __ tst(entity_name, Operand(kIsSymbolMask)); |
| + __ b(eq, miss); |
| + |
| + // Restore the properties. |
| + __ ldr(properties, |
| + FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| + } |
| + } |
| + |
| + const int spill_mask = |
| + (lr.bit() | r6.bit() | r5.bit() | r4.bit() | r3.bit() | |
| + r2.bit() | r1.bit() | r0.bit()); |
| + |
| + __ stm(db_w, sp, spill_mask); |
| + __ ldr(r0, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| + __ mov(r1, Operand(Handle<String>(name))); |
| + StringDictionaryLookupStub stub(NEGATIVE_LOOKUP); |
| + __ CallStub(&stub); |
|
Kevin Millikin (Chromium)
2011/10/24 15:55:12
This is the only change from the original function
|
| + __ tst(r0, Operand(r0)); |
| + __ ldm(ia_w, sp, spill_mask); |
| + |
| + __ b(eq, done); |
| + __ b(ne, miss); |
| +} |
| + |
| + |
| +// TODO(kmillikin): Eliminate this function when the stub cache is fully |
| +// handlified. |
| +MaybeObject* StringDictionaryLookupStub::TryGenerateNegativeLookup( |
| MacroAssembler* masm, |
| Label* miss, |
| Label* done, |