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