-
-
Save yorickpeterse/0df70b4f341cb67f21ed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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