This refactoring makes the code a bit simpler.
if (!atomic::load(&sampling_profiler_p))
return;
- atomic::fetch_add(&sample_counts.sample_count, samples);
+ atomic::fetch_add(¤t_sample.sample_count, samples);
if (foreign_thread_p)
- atomic::fetch_add(&sample_counts.foreign_thread_sample_count, samples);
+ atomic::fetch_add(¤t_sample.foreign_thread_sample_count, samples);
else {
if (atomic::load(¤t_gc_p))
- atomic::fetch_add(&sample_counts.gc_sample_count, samples);
+ atomic::fetch_add(¤t_sample.gc_sample_count, samples);
if (atomic::load(¤t_jit_count) > 0)
- atomic::fetch_add(&sample_counts.jit_sample_count, samples);
+ atomic::fetch_add(¤t_sample.jit_sample_count, samples);
if (!code->seg->in_segment_p(pc))
- atomic::fetch_add(&sample_counts.foreign_sample_count, samples);
+ atomic::fetch_add(¤t_sample.foreign_sample_count, samples);
}
code->set_safepoint_guard(true);
}
+// Allocates memory (record_sample)
void factor_vm::handle_safepoint(cell pc) {
code->set_safepoint_guard(false);
faulting_p = false;
set_array_nth(growarr.untagged(), 0, tag_fixnum(count + 1));
}
-profiling_sample_count profiling_sample_count::record_counts() volatile {
+profiling_sample profiling_sample::record_counts() volatile {
atomic::fence();
- profiling_sample_count returned(sample_count, gc_sample_count,
- jit_sample_count, foreign_sample_count,
- foreign_thread_sample_count);
+ profiling_sample returned(sample_count, gc_sample_count,
+ jit_sample_count, foreign_sample_count,
+ foreign_thread_sample_count);
atomic::fetch_subtract(&sample_count, returned.sample_count);
atomic::fetch_subtract(&gc_sample_count, returned.gc_sample_count);
atomic::fetch_subtract(&jit_sample_count, returned.jit_sample_count);
return returned;
}
-void profiling_sample_count::clear() volatile {
+void profiling_sample::clear_counts() volatile {
sample_count = 0;
gc_sample_count = 0;
jit_sample_count = 0;
atomic::fence();
}
-profiling_sample::profiling_sample(profiling_sample_count const& counts, cell thread,
- cell callstack_begin, cell callstack_end)
- : counts(counts), thread(thread),
- callstack_begin(callstack_begin),
- callstack_end(callstack_end) { }
-
// Allocates memory (sample_callstacks2->add)
void factor_vm::record_sample(bool prolog_p) {
- profiling_sample_count counts = sample_counts.record_counts();
- if (counts.empty()) {
+ profiling_sample result = current_sample.record_counts();
+ if (result.empty()) {
return;
}
// Appends the callstack, which is just a sequence of quotation or
cell end = growarr_capacity(callstacks.untagged());
// Add the sample.
- cell thread = special_objects[OBJ_CURRENT_THREAD];
- samples.push_back(profiling_sample(counts, thread, begin, end));
+ result.thread = special_objects[OBJ_CURRENT_THREAD];
+ result.callstack_begin = begin;
+ result.callstack_end = end;
+ samples.push_back(result);
}
void factor_vm::set_sampling_profiler(fixnum rate) {
void factor_vm::start_sampling_profiler(fixnum rate) {
special_objects[OBJ_SAMPLE_CALLSTACKS] = tag<array>(allot_growarr());
samples_per_second = rate;
- sample_counts.clear();
+ current_sample.clear_counts();
// Release the memory consumed by collecting samples.
samples.clear();
samples.shrink_to_fit();
data_root<array> sample(allot_array(7, false_object), this);
set_array_nth(sample.untagged(), 0,
- tag_fixnum(from_iter->counts.sample_count));
+ tag_fixnum(from_iter->sample_count));
set_array_nth(sample.untagged(), 1,
- tag_fixnum(from_iter->counts.gc_sample_count));
+ tag_fixnum(from_iter->gc_sample_count));
set_array_nth(sample.untagged(), 2,
- tag_fixnum(from_iter->counts.jit_sample_count));
+ tag_fixnum(from_iter->jit_sample_count));
set_array_nth(sample.untagged(), 3,
- tag_fixnum(from_iter->counts.foreign_sample_count));
+ tag_fixnum(from_iter->foreign_sample_count));
set_array_nth(sample.untagged(), 4,
- tag_fixnum(from_iter->counts.foreign_thread_sample_count));
+ tag_fixnum(from_iter->foreign_thread_sample_count));
set_array_nth(sample.untagged(), 5, from_iter->thread);
namespace factor {
-struct profiling_sample_count {
+struct profiling_sample {
+ // Active thread during sample
+ cell thread;
+ // The callstack at safepoint time. Indexes to the beginning and ending
+ // word entries in the vm sample_callstacks array.
+ cell callstack_begin, callstack_end;
+
// Number of samples taken before the safepoint that recorded the sample
fixnum sample_count;
// Number of samples taken during GC
// Number of samples taken during code execution in non-Factor threads
fixnum foreign_thread_sample_count;
- profiling_sample_count(fixnum sample_count, fixnum gc_sample_count,
- fixnum jit_sample_count, fixnum foreign_sample_count,
- fixnum foreign_thread_sample_count)
- : sample_count(sample_count),
+ profiling_sample(fixnum sample_count, fixnum gc_sample_count,
+ fixnum jit_sample_count, fixnum foreign_sample_count,
+ fixnum foreign_thread_sample_count)
+ : thread(0),
+ callstack_begin(0),
+ callstack_end(0),
+ sample_count(sample_count),
gc_sample_count(gc_sample_count),
jit_sample_count(jit_sample_count),
foreign_sample_count(foreign_sample_count),
foreign_thread_sample_count(foreign_thread_sample_count) {}
+ profiling_sample record_counts() volatile;
+ void clear_counts() volatile;
bool empty() const {
return sample_count + gc_sample_count + jit_sample_count +
foreign_sample_count + foreign_thread_sample_count ==
0;
}
-
- profiling_sample_count record_counts() volatile;
- void clear() volatile;
-};
-
-struct profiling_sample {
- // Sample counts
- profiling_sample_count counts;
- // Active thread during sample
- cell thread;
- // The callstack at safepoint time. Indexes to the beginning and ending
- // code_block entries in the vm sample_callstacks array.
- cell callstack_begin, callstack_end;
-
- profiling_sample(profiling_sample_count const& counts, cell thread,
- cell callstack_begin, cell callstack_end);
};
}
sampling_profiler_p(false),
signal_pipe_input(0),
signal_pipe_output(0),
- sample_counts(0, 0, 0, 0, 0),
+ current_sample(0, 0, 0, 0, 0),
gc_off(false),
data(NULL), code(NULL), callbacks(NULL),
current_gc(NULL),
// State kept by the sampling profiler
std::vector<profiling_sample> samples;
- volatile profiling_sample_count sample_counts;
+ volatile profiling_sample current_sample;
// GC is off during heap walking
bool gc_off;