Chromium Code Reviews| Index: src/ic/ic.cc |
| diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
| index 93164f9d4affdaa4bd69454bc2f6cdb797daeefb..66a490ac4efeb052fd9852a9f8c9c5cdb4d6ce1c 100644 |
| --- a/src/ic/ic.cc |
| +++ b/src/ic/ic.cc |
| @@ -21,6 +21,7 @@ |
| #include "src/ic/handler-configuration-inl.h" |
| #include "src/ic/ic-compiler.h" |
| #include "src/ic/ic-inl.h" |
| +#include "src/ic/ic-stats.h" |
| #include "src/ic/stub-cache.h" |
| #include "src/isolate-inl.h" |
| #include "src/macro-assembler.h" |
| @@ -29,6 +30,7 @@ |
| #include "src/runtime/runtime-utils.h" |
| #include "src/runtime/runtime.h" |
| #include "src/tracing/trace-event.h" |
| +#include "src/tracing/tracing-category-observer.h" |
| namespace v8 { |
| namespace internal { |
| @@ -90,7 +92,7 @@ const char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) { |
| void IC::TraceIC(const char* type, Handle<Object> name) { |
| - if (FLAG_trace_ic) { |
| + if (FLAG_ic_stats) { |
| if (AddressIsDeoptimizedCode()) return; |
| DCHECK(UseVector()); |
| State new_state = nexus()->StateFromFeedback(); |
| @@ -101,8 +103,17 @@ void IC::TraceIC(const char* type, Handle<Object> name) { |
| void IC::TraceIC(const char* type, Handle<Object> name, State old_state, |
| State new_state) { |
| - if (!FLAG_trace_ic) return; |
| - PrintF("[%s%s in ", is_keyed() ? "Keyed" : "", type); |
| + if (V8_LIKELY(!FLAG_ic_stats)) return; |
| + |
| + if (FLAG_ic_stats & |
|
Camillo Bruni
2016/12/02 12:12:55
no need to recheck the flag
lpy
2016/12/05 17:49:11
same here, we want to check whether the flag is en
|
| + v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { |
| + ICStats::instance()->Begin(); |
| + ICInfo& ic_info = ICStats::instance()->Current(); |
| + ic_info.type = is_keyed() ? "Keyed" : ""; |
| + ic_info.type += type; |
| + } else if (FLAG_ic_stats) { |
|
Camillo Bruni
2016/12/02 12:12:55
same here.
lpy
2016/12/05 17:49:11
see explanation above
|
| + PrintF("[%s%s in ", is_keyed() ? "Keyed" : "", type); |
| + } |
| // TODO(jkummerow): Add support for "apply". The logic is roughly: |
| // marker = [fp_ + kMarkerOffset]; |
| @@ -121,8 +132,14 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state, |
| code_offset = |
| static_cast<int>(pc() - function->code()->instruction_start()); |
| } |
| - JavaScriptFrame::PrintFunctionAndOffset(function, function->abstract_code(), |
| - code_offset, stdout, true); |
| + if (FLAG_ic_stats & |
| + v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { |
| + JavaScriptFrame::CollectFunctionAndOffsetForICStats( |
| + function, function->abstract_code(), code_offset); |
| + } else if (FLAG_ic_stats) { |
| + JavaScriptFrame::PrintFunctionAndOffset( |
| + function, function->abstract_code(), code_offset, stdout, true); |
| + } |
| } |
| const char* modifier = ""; |
| @@ -135,17 +152,43 @@ void IC::TraceIC(const char* type, Handle<Object> name, State old_state, |
| if (!receiver_map().is_null()) { |
| map = *receiver_map(); |
| } |
| - PrintF(" (%c->%c%s) map=(%p", TransitionMarkFromState(old_state), |
| - TransitionMarkFromState(new_state), modifier, |
| - reinterpret_cast<void*>(map)); |
| + if (FLAG_ic_stats & |
| + v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { |
| + ICInfo& ic_info = ICStats::instance()->Current(); |
| + ic_info.state = "("; |
|
Camillo Bruni
2016/12/02 12:12:55
I'm not too familiar with the C++ standard library
lpy
2016/12/05 17:49:11
Done.
|
| + ic_info.state += TransitionMarkFromState(old_state); |
| + ic_info.state += "->"; |
| + ic_info.state += TransitionMarkFromState(new_state); |
| + ic_info.state += modifier; |
| + ic_info.state += ")"; |
| + ic_info.map = reinterpret_cast<void*>(map); |
| + } else if (FLAG_ic_stats) { |
| + PrintF(" (%c->%c%s) map=(%p", TransitionMarkFromState(old_state), |
| + TransitionMarkFromState(new_state), modifier, |
| + reinterpret_cast<void*>(map)); |
| + } |
| if (map != nullptr) { |
| - PrintF(" dict=%u own=%u type=", map->is_dictionary_map(), |
| - map->NumberOfOwnDescriptors()); |
| - std::cout << map->instance_type(); |
| + if (FLAG_ic_stats & |
| + v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { |
| + ICInfo& ic_info = ICStats::instance()->Current(); |
| + ic_info.dict = map->is_dictionary_map(); |
| + ic_info.own = map->NumberOfOwnDescriptors(); |
| + ic_info.instance_type = std::to_string(map->instance_type()); |
| + } else if (FLAG_ic_stats) { |
| + PrintF(" dict=%u own=%u type=", map->is_dictionary_map(), |
| + map->NumberOfOwnDescriptors()); |
| + std::cout << map->instance_type(); |
| + } |
| + } |
| + if (FLAG_ic_stats & |
| + v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { |
| + // TODO(lpy) Add name as key field in ICStats. |
| + ICStats::instance()->End(); |
| + } else if (FLAG_ic_stats) { |
| + PrintF(") "); |
| + name->ShortPrint(stdout); |
| + PrintF("]\n"); |
| } |
| - PrintF(") "); |
| - name->ShortPrint(stdout); |
| - PrintF("]\n"); |
| } |
| @@ -2912,7 +2955,19 @@ MaybeHandle<Object> BinaryOpIC::Transition( |
| } |
| set_target(*new_target); |
| - if (FLAG_trace_ic) { |
| + if (FLAG_ic_stats & |
| + v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { |
| + auto ic_stats = ICStats::instance(); |
| + ic_stats->Begin(); |
| + ICInfo& ic_info = ic_stats->Current(); |
| + ic_info.type = "BinaryOpIC"; |
| + ic_info.state = old_state.ToString(); |
| + ic_info.state += " => "; |
| + ic_info.state += state.ToString(); |
| + JavaScriptFrame::CollectTopFrameForICStats(isolate()); |
| + ic_stats->End(); |
| + } else if (FLAG_ic_stats) { |
| + // if (FLAG_trace_ic) { |
| OFStream os(stdout); |
| os << "[BinaryOpIC" << old_state << " => " << state << " @ " |
| << static_cast<void*>(*new_target) << " <- "; |
| @@ -2986,7 +3041,30 @@ Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { |
| Handle<Code> new_target = stub.GetCode(); |
| set_target(*new_target); |
| - if (FLAG_trace_ic) { |
| + if (FLAG_ic_stats & |
| + v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { |
| + auto ic_stats = ICStats::instance(); |
| + ic_stats->Begin(); |
| + ICInfo& ic_info = ic_stats->Current(); |
| + ic_info.type = "CompareIC"; |
| + JavaScriptFrame::CollectTopFrameForICStats(isolate()); |
| + ic_info.state = "(("; |
| + ic_info.state += CompareICState::GetStateName(old_stub.left()); |
| + ic_info.state += "+"; |
| + ic_info.state += CompareICState::GetStateName(old_stub.right()); |
| + ic_info.state += "="; |
| + ic_info.state += CompareICState::GetStateName(old_stub.state()); |
| + ic_info.state += ")->("; |
| + ic_info.state += CompareICState::GetStateName(new_left); |
| + ic_info.state += "+"; |
| + ic_info.state += CompareICState::GetStateName(new_right); |
| + ic_info.state += "="; |
| + ic_info.state += CompareICState::GetStateName(state); |
| + ic_info.state += "))#"; |
| + ic_info.state += Token::Name(op_); |
| + ic_stats->End(); |
| + } else if (FLAG_ic_stats) { |
| + // if (FLAG_trace_ic) { |
| PrintF("[CompareIC in "); |
| JavaScriptFrame::PrintTop(isolate(), stdout, false, true); |
| PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", |