[Bf-blender-cvs] [a3ad5abf2fe] master: Allocator: simplify using guarded allocator in C++ code

Jacques Lucke noreply at git.blender.org
Fri Dec 17 15:44:53 CET 2021


Commit: a3ad5abf2fe85d623f9e78fefc34e27bdc14632e
Author: Jacques Lucke
Date:   Fri Dec 17 15:38:15 2021 +0100
Branches: master
https://developer.blender.org/rBa3ad5abf2fe85d623f9e78fefc34e27bdc14632e

Allocator: simplify using guarded allocator in C++ code

Using the `MEM_*` API from C++ code was a bit annoying:
* When converting C to C++ code, one often has to add a type cast on
  returned `void *`. That leads to having the same type name three times
  in the same line. This patch reduces the amount to two and removes the
  `sizeof(...)` from the line.
* The existing alternative of using `OBJECT_GUARDED_NEW` looks a out
  of place compared to other allocation methods. Sometimes
  `MEM_CXX_CLASS_ALLOC_FUNCS` can be used when structs are defined
  in C++ code. It doesn't look great but it's definitely better. The downside
  is that it makes the name of the allocation less useful. That's because
  the same name is used for all allocations of a type, independend of
  where it is allocated.

This patch introduces three new functions: `MEM_new`, `MEM_cnew` and
`MEM_delete`. These cover the majority of use cases (array allocation is
not covered).

The `OBJECT_GUARDED_*` macros are removed because they are not
needed anymore.

Differential Revision: https://developer.blender.org/D13502

===================================================================

M	intern/guardedalloc/MEM_guardedalloc.h
M	intern/libmv/intern/utildefines.h
M	intern/opencolorio/ocio_impl.cc
M	intern/opensubdiv/internal/evaluator/evaluator_capi.cc
M	intern/opensubdiv/internal/topology/topology_refiner_capi.cc
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/blenlib/intern/task_scheduler.cc
M	source/blender/editors/asset/intern/asset_indexer.cc
M	source/blender/editors/asset/intern/asset_temp_id_consumer.cc
M	source/blender/editors/interface/interface_view.cc
M	source/blender/editors/space_file/asset_catalog_tree_view.cc
M	source/blender/editors/space_node/node_geometry_attribute_search.cc
M	source/blender/modifiers/intern/MOD_nodes.cc

===================================================================

diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 3c006b9a70c..043f7055ab1 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -259,6 +259,49 @@ void MEM_use_guarded_allocator(void);
 #endif /* __cplusplus */
 
 #ifdef __cplusplus
+
+#  include <type_traits>
+#  include <utility>
+
+/**
+ * Allocate new memory for and constructs an object of type #T.
+ * #MEM_delete should be used to delete the object. Just calling #MEM_freeN is not enough when #T
+ * is not a trivial type.
+ */
+template<typename T, typename... Args>
+inline T *MEM_new(const char *allocation_name, Args &&...args)
+{
+  void *buffer = MEM_mallocN(sizeof(T), allocation_name);
+  return new (buffer) T(std::forward<Args>(args)...);
+}
+
+/**
+ * Allocates zero-initialized memory for an object of type #T. The constructor of #T is not called,
+ * therefor this should only used with trivial types (like all C types).
+ * It's valid to call #MEM_freeN on a pointer returned by this, because a destructor call is not
+ * necessary, because the type is trivial.
+ */
+template<typename T> inline T *MEM_cnew(const char *allocation_name)
+{
+  static_assert(std::is_trivial_v<T>, "For non-trivial types, MEM_new should be used.");
+  return static_cast<T *>(MEM_callocN(sizeof(T), allocation_name));
+}
+
+/**
+ * Destructs and deallocates an object previously allocated with any `MEM_*` function.
+ * Passing in null does nothing.
+ */
+template<typename T> inline void MEM_delete(const T *ptr)
+{
+  if (ptr == nullptr) {
+    /* Support #ptr being null, because C++ `delete` supports that as well. */
+    return;
+  }
+  /* C++ allows destruction of const objects, so the pointer is allowed to be const. */
+  ptr->~T();
+  MEM_freeN(const_cast<T *>(ptr));
+}
+
 /* Allocation functions (for C++ only). */
 #  define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
    public: \
@@ -292,36 +335,6 @@ void MEM_use_guarded_allocator(void);
     { \
     }
 
-/* Needed when type includes a namespace, then the namespace should not be
- * specified after ~, so using a macro fails. */
-template<class T> inline void OBJECT_GUARDED_DESTRUCTOR(T *what)
-{
-  what->~T();
-}
-
-#  if defined __GNUC__
-#    define OBJECT_GUARDED_NEW(type, args...) new (MEM_mallocN(sizeof(type), __func__)) type(args)
-#  else
-#    define OBJECT_GUARDED_NEW(type, ...) \
-      new (MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
-#  endif
-#  define OBJECT_GUARDED_DELETE(what, type) \
-    { \
-      if (what) { \
-        OBJECT_GUARDED_DESTRUCTOR((type *)what); \
-        MEM_freeN(what); \
-      } \
-    } \
-    (void)0
-#  define OBJECT_GUARDED_SAFE_DELETE(what, type) \
-    { \
-      if (what) { \
-        OBJECT_GUARDED_DESTRUCTOR((type *)what); \
-        MEM_freeN(what); \
-        what = NULL; \
-      } \
-    } \
-    (void)0
 #endif /* __cplusplus */
 
 #endif /* __MEM_GUARDEDALLOC_H__ */
diff --git a/intern/libmv/intern/utildefines.h b/intern/libmv/intern/utildefines.h
index 052052a1d76..8b37253698d 100644
--- a/intern/libmv/intern/utildefines.h
+++ b/intern/libmv/intern/utildefines.h
@@ -27,9 +27,21 @@
 
 #ifdef WITH_LIBMV_GUARDED_ALLOC
 #  include "MEM_guardedalloc.h"
-#  define LIBMV_OBJECT_NEW OBJECT_GUARDED_NEW
-#  define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
-#  define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
+#  if defined __GNUC__
+#    define LIBMV_OBJECT_NEW(type, args...)                                    \
+      new (MEM_mallocN(sizeof(type), __func__)) type(args)
+#  else
+#    define LIBMV_OBJECT_NEW(type, ...)                                        \
+      new (MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
+#  endif
+#  define LIBMV_OBJECT_DELETE(what, type)                                      \
+    {                                                                          \
+      if (what) {                                                              \
+        ((type*)what)->~type();                                                \
+        MEM_freeN(what);                                                       \
+      }                                                                        \
+    }                                                                          \
+    (void)0
 #  define LIBMV_STRUCT_NEW(type, count)                                        \
     (type*)MEM_mallocN(sizeof(type) * count, __func__)
 #  define LIBMV_STRUCT_DELETE(what) MEM_freeN(what)
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index 058b8f51dd6..b4e48c013c0 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -67,7 +67,7 @@ static void OCIO_reportException(Exception &exception)
 
 OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
 {
-  ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
+  ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
 
   try {
     *config = GetCurrentConfig();
@@ -79,7 +79,7 @@ OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
     OCIO_reportException(exception);
   }
 
-  OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
+  MEM_delete(config);
 
   return NULL;
 }
@@ -96,7 +96,7 @@ void OCIOImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *config)
 
 OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
 {
-  ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
+  ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
 
   try {
     *config = Config::CreateFromEnv();
@@ -108,14 +108,14 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
     OCIO_reportException(exception);
   }
 
-  OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
+  MEM_delete(config);
 
   return NULL;
 }
 
 OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
 {
-  ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
+  ConstConfigRcPtr *config = MEM_new<ConstConfigRcPtr>(__func__);
 
   try {
     *config = Config::CreateFromFile(filename);
@@ -127,14 +127,14 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
     OCIO_reportException(exception);
   }
 
-  OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
+  MEM_delete(config);
 
   return NULL;
 }
 
 void OCIOImpl::configRelease(OCIO_ConstConfigRcPtr *config)
 {
-  OBJECT_GUARDED_DELETE((ConstConfigRcPtr *)config, ConstConfigRcPtr);
+  MEM_delete((ConstConfigRcPtr *)config);
 }
 
 int OCIOImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config)
@@ -164,7 +164,7 @@ const char *OCIOImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *conf
 OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config,
                                                          const char *name)
 {
-  ConstColorSpaceRcPtr *cs = OBJECT_GUARDED_NEW(ConstColorSpaceRcPtr);
+  ConstColorSpaceRcPtr *cs = MEM_new<ConstColorSpaceRcPtr>(__func__);
 
   try {
     *cs = (*(ConstConfigRcPtr *)config)->getColorSpace(name);
@@ -176,7 +176,7 @@ OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *
     OCIO_reportException(exception);
   }
 
-  OBJECT_GUARDED_DELETE(cs, ConstColorSpaceRcPtr);
+  MEM_delete(cs);
 
   return NULL;
 }
@@ -380,7 +380,7 @@ const char *OCIOImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, in
 
 OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, const char *name)
 {
-  ConstLookRcPtr *look = OBJECT_GUARDED_NEW(ConstLookRcPtr);
+  ConstLookRcPtr *look = MEM_new<ConstLookRcPtr>(__func__);
 
   try {
     *look = (*(ConstConfigRcPtr *)config)->getLook(name);
@@ -392,7 +392,7 @@ OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, cons
     OCIO_reportException(exception);
   }
 
-  OBJECT_GUARDED_DELETE(look, ConstLookRcPtr);
+  MEM_delete(look);
 
   return NULL;
 }
@@ -404,7 +404,7 @@ const char *OCIOImpl::lookGetProcessSpace(OCIO_ConstLookRcPtr *look)
 
 void OCIOImpl::lookRelease(OCIO_ConstLookRcPtr *look)
 {
-  OBJECT_GUARDED_DELETE((ConstLookRcPtr *)look, ConstLookRcPtr);
+  MEM_delete((ConstLookRcPtr *)look);
 }
 
 int OCIOImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs_)
@@ -521,14 +521,14 @@ void OCIOImpl::colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config_,
 
 void OCIOImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs)
 {
-  OBJECT_GUARDED_DELETE((ConstColorSpaceRcPtr *)cs, ConstColorSpaceRcPtr);
+  MEM_delete((ConstColorSpaceRcPtr *)cs);
 }
 
 OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
                                                                 const char *srcName,
                                                                 const char *dstName)
 {
-  ConstProcessorRcPtr *processor = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
+  ConstProcessorRcPtr *processor = MEM_new<ConstProcessorRcPtr>(__func__);
 
   try {
     *processor = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
@@ -540,20 +540,20 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfig
     OCIO_reportException(exception);
   }
 
-  OBJECT_GUARDED_DELETE(processor, ConstProcessorRcPtr);
+  MEM_delete(processor);
 
   return 0;
 }
 
 void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
 {
-  OBJECT_GUARDED_DELETE(processor, ConstProcessorRcPtr);
+  MEM_delete(processor);
 }
 
 OCIO_ConstCPUProcessorRcPtr *OCIOImpl::processorGetCPUProcessor(
     OCIO_ConstProcessorRcPtr *processor)
 {
-  ConstCPUProcessorRcPtr *cpu_processor = OBJECT_GUARDED_NEW(ConstCPUProcessorRcPtr);
+  ConstCPUProcessorRcPtr *cpu_processor = MEM_new<ConstCPUProcessorRcPtr>(__func__);
   *cpu_processor = (*(ConstProcessorRcPtr *)processor)->getDefaultCPUProcessor();
   return (OCIO_ConstCPUProcessorRcPtr *)cpu_processor;
 }
@@ -636,7 +636,7 @@ void OCIOImpl::cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_
 
 void OCIOImpl::cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
 {
-  OBJECT_GUARDED_DELETE(cpu_processor, ConstCPUProcessorRcPtr);
+  MEM_delete(cpu_processor);
 }
 
 const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpac

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list