@@ -83,27 +83,35 @@ struct FuncInfo {
8383 return StringValueCStr (label);
8484 }
8585
86- static const char *file_cstr (VALUE frame) {
87- VALUE file = rb_profile_frame_absolute_path (frame);
88- if (NIL_P (file))
89- file = rb_profile_frame_path (frame);
86+ static const char *file_cstr (VALUE file) {
9087 if (NIL_P (file)) {
9188 return " (nil)" ;
9289 } else {
9390 return StringValueCStr (file);
9491 }
9592 }
9693
94+ static VALUE get_frame_file (VALUE frame) {
95+ VALUE file = rb_profile_frame_absolute_path (frame);
96+ if (NIL_P (file)) file = rb_profile_frame_path (frame);
97+ return file;
98+ }
99+
97100 static int first_lineno_int (VALUE frame) {
98101 VALUE first_lineno = rb_profile_frame_first_lineno (frame);
99102 return NIL_P (first_lineno) ? 0 : FIX2INT (first_lineno);
100103 }
101104
102105 FuncInfo (VALUE frame) :
103106 label (label_cstr(frame)),
104- file (file_cstr(frame)),
107+ file (file_cstr(is_refined_frame( frame) ? Qnil : get_frame_file(frame) )),
105108 first_lineno (first_lineno_int(frame)) { }
106109
110+ static bool is_refined_frame (VALUE frame) {
111+ VALUE label = rb_profile_frame_full_label (frame);
112+ return NIL_P (label);
113+ }
114+
107115 std::string label;
108116 std::string file;
109117 int first_lineno;
@@ -116,13 +124,25 @@ bool operator==(const FuncInfo& lhs, const FuncInfo& rhs) noexcept {
116124 lhs.first_lineno == rhs.first_lineno ;
117125}
118126
127+ bool operator !=(const FuncInfo& lhs, const FuncInfo& rhs) noexcept {
128+ return !(lhs == rhs);
129+ }
130+
119131struct Frame {
120132 VALUE frame;
133+ VALUE file;
121134 int line;
135+
136+ Frame () : frame(Qnil), file(Qnil), line(-1 ) { }
137+
138+ Frame (VALUE frame, int line) :
139+ frame (frame),
140+ file (Qnil),
141+ line (line) { }
122142};
123143
124144bool operator ==(const Frame& lhs, const Frame& rhs) noexcept {
125- return lhs.frame == rhs.frame && lhs.line == rhs.line ;
145+ return lhs.frame == rhs.frame && lhs.file == rhs. file && lhs. line == rhs.line ;
126146}
127147
128148bool operator !=(const Frame& lhs, const Frame& rhs) noexcept {
@@ -135,7 +155,7 @@ namespace std {
135155 {
136156 std::size_t operator ()(Frame const & s) const noexcept
137157 {
138- return s.frame ^ s.line ;
158+ return s.frame ^ s.file ^ s. line ;
139159 }
140160 };
141161}
@@ -164,7 +184,7 @@ class RawSample {
164184 Frame frame (int i) const {
165185 int idx = len - i - 1 ;
166186 if (idx < 0 ) throw std::out_of_range (" VERNIER BUG: index out of range" );
167- const Frame frame = { frames[idx], lines[idx]} ;
187+ const Frame frame = Frame ( frames[idx], lines[idx]) ;
168188 return frame;
169189 }
170190
@@ -279,10 +299,10 @@ struct StackTable {
279299 int parent;
280300 int index;
281301
282- StackNode (Frame frame, int index, int parent) : frame(frame), index(index), parent(parent) {}
302+ StackNode (Frame frame, int index, int parent) : frame(frame), index(index), parent(parent) { }
283303
284304 // root
285- StackNode () : frame(Frame{ 0 , 0 }) , index(-1 ), parent(-1 ) {}
305+ StackNode () : frame(Frame( 0 , 0 )) , index(-1 ), parent(-1 ) { }
286306 };
287307
288308 // This mutex guards the StackNodes only. The rest of the maps and vectors
@@ -349,20 +369,29 @@ struct StackTable {
349369 // Converts Frames from stacks other tables. "Symbolicates" the frames
350370 // which allocates.
351371 void finalize () {
372+ std::unordered_map<VALUE, Frame> frames_by_func;
373+
352374 {
353375 const std::lock_guard<std::mutex> lock (stack_mutex);
354376 for (int i = stack_node_list_finalized_idx; i < stack_node_list.size (); i++) {
355- const auto &stack_node = stack_node_list[i];
377+ auto &stack_node = stack_node_list[i];
378+ if (NIL_P (stack_node.frame .file ) && stack_node.frame .frame != 0 ) {
379+ VALUE file = rb_profile_frame_absolute_path (stack_node.frame .frame );
380+ if (NIL_P (file)) file = rb_profile_frame_path (stack_node.frame .frame );
381+ stack_node.frame .file = file;
382+ }
356383 frame_map.index (stack_node.frame );
357384 func_map.index (stack_node.frame .frame );
385+ frames_by_func.emplace (stack_node.frame .frame , stack_node.frame );
358386 stack_node_list_finalized_idx = i;
359387 }
360388 }
361389
362390 for (int i = func_info_list.size (); i < func_map.size (); i++) {
363391 const auto &func = func_map[i];
392+ const auto &frame = frames_by_func[func];
364393 // must not hold a mutex here
365- func_info_list.push_back (FuncInfo (func ));
394+ func_info_list.push_back (FuncInfo (frame. frame ));
366395 }
367396 }
368397
@@ -371,6 +400,7 @@ struct StackTable {
371400
372401 for (auto stack_node: stack_node_list) {
373402 rb_gc_mark (stack_node.frame .frame );
403+ rb_gc_mark (stack_node.frame .file );
374404 }
375405 }
376406
@@ -1177,9 +1207,10 @@ class BaseCollector {
11771207 VALUE start_thread;
11781208 TimeStamp started_at;
11791209
1180- BaseCollector (VALUE stack_table_value) : stack_table_value(stack_table_value), stack_table(get_stack_table(stack_table_value)) {
1181- }
1182- virtual ~BaseCollector () {}
1210+ BaseCollector (VALUE stack_table_value) :
1211+ stack_table_value (stack_table_value),
1212+ stack_table (get_stack_table(stack_table_value)) { }
1213+ virtual ~BaseCollector () { }
11831214
11841215 virtual bool start () {
11851216 if (running) {
@@ -1421,15 +1452,15 @@ class RetainedCollector : public BaseCollector {
14211452 RetainedCollector *collector = this ;
14221453 for (auto & obj: collector->object_list ) {
14231454 VALUE reloc_obj = rb_gc_location (obj);
1424-
1455+
14251456 const auto search = collector->object_frames .find (obj);
14261457 if (search != collector->object_frames .end ()) {
14271458 int stack_index = search->second ;
1428-
1459+
14291460 collector->object_frames .erase (search);
14301461 collector->object_frames .emplace (reloc_obj, stack_index);
14311462 }
1432-
1463+
14331464 obj = reloc_obj;
14341465 }
14351466 }
0 commit comments