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)