Consistently use "rG" constraint for copy instruction in move patterns
[official-gcc.git] / libsanitizer / tsan / tsan_defs.h
blobfe0c1da31599b18bbf885d4f1a1ad8a4a4a671b4
1 //===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //===----------------------------------------------------------------------===//
13 #ifndef TSAN_DEFS_H
14 #define TSAN_DEFS_H
16 #include "sanitizer_common/sanitizer_internal_defs.h"
17 #include "sanitizer_common/sanitizer_libc.h"
18 #include "sanitizer_common/sanitizer_mutex.h"
19 #include "ubsan/ubsan_platform.h"
21 #ifndef TSAN_VECTORIZE
22 # define TSAN_VECTORIZE __SSE4_2__
23 #endif
25 #if TSAN_VECTORIZE
26 // <emmintrin.h> transitively includes <stdlib.h>,
27 // and it's prohibited to include std headers into tsan runtime.
28 // So we do this dirty trick.
29 # define _MM_MALLOC_H_INCLUDED
30 # define __MM_MALLOC_H
31 # include <emmintrin.h>
32 # include <smmintrin.h>
33 # define VECTOR_ALIGNED ALIGNED(16)
34 typedef __m128i m128;
35 #else
36 # define VECTOR_ALIGNED
37 #endif
39 // Setup defaults for compile definitions.
40 #ifndef TSAN_NO_HISTORY
41 # define TSAN_NO_HISTORY 0
42 #endif
44 #ifndef TSAN_CONTAINS_UBSAN
45 # if CAN_SANITIZE_UB && !SANITIZER_GO
46 # define TSAN_CONTAINS_UBSAN 1
47 # else
48 # define TSAN_CONTAINS_UBSAN 0
49 # endif
50 #endif
52 namespace __tsan {
54 constexpr uptr kByteBits = 8;
56 // Thread slot ID.
57 enum class Sid : u8 {};
58 constexpr uptr kThreadSlotCount = 256;
59 constexpr Sid kFreeSid = static_cast<Sid>(255);
61 // Abstract time unit, vector clock element.
62 enum class Epoch : u16 {};
63 constexpr uptr kEpochBits = 14;
64 constexpr Epoch kEpochZero = static_cast<Epoch>(0);
65 constexpr Epoch kEpochOver = static_cast<Epoch>(1 << kEpochBits);
67 const int kClkBits = 42;
68 const unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1;
70 struct ClockElem {
71 u64 epoch : kClkBits;
72 u64 reused : 64 - kClkBits; // tid reuse count
75 struct ClockBlock {
76 static const uptr kSize = 512;
77 static const uptr kTableSize = kSize / sizeof(u32);
78 static const uptr kClockCount = kSize / sizeof(ClockElem);
79 static const uptr kRefIdx = kTableSize - 1;
80 static const uptr kBlockIdx = kTableSize - 2;
82 union {
83 u32 table[kTableSize];
84 ClockElem clock[kClockCount];
87 ClockBlock() {
91 const int kTidBits = 13;
92 // Reduce kMaxTid by kClockCount because one slot in ClockBlock table is
93 // occupied by reference counter, so total number of elements we can store
94 // in SyncClock is kClockCount * (kTableSize - 1).
95 const unsigned kMaxTid = (1 << kTidBits) - ClockBlock::kClockCount;
96 #if !SANITIZER_GO
97 const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit.
98 #else
99 const unsigned kMaxTidInClock = kMaxTid; // Go does not track freed memory.
100 #endif
101 const uptr kShadowStackSize = 64 * 1024;
103 // Count of shadow values in a shadow cell.
104 const uptr kShadowCnt = 4;
106 // That many user bytes are mapped onto a single shadow cell.
107 const uptr kShadowCell = 8;
109 // Single shadow value.
110 typedef u64 RawShadow;
111 const uptr kShadowSize = sizeof(RawShadow);
113 // Shadow memory is kShadowMultiplier times larger than user memory.
114 const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
116 // That many user bytes are mapped onto a single meta shadow cell.
117 // Must be less or equal to minimal memory allocator alignment.
118 const uptr kMetaShadowCell = 8;
120 // Size of a single meta shadow value (u32).
121 const uptr kMetaShadowSize = 4;
123 // All addresses and PCs are assumed to be compressable to that many bits.
124 const uptr kCompressedAddrBits = 44;
126 #if TSAN_NO_HISTORY
127 const bool kCollectHistory = false;
128 #else
129 const bool kCollectHistory = true;
130 #endif
132 // The following "build consistency" machinery ensures that all source files
133 // are built in the same configuration. Inconsistent builds lead to
134 // hard to debug crashes.
135 #if SANITIZER_DEBUG
136 void build_consistency_debug();
137 #else
138 void build_consistency_release();
139 #endif
141 static inline void USED build_consistency() {
142 #if SANITIZER_DEBUG
143 build_consistency_debug();
144 #else
145 build_consistency_release();
146 #endif
149 template<typename T>
150 T min(T a, T b) {
151 return a < b ? a : b;
154 template<typename T>
155 T max(T a, T b) {
156 return a > b ? a : b;
159 template<typename T>
160 T RoundUp(T p, u64 align) {
161 DCHECK_EQ(align & (align - 1), 0);
162 return (T)(((u64)p + align - 1) & ~(align - 1));
165 template<typename T>
166 T RoundDown(T p, u64 align) {
167 DCHECK_EQ(align & (align - 1), 0);
168 return (T)((u64)p & ~(align - 1));
171 // Zeroizes high part, returns 'bits' lsb bits.
172 template<typename T>
173 T GetLsb(T v, int bits) {
174 return (T)((u64)v & ((1ull << bits) - 1));
177 struct MD5Hash {
178 u64 hash[2];
179 bool operator==(const MD5Hash &other) const;
182 MD5Hash md5_hash(const void *data, uptr size);
184 struct Processor;
185 struct ThreadState;
186 class ThreadContext;
187 struct Context;
188 struct ReportStack;
189 class ReportDesc;
190 class RegionAlloc;
192 typedef uptr AccessType;
194 enum : AccessType {
195 kAccessWrite = 0,
196 kAccessRead = 1 << 0,
197 kAccessAtomic = 1 << 1,
198 kAccessVptr = 1 << 2, // read or write of an object virtual table pointer
199 kAccessFree = 1 << 3, // synthetic memory access during memory freeing
200 kAccessExternalPC = 1 << 4, // access PC can have kExternalPCBit set
203 // Descriptor of user's memory block.
204 struct MBlock {
205 u64 siz : 48;
206 u64 tag : 16;
207 StackID stk;
208 Tid tid;
211 COMPILER_CHECK(sizeof(MBlock) == 16);
213 enum ExternalTag : uptr {
214 kExternalTagNone = 0,
215 kExternalTagSwiftModifyingAccess = 1,
216 kExternalTagFirstUserAvailable = 2,
217 kExternalTagMax = 1024,
218 // Don't set kExternalTagMax over 65,536, since MBlock only stores tags
219 // as 16-bit values, see tsan_defs.h.
222 enum MutexType {
223 MutexTypeTrace = MutexLastCommon,
224 MutexTypeReport,
225 MutexTypeSyncVar,
226 MutexTypeAnnotations,
227 MutexTypeAtExit,
228 MutexTypeFired,
229 MutexTypeRacy,
230 MutexTypeGlobalProc,
233 } // namespace __tsan
235 #endif // TSAN_DEFS_H