Restore zero-initialization of memory allocations
This change replaces the single sw::allocate() with three variants that
make it explicit whether or not the memory is initialized. For now, only
sw::allocateZero() is used, to work around MemorySantizer errors that
have been encountered.
Subsequent changes will split vk::allocate() too, to discern between the
different kinds of allocations made at the Vulkan level. These will then
systematically call sw::allocateZeroOrPoison() to isolate the culprit of
MemorySanitizer errors. Eventually they should use
sw::allocateUninitialized() to improve performance.
Bug: b/140991626
Change-Id: I962c91edab474b8791b1e2acb999c7e7e9718a5e
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/57728
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Commit-Queue: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp
index a3002a5..c1c52ad 100644
--- a/src/Device/Renderer.cpp
+++ b/src/Device/Renderer.cpp
@@ -146,7 +146,9 @@
DrawCall::DrawCall()
{
- data = (DrawData *)allocate(sizeof(DrawData));
+ // TODO(b/140991626): Use allocateZeroOrPoison() instead of allocateZero() to detect MemorySanitizer errors.
+ // TODO(b/140991626): Use allocateUninitialized() instead of allocateZeroOrPoison() to improve startup peformance.
+ data = (DrawData *)allocateZero(sizeof(DrawData));
data->constants = &Constants::Get();
}
diff --git a/src/System/Memory.cpp b/src/System/Memory.cpp
index 6c0d300..0c6c52b 100644
--- a/src/System/Memory.cpp
+++ b/src/System/Memory.cpp
@@ -73,7 +73,7 @@
return pageSize;
}
-void *allocate(size_t bytes, size_t alignment)
+static void *allocate(size_t bytes, size_t alignment, bool clearToZero)
{
ASSERT((alignment & (alignment - 1)) == 0); // Power of 2 alignment.
@@ -83,8 +83,7 @@
if(block)
{
- // TODO(b/140991626): Never initialize the allocated memory.
- if(!__has_feature(memory_sanitizer))
+ if(clearToZero)
{
memset(block, 0, size);
}
@@ -99,6 +98,24 @@
return aligned;
}
+// TODO(b/140991626): Rename to allocate().
+void *allocateUninitialized(size_t bytes, size_t alignment)
+{
+ return allocate(bytes, alignment, false);
+}
+
+void *allocateZero(size_t bytes, size_t alignment)
+{
+ return allocate(bytes, alignment, true);
+}
+
+// This funtion allocates memory that is zero-initialized for security reasons
+// only. In MemorySanitizer enabled builds it is left uninitialized.
+void *allocateZeroOrPoison(size_t bytes, size_t alignment)
+{
+ return allocate(bytes, alignment, !__has_feature(memory_sanitizer));
+}
+
void deallocate(void *memory)
{
if(memory)
diff --git a/src/System/Memory.hpp b/src/System/Memory.hpp
index eff959b..53c2409 100644
--- a/src/System/Memory.hpp
+++ b/src/System/Memory.hpp
@@ -22,7 +22,10 @@
size_t memoryPageSize();
-void *allocate(size_t bytes, size_t alignment = 16);
+void *allocateUninitialized(size_t bytes, size_t alignment = 16); // Never initialized.
+void *allocateZero(size_t bytes, size_t alignment = 16); // Always initialized to zero.
+void *allocateZeroOrPoison(size_t bytes, size_t alignment = 16); // Initialized to zero, except in MemorySanitizer builds.
+
void deallocate(void *memory);
void clear(uint16_t *memory, uint16_t element, size_t count);
diff --git a/src/Vulkan/VkMemory.cpp b/src/Vulkan/VkMemory.cpp
index 3957522..3ff3b45 100644
--- a/src/Vulkan/VkMemory.cpp
+++ b/src/Vulkan/VkMemory.cpp
@@ -24,7 +24,10 @@
void *allocate(size_t count, size_t alignment, const VkAllocationCallbacks *pAllocator, VkSystemAllocationScope allocationScope)
{
- return pAllocator ? pAllocator->pfnAllocation(pAllocator->pUserData, count, alignment, allocationScope) : sw::allocate(count, alignment);
+ // TODO(b/140991626): Use allocateZeroOrPoison() instead of allocateZero() to detect MemorySanitizer errors.
+ // TODO(b/140991626): Use allocateUninitialized() instead of allocateZeroOrPoison() to improve startup peformance.
+ return pAllocator ? pAllocator->pfnAllocation(pAllocator->pUserData, count, alignment, allocationScope)
+ : sw::allocateZero(count, alignment);
}
void deallocate(void *ptr, const VkAllocationCallbacks *pAllocator)