From 8483d794ffec51a22d9dc8872cc082f9f0ece9db Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Mon, 16 Dec 2024 16:44:32 +0100 Subject: [PATCH] Abstract `CowData`'s reallocations into `_realloc` to consolidate duplicate logic. --- core/templates/cowdata.h | 44 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index f87fa1ad811..ce32a903386 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -164,6 +164,7 @@ private: void _ref(const CowData *p_from); void _ref(const CowData &p_from); USize _copy_on_write(); + Error _realloc(Size p_alloc_size); public: void operator=(const CowData &p_from) { _ref(p_from); } @@ -342,7 +343,7 @@ Error CowData::resize(Size p_size) { } // possibly changing size, copy on write - USize rc = _copy_on_write(); + _copy_on_write(); USize current_alloc_size = _get_alloc_size(current_size); USize alloc_size; @@ -365,15 +366,10 @@ Error CowData::resize(Size p_size) { _ptr = _data_ptr; } else { - uint8_t *mem_new = (uint8_t *)Memory::realloc_static(((uint8_t *)_ptr) - DATA_OFFSET, alloc_size + DATA_OFFSET, false); - ERR_FAIL_NULL_V(mem_new, ERR_OUT_OF_MEMORY); - - SafeNumeric *_refc_ptr = _get_refcount_ptr(mem_new); - T *_data_ptr = _get_data_ptr(mem_new); - - new (_refc_ptr) SafeNumeric(rc); //refcount - - _ptr = _data_ptr; + const Error error = _realloc(alloc_size); + if (error) { + return error; + } } } @@ -399,15 +395,10 @@ Error CowData::resize(Size p_size) { } if (alloc_size != current_alloc_size) { - uint8_t *mem_new = (uint8_t *)Memory::realloc_static(((uint8_t *)_ptr) - DATA_OFFSET, alloc_size + DATA_OFFSET, false); - ERR_FAIL_NULL_V(mem_new, ERR_OUT_OF_MEMORY); - - SafeNumeric *_refc_ptr = _get_refcount_ptr(mem_new); - T *_data_ptr = _get_data_ptr(mem_new); - - new (_refc_ptr) SafeNumeric(rc); //refcount - - _ptr = _data_ptr; + const Error error = _realloc(alloc_size); + if (error) { + return error; + } } *_get_size() = p_size; @@ -416,6 +407,21 @@ Error CowData::resize(Size p_size) { return OK; } +template +Error CowData::_realloc(Size p_alloc_size) { + uint8_t *mem_new = (uint8_t *)Memory::realloc_static(((uint8_t *)_ptr) - DATA_OFFSET, p_alloc_size + DATA_OFFSET, false); + ERR_FAIL_NULL_V(mem_new, ERR_OUT_OF_MEMORY); + + SafeNumeric *_refc_ptr = _get_refcount_ptr(mem_new); + T *_data_ptr = _get_data_ptr(mem_new); + + // If we realloc, we're guaranteed to be the only reference. + new (_refc_ptr) SafeNumeric(1); + _ptr = _data_ptr; + + return OK; +} + template typename CowData::Size CowData::find(const T &p_val, Size p_from) const { Size ret = -1;