Merge pull request #37373 from reduz/fix-vector-resize
Ensure COWData does not always reallocate on resize, fixes #22561
This commit is contained in:
commit
f8cb0a1b3c
1 changed files with 24 additions and 17 deletions
|
@ -253,7 +253,9 @@ Error CowData<T>::resize(int p_size) {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
|
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;
|
return OK;
|
||||||
|
|
||||||
if (p_size == 0) {
|
if (p_size == 0) {
|
||||||
|
@ -266,12 +268,14 @@ Error CowData<T>::resize(int p_size) {
|
||||||
// possibly changing size, copy on write
|
// possibly changing size, copy on write
|
||||||
_copy_on_write();
|
_copy_on_write();
|
||||||
|
|
||||||
|
size_t current_alloc_size = _get_alloc_size(current_size);
|
||||||
size_t alloc_size;
|
size_t alloc_size;
|
||||||
ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
|
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) {
|
if (alloc_size != current_alloc_size) {
|
||||||
|
if (current_size == 0) {
|
||||||
// alloc from scratch
|
// alloc from scratch
|
||||||
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
|
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
|
||||||
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
|
||||||
|
@ -285,6 +289,7 @@ Error CowData<T>::resize(int p_size) {
|
||||||
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
||||||
_ptr = (T *)(_ptrnew);
|
_ptr = (T *)(_ptrnew);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// construct the newly created elements
|
// construct the newly created elements
|
||||||
|
|
||||||
|
@ -298,7 +303,7 @@ Error CowData<T>::resize(int p_size) {
|
||||||
|
|
||||||
*_get_size() = p_size;
|
*_get_size() = p_size;
|
||||||
|
|
||||||
} else if (p_size < size()) {
|
} else if (p_size < current_size) {
|
||||||
|
|
||||||
if (!__has_trivial_destructor(T)) {
|
if (!__has_trivial_destructor(T)) {
|
||||||
// deinitialize no longer needed elements
|
// deinitialize no longer needed elements
|
||||||
|
@ -308,10 +313,12 @@ Error CowData<T>::resize(int p_size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alloc_size != current_alloc_size) {
|
||||||
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
|
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||||
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
_ptr = (T *)(_ptrnew);
|
_ptr = (T *)(_ptrnew);
|
||||||
|
}
|
||||||
|
|
||||||
*_get_size() = p_size;
|
*_get_size() = p_size;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue