Index: src/mips/macro-assembler-mips.cc |
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc |
index d99fbdcaa4f426f4e140ca8bb3613d0c325c3f34..7ded49499957b010b996229de161b0268dd45192 100644 |
--- a/src/mips/macro-assembler-mips.cc |
+++ b/src/mips/macro-assembler-mips.cc |
@@ -5313,51 +5313,44 @@ void MacroAssembler::LoadInstanceDescriptors(Register map, |
} |
+void MacroAssembler::EnumLength(Register dst, Register map) { |
+ STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); |
+ lw(dst, FieldMemOperand(map, Map::kBitField3Offset)); |
+ And(dst, dst, Operand(Smi::FromInt(Map::EnumLengthBits::kMask))); |
+} |
+ |
+ |
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 = t2; |
LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); |
- mov(a1, a0); |
- bind(&next); |
+ Label next, start; |
+ mov(a2, a0); |
- // Check that there are no elements. Register a1 contains the |
- // current JS object we've reached through the prototype chain. |
- lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset)); |
- Branch(call_runtime, ne, a2, Operand(empty_fixed_array_value)); |
- |
- // Check that instance descriptors are not empty so that we can |
- // check for an enum cache. Leave the map in a2 for the subsequent |
- // prototype load. |
- lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); |
- lw(a3, FieldMemOperand(a2, Map::kTransitionsOrBackPointerOffset)); |
+ // Check if the enum length field is properly initialized, indicating that |
+ // there is an enum cache. |
+ lw(a1, FieldMemOperand(a2, HeapObject::kMapOffset)); |
- CheckMap(a3, |
- t3, |
- isolate()->factory()->fixed_array_map(), |
- call_runtime, |
- DONT_DO_SMI_CHECK); |
+ EnumLength(a3, a1); |
+ Branch(call_runtime, eq, a3, Operand(Smi::FromInt(Map::kInvalidEnumCache))); |
- LoadRoot(t3, Heap::kEmptyDescriptorArrayRootIndex); |
- lw(a3, FieldMemOperand(a3, TransitionArray::kDescriptorsOffset)); |
- Branch(call_runtime, eq, a3, Operand(t3)); |
+ jmp(&start); |
- // Check that there is an enum cache in the non-empty instance |
- // descriptors (a3). This is the case if the next enumeration |
- // index field does not contain a smi. |
- lw(a3, FieldMemOperand(a3, DescriptorArray::kEnumCacheOffset)); |
- JumpIfSmi(a3, call_runtime); |
+ bind(&next); |
+ lw(a1, FieldMemOperand(a2, HeapObject::kMapOffset)); |
// For all objects but the receiver, check that the cache is empty. |
- Label check_prototype; |
- Branch(&check_prototype, eq, a1, Operand(a0)); |
- lw(a3, FieldMemOperand(a3, DescriptorArray::kEnumCacheBridgeCacheOffset)); |
- Branch(call_runtime, ne, a3, Operand(empty_fixed_array_value)); |
- |
- // Load the prototype from the map and loop if non-null. |
- bind(&check_prototype); |
- lw(a1, FieldMemOperand(a2, Map::kPrototypeOffset)); |
- Branch(&next, ne, a1, Operand(null_value)); |
+ EnumLength(a3, a1); |
+ Branch(call_runtime, ne, a3, Operand(Smi::FromInt(0))); |
+ |
+ bind(&start); |
+ |
+ // Check that there are no elements. Register r2 contains the current JS |
+ // object we've reached through the prototype chain. |
+ lw(a2, FieldMemOperand(a2, JSObject::kElementsOffset)); |
+ Branch(call_runtime, ne, a2, Operand(empty_fixed_array_value)); |
+ |
+ lw(a2, FieldMemOperand(a1, Map::kPrototypeOffset)); |
+ Branch(&next, ne, a2, Operand(null_value)); |
} |