| Index: src/ic/ic.cc
|
| diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
| index 93164f9d4affdaa4bd69454bc2f6cdb797daeefb..022fa73b50a9d97cc4a4aeacb62d2d4a41424ee3 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 &
|
| + 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 {
|
| + 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 {
|
| + JavaScriptFrame::PrintFunctionAndOffset(
|
| + function, function->abstract_code(), code_offset, stdout, true);
|
| + }
|
| }
|
|
|
| const char* modifier = "";
|
| @@ -135,17 +152,45 @@ 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();
|
| + // Reverse enough space for IC transition state, the longest length is 17.
|
| + ic_info.state.reserve(17);
|
| + ic_info.state = "(";
|
| + 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 {
|
| + 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.is_dictionary_map = map->is_dictionary_map();
|
| + ic_info.number_of_own_descriptors = map->NumberOfOwnDescriptors();
|
| + ic_info.instance_type = std::to_string(map->instance_type());
|
| + } else {
|
| + 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 {
|
| + PrintF(") ");
|
| + name->ShortPrint(stdout);
|
| + PrintF("]\n");
|
| }
|
| - PrintF(") ");
|
| - name->ShortPrint(stdout);
|
| - PrintF("]\n");
|
| }
|
|
|
|
|
| @@ -2912,7 +2957,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 +3043,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",
|
|
|