Commit eea9d35b by Ben Clayton Committed by Nicolas Capens

Device/Renderer: Work arounds for MemorySanitizer false-positives

MemorySanitizer has no visibility into writes performed by JIT'd code. If we have built the project with the MemorySanitizer enabled, memset the Triangle and Primitive structs so the sanitizer has a write to see. This is only cleared in MemorySanitizer enabled builds, as this adds a non negligable cost to Renderer construction. Bug: chromium:998457 Change-Id: I3b4f9e48783c6e8a1109a578988567b0a42eb1f9 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/35688 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 88289191
...@@ -1724,6 +1724,7 @@ file(GLOB_RECURSE VULKAN_LIST ...@@ -1724,6 +1724,7 @@ file(GLOB_RECURSE VULKAN_LIST
${VULKAN_DIR}/*.cpp ${VULKAN_DIR}/*.cpp
${VULKAN_DIR}/*.h ${VULKAN_DIR}/*.h
${VULKAN_DIR}/*.hpp ${VULKAN_DIR}/*.hpp
${SOURCE_DIR}/System/Build.hpp
${SOURCE_DIR}/System/CPUID.cpp ${SOURCE_DIR}/System/CPUID.cpp
${SOURCE_DIR}/System/CPUID.hpp ${SOURCE_DIR}/System/CPUID.hpp
${SOURCE_DIR}/System/Configurator.cpp ${SOURCE_DIR}/System/Configurator.cpp
......
...@@ -166,6 +166,7 @@ ...@@ -166,6 +166,7 @@
<ClInclude Include="$(SolutionDir)src\Renderer\LRUCache.hpp" /> <ClInclude Include="$(SolutionDir)src\Renderer\LRUCache.hpp" />
<ClCompile Include="$(SolutionDir)src\Renderer\Matrix.cpp" /> <ClCompile Include="$(SolutionDir)src\Renderer\Matrix.cpp" />
<ClInclude Include="$(SolutionDir)src\Renderer\Matrix.hpp" /> <ClInclude Include="$(SolutionDir)src\Renderer\Matrix.hpp" />
<ClInclude Include="$(SolutionDir)src\Renderer\Memset.hpp" />
<ClCompile Include="$(SolutionDir)src\Renderer\PixelProcessor.cpp" /> <ClCompile Include="$(SolutionDir)src\Renderer\PixelProcessor.cpp" />
<ClInclude Include="$(SolutionDir)src\Renderer\PixelProcessor.hpp" /> <ClInclude Include="$(SolutionDir)src\Renderer\PixelProcessor.hpp" />
<ClCompile Include="$(SolutionDir)src\Renderer\Plane.cpp" /> <ClCompile Include="$(SolutionDir)src\Renderer\Plane.cpp" />
......
...@@ -204,6 +204,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command> ...@@ -204,6 +204,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
<ClInclude Include="$(SolutionDir)src\Device\LRUCache.hpp" /> <ClInclude Include="$(SolutionDir)src\Device\LRUCache.hpp" />
<ClCompile Include="$(SolutionDir)src\Device\Matrix.cpp" /> <ClCompile Include="$(SolutionDir)src\Device\Matrix.cpp" />
<ClInclude Include="$(SolutionDir)src\Device\Matrix.hpp" /> <ClInclude Include="$(SolutionDir)src\Device\Matrix.hpp" />
<ClInclude Include="$(SolutionDir)src\Device\Memset.hpp" />
<ClCompile Include="$(SolutionDir)src\Device\PixelProcessor.cpp" /> <ClCompile Include="$(SolutionDir)src\Device\PixelProcessor.cpp" />
<ClInclude Include="$(SolutionDir)src\Device\PixelProcessor.hpp" /> <ClInclude Include="$(SolutionDir)src\Device\PixelProcessor.hpp" />
<ClCompile Include="$(SolutionDir)src\Device\Plane.cpp" /> <ClCompile Include="$(SolutionDir)src\Device\Plane.cpp" />
...@@ -253,6 +254,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command> ...@@ -253,6 +254,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
<ClInclude Include="$(SolutionDir)src\Pipeline\VertexRoutine.hpp" /> <ClInclude Include="$(SolutionDir)src\Pipeline\VertexRoutine.hpp" />
<ClCompile Include="$(SolutionDir)src\System\CPUID.cpp" /> <ClCompile Include="$(SolutionDir)src\System\CPUID.cpp" />
<ClInclude Include="$(SolutionDir)src\System\CPUID.hpp" /> <ClInclude Include="$(SolutionDir)src\System\CPUID.hpp" />
<ClInclude Include="$(SolutionDir)src\System\Build.hpp" />
<ClCompile Include="$(SolutionDir)src\System\Configurator.cpp" /> <ClCompile Include="$(SolutionDir)src\System\Configurator.cpp" />
<ClInclude Include="$(SolutionDir)src\System\Configurator.hpp" /> <ClInclude Include="$(SolutionDir)src\System\Configurator.hpp" />
<ClCompile Include="$(SolutionDir)src\System\Debug.cpp" /> <ClCompile Include="$(SolutionDir)src\System\Debug.cpp" />
......
...@@ -225,6 +225,9 @@ ...@@ -225,6 +225,9 @@
<ClInclude Include="$(SolutionDir)src\Device\Matrix.hpp"> <ClInclude Include="$(SolutionDir)src\Device\Matrix.hpp">
<Filter>src\Device</Filter> <Filter>src\Device</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)src\Device\Memset.hpp">
<Filter>src\Device</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)src\Device\PixelProcessor.hpp"> <ClInclude Include="$(SolutionDir)src\Device\PixelProcessor.hpp">
<Filter>src\Device</Filter> <Filter>src\Device</Filter>
</ClInclude> </ClInclude>
...@@ -306,6 +309,9 @@ ...@@ -306,6 +309,9 @@
<ClInclude Include="$(SolutionDir)src\Pipeline\VertexRoutine.hpp"> <ClInclude Include="$(SolutionDir)src\Pipeline\VertexRoutine.hpp">
<Filter>src\Pipeline</Filter> <Filter>src\Pipeline</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)src\System\Build.hpp">
<Filter>src\System</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)src\System\CPUID.hpp"> <ClInclude Include="$(SolutionDir)src\System\CPUID.hpp">
<Filter>src\System</Filter> <Filter>src\System</Filter>
</ClInclude> </ClInclude>
......
...@@ -30,6 +30,7 @@ swiftshader_source_set("Device") { ...@@ -30,6 +30,7 @@ swiftshader_source_set("Device") {
"ETC_Decoder.hpp", "ETC_Decoder.hpp",
"Matrix.cpp", "Matrix.cpp",
"Matrix.hpp", "Matrix.hpp",
"Memset.hpp",
"PixelProcessor.cpp", "PixelProcessor.cpp",
"PixelProcessor.hpp", "PixelProcessor.hpp",
"Plane.cpp", "Plane.cpp",
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#ifndef sw_Blitter_hpp #ifndef sw_Blitter_hpp
#define sw_Blitter_hpp #define sw_Blitter_hpp
#include "Memset.hpp"
#include "RoutineCache.hpp" #include "RoutineCache.hpp"
#include "Reactor/Reactor.hpp" #include "Reactor/Reactor.hpp"
#include "Vulkan/VkFormat.h" #include "Vulkan/VkFormat.h"
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "System/Math.hpp" #include "System/Math.hpp"
#include <cstring>
#include <type_traits> #include <type_traits>
#include <unordered_map> #include <unordered_map>
...@@ -71,32 +70,6 @@ namespace sw ...@@ -71,32 +70,6 @@ namespace sw
std::unordered_map<Key, Data, Hasher> constCache; std::unordered_map<Key, Data, Hasher> constCache;
}; };
// Helper class for clearing the memory of objects at construction.
// Useful as the first base class of cache keys which may contain padding bytes or bits otherwise left uninitialized.
template<class T>
struct Memset
{
Memset(T *object, int val)
{
static_assert(std::is_base_of<Memset<T>, T>::value, "Memset<T> must only clear the memory of a type of which it is a base class");
// GCC 8+ warns that
// "‘void* memset(void*, int, size_t)’ clearing an object of non-trivial type ‘T’;
// use assignment or value-initialization instead [-Werror=class-memaccess]"
// This is benign iff it happens before any of the base or member constructrs are called.
#if defined(__GNUC__) && (__GNUC__ >= 8)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif
memset(object, 0, sizeof(T));
#if defined(__GNUC__) && (__GNUC__ >= 8)
#pragma GCC diagnostic pop
#endif
}
};
// Traits-like helper class for checking if objects can be compared using memcmp(). // Traits-like helper class for checking if objects can be compared using memcmp().
// Useful for statically asserting if a cache key can implement operator==() with memcmp(). // Useful for statically asserting if a cache key can implement operator==() with memcmp().
template<typename T> template<typename T>
......
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Memset_hpp
#define sw_Memset_hpp
#include <cstring>
#include <type_traits>
namespace sw
{
// Helper class for clearing the memory of objects at construction.
// Useful as the first base class of cache keys which may contain padding
// bytes or bits otherwise left uninitialized.
template<class T>
struct Memset
{
Memset(T *object, int val)
{
static_assert(std::is_base_of<Memset<T>, T>::value, "Memset<T> must only clear the memory of a type of which it is a base class");
// GCC 8+ warns that
// "‘void* memset(void*, int, size_t)’ clearing an object of non-trivial type ‘T’;
// use assignment or value-initialization instead [-Werror=class-memaccess]"
// This is benign iff it happens before any of the base or member constructrs are called.
#if defined(__GNUC__) && (__GNUC__ >= 8)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif
memset(object, 0, sizeof(T));
#if defined(__GNUC__) && (__GNUC__ >= 8)
#pragma GCC diagnostic pop
#endif
}
};
}
#endif // sw_Memset_hpp
\ No newline at end of file
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "Color.hpp" #include "Color.hpp"
#include "Context.hpp" #include "Context.hpp"
#include "Memset.hpp"
#include "RoutineCache.hpp" #include "RoutineCache.hpp"
namespace sw namespace sw
......
...@@ -15,13 +15,22 @@ ...@@ -15,13 +15,22 @@
#ifndef sw_Primitive_hpp #ifndef sw_Primitive_hpp
#define sw_Primitive_hpp #define sw_Primitive_hpp
#include "Memset.hpp"
#include "Vertex.hpp" #include "Vertex.hpp"
#include "Device/Config.hpp" #include "Device/Config.hpp"
#include "System/Build.hpp"
namespace sw namespace sw
{ {
struct Triangle struct Triangle MEMORY_SANITIZER_ONLY(: Memset<Triangle>)
{ {
#if MEMORY_SANITIZER_ENABLED
// Memory sanitizer cannot 'see' writes from JIT'd code, and can raise
// false-positives when read. By clearing the struct in the constructor,
// we can avoid triggering these false-positives.
inline Triangle() : Memset<Triangle>(this, 0) {}
#endif // MEMORY_SANITIZER_ENABLED
Vertex v0; Vertex v0;
Vertex v1; Vertex v1;
Vertex v2; Vertex v2;
...@@ -34,8 +43,15 @@ namespace sw ...@@ -34,8 +43,15 @@ namespace sw
float4 C; float4 C;
}; };
struct Primitive struct Primitive MEMORY_SANITIZER_ONLY(: Memset<Primitive>)
{ {
#if MEMORY_SANITIZER_ENABLED
// Memory sanitizer cannot 'see' writes from JIT'd code, and can raise
// false-positives when read. By clearing the struct in the constructor,
// we can avoid triggering these false-positives.
inline Primitive() : Memset<Primitive>(this, 0) {}
#endif // MEMORY_SANITIZER_ENABLED
int yMin; int yMin;
int yMax; int yMax;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <Pipeline/SpirvShader.hpp> #include <Pipeline/SpirvShader.hpp>
#include "Context.hpp" #include "Context.hpp"
#include "Memset.hpp"
#include "RoutineCache.hpp" #include "RoutineCache.hpp"
#include "System/Types.hpp" #include "System/Types.hpp"
......
...@@ -15,8 +15,9 @@ ...@@ -15,8 +15,9 @@
#ifndef sw_VertexProcessor_hpp #ifndef sw_VertexProcessor_hpp
#define sw_VertexProcessor_hpp #define sw_VertexProcessor_hpp
#include "Matrix.hpp"
#include "Context.hpp" #include "Context.hpp"
#include "Matrix.hpp"
#include "Memset.hpp"
#include "RoutineCache.hpp" #include "RoutineCache.hpp"
#include "Vertex.hpp" #include "Vertex.hpp"
#include "Pipeline/SpirvShader.hpp" #include "Pipeline/SpirvShader.hpp"
......
...@@ -429,6 +429,7 @@ ...@@ -429,6 +429,7 @@
<ClInclude Include="..\Renderer\Context.hpp" /> <ClInclude Include="..\Renderer\Context.hpp" />
<ClInclude Include="..\Renderer\LRUCache.hpp" /> <ClInclude Include="..\Renderer\LRUCache.hpp" />
<ClInclude Include="..\Renderer\Matrix.hpp" /> <ClInclude Include="..\Renderer\Matrix.hpp" />
<ClInclude Include="..\Renderer\Memset.hpp" />
<ClInclude Include="..\Renderer\PixelProcessor.hpp" /> <ClInclude Include="..\Renderer\PixelProcessor.hpp" />
<ClInclude Include="..\Renderer\Plane.hpp" /> <ClInclude Include="..\Renderer\Plane.hpp" />
<ClInclude Include="..\Renderer\Point.hpp" /> <ClInclude Include="..\Renderer\Point.hpp" />
......
...@@ -229,6 +229,9 @@ ...@@ -229,6 +229,9 @@
<ClInclude Include="..\Renderer\Matrix.hpp"> <ClInclude Include="..\Renderer\Matrix.hpp">
<Filter>Header Files\Renderer</Filter> <Filter>Header Files\Renderer</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Renderer\Memset.hpp">
<Filter>Header Files\Renderer</Filter>
</ClInclude>
<ClInclude Include="..\Renderer\PixelProcessor.hpp"> <ClInclude Include="..\Renderer\PixelProcessor.hpp">
<Filter>Header Files\Renderer</Filter> <Filter>Header Files\Renderer</Filter>
</ClInclude> </ClInclude>
......
...@@ -16,6 +16,7 @@ import("../swiftshader.gni") ...@@ -16,6 +16,7 @@ import("../swiftshader.gni")
swiftshader_source_set("System") { swiftshader_source_set("System") {
sources = [ sources = [
"Build.hpp",
"CPUID.cpp", "CPUID.cpp",
"CPUID.hpp", "CPUID.hpp",
"Configurator.cpp", "Configurator.cpp",
......
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef Build_hpp
#define Build_hpp
// Define MEMORY_SANITIZER_ENABLED to 1 if the project was build with the memory
// sanitizer enabled (-fsanitize=memory).
#if defined(__SANITIZE_MEMORY__)
#define MEMORY_SANITIZER_ENABLED 1
#else // defined(__SANITIZE_MEMORY__)
#if defined(__clang__)
#if __has_feature(memory_sanitizer)
#define MEMORY_SANITIZER_ENABLED 1
#endif // __has_feature(memory_sanitizer)
#endif // defined(__clang__)
#endif // defined(__SANITIZE_MEMORY__)
// MEMORY_SANITIZER_ONLY(X) resolves to X if MEMORY_SANITIZER_ENABLED is defined
// to a non-zero value, otherwise MEMORY_SANITIZER_ONLY() is stripped by the
// preprocessor.
#if MEMORY_SANITIZER_ENABLED
#define MEMORY_SANITIZER_ONLY(x) x
#else
#define MEMORY_SANITIZER_ONLY(x)
#endif // MEMORY_SANITIZER_ENABLED
#endif // Build_hpp
...@@ -236,6 +236,7 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\Release" ...@@ -236,6 +236,7 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\Release"
<ClInclude Include="..\Device\ETC_Decoder.hpp" /> <ClInclude Include="..\Device\ETC_Decoder.hpp" />
<ClInclude Include="..\Device\LRUCache.hpp" /> <ClInclude Include="..\Device\LRUCache.hpp" />
<ClInclude Include="..\Device\Matrix.hpp" /> <ClInclude Include="..\Device\Matrix.hpp" />
<ClInclude Include="..\Device\Memset.hpp" />
<ClInclude Include="..\Device\PixelProcessor.hpp" /> <ClInclude Include="..\Device\PixelProcessor.hpp" />
<ClInclude Include="..\Device\Plane.hpp" /> <ClInclude Include="..\Device\Plane.hpp" />
<ClInclude Include="..\Device\Point.hpp" /> <ClInclude Include="..\Device\Point.hpp" />
...@@ -263,6 +264,7 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\Release" ...@@ -263,6 +264,7 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\Release"
<ClInclude Include="..\Pipeline\VertexPipeline.hpp" /> <ClInclude Include="..\Pipeline\VertexPipeline.hpp" />
<ClInclude Include="..\Pipeline\VertexProgram.hpp" /> <ClInclude Include="..\Pipeline\VertexProgram.hpp" />
<ClInclude Include="..\Pipeline\VertexRoutine.hpp" /> <ClInclude Include="..\Pipeline\VertexRoutine.hpp" />
<ClInclude Include="..\System\Build.hpp" />
<ClInclude Include="..\System\Configurator.hpp" /> <ClInclude Include="..\System\Configurator.hpp" />
<ClInclude Include="..\System\CPUID.hpp" /> <ClInclude Include="..\System\CPUID.hpp" />
<ClInclude Include="..\System\Debug.hpp" /> <ClInclude Include="..\System\Debug.hpp" />
......
...@@ -395,6 +395,9 @@ ...@@ -395,6 +395,9 @@
<ClInclude Include="..\Device\Plane.hpp"> <ClInclude Include="..\Device\Plane.hpp">
<Filter>Header Files\Device</Filter> <Filter>Header Files\Device</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Device\Memset.hpp">
<Filter>Header Files\Device</Filter>
</ClInclude>
<ClInclude Include="..\Device\PixelProcessor.hpp"> <ClInclude Include="..\Device\PixelProcessor.hpp">
<Filter>Header Files\Device</Filter> <Filter>Header Files\Device</Filter>
</ClInclude> </ClInclude>
...@@ -452,6 +455,9 @@ ...@@ -452,6 +455,9 @@
<ClInclude Include="..\Pipeline\PixelProgram.hpp"> <ClInclude Include="..\Pipeline\PixelProgram.hpp">
<Filter>Header Files\Pipeline</Filter> <Filter>Header Files\Pipeline</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\System\Build.hpp">
<Filter>Header Files\System</Filter>
</ClInclude>
<ClInclude Include="..\Pipeline\ComputeProgram.hpp"> <ClInclude Include="..\Pipeline\ComputeProgram.hpp">
<Filter>Header Files\Pipeline</Filter> <Filter>Header Files\Pipeline</Filter>
</ClInclude> </ClInclude>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment