Skip to content

Commit a0a4068

Browse files
Aiden Fox Iveyk0kubun
authored andcommitted
ZJIT: Use optimized exit_locations implementation
1 parent 55d363b commit a0a4068

1 file changed

Lines changed: 28 additions & 21 deletions

File tree

zjit.rb

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,56 +40,63 @@ def exit_locations
4040
frames = results[:frames].dup
4141
samples_count = 0
4242

43-
frames.each do |frame_id, frame|
44-
frame[:samples] = 0
45-
frame[:edges] = {}
46-
end
47-
4843
# Loop through the instructions and set the frame hash with the data.
4944
# We use nonexistent.def for the file name, otherwise insns.def will be displayed
5045
# and that information isn't useful in this context.
5146
RubyVM::INSTRUCTION_NAMES.each_with_index do |name, frame_id|
52-
frame_hash = { samples: 0, total_samples: 0, edges: {}, name: name, file: "nonexistent.def", line: nil }
47+
frame_hash = { samples: 0, total_samples: 0, edges: {}, name: name, file: "nonexistent.def", line: nil, lines: {} }
5348
results[:frames][frame_id] = frame_hash
5449
frames[frame_id] = frame_hash
5550
end
5651

5752
# Loop through the raw_samples and build the hashes for StackProf.
5853
# The loop is based off an example in the StackProf documentation and therefore
5954
# this functionality can only work with that library.
60-
while raw_samples.length > 0
61-
stack_trace = raw_samples.shift(raw_samples.shift + 1)
62-
lines = line_samples.shift(line_samples.shift + 1)
55+
#
56+
# Raw Samples:
57+
# [ length, frame1, frame2, frameN, ..., instruction, count
58+
#
59+
# Line Samples
60+
# [ length, line_1, line_2, line_n, ..., dummy value, count
61+
i = 0
62+
while i < raw_samples.length
63+
stack_length = raw_samples[i]
64+
i += 1 # consume the stack length
65+
66+
sample_count = raw_samples[i + stack_length]
67+
6368
prev_frame_id = nil
69+
stack_length.times do |idx|
70+
idx += i
71+
frame_id = raw_samples[idx]
6472

65-
stack_trace.each_with_index do |frame_id, idx|
6673
if prev_frame_id
6774
prev_frame = frames[prev_frame_id]
6875
prev_frame[:edges][frame_id] ||= 0
69-
prev_frame[:edges][frame_id] += 1
76+
prev_frame[:edges][frame_id] += sample_count
7077
end
7178

7279
frame_info = frames[frame_id]
73-
frame_info[:total_samples] ||= 0
74-
frame_info[:total_samples] += 1
80+
frame_info[:total_samples] += sample_count
7581

76-
frame_info[:lines] ||= {}
77-
frame_info[:lines][lines[idx]] ||= [0, 0]
78-
frame_info[:lines][lines[idx]][0] += 1
82+
frame_info[:lines][line_samples[idx]] ||= [0, 0]
83+
frame_info[:lines][line_samples[idx]][0] += sample_count
7984

8085
prev_frame_id = frame_id
8186
end
8287

83-
top_frame_id = stack_trace.last
88+
i += stack_length # consume the stack
89+
90+
top_frame_id = prev_frame_id
8491
top_frame_line = 1
8592

86-
frames[top_frame_id][:samples] += 1
93+
frames[top_frame_id][:samples] += sample_count
8794
frames[top_frame_id][:lines] ||= {}
8895
frames[top_frame_id][:lines][top_frame_line] ||= [0, 0]
89-
frames[top_frame_id][:lines][top_frame_line][1] += 1
96+
frames[top_frame_id][:lines][top_frame_line][1] += sample_count
9097

91-
samples_count += raw_samples.shift
92-
line_samples.shift
98+
samples_count += sample_count
99+
i += 1
93100
end
94101

95102
results[:samples] = samples_count

0 commit comments

Comments
 (0)