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 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14 #ifdef _TARGET_ARMARCH_
16 // Windows no longer imposes a maximum prolog size. However, we still have an
17 // assert here just to inform us if we increase the size of the prolog
18 // accidentally, as there is still a slight performance advantage in the
19 // OS unwinder to having as few unwind codes as possible.
20 // You can increase this "max" number if necessary.
22 #if defined(_TARGET_ARM_)
23 const unsigned MAX_PROLOG_SIZE_BYTES = 40;
24 const unsigned MAX_EPILOG_SIZE_BYTES = 40;
25 #define UWC_END 0xFF // "end" unwind code
26 #define UW_MAX_FRAGMENT_SIZE_BYTES (1U << 19)
27 #define UW_MAX_CODE_WORDS_COUNT 15 // Max number that can be encoded in the "Code Words" field of the .pdata record
28 #define UW_MAX_EPILOG_START_INDEX 0xFFU // Max number that can be encoded in the "Epilog Start Index" field
29 // of the .pdata record
30 #elif defined(_TARGET_ARM64_)
31 const unsigned MAX_PROLOG_SIZE_BYTES = 100;
32 const unsigned MAX_EPILOG_SIZE_BYTES = 100;
33 #define UWC_END 0xE4 // "end" unwind code
34 #define UWC_END_C 0xE5 // "end_c" unwind code
35 #define UW_MAX_FRAGMENT_SIZE_BYTES (1U << 20)
36 #define UW_MAX_CODE_WORDS_COUNT 31
37 #define UW_MAX_EPILOG_START_INDEX 0x3FFU
38 #endif // _TARGET_ARM64_
40 #define UW_MAX_EPILOG_COUNT 31 // Max number that can be encoded in the "Epilog count" field
41 // of the .pdata record
42 #define UW_MAX_EXTENDED_CODE_WORDS_COUNT 0xFFU // Max number that can be encoded in the "Extended Code Words"
43 // field of the .pdata record
44 #define UW_MAX_EXTENDED_EPILOG_COUNT 0xFFFFU // Max number that can be encoded in the "Extended Epilog Count"
45 // field of the .pdata record
46 #define UW_MAX_EPILOG_START_OFFSET 0x3FFFFU // Max number that can be encoded in the "Epilog Start Offset"
47 // field of the .pdata record
50 // Forward declaration of class defined in emit.h
56 // Forward declarations of classes defined in this file
59 class UnwindCodesBase;
60 class UnwindPrologCodes;
61 class UnwindEpilogCodes;
62 class UnwindEpilogInfo;
63 class UnwindFragmentInfo;
66 // UnwindBase: A base class shared by the the unwind classes that require
67 // a Compiler* for memory allocation.
72 UnwindBase(Compiler* comp) : uwiComp(comp)
83 // TODO: How do we get the ability to access uwiComp without error on Clang?
84 #if defined(DEBUG) && !defined(__GNUC__)
89 return uwiComp->dspPtr(p);
95 return uwiComp->dspOffset(o);
98 static char* dspBool(bool b)
100 return (b) ? "true" : "false";
112 // UnwindCodesBase: A base class shared by the the classes used to represent the prolog
113 // and epilog unwind codes.
115 class UnwindCodesBase
118 // Add a single unwind code.
120 virtual void AddCode(BYTE b1) = 0;
121 virtual void AddCode(BYTE b1, BYTE b2) = 0;
122 virtual void AddCode(BYTE b1, BYTE b2, BYTE b3) = 0;
123 virtual void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4) = 0;
125 // Get access to the unwind codes
127 virtual BYTE* GetCodes() = 0;
129 bool IsEndCode(BYTE b)
131 #if defined(_TARGET_ARM_)
133 #elif defined(_TARGET_ARM64_)
134 return (b == UWC_END); // TODO-ARM64-Bug?: what about the "end_c" code?
135 #endif // _TARGET_ARM64_
140 unsigned GetCodeSizeFromUnwindCodes(bool isProlog);
145 // UnwindPrologCodes: represents the unwind codes for a prolog sequence.
146 // Prolog unwind codes arrive in reverse order from how they will be emitted.
147 // Store them as a stack, storing from the end of an array towards the beginning.
148 // This class is also re-used as the final location of the consolidated unwind
149 // information for a function, including unwind info header, the prolog codes,
150 // and any epilog codes.
152 class UnwindPrologCodes : public UnwindBase, public UnwindCodesBase
154 // UPC_LOCAL_COUNT is the amount of memory local to this class. For ARM mscorlib.dll, the maximum size is 34.
155 // Here is a histogram of other interesting sizes:
159 // From this data, we choose to use 24.
161 static const int UPC_LOCAL_COUNT = 24;
164 UnwindPrologCodes(Compiler* comp)
166 , upcMem(upcMemLocal)
167 , upcMemSize(UPC_LOCAL_COUNT)
168 , upcCodeSlot(UPC_LOCAL_COUNT)
172 // Assume we've got a normal end code.
173 // Push four so we can generate an array that is a multiple of 4 bytes in size with the
174 // end codes (and padding) already in place. One is the end code for the prolog codes,
175 // three are end-of-array alignment padding.
183 // Implementation of UnwindCodesBase
186 virtual void AddCode(BYTE b1)
191 virtual void AddCode(BYTE b1, BYTE b2)
197 virtual void AddCode(BYTE b1, BYTE b2, BYTE b3)
204 virtual void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
212 // Return a pointer to the first unwind code byte
213 virtual BYTE* GetCodes()
215 assert(upcCodeSlot < upcMemSize); // There better be at least one code!
216 return &upcMem[upcCodeSlot];
219 ///////////////////////////////////////////////////////////////////////////
221 BYTE GetByte(int index)
223 assert(upcCodeSlot <= index && index < upcMemSize);
224 return upcMem[index];
227 // Push a single byte on the unwind code stack
228 void PushByte(BYTE b)
230 if (upcCodeSlot == 0)
232 // We've run out of space! Reallocate, and copy everything to a new array.
233 EnsureSize(upcMemSize + 1);
237 noway_assert(0 <= upcCodeSlot && upcCodeSlot < upcMemSize);
239 upcMem[upcCodeSlot] = b;
242 // Return the size of the unwind codes, in bytes. The size is the exact size, not an aligned size.
243 // The size includes exactly one "end" code.
246 // -3 because we put 4 "end" codes at the end in the constructor, and we shouldn't count that here
247 return upcMemSize - upcCodeSlot - 3;
250 void SetFinalSize(int headerBytes, int epilogBytes);
252 void AddHeaderWord(DWORD d);
254 void GetFinalInfo(/* OUT */ BYTE** ppUnwindBlock, /* OUT */ ULONG* pUnwindBlockSize);
256 // AppendEpilog: copy the epilog bytes to the next epilog bytes slot
257 void AppendEpilog(UnwindEpilogInfo* pEpi);
259 // Match the prolog codes to a set of epilog codes
260 int Match(UnwindEpilogInfo* pEpi);
262 // Copy the prolog codes from another prolog
263 void CopyFrom(UnwindPrologCodes* pCopyFrom);
273 void Dump(int indent = 0);
277 void EnsureSize(int requiredSize);
279 // No copy constructor or operator=
280 UnwindPrologCodes(const UnwindPrologCodes& info);
281 UnwindPrologCodes& operator=(const UnwindPrologCodes&);
287 // To store the unwind codes, we first use a local array that should satisfy almost all cases.
288 // If there are more unwind codes, we dynamically allocate memory.
289 BYTE upcMemLocal[UPC_LOCAL_COUNT];
292 // upcMemSize is the number of bytes in upcMem. This is equal to UPC_LOCAL_COUNT unless
293 // we've dynamically allocated memory to store the codes.
296 // upcCodeSlot points to the last unwind code added to the array. The array is filled in from
297 // the end, so it starts pointing one beyond the array end.
300 // upcHeaderSlot points to the last header byte prepended to the array. Headers bytes are
301 // filled in from the beginning, and only after SetFinalSize() is called.
304 // upcEpilogSlot points to the next epilog location to fill
307 // upcUnwindBlockSlot is only set after SetFinalSize() is called. It is the index of the first
308 // byte of the final unwind data, namely the first byte of the header.
309 int upcUnwindBlockSlot;
312 // UnwindEpilogCodes: represents the unwind codes for a single epilog sequence.
313 // Epilog unwind codes arrive in the order they will be emitted. Store them as an array,
314 // adding new ones to the end of the array.
316 class UnwindEpilogCodes : public UnwindBase, public UnwindCodesBase
318 // UEC_LOCAL_COUNT is the amount of memory local to this class. For ARM mscorlib.dll, the maximum size is 6,
319 // while 89% of epilogs fit in 4. So, set it to 4 to maintain array alignment and hit most cases.
320 static const int UEC_LOCAL_COUNT = 4;
323 UnwindEpilogCodes(Compiler* comp)
325 , uecMem(uecMemLocal)
326 , firstByteOfLastCode(0)
327 , uecMemSize(UEC_LOCAL_COUNT)
329 , uecFinalized(false)
334 // Implementation of UnwindCodesBase
337 virtual void AddCode(BYTE b1)
341 firstByteOfLastCode = b1;
344 virtual void AddCode(BYTE b1, BYTE b2)
349 firstByteOfLastCode = b1;
352 virtual void AddCode(BYTE b1, BYTE b2, BYTE b3)
358 firstByteOfLastCode = b1;
361 virtual void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
368 firstByteOfLastCode = b1;
371 // Return a pointer to the first unwind code byte
372 virtual BYTE* GetCodes()
374 assert(uecFinalized);
376 // Codes start at the beginning
380 ///////////////////////////////////////////////////////////////////////////
382 BYTE GetByte(int index)
384 assert(0 <= index && index <= uecCodeSlot);
385 return uecMem[index];
388 // Add a single byte on the unwind code array
389 void AppendByte(BYTE b)
391 if (uecCodeSlot == uecMemSize - 1)
393 // We've run out of space! Reallocate, and copy everything to a new array.
394 EnsureSize(uecMemSize + 1);
398 noway_assert(0 <= uecCodeSlot && uecCodeSlot < uecMemSize);
400 uecMem[uecCodeSlot] = b;
403 // Return the size of the unwind codes, in bytes. The size is the exact size, not an aligned size.
408 // Add one because uecCodeSlot is 0-based
409 return uecCodeSlot + 1;
413 // Add one because uecCodeSlot is 0-based, and one for an "end" code that isn't stored (yet).
414 return uecCodeSlot + 2;
420 assert(!uecFinalized);
421 noway_assert(0 <= uecCodeSlot && uecCodeSlot < uecMemSize); // There better be at least one code!
423 if (!IsEndCode(firstByteOfLastCode)) // If the last code is an end code, we don't need to append one.
425 AppendByte(UWC_END); // Add a default "end" code to the end of the array of unwind codes
426 firstByteOfLastCode = UWC_END; // Update firstByteOfLastCode in case we use it later
429 uecFinalized = true; // With the "end" code in place, now we're done
432 unsigned codeSize = GetCodeSizeFromUnwindCodes(false);
433 assert(codeSize <= MAX_EPILOG_SIZE_BYTES);
445 void Dump(int indent = 0);
449 void EnsureSize(int requiredSize);
451 // No destructor, copy constructor or operator=
452 UnwindEpilogCodes(const UnwindEpilogCodes& info);
453 UnwindEpilogCodes& operator=(const UnwindEpilogCodes&);
459 // To store the unwind codes, we first use a local array that should satisfy almost all cases.
460 // If there are more unwind codes, we dynamically allocate memory.
461 BYTE uecMemLocal[UEC_LOCAL_COUNT];
463 BYTE firstByteOfLastCode;
465 // uecMemSize is the number of bytes/slots in uecMem. This is equal to UEC_LOCAL_COUNT unless
466 // we've dynamically allocated memory to store the codes.
469 // uecCodeSlot points to the last unwind code added to the array. The array is filled in from
470 // the beginning, so it starts at -1.
473 // Is the unwind information finalized? Finalized info has an end code appended.
477 // UnwindEpilogInfo: represents the unwind information for a single epilog sequence. Epilogs for a
478 // single function/funclet are in a linked list.
480 class UnwindEpilogInfo : public UnwindBase
482 friend class UnwindFragmentInfo;
484 static const unsigned EPI_ILLEGAL_OFFSET = 0xFFFFFFFF;
487 UnwindEpilogInfo(Compiler* comp)
490 , epiEmitLocation(NULL)
492 , epiStartOffset(EPI_ILLEGAL_OFFSET)
498 void CaptureEmitLocation();
500 void FinalizeOffset();
504 epiCodes.FinalizeCodes();
507 UNATIVE_OFFSET GetStartOffset()
509 assert(epiStartOffset != EPI_ILLEGAL_OFFSET);
510 return epiStartOffset;
515 assert(epiStartIndex != -1);
516 return epiStartIndex; // The final "Epilog Start Index" of this epilog's unwind codes
519 void SetStartIndex(int index)
521 assert(epiStartIndex == -1);
522 epiStartIndex = (int)index;
535 // Size of epilog unwind codes in bytes
538 return epiCodes.Size();
541 // Return a pointer to the first unwind code byte
544 return epiCodes.GetCodes();
547 // Match the codes to a set of epilog codes
548 int Match(UnwindEpilogInfo* pEpi);
558 void Dump(int indent = 0);
562 // No copy constructor or operator=
563 UnwindEpilogInfo(const UnwindEpilogInfo& info);
564 UnwindEpilogInfo& operator=(const UnwindEpilogInfo&);
570 UnwindEpilogInfo* epiNext;
571 emitLocation* epiEmitLocation; // The emitter location of the beginning of the epilog
572 UnwindEpilogCodes epiCodes;
573 UNATIVE_OFFSET epiStartOffset; // Actual offset of the epilog, in bytes, from the start of the function. Set in
575 bool epiMatches; // Do the epilog unwind codes match some other set of codes? If so, we don't copy these to the
576 // final set; we just point to another set.
577 int epiStartIndex; // The final "Epilog Start Index" of this epilog's unwind codes
580 // UnwindFragmentInfo: represents all the unwind information for a single fragment of a function or funclet.
581 // A fragment is a section with a code size less than the maximum unwind code size: either 512K bytes, or
582 // that specified by COMPlus_JitSplitFunctionSize. In most cases, there will be exactly one fragment.
584 class UnwindFragmentInfo : public UnwindBase
586 friend class UnwindInfo;
588 static const unsigned UFI_ILLEGAL_OFFSET = 0xFFFFFFFF;
591 UnwindFragmentInfo(Compiler* comp, emitLocation* emitLoc, bool hasPhantomProlog);
593 void FinalizeOffset();
595 UNATIVE_OFFSET GetStartOffset()
597 assert(ufiStartOffset != UFI_ILLEGAL_OFFSET);
598 return ufiStartOffset;
601 // Add an unwind code. It could be for a prolog, or for the current epilog.
602 // A single unwind code can be from 1 to 4 bytes.
604 void AddCode(BYTE b1)
606 assert(ufiInitialized == UFI_INITIALIZED_PATTERN);
607 ufiCurCodes->AddCode(b1);
610 void AddCode(BYTE b1, BYTE b2)
612 assert(ufiInitialized == UFI_INITIALIZED_PATTERN);
613 ufiCurCodes->AddCode(b1, b2);
616 void AddCode(BYTE b1, BYTE b2, BYTE b3)
618 assert(ufiInitialized == UFI_INITIALIZED_PATTERN);
619 ufiCurCodes->AddCode(b1, b2, b3);
622 void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
624 assert(ufiInitialized == UFI_INITIALIZED_PATTERN);
625 ufiCurCodes->AddCode(b1, b2, b3, b4);
628 unsigned EpilogCount()
631 for (UnwindEpilogInfo* pEpi = ufiEpilogList; pEpi != NULL; pEpi = pEpi->epiNext)
642 void CopyPrologCodes(UnwindFragmentInfo* pCopyFrom);
644 void SplitEpilogCodes(emitLocation* emitLoc, UnwindFragmentInfo* pSplitFrom);
646 bool IsAtFragmentEnd(UnwindEpilogInfo* pEpi);
648 // Return the full, final size of unwind block. This will be used to allocate memory for
649 // the unwind block. This is called before the code offsets are finalized.
653 assert(ufiSize != 0);
657 void Finalize(UNATIVE_OFFSET functionLength);
659 // GetFinalInfo: return a pointer to the final unwind info to hand to the VM, and the size of this info in bytes
660 void GetFinalInfo(/* OUT */ BYTE** ppUnwindBlock, /* OUT */ ULONG* pUnwindBlockSize)
662 ufiPrologCodes.GetFinalInfo(ppUnwindBlock, pUnwindBlockSize);
665 void Reserve(BOOL isFunclet, bool isHotCode);
668 CorJitFuncKind funKind, void* pHotCode, void* pColdCode, UNATIVE_OFFSET funcEndOffset, bool isHotCode);
673 ~UnwindFragmentInfo()
678 void Dump(int indent = 0);
682 // No copy constructor or operator=
683 UnwindFragmentInfo(const UnwindFragmentInfo& info);
684 UnwindFragmentInfo& operator=(const UnwindFragmentInfo&);
690 UnwindFragmentInfo* ufiNext; // The next fragment
691 emitLocation* ufiEmitLoc; // Emitter location for start of fragment
692 bool ufiHasPhantomProlog; // Are the prolog codes for a phantom prolog, or a real prolog?
693 // (For a phantom prolog, this code fragment represents a fragment in
694 // the sense of the unwind info spec; something without a real prolog.)
695 UnwindPrologCodes ufiPrologCodes; // The unwind codes for the prolog
696 UnwindEpilogInfo ufiEpilogFirst; // In-line the first epilog to avoid separate memory allocation, since
697 // almost all functions will have at least one epilog. It is pointed
698 // to by ufiEpilogList when the first epilog is added.
699 UnwindEpilogInfo* ufiEpilogList; // The head of the epilog list
700 UnwindEpilogInfo* ufiEpilogLast; // The last entry in the epilog list (the last epilog added)
701 UnwindCodesBase* ufiCurCodes; // Pointer to current unwind codes, either prolog or epilog
703 // Some data computed when merging the unwind codes, and used when finalizing the
704 // unwind block for emission.
705 unsigned ufiSize; // The size of the unwind data for this fragment, in bytes
707 bool ufiNeedExtendedCodeWordsEpilogCount;
708 unsigned ufiCodeWords;
709 unsigned ufiEpilogScopes;
710 UNATIVE_OFFSET ufiStartOffset;
716 // Are we processing the prolog? The prolog must come first, followed by a (possibly empty)
717 // set of epilogs, for this function/funclet.
720 static const unsigned UFI_INITIALIZED_PATTERN = 0x0FACADE0; // Something unlikely to be the fill pattern for
721 // uninitialized memory
722 unsigned ufiInitialized;
727 // UnwindInfo: represents all the unwind information for a single function or funclet
729 class UnwindInfo : public UnwindBase
732 void InitUnwindInfo(Compiler* comp, emitLocation* startLoc, emitLocation* endLoc);
734 void HotColdSplitCodes(UnwindInfo* puwi);
736 // The following act on all the fragments that make up the unwind info for this function or funclet.
740 static void EmitSplitCallback(void* context, emitLocation* emitLoc);
742 void Reserve(BOOL isFunclet, bool isHotCode);
744 void Allocate(CorJitFuncKind funKind, void* pHotCode, void* pColdCode, bool isHotCode);
746 // The following act on the current fragment (the one pointed to by 'uwiFragmentLast').
748 // Add an unwind code. It could be for a prolog, or for the current epilog.
749 // A single unwind code can be from 1 to 4 bytes.
751 void AddCode(BYTE b1)
753 assert(uwiInitialized == UWI_INITIALIZED_PATTERN);
754 assert(uwiFragmentLast != NULL);
755 INDEBUG(CheckOpsize(b1));
757 uwiFragmentLast->AddCode(b1);
761 void AddCode(BYTE b1, BYTE b2)
763 assert(uwiInitialized == UWI_INITIALIZED_PATTERN);
764 assert(uwiFragmentLast != NULL);
765 INDEBUG(CheckOpsize(b1));
767 uwiFragmentLast->AddCode(b1, b2);
771 void AddCode(BYTE b1, BYTE b2, BYTE b3)
773 assert(uwiInitialized == UWI_INITIALIZED_PATTERN);
774 assert(uwiFragmentLast != NULL);
775 INDEBUG(CheckOpsize(b1));
777 uwiFragmentLast->AddCode(b1, b2, b3);
781 void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
783 assert(uwiInitialized == UWI_INITIALIZED_PATTERN);
784 assert(uwiFragmentLast != NULL);
785 INDEBUG(CheckOpsize(b1));
787 uwiFragmentLast->AddCode(b1, b2, b3, b4);
793 emitLocation* GetCurrentEmitterLocation()
798 #if defined(_TARGET_ARM_)
799 unsigned GetInstructionSize();
800 #endif // defined(_TARGET_ARM_)
802 void CaptureLocation();
813 #if defined(_TARGET_ARM_)
814 // Given the first byte of the unwind code, check that its opsize matches
815 // the last instruction added in the emitter.
816 void CheckOpsize(BYTE b1);
817 #elif defined(_TARGET_ARM64_)
818 void CheckOpsize(BYTE b1)
820 } // nothing to do; all instructions are 4 bytes
821 #endif // defined(_TARGET_ARM64_)
823 void Dump(bool isHotCode, int indent = 0);
830 void AddFragment(emitLocation* emitLoc);
832 // No copy constructor or operator=
833 UnwindInfo(const UnwindInfo& info);
834 UnwindInfo& operator=(const UnwindInfo&);
840 UnwindFragmentInfo uwiFragmentFirst; // The first fragment is directly here, so it doesn't need to be separately
842 UnwindFragmentInfo* uwiFragmentLast; // The last entry in the fragment list (the last fragment added)
843 emitLocation* uwiEndLoc; // End emitter location of this function/funclet (NULL == end of all code)
844 emitLocation* uwiCurLoc; // The current emitter location (updated after an unwind code is added), used for NOP
845 // padding, and asserts.
849 static const unsigned UWI_INITIALIZED_PATTERN = 0x0FACADE1; // Something unlikely to be the fill pattern for
850 // uninitialized memory
851 unsigned uwiInitialized;
858 // Forward declaration
859 void DumpUnwindInfo(Compiler* comp,
861 UNATIVE_OFFSET startOffset,
862 UNATIVE_OFFSET endOffset,
863 const BYTE* const pHeader,
864 ULONG unwindBlockSize);
868 #endif // _TARGET_ARMARCH_