| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "ParserPch.h"
- #if DEBUG
- #define DEBUG_TRASHMEM(pv, cb) memset(pv, 0xbc, cb)
- #else
- #define DEBUG_TRASHMEM
- #endif //DEBUG
- #if TARGET_64
- struct __ALIGN_FOO__ {
- int w1;
- double dbl;
- };
- #define ALIGN_FULL (offsetof(__ALIGN_FOO__, dbl))
- #else
- // Force check for 4 byte alignment to support Win98/ME
- #define ALIGN_FULL 4
- #endif // TARGET_64
- #define AlignFull(VALUE) (~(~((VALUE) + (ALIGN_FULL-1)) | (ALIGN_FULL-1)))
- NoReleaseAllocator::NoReleaseAllocator(int32 cbFirst, int32 cbMax)
- : m_pblkList(NULL)
- , m_ibCur(0)
- , m_ibMax(0)
- , m_cbMinBlock(cbFirst)
- , m_cbMaxBlock(cbMax)
- #if DEBUG
- , m_cbTotRequested(0)
- , m_cbTotAlloced(0)
- , m_cblk(0)
- , m_cpvBig(0)
- , m_cpvSmall(0)
- #endif
- {
- // require reasonable ranges
- Assert((0 < cbFirst) && (cbFirst < SHRT_MAX/2));
- Assert((0 < cbMax ) && (cbMax < SHRT_MAX));
- }
- void * NoReleaseAllocator::Alloc(int32 cb)
- {
- Assert(cb > 0);
- if (cb <= 0)
- return NULL;
- const int32 kcbHead = AlignFull(sizeof(NoReleaseAllocator::NraBlock));
- void * pv;
- if (cb > m_ibMax - m_ibCur)
- {
- int32 cbBlock;
- int32 cbAlloc;
- NraBlock * pblk;
- if (cb >= m_cbMaxBlock)
- {
- // check for integer overflow before allocating (See WindowsSE #88972)
- cbAlloc = cb + kcbHead;
- if (cbAlloc < cb)
- {
- Assert(FALSE); // too big!
- return NULL;
- }
- // create a chunk just for this allocation
- pblk = (NraBlock *)malloc(cbAlloc);
- if (NULL == pblk)
- return NULL;
- #if DEBUG
- m_cbTotAlloced += cbAlloc;
- m_cbTotRequested += cb;
- m_cpvBig++;
- m_cblk++;
- #endif //DEBUG
- if (m_ibCur < m_ibMax)
- {
- // There is still room in current block, so put the new block
- // after the current block.
- pblk->pblkNext = m_pblkList->pblkNext;
- m_pblkList->pblkNext = pblk;
- }
- else
- {
- // Link into front of the list.
- // Don't need to adjust m_ibCur and m_ibMax, because they
- // already have the correct relationship for this full block
- // (m_ibCur >= m_ibMax) and the actual values will not be
- // used.
- pblk->pblkNext = m_pblkList;
- m_pblkList = pblk;
- }
- DEBUG_TRASHMEM((byte *)pblk + kcbHead, cb);
- return (byte *)pblk + kcbHead;
- }
- cbBlock = cb; // requested size
- if (m_ibMax > cbBlock) // at least current block size
- cbBlock = m_ibMax;
- cbBlock += cbBlock; // *2 (can overflow, but checked below)
- if (m_cbMinBlock > cbBlock) // at least minimum size
- cbBlock = m_cbMinBlock;
- if (cbBlock > m_cbMaxBlock) // no larger than the max
- cbBlock = m_cbMaxBlock;
- if (cb > cbBlock) // guarantee it's big enough
- {
- Assert(("Request too large", FALSE));
- return NULL;
- }
- // check for integer overflow before allocating (See WindowsSE #88972)
- cbAlloc = cbBlock + kcbHead;
- if ((cbAlloc < cbBlock) || (cbAlloc < cb))
- {
- Assert(FALSE); // too big!
- return NULL ;
- }
- // allocate a new block
- pblk = (NraBlock *)malloc(cbAlloc);
- #ifdef MEM_TRACK
- RegisterAlloc((char*)pblk,cbAlloc);
- #endif
- if (NULL == pblk)
- return NULL;
- #if DEBUG
- m_cbTotAlloced += cbAlloc;
- m_cblk++;
- #endif //DEBUG
- pblk->pblkNext = m_pblkList;
- m_pblkList = pblk;
- m_ibMax = cbBlock;
- m_ibCur = 0;
- }
- Assert(m_ibCur + cb <= m_ibMax);
- #if DEBUG
- m_cbTotRequested += cb;
- m_cpvSmall++;
- #endif //DEBUG
- pv = (byte *)m_pblkList + kcbHead + m_ibCur;
- DEBUG_TRASHMEM(pv, cb);
- m_ibCur += (int32)AlignFull(cb);
- Assert(m_ibCur >= 0);
- return pv;
- }
- void NoReleaseAllocator::FreeAll(void)
- {
- // Free all of the allocated blocks
- while (NULL != m_pblkList)
- {
- NraBlock * pblk = m_pblkList;
- #pragma prefast(suppress:6001, "Not sure why it is complaining *m_plkList is uninitialized")
- m_pblkList = pblk->pblkNext;
- free(pblk);
- }
- // prepare for next round of allocations
- m_ibCur = m_ibMax = 0;
- #if DEBUG
- m_cbTotRequested = 0;
- m_cbTotAlloced = 0;
- m_cblk = 0;
- m_cpvBig = 0;
- m_cpvSmall = 0;
- #endif
- }
|