1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
8 // common.h - precompiled headers include for the COM+ Execution Engine
12 // Make sure _ASSERTE is defined before including this header file
13 // Other than that, please keep this header self-contained so that it can be included in
21 #include "specstrings.h"
25 #error Please define _ASSERTE before including StdMacros.h
29 #define DEBUG_ARG(x) , x
30 #define DEBUG_ARG1(x) x
36 #ifdef DACCESS_COMPILE
37 #define DAC_ARG(x) , x
43 /********************************************/
44 /* Portability macros */
45 /********************************************/
48 #define AMD64_FIRST_ARG(x) x ,
49 #define AMD64_ARG(x) , x
50 #define AMD64_ONLY(x) x
52 #define NOT_AMD64_ARG(x)
54 #define AMD64_FIRST_ARG(x)
57 #define NOT_AMD64(x) x
58 #define NOT_AMD64_ARG(x) , x
62 #define X86_FIRST_ARG(x) x ,
63 #define X86_ARG(x) , x
66 #define NOT_X86_ARG(x)
68 #define X86_FIRST_ARG(x)
72 #define NOT_X86_ARG(x) , x
76 #define WIN64_ARG(x) , x
77 #define WIN64_ONLY(x) x
79 #define NOT_WIN64_ARG(x)
83 #define NOT_WIN64(x) x
84 #define NOT_WIN64_ARG(x) , x
88 #define ARM_FIRST_ARG(x) x ,
89 #define ARM_ARG(x) , x
92 #define NOT_ARM_ARG(x)
94 #define ARM_FIRST_ARG(x)
98 #define NOT_ARM_ARG(x) , x
101 #ifdef _TARGET_ARM64_
102 #define ARM64_FIRST_ARG(x) x ,
103 #define ARM64_ARG(x) , x
104 #define ARM64_ONLY(x) x
106 #define NOT_ARM64_ARG(x)
108 #define ARM64_FIRST_ARG(x)
110 #define ARM64_ONLY(x)
111 #define NOT_ARM64(x) x
112 #define NOT_ARM64_ARG(x) , x
115 #ifdef _TARGET_64BIT_
116 #define LOG2_PTRSIZE 3
118 #define LOG2_PTRSIZE 2
122 #define INVALID_POINTER_CC 0xcccccccccccccccc
123 #define INVALID_POINTER_CD 0xcdcdcdcdcdcdcdcd
124 #define FMT_ADDR " %08x`%08x "
125 #define LFMT_ADDR W(" %08x`%08x ")
126 #define DBG_ADDR(ptr) (((UINT_PTR) (ptr)) >> 32), (((UINT_PTR) (ptr)) & 0xffffffff)
128 #define INVALID_POINTER_CC 0xcccccccc
129 #define INVALID_POINTER_CD 0xcdcdcdcd
130 #define FMT_ADDR " %08x "
131 #define LFMT_ADDR W(" %08x ")
132 #define DBG_ADDR(ptr) ((UINT_PTR)(ptr))
136 #define ALIGN_ACCESS ((1<<LOG2_PTRSIZE)-1)
140 #ifndef ALLOC_ALIGN_CONSTANT
141 #define ALLOC_ALIGN_CONSTANT (sizeof(void*)-1)
145 inline void *GetTopMemoryAddress(void)
149 static void *result; // = NULL;
153 GetSystemInfo( &sysInfo );
154 result = sysInfo.lpMaximumApplicationAddress;
158 inline void *GetBotMemoryAddress(void)
162 static void *result; // = NULL;
166 GetSystemInfo( &sysInfo );
167 result = sysInfo.lpMinimumApplicationAddress;
172 #define TOP_MEMORY (GetTopMemoryAddress())
173 #define BOT_MEMORY (GetBotMemoryAddress())
177 // This macro returns val rounded up as necessary to be a multiple of alignment; alignment must be a power of 2
179 inline size_t ALIGN_UP( size_t val, size_t alignment )
181 LIMITED_METHOD_DAC_CONTRACT;
183 // alignment must be a power of 2 for this implementation to work (need modulo otherwise)
184 _ASSERTE( 0 == (alignment & (alignment - 1)) );
185 size_t result = (val + (alignment - 1)) & ~(alignment - 1);
186 _ASSERTE( result >= val ); // check for overflow
189 inline void* ALIGN_UP( void* val, size_t alignment )
193 return (void*) ALIGN_UP( (size_t)val, alignment );
195 inline uint8_t* ALIGN_UP( uint8_t* val, size_t alignment )
199 return (uint8_t*) ALIGN_UP( (size_t)val, alignment );
202 inline size_t ALIGN_DOWN( size_t val, size_t alignment )
204 LIMITED_METHOD_CONTRACT;
206 // alignment must be a power of 2 for this implementation to work (need modulo otherwise)
207 _ASSERTE( 0 == (alignment & (alignment - 1)) );
208 size_t result = val & ~(alignment - 1);
211 inline void* ALIGN_DOWN( void* val, size_t alignment )
214 return (void*) ALIGN_DOWN( (size_t)val, alignment );
216 inline uint8_t* ALIGN_DOWN( uint8_t* val, size_t alignment )
219 return (uint8_t*) ALIGN_DOWN( (size_t)val, alignment );
222 inline BOOL IS_ALIGNED( size_t val, size_t alignment )
224 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 return 0 == (val & (alignment - 1));
231 inline BOOL IS_ALIGNED( const void* val, size_t alignment )
234 return IS_ALIGNED( (size_t) val, alignment );
237 // Rounds a ULONG up to the nearest power of two number.
238 inline ULONG RoundUpToPower2(ULONG x)
240 if (x == 0) return 1;
253 // NOTE: pSrc is evaluated three times!!!
254 #define MAYBE_UNALIGNED_READ(pSrc, bits) (IS_ALIGNED((size_t)(pSrc), sizeof(UINT##bits)) ? \
255 (*(UINT##bits*) (pSrc)) : \
256 (GET_UNALIGNED_##bits(pSrc)) )
258 #define MAYBE_UNALIGNED_WRITE(pDst, bits, expr) do { if (IS_ALIGNED((size_t)(pDst), sizeof(UINT##bits))) \
259 *(UINT##bits*)(pDst) = (UINT##bits)(expr); else \
260 SET_UNALIGNED_##bits(pDst, (UINT##bits)(expr)); } while (0)
262 // these are necessary for MAYBE_UNALIGNED_XXX to work with UINT_PTR
263 #define GET_UNALIGNED__PTR(x) GET_UNALIGNED_PTR(x)
264 #define SET_UNALIGNED__PTR(p,x) SET_UNALIGNED_PTR(p,x)
266 #else // ALIGN_ACCESS
267 #define MAYBE_UNALIGNED_READ(pSrc, bits) (*(UINT##bits*)(pSrc))
268 #define MAYBE_UNALIGNED_WRITE(pDst, bits, expr) do { *(UINT##bits*)(pDst) = (UINT##bits)(expr); } while(0)
269 #endif // ALIGN_ACCESS
272 // define some useful macros for logging object
275 #define FMT_OBJECT "object" FMT_ADDR
276 #define FMT_HANDLE "handle" FMT_ADDR
277 #define FMT_CLASS "%s"
278 #define FMT_REG "r%d "
279 #define FMT_STK "sp%s0x%02x "
280 #define FMT_PIPTR "%s%s pointer "
283 #define DBG_GET_CLASS_NAME(pMT) \
284 (((pMT) == NULL) ? NULL : (pMT)->GetClass()->GetDebugClassName())
286 #define DBG_CLASS_NAME_MT(pMT) \
287 (DBG_GET_CLASS_NAME(pMT) == NULL) ? "<null-class>" : DBG_GET_CLASS_NAME(pMT)
289 #define DBG_GET_MT_FROM_OBJ(obj) \
290 (MethodTable*)((size_t)((Object*) (obj))->GetGCSafeMethodTable())
292 #define DBG_CLASS_NAME_OBJ(obj) \
293 ((obj) == NULL) ? "null" : DBG_CLASS_NAME_MT(DBG_GET_MT_FROM_OBJ(obj))
295 #define DBG_CLASS_NAME_IPTR2(obj,iptr) \
296 ((iptr) != 0) ? "" : DBG_CLASS_NAME_MT(DBG_GET_MT_FROM_OBJ(obj))
298 #define DBG_CLASS_NAME_IPTR(obj,iptr) \
299 ((obj) == NULL) ? "null" : DBG_CLASS_NAME_IPTR2(obj,iptr)
301 #define DBG_STK(off) \
302 (off >= 0) ? "+" : "-", \
303 (off >= 0) ? off : -off
305 #define DBG_PIN_NAME(pin) \
306 (pin) ? "pinned " : ""
308 #define DBG_IPTR_NAME(iptr) \
309 (iptr) ? "interior" : "base"
311 #define LOG_HANDLE_OBJECT_CLASS(str1, hnd, str2, obj) \
312 str1 FMT_HANDLE str2 FMT_OBJECT FMT_CLASS "\n", \
313 DBG_ADDR(hnd), DBG_ADDR(obj), DBG_CLASS_NAME_OBJ(obj)
315 #define LOG_OBJECT_CLASS(obj) \
316 FMT_OBJECT FMT_CLASS "\n", \
317 DBG_ADDR(obj), DBG_CLASS_NAME_OBJ(obj)
319 #define LOG_PIPTR_OBJECT_CLASS(obj, pin, iptr) \
320 FMT_PIPTR FMT_ADDR FMT_CLASS "\n", \
321 DBG_PIN_NAME(pin), DBG_IPTR_NAME(iptr), \
322 DBG_ADDR(obj), DBG_CLASS_NAME_IPTR(obj,iptr)
324 #define LOG_HANDLE_OBJECT(str1, hnd, str2, obj) \
325 str1 FMT_HANDLE str2 FMT_OBJECT "\n", \
326 DBG_ADDR(hnd), DBG_ADDR(obj)
328 #define LOG_PIPTR_OBJECT(obj, pin, iptr) \
329 FMT_PIPTR FMT_ADDR "\n", \
330 DBG_PIN_NAME(pin), DBG_IPTR_NAME(iptr), \
333 #define UNIQUE_LABEL_DEF(a,x) a##x
334 #define UNIQUE_LABEL_DEF_X(a,x) UNIQUE_LABEL_DEF(a,x)
336 #define UNIQUE_LABEL(a) UNIQUE_LABEL_DEF_X(_unique_label_##a##_, __COUNTER__)
338 #define UNIQUE_LABEL(a) UNIQUE_LABEL_DEF_X(_unique_label_##a##_, __LINE__)
343 #define _countof(_array) (sizeof(_array)/sizeof(_array[0]))
347 // This is temporary. LKG should provide these macros and we should then
348 // remove STRUNCATE and _TRUNCATE from here.
351 #if !defined(STRUNCATE)
356 #if !defined(_TRUNCATE)
357 #define _TRUNCATE ((size_t)-1)
360 #endif //_stdmacros_h_