Skip to content

Instantly share code, notes, and snippets.

@HParker
Created September 23, 2022 00:54
Show Gist options
  • Save HParker/04700633cceeb21e376716d6f3f53580 to your computer and use it in GitHub Desktop.
Save HParker/04700633cceeb21e376716d6f3f53580 to your computer and use it in GitHub Desktop.
Common YARV Instruction Sequences

Common instruction sequences

What are some common instruction sequences in Ruby?

Results

results (172130552) instructions captured



==== top ====



opt_send_without_block = 26771616

getlocal_WC_0 = 24152570

leave = 20986069

putself = 13459785

getinstancevariable = 7888974

dup = 6825082

branchunless = 6586019

opt_getconstant_path = 5920847

setlocal_WC_0 = 5705813

putobject = 5508571

pop = 5093786

branchif = 5013099

getlocal_WC_1 = 3849367

send = 3826551

opt_aref = 3704390

putnil = 3367462

setinstancevariable = 2550503

nop = 2517919

invokesuper = 1327654

getblockparamproxy = 1262760

anytostring = 970513

objtostring = 970483

invokeblock = 929644

topn = 778921

opt_nil_p = 730179



==== 2 chains ====



chain ["putself", "opt_send_without_block"] = 7487855

chain ["leave", "leave"] = 7230372

chain ["getlocal_WC_0", "opt_send_without_block"] = 6637231

chain ["opt_send_without_block", "putself"] = 5202440

chain ["opt_send_without_block", "getlocal_WC_0"] = 3166332

chain ["putself", "getlocal_WC_0"] = 3079552

chain ["dup", "branchif"] = 3020450

chain ["opt_send_without_block", "getinstancevariable"] = 2921281

chain ["getlocal_WC_0", "getlocal_WC_0"] = 2513945

chain ["opt_send_without_block", "opt_send_without_block"] = 2194330

chain ["setlocal_WC_0", "getlocal_WC_0"] = 2104506

chain ["getinstancevariable", "getlocal_WC_0"] = 2079343

chain ["branchunless", "getlocal_WC_0"] = 2078492

chain ["opt_getconstant_path", "opt_send_without_block"] = 2069089

chain ["opt_send_without_block", "leave"] = 1997695

chain ["leave", "dup"] = 1970800

chain ["leave", "pop"] = 1960633

chain ["getlocal_WC_0", "leave"] = 1779102

chain ["opt_send_without_block", "opt_getconstant_path"] = 1751133

chain ["leave", "opt_send_without_block"] = 1675828

chain ["leave", "getlocal_WC_0"] = 1655517

chain ["opt_send_without_block", "branchunless"] = 1511248

chain ["branchunless", "putself"] = 1504074

chain ["getlocal_WC_0", "opt_aref"] = 1494720

chain ["opt_send_without_block", "setlocal_WC_0"] = 1492185



==== 3 chains ====



chain ["opt_send_without_block", "putself", "opt_send_without_block"] = 3413684

chain ["leave", "leave", "leave"] = 3349984

chain ["putself", "opt_send_without_block", "putself"] = 1545718

chain ["dup", "branchif", "leave"] = 1389588

chain ["getlocal_WC_0", "opt_send_without_block", "getlocal_WC_0"] = 1359823

chain ["putself", "getlocal_WC_0", "opt_send_without_block"] = 1318387

chain ["getinstancevariable", "dup", "branchif"] = 1253995

chain ["putself", "opt_send_without_block", "opt_send_without_block"] = 1187504

chain ["getlocal_WC_0", "opt_send_without_block", "putself"] = 1077235

chain ["branchunless", "putnil", "leave"] = 1055231

chain ["opt_send_without_block", "getlocal_WC_0", "opt_send_without_block"] = 1054997

chain ["getlocal_WC_0", "getlocal_WC_0", "opt_send_without_block"] = 1040941

chain ["opt_send_without_block", "putself", "getlocal_WC_0"] = 1032791

chain ["putself", "opt_send_without_block", "getinstancevariable"] = 1016305

chain ["branchunless", "getlocal_WC_0", "leave"] = 942084

chain ["getlocal_WC_0", "opt_aref", "leave"] = 924653

chain ["opt_send_without_block", "getinstancevariable", "dup"] = 916901

chain ["dup", "branchif", "pop"] = 912485

chain ["dup", "objtostring", "anytostring"] = 887359

chain ["opt_send_without_block", "opt_getconstant_path", "opt_send_without_block"] = 847526

chain ["putself", "getlocal_WC_0", "invokesuper"] = 817403

chain ["opt_aref", "opt_send_without_block", "putself"] = 797899

chain ["pop", "putself", "opt_send_without_block"] = 776257

chain ["topn", "opt_send_without_block", "branchif"] = 762999

chain ["putself", "opt_send_without_block", "getlocal_WC_0"] = 756618



==== 4 chains ====



chain ["leave", "leave", "leave", "leave"] = 1986709

chain ["putself", "opt_send_without_block", "putself", "opt_send_without_block"] = 1450282

chain ["getinstancevariable", "dup", "branchif", "leave"] = 925721

chain ["opt_send_without_block", "putself", "opt_send_without_block", "opt_send_without_block"] = 904834

chain ["opt_send_without_block", "getinstancevariable", "dup", "branchif"] = 881274

chain ["opt_send_without_block", "putself", "opt_send_without_block", "putself"] = 781554

chain ["getlocal_WC_0", "dup", "objtostring", "anytostring"] = 721364

chain ["putself", "getlocal_WC_0", "opt_send_without_block", "getlocal_WC_0"] = 669573

chain ["getlocal_WC_0", "opt_aref", "leave", "dup"] = 665421

chain ["leave", "dup", "setlocal_WC_0", "branchunless"] = 610493

chain ["getinstancevariable", "getlocal_WC_0", "opt_aref", "leave"] = 605809

chain ["dup", "objtostring", "anytostring", "putobject"] = 583694

chain ["putself", "opt_send_without_block", "getinstancevariable", "dup"] = 578240

chain ["putself", "opt_send_without_block", "getlocal_WC_0", "opt_send_without_block"] = 566360

chain ["opt_aref", "leave", "dup", "setlocal_WC_0"] = 560787

chain ["opt_send_without_block", "putself", "getlocal_WC_0", "invokesuper"] = 547972

chain ["putobject", "getlocal_WC_0", "dup", "objtostring"] = 525379

chain ["dup", "setlocal_WC_0", "branchunless", "getlocal_WC_0"] = 514989

chain ["opt_aref", "opt_send_without_block", "putself", "getlocal_WC_0"] = 510009

chain ["putself", "opt_send_without_block", "opt_send_without_block", "leave"] = 501988

chain ["setlocal_WC_0", "branchunless", "getlocal_WC_0", "leave"] = 498063

chain ["getlocal_WC_0", "opt_send_without_block", "putself", "opt_send_without_block"] = 478331

chain ["getlocal_WC_0", "setinstancevariable", "getlocal_WC_0", "setinstancevariable"] = 476456

chain ["putself", "getlocal_WC_0", "invokesuper", "getinstancevariable"] = 472142

chain ["invokesuper", "getinstancevariable", "getlocal_WC_0", "opt_aref"] = 472136


Methodology

build Ruby with dtrace & set VM_COLLECT_USAGE_DETAILS to 1

run activerecord tests and capture instruction events with this stap script

// ruby-instructions.stp
probe process("/home/adam/.rubies/ruby-master/bin/ruby").mark("insn")
{
    printf("%s\n", user_string($arg1))

}

Capture with,

sudo stap ruby-instructions.stp -o rails-tests2.txt -x $(pgrep ruby)

Parse the output with this script:

# parse_stap.rb

counts = {}

two_chains = {}
three_chains = {}
four_chains = {}

last = []

File.new("activerecord.txt", "r").each do |line|
  if !line.valid_encoding?
    # reset history when we encounter an invalid line
    last = []
    next
  end

  instruction = line.strip

  if counts[instruction]
    counts[instruction] += 1
  else
    counts[instruction] = 1
  end

  if last.size == 3
    key = last + [instruction]
    if two_chains[key.last(2)]
      two_chains[key.last(2)] += 1
    else
      two_chains[key.last(2)] = 1
    end

    if three_chains[key.last(3)]
      three_chains[key.last(3)] += 1
    else
      three_chains[key.last(3)] = 1
    end

    if four_chains[key.last(4)]
      four_chains[key.last(4)] += 1
    else
      four_chains[key.last(4)] = 1
    end

    last.shift
  end

  last.append(instruction)
end

puts counts.inspect
puts "="*100

puts "results (#{counts.values.sum}) instructions captured"

puts "\n==== top ====\n\n"

counts.sort_by { |x| x.last }.reverse.first(25).each do |(key, value)|
  puts "#{key} = #{value}"
end

puts "\n==== 2 chains ====\n\n"

two_chains.sort_by { |x| x.last }.reverse.first(25).each do |(key, value)|
  puts "chain #{key.inspect} = #{value}"
end

puts "\n==== 3 chains ====\n\n"

three_chains.sort_by { |x| x.last }.reverse.first(25).each do |(key, value)|
  puts "chain #{key.inspect} = #{value}"
end

puts "\n==== 4 chains ====\n\n"

four_chains.sort_by { |x| x.last }.reverse.first(25).each do |(key, value)|
  puts "chain #{key.inspect} = #{value}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment