Chromium Code Reviews| Index: src/type-info.cc |
| =================================================================== |
| --- src/type-info.cc (revision 10254) |
| +++ src/type-info.cc (working copy) |
| @@ -438,11 +438,45 @@ |
| Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) { |
| types->Reserve(4); |
| ASSERT(object->IsCode()); |
| - isolate_->stub_cache()->CollectMatchingMaps(types, *name, flags); |
| + isolate_->stub_cache()->CollectMatchingMaps(types, |
| + *name, |
| + flags, |
| + global_context_); |
| } |
| } |
| +// Check if a map originates from a given global context. We use this |
| +// information to filter out maps from different context to avoid |
| +// retaining objects from different tabs in Chrome via optimized code. |
| +bool TypeFeedbackOracle::InSameContext(Map* map, |
|
Vyacheslav Egorov (Chromium)
2011/12/14 13:34:46
I would call it IsLikelyToRetainOtherContext.
It'
fschneider
2011/12/14 14:01:42
Done.
|
| + Context* global_context) { |
| + Object* constructor = map->constructor(); |
| + ASSERT(constructor != NULL); |
| + while (!constructor->IsJSFunction()) { |
| + // If the constructor is not null or a JSFunction, we have to |
| + // conservatively assume that it may retain a global context. |
| + if (!constructor->IsNull()) return false; |
| + |
| + // If both, constructor and prototype are null, we conclude |
| + // that no global context will be retained by this map. |
| + if (map->prototype()->IsNull()) return true; |
| + |
| + map = JSObject::cast(map->prototype())->map(); |
| + constructor = map->constructor(); |
| + } |
| + JSFunction* function = JSFunction::cast(constructor); |
| + return InSameContext(function, global_context); |
| +} |
| + |
| + |
| +bool TypeFeedbackOracle::InSameContext(JSFunction* function, |
| + Context* global_context) { |
| + return function->context()->global() == global_context->global() |
| + || function->context()->global() == global_context->builtins(); |
| +} |
| + |
| + |
| static void AddMapIfMissing(Handle<Map> map, SmallMapList* list) { |
| for (int i = 0; i < list->length(); ++i) { |
| if (list->at(i).is_identical_to(map)) return; |
| @@ -539,7 +573,11 @@ |
| SetInfo(ast_id, Smi::FromInt(target->check_type())); |
| } else { |
| Object* map = target->FindFirstMap(); |
| - SetInfo(ast_id, map == NULL ? static_cast<Object*>(target) : map); |
| + if (map == NULL) { |
| + SetInfo(ast_id, static_cast<Object*>(target)); |
| + } else if (InSameContext(Map::cast(map), *global_context_)) { |
| + SetInfo(ast_id, map); |
| + } |
| } |
| } else if (target->ic_state() == MEGAMORPHIC) { |
| SetInfo(ast_id, target); |
| @@ -565,7 +603,8 @@ |
| if (target->major_key() == CodeStub::CallFunction && |
| target->has_function_cache()) { |
| Object* value = CallFunctionStub::GetCachedValue(reloc_entry.pc()); |
| - if (value->IsJSFunction()) { |
| + if (value->IsJSFunction() && |
| + InSameContext(JSFunction::cast(value), *global_context_)) { |
| SetInfo(ast_id, value); |
| } |
| } |