From f7ea46e49e4851ee906ef9aad667f38f2d6a3e4f Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 25 Feb 2024 17:09:04 -0800 Subject: [PATCH] [build] Get release mode optimizations working Added a release config, and fixed a few spots where optimizations broke things: - Clang was generating incorrect code for run_ctor_list in libc's init.cpp (it ignored a check for the end of the list) - my rep movsb memcpy implementation used incorrect inline asm constraints, so it was returning a pointer to the end of the copied range instead of the start. Since this function was just inline asm anyway, I rewrote it in asm by hand in a new memutils.s file. --- assets/build/config.release.yaml | 3 +++ src/kernel/interrupts.cpp | 19 +++++++++++-------- src/libraries/j6/j6.module | 1 + src/libraries/j6/memutils.cpp | 8 -------- src/libraries/j6/memutils.s | 7 +++++++ src/libraries/libc/arch/amd64/init.cpp | 17 ++++++----------- 6 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 assets/build/config.release.yaml create mode 100644 src/libraries/j6/memutils.s diff --git a/assets/build/config.release.yaml b/assets/build/config.release.yaml new file mode 100644 index 0000000..7574ae4 --- /dev/null +++ b/assets/build/config.release.yaml @@ -0,0 +1,3 @@ +ccflags: [ + "-O3", +] \ No newline at end of file diff --git a/src/kernel/interrupts.cpp b/src/kernel/interrupts.cpp index 89705a6..fd95a7f 100644 --- a/src/kernel/interrupts.cpp +++ b/src/kernel/interrupts.cpp @@ -123,16 +123,19 @@ isr_handler(cpu_state *regs) uintptr_t cr2 = 0; __asm__ __volatile__ ("mov %%cr2, %0" : "=r"(cr2)); - bool user = cr2 < mem::kernel_offset; - vm_space::fault_type ft = - static_cast(regs->errorcode); + // The zero page is always invalid + if (cr2 > mem::frame_size) { + bool user = cr2 < mem::kernel_offset; + vm_space::fault_type ft = + static_cast(regs->errorcode); - vm_space &space = user - ? obj::process::current().space() - : vm_space::kernel_space(); + vm_space &space = user + ? obj::process::current().space() + : vm_space::kernel_space(); - if (cr2 && space.handle_fault(cr2, ft)) - break; + if (cr2 && space.handle_fault(cr2, ft)) + break; + } util::format({message, sizeof(message)}, "Page fault: %016lx%s%s%s%s%s", cr2, diff --git a/src/libraries/j6/j6.module b/src/libraries/j6/j6.module index 8c4524a..05bac16 100644 --- a/src/libraries/j6/j6.module +++ b/src/libraries/j6/j6.module @@ -8,6 +8,7 @@ j6 = module("j6", "condition.cpp", "init.cpp", "memutils.cpp", + "memutils.s", "mutex.cpp", "protocol_ids.cpp", "protocols/service_locator.cpp", diff --git a/src/libraries/j6/memutils.cpp b/src/libraries/j6/memutils.cpp index ff4fd1f..8e503c5 100644 --- a/src/libraries/j6/memutils.cpp +++ b/src/libraries/j6/memutils.cpp @@ -7,14 +7,6 @@ using namespace j6; using namespace __j6libc; -void *memcpy(void * restrict dst, const void * restrict src, size_t n) { - asm volatile ("rep movsb" - : - : "D"(dst), "S"(src), "c"(n) - : "memory"); - return dst; -} - static void memmove_dispatch(char *s1, const char *s2, size_t n) { if (s1 == s2) return; diff --git a/src/libraries/j6/memutils.s b/src/libraries/j6/memutils.s new file mode 100644 index 0000000..6e21817 --- /dev/null +++ b/src/libraries/j6/memutils.s @@ -0,0 +1,7 @@ +global memcpy: function (memcpy.end - memcpy) +memcpy: + mov rax, rdi + mov rcx, rdx + rep movsb + ret +memcpy.end: \ No newline at end of file diff --git a/src/libraries/libc/arch/amd64/init.cpp b/src/libraries/libc/arch/amd64/init.cpp index 4103b76..5f57c1a 100644 --- a/src/libraries/libc/arch/amd64/init.cpp +++ b/src/libraries/libc/arch/amd64/init.cpp @@ -9,16 +9,11 @@ extern cb __init_array_end; namespace { void -run_ctor_list(cb *array, cb *end) +run_ctor_list(cb *p, cb *end) { - if (!array || !end) - return; - - size_t i = 0; - while (true) { - const cb &ctor = array[i++]; - if (&ctor == end) return; - if (ctor) ctor(); + while (p && end && p < end) { + if (p) (*p)(); + ++p; } } @@ -31,8 +26,8 @@ run_global_ctors() } // namespace -extern "C" -void __init_libc() +extern "C" void +__init_libc() { run_global_ctors(); }