Skip to content

Commit

Permalink
Added Rubinius::Diagnostics.
Browse files Browse the repository at this point in the history
  • Loading branch information
brixen committed Jul 7, 2015
1 parent 677a149 commit dff4b12
Show file tree
Hide file tree
Showing 34 changed files with 547 additions and 194 deletions.
1 change: 1 addition & 0 deletions rakelib/vm.rake
Expand Up @@ -124,6 +124,7 @@ field_extract_headers = %w[
vm/builtin/character.hpp
vm/builtin/thread_state.hpp
vm/builtin/jit.hpp
vm/builtin/diagnostics.hpp
]

transcoders_src_dir = File.expand_path "../../vendor/oniguruma/enc/trans", __FILE__
Expand Down
4 changes: 3 additions & 1 deletion vm/builtin/bignum.hpp
Expand Up @@ -2,12 +2,14 @@
#define RBX_BUILTIN_BIGNUM_HPP

#include "tommath.h"

#include "builtin/integer.hpp"

namespace rubinius {
class Array;
class String;
class Fixnum;
class Float;
class String;

class Bignum : public Integer {
public:
Expand Down
12 changes: 12 additions & 0 deletions vm/builtin/diagnostics.cpp
@@ -0,0 +1,12 @@
#include "builtin/class.hpp"
#include "builtin/diagnostics.hpp"
#include "builtin/lookup_table.hpp"

namespace rubinius {
void Diagnostics::init(STATE) {
Module* diagnostics = state->new_object<Diagnostics>(G(module));
diagnostics->setup(state, "Diagnostics", G(rubinius));

diagnostics->set_const(state, "Map", LookupTable::create(state));
}
}
35 changes: 35 additions & 0 deletions vm/builtin/diagnostics.hpp
@@ -0,0 +1,35 @@
#ifndef RBX_BUILTIN_DIAGNOSTICS_HPP
#define RBX_BUILTIN_DIAGNOSTICS_HPP

#include "builtin/class.hpp"
#include "builtin/module.hpp"
#include "builtin/object.hpp"

#include "object_utils.hpp"
#include "diagnostics.hpp"

namespace rubinius {
class LookupTable;

class Diagnostics : public Module {
public:
const static object_type type = DiagnosticsType;

private:
LookupTable* map_; // slot

public:
attr_accessor(map, LookupTable);

public:
static void init(STATE);


class Info : public Module::Info {
public:
BASIC_TYPEINFO(Module::Info)
};
};
}

#endif
23 changes: 22 additions & 1 deletion vm/capi/handles.cpp
Expand Up @@ -3,18 +3,30 @@
#include "gc/baker.hpp"
#include "capi/capi.hpp"
#include "capi/handles.hpp"
#include "util/logger.hpp"

namespace rubinius {
namespace capi {
void Handles::Diagnostics::log() {
if(!modified_p()) return;

diagnostics::Diagnostics::log();

utilities::logger::write("C-API handles: diagnostics: " \
"objects: %ld, bytes: %ld, collections: %ld\n",
objects_, bytes_, collections_);
}

Handle* Handles::allocate(STATE, Object* obj) {
bool needs_gc = false;
Handle* handle = allocator_->allocate(&needs_gc);
handle->set_object(obj);
handle->validate();
if(needs_gc) {
diagnostics_.collections_++;
state->memory()->collect_mature_now = true;
}
diagnostics_.objects_++;
atomic::memory_barrier();
return handle;
}
Expand All @@ -29,8 +41,10 @@ namespace rubinius {
handle->set_object(obj);
handle->validate();
if(needs_gc) {
diagnostics_.collections_++;
state->memory()->collect_mature_now = true;
}
diagnostics_.objects_++;
atomic::memory_barrier();

if(handle_index > UINT32_MAX) {
Expand Down Expand Up @@ -58,7 +72,9 @@ namespace rubinius {
delete allocator_;
}

void Handles::deallocate_handles(std::list<Handle*>* cached, unsigned int mark, BakerGC* young) {
void Handles::deallocate_handles(std::list<Handle*>* cached,
unsigned int mark, BakerGC* young)
{
std::vector<bool> chunk_marks(allocator_->chunks_.size(), false);

for(std::vector<int>::size_type i = 0; i < allocator_->chunks_.size(); ++i) {
Expand Down Expand Up @@ -94,6 +110,7 @@ namespace rubinius {
// A weakref pointing to a dead young object
} else {
handle->clear();
diagnostics_.objects_--;
}
} else {
// Not a young object, so won't be GC'd so mark
Expand All @@ -104,6 +121,7 @@ namespace rubinius {
// A weakref pointing to a dead mature object
} else if(!obj->marked_p(mark)) {
handle->clear();
diagnostics_.objects_--;
} else {
chunk_marks[i] = true;
}
Expand All @@ -122,6 +140,9 @@ namespace rubinius {
}

allocator_->rebuild_freelist(&chunk_marks);

diagnostics_.bytes_ = allocator_->in_use_;
diagnostics_.modify();
}
}
}
21 changes: 20 additions & 1 deletion vm/capi/handles.hpp
@@ -1,27 +1,43 @@
#ifndef RBX_CAPI_HANDLES_HPP
#define RBX_CAPI_HANDLES_HPP

#include "diagnostics.hpp"
#include "vm.hpp"
#include "gc/root.hpp"
#include "util/allocator.hpp"
#include "capi/handle.hpp"

#include <vector>
#include <stdint.h>

namespace rubinius {
class BakerGC;

namespace capi {

class Handles {
public:
class Diagnostics : public diagnostics::MemoryDiagnostics {
public:
int64_t collections_;

Diagnostics()
: diagnostics::MemoryDiagnostics()
, collections_(0)
{ }

void log();
};

private:
Allocator<Handle>* allocator_;

Diagnostics diagnostics_;

public:

Handles()
: allocator_(new Allocator<Handle>())
, diagnostics_(Diagnostics())
{}

~Handles();
Expand All @@ -48,6 +64,9 @@ namespace rubinius {
return allocator_->in_use_;
}

Diagnostics& diagnostics() {
return diagnostics_;
}
};
}
}
Expand Down
2 changes: 1 addition & 1 deletion vm/codegen/field_extract.rb
Expand Up @@ -744,7 +744,7 @@ def generate_marks(cpp)
if(target->#{name}()->reference_p()) {
Object* old = target->#{name}();
Object* cur = mark.call(old);
if(cur && cur != old) target->#{name}(mark.state(), force_as<#{type}>(cur));
if(cur && cur != old) target->#{name}(mark.vm(), force_as<#{type}>(cur));
}
}
Expand Down
42 changes: 42 additions & 0 deletions vm/diagnostics.hpp
@@ -0,0 +1,42 @@
#ifndef RBX_DIAGNOSTICS_HPP
#define RBX_DIAGNOSTICS_HPP

#include <stdint.h>

namespace rubinius {
namespace diagnostics {
class Diagnostics {
bool modified_;

public:
Diagnostics() : modified_(false) { }
virtual ~Diagnostics() { }

virtual void log() {
modified_ = false;
}

bool modified_p() {
return modified_;
}

void modify() {
modified_ = true;
}
};

class MemoryDiagnostics : public Diagnostics {
public:
int64_t objects_;
int64_t bytes_;

MemoryDiagnostics()
: Diagnostics()
, objects_(0)
, bytes_(0)
{ }
};
}
}

#endif
8 changes: 7 additions & 1 deletion vm/environment.cpp
Expand Up @@ -6,8 +6,8 @@
#include "config_parser.hpp"
#include "compiled_file.hpp"
#include "object_memory.hpp"

#include "exception.hpp"
#include "system_diagnostics.hpp"

#include "builtin/array.hpp"
#include "builtin/class.hpp"
Expand Down Expand Up @@ -208,6 +208,11 @@ namespace rubinius {
finalizer_thread_->start(state);
}

void Environment::start_diagnostics(STATE) {
diagnostics_ = new diagnostics::SystemDiagnostics(
state->shared().memory()->diagnostics());
}

void Environment::start_logging(STATE) {
utilities::logger::logger_level level = utilities::logger::eWarn;

Expand Down Expand Up @@ -841,6 +846,7 @@ namespace rubinius {
load_platform_conf(runtime);
boot_vm();

start_diagnostics(state);
start_finalizer(state);

load_argv(argc_, argv_);
Expand Down
12 changes: 11 additions & 1 deletion vm/environment.hpp
Expand Up @@ -12,6 +12,10 @@

namespace rubinius {

namespace diagnostics {
class SystemDiagnostics;
}

class ConfigParser;
class QueryAgent;
class SignalThread;
Expand Down Expand Up @@ -65,6 +69,8 @@ namespace rubinius {

TypedRoot<Object*>* loader_;

diagnostics::SystemDiagnostics* diagnostics_;

public:
SharedState* shared;
VM* root_vm;
Expand All @@ -89,6 +95,10 @@ namespace rubinius {
return loader_->get();
}

diagnostics::SystemDiagnostics* diagnostics() {
return diagnostics_;
}

void set_root_vm(VM* vm) {
root_vm = vm;
state->set_vm(vm);
Expand Down Expand Up @@ -130,6 +140,7 @@ namespace rubinius {
void atexit();

void start_finalizer(STATE);
void start_diagnostics(STATE);

void start_signals(STATE);
void stop_signals(STATE);
Expand All @@ -140,7 +151,6 @@ namespace rubinius {
void start_jit(STATE);
void stop_jit(STATE);
};

}

#endif
24 changes: 20 additions & 4 deletions vm/gc/baker.cpp
Expand Up @@ -42,6 +42,7 @@ namespace rubinius {
, current(heap_a)
, next(heap_b)
, lifetime_(config.gc_young_lifetime)
, diagnostics_(Diagnostics())
{
reset();
}
Expand All @@ -53,6 +54,19 @@ namespace rubinius {
delete full;
}

void BakerGC::Diagnostics::log() {
if(!modified_p()) return;

diagnostics::Diagnostics::log();

utilities::logger::write("baker: diagnostics: " \
"10%: %ld, 20%: %ld, 30%: %ld, 40%: %ld, 50%: %ld, " \
"60%: %ld, 70%: %ld, 80%: %ld, 90%: %ld",
occupancy_histo_[0], occupancy_histo_[1], occupancy_histo_[2],
occupancy_histo_[3], occupancy_histo_[4], occupancy_histo_[5],
occupancy_histo_[6], occupancy_histo_[7], occupancy_histo_[8]);
}

/**
* Called for each object in the young generation that is seen during garbage
* collection. An object is seen by scanning from the root objects to all
Expand Down Expand Up @@ -86,8 +100,8 @@ namespace rubinius {

promoted_push(copy);
} else if(likely(next->enough_space_p(
obj->size_in_bytes(object_memory_->state())))) {
copy = next->move_object(object_memory_->state(), obj);
obj->size_in_bytes(object_memory_->vm())))) {
copy = next->move_object(object_memory_->vm(), obj);
} else {
copy = object_memory_->promote_object(obj);
promoted_push(copy);
Expand All @@ -106,11 +120,11 @@ namespace rubinius {
* Scans the remaining unscanned portion of the Next heap.
*/
void BakerGC::copy_unscanned() {
Object* iobj = next->next_unscanned(object_memory_->state());
Object* iobj = next->next_unscanned(object_memory_->vm());

while(iobj) {
if(!iobj->forwarded_p()) scan_object(iobj);
iobj = next->next_unscanned(object_memory_->state());
iobj = next->next_unscanned(object_memory_->vm());
}
}

Expand Down Expand Up @@ -269,6 +283,8 @@ namespace rubinius {
Heap* x = next;
next = current;
current = x;

diagnostics_.record_occupancy(current->percentage_used());
}

void BakerGC::reset() {
Expand Down

0 comments on commit dff4b12

Please sign in to comment.