diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp index e01c181a18b..4de4710da79 100644 --- a/core/io/zip_io.cpp +++ b/core/io/zip_io.cpp @@ -161,8 +161,7 @@ int zipio_testerror(voidpf opaque, voidpf stream) { } voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) { - voidpf ptr = memalloc((size_t)items * size); - memset(ptr, 0, items * size); + voidpf ptr = memalloc_zeroed((size_t)items * size); return ptr; } diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 8ed6106d047..867158d52a1 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -93,6 +93,7 @@ void Memory::free_aligned_static(void *p_memory) { free(p); } +template void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { #ifdef DEBUG_ENABLED bool prepad = true; @@ -100,7 +101,12 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { bool prepad = p_pad_align; #endif - void *mem = malloc(p_bytes + (prepad ? DATA_OFFSET : 0)); + void *mem; + if constexpr (p_ensure_zero) { + mem = calloc(1, p_bytes + (prepad ? DATA_OFFSET : 0)); + } else { + mem = malloc(p_bytes + (prepad ? DATA_OFFSET : 0)); + } ERR_FAIL_NULL_V(mem, nullptr); @@ -120,6 +126,9 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { } } +template void *Memory::alloc_static(size_t p_bytes, bool p_pad_align); +template void *Memory::alloc_static(size_t p_bytes, bool p_pad_align); + void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { if (p_memory == nullptr) { return alloc_static(p_bytes, p_pad_align); diff --git a/core/os/memory.h b/core/os/memory.h index 7164a3e3fbc..bec4f949d7f 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -54,7 +54,9 @@ public: 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))); + template static void *alloc_static(size_t p_bytes, bool p_pad_align = false); + _FORCE_INLINE_ static void *alloc_static_zeroed(size_t p_bytes, bool p_pad_align = false) { return alloc_static(p_bytes, p_pad_align); } 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); @@ -107,6 +109,7 @@ void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_d #endif #define memalloc(m_size) Memory::alloc_static(m_size) +#define memalloc_zeroed(m_size) Memory::alloc_static_zeroed(m_size) #define memrealloc(m_mem, m_size) Memory::realloc_static(m_mem, m_size) #define memfree(m_mem) Memory::free_static(m_mem) diff --git a/core/templates/a_hash_map.h b/core/templates/a_hash_map.h index e603d0aa5f2..49adf28da50 100644 --- a/core/templates/a_hash_map.h +++ b/core/templates/a_hash_map.h @@ -214,11 +214,9 @@ private: HashMapData *old_map_data = map_data; - map_data = reinterpret_cast(Memory::alloc_static(sizeof(HashMapData) * real_capacity)); + map_data = reinterpret_cast(Memory::alloc_static_zeroed(sizeof(HashMapData) * real_capacity)); elements = reinterpret_cast(Memory::realloc_static(elements, sizeof(MapKeyValue) * (_get_resize_count(capacity) + 1))); - memset(map_data, EMPTY_HASH, real_capacity * sizeof(HashMapData)); - if (num_elements != 0) { for (uint32_t i = 0; i < real_old_capacity; i++) { HashMapData data = old_map_data[i]; @@ -236,10 +234,8 @@ private: // Allocate on demand to save memory. uint32_t real_capacity = capacity + 1; - map_data = reinterpret_cast(Memory::alloc_static(sizeof(HashMapData) * real_capacity)); + map_data = reinterpret_cast(Memory::alloc_static_zeroed(sizeof(HashMapData) * real_capacity)); elements = reinterpret_cast(Memory::alloc_static(sizeof(MapKeyValue) * (_get_resize_count(capacity) + 1))); - - memset(map_data, EMPTY_HASH, real_capacity * sizeof(HashMapData)); } if (unlikely(num_elements > _get_resize_count(capacity))) { diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h index ef0ca33046a..6832be80487 100644 --- a/core/templates/hash_map.h +++ b/core/templates/hash_map.h @@ -169,13 +169,9 @@ private: uint32_t *old_hashes = hashes; num_elements = 0; - hashes = reinterpret_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); - elements = reinterpret_cast **>(Memory::alloc_static(sizeof(HashMapElement *) * capacity)); - - for (uint32_t i = 0; i < capacity; i++) { - hashes[i] = 0; - elements[i] = nullptr; - } + static_assert(EMPTY_HASH == 0, "Assuming EMPTY_HASH = 0 for alloc_static_zeroed call"); + hashes = reinterpret_cast(Memory::alloc_static_zeroed(sizeof(uint32_t) * capacity)); + elements = reinterpret_cast **>(Memory::alloc_static_zeroed(sizeof(HashMapElement *) * capacity)); if (old_capacity == 0) { // Nothing to do. @@ -199,13 +195,9 @@ private: if (unlikely(elements == nullptr)) { // Allocate on demand to save memory. - hashes = reinterpret_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); - elements = reinterpret_cast **>(Memory::alloc_static(sizeof(HashMapElement *) * capacity)); - - for (uint32_t i = 0; i < capacity; i++) { - hashes[i] = EMPTY_HASH; - elements[i] = nullptr; - } + static_assert(EMPTY_HASH == 0, "Assuming EMPTY_HASH = 0 for alloc_static_zeroed call"); + hashes = reinterpret_cast(Memory::alloc_static_zeroed(sizeof(uint32_t) * capacity)); + elements = reinterpret_cast **>(Memory::alloc_static_zeroed(sizeof(HashMapElement *) * capacity)); } if (num_elements + 1 > MAX_OCCUPANCY * capacity) { diff --git a/core/templates/hash_set.h b/core/templates/hash_set.h index b2982f68600..f180957dfe5 100644 --- a/core/templates/hash_set.h +++ b/core/templates/hash_set.h @@ -144,15 +144,12 @@ private: uint32_t *old_hashes = hashes; uint32_t *old_key_to_hash = key_to_hash; - hashes = reinterpret_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); + static_assert(EMPTY_HASH == 0, "Assuming EMPTY_HASH = 0 for alloc_static_zeroed call"); + hashes = reinterpret_cast(Memory::alloc_static_zeroed(sizeof(uint32_t) * capacity)); keys = reinterpret_cast(Memory::realloc_static(keys, sizeof(TKey) * capacity)); key_to_hash = reinterpret_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); hash_to_key = reinterpret_cast(Memory::realloc_static(hash_to_key, sizeof(uint32_t) * capacity)); - for (uint32_t i = 0; i < capacity; i++) { - hashes[i] = EMPTY_HASH; - } - for (uint32_t i = 0; i < num_elements; i++) { uint32_t h = old_hashes[old_key_to_hash[i]]; _insert_with_hash(h, i); @@ -167,14 +164,11 @@ private: if (unlikely(keys == nullptr)) { // Allocate on demand to save memory. - hashes = reinterpret_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); + static_assert(EMPTY_HASH == 0, "Assuming EMPTY_HASH = 0 for alloc_static_zeroed call"); + hashes = reinterpret_cast(Memory::alloc_static_zeroed(sizeof(uint32_t) * capacity)); keys = reinterpret_cast(Memory::alloc_static(sizeof(TKey) * capacity)); key_to_hash = reinterpret_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); hash_to_key = reinterpret_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); - - for (uint32_t i = 0; i < capacity; i++) { - hashes[i] = EMPTY_HASH; - } } uint32_t pos = 0; diff --git a/core/templates/oa_hash_map.h b/core/templates/oa_hash_map.h index 18487e107fa..ce6813b3f19 100644 --- a/core/templates/oa_hash_map.h +++ b/core/templates/oa_hash_map.h @@ -153,11 +153,8 @@ private: num_elements = 0; keys = static_cast(Memory::alloc_static(sizeof(TKey) * capacity)); values = static_cast(Memory::alloc_static(sizeof(TValue) * capacity)); - hashes = static_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); - - for (uint32_t i = 0; i < capacity; i++) { - hashes[i] = 0; - } + static_assert(EMPTY_HASH == 0, "Assuming EMPTY_HASH = 0 for alloc_static_zeroed call"); + hashes = static_cast(Memory::alloc_static_zeroed(sizeof(uint32_t) * capacity)); if (old_capacity == 0) { // Nothing to do. @@ -384,11 +381,8 @@ public: keys = static_cast(Memory::alloc_static(sizeof(TKey) * capacity)); values = static_cast(Memory::alloc_static(sizeof(TValue) * capacity)); - hashes = static_cast(Memory::alloc_static(sizeof(uint32_t) * capacity)); - - for (uint32_t i = 0; i < capacity; i++) { - hashes[i] = EMPTY_HASH; - } + static_assert(EMPTY_HASH == 0, "Assuming EMPTY_HASH = 0 for alloc_static_zeroed call"); + hashes = static_cast(Memory::alloc_static_zeroed(sizeof(uint32_t) * capacity)); } ~OAHashMap() { diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 794ec97a570..9b4628d8a42 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -341,8 +341,7 @@ void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_ iloglen = 4096; // buggy driver (Adreno 220+) } - char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); - memset(ilogmem, 0, iloglen + 1); + char *ilogmem = (char *)Memory::alloc_static_zeroed(iloglen + 1); glGetShaderInfoLog(spec.vert_id, iloglen, &iloglen, ilogmem); String err_string = name + ": Vertex shader compilation failed:\n"; @@ -390,8 +389,7 @@ void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_ iloglen = 4096; // buggy driver (Adreno 220+) } - char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); - memset(ilogmem, 0, iloglen + 1); + char *ilogmem = (char *)Memory::alloc_static_zeroed(iloglen + 1); glGetShaderInfoLog(spec.frag_id, iloglen, &iloglen, ilogmem); String err_string = name + ": Fragment shader compilation failed:\n";