Disable object stack allocation verification under GCStress.
authorEugene Rozenfeld <erozen@microsoft.com>
Mon, 19 Nov 2018 21:25:56 +0000 (13:25 -0800)
committerEugene Rozenfeld <erozen@microsoft.com>
Wed, 21 Nov 2018 19:11:50 +0000 (11:11 -0800)
commitd42f6c7a0ff3a18d2495e2527b4ae68825a42e02
treeb66026421f29b31adafd730e4c3c2d8f2df007ed
parenta0cedb51535c87902a8d4de7620bf6b5f62fee28
Disable object stack allocation verification under GCStress.

ObjectStackAllocationTests use GC.GetAllocatedBytesForCurrentThread to
verify object stack allocations. Under GCStress the vm may initiate additional
heap allocations in GCHeap::StressHeap (see the call to 'pGenGCHeap->allocate' below).

This change re-enables ObjectStackAllocationTests and updates then to not verify stack allocations under GCStress.
It's useful to run the tests even without the verification to catch crashes, gc asserts, etc.

```
if (Interlocked::Increment(&OneAtATime) == 0 &&
        !TrackAllocations()) // Messing with object sizes can confuse the profiler (see ICorProfilerInfo::GetObjectSize)
    {
        StringObject* str;

        // If the current string is used up
        if (HndFetchHandle(m_StressObjs[m_CurStressObj]) == 0)
        {
            // Populate handles with strings
            int i = m_CurStressObj;
            while(HndFetchHandle(m_StressObjs[i]) == 0)
            {
                _ASSERTE(m_StressObjs[i] != 0);
                unsigned strLen = (LARGE_OBJECT_SIZE - 32) / sizeof(WCHAR);
                unsigned strSize = PtrAlign(StringObject::GetSize(strLen));

                // update the cached type handle before allocating
                SetTypeHandleOnThreadForAlloc(TypeHandle(g_pStringClass));
                str = (StringObject*) pGenGCHeap->allocate (strSize, acontext);
                if (str)
                {
                    str->SetMethodTable (g_pStringClass);
                    str->SetStringLength (strLen);

                    HndAssignHandle(m_StressObjs[i], ObjectToOBJECTREF(str));
                }
                i = (i + 1) % NUM_HEAP_STRESS_OBJS;
                if (i == m_CurStressObj) break;
            }

            // advance the current handle to the next string
            m_CurStressObj = (m_CurStressObj + 1) % NUM_HEAP_STRESS_OBJS;
        }

        // Get the current string
        str = (StringObject*) OBJECTREFToObject(HndFetchHandle(m_StressObjs[m_CurStressObj]));
        if (str)
        {
            // Chop off the end of the string and form a new object out of it.
            // This will 'free' an object at the begining of the heap, which will
            // force data movement.  Note that we can only do this so many times.
            // before we have to move on to the next string.
            unsigned sizeOfNewObj = (unsigned)Align(min_obj_size * 31);
            if (str->GetStringLength() > sizeOfNewObj / sizeof(WCHAR))
            {
                unsigned sizeToNextObj = (unsigned)Align(size(str));
                uint8_t* freeObj = ((uint8_t*) str) + sizeToNextObj - sizeOfNewObj;
                pGenGCHeap->make_unused_array (freeObj, sizeOfNewObj);
                str->SetStringLength(str->GetStringLength() - (sizeOfNewObj / sizeof(WCHAR)));
            }
            else
            {
                // Let the string itself become garbage.
                // will be realloced next time around
                HndAssignHandle(m_StressObjs[m_CurStressObj], 0);
            }
        }
    }
    Interlocked::Decrement(&OneAtATime);
```

Commit migrated from https://github.com/dotnet/coreclr/commit/5ef00810b53dcb7cbc4f2cb152ca6af971284e82
src/coreclr/tests/src/JIT/opt/ObjectStackAllocation/ObjectStackAllocationTests.cs
src/coreclr/tests/src/JIT/opt/ObjectStackAllocation/ObjectStackAllocationTests.csproj