| Index: src/x64/stub-cache-x64.cc
 | 
| diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
 | 
| index 41e5b882642287e01ed347cdd347c373643b0c16..227710e9a7dd665dd354387cb7a788881552a976 100644
 | 
| --- a/src/x64/stub-cache-x64.cc
 | 
| +++ b/src/x64/stub-cache-x64.cc
 | 
| @@ -753,6 +753,25 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm,
 | 
|      __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label);
 | 
|    }
 | 
|  
 | 
| +  int descriptor = transition->LastAdded();
 | 
| +  DescriptorArray* descriptors = transition->instance_descriptors();
 | 
| +  PropertyDetails details = descriptors->GetDetails(descriptor);
 | 
| +  Representation representation = details.representation();
 | 
| +  ASSERT(!representation.IsNone());
 | 
| +
 | 
| +  // Ensure no transitions to deprecated maps are followed.
 | 
| +  __ CheckMapDeprecated(transition, scratch1, 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;
 | 
| @@ -836,11 +855,13 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm,
 | 
|      int offset = object->map()->instance_size() + (index * kPointerSize);
 | 
|      __ movq(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.
 | 
| -    __ movq(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.
 | 
| +      __ movq(name_reg, value_reg);
 | 
| +      __ RecordWriteField(
 | 
| +          receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs);
 | 
| +    }
 | 
|    } else {
 | 
|      // Write to the properties array.
 | 
|      int offset = index * kPointerSize + FixedArray::kHeaderSize;
 | 
| @@ -848,11 +869,13 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm,
 | 
|      __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
 | 
|      __ movq(FieldOperand(scratch1, offset), value_reg);
 | 
|  
 | 
| -    // Update the write barrier for the array address.
 | 
| -    // Pass the value being stored in the now unused name_reg.
 | 
| -    __ movq(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.
 | 
| +      __ movq(name_reg, value_reg);
 | 
| +      __ RecordWriteField(
 | 
| +          scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs);
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    // Return the value (register rax).
 | 
| @@ -892,17 +915,31 @@ 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->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);
 | 
|      __ movq(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.
 | 
| -    __ movq(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.
 | 
| +      __ movq(name_reg, value_reg);
 | 
| +      __ RecordWriteField(
 | 
| +          receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs);
 | 
| +    }
 | 
|    } else {
 | 
|      // Write to the properties array.
 | 
|      int offset = index * kPointerSize + FixedArray::kHeaderSize;
 | 
| @@ -910,11 +947,13 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
 | 
|      __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
 | 
|      __ movq(FieldOperand(scratch1, offset), value_reg);
 | 
|  
 | 
| -    // Update the write barrier for the array address.
 | 
| -    // Pass the value being stored in the now unused name_reg.
 | 
| -    __ movq(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.
 | 
| +      __ movq(name_reg, value_reg);
 | 
| +      __ RecordWriteField(
 | 
| +          scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs);
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    // Return the value (register rax).
 | 
| @@ -2799,18 +2838,24 @@ Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
 | 
|    Register map_reg = scratch1();
 | 
|    __ movq(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) {
 | 
| -    // Check map and tail call if there's a match
 | 
| -    __ Cmp(map_reg, receiver_maps->at(current));
 | 
| -    __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET);
 | 
| +    Handle<Map> map = receiver_maps->at(current);
 | 
| +    if (!map->is_deprecated()) {
 | 
| +      number_of_handled_maps++;
 | 
| +      // Check map and tail call if there's a match
 | 
| +      __ Cmp(map_reg, receiver_maps->at(current));
 | 
| +      __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET);
 | 
| +    }
 | 
|    }
 | 
| +  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);
 | 
|  }
 | 
|  
 | 
| 
 |