 Chromium Code Reviews
 Chromium Code Reviews Issue 2511603002:
  [ic] Support data handlers in LoadGlobalIC.  (Closed)
    
  
    Issue 2511603002:
  [ic] Support data handlers in LoadGlobalIC.  (Closed) 
  | 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); |