Browse Source

Use C++11 move semantics to dramatically improve PointerTo performance

rdb 11 years ago
parent
commit
e8905b840c

+ 22 - 19
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<cl>::m()
-#define EXT_METHOD_ARGS(cl, m, ...) Extension<cl>::m(__VA_ARGS__)
-#define EXT_CONST_METHOD(cl, m) Extension<cl>::m() const
-#define EXT_CONST_METHOD_ARGS(cl, m, ...) Extension<cl>::m(__VA_ARGS__) const
-#define EXT_NESTED_METHOD(cl1, cl2, m) Extension<cl1::cl2>::m()
-#define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) Extension<cl1::cl2>::m(__VA_ARGS__)
-#define EXT_NESTED_CONST_METHOD(cl1, cl2, m) Extension<cl1::cl2>::m() const
-#define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) Extension<cl1::cl2>::m(__VA_ARGS__) const
-#define CALL_EXT_METHOD(cl, m, obj, ...) invoke_extension(obj).m(__VA_ARGS__)
-
 #endif  //  __cplusplus
 #endif

+ 68 - 0
panda/src/express/pointerTo.I

@@ -35,6 +35,40 @@ PointerTo(const PointerTo<T> &copy) :
 {
 }
 
+#ifdef USE_MOVE_SEMANTICS
+////////////////////////////////////////////////////////////////////
+//     Function: PointerTo::Move Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class T>
+INLINE PointerTo<T>::
+PointerTo(PointerTo<T> &&move) NOEXCEPT :
+  PointerToBase<T>((PointerToBase<T> &&)move)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerTo::Move Assignment Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class T>
+INLINE PointerTo<T> &PointerTo<T>::
+operator = (PointerTo<T> &&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<T> &copy) :
 {
 }
 
+#ifdef USE_MOVE_SEMANTICS
+////////////////////////////////////////////////////////////////////
+//     Function: ConstPointerTo::Move Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class T>
+INLINE ConstPointerTo<T>::
+ConstPointerTo(ConstPointerTo<T> &&move) NOEXCEPT :
+  PointerToBase<T>((PointerToBase<T> &&)move)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConstPointerTo::Move Assignment Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class T>
+INLINE ConstPointerTo<T> &ConstPointerTo<T>::
+operator = (ConstPointerTo<T> &&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

+ 10 - 0
panda/src/express/pointerTo.h

@@ -85,6 +85,11 @@ PUBLISHED:
   INLINE ~PointerTo();
 
 public:
+#ifdef USE_MOVE_SEMANTICS
+  INLINE PointerTo(PointerTo<T> &&move) NOEXCEPT;
+  INLINE PointerTo<T> &operator = (PointerTo<T> &&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<T> &&move) NOEXCEPT;
+  INLINE ConstPointerTo<T> &operator = (ConstPointerTo<T> &&move) NOEXCEPT;
+#endif
+
   INLINE const To &operator *() const;
   INLINE const To *operator -> () const;
   INLINE operator const T *() const;

+ 14 - 0
panda/src/express/pointerToBase.I

@@ -35,6 +35,20 @@ PointerToBase(const PointerToBase<T> &copy) {
   reassign(copy);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToBase::Move Constructor
+//       Access: Protected
+//  Description:
+////////////////////////////////////////////////////////////////////
+#ifdef USE_MOVE_SEMANTICS
+template<class T>
+INLINE PointerToBase<T>::
+PointerToBase(PointerToBase<T> &&move) NOEXCEPT {
+  _void_ptr = move._void_ptr;
+  move._void_ptr = (void *)NULL;
+}
+#endif
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PointerToBase::Destructor
 //       Access: Protected

+ 4 - 0
panda/src/express/pointerToBase.h

@@ -38,6 +38,10 @@ protected:
   INLINE PointerToBase(const PointerToBase<T> &copy);
   INLINE ~PointerToBase();
 
+#ifdef USE_MOVE_SEMANTICS
+  INLINE PointerToBase(PointerToBase<T> &&move) NOEXCEPT;
+#endif
+
   INLINE void reassign(To *ptr);
   INLINE void reassign(const PointerToBase<To> &copy);