Skip to content

Commit

Permalink
Ensure COWData does not reallocate on push back, fixes godotengine#22561
Browse files Browse the repository at this point in the history
  • Loading branch information
reduz committed Mar 28, 2020
1 parent fcfffd7 commit 0c24a84
Showing 1 changed file with 24 additions and 17 deletions.
41 changes: 24 additions & 17 deletions core/cowdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ Error CowData<T>::resize(int p_size) {

ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);

if (p_size == size())
int current_size = size();

if (p_size == current_size)
return OK;

if (p_size == 0) {
Expand All @@ -266,24 +268,27 @@ Error CowData<T>::resize(int p_size) {
// possibly changing size, copy on write
_copy_on_write();

size_t current_alloc_size = _get_alloc_size(current_size);
size_t alloc_size;
ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);

if (p_size > size()) {
if (p_size > current_size) {

if (size() == 0) {
// alloc from scratch
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
*(ptr - 1) = 0; //size, currently none
*(ptr - 2) = 1; //refcount
if (alloc_size != current_alloc_size) {
if (current_size == 0) {
// alloc from scratch
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
*(ptr - 1) = 0; //size, currently none
*(ptr - 2) = 1; //refcount

_ptr = (T *)ptr;
_ptr = (T *)ptr;

} else {
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
_ptr = (T *)(_ptrnew);
} else {
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
_ptr = (T *)(_ptrnew);
}
}

// construct the newly created elements
Expand All @@ -298,7 +303,7 @@ Error CowData<T>::resize(int p_size) {

*_get_size() = p_size;

} else if (p_size < size()) {
} else if (p_size < current_size) {

if (!__has_trivial_destructor(T)) {
// deinitialize no longer needed elements
Expand All @@ -308,10 +313,12 @@ Error CowData<T>::resize(int p_size) {
}
}

void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
if (alloc_size != current_alloc_size) {
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);

_ptr = (T *)(_ptrnew);
_ptr = (T *)(_ptrnew);
}

*_get_size() = p_size;
}
Expand Down

0 comments on commit 0c24a84

Please sign in to comment.