summaryrefslogtreecommitdiff
path: root/core/cowdata.h
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2019-01-04 15:09:05 +0100
committerGitHub <noreply@github.com>2019-01-04 15:09:05 +0100
commit578c6316c884cd136c9d9de94f1ba20468e4737a (patch)
tree69e89083332574d051ccebadef64ae296316f902 /core/cowdata.h
parentfa5ca1bbf0451017f388c660cd06bd141eb762b6 (diff)
parent4240e3d668be01a8497747b542279041a64a11cd (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.h41
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);