mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-03 18:09:13 +03:00
[Core] Improve CowData and Memory metadata alignment.
(cherry picked from commit b173a4d935)
This commit is contained in:
@@ -40,10 +40,6 @@
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#ifndef PAD_ALIGN
|
||||
#define PAD_ALIGN 16 //must always be greater than this at much
|
||||
#endif
|
||||
|
||||
// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
|
||||
void *operator new(size_t p_size, const char *p_dummy, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
|
||||
void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool
|
||||
@@ -69,6 +65,18 @@ class Memory {
|
||||
Memory();
|
||||
|
||||
public:
|
||||
// Alignment: ↓ max_align_t ↓ uint64_t ↓ max_align_t
|
||||
// ┌─────────────────┬──┬────────────────┬──┬───────────...
|
||||
// │ uint64_t │░░│ uint64_t │░░│ T[]
|
||||
// │ alloc size │░░│ element count │░░│ data
|
||||
// └─────────────────┴──┴────────────────┴──┴───────────...
|
||||
// Offset: ↑ SIZE_OFFSET ↑ ELEMENT_OFFSET ↑ DATA_OFFSET
|
||||
// Note: "alloc size" is used and set by the engine and is never accessed or changed for the extension.
|
||||
|
||||
static constexpr size_t SIZE_OFFSET = 0;
|
||||
static constexpr size_t ELEMENT_OFFSET = ((SIZE_OFFSET + sizeof(uint64_t)) % alignof(uint64_t) == 0) ? (SIZE_OFFSET + sizeof(uint64_t)) : ((SIZE_OFFSET + sizeof(uint64_t)) + alignof(uint64_t) - ((SIZE_OFFSET + sizeof(uint64_t)) % alignof(uint64_t)));
|
||||
static constexpr size_t DATA_OFFSET = ((ELEMENT_OFFSET + sizeof(uint64_t)) % alignof(max_align_t) == 0) ? (ELEMENT_OFFSET + sizeof(uint64_t)) : ((ELEMENT_OFFSET + sizeof(uint64_t)) + alignof(max_align_t) - ((ELEMENT_OFFSET + sizeof(uint64_t)) % alignof(max_align_t)));
|
||||
|
||||
static void *alloc_static(size_t p_bytes, bool p_pad_align = false);
|
||||
static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false);
|
||||
static void free_static(void *p_ptr, bool p_pad_align = false);
|
||||
@@ -99,7 +107,7 @@ struct Comparator {
|
||||
|
||||
template <class T>
|
||||
void memdelete(T *p_class, typename std::enable_if<!std::is_base_of_v<godot::Wrapped, T>>::type * = nullptr) {
|
||||
if (!std::is_trivially_destructible<T>::value) {
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
p_class->~T();
|
||||
}
|
||||
|
||||
@@ -113,7 +121,7 @@ void memdelete(T *p_class) {
|
||||
|
||||
template <class T, class A>
|
||||
void memdelete_allocator(T *p_class) {
|
||||
if (!std::is_trivially_destructible<T>::value) {
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
p_class->~T();
|
||||
}
|
||||
|
||||
@@ -136,6 +144,10 @@ public:
|
||||
|
||||
#define memnew_arr(m_class, m_count) memnew_arr_template<m_class>(m_count)
|
||||
|
||||
_FORCE_INLINE_ uint64_t *_get_element_count_ptr(uint8_t *p_ptr) {
|
||||
return (uint64_t *)(p_ptr - Memory::DATA_OFFSET + Memory::ELEMENT_OFFSET);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
|
||||
if (p_elements == 0) {
|
||||
@@ -145,12 +157,14 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
|
||||
same strategy used by std::vector, and the Vector class, so it should be safe.*/
|
||||
|
||||
size_t len = sizeof(T) * p_elements;
|
||||
uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
|
||||
uint8_t *mem = (uint8_t *)Memory::alloc_static(len, true);
|
||||
T *failptr = nullptr; // Get rid of a warning.
|
||||
ERR_FAIL_NULL_V(mem, failptr);
|
||||
*(mem - 1) = p_elements;
|
||||
|
||||
if (!std::is_trivially_destructible<T>::value) {
|
||||
uint64_t *_elem_count_ptr = _get_element_count_ptr(mem);
|
||||
*(_elem_count_ptr) = p_elements;
|
||||
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
T *elems = (T *)mem;
|
||||
|
||||
/* call operator new */
|
||||
@@ -163,11 +177,19 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void memdelete_arr(T *p_class) {
|
||||
uint64_t *ptr = (uint64_t *)p_class;
|
||||
size_t memarr_len(const T *p_class) {
|
||||
uint8_t *ptr = (uint8_t *)p_class;
|
||||
uint64_t *_elem_count_ptr = _get_element_count_ptr(ptr);
|
||||
return *(_elem_count_ptr);
|
||||
}
|
||||
|
||||
if (!std::is_trivially_destructible<T>::value) {
|
||||
uint64_t elem_count = *(ptr - 1);
|
||||
template <typename T>
|
||||
void memdelete_arr(T *p_class) {
|
||||
uint8_t *ptr = (uint8_t *)p_class;
|
||||
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
uint64_t *_elem_count_ptr = _get_element_count_ptr(ptr);
|
||||
uint64_t elem_count = *(_elem_count_ptr);
|
||||
|
||||
for (uint64_t i = 0; i < elem_count; i++) {
|
||||
p_class[i].~T();
|
||||
|
||||
Reference in New Issue
Block a user