Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 2abfa7389697afd0482e103983b3d2e4c04a78ac..ebcc2339f357f3a4042fbebdbb1277203b37b508 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -630,12 +630,23 @@ Object* JSObject::GetNormalizedProperty(LookupResult* result) { |
} |
-Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) { |
+Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, |
+ LookupResult* result, |
+ Handle<Object> value) { |
+ CALL_HEAP_FUNCTION(object->GetIsolate(), |
+ object->SetNormalizedProperty(result, *value), |
+ Object); |
+} |
+ |
+ |
+MaybeObject* JSObject::SetNormalizedProperty(LookupResult* result, |
+ Object* value) { |
ASSERT(!HasFastProperties()); |
if (IsGlobalObject()) { |
PropertyCell* cell = PropertyCell::cast( |
property_dictionary()->ValueAt(result->GetDictionaryEntry())); |
- cell->set_value(value); |
+ MaybeObject* maybe_type = cell->SetValueInferType(value); |
+ if (maybe_type->IsFailure()) return maybe_type; |
} else { |
property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
} |
@@ -691,7 +702,8 @@ MaybeObject* JSObject::SetNormalizedProperty(Name* name, |
if (IsGlobalObject()) { |
PropertyCell* cell = |
PropertyCell::cast(property_dictionary()->ValueAt(entry)); |
- cell->set_value(value); |
+ MaybeObject* maybe_type = cell->SetValueInferType(value); |
+ if (maybe_type->IsFailure()) return maybe_type; |
// Please note we have to update the property details. |
property_dictionary()->DetailsAtPut(entry, details); |
} else { |
@@ -723,7 +735,9 @@ MaybeObject* JSObject::DeleteNormalizedProperty(Name* name, DeleteMode mode) { |
set_map(new_map); |
} |
PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry)); |
- cell->set_value(cell->GetHeap()->the_hole_value()); |
+ MaybeObject* maybe_type = |
+ cell->SetValueInferType(cell->GetHeap()->the_hole_value()); |
+ if (maybe_type->IsFailure()) return maybe_type; |
dictionary->DetailsAtPut(entry, details.AsDeleted()); |
} else { |
Object* deleted = dictionary->DeleteProperty(entry, mode); |
@@ -1930,7 +1944,9 @@ MaybeObject* JSObject::AddSlowProperty(Name* name, |
int entry = dict->FindEntry(name); |
if (entry != NameDictionary::kNotFound) { |
store_value = dict->ValueAt(entry); |
- PropertyCell::cast(store_value)->set_value(value); |
+ MaybeObject* maybe_type = |
+ PropertyCell::cast(store_value)->SetValueInferType(value); |
+ if (maybe_type->IsFailure()) return maybe_type; |
// Assign an enumeration index to the property and update |
// SetNextEnumerationIndex. |
int index = dict->NextEnumerationIndex(); |
@@ -1944,7 +1960,9 @@ MaybeObject* JSObject::AddSlowProperty(Name* name, |
heap->AllocatePropertyCell(value); |
if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
} |
- PropertyCell::cast(store_value)->set_value(value); |
+ MaybeObject* maybe_type = |
+ PropertyCell::cast(store_value)->SetValueInferType(value); |
+ if (maybe_type->IsFailure()) return maybe_type; |
} |
PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
Object* result; |
@@ -15813,6 +15831,46 @@ void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) { |
} |
+Type* PropertyCell::UpdateType(Handle<PropertyCell> cell, |
+ Handle<Object> value) { |
+ Isolate* isolate = cell->GetIsolate(); |
+ Handle<Type> old_type(cell->type(), isolate); |
+ Handle<Type> new_type((value->IsSmi() || value->IsUndefined()) |
+ ? Type::Constant(value, isolate) |
+ : Type::Any(), isolate); |
+ |
+ if (new_type->Is(old_type)) { |
+ return *old_type; |
+ } |
+ |
+ cell->dependent_code()->DeoptimizeDependentCodeGroup( |
+ isolate, DependentCode::kPropertyCellChangedGroup); |
+ |
+ if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) { |
+ return *new_type; |
+ } |
+ |
+ return Type::Any(); |
+} |
+ |
+ |
+MaybeObject* PropertyCell::SetValueInferType(Object* value, |
+ WriteBarrierMode ignored) { |
+ set_value(value, ignored); |
+ if (!Type::Any()->Is(type())) { |
+ IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate()); |
+ MaybeObject* maybe_type = trampoline.CallWithReturnValue( |
+ &PropertyCell::UpdateType, |
+ Handle<PropertyCell>(this), |
+ Handle<Object>(value, GetIsolate())); |
+ if (maybe_type->IsFailure()) return maybe_type; |
+ Type* new_type = static_cast<Type*>(maybe_type); |
+ set_type(new_type); |
+ } |
+ return value; |
+} |
+ |
+ |
void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) { |
Handle<DependentCode> dep(dependent_code()); |
Handle<DependentCode> codes = |