Keep the main Context instance as static value, not pointer

This allows us to remove the lazy init checks, improving the inlining
potential when retrieving current context, thus slightly improving
the performance of assertions.

**runtime difference**

| --------- | Debug | Release |
|:----------|------:|--------:|
| Slow path |  1.01 |    0.98 |
| Fast path |  1.02 |    1.02 |

There is small slowdown in case of Release build + assertions taking
the slow path, but

1) going through the slow path is rare
2) Given the code change, I believe this to be artifact of the
   optimizer in the old GCC version I am using locally.
This commit is contained in:
Martin Hořeňovský
2025-09-23 11:32:20 +02:00
parent 0e772cc0d2
commit a2e41916f2
3 changed files with 4 additions and 24 deletions

View File

@@ -96,7 +96,6 @@ namespace Catch {
}
void cleanUp() {
cleanupSingletons();
cleanUpContext();
}
std::string translateActiveException() {
return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();

View File

@@ -6,25 +6,14 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_context.hpp>
#include <catch2/internal/catch_noncopyable.hpp>
#include <catch2/internal/catch_random_number_generator.hpp>
namespace Catch {
Context* Context::currentContext = nullptr;
void cleanUpContext() {
delete Context::currentContext;
Context::currentContext = nullptr;
}
void Context::createContext() {
currentContext = new Context();
}
Context Context::currentContext;
Context& getCurrentMutableContext() {
if ( !Context::currentContext ) { Context::createContext(); }
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
return *Context::currentContext;
return Context::currentContext;
}
SimplePcg32& sharedRng() {

View File

@@ -19,11 +19,9 @@ namespace Catch {
IConfig const* m_config = nullptr;
IResultCapture* m_resultCapture = nullptr;
CATCH_EXPORT static Context* currentContext;
CATCH_EXPORT static Context currentContext;
friend Context& getCurrentMutableContext();
friend Context const& getCurrentContext();
static void createContext();
friend void cleanUpContext();
public:
constexpr IResultCapture* getResultCapture() const {
@@ -40,15 +38,9 @@ namespace Catch {
Context& getCurrentMutableContext();
inline Context const& getCurrentContext() {
// We duplicate the logic from `getCurrentMutableContext` here,
// to avoid paying the call overhead in debug mode.
if ( !Context::currentContext ) { Context::createContext(); }
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
return *Context::currentContext;
return Context::currentContext;
}
void cleanUpContext();
class SimplePcg32;
SimplePcg32& sharedRng();
}