5 #include "src/ic/ic-stats.h" 8 #include "src/objects-inl.h" 9 #include "src/tracing/trace-event.h" 10 #include "src/tracing/traced-value.h" 16 base::LazyInstance<ICStats>::type ICStats::instance_ =
17 LAZY_INSTANCE_INITIALIZER;
19 ICStats::ICStats() : ic_infos_(MAX_IC_INFO), pos_(0) {
20 base::Relaxed_Store(&enabled_, 0);
23 void ICStats::Begin() {
24 if (V8_LIKELY(!FLAG_ic_stats))
return;
25 base::Relaxed_Store(&enabled_, 1);
29 if (base::Relaxed_Load(&enabled_) != 1)
return;
31 if (pos_ == MAX_IC_INFO) {
34 base::Relaxed_Store(&enabled_, 0);
37 void ICStats::Reset() {
38 for (
auto ic_info : ic_infos_) {
44 void ICStats::Dump() {
45 auto value = v8::tracing::TracedValue::Create();
46 value->BeginArray(
"data");
47 for (
int i = 0;
i < pos_; ++
i) {
48 ic_infos_[
i].AppendToTracedValue(value.get());
52 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT(
"v8.ic_stats"),
"V8.ICStats",
53 TRACE_EVENT_SCOPE_THREAD,
"ic-stats", std::move(value));
57 const char* ICStats::GetOrCacheScriptName(Script* script) {
58 if (script_name_map_.find(script) != script_name_map_.end()) {
59 return script_name_map_[script].get();
61 Object* script_name_raw = script->name();
62 if (script_name_raw->IsString()) {
63 String script_name = String::cast(script_name_raw);
65 script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)
67 script_name_map_.insert(
68 std::make_pair(script, std::unique_ptr<
char[]>(c_script_name)));
71 script_name_map_.insert(
72 std::make_pair(script, std::unique_ptr<
char[]>(
nullptr)));
78 const char* ICStats::GetOrCacheFunctionName(JSFunction*
function) {
79 if (function_name_map_.find(
function) != function_name_map_.end()) {
80 return function_name_map_[
function].get();
82 SharedFunctionInfo* shared =
function->shared();
83 ic_infos_[pos_].is_optimized =
function->IsOptimized();
84 char* function_name = shared->DebugName()->ToCString().release();
85 function_name_map_.insert(
86 std::make_pair(
function, std::unique_ptr<
char[]>(function_name)));
91 : function_name(nullptr),
95 is_constructor(false),
98 is_dictionary_map(false),
99 number_of_own_descriptors(0) {}
101 void ICInfo::Reset() {
103 function_name =
nullptr;
105 script_name =
nullptr;
107 is_constructor =
false;
108 is_optimized =
false;
111 is_dictionary_map =
false;
112 number_of_own_descriptors = 0;
113 instance_type.clear();
117 value->BeginDictionary();
118 value->SetString(
"type", type);
120 value->SetString(
"functionName", function_name);
122 value->SetInteger(
"optimized", is_optimized);
125 if (script_offset) value->SetInteger(
"offset", script_offset);
126 if (script_name) value->SetString(
"scriptName", script_name);
127 if (line_num != -1) value->SetInteger(
"lineNum", line_num);
128 if (is_constructor) value->SetInteger(
"constructor", is_constructor);
129 if (!state.empty()) value->SetString(
"state", state);
133 std::stringstream ss;
135 value->SetString(
"map", ss.str());
137 if (map) value->SetInteger(
"dict", is_dictionary_map);
138 if (map) value->SetInteger(
"own", number_of_own_descriptors);
139 if (!instance_type.empty()) value->SetString(
"instanceType", instance_type);
140 value->EndDictionary();