Procházet zdrojové kódy

Restored the monotonic allocator

Benoit Blanchon před 7 roky
rodič
revize
45f4e5ac20

+ 2 - 1
CHANGELOG.md

@@ -5,6 +5,7 @@ HEAD
 ----
 ----
 
 
 * Removed the automatic expansion of `DynamicJsonDocument`, it now has a fixed capacity.
 * Removed the automatic expansion of `DynamicJsonDocument`, it now has a fixed capacity.
+* Restored the monotonic allocator because the code was getting too big
 
 
 v6.6.0-beta (2018-11-13)
 v6.6.0-beta (2018-11-13)
 -----------
 -----------
@@ -14,7 +15,7 @@ v6.6.0-beta (2018-11-13)
 * Replaced `T JsonArray::get<T>(i)` with `JsonVariant JsonArray::get(i)`
 * Replaced `T JsonArray::get<T>(i)` with `JsonVariant JsonArray::get(i)`
 * Replaced `T JsonObject::get<T>(k)` with `JsonVariant JsonObject::get(k)`
 * Replaced `T JsonObject::get<T>(k)` with `JsonVariant JsonObject::get(k)`
 * Added `JSON_STRING_SIZE()`
 * Added `JSON_STRING_SIZE()`
-* Replacing or removing a value now releases the memory
+* ~~Replacing or removing a value now releases the memory~~
 * Added `DeserializationError::code()` to be used in switch statements (issue #846)
 * Added `DeserializationError::code()` to be used in switch statements (issue #846)
 
 
 v6.5.0-beta (2018-10-13)
 v6.5.0-beta (2018-10-13)

+ 3 - 17
src/ArduinoJson/Data/ArrayFunctions.hpp

@@ -42,8 +42,7 @@ inline JsonVariantData* arrayGet(const JsonArrayData* arr, size_t index) {
   return slot ? &slot->value : 0;
   return slot ? &slot->value : 0;
 }
 }
 
 
-inline void arrayRemove(JsonArrayData* arr, VariantSlot* slot,
-                        MemoryPool* pool) {
+inline void arrayRemove(JsonArrayData* arr, VariantSlot* slot) {
   if (!arr || !slot) return;
   if (!arr || !slot) return;
 
 
   if (slot->prev)
   if (slot->prev)
@@ -54,12 +53,10 @@ inline void arrayRemove(JsonArrayData* arr, VariantSlot* slot,
     slot->next->prev = slot->prev;
     slot->next->prev = slot->prev;
   else
   else
     arr->tail = slot->prev;
     arr->tail = slot->prev;
-
-  slotFree(slot, pool);
 }
 }
 
 
-inline void arrayRemove(JsonArrayData* arr, size_t index, MemoryPool* pool) {
-  arrayRemove(arr, arrayGetSlot(arr, index), pool);
+inline void arrayRemove(JsonArrayData* arr, size_t index) {
+  arrayRemove(arr, arrayGetSlot(arr, index));
 }
 }
 
 
 inline void arrayClear(JsonArrayData* arr) {
 inline void arrayClear(JsonArrayData* arr) {
@@ -100,15 +97,4 @@ inline size_t arraySize(const JsonArrayData* arr) {
   if (!arr) return 0;
   if (!arr) return 0;
   return slotSize(arr->head);
   return slotSize(arr->head);
 }
 }
-
-inline void arrayFree(JsonArrayData* arr, MemoryPool* pool) {
-  ARDUINOJSON_ASSERT(arr);
-
-  VariantSlot* cur = arr->head;
-  while (cur) {
-    VariantSlot* next = cur->next;
-    slotFree(cur, pool);
-    cur = next;
-  }
-}
 }  // namespace ARDUINOJSON_NAMESPACE
 }  // namespace ARDUINOJSON_NAMESPACE

+ 1 - 4
src/ArduinoJson/Data/ObjectFunctions.hpp

@@ -76,8 +76,7 @@ inline void objectClear(JsonObjectData* obj) {
   obj->tail = 0;
   obj->tail = 0;
 }
 }
 
 
-inline void objectRemove(JsonObjectData* obj, VariantSlot* slot,
-                         MemoryPool* pool) {
+inline void objectRemove(JsonObjectData* obj, VariantSlot* slot) {
   if (!obj) return;
   if (!obj) return;
   if (!slot) return;
   if (!slot) return;
   if (slot->prev)
   if (slot->prev)
@@ -88,8 +87,6 @@ inline void objectRemove(JsonObjectData* obj, VariantSlot* slot,
     slot->next->prev = slot->prev;
     slot->next->prev = slot->prev;
   else
   else
     obj->tail = slot->prev;
     obj->tail = slot->prev;
-
-  slotFree(slot, pool);
 }
 }
 
 
 inline size_t objectSize(const JsonObjectData* obj) {
 inline size_t objectSize(const JsonObjectData* obj) {

+ 0 - 13
src/ArduinoJson/Data/SlotFunctions.hpp

@@ -61,17 +61,4 @@ inline size_t slotSize(const VariantSlot* var) {
   }
   }
   return n;
   return n;
 }
 }
-
-void variantFree(JsonVariantData* var, MemoryPool* pool);
-
-inline void slotFree(VariantSlot* var, MemoryPool* pool) {
-  ARDUINOJSON_ASSERT(var != 0);
-  ARDUINOJSON_ASSERT(pool != 0);
-
-  variantFree(&var->value, pool);
-
-  if (var->value.keyIsOwned) pool->freeString(var->ownedKey);
-
-  pool->freeVariant(var);
-}
 }  // namespace ARDUINOJSON_NAMESPACE
 }  // namespace ARDUINOJSON_NAMESPACE

+ 12 - 54
src/ArduinoJson/Data/VariantFunctions.hpp

@@ -12,25 +12,6 @@
 #include "ObjectFunctions.hpp"
 #include "ObjectFunctions.hpp"
 
 
 namespace ARDUINOJSON_NAMESPACE {
 namespace ARDUINOJSON_NAMESPACE {
-
-inline void variantFree(JsonVariantData* var, MemoryPool* pool) {
-  ARDUINOJSON_ASSERT(var != 0);
-  ARDUINOJSON_ASSERT(pool != 0);
-
-  switch (var->type) {
-    case JSON_ARRAY:
-    case JSON_OBJECT:
-      arrayFree(&var->content.asArray, pool);
-      break;
-    case JSON_OWNED_STRING:
-    case JSON_OWNED_RAW:
-      pool->freeString(var->content.asOwnedString);
-      break;
-    default:
-      break;
-  }
-}
-
 template <typename T>
 template <typename T>
 inline T variantAsIntegral(const JsonVariantData* var) {
 inline T variantAsIntegral(const JsonVariantData* var) {
   if (!var) return 0;
   if (!var) return 0;
@@ -116,30 +97,23 @@ inline const JsonObjectData* variantAsObject(const JsonVariantData* var) {
     return 0;
     return 0;
 }
 }
 
 
-inline bool variantSetBoolean(JsonVariantData* var, bool value,
-                              MemoryPool* pool) {
+inline bool variantSetBoolean(JsonVariantData* var, bool value) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
   var->type = JSON_BOOLEAN;
   var->type = JSON_BOOLEAN;
   var->content.asInteger = static_cast<JsonUInt>(value);
   var->content.asInteger = static_cast<JsonUInt>(value);
   return true;
   return true;
 }
 }
 
 
-inline bool variantSetFloat(JsonVariantData* var, JsonFloat value,
-                            MemoryPool* pool) {
+inline bool variantSetFloat(JsonVariantData* var, JsonFloat value) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
   var->type = JSON_FLOAT;
   var->type = JSON_FLOAT;
   var->content.asFloat = value;
   var->content.asFloat = value;
   return true;
   return true;
 }
 }
 
 
 template <typename T>
 template <typename T>
-inline bool variantSetSignedInteger(JsonVariantData* var, T value,
-                                    MemoryPool* pool) {
+inline bool variantSetSignedInteger(JsonVariantData* var, T value) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
-
   if (value >= 0) {
   if (value >= 0) {
     var->type = JSON_POSITIVE_INTEGER;
     var->type = JSON_POSITIVE_INTEGER;
     var->content.asInteger = static_cast<JsonUInt>(value);
     var->content.asInteger = static_cast<JsonUInt>(value);
@@ -150,20 +124,16 @@ inline bool variantSetSignedInteger(JsonVariantData* var, T value,
   return true;
   return true;
 }
 }
 
 
-inline bool variantSetUnsignedInteger(JsonVariantData* var, JsonUInt value,
-                                      MemoryPool* pool) {
+inline bool variantSetUnsignedInteger(JsonVariantData* var, JsonUInt value) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
   var->type = JSON_POSITIVE_INTEGER;
   var->type = JSON_POSITIVE_INTEGER;
   var->content.asInteger = static_cast<JsonUInt>(value);
   var->content.asInteger = static_cast<JsonUInt>(value);
   return true;
   return true;
 }
 }
 
 
 inline bool variantSetLinkedRaw(JsonVariantData* var,
 inline bool variantSetLinkedRaw(JsonVariantData* var,
-                                SerializedValue<const char*> value,
-                                MemoryPool* pool) {
+                                SerializedValue<const char*> value) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
   var->type = JSON_LINKED_RAW;
   var->type = JSON_LINKED_RAW;
   var->content.asRaw.data = value.data();
   var->content.asRaw.data = value.data();
   var->content.asRaw.size = value.size();
   var->content.asRaw.size = value.size();
@@ -174,7 +144,6 @@ template <typename T>
 inline bool variantSetOwnedRaw(JsonVariantData* var, SerializedValue<T> value,
 inline bool variantSetOwnedRaw(JsonVariantData* var, SerializedValue<T> value,
                                MemoryPool* pool) {
                                MemoryPool* pool) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
   StringSlot* slot = makeString(value.data(), value.size()).save(pool);
   StringSlot* slot = makeString(value.data(), value.size()).save(pool);
   if (slot) {
   if (slot) {
     var->type = JSON_OWNED_RAW;
     var->type = JSON_OWNED_RAW;
@@ -189,7 +158,6 @@ inline bool variantSetOwnedRaw(JsonVariantData* var, SerializedValue<T> value,
 template <typename T>
 template <typename T>
 inline bool variantSetString(JsonVariantData* var, T value, MemoryPool* pool) {
 inline bool variantSetString(JsonVariantData* var, T value, MemoryPool* pool) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
   StringSlot* slot = value.save(pool);
   StringSlot* slot = value.save(pool);
   if (slot) {
   if (slot) {
     var->type = JSON_OWNED_STRING;
     var->type = JSON_OWNED_STRING;
@@ -201,42 +169,35 @@ inline bool variantSetString(JsonVariantData* var, T value, MemoryPool* pool) {
   }
   }
 }
 }
 
 
-inline bool variantSetOwnedString(JsonVariantData* var, StringSlot* slot,
-                                  MemoryPool* pool) {
+inline bool variantSetOwnedString(JsonVariantData* var, StringSlot* slot) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
   var->type = JSON_OWNED_STRING;
   var->type = JSON_OWNED_STRING;
   var->content.asOwnedString = slot;
   var->content.asOwnedString = slot;
   return true;
   return true;
 }
 }
 
 
-inline bool variantSetString(JsonVariantData* var, const char* value,
-                             MemoryPool* pool) {
+inline bool variantSetString(JsonVariantData* var, const char* value) {
   if (!var) return false;
   if (!var) return false;
-  variantFree(var, pool);
   var->type = JSON_LINKED_STRING;
   var->type = JSON_LINKED_STRING;
   var->content.asString = value;
   var->content.asString = value;
   return true;
   return true;
 }
 }
 
 
-inline void variantSetNull(JsonVariantData* var, MemoryPool* pool) {
+inline void variantSetNull(JsonVariantData* var) {
   if (!var) return;
   if (!var) return;
-  variantFree(var, pool);
   var->type = JSON_NULL;
   var->type = JSON_NULL;
 }
 }
 
 
-inline JsonArrayData* variantToArray(JsonVariantData* var, MemoryPool* pool) {
+inline JsonArrayData* variantToArray(JsonVariantData* var) {
   if (!var) return 0;
   if (!var) return 0;
-  variantFree(var, pool);
   var->type = JSON_ARRAY;
   var->type = JSON_ARRAY;
   var->content.asArray.head = 0;
   var->content.asArray.head = 0;
   var->content.asArray.tail = 0;
   var->content.asArray.tail = 0;
   return &var->content.asArray;
   return &var->content.asArray;
 }
 }
 
 
-inline JsonObjectData* variantToObject(JsonVariantData* var, MemoryPool* pool) {
+inline JsonObjectData* variantToObject(JsonVariantData* var) {
   if (!var) return 0;
   if (!var) return 0;
-  variantFree(var, pool);
   var->type = JSON_OBJECT;
   var->type = JSON_OBJECT;
   var->content.asObject.head = 0;
   var->content.asObject.head = 0;
   var->content.asObject.tail = 0;
   var->content.asObject.tail = 0;
@@ -247,16 +208,14 @@ inline bool variantCopy(JsonVariantData* dst, const JsonVariantData* src,
                         MemoryPool* pool) {
                         MemoryPool* pool) {
   if (!dst) return false;
   if (!dst) return false;
   if (!src) {
   if (!src) {
-    variantFree(dst, pool);
     dst->type = JSON_NULL;
     dst->type = JSON_NULL;
     return true;
     return true;
   }
   }
   switch (src->type) {
   switch (src->type) {
     case JSON_ARRAY:
     case JSON_ARRAY:
-      return arrayCopy(variantToArray(dst, pool), &src->content.asArray, pool);
+      return arrayCopy(variantToArray(dst), &src->content.asArray, pool);
     case JSON_OBJECT:
     case JSON_OBJECT:
-      return objectCopy(variantToObject(dst, pool), &src->content.asObject,
-                        pool);
+      return objectCopy(variantToObject(dst), &src->content.asObject, pool);
     case JSON_OWNED_STRING:
     case JSON_OWNED_STRING:
       return variantSetString(
       return variantSetString(
           dst, makeString(src->content.asOwnedString->value), pool);
           dst, makeString(src->content.asOwnedString->value), pool);
@@ -266,7 +225,6 @@ inline bool variantCopy(JsonVariantData* dst, const JsonVariantData* src,
                                            src->content.asOwnedRaw->size),
                                            src->content.asOwnedRaw->size),
                                 pool);
                                 pool);
     default:
     default:
-      variantFree(dst, pool);
       // caution: don't override keyIsOwned
       // caution: don't override keyIsOwned
       dst->type = src->type;
       dst->type = src->type;
       dst->content = src->content;
       dst->content = src->content;

+ 2 - 2
src/ArduinoJson/JsonArray.hpp

@@ -197,12 +197,12 @@ class JsonArray : public JsonArrayProxy<JsonArrayData>, public Visitable {
 
 
   // Removes element at specified position.
   // Removes element at specified position.
   FORCE_INLINE void remove(iterator it) const {
   FORCE_INLINE void remove(iterator it) const {
-    arrayRemove(_data, it.internal(), _memoryPool);
+    arrayRemove(_data, it.internal());
   }
   }
 
 
   // Removes element at specified index.
   // Removes element at specified index.
   FORCE_INLINE void remove(size_t index) const {
   FORCE_INLINE void remove(size_t index) const {
-    arrayRemove(_data, index, _memoryPool);
+    arrayRemove(_data, index);
   }
   }
 
 
   template <typename Visitor>
   template <typename Visitor>

+ 2 - 2
src/ArduinoJson/JsonObject.hpp

@@ -227,7 +227,7 @@ class JsonObject : public JsonObjectProxy<JsonObjectData>, public Visitable {
   }
   }
 
 
   FORCE_INLINE void remove(iterator it) const {
   FORCE_INLINE void remove(iterator it) const {
-    objectRemove(_data, it.internal(), _memoryPool);
+    objectRemove(_data, it.internal());
   }
   }
 
 
   // Removes the specified key and the associated value.
   // Removes the specified key and the associated value.
@@ -282,7 +282,7 @@ class JsonObject : public JsonObjectProxy<JsonObjectData>, public Visitable {
 
 
   template <typename TStringRef>
   template <typename TStringRef>
   FORCE_INLINE void remove_impl(TStringRef key) const {
   FORCE_INLINE void remove_impl(TStringRef key) const {
-    objectRemove(_data, objectFindSlot(_data, key), _memoryPool);
+    objectRemove(_data, objectFindSlot(_data, key));
   }
   }
 
 
   MemoryPool* _memoryPool;
   MemoryPool* _memoryPool;

+ 8 - 9
src/ArduinoJson/JsonVariant.hpp

@@ -133,7 +133,7 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
 
 
   // set(bool value)
   // set(bool value)
   FORCE_INLINE bool set(bool value) const {
   FORCE_INLINE bool set(bool value) const {
-    return variantSetBoolean(_data, value, _memoryPool);
+    return variantSetBoolean(_data, value);
   }
   }
 
 
   // set(double value);
   // set(double value);
@@ -142,7 +142,7 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
   FORCE_INLINE bool set(
   FORCE_INLINE bool set(
       T value,
       T value,
       typename enable_if<is_floating_point<T>::value>::type * = 0) const {
       typename enable_if<is_floating_point<T>::value>::type * = 0) const {
-    return variantSetFloat(_data, static_cast<JsonFloat>(value), _memoryPool);
+    return variantSetFloat(_data, static_cast<JsonFloat>(value));
   }
   }
 
 
   // set(char)
   // set(char)
@@ -155,7 +155,7 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
       T value,
       T value,
       typename enable_if<is_integral<T>::value && is_signed<T>::value>::type * =
       typename enable_if<is_integral<T>::value && is_signed<T>::value>::type * =
           0) const {
           0) const {
-    return variantSetSignedInteger(_data, value, _memoryPool);
+    return variantSetSignedInteger(_data, value);
   }
   }
 
 
   // set(unsigned short)
   // set(unsigned short)
@@ -165,13 +165,12 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
   FORCE_INLINE bool set(
   FORCE_INLINE bool set(
       T value, typename enable_if<is_integral<T>::value &&
       T value, typename enable_if<is_integral<T>::value &&
                                   is_unsigned<T>::value>::type * = 0) const {
                                   is_unsigned<T>::value>::type * = 0) const {
-    return variantSetUnsignedInteger(_data, static_cast<JsonUInt>(value),
-                                     _memoryPool);
+    return variantSetUnsignedInteger(_data, static_cast<JsonUInt>(value));
   }
   }
 
 
   // set(SerializedValue<const char *>)
   // set(SerializedValue<const char *>)
   FORCE_INLINE bool set(SerializedValue<const char *> value) const {
   FORCE_INLINE bool set(SerializedValue<const char *> value) const {
-    return variantSetLinkedRaw(_data, value, _memoryPool);
+    return variantSetLinkedRaw(_data, value);
   }
   }
 
 
   // set(SerializedValue<std::string>)
   // set(SerializedValue<std::string>)
@@ -202,15 +201,15 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
 
 
   // set(const char*);
   // set(const char*);
   FORCE_INLINE bool set(const char *value) const {
   FORCE_INLINE bool set(const char *value) const {
-    return variantSetString(_data, value, _memoryPool);
+    return variantSetString(_data, value);
   }
   }
 
 
   // for internal use only
   // for internal use only
   FORCE_INLINE bool set(StringInMemoryPool value) const {
   FORCE_INLINE bool set(StringInMemoryPool value) const {
-    return variantSetOwnedString(_data, value.slot(), _memoryPool);
+    return variantSetOwnedString(_data, value.slot());
   }
   }
   FORCE_INLINE bool set(ZeroTerminatedRamStringConst value) const {
   FORCE_INLINE bool set(ZeroTerminatedRamStringConst value) const {
-    return variantSetString(_data, value.c_str(), _memoryPool);
+    return variantSetString(_data, value.c_str());
   }
   }
 
 
   bool set(JsonVariantConst value) const;
   bool set(JsonVariantConst value) const;

+ 3 - 3
src/ArduinoJson/JsonVariantImpl.hpp

@@ -53,19 +53,19 @@ JsonVariant::as() const {
 template <typename T>
 template <typename T>
 inline typename enable_if<is_same<T, JsonArray>::value, JsonArray>::type
 inline typename enable_if<is_same<T, JsonArray>::value, JsonArray>::type
 JsonVariant::to() const {
 JsonVariant::to() const {
-  return JsonArray(_memoryPool, variantToArray(_data, _memoryPool));
+  return JsonArray(_memoryPool, variantToArray(_data));
 }
 }
 
 
 template <typename T>
 template <typename T>
 typename enable_if<is_same<T, JsonObject>::value, JsonObject>::type
 typename enable_if<is_same<T, JsonObject>::value, JsonObject>::type
 JsonVariant::to() const {
 JsonVariant::to() const {
-  return JsonObject(_memoryPool, variantToObject(_data, _memoryPool));
+  return JsonObject(_memoryPool, variantToObject(_data));
 }
 }
 
 
 template <typename T>
 template <typename T>
 typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type
 typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type
 JsonVariant::to() const {
 JsonVariant::to() const {
-  variantSetNull(_data, _memoryPool);
+  variantSetNull(_data);
   return *this;
   return *this;
 }
 }
 
 

+ 2 - 64
src/ArduinoJson/Memory/MemoryPool.hpp

@@ -9,7 +9,6 @@
 #include "../Strings/StringInMemoryPool.hpp"
 #include "../Strings/StringInMemoryPool.hpp"
 #include "Alignment.hpp"
 #include "Alignment.hpp"
 #include "MemoryPool.hpp"
 #include "MemoryPool.hpp"
-#include "SlotList.hpp"
 #include "StringSlot.hpp"
 #include "StringSlot.hpp"
 #include "VariantSlot.hpp"
 #include "VariantSlot.hpp"
 
 
@@ -60,24 +59,11 @@ class MemoryPool {
   }
   }
 
 
   size_t size() const {
   size_t size() const {
-    return allocated_bytes() - _freeVariants.size() - _freeStrings.size();
+    return size_t(_left - _begin + _end - _right);
   }
   }
 
 
   VariantSlot* allocVariant() {
   VariantSlot* allocVariant() {
-    VariantSlot* s = _freeVariants.pop();
-    if (s) return s;
-    return s ? s : allocRight<VariantSlot>();
-  }
-
-  void freeVariant(VariantSlot* slot) {
-    freeVariantSlot(slot);
-    compactRightSide();
-  }
-
-  void freeString(StringSlot* slot) {
-    freeStringSlot(slot);
-    compactLeftSide(slot->value, slot->size);
-    compactRightSide();
+    return allocRight<VariantSlot>();
   }
   }
 
 
   StringSlot* allocFrozenString(size_t n) {
   StringSlot* allocFrozenString(size_t n) {
@@ -88,7 +74,6 @@ class MemoryPool {
     s->value = _left;
     s->value = _left;
     s->size = n;
     s->size = n;
     _left += n;
     _left += n;
-    _usedString.push(s);
     checkInvariants();
     checkInvariants();
 
 
     return s;
     return s;
@@ -100,7 +85,6 @@ class MemoryPool {
 
 
     s->value = _left;
     s->value = _left;
     s->size = size_t(_right - _left);
     s->size = size_t(_right - _left);
-    _usedString.push(s);
     _left = _right;
     _left = _right;
 
 
     checkInvariants();
     checkInvariants();
@@ -116,9 +100,6 @@ class MemoryPool {
   void clear() {
   void clear() {
     _left = _begin;
     _left = _begin;
     _right = _end;
     _right = _end;
-    _freeVariants.clear();
-    _freeStrings.clear();
-    _usedString.clear();
   }
   }
 
 
   bool canAlloc(size_t bytes) const {
   bool canAlloc(size_t bytes) const {
@@ -146,50 +127,10 @@ class MemoryPool {
   }
   }
 
 
  private:
  private:
-  size_t allocated_bytes() const {
-    return size_t(_left - _begin + _end - _right);
-  }
-
   StringSlot* allocStringSlot() {
   StringSlot* allocStringSlot() {
-    StringSlot* s = _freeStrings.pop();
-    if (s) return s;
     return allocRight<StringSlot>();
     return allocRight<StringSlot>();
   }
   }
 
 
-  void freeVariantSlot(VariantSlot* slot) {
-    _freeVariants.push(slot);
-  }
-
-  void freeStringSlot(StringSlot* slot) {
-    _usedString.remove(slot);
-    _freeStrings.push(slot);
-  }
-
-  void compactLeftSide(char* holeAddress, size_t holeSize) {
-    ARDUINOJSON_ASSERT(holeAddress >= _begin);
-    ARDUINOJSON_ASSERT(holeAddress + holeSize <= _left);
-    char* holeEnd = holeAddress + holeSize;
-    memmove(holeAddress,               // where the hole begun
-            holeEnd,                   // where the hole ended
-            size_t(_left - holeEnd));  // everything after the hole
-    _left -= holeSize;
-    _usedString.forEach(UpdateStringSlotAddress(holeAddress, holeSize));
-    checkInvariants();
-  }
-
-  void compactRightSide() {
-  loop:
-    if (_freeStrings.remove(_right)) {
-      _right += sizeof(StringSlot);
-      goto loop;
-    }
-    if (_freeVariants.remove(_right)) {
-      _right += sizeof(VariantSlot);
-      goto loop;
-    }
-    checkInvariants();
-  }
-
   void checkInvariants() {
   void checkInvariants() {
     ARDUINOJSON_ASSERT(_begin <= _left);
     ARDUINOJSON_ASSERT(_begin <= _left);
     ARDUINOJSON_ASSERT(_left <= _right);
     ARDUINOJSON_ASSERT(_left <= _right);
@@ -198,9 +139,6 @@ class MemoryPool {
   }
   }
 
 
   char *_begin, *_left, *_right, *_end;
   char *_begin, *_left, *_right, *_end;
-  SlotList<VariantSlot> _freeVariants;
-  SlotList<StringSlot> _freeStrings;
-  SlotList<StringSlot> _usedString;
 };
 };
 
 
 }  // namespace ARDUINOJSON_NAMESPACE
 }  // namespace ARDUINOJSON_NAMESPACE

+ 0 - 67
src/ArduinoJson/Memory/SlotList.hpp

@@ -1,67 +0,0 @@
-// ArduinoJson - arduinojson.org
-// Copyright Benoit Blanchon 2014-2018
-// MIT License
-
-#pragma once
-
-#include <stddef.h>  // for size_t
-
-namespace ARDUINOJSON_NAMESPACE {
-
-template <typename TSlot>
-class SlotList {
- public:
-  SlotList() : _head(0) {}
-
-  TSlot *pop() {
-    TSlot *slot = _head;
-    if (slot) _head = slot->next;
-    return slot;
-  }
-
-  void push(TSlot *slot) {
-    slot->next = _head;
-    _head = slot;
-  }
-
-  bool remove(const TSlot *slot) {
-    if (_head == slot) {
-      _head = slot->next;
-      return true;
-    }
-
-    for (TSlot *s = _head; s; s = s->next) {
-      if (s->next == slot) {
-        s->next = slot->next;
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  bool remove(const void *slot) {
-    return remove(reinterpret_cast<const TSlot *>(slot));
-  }
-
-  template <typename Functor>
-  void forEach(const Functor &f) {
-    for (TSlot *s = _head; s; s = s->next) {
-      f(s);
-    }
-  }
-
-  size_t size() const {
-    size_t sum = 0;
-    for (TSlot *s = _head; s; s = s->next) sum += sizeof(TSlot);
-    return sum;
-  }
-
-  void clear() {
-    _head = 0;
-  }
-
- private:
-  TSlot *_head;
-};
-}  // namespace ARDUINOJSON_NAMESPACE

+ 0 - 44
test/JsonDocument/DynamicJsonDocument.cpp

@@ -116,18 +116,6 @@ TEST_CASE("DynamicJsonDocument") {
       REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2));
       REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2));
     }
     }
 
 
-    SECTION("Decreases after removing value from array") {
-      JsonArray arr = doc.to<JsonArray>();
-      arr.add(42);
-      arr.add(43);
-
-      REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2));
-      arr.remove(1);
-      REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1));
-      arr.remove(0);
-      REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0));
-    }
-
     SECTION("Increases after adding value to object") {
     SECTION("Increases after adding value to object") {
       JsonObject obj = doc.to<JsonObject>();
       JsonObject obj = doc.to<JsonObject>();
 
 
@@ -137,37 +125,5 @@ TEST_CASE("DynamicJsonDocument") {
       obj["b"] = 2;
       obj["b"] = 2;
       REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
       REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
     }
     }
-
-    SECTION("Decreases after removing value from object") {
-      JsonObject obj = doc.to<JsonObject>();
-      obj["a"] = 1;
-      obj["b"] = 2;
-
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
-      obj.remove("a");
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1));
-      obj.remove("b");
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0));
-    }
-
-    SECTION("Decreases after removing nested object from array") {
-      JsonArray arr = doc.to<JsonArray>();
-      JsonObject obj = arr.createNestedObject();
-      obj["hello"] = "world";
-
-      REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1));
-      arr.remove(0);
-      REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0));
-    }
-
-    SECTION("Decreases after removing nested array from object") {
-      JsonObject obj = doc.to<JsonObject>();
-      JsonArray arr = obj.createNestedArray("hello");
-      arr.add("world");
-
-      REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1));
-      obj.remove("hello");
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0));
-    }
   }
   }
 }
 }

+ 0 - 13
test/JsonObject/createNestedObject.cpp

@@ -22,17 +22,4 @@ TEST_CASE("JsonObject::createNestedObject()") {
     obj.createNestedObject(vla);
     obj.createNestedObject(vla);
   }
   }
 #endif
 #endif
-
-  SECTION("releases memory from nested object") {
-    obj.createNestedObject(std::string("a"))
-        .createNestedObject(std::string("b"))
-        .set(std::string("c"))
-        .set(1);
-    // {"a":{"b":{"c":1}}}
-    REQUIRE(doc.memoryUsage() ==
-            3 * JSON_OBJECT_SIZE(1) + 3 * JSON_STRING_SIZE(2));
-
-    obj.createNestedObject(std::string("a"));
-    REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2));
-  }
 }
 }

+ 0 - 29
test/JsonObject/remove.cpp

@@ -19,47 +19,18 @@ TEST_CASE("JsonObject::remove()") {
       obj.remove("a");
       obj.remove("a");
       serializeJson(obj, result);
       serializeJson(obj, result);
       REQUIRE("{\"b\":1,\"c\":2}" == result);
       REQUIRE("{\"b\":1,\"c\":2}" == result);
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
     }
     }
 
 
     SECTION("Remove middle") {
     SECTION("Remove middle") {
       obj.remove("b");
       obj.remove("b");
       serializeJson(obj, result);
       serializeJson(obj, result);
       REQUIRE("{\"a\":0,\"c\":2}" == result);
       REQUIRE("{\"a\":0,\"c\":2}" == result);
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
     }
     }
 
 
     SECTION("Remove last") {
     SECTION("Remove last") {
       obj.remove("c");
       obj.remove("c");
       serializeJson(obj, result);
       serializeJson(obj, result);
       REQUIRE("{\"a\":0,\"b\":1}" == result);
       REQUIRE("{\"a\":0,\"b\":1}" == result);
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
-    }
-
-    SECTION("Release value string memory") {
-      obj["c"] = std::string("Copy me!");
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(3) + JSON_STRING_SIZE(9));
-
-      obj.remove("c");
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
-    }
-
-    SECTION("Release key string memory") {
-      obj[std::string("Copy me!")] = 42;
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(4) + JSON_STRING_SIZE(9));
-
-      obj.remove("Copy me!");
-
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(3));
-    }
-
-    SECTION("Release raw string memory") {
-      obj["c"] = serialized(std::string("Copy me!"));
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(3) + JSON_STRING_SIZE(8));
-
-      obj.remove("c");
-
-      REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
     }
     }
   }
   }
 
 

+ 0 - 16
test/JsonObject/subscript.cpp

@@ -141,22 +141,6 @@ TEST_CASE("JsonObject::operator[]") {
     REQUIRE(expectedSize <= doc.memoryUsage());
     REQUIRE(expectedSize <= doc.memoryUsage());
   }
   }
 
 
-  SECTION("should release string memory when overiding value") {
-    obj["hello"] = std::string("world");
-    REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6));
-
-    obj["hello"] = 42;
-    REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1));
-  }
-
-  SECTION("should release nested array memory when overiding value") {
-    obj.createNestedArray("hello").add("world");
-    REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1));
-
-    obj["hello"] = 42;
-    REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1));
-  }
-
   SECTION("should ignore null key") {
   SECTION("should ignore null key") {
     // object must have a value to make a call to strcmp()
     // object must have a value to make a call to strcmp()
     obj["dummy"] = 42;
     obj["dummy"] = 42;

+ 0 - 1
test/JsonVariant/CMakeLists.txt

@@ -13,7 +13,6 @@ add_executable(JsonVariantTests
 	or.cpp
 	or.cpp
 	set.cpp
 	set.cpp
 	subscript.cpp
 	subscript.cpp
-	to.cpp
 	undefined.cpp
 	undefined.cpp
 )
 )
 
 

+ 0 - 19
test/JsonVariant/copy.cpp

@@ -83,23 +83,4 @@ TEST_CASE("JsonVariant::set(JsonVariant)") {
     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8));
     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8));
     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8));
     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8));
   }
   }
-
-  SECTION("releases string memory when replacing with null") {
-    var1.set(std::string("hello"));
-    REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(6));
-
-    var1.set(JsonVariant());
-
-    REQUIRE(doc1.memoryUsage() == 0);
-  }
-
-  SECTION("releases string memory when replacing with iteger") {
-    var1.set(std::string("hello"));
-    REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(6));
-
-    var2.set(42);
-    var1.set(var2);
-
-    REQUIRE(doc1.memoryUsage() == 0);
-  }
 }
 }

+ 0 - 56
test/JsonVariant/set.cpp

@@ -73,62 +73,6 @@ TEST_CASE("JsonVariant and strings") {
   }
   }
 }
 }
 
 
-TEST_CASE("JsonVariant::set() should release string memory") {
-  DynamicJsonDocument doc;
-  JsonVariant variant = doc.to<JsonVariant>();
-
-  variant.set(std::string("hello"));
-  REQUIRE(doc.memoryUsage() == JSON_STRING_SIZE(6));
-
-  SECTION("int") {
-    variant.set(-42);
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-
-  SECTION("unsigned int") {
-    variant.set(42U);
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-
-  SECTION("bool") {
-    variant.set(true);
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-
-  SECTION("float") {
-    variant.set(3.14);
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-
-  SECTION("const char*") {
-    variant.set("hello");
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-
-  SECTION("std::string") {
-    variant.set(std::string("X"));
-    REQUIRE(doc.memoryUsage() == JSON_STRING_SIZE(2));
-  }
-
-  SECTION("SerializedValue<const char*>") {
-    variant.set(serialized("[42]"));
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-
-  SECTION("SerializedValue<std::string>") {
-    variant.set(serialized(std::string("42")));
-    REQUIRE(doc.memoryUsage() == JSON_STRING_SIZE(2));
-  }
-
-  SECTION("StringInMemoryPool") {
-    DeserializationError err =
-        deserializeJson(doc, std::string("{\"A\":\"hello\",\"A\":\"B\"}"));
-    REQUIRE(err == DeserializationError::Ok);
-    // it stores the key twice, but should release "hello"
-    REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 3 * JSON_STRING_SIZE(2));
-  }
-}
-
 TEST_CASE("JsonVariant with not enough memory") {
 TEST_CASE("JsonVariant with not enough memory") {
   StaticJsonDocument<1> doc;
   StaticJsonDocument<1> doc;
 
 

+ 0 - 32
test/JsonVariant/to.cpp

@@ -1,32 +0,0 @@
-// ArduinoJson - arduinojson.org
-// Copyright Benoit Blanchon 2014-2018
-// MIT License
-
-#include <ArduinoJson.h>
-#include <stdint.h>
-#include <catch.hpp>
-
-static const char* null = 0;
-
-TEST_CASE("JsonVariant::to<T>() releases string memory") {
-  DynamicJsonDocument doc;
-  JsonVariant variant = doc.to<JsonVariant>();
-
-  variant.set(std::string("hello"));
-  REQUIRE(doc.memoryUsage() == JSON_STRING_SIZE(6));
-
-  SECTION("JsonVariant") {
-    variant.to<JsonVariant>();
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-
-  SECTION("JsonArray") {
-    variant.to<JsonArray>();
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-
-  SECTION("JsonObject") {
-    variant.to<JsonObject>();
-    REQUIRE(doc.memoryUsage() == 0);
-  }
-}

+ 0 - 66
test/MemoryPool/allocString.cpp

@@ -60,15 +60,6 @@ TEST_CASE("MemoryPool::allocFrozenString()") {
     REQUIRE(a->value == b->value);
     REQUIRE(a->value == b->value);
   }
   }
 
 
-  SECTION("Returns same address after freeString()") {
-    StringSlot *a = pool.allocFrozenString(1);
-    pool.freeString(a);
-    StringSlot *b = pool.allocFrozenString(1);
-
-    REQUIRE(a == b);
-    REQUIRE(a->value == b->value);
-  }
-
   SECTION("Can use full capacity when fresh") {
   SECTION("Can use full capacity when fresh") {
     StringSlot *a = pool.allocFrozenString(longestString);
     StringSlot *a = pool.allocFrozenString(longestString);
 
 
@@ -84,60 +75,3 @@ TEST_CASE("MemoryPool::allocFrozenString()") {
     REQUIRE(a != 0);
     REQUIRE(a != 0);
   }
   }
 }
 }
-
-TEST_CASE("MemoryPool::freeString()") {
-  const size_t poolCapacity = 512;
-  const size_t longestString = poolCapacity - sizeof(StringSlot);
-  char buffer[poolCapacity];
-  MemoryPool pool(buffer, poolCapacity);
-
-  static const size_t testStringSize =
-      (poolCapacity - sizeof(StringSlot) * 4 - sizeof(VariantSlot) * 4) / 4;
-
-  SECTION("Restores full capacity") {
-    StringSlot *strings[4];
-    VariantSlot *variants[4];
-
-    for (int i = 0; i < 4; i++) {
-      strings[i] = pool.allocFrozenString(testStringSize);
-      REQUIRE(strings[i] != 0);
-      variants[i] = pool.allocVariant();
-      REQUIRE(variants[i] != 0);
-    }
-
-    // In random order
-    pool.freeString(strings[2]);
-    pool.freeVariant(variants[3]);
-    pool.freeVariant(variants[0]);
-    pool.freeString(strings[0]);
-    pool.freeVariant(variants[1]);
-    pool.freeString(strings[1]);
-    pool.freeVariant(variants[2]);
-    pool.freeString(strings[3]);
-
-    StringSlot *b = pool.allocFrozenString(longestString);
-
-    REQUIRE(b != 0);
-    REQUIRE(b->size == longestString);
-  }
-
-  SECTION("Move strings") {
-    StringSlot *a = pool.allocFrozenString(6);
-    strcpy(a->value, "hello");
-
-    StringSlot *b = pool.allocFrozenString(7);
-    strcpy(b->value, "world!");
-    pool.freeString(a);
-
-    REQUIRE(b->size == 7);
-    REQUIRE(b->value == std::string("world!"));
-    REQUIRE(a->value == b->value);
-  }
-
-  SECTION("Accepts non-frozen string") {
-    StringSlot *a = pool.allocExpandableString();
-    pool.freeString(a);
-
-    REQUIRE(pool.size() == 0);
-  }
-}

+ 0 - 10
test/MemoryPool/allocVariant.cpp

@@ -21,16 +21,6 @@ TEST_CASE("MemoryPool::allocVariant()") {
     REQUIRE(s1 != s2);
     REQUIRE(s1 != s2);
   }
   }
 
 
-  SECTION("Returns same pointer after freeSlot()") {
-    MemoryPool pool(buffer, sizeof(buffer));
-
-    VariantSlot* s1 = pool.allocVariant();
-    pool.freeVariant(s1);
-    VariantSlot* s2 = pool.allocVariant();
-
-    REQUIRE(s1 == s2);
-  }
-
   SECTION("Returns aligned pointers") {
   SECTION("Returns aligned pointers") {
     MemoryPool pool(buffer, sizeof(buffer));
     MemoryPool pool(buffer, sizeof(buffer));
 
 

+ 0 - 52
test/MemoryPool/clear.cpp

@@ -28,56 +28,4 @@ TEST_CASE("MemoryPool::clear()") {
 
 
     REQUIRE(memoryPool.size() == 0);
     REQUIRE(memoryPool.size() == 0);
   }
   }
-
-  SECTION("Purges variant cache") {
-    VariantSlot* a = memoryPool.allocVariant();
-    REQUIRE(a != 0);
-    VariantSlot* b = memoryPool.allocVariant();
-    REQUIRE(b != 0);
-
-    // place slot a in the pool of free slots
-    memoryPool.freeVariant(a);
-    memoryPool.clear();
-
-    REQUIRE(memoryPool.size() == 0);
-  }
-
-  SECTION("Purges string cache") {
-    StringSlot* a = memoryPool.allocFrozenString(10);
-    REQUIRE(a != 0);
-    StringSlot* b = memoryPool.allocFrozenString(10);
-    REQUIRE(b != 0);
-
-    // place slot a in the pool of free slots
-    memoryPool.freeString(a);
-    memoryPool.clear();
-
-    REQUIRE(memoryPool.size() == 0);
-  }
-
-  SECTION("Purges list of string") {
-    StringSlot* a = memoryPool.allocFrozenString(6);
-    REQUIRE(a != 0);
-    strcpy(a->value, "hello");
-
-    StringSlot* b = memoryPool.allocFrozenString(6);
-    REQUIRE(b != 0);
-    strcpy(b->value, "world");
-
-    memoryPool.clear();  // ACT!
-
-    StringSlot* c = memoryPool.allocFrozenString(2);
-    REQUIRE(c != 0);
-    strcpy(c->value, "H");
-
-    StringSlot* d = memoryPool.allocFrozenString(2);
-    REQUIRE(d != 0);
-    strcpy(d->value, "W");
-
-    // if the memory pool keeps pointer to the old strings
-    // it will try to compact the strings
-    memoryPool.freeString(c);
-
-    REQUIRE(d->value == std::string("W"));
-  }
 }
 }

+ 0 - 35
test/MemoryPool/size.cpp

@@ -45,41 +45,6 @@ TEST_CASE("MemoryPool::size()") {
     REQUIRE(memoryPool.size() == 2 * JSON_STRING_SIZE(0));
     REQUIRE(memoryPool.size() == 2 * JSON_STRING_SIZE(0));
   }
   }
 
 
-  SECTION("Decreases after freeVariant()") {
-    VariantSlot* a = memoryPool.allocVariant();
-    VariantSlot* b = memoryPool.allocVariant();
-
-    memoryPool.freeVariant(b);
-    REQUIRE(memoryPool.size() == sizeof(VariantSlot));
-
-    memoryPool.freeVariant(a);
-    REQUIRE(memoryPool.size() == 0);
-  }
-
-  SECTION("Decreases after calling freeString() in order") {
-    StringSlot* a = memoryPool.allocFrozenString(5);
-    REQUIRE(a != 0);
-    StringSlot* b = memoryPool.allocFrozenString(6);
-    REQUIRE(b != 0);
-
-    memoryPool.freeString(b);
-    REQUIRE(memoryPool.size() == JSON_STRING_SIZE(5));
-    memoryPool.freeString(a);
-    REQUIRE(memoryPool.size() == 0);
-  }
-
-  SECTION("Decreases after calling freeString() in reverse order") {
-    StringSlot* a = memoryPool.allocFrozenString(5);
-    REQUIRE(a != 0);
-    StringSlot* b = memoryPool.allocFrozenString(6);
-    REQUIRE(b != 0);
-
-    memoryPool.freeString(a);
-    REQUIRE(memoryPool.size() == JSON_STRING_SIZE(6));
-    memoryPool.freeString(b);
-    REQUIRE(memoryPool.size() == 0);
-  }
-
   SECTION("Doesn't grow when memory pool is full") {
   SECTION("Doesn't grow when memory pool is full") {
     const size_t variantCount = sizeof(buffer) / sizeof(VariantSlot);
     const size_t variantCount = sizeof(buffer) / sizeof(VariantSlot);