Commit 6bc71431 authored by cbruni's avatar cbruni Committed by Commit bot

[counters] moving runtime counters to counter.h

Additionally list C++ builtins as well under --runtime_call_stats.
Let's try to keep all counters in one place, that makes it a bit
easier to maintain and especially discard unused ones.

BUG=

Review URL: https://codereview.chromium.org/1678973002

Cr-Commit-Position: refs/heads/master@{#33847}
parent e932c0e7
...@@ -273,32 +273,30 @@ double ClobberDoubleRegisters(double x1, double x2, double x3, double x4); ...@@ -273,32 +273,30 @@ double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
#define CLOBBER_DOUBLE_REGISTERS() #define CLOBBER_DOUBLE_REGISTERS()
#endif #endif
#define RUNTIME_FUNCTION_RETURNS_TYPE(Type, Name) \
#define RUNTIME_FUNCTION_RETURNS_TYPE(Type, Name) \ static INLINE(Type __RT_impl_##Name(Arguments args, Isolate* isolate)); \
static INLINE(Type __RT_impl_##Name(Arguments args, Isolate* isolate)); \ Type Name(int args_length, Object** args_object, Isolate* isolate) { \
Type Name(int args_length, Object** args_object, Isolate* isolate) { \ CLOBBER_DOUBLE_REGISTERS(); \
CLOBBER_DOUBLE_REGISTERS(); \ RuntimeCallStats* stats = isolate->counters()->runtime_call_stats(); \
RuntimeCallStats* stats = isolate->runtime_state()->runtime_call_stats(); \ stats->Count_##Name++; \
stats->Count_##Name++; \ base::ElapsedTimer timer; \
base::ElapsedTimer timer; \ bool timing = false; \
bool timing = false; \ if (FLAG_runtime_call_stats && !stats->in_runtime_call) { \
if (FLAG_runtime_call_stats && !stats->in_runtime_call) { \ stats->in_runtime_call = true; \
stats->in_runtime_call = true; \ timing = true; \
timing = true; \ timer.Start(); \
timer.Start(); \ } \
} \ Arguments args(args_length, args_object); \
Arguments args(args_length, args_object); \ Type value = __RT_impl_##Name(args, isolate); \
Type value = __RT_impl_##Name(args, isolate); \ if (timing) { \
if (timing) { \ stats->in_runtime_call = false; \
stats->in_runtime_call = false; \ isolate->counters()->runtime_call_stats()->Time_##Name += \
isolate->runtime_state()->runtime_call_stats()->Time_##Name += \ timer.Elapsed(); \
timer.Elapsed(); \ } \
} \ return value; \
return value; \ } \
} \
static Type __RT_impl_##Name(Arguments args, Isolate* isolate) static Type __RT_impl_##Name(Arguments args, Isolate* isolate)
#define RUNTIME_FUNCTION(Name) RUNTIME_FUNCTION_RETURNS_TYPE(Object*, Name) #define RUNTIME_FUNCTION(Name) RUNTIME_FUNCTION_RETURNS_TYPE(Object*, Name)
#define RUNTIME_FUNCTION_RETURN_PAIR(Name) \ #define RUNTIME_FUNCTION_RETURN_PAIR(Name) \
RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name) RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name)
......
...@@ -139,10 +139,26 @@ BUILTIN_LIST_C(DEF_ARG_TYPE) ...@@ -139,10 +139,26 @@ BUILTIN_LIST_C(DEF_ARG_TYPE)
Isolate* isolate); \ Isolate* isolate); \
MUST_USE_RESULT static Object* Builtin_##name( \ MUST_USE_RESULT static Object* Builtin_##name( \
int args_length, Object** args_object, Isolate* isolate) { \ int args_length, Object** args_object, Isolate* isolate) { \
RuntimeCallStats* stats = isolate->counters()->runtime_call_stats(); \
stats->Count_Builtin_##name++; \
base::ElapsedTimer timer; \
bool timing = false; \
if (FLAG_runtime_call_stats && !stats->in_runtime_call) { \
stats->in_runtime_call = true; \
timing = true; \
timer.Start(); \
} \
name##ArgumentsType args(args_length, args_object); \ name##ArgumentsType args(args_length, args_object); \
isolate->counters()->runtime_calls()->Increment(); \ isolate->counters()->runtime_calls()->Increment(); \
return Builtin_Impl_##name(args, isolate); \ Object* value = Builtin_Impl_##name(args, isolate); \
if (timing) { \
stats->in_runtime_call = false; \
isolate->counters()->runtime_call_stats()->Time_Builtin_##name += \
timer.Elapsed(); \
} \
return value; \
} \ } \
\
MUST_USE_RESULT static Object* Builtin_Impl_##name(name##ArgumentsType args, \ MUST_USE_RESULT static Object* Builtin_Impl_##name(name##ArgumentsType args, \
Isolate* isolate) Isolate* isolate)
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "src/counters.h" #include "src/counters.h"
#include <iomanip>
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/log-inl.h" #include "src/log-inl.h"
...@@ -193,5 +195,104 @@ void Counters::ResetHistograms() { ...@@ -193,5 +195,104 @@ void Counters::ResetHistograms() {
#undef HM #undef HM
} }
class RuntimeCallStatEntries {
public:
void Print(std::ostream& os) {
if (total_call_count > 0) {
std::sort(entries.rbegin(), entries.rend());
os << std::setw(50) << "Runtime Function/C++ Builtin" << std::setw(10)
<< "Time" << std::setw(18) << "Count" << std::endl
<< std::string(86, '=') << std::endl;
for (Entry& entry : entries) {
entry.SetTotal(total_time, total_call_count);
entry.Print(os);
}
os << std::string(86, '-') << std::endl;
Entry("Total", total_time, total_call_count).Print(os);
}
}
void Add(const char* name, base::TimeDelta time, uint32_t count) {
entries.push_back(Entry(name, time, count));
total_time += time;
total_call_count += count;
}
private:
class Entry {
public:
Entry(const char* name, base::TimeDelta time, uint64_t count)
: name_(name),
time_(time.InMilliseconds()),
count_(count),
time_percent_(100),
count_percent_(100) {}
bool operator<(const Entry& other) const {
if (time_ < other.time_) return true;
if (time_ > other.time_) return false;
return count_ < other.count_;
}
void Print(std::ostream& os) {
os.precision(2);
os << std::fixed;
os << std::setw(50) << name_;
os << std::setw(8) << time_ << "ms ";
os << std::setw(6) << time_percent_ << "%";
os << std::setw(10) << count_ << " ";
os << std::setw(6) << count_percent_ << "%";
os << std::endl;
}
void SetTotal(base::TimeDelta total_time, uint64_t total_count) {
time_percent_ = 100.0 * time_ / total_time.InMilliseconds();
count_percent_ = 100.0 * count_ / total_count;
}
private:
const char* name_;
int64_t time_;
uint64_t count_;
double time_percent_;
double count_percent_;
};
uint64_t total_call_count = 0;
base::TimeDelta total_time;
std::vector<Entry> entries;
};
void RuntimeCallStats::Print(std::ostream& os) {
RuntimeCallStatEntries entries;
#define PRINT_COUNTER(name, nargs, ressize) \
if (this->Count_Runtime_##name > 0) { \
entries.Add(#name, this->Time_Runtime_##name, this->Count_Runtime_##name); \
}
FOR_EACH_INTRINSIC(PRINT_COUNTER)
#undef PRINT_COUNTER
#define PRINT_COUNTER(name, type) \
if (this->Count_Builtin_##name > 0) { \
entries.Add(#name, this->Time_Builtin_##name, this->Count_Builtin_##name); \
}
BUILTIN_LIST_C(PRINT_COUNTER)
#undef PRINT_COUNTER
entries.Print(os);
}
void RuntimeCallStats::Reset() {
#define RESET_COUNTER(name, nargs, ressize) \
Count_Runtime_##name = 0; \
Time_Runtime_##name = base::TimeDelta();
FOR_EACH_INTRINSIC(RESET_COUNTER)
#undef RESET_COUNTER
#define RESET_COUNTER(name, type) \
Count_Builtin_##name = 0; \
Time_Builtin_##name = base::TimeDelta();
BUILTIN_LIST_C(RESET_COUNTER)
#undef RESET_COUNTER
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -9,8 +9,10 @@ ...@@ -9,8 +9,10 @@
#include "src/allocation.h" #include "src/allocation.h"
#include "src/base/platform/elapsed-timer.h" #include "src/base/platform/elapsed-timer.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/builtins.h"
#include "src/globals.h" #include "src/globals.h"
#include "src/objects.h" #include "src/objects.h"
#include "src/runtime/runtime.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -699,6 +701,30 @@ double AggregatedMemoryHistogram<Histogram>::Aggregate(double current_ms, ...@@ -699,6 +701,30 @@ double AggregatedMemoryHistogram<Histogram>::Aggregate(double current_ms,
/* Total count of functions compiled using the baseline compiler. */ \ /* Total count of functions compiled using the baseline compiler. */ \
SC(total_baseline_compile_count, V8.TotalBaselineCompileCount) SC(total_baseline_compile_count, V8.TotalBaselineCompileCount)
struct RuntimeCallStats {
#define CALL_RUNTIME_COUNTER(name, nargs, ressize) \
uint32_t Count_Runtime_##name; \
base::TimeDelta Time_Runtime_##name;
FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER)
#undef CALL_RUNTIME_COUNTER
#define CALL_BUILTIN_COUNTER(name, type) \
uint32_t Count_Builtin_##name; \
base::TimeDelta Time_Builtin_##name;
BUILTIN_LIST_C(CALL_BUILTIN_COUNTER)
#undef CALL_BUILTIN_COUNTER
// Dummy counter for the unexpected stub miss.
uint32_t Count_UnexpectedStubMiss;
base::TimeDelta Time_UnexpectedStubMiss;
bool in_runtime_call = false;
void Reset();
void Print(std::ostream& os);
RuntimeCallStats() { Reset(); }
};
// This file contains all the v8 counters that are in use. // This file contains all the v8 counters that are in use.
class Counters { class Counters {
public: public:
...@@ -809,6 +835,7 @@ class Counters { ...@@ -809,6 +835,7 @@ class Counters {
void ResetCounters(); void ResetCounters();
void ResetHistograms(); void ResetHistograms();
RuntimeCallStats* runtime_call_stats() { return &runtime_call_stats_; }
private: private:
#define HR(name, caption, min, max, num_buckets) Histogram name##_; #define HR(name, caption, min, max, num_buckets) Histogram name##_;
...@@ -870,6 +897,8 @@ class Counters { ...@@ -870,6 +897,8 @@ class Counters {
CODE_AGE_LIST_COMPLETE(SC) CODE_AGE_LIST_COMPLETE(SC)
#undef SC #undef SC
RuntimeCallStats runtime_call_stats_;
friend class Isolate; friend class Isolate;
explicit Counters(Isolate* isolate); explicit Counters(Isolate* isolate);
......
...@@ -2402,8 +2402,8 @@ void Isolate::DumpAndResetCompilationStats() { ...@@ -2402,8 +2402,8 @@ void Isolate::DumpAndResetCompilationStats() {
hstatistics_ = nullptr; hstatistics_ = nullptr;
if (FLAG_runtime_call_stats) { if (FLAG_runtime_call_stats) {
OFStream os(stdout); OFStream os(stdout);
runtime_state()->runtime_call_stats()->Print(os); counters()->runtime_call_stats()->Print(os);
runtime_state()->runtime_call_stats()->Reset(); counters()->runtime_call_stats()->Reset();
} }
} }
......
...@@ -482,10 +482,10 @@ RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) { ...@@ -482,10 +482,10 @@ RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(0, args.length()); DCHECK_EQ(0, args.length());
std::stringstream stats_stream; std::stringstream stats_stream;
isolate->runtime_state()->runtime_call_stats()->Print(stats_stream); isolate->counters()->runtime_call_stats()->Print(stats_stream);
Handle<String> result = Handle<String> result =
isolate->factory()->NewStringFromAsciiChecked(stats_stream.str().c_str()); isolate->factory()->NewStringFromAsciiChecked(stats_stream.str().c_str());
isolate->runtime_state()->runtime_call_stats()->Reset(); isolate->counters()->runtime_call_stats()->Reset();
return *result; return *result;
} }
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#include "src/runtime/runtime.h" #include "src/runtime/runtime.h"
#include <iomanip>
#include "src/assembler.h" #include "src/assembler.h"
#include "src/contexts.h" #include "src/contexts.h"
#include "src/handles-inl.h" #include "src/handles-inl.h"
...@@ -133,79 +131,5 @@ std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) { ...@@ -133,79 +131,5 @@ std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
} }
class RuntimeCallStatEntries {
public:
void Print(std::ostream& os) {
if (total_call_count > 0) {
std::sort(entries.rbegin(), entries.rend());
os << "Runtime function Time "
"Count"
<< std::endl
<< std::string(70, '=') << std::endl;
for (Entry& entry : entries) {
entry.Print(os);
}
os << std::string(60, '-') << std::endl;
Entry("Total", total_time, total_call_count).Print(os);
}
}
void Add(const char* name, base::TimeDelta time, uint32_t count) {
entries.push_back(Entry(name, time, count));
total_time += time;
total_call_count += count;
}
private:
class Entry {
public:
Entry(const char* name, base::TimeDelta time, uint64_t count)
: name_(name), time_(time.InMilliseconds()), count_(count) {}
bool operator<(const Entry& other) const {
if (time_ < other.time_) return true;
if (time_ > other.time_) return false;
return count_ < other.count_;
}
void Print(std::ostream& os) {
os << std::setw(50) << name_;
os << std::setw(8) << time_ << "ms";
os << std::setw(10) << count_ << std::endl;
}
private:
const char* name_;
int64_t time_;
uint64_t count_;
};
uint64_t total_call_count = 0;
base::TimeDelta total_time;
std::vector<Entry> entries;
};
void RuntimeCallStats::Print(std::ostream& os) {
RuntimeCallStatEntries entries;
#define PRINT_COUNTER(name, nargs, ressize) \
if (this->Count_Runtime_##name > 0) { \
entries.Add(#name, this->Time_Runtime_##name, this->Count_Runtime_##name); \
}
FOR_EACH_INTRINSIC(PRINT_COUNTER)
#undef PRINT_COUNTER
entries.Print(os);
}
void RuntimeCallStats::Reset() {
#define RESET_COUNTER(name, nargs, ressize) \
Count_Runtime_##name = 0; \
Time_Runtime_##name = base::TimeDelta();
FOR_EACH_INTRINSIC(RESET_COUNTER)
#undef RESET_COUNTER
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -1187,26 +1187,6 @@ class Runtime : public AllStatic { ...@@ -1187,26 +1187,6 @@ class Runtime : public AllStatic {
}; };
struct RuntimeCallStats {
#define CALL_RUNTIME_COUNTER(name, nargs, ressize) \
uint32_t Count_Runtime_##name; \
base::TimeDelta Time_Runtime_##name;
FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER)
#undef CALL_RUNTIME_COUNTER
// Dummy counter for the unexpected stub miss.
uint32_t Count_UnexpectedStubMiss;
base::TimeDelta Time_UnexpectedStubMiss;
bool in_runtime_call = false;
void Reset();
void Print(std::ostream& os);
RuntimeCallStats() { Reset(); }
};
class RuntimeState { class RuntimeState {
public: public:
unibrow::Mapping<unibrow::ToUppercase, 128>* to_upper_mapping() { unibrow::Mapping<unibrow::ToUppercase, 128>* to_upper_mapping() {
...@@ -1225,14 +1205,11 @@ class RuntimeState { ...@@ -1225,14 +1205,11 @@ class RuntimeState {
redirected_intrinsic_functions_.Reset(redirected_intrinsic_functions); redirected_intrinsic_functions_.Reset(redirected_intrinsic_functions);
} }
RuntimeCallStats* runtime_call_stats() { return &runtime_call_stats_; }
private: private:
RuntimeState() {} RuntimeState() {}
unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_; unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_;
unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_; unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_;
RuntimeCallStats runtime_call_stats_;
base::SmartArrayPointer<Runtime::Function> redirected_intrinsic_functions_; base::SmartArrayPointer<Runtime::Function> redirected_intrinsic_functions_;
......
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