Create a gist now

Instantly share code, notes, and snippets.

Embed
require 'objspace'
require 'config/environment'
require 'fiddle'
require 'fiddle/import'
extend Fiddle::Importer
include Fiddle
dlload
typealias "VALUE", "unsigned long"
Basic = ["VALUE flags", "VALUE klass"]
RUBY_FL_USHIFT = 12
RUBY_T_IMEMO = 0x1a # /*!< @see imemo_type */
RUBY_T_MASK = 0x1f
RBasic = Class.new(struct Basic) do
table = Object.constants.grep(/^RUBY_T_/).each_with_object({}) do |name, obj|
obj[Object.const_get(name)] = name.to_s.sub(/^RUBY_/, '').to_sym
end
TYPE_TABLE = table
def imemo?
flags & RUBY_T_MASK == RUBY_T_IMEMO
end
def imemo_type
(flags >> RUBY_FL_USHIFT) & 0x0f
end
def iseq?
imemo_type == 7 # https://github.com/ruby/ruby/blob/dc03bdcefbf1fe062c0a7ad7fa5f6829866b8cab/internal.h#L852
end
end
ptr = Handle::DEFAULT["rb_objspace_each_objects"]
rb_objspace_each_objects = Function.new(ptr, [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOID)
ptr = Handle::DEFAULT["rb_iseqw_new"]
rb_iseq_new = Function.new ptr, [TYPE_VOIDP], TYPE_VOIDP
callback = Closure::BlockCaller.new TYPE_INT, [TYPE_VOIDP, TYPE_VOIDP, TYPE_INT, TYPE_VOIDP] do |vstart, vend, stride, data|
while vstart != vend
slot = RBasic.new(vstart)
if slot.imemo? && slot.iseq?
iseq = rb_iseq_new.call(vstart).to_value
puts [iseq.size, iseq.markable_object_count].join ','
end
vstart += stride
end
0
end
GC.start
puts "size,markables"
rb_objspace_each_objects.call(callback, nil)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment