VM: removing the safepoint_state class
The code reads better if the safepoint_state methods and attributes (sample_counts and safepoint_fep_p) are moved to the vm class.char-rename
parent
2f6f69eb5b
commit
b5c6658ae5
|
@ -104,7 +104,6 @@ ifdef CONFIG
|
|||
vm/image.hpp \
|
||||
vm/callbacks.hpp \
|
||||
vm/dispatch.hpp \
|
||||
vm/safepoints.hpp \
|
||||
vm/vm.hpp \
|
||||
vm/allot.hpp \
|
||||
vm/tagged.hpp \
|
||||
|
|
|
@ -124,7 +124,7 @@ void factor_vm::primitive_unimplemented() { not_implemented_error(); }
|
|||
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);
|
||||
|
|
|
@ -122,7 +122,6 @@ namespace factor { struct factor_vm; }
|
|||
#include "image.hpp"
|
||||
#include "callbacks.hpp"
|
||||
#include "dispatch.hpp"
|
||||
#include "safepoints.hpp"
|
||||
#include "vm.hpp"
|
||||
#include "allot.hpp"
|
||||
#include "data_roots.hpp"
|
||||
|
|
|
@ -170,7 +170,7 @@ void fep_signal_handler(int signal, siginfo_t* siginfo, void* uap) {
|
|||
|
||||
factor_vm* vm = current_vm_p();
|
||||
if (vm) {
|
||||
vm->safepoint.enqueue_fep(vm);
|
||||
vm->enqueue_fep();
|
||||
enqueue_signal(vm, signal);
|
||||
} else
|
||||
fatal_error("Foreign thread received signal", signal);
|
||||
|
@ -184,8 +184,7 @@ void sample_signal_handler(int signal, siginfo_t* siginfo, void* uap) {
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) {
|
|||
actually support native threads. */
|
||||
FACTOR_ASSERT(thread_vms.size() == 1);
|
||||
factor_vm* vm = thread_vms.begin()->second;
|
||||
vm->safepoint.enqueue_fep(vm);
|
||||
vm->enqueue_fep();
|
||||
|
||||
/* Before leaving the ctrl_handler, try and wake up the main
|
||||
thread. */
|
||||
|
@ -344,7 +344,7 @@ void factor_vm::sampler_thread_loop() {
|
|||
continue;
|
||||
|
||||
cell pc = get_thread_pc(thread);
|
||||
safepoint.enqueue_samples(this, samples, pc, false);
|
||||
enqueue_samples(samples, pc, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,51 +2,50 @@
|
|||
|
||||
namespace factor {
|
||||
|
||||
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);
|
||||
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,
|
||||
void factor_vm::enqueue_samples(cell samples,
|
||||
cell pc,
|
||||
bool foreign_thread_p) volatile {
|
||||
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 {
|
||||
if (atomic::load(&parent->current_gc_p))
|
||||
if (atomic::load(¤t_gc_p))
|
||||
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);
|
||||
if (!parent->code->seg->in_segment_p(pc))
|
||||
if (!code->seg->in_segment_p(pc))
|
||||
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";
|
||||
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;
|
||||
|
||||
parent->record_sample(prolog_p);
|
||||
record_sample(prolog_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
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;
|
||||
};
|
||||
|
||||
}
|
|
@ -32,7 +32,7 @@ profiling_sample::profiling_sample(profiling_sample_count const& counts, cell th
|
|||
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;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ void factor_vm::set_sampling_profiler(fixnum rate) {
|
|||
|
||||
void factor_vm::start_sampling_profiler(fixnum rate) {
|
||||
samples_per_second = rate;
|
||||
safepoint.sample_counts.clear();
|
||||
sample_counts.clear();
|
||||
/* Release the memory consumed by collecting samples. */
|
||||
samples.clear();
|
||||
samples.shrink_to_fit();
|
||||
|
|
|
@ -12,13 +12,6 @@ struct profiling_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)
|
||||
|
|
|
@ -12,6 +12,7 @@ factor_vm::factor_vm(THREADHANDLE thread)
|
|||
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),
|
||||
|
@ -24,7 +25,7 @@ factor_vm::factor_vm(THREADHANDLE thread)
|
|||
full_output(false),
|
||||
last_nano_count(0),
|
||||
signal_callstack_seg(NULL),
|
||||
safepoint() {
|
||||
safepoint_fep_p(false) {
|
||||
primitive_reset_dispatch_stats();
|
||||
}
|
||||
|
||||
|
|
10
vm/vm.hpp
10
vm/vm.hpp
|
@ -87,6 +87,7 @@ struct factor_vm {
|
|||
/* 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;
|
||||
|
@ -145,8 +146,8 @@ struct factor_vm {
|
|||
/* 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();
|
||||
|
@ -679,6 +680,11 @@ struct factor_vm {
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue