[ic] Avoid extra prototype chain iteration when creating a load IC data handler.

Since all possible data-encoded prototype chain checks are supported by LoadIC
we can remove this extra iteration.

LoadGlobalIC does not support data handlers yet.

BUG=v8:5561

Review-Url: https://codereview.chromium.org/2479523002
Cr-Commit-Position: refs/heads/master@{#40738}
This commit is contained in:
ishell 2016-11-03 10:52:16 -07:00 committed by Commit bot
parent 3c96c5e232
commit 2010ac0c7d
2 changed files with 16 additions and 19 deletions

View File

@ -915,10 +915,10 @@ int LoadIC::GetPrototypeCheckCount(Handle<Map> receiver_map,
Handle<FixedArray>(), Handle<Name>());
}
Handle<Object> LoadIC::SimpleLoadFromPrototype(Handle<Map> receiver_map,
Handle<JSObject> holder,
Handle<Name> name,
Handle<Object> smi_handler) {
Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
Handle<JSObject> holder,
Handle<Name> name,
Handle<Object> smi_handler) {
int checks_count = GetPrototypeCheckCount(receiver_map, holder);
DCHECK_LE(0, checks_count);
@ -950,8 +950,8 @@ Handle<Object> LoadIC::SimpleLoadFromPrototype(Handle<Map> receiver_map,
return handler_array;
}
Handle<Object> LoadIC::SimpleLoadNonExistent(Handle<Map> receiver_map,
Handle<Name> name) {
Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map,
Handle<Name> name) {
Handle<JSObject> holder; // null handle
int checks_count = GetPrototypeCheckCount(receiver_map, holder);
DCHECK_LE(0, checks_count);
@ -1041,7 +1041,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
} else if (!lookup->IsFound()) {
if (kind() == Code::LOAD_IC) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
code = SimpleLoadNonExistent(receiver_map(), lookup->name());
code = LoadNonExistent(receiver_map(), lookup->name());
} else if (kind() == Code::LOAD_GLOBAL_IC) {
code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
receiver_map());
@ -1387,10 +1387,9 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
if (receiver_is_holder) {
return smi_handler;
}
if (FLAG_tf_load_ic_stub && GetPrototypeCheckCount(map, holder) >= 0) {
if (FLAG_tf_load_ic_stub && kind() != Code::LOAD_GLOBAL_IC) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH);
return SimpleLoadFromPrototype(map, holder, lookup->name(),
smi_handler);
return LoadFromPrototype(map, holder, lookup->name(), smi_handler);
}
break; // Custom-compiled handler.
}
@ -1404,10 +1403,9 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH);
return smi_handler;
}
if (GetPrototypeCheckCount(map, holder) >= 0) {
if (kind() != Code::LOAD_GLOBAL_IC) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH);
return SimpleLoadFromPrototype(map, holder, lookup->name(),
smi_handler);
return LoadFromPrototype(map, holder, lookup->name(), smi_handler);
}
} else {
if (receiver_is_holder) {

View File

@ -325,14 +325,13 @@ class LoadIC : public IC {
// Creates a data handler that represents a prototype chain check followed
// by given Smi-handler that encoded a load from the holder.
// Can be used only if GetPrototypeCheckCount() returns non negative value.
Handle<Object> SimpleLoadFromPrototype(Handle<Map> receiver_map,
Handle<JSObject> holder,
Handle<Name> name,
Handle<Object> smi_handler);
Handle<Object> LoadFromPrototype(Handle<Map> receiver_map,
Handle<JSObject> holder, Handle<Name> name,
Handle<Object> smi_handler);
// Creates a data handler that represents a load of a non-existent property.
Handle<Object> SimpleLoadNonExistent(Handle<Map> receiver_map,
Handle<Name> name);
Handle<Object> LoadNonExistent(Handle<Map> receiver_map, Handle<Name> name);
friend class IC;
};