Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 6b605e5841ebff66b737c36a11bac03b631a183e..a09ae66a533ae4de2d99971a3ffb20707e5c3d05 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -641,7 +641,7 @@ Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) { |
if (IsGlobalObject()) { |
PropertyCell* cell = PropertyCell::cast( |
property_dictionary()->ValueAt(result->GetDictionaryEntry())); |
- cell->set_value(value); |
+ cell->set_value_infer_type(value); |
} else { |
property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
} |
@@ -668,8 +668,7 @@ MaybeObject* JSObject::SetNormalizedProperty(Name* name, |
Object* store_value = value; |
if (IsGlobalObject()) { |
Heap* heap = name->GetHeap(); |
- MaybeObject* maybe_store_value = |
- heap->AllocatePropertyCell(value); |
+ MaybeObject* maybe_store_value = heap->AllocatePropertyCell(value); |
if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
} |
Object* dict; |
@@ -698,7 +697,7 @@ MaybeObject* JSObject::SetNormalizedProperty(Name* name, |
if (IsGlobalObject()) { |
PropertyCell* cell = |
PropertyCell::cast(property_dictionary()->ValueAt(entry)); |
- cell->set_value(value); |
+ cell->set_value_infer_type(value); |
// Please note we have to update the property details. |
property_dictionary()->DetailsAtPut(entry, details); |
} else { |
@@ -730,7 +729,7 @@ 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()); |
+ cell->set_value_infer_type(cell->GetHeap()->the_hole_value()); |
dictionary->DetailsAtPut(entry, details.AsDeleted()); |
} else { |
Object* deleted = dictionary->DeleteProperty(entry, mode); |
@@ -1936,7 +1935,7 @@ 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); |
+ PropertyCell::cast(store_value)->set_value_infer_type(value); |
// Assign an enumeration index to the property and update |
// SetNextEnumerationIndex. |
int index = dict->NextEnumerationIndex(); |
@@ -1950,7 +1949,7 @@ 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); |
+ PropertyCell::cast(store_value)->set_value_infer_type(value); |
} |
PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
Object* result; |
@@ -10147,29 +10146,46 @@ SafepointEntry Code::GetSafepointEntry(Address pc) { |
} |
-Map* Code::FindFirstMap() { |
+Object* Code::FindNthObject(int n, Map* match_map) { |
ASSERT(is_inline_cache_stub()); |
DisallowHeapAllocation no_allocation; |
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
for (RelocIterator it(this, mask); !it.done(); it.next()) { |
RelocInfo* info = it.rinfo(); |
Object* object = info->target_object(); |
- if (object->IsMap()) return Map::cast(object); |
+ if (object->IsHeapObject()) { |
+ if (HeapObject::cast(object)->map() == match_map) { |
+ if (--n == 0) return object; |
+ } |
+ } |
} |
return NULL; |
} |
-void Code::ReplaceFirstMap(Map* replace_with) { |
+Map* Code::FindFirstMap() { |
+ Object* result = FindNthObject(1, GetHeap()->meta_map()); |
+ if (result == NULL) return NULL; |
+ return Map::cast(result); |
+} |
+ |
+ |
+void Code::ReplaceNthObject(int n, |
+ Map* match_map, |
+ Object* replace_with) { |
ASSERT(is_inline_cache_stub()); |
DisallowHeapAllocation no_allocation; |
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
for (RelocIterator it(this, mask); !it.done(); it.next()) { |
RelocInfo* info = it.rinfo(); |
Object* object = info->target_object(); |
- if (object->IsMap()) { |
- info->set_target_object(replace_with); |
- return; |
+ if (object->IsHeapObject()) { |
+ if (HeapObject::cast(object)->map() == match_map) { |
+ if (--n == 0) { |
+ info->set_target_object(replace_with); |
+ return; |
+ } |
+ } |
} |
} |
UNREACHABLE(); |
@@ -10188,6 +10204,11 @@ void Code::FindAllMaps(MapHandleList* maps) { |
} |
+void Code::ReplaceFirstMap(Map* replace_with) { |
+ ReplaceNthObject(1, GetHeap()->meta_map(), replace_with); |
+} |
+ |
+ |
Code* Code::FindFirstCode() { |
ASSERT(is_inline_cache_stub()); |
DisallowHeapAllocation no_allocation; |
@@ -10217,6 +10238,11 @@ void Code::FindAllCode(CodeHandleList* code_list, int length) { |
Name* Code::FindFirstName() { |
+ #if 0 |
+ Object* result = FindNthObject(1, GetHeap()->symbol_map()); |
+ if (result == NULL) return NULL; |
+ return Name::cast(result); |
+#else |
ASSERT(is_inline_cache_stub()); |
DisallowHeapAllocation no_allocation; |
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
@@ -10226,6 +10252,23 @@ Name* Code::FindFirstName() { |
if (object->IsName()) return Name::cast(object); |
} |
return NULL; |
+ #endif |
+} |
+ |
+ |
+void Code::ReplaceNthCell(int n, |
+ Cell* replace_with) { |
+ ASSERT(is_inline_cache_stub()); |
+ DisallowHeapAllocation no_allocation; |
+ int mask = RelocInfo::ModeMask(RelocInfo::CELL); |
+ for (RelocIterator it(this, mask); !it.done(); it.next()) { |
+ RelocInfo* info = it.rinfo(); |
+ if (--n == 0) { |
+ info->set_target_cell(replace_with); |
+ return; |
+ } |
+ } |
+ UNREACHABLE(); |
} |
@@ -11111,7 +11154,7 @@ void Map::AddDependentCompilationInfo(DependentCode::DependencyGroup group, |
Handle<DependentCode> codes = |
DependentCode::Insert(dep, group, info->object_wrapper()); |
if (*codes != dependent_code()) set_dependent_code(*codes); |
- info->dependent_maps(group)->Add(Handle<Map>(this), info->zone()); |
+ info->dependencies(group)->Add(Handle<HeapObject>(this), info->zone()); |
} |
@@ -11137,6 +11180,15 @@ void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) { |
} |
+DependentCode* DependentCode::ForObject(Handle<HeapObject> object, |
+ DependencyGroup group) { |
+ if (group == DependentCode::kPropertyCellChangedGroup) { |
+ return Handle<PropertyCell>::cast(object)->dependent_code(); |
+ } |
+ return Handle<Map>::cast(object)->dependent_code(); |
+} |
+ |
+ |
Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, |
DependencyGroup group, |
Handle<Object> object) { |
@@ -15820,4 +15872,55 @@ void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) { |
} |
+Type* PropertyCell::union_type(Object* value) { |
+ Isolate* isolate = GetIsolate(); |
+ Handle<Object> value_handle(value, isolate); |
+ Handle<Type> old_type(type(), isolate); |
+ Handle<Type> new_type(Type::Constant(value_handle, isolate), isolate); |
+ |
+ if (new_type->Is(old_type)) { |
+ return *new_type; |
+ } |
+ |
+ dependent_code()->DeoptimizeDependentCodeGroup( |
+ isolate, DependentCode::kPropertyCellChangedGroup); |
+ |
+ if (old_type->IsConstant()) { |
+ Handle<Object> undefined(isolate->heap()->undefined_value(), isolate); |
+ Type* const_undefined = Type::Constant(undefined, isolate); |
+ if (old_type->Is(const_undefined)) { |
+ return *new_type; |
+ } |
+ } |
+ |
+ return Type::Union(old_type, new_type); |
+} |
+ |
+ |
+void PropertyCell::set_value_infer_type(Object* value, |
+ WriteBarrierMode ignored) { |
+ set_value(value, ignored); |
+ set_type(union_type(value)); |
+} |
+ |
+ |
+void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) { |
+ Handle<DependentCode> dep(dependent_code()); |
+ Handle<DependentCode> codes = |
+ DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup, |
+ info->object_wrapper()); |
+ if (*codes != dependent_code()) set_dependent_code(*codes); |
+ info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
+ Handle<HeapObject>(this), info->zone()); |
+} |
+ |
+ |
+void PropertyCell::AddDependentCode(Handle<Code> code) { |
+ Handle<DependentCode> codes = DependentCode::Insert( |
+ Handle<DependentCode>(dependent_code()), |
+ DependentCode::kPropertyCellChangedGroup, code); |
+ if (*codes != dependent_code()) set_dependent_code(*codes); |
+} |
+ |
+ |
} } // namespace v8::internal |