Added support in d8 for memory-mapped counters and added the python

stats-viewer tool.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@904 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a56ced1b
...@@ -84,6 +84,9 @@ i::SmartPointer<char> DumbLineEditor::Prompt(const char* prompt) { ...@@ -84,6 +84,9 @@ i::SmartPointer<char> DumbLineEditor::Prompt(const char* prompt) {
Shell::CounterMap Shell::counter_map_; Shell::CounterMap Shell::counter_map_;
i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
CounterCollection Shell::local_counters_;
CounterCollection* Shell::counters_ = &local_counters_;
Persistent<Context> Shell::utility_context_; Persistent<Context> Shell::utility_context_;
Persistent<Context> Shell::evaluation_context_; Persistent<Context> Shell::evaluation_context_;
...@@ -209,20 +212,59 @@ Handle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) { ...@@ -209,20 +212,59 @@ Handle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) {
} }
int32_t* Counter::Bind(const char* name) {
int i;
for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
name_[i] = static_cast<char>(name[i]);
name_[i] = '\0';
return &counter_;
}
CounterCollection::CounterCollection() {
magic_number_ = 0xDEADFACE;
max_counters_ = kMaxCounters;
max_name_size_ = Counter::kMaxNameSize;
counters_in_use_ = 0;
}
Counter* CounterCollection::GetNextCounter() {
if (counters_in_use_ == kMaxCounters) return NULL;
return &counters_[counters_in_use_++];
}
void Shell::MapCounters(const char* name) {
counters_file_ = i::OS::MemoryMappedFile::create(name,
sizeof(CounterCollection), &local_counters_);
void* memory = (counters_file_ == NULL) ?
NULL : counters_file_->memory();
if (memory == NULL) {
printf("Could not map counters file %s\n", name);
exit(1);
}
counters_ = static_cast<CounterCollection*>(memory);
V8::SetCounterFunction(LookupCounter);
}
int* Shell::LookupCounter(const char* name) { int* Shell::LookupCounter(const char* name) {
CounterMap::iterator item = counter_map_.find(name); CounterMap::iterator item = counter_map_.find(name);
if (item != counter_map_.end()) { if (item != counter_map_.end()) {
Counter* result = (*item).second; Counter* result = (*item).second;
return result->GetValuePtr(); return result->ptr();
} }
Counter* result = new Counter(name); Counter* result = counters_->GetNextCounter();
counter_map_[name] = result; if (result == NULL) return NULL;
return result->GetValuePtr(); return result->Bind(name);
} }
void Shell::Initialize() { void Shell::Initialize() {
// Set up counters // Set up counters
if (i::FLAG_map_counters != NULL)
MapCounters(i::FLAG_map_counters);
if (i::FLAG_dump_counters) if (i::FLAG_dump_counters)
V8::SetCounterFunction(LookupCounter); V8::SetCounterFunction(LookupCounter);
// Initialize the global objects // Initialize the global objects
...@@ -286,10 +328,12 @@ void Shell::OnExit() { ...@@ -286,10 +328,12 @@ void Shell::OnExit() {
i != counter_map_.end(); i != counter_map_.end();
i++) { i++) {
Counter* counter = (*i).second; Counter* counter = (*i).second;
::printf("| %-38s | %8i |\n", counter->name(), counter->value()); ::printf("| %-38s | %8i |\n", (*i).first, counter->value());
} }
::printf("+----------------------------------------+----------+\n"); ::printf("+----------------------------------------+----------+\n");
} }
if (counters_file_ != NULL)
delete counters_file_;
} }
......
...@@ -42,16 +42,33 @@ namespace v8 { ...@@ -42,16 +42,33 @@ namespace v8 {
namespace i = v8::internal; namespace i = v8::internal;
// A single counter in a counter collection.
class Counter { class Counter {
public: public:
explicit Counter(const char* name) static const int kMaxNameSize = 64;
: name_(name), value_(0) { } int32_t* Bind(const char* name);
int* GetValuePtr() { return &value_; } int32_t* ptr() { return &counter_; }
const char* name() { return name_; } int32_t value() { return counter_; }
int value() { return value_; }
private: private:
const char* name_; int32_t counter_;
int value_; uint8_t name_[kMaxNameSize];
};
// A set of counters and associated information. An instance of this
// class is stored directly in the memory-mapped counters file if
// the --map-counters options is used
class CounterCollection {
public:
CounterCollection();
Counter* GetNextCounter();
private:
static const unsigned kMaxCounters = 256;
uint32_t magic_number_;
uint32_t max_counters_;
uint32_t max_name_size_;
uint32_t counters_in_use_;
Counter counters_[kMaxCounters];
}; };
...@@ -65,6 +82,7 @@ class Shell: public i::AllStatic { ...@@ -65,6 +82,7 @@ class Shell: public i::AllStatic {
static void Initialize(); static void Initialize();
static void OnExit(); static void OnExit();
static int* LookupCounter(const char* name); static int* LookupCounter(const char* name);
static void MapCounters(const char* name);
static Handle<String> ReadFile(const char* name); static Handle<String> ReadFile(const char* name);
static void RunShell(); static void RunShell();
static int Main(int argc, char* argv[]); static int Main(int argc, char* argv[]);
...@@ -83,6 +101,11 @@ class Shell: public i::AllStatic { ...@@ -83,6 +101,11 @@ class Shell: public i::AllStatic {
static Persistent<Context> evaluation_context_; static Persistent<Context> evaluation_context_;
typedef std::map<const char*, Counter*> CounterMap; typedef std::map<const char*, Counter*> CounterMap;
static CounterMap counter_map_; static CounterMap counter_map_;
// We statically allocate a set of local counters to be used if we
// don't want to store the stats in a memory-mapped file
static CounterCollection local_counters_;
static CounterCollection* counters_;
static i::OS::MemoryMappedFile* counters_file_;
}; };
......
...@@ -226,6 +226,7 @@ DEFINE_string(testing_serialization_file, "/tmp/serdes", ...@@ -226,6 +226,7 @@ DEFINE_string(testing_serialization_file, "/tmp/serdes",
DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(help, false, "Print usage message, including flags, on console")
DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_bool(dump_counters, false, "Dump counters on exit")
DEFINE_string(map_counters, false, "Map counters to a file")
DEFINE_args(js_arguments, JSArguments(), DEFINE_args(js_arguments, JSArguments(),
"Pass all remaining arguments to the script. Alias for \"--\".") "Pass all remaining arguments to the script. Alias for \"--\".")
......
This diff is collapsed.
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