ext/calleree/calleree.c in calleree-0.1.0 vs ext/calleree/calleree.c in calleree-0.2.0
- old
+ new
@@ -1,60 +1,81 @@
#include "ruby/ruby.h"
#include "ruby/debug.h"
#include "ruby/st.h"
+#define USE_LOCINDEX 0 // Ruby 3.1 feature trial
+
VALUE rb_mCalleree;
struct eree_data {
VALUE tp; // TracePoint.new(:call)
- VALUE files; // name -> [ {[fname, 1], ... } ]
- struct st_table* caller_callee; // [posnum | posnum] -> cnt
+ VALUE files; // name -> [ nil, posnum1, posnum,2 ... ]
+ struct st_table* caller_callee; // { (posnumX | posnumY) => cnt, ... }
int last_posnum;
} eree_data;
-static int
+#if !USE_LOCINDEX
+static unsigned int
posnum(struct eree_data *data, VALUE path, int line)
{
VALUE lines, posnumv;
if (NIL_P(lines = rb_hash_aref(data->files, path))) {
rb_hash_aset(data->files, path, lines = rb_ary_new());
}
if (NIL_P(posnumv = rb_ary_entry(lines, line))) {
- rb_ary_store(lines, line, posnumv = INT2FIX(data->last_posnum++));
+ int posnum = ++data->last_posnum;
+ if (RB_UNLIKELY(posnum == 0)) rb_raise(rb_eRuntimeError, "posnum overflow");
+ rb_ary_store(lines, line, posnumv = INT2FIX(posnum));
}
- return FIX2INT(posnumv);
+ return (unsigned int)FIX2INT(posnumv);
}
+#endif
static int
increment_i(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
{
*value = (existing ? *value : 0) + 1;
return ST_CONTINUE;
}
static void
-erree_called(VALUE tpval, void *ptr)
+eree_called(VALUE tpval, void *ptr)
{
struct eree_data *data = ptr;
+
+#if !USE_LOCINDEX
VALUE frames[2];
int lines[2];
// int start, int limit, VALUE *buff, int *lines);
- rb_profile_frames(1, 2, frames, lines);
- int callee_posnum = posnum(data, rb_profile_frame_path(frames[0]), lines[0]);
- int caller_posnum = posnum(data, rb_profile_frame_path(frames[1]), lines[1]);
- // rb_p(rb_profile_frame_path(frames[1]));
- st_data_t eree_pair = (((VALUE)caller_posnum << 32) | ((VALUE)callee_posnum));
+ int r = rb_profile_frames(1, 2, frames, lines);
- st_update(data->caller_callee, eree_pair, increment_i, 0);
+ if (r >= 2) {
+ unsigned int callee_posnum = posnum(data, rb_profile_frame_absolute_path(frames[0]), lines[0]);
+ unsigned int caller_posnum = posnum(data, rb_profile_frame_absolute_path(frames[1]), lines[1]);
+
+ st_data_t eree_pair = (((VALUE)caller_posnum << 32) | ((VALUE)callee_posnum));
+ st_update(data->caller_callee, eree_pair, increment_i, 0);
+ }
+#else
+ unsigned int locs[2];
+ int r = rb_profile_locindex(0, 2, locs, 0);
+ if (r >= 2) {
+ unsigned int callee_posnum = locs[0];// posnum(data, rb_profile_frame_absolute_path (frames[0]), lines[0]);
+ unsigned int caller_posnum = locs[1];// posnum(data, rb_profile_frame_absolute_path (frames[1]), lines[1]);
+ st_data_t eree_pair = (((VALUE)caller_posnum << 32) | ((VALUE)callee_posnum));
+ st_update(data->caller_callee, eree_pair, increment_i, 0);
+ }
+#endif
}
static VALUE
eree_start(VALUE self)
{
if (!eree_data.tp) {
- eree_data.tp = rb_tracepoint_new(0, RUBY_EVENT_CALL, erree_called, &eree_data);
+ eree_data.tp = rb_tracepoint_new(0, RUBY_EVENT_CALL, eree_called, &eree_data);
+ rb_gc_register_mark_object(eree_data.tp);
eree_data.caller_callee = st_init_numtable();
}
rb_tracepoint_enable(eree_data.tp);
return self;
}
@@ -70,13 +91,25 @@
static int
raw_result_i(st_data_t key, st_data_t val, st_data_t data)
{
VALUE ary = (VALUE)data;
- int callee_posnum = (int)(key & 0xffffffff);
- int caller_posnum = (int)(key >> 32);
- rb_ary_push(ary, rb_ary_new_from_args(3, INT2FIX(caller_posnum), INT2FIX(callee_posnum), INT2FIX((int)val)));
+ unsigned int callee_posnum = (unsigned int)(key & 0xffffffff);
+ unsigned int caller_posnum = (unsigned int)(key >> 32);
+#if !USE_LOCINDEX
+ rb_ary_push(ary, rb_ary_new_from_args(3, UINT2NUM(caller_posnum), UINT2NUM(callee_posnum), INT2FIX((int)val)));
+#else
+ VALUE er_path, ee_path;
+ int er_line, ee_line;
+ rb_locindex_resolve(callee_posnum, &ee_path, &ee_line);
+ rb_locindex_resolve(caller_posnum, &er_path, &er_line);
+
+ rb_ary_push(ary, rb_ary_new_from_args(3,
+ rb_ary_new_from_args(2, er_path, INT2FIX(er_line)),
+ rb_ary_new_from_args(2, ee_path, INT2FIX(ee_line)),
+ INT2FIX((int)val)));
+#endif
return ST_CONTINUE;
}
static VALUE
eree_raw_result(VALUE self, VALUE clear_p)
@@ -90,23 +123,29 @@
}
}
return ary;
}
+#if !USE_LOCINDEX
static VALUE
eree_raw_posmap(VALUE self)
{
return eree_data.files;
}
+#endif
void
Init_calleree(void)
{
eree_data.files = rb_hash_new();
+ rb_funcall(eree_data.files, rb_intern("compare_by_identity"), 0);
rb_gc_register_mark_object(eree_data.files);
rb_mCalleree = rb_define_module("Calleree");
rb_define_singleton_method(rb_mCalleree, "_start", eree_start, 0);
rb_define_singleton_method(rb_mCalleree, "_stop", eree_stop, 0);
rb_define_singleton_method(rb_mCalleree, "raw_result", eree_raw_result, 1);
+
+#if !USE_LOCINDEX
rb_define_singleton_method(rb_mCalleree, "raw_posmap", eree_raw_posmap, 0);
+#endif
}