Refactor `MemoryBlockDesc`.
authorPat Gavlin <pagavlin@microsoft.com>
Wed, 13 Apr 2016 19:55:47 +0000 (12:55 -0700)
committerPat Gavlin <pagavlin@microsoft.com>
Wed, 13 Apr 2016 19:55:47 +0000 (12:55 -0700)
- Encapsulate link management into `MemoryBlockDescList`.
- Replace `MemoryBlockDesc` and its separately-allocated buffer
  with a new type, `MemoryBlock`, that stores the link to the
  next memory block with the buffer itself.

src/gcinfo/dbggcinfoencoder.cpp
src/gcinfo/gcinfoencoder.cpp
src/inc/dbggcinfoencoder.h
src/inc/gcinfoencoder.h

index 7912c73..98480cf 100644 (file)
@@ -43,46 +43,49 @@ void GcInfoEncoder::LifetimeTransitionAllocator::Free (void *context, void *pv)
 }
 
 
-void BitStreamWriter::AllocMemoryBlock()
+BitStreamWriter::MemoryBlockList::MemoryBlockList()
+    : m_head(nullptr),
+      m_tail(nullptr)
 {
-    _ASSERTE( IS_ALIGNED( m_MemoryBlockSize, sizeof( size_t ) ) );
-    m_pCurrentSlot = (size_t*) m_pAllocator->Alloc( m_MemoryBlockSize );
-    m_OutOfBlockSlot = m_pCurrentSlot + m_MemoryBlockSize / sizeof( size_t );
+}
 
-    MemoryBlockDesc* pMemBlockDesc = (MemoryBlockDesc*) m_pAllocator->Alloc( sizeof( MemoryBlockDesc ) );
-    _ASSERTE( IS_ALIGNED( pMemBlockDesc, sizeof( void* ) ) );
+BitStreamWriter::MemoryBlock* BitStreamWriter::MemoryBlockList::AppendNew(IJitAllocator* allocator, size_t bytes)
+{
+    auto* memBlock = reinterpret_cast<MemoryBlock*>(allocator->Alloc(sizeof(MemoryBlock) + bytes));
+    memBlock->m_next = nullptr;
 
-    pMemBlockDesc->Init();
-    pMemBlockDesc->StartAddress = m_pCurrentSlot;
-    if (m_MemoryBlocksTail != NULL)
+    if (m_tail != nullptr)
     {
-        _ASSERTE(m_MemoryBlocksHead != NULL);
-        m_MemoryBlocksTail->m_Next = pMemBlockDesc;
+        _ASSERTE(m_head != nullptr);
+        m_tail->m_next = memBlock;
     }
     else
     {
-        _ASSERTE(m_MemoryBlocksHead == NULL);
-        m_MemoryBlocksHead = pMemBlockDesc;
+        _ASSERTE(m_head == nullptr);
+        m_head = memBlock;
     }
-    m_MemoryBlocksTail = pMemBlockDesc;
-
-#ifdef _DEBUG
-       m_MemoryBlocksCount++;
-#endif
 
+    m_tail = memBlock;
+    return memBlock;
 }
 
-GcInfoEncoder::GcInfoEncoder(
-            ICorJitInfo*                pCorJitInfo,
-            CORINFO_METHOD_INFO*        pMethodInfo,
-            IJitAllocator*              pJitAllocator
-            )
-    :   m_HeaderInfoWriter( pJitAllocator ),
-#if 0
-#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
-        m_PartiallyInterruptibleInfoWriter( pJitAllocator ),
-#endif
+void BitStreamWriter::MemoryBlockList::Dispose(IJitAllocator* allocator)
+{
+#ifdef MUST_CALL_JITALLOCATOR_FREE
+    for (MemoryBlock* block = m_head, *next; block != nullptr; block = next)
+    {
+        next = block->m_next;
+        allocator->Free(block);
+    }
+    m_head = nullptr;
+    m_tail = nullptr;
 #endif
+}
+
+
+void BitStreamWriter::AllocMemoryBlock()
+{
+    _ASSERTE( IS_ALIGNED( m_MemoryBlockSize, sizeof( size_t ) ) );
         m_FullyInterruptibleInfoWriter( pJitAllocator ),
         m_LifetimeTransitions( pJitAllocator )
 {
@@ -941,21 +944,21 @@ void BitStreamWriter::CopyTo( BYTE* buffer )
     int i,c;
     BYTE* source = NULL;
 
-    MemoryBlockDesc* pMemBlockDesc = m_MemoryBlocks.GetHead();
+    MemoryBlock* pMemBlock = m_MemoryBlocks.Head();
     _ASSERTE( pMemBlockDesc != NULL );
-    while (pMemBlockDesc->m_Next != NULL)
+    while (pMemBlock->Next() != NULL)
     {
-        source = (BYTE*) pMemBlockDesc->StartAddress;
+        source = (BYTE*) pMemBlock->Contents;
         // @TODO: use memcpy instead
         for( i = 0; i < m_MemoryBlockSize; i++ )
         {
             *( buffer++ ) = *( source++ );
         }
 
-        pMemBlockDesc = pMemBlockDesc->m_Next;
+        pMemBlock = pMemBlock->Next();
     }
 
-    source = (BYTE*) pMemBlockDesc->StartAddress;
+    source = (BYTE*) pMemBlock->Contents;
     // The number of bytes to copy in the last block
     c = (int) ((BYTE*) ( m_pCurrentSlot + 1 ) - source - m_FreeBitsInCurrentSlot/8);
     _ASSERTE( c >= 0 );
@@ -969,18 +972,7 @@ void BitStreamWriter::CopyTo( BYTE* buffer )
 
 void BitStreamWriter::Dispose()
 {
-#ifdef MUST_CALL_JITALLOCATOR_FREE
-    for (MemoryBlockDes* block = m_MemoryBlocksHead, *next; block != NULL; block = next)
-    {
-        next = block->m_Next;
-        m_pAllocator->Free(block->StartAddress);
-        m_pAllocator->Free(block);
-    }
-    m_MemoryBlocksHead = NULL;
-    m_MemoryBlocksTail = NULL;
-
-    m_pAllocator->Free( m_SlotMappings );
-#endif
+    m_MemoryBlocks.Dispose(m_pAllocator);
 }
 
 }
index 88b79fb..9fb37d3 100644 (file)
@@ -900,6 +900,45 @@ int __cdecl CompareLifetimeTransitionsBySlot(const void* p1, const void* p2)
     }
 }
 
+BitStreamWriter::MemoryBlockList::MemoryBlockList()
+    : m_head(nullptr),
+      m_tail(nullptr)
+{
+}
+
+BitStreamWriter::MemoryBlock* BitStreamWriter::MemoryBlockList::AppendNew(IAllocator* allocator, size_t bytes)
+{
+    auto* memBlock = reinterpret_cast<MemoryBlock*>(allocator->Alloc(sizeof(MemoryBlock) + bytes));
+    memBlock->m_next = nullptr;
+
+    if (m_tail != nullptr)
+    {
+        _ASSERTE(m_head != nullptr);
+        m_tail->m_next = memBlock;
+    }
+    else
+    {
+        _ASSERTE(m_head == nullptr);
+        m_head = memBlock;
+    }
+
+    m_tail = memBlock;
+    return memBlock;
+}
+
+void BitStreamWriter::MemoryBlockList::Dispose(IAllocator* allocator)
+{
+#ifdef MUST_CALL_JITALLOCATOR_FREE
+    for (MemoryBlock* block = m_head, *next; block != nullptr; block = next)
+    {
+        next = block->m_next;
+        allocator->Free(block);
+    }
+    m_head = nullptr;
+    m_tail = nullptr;
+#endif
+}
+
 void BitStreamWriter::Write(BitArray& a, UINT32 count)
 {
     size_t* dataPtr = a.DataPtr();
@@ -2647,8 +2686,6 @@ BitStreamWriter::BitStreamWriter( IAllocator* pAllocator )
 {
     m_pAllocator = pAllocator;
     m_BitCount = 0;
-    m_MemoryBlocksHead = NULL;
-    m_MemoryBlocksTail = NULL;
 #ifdef _DEBUG
     m_MemoryBlocksCount = 0;
 #endif
@@ -2711,23 +2748,23 @@ void BitStreamWriter::CopyTo( BYTE* buffer )
     int i,c;
     BYTE* source = NULL;
 
-    MemoryBlockDesc* pMemBlockDesc = m_MemoryBlocksHead;
-    if( pMemBlockDesc == NULL )
+    MemoryBlock* pMemBlock = m_MemoryBlocks.Head();
+    if( pMemBlock == NULL )
         return;
         
-    while (pMemBlockDesc->m_Next != NULL)
+    while (pMemBlock->Next() != NULL)
     {
-        source = (BYTE*) pMemBlockDesc->StartAddress;
+        source = (BYTE*) pMemBlock->Contents;
         // @TODO: use memcpy instead
         for( i = 0; i < m_MemoryBlockSize; i++ )
         {
             *( buffer++ ) = *( source++ );
         }
 
-        pMemBlockDesc = pMemBlockDesc->m_Next;
+        pMemBlock = pMemBlock->Next();
     }
 
-    source = (BYTE*) pMemBlockDesc->StartAddress;
+    source = (BYTE*) pMemBlock->Contents;
     // The number of bytes to copy in the last block
     c = (int) ((BYTE*) ( m_pCurrentSlot + 1 ) - source - m_FreeBitsInCurrentSlot/8);
     _ASSERTE( c >= 0 );
@@ -2741,16 +2778,7 @@ void BitStreamWriter::CopyTo( BYTE* buffer )
 
 void BitStreamWriter::Dispose()
 {
-#ifdef MUST_CALL_JITALLOCATOR_FREE
-    for (MemoryBlockDes* block = m_MemoryBlocksHead, *next; block != NULL; block = next)
-    {
-        next = block->m_Next;
-        m_pAllocator->Free(block->StartAddress);
-        m_pAllocator->Free(block);
-    }
-    m_MemoryBlocksHead = NULL;
-    m_MemoryBlocksTail = NULL;
-#endif
+    m_MemoryBlocks.Dispose(m_pAllocator);
 }
 
 int BitStreamWriter::SizeofVarLengthUnsigned( size_t n, UINT32 base)
index d92396c..573985b 100644 (file)
@@ -121,23 +121,42 @@ public:
 
 private:
 
-    class MemoryBlockDesc
+    class MemoryBlockList;
+    class MemoryBlock
     {
+        friend class MemoryBlockList;
+        MemoryBlock* m_next;
+
+    public:
+        size_t Contents[];
+
+        inline MemoryBlock* Next()
+        {
+            return m_next;
+        }
+    };
+
+    class MemoryBlockList
+    {
+        MemoryBlock* m_head;
+        MemoryBlock* m_tail;
+
     public:
-        size_t* StartAddress;
-        MemoryBlockDesc* m_Next;
+        MemoryBlockList();
 
-        inline void Init()
+        inline MemoryBlock* Head()
         {
-            m_Next = NULL;
+            return m_head;
         }
+
+        MemoryBlock* AppendNew(IAllocator* allocator, size_t bytes);
+        void Dispose(IAllocator* allocator);
     };
 
     IJitAllocator* m_pAllocator;
     size_t m_BitCount;
     int m_FreeBitsInCurrentSlot;
-    MemoryBlockDesc* m_MemoryBlocksHead;
-    MemoryBlockDesc* m_MemoryBlocksTail;
+    MemoryBlockList m_MemoryBlocks;
     const static int m_MemoryBlockSize = 512;    // must be a multiple of the pointer size
     size_t* m_pCurrentSlot;            // bits are written through this pointer
     size_t* m_OutOfBlockSlot;        // sentinel value to determine when the block is full
index 8f0ce34..2740acb 100644 (file)
@@ -223,24 +223,42 @@ public:
     int EncodeVarLengthSigned( SSIZE_T n, UINT32 base );
 
 private:
+    class MemoryBlockList;
+    class MemoryBlock
+    {
+        friend class MemoryBlockList;
+        MemoryBlock* m_next;
+
+    public:
+        size_t Contents[];
+
+        inline MemoryBlock* Next()
+        {
+            return m_next;
+        }
+    };
 
-    class MemoryBlockDesc
+    class MemoryBlockList
     {
+        MemoryBlock* m_head;
+        MemoryBlock* m_tail;
+
     public:
-        size_t* StartAddress;
-        MemoryBlockDesc* m_Next;
+        MemoryBlockList();
 
-        inline void Init()
+        inline MemoryBlock* Head()
         {
-            m_Next = NULL;
+            return m_head;
         }
+
+        MemoryBlock* AppendNew(IAllocator* allocator, size_t bytes);
+        void Dispose(IAllocator* allocator);
     };
 
     IAllocator* m_pAllocator;
     size_t m_BitCount;
     UINT32 m_FreeBitsInCurrentSlot;
-    MemoryBlockDesc* m_MemoryBlocksHead;
-    MemoryBlockDesc* m_MemoryBlocksTail;
+    MemoryBlockList m_MemoryBlocks;
     const static int m_MemoryBlockSize = 128;    // must be a multiple of the pointer size
     size_t* m_pCurrentSlot;            // bits are written through this pointer
     size_t* m_OutOfBlockSlot;        // sentinel value to determine when the block is full
@@ -260,25 +278,10 @@ private:
     inline void AllocMemoryBlock()
     {
         _ASSERTE( IS_ALIGNED( m_MemoryBlockSize, sizeof( size_t ) ) );
-        m_pCurrentSlot = (size_t*) m_pAllocator->Alloc( m_MemoryBlockSize );
-        m_OutOfBlockSlot = m_pCurrentSlot + m_MemoryBlockSize / sizeof( size_t );
+        MemoryBlock* pMemBlock = m_MemoryBlocks.AppendNew(m_pAllocator, m_MemoryBlockSize);
 
-        MemoryBlockDesc* pMemBlockDesc = (MemoryBlockDesc*) m_pAllocator->Alloc( sizeof( MemoryBlockDesc ) );
-        _ASSERTE( IS_ALIGNED( pMemBlockDesc, sizeof( void* ) ) );
-
-        pMemBlockDesc->Init();
-        pMemBlockDesc->StartAddress = m_pCurrentSlot;
-        if (m_MemoryBlocksTail != NULL)
-        {
-            _ASSERTE(m_MemoryBlocksHead != NULL);
-            m_MemoryBlocksTail->m_Next = pMemBlockDesc;
-        }
-        else
-        {
-            _ASSERTE(m_MemoryBlocksHead == NULL);
-            m_MemoryBlocksHead = pMemBlockDesc;
-        }
-        m_MemoryBlocksTail = pMemBlockDesc;
+        m_pCurrentSlot = pMemBlock->Contents;
+        m_OutOfBlockSlot = m_pCurrentSlot + m_MemoryBlockSize / sizeof( size_t );
 
 #ifdef _DEBUG
            m_MemoryBlocksCount++;