Skip to content

Commit

Permalink
Add SymbolTable diagnostics.
Browse files Browse the repository at this point in the history
  • Loading branch information
brixen committed Feb 1, 2018
1 parent ce9249d commit 8c6e491
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 66 deletions.
50 changes: 32 additions & 18 deletions machine/diagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#include "state.hpp"
#include "environment.hpp"
#include "logger.hpp"
#include "thread_phase.hpp"

#include "diagnostics.hpp"
#include "diagnostics/emitter.hpp"
#include "diagnostics/formatter.hpp"
#include "diagnostics/measurement.hpp"

#include <unistd.h>
Expand All @@ -20,19 +22,26 @@ namespace rubinius {
m->update(Measurement::update_counter);
m->report(Measurement::report_counter);

state->shared().diagnostics()->add_measurement(m);
// TODO: diagnostics
// state->shared().diagnostics()->add_measurement(m);

return m;
}

Diagnostics::Diagnostics(STATE)
: recurring_reports_()
, intermittent_reports_()
, reporter_(nullptr)
, lock_()
, interval_(state->shared().config.diagnostics_interval)
{
}

Reporter::Reporter(STATE, Diagnostics* d)
: MachineThread(state, "rbx.diagnostics", MachineThread::eSmall)
, diagnostics_(d)
, timer_(nullptr)
, interval_(state->shared().config.diagnostics_interval)
, list_()
, emitter_(Emitter::create(state))
, diagnostics_lock_()
, diagnostics_(d)
{
}

Expand All @@ -55,11 +64,7 @@ namespace rubinius {
MachineThread::after_fork_child(state);
}

void Reporter::report(Formatter* formatter) {
std::lock_guard<std::mutex> guard(diagnostics_lock_);

list_.push_back(formatter);

void Reporter::report() {
if(timer_) {
timer_->clear();
timer_->cancel();
Expand All @@ -70,7 +75,7 @@ namespace rubinius {
state->vm()->unmanaged_phase(state);

while(!thread_exit_) {
timer_->set(interval_);
timer_->set(diagnostics_->interval());

if(timer_->wait_for_tick() < 0) {
logger::error("diagnostics: error waiting for timer");
Expand All @@ -79,17 +84,26 @@ namespace rubinius {
if(thread_exit_) break;

{
std::lock_guard<std::mutex> guard(diagnostics_lock_);
ManagedPhase managed(state);
LockWaiting<std::mutex> lock_waiting(state, diagnostics_->lock());

for(auto f : diagnostics_->recurring_reports()) {
f->update();
}
}

{
std::lock_guard<std::mutex> guard(diagnostics_->lock());

for(auto m : diagnostics_->measurements()) {
m->report(state);
for(auto f : diagnostics_->recurring_reports()) {
emitter_->transmit(f);
}

if(!list_.empty()) {
Formatter* formatter = list_.back();
list_.pop_back();
while(!diagnostics_->intermittent_reports().empty()) {
auto f = diagnostics_->intermittent_reports().back();
diagnostics_->intermittent_reports().pop_back();

emitter_->transmit(formatter);
emitter_->transmit(f);
}
}
}
Expand Down
58 changes: 37 additions & 21 deletions machine/diagnostics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,20 @@ namespace rubinius {
class Emitter;
class Formatter;
class ImmixFormatter;
class Measurement;
class SymbolFormatter;

typedef std::unordered_set<Measurement*> Measurements;
typedef std::list<Formatter*> ReportRequests;
typedef std::unordered_set<Formatter*> RecurringReports;
typedef std::list<Formatter*> IntermittentReports;

class Diagnostics;

class Reporter : public MachineThread {
Diagnostics* diagnostics_;

utilities::timer::Timer* timer_;
int interval_;

ReportRequests list_;
Emitter* emitter_;

std::mutex diagnostics_lock_;

Diagnostics* diagnostics_;

public:
Reporter(STATE, Diagnostics* d);

Expand All @@ -47,19 +43,21 @@ namespace rubinius {
void wakeup(STATE);
void after_fork_child(STATE);

void report(Formatter* formatter);
void report();
};

class Diagnostics {
Measurements measurements_;
RecurringReports recurring_reports_;
IntermittentReports intermittent_reports_;

Reporter* reporter_;

std::mutex lock_;

int interval_;

public:
Diagnostics()
: measurements_()
, reporter_(nullptr)
{
}
Diagnostics(STATE);

~Diagnostics() {
if(reporter_) {
Expand All @@ -68,8 +66,20 @@ namespace rubinius {
}
}

Measurements& measurements() {
return measurements_;
std::mutex& lock() {
return lock_;
}

int interval() const {
return interval_;
}

RecurringReports& recurring_reports() {
return recurring_reports_;
}

IntermittentReports& intermittent_reports() {
return intermittent_reports_;
}

void start_reporter(STATE) {
Expand All @@ -80,13 +90,19 @@ namespace rubinius {
}

void report(Formatter* formatter) {
std::lock_guard<std::mutex> guard(lock_);

intermittent_reports_.push_back(formatter);

if(reporter_) {
reporter_->report(formatter);
reporter_->report();
}
}

void add_measurement(Measurement* m) {
measurements_.insert(m);
void add_report(Formatter* formatter) {
std::lock_guard<std::mutex> guard(lock_);

recurring_reports_.insert(formatter);
}
};
}
Expand Down
25 changes: 25 additions & 0 deletions machine/diagnostics/formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@

namespace rubinius {
namespace diagnostics {
std::string Formatter::to_string() {
rapidjson::StringBuffer buffer;

rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);

document_.Accept(writer);

return std::move(buffer.GetString());
}

ImmixFormatter::ImmixFormatter(ImmixDiagnostics* d)
: Formatter()
, diagnostics_(d)
Expand Down Expand Up @@ -50,5 +60,20 @@ namespace rubinius {

return std::move(buffer.GetString());
}

SymbolFormatter::SymbolFormatter(SymbolDiagnostics* d)
: Formatter()
, diagnostics_(d)
{
set_type("SymbolTable");

document_.AddMember("symbols", diagnostics_->symbols_, document_.GetAllocator());
document_.AddMember("bytes", diagnostics_->bytes_, document_.GetAllocator());
}

void SymbolFormatter::update() {
document_["symbols"] = diagnostics_->symbols_;
document_["bytes"] = diagnostics_->bytes_;
}
}
}
16 changes: 13 additions & 3 deletions machine/diagnostics/formatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ namespace rubinius {
: document_()
{
document_.SetObject();
document_.AddMember("diagnostic_type", "Diagnostics", document_.GetAllocator());
document_.AddMember("type", "Diagnostics", document_.GetAllocator());
}

virtual ~Formatter() {}

virtual void set_type(const char* type) {
document_["diagnostic_type"].SetString(type, document_.GetAllocator());
document_["type"].SetString(type, document_.GetAllocator());
}

virtual void update() {}
virtual std::string to_string() { return std::string(""); }
virtual std::string to_string();
};

class ImmixFormatter : public Formatter {
Expand All @@ -39,6 +39,16 @@ namespace rubinius {
virtual void update();
virtual std::string to_string();
};

class SymbolFormatter : public Formatter {
SymbolDiagnostics* diagnostics_;

public:
SymbolFormatter(SymbolDiagnostics* d);
~SymbolFormatter() {}

virtual void update();
};
}
}

Expand Down
12 changes: 12 additions & 0 deletions machine/diagnostics/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ namespace rubinius {
void update() {}
};

class SymbolDiagnostics : public MemoryDiagnostics {
public:
int64_t symbols_;

SymbolDiagnostics()
: MemoryDiagnostics()
, symbols_(0)
{ }

void update() {}
};

struct MemoryMetrics {
metric young_bytes;
metric young_objects;
Expand Down
2 changes: 2 additions & 0 deletions machine/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,8 @@ namespace rubinius {
#endif
immix_->sweep();

state->shared().symbols.sweep(state);

rotate_mark();

diagnostics::GCMetrics& metrics = state->shared().gc_metrics();
Expand Down
9 changes: 9 additions & 0 deletions machine/memory/immix_collector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ namespace memory {
}

ImmixGC::~ImmixGC() {
if(diagnostics_) {
delete diagnostics_;
diagnostics_ = nullptr;
}

if(formatter_) {
delete formatter_;
formatter_ = nullptr;
}
}

Address ImmixGC::ObjectDescriber::copy(Address original,
Expand Down
4 changes: 3 additions & 1 deletion machine/shared_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace rubinius {
, finalizer_(nullptr)
, console_(nullptr)
, metrics_(nullptr)
, diagnostics_(new diagnostics::Diagnostics())
, diagnostics_(nullptr)
, profiler_(nullptr)
, jit_(nullptr)
, start_time_(get_current_time())
Expand Down Expand Up @@ -241,6 +241,8 @@ namespace rubinius {
}

diagnostics::Diagnostics* SharedState::start_diagnostics(STATE) {
diagnostics_ = new diagnostics::Diagnostics(state);

if(state->shared().config.diagnostics_target.value.compare("none")) {
diagnostics_->start_reporter(state);
}
Expand Down
27 changes: 25 additions & 2 deletions machine/symbol_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,36 @@
#include "class/string.hpp"
#include "class/symbol.hpp"

#include "diagnostics/formatter.hpp"

#include "logger.hpp"

#include <iostream>
#include <iomanip>

namespace rubinius {
void SymbolTable::Diagnostics::update() {
SymbolTable::SymbolTable()
: diagnostics_(new diagnostics::SymbolDiagnostics())
, formatter_(new diagnostics::SymbolFormatter(diagnostics_))
{
lock_.init();
}

SymbolTable::~SymbolTable() {
if(diagnostics_) {
delete diagnostics_;
diagnostics_ = nullptr;
}

if(formatter_) {
delete formatter_;
formatter_ = nullptr;
}
}

void SymbolTable::sweep(STATE) {
formatter_->update();
state->shared().report_diagnostics(formatter_);
}

SymbolTable::Kind SymbolTable::detect_kind(STATE, const Symbol* sym) {
Expand Down Expand Up @@ -89,7 +112,7 @@ namespace rubinius {

size_t SymbolTable::add(STATE, std::string str, int enc) {
size_t bytes = (str.size() + sizeof(std::string) + sizeof(int) + sizeof(Kind));
diagnostics()->objects_++;
diagnostics()->symbols_++;
diagnostics()->bytes_ += bytes;

strings.push_back(str);
Expand Down
Loading

0 comments on commit 8c6e491

Please sign in to comment.