| Index: src/arm/macro-assembler-arm.cc
|
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
|
| index a1a736e8413c4cce9d9ad2bb430915e6343de453..45dd80ffb738b887e126bf70cc1c748d68235602 100644
|
| --- a/src/arm/macro-assembler-arm.cc
|
| +++ b/src/arm/macro-assembler-arm.cc
|
| @@ -3664,6 +3664,52 @@ void MacroAssembler::LoadInstanceDescriptors(Register map,
|
| }
|
|
|
|
|
| +void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
|
| + Label next;
|
| + // Preload a couple of values used in the loop.
|
| + Register empty_fixed_array_value = r6;
|
| + LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
|
| + Register empty_descriptor_array_value = r7;
|
| + LoadRoot(empty_descriptor_array_value,
|
| + Heap::kEmptyDescriptorArrayRootIndex);
|
| + mov(r1, r0);
|
| + bind(&next);
|
| +
|
| + // Check that there are no elements. Register r1 contains the
|
| + // current JS object we've reached through the prototype chain.
|
| + ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset));
|
| + cmp(r2, empty_fixed_array_value);
|
| + b(ne, call_runtime);
|
| +
|
| + // Check that instance descriptors are not empty so that we can
|
| + // check for an enum cache. Leave the map in r2 for the subsequent
|
| + // prototype load.
|
| + ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
|
| + ldr(r3, FieldMemOperand(r2, Map::kInstanceDescriptorsOrBitField3Offset));
|
| + JumpIfSmi(r3, call_runtime);
|
| +
|
| + // Check that there is an enum cache in the non-empty instance
|
| + // descriptors (r3). This is the case if the next enumeration
|
| + // index field does not contain a smi.
|
| + ldr(r3, FieldMemOperand(r3, DescriptorArray::kEnumerationIndexOffset));
|
| + JumpIfSmi(r3, call_runtime);
|
| +
|
| + // For all objects but the receiver, check that the cache is empty.
|
| + Label check_prototype;
|
| + cmp(r1, r0);
|
| + b(eq, &check_prototype);
|
| + ldr(r3, FieldMemOperand(r3, DescriptorArray::kEnumCacheBridgeCacheOffset));
|
| + cmp(r3, empty_fixed_array_value);
|
| + b(ne, call_runtime);
|
| +
|
| + // Load the prototype from the map and loop if non-null.
|
| + bind(&check_prototype);
|
| + ldr(r1, FieldMemOperand(r2, Map::kPrototypeOffset));
|
| + cmp(r1, null_value);
|
| + b(ne, &next);
|
| +}
|
| +
|
| +
|
| bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
|
| if (r1.is(r2)) return true;
|
| if (r1.is(r3)) return true;
|
|
|