Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index 4924dbb8d7e2959dd781953b2b826019be356f6d..d9ce3217a44857266e9ab7529e9b452cddbf6030 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -1171,16 +1171,46 @@ static bool LookupForWrite(Handle<JSObject> receiver, |
// Ensure the instance and its map were migrated before trying to update the |
// transition target. |
ASSERT(!receiver->map()->is_deprecated()); |
+ Handle<HeapType> value_type = FLAG_track_field_types |
+ ? HeapType::OfCurrently(value, lookup->isolate()) |
+ : HeapType::Any(lookup->isolate()); |
+ Handle<Map> target(lookup->GetTransitionTarget()); |
if (!value->FitsRepresentation(target_details.representation())) { |
- Handle<Map> target(lookup->GetTransitionTarget()); |
Map::GeneralizeRepresentation( |
target, target->LastAdded(), |
- value->OptimalRepresentation(), FORCE_FIELD); |
+ value->OptimalRepresentation(), |
+ value_type, FORCE_FIELD); |
// Lookup the transition again since the transition tree may have changed |
// entirely by the migration above. |
receiver->map()->LookupTransition(*holder, *name, lookup); |
if (!lookup->IsTransition()) return false; |
ic->MarkMonomorphicPrototypeFailure(); |
+ } else if (target_details.type() == FIELD && |
+ target_details.representation().IsHeapObject()) { |
+ int descriptor_number = target->LastAdded(); |
+ Handle<DescriptorArray> target_descriptors(target->instance_descriptors()); |
+ Handle<HeapType> field_type(target_descriptors->GetFieldType( |
+ descriptor_number), lookup->isolate()); |
+ if (!value_type->IsCurrently(field_type)) { |
+ if (!field_type->IsCurrently(value_type)) { |
+ value_type = HeapType::Any(lookup->isolate()); |
+ } |
+ if (FLAG_trace_track_field_types) { |
+#ifdef OBJECT_PRINT |
+ PrintF("[Updating type of field "); |
+ name->Print(); |
+ PrintF(" in transition map "); |
+ target->ShortPrint(); |
+ PrintF(": "); |
+ field_type->TypePrint(stdout); |
+ PrintF(" -> "); |
+ value_type->TypePrint(stdout); |
+ PrintF("]\n"); |
+#endif |
+ } |
+ target->UpdateFieldType(descriptor_number, *value_type); |
+ ic->MarkMonomorphicPrototypeFailure(); |
+ } |
} |
return true; |
} |