vm_backtrace.c: let rb_profile_frames show cfunc frames
... in addition to normal iseq frames. It is sometimes useful to point the bottleneck more precisely.
This commit is contained in:
parent
e4b63202eb
commit
da31900d9d
Notes:
git
2020-07-28 13:18:35 +09:00
@ -44,6 +44,7 @@ class TestProfileFrames < Test::Unit::TestCase
|
|||||||
}.resume
|
}.resume
|
||||||
|
|
||||||
labels = [
|
labels = [
|
||||||
|
nil,
|
||||||
"test_profile_frames",
|
"test_profile_frames",
|
||||||
"zab",
|
"zab",
|
||||||
"baz",
|
"baz",
|
||||||
@ -54,6 +55,7 @@ class TestProfileFrames < Test::Unit::TestCase
|
|||||||
"test_profile_frames",
|
"test_profile_frames",
|
||||||
]
|
]
|
||||||
base_labels = [
|
base_labels = [
|
||||||
|
nil,
|
||||||
"test_profile_frames",
|
"test_profile_frames",
|
||||||
"zab",
|
"zab",
|
||||||
"baz",
|
"baz",
|
||||||
@ -64,6 +66,7 @@ class TestProfileFrames < Test::Unit::TestCase
|
|||||||
"test_profile_frames",
|
"test_profile_frames",
|
||||||
]
|
]
|
||||||
full_labels = [
|
full_labels = [
|
||||||
|
"Bug::Debug.profile_frames",
|
||||||
"TestProfileFrames#test_profile_frames",
|
"TestProfileFrames#test_profile_frames",
|
||||||
"#{obj.inspect}.zab",
|
"#{obj.inspect}.zab",
|
||||||
"SampleClassForTestProfileFrames::Sample2#baz",
|
"SampleClassForTestProfileFrames::Sample2#baz",
|
||||||
@ -74,6 +77,7 @@ class TestProfileFrames < Test::Unit::TestCase
|
|||||||
"TestProfileFrames#test_profile_frames",
|
"TestProfileFrames#test_profile_frames",
|
||||||
]
|
]
|
||||||
classes = [
|
classes = [
|
||||||
|
Bug::Debug,
|
||||||
TestProfileFrames,
|
TestProfileFrames,
|
||||||
obj,
|
obj,
|
||||||
SampleClassForTestProfileFrames::Sample2,
|
SampleClassForTestProfileFrames::Sample2,
|
||||||
@ -84,9 +88,10 @@ class TestProfileFrames < Test::Unit::TestCase
|
|||||||
TestProfileFrames,
|
TestProfileFrames,
|
||||||
]
|
]
|
||||||
singleton_method_p = [
|
singleton_method_p = [
|
||||||
false, true, false, true, true, true, false, false, false,
|
true, false, true, false, true, true, true, false, false, false,
|
||||||
]
|
]
|
||||||
method_names = [
|
method_names = [
|
||||||
|
"profile_frames",
|
||||||
"test_profile_frames",
|
"test_profile_frames",
|
||||||
"zab",
|
"zab",
|
||||||
"baz",
|
"baz",
|
||||||
@ -97,6 +102,7 @@ class TestProfileFrames < Test::Unit::TestCase
|
|||||||
"test_profile_frames",
|
"test_profile_frames",
|
||||||
]
|
]
|
||||||
qualified_method_names = [
|
qualified_method_names = [
|
||||||
|
"Bug::Debug.profile_frames",
|
||||||
"TestProfileFrames#test_profile_frames",
|
"TestProfileFrames#test_profile_frames",
|
||||||
"#{obj.inspect}.zab",
|
"#{obj.inspect}.zab",
|
||||||
"SampleClassForTestProfileFrames::Sample2#baz",
|
"SampleClassForTestProfileFrames::Sample2#baz",
|
||||||
@ -106,8 +112,8 @@ class TestProfileFrames < Test::Unit::TestCase
|
|||||||
"SampleClassForTestProfileFrames#foo",
|
"SampleClassForTestProfileFrames#foo",
|
||||||
"TestProfileFrames#test_profile_frames",
|
"TestProfileFrames#test_profile_frames",
|
||||||
]
|
]
|
||||||
paths = [ file=__FILE__, "(eval)", file, file, file, file, file, file ]
|
paths = [ nil, file=__FILE__, "(eval)", file, file, file, file, file, file, nil ]
|
||||||
absolute_paths = [ file, nil, file, file, file, file, file, file ]
|
absolute_paths = [ "<cfunc>", file, nil, file, file, file, file, file, file, nil ]
|
||||||
|
|
||||||
assert_equal(labels.size, frames.size)
|
assert_equal(labels.size, frames.size)
|
||||||
|
|
||||||
@ -120,8 +126,8 @@ class TestProfileFrames < Test::Unit::TestCase
|
|||||||
assert_equal(base_labels[i], base_label, err_msg)
|
assert_equal(base_labels[i], base_label, err_msg)
|
||||||
assert_equal(singleton_method_p[i], singleton_p, err_msg)
|
assert_equal(singleton_method_p[i], singleton_p, err_msg)
|
||||||
assert_equal(method_names[i], method_name, err_msg)
|
assert_equal(method_names[i], method_name, err_msg)
|
||||||
assert_match(qualified_method_names[i], qualified_method_name, err_msg)
|
assert_equal(qualified_method_names[i], qualified_method_name, err_msg)
|
||||||
assert_match(full_labels[i], full_label, err_msg)
|
assert_equal(full_labels[i], full_label, err_msg)
|
||||||
assert_match(classes[i].inspect, classpath, err_msg)
|
assert_match(classes[i].inspect, classpath, err_msg)
|
||||||
if label == method_name
|
if label == method_name
|
||||||
c = classes[i]
|
c = classes[i]
|
||||||
|
@ -1360,6 +1360,14 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
cme = rb_vm_frame_method_entry(cfp);
|
||||||
|
if (cme && cme->def->type == VM_METHOD_TYPE_CFUNC) {
|
||||||
|
buff[i] = (VALUE)cme;
|
||||||
|
if (lines) lines[i] = 0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1399,9 +1407,42 @@ rb_profile_frame_path(VALUE frame)
|
|||||||
return iseq ? rb_iseq_path(iseq) : Qnil;
|
return iseq ? rb_iseq_path(iseq) : Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const rb_callable_method_entry_t *
|
||||||
|
cframe(VALUE frame)
|
||||||
|
{
|
||||||
|
if (frame == Qnil) return NULL;
|
||||||
|
|
||||||
|
if (RB_TYPE_P(frame, T_IMEMO)) {
|
||||||
|
switch (imemo_type(frame)) {
|
||||||
|
case imemo_ment:
|
||||||
|
{
|
||||||
|
const rb_callable_method_entry_t *cme = (rb_callable_method_entry_t *)frame;
|
||||||
|
switch (cme->def->type) {
|
||||||
|
case VM_METHOD_TYPE_CFUNC:
|
||||||
|
return cme;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_profile_frame_absolute_path(VALUE frame)
|
rb_profile_frame_absolute_path(VALUE frame)
|
||||||
{
|
{
|
||||||
|
if (cframe(frame)) {
|
||||||
|
static VALUE cfunc_str = Qfalse;
|
||||||
|
if (!cfunc_str) {
|
||||||
|
cfunc_str = rb_str_new_literal("<cfunc>");
|
||||||
|
rb_gc_register_mark_object(cfunc_str);
|
||||||
|
}
|
||||||
|
return cfunc_str;
|
||||||
|
}
|
||||||
const rb_iseq_t *iseq = frame2iseq(frame);
|
const rb_iseq_t *iseq = frame2iseq(frame);
|
||||||
return iseq ? rb_iseq_realpath(iseq) : Qnil;
|
return iseq ? rb_iseq_realpath(iseq) : Qnil;
|
||||||
}
|
}
|
||||||
@ -1479,15 +1520,18 @@ rb_profile_frame_singleton_method_p(VALUE frame)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_profile_frame_method_name(VALUE frame)
|
rb_profile_frame_method_name(VALUE frame)
|
||||||
{
|
{
|
||||||
|
const rb_callable_method_entry_t *cme = cframe(frame);
|
||||||
|
if (cme) {
|
||||||
|
ID mid = cme->def->original_id;
|
||||||
|
return id2str(mid);
|
||||||
|
}
|
||||||
const rb_iseq_t *iseq = frame2iseq(frame);
|
const rb_iseq_t *iseq = frame2iseq(frame);
|
||||||
return iseq ? rb_iseq_method_name(iseq) : Qnil;
|
return iseq ? rb_iseq_method_name(iseq) : Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
static VALUE
|
||||||
rb_profile_frame_qualified_method_name(VALUE frame)
|
qualified_method_name(VALUE frame, VALUE method_name)
|
||||||
{
|
{
|
||||||
VALUE method_name = rb_profile_frame_method_name(frame);
|
|
||||||
|
|
||||||
if (method_name != Qnil) {
|
if (method_name != Qnil) {
|
||||||
VALUE classpath = rb_profile_frame_classpath(frame);
|
VALUE classpath = rb_profile_frame_classpath(frame);
|
||||||
VALUE singleton_p = rb_profile_frame_singleton_method_p(frame);
|
VALUE singleton_p = rb_profile_frame_singleton_method_p(frame);
|
||||||
@ -1505,9 +1549,24 @@ rb_profile_frame_qualified_method_name(VALUE frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_profile_frame_qualified_method_name(VALUE frame)
|
||||||
|
{
|
||||||
|
VALUE method_name = rb_profile_frame_method_name(frame);
|
||||||
|
|
||||||
|
return qualified_method_name(frame, method_name);
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_profile_frame_full_label(VALUE frame)
|
rb_profile_frame_full_label(VALUE frame)
|
||||||
{
|
{
|
||||||
|
const rb_callable_method_entry_t *cme = cframe(frame);
|
||||||
|
if (cme) {
|
||||||
|
ID mid = cme->def->original_id;
|
||||||
|
VALUE method_name = id2str(mid);
|
||||||
|
return qualified_method_name(frame, method_name);
|
||||||
|
}
|
||||||
|
|
||||||
VALUE label = rb_profile_frame_label(frame);
|
VALUE label = rb_profile_frame_label(frame);
|
||||||
VALUE base_label = rb_profile_frame_base_label(frame);
|
VALUE base_label = rb_profile_frame_base_label(frame);
|
||||||
VALUE qualified_method_name = rb_profile_frame_qualified_method_name(frame);
|
VALUE qualified_method_name = rb_profile_frame_qualified_method_name(frame);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user