From 7a7425114c0c3dd8fa2ae5f92181dc6ac9c988f0 Mon Sep 17 00:00:00 2001 From: Pat Gavlin Date: Tue, 8 Mar 2016 13:42:39 -0800 Subject: [PATCH] Move some definitions out of gcinfoencoder.h. There are a number of macros, method bodies, and type definitions that do not need to be in gcinfoencoder.h. Instead, these definitions have been moved into gcinfoencoder.cpp. Commit migrated from https://github.com/dotnet/coreclr/commit/98f288530eaa97a5e8ef5c796e6db24c1ac65f49 --- src/coreclr/src/gcinfo/gcinfoencoder.cpp | 415 +++++++++++++++++++++++++++++ src/coreclr/src/inc/gcinfoencoder.h | 432 +------------------------------ 2 files changed, 424 insertions(+), 423 deletions(-) diff --git a/src/coreclr/src/gcinfo/gcinfoencoder.cpp b/src/coreclr/src/gcinfo/gcinfoencoder.cpp index 4e2b948..cc4bb52 100644 --- a/src/coreclr/src/gcinfo/gcinfoencoder.cpp +++ b/src/coreclr/src/gcinfo/gcinfoencoder.cpp @@ -27,10 +27,278 @@ #include "simplerhash.h" #endif +#ifdef MEASURE_GCINFO +#define GCINFO_WRITE(writer, val, numBits, counter) \ + { \ + writer.Write(val, numBits); \ + m_CurrentMethodSize.counter += numBits; \ + m_CurrentMethodSize.TotalSize += numBits; \ + } +#define GCINFO_WRITE_VARL_U(writer, val, base, counter) \ + { \ + size_t __temp = \ + writer.EncodeVarLengthUnsigned(val, base); \ + m_CurrentMethodSize.counter += __temp; \ + m_CurrentMethodSize.TotalSize += __temp; \ + } +#define GCINFO_WRITE_VARL_S(writer, val, base, counter) \ + { \ + size_t __temp = \ + writer.EncodeVarLengthSigned(val, base); \ + m_CurrentMethodSize.counter += __temp; \ + m_CurrentMethodSize.TotalSize += __temp; \ + } +#define GCINFO_WRITE_VECTOR(writer, vector, counter) \ + { \ + WriteSlotStateVector(writer, vector); \ + for(UINT32 i = 0; i < m_NumSlots; i++) \ + { \ + if(!m_SlotTable[i].IsDeleted() && \ + !m_SlotTable[i].IsUntracked()) \ + { \ + m_CurrentMethodSize.counter++; \ + m_CurrentMethodSize.TotalSize++; \ + } \ + } \ + } +#define GCINFO_WRITE_VAR_VECTOR(writer, vector, baseSkip, baseRun, counter) \ + { \ + size_t __temp = \ + WriteSlotStateVarLengthVector(writer, vector, baseSkip, baseRun); \ + m_CurrentMethodSize.counter += __temp; \ + m_CurrentMethodSize.TotalSize += __temp; \ + } +#else +#define GCINFO_WRITE(writer, val, numBits, counter) \ + writer.Write(val, numBits); + +#define GCINFO_WRITE_VARL_U(writer, val, base, counter) \ + writer.EncodeVarLengthUnsigned(val, base); + +#define GCINFO_WRITE_VARL_S(writer, val, base, counter) \ + writer.EncodeVarLengthSigned(val, base); + +#define GCINFO_WRITE_VECTOR(writer, vector, counter) \ + WriteSlotStateVector(writer, vector); + +#define GCINFO_WRITE_VAR_VECTOR(writer, vector, baseSkip, baseRun, counter) \ + WriteSlotStateVarLengthVector(writer, vector, baseSkip, baseRun); +#endif + +#define LOG_GCSLOTDESC_FMT "%s%c%d%s%s%s" +#define LOG_GCSLOTDESC_ARGS(pDesc) (pDesc)->IsRegister() ? "register" \ + : GcStackSlotBaseNames[(pDesc)->Slot.Stack.Base], \ + (pDesc)->IsRegister() ? ' ' : (pDesc)->Slot.Stack.SpOffset < 0 ? '-' : '+', \ + (pDesc)->IsRegister() ? (pDesc)->Slot.RegisterNumber \ + : ((pDesc)->Slot.Stack.SpOffset), \ + (pDesc)->IsPinned() ? " pinned" : "", \ + (pDesc)->IsInterior() ? " interior" : "", \ + (pDesc)->IsUntracked() ? " untracked" : "" + +#define LOG_REGTRANSITION_FMT "register %u%s%s" +#define LOG_REGTRANSITION_ARGS(RegisterNumber, Flags) \ + RegisterNumber, \ + (Flags & GC_SLOT_PINNED) ? " pinned" : "", \ + (Flags & GC_SLOT_INTERIOR) ? " interior" : "" + +#define LOG_STACKTRANSITION_FMT "%s%c%d%s%s%s" +#define LOG_STACKTRANSITION_ARGS(BaseRegister, StackOffset, Flags) \ + GcStackSlotBaseNames[BaseRegister], \ + ((StackOffset) < 0) ? '-' : '+', \ + ((StackOffset) >= 0) ? (StackOffset) \ + : -(StackOffset), \ + (Flags & GC_SLOT_PINNED) ? " pinned" : "", \ + (Flags & GC_SLOT_INTERIOR) ? " interior" : "", \ + (Flags & GC_SLOT_UNTRACKED) ? " untracked" : "" + +class BitArray +{ + friend class BitArrayIterator; +public: + BitArray(IAllocator* pJitAllocator, size_t size_tCount) + { + m_pData = (size_t*)pJitAllocator->Alloc(size_tCount*sizeof(size_t)); + m_pEndData = m_pData + size_tCount; +#ifdef MUST_CALL_IALLOCATOR_FREE + m_pJitAllocator = pJitAllocator; +#endif + } + + inline size_t* DataPtr() + { + return m_pData; + } + + inline void SetBit( size_t pos ) + { + size_t element = pos / BITS_PER_SIZE_T; + int bpos = (int)(pos % BITS_PER_SIZE_T); + m_pData[element] |= ((size_t)1 << bpos); + } + + inline void ClearBit( size_t pos ) + { + size_t element = pos / BITS_PER_SIZE_T; + int bpos = (int)(pos % BITS_PER_SIZE_T); + m_pData[element] &= ~((size_t)1 << bpos); + } + + inline void SetAll() + { + size_t* ptr = m_pData; + while(ptr < m_pEndData) + *(ptr++) = (size_t)(SSIZE_T)(-1); + } + + inline void ClearAll() + { + size_t* ptr = m_pData; + while(ptr < m_pEndData) + *(ptr++) = (size_t) 0; + } + + inline void WriteBit( size_t pos, BOOL val) + { + if(val) + SetBit(pos); + else + ClearBit(pos); + } + + inline size_t ReadBit( size_t pos ) const + { + size_t element = pos / BITS_PER_SIZE_T; + int bpos = (int)(pos % BITS_PER_SIZE_T); + return (m_pData[element] & ((size_t)1 << bpos)); + } + + inline bool operator==(const BitArray &other) const + { + _ASSERTE(other.m_pEndData - other.m_pData == m_pEndData - m_pData); + size_t* dest = m_pData; + size_t* src = other.m_pData; + return 0 == memcmp(dest, src, (m_pEndData - m_pData) * sizeof(*m_pData)); + } + + inline int GetHashCode() const + { + const int* src = (const int*)m_pData; + int result = *src++; + while(src < (const int*)m_pEndData) + result = _rotr(result, 5) ^ *src++; + + return result; + } + + inline BitArray& operator=(const BitArray &other) + { + _ASSERTE(other.m_pEndData - other.m_pData == m_pEndData - m_pData); + size_t* dest = m_pData; + size_t* src = other.m_pData; + while(dest < m_pEndData) + *(dest++) = *(src++); + + return *this; + } + + inline BitArray& operator|=(const BitArray &other) + { + _ASSERTE(other.m_pEndData - other.m_pData == m_pEndData - m_pData); + size_t* dest = m_pData; + size_t* src = other.m_pData; + while(dest < m_pEndData) + *(dest++) |= *(src++); + + return *this; + } + +#ifdef MUST_CALL_IALLOCATOR_FREE + ~BitArray() + { + m_pAllocator->Free( m_pData ); + } +#endif + +private: + size_t * m_pData; + size_t * m_pEndData; +#ifdef MUST_CALL_IALLOCATOR_FREE + IAllocator* m_pJitAllocator; +#endif +}; + + +class BitArrayIterator +{ +public: + BitArrayIterator(BitArray* bitArray) + { + m_pCurData = (unsigned *)bitArray->m_pData; + m_pEndData = (unsigned *)bitArray->m_pEndData; + m_curBits = *m_pCurData; + m_curBit = 0; + m_curBase = 0; + GetNext(); + } + void operator++(int dummy) //int dummy is c++ for "this is postfix ++" + { + GetNext(); + } + + void operator++() // prefix ++ + { + GetNext(); + } + void GetNext() + { + m_curBits -= m_curBit; + while (m_curBits == 0) + { + m_pCurData++; + m_curBase += 32; + if (m_pCurData == m_pEndData) + break; + m_curBits = *m_pCurData; + } + m_curBit = (unsigned)((int)m_curBits & -(int)m_curBits); + } + unsigned operator*() + { + assert(!end() && (m_curBit != 0)); + unsigned bitPosition = BitPosition(m_curBit); + return bitPosition + m_curBase; + } + bool end() + { + return (m_pCurData == m_pEndData); + } +private: + unsigned* m_pCurData; + unsigned* m_pEndData; + unsigned m_curBits; + unsigned m_curBit; + unsigned m_curBase; +}; + + #ifdef MDIL #define MUST_CALL_JITALLOCATOR_FREE 1 #endif +class LiveStateFuncs +{ +public: + static int GetHashCode(const BitArray * key) + { + return key->GetHashCode(); + } + + static bool Equals(const BitArray * k1, const BitArray * k2) + { + return *k1 == *k2; + } +}; + typedef SimplerHashTable< const BitArray *, LiveStateFuncs, UINT32, DefaultSimplerHashBehavior > LiveStateHashTable; #ifdef MEASURE_GCINFO @@ -39,6 +307,53 @@ typedef SimplerHashTable< const BitArray *, LiveStateFuncs, UINT32, DefaultSimpl GcInfoSize g_FiGcInfoSize; GcInfoSize g_PiGcInfoSize; +GcInfoSize::GcInfoSize() +{ + memset(this, 0, sizeof(*this)); +} + +GcInfoSize& operator+=(const GcInfoSize& other) +{ + TotalSize += other.TotalSize; + + NumMethods += other.NumMethods; + NumCallSites += other.NumCallSites; + NumRanges += other.NumRanges; + NumRegs += other.NumRegs; + NumStack += other.NumStack; + NumEh += other.NumEh; + NumTransitions += other.NumTransitions; + SizeOfCode += other.SizeOfCode; + + FlagsSize += other.FlagsSize; + CodeLengthSize += other.CodeLengthSize; + ProEpilogSize += other.ProEpilogSize; + SecObjSize += other.SecObjSize; + GsCookieSize += other.GsCookieSize; + GenericsCtxSize += other.GenericsCtxSize; + PspSymSize += other.PspSymSize; + StackBaseSize += other.StackBaseSize; + FrameMarkerSize += other.FrameMarkerSize; + FixedAreaSize += other.FixedAreaSize; + NumCallSitesSize += other.NumCallSitesSize; + NumRangesSize += other.NumRangesSize; + CallSitePosSize += other.CallSitePosSize; + RangeSize += other.RangeSize; + NumRegsSize += other.NumRegsSize; + NumStackSize += other.NumStackSize; + RegSlotSize += other.RegSlotSize; + StackSlotSize += other.StackSlotSize; + CallSiteStateSize += other.CallSiteStateSize; + NumEhSize += other.NumEhSize; + EhPosSize += other.EhPosSize; + EhStateSize += other.EhStateSize; + ChunkPtrSize += other.ChunkPtrSize; + ChunkMaskSize += other.ChunkMaskSize; + ChunkFinalStateSize += other.ChunkFinalStateSize; + ChunkTransitionSize += other.ChunkTransitionSize; + + return *this; +} void GcInfoSize::Log(DWORD level, const char * header) { @@ -168,6 +483,28 @@ GcInfoEncoder::GcInfoEncoder( #endif //_DEBUG } +#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED +void GcInfoEncoder::DefineCallSites(UINT32* pCallSites, BYTE* pCallSiteSizes, UINT32 numCallSites) +{ + m_pCallSites = pCallSites; + m_pCallSiteSizes = pCallSiteSizes; + m_NumCallSites = numCallSites; +#ifdef _DEBUG + for(UINT32 i=0; i 0); + _ASSERTE(DENORMALIZE_CODE_OFFSET(NORMALIZE_CODE_OFFSET(pCallSites[i])) == pCallSites[i]); + if(i > 0) + { + UINT32 prevEnd = pCallSites[i-1] + pCallSiteSizes[i-1]; + UINT32 curStart = pCallSites[i]; + _ASSERTE(curStart >= prevEnd); + } + } +#endif +} +#endif + GcSlotId GcInfoEncoder::GetRegisterSlotId( UINT32 regNum, GcSlotFlags flags ) { // We could lookup an existing identical slot in the slot table (via some hashtable mechanism). @@ -249,6 +586,17 @@ void GcInfoEncoder::GrowSlotTable() m_SlotTable = newSlotTable; } +void GcInfoEncoder::WriteSlotStateVector(BitStreamWriter &writer, const BitArray& vector) +{ + for(UINT32 i = 0; i < m_NumSlots && !m_SlotTable[i].IsUntracked(); i++) + { + if(!m_SlotTable[i].IsDeleted()) + writer.Write(vector.ReadBit(i) ? 1 : 0, 1); + else + _ASSERTE(vector.ReadBit(i) == 0); + } +} + void GcInfoEncoder::DefineInterruptibleRange( UINT32 startInstructionOffset, UINT32 length ) { #ifdef VERIFY_GCINFO @@ -2384,3 +2732,70 @@ void BitStreamWriter::Dispose() #endif } +int BitStreamWriter::SizeofVarLengthUnsigned( size_t n, UINT32 base) +{ + // If a value gets so big we are probably doing something wrong + _ASSERTE(((INT32)(UINT32)n) >= 0); + _ASSERTE((base > 0) && (base < BITS_PER_SIZE_T)); + size_t numEncodings = 1 << base; + int bitsUsed; + for(bitsUsed = base+1; ; bitsUsed += base+1) + { + if( n < numEncodings ) + { + return bitsUsed; + } + else + { + n >>= base; + } + } + return bitsUsed; +} + +int BitStreamWriter::EncodeVarLengthUnsigned( size_t n, UINT32 base) +{ + // If a value gets so big we are probably doing something wrong + _ASSERTE(((INT32)(UINT32)n) >= 0); + _ASSERTE((base > 0) && (base < BITS_PER_SIZE_T)); + size_t numEncodings = 1 << base; + int bitsUsed; + for(bitsUsed = base+1; ; bitsUsed += base+1) + { + if( n < numEncodings ) + { + Write( n, base+1 ); // This sets the extension bit to zero + return bitsUsed; + } + else + { + size_t currentChunk = n & (numEncodings-1); + Write( currentChunk | numEncodings, base+1 ); + n >>= base; + } + } + return bitsUsed; +} + +int BitStreamWriter::EncodeVarLengthSigned( SSIZE_T n, UINT32 base ) +{ + _ASSERTE((base > 0) && (base < BITS_PER_SIZE_T)); + size_t numEncodings = 1 << base; + for(int bitsUsed = base+1; ; bitsUsed += base+1) + { + size_t currentChunk = ((size_t) n) & (numEncodings-1); + size_t topmostBit = currentChunk & (numEncodings >> 1); + n >>= base; // signed arithmetic shift + if((topmostBit && (n == (SSIZE_T)-1)) || (!topmostBit && (n == 0))) + { + // The topmost bit correctly represents the sign + Write( currentChunk, base+1 ); // This sets the extension bit to zero + return bitsUsed; + } + else + { + Write( currentChunk | numEncodings, base+1 ); + } + } +} + diff --git a/src/coreclr/src/inc/gcinfoencoder.h b/src/coreclr/src/inc/gcinfoencoder.h index 8761bd5..e5e1f79 100644 --- a/src/coreclr/src/inc/gcinfoencoder.h +++ b/src/coreclr/src/inc/gcinfoencoder.h @@ -94,64 +94,6 @@ #endif //VERIFY_GCINFO #ifdef MEASURE_GCINFO -#define GCINFO_WRITE(writer, val, numBits, counter) \ - { \ - writer.Write(val, numBits); \ - m_CurrentMethodSize.counter += numBits; \ - m_CurrentMethodSize.TotalSize += numBits; \ - } -#define GCINFO_WRITE_VARL_U(writer, val, base, counter) \ - { \ - size_t __temp = \ - writer.EncodeVarLengthUnsigned(val, base); \ - m_CurrentMethodSize.counter += __temp; \ - m_CurrentMethodSize.TotalSize += __temp; \ - } -#define GCINFO_WRITE_VARL_S(writer, val, base, counter) \ - { \ - size_t __temp = \ - writer.EncodeVarLengthSigned(val, base); \ - m_CurrentMethodSize.counter += __temp; \ - m_CurrentMethodSize.TotalSize += __temp; \ - } -#define GCINFO_WRITE_VECTOR(writer, vector, counter) \ - { \ - WriteSlotStateVector(writer, vector); \ - for(UINT32 i = 0; i < m_NumSlots; i++) \ - { \ - if(!m_SlotTable[i].IsDeleted() && \ - !m_SlotTable[i].IsUntracked()) \ - { \ - m_CurrentMethodSize.counter++; \ - m_CurrentMethodSize.TotalSize++; \ - } \ - } \ - } -#define GCINFO_WRITE_VAR_VECTOR(writer, vector, baseSkip, baseRun, counter) \ - { \ - size_t __temp = \ - WriteSlotStateVarLengthVector(writer, vector, baseSkip, baseRun); \ - m_CurrentMethodSize.counter += __temp; \ - m_CurrentMethodSize.TotalSize += __temp; \ - } -#else -#define GCINFO_WRITE(writer, val, numBits, counter) \ - writer.Write(val, numBits); - -#define GCINFO_WRITE_VARL_U(writer, val, base, counter) \ - writer.EncodeVarLengthUnsigned(val, base); - -#define GCINFO_WRITE_VARL_S(writer, val, base, counter) \ - writer.EncodeVarLengthSigned(val, base); - -#define GCINFO_WRITE_VECTOR(writer, vector, counter) \ - WriteSlotStateVector(writer, vector); - -#define GCINFO_WRITE_VAR_VECTOR(writer, vector, baseSkip, baseRun, counter) \ - WriteSlotStateVarLengthVector(writer, vector, baseSkip, baseRun); -#endif - -#ifdef MEASURE_GCINFO struct GcInfoSize { size_t TotalSize; @@ -192,66 +134,12 @@ struct GcInfoSize size_t ChunkFinalStateSize; size_t ChunkTransitionSize; - GcInfoSize() - { - memset(this, 0, sizeof(GcInfoSize)); - } - - GcInfoSize& operator+=(GcInfoSize& other) - { - TotalSize += other.TotalSize; - - NumMethods += other.NumMethods; - NumCallSites += other.NumCallSites; - NumRanges += other.NumRanges; - NumRegs += other.NumRegs; - NumStack += other.NumStack; - NumEh += other.NumEh; - NumTransitions += other.NumTransitions; - SizeOfCode += other.SizeOfCode; - - FlagsSize += other.FlagsSize; - CodeLengthSize += other.CodeLengthSize; - ProEpilogSize += other.ProEpilogSize; - SecObjSize += other.SecObjSize; - GsCookieSize += other.GsCookieSize; - GenericsCtxSize += other.GenericsCtxSize; - PspSymSize += other.PspSymSize; - StackBaseSize += other.StackBaseSize; - FrameMarkerSize += other.FrameMarkerSize; - FixedAreaSize += other.FixedAreaSize; - NumCallSitesSize += other.NumCallSitesSize; - NumRangesSize += other.NumRangesSize; - CallSitePosSize += other.CallSitePosSize; - RangeSize += other.RangeSize; - NumRegsSize += other.NumRegsSize; - NumStackSize += other.NumStackSize; - RegSlotSize += other.RegSlotSize; - StackSlotSize += other.StackSlotSize; - CallSiteStateSize += other.CallSiteStateSize; - NumEhSize += other.NumEhSize; - EhPosSize += other.EhPosSize; - EhStateSize += other.EhStateSize; - ChunkPtrSize += other.ChunkPtrSize; - ChunkMaskSize += other.ChunkMaskSize; - ChunkFinalStateSize += other.ChunkFinalStateSize; - ChunkTransitionSize += other.ChunkTransitionSize; - - return *this; - } - + GcInfoSize(); + GcInfoSize& operator+=(GcInfoSize& other); void Log(DWORD level, const char * header); }; #endif -//----------------------------------------------------------------------------- -// The following macro controls whether the encoder has to call the IAllocator::Free method -// Don't call IAllocator::Free for mscorjit64.dll -//----------------------------------------------------------------------------- -//#define MUST_CALL_IALLOCATOR_FREE - - - struct GcSlotDesc { union @@ -287,202 +175,7 @@ struct GcSlotDesc } }; -#define LOG_GCSLOTDESC_FMT "%s%c%d%s%s%s" -#define LOG_GCSLOTDESC_ARGS(pDesc) (pDesc)->IsRegister() ? "register" \ - : GcStackSlotBaseNames[(pDesc)->Slot.Stack.Base], \ - (pDesc)->IsRegister() ? ' ' : (pDesc)->Slot.Stack.SpOffset < 0 ? '-' : '+', \ - (pDesc)->IsRegister() ? (pDesc)->Slot.RegisterNumber \ - : ((pDesc)->Slot.Stack.SpOffset), \ - (pDesc)->IsPinned() ? " pinned" : "", \ - (pDesc)->IsInterior() ? " interior" : "", \ - (pDesc)->IsUntracked() ? " untracked" : "" - -#define LOG_REGTRANSITION_FMT "register %u%s%s" -#define LOG_REGTRANSITION_ARGS(RegisterNumber, Flags) \ - RegisterNumber, \ - (Flags & GC_SLOT_PINNED) ? " pinned" : "", \ - (Flags & GC_SLOT_INTERIOR) ? " interior" : "" - -#define LOG_STACKTRANSITION_FMT "%s%c%d%s%s%s" -#define LOG_STACKTRANSITION_ARGS(BaseRegister, StackOffset, Flags) \ - GcStackSlotBaseNames[BaseRegister], \ - ((StackOffset) < 0) ? '-' : '+', \ - ((StackOffset) >= 0) ? (StackOffset) \ - : -(StackOffset), \ - (Flags & GC_SLOT_PINNED) ? " pinned" : "", \ - (Flags & GC_SLOT_INTERIOR) ? " interior" : "", \ - (Flags & GC_SLOT_UNTRACKED) ? " untracked" : "" - - -class BitArray -{ - friend class BitArrayIterator; -public: - BitArray(IAllocator* pJitAllocator, size_t size_tCount) - { - m_pData = (size_t*)pJitAllocator->Alloc(size_tCount*sizeof(size_t)); - m_pEndData = m_pData + size_tCount; -#ifdef MUST_CALL_IALLOCATOR_FREE - m_pJitAllocator = pJitAllocator; -#endif - } - - inline size_t* DataPtr() - { - return m_pData; - } - - inline void SetBit( size_t pos ) - { - size_t element = pos / BITS_PER_SIZE_T; - int bpos = (int)(pos % BITS_PER_SIZE_T); - m_pData[element] |= ((size_t)1 << bpos); - } - - inline void ClearBit( size_t pos ) - { - size_t element = pos / BITS_PER_SIZE_T; - int bpos = (int)(pos % BITS_PER_SIZE_T); - m_pData[element] &= ~((size_t)1 << bpos); - } - - inline void SetAll() - { - size_t* ptr = m_pData; - while(ptr < m_pEndData) - *(ptr++) = (size_t)(SSIZE_T)(-1); - } - - inline void ClearAll() - { - size_t* ptr = m_pData; - while(ptr < m_pEndData) - *(ptr++) = (size_t) 0; - } - - inline void WriteBit( size_t pos, BOOL val) - { - if(val) - SetBit(pos); - else - ClearBit(pos); - } - - inline size_t ReadBit( size_t pos ) const - { - size_t element = pos / BITS_PER_SIZE_T; - int bpos = (int)(pos % BITS_PER_SIZE_T); - return (m_pData[element] & ((size_t)1 << bpos)); - } - - inline bool operator==(const BitArray &other) const - { - _ASSERTE(other.m_pEndData - other.m_pData == m_pEndData - m_pData); - size_t* dest = m_pData; - size_t* src = other.m_pData; - return 0 == memcmp(dest, src, (m_pEndData - m_pData) * sizeof(*m_pData)); - } - - inline int GetHashCode() const - { - const int* src = (const int*)m_pData; - int result = *src++; - while(src < (const int*)m_pEndData) - result = _rotr(result, 5) ^ *src++; - - return result; - } - - inline BitArray& operator=(const BitArray &other) - { - _ASSERTE(other.m_pEndData - other.m_pData == m_pEndData - m_pData); - size_t* dest = m_pData; - size_t* src = other.m_pData; - while(dest < m_pEndData) - *(dest++) = *(src++); - - return *this; - } - - inline BitArray& operator|=(const BitArray &other) - { - _ASSERTE(other.m_pEndData - other.m_pData == m_pEndData - m_pData); - size_t* dest = m_pData; - size_t* src = other.m_pData; - while(dest < m_pEndData) - *(dest++) |= *(src++); - - return *this; - } - -#ifdef MUST_CALL_IALLOCATOR_FREE - ~BitArray() - { - m_pAllocator->Free( m_pData ); - } -#endif - -private: - size_t * m_pData; - size_t * m_pEndData; -#ifdef MUST_CALL_IALLOCATOR_FREE - IAllocator* m_pJitAllocator; -#endif -}; - - -class BitArrayIterator -{ -public: - BitArrayIterator(BitArray* bitArray) - { - m_pCurData = (unsigned *)bitArray->m_pData; - m_pEndData = (unsigned *)bitArray->m_pEndData; - m_curBits = *m_pCurData; - m_curBit = 0; - m_curBase = 0; - GetNext(); - } - void operator++(int dummy) //int dummy is c++ for "this is postfix ++" - { - GetNext(); - } - - void operator++() // prefix ++ - { - GetNext(); - } - void GetNext() - { - m_curBits -= m_curBit; - while (m_curBits == 0) - { - m_pCurData++; - m_curBase += 32; - if (m_pCurData == m_pEndData) - break; - m_curBits = *m_pCurData; - } - m_curBit = (unsigned)((int)m_curBits & -(int)m_curBits); - } - unsigned operator*() - { - assert(!end() && (m_curBit != 0)); - unsigned bitPosition = BitPosition(m_curBit); - return bitPosition + m_curBase; - } - bool end() - { - return (m_pCurData == m_pEndData); - } -private: - unsigned* m_pCurData; - unsigned* m_pEndData; - unsigned m_curBits; - unsigned m_curBit; - unsigned m_curBase; -}; - +class BitArray; class BitStreamWriter { public: @@ -512,27 +205,7 @@ public: // Bits 0..(base-1) represent the encoded quantity // If it doesn't fit, set bit #base to 1 and use base+1 more bits //-------------------------------------------------------- - static - int SizeofVarLengthUnsigned( size_t n, UINT32 base ) - { - // If a value gets so big we are probably doing something wrong - _ASSERTE(((INT32)(UINT32)n) >= 0); - _ASSERTE((base > 0) && (base < BITS_PER_SIZE_T)); - size_t numEncodings = 1 << base; - int bitsUsed; - for(bitsUsed = base+1; ; bitsUsed += base+1) - { - if( n < numEncodings ) - { - return bitsUsed; - } - else - { - n >>= base; - } - } - return bitsUsed; - } + static int SizeofVarLengthUnsigned( size_t n, UINT32 base ); //-------------------------------------------------------- // Encode variable length numbers @@ -540,29 +213,7 @@ public: // Bits 0..(base-1) represent the encoded quantity // If it doesn't fit, set bit #base to 1 and use base+1 more bits //-------------------------------------------------------- - int EncodeVarLengthUnsigned( size_t n, UINT32 base ) - { - // If a value gets so big we are probably doing something wrong - _ASSERTE(((INT32)(UINT32)n) >= 0); - _ASSERTE((base > 0) && (base < BITS_PER_SIZE_T)); - size_t numEncodings = 1 << base; - int bitsUsed; - for(bitsUsed = base+1; ; bitsUsed += base+1) - { - if( n < numEncodings ) - { - Write( n, base+1 ); // This sets the extension bit to zero - return bitsUsed; - } - else - { - size_t currentChunk = n & (numEncodings-1); - Write( currentChunk | numEncodings, base+1 ); - n >>= base; - } - } - return bitsUsed; - } + int EncodeVarLengthUnsigned( size_t n, UINT32 base ); //-------------------------------------------------------- // Signed quantities are encoded the same as unsigned @@ -570,27 +221,7 @@ public: // to fit in base bits if the topmost bit of a base-long chunk // matches the sign of the whole number //-------------------------------------------------------- - int EncodeVarLengthSigned( SSIZE_T n, UINT32 base ) - { - _ASSERTE((base > 0) && (base < BITS_PER_SIZE_T)); - size_t numEncodings = 1 << base; - for(int bitsUsed = base+1; ; bitsUsed += base+1) - { - size_t currentChunk = ((size_t) n) & (numEncodings-1); - size_t topmostBit = currentChunk & (numEncodings >> 1); - n >>= base; // signed arithmetic shift - if((topmostBit && (n == (SSIZE_T)-1)) || (!topmostBit && (n == 0))) - { - // The topmost bit correctly represents the sign - Write( currentChunk, base+1 ); // This sets the extension bit to zero - return bitsUsed; - } - else - { - Write( currentChunk | numEncodings, base+1 ); - } - } - } + int EncodeVarLengthSigned( SSIZE_T n, UINT32 base ); private: @@ -650,9 +281,9 @@ private: m_FreeBitsInCurrentSlot = BITS_PER_SIZE_T; *m_pCurrentSlot = 0; } - }; + typedef UINT32 GcSlotId; @@ -693,25 +324,7 @@ public: #ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - void DefineCallSites(UINT32* pCallSites, BYTE* pCallSiteSizes, UINT32 numCallSites) - { - m_pCallSites = pCallSites; - m_pCallSiteSizes = pCallSiteSizes; - m_NumCallSites = numCallSites; -#ifdef _DEBUG - for(UINT32 i=0; i 0); - _ASSERTE(DENORMALIZE_CODE_OFFSET(NORMALIZE_CODE_OFFSET(pCallSites[i])) == pCallSites[i]); - if(i > 0) - { - UINT32 prevEnd = pCallSites[i-1] + pCallSiteSizes[i-1]; - UINT32 curStart = pCallSites[i]; - _ASSERTE(curStart >= prevEnd); - } - } -#endif - } + void DefineCallSites(UINT32* pCallSites, BYTE* pCallSiteSizes, UINT32 numCallSites); #endif //------------------------------------------------------------------------ @@ -911,18 +524,7 @@ private: void GrowSlotTable(); - void WriteBitArray(BitArray& a, UINT32 count); - - inline void WriteSlotStateVector(BitStreamWriter &writer, const BitArray& vector) - { - for(UINT32 i = 0; i < m_NumSlots && !m_SlotTable[i].IsUntracked(); i++) - { - if(!m_SlotTable[i].IsDeleted()) - writer.Write(vector.ReadBit(i) ? 1 : 0, 1); - else - _ASSERTE(vector.ReadBit(i) == 0); - } - } + void WriteSlotStateVector(BitStreamWriter &writer, const BitArray& vector); UINT32 SizeofSlotStateVarLengthVector(const BitArray& vector, UINT32 baseSkip, UINT32 baseRun); void SizeofSlotStateVarLengthVector(const BitArray& vector, UINT32 baseSkip, UINT32 baseRun, UINT32 * pSizeofSimple, UINT32 * pSizeofRLE, UINT32 * pSizeofRLENeg); @@ -953,20 +555,4 @@ private: #endif }; -class LiveStateFuncs -{ -public: - static int GetHashCode(const BitArray * key) - { - return key->GetHashCode(); - } - - static bool Equals(const BitArray * k1, const BitArray * k2) - { - return *k1 == *k2; - } -}; - - #endif // !__GCINFOENCODER_H__ - -- 2.7.4