2
0
mirror of https://github.com/godotengine/godot.git synced 2025-04-13 01:00:35 +08:00

Merge pull request from hpvb/vector-pod-optimization

Optimizations for trivial types
This commit is contained in:
Rémi Verschelde 2019-01-04 15:09:05 +01:00 committed by GitHub
commit 578c6316c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 25 deletions

@ -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);

@ -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);
}