diff options
author | Carol Eidt <carol.eidt@microsoft.com> | 2018-03-30 16:46:05 -0700 |
---|---|---|
committer | Carol Eidt <carol.eidt@microsoft.com> | 2018-03-30 16:46:05 -0700 |
commit | 2fbbf62d365fec4d778d7342908ddbb3f924a2eb (patch) | |
tree | 70ecd0fbde5fddb480c053b73c3968d6bb1fbe7c | |
parent | 757cb82a5800fd043713d7ee40feba1dd2c89793 (diff) | |
download | coreclr-2fbbf62d365fec4d778d7342908ddbb3f924a2eb.tar.gz coreclr-2fbbf62d365fec4d778d7342908ddbb3f924a2eb.tar.bz2 coreclr-2fbbf62d365fec4d778d7342908ddbb3f924a2eb.zip |
GC info fix: correctly adjust argCnt
When there are nested calls, and there is a non-ptr on the stack below the last ptr popped by the inner call, the `argHigh` and `argCnt` values can get out of sync.
-rw-r--r-- | src/vm/eetwain.cpp | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp index fcaa010895..1fb332ecd4 100644 --- a/src/vm/eetwain.cpp +++ b/src/vm/eetwain.cpp @@ -2402,6 +2402,11 @@ FINISHED: this function is called to find all live objects (pushed arguments) and to get the stack base for fully interruptible methods. Returns size of things pushed on the stack for ESP frames + + Arguments: + table - The pointer table + curOffs - The current code offset + info - Incoming arg used to determine if there's a frame, and to save results */ static @@ -2416,14 +2421,14 @@ unsigned scanArgRegTableI(PTR_CBYTE table, } CONTRACTL_END; regNum thisPtrReg = REGI_NA; - unsigned ptrRegs = 0; - unsigned iptrRegs = 0; - unsigned ptrOffs = 0; - unsigned argCnt = 0; + unsigned ptrRegs = 0; // The mask of registers that contain pointers + unsigned iptrRegs = 0; // The subset of ptrRegs that are interior pointers + unsigned ptrOffs = 0; // The code offset of the table entry we are currently looking at + unsigned argCnt = 0; // The number of args that have been pushed - ptrArgTP ptrArgs(0); - ptrArgTP iptrArgs(0); - ptrArgTP argHigh(0); + ptrArgTP ptrArgs(0); // The mask of stack values that contain pointers. + ptrArgTP iptrArgs(0); // The subset of ptrArgs that are interior pointers. + ptrArgTP argHigh(0); // The current mask position that corresponds to the top of the stack. bool isThis = false; bool iptr = false; @@ -2659,8 +2664,14 @@ unsigned scanArgRegTableI(PTR_CBYTE table, if (hasPartialArgInfo) { + // We always leave argHigh pointing to the next ptr arg. + // So, while argHigh is non-zero, and not a ptrArg, we shift right (and subtract + // one arg from our argCnt) until it is a ptrArg. while (!intersect(argHigh, ptrArgs) && (!isZero(argHigh))) + { argHigh >>= 1; + argCnt--; + } } } |