1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
7 // common.h - precompiled headers include for the COM+ Execution Engine
11 // Make sure _ASSERTE is defined before including this header file
12 // Other than that, please keep this header self-contained so that it can be included in
20 #include "specstrings.h"
24 #error Please define _ASSERTE before including StdMacros.h
28 #define DEBUG_ARG(x) , x
29 #define DEBUG_ARG1(x) x
35 #ifdef DACCESS_COMPILE
36 #define DAC_ARG(x) , x
42 /********************************************/
43 /* Portability macros */
44 /********************************************/
47 #define AMD64_FIRST_ARG(x) x ,
48 #define AMD64_ARG(x) , x
49 #define AMD64_ONLY(x) x
51 #define NOT_AMD64_ARG(x)
53 #define AMD64_FIRST_ARG(x)
56 #define NOT_AMD64(x) x
57 #define NOT_AMD64_ARG(x) , x
61 #define X86_FIRST_ARG(x) x ,
62 #define X86_ARG(x) , x
65 #define NOT_X86_ARG(x)
67 #define X86_FIRST_ARG(x)
71 #define NOT_X86_ARG(x) , x
75 #define BIT64_ARG(x) , x
76 #define BIT64_ONLY(x) x
78 #define NOT_BIT64_ARG(x)
82 #define NOT_BIT64(x) x
83 #define NOT_BIT64_ARG(x) , x
87 #define ARM_FIRST_ARG(x) x ,
88 #define ARM_ARG(x) , x
91 #define NOT_ARM_ARG(x)
93 #define ARM_FIRST_ARG(x)
97 #define NOT_ARM_ARG(x) , x
101 #define ARM64_FIRST_ARG(x) x ,
102 #define ARM64_ARG(x) , x
103 #define ARM64_ONLY(x) x
105 #define NOT_ARM64_ARG(x)
107 #define ARM64_FIRST_ARG(x)
109 #define ARM64_ONLY(x)
110 #define NOT_ARM64(x) x
111 #define NOT_ARM64_ARG(x) , x
114 #ifdef TARGET_LOONGARCH64
115 #define LOONGARCH64_FIRST_ARG(x) x ,
116 #define LOONGARCH64_ARG(x) , x
117 #define LOONGARCH64_ONLY(x) x
118 #define NOT_LOONGARCH64(x)
119 #define NOT_LOONGARCH64_ARG(x)
121 #define LOONGARCH64_FIRST_ARG(x)
122 #define LOONGARCH64_ARG(x)
123 #define LOONGARCH64_ONLY(x)
124 #define NOT_LOONGARCH64(x) x
125 #define NOT_LOONGARCH64_ARG(x) , x
128 #ifdef TARGET_RISCV64
129 #define RISCV64_FIRST_ARG(x) x ,
130 #define RISCV64_ARG(x) , x
131 #define RISCV64_ONLY(x) x
132 #define NOT_RISCV64(x)
133 #define NOT_RISCV64_ARG(x)
135 #define RISCV64_FIRST_ARG(x)
136 #define RISCV64_ARG(x)
137 #define RISCV64_ONLY(x)
138 #define NOT_RISCV64(x) x
139 #define NOT_RISCV64_ARG(x) , x
143 #define LOG2_PTRSIZE 3
145 #define LOG2_PTRSIZE 2
149 #define INVALID_POINTER_CC 0xcccccccccccccccc
150 #define INVALID_POINTER_CD 0xcdcdcdcdcdcdcdcd
151 #define FMT_ADDR " %08x`%08x "
152 #define LFMT_ADDR W(" %08x`%08x ")
153 #define DBG_ADDR(ptr) (DWORD)(((UINT_PTR) (ptr)) >> 32), (DWORD)(((UINT_PTR) (ptr)) & 0xffffffff)
155 #define INVALID_POINTER_CC 0xcccccccc
156 #define INVALID_POINTER_CD 0xcdcdcdcd
157 #define FMT_ADDR " %08x "
158 #define LFMT_ADDR W(" %08x ")
159 #define DBG_ADDR(ptr) (DWORD)((UINT_PTR)(ptr))
163 #define ALIGN_ACCESS ((1<<LOG2_PTRSIZE)-1)
167 #ifndef ALLOC_ALIGN_CONSTANT
168 #define ALLOC_ALIGN_CONSTANT (sizeof(void*)-1)
172 inline void *GetTopMemoryAddress(void)
176 static void *result; // = NULL;
180 GetSystemInfo( &sysInfo );
181 result = sysInfo.lpMaximumApplicationAddress;
185 inline void *GetBotMemoryAddress(void)
189 static void *result; // = NULL;
193 GetSystemInfo( &sysInfo );
194 result = sysInfo.lpMinimumApplicationAddress;
199 #define TOP_MEMORY (GetTopMemoryAddress())
200 #define BOT_MEMORY (GetBotMemoryAddress())
204 // This macro returns val rounded up as necessary to be a multiple of alignment; alignment must be a power of 2
206 inline size_t ALIGN_UP( size_t val, size_t alignment )
208 LIMITED_METHOD_DAC_CONTRACT;
210 // alignment must be a power of 2 for this implementation to work (need modulo otherwise)
211 _ASSERTE( 0 == (alignment & (alignment - 1)) );
212 size_t result = (val + (alignment - 1)) & ~(alignment - 1);
213 _ASSERTE( result >= val ); // check for overflow
217 template <typename T> inline T ALIGN_UP(T val, size_t alignment)
220 return (T)ALIGN_UP((size_t)val, alignment);
223 inline size_t ALIGN_DOWN( size_t val, size_t alignment )
225 LIMITED_METHOD_CONTRACT;
227 // alignment must be a power of 2 for this implementation to work (need modulo otherwise)
228 _ASSERTE( 0 == (alignment & (alignment - 1)) );
229 size_t result = val & ~(alignment - 1);
232 inline void* ALIGN_DOWN( void* val, size_t alignment )
235 return (void*) ALIGN_DOWN( (size_t)val, alignment );
237 inline uint8_t* ALIGN_DOWN( uint8_t* val, size_t alignment )
240 return (uint8_t*) ALIGN_DOWN( (size_t)val, alignment );
243 inline BOOL IS_ALIGNED( size_t val, size_t alignment )
245 LIMITED_METHOD_CONTRACT;
248 // alignment must be a power of 2 for this implementation to work (need modulo otherwise)
249 _ASSERTE( 0 == (alignment & (alignment - 1)) );
250 return 0 == (val & (alignment - 1));
252 inline BOOL IS_ALIGNED( const void* val, size_t alignment )
255 return IS_ALIGNED( (size_t) val, alignment );
258 // Rounds a ULONG up to the nearest power of two number.
259 inline ULONG RoundUpToPower2(ULONG x)
261 if (x == 0) return 1;
274 // NOTE: pSrc is evaluated three times!!!
275 #define MAYBE_UNALIGNED_READ(pSrc, bits) (IS_ALIGNED((size_t)(pSrc), sizeof(UINT##bits)) ? \
276 (*(UINT##bits*) (pSrc)) : \
277 (GET_UNALIGNED_##bits(pSrc)) )
279 #define MAYBE_UNALIGNED_WRITE(pDst, bits, expr) do { if (IS_ALIGNED((size_t)(pDst), sizeof(UINT##bits))) \
280 *(UINT##bits*)(pDst) = (UINT##bits)(expr); else \
281 SET_UNALIGNED_##bits(pDst, (UINT##bits)(expr)); } while (0)
283 // these are necessary for MAYBE_UNALIGNED_XXX to work with UINT_PTR
284 #define GET_UNALIGNED__PTR(x) GET_UNALIGNED_PTR(x)
285 #define SET_UNALIGNED__PTR(p,x) SET_UNALIGNED_PTR(p,x)
287 #else // ALIGN_ACCESS
288 #define MAYBE_UNALIGNED_READ(pSrc, bits) (*(UINT##bits*)(pSrc))
289 #define MAYBE_UNALIGNED_WRITE(pDst, bits, expr) do { *(UINT##bits*)(pDst) = (UINT##bits)(expr); } while(0)
290 #endif // ALIGN_ACCESS
293 // define some useful macros for logging object
296 #define FMT_OBJECT "object" FMT_ADDR
297 #define FMT_HANDLE "handle" FMT_ADDR
298 #define FMT_CLASS "%s"
299 #define FMT_REG "r%d "
300 #define FMT_STK "sp%s0x%02x "
301 #define FMT_PIPTR "%s%s pointer "
304 #define DBG_GET_CLASS_NAME(pMT) \
305 (((pMT) == NULL) ? NULL : (pMT)->GetClass()->GetDebugClassName())
307 #define DBG_CLASS_NAME_MT(pMT) \
308 (DBG_GET_CLASS_NAME(pMT) == NULL) ? "<null-class>" : DBG_GET_CLASS_NAME(pMT)
310 #define DBG_GET_MT_FROM_OBJ(obj) \
311 (MethodTable*)((size_t)((Object*) (obj))->GetGCSafeMethodTable())
313 #define DBG_CLASS_NAME_OBJ(obj) \
314 ((obj) == NULL) ? "null" : DBG_CLASS_NAME_MT(DBG_GET_MT_FROM_OBJ(obj))
316 #define DBG_CLASS_NAME_IPTR2(obj,iptr) \
317 ((iptr) != 0) ? "" : DBG_CLASS_NAME_MT(DBG_GET_MT_FROM_OBJ(obj))
319 #define DBG_CLASS_NAME_IPTR(obj,iptr) \
320 ((obj) == NULL) ? "null" : DBG_CLASS_NAME_IPTR2(obj,iptr)
322 #define DBG_STK(off) \
323 (off >= 0) ? "+" : "-", \
324 (off >= 0) ? off : -off
326 #define DBG_PIN_NAME(pin) \
327 (pin) ? "pinned " : ""
329 #define DBG_IPTR_NAME(iptr) \
330 (iptr) ? "interior" : "base"
332 #define LOG_HANDLE_OBJECT_CLASS(str1, hnd, str2, obj) \
333 str1 FMT_HANDLE str2 FMT_OBJECT FMT_CLASS "\n", \
334 DBG_ADDR(hnd), DBG_ADDR(obj), DBG_CLASS_NAME_OBJ(obj)
336 #define LOG_OBJECT_CLASS(obj) \
337 FMT_OBJECT FMT_CLASS "\n", \
338 DBG_ADDR(obj), DBG_CLASS_NAME_OBJ(obj)
340 #define LOG_PIPTR_OBJECT_CLASS(obj, pin, iptr) \
341 FMT_PIPTR FMT_ADDR FMT_CLASS "\n", \
342 DBG_PIN_NAME(pin), DBG_IPTR_NAME(iptr), \
343 DBG_ADDR(obj), DBG_CLASS_NAME_IPTR(obj,iptr)
345 #define LOG_HANDLE_OBJECT(str1, hnd, str2, obj) \
346 str1 FMT_HANDLE str2 FMT_OBJECT "\n", \
347 DBG_ADDR(hnd), DBG_ADDR(obj)
349 #define LOG_PIPTR_OBJECT(obj, pin, iptr) \
350 FMT_PIPTR FMT_ADDR "\n", \
351 DBG_PIN_NAME(pin), DBG_IPTR_NAME(iptr), \
354 #define UNIQUE_LABEL_DEF(a,x) a##x
355 #define UNIQUE_LABEL_DEF_X(a,x) UNIQUE_LABEL_DEF(a,x)
357 #define UNIQUE_LABEL(a) UNIQUE_LABEL_DEF_X(_unique_label_##a##_, __COUNTER__)
359 #define UNIQUE_LABEL(a) UNIQUE_LABEL_DEF_X(_unique_label_##a##_, __LINE__)
362 // This is temporary. LKG should provide these macros and we should then
363 // remove STRUNCATE and _TRUNCATE from here.
366 #if !defined(STRUNCATE)
371 #if !defined(_TRUNCATE)
372 #define _TRUNCATE ((size_t)-1)
375 #endif //_stdmacros_h_