From accbe2216eb6b4690e1ae7617450c99058f64ff5 Mon Sep 17 00:00:00 2001 From: verwaest Date: Thu, 26 Mar 2015 04:21:52 -0700 Subject: [PATCH] Remove CanRetainOtherContext since embedded objects are now weak. Instead of CanRetainOtherContext, we now manually blacklist all access-checked objects. BUG= Review URL: https://codereview.chromium.org/1020803004 Cr-Commit-Position: refs/heads/master@{#27473} --- src/hydrogen.cc | 17 +++++++-- src/ic/stub-cache.cc | 4 +- src/type-info.cc | 59 +++--------------------------- src/type-info.h | 9 +++-- test/mjsunit/constant-folding-2.js | 2 +- 5 files changed, 27 insertions(+), 64 deletions(-) diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 230939fe56..0ca78f3da9 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -5445,9 +5445,10 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { static bool CanInlinePropertyAccess(Handle map) { if (map->instance_type() == HEAP_NUMBER_TYPE) return true; if (map->instance_type() < FIRST_NONSTRING_TYPE) return true; - return map->IsJSObjectMap() && - !map->is_dictionary_map() && - !map->has_named_interceptor(); + return map->IsJSObjectMap() && !map->is_dictionary_map() && + !map->has_named_interceptor() && + // TODO(verwaest): Whitelist contexts to which we have access. + !map->is_access_check_needed(); } @@ -6956,7 +6957,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( static bool CanInlineElementAccess(Handle map) { return map->IsJSObjectMap() && !map->has_slow_elements_kind() && - !map->has_indexed_interceptor(); + !map->has_indexed_interceptor() && !map->is_access_check_needed(); } @@ -7816,6 +7817,10 @@ bool HOptimizedGraphBuilder::TryInline(Handle target, HValue* implicit_return_value, BailoutId ast_id, BailoutId return_id, InliningKind inlining_kind) { + if (target->context()->native_context() != + top_info()->closure()->context()->native_context()) { + return false; + } int nodes_added = InliningAstSize(target); if (nodes_added == kNotInlinable) return false; @@ -8643,6 +8648,10 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Handle function, int argc, BailoutId ast_id, ApiCallType call_type) { + if (function->context()->native_context() != + top_info()->closure()->context()->native_context()) { + return false; + } CallOptimization optimization(function); if (!optimization.is_simple_api_call()) return false; Handle holder_map; diff --git a/src/ic/stub-cache.cc b/src/ic/stub-cache.cc index 35a4acf8cc..e3a4938d6a 100644 --- a/src/ic/stub-cache.cc +++ b/src/ic/stub-cache.cc @@ -118,7 +118,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types, Handle name, int offset = PrimaryOffset(*name, flags, map); if (entry(primary_, offset) == &primary_[i] && - !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { + TypeFeedbackOracle::IsRelevantFeedback(map, *native_context)) { types->AddMapIfMissing(Handle(map), zone); } } @@ -137,7 +137,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types, Handle name, // Lookup in secondary table and add matches. int offset = SecondaryOffset(*name, flags, primary_offset); if (entry(secondary_, offset) == &secondary_[i] && - !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { + TypeFeedbackOracle::IsRelevantFeedback(map, *native_context)) { types->AddMapIfMissing(Handle(map), zone); } } diff --git a/src/type-info.cc b/src/type-info.cc index 1059c7aecd..087e1db148 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -52,12 +52,7 @@ Handle TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) { Handle TypeFeedbackOracle::GetInfo(FeedbackVectorSlot slot) { DCHECK(slot.ToInt() >= 0 && slot.ToInt() < feedback_vector_->length()); Object* obj = feedback_vector_->Get(slot); - if (!obj->IsJSFunction() || - !CanRetainOtherContext(JSFunction::cast(obj), *native_context_)) { - DCHECK(!obj->IsMap()); - return Handle(obj, isolate()); - } - return Handle::cast(isolate()->factory()->undefined_value()); + return Handle(obj, isolate()); } @@ -75,9 +70,7 @@ Handle TypeFeedbackOracle::GetInfo(FeedbackVectorICSlot slot) { obj = cell->value(); } - if ((obj->IsJSFunction() && - !CanRetainOtherContext(JSFunction::cast(obj), *native_context_)) || - obj->IsAllocationSite() || obj->IsSymbol()) { + if (obj->IsJSFunction() || obj->IsAllocationSite() || obj->IsSymbol()) { return Handle(obj, isolate()); } @@ -248,12 +241,7 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id, Handle map; Map* raw_map = code->FindFirstMap(); - if (raw_map != NULL) { - if (Map::TryUpdate(handle(raw_map)).ToHandle(&map) && - CanRetainOtherContext(*map, *native_context_)) { - map = Handle::null(); - } - } + if (raw_map != NULL) Map::TryUpdate(handle(raw_map)).ToHandle(&map); if (code->is_compare_ic_stub()) { CompareICStub stub(code->stub_key(), isolate()); @@ -419,43 +407,6 @@ void TypeFeedbackOracle::CollectReceiverTypes(T* obj, Handle name, } -// Check if a map originates from a given native 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::CanRetainOtherContext(Map* map, - Context* native_context) { - Object* constructor = NULL; - while (!map->prototype()->IsNull()) { - constructor = map->GetConstructor(); - if (!constructor->IsNull()) { - // If the constructor is not null or a JSFunction, we have to - // conservatively assume that it may retain a native context. - if (!constructor->IsJSFunction()) return true; - // Check if the constructor directly references a foreign context. - if (CanRetainOtherContext(JSFunction::cast(constructor), - native_context)) { - return true; - } - } - map = HeapObject::cast(map->prototype())->map(); - } - constructor = map->GetConstructor(); - if (constructor->IsNull()) return false; - // If the constructor is not null or a JSFunction, we have to conservatively - // assume that it may retain a native context. - if (!constructor->IsJSFunction()) return true; - JSFunction* function = JSFunction::cast(constructor); - return CanRetainOtherContext(function, native_context); -} - - -bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function, - Context* native_context) { - return function->context()->global_object() != native_context->global_object() - && function->context()->global_object() != native_context->builtins(); -} - - void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, SmallMapList* types) { Handle object = GetInfo(ast_id); @@ -479,8 +430,8 @@ void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) { types->Reserve(maps.length(), zone()); for (int i = 0; i < maps.length(); i++) { Handle map(maps.at(i)); - if (!CanRetainOtherContext(*map, *native_context_)) { - types->AddMapIfMissing(map, zone()); + if (IsRelevantFeedback(*map, *native_context_)) { + types->AddMapIfMissing(maps.at(i), zone()); } } } diff --git a/src/type-info.h b/src/type-info.h index 6866da2d1a..bd275e671a 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -67,9 +67,12 @@ class TypeFeedbackOracle: public ZoneObject { template void CollectReceiverTypes(T* obj, SmallMapList* types); - static bool CanRetainOtherContext(Map* map, Context* native_context); - static bool CanRetainOtherContext(JSFunction* function, - Context* native_context); + static bool IsRelevantFeedback(Map* map, Context* native_context) { + Object* constructor = map->GetConstructor(); + return !constructor->IsJSFunction() || + JSFunction::cast(constructor)->context()->native_context() == + native_context; + } Handle GetCallTarget(FeedbackVectorICSlot slot); Handle GetCallAllocationSite(FeedbackVectorICSlot slot); diff --git a/test/mjsunit/constant-folding-2.js b/test/mjsunit/constant-folding-2.js index 73cf040f5a..3f82c2fa43 100644 --- a/test/mjsunit/constant-folding-2.js +++ b/test/mjsunit/constant-folding-2.js @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --nodead-code-elimination --fold-constants --allow-natives-syntax +// Flags: --nodead-code-elimination --fold-constants --allow-natives-syntax --nostress-opt function test(f) { f();