Skip to content

Commit fe67f99

Browse files
committed
Added aligned memory management methods
1 parent 543c1f7 commit fe67f99

File tree

5 files changed

+109
-0
lines changed

5 files changed

+109
-0
lines changed

gdextension/gdextension_interface.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,45 @@ typedef void *(*GDExtensionInterfaceMemRealloc)(void *p_ptr, size_t p_bytes);
839839
*/
840840
typedef void (*GDExtensionInterfaceMemFree)(void *p_ptr);
841841

842+
// TODO: Uncomment if the approach is to add to the interface instead of a local implementation
843+
// /**
844+
// * @name mem_aligned_alloc
845+
// * @since 4.5
846+
// *
847+
// * Allocates memory aligned to user input
848+
// *
849+
// * @param p_bytes The amount of memory to allocate in bytes
850+
// * @param p_align The alignment of the memory block to allocate to the nearest byte
851+
// *
852+
// * @return A pointer to the allocated aligned memory, or NULL if unsucessful
853+
// */
854+
// typedef void *(*GDExtensionInterfaceMemAlignedAlloc)(size_t p_bytes, size_t p_align);
855+
856+
// /**
857+
// * @name mem_aligned_realloc
858+
// * @since 4.5
859+
// *
860+
// * Reallocates memory aligned to user input.
861+
// *
862+
// * @param p_ptr A pointer to the previously allocated aligned memory.
863+
// * @param p_bytes The number of bytes to resize the memory block to.
864+
// * @param p_prev_bytes The previous size of the memory block in bytes.
865+
// * @param p_align The alignment of the memory block to allocate to the nearest byte.
866+
// *
867+
// * @return A pointer to the allocated aligned memory, or NULL if unsuccessful.
868+
// */
869+
// typedef void *(*GDExtensionInterfaceMemAlignedRealloc)(void *p_ptr, size_t p_bytes, size_t p_prev_bytes, size_t p_align);
870+
871+
// /**
872+
// * @name mem_aligned_free
873+
// * @since 4.5
874+
// *
875+
// * Frees memory allocated with `mem_aligned_alloc`.
876+
// *
877+
// * @param p_ptr A pointer to the previously allocated aligned memory.
878+
// */
879+
// typedef void (*GDExtensionInterfaceMemAlignedFree)(void *p_ptr);
880+
842881
/* INTERFACE: Godot Core */
843882

844883
/**

include/godot_cpp/core/memory.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ class Memory {
7979
static void *alloc_static(size_t p_bytes, bool p_pad_align = false);
8080
static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false);
8181
static void free_static(void *p_ptr, bool p_pad_align = false);
82+
83+
static void *alloc_aligned_static(size_t p_bytes, size_t p_alignment);
84+
static void *realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment);
85+
static void free_aligned_static(void *p_ptr);
8286
};
8387

8488
template <typename T, std::enable_if_t<!std::is_base_of<::godot::Wrapped, T>::value, bool> = true>
@@ -96,6 +100,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
96100
#define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size)
97101
#define memfree(m_mem) ::godot::Memory::free_static(m_mem)
98102

103+
#define memalloc_aligned(m_size, m_alignment) ::godot::Memory::alloc_aligned_static(m_size, m_alignment)
104+
#define memrealloc_aligned(m_mem, m_size, m_prev_size, m_alignment) ::godot::Memory::realloc_aligned_static(m_mem, m_size, m_prev_size, m_alignment)
105+
#define memfree_aligned(m_mem) ::godot::Memory::free_aligned_static(m_mem)
106+
99107
#define memnew(m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", "") m_class))
100108

101109
#define memnew_allocator(m_class, m_allocator) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", m_allocator::alloc) m_class))

include/godot_cpp/godot.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ extern "C" GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_v
4747
extern "C" GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc;
4848
extern "C" GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc;
4949
extern "C" GDExtensionInterfaceMemFree gdextension_interface_mem_free;
50+
// TODO: Uncomment if the engine is updated to use this extended interface
51+
// extern "C" GDExtensionInterfaceMemAlignedAlloc gdextension_interface_mem_aligned_alloc;
52+
// extern "C" GDExtensionInterfaceMemAlignedRealloc gdextension_interface_mem_aligned_realloc;
53+
// extern "C" GDExtensionInterfaceMemAlignedFree gdextension_interface_mem_aligned_free;
5054
extern "C" GDExtensionInterfacePrintError gdextension_interface_print_error;
5155
extern "C" GDExtensionInterfacePrintErrorWithMessage gdextension_interface_print_error_with_message;
5256
extern "C" GDExtensionInterfacePrintWarning gdextension_interface_print_warning;

src/core/memory.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,60 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
9393
internal::gdextension_interface_mem_free(mem);
9494
}
9595

96+
void *Memory::alloc_aligned_static(size_t p_bytes, size_t p_alignment) {
97+
DEV_ASSERT(is_power_of_2(p_alignment));
98+
99+
void *p1, *p2;
100+
if ((p1 = (void *)alloc_static(p_bytes + p_alignment - 1 + sizeof(uint32_t))) == nullptr) {
101+
return nullptr;
102+
}
103+
104+
p2 = (void *)(((uintptr_t)p1 + sizeof(uint32_t) + p_alignment - 1) & ~((p_alignment)-1));
105+
*((uint32_t *)p2 - 1) = (uint32_t)((uintptr_t)p2 - (uintptr_t)p1);
106+
return p2;
107+
108+
// TODO: Alternate implementation if engine accepts this interface
109+
// void *mem = internal::gdextension_interface_mem_aligned_alloc(p_bytes, p_alignment);
110+
// ERR_FAIL_NULL_V(mem, nullptr);
111+
// return mem;
112+
}
113+
114+
void *Memory::realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment) {
115+
DEV_ASSERT(is_power_of_2(p_alignment));
116+
117+
if (p_memory == nullptr) {
118+
return alloc_aligned_static(p_bytes, p_alignment);
119+
}
120+
121+
void *ret = alloc_aligned_static(p_bytes, p_alignment);
122+
if (ret) {
123+
memcpy(ret, p_memory, p_prev_bytes);
124+
}
125+
free_aligned_static(p_memory);
126+
return ret;
127+
128+
// TODO: Alternate implementation if engine accepts this interface
129+
// if (p_memory == nullptr) {
130+
// return alloc_aligned_static(p_bytes, p_alignment);
131+
// } else if (p_bytes == 0) {
132+
// free_aligned_static(p_memory);
133+
// return nullptr;
134+
// }
135+
136+
// void *mem = internal::gdextension_interface_mem_aligned_realloc(p_memory, p_bytes, p_prev_bytes, p_alignment);
137+
// ERR_FAIL_NULL_V(mem, nullptr);
138+
// return mem;
139+
}
140+
141+
void Memory::free_aligned_static(void *p_ptr) {
142+
uint32_t offset = *((uint32_t *)p_ptr - 1);
143+
void *p = (void *)((uint8_t *)p_ptr - offset);
144+
free_static(p);
145+
146+
// TODO: Alternate implementation if engine accepts this interface
147+
// internal::gdextension_interface_mem_aligned_free(p_ptr);
148+
}
149+
96150
_GlobalNil::_GlobalNil() {
97151
left = this;
98152
right = this;

src/godot.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version = nu
5454
GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc = nullptr;
5555
GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc = nullptr;
5656
GDExtensionInterfaceMemFree gdextension_interface_mem_free = nullptr;
57+
// TODO: Uncomment if the engine is updated to use this extended interface
58+
// GDExtensionInterfaceMemAlignedAlloc gdextension_interface_mem_aligned_alloc = nullptr;
59+
// GDExtensionInterfaceMemAlignedRealloc gdextension_interface_mem_aligned_realloc = nullptr;
60+
// GDExtensionInterfaceMemAlignedFree gdextension_interface_mem_aligned_free = nullptr;
5761
GDExtensionInterfacePrintError gdextension_interface_print_error = nullptr;
5862
GDExtensionInterfacePrintErrorWithMessage gdextension_interface_print_error_with_message = nullptr;
5963
GDExtensionInterfacePrintWarning gdextension_interface_print_warning = nullptr;

0 commit comments

Comments
 (0)