Skip to content

Commit 90810be

Browse files
authored
Record more GC info (#60)
* Record more GC info
1 parent 1ac140c commit 90810be

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

ext/vernier/vernier.cc

+50-7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ static VALUE rb_mVernierMarkerType;
5959
static VALUE rb_cVernierCollector;
6060
static VALUE rb_cStackTable;
6161

62+
static VALUE sym_state, sym_gc_by;
63+
6264
static const char *gvl_event_name(rb_event_flag_t event) {
6365
switch (event) {
6466
case RUBY_INTERNAL_THREAD_EVENT_STARTED:
@@ -796,6 +798,12 @@ static native_thread_id_t get_native_thread_id() {
796798
#endif
797799
}
798800

801+
union MarkerInfo {
802+
struct {
803+
VALUE gc_by;
804+
VALUE gc_state;
805+
} gc_data;
806+
};
799807

800808
class Marker {
801809
public:
@@ -833,8 +841,10 @@ class Marker {
833841
//native_thread_id_t thread_id;
834842
int stack_index = -1;
835843

844+
MarkerInfo extra_info;
845+
836846
VALUE to_array() {
837-
VALUE record[6] = {0};
847+
VALUE record[7] = {0};
838848
record[0] = Qnil; // FIXME
839849
record[1] = INT2NUM(type);
840850
record[2] = INT2NUM(phase);
@@ -848,7 +858,14 @@ class Marker {
848858
}
849859
record[5] = stack_index == -1 ? Qnil : INT2NUM(stack_index);
850860

851-
return rb_ary_new_from_values(6, record);
861+
if (type == Marker::MARKER_GC_PAUSE) {
862+
VALUE hash = rb_hash_new();
863+
record[6] = hash;
864+
865+
rb_hash_aset(hash, sym_gc_by, extra_info.gc_data.gc_by);
866+
rb_hash_aset(hash, sym_state, extra_info.gc_data.gc_state);
867+
}
868+
return rb_ary_new_from_values(7, record);
852869
}
853870
};
854871

@@ -863,7 +880,7 @@ class MarkerTable {
863880
list.push_back({ type, Marker::INTERVAL, from, to, stack_index });
864881
}
865882

866-
void record(Marker::Type type, int stack_index = -1) {
883+
void record(Marker::Type type, int stack_index = -1, MarkerInfo extra_info = {}) {
867884
const std::lock_guard<std::mutex> lock(mutex);
868885

869886
list.push_back({ type, Marker::INSTANT, TimeStamp::Now(), TimeStamp(), stack_index });
@@ -874,12 +891,34 @@ class GCMarkerTable: public MarkerTable {
874891
TimeStamp last_gc_entry;
875892

876893
public:
894+
void record_gc_start() {
895+
record(Marker::Type::MARKER_GC_START);
896+
}
897+
877898
void record_gc_entered() {
878899
last_gc_entry = TimeStamp::Now();
879900
}
880901

881902
void record_gc_leave() {
882-
list.push_back({ Marker::MARKER_GC_PAUSE, Marker::INTERVAL, last_gc_entry, TimeStamp::Now(), -1 });
903+
VALUE gc_state = rb_gc_latest_gc_info(sym_state);
904+
VALUE gc_by = rb_gc_latest_gc_info(sym_gc_by);
905+
union MarkerInfo info = {
906+
.gc_data = {
907+
.gc_by = gc_by,
908+
.gc_state = gc_state
909+
}
910+
};
911+
list.push_back({ Marker::MARKER_GC_PAUSE, Marker::INTERVAL, last_gc_entry, TimeStamp::Now(), -1, info });
912+
}
913+
914+
void record_gc_end_mark() {
915+
record_gc_leave();
916+
record(Marker::Type::MARKER_GC_END_MARK);
917+
record_gc_entered();
918+
}
919+
920+
void record_gc_end_sweep() {
921+
record(Marker::Type::MARKER_GC_END_SWEEP);
883922
}
884923
};
885924

@@ -1701,13 +1740,13 @@ class TimeCollector : public BaseCollector {
17011740

17021741
switch (event) {
17031742
case RUBY_INTERNAL_EVENT_GC_START:
1704-
collector->gc_markers.record(Marker::Type::MARKER_GC_START);
1743+
collector->gc_markers.record_gc_start();
17051744
break;
17061745
case RUBY_INTERNAL_EVENT_GC_END_MARK:
1707-
collector->gc_markers.record(Marker::Type::MARKER_GC_END_MARK);
1746+
collector->gc_markers.record_gc_end_mark();
17081747
break;
17091748
case RUBY_INTERNAL_EVENT_GC_END_SWEEP:
1710-
collector->gc_markers.record(Marker::Type::MARKER_GC_END_SWEEP);
1749+
collector->gc_markers.record_gc_end_sweep();
17111750
break;
17121751
case RUBY_INTERNAL_EVENT_GC_ENTER:
17131752
collector->gc_markers.record_gc_entered();
@@ -1998,6 +2037,10 @@ Init_consts(VALUE rb_mVernierMarkerPhase) {
19982037
extern "C" void
19992038
Init_vernier(void)
20002039
{
2040+
sym_state = sym("state");
2041+
sym_gc_by = sym("gc_by");
2042+
rb_gc_latest_gc_info(sym_state); // HACK: needs to be warmed so that it can be called during GC
2043+
20012044
rb_mVernier = rb_define_module("Vernier");
20022045
rb_cVernierResult = rb_define_class_under(rb_mVernier, "Result", rb_cObject);
20032046
VALUE rb_mVernierMarker = rb_define_module_under(rb_mVernier, "Marker");

lib/vernier/collector.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,12 @@ def stop
9494

9595
marker_strings = Marker.name_table
9696

97-
markers = self.markers.map do |(tid, type, phase, ts, te, stack)|
97+
markers = self.markers.map do |(tid, type, phase, ts, te, stack, extra_info)|
9898
name = marker_strings[type]
9999
sym = Marker::MARKER_SYMBOLS[type]
100100
data = { type: sym }
101101
data[:cause] = { stack: stack } if stack
102+
data.merge!(extra_info) if extra_info
102103
[tid, name, ts, te, phase, data]
103104
end
104105

lib/vernier/output/firefox.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@ def marker_schema
194194
{
195195
label: "Description",
196196
value: "All threads are paused as GC is performed"
197-
}
197+
},
198+
{ key: "state", format: "string" },
199+
{ key: "gc_by", format: "string" },
198200
]
199201
},
200202
*hook_additions

0 commit comments

Comments
 (0)