From e8905b840cb13113f4d62c58f6730488628d694d Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 2 Jan 2015 15:25:58 +0100 Subject: [PATCH] Use C++11 move semantics to dramatically improve PointerTo performance --- dtool/src/dtoolbase/dtoolbase_cc.h | 41 +++++++++--------- panda/src/express/pointerTo.I | 68 ++++++++++++++++++++++++++++++ panda/src/express/pointerTo.h | 10 +++++ panda/src/express/pointerToBase.I | 14 ++++++ panda/src/express/pointerToBase.h | 4 ++ 5 files changed, 118 insertions(+), 19 deletions(-) diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h index 94891de299..93d90efe48 100644 --- a/dtool/src/dtoolbase/dtoolbase_cc.h +++ b/dtool/src/dtoolbase/dtoolbase_cc.h @@ -34,6 +34,7 @@ using namespace std; #define INLINE inline #define TYPENAME typename #define CONSTEXPR +#define NOEXCEPT noexcept #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname) @@ -121,15 +122,28 @@ typedef ios::seekdir ios_seekdir; #endif #if defined(__has_extension) // Clang magic. -#if __has_extension(cxx_constexpr) -#define CONSTEXPR constexpr -#else -#define CONSTEXPR INLINE -#endif +# if __has_extension(cxx_constexpr) +# define CONSTEXPR constexpr +# else +# define CONSTEXPR INLINE +# endif +# if __has_extension(cxx_noexcept) +# define NOEXCEPT noexcept +# else +# define NOEXCEPT +# endif +# if __has_extension(cxx_rvalue_references) +# define USE_MOVE_SEMANTICS +# endif #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && (__cplusplus >= 201103L) -#define CONSTEXPR constexpr +// noexcept was introduced in GCC 4.6, constexpr in GCC 4.7, rvalue refs in +// GCC 4.3. However, GCC only started defining __cplusplus properly in 4.7. +# define CONSTEXPR constexpr +# define NOEXCEPT noexcept +# define USE_MOVE_SEMANTICS #else -#define CONSTEXPR INLINE +# define CONSTEXPR INLINE +# define NOEXCEPT #endif #if defined(WIN32_VC) && !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES) @@ -209,7 +223,7 @@ public: TauProfile(void *&tautimer, char *name, char *type, int group, char *group_name) { Tau_profile_c_timer(&tautimer, name, type, group, group_name); _tautimer = tautimer; - TAU_PROFILE_START(_tautimer); + TAU_PROFILE_START(_tautimer); } ~TauProfile() { if (!__tau_shutdown) { @@ -233,16 +247,5 @@ private: #endif // USE_TAU -// Macros from hell. -#define EXT_METHOD(cl, m) Extension::m() -#define EXT_METHOD_ARGS(cl, m, ...) Extension::m(__VA_ARGS__) -#define EXT_CONST_METHOD(cl, m) Extension::m() const -#define EXT_CONST_METHOD_ARGS(cl, m, ...) Extension::m(__VA_ARGS__) const -#define EXT_NESTED_METHOD(cl1, cl2, m) Extension::m() -#define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) Extension::m(__VA_ARGS__) -#define EXT_NESTED_CONST_METHOD(cl1, cl2, m) Extension::m() const -#define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) Extension::m(__VA_ARGS__) const -#define CALL_EXT_METHOD(cl, m, obj, ...) invoke_extension(obj).m(__VA_ARGS__) - #endif // __cplusplus #endif diff --git a/panda/src/express/pointerTo.I b/panda/src/express/pointerTo.I index d17d6ed6e8..5b021f8e86 100644 --- a/panda/src/express/pointerTo.I +++ b/panda/src/express/pointerTo.I @@ -35,6 +35,40 @@ PointerTo(const PointerTo ©) : { } +#ifdef USE_MOVE_SEMANTICS +//////////////////////////////////////////////////////////////////// +// Function: PointerTo::Move Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE PointerTo:: +PointerTo(PointerTo &&move) NOEXCEPT : + PointerToBase((PointerToBase &&)move) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: PointerTo::Move Assignment Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE PointerTo &PointerTo:: +operator = (PointerTo &&move) NOEXCEPT { + To *old_ptr = (To *)this->_void_ptr; + + this->_void_ptr = move._void_ptr; + move._void_ptr = NULL; + + if (old_ptr != (To *)NULL) { + unref_delete(old_ptr); + } + + return *this; +} +#endif + //////////////////////////////////////////////////////////////////// // Function: PointerTo::Destructor // Access: Public @@ -166,6 +200,40 @@ ConstPointerTo(const ConstPointerTo ©) : { } +#ifdef USE_MOVE_SEMANTICS +//////////////////////////////////////////////////////////////////// +// Function: ConstPointerTo::Move Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE ConstPointerTo:: +ConstPointerTo(ConstPointerTo &&move) NOEXCEPT : + PointerToBase((PointerToBase &&)move) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: ConstPointerTo::Move Assignment Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE ConstPointerTo &ConstPointerTo:: +operator = (ConstPointerTo &&move) NOEXCEPT { + To *old_ptr = (To *)this->_void_ptr; + + this->_void_ptr = move._void_ptr; + move._void_ptr = NULL; + + if (old_ptr != (To *)NULL) { + unref_delete(old_ptr); + } + + return *this; +} +#endif + //////////////////////////////////////////////////////////////////// // Function: ConstPointerTo::Dereference operator // Access: Public diff --git a/panda/src/express/pointerTo.h b/panda/src/express/pointerTo.h index 144bc0eb87..e93ef68f80 100644 --- a/panda/src/express/pointerTo.h +++ b/panda/src/express/pointerTo.h @@ -85,6 +85,11 @@ PUBLISHED: INLINE ~PointerTo(); public: +#ifdef USE_MOVE_SEMANTICS + INLINE PointerTo(PointerTo &&move) NOEXCEPT; + INLINE PointerTo &operator = (PointerTo &&move) NOEXCEPT; +#endif + INLINE To &operator *() const; INLINE To *operator -> () const; // MSVC.NET 2005 insists that we use T *, and not To *, here. @@ -144,6 +149,11 @@ PUBLISHED: INLINE ~ConstPointerTo(); public: +#ifdef USE_MOVE_SEMANTICS + INLINE ConstPointerTo(ConstPointerTo &&move) NOEXCEPT; + INLINE ConstPointerTo &operator = (ConstPointerTo &&move) NOEXCEPT; +#endif + INLINE const To &operator *() const; INLINE const To *operator -> () const; INLINE operator const T *() const; diff --git a/panda/src/express/pointerToBase.I b/panda/src/express/pointerToBase.I index df0b635093..f6c5e192fd 100644 --- a/panda/src/express/pointerToBase.I +++ b/panda/src/express/pointerToBase.I @@ -35,6 +35,20 @@ PointerToBase(const PointerToBase ©) { reassign(copy); } +//////////////////////////////////////////////////////////////////// +// Function: PointerToBase::Move Constructor +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +#ifdef USE_MOVE_SEMANTICS +template +INLINE PointerToBase:: +PointerToBase(PointerToBase &&move) NOEXCEPT { + _void_ptr = move._void_ptr; + move._void_ptr = (void *)NULL; +} +#endif + //////////////////////////////////////////////////////////////////// // Function: PointerToBase::Destructor // Access: Protected diff --git a/panda/src/express/pointerToBase.h b/panda/src/express/pointerToBase.h index dd8a610188..495033ff71 100644 --- a/panda/src/express/pointerToBase.h +++ b/panda/src/express/pointerToBase.h @@ -38,6 +38,10 @@ protected: INLINE PointerToBase(const PointerToBase ©); INLINE ~PointerToBase(); +#ifdef USE_MOVE_SEMANTICS + INLINE PointerToBase(PointerToBase &&move) NOEXCEPT; +#endif + INLINE void reassign(To *ptr); INLINE void reassign(const PointerToBase ©);