@@ -2404,14 +2404,16 @@ unsigned scanArgRegTable(PTR_CBYTE table,
2404
2404
Returns size of things pushed on the stack for ESP frames
2405
2405
2406
2406
Arguments:
2407
- table - The pointer table
2408
- curOffs - The current code offset
2409
- info - Incoming arg used to determine if there's a frame, and to save results
2407
+ table - The pointer table
2408
+ curOffsRegs - The current code offset that should be used for reporting registers
2409
+ curOffsArgs - The current code offset that should be used for reporting args
2410
+ info - Incoming arg used to determine if there's a frame, and to save results
2410
2411
*/
2411
2412
2412
2413
static
2413
- unsigned scanArgRegTableI (PTR_CBYTE table,
2414
- unsigned curOffs,
2414
+ unsigned scanArgRegTableI (PTR_CBYTE table,
2415
+ unsigned curOffsRegs,
2416
+ unsigned curOffsArgs,
2415
2417
hdrInfo * info)
2416
2418
{
2417
2419
CONTRACTL {
@@ -2433,6 +2435,10 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
2433
2435
bool isThis = false ;
2434
2436
bool iptr = false ;
2435
2437
2438
+ // The comment before the call to scanArgRegTableI in EnumGCRefs
2439
+ // describes why curOffsRegs can be smaller than curOffsArgs.
2440
+ _ASSERTE (curOffsRegs <= curOffsArgs);
2441
+
2436
2442
#if VERIFY_GC_TABLES
2437
2443
_ASSERTE (*castto (table, unsigned short *)++ == 0xBABE );
2438
2444
#endif
@@ -2506,7 +2512,7 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
2506
2512
2507
2513
/* Have we reached the instruction we're looking for? */
2508
2514
2509
- while (ptrOffs <= curOffs )
2515
+ while (ptrOffs <= curOffsArgs )
2510
2516
{
2511
2517
unsigned val;
2512
2518
@@ -2543,10 +2549,14 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
2543
2549
regNum reg;
2544
2550
2545
2551
ptrOffs += (val ) & 0x7 ;
2546
- if (ptrOffs > curOffs ) {
2552
+ if (ptrOffs > curOffsArgs ) {
2547
2553
iptr = isThis = false ;
2548
2554
goto REPORT_REFS;
2549
2555
}
2556
+ else if (ptrOffs > curOffsRegs) {
2557
+ iptr = isThis = false ;
2558
+ continue ;
2559
+ }
2550
2560
2551
2561
reg = (regNum)((val >> 3 ) & 0x7 );
2552
2562
regMask = 1 << reg; // EAX,ECX,EDX,EBX,---,EBP,ESI,EDI
@@ -2606,7 +2616,7 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
2606
2616
/* A small argument encoding */
2607
2617
2608
2618
ptrOffs += (val & 0x07 );
2609
- if (ptrOffs > curOffs ) {
2619
+ if (ptrOffs > curOffsArgs ) {
2610
2620
iptr = isThis = false ;
2611
2621
goto REPORT_REFS;
2612
2622
}
@@ -2736,7 +2746,7 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
2736
2746
/* non-ptr arg push */
2737
2747
_ASSERTE (!hasPartialArgInfo);
2738
2748
ptrOffs += (val & 0x07 );
2739
- if (ptrOffs > curOffs ) {
2749
+ if (ptrOffs > curOffsArgs ) {
2740
2750
iptr = isThis = false ;
2741
2751
goto REPORT_REFS;
2742
2752
}
@@ -2858,6 +2868,7 @@ unsigned GetPushedArgSize(hdrInfo * info, PTR_CBYTE table, DWORD curOffs)
2858
2868
if (info->interruptible )
2859
2869
{
2860
2870
sz = scanArgRegTableI (skipToArgReg (*info, table),
2871
+ curOffs,
2861
2872
curOffs,
2862
2873
info);
2863
2874
}
@@ -4436,7 +4447,15 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
4436
4447
4437
4448
if (info.interruptible )
4438
4449
{
4439
- pushedSize = scanArgRegTableI (skipToArgReg (info, table), curOffs, &info);
4450
+ // If we are not on the active stack frame, we need to report gc registers
4451
+ // that are live before the call. The reason is that the liveness of gc registers
4452
+ // may change across a call to a method that does not return. In this case the instruction
4453
+ // after the call may be a jump target and a register that didn't have a live gc pointer
4454
+ // before the call may have a live gc pointer after the jump. To make sure we report the
4455
+ // registers that have live gc pointers before the call we subtract 1 from curOffs.
4456
+ unsigned curOffsRegs = (flags & ActiveStackFrame) != 0 ? curOffs : curOffs - 1 ;
4457
+
4458
+ pushedSize = scanArgRegTableI (skipToArgReg (info, table), curOffsRegs, curOffs, &info);
4440
4459
4441
4460
RegMask regs = info.regMaskResult ;
4442
4461
RegMask iregs = info.iregMaskResult ;
@@ -5342,7 +5361,7 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext,
5342
5361
5343
5362
if (info.interruptible )
5344
5363
{
5345
- stackDepth = scanArgRegTableI (skipToArgReg (info, table), ( unsigned ) relOffset, &info);
5364
+ stackDepth = scanArgRegTableI (skipToArgReg (info, table), relOffset, relOffset, &info);
5346
5365
}
5347
5366
else
5348
5367
{
@@ -6046,6 +6065,7 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext,
6046
6065
if (stateBuf->hdrInfoBody .interruptible )
6047
6066
{
6048
6067
baseSP += scanArgRegTableI (skipToArgReg (stateBuf->hdrInfoBody , table),
6068
+ dwRelOffset,
6049
6069
dwRelOffset,
6050
6070
&stateBuf->hdrInfoBody );
6051
6071
}
0 commit comments