Chromium Code Reviews| Index: src/ia32/stub-cache-ia32.cc |
| diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc |
| index cb3c68ea8eeeacb2d105ee62a800ac5480fdf3d9..24727c005d63b4ae3676a267d9e0bd5ec7f99266 100644 |
| --- a/src/ia32/stub-cache-ia32.cc |
| +++ b/src/ia32/stub-cache-ia32.cc |
| @@ -772,6 +772,31 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| __ CheckAccessGlobalProxy(receiver_reg, scratch1, scratch2, miss_label); |
| } |
| + int descriptor = transition->LastAdded(); |
| + DescriptorArray* descriptors = transition->instance_descriptors(); |
| + PropertyDetails details = descriptors->GetDetails(descriptor); |
| + Representation representation = details.representation(); |
| + ASSERT(!representation.IsNone()); |
| + |
| + // Unless we are in the most general state, check whether the map is still a |
| + // valid transition. |
| + if (transition->CanTransitionBeInvalidated()) { |
| + __ mov(scratch1, transition); |
|
danno
2013/04/24 15:23:00
Perhaps create a macro-assembler function for this
Toon Verwaest
2013/04/25 14:49:10
Done.
|
| + __ mov(scratch1, FieldOperand(scratch1, Map::kBitField3Offset)); |
| + __ and_(scratch1, Immediate(Smi::FromInt(Map::InvalidTransition::kMask))); |
| + __ j(not_zero, miss_label); |
| + } |
| + |
| + if (FLAG_track_fields && representation.IsSmi()) { |
| + __ JumpIfNotSmi(value_reg, miss_label); |
| + } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| + Label do_store; |
| + __ JumpIfSmi(value_reg, &do_store); |
| + __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
| + miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP); |
| + __ bind(&do_store); |
| + } |
| + |
| // Check that we are allowed to write this. |
| if (object->GetPrototype()->IsJSObject()) { |
| JSObject* holder; |
| @@ -856,14 +881,16 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| int offset = object->map()->instance_size() + (index * kPointerSize); |
| __ mov(FieldOperand(receiver_reg, offset), value_reg); |
| - // Update the write barrier for the array address. |
| - // Pass the value being stored in the now unused name_reg. |
| - __ mov(name_reg, value_reg); |
| - __ RecordWriteField(receiver_reg, |
| - offset, |
| - name_reg, |
| - scratch1, |
| - kDontSaveFPRegs); |
| + if (!FLAG_track_fields || !representation.IsSmi()) { |
| + // Update the write barrier for the array address. |
| + // Pass the value being stored in the now unused name_reg. |
| + __ mov(name_reg, value_reg); |
| + __ RecordWriteField(receiver_reg, |
| + offset, |
| + name_reg, |
| + scratch1, |
| + kDontSaveFPRegs); |
| + } |
| } else { |
| // Write to the properties array. |
| int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| @@ -871,14 +898,16 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| __ mov(FieldOperand(scratch1, offset), eax); |
| - // Update the write barrier for the array address. |
| - // Pass the value being stored in the now unused name_reg. |
| - __ mov(name_reg, value_reg); |
| - __ RecordWriteField(scratch1, |
| - offset, |
| - name_reg, |
| - receiver_reg, |
| - kDontSaveFPRegs); |
| + if (!FLAG_track_fields || !representation.IsSmi()) { |
| + // Update the write barrier for the array address. |
| + // Pass the value being stored in the now unused name_reg. |
| + __ mov(name_reg, value_reg); |
| + __ RecordWriteField(scratch1, |
| + offset, |
| + name_reg, |
| + receiver_reg, |
| + kDontSaveFPRegs); |
| + } |
| } |
| // Return the value (register eax). |
| @@ -918,20 +947,34 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| // object and the number of in-object properties is not going to change. |
| index -= object->map()->inobject_properties(); |
| + Representation representation = lookup->GetPropertyDetails().representation(); |
| + ASSERT(!representation.IsNone()); |
| + if (FLAG_track_fields && representation.IsSmi()) { |
| + __ JumpIfNotSmi(value_reg, miss_label); |
| + } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| + Label do_store; |
| + __ JumpIfSmi(value_reg, &do_store); |
| + __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
| + miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP); |
| + __ bind(&do_store); |
| + } |
| + |
| // TODO(verwaest): Share this code as a code stub. |
| if (index < 0) { |
| // Set the property straight into the object. |
| int offset = object->map()->instance_size() + (index * kPointerSize); |
| __ mov(FieldOperand(receiver_reg, offset), value_reg); |
| - // Update the write barrier for the array address. |
| - // Pass the value being stored in the now unused name_reg. |
| - __ mov(name_reg, value_reg); |
| - __ RecordWriteField(receiver_reg, |
| - offset, |
| - name_reg, |
| - scratch1, |
| - kDontSaveFPRegs); |
| + if (!FLAG_track_fields || !representation.IsSmi()) { |
| + // Update the write barrier for the array address. |
| + // Pass the value being stored in the now unused name_reg. |
| + __ mov(name_reg, value_reg); |
| + __ RecordWriteField(receiver_reg, |
| + offset, |
| + name_reg, |
| + scratch1, |
| + kDontSaveFPRegs); |
| + } |
| } else { |
| // Write to the properties array. |
| int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| @@ -939,14 +982,16 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| __ mov(FieldOperand(scratch1, offset), eax); |
| - // Update the write barrier for the array address. |
| - // Pass the value being stored in the now unused name_reg. |
| - __ mov(name_reg, value_reg); |
| - __ RecordWriteField(scratch1, |
| - offset, |
| - name_reg, |
| - receiver_reg, |
| - kDontSaveFPRegs); |
| + if (!FLAG_track_fields || !representation.IsSmi()) { |
| + // Update the write barrier for the array address. |
| + // Pass the value being stored in the now unused name_reg. |
| + __ mov(name_reg, value_reg); |
| + __ RecordWriteField(scratch1, |
| + offset, |
| + name_reg, |
| + receiver_reg, |
| + kDontSaveFPRegs); |
| + } |
| } |
| // Return the value (register eax). |
| @@ -2976,17 +3021,23 @@ Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
| Register map_reg = scratch1(); |
| __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); |
| int receiver_count = receiver_maps->length(); |
| + int number_of_handled_maps = 0; |
| for (int current = 0; current < receiver_count; ++current) { |
| - __ cmp(map_reg, receiver_maps->at(current)); |
| - __ j(equal, handlers->at(current)); |
| + Handle<Map> map = receiver_maps->at(current); |
| + if (!map->is_invalid_transition()) { |
| + number_of_handled_maps++; |
| + __ cmp(map_reg, map); |
| + __ j(equal, handlers->at(current)); |
| + } |
| } |
| + ASSERT(number_of_handled_maps != 0); |
| __ bind(&miss); |
| TailCallBuiltin(masm(), MissBuiltin(kind())); |
| // Return the generated code. |
| InlineCacheState state = |
| - receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; |
| + number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; |
| return GetICCode(kind(), type, name, state); |
| } |