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();
}
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();
}
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;
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;
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);
}
}
// 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);
}
}
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());
}
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());
}
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());
}
-// 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);
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());
}
}
}
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);