diff options
-rw-r--r-- | core/cowdata.h | 41 | ||||
-rw-r--r-- | core/os/memory.h | 28 |
2 files changed, 44 insertions, 25 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); diff --git a/core/os/memory.h b/core/os/memory.h index 558dc5ddf3..f3ca9fc614 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -116,7 +116,9 @@ void memdelete(T *p_class) { if (!predelete_handler(p_class)) return; // doesn't want to be deleted - p_class->~T(); + if (!__has_trivial_destructor(T)) + p_class->~T(); + Memory::free_static(p_class, false); } @@ -125,7 +127,9 @@ void memdelete_allocator(T *p_class) { if (!predelete_handler(p_class)) return; // doesn't want to be deleted - p_class->~T(); + if (!__has_trivial_destructor(T)) + p_class->~T(); + A::free(p_class); } @@ -150,11 +154,13 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") { ERR_FAIL_COND_V(!mem, failptr); *(mem - 1) = p_elements; - T *elems = (T *)mem; + if (!__has_trivial_constructor(T)) { + T *elems = (T *)mem; - /* call operator new */ - for (size_t i = 0; i < p_elements; i++) { - new (&elems[i], sizeof(T), p_descr) T; + /* call operator new */ + for (size_t i = 0; i < p_elements; i++) { + new (&elems[i], sizeof(T), p_descr) T; + } } return (T *)mem; @@ -177,12 +183,14 @@ void memdelete_arr(T *p_class) { uint64_t *ptr = (uint64_t *)p_class; - uint64_t elem_count = *(ptr - 1); + if (!__has_trivial_destructor(T)) { + uint64_t elem_count = *(ptr - 1); - for (uint64_t i = 0; i < elem_count; i++) { + for (uint64_t i = 0; i < elem_count; i++) { + p_class[i].~T(); + } + } - p_class[i].~T(); - }; Memory::free_static(ptr, true); } |