@@ -92,10 +92,15 @@ template <typename GcInfoEncoding> bool TGcInfoDecoder<GcInfoEncoding>::SetIsInt
92
92
// returns true if we decoded all that was asked;
93
93
template <typename GcInfoEncoding> bool TGcInfoDecoder<GcInfoEncoding>::PredecodeFatHeader(int remainingFlags)
94
94
{
95
- int numFlagBits = (m_Version == 1 ) ? GC_INFO_FLAGS_BIT_SIZE_VERSION_1 : GC_INFO_FLAGS_BIT_SIZE;
96
- m_headerFlags = (GcInfoHeaderFlags)m_Reader.Read (numFlagBits);
95
+ m_headerFlags = (GcInfoHeaderFlags)m_Reader.Read (GC_INFO_FLAGS_BIT_SIZE);
97
96
98
- remainingFlags &= ~DECODE_VARARG;
97
+ #ifdef DECODE_OLD_FORMATS
98
+ if (Version () < 4 )
99
+ {
100
+ m_ReturnKind = (ReturnKind)((UINT32)m_Reader.Read (GcInfoEncoding::SIZE_OF_RETURN_KIND_IN_FAT_HEADER));
101
+ }
102
+ #endif
103
+ remainingFlags &= ~(DECODE_RETURN_KIND | DECODE_VARARG);
99
104
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
100
105
remainingFlags &= ~DECODE_HAS_TAILCALLS;
101
106
#endif
@@ -117,21 +122,21 @@ template <typename GcInfoEncoding> bool TGcInfoDecoder<GcInfoEncoding>::Predecod
117
122
{
118
123
// Note that normalization as a code offset can be different than
119
124
// normalization as code length
120
- UINT32 normCodeLength = GcInfoEncoding::NORMALIZE_CODE_OFFSET (m_CodeLength);
125
+ UINT32 normCodeLength = NormalizeCodeOffset (m_CodeLength);
121
126
122
127
// Decode prolog/epilog information
123
128
UINT32 normPrologSize = (UINT32)m_Reader.DecodeVarLengthUnsigned (GcInfoEncoding::NORM_PROLOG_SIZE_ENCBASE) + 1 ;
124
129
UINT32 normEpilogSize = (UINT32)m_Reader.DecodeVarLengthUnsigned (GcInfoEncoding::NORM_EPILOG_SIZE_ENCBASE);
125
130
126
- m_ValidRangeStart = GcInfoEncoding::DENORMALIZE_CODE_OFFSET (normPrologSize);
127
- m_ValidRangeEnd = GcInfoEncoding::DENORMALIZE_CODE_OFFSET (normCodeLength - normEpilogSize);
131
+ m_ValidRangeStart = DenormalizeCodeOffset (normPrologSize);
132
+ m_ValidRangeEnd = DenormalizeCodeOffset (normCodeLength - normEpilogSize);
128
133
_ASSERTE (m_ValidRangeStart < m_ValidRangeEnd);
129
134
}
130
135
else if ((m_headerFlags & GC_INFO_HAS_GENERICS_INST_CONTEXT_MASK) != GC_INFO_HAS_GENERICS_INST_CONTEXT_NONE)
131
136
{
132
137
// Decode prolog information
133
138
UINT32 normPrologSize = (UINT32)m_Reader.DecodeVarLengthUnsigned (GcInfoEncoding::NORM_PROLOG_SIZE_ENCBASE) + 1 ;
134
- m_ValidRangeStart = GcInfoEncoding::DENORMALIZE_CODE_OFFSET (normPrologSize);
139
+ m_ValidRangeStart = DenormalizeCodeOffset (normPrologSize);
135
140
// satisfy asserts that assume m_GSCookieValidRangeStart != 0 ==> m_GSCookieValidRangeStart < m_GSCookieValidRangeEnd
136
141
m_ValidRangeEnd = m_ValidRangeStart + 1 ;
137
142
}
@@ -262,6 +267,7 @@ TGcInfoDecoder<GcInfoEncoding>::TGcInfoDecoder(
262
267
: m_Reader(dac_cast<PTR_CBYTE>(gcInfoToken.Info))
263
268
, m_InstructionOffset(breakOffset)
264
269
, m_IsInterruptible(false )
270
+ , m_ReturnKind(RT_Illegal)
265
271
#ifdef _DEBUG
266
272
, m_Flags( flags )
267
273
, m_GcInfoAddress(dac_cast<PTR_CBYTE>(gcInfoToken.Info))
@@ -301,7 +307,13 @@ TGcInfoDecoder<GcInfoEncoding>::TGcInfoDecoder(
301
307
m_StackBaseRegister = NO_STACK_BASE_REGISTER;
302
308
}
303
309
304
- remainingFlags &= ~DECODE_VARARG;
310
+ #ifdef DECODE_OLD_FORMATS
311
+ if (Version () < 4 )
312
+ {
313
+ m_ReturnKind = (ReturnKind)((UINT32)m_Reader.Read (GcInfoEncoding::SIZE_OF_RETURN_KIND_IN_SLIM_HEADER));
314
+ }
315
+ #endif
316
+ remainingFlags &= ~(DECODE_RETURN_KIND | DECODE_VARARG);
305
317
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
306
318
remainingFlags &= ~DECODE_HAS_TAILCALLS;
307
319
#endif
@@ -369,14 +381,25 @@ TGcInfoDecoder<GcInfoEncoding>::TGcInfoDecoder(
369
381
{
370
382
if (m_NumSafePoints)
371
383
{
384
+ #ifdef DECODE_OLD_FORMATS
385
+ if (Version () < 4 )
386
+ {
387
+ // Safepoints are encoded with a -1 adjustment
388
+ // DECODE_GC_LIFETIMES adjusts the offset accordingly, but DECODE_INTERRUPTIBILITY does not
389
+ // adjust here
390
+ UINT32 offset = flags & DECODE_INTERRUPTIBILITY ? m_InstructionOffset - 1 : m_InstructionOffset;
391
+ m_SafePointIndex = FindSafePoint (offset);
392
+ }
393
+ #else
372
394
m_SafePointIndex = FindSafePoint (m_InstructionOffset);
395
+ #endif
373
396
}
374
397
}
375
398
else if (flags & DECODE_FOR_RANGES_CALLBACK)
376
399
{
377
400
// Note that normalization as a code offset can be different than
378
401
// normalization as code length
379
- UINT32 normCodeLength = GcInfoEncoding::NORMALIZE_CODE_OFFSET (m_CodeLength);
402
+ UINT32 normCodeLength = NormalizeCodeOffset (m_CodeLength);
380
403
381
404
UINT32 numBitsPerOffset = CeilOfLog2 (normCodeLength);
382
405
m_Reader.Skip (m_NumSafePoints * numBitsPerOffset);
@@ -445,6 +468,14 @@ template <typename GcInfoEncoding> bool TGcInfoDecoder<GcInfoEncoding>::IsSafePo
445
468
if (m_NumSafePoints == 0 )
446
469
return false ;
447
470
471
+ #ifdef DECODE_OLD_FORMATS
472
+ if (Version () < 4 )
473
+ {
474
+ // Safepoints are encoded with a -1 adjustment, adjust before searching.
475
+ codeOffset--;
476
+ }
477
+ #endif
478
+
448
479
size_t savedPos = m_Reader.GetCurrentPos ();
449
480
UINT32 safePointIndex = FindSafePoint (codeOffset);
450
481
m_Reader.SetCurrentPos (savedPos);
@@ -466,7 +497,7 @@ UINT32 TGcInfoDecoder<GcInfoEncoding>::NarrowSafePointSearch(size_t savedPos, UI
466
497
INT32 low = 0 ;
467
498
INT32 high = (INT32)m_NumSafePoints;
468
499
469
- const UINT32 numBitsPerOffset = CeilOfLog2 (GcInfoEncoding::NORMALIZE_CODE_OFFSET (m_CodeLength));
500
+ const UINT32 numBitsPerOffset = CeilOfLog2 (NormalizeCodeOffset (m_CodeLength));
470
501
while (high - low > MAX_LINEAR_SEARCH)
471
502
{
472
503
const INT32 mid = (low + high) / 2 ;
@@ -490,9 +521,9 @@ template <typename GcInfoEncoding> UINT32 TGcInfoDecoder<GcInfoEncoding>::FindSa
490
521
_ASSERTE (m_NumSafePoints > 0 );
491
522
UINT32 result = m_NumSafePoints;
492
523
const size_t savedPos = m_Reader.GetCurrentPos ();
493
- const UINT32 numBitsPerOffset = CeilOfLog2 (GcInfoEncoding::NORMALIZE_CODE_OFFSET (m_CodeLength));
524
+ const UINT32 numBitsPerOffset = CeilOfLog2 (NormalizeCodeOffset (m_CodeLength));
494
525
495
- const UINT32 normBreakOffset = GcInfoEncoding::NORMALIZE_CODE_OFFSET (breakOffset);
526
+ const UINT32 normBreakOffset = NormalizeCodeOffset (breakOffset);
496
527
UINT32 linearSearchStart = 0 ;
497
528
UINT32 linearSearchEnd = m_NumSafePoints;
498
529
if (linearSearchEnd - linearSearchStart > MAX_LINEAR_SEARCH)
@@ -527,12 +558,21 @@ template <typename GcInfoEncoding> void TGcInfoDecoder<GcInfoEncoding>::Enumerat
527
558
if (m_NumSafePoints == 0 )
528
559
return ;
529
560
530
- const UINT32 numBitsPerOffset = CeilOfLog2 (GcInfoEncoding::NORMALIZE_CODE_OFFSET (m_CodeLength));
561
+ const UINT32 numBitsPerOffset = CeilOfLog2 (NormalizeCodeOffset (m_CodeLength));
531
562
532
563
for (UINT32 i = 0 ; i < m_NumSafePoints; i++)
533
564
{
534
565
UINT32 normOffset = (UINT32)m_Reader.Read (numBitsPerOffset);
535
- UINT32 offset = GcInfoEncoding::DENORMALIZE_CODE_OFFSET (normOffset);
566
+ UINT32 offset = DenormalizeCodeOffset (normOffset);
567
+
568
+ #ifdef DECODE_OLD_FORMATS
569
+ if (Version () < 4 )
570
+ {
571
+ // Safepoints are encoded with a -1 adjustment, adjust before reporting
572
+ offset++;
573
+ }
574
+ #endif
575
+
536
576
pCallback (this , offset, hCallback);
537
577
}
538
578
}
@@ -555,8 +595,8 @@ template <typename GcInfoEncoding> void TGcInfoDecoder<GcInfoEncoding>::Enumerat
555
595
UINT32 rangeStartOffsetNormalized = lastInterruptibleRangeStopOffsetNormalized + normStartDelta;
556
596
UINT32 rangeStopOffsetNormalized = rangeStartOffsetNormalized + normStopDelta;
557
597
558
- UINT32 rangeStartOffset = GcInfoEncoding::DENORMALIZE_CODE_OFFSET (rangeStartOffsetNormalized);
559
- UINT32 rangeStopOffset = GcInfoEncoding::DENORMALIZE_CODE_OFFSET (rangeStopOffsetNormalized);
598
+ UINT32 rangeStartOffset = DenormalizeCodeOffset (rangeStartOffsetNormalized);
599
+ UINT32 rangeStopOffset = DenormalizeCodeOffset (rangeStopOffsetNormalized);
560
600
561
601
bool fStop = pCallback (rangeStartOffset, rangeStopOffset, hCallback);
562
602
if (fStop )
@@ -639,6 +679,13 @@ template <typename GcInfoEncoding> UINT32 TGcInfoDecoder<GcInfoEncoding>::GetCod
639
679
return m_CodeLength;
640
680
}
641
681
682
+ template <typename GcInfoEncoding> ReturnKind TGcInfoDecoder<GcInfoEncoding>::GetReturnKind()
683
+ {
684
+ // SUPPORTS_DAC;
685
+ _ASSERTE (m_Flags & DECODE_RETURN_KIND);
686
+ return m_ReturnKind;
687
+ }
688
+
642
689
template <typename GcInfoEncoding> UINT32 TGcInfoDecoder<GcInfoEncoding>::GetStackBaseRegister()
643
690
{
644
691
return m_StackBaseRegister;
@@ -702,7 +749,7 @@ template <typename GcInfoEncoding> bool TGcInfoDecoder<GcInfoEncoding>::Enumerat
702
749
703
750
GcSlotDecoder<GcInfoEncoding> slotDecoder;
704
751
705
- UINT32 normBreakOffset = GcInfoEncoding::NORMALIZE_CODE_OFFSET (m_InstructionOffset);
752
+ UINT32 normBreakOffset = NormalizeCodeOffset (m_InstructionOffset);
706
753
707
754
// Normalized break offset
708
755
// Relative to interruptible ranges #if PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
0 commit comments