The code reads better if the safepoint_state methods and
attributes (sample_counts and safepoint_fep_p) are moved to the vm
class.
vm/image.hpp \
vm/callbacks.hpp \
vm/dispatch.hpp \
vm/image.hpp \
vm/callbacks.hpp \
vm/dispatch.hpp \
vm/vm.hpp \
vm/allot.hpp \
vm/tagged.hpp \
vm/vm.hpp \
vm/allot.hpp \
vm/tagged.hpp \
void memory_signal_handler_impl() {
factor_vm* vm = current_vm();
if (vm->code->safepoint_p(vm->signal_fault_addr)) {
void memory_signal_handler_impl() {
factor_vm* vm = current_vm();
if (vm->code->safepoint_p(vm->signal_fault_addr)) {
- vm->safepoint.handle_safepoint(vm, vm->signal_fault_pc);
+ vm->handle_safepoint(vm->signal_fault_pc);
}
else {
vm_error_type type = vm->ctx->address_to_error(vm->signal_fault_addr);
}
else {
vm_error_type type = vm->ctx->address_to_error(vm->signal_fault_addr);
#include "image.hpp"
#include "callbacks.hpp"
#include "dispatch.hpp"
#include "image.hpp"
#include "callbacks.hpp"
#include "dispatch.hpp"
-#include "safepoints.hpp"
#include "vm.hpp"
#include "allot.hpp"
#include "data_roots.hpp"
#include "vm.hpp"
#include "allot.hpp"
#include "data_roots.hpp"
factor_vm* vm = current_vm_p();
if (vm) {
factor_vm* vm = current_vm_p();
if (vm) {
- vm->safepoint.enqueue_fep(vm);
enqueue_signal(vm, signal);
} else
fatal_error("Foreign thread received signal", signal);
enqueue_signal(vm, signal);
} else
fatal_error("Foreign thread received signal", signal);
vm = thread_vms.begin()->second;
}
if (atomic::load(&vm->sampling_profiler_p))
vm = thread_vms.begin()->second;
}
if (atomic::load(&vm->sampling_profiler_p))
- vm->safepoint.enqueue_samples(vm, 1, (cell)UAP_PROGRAM_COUNTER(uap),
- foreign_thread);
+ vm->enqueue_samples(1, (cell)UAP_PROGRAM_COUNTER(uap), foreign_thread);
else if (!foreign_thread)
enqueue_signal(vm, signal);
}
else if (!foreign_thread)
enqueue_signal(vm, signal);
}
actually support native threads. */
FACTOR_ASSERT(thread_vms.size() == 1);
factor_vm* vm = thread_vms.begin()->second;
actually support native threads. */
FACTOR_ASSERT(thread_vms.size() == 1);
factor_vm* vm = thread_vms.begin()->second;
- vm->safepoint.enqueue_fep(vm);
/* Before leaving the ctrl_handler, try and wake up the main
thread. */
/* Before leaving the ctrl_handler, try and wake up the main
thread. */
continue;
cell pc = get_thread_pc(thread);
continue;
cell pc = get_thread_pc(thread);
- safepoint.enqueue_samples(this, samples, pc, false);
+ enqueue_samples(samples, pc, false);
-void safepoint_state::enqueue_fep(factor_vm* parent) volatile {
- if (parent->fep_p)
+void factor_vm::enqueue_fep() {
+ if (fep_p)
fatal_error("Low-level debugger interrupted", 0);
fatal_error("Low-level debugger interrupted", 0);
- atomic::store(&fep_p, true);
- parent->code->set_safepoint_guard(true);
+ atomic::store(&safepoint_fep_p, true);
+ code->set_safepoint_guard(true);
-void safepoint_state::enqueue_samples(factor_vm* parent,
- cell samples,
- cell pc,
- bool foreign_thread_p) volatile {
+void factor_vm::enqueue_samples(cell samples,
+ cell pc,
+ bool foreign_thread_p) {
- if (!atomic::load(&parent->sampling_profiler_p))
+ if (!atomic::load(&sampling_profiler_p))
return;
atomic::fetch_add(&sample_counts.sample_count, samples);
if (foreign_thread_p)
atomic::fetch_add(&sample_counts.foreign_thread_sample_count, samples);
else {
return;
atomic::fetch_add(&sample_counts.sample_count, samples);
if (foreign_thread_p)
atomic::fetch_add(&sample_counts.foreign_thread_sample_count, samples);
else {
- if (atomic::load(&parent->current_gc_p))
+ if (atomic::load(¤t_gc_p))
atomic::fetch_add(&sample_counts.gc_sample_count, samples);
atomic::fetch_add(&sample_counts.gc_sample_count, samples);
- if (atomic::load(&parent->current_jit_count) > 0)
+ if (atomic::load(¤t_jit_count) > 0)
atomic::fetch_add(&sample_counts.jit_sample_count, samples);
atomic::fetch_add(&sample_counts.jit_sample_count, samples);
- if (!parent->code->seg->in_segment_p(pc))
+ if (!code->seg->in_segment_p(pc))
atomic::fetch_add(&sample_counts.foreign_sample_count, samples);
}
atomic::fetch_add(&sample_counts.foreign_sample_count, samples);
}
- parent->code->set_safepoint_guard(true);
+ code->set_safepoint_guard(true);
-void safepoint_state::handle_safepoint(factor_vm* parent, cell pc) volatile {
- parent->code->set_safepoint_guard(false);
- parent->faulting_p = false;
+void factor_vm::handle_safepoint(cell pc) {
+ code->set_safepoint_guard(false);
+ faulting_p = false;
- if (atomic::load(&fep_p)) {
- if (atomic::load(&parent->sampling_profiler_p))
- parent->end_sampling_profiler();
+ if (atomic::load(&safepoint_fep_p)) {
+ if (atomic::load(&sampling_profiler_p))
+ end_sampling_profiler();
std::cout << "Interrupted\n";
std::cout << "Interrupted\n";
- parent->factorbug();
- atomic::store(&fep_p, false);
- } else if (atomic::load(&parent->sampling_profiler_p)) {
- FACTOR_ASSERT(parent->code->seg->in_segment_p(pc));
- code_block* block = parent->code->code_block_for_address(pc);
+ factorbug();
+ atomic::store(&safepoint_fep_p, false);
+ } else if (atomic::load(&sampling_profiler_p)) {
+ FACTOR_ASSERT(code->seg->in_segment_p(pc));
+ code_block* block = code->code_block_for_address(pc);
bool prolog_p = block->entry_point() == pc;
bool prolog_p = block->entry_point() == pc;
- parent->record_sample(prolog_p);
+ record_sample(prolog_p);
+++ /dev/null
-namespace factor {
-
-struct safepoint_state {
- cell fep_p;
- profiling_sample_count sample_counts;
-
- safepoint_state() : fep_p(false), sample_counts() {}
-
- void handle_safepoint(factor_vm* parent, cell pc) volatile;
-
- void enqueue_samples(factor_vm* parent, cell samples, cell pc,
- bool foreign_thread_p) volatile;
- void enqueue_fep(factor_vm* parent) volatile;
-};
-
-}
callstack_end(callstack_end) { }
void factor_vm::record_sample(bool prolog_p) {
callstack_end(callstack_end) { }
void factor_vm::record_sample(bool prolog_p) {
- profiling_sample_count counts = safepoint.sample_counts.record_counts();
+ profiling_sample_count counts = sample_counts.record_counts();
if (counts.empty()) {
return;
}
if (counts.empty()) {
return;
}
void factor_vm::start_sampling_profiler(fixnum rate) {
samples_per_second = rate;
void factor_vm::start_sampling_profiler(fixnum rate) {
samples_per_second = rate;
- safepoint.sample_counts.clear();
/* Release the memory consumed by collecting samples. */
samples.clear();
samples.shrink_to_fit();
/* Release the memory consumed by collecting samples. */
samples.clear();
samples.shrink_to_fit();
/* Number of samples taken during code execution in non-Factor threads */
fixnum foreign_thread_sample_count;
/* Number of samples taken during code execution in non-Factor threads */
fixnum foreign_thread_sample_count;
- profiling_sample_count()
- : sample_count(0),
- gc_sample_count(0),
- jit_sample_count(0),
- foreign_sample_count(0),
- foreign_thread_sample_count(0) {}
-
profiling_sample_count(fixnum sample_count, fixnum gc_sample_count,
fixnum jit_sample_count, fixnum foreign_sample_count,
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)
sampling_profiler_p(false),
signal_pipe_input(0),
signal_pipe_output(0),
sampling_profiler_p(false),
signal_pipe_input(0),
signal_pipe_output(0),
+ sample_counts(0, 0, 0, 0, 0),
gc_off(false),
data(NULL), code(NULL), callbacks(NULL),
current_gc(NULL),
gc_off(false),
data(NULL), code(NULL), callbacks(NULL),
current_gc(NULL),
full_output(false),
last_nano_count(0),
signal_callstack_seg(NULL),
full_output(false),
last_nano_count(0),
signal_callstack_seg(NULL),
+ safepoint_fep_p(false) {
primitive_reset_dispatch_stats();
}
primitive_reset_dispatch_stats();
}
/* State kept by the sampling profiler */
std::vector<profiling_sample> samples;
std::vector<cell> sample_callstacks;
/* State kept by the sampling profiler */
std::vector<profiling_sample> samples;
std::vector<cell> sample_callstacks;
+ volatile profiling_sample_count sample_counts;
/* GC is off during heap walking */
bool gc_off;
/* GC is off during heap walking */
bool gc_off;
/* Are we already handling a fault? Used to catch double memory faults */
static bool fatal_erroring_p;
/* Are we already handling a fault? Used to catch double memory faults */
static bool fatal_erroring_p;
- /* Safepoint state */
- volatile safepoint_state safepoint;
+ /* Two fep_p variants, one might be redundant. */
+ volatile cell safepoint_fep_p;
/* contexts */
context* new_context();
/* contexts */
context* new_context();
cell get_fpu_state();
void set_fpu_state(cell state);
cell get_fpu_state();
void set_fpu_state(cell state);
+ /* safepoints */
+ void handle_safepoint(cell pc);
+ void enqueue_samples(cell samples, cell pc, bool foreign_thread_p);
+ void enqueue_fep();
+
/* factor */
void prepare_boot_image();
void init_factor(vm_parameters* p);
/* factor */
void prepare_boot_image();
void init_factor(vm_parameters* p);