Memory pool key uses ptr in 32bit mode 32/285432/10
authorDavid Steele <david.steele@samsung.com>
Mon, 12 Dec 2022 17:38:27 +0000 (17:38 +0000)
committerDavid Steele <david.steele@samsung.com>
Fri, 20 Jan 2023 16:46:42 +0000 (16:46 +0000)
When compiled for a 32bit architecture, memory pool keys are
functionally identical to ptrs, and don't require any lookup or
comparison.

Have removed int32_t comparison operators and made the INVALID const
private. Added nullptr comparison operator to ensure that the keys can
be compared against nullptr, or utilize the boolean operator to check
for validity. (An int32_t key of 0 is valid in 64 bit mode)

Change-Id: I0eff1efede539e02c330ab601b10f018fcebeafd

build/tizen/linker-test.cpp
dali/internal/common/fixed-size-memory-pool.cpp
dali/internal/common/fixed-size-memory-pool.h
dali/internal/common/memory-pool-key.h
dali/internal/common/memory-pool-object-allocator.h
dali/internal/event/size-negotiation/memory-pool-relayout-container.cpp
dali/internal/update/manager/render-instruction-processor.cpp
dali/internal/update/manager/render-task-processor.cpp
dali/internal/update/nodes/scene-graph-layer.h
dali/internal/update/rendering/scene-graph-renderer.cpp

index ed9d2f7..47ae499 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -53,5 +53,6 @@ int main(int argc, char** argv)
 #ifndef _ARCH_ARM_
   Dali::TestApplication application;
 #endif
+
   return 0;
 }
index ce15e68..878755c 100644 (file)
@@ -260,8 +260,9 @@ void FixedSizeMemoryPool::FreeThreadSafe(void* memory)
   }
 }
 
-void* FixedSizeMemoryPool::GetPtrFromKey(uint32_t key)
+void* FixedSizeMemoryPool::GetPtrFromKey(FixedSizeMemoryPool::KeyType key)
 {
+#if defined(__LP64__)
   uint32_t blockId{0u};
   uint32_t index = key & mImpl->mIndexMask;
 
@@ -290,10 +291,15 @@ void* FixedSizeMemoryPool::GetPtrFromKey(uint32_t key)
     }
   }
   return nullptr;
+#else
+  // Treat ptrs as keys
+  return static_cast<void*>(key);
+#endif
 }
 
-uint32_t FixedSizeMemoryPool::GetKeyFromPtr(void* ptr)
+FixedSizeMemoryPool::KeyType FixedSizeMemoryPool::GetKeyFromPtr(void* ptr)
 {
+#if defined(__LP64__)
   uint32_t blockId = 0;
   uint32_t index   = 0;
   bool     found   = false;
@@ -338,6 +344,9 @@ uint32_t FixedSizeMemoryPool::GetKeyFromPtr(void* ptr)
   }
 
   return -1;
+#else
+  return static_cast<FixedSizeMemoryPool::KeyType>(ptr);
+#endif
 }
 
 uint32_t FixedSizeMemoryPool::GetCapacity() const
index 3a942b8..fd2207f 100644 (file)
@@ -52,6 +52,12 @@ class FixedSizeMemoryPool
 public:
   using SizeType = uint32_t;
 
+#if defined(__LP64__)
+  using KeyType = uint32_t;
+#else
+  using KeyType = void*;
+#endif
+
 public:
   /**
    * @brief Constructor.
@@ -104,7 +110,7 @@ public:
    * @param[in] key The key to convert
    * @return A valid ptr to the memory or nullptr if not found
    */
-  void* GetPtrFromKey(uint32_t key);
+  void* GetPtrFromKey(KeyType key);
 
   /**
    * @brief Given a ptr to some memory in the pool, return it's key
@@ -112,7 +118,7 @@ public:
    * @param[in] ptr The ptr to convert
    * @return A key to the valid memory, or -1 if not found
    */
-  uint32_t GetKeyFromPtr(void* ptr);
+  KeyType GetKeyFromPtr(void* ptr);
 
   /**
    * Get the current capacity of the memory pool
index 2f5006c..59f8c00 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_MEMORY_POOL_KEY_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
+#include <dali/internal/common/fixed-size-memory-pool.h>
+
 namespace Dali::Internal
 {
-
 /**
  * MemoryPoolKey is a 32bit replacement for pointers to objects stored
- * within MemoryPools.
+ * within MemoryPools. In a 32 bit environment, it is an actual ptr.
  *
  * @tparam Class The class of object stored within a memory pool. The
  * class grants limited access to the actual memory pool.
  *
- * The key has pointer semantics. Please note that 0 is a valid key value,
- * so be sure to test against INVALID instead.
+ * The key has pointer semantics.
  *
  * As this has a copy constructor, it's not a trivial type, however because
  * it encapsulates an integer, specialized types can use Dali::Vector by
@@ -47,7 +47,7 @@ template<typename Class>
 class MemoryPoolKey
 {
 public:
-  using KeyType = uint32_t;
+  using KeyType = FixedSizeMemoryPool::KeyType;
 
   /**
    * Default Constructor - generates an empty key.
@@ -61,7 +61,7 @@ public:
    * Constructor - Construct a key object from an int key.
    * @param[in] aKey A key of an object in the pool
    */
-  explicit MemoryPoolKey(uint32_t aKey)
+  explicit MemoryPoolKey(KeyType aKey)
   : key(aKey)
   {
   }
@@ -101,7 +101,11 @@ public:
    */
   Class* operator->() const
   {
+#if defined(__LP64__)
     return Class::Get(key);
+#else
+    return static_cast<Class*>(key);
+#endif
   }
 
   /**
@@ -110,7 +114,11 @@ public:
    */
   Class* Get() const
   {
+#if defined(__LP64__)
     return Class::Get(key);
+#else
+    return static_cast<Class*>(key);
+#endif
   }
 
   /**
@@ -143,26 +151,37 @@ public:
   }
 
   /**
-   * Equality Operator against int
-   * @param[in] match The key to test against
-   * @return true if the keys match
+   * Equality operator for nullptr
+   * @param[in] np nullptr
+   * @return true if the key is invalid
    */
-  bool operator==(KeyType match) const
+  bool operator==(std::nullptr_t np) const
   {
-    return key == match;
+    return key == INVALID;
   }
 
   /**
-   * Inequality operator against int
-   * @param[in] match The key to test against
-   * @return true if the keys don't match
+   * Inequality operator for nullptr
+   * @param[in] np nullptr
+   * @return true if the keys is valid
    */
-  bool operator!=(KeyType match) const
+  bool operator!=(std::nullptr_t np) const
+  {
+    return key != INVALID;
+  }
+
+  uint32_t Value() const
   {
-    return key != match;
+    return reinterpret_cast<uint32_t>(key);
   }
 
+private:
+  // Ensure that INVALID constant can't be used directly.
+#if defined(__LP64__)
   static const KeyType INVALID{0xffffffff}; ///< Null or Invalid constant.
+#else
+  static constexpr KeyType INVALID{nullptr};
+#endif
 
   KeyType key{INVALID}; ///< The actual key.
 };
index 0d15f12..0c64d7d 100644 (file)
@@ -61,26 +61,6 @@ public:
   }
 
   /**
-   * @brief Allocate from the memory pool
-   *
-   * @return Return the allocated object
-   */
-  T* Allocate()
-  {
-    return new(mPool->Allocate()) T();
-  }
-
-  /**
-   * @brief Thread-safe version of Allocate()
-   *
-   * @return Return the allocated object
-   */
-  T* AllocateThreadSafe()
-  {
-    return new(mPool->AllocateThreadSafe()) T();
-  }
-
-  /**
    * @brief Allocate a block of memory from the memory pool of the appropriate size to
    *        store an object of type T. This is usually so the memory can be used in a
    *        placement new for an object of type T with a constructor that takes multiple
@@ -162,12 +142,16 @@ public:
   }
 
   /**
-   * Get a pointer to the keyed item
+   * Get a pointer to the keyed item.
+   *
    * Key must be valid.
    * @param[in] key 32 bit value indexing block/entry
    * @return ptr to the memory of item, or nullptr if key is invalid
+   *
+   * @note on 32 bit systems, there is zero overhead, key is a raw ptr,
+   * and this method will return it's argument.
    */
-  T* GetPtrFromKey(uint32_t key)
+  T* GetPtrFromKey(FixedSizeMemoryPool::KeyType key)
   {
     return static_cast<T*>(mPool->GetPtrFromKey(key));
   }
@@ -176,8 +160,11 @@ public:
    * Get a key to the pointed at item
    * @param[in] ptr Pointer to an item in the memory pool
    * @return key of the item, or -1 if not found.
+   *
+   * @note on 32 bit systems, there is zero overhead, key is a raw ptr,
+   * and this method will return it's argument.
    */
-  uint32_t GetKeyFromPtr(T* ptr)
+  FixedSizeMemoryPool::KeyType GetKeyFromPtr(T* ptr)
   {
     return mPool->GetKeyFromPtr(ptr);
   }
index be4fc65..2554e14 100644 (file)
@@ -48,7 +48,8 @@ void MemoryPoolRelayoutContainer::Add(const Dali::Actor& actor, const Vector2& s
 {
   if(!Contains(actor))
   {
-    RelayoutInfo* info = mAllocator.Allocate();
+    void*         ptr  = mAllocator.AllocateRaw();
+    RelayoutInfo* info = new(ptr) RelayoutInfo();
     info->actor        = actor;
     info->size         = size;
 
index 1c57380..9486e91 100644 (file)
@@ -385,7 +385,7 @@ inline bool TryReuseCachedRenderers(Layer&               layer,
     //@todo just use keys, don't deref.
     for(uint32_t index = 0; index < renderableCount; ++index)
     {
-      if(DALI_LIKELY(renderables[index].mRenderer != RendererKey::INVALID))
+      if(DALI_LIKELY(renderables[index].mRenderer != nullptr))
       {
         const Render::Renderer& renderer = renderables[index].mRenderer->GetRenderer();
         checkSumNew += reinterpret_cast<std::size_t>(&renderer);
index 7f7efad..1b361ce 100644 (file)
@@ -156,7 +156,7 @@ bool AddRenderablesForTask(BufferIndex updateBufferIndex,
       // If we do not have any renderers, create one to house the scissor operation.
       if(count == 0u)
       {
-        layer->colorRenderables.PushBack(Renderable(&node, RendererKey(RendererKey::INVALID)));
+        layer->colorRenderables.PushBack(Renderable(&node, RendererKey{}));
       }
     }
     else
index 764c7c5..638688b 100644 (file)
@@ -48,11 +48,7 @@ class Camera;
  */
 struct Renderable
 {
-  Renderable()
-  : mNode(nullptr),
-    mRenderer(RendererKey::INVALID)
-  {
-  }
+  Renderable() = default;
 
   Renderable(Node* node, RendererKey renderer)
   : mNode(node),
@@ -61,7 +57,7 @@ struct Renderable
   }
 
   Node*       mNode{nullptr};
-  RendererKey mRenderer{RendererKey::INVALID};
+  RendererKey mRenderer{};
 };
 
 } // namespace SceneGraph
index 904b2f8..ce0d718 100644 (file)
@@ -83,8 +83,6 @@ Renderer* Renderer::New()
   return new(gRendererMemoryPool.AllocateRawThreadSafe()) Renderer();
 }
 
-// Becomes
-
 RendererKey Renderer::NewKey()
 {
   void* ptr = gRendererMemoryPool.AllocateRawThreadSafe();