Index: src/ic/ic.cc |
diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
index 07bd68dfbf9caea4e19bd49996bc396b62527e91..c01914f3a1953ad4121ef6a28be6f39f07f7e561 100644 |
--- a/src/ic/ic.cc |
+++ b/src/ic/ic.cc |
@@ -564,7 +564,7 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, |
nexus->ConfigureMonomorphic(map, handler); |
} else if (kind() == Code::LOAD_GLOBAL_IC) { |
LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); |
- nexus->ConfigureHandlerMode(Handle<Code>::cast(handler)); |
+ nexus->ConfigureHandlerMode(handler); |
} else if (kind() == Code::KEYED_LOAD_IC) { |
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); |
nexus->ConfigureMonomorphic(name, map, handler); |
@@ -794,6 +794,7 @@ void IC::PatchCache(Handle<Name> name, Handle<Object> handler) { |
DCHECK(IsHandler(*handler)); |
// Currently only LoadIC and KeyedLoadIC support non-code handlers. |
DCHECK_IMPLIES(!handler->IsCode(), kind() == Code::LOAD_IC || |
+ kind() == Code::LOAD_GLOBAL_IC || |
kind() == Code::KEYED_LOAD_IC || |
kind() == Code::STORE_IC || |
kind() == Code::KEYED_STORE_IC); |
@@ -858,10 +859,6 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, |
Handle<Name> name, int first_index) { |
DCHECK(holder.is_null() || holder->HasFastProperties()); |
- // The following kinds of receiver maps require custom handler compilation. |
- if (receiver_map->IsJSGlobalObjectMap()) { |
- return -1; |
- } |
// We don't encode the requirement to check access rights because we already |
// passed the access check for current native context and the access |
// can't be revoked. |
@@ -882,6 +879,17 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, |
native_context->self_weak_cell()); |
} |
checks_count++; |
+ |
+ } else if (receiver_map->IsJSGlobalObjectMap()) { |
+ if (fill_array) { |
+ Handle<JSGlobalObject> global = isolate->global_object(); |
+ Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( |
+ global, name, PropertyCellType::kInvalidated); |
+ DCHECK(cell->value()->IsTheHole(isolate)); |
+ Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); |
+ array->set(LoadHandler::kFirstPrototypeIndex + checks_count, *weak_cell); |
+ } |
+ checks_count++; |
} |
// Create/count entries for each global or dictionary prototype appeared in |
@@ -937,14 +945,14 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, |
Handle<Object> smi_handler) { |
int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); |
DCHECK_LE(0, checks_count); |
- DCHECK(!receiver_map->IsJSGlobalObjectMap()); |
if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { |
DCHECK(!receiver_map->is_dictionary_map()); |
DCHECK_LE(1, checks_count); // For native context. |
smi_handler = |
LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); |
- } else if (receiver_map->is_dictionary_map()) { |
+ } else if (receiver_map->is_dictionary_map() && |
+ !receiver_map->IsJSGlobalObjectMap()) { |
smi_handler = |
LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); |
} |
@@ -975,10 +983,11 @@ Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, |
Handle<JSObject> holder; // null handle |
int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); |
DCHECK_LE(0, checks_count); |
- DCHECK(!receiver_map->IsJSGlobalObjectMap()); |
- Handle<Object> smi_handler = LoadHandler::LoadNonExistent( |
- isolate(), receiver_map->is_dictionary_map()); |
+ bool do_negative_lookup_on_receiver = |
+ receiver_map->is_dictionary_map() && !receiver_map->IsJSGlobalObjectMap(); |
Igor Sheludko
2016/11/17 11:32:09
The fix.
|
+ Handle<Object> smi_handler = |
+ LoadHandler::LoadNonExistent(isolate(), do_negative_lookup_on_receiver); |
if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { |
DCHECK(!receiver_map->is_dictionary_map()); |
@@ -1066,14 +1075,16 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { |
lookup->state() == LookupIterator::ACCESS_CHECK) { |
code = slow_stub(); |
} else if (!lookup->IsFound()) { |
- if (kind() == Code::LOAD_IC) { |
- TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH); |
- code = LoadNonExistent(receiver_map(), lookup->name()); |
- } else if (kind() == Code::LOAD_GLOBAL_IC) { |
- code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), |
- receiver_map()); |
- // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. |
- if (code.is_null()) code = slow_stub(); |
+ if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) { |
+ if (FLAG_tf_load_ic_stub) { |
+ TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH); |
+ code = LoadNonExistent(receiver_map(), lookup->name()); |
+ } else { |
+ code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), |
+ receiver_map()); |
+ // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. |
+ if (code.is_null()) code = slow_stub(); |
+ } |
} else { |
code = slow_stub(); |
} |
@@ -1401,7 +1412,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { |
if (receiver_is_holder) { |
return smi_handler; |
} |
- if (FLAG_tf_load_ic_stub && kind() != Code::LOAD_GLOBAL_IC) { |
+ if (FLAG_tf_load_ic_stub) { |
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH); |
return LoadFromPrototype(map, holder, lookup->name(), smi_handler); |
} |
@@ -1417,10 +1428,8 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { |
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH); |
return smi_handler; |
} |
- if (kind() != Code::LOAD_GLOBAL_IC) { |
- TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH); |
- return LoadFromPrototype(map, holder, lookup->name(), smi_handler); |
- } |
+ TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH); |
+ return LoadFromPrototype(map, holder, lookup->name(), smi_handler); |
} else { |
if (receiver_is_holder) { |
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); |