namespace factor {
-void safepoint_state::enqueue_safepoint(factor_vm* parent) volatile {
- parent->code->set_safepoint_guard(true);
-}
-
-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);
- enqueue_safepoint(parent);
+ 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);
+ 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(&parent->current_gc_p))
- atomic::fetch_add(&sample_counts.gc_sample_count, samples);
- if (atomic::load(&parent->current_jit_count) > 0)
- atomic::fetch_add(&sample_counts.jit_sample_count, samples);
- if (!parent->code->seg->in_segment_p(pc))
- atomic::fetch_add(&sample_counts.foreign_sample_count, samples);
+ if (atomic::load(¤t_gc_p))
+ atomic::fetch_add(¤t_sample.gc_sample_count, samples);
+ if (atomic::load(¤t_jit_count) > 0)
+ atomic::fetch_add(¤t_sample.jit_sample_count, samples);
+ if (!code->seg->in_segment_p(pc))
+ atomic::fetch_add(¤t_sample.foreign_sample_count, samples);
}
- enqueue_safepoint(parent);
+ 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;
+// Allocates memory (record_sample)
+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);
+ if (stop_on_ctrl_break) {
+ /* Ctrl-Break throws an exception, interrupting the main thread, same
+ as the "t" command in the factorbug debugger. But for Ctrl-Break to
+ work we don't require the debugger to be activated, or even enabled. */
+ atomic::store(&safepoint_fep_p, false);
+ general_error(ERROR_INTERRUPT, false_object, false_object);
+ FACTOR_ASSERT(false);
+ }
+ 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);
}
}