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.
5 /*****************************************************************************/
8 /*****************************************************************************/
11 // clr.sln only defines _DEBUG
12 // The jit uses DEBUG rather than _DEBUG
13 // So we make sure that _DEBUG implies DEBUG
21 // Clang-format messes with the indentation of comments if they directly precede an
22 // ifdef. This macro allows us to anchor the comments to the regular flow of code.
23 #define CLANG_FORMAT_COMMENT_ANCHOR ;
25 // Clang-tidy replaces 0 with nullptr in some templated functions, causing a build
26 // break. Replacing those instances with ZERO avoids this change
30 // These don't seem useful, so turning them off is no big deal
31 #pragma warning(disable : 4065) // "switch statement contains 'default' but no 'case' labels" (happens due to #ifdefs)
32 #pragma warning(disable : 4510) // can't generate default constructor
33 #pragma warning(disable : 4511) // can't generate copy constructor
34 #pragma warning(disable : 4512) // can't generate assignment constructor
35 #pragma warning(disable : 4610) // user defined constructor required
36 #pragma warning(disable : 4211) // nonstandard extention used (char name[0] in structs)
37 #pragma warning(disable : 4127) // conditional expression constant
38 #pragma warning(disable : 4201) // "nonstandard extension used : nameless struct/union"
40 // Depending on the code base, you may want to not disable these
41 #pragma warning(disable : 4245) // assigning signed / unsigned
42 #pragma warning(disable : 4146) // unary minus applied to unsigned
44 #pragma warning(disable : 4100) // unreferenced formal parameter
45 #pragma warning(disable : 4291) // new operator without delete (only in emitX86.cpp)
49 #define CHECK_STRUCT_PADDING 0 // Set this to '1' to enable warning C4820 "'bytes' bytes padding added after
50 // construct 'member_name'" on interesting structs/classes
52 #define CHECK_STRUCT_PADDING 0 // Never enable it for non-MSFT compilers
57 #error Cannot define both _X86_ and _ARM_
60 #error Cannot define both _X86_ and _AMD64_
63 #error Cannot define both _X86_ and _ARM64_
66 #elif defined(_AMD64_)
68 #error Cannot define both _AMD64_ and _X86_
71 #error Cannot define both _AMD64_ and _ARM_
74 #error Cannot define both _AMD64_ and _ARM64_
79 #error Cannot define both _ARM_ and _X86_
82 #error Cannot define both _ARM_ and _AMD64_
85 #error Cannot define both _ARM_ and _ARM64_
88 #elif defined(_ARM64_)
90 #error Cannot define both _ARM64_ and _X86_
93 #error Cannot define both _ARM64_ and _AMD64_
96 #error Cannot define both _ARM64_ and _ARM_
100 #error Unsupported or unset host architecture
103 #if defined(_HOST_AMD64_) || defined(_HOST_ARM64_)
107 #if defined(_TARGET_X86_)
108 #if defined(_TARGET_ARM_)
109 #error Cannot define both _TARGET_X86_ and _TARGET_ARM_
111 #if defined(_TARGET_AMD64_)
112 #error Cannot define both _TARGET_X86_ and _TARGET_AMD64_
114 #if defined(_TARGET_ARM64_)
115 #error Cannot define both _TARGET_X86_ and _TARGET_ARM64_
117 #if !defined(_HOST_X86_)
118 #define _CROSS_COMPILER_
120 #elif defined(_TARGET_AMD64_)
121 #if defined(_TARGET_X86_)
122 #error Cannot define both _TARGET_AMD64_ and _TARGET_X86_
124 #if defined(_TARGET_ARM_)
125 #error Cannot define both _TARGET_AMD64_ and _TARGET_ARM_
127 #if defined(_TARGET_ARM64_)
128 #error Cannot define both _TARGET_AMD64_ and _TARGET_ARM64_
130 #if !defined(_HOST_AMD64_)
131 #define _CROSS_COMPILER_
133 #elif defined(_TARGET_ARM_)
134 #if defined(_TARGET_X86_)
135 #error Cannot define both _TARGET_ARM_ and _TARGET_X86_
137 #if defined(_TARGET_AMD64_)
138 #error Cannot define both _TARGET_ARM_ and _TARGET_AMD64_
140 #if defined(_TARGET_ARM64_)
141 #error Cannot define both _TARGET_ARM_ and _TARGET_ARM64_
143 #if !defined(_HOST_ARM_)
144 #define _CROSS_COMPILER_
146 #elif defined(_TARGET_ARM64_)
147 #if defined(_TARGET_X86_)
148 #error Cannot define both _TARGET_ARM64_ and _TARGET_X86_
150 #if defined(_TARGET_AMD64_)
151 #error Cannot define both _TARGET_ARM64_ and _TARGET_AMD64_
153 #if defined(_TARGET_ARM_)
154 #error Cannot define both _TARGET_ARM64_ and _TARGET_ARM_
156 #if !defined(_HOST_ARM64_)
157 #define _CROSS_COMPILER_
160 #error Unsupported or unset target architecture
163 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
164 #define _TARGET_64BIT_
167 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
168 #define _TARGET_XARCH_
171 #if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
172 #define _TARGET_ARMARCH_
175 // If the UNIX_AMD64_ABI is defined make sure that _TARGET_AMD64_ is also defined.
176 #if defined(UNIX_AMD64_ABI)
177 #if !defined(_TARGET_AMD64_)
178 #error When UNIX_AMD64_ABI is defined you must define _TARGET_AMD64_ defined as well.
182 // If the UNIX_X86_ABI is defined make sure that _TARGET_X86_ is also defined.
183 #if defined(UNIX_X86_ABI)
184 #if !defined(_TARGET_X86_)
185 #error When UNIX_X86_ABI is defined you must define _TARGET_X86_ defined as well.
189 #if defined(PLATFORM_UNIX)
193 // Are we generating code to target Unix? This is true if we will run on Unix (_HOST_UNIX_ is defined).
194 // It's also true if we are building an altjit targetting Unix, which we determine by checking if either
195 // UNIX_AMD64_ABI or UNIX_X86_ABI is defined.
196 #if defined(_HOST_UNIX_) || ((defined(UNIX_AMD64_ABI) || defined(UNIX_X86_ABI)) && defined(ALT_JIT))
197 #define _TARGET_UNIX_
200 // --------------------------------------------------------------------------------
201 // IMAGE_FILE_MACHINE_TARGET
202 // --------------------------------------------------------------------------------
204 #if defined(_TARGET_X86_)
205 #define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_I386
206 #elif defined(_TARGET_AMD64_)
207 #define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_AMD64
208 #elif defined(_TARGET_ARM_)
209 #define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_ARMNT
210 #elif defined(_TARGET_ARM64_)
211 #define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_ARM64 // 0xAA64
213 #error Unsupported or unset target architecture
216 // Include the AMD64 unwind codes when appropriate.
217 #if defined(_TARGET_AMD64_)
218 // We need to temporarily set PLATFORM_UNIX, if necessary, to get the Unix-specific unwind codes.
219 #if defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)
220 #define PLATFORM_UNIX
222 #include "win64unwind.h"
223 #if defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)
228 // Macros for defining strongly-typed enums. Use as follows:
230 // DECLARE_TYPED_ENUM(FooEnum,BYTE)
234 // END_DECLARE_TYPED_ENUM(FooEnum, BYTE)
236 // VC++ understands the syntax to declare these directly, e.g., "enum FooEnum : BYTE",
237 // but GCC does not, so we use typedefs.
239 #define DECLARE_TYPED_ENUM(tag, baseType) enum tag : baseType
241 #define END_DECLARE_TYPED_ENUM(tag, baseType) ;
247 #define __OPERATOR_NEW_INLINE 1 // indicate that I will define these
248 #define __PLACEMENT_NEW_INLINE // don't bring in the global placement new, it is easy to make a mistake
249 // with our new(compiler*) pattern.
251 #include "utilcode.h" // this defines assert as _ASSERTE
252 #include "host.h" // this redefines assert for the JIT to use assertAbort
257 #define INDEBUG_COMMA(x) x,
258 #define DEBUGARG(x) , x
261 #define INDEBUG_COMMA(x)
265 #if defined(DEBUG) || defined(LATE_DISASM)
266 #define INDEBUG_LDISASM_COMMA(x) x,
268 #define INDEBUG_LDISASM_COMMA(x)
271 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
272 #define FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(x) , x
273 #define FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY(x) x
274 #else // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
275 #define FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(x)
276 #define FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY(x)
277 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
279 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING) || (!defined(_TARGET_64BIT_) && !defined(LEGACY_BACKEND))
280 #define FEATURE_PUT_STRUCT_ARG_STK 1
281 #define PUT_STRUCT_ARG_STK_ONLY_ARG(x) , x
282 #define PUT_STRUCT_ARG_STK_ONLY(x) x
283 #else // !(defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)|| (!defined(_TARGET_64BIT_) && !defined(LEGACY_BACKEND)))
284 #define PUT_STRUCT_ARG_STK_ONLY_ARG(x)
285 #define PUT_STRUCT_ARG_STK_ONLY(x)
286 #endif // !(defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)|| (!defined(_TARGET_64BIT_) && !defined(LEGACY_BACKEND)))
288 #if defined(UNIX_AMD64_ABI)
289 #define UNIX_AMD64_ABI_ONLY_ARG(x) , x
290 #define UNIX_AMD64_ABI_ONLY(x) x
291 #else // !defined(UNIX_AMD64_ABI)
292 #define UNIX_AMD64_ABI_ONLY_ARG(x)
293 #define UNIX_AMD64_ABI_ONLY(x)
294 #endif // defined(UNIX_AMD64_ABI)
296 #if defined(UNIX_AMD64_ABI) || defined(_TARGET_ARM64_)
297 #define MULTIREG_HAS_SECOND_GC_RET 1
298 #define MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(x) , x
299 #define MULTIREG_HAS_SECOND_GC_RET_ONLY(x) x
300 #else // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
301 #define MULTIREG_HAS_SECOND_GC_RET 0
302 #define MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(x)
303 #define MULTIREG_HAS_SECOND_GC_RET_ONLY(x)
304 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
306 // To get rid of warning 4701 : local variable may be used without being initialized
307 #define DUMMY_INIT(x) (x)
309 #define REGEN_SHORTCUTS 0
310 #define REGEN_CALLPAT 0
312 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
313 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
317 XX Interface of the JIT with jit.cpp XX
319 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
320 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
323 /*****************************************************************************/
327 #define INFO6 LL_INFO10000 // Did Jit or Inline succeeded?
328 #define INFO7 LL_INFO100000 // NYI stuff
329 #define INFO8 LL_INFO1000000 // Weird failures
330 #define INFO9 LL_EVERYTHING // Info about incoming settings
331 #define INFO10 LL_EVERYTHING // Totally verbose
335 typedef class ICorJitInfo* COMP_HANDLE;
337 const CORINFO_CLASS_HANDLE NO_CLASS_HANDLE = (CORINFO_CLASS_HANDLE) nullptr;
339 /*****************************************************************************/
344 } // Use to disable code while keeping prefast happy
346 // We define two IL offset types, as follows:
348 // IL_OFFSET: either a distinguished value, or an IL offset.
349 // IL_OFFSETX: either a distinguished value, or the top two bits are a flags, and the remaining bottom
350 // bits are a IL offset.
352 // In both cases, the set of legal distinguished values is:
353 // BAD_IL_OFFSET -- A unique illegal IL offset number. Note that it must be different from
354 // the ICorDebugInfo values, below, and must also not be a legal IL offset.
355 // ICorDebugInfo::NO_MAPPING -- The IL offset corresponds to no source code (such as EH step blocks).
356 // ICorDebugInfo::PROLOG -- The IL offset indicates a prolog
357 // ICorDebugInfo::EPILOG -- The IL offset indicates an epilog
359 // The IL offset must be in the range [0 .. 0x3fffffff]. This is because we steal
360 // the top two bits in IL_OFFSETX for flags, but we want the maximum range to be the same
361 // for both types. The IL value can't be larger than the maximum IL offset of the function
364 // Blocks and statements never store one of the ICorDebugInfo values, even for IL_OFFSETX types. These are
365 // only stored in the IPmappingDsc struct, ipmdILoffsx field.
367 typedef unsigned IL_OFFSET;
369 const IL_OFFSET BAD_IL_OFFSET = 0x80000000;
370 const IL_OFFSET MAX_IL_OFFSET = 0x3fffffff;
372 typedef unsigned IL_OFFSETX; // IL_OFFSET with stack-empty or call-instruction bit
373 const IL_OFFSETX IL_OFFSETX_STKBIT = 0x80000000; // Note: this bit is set when the stack is NOT empty!
374 const IL_OFFSETX IL_OFFSETX_CALLINSTRUCTIONBIT = 0x40000000; // Set when the IL offset is for a call instruction.
375 const IL_OFFSETX IL_OFFSETX_BITS = IL_OFFSETX_STKBIT | IL_OFFSETX_CALLINSTRUCTIONBIT;
377 IL_OFFSET jitGetILoffs(IL_OFFSETX offsx);
378 IL_OFFSET jitGetILoffsAny(IL_OFFSETX offsx);
379 bool jitIsStackEmpty(IL_OFFSETX offsx);
380 bool jitIsCallInstruction(IL_OFFSETX offsx);
382 const unsigned BAD_VAR_NUM = UINT_MAX;
384 // Code can't be more than 2^31 in any direction. This is signed, so it should be used for anything that is
385 // relative to something else.
386 typedef int NATIVE_OFFSET;
388 // This is the same as the above, but it's used in absolute contexts (i.e. offset from the start). Also,
389 // this is used for native code sizes.
390 typedef unsigned UNATIVE_OFFSET;
392 typedef ptrdiff_t ssize_t;
394 // For the following specially handled FIELD_HANDLES we need
395 // values that are negative and have the low two bits zero
396 // See eeFindJitDataOffs and eeGetJitDataOffs in Compiler.hpp
397 #define FLD_GLOBAL_DS ((CORINFO_FIELD_HANDLE)-4)
398 #define FLD_GLOBAL_FS ((CORINFO_FIELD_HANDLE)-8)
400 /*****************************************************************************/
404 /*****************************************************************************/
406 // Late disassembly is OFF by default. Can be turned ON by
407 // adding /DLATE_DISASM=1 on the command line.
408 // Always OFF in the non-debug version
410 #if defined(LATE_DISASM) && (LATE_DISASM == 0)
414 /*****************************************************************************/
416 /*****************************************************************************/
418 #define FEATURE_VALNUM_CSE 1 // enable the Value Number CSE optimization logic
420 // true if Value Number CSE is enabled
421 #define FEATURE_ANYCSE FEATURE_VALNUM_CSE
423 #define CSE_INTO_HANDLERS 0
425 #define CAN_DISABLE_DFA 1 // disable data flow for minopts
427 #define LARGE_EXPSET 1 // Track 64 or 32 assertions/copies/consts/rangechecks
428 #define ASSERTION_PROP 1 // Enable value/assertion propagation
430 #define LOCAL_ASSERTION_PROP ASSERTION_PROP // Enable local assertion propagation
432 //=============================================================================
434 #define OPT_MULT_ADDSUB 1 // optimize consecutive "lclVar += or -= icon"
435 #define OPT_BOOL_OPS 1 // optimize boolean operations
437 //=============================================================================
439 #define REDUNDANT_LOAD 1 // track locals in regs, suppress loads
440 #define STACK_PROBES 0 // Support for stack probes
441 #define DUMP_FLOWGRAPHS DEBUG // Support for creating Xml Flowgraph reports in *.fgx files
443 #define HANDLER_ENTRY_MUST_BE_IN_HOT_SECTION 1 // if 1 we must have all handler entry points in the Hot code section
445 /*****************************************************************************/
447 #define VPTR_OFFS 0 // offset of vtable pointer from obj ptr
449 /*****************************************************************************/
451 #define DUMP_GC_TABLES DEBUG
452 #define VERIFY_GC_TABLES 0
453 #define REARRANGE_ADDS 1
455 #define FUNC_INFO_LOGGING 1 // Support dumping function info to a file. In retail, only NYIs, with no function name,
458 /*****************************************************************************/
459 /*****************************************************************************/
460 /* Set these to 1 to collect and output various statistics about the JIT */
462 #define CALL_ARG_STATS 0 // Collect stats about calls and call arguments.
463 #define COUNT_BASIC_BLOCKS 0 // Create a histogram of basic block sizes, and a histogram of IL sizes in the simple
464 // case of single block methods.
465 #define COUNT_LOOPS 0 // Collect stats about loops, such as the total number of natural loops, a histogram of
466 // the number of loop exits, etc.
467 #define COUNT_RANGECHECKS 0 // Count range checks removed (in lexical CSE?).
468 #define DATAFLOW_ITER 0 // Count iterations in lexical CSE and constant folding dataflow.
469 #define DISPLAY_SIZES 0 // Display generated code, data, and GC information sizes.
470 #define MEASURE_BLOCK_SIZE 0 // Collect stats about basic block and flowList node sizes and memory allocations.
471 #define MEASURE_FATAL 0 // Count the number of calls to fatal(), including NYIs and noway_asserts.
472 #define MEASURE_NODE_SIZE 0 // Collect stats about GenTree node allocations.
473 #define MEASURE_PTRTAB_SIZE 0 // Collect stats about GC pointer table allocations.
474 #define EMITTER_STATS 0 // Collect stats on the emitter.
475 #define NODEBASH_STATS 0 // Collect stats on changed gtOper values in GenTree's.
476 #define COUNT_AST_OPERS 0 // Display use counts for GenTree operators.
478 #define VERBOSE_SIZES 0 // Always display GC info sizes. If set, DISPLAY_SIZES must also be set.
479 #define VERBOSE_VERIFY 0 // Dump additional information when verifying code. Useful to debug verification bugs.
482 #define MEASURE_MEM_ALLOC 1 // Collect memory allocation stats.
483 #define LOOP_HOIST_STATS 1 // Collect loop hoisting stats.
484 #define TRACK_LSRA_STATS 1 // Collect LSRA stats
486 #define MEASURE_MEM_ALLOC 0 // You can set this to 1 to get memory stats in retail, as well
487 #define LOOP_HOIST_STATS 0 // You can set this to 1 to get loop hoist stats in retail, as well
488 #define TRACK_LSRA_STATS 0 // You can set this to 1 to get LSRA stats in retail, as well
491 // Timing calls to clr.dll is only available under certain conditions.
492 #ifndef FEATURE_JIT_METHOD_PERF
493 #define MEASURE_CLRAPI_CALLS 0 // Can't time these calls without METHOD_PERF.
496 #define MEASURE_CLRAPI_CALLS 0 // No point in measuring DEBUG code.
498 #if !defined(_HOST_X86_) && !defined(_HOST_AMD64_)
499 #define MEASURE_CLRAPI_CALLS 0 // Cycle counters only hooked up on x86/x64.
501 #if !defined(_MSC_VER) && !defined(__clang__)
502 #define MEASURE_CLRAPI_CALLS 0 // Only know how to do this with VC and Clang.
505 // If none of the above set the flag to 0, it's available.
506 #ifndef MEASURE_CLRAPI_CALLS
507 #define MEASURE_CLRAPI_CALLS 0 // Set to 1 to measure time in ICorJitInfo calls.
510 /*****************************************************************************/
511 /* Portability Defines */
512 /*****************************************************************************/
514 #define JIT32_GCENCODER
517 /*****************************************************************************/
519 /*****************************************************************************/
526 #pragma message("NOTE: this non-debug build has GC ptr table dumping always enabled!")
527 const bool dspGCtbls = true;
530 /*****************************************************************************/
534 void JitDump(const char* pcFormat, ...);
535 #define JITDUMP(...) \
537 if (JitTls::GetCompiler()->verbose) \
538 JitDump(__VA_ARGS__); \
544 #define JITLOG_THIS(t, x) \
548 #define DBEXEC(flg, expr) \
553 #define DISPNODE(t) \
554 if (JitTls::GetCompiler()->verbose) \
555 JitTls::GetCompiler()->gtDispTree(t, nullptr, nullptr, true);
556 #define DISPTREE(t) \
557 if (JitTls::GetCompiler()->verbose) \
558 JitTls::GetCompiler()->gtDispTree(t);
559 #define DISPRANGE(range) \
560 if (JitTls::GetCompiler()->verbose) \
561 JitTls::GetCompiler()->gtDispRange(range);
562 #define DISPTREERANGE(range, t) \
563 if (JitTls::GetCompiler()->verbose) \
564 JitTls::GetCompiler()->gtDispTreeRange(range, t);
565 #define VERBOSE JitTls::GetCompiler()->verbose
569 #define JITLOG_THIS(t, x)
570 #define DBEXEC(flg, expr)
573 #define DISPRANGE(range)
574 #define DISPTREERANGE(range, t)
578 /*****************************************************************************
580 * Double alignment. This aligns ESP to 0 mod 8 in function prolog, then uses ESP
581 * to reference locals, EBP to reference parameters.
582 * It only makes sense if frameless method support is on.
583 * (frameless method support is now always on)
587 #define DOUBLE_ALIGN 1 // permit the double alignment of ESP in prolog,
588 // and permit the double alignment of local offsets
590 #define DOUBLE_ALIGN 0 // no special handling for double alignment
592 /*****************************************************************************/
594 extern void _cdecl debugStop(const char* why, ...);
596 /*****************************************************************************/
602 const char* methodName; // Method to display output for
603 const char* className; // Class to display output for
605 double CGknob; // Tweakable knob for testing
606 unsigned testMask; // Tweakable mask for testing
608 JitOptions* lastDummyField; // Ensures instantiation uses right order of arguments
611 extern JitOptions jitOpts;
613 /*****************************************************************************
615 * Returns a word filled with the JITs allocator CHK fill value.
618 template <typename T>
619 inline T UninitializedWord()
621 __int64 word = 0x0101010101010101LL * (JitConfig.JitDefaultFill() & 0xFF);
625 /*****************************************************************************
627 * Determines whether this value is coming from uninitialized JIT memory
631 template <typename T>
632 inline bool IsUninitialized(T data)
634 return data == UninitializedWord<T>();
638 /*****************************************************************************/
649 /*****************************************************************************/
651 #define castto(var, typ) (*(typ*)&var)
653 #define sizeto(typ, mem) (offsetof(typ, mem) + sizeof(((typ*)0)->mem))
655 /*****************************************************************************/
657 #ifdef NO_MISALIGNED_ACCESS
659 #define MISALIGNED_RD_I2(src) (*castto(src, char*) | *castto(src + 1, char*) << 8)
661 #define MISALIGNED_RD_U2(src) (*castto(src, char*) | *castto(src + 1, char*) << 8)
663 #define MISALIGNED_WR_I2(dst, val) \
664 *castto(dst, char*) = val; \
665 *castto(dst + 1, char*) = val >> 8;
667 #define MISALIGNED_WR_I4(dst, val) \
668 *castto(dst, char*) = val; \
669 *castto(dst + 1, char*) = val >> 8; \
670 *castto(dst + 2, char*) = val >> 16; \
671 *castto(dst + 3, char*) = val >> 24;
675 #define MISALIGNED_RD_I2(src) (*castto(src, short*))
676 #define MISALIGNED_RD_U2(src) (*castto(src, unsigned short*))
678 #define MISALIGNED_WR_I2(dst, val) *castto(dst, short*) = val;
679 #define MISALIGNED_WR_I4(dst, val) *castto(dst, int*) = val;
681 #define MISALIGNED_WR_ST(dst, val) *castto(dst, ssize_t*) = val;
685 /*****************************************************************************/
687 inline size_t roundUp(size_t size, size_t mult = sizeof(size_t))
689 assert(mult && ((mult & (mult - 1)) == 0)); // power of two test
691 return (size + (mult - 1)) & ~(mult - 1);
694 inline size_t roundDn(size_t size, size_t mult = sizeof(size_t))
696 assert(mult && ((mult & (mult - 1)) == 0)); // power of two test
698 return (size) & ~(mult - 1);
701 inline unsigned int unsigned_abs(int x)
703 return ((unsigned int)abs(x));
706 #ifdef _TARGET_64BIT_
707 inline size_t unsigned_abs(ssize_t x)
709 return ((size_t)abs(x));
711 #endif // _TARGET_64BIT_
713 /*****************************************************************************/
715 #if CALL_ARG_STATS || COUNT_BASIC_BLOCKS || COUNT_LOOPS || EMITTER_STATS || MEASURE_NODE_SIZE || MEASURE_MEM_ALLOC
720 Histogram(IAllocator* allocator, const unsigned* const sizeTable);
723 void dump(FILE* output);
724 void record(unsigned size);
727 void ensureAllocated();
729 IAllocator* m_allocator;
730 unsigned m_sizeCount;
731 const unsigned* const m_sizeTable;
735 #endif // CALL_ARG_STATS || COUNT_BASIC_BLOCKS || COUNT_LOOPS || EMITTER_STATS || MEASURE_NODE_SIZE
737 /*****************************************************************************/
740 #include "icapctrl.h"
743 /*****************************************************************************/
747 /*****************************************************************************/
749 #if CHECK_STRUCT_PADDING
750 #pragma warning(push)
751 #pragma warning(default : 4820) // 'bytes' bytes padding added after construct 'member_name'
752 #endif // CHECK_STRUCT_PADDING
757 #if FEATURE_TAILCALL_OPT
759 #ifdef FEATURE_CORECLR
760 // CoreCLR - enable tail call opt for the following IL pattern
767 #define FEATURE_TAILCALL_OPT_SHARED_RETURN 1
769 // Desktop: Keep this to zero as one of app-compat apps that is using GetCallingAssembly()
770 // has an issue turning this ON.
772 // Refer to TF: Bug: 824625 and its associated regression TF Bug: 1113265
773 #define FEATURE_TAILCALL_OPT_SHARED_RETURN 0
774 #endif // FEATURE_CORECLR
776 #else // !FEATURE_TAILCALL_OPT
777 #define FEATURE_TAILCALL_OPT_SHARED_RETURN 0
778 #endif // !FEATURE_TAILCALL_OPT
780 #define CLFLG_CODESIZE 0x00001
781 #define CLFLG_CODESPEED 0x00002
782 #define CLFLG_CSE 0x00004
783 #define CLFLG_REGVAR 0x00008
784 #define CLFLG_RNGCHKOPT 0x00010
785 #define CLFLG_DEADASGN 0x00020
786 #define CLFLG_CODEMOTION 0x00040
787 #define CLFLG_QMARK 0x00080
788 #define CLFLG_TREETRANS 0x00100
789 #define CLFLG_INLINING 0x00200
790 #define CLFLG_CONSTANTFOLD 0x00800
792 #if FEATURE_STRUCTPROMOTE
793 #define CLFLG_STRUCTPROMOTE 0x00400
795 #define CLFLG_STRUCTPROMOTE 0x00000
798 #define CLFLG_MAXOPT \
799 (CLFLG_CSE | CLFLG_REGVAR | CLFLG_RNGCHKOPT | CLFLG_DEADASGN | CLFLG_CODEMOTION | CLFLG_QMARK | CLFLG_TREETRANS | \
800 CLFLG_INLINING | CLFLG_STRUCTPROMOTE | CLFLG_CONSTANTFOLD)
802 #define CLFLG_MINOPT (CLFLG_TREETRANS)
804 #define JIT_RESERVED_STACK 64 // Reserved for arguments of calls and hidden
805 // pushes for finallys so that we don't
806 // probe on every call site. See comment in
807 // for CORINFO_STACKPROBE_DEPTH in corjit.h
809 /*****************************************************************************/
811 extern void dumpILBytes(const BYTE* const codeAddr, unsigned codeSize, unsigned alignSize);
813 extern unsigned dumpSingleInstr(const BYTE* const codeAddr, IL_OFFSET offs, const char* prefix = nullptr);
815 extern void dumpILRange(const BYTE* const codeAddr, unsigned codeSize); // in bytes
817 /*****************************************************************************/
819 extern int jitNativeCode(CORINFO_METHOD_HANDLE methodHnd,
820 CORINFO_MODULE_HANDLE classHnd,
822 CORINFO_METHOD_INFO* methodInfo,
823 void** methodCodePtr,
824 ULONG* methodCodeSize,
825 JitFlags* compileFlags,
826 void* inlineInfoPtr);
829 const size_t INVALID_POINTER_VALUE = 0xFEEDFACEABADF00D;
831 const size_t INVALID_POINTER_VALUE = 0xFEEDFACE;
834 // Constants for making sure size_t fit into smaller types.
835 const size_t MAX_USHORT_SIZE_T = static_cast<size_t>(static_cast<unsigned short>(-1));
836 const size_t MAX_UNSIGNED_SIZE_T = static_cast<size_t>(static_cast<unsigned>(-1));
838 // These assume 2's complement...
839 const int MAX_SHORT_AS_INT = 32767;
840 const int MIN_SHORT_AS_INT = -32768;
842 /*****************************************************************************/
846 #define CompMemKindMacro(kind) CMK_##kind,
847 #include "compmemkind.h"
855 Compiler* m_compiler;
861 JitTls(ICorJitInfo* jitInfo);
865 static LogEnv* GetLogEnv();
868 static Compiler* GetCompiler();
869 static void SetCompiler(Compiler* compiler);
874 #include "compiler.h"
876 template <typename T>
879 return (p == ZERO) ? ZERO : (JitTls::GetCompiler()->opts.dspDiffable ? T(0xD1FFAB1E) : p);
882 template <typename T>
885 return (o == ZERO) ? ZERO : (JitTls::GetCompiler()->opts.dspDiffable ? T(0xD1FFAB1E) : o);
888 #else // !defined(DEBUG)
890 template <typename T>
896 template <typename T>
902 #endif // !defined(DEBUG)
904 /*****************************************************************************/
906 /*****************************************************************************/