aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-09-17 19:09:10 +0200
committerStefan Boberg <[email protected]>2021-09-17 19:09:10 +0200
commitfeb3e97f486e474f0c5775a4c407ef6db540df49 (patch)
treed72dffdb0e66ab5b54aec3bbd466850f10bf7417
parentRemoved WindowsException from public headers (diff)
downloadzen-feb3e97f486e474f0c5775a4c407ef6db540df49.tar.xz
zen-feb3e97f486e474f0c5775a4c407ef6db540df49.zip
Assert improvements
-rw-r--r--zencore/include/zencore/zencore.h76
-rw-r--r--zencore/zencore.cpp10
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;