Commit 61b49b3c authored by ishell's avatar ishell Committed by Commit bot

[runtime] Refine runtime call stats for IC misses.

Now we are able to distinguish different kind of misses based on which handler/stub did we actually use.

Review-Url: https://codereview.chromium.org/1969733002
Cr-Commit-Position: refs/heads/master@{#36175}
parent bf90d9a3
...@@ -288,6 +288,15 @@ void RuntimeCallStats::Leave(Isolate* isolate, RuntimeCallTimer* timer) { ...@@ -288,6 +288,15 @@ void RuntimeCallStats::Leave(Isolate* isolate, RuntimeCallTimer* timer) {
stats->current_timer_ = timer->Stop(); stats->current_timer_ = timer->Stop();
} }
// static
void RuntimeCallStats::CorrectCurrentCounterId(Isolate* isolate,
CounterId counter_id) {
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats();
DCHECK_NOT_NULL(stats->current_timer_);
RuntimeCallCounter* counter = &(stats->*counter_id);
stats->current_timer_->counter_ = counter;
}
void RuntimeCallStats::Print(std::ostream& os) { void RuntimeCallStats::Print(std::ostream& os) {
RuntimeCallStatEntries entries; RuntimeCallStatEntries entries;
...@@ -299,6 +308,10 @@ void RuntimeCallStats::Print(std::ostream& os) { ...@@ -299,6 +308,10 @@ void RuntimeCallStats::Print(std::ostream& os) {
BUILTIN_LIST_C(PRINT_COUNTER) BUILTIN_LIST_C(PRINT_COUNTER)
#undef PRINT_COUNTER #undef PRINT_COUNTER
#define PRINT_COUNTER(name) entries.Add(&this->Handler_##name);
FOR_EACH_HANDLER_COUNTER(PRINT_COUNTER)
#undef PRINT_COUNTER
entries.Add(&this->ExternalCallback); entries.Add(&this->ExternalCallback);
entries.Add(&this->GC); entries.Add(&this->GC);
entries.Add(&this->UnexpectedStubMiss); entries.Add(&this->UnexpectedStubMiss);
......
...@@ -501,12 +501,12 @@ class RuntimeCallTimer { ...@@ -501,12 +501,12 @@ class RuntimeCallTimer {
counter_ = counter; counter_ = counter;
parent_ = parent; parent_ = parent;
timer_.Start(); timer_.Start();
counter_->count++;
} }
inline RuntimeCallTimer* Stop() { inline RuntimeCallTimer* Stop() {
base::TimeDelta delta = timer_.Elapsed(); base::TimeDelta delta = timer_.Elapsed();
timer_.Stop(); timer_.Stop();
counter_->count++;
counter_->time += delta; counter_->time += delta;
if (parent_ != NULL) { if (parent_ != NULL) {
// Adjust parent timer so that it does not include sub timer's time. // Adjust parent timer so that it does not include sub timer's time.
...@@ -520,6 +520,46 @@ class RuntimeCallTimer { ...@@ -520,6 +520,46 @@ class RuntimeCallTimer {
base::ElapsedTimer timer_; base::ElapsedTimer timer_;
}; };
#define FOR_EACH_HANDLER_COUNTER(V) \
V(IC_HandlerCacheHit) \
V(KeyedLoadIC_LoadIndexedStringStub) \
V(KeyedLoadIC_LoadIndexedInterceptorStub) \
V(KeyedLoadIC_KeyedLoadSloppyArgumentsStub) \
V(KeyedLoadIC_LoadFastElementStub) \
V(KeyedLoadIC_LoadDictionaryElementStub) \
V(KeyedLoadIC_PolymorphicElement) \
V(KeyedStoreIC_KeyedStoreSloppyArgumentsStub) \
V(KeyedStoreIC_StoreFastElementStub) \
V(KeyedStoreIC_StoreElementStub) \
V(KeyedStoreIC_Polymorphic) \
V(LoadIC_FunctionPrototypeStub) \
V(LoadIC_ArrayBufferViewLoadFieldStub) \
V(LoadIC_LoadApiGetterStub) \
V(LoadIC_LoadCallback) \
V(LoadIC_LoadConstant) \
V(LoadIC_LoadConstantStub) \
V(LoadIC_LoadField) \
V(LoadIC_LoadFieldStub) \
V(LoadIC_LoadGlobal) \
V(LoadIC_LoadInterceptor) \
V(LoadIC_LoadNonexistent) \
V(LoadIC_LoadNormal) \
V(LoadIC_LoadScriptContextFieldStub) \
V(LoadIC_LoadViaGetter) \
V(LoadIC_SlowStub) \
V(LoadIC_StringLengthStub) \
V(StoreIC_SlowStub) \
V(StoreIC_StoreCallback) \
V(StoreIC_StoreField) \
V(StoreIC_StoreFieldStub) \
V(StoreIC_StoreGlobal) \
V(StoreIC_StoreGlobalTransition) \
V(StoreIC_StoreInterceptorStub) \
V(StoreIC_StoreNormal) \
V(StoreIC_StoreScriptContextFieldStub) \
V(StoreIC_StoreTransition) \
V(StoreIC_StoreViaSetter)
class RuntimeCallStats { class RuntimeCallStats {
public: public:
typedef RuntimeCallCounter RuntimeCallStats::*CounterId; typedef RuntimeCallCounter RuntimeCallStats::*CounterId;
...@@ -538,6 +578,10 @@ class RuntimeCallStats { ...@@ -538,6 +578,10 @@ class RuntimeCallStats {
RuntimeCallCounter Builtin_##name = RuntimeCallCounter(#name); RuntimeCallCounter Builtin_##name = RuntimeCallCounter(#name);
BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) BUILTIN_LIST_C(CALL_BUILTIN_COUNTER)
#undef CALL_BUILTIN_COUNTER #undef CALL_BUILTIN_COUNTER
#define CALL_BUILTIN_COUNTER(name) \
RuntimeCallCounter Handler_##name = RuntimeCallCounter(#name);
FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER)
#undef CALL_BUILTIN_COUNTER
// Starting measuring the time for a function. This will establish the // Starting measuring the time for a function. This will establish the
// connection to the parent counter for properly calculating the own times. // connection to the parent counter for properly calculating the own times.
...@@ -549,6 +593,10 @@ class RuntimeCallStats { ...@@ -549,6 +593,10 @@ class RuntimeCallStats {
// parent. // parent.
static void Leave(Isolate* isolate, RuntimeCallTimer* timer); static void Leave(Isolate* isolate, RuntimeCallTimer* timer);
// Set counter id for the innermost measurement. It can be used to refine
// event kind when a runtime entry counter is too generic.
static void CorrectCurrentCounterId(Isolate* isolate, CounterId counter_id);
void Reset(); void Reset();
void Print(std::ostream& os); void Print(std::ostream& os);
...@@ -559,6 +607,17 @@ class RuntimeCallStats { ...@@ -559,6 +607,17 @@ class RuntimeCallStats {
RuntimeCallTimer* current_timer_ = NULL; RuntimeCallTimer* current_timer_ = NULL;
}; };
#define TRACE_RUNTIME_CALL_STATS(isolate, counter_name) \
do { \
if (FLAG_runtime_call_stats) { \
RuntimeCallStats::CorrectCurrentCounterId( \
isolate, &RuntimeCallStats::counter_name); \
} \
} while (false)
#define TRACE_HANDLER_STATS(isolate, counter_name) \
TRACE_RUNTIME_CALL_STATS(isolate, Handler_##counter_name)
// A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the
// the time of C++ scope. // the time of C++ scope.
class RuntimeCallTimerScope { class RuntimeCallTimerScope {
......
...@@ -67,6 +67,7 @@ Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent( ...@@ -67,6 +67,7 @@ Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
cache_name, stub_holder_map, Code::LOAD_IC, flag); cache_name, stub_holder_map, Code::LOAD_IC, flag);
if (!handler.is_null()) return handler; if (!handler.is_null()) return handler;
TRACE_HANDLER_STATS(isolate, LoadIC_LoadNonexistent);
NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag); NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag);
handler = compiler.CompileLoadNonexistent(cache_name); handler = compiler.CompileLoadNonexistent(cache_name);
Map::UpdateCodeCache(stub_holder_map, cache_name, handler); Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
......
...@@ -26,17 +26,22 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler( ...@@ -26,17 +26,22 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
*receiver_map == isolate->get_initial_js_array_map(elements_kind); *receiver_map == isolate->get_initial_js_array_map(elements_kind);
Handle<Code> stub; Handle<Code> stub;
if (receiver_map->has_indexed_interceptor()) { if (receiver_map->has_indexed_interceptor()) {
TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadIndexedInterceptorStub);
stub = LoadIndexedInterceptorStub(isolate).GetCode(); stub = LoadIndexedInterceptorStub(isolate).GetCode();
} else if (receiver_map->IsStringMap()) { } else if (receiver_map->IsStringMap()) {
TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadIndexedStringStub);
stub = LoadIndexedStringStub(isolate).GetCode(); stub = LoadIndexedStringStub(isolate).GetCode();
} else if (receiver_map->has_sloppy_arguments_elements()) { } else if (receiver_map->has_sloppy_arguments_elements()) {
TRACE_HANDLER_STATS(isolate, KeyedLoadIC_KeyedLoadSloppyArgumentsStub);
stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode(); stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode();
} else if (receiver_map->has_fast_elements() || } else if (receiver_map->has_fast_elements() ||
receiver_map->has_fixed_typed_array_elements()) { receiver_map->has_fixed_typed_array_elements()) {
TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadFastElementStub);
stub = LoadFastElementStub(isolate, is_js_array, elements_kind, stub = LoadFastElementStub(isolate, is_js_array, elements_kind,
convert_hole_to_undefined).GetCode(); convert_hole_to_undefined).GetCode();
} else { } else {
DCHECK(receiver_map->has_dictionary_elements()); DCHECK(receiver_map->has_dictionary_elements());
TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadDictionaryElementStub);
stub = LoadDictionaryElementStub(isolate, LoadICState(extra_ic_state)) stub = LoadDictionaryElementStub(isolate, LoadICState(extra_ic_state))
.GetCode(); .GetCode();
} }
...@@ -126,12 +131,15 @@ Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler( ...@@ -126,12 +131,15 @@ Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler(
bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
Handle<Code> stub; Handle<Code> stub;
if (receiver_map->has_sloppy_arguments_elements()) { if (receiver_map->has_sloppy_arguments_elements()) {
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_KeyedStoreSloppyArgumentsStub);
stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode(); stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
} else if (receiver_map->has_fast_elements() || } else if (receiver_map->has_fast_elements() ||
receiver_map->has_fixed_typed_array_elements()) { receiver_map->has_fixed_typed_array_elements()) {
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind, stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
store_mode).GetCode(); store_mode).GetCode();
} else { } else {
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode(); stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
} }
return stub; return stub;
......
...@@ -631,6 +631,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { ...@@ -631,6 +631,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
} }
if (use_ic && LoadScriptContextFieldStub::Accepted(&lookup_result)) { if (use_ic && LoadScriptContextFieldStub::Accepted(&lookup_result)) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadScriptContextFieldStub);
LoadScriptContextFieldStub stub(isolate(), &lookup_result); LoadScriptContextFieldStub stub(isolate(), &lookup_result);
PatchCache(name, stub.GetCode()); PatchCache(name, stub.GetCode());
} }
...@@ -835,6 +836,7 @@ Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate, ...@@ -835,6 +836,7 @@ Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate,
Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub);
LoadFieldStub stub(isolate(), index); LoadFieldStub stub(isolate(), index);
return stub.GetCode(); return stub.GetCode();
} }
...@@ -946,7 +948,10 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { ...@@ -946,7 +948,10 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
if (!code.is_null()) { if (!code.is_null()) {
Handle<Code> handler; Handle<Code> handler;
if (maybe_handler_.ToHandle(&handler)) { if (maybe_handler_.ToHandle(&handler)) {
if (!handler.is_identical_to(code)) return code; if (!handler.is_identical_to(code)) {
TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
return code;
}
} else { } else {
// maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs. // maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs.
// In MEGAMORPHIC case, check if the handler in the megamorphic stub // In MEGAMORPHIC case, check if the handler in the megamorphic stub
...@@ -955,8 +960,12 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { ...@@ -955,8 +960,12 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
Map* map = Handle<HeapObject>::cast(lookup->GetReceiver())->map(); Map* map = Handle<HeapObject>::cast(lookup->GetReceiver())->map();
Code* megamorphic_cached_code = Code* megamorphic_cached_code =
isolate()->stub_cache()->Get(*lookup->name(), map, code->flags()); isolate()->stub_cache()->Get(*lookup->name(), map, code->flags());
if (megamorphic_cached_code != *code) return code; if (megamorphic_cached_code != *code) {
TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
return code;
}
} else { } else {
TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
return code; return code;
} }
} }
...@@ -992,6 +1001,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -992,6 +1001,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
if (receiver->IsStringWrapper() && if (receiver->IsStringWrapper() &&
Name::Equals(isolate()->factory()->length_string(), lookup->name())) { Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
TRACE_HANDLER_STATS(isolate(), LoadIC_StringLengthStub);
StringLengthStub string_length_stub(isolate()); StringLengthStub string_length_stub(isolate());
return string_length_stub.GetCode(); return string_length_stub.GetCode();
} }
...@@ -1004,6 +1014,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1004,6 +1014,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
->map() ->map()
->has_non_instance_prototype()) { ->has_non_instance_prototype()) {
Handle<Code> stub; Handle<Code> stub;
TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub);
FunctionPrototypeStub function_prototype_stub(isolate()); FunctionPrototypeStub function_prototype_stub(isolate());
return function_prototype_stub.GetCode(); return function_prototype_stub.GetCode();
} }
...@@ -1014,6 +1025,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1014,6 +1025,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
switch (lookup->state()) { switch (lookup->state()) {
case LookupIterator::INTERCEPTOR: { case LookupIterator::INTERCEPTOR: {
DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined()); DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined());
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptor);
NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
// Perform a lookup behind the interceptor. Copy the LookupIterator since // Perform a lookup behind the interceptor. Copy the LookupIterator since
// the original iterator will be used to fetch the value. // the original iterator will be used to fetch the value.
...@@ -1035,6 +1047,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1035,6 +1047,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
} }
if (Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(), if (Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(),
&object_offset)) { &object_offset)) {
TRACE_HANDLER_STATS(isolate(), LoadIC_ArrayBufferViewLoadFieldStub);
FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map);
ArrayBufferViewLoadFieldStub stub(isolate(), index); ArrayBufferViewLoadFieldStub stub(isolate(), index);
return stub.GetCode(); return stub.GetCode();
...@@ -1052,10 +1065,12 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1052,10 +1065,12 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
NamedLoadHandlerCompiler compiler(isolate(), map, holder, NamedLoadHandlerCompiler compiler(isolate(), map, holder,
cache_holder); cache_holder);
if (call_optimization.is_simple_api_call()) { if (call_optimization.is_simple_api_call()) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback);
int index = lookup->GetAccessorIndex(); int index = lookup->GetAccessorIndex();
return compiler.CompileLoadCallback(lookup->name(), return compiler.CompileLoadCallback(lookup->name(),
call_optimization, index); call_optimization, index);
} }
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadViaGetter);
int expected_arguments = Handle<JSFunction>::cast(getter) int expected_arguments = Handle<JSFunction>::cast(getter)
->shared() ->shared()
->internal_formal_parameter_count(); ->internal_formal_parameter_count();
...@@ -1071,11 +1086,13 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1071,11 +1086,13 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
} }
if (!holder->HasFastProperties()) break; if (!holder->HasFastProperties()) break;
if (receiver_is_holder) { if (receiver_is_holder) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterStub);
int index = lookup->GetAccessorIndex(); int index = lookup->GetAccessorIndex();
LoadApiGetterStub stub(isolate(), true, index); LoadApiGetterStub stub(isolate(), true, index);
return stub.GetCode(); return stub.GetCode();
} }
if (info->is_sloppy() && !receiver->IsJSReceiver()) break; if (info->is_sloppy() && !receiver->IsJSReceiver()) break;
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback);
NamedLoadHandlerCompiler compiler(isolate(), map, holder, NamedLoadHandlerCompiler compiler(isolate(), map, holder,
cache_holder); cache_holder);
return compiler.CompileLoadCallback(lookup->name(), info); return compiler.CompileLoadCallback(lookup->name(), info);
...@@ -1088,6 +1105,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1088,6 +1105,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
if (lookup->is_dictionary_holder()) { if (lookup->is_dictionary_holder()) {
if (kind() != Code::LOAD_IC) break; if (kind() != Code::LOAD_IC) break;
if (holder->IsJSGlobalObject()) { if (holder->IsJSGlobalObject()) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal);
NamedLoadHandlerCompiler compiler(isolate(), map, holder, NamedLoadHandlerCompiler compiler(isolate(), map, holder,
cache_holder); cache_holder);
Handle<PropertyCell> cell = lookup->GetPropertyCell(); Handle<PropertyCell> cell = lookup->GetPropertyCell();
...@@ -1105,6 +1123,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1105,6 +1123,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
// property must be found in the object for the stub to be // property must be found in the object for the stub to be
// applicable. // applicable.
if (!receiver_is_holder) break; if (!receiver_is_holder) break;
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal);
return isolate()->builtins()->LoadIC_Normal(); return isolate()->builtins()->LoadIC_Normal();
} }
...@@ -1114,6 +1133,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1114,6 +1133,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
if (receiver_is_holder) { if (receiver_is_holder) {
return SimpleFieldLoad(field); return SimpleFieldLoad(field);
} }
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadField);
NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
return compiler.CompileLoadField(lookup->name(), field); return compiler.CompileLoadField(lookup->name(), field);
} }
...@@ -1121,16 +1141,18 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1121,16 +1141,18 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
// -------------- Constant properties -------------- // -------------- Constant properties --------------
DCHECK(lookup->property_details().type() == DATA_CONSTANT); DCHECK(lookup->property_details().type() == DATA_CONSTANT);
if (receiver_is_holder) { if (receiver_is_holder) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub);
LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); LoadConstantStub stub(isolate(), lookup->GetConstantIndex());
return stub.GetCode(); return stub.GetCode();
} }
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstant);
NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
return compiler.CompileLoadConstant(lookup->name(), return compiler.CompileLoadConstant(lookup->name(),
lookup->GetConstantIndex()); lookup->GetConstantIndex());
} }
case LookupIterator::INTEGER_INDEXED_EXOTIC: case LookupIterator::INTEGER_INDEXED_EXOTIC:
return slow_stub(); break;
case LookupIterator::ACCESS_CHECK: case LookupIterator::ACCESS_CHECK:
case LookupIterator::JSPROXY: case LookupIterator::JSPROXY:
case LookupIterator::NOT_FOUND: case LookupIterator::NOT_FOUND:
...@@ -1138,6 +1160,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, ...@@ -1138,6 +1160,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
UNREACHABLE(); UNREACHABLE();
} }
TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
return slow_stub(); return slow_stub();
} }
...@@ -1224,6 +1247,7 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) { ...@@ -1224,6 +1247,7 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) {
} }
CodeHandleList handlers(target_receiver_maps.length()); CodeHandleList handlers(target_receiver_maps.length());
TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_PolymorphicElement);
ElementHandlerCompiler compiler(isolate()); ElementHandlerCompiler compiler(isolate());
compiler.CompileElementHandlers(&target_receiver_maps, &handlers); compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
ConfigureVectorState(Handle<Name>(), &target_receiver_maps, &handlers); ConfigureVectorState(Handle<Name>(), &target_receiver_maps, &handlers);
...@@ -1389,6 +1413,7 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, ...@@ -1389,6 +1413,7 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
if (FLAG_use_ic && if (FLAG_use_ic &&
StoreScriptContextFieldStub::Accepted(&lookup_result)) { StoreScriptContextFieldStub::Accepted(&lookup_result)) {
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreScriptContextFieldStub);
StoreScriptContextFieldStub stub(isolate(), &lookup_result); StoreScriptContextFieldStub stub(isolate(), &lookup_result);
PatchCache(name, stub.GetCode()); PatchCache(name, stub.GetCode());
} }
...@@ -1503,6 +1528,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1503,6 +1528,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
auto store_target = lookup->GetStoreTarget(); auto store_target = lookup->GetStoreTarget();
if (store_target->IsJSGlobalObject()) { if (store_target->IsJSGlobalObject()) {
// TODO(dcarney): this currently just deopts. Use the transition cell. // TODO(dcarney): this currently just deopts. Use the transition cell.
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransition);
auto cell = isolate()->factory()->NewPropertyCell(); auto cell = isolate()->factory()->NewPropertyCell();
cell->set_value(*value); cell->set_value(*value);
auto code = PropertyCellStoreHandler( auto code = PropertyCellStoreHandler(
...@@ -1519,12 +1545,14 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1519,12 +1545,14 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
} }
DCHECK(lookup->IsCacheableTransition()); DCHECK(lookup->IsCacheableTransition());
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransition);
NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
return compiler.CompileStoreTransition(transition, lookup->name()); return compiler.CompileStoreTransition(transition, lookup->name());
} }
case LookupIterator::INTERCEPTOR: { case LookupIterator::INTERCEPTOR: {
DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined());
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub);
StoreInterceptorStub stub(isolate()); StoreInterceptorStub stub(isolate());
return stub.GetCode(); return stub.GetCode();
} }
...@@ -1553,6 +1581,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1553,6 +1581,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
break; break;
} }
if (info->is_sloppy() && !receiver->IsJSReceiver()) break; if (info->is_sloppy() && !receiver->IsJSReceiver()) break;
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback);
NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
return compiler.CompileStoreCallback(receiver, lookup->name(), info, return compiler.CompileStoreCallback(receiver, lookup->name(), info,
language_mode()); language_mode());
...@@ -1567,6 +1596,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1567,6 +1596,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
if (call_optimization.is_simple_api_call()) { if (call_optimization.is_simple_api_call()) {
if (call_optimization.IsCompatibleReceiver(receiver, holder)) { if (call_optimization.IsCompatibleReceiver(receiver, holder)) {
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback);
return compiler.CompileStoreCallback(receiver, lookup->name(), return compiler.CompileStoreCallback(receiver, lookup->name(),
call_optimization, call_optimization,
lookup->GetAccessorIndex()); lookup->GetAccessorIndex());
...@@ -1574,6 +1604,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1574,6 +1604,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver"); TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver");
break; break;
} }
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreViaSetter);
int expected_arguments = JSFunction::cast(*setter) int expected_arguments = JSFunction::cast(*setter)
->shared() ->shared()
->internal_formal_parameter_count(); ->internal_formal_parameter_count();
...@@ -1587,6 +1618,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1587,6 +1618,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
case LookupIterator::DATA: { case LookupIterator::DATA: {
if (lookup->is_dictionary_holder()) { if (lookup->is_dictionary_holder()) {
if (holder->IsJSGlobalObject()) { if (holder->IsJSGlobalObject()) {
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobal);
DCHECK(holder.is_identical_to(receiver) || DCHECK(holder.is_identical_to(receiver) ||
receiver->map()->prototype() == *holder); receiver->map()->prototype() == *holder);
auto cell = lookup->GetPropertyCell(); auto cell = lookup->GetPropertyCell();
...@@ -1597,6 +1629,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1597,6 +1629,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
lookup->name(), cell, updated_type); lookup->name(), cell, updated_type);
return code; return code;
} }
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal);
DCHECK(holder.is_identical_to(receiver)); DCHECK(holder.is_identical_to(receiver));
return isolate()->builtins()->StoreIC_Normal(); return isolate()->builtins()->StoreIC_Normal();
} }
...@@ -1610,10 +1643,12 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1610,10 +1643,12 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
use_stub = !field_type->IsClass(); use_stub = !field_type->IsClass();
} }
if (use_stub) { if (use_stub) {
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub);
StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
lookup->representation()); lookup->representation());
return stub.GetCode(); return stub.GetCode();
} }
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField);
NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
return compiler.CompileStoreField(lookup); return compiler.CompileStoreField(lookup);
} }
...@@ -1630,6 +1665,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1630,6 +1665,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
case LookupIterator::NOT_FOUND: case LookupIterator::NOT_FOUND:
UNREACHABLE(); UNREACHABLE();
} }
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
return slow_stub(); return slow_stub();
} }
...@@ -1749,6 +1785,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, ...@@ -1749,6 +1785,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
} }
} }
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_Polymorphic);
MapHandleList transitioned_maps(target_receiver_maps.length()); MapHandleList transitioned_maps(target_receiver_maps.length());
CodeHandleList handlers(target_receiver_maps.length()); CodeHandleList handlers(target_receiver_maps.length());
PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment