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}
This commit is contained in:
verwaest 2015-03-26 04:21:52 -07:00 committed by Commit bot
parent 69383d6366
commit accbe2216e
5 changed files with 27 additions and 64 deletions

View File

@ -5445,9 +5445,10 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
static bool CanInlinePropertyAccess(Handle<Map> 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> 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<JSFunction> 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<JSFunction> 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<Map> holder_map;

View File

@ -118,7 +118,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types, Handle<Name> 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>(map), zone);
}
}
@ -137,7 +137,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types, Handle<Name> 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>(map), zone);
}
}

View File

@ -52,12 +52,7 @@ Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
Handle<Object> 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<Object>(obj, isolate());
}
return Handle<Object>::cast(isolate()->factory()->undefined_value());
return Handle<Object>(obj, isolate());
}
@ -75,9 +70,7 @@ Handle<Object> 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<Object>(obj, isolate());
}
@ -248,12 +241,7 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id,
Handle<Map> map;
Map* raw_map = code->FindFirstMap();
if (raw_map != NULL) {
if (Map::TryUpdate(handle(raw_map)).ToHandle(&map) &&
CanRetainOtherContext(*map, *native_context_)) {
map = Handle<Map>::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> 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> 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> map(maps.at(i));
if (!CanRetainOtherContext(*map, *native_context_)) {
types->AddMapIfMissing(map, zone());
if (IsRelevantFeedback(*map, *native_context_)) {
types->AddMapIfMissing(maps.at(i), zone());
}
}
}

View File

@ -67,9 +67,12 @@ class TypeFeedbackOracle: public ZoneObject {
template <class T>
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<JSFunction> GetCallTarget(FeedbackVectorICSlot slot);
Handle<AllocationSite> GetCallAllocationSite(FeedbackVectorICSlot slot);

View File

@ -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();