Skip to content

Instantly share code, notes, and snippets.

@yorickpeterse
Created December 17, 2015 10:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yorickpeterse/0df70b4f341cb67f21ed to your computer and use it in GitHub Desktop.
Save yorickpeterse/0df70b4f341cb67f21ed to your computer and use it in GitHub Desktop.
#include "libinternalevents.h"
st_table *object_counts;
void newobj_callback(VALUE tracepoint, void* data) {
rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(tracepoint);
st_data_t count = 0;
VALUE obj = rb_tracearg_object(trace_arg);
VALUE klass = RBASIC_CLASS(obj);
/* These aren't actually allocated so there's no point in tracking them. */
if ( klass == Qtrue || klass == Qfalse || klass == Qnil ) {
return;
}
st_lookup(object_counts, (st_data_t) klass, &count);
st_insert(object_counts, (st_data_t) klass, count + 1);
}
void freeobj_callback(VALUE tracepoint, void* data) {
rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(tracepoint);
st_data_t count;
VALUE obj = rb_tracearg_object(trace_arg);
VALUE klass = RBASIC_CLASS(obj);
if ( st_lookup(object_counts, (st_data_t) klass, &count) ) {
if ( count > 0 && (count - 1) > 0) {
st_insert(object_counts, (st_data_t) klass, count - 1);
}
/* Remove the entry if the count is now 0 */
else {
st_delete(object_counts, (st_data_t*) &klass, NULL);
}
}
}
static int each_count(st_data_t key, st_data_t value, st_data_t hash_ptr) {
VALUE rb_hash = (VALUE) hash_ptr;
VALUE rb_key = (VALUE) key;
long count = (long) value;
rb_hash_aset(rb_hash, rb_key, INT2NUM(count));
return ST_CONTINUE;
}
VALUE to_hash(VALUE self) {
VALUE hash = rb_hash_new();
st_foreach(object_counts, each_count, (st_data_t) hash);
return hash;
}
void Init_libinternalevents() {
VALUE new_tracer = rb_tracepoint_new(Qnil, RUBY_INTERNAL_EVENT_NEWOBJ,
newobj_callback, NULL);
VALUE free_tracer = rb_tracepoint_new(Qnil, RUBY_INTERNAL_EVENT_FREEOBJ,
freeobj_callback, NULL);
VALUE mInternalEvents = rb_define_module_under(rb_cObject, "InternalEvents");
rb_define_singleton_method(mInternalEvents, "to_hash", to_hash, 0);
object_counts = st_init_numtable();
rb_tracepoint_enable(new_tracer);
rb_tracepoint_enable(free_tracer);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment