| 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
|
|
|