Skip to content

Commit

Permalink
Add simple test for sampling T_IMEMO objects
Browse files Browse the repository at this point in the history
  • Loading branch information
ivoanjo committed Nov 30, 2023
1 parent ffc9f36 commit 02e3f10
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions spec/datadog/profiling/collectors/cpu_and_wall_time_worker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,56 @@
expect(Time.new.strftime(String.new('Potato'))).to_not be nil
end
end

context 'T_IMEMO internal VM objects' do
let(:something_that_triggers_creation_of_imemo_objects) do
eval('proc { def self.foo; rand; end; foo }.call') # rubocop:disable Style/EvalWithLocation
end

context 'on Ruby 2.x' do
before { skip 'Behavior only applies on Ruby 2.x' unless RUBY_VERSION.start_with?('2.') }

it 'records internal VM objects, not including their specific kind' do
start

something_that_triggers_creation_of_imemo_objects

cpu_and_wall_time_worker.stop

imemo_samples =
samples_for_thread(samples_from_pprof(recorder.serialize!), Thread.current)
.select { |s| s.labels.fetch(:'allocation class', '') == '(VM Internal, T_IMEMO)' }

expect(imemo_samples.size).to be >= 1 # We should always get some T_IMEMO objects
end
end

context 'on Ruby 3.x' do
before { skip 'Behavior only applies on Ruby 3.x' if RUBY_VERSION.start_with?('2.') }

it 'records internal VM objects, including their specific kind' do
start

something_that_triggers_creation_of_imemo_objects

cpu_and_wall_time_worker.stop

imemo_samples =
samples_for_thread(samples_from_pprof(recorder.serialize!), Thread.current)
.select { |s| s.labels.fetch(:'allocation class', '').start_with?('(VM Internal, T_IMEMO') }

expect(imemo_samples.size).to be >= 1 # We should always get some T_IMEMO objects

# To avoid coupling too much on VM internals we check that at each of the found allocation classes are
# a known member of the imemo_type enum (even if we don't exactly match on which one)
expect(imemo_samples.map { |s| s.labels.fetch(:'allocation class') }).to all(
match(
/(env|cref|svar|throw_data|ifunc|memo|ment|iseq|tmpbuf|ast|parser_strterm|callinfo|callcache|constcache)/
)
)
end
end
end
end

context 'when allocation sampling is disabled' do
Expand Down

0 comments on commit 02e3f10

Please sign in to comment.