diff options
-rw-r--r-- | src/gcdump/gcdumpnonx86.cpp | 3 | ||||
-rw-r--r-- | src/gcinfo/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/gcinfo/dbggcinfoencoder.cpp | 981 | ||||
-rw-r--r-- | src/gcinfo/gcinfo.settings.targets | 1 | ||||
-rw-r--r-- | src/gcinfo/gcinfoencoder.cpp | 84 | ||||
-rw-r--r-- | src/inc/dbggcinfodecoder.h | 343 | ||||
-rw-r--r-- | src/inc/dbggcinfoencoder.h | 469 | ||||
-rw-r--r-- | src/inc/gcinfodecoder.h | 23 | ||||
-rw-r--r-- | src/inc/gcinfoencoder.h | 8 | ||||
-rw-r--r-- | src/vm/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/vm/crossgen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/vm/crossgen/wks_crossgen.nativeproj | 1 | ||||
-rw-r--r-- | src/vm/dac/dacwks.targets | 1 | ||||
-rw-r--r-- | src/vm/dbggcinfodecoder.cpp | 932 | ||||
-rw-r--r-- | src/vm/gcinfodecoder.cpp | 55 | ||||
-rw-r--r-- | src/vm/wks/wks.targets | 1 |
16 files changed, 1 insertions, 2905 deletions
diff --git a/src/gcdump/gcdumpnonx86.cpp b/src/gcdump/gcdumpnonx86.cpp index b6562d9892..53e16ffbff 100644 --- a/src/gcdump/gcdumpnonx86.cpp +++ b/src/gcdump/gcdumpnonx86.cpp @@ -522,6 +522,3 @@ void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock, #define VALIDATE_ROOT(isInterior, hCallBack, pObjRef) ((void)0) #include "../vm/gcinfodecoder.cpp" #include "../gcinfo/gcinfodumper.cpp" -#ifdef VERIFY_GCINFO -#include "../vm/dbggcinfodecoder.cpp" -#endif diff --git a/src/gcinfo/CMakeLists.txt b/src/gcinfo/CMakeLists.txt index 11857184e3..016e1e273f 100644 --- a/src/gcinfo/CMakeLists.txt +++ b/src/gcinfo/CMakeLists.txt @@ -3,7 +3,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set( GCINFO_SOURCES arraylist.cpp gcinfoencoder.cpp - dbggcinfoencoder.cpp ) if(CLR_CMAKE_PLATFORM_ARCH_I386) diff --git a/src/gcinfo/dbggcinfoencoder.cpp b/src/gcinfo/dbggcinfoencoder.cpp deleted file mode 100644 index 98480cf26d..0000000000 --- a/src/gcinfo/dbggcinfoencoder.cpp +++ /dev/null @@ -1,981 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -/***************************************************************************** - * - * GC Information Encoding API - * - * This is an older well-tested implementation - * now used to verify the real encoding - * Define VERIFY_GCINFO to enable the verification - * - */ - -#ifdef VERIFY_GCINFO - -#include "dbggcinfoencoder.h" -#include "gcinfoencoder.h" - - -namespace DbgGcInfo { - - -#ifdef _DEBUG - #ifndef LOGGING - #define LOGGING - #endif -#endif -#include "log.h" - - -void *GcInfoEncoder::LifetimeTransitionAllocator::Alloc (void *context, SIZE_T cb) -{ - GcInfoEncoder *pGcInfoEncoder = CONTAINING_RECORD(context, GcInfoEncoder, m_LifetimeTransitions); - return pGcInfoEncoder->m_pAllocator->Alloc(cb); -} - -void GcInfoEncoder::LifetimeTransitionAllocator::Free (void *context, void *pv) -{ -#ifdef MUST_CALL_JITALLOCATOR_FREE - GcInfoEncoder *pGcInfoEncoder = CONTAINING_RECORD(context, GcInfoEncoder, m_LifetimeTransitions); - pGcInfoEncoder->m_pAllocator->Free(pv); -#endif -} - - -BitStreamWriter::MemoryBlockList::MemoryBlockList() - : m_head(nullptr), - m_tail(nullptr) -{ -} - -BitStreamWriter::MemoryBlock* BitStreamWriter::MemoryBlockList::AppendNew(IJitAllocator* 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(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 ) -{ - _ASSERTE( pCorJitInfo != NULL ); - _ASSERTE( pMethodInfo != NULL ); - _ASSERTE( pJitAllocator != NULL ); - - m_pCorJitInfo = pCorJitInfo; - m_pMethodInfo = pMethodInfo; - m_pAllocator = pJitAllocator; - -#ifdef _DEBUG - CORINFO_METHOD_HANDLE methodHandle = pMethodInfo->ftn; - - // Get the name of the current method along with the enclosing class - // or module name. - m_MethodName = (char *) - pCorJitInfo->getMethodName(methodHandle, (const char **)&m_ModuleName); -#endif - - - m_MappingTableSize = m_MappingTableInitialSize; - m_SlotMappings = (GcSlotDesc*) m_pAllocator->Alloc( m_MappingTableSize*sizeof(GcSlotDesc) ); - m_NumSlotMappings = 0; -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - m_NumSafePointsWithGcState = 0; -#endif -#endif - - m_SecurityObjectStackSlot = NO_SECURITY_OBJECT; - m_PSPSymStackSlot = NO_PSP_SYM; - m_GenericsInstContextStackSlot = NO_GENERICS_INST_CONTEXT; - m_StackBaseRegister = NO_STACK_BASE_REGISTER; - m_SizeOfEditAndContinuePreservedArea = NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA; - m_IsVarArg = false; - m_LastInterruptibleRangeStopOffset = 0; - m_NumInterruptibleRanges = 0; - -#ifdef _DEBUG - m_IsMappingTableFrozen = FALSE; - m_CodeLength = 0; -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - m_SizeOfStackOutgoingAndScratchArea = -1; -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA -#endif //_DEBUG -} - -GcSlotId GcInfoEncoder::GetRegisterSlotId( UINT32 regNum, GcSlotFlags flags ) -{ - // We could lookup an existing identical slot in the mapping table (via some hashtable mechanism). - // We just create duplicates for now. - -#ifdef _DEBUG - _ASSERTE( !m_IsMappingTableFrozen ); -#endif - - if( m_NumSlotMappings == m_MappingTableSize ) - { - GrowMappingTable(); - } - _ASSERTE( m_NumSlotMappings < m_MappingTableSize ); - - m_SlotMappings[ m_NumSlotMappings ].IsRegister = 1; - m_SlotMappings[ m_NumSlotMappings ].Slot.RegisterNumber = regNum; - m_SlotMappings[ m_NumSlotMappings ].IsInterior = ( flags & GC_SLOT_INTERIOR ) ? 1 : 0; - m_SlotMappings[ m_NumSlotMappings ].IsPinned = ( flags & GC_SLOT_PINNED ) ? 1 : 0; - - GcSlotId newSlotId; - newSlotId = m_NumSlotMappings++; - return newSlotId; -} - -GcSlotId GcInfoEncoder::GetStackSlotId( INT32 spOffset, GcSlotFlags flags, GcStackSlotBase spBase ) -{ - // We could lookup an existing identical slot in the mapping table (via some hashtable mechanism). - // We just create duplicates for now. - -#ifdef _DEBUG - _ASSERTE( !m_IsMappingTableFrozen ); -#endif - - if( m_NumSlotMappings == m_MappingTableSize ) - { - GrowMappingTable(); - } - _ASSERTE( m_NumSlotMappings < m_MappingTableSize ); - - // Not valid to reference anything below the current stack pointer - _ASSERTE(GC_SP_REL != spBase || spOffset >= 0); - - m_SlotMappings[ m_NumSlotMappings ].IsRegister = 0; - m_SlotMappings[ m_NumSlotMappings ].Slot.Stack.SpOffset = spOffset; - m_SlotMappings[ m_NumSlotMappings ].Slot.Stack.Base = spBase; - m_SlotMappings[ m_NumSlotMappings ].IsInterior = ( flags & GC_SLOT_INTERIOR ) ? 1 : 0; - m_SlotMappings[ m_NumSlotMappings ].IsPinned = ( flags & GC_SLOT_PINNED ) ? 1 : 0; - - GcSlotId newSlotId; - newSlotId = m_NumSlotMappings++; - return newSlotId; -} - -void GcInfoEncoder::GrowMappingTable() -{ - m_MappingTableSize *= 2; - GcSlotDesc* newMappingTable = (GcSlotDesc*) m_pAllocator->Alloc( m_MappingTableSize * sizeof(GcSlotDesc) ); - memcpy( newMappingTable, m_SlotMappings, m_NumSlotMappings * sizeof(GcSlotDesc) ); - -#ifdef MUST_CALL_JITALLOCATOR_FREE - m_pAllocator->Free( m_SlotMappings ); -#endif - - m_SlotMappings = newMappingTable; -} - -GcSlotSet::GcSlotSet( GcInfoEncoder* pEncoder ) -{ -#ifdef _DEBUG - _ASSERTE( pEncoder->m_IsMappingTableFrozen ); -#endif - - m_pEncoder = pEncoder; - m_NumBytes = ( pEncoder->m_NumSlotMappings + 7 ) / 8; - m_Data = (BYTE*) pEncoder->m_pAllocator->Alloc( m_NumBytes ); -} - -// Copy constructor -GcSlotSet::GcSlotSet( GcSlotSet & other ) -{ - m_pEncoder = other.m_pEncoder; - m_NumBytes = other.m_NumBytes; - m_Data = (BYTE*) other.m_pEncoder->m_pAllocator->Alloc( m_NumBytes ); - memcpy( m_Data, other.m_Data, m_NumBytes); -} - -void GcSlotSet::Add( GcSlotId slotId ) -{ - _ASSERTE( slotId < m_pEncoder->m_NumSlotMappings ); - m_Data[ slotId / 8 ] |= 1 << ( slotId % 8 ); -} - -void GcSlotSet::Remove( GcSlotId slotId ) -{ - _ASSERTE( slotId < m_pEncoder->m_NumSlotMappings ); - m_Data[ slotId / 8 ] &= ~( 1 << ( slotId % 8 ) ); -} - -// Not used -#if 0 - -void GcSlotSet::Add( GcSlotSet & other ) -{ - _ASSERTE( m_pEncoder == other.m_pEncoder ); - - for( int i=0; i<m_NumBytes; i++ ) - { - m_Data[ i ] |= other.m_Data[ i ]; - } -} - -void GcSlotSet::Subtract( GcSlotSet & other ) -{ - _ASSERTE( m_pEncoder == other.m_pEncoder ); - - for( int i=0; i<m_NumBytes; i++ ) - { - m_Data[ i ] &= ~( other.m_Data[ i ] ); - } -} - -void GcSlotSet::Intersect( GcSlotSet & other ) -{ - _ASSERTE( m_pEncoder == other.m_pEncoder ); - - for( int i=0; i<m_NumBytes; i++ ) - { - m_Data[ i ] &= other.m_Data[ i ]; - } -} - -#endif // unused - - -void GcInfoEncoder::FinalizeSlotIds() -{ -#ifdef _DEBUG - m_IsMappingTableFrozen = TRUE; -#endif -} - - -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - -void GcInfoEncoder::DefineGcStateAtSafePoint( - UINT32 instructionOffset, - GcSlotSet &liveSlots - ) -{ -#ifdef _DEBUG - _ASSERTE( m_IsMappingTableFrozen ); -#endif - -#ifdef _DEBUG - // Verify that any slot is not reported multiple times. This is O(n^2) but it executes only under _DEBUG - for( INT32 i1=0; i1<((INT32)m_NumSlotMappings)-1; i1++ ) - { - BYTE isLive1 = liveSlots.m_Data[ i1 / 8 ] & ( 1 << ( i1 % 8 ) ); - if( isLive1 ) - for( UINT32 i2=i1+1; i2<m_NumSlotMappings; i2++ ) - { - BYTE isLive2 = liveSlots.m_Data[ i2 / 8 ] & ( 1 << ( i2 % 8 ) ); - if( isLive2 ) - { - if( m_SlotMappings[ i1 ].IsRegister && m_SlotMappings[ i2 ].IsRegister ) - { - _ASSERTE( m_SlotMappings[ i1 ].Slot.RegisterNumber != m_SlotMappings[ i2 ].Slot.RegisterNumber ); - } - else if( !m_SlotMappings[ i1 ].IsRegister && !m_SlotMappings[ i2 ].IsRegister ) - { - _ASSERTE( m_SlotMappings[ i1 ].Slot.SpOffset != m_SlotMappings[ i2 ].Slot.SpOffset ); - } - } - } - } -#endif - - m_PartiallyInterruptibleInfoWriter.Write( instructionOffset, 32 ); - - UINT32 i; - for( i=0; i<m_NumSlotMappings/8; i++ ) - m_PartiallyInterruptibleInfoWriter.Write( liveSlots.m_Data[ i ], 8 ); - - if( m_NumSlotMappings % 8 > 0 ) - m_PartiallyInterruptibleInfoWriter.Write( liveSlots.m_Data[ i ], m_NumSlotMappings % 8 ); - - m_NumSafePointsWithGcState++; -} - -#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED -#endif - -void GcInfoEncoder::DefineInterruptibleRange( UINT32 startInstructionOffset, UINT32 length ) -{ - UINT32 stopInstructionOffset = startInstructionOffset + length; - - size_t normStartDelta = NORMALIZE_CODE_OFFSET(startInstructionOffset) - NORMALIZE_CODE_OFFSET(m_LastInterruptibleRangeStopOffset); - size_t normStopDelta = NORMALIZE_CODE_OFFSET(stopInstructionOffset) - NORMALIZE_CODE_OFFSET(startInstructionOffset); - _ASSERTE(normStopDelta > 0); - - m_LastInterruptibleRangeStopOffset = startInstructionOffset + length; - - m_NumInterruptibleRanges++; - - m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(normStartDelta, INTERRUPTIBLE_RANGE_DELTA_ENCBASE); - - m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(normStopDelta-1, INTERRUPTIBLE_RANGE_DELTA_ENCBASE ); -} - - -/////////////////////////////////////////////////////////////////////////// -// Tracking information -/////////////////////////////////////////////////////////////////////////// - - -// -// For inputs, pass zero as offset -// - -void GcInfoEncoder::SetSlotState( - UINT32 instructionOffset, - GcSlotId slotId, - GcSlotState slotState - ) -{ - LifetimeTransition transition; - - transition.SlotDesc = m_SlotMappings[ slotId ]; - transition.CodeOffset = instructionOffset; - transition.BecomesLive = ( slotState == GC_SLOT_LIVE ); - - *( m_LifetimeTransitions.Append() ) = transition; -} - - -void GcInfoEncoder::SetIsVarArg() -{ - m_IsVarArg = true; -} - -void GcInfoEncoder::SetCodeLength( UINT32 length ) -{ - _ASSERTE( length > 0 ); - _ASSERTE( m_CodeLength == 0 || m_CodeLength == length ); - m_CodeLength = length; -} - - -void GcInfoEncoder::SetSecurityObjectStackSlot( INT32 spOffset ) -{ - _ASSERTE( spOffset != NO_SECURITY_OBJECT ); - _ASSERTE( m_SecurityObjectStackSlot == NO_SECURITY_OBJECT || m_SecurityObjectStackSlot == spOffset ); - m_SecurityObjectStackSlot = spOffset; -} - -void GcInfoEncoder::SetPSPSymStackSlot( INT32 spOffsetPSPSym ) -{ - _ASSERTE( spOffsetPSPSym != NO_PSP_SYM ); - _ASSERTE( m_PSPSymStackSlot == NO_PSP_SYM || m_PSPSymStackSlot == spOffsetPSPSym ); - - m_PSPSymStackSlot = spOffsetPSPSym; -} - -void GcInfoEncoder::SetGenericsInstContextStackSlot( INT32 spOffsetGenericsContext ) -{ - _ASSERTE( spOffsetGenericsContext != NO_GENERICS_INST_CONTEXT); - _ASSERTE( m_GenericsInstContextStackSlot == NO_GENERICS_INST_CONTEXT || m_GenericsInstContextStackSlot == spOffsetGenericsContext ); - - m_GenericsInstContextStackSlot = spOffsetGenericsContext; -} - -void GcInfoEncoder::SetStackBaseRegister( UINT32 regNum ) -{ - _ASSERTE( regNum != NO_STACK_BASE_REGISTER ); - _ASSERTE( m_StackBaseRegister == NO_STACK_BASE_REGISTER || m_StackBaseRegister == regNum ); - m_StackBaseRegister = regNum; -} - -void GCInfoEncoder::SetSizeOfEditAndContinuePreservedArea( UINT32 slots ) -{ - _ASSERTE( regNum != NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA ); - _ASSERTE( m_SizeOfEditAndContinuePreservedArea == NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA ); - m_SizeOfEditAndContinuePreservedArea = slots; -} - - - -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA -void GcInfoEncoder::SetSizeOfStackOutgoingAndScratchArea( UINT32 size ) -{ - _ASSERTE( size != -1 ); - _ASSERTE( m_SizeOfStackOutgoingAndScratchArea == -1 || m_SizeOfStackOutgoingAndScratchArea == size ); - m_SizeOfStackOutgoingAndScratchArea = size; -} -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA - - -int __cdecl CompareLifetimeTransitionsForQsort(const void* p1, const void* p2) -{ - const GcInfoEncoder::LifetimeTransition* pFirst = (const GcInfoEncoder::LifetimeTransition*) p1; - const GcInfoEncoder::LifetimeTransition* pSecond = (const GcInfoEncoder::LifetimeTransition*) p2; - - // All registers come before all stack slots - if( pFirst->SlotDesc.IsRegister && !pSecond->SlotDesc.IsRegister ) return -1; - if( !pFirst->SlotDesc.IsRegister && pSecond->SlotDesc.IsRegister ) return 1; - - // Then sort them by slot - if( pFirst->SlotDesc.IsRegister ) - { - _ASSERTE( pSecond->SlotDesc.IsRegister ); - if( pFirst->SlotDesc.Slot.RegisterNumber < pSecond->SlotDesc.Slot.RegisterNumber ) return -1; - if( pFirst->SlotDesc.Slot.RegisterNumber > pSecond->SlotDesc.Slot.RegisterNumber ) return 1; - } - else - { - _ASSERTE( !pSecond->SlotDesc.IsRegister ); - if( pFirst->SlotDesc.Slot.Stack.SpOffset < pSecond->SlotDesc.Slot.Stack.SpOffset ) return -1; - if( pFirst->SlotDesc.Slot.Stack.SpOffset > pSecond->SlotDesc.Slot.Stack.SpOffset ) return 1; - - // This is arbitrary, but we want to make sure they are considered separate slots - if( pFirst->SlotDesc.Slot.Stack.Base < pSecond->SlotDesc.Slot.Stack.Base ) return -1; - if( pFirst->SlotDesc.Slot.Stack.Base > pSecond->SlotDesc.Slot.Stack.Base ) return 1; - } - - // Then sort them by code offset - size_t firstOffset = pFirst->CodeOffset; - size_t secondOffset = pSecond->CodeOffset; - if( firstOffset < secondOffset ) return -1; - if( firstOffset > secondOffset ) return 1; - - // - // Same slot and offset. We put all the going-live transition first - // so that the encoder will skip the remaining transitions and - // the going-live transitions take precedence - // - _ASSERTE( ( pFirst->BecomesLive == 0 ) || ( pFirst->BecomesLive == 1 ) ); - _ASSERTE( ( pSecond->BecomesLive == 0 ) || ( pSecond->BecomesLive == 1 ) ); - return ( pSecond->BecomesLive - pFirst->BecomesLive ); -} - - -void GcInfoEncoder::Build() -{ - SIZE_T i; - - /////////////////////////////////////////////////////////////////////// - // Method header - /////////////////////////////////////////////////////////////////////// - - m_HeaderInfoWriter.Write( ( m_IsVarArg ? 1 : 0 ), 1 ); - - if(m_SecurityObjectStackSlot != NO_SECURITY_OBJECT) - { - m_HeaderInfoWriter.Write( 1, 1 ); - m_HeaderInfoWriter.EncodeVarLengthSigned(NORMALIZE_STACK_SLOT(m_SecurityObjectStackSlot), SECURITY_OBJECT_STACK_SLOT_ENCBASE); - } - else - { - m_HeaderInfoWriter.Write( 0, 1 ); - } - - if (m_PSPSymStackSlot != NO_PSP_SYM) - { - m_HeaderInfoWriter.Write( 1, 1 ); - m_HeaderInfoWriter.EncodeVarLengthSigned(NORMALIZE_STACK_SLOT(m_PSPSymStackSlot), PSP_SYM_STACK_SLOT_ENCBASE); - } - else - { - m_HeaderInfoWriter.Write( 0, 1 ); - } - - if (m_GenericsInstContextStackSlot != NO_GENERICS_INST_CONTEXT) - { - m_HeaderInfoWriter.Write( 1, 1 ); - m_HeaderInfoWriter.EncodeVarLengthSigned(NORMALIZE_STACK_SLOT(m_GenericsInstContextStackSlot), GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE); - } - else - { - m_HeaderInfoWriter.Write( 0, 1 ); - } - - _ASSERTE( m_CodeLength > 0 ); - m_HeaderInfoWriter.EncodeVarLengthUnsigned(NORMALIZE_CODE_LENGTH(m_CodeLength), CODE_LENGTH_ENCBASE); - - if(m_StackBaseRegister != NO_STACK_BASE_REGISTER) - { - m_HeaderInfoWriter.Write( 1, 1 ); - m_HeaderInfoWriter.EncodeVarLengthUnsigned(NORMALIZE_STACK_BASE_REGISTER(m_StackBaseRegister), STACK_BASE_REGISTER_ENCBASE); - } - else - { - m_HeaderInfoWriter.Write( 0, 1 ); - } - - if(m_SizeOfEditAndContinuePreservedArea != NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA) - { - m_HeaderInfoWriter.Write( 1, 1 ); - m_HeaderInfoWriter.EncodeVarLengthUnsigned(m_SizeOfEditAndContinuePreservedArea, SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE); - } - else - { - m_HeaderInfoWriter.Write( 0, 1 ); - } - -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - _ASSERTE( m_SizeOfStackOutgoingAndScratchArea != -1 ); - m_HeaderInfoWriter.EncodeVarLengthUnsigned(NORMALIZE_SIZE_OF_STACK_AREA(m_SizeOfStackOutgoingAndScratchArea), SIZE_OF_STACK_AREA_ENCBASE); -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA - - - /////////////////////////////////////////////////////////////////////// - // Fully-interruptible: encode number of interruptible ranges - /////////////////////////////////////////////////////////////////////// - - m_HeaderInfoWriter.EncodeVarLengthUnsigned(NORMALIZE_NUM_INTERRUPTIBLE_RANGES(m_NumInterruptibleRanges), NUM_INTERRUPTIBLE_RANGES_ENCBASE); - -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - - /////////////////////////////////////////////////////////////////////// - // Partially-interruptible: Encode call sites - /////////////////////////////////////////////////////////////////////// - - m_HeaderInfoWriter.Write( m_NumSafePointsWithGcState, sizeof( m_NumSafePointsWithGcState ) * 8 ); - - if( m_NumSafePointsWithGcState > 0 ) - { - m_HeaderInfoWriter.Write( m_NumSlotMappings, sizeof( m_NumSlotMappings ) * 8 ); - - /////////////////////////////////////////////////////////////////////// - // Partially-interruptible: Encode slot mappings - /////////////////////////////////////////////////////////////////////// - - // Assert that we can write a GcSlotDesc with a single call to BitStreamWriter.Write() - _ASSERTE( sizeof( GcSlotDesc ) <= sizeof( size_t ) ); - for( UINT32 i=0; i<m_NumSlotMappings; i++ ) - { - size_t data = 0; - *( (GcSlotDesc*) &data ) = m_SlotMappings[ i ]; - m_PartiallyInterruptibleInfoWriter.Write( data, sizeof( GcSlotDesc ) * 8 ); - } - } - -#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED -#endif - - /////////////////////////////////////////////////////////////////////// - // Fully-interruptible: Encode lifetime transitions - /////////////////////////////////////////////////////////////////////// - - m_rgSortedTransitions = (LifetimeTransition*)m_pAllocator->Alloc(m_LifetimeTransitions.Count() * sizeof(LifetimeTransition)); - m_LifetimeTransitions.CopyTo(m_rgSortedTransitions); - - // Sort them first - size_t numTransitions = m_LifetimeTransitions.Count(); - qsort(m_rgSortedTransitions, numTransitions, sizeof(LifetimeTransition), CompareLifetimeTransitionsForQsort); - - //------------------------------------------------------------------ - // Count registers and stack slots - //------------------------------------------------------------------ - - int numRegisters = 0; - int numStackSlots = 0; - - if(numTransitions > 0) - { - i = 1; - if(m_rgSortedTransitions[ 0 ].SlotDesc.IsRegister) - { - numRegisters++; - - for( ; i < numTransitions; i++ ) - { - if(!(m_rgSortedTransitions[ i ].SlotDesc.IsRegister)) - { - numStackSlots++; - i++; - break; - } - _ASSERTE(m_rgSortedTransitions[ i-1 ].SlotDesc.IsRegister); - if((m_rgSortedTransitions[ i ].SlotDesc.Slot.RegisterNumber) != (m_rgSortedTransitions[ i-1 ].SlotDesc.Slot.RegisterNumber)) - numRegisters++; - } - } - else - { - numStackSlots++; - } - - for( ; i < numTransitions; i++ ) - { - _ASSERTE(!(m_rgSortedTransitions[ i-1 ].SlotDesc.IsRegister)); - if((m_rgSortedTransitions[ i ].SlotDesc.Slot.Stack) != (m_rgSortedTransitions[ i-1 ].SlotDesc.Slot.Stack)) - numStackSlots++; - } - } - - - size_t __registerSize = 0; - size_t __stackSlotSize = 0; - size_t __transitionSize = 0; - size_t __numTransitions = 0; - - - //------------------------------------------------------------------ - // Encode registers - //------------------------------------------------------------------ - - i = 0; - - m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(numRegisters, NUM_REGISTERS_ENCBASE); - - UINT32 lastNormRegNum = 0; - - for( int j=0; j < numRegisters; j++ ) - { - _ASSERTE(m_rgSortedTransitions[ i ].SlotDesc.IsRegister); - - UINT32 currentRegNum = m_rgSortedTransitions[ i ].SlotDesc.Slot.RegisterNumber; - - // Encode slot identification - UINT32 currentNormRegNum = NORMALIZE_REGISTER(currentRegNum); - if( j == 0 ) - __registerSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(currentNormRegNum, REGISTER_ENCBASE); - else - __registerSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(currentNormRegNum - lastNormRegNum - 1, REGISTER_DELTA_ENCBASE); - lastNormRegNum = currentNormRegNum; - - LifetimeTransition* pLastEncodedTransition = NULL; - - for( ; i < numTransitions; i++) - { - LifetimeTransition* pTransition = &(m_rgSortedTransitions[ i ]); - - if( !(pTransition->SlotDesc.IsRegister) || (pTransition->SlotDesc.Slot.RegisterNumber != currentRegNum)) - break; - - if( (pLastEncodedTransition == NULL) ) - { - // Skip initial going-dead transitions (if any) - if(!pTransition->BecomesLive) - continue; - - // Encode first going-live transition - size_t normCodeOffset = NORMALIZE_CODE_OFFSET(pTransition->CodeOffset)+1; // Leave 0 available as terminator - __transitionSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(normCodeOffset, NORM_CODE_OFFSET_DELTA_ENCBASE); - - __transitionSize += EncodeFullyInterruptibleSlotFlags(pTransition->SlotDesc); - - __numTransitions++; - } - else - { - _ASSERTE(pLastEncodedTransition->SlotDesc.IsRegister && pLastEncodedTransition->SlotDesc.Slot.RegisterNumber == currentRegNum); - - // Skip transitions on identical offsets - // If there are multiple transitions on the same code offset, we'll encode the first one only - _ASSERTE(i > 0); - LifetimeTransition* pPrevTransition = &(m_rgSortedTransitions[ i-1 ]); - if( (pPrevTransition->CodeOffset == pTransition->CodeOffset) ) - { - _ASSERTE((!pPrevTransition->BecomesLive || !pTransition->BecomesLive) || - (pPrevTransition->SlotDesc.IsInterior == pTransition->SlotDesc.IsInterior) && - (pPrevTransition->SlotDesc.IsPinned == pTransition->SlotDesc.IsPinned)); - continue; - } - - // Also skip redundant transitions - if( (pLastEncodedTransition->BecomesLive == pTransition->BecomesLive) && - (pLastEncodedTransition->SlotDesc.IsInterior == pTransition->SlotDesc.IsInterior) && - (pLastEncodedTransition->SlotDesc.IsPinned == pTransition->SlotDesc.IsPinned) ) - continue; - - // Encode transition - size_t normCodeOffsetDelta = NORMALIZE_CODE_OFFSET(pTransition->CodeOffset) - NORMALIZE_CODE_OFFSET(pLastEncodedTransition->CodeOffset); - _ASSERTE(normCodeOffsetDelta != 0); // Leave 0 available as terminator - __transitionSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(normCodeOffsetDelta, NORM_CODE_OFFSET_DELTA_ENCBASE); - - if(pTransition->BecomesLive) - { - m_FullyInterruptibleInfoWriter.Write(1, 1); - __transitionSize += EncodeFullyInterruptibleSlotFlags(pTransition->SlotDesc) + 1; - } - else - { - m_FullyInterruptibleInfoWriter.Write(0, 1); - __transitionSize++; - } - - __numTransitions++; - } - - pLastEncodedTransition = pTransition; - } - - // Encode termination for this slot - m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(0, NORM_CODE_OFFSET_DELTA_ENCBASE); - } - - - //------------------------------------------------------------------ - // Encode stack slots - //------------------------------------------------------------------ - - m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(numStackSlots, NUM_STACK_SLOTS_ENCBASE); - - INT32 lastNormStackSlot = 0; - - for( int j=0; j < numStackSlots; j++ ) - { - _ASSERTE(!m_rgSortedTransitions[ i ].SlotDesc.IsRegister); - - GcStackSlot currentStackSlot = m_rgSortedTransitions[ i ].SlotDesc.Slot.Stack; - - // Encode slot identification - INT32 currentNormStackSlot = NORMALIZE_STACK_SLOT(currentStackSlot.SpOffset); - if( j == 0 ) - __stackSlotSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthSigned(currentNormStackSlot, STACK_SLOT_ENCBASE); - else - __stackSlotSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(currentNormStackSlot - lastNormStackSlot, STACK_SLOT_DELTA_ENCBASE); - lastNormStackSlot = currentNormStackSlot; - _ASSERTE((currentStackSlot.Base & ~3) == 0); - m_FullyInterruptibleInfoWriter.Write(currentStackSlot.Base, 2); - __stackSlotSize += 2; - - LifetimeTransition* pLastEncodedTransition = NULL; - - for( ; i < numTransitions; i++) - { - LifetimeTransition* pTransition = &(m_rgSortedTransitions[ i ]); - - _ASSERTE(!pTransition->SlotDesc.IsRegister); - - if(pTransition->SlotDesc.Slot.Stack != currentStackSlot) - break; - - if( (pLastEncodedTransition == NULL) ) - { - // Skip initial going-dead transitions (if any) - if(!pTransition->BecomesLive) - continue; - - // Encode first going-live transition - size_t normCodeOffset = NORMALIZE_CODE_OFFSET(pTransition->CodeOffset)+1; // Leave 0 available as terminator - __transitionSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(normCodeOffset, NORM_CODE_OFFSET_DELTA_ENCBASE); - - __transitionSize += EncodeFullyInterruptibleSlotFlags(pTransition->SlotDesc); - - __numTransitions++; - } - else - { - _ASSERTE(!(pLastEncodedTransition->SlotDesc.IsRegister) && pLastEncodedTransition->SlotDesc.Slot.Stack == currentStackSlot); - - // Skip transitions on identical offsets - // If there are multiple transitions on the same code offset, we'll encode the first one only - _ASSERTE(i > 0); - LifetimeTransition* pPrevTransition = &(m_rgSortedTransitions[ i-1 ]); - if( (pPrevTransition->CodeOffset == pTransition->CodeOffset) ) - { - _ASSERTE((!pPrevTransition->BecomesLive || !pTransition->BecomesLive) || - (pPrevTransition->SlotDesc.IsInterior == pTransition->SlotDesc.IsInterior) && - (pPrevTransition->SlotDesc.IsPinned == pTransition->SlotDesc.IsPinned)); - continue; - } - - // Also skip redundant transitions - if( (pLastEncodedTransition->BecomesLive == pTransition->BecomesLive) && - (pLastEncodedTransition->SlotDesc.IsInterior == pTransition->SlotDesc.IsInterior) && - (pLastEncodedTransition->SlotDesc.IsPinned == pTransition->SlotDesc.IsPinned) ) - continue; - - // Encode transition - size_t normCodeOffsetDelta = NORMALIZE_CODE_OFFSET(pTransition->CodeOffset) - NORMALIZE_CODE_OFFSET(pLastEncodedTransition->CodeOffset); - _ASSERTE(normCodeOffsetDelta != 0); // Leave 0 available as terminator - __transitionSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(normCodeOffsetDelta, NORM_CODE_OFFSET_DELTA_ENCBASE); - - if(pTransition->BecomesLive) - { - m_FullyInterruptibleInfoWriter.Write(1, 1); - __transitionSize += EncodeFullyInterruptibleSlotFlags(pTransition->SlotDesc) + 1; - } - else - { - m_FullyInterruptibleInfoWriter.Write(0, 1); - __transitionSize++; - } - - __numTransitions++; - } - - pLastEncodedTransition = pTransition; - } - - // Encode termination for this slot - __transitionSize += m_FullyInterruptibleInfoWriter.EncodeVarLengthUnsigned(0, NORM_CODE_OFFSET_DELTA_ENCBASE); - } - -} - -size_t GcInfoEncoder::GetByteCount() -{ - return m_HeaderInfoWriter.GetByteCount() + -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - m_PartiallyInterruptibleInfoWriter.GetByteCount() + -#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED -#endif - m_FullyInterruptibleInfoWriter.GetByteCount(); -} - -// -// Write encoded information to its final destination and frees temporary buffers. -// The encoder shouldn't be used anymore after calling this method. -// -BYTE* GcInfoEncoder::Emit(BYTE* destBuffer) -{ - size_t cbGcInfoSize = GetByteCount(); - - _ASSERTE( destBuffer ); - - m_HeaderInfoWriter.CopyTo( destBuffer ); - destBuffer += m_HeaderInfoWriter.GetByteCount(); - m_HeaderInfoWriter.Dispose(); - -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - m_PartiallyInterruptibleInfoWriter.CopyTo( destBuffer ); - destBuffer += m_PartiallyInterruptibleInfoWriter.GetByteCount(); - m_PartiallyInterruptibleInfoWriter.Dispose(); -#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED -#endif - - m_FullyInterruptibleInfoWriter.CopyTo( destBuffer ); - m_FullyInterruptibleInfoWriter.Dispose(); - - return destBuffer; -} - -void * GcInfoEncoder::eeAllocGCInfo (size_t blockSize) -{ - return m_pCorJitInfo->allocGCInfo((ULONG)blockSize); -} - - -BitStreamWriter::BitStreamWriter( IJitAllocator* pAllocator ) -{ - m_pAllocator = pAllocator; - m_BitCount = 0; -#ifdef _DEBUG - m_MemoryBlocksCount = 0; -#endif - - // We are going to need at least one memory block, so we pre-allocate it - AllocMemoryBlock(); - InitCurrentSlot(); -} - -// -// bit 0 is the least significative bit -// The stream encodes the first come bit in the least significant bit of each byte -// -void BitStreamWriter::Write( size_t data, int count ) -{ - _ASSERTE( count > 0 ); - _ASSERT( count <= sizeof( size_t )*8 ); - - // Increment it now as we change count later on - m_BitCount += count; - - if( count > m_FreeBitsInCurrentSlot ) - { - if( m_FreeBitsInCurrentSlot > 0 ) - { - WriteInCurrentSlot( data, m_FreeBitsInCurrentSlot ); - count -= m_FreeBitsInCurrentSlot; - data >>= m_FreeBitsInCurrentSlot; - } - - _ASSERTE( count > 0 ); - - // Initialize the next slot - if( ++m_pCurrentSlot >= m_OutOfBlockSlot ) - { - // Get a new memory block - AllocMemoryBlock(); - } - - InitCurrentSlot(); - - // Write the remainder - WriteInCurrentSlot( data, count ); - m_FreeBitsInCurrentSlot -= count; - } - else - { - WriteInCurrentSlot( data, count ); - m_FreeBitsInCurrentSlot -= count; - // if m_FreeBitsInCurrentSlot becomes 0 a nwe slot will initialized on the next request - } -} - - -void BitStreamWriter::CopyTo( BYTE* buffer ) -{ - int i,c; - BYTE* source = NULL; - - MemoryBlock* pMemBlock = m_MemoryBlocks.Head(); - _ASSERTE( pMemBlockDesc != NULL ); - while (pMemBlock->Next() != NULL) - { - source = (BYTE*) pMemBlock->Contents; - // @TODO: use memcpy instead - for( i = 0; i < m_MemoryBlockSize; i++ ) - { - *( buffer++ ) = *( source++ ); - } - - pMemBlock = pMemBlock->Next(); - } - - 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 ); - // @TODO: use memcpy instead - for( i = 0; i < c; i++ ) - { - *( buffer++ ) = *( source++ ); - } - -} - -void BitStreamWriter::Dispose() -{ - m_MemoryBlocks.Dispose(m_pAllocator); -} - -} - -#endif // VERIFY_GCINFO - diff --git a/src/gcinfo/gcinfo.settings.targets b/src/gcinfo/gcinfo.settings.targets index f600e2a904..5c241b353a 100644 --- a/src/gcinfo/gcinfo.settings.targets +++ b/src/gcinfo/gcinfo.settings.targets @@ -14,7 +14,6 @@ <ItemGroup> <CppCompile Include="..\ArrayList.cpp" /> <CppCompile Include="..\GCInfoEncoder.cpp" /> - <CppCompile Include="..\DbgGCInfoEncoder.cpp" /> </ItemGroup> <!-- Import the targets --> diff --git a/src/gcinfo/gcinfoencoder.cpp b/src/gcinfo/gcinfoencoder.cpp index e6359c86c8..514a3c96be 100644 --- a/src/gcinfo/gcinfoencoder.cpp +++ b/src/gcinfo/gcinfoencoder.cpp @@ -12,10 +12,6 @@ #include "gcinfoencoder.h" -#ifdef VERIFY_GCINFO -#include "dbggcinfoencoder.h" -#endif - #ifdef _DEBUG #ifndef LOGGING #define LOGGING @@ -446,9 +442,6 @@ GcInfoEncoder::GcInfoEncoder( m_Info2( pJitAllocator ), m_InterruptibleRanges( pJitAllocator ), m_LifetimeTransitions( pJitAllocator ) -#ifdef VERIFY_GCINFO - , m_DbgEncoder(pCorJitInfo, pMethodInfo, pJitAllocator) -#endif { #ifdef MEASURE_GCINFO // This causes multiple complus.log files in JIT64. TODO: consider using ICorJitInfo::logMsg instead. @@ -552,11 +545,6 @@ GcSlotId GcInfoEncoder::GetRegisterSlotId( UINT32 regNum, GcSlotFlags flags ) GcSlotId newSlotId; newSlotId = m_NumSlots++; -#ifdef VERIFY_GCINFO - GcSlotId dbgSlotId = m_DbgEncoder.GetRegisterSlotId(regNum, flags); - _ASSERTE(dbgSlotId == newSlotId); -#endif - return newSlotId; } @@ -590,11 +578,6 @@ GcSlotId GcInfoEncoder::GetStackSlotId( INT32 spOffset, GcSlotFlags flags, GcSta GcSlotId newSlotId; newSlotId = m_NumSlots++; -#ifdef VERIFY_GCINFO - GcSlotId dbgSlotId = m_DbgEncoder.GetStackSlotId(spOffset, flags, spBase); - _ASSERTE(dbgSlotId == newSlotId); -#endif - return newSlotId; } @@ -624,10 +607,6 @@ void GcInfoEncoder::WriteSlotStateVector(BitStreamWriter &writer, const BitArray void GcInfoEncoder::DefineInterruptibleRange( UINT32 startInstructionOffset, UINT32 length ) { -#ifdef VERIFY_GCINFO - m_DbgEncoder.DefineInterruptibleRange(startInstructionOffset, length); -#endif - UINT32 stopInstructionOffset = startInstructionOffset + length; UINT32 normStartOffset = NORMALIZE_CODE_OFFSET(startInstructionOffset); @@ -674,10 +653,6 @@ void GcInfoEncoder::SetSlotState( { _ASSERTE( (m_SlotTable[ slotId ].Flags & GC_SLOT_UNTRACKED) == 0 ); -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetSlotState(instructionOffset, slotId, slotState); -#endif - LifetimeTransition transition; transition.SlotId = slotId; @@ -693,19 +668,11 @@ void GcInfoEncoder::SetSlotState( void GcInfoEncoder::SetIsVarArg() { -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetIsVarArg(); -#endif - m_IsVarArg = true; } void GcInfoEncoder::SetCodeLength( UINT32 length ) { -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetCodeLength(length); -#endif - _ASSERTE( length > 0 ); _ASSERTE( m_CodeLength == 0 || m_CodeLength == length ); m_CodeLength = length; @@ -714,10 +681,6 @@ void GcInfoEncoder::SetCodeLength( UINT32 length ) void GcInfoEncoder::SetSecurityObjectStackSlot( INT32 spOffset ) { -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetSecurityObjectStackSlot(spOffset); -#endif - _ASSERTE( spOffset != NO_SECURITY_OBJECT ); #if defined(_TARGET_AMD64_) _ASSERTE( spOffset < 0x10 && "The security object cannot reside in an input variable!" ); @@ -751,10 +714,6 @@ void GcInfoEncoder::SetGSCookieStackSlot( INT32 spOffsetGSCookie, UINT32 validRa void GcInfoEncoder::SetPSPSymStackSlot( INT32 spOffsetPSPSym ) { -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetPSPSymStackSlot(spOffsetPSPSym); -#endif - _ASSERTE( spOffsetPSPSym != NO_PSP_SYM ); _ASSERTE( m_PSPSymStackSlot == NO_PSP_SYM || m_PSPSymStackSlot == spOffsetPSPSym ); @@ -763,10 +722,6 @@ void GcInfoEncoder::SetPSPSymStackSlot( INT32 spOffsetPSPSym ) void GcInfoEncoder::SetGenericsInstContextStackSlot( INT32 spOffsetGenericsContext, GENERIC_CONTEXTPARAM_TYPE type) { -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetGenericsInstContextStackSlot(spOffsetGenericsContext); -#endif - _ASSERTE( spOffsetGenericsContext != NO_GENERICS_INST_CONTEXT); _ASSERTE( m_GenericsInstContextStackSlot == NO_GENERICS_INST_CONTEXT || m_GenericsInstContextStackSlot == spOffsetGenericsContext ); @@ -776,10 +731,6 @@ void GcInfoEncoder::SetGenericsInstContextStackSlot( INT32 spOffsetGenericsConte void GcInfoEncoder::SetStackBaseRegister( UINT32 regNum ) { -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetStackBaseRegister(regNum); -#endif - _ASSERTE( regNum != NO_STACK_BASE_REGISTER ); _ASSERTE(DENORMALIZE_STACK_BASE_REGISTER(NORMALIZE_STACK_BASE_REGISTER(regNum)) == regNum); _ASSERTE( m_StackBaseRegister == NO_STACK_BASE_REGISTER || m_StackBaseRegister == regNum ); @@ -788,10 +739,6 @@ void GcInfoEncoder::SetStackBaseRegister( UINT32 regNum ) void GcInfoEncoder::SetSizeOfEditAndContinuePreservedArea( UINT32 slots ) { -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetSizeOfEditAndContinuePreservedArea(slots); -#endif - _ASSERTE( slots != NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA ); _ASSERTE( m_SizeOfEditAndContinuePreservedArea == NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA ); m_SizeOfEditAndContinuePreservedArea = slots; @@ -805,10 +752,6 @@ void GcInfoEncoder::SetWantsReportOnlyLeaf() #ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA void GcInfoEncoder::SetSizeOfStackOutgoingAndScratchArea( UINT32 size ) { -#ifdef VERIFY_GCINFO - m_DbgEncoder.SetSizeOfStackOutgoingAndScratchArea(size); -#endif - _ASSERTE( size != (UINT32)-1 ); _ASSERTE( m_SizeOfStackOutgoingAndScratchArea == (UINT32)-1 || m_SizeOfStackOutgoingAndScratchArea == size ); m_SizeOfStackOutgoingAndScratchArea = size; @@ -962,10 +905,6 @@ void BitStreamWriter::Write(BitArray& a, UINT32 count) void GcInfoEncoder::FinalizeSlotIds() { -#ifdef VERIFY_GCINFO - m_DbgEncoder.FinalizeSlotIds(); -#endif - #ifdef _DEBUG m_IsSlotTableFrozen = TRUE; #endif @@ -1030,10 +969,6 @@ bool GcInfoEncoder::IsAlwaysScratch(GcSlotDesc &slotDesc) void GcInfoEncoder::Build() { -#ifdef VERIFY_GCINFO - m_DbgEncoder.Build(); -#endif - #ifdef _DEBUG _ASSERTE(m_IsSlotTableFrozen || m_NumSlots == 0); #endif @@ -2641,10 +2576,6 @@ BYTE* GcInfoEncoder::Emit() size_t cbGcInfoSize = m_Info1.GetByteCount() + m_Info2.GetByteCount(); -#ifdef VERIFY_GCINFO - cbGcInfoSize += (sizeof(size_t)) + m_DbgEncoder.GetByteCount(); -#endif - LOG((LF_GCINFO, LL_INFO100, "GcInfoEncoder::Emit(): Size of GC info is %u bytes, code size %u bytes.\n", (unsigned)cbGcInfoSize, m_CodeLength )); BYTE* destBuffer = (BYTE *)eeAllocGCInfo(cbGcInfoSize); @@ -2654,16 +2585,6 @@ BYTE* GcInfoEncoder::Emit() BYTE* ptr = destBuffer; -#ifdef VERIFY_GCINFO - _ASSERTE(sizeof(size_t) >= sizeof(UINT32)); - size_t __displacement = cbGcInfoSize - m_DbgEncoder.GetByteCount(); - ptr[0] = (BYTE)__displacement; - ptr[1] = (BYTE) (__displacement >> 8); - ptr[2] = (BYTE) (__displacement >> 16); - ptr[3] = (BYTE) (__displacement >> 24); - ptr += sizeof(size_t); -#endif - m_Info1.CopyTo( ptr ); ptr += m_Info1.GetByteCount(); m_Info1.Dispose(); @@ -2676,11 +2597,6 @@ BYTE* GcInfoEncoder::Emit() m_pAllocator->Free( m_SlotTable ); #endif -#ifdef VERIFY_GCINFO - _ASSERTE(ptr - destBuffer == __displacement); - m_DbgEncoder.Emit(ptr); -#endif - return destBuffer; } diff --git a/src/inc/dbggcinfodecoder.h b/src/inc/dbggcinfodecoder.h deleted file mode 100644 index 71b62637b7..0000000000 --- a/src/inc/dbggcinfodecoder.h +++ /dev/null @@ -1,343 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -/***************************************************************** - * - * GC Information Decoding API - * - * This is an older well-tested implementation - * now used to verify the real encoding - * Define VERIFY_GCINFO to enable the verification - * - *****************************************************************/ - -#ifdef VERIFY_GCINFO - -#ifndef _DBG_GC_INFO_DECODER_ -#define _DBG_GC_INFO_DECODER_ - -#include "daccess.h" - -#ifndef GCINFODECODER_NO_EE - -#include "eetwain.h" - -#else // GCINFODECODER_NO_EE - -#if !defined(_NTAMD64_) -#include "clrnt.h" -#endif - -// Misc. VM types: - -class Object; -typedef Object *OBJECTREF; -typedef SIZE_T TADDR; - -// Stuff from gc.h: - -#ifndef __GC_H - -#define GC_CALL_INTERIOR 0x1 -#define GC_CALL_PINNED 0x2 - -#endif // !__GC_H - - -// Stuff from check.h: - -#ifndef UNREACHABLE -#define UNREACHABLE() __assume(0) -#endif - -// Stuff from eetwain.h: - -#ifndef _EETWAIN_H - -typedef void (*GCEnumCallback)( - LPVOID hCallback, // callback data - OBJECTREF* pObject, // address of obect-reference we are reporting - uint32_t flags // is this a pinned and/or interior pointer -); - - -#if !defined(_TARGET_X86_) -#define USE_GC_INFO_DECODER -#endif - -#include "regdisp.h" - -#endif // !_EETWAIN_H - -#endif // GCINFODECODER_NO_EE - -#include "gcinfotypes.h" - - -namespace DbgGcInfo { - -struct GcSlotDesc -{ - union - { - UINT32 RegisterNumber; - GcStackSlot Stack; - } Slot; - GcSlotFlags Flags; -}; - -class BitStreamReader -{ -public: - BitStreamReader( const BYTE* pBuffer ) - { - _ASSERTE( pBuffer != NULL ); - m_pBuffer = (PTR_BYTE)(TADDR)pBuffer; - m_BitsRead = 0; - } - - // - // bit 0 is the least significative bit - // count can be negative so that bits are written in most-significative to least-significative order - // - size_t Read( int numBits ) - { - size_t result = 0; - int curBitsRead = 0; - - while( curBitsRead < numBits ) - { - int currByte = m_BitsRead /8; - int currBitInCurrentByte = m_BitsRead % 8; - int bitsLeftInCurrentByte = 8 - currBitInCurrentByte; - _ASSERTE( bitsLeftInCurrentByte > 0 ); - - int bitsToReadInCurrentByte = min( numBits - curBitsRead, bitsLeftInCurrentByte ); - - size_t data = m_pBuffer[ currByte ]; - data >>= currBitInCurrentByte; - data &= (1<<bitsToReadInCurrentByte) -1; - - data <<= curBitsRead; - result |= data; - - curBitsRead += bitsToReadInCurrentByte; - m_BitsRead += bitsToReadInCurrentByte; - } - - return result; - } - - // Returns the number of bits read so far - size_t GetCurrentPos() - { - return m_BitsRead; - } - - void SetCurrentPos( size_t pos ) - { - m_BitsRead = pos; - } - - // Can use negative values - void Skip( SSIZE_T numBitsToSkip ) - { - m_BitsRead += numBitsToSkip; - _ASSERTE( m_BitsRead >= 0 ); - } - - //-------------------------------------------------------------------------- - // Decode variable length numbers - // See the corresponding methods on BitStreamWriter for more information on the format - //-------------------------------------------------------------------------- - - inline size_t DecodeVarLengthUnsigned( int base ) - { - _ASSERTE((base > 0) && (base < (int)sizeof(size_t)*8)); - size_t numEncodings = 1 << base; - size_t result = 0; - for(int shift=0; ; shift+=base) - { - _ASSERTE(shift+base <= (int)sizeof(size_t)*8); - - size_t currentChunk = Read(base+1); - result |= (currentChunk & (numEncodings-1)) << shift; - if(!(currentChunk & numEncodings)) - { - // Extension bit is not set, we're done. - return result; - } - } - } - - inline SSIZE_T DecodeVarLengthSigned( int base ) - { - _ASSERTE((base > 0) && (base < (int)sizeof(SSIZE_T)*8)); - size_t numEncodings = 1 << base; - SSIZE_T result = 0; - for(int shift=0; ; shift+=base) - { - _ASSERTE(shift+base <= (int)sizeof(SSIZE_T)*8); - - size_t currentChunk = Read(base+1); - result |= (currentChunk & (numEncodings-1)) << shift; - if(!(currentChunk & numEncodings)) - { - // Extension bit is not set, sign-extend and we're done. - int sbits = sizeof(SSIZE_T)*8 - (shift+base); - result <<= sbits; - result >>= sbits; // This provides the sign extension - return result; - } - } - } - -private: - PTR_BYTE m_pBuffer; - size_t m_BitsRead; -}; - - -class GcInfoDecoder -{ -public: - - // If you are not insterested in interruptibility or gc lifetime information, pass 0 as instructionOffset - GcInfoDecoder( - const BYTE* gcInfoAddr, - GcInfoDecoderFlags flags, - UINT32 instructionOffset = 0 - ); - - - //------------------------------------------------------------------------ - // Interruptibility - //------------------------------------------------------------------------ - - bool IsInterruptible(); - - // Returns true to stop enumerating. - typedef bool EnumerateInterruptibleRangesCallback (UINT32 startOffset, UINT32 stopOffset, LPVOID hCallback); - - void EnumerateInterruptibleRanges ( - EnumerateInterruptibleRangesCallback *pCallback, - LPVOID hCallback); - - //------------------------------------------------------------------------ - // GC lifetime information - //------------------------------------------------------------------------ - - bool EnumerateLiveSlots( - PREGDISPLAY pRD, - bool reportScratchSlots, - unsigned flags, - GCEnumCallback pCallBack, - LPVOID hCallBack - ); - - void VerifyLiveRegister( - UINT32 regNum, - GcSlotFlags flags - ); - - - void VerifyLiveStackSlot( - int spOffset, - GcStackSlotBase spBase, - GcSlotFlags flags - ); - - void DoFinalVerification(); - - //------------------------------------------------------------------------ - // Miscellaneous method information - //------------------------------------------------------------------------ - - INT32 GetSecurityObjectStackSlot(); - INT32 GetPSPSymStackSlot(); - INT32 GetGenericsInstContextStackSlot(); - bool GetIsVarArg(); - UINT32 GetCodeLength(); - UINT32 GetStackBaseRegister(); - UINT32 GetSizeOfEditAndContinuePreservedArea(); - -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - UINT32 GetSizeOfStackParameterArea(); -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA - -private: - BitStreamReader m_Reader; - UINT32 m_InstructionOffset; - - // Pre-decoded information - bool m_IsInterruptible; - bool m_IsVarArg; - INT32 m_SecurityObjectStackSlot; - INT32 m_PSPSymStackSlot; - INT32 m_GenericsInstContextStackSlot; - UINT32 m_CodeLength; - UINT32 m_StackBaseRegister; - UINT32 m_SizeOfEditAndContinuePreservedArea; - UINT32 m_NumInterruptibleRanges; - -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - UINT32 m_SizeOfStackOutgoingAndScratchArea; -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA - -#ifdef _DEBUG - GcInfoDecoderFlags m_Flags; -#endif - - GcSlotDesc* m_pLiveRegisters; - GcSlotDesc* m_pLiveStackSlots; - int m_NumLiveRegisters; - int m_NumLiveStackSlots; - - CQuickBytes qbSlots1; - CQuickBytes qbSlots2; - - static bool SetIsInterruptibleCB (UINT32 startOffset, UINT32 stopOffset, LPVOID hCallback); - - OBJECTREF* GetRegisterSlot( - int regNum, - PREGDISPLAY pRD - ); - - OBJECTREF* GetStackSlot( - INT32 spOffset, - GcStackSlotBase spBase, - PREGDISPLAY pRD - ); - - bool IsScratchRegister(int regNum, PREGDISPLAY pRD); - bool IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD); - - void ReportRegisterToGC( - int regNum, - BOOL isInterior, - BOOL isPinned, - PREGDISPLAY pRD, - unsigned flags, - GCEnumCallback pCallBack, - LPVOID hCallBack - ); - - void ReportStackSlotToGC( - INT32 spOffset, - GcStackSlotBase spBase, - BOOL isInterior, - BOOL isPinned, - PREGDISPLAY pRD, - unsigned flags, - GCEnumCallback pCallBack, - LPVOID hCallBack - ); - - -}; - -} - -#endif // _DBG_GC_INFO_DECODER_ -#endif // VERIFY_GCINFO - diff --git a/src/inc/dbggcinfoencoder.h b/src/inc/dbggcinfoencoder.h deleted file mode 100644 index 85b56ad297..0000000000 --- a/src/inc/dbggcinfoencoder.h +++ /dev/null @@ -1,469 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -/***************************************************************************** - * - * GC Information Encoding API - * - * This is an older well-tested implementation - * now used to verify the real encoding - * Define VERIFY_GCINFO to enable the verification - * - */ - -#ifdef VERIFY_GCINFO - -#ifndef __DBGGCINFOENCODER_H__ -#define __DBGGCINFOENCODER_H__ - -#include <windows.h> - -#include <wchar.h> -#include <stdio.h> - -#include "corjit.h" -#include "iallocator.h" -#include "gcinfoarraylist.h" - -#include "stdmacros.h" -#include "gcinfotypes.h" - - -class IJitAllocator; - - - -namespace DbgGcInfo { - -//----------------------------------------------------------------------------- -// The following macro controls whether the encoder has to call the IJitAllocator::Free method -// Don't call IJitAllocator::Free for mscorjit64.dll -//----------------------------------------------------------------------------- -//#define MUST_CALL_JITALLOCATOR_FREE - - -class BitStreamWriter -{ -public: - BitStreamWriter( IJitAllocator* pAllocator ); - void Write( size_t data, int count ); - - inline size_t GetBitCount() - { - return m_BitCount; - } - - inline size_t GetByteCount() - { - return ( m_BitCount + 7 ) / 8; - } - - - void CopyTo( BYTE* buffer ); - void Dispose(); - - //-------------------------------------------------------- - // Encode variable length numbers - // Uses base+1 bits at minimum - // 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, int base ) - { - _ASSERTE((base > 0) && (base < sizeof(size_t)*8)); - size_t numEncodings = 1 << base; - int bitsUsed = base+1; - for( ; ; 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; - } - - //-------------------------------------------------------- - // Signed quantities are encoded the same as unsigned - // The most relevant difference is that a number is considered - // 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, int base ) - { - _ASSERTE((base > 0) && (base < sizeof(SSIZE_T)*8)); - 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 ); - } - } - } - -private: - - 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: - MemoryBlockList(); - - inline MemoryBlock* Head() - { - return m_head; - } - - MemoryBlock* AppendNew(IAllocator* allocator, size_t bytes); - void Dispose(IAllocator* allocator); - }; - - IJitAllocator* m_pAllocator; - size_t m_BitCount; - int m_FreeBitsInCurrentSlot; - 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 -#ifdef _DEBUG - int m_MemoryBlocksCount; -#endif - -private: - // Writes bits knowing that they will all fit in the current memory slot - inline void WriteInCurrentSlot( size_t data, int count ) - { - data &= SAFE_SHIFT_LEFT(1, count) - 1; - - data <<= (sizeof( size_t )*8-m_FreeBitsInCurrentSlot); - - *m_pCurrentSlot |= data; - } - - void AllocMemoryBlock(); - - inline void InitCurrentSlot() - { - m_FreeBitsInCurrentSlot = sizeof( size_t )*8; - *m_pCurrentSlot = 0; - } - -}; - -struct GcSlotDesc -{ - union - { - UINT32 RegisterNumber; - GcStackSlot Stack; - } Slot; - unsigned IsRegister : 1; - unsigned IsInterior : 1; - unsigned IsPinned : 1; -}; - - - -typedef UINT32 GcSlotId; - - -class GcSlotSet -{ - friend class GcInfoEncoder; -public: - GcSlotSet( GcInfoEncoder * pEncoder ); - - // Copy constructor - GcSlotSet( GcSlotSet & other ); - - inline void Add( GcSlotId slotId ); - - inline void Remove( GcSlotId slotId ); - -// Not used -#if 0 - inline void RemoveAll(); - - void Add( GcSlotSet & other ); - void Subtract( GcSlotSet & other ); - void Intersect( GcSlotSet & other ); -#endif - - // Must be called when done with the object - inline void Dispose(); - -private: - // A bit vector representing the set - BYTE * m_Data; - - int m_NumBytes; - - GcInfoEncoder* m_pEncoder; -}; - - -class GcInfoEncoder -{ -public: - GcInfoEncoder( - ICorJitInfo* pCorJitInfo, - CORINFO_METHOD_INFO* pMethodInfo, - IJitAllocator* pJitAllocator - ); - - - //------------------------------------------------------------------------ - // Interruptibility - //------------------------------------------------------------------------ - - // An instruction at offset x will be interruptible - // if-and-only-if startInstructionOffset <= x < startInstructionOffset+length - void DefineInterruptibleRange( UINT32 startInstructionOffset, UINT32 length ); - - - //------------------------------------------------------------------------ - // Slot information - //------------------------------------------------------------------------ - - // - // spOffset are always relative to the SP of the caller (same as SP at the method entry and exit) - // Negative offsets describe GC refs in the local and outgoing areas. - // Positive offsets describe GC refs in the scratch area - // Note that if the dynamic allocation area is resized, the outgoing area will not be valid anymore - // Old slots must be declared dead and new ones can be defined. - // It's up to the JIT to do the right thing. We don't enforce this. - // - - GcSlotId GetRegisterSlotId( UINT32 regNum, GcSlotFlags flags ); - GcSlotId GetStackSlotId( INT32 spOffset, GcSlotFlags flags, GcStackSlotBase spBase = GC_CALLER_SP_REL ); - - // - // After a FinalizeSlotIds is called, no more slot definitions can be made. - // FinalizeSlotIds must be called once and only once before calling DefineGcStateAtCallSite - // If no call sites are described, calling FinalizeSlotIds can and should (for performance reasons) be avoided - // - void FinalizeSlotIds(); - - -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - - //------------------------------------------------------------------------ - // Partially-interruptible information - //------------------------------------------------------------------------ - - - void DefineGcStateAtSafePoint( - UINT32 instructionOffset, - GcSlotSet &liveSlots - ); - -#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED -#endif - - //------------------------------------------------------------------------ - // Fully-interruptible information - //------------------------------------------------------------------------ - - // - // For inputs, pass zero as offset - // - - // This method defines what the GC state of a slot is when a thread's suspension IP - // is equal to instructionOffset - - void SetSlotState( UINT32 instructionOffset, - GcSlotId slotId, - GcSlotState slotState - ); - - - - //------------------------------------------------------------------------ - // Miscellaneous method information - //------------------------------------------------------------------------ - - void SetSecurityObjectStackSlot( INT32 spOffset ); - void SetPSPSymStackSlot( INT32 spOffsetPSPSym ); - void SetGenericsInstContextStackSlot( INT32 spOffsetGenericsContext ); - void SetIsVarArg(); - void SetCodeLength( UINT32 length ); - - // Optional in the general case. Required if the method uses GC_FRAMEREG_REL stack slots - void SetStackBaseRegister( UINT32 registerNumber ); - void SetSizeOfEditAndContinuePreservedArea( UINT32 size ); - -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - void SetSizeOfStackOutgoingAndScratchArea( UINT32 size ); -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA - - - //------------------------------------------------------------------------ - // Encoding - //------------------------------------------------------------------------ - - // - // Build() encodes GC information into temporary buffers. - // The method description cannot change after Build is called - // - void Build(); - - // - // Write encoded information to its final destination and frees temporary buffers. - // The encoder shouldn't be used anymore after calling this method. - // It returns a pointer to the destination buffer, which address is byte-aligned - // - size_t GetByteCount(); - BYTE* Emit(BYTE* dest); - -private: - - friend class LifetimeTransitionsQuickSort; - friend class LifetimeTransitionsQuickSortByOffset; - - struct LifetimeTransition - { - UINT32 CodeOffset; - GcSlotDesc SlotDesc; - bool BecomesLive; - }; - - ICorJitInfo* m_pCorJitInfo; - CORINFO_METHOD_INFO* m_pMethodInfo; - IJitAllocator* m_pAllocator; - -#ifdef _DEBUG - char *m_MethodName, *m_ModuleName; -#endif - - BitStreamWriter m_HeaderInfoWriter; -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - BitStreamWriter m_PartiallyInterruptibleInfoWriter; -#endif -#endif - BitStreamWriter m_FullyInterruptibleInfoWriter; - - GcInfoArrayList<LifetimeTransition, 64> m_LifetimeTransitions; - LifetimeTransition *m_rgSortedTransitions; - - bool m_IsVarArg; - INT32 m_SecurityObjectStackSlot; - INT32 m_PSPSymStackSlot; - INT32 m_GenericsInstContextStackSlot; - UINT32 m_CodeLength; - UINT32 m_StackBaseRegister; - UINT32 m_SizeOfEditAndContinuePreservedArea; - UINT32 m_LastInterruptibleRangeStopOffset; - UINT32 m_NumInterruptibleRanges; - -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - UINT32 m_SizeOfStackOutgoingAndScratchArea; -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA - - void * eeAllocGCInfo (size_t blockSize); - - inline int EncodeFullyInterruptibleSlotFlags(GcSlotDesc slotDesc) - { - int flagEnc = 1; - if( slotDesc.IsInterior ) - flagEnc |= 0x2; - if( slotDesc.IsPinned ) - flagEnc |= 0x4; - if(flagEnc == 1) - { - m_FullyInterruptibleInfoWriter.Write(0, 1); - return 1; - } - else - { - m_FullyInterruptibleInfoWriter.Write(flagEnc, 3); - return 3; - } - } - - -private: - - friend class GcSlotSet; - friend class EncoderCheckState; - - static const UINT32 m_MappingTableInitialSize = 32; - UINT32 m_MappingTableSize; - UINT32 m_NumSlotMappings; - GcSlotDesc *m_SlotMappings; - -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - UINT32 m_NumSafePointsWithGcState; -#endif -#endif - - void GrowMappingTable(); - -#ifdef _DEBUG - bool m_IsMappingTableFrozen; -#endif -}; - - - -// Not used -#if 0 - -void GcSlotSet::RemoveAll() -{ - ZeroMemory( m_Data, m_NumBytes ); -} - -#endif - - -void GcSlotSet::Dispose() -{ -#ifdef MUST_CALL_JITALLOCATOR_FREE - m_pEncoder->m_pAllocator->Free( m_Data ); -#endif -} - - -} - -#endif // !__DBGGCINFOENCODER_H__ - -#endif // VERIFY_GCINFO - diff --git a/src/inc/gcinfodecoder.h b/src/inc/gcinfodecoder.h index 466ac15b68..f703727a76 100644 --- a/src/inc/gcinfodecoder.h +++ b/src/inc/gcinfodecoder.h @@ -176,10 +176,6 @@ enum GcInfoDecoderFlags DECODE_EDIT_AND_CONTINUE = 0x800, }; -#ifdef VERIFY_GCINFO -#include "dbggcinfodecoder.h" -#endif - enum GcInfoHeaderFlags { GC_INFO_IS_VARARG = 0x1, @@ -540,10 +536,6 @@ private: UINT32 m_Version; #endif -#ifdef VERIFY_GCINFO - DbgGcInfo::GcInfoDecoder m_DbgDecoder; -#endif - static bool SetIsInterruptibleCB (UINT32 startOffset, UINT32 stopOffset, LPVOID hCallback); OBJECTREF* GetRegisterSlot( @@ -617,13 +609,6 @@ private: UINT32 regNum = pSlot->Slot.RegisterNumber; if( reportScratchSlots || !IsScratchRegister( regNum, pRD ) ) { -#ifdef VERIFY_GCINFO - m_DbgDecoder.VerifyLiveRegister( - regNum, - pSlot->Flags - ); -#endif - ReportRegisterToGC( regNum, pSlot->Flags, @@ -644,14 +629,6 @@ private: GcStackSlotBase spBase = pSlot->Slot.Stack.Base; if( reportScratchSlots || !IsScratchStackSlot(spOffset, spBase, pRD) ) { -#ifdef VERIFY_GCINFO - m_DbgDecoder.VerifyLiveStackSlot( - spOffset, - spBase, - pSlot->Flags - ); -#endif - ReportStackSlotToGC( spOffset, spBase, diff --git a/src/inc/gcinfoencoder.h b/src/inc/gcinfoencoder.h index ff03138032..8875d3b492 100644 --- a/src/inc/gcinfoencoder.h +++ b/src/inc/gcinfoencoder.h @@ -87,10 +87,6 @@ #include "gcinfotypes.h" -#ifdef VERIFY_GCINFO -#include "dbggcinfoencoder.h" -#endif //VERIFY_GCINFO - #ifdef MEASURE_GCINFO struct GcInfoSize { @@ -526,10 +522,6 @@ private: bool m_IsSlotTableFrozen; #endif -#ifdef VERIFY_GCINFO - DbgGcInfo::GcInfoEncoder m_DbgEncoder; -#endif - #ifdef MEASURE_GCINFO GcInfoSize m_CurrentMethodSize; #endif diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index b24a1509e6..89a6437da1 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -151,7 +151,6 @@ set(VM_SOURCES_WKS coverage.cpp customattribute.cpp custommarshalerinfo.cpp - dbggcinfodecoder.cpp dllimportcallback.cpp eeconfig.cpp eecontract.cpp @@ -430,7 +429,6 @@ endif(CLR_CMAKE_PLATFORM_UNIX) set(VM_SOURCES_DAC_ARCH gcinfodecoder.cpp - dbggcinfodecoder.cpp exceptionhandling.cpp ) diff --git a/src/vm/crossgen/CMakeLists.txt b/src/vm/crossgen/CMakeLists.txt index 3a20675ef1..c2392a2d9a 100644 --- a/src/vm/crossgen/CMakeLists.txt +++ b/src/vm/crossgen/CMakeLists.txt @@ -92,7 +92,6 @@ set(VM_CROSSGEN_SOURCES ../vars.cpp ../versionresilienthashcode.cpp ../zapsig.cpp - ../dbggcinfodecoder.cpp ../gcinfodecoder.cpp ../sha1.cpp ../crossgencompile.cpp diff --git a/src/vm/crossgen/wks_crossgen.nativeproj b/src/vm/crossgen/wks_crossgen.nativeproj index 31404a3d66..803a3cb705 100644 --- a/src/vm/crossgen/wks_crossgen.nativeproj +++ b/src/vm/crossgen/wks_crossgen.nativeproj @@ -130,7 +130,6 @@ <!-- SOURCES_NONPAL --> <ItemGroup> - <CppCompile Include="$(VmSourcesDir)\DbgGcInfoDecoder.cpp" /> <CppCompile Include="$(VmSourcesDir)\GcInfoDecoder.cpp" /> <CppCompile Include="$(VmSourcesDir)\Crypto\SHA1.cpp" Condition="'$(FeatureCoreclr)' != 'true'"/> <CppCompile Include="$(VmSourcesDir)\SHA1.cpp" Condition="'$(FeatureCoreclr)' == 'true'"/> diff --git a/src/vm/dac/dacwks.targets b/src/vm/dac/dacwks.targets index 121b14ec90..82ab5439d5 100644 --- a/src/vm/dac/dacwks.targets +++ b/src/vm/dac/dacwks.targets @@ -127,7 +127,6 @@ <ItemGroup Condition="'$(TargetArch)' == 'amd64'" > <CppCompile Include="$(ClrSrcDirectory)\vm\GcInfoDecoder.cpp" /> - <CppCompile Include="$(ClrSrcDirectory)\vm\DbgGcInfoDecoder.cpp" /> <CppCompile Include="$(ClrSrcDirectory)\vm\amd64\cGenAMD64.cpp" /> <CppCompile Include="$(ClrSrcDirectory)\vm\amd64\ExcepAMD64.cpp" /> <CppCompile Include="$(ClrSrcDirectory)\vm\amd64\gmsAMD64.cpp" /> diff --git a/src/vm/dbggcinfodecoder.cpp b/src/vm/dbggcinfodecoder.cpp deleted file mode 100644 index c921256ef9..0000000000 --- a/src/vm/dbggcinfodecoder.cpp +++ /dev/null @@ -1,932 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - - - - -#include "common.h" -#include "gcinfodecoder.h" - -#ifdef VERIFY_GCINFO -#ifdef USE_GC_INFO_DECODER - -#include "dbggcinfodecoder.h" - -#ifndef GCINFODECODER_CONTRACT -#define GCINFODECODER_CONTRACT(contract) contract -#endif // !GCINFODECODER_CONTRACT - -#ifndef GET_CALLER_SP -#define GET_CALLER_SP(pREGDISPLAY) EECodeManager::GetCallerSp(pREGDISPLAY) -#endif // !GET_CALLER_SP - -#ifndef VALIDATE_OBJECTREF -#ifdef DACCESS_COMPILE -#define VALIDATE_OBJECTREF(objref, fDeep) -#else // DACCESS_COMPILE -#define VALIDATE_OBJECTREF(objref, fDeep) OBJECTREFToObject(objref)->Validate(fDeep) -#endif // DACCESS_COMPILE -#endif // !VALIDATE_OBJECTREF - -#ifndef VALIDATE_ROOT -#define VALIDATE_ROOT(isInterior, hCallBack, pObjRef) \ - do { \ - /* Only call Object::Validate() with bDeep == TRUE if we are in the promote phase. */ \ - /* We should call Validate() with bDeep == FALSE if we are in the relocation phase. */ \ - \ - GCCONTEXT* pGCCtx = (GCCONTEXT*)(hCallBack); \ - \ - if (!(isInterior) && !(m_Flags & DECODE_NO_VALIDATION)) \ - VALIDATE_OBJECTREF(*(pObjRef), pGCCtx->sc->promotion == TRUE); \ - } while (0) -#endif // !VALIDATE_ROOT - - - -namespace DbgGcInfo { - - -//static -bool GcInfoDecoder::SetIsInterruptibleCB (UINT32 startOffset, UINT32 stopOffset, LPVOID hCallback) -{ - GcInfoDecoder *pThis = (GcInfoDecoder*)hCallback; - - bool fStop = pThis->m_InstructionOffset >= startOffset && pThis->m_InstructionOffset < stopOffset; - - if (fStop) - pThis->m_IsInterruptible = true; - - return fStop; -} - - -GcInfoDecoder::GcInfoDecoder( - const BYTE* gcInfoAddr, - GcInfoDecoderFlags flags, - UINT32 breakOffset - ) - : m_Reader( gcInfoAddr ) - , m_InstructionOffset( breakOffset ) - , m_IsInterruptible( false ) - , m_pLiveRegisters( NULL ) - , m_pLiveStackSlots( NULL ) - , m_NumLiveRegisters(0) - , m_NumLiveStackSlots(0) -#ifdef _DEBUG - , m_Flags( flags ) -#endif -{ -#ifdef _TARGET_ARM_ - _ASSERTE(!"JIT32 is not generating GCInfo in the correct format yet!"); -#endif - - _ASSERTE( (flags & (DECODE_INTERRUPTIBILITY | DECODE_GC_LIFETIMES)) || (0 == breakOffset) ); - - // The current implementation doesn't support the two flags together - _ASSERTE( - ((flags & (DECODE_INTERRUPTIBILITY | DECODE_GC_LIFETIMES)) != (DECODE_INTERRUPTIBILITY | DECODE_GC_LIFETIMES)) - ); - - - //-------------------------------------------- - // Pre-decode information - //-------------------------------------------- - - m_IsVarArg = (m_Reader.Read(1)) ? true : false; - - size_t hasSecurityObject = m_Reader.Read(1); - if(hasSecurityObject) - m_SecurityObjectStackSlot = (INT32) DENORMALIZE_STACK_SLOT(m_Reader.DecodeVarLengthSigned(SECURITY_OBJECT_STACK_SLOT_ENCBASE)); - else - m_SecurityObjectStackSlot = NO_SECURITY_OBJECT; - - size_t hasPSPSym = m_Reader.Read(1); - if(hasPSPSym) - { - m_PSPSymStackSlot = (INT32) DENORMALIZE_STACK_SLOT(m_Reader.DecodeVarLengthSigned(PSP_SYM_STACK_SLOT_ENCBASE)); - } - else - { - m_PSPSymStackSlot = NO_PSP_SYM; - } - - size_t hasGenericsInstContext = m_Reader.Read(1); - if(hasGenericsInstContext) - { - m_GenericsInstContextStackSlot = (INT32) DENORMALIZE_STACK_SLOT(m_Reader.DecodeVarLengthSigned(GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE)); - } - else - { - m_GenericsInstContextStackSlot = NO_GENERICS_INST_CONTEXT; - } - - m_CodeLength = (UINT32) DENORMALIZE_CODE_LENGTH(m_Reader.DecodeVarLengthUnsigned(CODE_LENGTH_ENCBASE)); - - size_t hasStackBaseRegister = m_Reader.Read(1); - if(hasStackBaseRegister) - m_StackBaseRegister = (UINT32) DENORMALIZE_STACK_BASE_REGISTER(m_Reader.DecodeVarLengthUnsigned(STACK_BASE_REGISTER_ENCBASE)); - else - m_StackBaseRegister = NO_STACK_BASE_REGISTER; - - size_t hasSizeOfEditAndContinuePreservedArea = m_Reader.Read(1); - if(hasSizeOfEditAndContinuePreservedArea) - m_SizeOfEditAndContinuePreservedArea = (UINT32) m_Reader.DecodeVarLengthUnsigned(SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE); - else - m_SizeOfEditAndContinuePreservedArea = NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA; - -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - m_SizeOfStackOutgoingAndScratchArea = (UINT32)DENORMALIZE_SIZE_OF_STACK_AREA(m_Reader.DecodeVarLengthUnsigned(SIZE_OF_STACK_AREA_ENCBASE)); -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA - - m_NumInterruptibleRanges = (UINT32) DENORMALIZE_NUM_INTERRUPTIBLE_RANGES(m_Reader.DecodeVarLengthUnsigned(NUM_INTERRUPTIBLE_RANGES_ENCBASE)); - - if( flags & DECODE_INTERRUPTIBILITY ) - { - EnumerateInterruptibleRanges(&SetIsInterruptibleCB, this); - } -} - - -bool GcInfoDecoder::IsInterruptible() -{ - _ASSERTE( m_Flags & DECODE_INTERRUPTIBILITY ); - return m_IsInterruptible; -} - - -void GcInfoDecoder::EnumerateInterruptibleRanges ( - EnumerateInterruptibleRangesCallback *pCallback, - LPVOID hCallback) -{ -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - - //------------------------------------------------------------------------------ - // Try partially interruptible first - //------------------------------------------------------------------------------ - - UINT32 numCallSites = (UINT32)m_Reader.Read( sizeof( numCallSites ) * 8 ); - UINT32 callSiteIdx = 0; - - if( numCallSites > 0 ) - { - UINT32 numSlotMappings = (UINT32)m_Reader.Read( sizeof( numSlotMappings ) * 8 ); - - // Align the reader to the next byte to continue decoding - m_Reader.Skip( ( 8 - ( m_Reader.GetCurrentPos() % 8 ) ) % 8 ); - - for( callSiteIdx=0; callSiteIdx<numCallSites; callSiteIdx++ ) - { - UINT32 instructionOffset = (UINT32)m_Reader.Read( 32 ); - - bool fStop = pCallback(instructionOffset, instructionOffset+1, hCallback); - if (fStop) - return; - - m_Reader.Skip( numSlotMappings ); - } - - // Call site not found. Skip the slot mapping table in preparation for reading the fully-interruptible information - m_Reader.Skip( numSlotMappings * sizeof( GcSlotDesc ) * 8 ); - } - -#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED -#endif - - - // If no info is found for the call site, we default to fully-interruptbile - LOG((LF_GCROOTS, LL_INFO1000000, "No GC info found for call site at offset %x. Defaulting to fully-interruptible information.\n", (int) m_InstructionOffset)); - - // Align the reader to the next byte to continue decoding - m_Reader.Skip( ( 8 - ( m_Reader.GetCurrentPos() % 8 ) ) % 8 ); - - UINT32 lastInterruptibleRangeStopOffsetNormalized = 0; - - for(UINT32 i=0; i<m_NumInterruptibleRanges; i++) - { - UINT32 normStartDelta = (UINT32) m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA_ENCBASE ); - UINT32 normStopDelta = (UINT32) m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA_ENCBASE ) + 1; - - UINT32 rangeStartOffsetNormalized = lastInterruptibleRangeStopOffsetNormalized + normStartDelta; - UINT32 rangeStopOffsetNormalized = rangeStartOffsetNormalized + normStopDelta; - - UINT32 rangeStartOffset = DENORMALIZE_CODE_OFFSET(rangeStartOffsetNormalized); - UINT32 rangeStopOffset = DENORMALIZE_CODE_OFFSET(rangeStopOffsetNormalized); - - bool fStop = pCallback(rangeStartOffset, rangeStopOffset, hCallback); - if (fStop) - return; - - lastInterruptibleRangeStopOffsetNormalized = rangeStopOffsetNormalized; - } -} - - -INT32 GcInfoDecoder::GetSecurityObjectStackSlot() -{ - _ASSERTE( m_Flags & DECODE_SECURITY_OBJECT ); - return m_SecurityObjectStackSlot; -} - -INT32 GcInfoDecoder::GetGenericsInstContextStackSlot() -{ - _ASSERTE( m_Flags & DECODE_GENERICS_INST_CONTEXT ); - return m_GenericsInstContextStackSlot; -} - -INT32 GcInfoDecoder::GetPSPSymStackSlot() -{ - _ASSERTE( m_Flags & DECODE_PSP_SYM); - return m_PSPSymStackSlot; -} - -bool GcInfoDecoder::GetIsVarArg() -{ - _ASSERTE( m_Flags & DECODE_VARARG ); - return m_IsVarArg; -} - -UINT32 GcInfoDecoder::GetCodeLength() -{ - _ASSERTE( m_Flags & DECODE_CODE_LENGTH ); - return m_CodeLength; -} - -UINT32 GcInfoDecoder::GetStackBaseRegister() -{ - return m_StackBaseRegister; -} - -UINT32 GcInfoDecoder::GetSizeOfEditAndContinuePreservedArea() -{ - _ASSERTE( m_Flags & DECODE_EDIT_AND_CONTINUE ); - return m_SizeOfEditAndContinuePreservedArea; -} - - -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - -UINT32 GcInfoDecoder::GetSizeOfStackParameterArea() -{ - return m_SizeOfStackOutgoingAndScratchArea; -} - -#endif // FIXED_STACK_PARAMETER_SCRATCH_AREA - - -bool GcInfoDecoder::EnumerateLiveSlots( - PREGDISPLAY pRD, - bool reportScratchSlots, - unsigned flags, - GCEnumCallback pCallBack, - LPVOID hCallBack - ) -{ - _ASSERTE( m_Flags & DECODE_GC_LIFETIMES ); - -#if 0 -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - - //------------------------------------------------------------------------------ - // Try partially interruptible first - //------------------------------------------------------------------------------ - - UINT32 numCallSites = (UINT32)m_Reader.Read( sizeof( numCallSites ) * 8 ); - UINT32 callSiteIdx = 0; - - if( numCallSites > 0 ) - { - UINT32 numSlotMappings = (UINT32)m_Reader.Read( sizeof( numSlotMappings ) * 8 ); - - // Align the reader to the next byte to continue decoding - m_Reader.Skip( ( 8 - ( m_Reader.GetCurrentPos() % 8 ) ) % 8 ); - - for( callSiteIdx=0; callSiteIdx<numCallSites; callSiteIdx++ ) - { - UINT32 instructionOffset = (UINT32)m_Reader.Read( 32 ); - if( instructionOffset == m_InstructionOffset ) - { - m_IsInterruptible = true; - - BYTE* callSiteLiveSet = (BYTE*) _alloca( ( numSlotMappings + 7 ) / 8 ); - - UINT32 i; - for( i=0; i<numSlotMappings/8; i++ ) - callSiteLiveSet[ i ] = (BYTE)m_Reader.Read( 8 ); - - callSiteLiveSet[ i ] = (BYTE)m_Reader.Read( numSlotMappings % 8 ); - - m_Reader.Skip( ( numCallSites - callSiteIdx - 1 ) * ( 32 + numSlotMappings ) ); - - //--------------------------------------------------------------------------- - // Read slot mappings - //--------------------------------------------------------------------------- - - GcSlotDesc* slotMappings = (GcSlotDesc*) _alloca( numSlotMappings * sizeof( GcSlotDesc ) ); - // Assert that we can read a GcSlotDesc with a single call to m_Reader.Read() - _ASSERTE( sizeof( GcSlotDesc ) <= sizeof ( size_t ) ); - for( UINT32 i=0; i<numSlotMappings; i++ ) - { - size_t data = m_Reader.Read( sizeof( GcSlotDesc ) * 8 ); - slotMappings[ i ] = *( (GcSlotDesc*) &data ); - } - - //--------------------------------------------------------------------------- - // Report live slots - //--------------------------------------------------------------------------- - - for( UINT32 i=0; i<numSlotMappings; i++ ) - { - BYTE isLive = callSiteLiveSet[ i / 8 ] & ( 1 << ( i % 8 ) ); - if( isLive ) - { - GcSlotDesc slotDesc = slotMappings[ i ]; - if( slotDesc.IsRegister ) - { - if( reportScratchSlots || !IsScratchRegister( slotDesc.Slot.RegisterNumber, pRD ) ) - { - ReportRegisterToGC( - slotDesc.Slot.RegisterNumber, - slotDesc.IsInterior, - slotDesc.IsPinned, - pRD, - flags, - pCallBack, - hCallBack - ); - } - else - { - LOG((LF_GCROOTS, LL_INFO1000, "\"Live\" scratch register " FMT_REG " not reported\n", slotDesc.Slot.RegisterNumber)); - } - } - else - { - GcStackSlotBase spBase = (GcStackSlotBase) (slotDesc.Slot.SpOffset & 0x3); - INT32 realSpOffset = slotDesc.Slot.SpOffset ^ (int) spBase; - - if( reportScratchSlots || !IsScratchStackSlot(realSpOffset, spBase, pRD) ) - { - ReportStackSlotToGC( - realSpOffset, - spBase, - slotDesc.IsInterior, - slotDesc.IsPinned, - pRD, - flags, - pCallBack, - hCallBack - ); - } - else - { - LOG((LF_GCROOTS, LL_INFO1000, "\"Live\" scratch stack slot " FMT_STK " not reported\n", DBG_STK(realSpOffset))); - } - } - } - } - - return true; - } - - m_Reader.Skip( numSlotMappings ); - } - - // Call site not found. Skip the slot mapping table in preparation for reading the fully-interruptible information - m_Reader.Skip( numSlotMappings * sizeof( GcSlotDesc ) * 8 ); - } - -#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED -#endif - - - // If no info is found for the call site, we default to fully-interruptbile - LOG((LF_GCROOTS, LL_INFO1000000, "No GC info found for call site at offset %x. Defaulting to fully-interruptible information.\n", (int) m_InstructionOffset)); - - // Align the reader to the next byte to continue decoding - m_Reader.Skip( ( 8 - ( m_Reader.GetCurrentPos() % 8 ) ) % 8 ); - - // Skip interruptibility information - for(UINT32 i=0; i<m_NumInterruptibleRanges; i++) - { - m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA_ENCBASE ); - m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA_ENCBASE ); - } - - // - // If this is a non-leaf frame and we are executing a call, the unwinder has given us the PC - // of the call instruction. We should adjust it to the PC of the instruction after the call in order to - // obtain transition information for scratch slots. However, we always assume scratch slots to be - // dead for non-leaf frames (except for ResumableFrames), so we don't need to adjust the PC. - // If this is a non-leaf frame and we are not executing a call (i.e.: a fault occurred in the function), - // then it would be incorrect to ajust the PC - // - - int lifetimeTransitionsCount = 0; - - //-------------------------------------------------------------------- - // Decode registers - //-------------------------------------------------------------------- - - size_t numRegisters = m_Reader.DecodeVarLengthUnsigned(NUM_REGISTERS_ENCBASE); - - { -#ifdef ENABLE_CONTRACTS_IMPL - CONTRACT_VIOLATION(FaultViolation | FaultNotFatal); -#endif - m_pLiveRegisters = (GcSlotDesc*) qbSlots1.AllocNoThrow(sizeof(GcSlotDesc)*numRegisters); - } - if (m_pLiveRegisters == NULL) - { - return false; - } - - - _ASSERTE(m_pLiveRegisters); - - int lastNormRegNum = 0; - - for(int i=0; i<numRegisters; i++) - { - if( i==0 ) - { - lastNormRegNum = (int) m_Reader.DecodeVarLengthUnsigned(REGISTER_ENCBASE); - } - else - { - int normRegDelta = (int) m_Reader.DecodeVarLengthUnsigned(REGISTER_DELTA_ENCBASE) + 1; - lastNormRegNum += normRegDelta; - } - int regNum = DENORMALIZE_REGISTER(lastNormRegNum); - - BOOL isInterior = FALSE; - BOOL isPinned = FALSE; - BOOL isLive = FALSE; - - size_t normCodeOffset = (size_t)(SSIZE_T)(-1); - BOOL becomesLive = TRUE; - for(;;) - { - size_t normCodeOffsetDelta = m_Reader.DecodeVarLengthUnsigned(NORM_CODE_OFFSET_DELTA_ENCBASE); - if(normCodeOffsetDelta == 0) // terminator - break; - - if(normCodeOffset != (size_t)(SSIZE_T)(-1)) - becomesLive = (BOOL) m_Reader.Read(1); - - normCodeOffset += normCodeOffsetDelta; - - UINT32 instructionOffset = DENORMALIZE_CODE_OFFSET((UINT32)normCodeOffset); - - BOOL becomesInterior = FALSE; - BOOL becomesPinned = FALSE; - - if(becomesLive) - { - if(m_Reader.Read(1)) - { - size_t flagEnc = m_Reader.Read( 2 ); - becomesInterior = (BOOL)(flagEnc & 0x1); - becomesPinned = (BOOL)(flagEnc & 0x2); - } - } - - lifetimeTransitionsCount++; - - LOG((LF_GCROOTS, LL_INFO1000000, - "Transition " FMT_PIPTR "in " FMT_REG "going %s at offset %04x.\n", - DBG_PIN_NAME(becomesPinned), DBG_IPTR_NAME(becomesInterior), regNum, - becomesLive ? "live" : "dead", - (int) instructionOffset )); - - if( instructionOffset > m_InstructionOffset ) - continue; - - isLive = becomesLive; - isInterior = becomesInterior; - isPinned = becomesPinned; - } - - if( isLive ) - { - if( reportScratchSlots || !IsScratchRegister( regNum, pRD ) ) - { - m_pLiveRegisters[m_NumLiveRegisters].Slot.RegisterNumber = regNum; - GcSlotFlags flags = GC_SLOT_BASE; - if(isInterior) - flags = (GcSlotFlags) (flags | GC_SLOT_INTERIOR); - if(isPinned) - flags = (GcSlotFlags) (flags | GC_SLOT_PINNED); - - m_pLiveRegisters[m_NumLiveRegisters].Flags = flags; - m_NumLiveRegisters++; - } - else - { - LOG((LF_GCROOTS, LL_INFO1000, "\"Live\" scratch register " FMT_REG " not reported\n", regNum)); - } - } - } - - //-------------------------------------------------------------------- - // Decode stack slots - //-------------------------------------------------------------------- - - size_t numStackSlots = m_Reader.DecodeVarLengthUnsigned(NUM_STACK_SLOTS_ENCBASE); - { -#ifdef ENABLE_CONTRACTS_IMPL - CONTRACT_VIOLATION(FaultViolation | FaultNotFatal); -#endif - m_pLiveStackSlots = (GcSlotDesc*) qbSlots2.AllocNoThrow(sizeof(GcSlotDesc)*numStackSlots); - } - if (m_pLiveStackSlots == NULL) - { - return false; - } - _ASSERTE(m_pLiveStackSlots); - - INT32 lastNormStackSlot = 0; - - for(int i=0; i<numStackSlots; i++) - { - if( i==0 ) - { - lastNormStackSlot = (INT32) m_Reader.DecodeVarLengthSigned(STACK_SLOT_ENCBASE); - } - else - { - INT32 normStackSlotDelta = (INT32) m_Reader.DecodeVarLengthUnsigned(STACK_SLOT_DELTA_ENCBASE); - lastNormStackSlot += normStackSlotDelta; - } - INT32 spOffset = DENORMALIZE_STACK_SLOT(lastNormStackSlot); - GcStackSlotBase spBase = (GcStackSlotBase) m_Reader.Read(2); - - BOOL isInterior = FALSE; - BOOL isPinned = FALSE; - BOOL isLive = FALSE; - - size_t normCodeOffset = (size_t)(SSIZE_T)(-1); - BOOL becomesLive = TRUE; - for(;;) - { - size_t normCodeOffsetDelta = m_Reader.DecodeVarLengthUnsigned(NORM_CODE_OFFSET_DELTA_ENCBASE); - if(normCodeOffsetDelta == 0) // terminator - break; - - if(normCodeOffset != (size_t)(SSIZE_T)(-1)) - becomesLive = (BOOL) m_Reader.Read(1); - - normCodeOffset += normCodeOffsetDelta; - - UINT32 instructionOffset = DENORMALIZE_CODE_OFFSET((UINT32)normCodeOffset); - - BOOL becomesInterior = FALSE; - BOOL becomesPinned = FALSE; - - if(becomesLive) - { - if(m_Reader.Read(1)) - { - size_t flagEnc = m_Reader.Read( 2 ); - becomesInterior = (BOOL)(flagEnc & 0x1); - becomesPinned = (BOOL)(flagEnc & 0x2); - } - } - - lifetimeTransitionsCount++; - - LOG((LF_GCROOTS, LL_INFO1000000, - "Transition " FMT_PIPTR "in " FMT_STK "going %s at offset %04x.\n", - DBG_PIN_NAME(becomesPinned), DBG_IPTR_NAME(becomesInterior), DBG_STK(spOffset), - becomesLive ? "live" : "dead", - (int) instructionOffset )); - - if( instructionOffset > m_InstructionOffset ) - continue; - - isLive = becomesLive; - isInterior = becomesInterior; - isPinned = becomesPinned; - } - - if( isLive ) - { - if( reportScratchSlots || !IsScratchStackSlot(spOffset, spBase, pRD) ) - { - m_pLiveStackSlots[m_NumLiveStackSlots].Slot.Stack.SpOffset = spOffset; - m_pLiveStackSlots[m_NumLiveStackSlots].Slot.Stack.Base = spBase; - GcSlotFlags flags = GC_SLOT_BASE; - if(isInterior) - flags = (GcSlotFlags) (flags | GC_SLOT_INTERIOR); - if(isPinned) - flags = (GcSlotFlags) (flags | GC_SLOT_PINNED); - - m_pLiveStackSlots[m_NumLiveStackSlots].Flags = flags; - m_NumLiveStackSlots++; - } - else - { - LOG((LF_GCROOTS, LL_INFO1000, "\"Live\" scratch stack slot " FMT_STK " not reported\n", DBG_STK(spOffset))); - } - } - } - - - LOG((LF_GCROOTS, LL_INFO1000000, "Decoded %d lifetime transitions.\n", (int) lifetimeTransitionsCount )); - - return true; -} - -void GcInfoDecoder::VerifyLiveRegister( - UINT32 regNum, - GcSlotFlags flags - ) -{ - _ASSERTE(m_pLiveRegisters); - - // If this assert fails, the slot being passed was not found to be live in this decoder - _ASSERTE(m_NumLiveRegisters > 0); - - int pos; - for(pos = 0; pos < m_NumLiveRegisters; pos++) - { - if(regNum == m_pLiveRegisters[pos].Slot.RegisterNumber && - flags == m_pLiveRegisters[pos].Flags) - { - break; - } - } - - // If this assert fails, the slot being passed was not found to be live in this decoder - _ASSERTE(pos < m_NumLiveRegisters); - - m_pLiveRegisters[pos] = m_pLiveRegisters[--m_NumLiveRegisters]; -} - -void GcInfoDecoder::VerifyLiveStackSlot( - INT32 spOffset, - GcStackSlotBase spBase, - GcSlotFlags flags - ) -{ - _ASSERTE(m_pLiveStackSlots); - - // If this assert fails, the slot being passed was not found to be live in this decoder - _ASSERTE(m_NumLiveStackSlots > 0); - - int pos; - for(pos = 0; pos < m_NumLiveStackSlots; pos++) - { - if(spOffset == m_pLiveStackSlots[pos].Slot.Stack.SpOffset && - spBase == m_pLiveStackSlots[pos].Slot.Stack.Base && - flags == m_pLiveStackSlots[pos].Flags) - { - break; - } - } - - // If this assert fails, the slot being passed was not found to be live in this decoder - _ASSERTE(pos < m_NumLiveStackSlots); - - m_pLiveStackSlots[pos] = m_pLiveStackSlots[--m_NumLiveStackSlots]; -} - -void GcInfoDecoder::DoFinalVerification() -{ - // If this assert fails, the m_NumLiveRegisters slots remaining in m_pLiveRegisters - // were not reported by the calling decoder - _ASSERTE(m_NumLiveRegisters == 0); - - // If this assert fails, the m_NumLiveStackSlots slots remaining in m_pLiveStackSlots - // were not reported by the calling decoder - _ASSERTE(m_NumLiveStackSlots == 0); - -} - -//----------------------------------------------------------------------------- -// Platform-specific methods -//----------------------------------------------------------------------------- - -#if defined(_TARGET_AMD64_) - - -OBJECTREF* GcInfoDecoder::GetRegisterSlot( - int regNum, - PREGDISPLAY pRD - ) -{ - _ASSERTE(regNum >= 0 && regNum <= 16); - _ASSERTE(regNum != 4); // rsp - - // The fields of KNONVOLATILE_CONTEXT_POINTERS are in the same order as - // the processor encoding numbers. - - ULONGLONG **ppRax; -#ifdef _NTAMD64_ - ppRax = &pRD->pCurrentContextPointers->Rax; -#else - ppRax = &pRD->pCurrentContextPointers->Integer.Register.Rax; -#endif - - return (OBJECTREF*)*(ppRax + regNum); -} - - -bool GcInfoDecoder::IsScratchRegister(int regNum, PREGDISPLAY pRD) -{ - _ASSERTE(regNum >= 0 && regNum <= 16); - _ASSERTE(regNum != 4); // rsp - - UINT16 PreservedRegMask = - (1 << 3) // rbx - | (1 << 5) // rbp - | (1 << 6) // rsi - | (1 << 7) // rdi - | (1 << 12) // r12 - | (1 << 13) // r13 - | (1 << 14) // r14 - | (1 << 15); // r15 - - return !(PreservedRegMask & (1 << regNum)); -} - - -bool GcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) -{ -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - _ASSERTE( m_Flags & DECODE_GC_LIFETIMES ); - - ULONGLONG pSlot = (ULONGLONG) GetStackSlot(spOffset, spBase, pRD); - _ASSERTE(pSlot >= pRD->SP); - - return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea); -#else - return FALSE; -#endif -} - - -void GcInfoDecoder::ReportRegisterToGC( // AMD64 - int regNum, - BOOL isInterior, - BOOL isPinned, - PREGDISPLAY pRD, - unsigned flags, - GCEnumCallback pCallBack, - LPVOID hCallBack) -{ - GCINFODECODER_CONTRACT(CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END); - - _ASSERTE(regNum >= 0 && regNum <= 16); - _ASSERTE(regNum != 4); // rsp - - LOG((LF_GCROOTS, LL_INFO1000, "Reporting " FMT_REG, regNum )); - - OBJECTREF* pObjRef = GetRegisterSlot( regNum, pRD ); - -#ifdef _DEBUG - if(IsScratchRegister(regNum, pRD)) - { - // Scratch registers cannot be reported for non-leaf frames - _ASSERTE(flags & ActiveStackFrame); - } - - LOG((LF_GCROOTS, LL_INFO1000, /* Part Two */ - "at" FMT_ADDR "as ", DBG_ADDR(pObjRef) )); - - VALIDATE_ROOT(isInterior, hCallBack, pObjRef); - - LOG((LF_GCROOTS, LL_INFO1000, /* Part Three */ - LOG_PIPTR_OBJECT_CLASS(OBJECTREF_TO_UNCHECKED_OBJECTREF(*pObjRef), isPinned, isInterior))); -#endif //_DEBUG - - DWORD gcFlags = CHECK_APP_DOMAIN; - - if (isInterior) - gcFlags |= GC_CALL_INTERIOR; - - if (isPinned) - gcFlags |= GC_CALL_PINNED; - - pCallBack(hCallBack, pObjRef, gcFlags); -} - -#else // Unknown platform - -OBJECTREF* GcInfoDecoder::GetRegisterSlot( - int regNum, - PREGDISPLAY pRD - ) -{ - PORTABILITY_ASSERT("GcInfoDecoder::GetRegisterSlot"); - return NULL; -} - -bool GcInfoDecoder::IsScratchRegister(int regNum, PREGDISPLAY pRD) -{ - PORTABILITY_ASSERT("GcInfoDecoder::IsScratchRegister"); - return false; -} - -bool GcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) -{ - _ASSERTE( !"NYI" ); - return false; -} - -void GcInfoDecoder::ReportRegisterToGC( - int regNum, - BOOL isInterior, - BOOL isPinned, - PREGDISPLAY pRD, - unsigned flags, - GCEnumCallback pCallBack, - LPVOID hCallBack) -{ - _ASSERTE( !"NYI" ); -} - -#endif // Unknown platform - - -OBJECTREF* GcInfoDecoder::GetStackSlot( - INT32 spOffset, - GcStackSlotBase spBase, - PREGDISPLAY pRD - ) -{ - OBJECTREF* pObjRef; - - if( GC_SP_REL == spBase ) - { - pObjRef = (OBJECTREF*) ((SIZE_T)GetRegdisplaySP(pRD) + spOffset); - } - else if( GC_CALLER_SP_REL == spBase ) - { - pObjRef = (OBJECTREF*) (GET_CALLER_SP(pRD) + spOffset); - } - else - { - _ASSERTE( GC_FRAMEREG_REL == spBase ); - _ASSERTE( NO_STACK_BASE_REGISTER != m_StackBaseRegister ); - - pObjRef = (OBJECTREF*)((*((INT64*)(GetRegisterSlot( m_StackBaseRegister, pRD )))) + spOffset); - } - - return pObjRef; -} - -void GcInfoDecoder::ReportStackSlotToGC( - INT32 spOffset, - GcStackSlotBase spBase, - BOOL isInterior, - BOOL isPinned, - PREGDISPLAY pRD, - unsigned flags, - GCEnumCallback pCallBack, - LPVOID hCallBack) -{ - GCINFODECODER_CONTRACT(CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END); - - OBJECTREF* pObjRef = GetStackSlot(spOffset, spBase, pRD); - _ASSERTE( IS_ALIGNED( pObjRef, sizeof( Object* ) ) ); - -#ifdef _DEBUG - LOG((LF_GCROOTS, LL_INFO1000, /* Part One */ - "Reporting %s" FMT_STK, - ( (GC_SP_REL == spBase) ? "" : - ((GC_CALLER_SP_REL == spBase) ? "caller's " : - ((GC_FRAMEREG_REL == spBase) ? "frame " : "<unrecognized GcStackSlotBase> "))), - DBG_STK(spOffset) )); - - LOG((LF_GCROOTS, LL_INFO1000, /* Part Two */ - "at" FMT_ADDR "as ", DBG_ADDR(pObjRef) )); - - VALIDATE_ROOT(isInterior, hCallBack, pObjRef); - - LOG((LF_GCROOTS, LL_INFO1000, /* Part Three */ - LOG_PIPTR_OBJECT_CLASS(OBJECTREF_TO_UNCHECKED_OBJECTREF(*pObjRef), isPinned, isInterior))); -#endif - - DWORD gcFlags = CHECK_APP_DOMAIN; - - if (isInterior) - gcFlags |= GC_CALL_INTERIOR; - - if (isPinned) - gcFlags |= GC_CALL_PINNED; - - pCallBack(hCallBack, pObjRef, gcFlags); -} - -} - -#endif // USE_GC_INFO_DECODER -#endif // VERIFY_GCINFO diff --git a/src/vm/gcinfodecoder.cpp b/src/vm/gcinfodecoder.cpp index b2f5640331..351e221d82 100644 --- a/src/vm/gcinfodecoder.cpp +++ b/src/vm/gcinfodecoder.cpp @@ -87,11 +87,7 @@ GcInfoDecoder::GcInfoDecoder( GcInfoDecoderFlags flags, UINT32 breakOffset ) - : m_Reader(dac_cast<PTR_CBYTE>(gcInfoToken.Info) -#ifdef VERIFY_GCINFO - + sizeof(size_t) -#endif - ) + : m_Reader(dac_cast<PTR_CBYTE>(gcInfoToken.Info)) , m_InstructionOffset(breakOffset) , m_IsInterruptible(false) #ifdef _DEBUG @@ -99,14 +95,6 @@ GcInfoDecoder::GcInfoDecoder( , m_GcInfoAddress(dac_cast<PTR_CBYTE>(gcInfoToken.Info)) , m_Version(gcInfoToken.Version) #endif -#ifdef VERIFY_GCINFO - , m_DbgDecoder(dac_cast<PTR_CBYTE>(gcInfoToken.Info) + - (((UINT32)((PTR_BYTE)(TADDR)gcInfoToken.Info)[3])<<24)+ - (((UINT32)((PTR_BYTE)(TADDR)gcInfoToken.Info)[2])<<16)+ - (((UINT32)((PTR_BYTE)(TADDR)gcInfoToken.Info)[1])<<8)+ - ((PTR_BYTE)(TADDR)gcInfoAddr)[0], - flags, breakOffset) -#endif { _ASSERTE( (flags & (DECODE_INTERRUPTIBILITY | DECODE_GC_LIFETIMES)) || (0 == breakOffset) ); @@ -320,30 +308,6 @@ GcInfoDecoder::GcInfoDecoder( { EnumerateInterruptibleRanges(&SetIsInterruptibleCB, this); } - -#ifdef VERIFY_GCINFO -#if 0 - if(flags & DECODE_INTERRUPTIBILITY) - _ASSERTE(IsInterruptible() == m_DbgDecoder.IsInterruptible()); -#endif - if(flags & DECODE_SECURITY_OBJECT) - _ASSERTE(GetSecurityObjectStackSlot() == m_DbgDecoder.GetSecurityObjectStackSlot()); - if(flags & DECODE_GENERICS_INST_CONTEXT) - { - _ASSERTE(GetGenericsInstContextStackSlot() == m_DbgDecoder.GetGenericsInstContextStackSlot()); - _ASSERTE(GetPSPSymStackSlot() == m_DbgDecoder.GetPSPSymStackSlot()); - } - if(flags & DECODE_VARARG) - _ASSERTE(GetIsVarArg() == m_DbgDecoder.GetIsVarArg()); - if(flags & DECODE_CODE_LENGTH) - _ASSERTE(GetCodeLength() == m_DbgDecoder.GetCodeLength()); - _ASSERTE(GetStackBaseRegister() == m_DbgDecoder.GetStackBaseRegister()); - _ASSERTE(GetSizeOfEditAndContinuePreservedArea() == m_DbgDecoder.GetSizeOfEditAndContinuePreservedArea()); -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - _ASSERTE(GetSizeOfStackParameterArea() == m_DbgDecoder.GetSizeOfStackParameterArea()); -#endif -#endif - } bool GcInfoDecoder::IsInterruptible() @@ -587,16 +551,6 @@ bool GcInfoDecoder::EnumerateLiveSlots( return true; } -#ifdef VERIFY_GCINFO - m_DbgDecoder.EnumerateLiveSlots( - pRD, - reportScratchSlots, - inputFlags, - pCallBack, - hCallBack - ); -#endif - // // If this is a non-leaf frame and we are executing a call, the unwinder has given us the PC // of the call instruction. We should adjust it to the PC of the instruction after the call in order to @@ -1073,13 +1027,6 @@ ReportUntracked: ExitSuccess: #endif -#ifdef VERIFY_GCINFO -#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - if(!executionAborted) -#endif - m_DbgDecoder.DoFinalVerification(); -#endif - return true; } diff --git a/src/vm/wks/wks.targets b/src/vm/wks/wks.targets index b9f57e882e..04562365f6 100644 --- a/src/vm/wks/wks.targets +++ b/src/vm/wks/wks.targets @@ -251,7 +251,6 @@ <ItemGroup> <CppCompile Include="$(VmSourcesDir)\AssemblyNativeResource.cpp" /> <CppCompile Include="$(VmSourcesDir)\coverage.cpp" /> - <CppCompile Include="$(VmSourcesDir)\DbgGcInfoDecoder.cpp" /> <CppCompile Include="$(VmSourcesDir)\dwreport.cpp" /> <CppCompile Include="$(VmSourcesDir)\EnCEE.cpp" /> <CppCompile Include="$(VmSourcesDir)\ExceptionHandling.cpp" /> |