Skip to content

Commit

Permalink
Added experimental allocation tracer.
Browse files Browse the repository at this point in the history
This currently segfaults Rbx for string types (at least whenever the traced
object is referenced). It's also a giant hack, but that's why I'm calling it
experimental.
  • Loading branch information
Yorick Peterse committed Sep 27, 2014
1 parent ddf95f8 commit a1c57ec
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 0 deletions.
23 changes: 23 additions & 0 deletions kernel/delta/allocation_tracer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Rubinius
##
#
module AllocationTracer
@lock = Mutex.new

def self.tracers
return @tracers ||= []
end

def self.add_tracer(&block)
@lock.synchronize { tracers << block }
end

def self.trace(object)
@lock.synchronize do
tracers.each do |tracer|
tracer.call(object)
end
end
end
end # AllocationTracer
end # Rubinius
1 change: 1 addition & 0 deletions kernel/delta/load_order.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ ffi.rbc
ruby_constants.rbc
pack.rbc
metrics.rbc
allocation_tracer.rbc
1 change: 1 addition & 0 deletions rakelib/vm.rake
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ field_extract_headers = %w[
vm/builtin/atomic.hpp
vm/builtin/character.hpp
vm/builtin/thread_state.hpp
vm/builtin/allocation_tracer.hpp
]

transcoders_src_dir = File.expand_path "../../vendor/oniguruma/enc/trans", __FILE__
Expand Down
32 changes: 32 additions & 0 deletions vm/builtin/allocation_tracer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "builtin/class.hpp"
#include "builtin/array.hpp"
#include "builtin/string.hpp"
#include "builtin/native_method.hpp"
#include "builtin/allocation_tracer.hpp"

#include "ontology.hpp"
#include "object_utils.hpp"

namespace rubinius {
void AllocationTracer::init(STATE) {
GO(allocation_tracer).set(ontology::new_module(state, "AllocationTracer", G(rubinius)));
}

Object* AllocationTracer::trace(STATE, CallFrame* call_frame, Object *object) {
Module* mod = G(allocation_tracer);
Symbol* sym_trace = state->symbol("trace");
Array* args;

// We'll use the method once its defined in Ruby, saving us quite some C++
// code.
if(CBOOL(mod->respond_to(state, sym_trace, cFalse))) {
args = Array::create(state, 1);

args->set(state, 0, object);

mod->send(state, call_frame, sym_trace, args);
}

return cNil;
}
}
15 changes: 15 additions & 0 deletions vm/builtin/allocation_tracer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef RBX_ALLOCATION_TRACER_HPP
#define RBX_ALLOCATION_TRACER_HPP

#include "builtin/object.hpp"

namespace rubinius {
class AllocationTracer : public Object {
public:
static void init(STATE);

static Object* trace(STATE, CallFrame* call_frame, Object *object);
};
}

#endif
10 changes: 10 additions & 0 deletions vm/builtin/class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "builtin/module.hpp"
#include "builtin/packed_object.hpp"
#include "builtin/symbol.hpp"
#include "builtin/allocation_tracer.hpp"
#include "configuration.hpp"
#include "object_utils.hpp"
#include "object_memory.hpp"
Expand Down Expand Up @@ -139,6 +140,9 @@ namespace rubinius {
#ifdef RBX_GC_STRESS
state->shared().gc_soon();
#endif

AllocationTracer::trace(state, calling_environment, new_obj);

return new_obj;
} else if(!type_info_->allow_user_allocate || kind_of<SingletonClass>(this)) {
std::ostringstream msg;
Expand All @@ -165,6 +169,9 @@ namespace rubinius {
#ifdef RBX_GC_STRESS
state->shared().gc_soon();
#endif

AllocationTracer::trace(state, calling_environment, new_obj);

return new_obj;
} else {
// type_info_->type is neither PackedObject nor Object, so use the
Expand All @@ -179,6 +186,9 @@ namespace rubinius {
#ifdef RBX_GC_STRESS
state->shared().gc_soon();
#endif

AllocationTracer::trace(state, calling_environment, new_obj);

return new_obj;
}
}
Expand Down
2 changes: 2 additions & 0 deletions vm/globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ namespace rubinius {
TypedRoot<Class*> mirror;
TypedRoot<Class*> fsevent;
TypedRoot<Class*> logger;
TypedRoot<Module*> allocation_tracer;

TypedRoot<Encoding*> usascii_encoding, utf8_encoding, ascii8bit_encoding;

Expand Down Expand Up @@ -257,6 +258,7 @@ namespace rubinius {
mirror(&roots),
fsevent(&roots),
logger(&roots),
allocation_tracer(&roots),
usascii_encoding(&roots),
utf8_encoding(&roots),
ascii8bit_encoding(&roots)
Expand Down
3 changes: 3 additions & 0 deletions vm/instructions.def
Original file line number Diff line number Diff line change
Expand Up @@ -1588,7 +1588,10 @@ instruction string_dup() [ string -- string ]
dup->setup_allocation_site(state, call_frame);
}
#endif

stack_push(dup);

AllocationTracer::trace(state, call_frame, dup);
end

section "Manipulate scope"
Expand Down
1 change: 1 addition & 0 deletions vm/instructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define RBX_INSTR

#include "machine_code.hpp"
#include "builtin/allocation_tracer.hpp"

namespace rubinius {
namespace instructions {
Expand Down
2 changes: 2 additions & 0 deletions vm/ontology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "builtin/fixnum.hpp"
#include "builtin/float.hpp"
#include "builtin/fsevent.hpp"
#include "builtin/allocation_tracer.hpp"
#include "builtin/io.hpp"
#include "builtin/iseq.hpp"
#include "builtin/list.hpp"
Expand Down Expand Up @@ -365,6 +366,7 @@ namespace rubinius {
Encoding::init(state);
FSEvent::init(state);
Logger::init(state);
AllocationTracer::init(state);
}

// @todo document all the sections of bootstrap_ontology
Expand Down

0 comments on commit a1c57ec

Please sign in to comment.