Explorar o código

ResourceManager: replace `allocFromPool()` with `allocVariant()`

Benoit Blanchon %!s(int64=2) %!d(string=hai) anos
pai
achega
8147625921

+ 9 - 9
extras/tests/ResourceManager/allocVariant.cpp

@@ -10,13 +10,13 @@
 
 using namespace ArduinoJson::detail;
 
-TEST_CASE("new (resources) VariantSlot()") {
+TEST_CASE("ResourceManager::allocVariant()") {
   SECTION("Returns different pointer") {
     ResourceManager resources(4096);
 
-    VariantSlot* s1 = new (&resources) VariantSlot();
+    VariantSlot* s1 = resources.allocVariant();
     REQUIRE(s1 != 0);
-    VariantSlot* s2 = new (&resources) VariantSlot();
+    VariantSlot* s2 = resources.allocVariant();
     REQUIRE(s2 != 0);
 
     REQUIRE(s1 != s2);
@@ -25,27 +25,27 @@ TEST_CASE("new (resources) VariantSlot()") {
   SECTION("Returns aligned pointers") {
     ResourceManager resources(4096);
 
-    REQUIRE(isAligned(new (&resources) VariantSlot()));
-    REQUIRE(isAligned(new (&resources) VariantSlot()));
+    REQUIRE(isAligned(resources.allocVariant()));
+    REQUIRE(isAligned(resources.allocVariant()));
   }
 
   SECTION("Returns zero if capacity is 0") {
     ResourceManager resources(0);
 
-    REQUIRE(new (&resources) VariantSlot() == 0);
+    REQUIRE(resources.allocVariant() == 0);
   }
 
   SECTION("Returns zero if buffer is null") {
     ResourceManager resources(4096, FailingAllocator::instance());
 
-    REQUIRE(new (&resources) VariantSlot() == 0);
+    REQUIRE(resources.allocVariant() == 0);
   }
 
   SECTION("Returns zero if capacity is insufficient") {
     ResourceManager resources(sizeof(VariantSlot));
 
-    new (&resources) VariantSlot();
+    resources.allocVariant();
 
-    REQUIRE(new (&resources) VariantSlot() == 0);
+    REQUIRE(resources.allocVariant() == 0);
   }
 }

+ 1 - 1
extras/tests/ResourceManager/clear.cpp

@@ -15,7 +15,7 @@ TEST_CASE("ResourceManager::clear()") {
   ResourceManager resources(poolCapacity);
 
   SECTION("Discards allocated variants") {
-    new (&resources) VariantSlot();
+    resources.allocVariant();
 
     resources.clear();
     REQUIRE(resources.size() == 0);

+ 2 - 2
extras/tests/ResourceManager/size.cpp

@@ -25,10 +25,10 @@ TEST_CASE("ResourceManager::size()") {
     const size_t variantCount = resources.capacity() / sizeof(VariantSlot);
 
     for (size_t i = 0; i < variantCount; i++)
-      new (&resources) VariantSlot();
+      resources.allocVariant();
     size_t size = resources.size();
 
-    new (&resources) VariantSlot();
+    resources.allocVariant();
 
     REQUIRE(size == resources.size());
   }

+ 2 - 2
src/ArduinoJson/Collection/CollectionFunctions.hpp

@@ -12,7 +12,7 @@ inline VariantData* collectionAddElement(CollectionData* array,
                                          ResourceManager* resources) {
   if (!array)
     return nullptr;
-  auto slot = new (resources) VariantSlot();
+  auto slot = resources->allocVariant();
   if (!slot)
     return nullptr;
   array->add(slot);
@@ -24,7 +24,7 @@ inline VariantData* collectionAddMember(CollectionData* obj, TAdaptedString key,
                                         ResourceManager* resources) {
   ARDUINOJSON_ASSERT(!key.isNull());
   ARDUINOJSON_ASSERT(obj != nullptr);
-  auto slot = new (resources) VariantSlot();
+  auto slot = resources->allocVariant();
   if (!slot)
     return nullptr;
   if (key.isLinked())

+ 1 - 1
src/ArduinoJson/Json/JsonDeserializer.hpp

@@ -279,7 +279,7 @@ class JsonDeserializer {
           auto savedKey = stringBuilder_.save();
 
           // Allocate slot in object
-          slot = new (resources_) VariantSlot();
+          slot = resources_->allocVariant();
           if (!slot)
             return DeserializationError::NoMemory;
 

+ 3 - 13
src/ArduinoJson/Memory/ResourceManager.hpp

@@ -12,6 +12,8 @@
 
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
+class VariantSlot;
+
 class ResourceManager {
  public:
   ResourceManager(size_t capa,
@@ -71,15 +73,7 @@ class ResourceManager {
     return overflowed_;
   }
 
-  void* allocFromPool(size_t bytes) {
-    if (!canAlloc(bytes)) {
-      overflowed_ = true;
-      return 0;
-    }
-    auto p = pool_ + poolUsage_;
-    poolUsage_ += bytes;
-    return p;
-  }
+  VariantSlot* allocVariant();
 
   template <typename TAdaptedString>
   StringNode* saveString(TAdaptedString str) {
@@ -171,10 +165,6 @@ class ResourceManager {
     deallocAllStrings();
   }
 
-  bool canAlloc(size_t bytes) const {
-    return poolUsage_ + bytes <= poolCapacity_;
-  }
-
   // Workaround for missing placement new
   void* operator new(size_t, void* p) {
     return p;

+ 1 - 1
src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp

@@ -495,7 +495,7 @@ class MsgPackDeserializer {
         // Save key in memory pool.
         auto savedKey = stringBuilder_.save();
 
-        VariantSlot* slot = new (resources_) VariantSlot();
+        VariantSlot* slot = resources_->allocVariant();
         if (!slot)
           return DeserializationError::NoMemory;
 

+ 1 - 1
src/ArduinoJson/Variant/VariantData.hpp

@@ -234,7 +234,7 @@ class VariantData {
     if (!slot)
       index++;
     while (index > 0) {
-      slot = new (resources) VariantSlot();
+      slot = resources->allocVariant();
       if (!slot)
         return nullptr;
       array->add(slot);

+ 14 - 5
src/ArduinoJson/Variant/VariantSlot.hpp

@@ -26,13 +26,12 @@ class VariantSlot {
   const char* key_;
 
  public:
-  static void* operator new(size_t size, ResourceManager* resources) noexcept {
-    return resources->allocFromPool(size);
+  // Placement new
+  static void* operator new(size_t, void* p) noexcept {
+    return p;
   }
 
-  static void operator delete(void*, ResourceManager*) noexcept {
-    // we cannot release memory from the pool
-  }
+  static void operator delete(void*, void*) noexcept {}
 
   VariantSlot() : flags_(0), next_(0), key_(0) {}
 
@@ -118,4 +117,14 @@ constexpr size_t sizeofObject(size_t n) {
   return n * sizeof(VariantSlot);
 }
 
+inline VariantSlot* ResourceManager::allocVariant() {
+  if (poolUsage_ + sizeof(VariantSlot) > poolCapacity_) {
+    overflowed_ = true;
+    return 0;
+  }
+  auto p = pool_ + poolUsage_;
+  poolUsage_ += sizeof(VariantSlot);
+  return new (p) VariantSlot;
+}
+
 ARDUINOJSON_END_PRIVATE_NAMESPACE