Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6155895

Browse files
committedJul 12, 2022
Use postponed jobs if YJIT is enabled.
Fix: tmm1#179 YJIT doesn't support being interrupted by signal in random places, and probably will never support it.
1 parent df24b85 commit 6155895

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed
 

‎ext/stackprof/stackprof.c

+27-19
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,14 @@
2525
#define FAKE_FRAME_MARK INT2FIX(1)
2626
#define FAKE_FRAME_SWEEP INT2FIX(2)
2727

28-
/*
29-
* As of Ruby 3.0, it should be safe to read stack frames at any time
30-
* See https://github.com/ruby/ruby/commit/0e276dc458f94d9d79a0f7c7669bde84abe80f21
31-
*/
32-
#if RUBY_API_VERSION_MAJOR < 3
33-
#define USE_POSTPONED_JOB
34-
#endif
35-
3628
static const char *fake_frame_cstrs[] = {
3729
"(garbage collection)",
3830
"(marking)",
3931
"(sweeping)",
4032
};
4133

34+
static int stackprof_use_postponed_job = 1;
35+
4236
#define TOTAL_FAKE_FRAMES (sizeof(fake_frame_cstrs) / sizeof(char *))
4337

4438
#ifdef _POSIX_MONOTONIC_CLOCK
@@ -701,15 +695,13 @@ stackprof_job_record_gc(void *data)
701695
stackprof_record_gc_samples();
702696
}
703697

704-
#ifdef USE_POSTPONED_JOB
705698
static void
706699
stackprof_job_sample_and_record(void *data)
707700
{
708701
if (!_stackprof.running) return;
709702

710703
stackprof_sample_and_record();
711704
}
712-
#endif
713705

714706
static void
715707
stackprof_job_record_buffer(void *data)
@@ -740,15 +732,15 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
740732
_stackprof.unrecorded_gc_samples++;
741733
rb_postponed_job_register_one(0, stackprof_job_record_gc, (void*)0);
742734
} else {
743-
#ifdef USE_POSTPONED_JOB
744-
rb_postponed_job_register_one(0, stackprof_job_sample_and_record, (void*)0);
745-
#else
746-
// Buffer a sample immediately, if an existing sample exists this will
747-
// return immediately
748-
stackprof_buffer_sample();
749-
// Enqueue a job to record the sample
750-
rb_postponed_job_register_one(0, stackprof_job_record_buffer, (void*)0);
751-
#endif
735+
if (stackprof_use_postponed_job) {
736+
rb_postponed_job_register_one(0, stackprof_job_sample_and_record, (void*)0);
737+
} else {
738+
// Buffer a sample immediately, if an existing sample exists this will
739+
// return immediately
740+
stackprof_buffer_sample();
741+
// Enqueue a job to record the sample
742+
rb_postponed_job_register_one(0, stackprof_job_record_buffer, (void*)0);
743+
}
752744
}
753745
pthread_mutex_unlock(&lock);
754746
}
@@ -826,9 +818,24 @@ stackprof_atfork_child(void)
826818
stackprof_stop(rb_mStackProf);
827819
}
828820

821+
static VALUE
822+
stackprof_use_postponed_job_l(VALUE self)
823+
{
824+
stackprof_use_postponed_job = true;
825+
return Qnil;
826+
}
827+
829828
void
830829
Init_stackprof(void)
831830
{
831+
/*
832+
* As of Ruby 3.0, it should be safe to read stack frames at any time, unless YJIT is enabled
833+
* See https://github.com/ruby/ruby/commit/0e276dc458f94d9d79a0f7c7669bde84abe80f21
834+
*/
835+
#if RUBY_API_VERSION_MAJOR < 3
836+
stackprof_use_postponed_job = false;
837+
#endif
838+
832839
size_t i;
833840
#define S(name) sym_##name = ID2SYM(rb_intern(#name));
834841
S(object);
@@ -890,6 +897,7 @@ Init_stackprof(void)
890897
rb_define_singleton_method(rb_mStackProf, "stop", stackprof_stop, 0);
891898
rb_define_singleton_method(rb_mStackProf, "results", stackprof_results, -1);
892899
rb_define_singleton_method(rb_mStackProf, "sample", stackprof_sample, 0);
900+
rb_define_singleton_method(rb_mStackProf, "use_postponed_job!", stackprof_use_postponed_job_l, 0);
893901

894902
pthread_atfork(stackprof_atfork_prepare, stackprof_atfork_parent, stackprof_atfork_child);
895903
}

‎lib/stackprof.rb

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
require "stackprof/stackprof"
22

3+
if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
4+
StackProf.use_postponed_job!
5+
end
6+
37
module StackProf
48
VERSION = '0.2.19'
59
end

0 commit comments

Comments
 (0)
Please sign in to comment.