diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2019-01-04 15:09:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-04 15:09:05 +0100 |
commit | 578c6316c884cd136c9d9de94f1ba20468e4737a (patch) | |
tree | 69e89083332574d051ccebadef64ae296316f902 /core/cowdata.h | |
parent | fa5ca1bbf0451017f388c660cd06bd141eb762b6 (diff) | |
parent | 4240e3d668be01a8497747b542279041a64a11cd (diff) |
Merge pull request #24732 from hpvb/vector-pod-optimization
Optimizations for trivial types
Diffstat (limited to 'core/cowdata.h')
-rw-r--r-- | core/cowdata.h | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/core/cowdata.h b/core/cowdata.h index d5d49215c2..319e61d261 100644 --- a/core/cowdata.h +++ b/core/cowdata.h @@ -31,6 +31,8 @@ #ifndef COWDATA_H_ #define COWDATA_H_ +#include <string.h> + #include "core/os/memory.h" #include "core/safe_refcount.h" @@ -194,12 +196,14 @@ void CowData<T>::_unref(void *p_data) { return; // still in use // clean up - uint32_t *count = _get_size(); - T *data = (T *)(count + 1); + if (!__has_trivial_destructor(T)) { + uint32_t *count = _get_size(); + T *data = (T *)(count + 1); - for (uint32_t i = 0; i < *count; ++i) { - // call destructors - data[i].~T(); + for (uint32_t i = 0; i < *count; ++i) { + // call destructors + data[i].~T(); + } } // free mem @@ -226,9 +230,13 @@ void CowData<T>::_copy_on_write() { T *_data = (T *)(mem_new); // initialize new elements - for (uint32_t i = 0; i < current_size; i++) { + if (__has_trivial_copy(T)) { + memcpy(mem_new, _ptr, current_size * sizeof(T)); - memnew_placement(&_data[i], T(_get_data()[i])); + } else { + for (uint32_t i = 0; i < current_size; i++) { + memnew_placement(&_data[i], T(_get_data()[i])); + } } _unref(_ptr); @@ -275,22 +283,25 @@ Error CowData<T>::resize(int p_size) { } // construct the newly created elements - T *elems = _get_data(); - for (int i = *_get_size(); i < p_size; i++) { + if (!__has_trivial_constructor(T)) { + T *elems = _get_data(); - memnew_placement(&elems[i], T); + for (int i = *_get_size(); i < p_size; i++) { + memnew_placement(&elems[i], T); + } } *_get_size() = p_size; } else if (p_size < size()) { - // deinitialize no longer needed elements - for (uint32_t i = p_size; i < *_get_size(); i++) { - - T *t = &_get_data()[i]; - t->~T(); + if (!__has_trivial_destructor(T)) { + // deinitialize no longer needed elements + for (uint32_t i = p_size; i < *_get_size(); i++) { + T *t = &_get_data()[i]; + t->~T(); + } } void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true); |