diff options
| author | Stefan Boberg <[email protected]> | 2021-09-17 19:09:10 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-09-17 19:09:10 +0200 |
| commit | feb3e97f486e474f0c5775a4c407ef6db540df49 (patch) | |
| tree | d72dffdb0e66ab5b54aec3bbd466850f10bf7417 | |
| parent | Removed WindowsException from public headers (diff) | |
| download | zen-feb3e97f486e474f0c5775a4c407ef6db540df49.tar.xz zen-feb3e97f486e474f0c5775a4c407ef6db540df49.zip | |
Assert improvements
| -rw-r--r-- | zencore/include/zencore/zencore.h | 76 | ||||
| -rw-r--r-- | zencore/zencore.cpp | 10 |
2 files changed, 54 insertions, 32 deletions
diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index 8011ab241..4f9dc6322 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -3,7 +3,7 @@ #pragma once #include <cinttypes> -#include <exception> +#include <stdexcept> #include <string> ////////////////////////////////////////////////////////////////////////// @@ -90,37 +90,69 @@ // Assert // +#if ZEN_PLATFORM_WINDOWS +// Tells the compiler to put the decorated function in a certain section (aka. segment) of the executable. +# define ZEN_CODE_SECTION(Name) __declspec(code_seg(Name)) +# define ZEN_FORCENOINLINE __declspec(noinline) /* Force code to NOT be inline */ +#else +# define ZEN_CODE_SECTION(Name) +# define ZEN_FORCENOINLINE +#endif + +#if ZEN_ARCH_ARM64 +// On ARM we can't do this because the executable will require jumps larger +// than the branch instruction can handle. Clang will only generate +// the trampolines in the .text segment of the binary. If the uedbg segment +// is present it will generate code that it cannot link. +# define ZEN_DEBUG_SECTION +#else +// We'll put all assert implementation code into a separate section in the linked +// executable. This code should never execute so using a separate section keeps +// it well off the hot path and hopefully out of the instruction cache. It also +// facilitates reasoning about the makeup of a compiled/linked binary. +# define ZEN_DEBUG_SECTION ZEN_CODE_SECTION(".zcold") +#endif // DO_CHECK || DO_GUARD_SLOW + namespace zen { -class AssertException : public std::exception +class AssertException : public std::logic_error { public: - AssertException(const char* Msg); - ~AssertException(); - - [[nodiscard]] virtual char const* what() const noexcept override { return m_Msg.c_str(); } - -private: - std::string m_Msg; + AssertException(const char* Msg) : std::logic_error(Msg) {} }; } // namespace zen -#define ZEN_ASSERT(x, ...) \ - do \ - { \ - if (x) \ - break; \ - throw ::zen::AssertException{#x}; \ +template<typename RetType = void, class InnerType, typename... ArgTypes> +RetType ZEN_FORCENOINLINE ZEN_DEBUG_SECTION +DispatchAssert(InnerType&& Inner, ArgTypes const&... Args) +{ + return Inner(Args...); +} + +#define ZEN_ASSERT(x, ...) \ + do \ + { \ + if (x) [[unlikely]] \ + break; \ + struct Impl \ + { \ + static void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION ExecThrow [[noreturn]] () { throw ::zen::AssertException{#x}; } \ + }; \ + Impl::ExecThrow(); \ } while (false) #ifndef NDEBUG -# define ZEN_ASSERT_SLOW(x, ...) \ - do \ - { \ - if (x) \ - break; \ - throw ::zen::AssertException{#x}; \ +# define ZEN_ASSERT_SLOW(x, ...) \ + do \ + { \ + if (x) [[unlikely]] \ + break; \ + struct Impl \ + { \ + static void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION ExecThrow [[noreturn]] () { throw ::zen::AssertException{#x}; } \ + }; \ + Impl::ExecThrow(); \ } while (false) #else # define ZEN_ASSERT_SLOW(x, ...) @@ -148,7 +180,7 @@ char (&ZenArrayCountHelper(const T (&)[N]))[N + 1]; #define ZEN_UNUSED(...) ((void)__VA_ARGS__) #define ZEN_NOT_IMPLEMENTED(...) ZEN_ASSERT(false, __VA_ARGS__) -#define ZENCORE_API // Placeholder to allow DLL configs in the future +#define ZENCORE_API // Placeholder to allow DLL configs in the future (maybe) namespace zen { diff --git a/zencore/zencore.cpp b/zencore/zencore.cpp index bb457ed0a..d0b1135dc 100644 --- a/zencore/zencore.cpp +++ b/zencore/zencore.cpp @@ -69,16 +69,6 @@ IsDebuggerPresent() ////////////////////////////////////////////////////////////////////////// -AssertException::AssertException(const char* Msg) : m_Msg(Msg) -{ -} - -AssertException::~AssertException() -{ -} - -////////////////////////////////////////////////////////////////////////// - static int s_ApplicationExitCode = 0; static bool s_ApplicationExitRequested; |