首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用TracePoint跟踪对“优化”方法调用的Ruby调用

使用TracePoint跟踪对“优化”方法调用的Ruby调用
EN

Stack Overflow用户
提问于 2015-07-21 00:43:32
回答 1查看 98关注 0票数 1

我正在尝试使用TracePoint跟踪Ruby程序中的所有方法调用。它工作得很好,直到我调用了一个“优化”的方法调用。

Ruby的运算符是通过用专门的指令替换YARV指令来“优化”的,以加速方法调用,如大于、小于。这些优化之一

您可以通过运行以下命令直接使用ruby查看这一点

代码语言:javascript
复制
code = <<END
   1 / 1
END
puts RubyVM::InstructionSequence.compile(code).disasm

# == disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
# 0000 trace            1                                               (   1)
# 0002 putobject_OP_INT2FIX_O_1_C_
# 0003 putobject_OP_INT2FIX_O_1_C_
# 0004 opt_div          <callinfo!mid:/, argc:1, ARGS_SIMPLE>
# 0006 leave

在这里,您看到使用的是opt_div而不是opt_send_without_block

看起来你不能跟踪这些优化的方法调用。例如:

代码语言:javascript
复制
trace = TracePoint.trace(:call, :c_call) do |tp|
  tp.disable
  puts "calling #{tp.defined_class}##{tp.method_id}"
  tp.enable
end

trace.enable
1.div(1)
1 / 1
1.div(2)

您可以看到,已跟踪1.div,但未跟踪1/1

代码语言:javascript
复制
calling TracePoint#enable
calling Fixnum#div
calling Fixnum#div

所以我的问题是:如何在Ruby (MRI)中跟踪所有的方法调用,包括“优化的”方法调用?

EN

回答 1

Stack Overflow用户

发布于 2015-07-21 01:43:55

在koichi中,您可以使用以下命令禁用优化:

代码语言:javascript
复制
RubyVM::InstructionSequence.compile_option = { specialized_instruction: false }

这将适用于我的情况,但我认为它会减慢执行速度。

如果您在家中尝试这样做,另一个警告是,您不能在同一文件中设置compile_option,因为在执行时,该文件已经被编译。相反,您需要在加载或请求您试图跟踪的文件之前执行此代码。

您也可以在eval-d代码中使用此选项:

代码语言:javascript
复制
iseq = RubyVM::InstructionSequence.compile(<<EOS, nil, nil, 1, specialized_instruction: false)
   1 / 1
EOS

trace = TracePoint.trace(:call, :c_call) do |tp|
  tp.disable
  puts "calling #{tp.defined_class}##{tp.method_id}"
  tp.enable
end

iseq.eval
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31521903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档