diff --git a/vm/code_heap.cpp b/vm/code_heap.cpp index 3dd4683bbe..f77b0a1e34 100644 --- a/vm/code_heap.cpp +++ b/vm/code_heap.cpp @@ -49,6 +49,12 @@ void code_heap::free(code_block* compiled) { void code_heap::flush_icache() { factor::flush_icache(seg->start, seg->size); } +void code_heap::set_safepoint_guard(bool locked) { + if (!set_memory_locked(safepoint_page, getpagesize(), locked)) { + fatal_error("Cannot (un)protect safepoint guard page", safepoint_page); + } +} + void code_heap::sweep() { auto clear_free_blocks_from_all_blocks = [&](code_block* block, cell size) { std::set::iterator erase_from = diff --git a/vm/code_heap.hpp b/vm/code_heap.hpp index dc74840990..f5f3a2dc81 100644 --- a/vm/code_heap.hpp +++ b/vm/code_heap.hpp @@ -39,8 +39,7 @@ struct code_heap { bool uninitialized_p(code_block* compiled); void free(code_block* compiled); void flush_icache(); - void guard_safepoint(); - void unguard_safepoint(); + void set_safepoint_guard(bool locked); void verify_all_blocks_set(); void initialize_all_blocks_set(); diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index 6d4a04a7a6..c0a65948cb 100644 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -125,16 +125,6 @@ segment::~segment() { fatal_error("Segment deallocation failed", 0); } -void code_heap::guard_safepoint() { - if (!set_memory_locked(safepoint_page, getpagesize(), true)) - fatal_error("Cannot protect safepoint guard page", safepoint_page); -} - -void code_heap::unguard_safepoint() { - if (!set_memory_locked(safepoint_page, getpagesize(), false)) - fatal_error("Cannot unprotect safepoint guard page", safepoint_page); -} - void factor_vm::dispatch_signal(void* uap, void(handler)()) { dispatch_signal_handler((cell*)&UAP_STACK_POINTER(uap), (cell*)&UAP_PROGRAM_COUNTER(uap), diff --git a/vm/os-windows.cpp b/vm/os-windows.cpp index 586849e0a5..71bceba51a 100644 --- a/vm/os-windows.cpp +++ b/vm/os-windows.cpp @@ -137,16 +137,6 @@ long getpagesize() { return g_pagesize; } -void code_heap::guard_safepoint() { - if (!set_memory_locked(safepoint_page, getpagesize(), true)) - fatal_error("Cannot protect safepoint guard page", safepoint_page); -} - -void code_heap::unguard_safepoint() { - if (!set_memory_locked(safepoint_page, getpagesize(), false)) - fatal_error("Cannot unprotect safepoint guard page", safepoint_page); -} - void factor_vm::move_file(const vm_char* path1, const vm_char* path2) { if (MoveFileEx((path1), (path2), MOVEFILE_REPLACE_EXISTING) == false) general_error(ERROR_IO, tag_fixnum(GetLastError()), false_object); diff --git a/vm/safepoints.cpp b/vm/safepoints.cpp index 0970d60331..3b064f42af 100644 --- a/vm/safepoints.cpp +++ b/vm/safepoints.cpp @@ -3,7 +3,7 @@ namespace factor { void safepoint_state::enqueue_safepoint(factor_vm* parent) volatile { - parent->code->guard_safepoint(); + parent->code->set_safepoint_guard(true); } void safepoint_state::enqueue_fep(factor_vm* parent) volatile { @@ -13,26 +13,30 @@ void safepoint_state::enqueue_fep(factor_vm* parent) volatile { enqueue_safepoint(parent); } -void safepoint_state::enqueue_samples(factor_vm* parent, cell samples, cell pc, +void safepoint_state::enqueue_samples(factor_vm* parent, + cell samples, + cell pc, bool foreign_thread_p) volatile { - if (atomic::load(&parent->sampling_profiler_p)) { - 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)) - 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); - } - enqueue_safepoint(parent); + + if (!atomic::load(&parent->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)) + 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); } + enqueue_safepoint(parent); } void safepoint_state::handle_safepoint(factor_vm* parent, cell pc) volatile { - parent->code->unguard_safepoint(); + parent->code->set_safepoint_guard(false); parent->faulting_p = false; if (atomic::load(&fep_p)) {