@@ -324,13 +324,17 @@ typedef SimplerHashTable<const BitArray *, LiveStateFuncs, UINT32, GcInfoHashBeh
324
324
// Pi = partially-interruptible; methods with zero fully-interruptible ranges
325
325
GcInfoSize g_FiGcInfoSize;
326
326
GcInfoSize g_PiGcInfoSize;
327
+ // Number of methods with GcInfo that have SlimHeader
328
+ size_t g_NumSlimHeaders = 0 ;
329
+ // Number of methods with GcInfo that have FatHeader
330
+ size_t g_NumFatHeaders = 0 ;
327
331
328
332
GcInfoSize::GcInfoSize ()
329
333
{
330
334
memset (this , 0 , sizeof (*this ));
331
335
}
332
336
333
- GcInfoSize& operator +=(const GcInfoSize& other)
337
+ GcInfoSize& GcInfoSize:: operator +=(const GcInfoSize& other)
334
338
{
335
339
TotalSize += other.TotalSize ;
336
340
@@ -351,7 +355,7 @@ GcInfoSize& operator+=(const GcInfoSize& other)
351
355
GenericsCtxSize += other.GenericsCtxSize ;
352
356
PspSymSize += other.PspSymSize ;
353
357
StackBaseSize += other.StackBaseSize ;
354
- FrameMarkerSize += other.FrameMarkerSize ;
358
+ ReversePInvokeFrameSize += other.ReversePInvokeFrameSize ;
355
359
FixedAreaSize += other.FixedAreaSize ;
356
360
NumCallSitesSize += other.NumCallSitesSize ;
357
361
NumRangesSize += other.NumRangesSize ;
@@ -398,8 +402,9 @@ void GcInfoSize::Log(DWORD level, const char * header)
398
402
LogSpew (LF_GCINFO, level, " GsCookie: %Iu\n " , GsCookieSize);
399
403
LogSpew (LF_GCINFO, level, " PspSym: %Iu\n " , PspSymSize);
400
404
LogSpew (LF_GCINFO, level, " GenericsCtx: %Iu\n " , GenericsCtxSize);
401
- LogSpew (LF_GCINFO, level, " FrameMarker : %Iu\n " , FrameMarkerSize );
405
+ LogSpew (LF_GCINFO, level, " StackBase : %Iu\n " , StackBaseSize );
402
406
LogSpew (LF_GCINFO, level, " FixedArea: %Iu\n " , FixedAreaSize);
407
+ LogSpew (LF_GCINFO, level, " ReversePInvokeFrame: %Iu\n " , ReversePInvokeFrameSize);
403
408
LogSpew (LF_GCINFO, level, " NumCallSites: %Iu\n " , NumCallSitesSize);
404
409
LogSpew (LF_GCINFO, level, " NumRanges: %Iu\n " , NumRangesSize);
405
410
LogSpew (LF_GCINFO, level, " CallSiteOffsets: %Iu\n " , CallSitePosSize);
@@ -488,17 +493,27 @@ GcInfoEncoder::GcInfoEncoder(
488
493
489
494
m_StackBaseRegister = NO_STACK_BASE_REGISTER;
490
495
m_SizeOfEditAndContinuePreservedArea = NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA;
496
+ m_ReversePInvokeFrameSlot = NO_REVERSE_PINVOKE_FRAME;
491
497
m_WantsReportOnlyLeaf = false ;
492
498
m_IsVarArg = false ;
493
499
m_pLastInterruptibleRange = NULL ;
494
500
495
501
#ifdef _DEBUG
496
502
m_IsSlotTableFrozen = FALSE ;
503
+ #endif // _DEBUG
504
+
505
+ #ifndef _TARGET_X86_
506
+ // If the compiler doesn't set the GCInfo, report RT_Unset.
507
+ // This is used for compatibility with JITs that aren't updated to use the new API.
508
+ m_ReturnKind = RT_Unset;
509
+ #else
510
+ m_ReturnKind = RT_Illegal;
511
+ #endif // _TARGET_X86_
497
512
m_CodeLength = 0 ;
498
513
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA
499
514
m_SizeOfStackOutgoingAndScratchArea = -1 ;
500
515
#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA
501
- # endif // _DEBUG
516
+
502
517
}
503
518
504
519
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
@@ -758,14 +773,24 @@ void GcInfoEncoder::SetSizeOfStackOutgoingAndScratchArea( UINT32 size )
758
773
}
759
774
#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA
760
775
776
+ void GcInfoEncoder::SetReversePInvokeFrameSlot (INT32 spOffset)
777
+ {
778
+ m_ReversePInvokeFrameSlot = spOffset;
779
+ }
780
+
781
+ void GcInfoEncoder::SetReturnKind (ReturnKind returnKind)
782
+ {
783
+ _ASSERTE (IsValidReturnKind (returnKind));
784
+
785
+ m_ReturnKind = returnKind;
786
+ }
761
787
762
788
struct GcSlotDescAndId
763
789
{
764
790
GcSlotDesc m_SlotDesc;
765
791
UINT32 m_SlotId;
766
792
};
767
793
768
-
769
794
int __cdecl CompareSlotDescAndIdBySlotDesc (const void * p1, const void * p2)
770
795
{
771
796
const GcSlotDesc* pFirst = &reinterpret_cast <const GcSlotDescAndId*>(p1)->m_SlotDesc ;
@@ -985,20 +1010,26 @@ void GcInfoEncoder::Build()
985
1010
// Method header
986
1011
// /////////////////////////////////////////////////////////////////////
987
1012
1013
+
988
1014
UINT32 hasSecurityObject = (m_SecurityObjectStackSlot != NO_SECURITY_OBJECT);
989
1015
UINT32 hasGSCookie = (m_GSCookieStackSlot != NO_GS_COOKIE);
990
1016
UINT32 hasContextParamType = (m_GenericsInstContextStackSlot != NO_GENERICS_INST_CONTEXT);
1017
+ UINT32 hasReversePInvokeFrame = (m_ReversePInvokeFrameSlot != NO_REVERSE_PINVOKE_FRAME);
991
1018
992
1019
BOOL slimHeader = (!m_IsVarArg && !hasSecurityObject && !hasGSCookie && (m_PSPSymStackSlot == NO_PSP_SYM) &&
993
- !hasContextParamType && !m_WantsReportOnlyLeaf && (m_InterruptibleRanges.Count () == 0 ) &&
1020
+ !hasContextParamType && !m_WantsReportOnlyLeaf && (m_InterruptibleRanges.Count () == 0 ) && !hasReversePInvokeFrame &&
994
1021
((m_StackBaseRegister == NO_STACK_BASE_REGISTER) || (NORMALIZE_STACK_BASE_REGISTER (m_StackBaseRegister) == 0 ))) &&
995
1022
(m_SizeOfEditAndContinuePreservedArea == NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA);
996
1023
1024
+ // All new code is generated for the latest GCINFO_VERSION.
1025
+ // So, always encode RetunrKind and encode ReversePInvokeFrameSlot where applicable.
997
1026
if (slimHeader)
998
1027
{
999
1028
// Slim encoding means nothing special, partially interruptible, maybe a default frame register
1000
1029
GCINFO_WRITE (m_Info1, 0 , 1 , FlagsSize); // Slim encoding
1001
1030
GCINFO_WRITE (m_Info1, (m_StackBaseRegister == NO_STACK_BASE_REGISTER) ? 0 : 1 , 1 , FlagsSize);
1031
+
1032
+ GCINFO_WRITE (m_Info1, m_ReturnKind, SIZE_OF_RETURN_KIND_IN_SLIM_HEADER, RetKindSize);
1002
1033
}
1003
1034
else
1004
1035
{
@@ -1011,6 +1042,9 @@ void GcInfoEncoder::Build()
1011
1042
GCINFO_WRITE (m_Info1, ((m_StackBaseRegister != NO_STACK_BASE_REGISTER) ? 1 : 0 ), 1 , FlagsSize);
1012
1043
GCINFO_WRITE (m_Info1, (m_WantsReportOnlyLeaf ? 1 : 0 ), 1 , FlagsSize);
1013
1044
GCINFO_WRITE (m_Info1, ((m_SizeOfEditAndContinuePreservedArea != NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA) ? 1 : 0 ), 1 , FlagsSize);
1045
+ GCINFO_WRITE (m_Info1, (hasReversePInvokeFrame ? 1 : 0 ), 1 , FlagsSize);
1046
+
1047
+ GCINFO_WRITE (m_Info1, m_ReturnKind, SIZE_OF_RETURN_KIND_IN_FAT_HEADER, RetKindSize);
1014
1048
}
1015
1049
1016
1050
_ASSERTE ( m_CodeLength > 0 );
@@ -1109,6 +1143,12 @@ void GcInfoEncoder::Build()
1109
1143
GCINFO_WRITE_VARL_U (m_Info1, m_SizeOfEditAndContinuePreservedArea, SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE, EncPreservedSlots);
1110
1144
}
1111
1145
1146
+ if (hasReversePInvokeFrame)
1147
+ {
1148
+ _ASSERTE (!slimHeader);
1149
+ GCINFO_WRITE_VARL_S (m_Info1, NORMALIZE_STACK_SLOT (m_ReversePInvokeFrameSlot), REVERSE_PINVOKE_FRAME_ENCBASE, ReversePInvokeFrameSize);
1150
+ }
1151
+
1112
1152
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA
1113
1153
if (!slimHeader)
1114
1154
{
@@ -2305,6 +2345,15 @@ lExitSuccess:;
2305
2345
// -------------------------------------------------------------------
2306
2346
2307
2347
#ifdef MEASURE_GCINFO
2348
+ if (slimHeader)
2349
+ {
2350
+ g_NumSlimHeaders++;
2351
+ }
2352
+ else
2353
+ {
2354
+ g_NumFatHeaders++;
2355
+ }
2356
+
2308
2357
m_CurrentMethodSize.NumMethods = 1 ;
2309
2358
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
2310
2359
m_CurrentMethodSize.NumCallSites = m_NumCallSites;
@@ -2331,6 +2380,8 @@ lExitSuccess:;
2331
2380
m_CurrentMethodSize.Log (LL_INFO100, " === PartiallyInterruptible method breakdown ===\r\n " );
2332
2381
g_PiGcInfoSize.Log (LL_INFO10, " === PartiallyInterruptible global breakdown ===\r\n " );
2333
2382
}
2383
+ LogSpew (LF_GCINFO, LL_INFO10, " Total SlimHeaders: %Iu\n " , g_NumSlimHeaders);
2384
+ LogSpew (LF_GCINFO, LL_INFO10, " NumMethods: %Iu\n " , g_NumFatHeaders);
2334
2385
#endif
2335
2386
}
2336
2387
0 commit comments