Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / unwind.h
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.
4
5 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 XX                                                                           XX
8 XX                              Unwind Info                                  XX
9 XX                                                                           XX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12 */
13
14 #ifdef _TARGET_ARMARCH_
15
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.
21
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_
39
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
48
49 //
50 // Forward declaration of class defined in emit.h
51 //
52
53 class emitLocation;
54
55 //
56 // Forward declarations of classes defined in this file
57 //
58
59 class UnwindCodesBase;
60 class UnwindPrologCodes;
61 class UnwindEpilogCodes;
62 class UnwindEpilogInfo;
63 class UnwindFragmentInfo;
64 class UnwindInfo;
65
66 // UnwindBase: A base class shared by the the unwind classes that require
67 // a Compiler* for memory allocation.
68
69 class UnwindBase
70 {
71 protected:
72     UnwindBase(Compiler* comp) : uwiComp(comp)
73     {
74     }
75
76     UnwindBase()
77     {
78     }
79     ~UnwindBase()
80     {
81     }
82
83 // TODO: How do we get the ability to access uwiComp without error on Clang?
84 #if defined(DEBUG) && !defined(__GNUC__)
85
86     template <typename T>
87     T dspPtr(T p)
88     {
89         return uwiComp->dspPtr(p);
90     }
91
92     template <typename T>
93     T dspOffset(T o)
94     {
95         return uwiComp->dspOffset(o);
96     }
97
98     static char* dspBool(bool b)
99     {
100         return (b) ? "true" : "false";
101     }
102
103 #endif // DEBUG
104
105     //
106     // Data
107     //
108
109     Compiler* uwiComp;
110 };
111
112 // UnwindCodesBase: A base class shared by the the classes used to represent the prolog
113 // and epilog unwind codes.
114
115 class UnwindCodesBase
116 {
117 public:
118     // Add a single unwind code.
119
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;
124
125     // Get access to the unwind codes
126
127     virtual BYTE* GetCodes() = 0;
128
129     bool IsEndCode(BYTE b)
130     {
131 #if defined(_TARGET_ARM_)
132         return b >= 0xFD;
133 #elif defined(_TARGET_ARM64_)
134         return (b == UWC_END); // TODO-ARM64-Bug?: what about the "end_c" code?
135 #endif // _TARGET_ARM64_
136     }
137
138 #ifdef DEBUG
139
140     unsigned GetCodeSizeFromUnwindCodes(bool isProlog);
141
142 #endif // DEBUG
143 };
144
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.
151
152 class UnwindPrologCodes : public UnwindBase, public UnwindCodesBase
153 {
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:
156     //     <=16  79%
157     //     <=24  96%
158     //     <=32  99%
159     // From this data, we choose to use 24.
160
161     static const int UPC_LOCAL_COUNT = 24;
162
163 public:
164     UnwindPrologCodes(Compiler* comp)
165         : UnwindBase(comp)
166         , upcMem(upcMemLocal)
167         , upcMemSize(UPC_LOCAL_COUNT)
168         , upcCodeSlot(UPC_LOCAL_COUNT)
169         , upcHeaderSlot(-1)
170         , upcEpilogSlot(-1)
171     {
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.
176         PushByte(UWC_END);
177         PushByte(UWC_END);
178         PushByte(UWC_END);
179         PushByte(UWC_END);
180     }
181
182     //
183     // Implementation of UnwindCodesBase
184     //
185
186     virtual void AddCode(BYTE b1)
187     {
188         PushByte(b1);
189     }
190
191     virtual void AddCode(BYTE b1, BYTE b2)
192     {
193         PushByte(b2);
194         PushByte(b1);
195     }
196
197     virtual void AddCode(BYTE b1, BYTE b2, BYTE b3)
198     {
199         PushByte(b3);
200         PushByte(b2);
201         PushByte(b1);
202     }
203
204     virtual void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
205     {
206         PushByte(b4);
207         PushByte(b3);
208         PushByte(b2);
209         PushByte(b1);
210     }
211
212     // Return a pointer to the first unwind code byte
213     virtual BYTE* GetCodes()
214     {
215         assert(upcCodeSlot < upcMemSize); // There better be at least one code!
216         return &upcMem[upcCodeSlot];
217     }
218
219     ///////////////////////////////////////////////////////////////////////////
220
221     BYTE GetByte(int index)
222     {
223         assert(upcCodeSlot <= index && index < upcMemSize);
224         return upcMem[index];
225     }
226
227     // Push a single byte on the unwind code stack
228     void PushByte(BYTE b)
229     {
230         if (upcCodeSlot == 0)
231         {
232             // We've run out of space! Reallocate, and copy everything to a new array.
233             EnsureSize(upcMemSize + 1);
234         }
235
236         --upcCodeSlot;
237         noway_assert(0 <= upcCodeSlot && upcCodeSlot < upcMemSize);
238
239         upcMem[upcCodeSlot] = b;
240     }
241
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.
244     int Size()
245     {
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;
248     }
249
250     void SetFinalSize(int headerBytes, int epilogBytes);
251
252     void AddHeaderWord(DWORD d);
253
254     void GetFinalInfo(/* OUT */ BYTE** ppUnwindBlock, /* OUT */ ULONG* pUnwindBlockSize);
255
256     // AppendEpilog: copy the epilog bytes to the next epilog bytes slot
257     void AppendEpilog(UnwindEpilogInfo* pEpi);
258
259     // Match the prolog codes to a set of epilog codes
260     int Match(UnwindEpilogInfo* pEpi);
261
262     // Copy the prolog codes from another prolog
263     void CopyFrom(UnwindPrologCodes* pCopyFrom);
264
265     UnwindPrologCodes()
266     {
267     }
268     ~UnwindPrologCodes()
269     {
270     }
271
272 #ifdef DEBUG
273     void Dump(int indent = 0);
274 #endif // DEBUG
275
276 private:
277     void EnsureSize(int requiredSize);
278
279     // No copy constructor or operator=
280     UnwindPrologCodes(const UnwindPrologCodes& info);
281     UnwindPrologCodes& operator=(const UnwindPrologCodes&);
282
283     //
284     // Data
285     //
286
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];
290     BYTE* upcMem;
291
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.
294     int upcMemSize;
295
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.
298     int upcCodeSlot;
299
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.
302     int upcHeaderSlot;
303
304     // upcEpilogSlot points to the next epilog location to fill
305     int upcEpilogSlot;
306
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;
310 };
311
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.
315
316 class UnwindEpilogCodes : public UnwindBase, public UnwindCodesBase
317 {
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;
321
322 public:
323     UnwindEpilogCodes(Compiler* comp)
324         : UnwindBase(comp)
325         , uecMem(uecMemLocal)
326         , firstByteOfLastCode(0)
327         , uecMemSize(UEC_LOCAL_COUNT)
328         , uecCodeSlot(-1)
329         , uecFinalized(false)
330     {
331     }
332
333     //
334     // Implementation of UnwindCodesBase
335     //
336
337     virtual void AddCode(BYTE b1)
338     {
339         AppendByte(b1);
340
341         firstByteOfLastCode = b1;
342     }
343
344     virtual void AddCode(BYTE b1, BYTE b2)
345     {
346         AppendByte(b1);
347         AppendByte(b2);
348
349         firstByteOfLastCode = b1;
350     }
351
352     virtual void AddCode(BYTE b1, BYTE b2, BYTE b3)
353     {
354         AppendByte(b1);
355         AppendByte(b2);
356         AppendByte(b3);
357
358         firstByteOfLastCode = b1;
359     }
360
361     virtual void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
362     {
363         AppendByte(b1);
364         AppendByte(b2);
365         AppendByte(b3);
366         AppendByte(b4);
367
368         firstByteOfLastCode = b1;
369     }
370
371     // Return a pointer to the first unwind code byte
372     virtual BYTE* GetCodes()
373     {
374         assert(uecFinalized);
375
376         // Codes start at the beginning
377         return uecMem;
378     }
379
380     ///////////////////////////////////////////////////////////////////////////
381
382     BYTE GetByte(int index)
383     {
384         assert(0 <= index && index <= uecCodeSlot);
385         return uecMem[index];
386     }
387
388     // Add a single byte on the unwind code array
389     void AppendByte(BYTE b)
390     {
391         if (uecCodeSlot == uecMemSize - 1)
392         {
393             // We've run out of space! Reallocate, and copy everything to a new array.
394             EnsureSize(uecMemSize + 1);
395         }
396
397         ++uecCodeSlot;
398         noway_assert(0 <= uecCodeSlot && uecCodeSlot < uecMemSize);
399
400         uecMem[uecCodeSlot] = b;
401     }
402
403     // Return the size of the unwind codes, in bytes. The size is the exact size, not an aligned size.
404     int Size()
405     {
406         if (uecFinalized)
407         {
408             // Add one because uecCodeSlot is 0-based
409             return uecCodeSlot + 1;
410         }
411         else
412         {
413             // Add one because uecCodeSlot is 0-based, and one for an "end" code that isn't stored (yet).
414             return uecCodeSlot + 2;
415         }
416     }
417
418     void FinalizeCodes()
419     {
420         assert(!uecFinalized);
421         noway_assert(0 <= uecCodeSlot && uecCodeSlot < uecMemSize); // There better be at least one code!
422
423         if (!IsEndCode(firstByteOfLastCode)) // If the last code is an end code, we don't need to append one.
424         {
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
427         }
428
429         uecFinalized = true; // With the "end" code in place, now we're done
430
431 #ifdef DEBUG
432         unsigned codeSize = GetCodeSizeFromUnwindCodes(false);
433         assert(codeSize <= MAX_EPILOG_SIZE_BYTES);
434 #endif // DEBUG
435     }
436
437     UnwindEpilogCodes()
438     {
439     }
440     ~UnwindEpilogCodes()
441     {
442     }
443
444 #ifdef DEBUG
445     void Dump(int indent = 0);
446 #endif // DEBUG
447
448 private:
449     void EnsureSize(int requiredSize);
450
451     // No destructor, copy constructor or operator=
452     UnwindEpilogCodes(const UnwindEpilogCodes& info);
453     UnwindEpilogCodes& operator=(const UnwindEpilogCodes&);
454
455     //
456     // Data
457     //
458
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];
462     BYTE* uecMem;
463     BYTE  firstByteOfLastCode;
464
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.
467     int uecMemSize;
468
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.
471     int uecCodeSlot;
472
473     // Is the unwind information finalized? Finalized info has an end code appended.
474     bool uecFinalized;
475 };
476
477 // UnwindEpilogInfo: represents the unwind information for a single epilog sequence. Epilogs for a
478 // single function/funclet are in a linked list.
479
480 class UnwindEpilogInfo : public UnwindBase
481 {
482     friend class UnwindFragmentInfo;
483
484     static const unsigned EPI_ILLEGAL_OFFSET = 0xFFFFFFFF;
485
486 public:
487     UnwindEpilogInfo(Compiler* comp)
488         : UnwindBase(comp)
489         , epiNext(NULL)
490         , epiEmitLocation(NULL)
491         , epiCodes(comp)
492         , epiStartOffset(EPI_ILLEGAL_OFFSET)
493         , epiMatches(false)
494         , epiStartIndex(-1)
495     {
496     }
497
498     void CaptureEmitLocation();
499
500     void FinalizeOffset();
501
502     void FinalizeCodes()
503     {
504         epiCodes.FinalizeCodes();
505     }
506
507     UNATIVE_OFFSET GetStartOffset()
508     {
509         assert(epiStartOffset != EPI_ILLEGAL_OFFSET);
510         return epiStartOffset;
511     }
512
513     int GetStartIndex()
514     {
515         assert(epiStartIndex != -1);
516         return epiStartIndex; // The final "Epilog Start Index" of this epilog's unwind codes
517     }
518
519     void SetStartIndex(int index)
520     {
521         assert(epiStartIndex == -1);
522         epiStartIndex = (int)index;
523     }
524
525     void SetMatches()
526     {
527         epiMatches = true;
528     }
529
530     bool Matches()
531     {
532         return epiMatches;
533     }
534
535     // Size of epilog unwind codes in bytes
536     int Size()
537     {
538         return epiCodes.Size();
539     }
540
541     // Return a pointer to the first unwind code byte
542     BYTE* GetCodes()
543     {
544         return epiCodes.GetCodes();
545     }
546
547     // Match the codes to a set of epilog codes
548     int Match(UnwindEpilogInfo* pEpi);
549
550     UnwindEpilogInfo()
551     {
552     }
553     ~UnwindEpilogInfo()
554     {
555     }
556
557 #ifdef DEBUG
558     void Dump(int indent = 0);
559 #endif // DEBUG
560
561 private:
562     // No copy constructor or operator=
563     UnwindEpilogInfo(const UnwindEpilogInfo& info);
564     UnwindEpilogInfo& operator=(const UnwindEpilogInfo&);
565
566     //
567     // Data
568     //
569
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
574                                       // FinalizeOffset().
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
578 };
579
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.
583
584 class UnwindFragmentInfo : public UnwindBase
585 {
586     friend class UnwindInfo;
587
588     static const unsigned UFI_ILLEGAL_OFFSET = 0xFFFFFFFF;
589
590 public:
591     UnwindFragmentInfo(Compiler* comp, emitLocation* emitLoc, bool hasPhantomProlog);
592
593     void FinalizeOffset();
594
595     UNATIVE_OFFSET GetStartOffset()
596     {
597         assert(ufiStartOffset != UFI_ILLEGAL_OFFSET);
598         return ufiStartOffset;
599     }
600
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.
603
604     void AddCode(BYTE b1)
605     {
606         assert(ufiInitialized == UFI_INITIALIZED_PATTERN);
607         ufiCurCodes->AddCode(b1);
608     }
609
610     void AddCode(BYTE b1, BYTE b2)
611     {
612         assert(ufiInitialized == UFI_INITIALIZED_PATTERN);
613         ufiCurCodes->AddCode(b1, b2);
614     }
615
616     void AddCode(BYTE b1, BYTE b2, BYTE b3)
617     {
618         assert(ufiInitialized == UFI_INITIALIZED_PATTERN);
619         ufiCurCodes->AddCode(b1, b2, b3);
620     }
621
622     void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
623     {
624         assert(ufiInitialized == UFI_INITIALIZED_PATTERN);
625         ufiCurCodes->AddCode(b1, b2, b3, b4);
626     }
627
628     unsigned EpilogCount()
629     {
630         unsigned count = 0;
631         for (UnwindEpilogInfo* pEpi = ufiEpilogList; pEpi != NULL; pEpi = pEpi->epiNext)
632         {
633             ++count;
634         }
635         return count;
636     }
637
638     void AddEpilog();
639
640     void MergeCodes();
641
642     void CopyPrologCodes(UnwindFragmentInfo* pCopyFrom);
643
644     void SplitEpilogCodes(emitLocation* emitLoc, UnwindFragmentInfo* pSplitFrom);
645
646     bool IsAtFragmentEnd(UnwindEpilogInfo* pEpi);
647
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.
650     // Size is in bytes.
651     ULONG Size()
652     {
653         assert(ufiSize != 0);
654         return ufiSize;
655     }
656
657     void Finalize(UNATIVE_OFFSET functionLength);
658
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)
661     {
662         ufiPrologCodes.GetFinalInfo(ppUnwindBlock, pUnwindBlockSize);
663     }
664
665     void Reserve(BOOL isFunclet, bool isHotCode);
666
667     void Allocate(
668         CorJitFuncKind funKind, void* pHotCode, void* pColdCode, UNATIVE_OFFSET funcEndOffset, bool isHotCode);
669
670     UnwindFragmentInfo()
671     {
672     }
673     ~UnwindFragmentInfo()
674     {
675     }
676
677 #ifdef DEBUG
678     void Dump(int indent = 0);
679 #endif // DEBUG
680
681 private:
682     // No copy constructor or operator=
683     UnwindFragmentInfo(const UnwindFragmentInfo& info);
684     UnwindFragmentInfo& operator=(const UnwindFragmentInfo&);
685
686     //
687     // Data
688     //
689
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
702
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
706     bool           ufiSetEBit;
707     bool           ufiNeedExtendedCodeWordsEpilogCount;
708     unsigned       ufiCodeWords;
709     unsigned       ufiEpilogScopes;
710     UNATIVE_OFFSET ufiStartOffset;
711
712 #ifdef DEBUG
713
714     unsigned ufiNum;
715
716     // Are we processing the prolog? The prolog must come first, followed by a (possibly empty)
717     // set of epilogs, for this function/funclet.
718     bool ufiInProlog;
719
720     static const unsigned UFI_INITIALIZED_PATTERN = 0x0FACADE0; // Something unlikely to be the fill pattern for
721                                                                 // uninitialized memory
722     unsigned ufiInitialized;
723
724 #endif // DEBUG
725 };
726
727 // UnwindInfo: represents all the unwind information for a single function or funclet
728
729 class UnwindInfo : public UnwindBase
730 {
731 public:
732     void InitUnwindInfo(Compiler* comp, emitLocation* startLoc, emitLocation* endLoc);
733
734     void HotColdSplitCodes(UnwindInfo* puwi);
735
736     // The following act on all the fragments that make up the unwind info for this function or funclet.
737
738     void Split();
739
740     static void EmitSplitCallback(void* context, emitLocation* emitLoc);
741
742     void Reserve(BOOL isFunclet, bool isHotCode);
743
744     void Allocate(CorJitFuncKind funKind, void* pHotCode, void* pColdCode, bool isHotCode);
745
746     // The following act on the current fragment (the one pointed to by 'uwiFragmentLast').
747
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.
750
751     void AddCode(BYTE b1)
752     {
753         assert(uwiInitialized == UWI_INITIALIZED_PATTERN);
754         assert(uwiFragmentLast != NULL);
755         INDEBUG(CheckOpsize(b1));
756
757         uwiFragmentLast->AddCode(b1);
758         CaptureLocation();
759     }
760
761     void AddCode(BYTE b1, BYTE b2)
762     {
763         assert(uwiInitialized == UWI_INITIALIZED_PATTERN);
764         assert(uwiFragmentLast != NULL);
765         INDEBUG(CheckOpsize(b1));
766
767         uwiFragmentLast->AddCode(b1, b2);
768         CaptureLocation();
769     }
770
771     void AddCode(BYTE b1, BYTE b2, BYTE b3)
772     {
773         assert(uwiInitialized == UWI_INITIALIZED_PATTERN);
774         assert(uwiFragmentLast != NULL);
775         INDEBUG(CheckOpsize(b1));
776
777         uwiFragmentLast->AddCode(b1, b2, b3);
778         CaptureLocation();
779     }
780
781     void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
782     {
783         assert(uwiInitialized == UWI_INITIALIZED_PATTERN);
784         assert(uwiFragmentLast != NULL);
785         INDEBUG(CheckOpsize(b1));
786
787         uwiFragmentLast->AddCode(b1, b2, b3, b4);
788         CaptureLocation();
789     }
790
791     void AddEpilog();
792
793     emitLocation* GetCurrentEmitterLocation()
794     {
795         return uwiCurLoc;
796     }
797
798 #if defined(_TARGET_ARM_)
799     unsigned GetInstructionSize();
800 #endif // defined(_TARGET_ARM_)
801
802     void CaptureLocation();
803
804     UnwindInfo()
805     {
806     }
807     ~UnwindInfo()
808     {
809     }
810
811 #ifdef DEBUG
812
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)
819     {
820     } // nothing to do; all instructions are 4 bytes
821 #endif // defined(_TARGET_ARM64_)
822
823     void Dump(bool isHotCode, int indent = 0);
824
825     bool uwiAddingNOP;
826
827 #endif // DEBUG
828
829 private:
830     void AddFragment(emitLocation* emitLoc);
831
832     // No copy constructor or operator=
833     UnwindInfo(const UnwindInfo& info);
834     UnwindInfo& operator=(const UnwindInfo&);
835
836     //
837     // Data
838     //
839
840     UnwindFragmentInfo uwiFragmentFirst; // The first fragment is directly here, so it doesn't need to be separately
841                                          // allocated.
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.
846
847 #ifdef DEBUG
848
849     static const unsigned UWI_INITIALIZED_PATTERN = 0x0FACADE1; // Something unlikely to be the fill pattern for
850                                                                 // uninitialized memory
851     unsigned uwiInitialized;
852
853 #endif // DEBUG
854 };
855
856 #ifdef DEBUG
857
858 // Forward declaration
859 void DumpUnwindInfo(Compiler*         comp,
860                     bool              isHotCode,
861                     UNATIVE_OFFSET    startOffset,
862                     UNATIVE_OFFSET    endOffset,
863                     const BYTE* const pHeader,
864                     ULONG             unwindBlockSize);
865
866 #endif // DEBUG
867
868 #endif // _TARGET_ARMARCH_