diff --git a/src/coreclr/binder/assembly.cpp b/src/coreclr/binder/assembly.cpp index b2459e7ae243ff..23b685290a9048 100644 --- a/src/coreclr/binder/assembly.cpp +++ b/src/coreclr/binder/assembly.cpp @@ -43,14 +43,6 @@ namespace BINDER_SPACE m_pPEImage = NULL; } -#ifdef FEATURE_PREJIT - if (m_pNativePEImage != NULL) - { - BinderReleasePEImage(m_pNativePEImage); - m_pNativePEImage = NULL; - } -#endif - SAFE_RELEASE(m_pAssemblyName); SAFE_RELEASE(m_pMDImport); } diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index 61f0d827e60f19..c72bba34fd8793 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -5821,28 +5821,8 @@ ClrDataAccess::RawGetMethodName( // // Special-cased stub managers // -#ifdef FEATURE_PREJIT - if (pStubManager == RangeSectionStubManager::g_pManager) - { - switch (RangeSectionStubManager::GetStubKind(TO_TADDR(address))) - { - case STUB_CODE_BLOCK_PRECODE: - goto PrecodeStub; - - case STUB_CODE_BLOCK_JUMPSTUB: - goto JumpStub; - - default: - break; - } - } - else -#endif if (pStubManager == PrecodeStubManager::g_pManager) { -#ifdef FEATURE_PREJIT - PrecodeStub: -#endif PCODE alignedAddress = AlignDown(TO_TADDR(address), PRECODE_ALIGNMENT); #ifdef TARGET_ARM @@ -5887,9 +5867,6 @@ ClrDataAccess::RawGetMethodName( else if (pStubManager == JumpStubStubManager::g_pManager) { -#ifdef FEATURE_PREJIT - JumpStub: -#endif PCODE pTarget = decodeBackToBackJump(TO_TADDR(address)); HRESULT hr = GetRuntimeNameByAddress(pTarget, flags, bufLen, symbolLen, symbolBuf, NULL); @@ -6592,14 +6569,8 @@ bool ClrDataAccess::GetILImageInfoFromNgenPEFile(PEFile *peFile, // Use DAC hint to retrieve the IL name. peFile->GetModuleFileNameHint().DacGetUnicode(cchFilePath, wszFilePath, (COUNT_T *)(&dwWritten)); } -#ifdef FEATURE_PREJIT - // Need to get IL image information from cached info in the ngen image. - dwTimeStamp = peFile->GetLoaded()->GetNativeVersionInfo()->sourceAssembly.timeStamp; - dwSize = peFile->GetLoaded()->GetNativeVersionInfo()->sourceAssembly.ilImageSize; -#else dwTimeStamp = 0; dwSize = 0; -#endif // FEATURE_PREJIT return true; } diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 2924be33c049de..16788129eec7de 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -705,12 +705,6 @@ HRESULT DacDbiInterfaceImpl::SetCompilerFlags(VMPTR_DomainFile vmDomainFile, HRESULT hr = S_OK; -#ifdef FEATURE_PREJIT - if (pModule->HasNativeImage()) - { - ThrowHR(CORDBG_E_CANT_CHANGE_JIT_SETTING_FOR_ZAP_MODULE); - } -#endif _ASSERTE(pModule != NULL); // Initialize dwBits. @@ -1256,32 +1250,9 @@ bool DacDbiInterfaceImpl::GetILImageInfoFromNgenPEFile(VMPTR_PEFile vmPEFile, DWORD &dwSize, IStringHolder* pStrFilename) { -#if !defined(FEATURE_PREJIT) return false; -#else // defined(FEATURE_PREJIT) - - DD_ENTER_MAY_THROW; - - PEFile * pPEFile = vmPEFile.GetDacPtr(); - _ASSERTE(pPEFile != NULL); - if (pPEFile == NULL) - { - return false; - } - - WCHAR wszFilePath[MAX_LONGPATH] = {0}; - DWORD cchFilePath = MAX_LONGPATH; - bool ret = ClrDataAccess::GetILImageInfoFromNgenPEFile(pPEFile, - dwTimeStamp, - dwSize, - wszFilePath, - cchFilePath); - - pStrFilename->AssignCopy(wszFilePath); - return ret; -#endif // !defined(FEATURE_PREJIT) } // Get start addresses and sizes for hot and cold regions for a native code blob. @@ -4184,31 +4155,6 @@ BOOL DacDbiInterfaceImpl::GetModuleNGenPath(VMPTR_Module vmModule, IStringHolder * pStrFilename) { DD_ENTER_MAY_THROW; -#ifdef FEATURE_PREJIT - Module * pModule = vmModule.GetDacPtr(); - PEFile * pFile = pModule->GetFile(); - if (pFile != NULL && pFile->HasNativeImage()) - { - PEImage * pImage = pFile->GetPersistentNativeImage(); - if (pImage != NULL && pImage->IsFile()) - { - // We have an on-disk ngen image. Return the path. - // since we no longer support Win9x, we assume all paths will be in unicode format already - const WCHAR * szPath = pImage->GetPath().DacGetRawUnicode(); - if (szPath == NULL) - { - szPath = pFile->GetModuleFileNameHint().DacGetRawUnicode(); - if (szPath == NULL) - { - goto NoFileName; - } - } - IfFailThrow(pStrFilename->AssignCopy(szPath)); - return TRUE; - } - } -NoFileName: -#endif // FEATURE_PREJIT // no ngen filename IfFailThrow(pStrFilename->AssignCopy(W(""))); @@ -5796,42 +5742,14 @@ HRESULT DacDbiInterfaceImpl::SetNGENCompilerFlags(DWORD dwFlags) { DD_ENTER_MAY_THROW; -#ifndef FEATURE_PREJIT return CORDBG_E_NGEN_NOT_SUPPORTED; -#else - // verify that we are still early enough in runtime lifecycle to mutate these - // flags. Typically this is done in the CreateProcess event though it is possible - // to do it even earlier - if(!Debugger::s_fCanChangeNgenFlags) - return CORDBG_E_MUST_BE_IN_CREATE_PROCESS; - - BOOL fAllowOpt = - ((dwFlags & CORDEBUG_JIT_DISABLE_OPTIMIZATION) != CORDEBUG_JIT_DISABLE_OPTIMIZATION); - PEFile::SetNGENDebugFlags(fAllowOpt); - return S_OK; -#endif } HRESULT DacDbiInterfaceImpl::GetNGENCompilerFlags(DWORD *pdwFlags) { DD_ENTER_MAY_THROW; -#ifndef FEATURE_PREJIT return CORDBG_E_NGEN_NOT_SUPPORTED; -#else - BOOL fAllowOpt = TRUE; - PEFile::GetNGENDebugFlags(&fAllowOpt); - if(!fAllowOpt) - { - *pdwFlags = CORDEBUG_JIT_DISABLE_OPTIMIZATION; - } - else - { - *pdwFlags = CORDEBUG_JIT_DEFAULT; - } - - return S_OK; -#endif } typedef DPTR(OBJECTREF) PTR_ObjectRef; diff --git a/src/coreclr/debug/daccess/enummem.cpp b/src/coreclr/debug/daccess/enummem.cpp index 577fdcbc6b2e44..d67e210964f28e 100644 --- a/src/coreclr/debug/daccess/enummem.cpp +++ b/src/coreclr/debug/daccess/enummem.cpp @@ -619,9 +619,6 @@ HRESULT ClrDataAccess::EnumMemDumpModuleList(CLRDataEnumMemoryFlags flags) ULONG32 length; PEFile *file; TSIZE_T cbMemoryReported = m_cbMemoryReported; -#ifdef FEATURE_PREJIT - COUNT_T count; -#endif // FEATURE_PREJIT // // Iterating through module list @@ -668,15 +665,6 @@ HRESULT ClrDataAccess::EnumMemDumpModuleList(CLRDataEnumMemoryFlags flags) file = modDef->GetFile(); base = PTR_TO_TADDR(file->GetLoadedImageContents(&length)); file->EnumMemoryRegions(flags); -#ifdef FEATURE_PREJIT - - // If module has native image and it has debug map, we need to get the debug map. - // - if (modDef->HasNativeImage() && modDef->GetNativeImage()->HasNativeDebugMap()) - { - modDef->GetNativeImage()->GetNativeDebugMap(&count); - } -#endif // FEATURE_PREJIT } EX_CATCH { diff --git a/src/coreclr/debug/daccess/nidump.cpp b/src/coreclr/debug/daccess/nidump.cpp index ccd642765398f0..6a6a6441058b7c 100644 --- a/src/coreclr/debug/daccess/nidump.cpp +++ b/src/coreclr/debug/daccess/nidump.cpp @@ -6,8995 +6,6 @@ /*vim: set foldmethod=marker: */ #include -#if defined(FEATURE_PREJIT) -#include "nidump.h" - -#include - -#include -#include -#include - -#if !defined(FEATURE_CORESYSTEM) -#include -#endif - - -#include - -#include - - -#include - -#if !defined(FEATURE_CORESYSTEM) -#include -#undef _ASSERTE -#define _ASSERTE(x) assert(x) -#endif - -#ifdef USE_GC_INFO_DECODER -#include -#endif - -#include - -#define FEATURE_MSDIS - -//---------------------------------------------------------------------------- -// -// ClrDump functionality -// -//---------------------------------------------------------------------------- - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Given a compressed integer(*pData), expand the compressed int to *pDataOut. -// Return value is the number of bytes that the integer occupies in the compressed format -// It is caller's responsibility to ensure pDataOut has at least 4 bytes to be written to. -// -// This function returns -1 if pass in with an incorrectly compressed data, such as -// (*pBytes & 0xE0) == 0XE0. -///////////////////////////////////////////////////////////////////////////////////////////// -/* XXX Wed 09/14/2005 - * copied from cor.h. Modified to operate on PTR_PCCOR_SIGNATUREs - */ -inline ULONG DacSigUncompressBigData( - PTR_CCOR_SIGNATURE &pData) // [IN,OUT] compressed data -{ - ULONG res; - - // 1 byte data is handled in DacSigUncompressData - // _ASSERTE(*pData & 0x80); - - // Medium. - if ((*pData & 0xC0) == 0x80) // 10?? ???? - { - res = (ULONG)((*pData++ & 0x3f) << 8); - res |= *pData++; - } - else // 110? ???? - { - res = (*pData++ & 0x1f) << 24; - res |= *pData++ << 16; - res |= *pData++ << 8; - res |= *pData++; - } - return res; -} -FORCEINLINE ULONG DacSigUncompressData( - PTR_CCOR_SIGNATURE &pData) // [IN,OUT] compressed data -{ - // Handle smallest data inline. - if ((*pData & 0x80) == 0x00) // 0??? ???? - return *pData++; - return DacSigUncompressBigData(pData); -} - -// uncompress a token -inline mdToken DacSigUncompressToken( // return the token. - PTR_CCOR_SIGNATURE &pData) // [IN,OUT] compressed data -{ - mdToken tk; - mdToken tkType; - - tk = DacSigUncompressData(pData); - tkType = CorSigDecodeTokenType(tk & 0x3); - tk = TokenFromRid(tk >> 2, tkType); - return tk; -} -// uncompress encoded element type -FORCEINLINE CorElementType DacSigUncompressElementType(//Element type - PTR_CCOR_SIGNATURE &pData) // [IN,OUT] compressed data -{ - return (CorElementType)*pData++; -} - - - -const char * g_helperNames[] = -{ -#define JITHELPER(val, fn, sig) # val, -#include -#undef JITHELPER -}; - - - -#define dim(x) (sizeof(x)/sizeof((x)[0])) - -void EnumFlagsToString( DWORD value, - const NativeImageDumper::EnumMnemonics * table, - int count, const WCHAR * sep, SString& output ) -{ - bool firstValue = true; - for( int i = 0; i < count; ++i ) - { - bool match = false; - const NativeImageDumper::EnumMnemonics& entry = table[i]; - if( entry.mask != 0 ) - match = ((entry.mask & value) == entry.value); - else - match = (entry.value == value); - - if( match ) - { - if( !firstValue ) - output.Append(sep); - firstValue = false; - - output.Append( table[i].mnemonic ); - - value &= ~entry.value; - } - } -} - -const NativeImageDumper::EnumMnemonics s_ImageSections[] = -{ -#define IS_ENTRY(v, s) NativeImageDumper::EnumMnemonics(v, s) - IS_ENTRY(IMAGE_SCN_MEM_READ, W("read")), - IS_ENTRY(IMAGE_SCN_MEM_WRITE, W("write")), - IS_ENTRY(IMAGE_SCN_MEM_EXECUTE, W("execute")), - IS_ENTRY(IMAGE_SCN_CNT_CODE, W("code")), - IS_ENTRY(IMAGE_SCN_CNT_INITIALIZED_DATA, W("init data")), - IS_ENTRY(IMAGE_SCN_CNT_UNINITIALIZED_DATA, W("uninit data")), -#undef IS_ENTRY -}; -inline int CheckFlags( DWORD source, DWORD flags ) -{ - return (source & flags) == flags; -} - -HRESULT ClrDataAccess::DumpNativeImage(CLRDATA_ADDRESS loadedBase, - LPCWSTR name, - IXCLRDataDisplay * display, - IXCLRLibrarySupport * support, - IXCLRDisassemblySupport *dis) -{ - DAC_ENTER(); - /* REVISIT_TODO Fri 09/09/2005 - * catch exceptions - */ - NativeImageDumper dump(dac_cast(CLRDATA_ADDRESS_TO_TADDR(loadedBase)), name, display, - support, dis); - dump.DumpNativeImage(); - DAC_LEAVE(); - return S_OK; -} - - - -static ULONG bigBufferSize = 8192; -static WCHAR bigBuffer[8192]; -static BYTE bigByteBuffer[1024]; - -//---------------------------------------------------------------------------- -// -// NativeImageDumper -// -//---------------------------------------------------------------------------- -template -inline T combine(T a, T b) -{ - return (T)(((DWORD)a) | ((DWORD)b)); -} -template -inline T combine(T a, T b, T c) -{ - return (T)(((DWORD)a) | ((DWORD)b) | ((DWORD)c)); -} -#define CLRNATIVEIMAGE_ALWAYS ((CLRNativeImageDumpOptions)~0) -#define CHECK_OPT(opt) CheckOptions(CLRNATIVEIMAGE_ ## opt) -#define IF_OPT(opt) if( CHECK_OPT(opt) ) -#define IF_OPT_AND(opt1, opt2) if( CHECK_OPT(opt1) && CHECK_OPT(opt2) ) -#define IF_OPT_OR(opt1, opt2) if( CHECK_OPT(opt1) || CHECK_OPT(opt2) ) -#define IF_OPT_OR3(opt1, opt2, opt3) if( CHECK_OPT(opt1) || CHECK_OPT(opt2) || CHECK_OPT(opt3) ) -#define IF_OPT_OR4(opt1, opt2, opt3, opt4) if( CHECK_OPT(opt1) || CHECK_OPT(opt2) || CHECK_OPT(opt3) || CHECK_OPT(opt4) ) -#define IF_OPT_OR5(opt1, opt2, opt3, opt4, opt5) if( CHECK_OPT(opt1) || CHECK_OPT(opt2) || CHECK_OPT(opt3) || CHECK_OPT(opt4) || CHECK_OPT(opt5) ) - -#define fieldsize(type, field) (sizeof(((type*)NULL)->field)) - - -/*{{{Display helpers*/ -#define DisplayStartCategory(name, filter)\ - do { IF_OPT(filter) m_display->StartCategory(name); } while(0) -#define DisplayEndCategory(filter)\ - do { IF_OPT(filter) m_display->EndCategory(); } while(0) -#define DisplayStartArray(name, fmt, filter) \ - do { IF_OPT(filter) m_display->StartArray(name, fmt); } while(0) -#define DisplayStartArrayWithOffset(field, fmt, type, filter) \ - do { IF_OPT(filter) m_display->StartArrayWithOffset( # field, offsetof(type, field), fieldsize(type, field), fmt); } while(0) - -#define DisplayStartElement( name, filter ) \ - do { IF_OPT(filter) m_display->StartElement( name ); } while(0) -#define DisplayStartStructure( name, ptr, size, filter ) \ - do { IF_OPT(filter) m_display->StartStructure( name, ptr, size ); } while(0) -#define DisplayStartList(fmt, filter) \ - do { IF_OPT(filter) m_display->StartList(fmt); } while(0) - -#define DisplayStartStructureWithOffset( field, ptr, size, type, filter ) \ - do { IF_OPT(filter) m_display->StartStructureWithOffset( # field, offsetof(type, field), fieldsize(type, field), ptr, size ); } while(0) -#define DisplayStartVStructure( name, filter ) \ - do { IF_OPT(filter) m_display->StartVStructure( name ); } while(0) -#define DisplayEndVStructure( filter ) \ - do { IF_OPT(filter) m_display->EndVStructure(); } while(0) - -#define DisplayEndList(filter) \ - do { IF_OPT(filter) m_display->EndList(); } while(0) -#define DisplayEndArray(footer, filter) \ - do { IF_OPT(filter) m_display->EndArray(footer); } while(0) -#define DisplayEndStructure(filter) \ - do { IF_OPT(filter) m_display->EndStructure(); } while(0) - -#define DisplayEndElement(filter) \ - do { IF_OPT(filter) m_display->EndElement(); } while(0) - -#define DisplayWriteElementString(name, value, filter) \ - do { IF_OPT(filter) m_display->WriteElementString(name, value); } while(0) -#define DisplayWriteElementStringW(name, value, filter) \ - do { IF_OPT(filter) m_display->WriteElementStringW(name, value); } while(0) - -#define DisplayWriteElementStringW(name, value, filter) \ - do { IF_OPT(filter) m_display->WriteElementStringW(name, value); } while(0) - -#define DisplayWriteElementInt(name, value, filter) \ - do { IF_OPT(filter) m_display->WriteElementInt(name, value); } while(0) -#define DisplayWriteElementIntWithSuppress(name, value, defVal, filter) \ - do { IF_OPT(filter) m_display->WriteElementIntWithSuppress(name, value, defVal); } while(0) -#define DisplayWriteElementUInt(name, value, filter) \ - do { IF_OPT(filter) m_display->WriteElementUInt(name, value); } while(0) -#define DisplayWriteElementFlag(name, value, filter) \ - do { IF_OPT(filter) m_display->WriteElementFlag(name, value); } while(0) -#define DisplayWriteElementPointer(name, value, filter) \ - do { IF_OPT(filter) m_display->WriteElementPointer(name, value); } while(0) -#define DisplayWriteElementPointerAnnotated(name, value, annotation, filter) \ - do { IF_OPT(filter) m_display->WriteElementPointerAnnotated(name, value, annotation ); } while(0) -#define DisplayWriteEmptyElement(name, filter) \ - do { IF_OPT(filter) m_display->WriteEmptyElement(name); } while(0) - -#define DisplayWriteElementEnumerated(name, value, mnemonics, sep, filter) \ - do { \ - IF_OPT(filter) { \ - TempBuffer buf; \ - EnumFlagsToString(value, mnemonics, _countof(mnemonics), sep, buf);\ - m_display->WriteElementEnumerated( name, value, (const WCHAR*)buf ); \ - }\ - }while(0) -#define DisplayWriteFieldEnumerated(field, value, type, mnemonics, sep, filter)\ - do { \ - IF_OPT(filter) { \ - TempBuffer buf; \ - EnumFlagsToString(value, mnemonics, _countof(mnemonics), sep, buf);\ - m_display->WriteFieldEnumerated( # field, offsetof(type, field), \ - fieldsize(type, field), value,\ - (const WCHAR*)buf ); \ - }\ - }while(0) -#define DisplayWriteElementAddress(name, ptr, size, filter) \ - do { IF_OPT(filter) m_display->WriteElementAddress( name, ptr, size ); } while(0) -#define DisplayWriteElementAddressNamed(eltName, name, ptr, size, filter) \ - do { IF_OPT(filter) m_display->WriteElementAddressNamed( eltName, name, ptr, size ); } while(0) -#define DisplayWriteElementAddressNamedW(eltName, name, ptr, size, filter) \ - do { IF_OPT(filter) m_display->WriteElementAddressNamedW( eltName, name, ptr, size ); } while(0) - -#define DisplayWriteFieldString(field, value, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldString( # field, offsetof(type, field), fieldsize(type, field), value ); } while(0) -#define DisplayWriteFieldStringW(field, value, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldStringW( # field, offsetof(type, field), fieldsize(type, field), value ); } while(0) -#define DisplayWriteFieldInt(field, value, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldInt( # field, offsetof(type, field), fieldsize(type, field), value ); } while(0) -#define DisplayWriteFieldUInt(field, value, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldUInt( # field, offsetof(type, field), fieldsize(type, field), value ); } while(0) -#define DisplayWriteFieldPointer(field, ptr, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldPointer( # field, offsetof(type, field), fieldsize(type, field), ptr ); } while(0) -#define DisplayWriteFieldPointerWithSize(field, ptr, size, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldPointerWithSize( # field, offsetof(type, field), fieldsize(type, field), ptr, size ); } while(0) -#define DisplayWriteFieldEmpty(field, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldEmpty( # field, offsetof(type, field), fieldsize(type, field) ); } while(0) -#define DisplayWriteFieldFlag(field, value, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldFlag(# field, offsetof(type, field), fieldsize(type, field), value); } while(0) -#define WriteFieldFieldDesc(field, ptr, type, filter) \ - do { IF_OPT(filter) DoWriteFieldFieldDesc( # field, offsetof(type, field), fieldsize(type, field), ptr ); } while(0) -#define WriteFieldMethodDesc(field, ptr, type, filter) \ - do { IF_OPT(filter) DoWriteFieldMethodDesc( # field, offsetof(type, field), fieldsize(type, field), ptr ); } while(0) -#define WriteFieldStr(field, ptr, type, filter) \ - do { IF_OPT(filter) DoWriteFieldStr( ptr, # field, offsetof(type, field), fieldsize(type, field) ); } while(0) -#define WriteFieldMethodTable(field, ptr, type, filter) \ - do { IF_OPT(filter) DoWriteFieldMethodTable( # field, offsetof(type, field), fieldsize(type, field), ptr ); } while(0) -#define WriteFieldMDToken(field, token, type, filter) \ - do { IF_OPT(filter) DoWriteFieldMDToken( # field, offsetof(type, field), fieldsize(type, field), token ); } while(0) -#define WriteFieldAsHex(field, ptr, type, filter) \ - do { IF_OPT(filter) DoWriteFieldAsHex( # field, offsetof(type, field), fieldsize(type, field), ptr, fieldsize(type, field)); } while(0) -#define WriteFieldMDTokenImport(field, token, type, filter, import) \ - do { IF_OPT(filter) DoWriteFieldMDToken( # field, offsetof(type, field), fieldsize(type, field), token, import); } while(0) -#define WriteFieldTypeHandle(field, ptr, type, filter) \ - do { IF_OPT(filter) DoWriteFieldTypeHandle( # field, offsetof(type, field), fieldsize(type, field), ptr ); } while(0) -#define WriteFieldCorElementType(field, et, type, filter) \ - do { IF_OPT(filter) DoWriteFieldCorElementType( # field, offsetof(type, field), fieldsize(type, field), et ); } while(0) -#define DumpFieldStub(field, ptr, type, filter) \ - do { IF_OPT(filter) DoDumpFieldStub( ptr, offsetof(type, field), fieldsize(type, field), # field ); } while(0) -#define DumpComPlusCallInfo(compluscall, filter) \ - do { IF_OPT(filter) DoDumpComPlusCallInfo( compluscall ); } while(0) -#define DisplayWriteFieldPointerAnnotated(field, ptr, annotation, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldPointer( # field, offsetof(type, field), fieldsize(type, field), ptr ); } while(0) -#define DisplayWriteFieldAddress(field, ptr, size, type, filter) \ - do { IF_OPT(filter) m_display->WriteFieldAddress( # field, offsetof(type, field), fieldsize(type, field), ptr, size ); } while(0) -#define DisplayStartTextElement(name, filter) \ - do { IF_OPT(filter) m_display->StartTextElement( name ); } while(0) -#define DisplayEndTextElement(filter) \ - do { IF_OPT(filter) m_display->EndTextElement(); } while(0) -#define DisplayWriteXmlText( args, filter ) \ - do { IF_OPT(filter) m_display->WriteXmlText args; } while(0) -#define DisplayWriteXmlTextBlock( args, filter ) \ - do { IF_OPT(filter) m_display->WriteXmlTextBlock args; } while(0) - -#define CoverageRead( ptr, size ) \ - do { IF_OPT(DEBUG_COVERAGE) PTR_READ(TO_TADDR(ptr), size); } while(0) -#define CoverageReadString( taddr ) \ - do { PTR_BYTE ptr(TO_TADDR(taddr)); while( *ptr++ ); }while(0) - -void AppendNilToken( mdToken token, SString& buf ) -{ - _ASSERTE(RidFromToken(token) == mdTokenNil); - - const WCHAR * id = NULL; - switch(token) - { -#define mdNilEnt(x) case x: \ - id = W(#x); \ - break - mdNilEnt(mdModuleNil); - mdNilEnt(mdTypeRefNil); - mdNilEnt(mdTypeDefNil); - mdNilEnt(mdFieldDefNil); - mdNilEnt(mdMethodDefNil); - mdNilEnt(mdParamDefNil); - mdNilEnt(mdInterfaceImplNil); - mdNilEnt(mdMemberRefNil); - mdNilEnt(mdCustomAttributeNil); - mdNilEnt(mdPermissionNil); - mdNilEnt(mdSignatureNil); - mdNilEnt(mdEventNil); - mdNilEnt(mdPropertyNil); - mdNilEnt(mdModuleRefNil); - mdNilEnt(mdTypeSpecNil); - mdNilEnt(mdAssemblyNil); - mdNilEnt(mdAssemblyRefNil); - mdNilEnt(mdFileNil); - mdNilEnt(mdExportedTypeNil); - mdNilEnt(mdManifestResourceNil); - - mdNilEnt(mdGenericParamNil); - mdNilEnt(mdGenericParamConstraintNil); - mdNilEnt(mdMethodSpecNil); - - mdNilEnt(mdStringNil); -#undef mdNilEnt - } - buf.Append( id ); -} -void appendByteArray(SString& buf, const BYTE * bytes, ULONG cbBytes) -{ - for( COUNT_T i = 0; i < cbBytes; ++i ) - { - buf.AppendPrintf(W("%02x"), bytes[i]); - } -} -/*}}}*/ - - - - -struct OptionDependencies -{ - OptionDependencies(CLRNativeImageDumpOptions value, - CLRNativeImageDumpOptions dep) : m_value(value), - m_dep(dep) - { - - } - CLRNativeImageDumpOptions m_value; - CLRNativeImageDumpOptions m_dep; -}; - -static OptionDependencies g_dependencies[] = -{ -#define OPT_DEP(value, dep) OptionDependencies(CLRNATIVEIMAGE_ ## value,\ - CLRNATIVEIMAGE_ ## dep) - OPT_DEP(RESOURCES, COR_INFO), - OPT_DEP(METADATA, COR_INFO), - OPT_DEP(PRECODES, MODULE), - //Does methoddescs require ModuleTables? - OPT_DEP(VERBOSE_TYPES, METHODDESCS), - OPT_DEP(GC_INFO, METHODS), - OPT_DEP(FROZEN_SEGMENT, MODULE), - OPT_DEP(SLIM_MODULE_TBLS, MODULE), - OPT_DEP(MODULE_TABLES, SLIM_MODULE_TBLS), - OPT_DEP(DISASSEMBLE_CODE, METHODS), - - OPT_DEP(FIXUP_HISTOGRAM, FIXUP_TABLES), - OPT_DEP(FIXUP_THUNKS, FIXUP_TABLES), - -#undef OPT_DEP -}; - -// Metadata helpers for DAC -// This is mostly copied from mscoree.cpp which isn't available in mscordacwks.dll. -// - -// This function gets the Dispenser interface given the CLSID and REFIID. -STDAPI DLLEXPORT MetaDataGetDispenser( - REFCLSID rclsid, // The class to desired. - REFIID riid, // Interface wanted on class factory. - LPVOID FAR * ppv) // Return interface pointer here. -{ - _ASSERTE(rclsid == CLSID_CorMetaDataDispenser); - - return InternalCreateMetaDataDispenser(riid, ppv); -} - - -NativeImageDumper::NativeImageDumper(PTR_VOID loadedBase, - const WCHAR * const name, - IXCLRDataDisplay * display, - IXCLRLibrarySupport * support, - IXCLRDisassemblySupport *dis) - : - m_decoder(loadedBase), - m_name(name), - m_baseAddress(loadedBase), - m_display(display), - m_librarySupport(support), - m_import(NULL), - m_assemblyImport(NULL), - m_manifestAssemblyImport(NULL), - m_dependencies(NULL), - m_imports(NULL), - m_dis(dis), - m_MetadataSize(0), - m_ILHostCopy(NULL), - m_isCoreLibHardBound(false), - m_sectionAlignment(0) -{ - IfFailThrow(m_display->GetDumpOptions(&m_dumpOptions)); - - //set up mscorwks stuff. - m_mscorwksBase = DacGlobalBase(); - _ASSERTE(m_mscorwksBase); - PEDecoder mscorwksDecoder(dac_cast(m_mscorwksBase)); - m_mscorwksSize = mscorwksDecoder.GetSize(); - m_mscorwksPreferred = TO_TADDR(mscorwksDecoder.GetPreferredBase()); - //add implied options (i.e. if you want to dump the module, you also have - //to dump the native info. - CLRNativeImageDumpOptions current; - do - { - current = m_dumpOptions; - for( unsigned i = 0; i < _countof(g_dependencies); ++i ) - { - if( m_dumpOptions & g_dependencies[i].m_value ) - m_dumpOptions |= g_dependencies[i].m_dep; - } - }while( current != m_dumpOptions ); - IF_OPT(DISASSEMBLE_CODE) - { - //configure the disassembler - m_dis->SetTranslateAddrCallback(TranslateAddressCallback); - m_dis->SetTranslateFixupCallback(TranslateFixupCallback); - m_dis->PvClientSet(this); - } -} - -void GuidToString( GUID& guid, SString& s ) -{ - WCHAR guidString[64]; - GuidToLPWSTR(guid, guidString, sizeof(guidString) / sizeof(WCHAR)); - //prune the { and } - _ASSERTE(guidString[0] == W('{') - && guidString[wcslen(guidString) - 1] == W('}')); - guidString[wcslen(guidString) - 1] = W('\0'); - s.Append( guidString + 1 ); -} - -NativeImageDumper::~NativeImageDumper() -{ -} - -inline const void * ptr_add(const void * ptr, COUNT_T size) -{ - return reinterpret_cast(ptr) + size; -} - -//This does pointer arithmetic on a DPtr. -template -inline const DPTR(T) dptr_add(T* ptr, COUNT_T offset) -{ - return DPTR(T)(PTR_HOST_TO_TADDR(ptr) + (offset * sizeof(T))); -} - -template -inline const DPTR(T) dptr_sub(T* ptr, COUNT_T offset) -{ - return DPTR(T)(PTR_HOST_TO_TADDR(ptr) - (offset * sizeof(T))); -} -template -inline const DPTR(T) dptr_sub(DPTR(T)* ptr, COUNT_T offset) -{ - return DPTR(T)(PTR_HOST_TO_TADDR(ptr) - (offset * sizeof(T))); -} - -struct MDTableType -{ - MDTableType(unsigned t, const char * n) : m_token(t), m_name(n) { } - unsigned m_token; - const char * m_name; -}; - -static unsigned s_tableTypes[] = -{ - /* -#ifdef MiniMdTable -#undef MiniMdTable -#endif -#define MiniMdTable(x) TBL_##x << 24, - MiniMdTables() -#undef MiniMdTable - mdtName - */ - mdtModule, - mdtTypeRef, - mdtTypeDef, - mdtFieldDef, - mdtMethodDef, - mdtParamDef, - mdtInterfaceImpl, - mdtMemberRef, - mdtCustomAttribute, - mdtPermission, - mdtSignature, - mdtEvent, - mdtProperty, - mdtModuleRef, - mdtTypeSpec, - mdtAssembly, - mdtAssemblyRef, - mdtFile, - mdtExportedType, - mdtManifestResource, - mdtGenericParam, - mdtMethodSpec, - mdtGenericParamConstraint, -}; - -const NativeImageDumper::EnumMnemonics s_CorHdrFlags[] = -{ -#define CHF_ENTRY(f,v) NativeImageDumper::EnumMnemonics(f, v) - CHF_ENTRY(COMIMAGE_FLAGS_ILONLY, W("IL Only")), - CHF_ENTRY(COMIMAGE_FLAGS_32BITREQUIRED, W("32-bit Required")), - CHF_ENTRY(COMIMAGE_FLAGS_IL_LIBRARY, W("IL Library")), - CHF_ENTRY(COMIMAGE_FLAGS_STRONGNAMESIGNED, W("Strong Name Signed")), - CHF_ENTRY(COMIMAGE_FLAGS_NATIVE_ENTRYPOINT, W("Has Native Entrypoint")), - CHF_ENTRY(COMIMAGE_FLAGS_TRACKDEBUGDATA, W("Track Debug Data")), - CHF_ENTRY(COMIMAGE_FLAGS_32BITPREFERRED, W("32-bit Preferred")) -#undef CHF_ENTRY -}; - -void NativeImageDumper::DumpAssemblySignature(CORCOMPILE_ASSEMBLY_SIGNATURE & assemblySignature) -{ - { - TempBuffer buf; - GuidToString(assemblySignature.mvid, buf); - DisplayWriteFieldStringW( mvid, (const WCHAR*)buf, - CORCOMPILE_ASSEMBLY_SIGNATURE, - COR_INFO ); - } - DisplayWriteFieldInt( timeStamp, assemblySignature.timeStamp, - CORCOMPILE_ASSEMBLY_SIGNATURE, COR_INFO ); - DisplayWriteFieldInt( ilImageSize, - assemblySignature.ilImageSize, - CORCOMPILE_ASSEMBLY_SIGNATURE, COR_INFO ); -} - - -//error code return? -void -NativeImageDumper::DumpNativeImage() -{ - COUNT_T size; - const void *data; - - m_display->StartDocument(); - - DisplayStartCategory( "File", PE_INFO ); - DisplayWriteElementStringW( "path", m_name, PE_INFO ); - - DisplayWriteElementInt( "diskSize", m_decoder.GetSize(), PE_INFO ); - _ASSERTE(sizeof(IMAGE_DOS_HEADER) < m_decoder.GetSize()); - - PTR_IMAGE_DOS_HEADER dosHeader = - PTR_IMAGE_DOS_HEADER(dac_cast(m_baseAddress)); - DisplayWriteElementAddress( "IMAGE_DOS_HEADER", - DPtrToPreferredAddr(dosHeader), - sizeof(*dosHeader), PE_INFO ); - - // NT headers - - if (!m_decoder.HasNTHeaders()) - { - IF_OPT(PE_INFO) - { - DisplayWriteElementString("isPEFile", "false", PE_INFO); - DisplayEndCategory(PE_INFO); - } - else - m_display->ErrorPrintF("Non-PE file"); - - m_display->EndDocument(); - return; - } - - CONSISTENCY_CHECK(m_decoder.CheckNTHeaders()); - if (!m_decoder.CheckNTHeaders()) - { - m_display->ErrorPrintF("*** NT headers are not valid ***"); - return; - } - - DisplayWriteElementString("imageType", m_decoder.Has32BitNTHeaders() - ? "32 bit image" : "64 bit image", PE_INFO); - DisplayWriteElementAddress("address", (SIZE_T)m_decoder.GetNativePreferredBase(), - m_decoder.GetVirtualSize(), PE_INFO); - DisplayWriteElementInt( "TimeDateStamp", m_decoder.GetTimeDateStamp(), - PE_INFO ); - - if( m_decoder.Has32BitNTHeaders() ) - { - PTR_IMAGE_NT_HEADERS32 ntHeaders(m_decoder.GetNTHeaders32()); - //base, size, sectionAlign - _ASSERTE(ntHeaders->OptionalHeader.SectionAlignment >= - ntHeaders->OptionalHeader.FileAlignment); - m_imageSize = ntHeaders->OptionalHeader.SizeOfImage; - m_display->NativeImageDimensions(PTR_TO_TADDR(m_decoder.GetBase()), - ntHeaders->OptionalHeader.SizeOfImage, - ntHeaders->OptionalHeader.SectionAlignment); - /* REVISIT_TODO Mon 11/21/2005 - * I don't understand this. Sections start on a two page boundary, but - * data ends on a one page boundary. What's up with that? - */ - m_sectionAlignment = GetOsPageSize(); //ntHeaders->OptionalHeader.SectionAlignment; - unsigned ntHeaderSize = sizeof(*ntHeaders) - - sizeof(ntHeaders->OptionalHeader) - + ntHeaders->FileHeader.SizeOfOptionalHeader; - DisplayWriteElementAddress( "IMAGE_NT_HEADERS32", - DPtrToPreferredAddr(ntHeaders), - ntHeaderSize, PE_INFO ); - - } - else - { - PTR_IMAGE_NT_HEADERS64 ntHeaders(m_decoder.GetNTHeaders64()); - //base, size, sectionAlign - _ASSERTE(ntHeaders->OptionalHeader.SectionAlignment >= - ntHeaders->OptionalHeader.FileAlignment); - m_imageSize = ntHeaders->OptionalHeader.SizeOfImage; - m_display->NativeImageDimensions((SIZE_T)ntHeaders->OptionalHeader.ImageBase, - ntHeaders->OptionalHeader.SizeOfImage, - ntHeaders->OptionalHeader.SectionAlignment); - m_sectionAlignment = ntHeaders->OptionalHeader.SectionAlignment; - unsigned ntHeaderSize = sizeof(*ntHeaders) - - sizeof(ntHeaders->OptionalHeader) - + ntHeaders->FileHeader.SizeOfOptionalHeader; - DisplayWriteElementAddress( "IMAGE_NT_HEADERS64", - DPtrToPreferredAddr(ntHeaders), - ntHeaderSize, PE_INFO ); - } - DisplayEndCategory(PE_INFO); - - // PE Section info - - DisplayStartArray("Sections", W("%-8s%s\t(disk %s) %s"), PE_INFO); - - for (COUNT_T i = 0; i < m_decoder.GetNumberOfSections(); i++) - { - PTR_IMAGE_SECTION_HEADER section = m_decoder.FindFirstSection() + i; - m_display->Section(reinterpret_cast(section->Name), - section->VirtualAddress, - section->SizeOfRawData); - DisplayStartStructure( "Section", DPtrToPreferredAddr(section), - sizeof(*section), PE_INFO ); - DisplayWriteElementString("name", (const char *)section->Name, PE_INFO); - DisplayWriteElementAddress( "address", RvaToDisplay(section->VirtualAddress), - section->Misc.VirtualSize, PE_INFO ); - DisplayWriteElementAddress( "disk", section->PointerToRawData, - section->SizeOfRawData, PE_INFO ); - - DisplayWriteElementEnumerated( "access", section->Characteristics, - s_ImageSections, W(", "), PE_INFO ); - DisplayEndStructure( PE_INFO ); //Section - } - DisplayEndArray("Total Sections", PE_INFO); - - // Image directory info - - DisplayStartArray( "Directories", W("%-40s%s"), PE_INFO ); - - for ( COUNT_T i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) - { - static const char *directoryNames[] = - { - /* 0*/"IMAGE_DIRECTORY_ENTRY_EXPORT", - /* 1*/"IMAGE_DIRECTORY_ENTRY_IMPORT", - /* 2*/"IMAGE_DIRECTORY_ENTRY_RESOURCE", - /* 3*/"IMAGE_DIRECTORY_ENTRY_EXCEPTION", - /* 4*/"IMAGE_DIRECTORY_ENTRY_SECURITY", - /* 5*/"IMAGE_DIRECTORY_ENTRY_BASERELOC", - /* 6*/"IMAGE_DIRECTORY_ENTRY_DEBUG", - /* 7*/"IMAGE_DIRECTORY_ENTRY_ARCHITECTURE", - /* 8*/"IMAGE_DIRECTORY_ENTRY_GLOBALPTR", - /* 9*/"IMAGE_DIRECTORY_ENTRY_TLS", - /*10*/"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", - /*11*/"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", - /*12*/"IMAGE_DIRECTORY_ENTRY_IAT", - /*13*/"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", - /*14*/"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", - /* 2*/"", - }; - - IMAGE_DATA_DIRECTORY *entry = m_decoder.GetDirectoryEntry(i); - - if (entry->VirtualAddress != 0) - { - DisplayStartElement("Directory", PE_INFO); - DisplayWriteElementString("name", directoryNames[i], PE_INFO); - DisplayWriteElementAddress("address", - RvaToDisplay(entry->VirtualAddress), - entry->Size, PE_INFO); - - DisplayEndElement( PE_INFO ); //Directory - } - } - DisplayEndArray("Total Directories", PE_INFO); //Directories - - // COM+ info - - if (!m_decoder.HasCorHeader()) - { - IF_OPT(COR_INFO) - DisplayWriteElementString("CLRInfo", "", COR_INFO); - else - m_display->ErrorPrintF("Non-CLR image\n"); - - m_display->EndDocument(); - return; - } - - CONSISTENCY_CHECK(m_decoder.CheckCorHeader()); - if (!m_decoder.CheckCorHeader()) - { - m_display->ErrorPrintF("*** INVALID CLR Header ***"); - m_display->EndDocument(); - return; - } - - DisplayStartCategory("CLRInfo", COR_INFO); - PTR_IMAGE_COR20_HEADER pCor(m_decoder.GetCorHeader()); - { -#define WRITE_COR20_FIELD( name ) m_display->WriteFieldAddress( \ - # name, offsetof(IMAGE_COR20_HEADER, name), \ - fieldsize(IMAGE_COR20_HEADER, name), \ - RvaToDisplay( pCor-> name . VirtualAddress ), \ - pCor-> name . Size ) - - m_display->StartStructure( "IMAGE_COR20_HEADER", - DPtrToPreferredAddr(pCor), - sizeof(*pCor) ); - - DisplayWriteFieldUInt( MajorRuntimeVersion, pCor->MajorRuntimeVersion, IMAGE_COR20_HEADER, COR_INFO ); - DisplayWriteFieldUInt( MinorRuntimeVersion, pCor->MinorRuntimeVersion, IMAGE_COR20_HEADER, COR_INFO ); - - // Symbol table and startup information - WRITE_COR20_FIELD(MetaData); - DisplayWriteFieldEnumerated( Flags, pCor->Flags, IMAGE_COR20_HEADER, s_CorHdrFlags, W(", "), COR_INFO ); - DisplayWriteFieldUInt( EntryPointToken, pCor->EntryPointToken, IMAGE_COR20_HEADER, COR_INFO ); - - // Binding information - WRITE_COR20_FIELD(Resources); - WRITE_COR20_FIELD(StrongNameSignature); - - // Regular fixup and binding information - WRITE_COR20_FIELD(CodeManagerTable); - WRITE_COR20_FIELD(VTableFixups); - WRITE_COR20_FIELD(ExportAddressTableJumps); - - // Precompiled image info - WRITE_COR20_FIELD(ManagedNativeHeader); - - m_display->EndStructure(); //IMAGE_COR20_HEADER -#undef WRITE_COR20_FIELD - } - - //make sure to touch the strong name signature even if we won't print it. - if (m_decoder.HasStrongNameSignature()) - { - if (m_decoder.IsStrongNameSigned()) - { - DACCOP_IGNORE(CastBetweenAddressSpaces,"nidump is in-proc and doesn't maintain a clean separation of address spaces (target and host are the same."); - data = reinterpret_cast(dac_cast(m_decoder.GetStrongNameSignature(&size))); - - IF_OPT(COR_INFO) - { - TempBuffer sig; - - appendByteArray(sig, (BYTE*)data, size); - - DisplayWriteElementStringW( "StrongName", (const WCHAR *)sig, - COR_INFO ); - } - } - else - { - DisplayWriteEmptyElement("DelaySigned", COR_INFO); - } - } - -#ifdef FEATURE_READYTORUN - if (m_decoder.HasReadyToRunHeader()) - DisplayWriteElementString( "imageType", "ReadyToRun image", COR_INFO); - else -#endif - if (m_decoder.IsILOnly()) - DisplayWriteElementString( "imageType", "IL only image", COR_INFO); - else - if (m_decoder.HasNativeHeader()) - DisplayWriteElementString( "imageType", "Native image", COR_INFO); - else - DisplayWriteElementString( "imageType", "Mixed image", COR_INFO); - - DACCOP_IGNORE(CastBetweenAddressSpaces,"nidump is in-proc and doesn't maintain a clean separation of address spaces (target and host are the same."); - data = reinterpret_cast(dac_cast(m_decoder.GetMetadata(&size))); - OpenMetadata(); - IF_OPT(METADATA) - { - DWORD dwAssemblyFlags = 0; - IfFailThrow(m_manifestAssemblyImport->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, &dwAssemblyFlags)); - if ((afContentType_WindowsRuntime & dwAssemblyFlags) == afContentType_WindowsRuntime) - { - DisplayWriteElementString ("Metadata", "Not supported by WinRT", COR_INFO); - } - else - { - WriteElementsMetadata( "Metadata", TO_TADDR(data), size ); - } - } - - CoverageRead(TO_TADDR(data), size); - - if (m_decoder.HasNativeHeader()) - { - DACCOP_IGNORE(CastBetweenAddressSpaces,"nidump is in-proc and doesn't maintain a clean separation of address spaces (target and host are the same."); - data = reinterpret_cast(dac_cast(m_decoder.GetNativeManifestMetadata(&size))); - - IF_OPT(METADATA) - { - WriteElementsMetadata( "NativeManifestMetadata", TO_TADDR(data), size ); - } - else - { - DisplayWriteElementAddress( "NativeManifestMetadata", - DataPtrToDisplay((TADDR)data), size, - COR_INFO ); - } - - - /* REVISIT_TODO Tue 09/20/2005 - * Anything to display in the native metadata? - */ - CoverageRead(TO_TADDR(data), size); - - /* REVISIT_TODO Tue 09/20/2005 - * Dump the debug map? Indexed by method RID... probably a good idea - */ - data = reinterpret_cast(m_decoder.GetNativeDebugMap(&size)); - - DisplayWriteElementAddress( "debugMap", DataPtrToDisplay((TADDR)data), size, - COR_INFO); - CoverageRead(TO_TADDR(data), size); - - //also read the entire debug map section - IMAGE_SECTION_HEADER * dbgmap = FindSection( ".dbgmap" ); - if (dbgmap != NULL) - { - CoverageRead(TO_TADDR(dbgmap->VirtualAddress) - + PTR_TO_TADDR(m_decoder.GetBase()), - (ULONG32)ALIGN_UP(dbgmap->Misc.VirtualSize, GetSectionAlignment())); - } - - //read the .il and .rsrc sections in their entirety - IF_OPT(DEBUG_COVERAGE) - { - IMAGE_SECTION_HEADER *hdr; - hdr = FindSection( ".rsrc" ); - if( hdr != NULL ) - { - CoverageRead( m_decoder.GetRvaData(hdr->VirtualAddress), - (ULONG32)hdr->Misc.VirtualSize ); - } - } - IF_OPT_OR(DEBUG_COVERAGE, IL) - { - IMAGE_SECTION_HEADER *hdr = FindSection( ".text" ); - - if( hdr != NULL ) - { - m_ILSectionStart = hdr->VirtualAddress; - m_ILHostCopy = (BYTE*)PTR_READ(m_decoder.GetRvaData(hdr->VirtualAddress), hdr->Misc.VirtualSize); -#ifdef _DEBUG - m_ILSectionSize = hdr->Misc.VirtualSize; -#endif - } - else - { - m_ILSectionStart = 0; - m_ILHostCopy = NULL; -#ifdef _DEBUG - m_ILSectionSize = 0; -#endif - } - _ASSERTE( (((TADDR)m_ILHostCopy) & 3) == 0 ); - _ASSERTE((m_ILSectionStart & 3) == 0); - - } - } - - data = m_decoder.GetResources(&size); - IF_OPT(RESOURCES) - { - DisplayStartStructure( "resource", DataPtrToDisplay((TADDR)data), size, - COR_INFO ); - DisplayStartArray( "Resources", NULL, COR_INFO ); - HCORENUM hEnum = NULL; - for(;;) - { - mdManifestResource resTokens[1]; - ULONG numTokens = 0; - IfFailThrow(m_assemblyImport->EnumManifestResources(&hEnum, - resTokens, - 1, - &numTokens)); - if( numTokens == 0 ) - break; - - WCHAR resourceName[256]; - ULONG nameLen; - mdToken impl; - DWORD offset, flags; - IfFailThrow(m_assemblyImport->GetManifestResourceProps(resTokens[0], - resourceName, - _countof(resourceName), - &nameLen, - &impl, - &offset, - &flags)); - if( RidFromToken(impl) != 0 ) - continue; //skip all non-zero providers - resourceName[nameLen] = W('\0'); - DPTR(DWORD UNALIGNED) res(TO_TADDR(data) + offset); - DWORD resSize = *res; - DisplayWriteElementAddressNamedW( "Resource", resourceName, - DPtrToPreferredAddr(res), - resSize + sizeof(DWORD), - RESOURCES ); - } - DisplayEndArray( "Total Resources", COR_INFO ); //Resources - DisplayEndStructure( COR_INFO ); //resource - } - else - { - DisplayWriteElementAddress( "resource", DataPtrToDisplay((TADDR)data), size, - COR_INFO ); - } - - ULONG resultSize; - GUID mvid; - m_manifestImport->GetScopeProps(bigBuffer, bigBufferSize, &resultSize, &mvid); - /* REVISIT_TODO Wed 09/07/2005 - * The name is the .module entry. Why isn't it present in the ngen image? - */ - TempBuffer guidString; - GuidToString( mvid, guidString ); - if( wcslen(bigBuffer) ) - DisplayWriteElementStringW( "scopeName", bigBuffer, COR_INFO ); - DisplayWriteElementStringW( "mvid", (const WCHAR *)guidString, COR_INFO ); - - if (m_decoder.HasManagedEntryPoint()) - { - DisplayStartVStructure( "ManagedEntryPoint", COR_INFO ); - unsigned token = m_decoder.GetEntryPointToken(); - DisplayWriteElementUInt( "Token", token, COR_INFO ); - TempBuffer buf; - AppendTokenName( token, buf ); - DisplayWriteElementStringW( "TokenName", (const WCHAR *)buf, COR_INFO ); - DisplayEndVStructure( COR_INFO ); - } - else if (m_decoder.HasNativeEntryPoint()) - { - DisplayWriteElementPointer( "NativeEntryPoint", (SIZE_T)m_decoder.GetNativeEntryPoint(), - COR_INFO ); - } - - /* REVISIT_TODO Mon 11/21/2005 - * Dump the version info completely - */ - if( m_decoder.HasNativeHeader() ) - { - PTR_CORCOMPILE_VERSION_INFO versionInfo( m_decoder.GetNativeVersionInfo() ); - - DisplayStartStructure("CORCOMPILE_VERSION_INFO", - DPtrToPreferredAddr(versionInfo), - sizeof(*versionInfo), COR_INFO); - - DisplayStartStructureWithOffset( sourceAssembly, - DPtrToPreferredAddr(versionInfo) + offsetof(CORCOMPILE_VERSION_INFO, sourceAssembly), - sizeof(versionInfo->sourceAssembly), - CORCOMPILE_VERSION_INFO, COR_INFO ); - DumpAssemblySignature(versionInfo->sourceAssembly); - DisplayEndStructure(COR_INFO); //sourceAssembly - - COUNT_T numDeps; - PTR_CORCOMPILE_DEPENDENCY deps(TO_TADDR(m_decoder.GetNativeDependencies(&numDeps))); - - DisplayStartArray( "Dependencies", NULL, COR_INFO ); - - for( COUNT_T i = 0; i < numDeps; ++i ) - { - DisplayStartStructure("CORCOMPILE_DEPENDENCY", DPtrToPreferredAddr(deps + i), - sizeof(deps[i]), COR_INFO ); - WriteFieldMDTokenImport( dwAssemblyRef, deps[i].dwAssemblyRef, - CORCOMPILE_DEPENDENCY, COR_INFO, - m_manifestImport ); - WriteFieldMDTokenImport( dwAssemblyDef, deps[i].dwAssemblyDef, - CORCOMPILE_DEPENDENCY, COR_INFO, - m_manifestImport ); - DisplayStartStructureWithOffset( signAssemblyDef, - DPtrToPreferredAddr(deps + i) + offsetof(CORCOMPILE_DEPENDENCY, signAssemblyDef), - sizeof(deps[i]).signAssemblyDef, - CORCOMPILE_DEPENDENCY, COR_INFO ); - DumpAssemblySignature(deps[i].signAssemblyDef); - DisplayEndStructure(COR_INFO); //signAssemblyDef - - { - TempBuffer buf; - if( deps[i].signNativeImage == INVALID_NGEN_SIGNATURE ) - { - buf.Append( W("INVALID_NGEN_SIGNATURE") ); - } - else - { - GuidToString(deps[i].signNativeImage, buf); - } - DisplayWriteFieldStringW( signNativeImage, (const WCHAR*)buf, - CORCOMPILE_DEPENDENCY, COR_INFO ); -#if 0 - if( m_librarySupport - && deps[i].signNativeImage != INVALID_NGEN_SIGNATURE ) - { - buf.Clear(); - AppendTokenName(deps[i].dwAssemblyRef, buf, m_import ); - IfFailThrow(m_librarySupport->LoadDependency( (const WCHAR*)buf, - deps[i].signNativeImage )); - } -#endif - - } - - - DisplayEndStructure(COR_INFO); //CORCOMPILE_DEPENDENCY - } - DisplayEndArray( "Total Dependencies", COR_INFO ); - DisplayEndStructure(COR_INFO); //CORCOMPILE_VERSION_INFO - - NativeImageDumper::Dependency * traceDependency = OpenDependency(0); - TraceDumpDependency( 0, traceDependency ); - - for( COUNT_T i = 0; i < numDeps; ++i ) - { - traceDependency = OpenDependency( i + 1 ); - TraceDumpDependency( i + 1, traceDependency ); - } - _ASSERTE(m_dependencies[0].pModule != NULL); - - /* XXX Wed 12/14/2005 - * Now for the real insanity. I need to initialize static classes in - * the DAC. First I need to find CoreLib's dependency entry. Search - * through all of the dependencies to find the one marked as - * fIsCoreLib. If I don't find anything marked that way, then "self" - * is CoreLib. - */ - Dependency * corelib = NULL; - for( COUNT_T i = 0; i < m_numDependencies; ++i ) - { - if( m_dependencies[i].fIsCoreLib ) - { - corelib = &m_dependencies[i]; - break; - } - } - - //If we're actually dumping CoreLib, remap the CoreLib dependency to our own native image. - if( (corelib == NULL) || !wcscmp(m_name, CoreLibName_W)) - { - corelib = GetDependency(0); - corelib->fIsCoreLib = TRUE; - _ASSERTE(corelib->fIsHardbound); - } - - _ASSERTE(corelib != NULL); - if( corelib->fIsHardbound ) - { - m_isCoreLibHardBound = true; - } - if( m_isCoreLibHardBound ) - { - //go through the module to the binder. - PTR_Module corelibModule = corelib->pModule; - - PTR_CoreLibBinder binder = corelibModule->m_pBinder; - g_CoreLib = *binder; - - PTR_MethodTable mt = CoreLibBinder::GetExistingClass(CLASS__OBJECT); - g_pObjectClass = mt; - } - - - if (g_pObjectClass == NULL) - { - //if CoreLib is not hard bound, then warn the user (many features of nidump are shut off) - m_display->ErrorPrintF( "Assembly %S is soft bound to CoreLib. nidump cannot dump MethodTables completely.\n", m_name ); - // TritonTODO: reason? - // reset "hard bound state" - m_isCoreLibHardBound = false; - - } - } - - - // @todo: VTable Fixups - - // @todo: EAT Jumps - - DisplayEndCategory(COR_INFO); //CLRInfo - -#ifdef FEATURE_READYTORUN - if (m_decoder.HasReadyToRunHeader()) - { - DumpReadyToRun(); - } - else -#endif - if (m_decoder.HasNativeHeader()) - { - DumpNative(); - } - - m_display->EndDocument(); -} - -void NativeImageDumper::DumpNative() -{ - DisplayStartCategory("NativeInfo", NATIVE_INFO); - - CONSISTENCY_CHECK(m_decoder.CheckNativeHeader()); - if (!m_decoder.CheckNativeHeader()) - { - m_display->ErrorPrintF("*** INVALID NATIVE HEADER ***\n"); - return; - } - - IF_OPT(NATIVE_INFO) - DumpNativeHeader(); - - //host pointer - CORCOMPILE_EE_INFO_TABLE * infoTable = m_decoder.GetNativeEEInfoTable(); - - DisplayStartStructure( "CORCOMPILE_EE_INFO_TABLE", - DataPtrToDisplay(PTR_HOST_TO_TADDR(infoTable)), - sizeof(*infoTable), NATIVE_INFO ); - - /* REVISIT_TODO Mon 09/26/2005 - * Move this further down to include the dumping of the module, and - * other things. - */ - DisplayEndStructure(NATIVE_INFO); //NativeInfoTable - DisplayEndCategory(NATIVE_INFO); //NativeInfo -#if LATER - //come back here and dump all the fields of the CORCOMPILE_EE_INFO_TABLE -#endif - - IF_OPT(RELOCATIONS) - DumpBaseRelocs(); - - IF_OPT(NATIVE_TABLES) - DumpHelperTable(); - - PTR_Module module = (TADDR)m_decoder.GetPersistedModuleImage(); - - //this needs to run for precodes to load the tables that identify precode ranges - IF_OPT_OR5(MODULE, METHODTABLES, EECLASSES, TYPEDESCS, PRECODES) - DumpModule(module); - - IF_OPT_OR3(FIXUP_TABLES, FIXUP_HISTOGRAM, FIXUP_THUNKS) - DumpFixupTables( module ); - IF_OPT_OR3(METHODS, GC_INFO, DISASSEMBLE_CODE ) - DumpMethods( module ); - IF_OPT_OR3(METHODTABLES, EECLASSES, TYPEDESCS) - DumpTypes( module ); -} - -void NativeImageDumper::TraceDumpDependency(int idx, NativeImageDumper::Dependency * dependency) -{ - IF_OPT(DEBUG_TRACE) - { - m_display->ErrorPrintF("Dependency: %d (%p)\n", idx, dependency); - m_display->ErrorPrintF("\tPreferred: %p\n", dependency->pPreferredBase); - m_display->ErrorPrintF("\tLoaded: %p\n", dependency->pLoadedAddress); - m_display->ErrorPrintF("\tSize: %x (%d)\n", dependency->size, dependency->size); - m_display->ErrorPrintF("\tModule: P=%p, L=%p\n", DataPtrToDisplay(dac_cast(dependency->pModule)), - PTR_TO_TADDR(dependency->pModule)); - m_display->ErrorPrintF("CoreLib=%s, Hardbound=%s\n", - (dependency->fIsCoreLib ? "true" : "false"), - (dependency->fIsHardbound ? "true" : "false")); - m_display->ErrorPrintF("Name: %S\n", dependency->name); - } -} - -void NativeImageDumper::WriteElementsMetadata( const char * elementName, - TADDR data, SIZE_T size ) -{ - DisplayStartStructure( elementName, - DataPtrToDisplay(data), size, ALWAYS ); - - /* XXX Mon 03/13/2006 - * Create new metatadata dispenser. When I define the Emit for defining - * assemblyrefs for dependencies, I copy the memory and totally hork any - * mapping back to base addresses. - */ - ReleaseHolder tables; - ReleaseHolder pDispenser; - IfFailThrow(MetaDataGetDispenser(CLSID_CorMetaDataDispenser, - IID_IMetaDataDispenserEx, (void **) &pDispenser)); - - VARIANT opt; - - TADDR hostCopyStart = TO_TADDR(PTR_READ(data, (ULONG32)size)); - TADDR rebasedPointer; - - IfFailThrow(pDispenser->GetOption(MetaDataCheckDuplicatesFor, &opt)); - V_UI4(&opt) |= MDDupAssemblyRef | MDDupFile; - IfFailThrow(pDispenser->SetOption(MetaDataCheckDuplicatesFor, &opt)); - - IfFailThrow(pDispenser->OpenScopeOnMemory((const void *)hostCopyStart, (DWORD)size, - ofRead, IID_IMetaDataTables, - (IUnknown **) &tables)); - DisplayStartArray( "Tables", W("%s"), ALWAYS ); - - for( unsigned i = 0; i < _countof(s_tableTypes); ++i ) - { - HRESULT hr = S_OK; - ULONG idx = 0; - hr = tables->GetTableIndex(s_tableTypes[i], &idx); - _ASSERTE(SUCCEEDED(hr)); - ULONG cbRow = 0, cRows = 0, cCols = 0, iKey = 0; - const char * name = NULL; - BYTE * ptr = NULL; - hr = tables->GetTableInfo(idx, &cbRow, &cRows, &cCols, - &iKey, &name); - _ASSERTE(SUCCEEDED(hr) || hr == E_INVALIDARG); - if( hr == E_INVALIDARG || cRows == 0 ) - { - continue; //no such table. - } - - hr = tables->GetRow(idx, 1, (void**)&ptr); - IfFailThrow(hr); - _ASSERTE(SUCCEEDED(hr)); - //compute address - rebasedPointer = data + (TO_TADDR(ptr) - hostCopyStart); - _ASSERTE( rebasedPointer >= data && rebasedPointer < (data + size) ); - DisplayWriteElementAddressNamed( "table", name, - DataPtrToDisplay(rebasedPointer), - cbRow * cRows , ALWAYS ); -#if 0 - DisplayStartElement( "table", ALWAYS ); - DisplayWriteElementString( "name", name, ALWAYS ); - //compute address - rebasedPointer = data + (TO_TADDR(ptr) - hostCopyStart); - _ASSERTE( rebasedPointer >= data && rebasedPointer < (data + size) ); - DisplayWriteElementAddress( "address", DataPtrToDisplay(rebasedPointer), - cbRow * cRows, ALWAYS ); - DisplayEndElement( ALWAYS ); //Table -#endif - } - DisplayEndArray( "Total Tables", ALWAYS ); - - PTR_STORAGESIGNATURE root(data); - _ASSERTE(root->lSignature == STORAGE_MAGIC_SIG); - //the root is followed by the version string who's length is - //root->iVersionString. After that is a storage header that counts the - //number of streams. - PTR_STORAGEHEADER sHdr(data + sizeof(*root) + root->iVersionString); - DisplayStartArray( "Pools", NULL, ALWAYS ); - - //now check the pools - - //start of stream headers - PTR_STORAGESTREAM streamHeader( PTR_TO_TADDR(sHdr) + sizeof(*sHdr) ); - for( unsigned i = 0; i < sHdr->iStreams; ++i ) - { - if( streamHeader->iSize > 0 ) - { - DisplayWriteElementAddressNamed( "heap", streamHeader->rcName, - DataPtrToDisplay( data + streamHeader->iOffset ), - streamHeader->iSize, ALWAYS ); - } - //Stream headers aren't fixed size. the size is aligned up based on a - //variable length string at the end. - streamHeader = PTR_STORAGESTREAM(PTR_TO_TADDR(streamHeader) - + ALIGN_UP(offsetof(STORAGESTREAM, rcName) + strlen(streamHeader->rcName) + 1, 4)); - } - - DisplayEndArray( "Total Pools", ALWAYS ); //Pools - DisplayEndStructure( ALWAYS ); //nativeMetadata -} -void NativeImageDumper::OpenMetadata() -{ - COUNT_T size; - - DACCOP_IGNORE(CastBetweenAddressSpaces,"nidump is in-proc and doesn't maintain a clean separation of address spaces (target and host are the same."); - const void *data = reinterpret_cast(dac_cast(m_decoder.GetMetadata(&size))); - - ReleaseHolder pDispenser; - IfFailThrow(MetaDataGetDispenser(CLSID_CorMetaDataDispenser, - IID_IMetaDataDispenserEx, (void **) &pDispenser)); - - VARIANT opt; - IfFailThrow(pDispenser->GetOption(MetaDataCheckDuplicatesFor, &opt)); - V_UI4(&opt) |= MDDupAssemblyRef | MDDupFile; - IfFailThrow(pDispenser->SetOption(MetaDataCheckDuplicatesFor, &opt)); - - data = PTR_READ(TO_TADDR(data), size); - IfFailThrow(pDispenser->OpenScopeOnMemory(data, size, ofRead, - IID_IMetaDataImport2, (IUnknown **) &m_import)); - - IfFailThrow(m_import->QueryInterface(IID_IMetaDataAssemblyImport, - (void **)&m_assemblyImport)); - - m_MetadataStartTarget = TO_TADDR(data); - m_MetadataSize = size; - data = PTR_READ(TO_TADDR(data), size); - m_MetadataStartHost = TO_TADDR(data); - - if (m_decoder.HasNativeHeader()) - { - DACCOP_IGNORE(CastBetweenAddressSpaces,"nidump is in-proc and doesn't maintain a clean separation of address spaces (target and host are the same."); - data = reinterpret_cast(dac_cast(m_decoder.GetNativeManifestMetadata(&size))); - - IfFailThrow(pDispenser->OpenScopeOnMemory(data, size, ofRead, - IID_IMetaDataImport2, (IUnknown **) &m_manifestImport)); - - IfFailThrow(m_manifestImport->QueryInterface(IID_IMetaDataAssemblyImport, - (void **)&m_manifestAssemblyImport)); - } - else - { - m_manifestImport = m_import; - m_manifestImport->AddRef(); - - m_manifestAssemblyImport = m_assemblyImport; - m_manifestAssemblyImport->AddRef(); - } -} -void -NativeImageDumper::AppendTokenName(mdToken token, SString& buf) -{ - AppendTokenName(token, buf, NULL); -} -void -NativeImageDumper::AppendTokenName(mdToken token, SString& buf, - IMetaDataImport2 *pImport, - bool force) -{ - mdToken parent; - ULONG size; - DWORD attr; - PCCOR_SIGNATURE pSig; - PTR_CCOR_SIGNATURE dacSig; - ULONG cSig; - DWORD flags; - ULONG rva; - CQuickBytes bytes; - - if( CHECK_OPT(DISABLE_NAMES) && !force ) - { - buf.Append( W("Disabled") ); - return; - } - - if (pImport == NULL) - pImport = m_import; - if( RidFromToken(token) == mdTokenNil ) - { - AppendNilToken( token, buf ); - } - else - { - switch (TypeFromToken(token)) - { - case mdtTypeDef: - IfFailThrow(pImport->GetTypeDefProps(token, bigBuffer, bigBufferSize, &size, &flags, &parent)); - buf.Append(bigBuffer); - break; - - case mdtTypeRef: - // TritonTODO: consolidate with desktop - // IfFailThrow(pImport->GetTypeRefProps(token, &parent, bigBuffer, bigBufferSize, &size)); - if (FAILED(pImport->GetTypeRefProps(token, &parent, bigBuffer, bigBufferSize, &size))) - buf.Append(W("ADDED TYPEREF (?)")); - else - buf.Append(bigBuffer); - break; - - case mdtTypeSpec: - IfFailThrow(pImport->GetTypeSpecFromToken(token, &pSig, &cSig)); - dacSig = metadataToHostDAC(pSig, pImport); - TypeToString(dacSig, buf, pImport); - break; - - case mdtFieldDef: - IfFailThrow(pImport->GetFieldProps(token, &parent, bigBuffer, bigBufferSize, &size, &attr, - &pSig, &cSig, &flags, NULL, NULL)); - AppendTokenName(parent, buf, pImport); - IfFailThrow(pImport->GetFieldProps(token, &parent, bigBuffer, bigBufferSize, &size, &attr, - &pSig, &cSig, &flags, NULL, NULL)); - buf.AppendPrintf( W("::%s"), bigBuffer ); - break; - - case mdtMethodDef: - IfFailThrow(pImport->GetMethodProps(token, &parent, bigBuffer, bigBufferSize, &size, &attr, - &pSig, &cSig, &rva, &flags)); - AppendTokenName(parent, buf, pImport); - IfFailThrow(pImport->GetMethodProps(token, &parent, bigBuffer, bigBufferSize, &size, &attr, - &pSig, &cSig, &rva, &flags)); - buf.AppendPrintf( W("::%s"), bigBuffer ); - break; - - case mdtMemberRef: - IfFailThrow(pImport->GetMemberRefProps(token, &parent, bigBuffer, bigBufferSize, &size, - &pSig, &cSig)); - AppendTokenName(parent, buf, pImport); - IfFailThrow(pImport->GetMemberRefProps(token, &parent, bigBuffer, bigBufferSize, &size, - &pSig, &cSig)); - buf.AppendPrintf( W("::%s"), bigBuffer ); - break; - - case mdtSignature: - IfFailThrow(pImport->GetSigFromToken(token, &pSig, &cSig)); -#if LATER - PrettyPrintSig(pSig, cSig, W(""), &bytes, pImport); - m_display->ErrorPrintF("%S", bytes.Ptr()); -#else - _ASSERTE(!"Unimplemented"); - m_display->ErrorPrintF( "unimplemented" ); -#endif - break; - - case mdtString: - IfFailThrow(pImport->GetUserString(token, bigBuffer, bigBufferSize, &size)); - bigBuffer[min(size, bigBufferSize-1)] = 0; - buf.Append( bigBuffer ); - break; - - case mdtAssembly: - case mdtAssemblyRef: - case mdtFile: - case mdtExportedType: - { - ReleaseHolder pAssemblyImport; - IfFailThrow(pImport->QueryInterface(IID_IMetaDataAssemblyImport, - (void **)&pAssemblyImport)); - PrintManifestTokenName(token, buf, pAssemblyImport, force); - } - break; - - case mdtGenericParam: - { - ULONG nameLen; - IfFailThrow(pImport->GetGenericParamProps(token, NULL, NULL, NULL, NULL, bigBuffer, - _countof(bigBuffer), &nameLen)); - bigBuffer[min(nameLen, _countof(bigBuffer) - 1)] = 0; - buf.Append( bigBuffer ); - } - break; - - default: - _ASSERTE( !"Unknown token type in AppendToken" ); - buf.AppendPrintf( W("token 0x%x"), token ); - } - } -} -void NativeImageDumper::PrintManifestTokenName(mdToken token, SString& str) -{ - PrintManifestTokenName(token, str, NULL); -} -void -NativeImageDumper::PrintManifestTokenName(mdToken token, - SString& buf, - IMetaDataAssemblyImport *pAssemblyImport, - bool force) -{ - ULONG size; - const void *pSig; - ULONG cSig; - DWORD flags; - CQuickBytes bytes; - ULONG hash; - - if( CHECK_OPT(DISABLE_NAMES) && !force ) - { - buf.Append( W("Disabled") ); - return; - } - - if (pAssemblyImport == NULL) - pAssemblyImport = m_manifestAssemblyImport; - - if( RidFromToken(token) == mdTokenNil ) - { - AppendNilToken( token, buf ); - } - else - { - switch (TypeFromToken(token)) - { - case mdtAssembly: - IfFailThrow(pAssemblyImport->GetAssemblyProps(token, &pSig, &cSig, - &hash, bigBuffer, - bigBufferSize, &size, - NULL, &flags)); - - buf.Append(bigBuffer); - break; - - case mdtAssemblyRef: - IfFailThrow(pAssemblyImport->GetAssemblyRefProps(token, &pSig, - &cSig, bigBuffer, - bigBufferSize, - &size, NULL, NULL, - NULL, &flags)); - buf.Append(bigBuffer); - break; - - case mdtFile: - IfFailThrow(pAssemblyImport->GetFileProps(token, bigBuffer, - bigBufferSize, &size, - NULL, NULL, &flags)); - - buf.Append(bigBuffer); - break; - - case mdtExportedType: - IfFailThrow(pAssemblyImport->GetExportedTypeProps(token, bigBuffer, - bigBufferSize, &size, - NULL, NULL, &flags)); - - buf.Append(bigBuffer); - break; - - default: - buf.AppendPrintf(W("token %x"), token); - } - } -} - -BOOL NativeImageDumper::HandleFixupForHistogram(PTR_CORCOMPILE_IMPORT_SECTION pSection, - SIZE_T fixupIndex, - SIZE_T *fixupCell, - BOOL mayUsePrecompiledNDirectMethods) -{ - COUNT_T nImportSections; - PTR_CORCOMPILE_IMPORT_SECTION pImportSections = m_decoder.GetNativeImportSections(&nImportSections); - - COUNT_T tableSize; - TADDR tableBase = m_decoder.GetDirectoryData(&pSection->Section, &tableSize); - - COUNT_T table = (COUNT_T)(pSection - pImportSections); - _ASSERTE(table < nImportSections); - - SIZE_T offset = dac_cast(fixupCell) - tableBase; - _ASSERTE( offset < tableSize ); - - COUNT_T entry = (COUNT_T)(offset / sizeof(TADDR)); - m_fixupHistogram[table][entry]++; - - return TRUE; -} - -void NativeImageDumper::ComputeMethodFixupHistogram( PTR_Module module ) -{ - COUNT_T nImportSections; - PTR_CORCOMPILE_IMPORT_SECTION pImportSections = m_decoder.GetNativeImportSections(&nImportSections); - - m_fixupHistogram = new COUNT_T * [nImportSections]; - - for (COUNT_T i=0; i < nImportSections; i++) - { - PTR_CORCOMPILE_IMPORT_SECTION pSection = m_decoder.GetNativeImportSectionFromIndex(i); - - COUNT_T count = pSection->Section.Size / sizeof(TADDR); - - m_fixupHistogram[i] = new COUNT_T [count]; - ZeroMemory(m_fixupHistogram[i], count * sizeof(COUNT_T)); - } - - ZeroMemory(&m_fixupCountHistogram, sizeof(m_fixupCountHistogram)); - // profiled hot code - - MethodIterator mi(module, &m_decoder, MethodIterator::Hot); - while (mi.Next()) - { - m_fixupCount = 0; - - TADDR pFixupList = mi.GetMethodDesc()->GetFixupList(); - - if (pFixupList != NULL) - { - COUNT_T nImportSections; - PTR_CORCOMPILE_IMPORT_SECTION pImportSections = m_decoder.GetNativeImportSections(&nImportSections); - - module->FixupDelayListAux(pFixupList, this, - &NativeImageDumper::HandleFixupForHistogram, - pImportSections, nImportSections, - &m_decoder); - } - - if (m_fixupCount < COUNT_HISTOGRAM_SIZE) - m_fixupCountHistogram[m_fixupCount]++; - else - m_fixupCountHistogram[COUNT_HISTOGRAM_SIZE-1]++; - } - - // unprofiled code - MethodIterator miUnprofiled(module, &m_decoder, MethodIterator::Unprofiled); - - while(miUnprofiled.Next()) - { - m_fixupCount = 0; - - TADDR pFixupList = miUnprofiled.GetMethodDesc()->GetFixupList(); - - if (pFixupList != NULL) - { - COUNT_T nImportSections; - PTR_CORCOMPILE_IMPORT_SECTION pImportSections = m_decoder.GetNativeImportSections(&nImportSections); - - module->FixupDelayListAux(pFixupList, this, - &NativeImageDumper::HandleFixupForHistogram, - pImportSections, nImportSections, - &m_decoder); - } - - if (m_fixupCount < COUNT_HISTOGRAM_SIZE) - m_fixupCountHistogram[m_fixupCount]++; - else - m_fixupCountHistogram[COUNT_HISTOGRAM_SIZE-1]++; - } -} - -void NativeImageDumper::DumpFixupTables( PTR_Module module ) -{ - IF_OPT(FIXUP_HISTOGRAM) - ComputeMethodFixupHistogram( module ); - - DisplayStartCategory( "Imports", FIXUP_TABLES ); - - COUNT_T nImportSections; - PTR_CORCOMPILE_IMPORT_SECTION pImportSections = m_decoder.GetNativeImportSections(&nImportSections); - - for (COUNT_T iImportSections = 0; iImportSections < nImportSections; iImportSections++) - { - PTR_CORCOMPILE_IMPORT_SECTION pImportSection = pImportSections + iImportSections; - - COUNT_T size; - TADDR pTable(m_decoder.GetDirectoryData(&pImportSection->Section, &size)); - TADDR pTableEnd = pTable + size; - - TADDR pDataTable(NULL); - - if (pImportSection->Signatures != 0) - pDataTable = m_decoder.GetRvaData(pImportSection->Signatures); - - switch (pImportSection->Type) - { - case CORCOMPILE_IMPORT_TYPE_VIRTUAL_METHOD: - { - COUNT_T entrySize = pImportSection->EntrySize; - COUNT_T count = size / entrySize; - _ASSERTE(entrySize == sizeof(CORCOMPILE_VIRTUAL_IMPORT_THUNK)); - - for (TADDR pEntry = pTable; pEntry < pTableEnd; pEntry += entrySize) - { - PTR_CORCOMPILE_VIRTUAL_IMPORT_THUNK pThunk = pEntry; - - DisplayStartStructure("VirtualImportThunk", DPtrToPreferredAddr(pThunk), - entrySize, FIXUP_THUNKS ); - - DisplayWriteElementInt( "Slot", pThunk->slotNum, FIXUP_THUNKS); - - DisplayEndStructure( FIXUP_THUNKS ); - } - } - break; - - case CORCOMPILE_IMPORT_TYPE_EXTERNAL_METHOD: - { - COUNT_T entrySize = pImportSection->EntrySize; - COUNT_T count = size / entrySize; - _ASSERTE(entrySize == sizeof(CORCOMPILE_EXTERNAL_METHOD_THUNK)); - - for (TADDR pEntry = pTable; pEntry < pTableEnd; pEntry += entrySize) - { - PTR_CORCOMPILE_EXTERNAL_METHOD_THUNK pThunk = pEntry; - - DisplayStartStructure("ExternalImportThunk", DPtrToPreferredAddr(pThunk), - entrySize, FIXUP_THUNKS ); - - TADDR pDataAddr = pDataTable + ((pEntry - pTable) / entrySize) * sizeof(DWORD); - PTR_DWORD pData = pDataAddr; - - DisplayWriteElementPointer( "DataAddress ", pDataAddr, FIXUP_THUNKS ); - - TADDR blobSigAddr = RvaToDisplay(*pData); - DisplayWriteElementPointer( "TargetSigAddress", blobSigAddr, FIXUP_THUNKS ); - TempBuffer buf; - FixupBlobToString(*pData, buf); - DisplayWriteElementStringW( "TargetName", (const WCHAR*)buf, FIXUP_THUNKS ); - - DisplayEndStructure( FIXUP_THUNKS ); - } - } - break; - - default: - { - COUNT_T count = size / sizeof(TADDR); - - for (COUNT_T j = 0; j < count; j++) - { - if (dac_cast(pTable)[j] == 0) - continue; - - SIZE_T nNextEntry = j + 1; - while (nNextEntry < count && dac_cast(pTable)[nNextEntry] == 0) - nNextEntry++; - - DisplayStartStructure("ImportEntry", DPtrToPreferredAddr(dac_cast(pTable) + j), - (nNextEntry - j) * sizeof(TADDR), FIXUP_TABLES ); - - if (pDataTable != NULL) - { - DWORD rva = dac_cast(pDataTable)[j]; - WriteElementsFixupTargetAndName(rva); - } - else - { - SIZE_T token = dac_cast(pTable)[j]; - DisplayWriteElementPointer( "TaggedValue", token, FIXUP_TABLES ); - WriteElementsFixupBlob(pImportSection, token); - } - - DisplayWriteElementInt( "index", j, FIXUP_HISTOGRAM); - DisplayWriteElementInt( "ReferenceCount", m_fixupHistogram[iImportSections][j], FIXUP_HISTOGRAM ); - - DisplayEndStructure( FIXUP_TABLES ); - } - } - } - } - DisplayEndCategory( FIXUP_TABLES ); -} - -void NativeImageDumper::FixupThunkToString(PTR_CORCOMPILE_IMPORT_SECTION pImportSection, TADDR addr, SString& buf) -{ - switch (pImportSection->Type) - { - case CORCOMPILE_IMPORT_TYPE_VIRTUAL_METHOD: - { - PTR_CORCOMPILE_VIRTUAL_IMPORT_THUNK pThunk = addr; - buf.AppendPrintf( W("slot %d"), pThunk->slotNum ); - } - break; - - case CORCOMPILE_IMPORT_TYPE_EXTERNAL_METHOD: - case CORCOMPILE_IMPORT_TYPE_STUB_DISPATCH: - { - TADDR pTable(m_decoder.GetDirectoryData(&pImportSection->Section)); - COUNT_T index = (COUNT_T)(addr - pTable) / pImportSection->EntrySize; - TADDR pDataTable(m_decoder.GetRvaData(pImportSection->Signatures)); - TADDR pDataAddr = pDataTable + (index * sizeof(DWORD)); - PTR_DWORD pData = pDataAddr; - FixupBlobToString(*pData, buf); - } - break; - - default: - _ASSERTE(!"Unknown import type"); - } -} - -void NativeImageDumper::WriteElementsFixupBlob(PTR_CORCOMPILE_IMPORT_SECTION pSection, SIZE_T fixup) -{ - if (pSection != NULL && !CORCOMPILE_IS_FIXUP_TAGGED(fixup, pSection)) - { - TempBuffer buf; - if (pSection->Type == CORCOMPILE_IMPORT_TYPE_TYPE_HANDLE) - { - TypeHandleToString(TypeHandle::FromTAddr((TADDR)fixup), buf); - } - else - if (pSection->Type == CORCOMPILE_IMPORT_TYPE_METHOD_HANDLE) - { - MethodDescToString(PTR_MethodDesc((TADDR)fixup), buf); - } - else - { - _ASSERTE(!"Unknown Type"); - IfFailThrow(E_FAIL); - } - m_display->WriteElementStringW( "FixupTargetName", (const WCHAR*)buf ); - return; - } - - RVA rva = CORCOMPILE_UNTAG_TOKEN(fixup); - - WriteElementsFixupTargetAndName(rva); -} - -const NativeImageDumper::EnumMnemonics s_EncodeMethodSigFlags[] = -{ -#define EMS_ENTRY(f) NativeImageDumper::EnumMnemonics(ENCODE_METHOD_SIG_ ## f, W(#f)) - EMS_ENTRY(UnboxingStub), - EMS_ENTRY(InstantiatingStub), - EMS_ENTRY(MethodInstantiation), - EMS_ENTRY(SlotInsteadOfToken), - EMS_ENTRY(MemberRefToken), - EMS_ENTRY(Constrained), - EMS_ENTRY(OwnerType), -#undef EMS_ENTRY -}; - -void NativeImageDumper::FixupBlobToString(RVA rva, SString& buf) -{ - PTR_CCOR_SIGNATURE sig = (TADDR) m_decoder.GetRvaData(rva); - BYTE kind = *sig++; - - CorTokenType tkType = (CorTokenType)0; - - IMetaDataImport2 * pImport = m_import; - - if (kind & ENCODE_MODULE_OVERRIDE) - { - Import *import = OpenImport(DacSigUncompressData(sig)); - kind &= ~ENCODE_MODULE_OVERRIDE; - - Dependency *pDep = import->dependency; - if (pDep == NULL) - { - return; - } - - pImport = pDep->pImport; - - _ASSERTE(pImport != NULL); - - // print assembly/module info - - mdToken realRef = - MapAssemblyRefToManifest(TokenFromRid(import->index, - mdtAssemblyRef), - m_assemblyImport); - AppendToken(realRef, buf, m_manifestImport); - buf.Append( W(" ") ); - } - - // print further info - - mdToken token; - - switch (kind) - { - case ENCODE_MODULE_HANDLE: - // No further info - break; - - case ENCODE_TYPE_HANDLE: - EncodeType: - if (pImport != NULL) - TypeToString(sig, buf, pImport); - else - buf.Append( W(" ") ); - - break; - - case ENCODE_METHOD_HANDLE: - EncodeMethod: - { - //Flags are first - DWORD methodFlags = DacSigUncompressData(sig); - - // If the type portion for this generic method signature - // is from a different module then both the generic type and the - // generic method tokens are interpreted in the context of that module, - // and not the current import. This is returned by TypeToString. - // - IMetaDataImport2 * pMethodImport = pImport; - if (pImport != NULL) - { - if (methodFlags & ENCODE_METHOD_SIG_OwnerType) - { - pMethodImport = TypeToString(sig, buf, pImport); - } - } - else - { - buf.Append( W("") ); - break; - } - - //If we have SlotInsteadOfToken set then this is a slot number (i.e. for an array) - if( methodFlags & ENCODE_METHOD_SIG_SlotInsteadOfToken ) - { - buf.AppendPrintf( W(" method slot %d"), DacSigUncompressData(sig) ); - } - else - { - // decode the methodToken (a rid is encoded) - RID rid = DacSigUncompressData(sig); - - mdMethodDef methodToken = ((methodFlags & ENCODE_METHOD_SIG_MemberRefToken) ? mdtMemberRef : mdtMethodDef) | rid; - - buf.Append( W(" ") ); - - // Get the full signature of method from external module - // Need temporary buffer because method name will be inserted - // in between the signature - - TempBuffer tempName; - - AppendTokenName( methodToken, tempName, pMethodImport ); - - if( methodFlags & ENCODE_METHOD_SIG_MethodInstantiation ) - { - //for each generic arg, there is a type handle. - ULONG numParams = DacSigUncompressData(sig); - - tempName.Append( W("<") ); - for( unsigned i = 0;i < numParams; ++i ) - { - if( i != 0 ) - tempName.Append( W(", ") ); - - // switch back to using pImport to resolve tokens - TypeToString(sig, tempName, pImport); - } - tempName.Append( W(">") ); - } - - PCCOR_SIGNATURE pvSigBlob; - ULONG cbSigBlob; - - if (methodFlags & ENCODE_METHOD_SIG_MemberRefToken) - { - IfFailThrow(pMethodImport->GetMemberRefProps(methodToken, - NULL, - NULL, - 0, - NULL, - &pvSigBlob, - &cbSigBlob)); - } - else - { - IfFailThrow(pMethodImport->GetMethodProps(methodToken, - NULL, - NULL, - 0, - NULL, - NULL, - &pvSigBlob, - &cbSigBlob, - NULL, - NULL)); - } - - CQuickBytes prettySig; - ReleaseHolder pInternal; - IfFailThrow(GetMDInternalInterfaceFromPublic(pMethodImport, IID_IMDInternalImport, - (void**)&pInternal)); - StackScratchBuffer buffer; - const ANSI * ansi = tempName.GetANSI(buffer); - ansi = PrettyPrintSig(pvSigBlob, cbSigBlob, ansi, &prettySig, pInternal, NULL); - tempName.SetANSI( ansi ); - buf.Append(tempName); - } - - buf.Append( W(" flags=(") ); - EnumFlagsToString( methodFlags, s_EncodeMethodSigFlags, _countof(s_EncodeMethodSigFlags), - W(", "), buf ); - buf.Append( W(")") ); - } - break; - - case ENCODE_FIELD_HANDLE: - EncodeField: - { - //Flags are first - DWORD fieldFlags = DacSigUncompressData(sig); - - IMetaDataImport2 * pFieldImport = pImport; - if (pImport != NULL) - { - if (fieldFlags & ENCODE_FIELD_SIG_OwnerType) - { - pFieldImport = TypeToString(sig, buf, pImport); - } - } - else - buf.Append( W("") ); - - if (fieldFlags & ENCODE_FIELD_SIG_IndexInsteadOfToken) - { - buf.AppendPrintf( W(" field index %d"), DacSigUncompressData(sig) ); - } - else - { - // decode the methodToken (a rid is encoded) - RID rid = DacSigUncompressData(sig); - - mdMethodDef fieldToken = ((fieldFlags & ENCODE_FIELD_SIG_MemberRefToken) ? mdtMemberRef : mdtFieldDef) | rid; - - buf.Append( W(" ") ); - - AppendTokenName( fieldToken, buf, pFieldImport ); - } - } - break; - - case ENCODE_STRING_HANDLE: - token = TokenFromRid(DacSigUncompressData(sig), mdtString); - if (pImport != NULL) - AppendToken(token, buf, pImport); - else - buf.AppendPrintf( W(""), token ); - break; - - case ENCODE_VARARGS_SIG: - tkType = mdtFieldDef; - goto DataToTokenCore; - case ENCODE_VARARGS_METHODREF: - tkType = mdtMemberRef; - goto DataToTokenCore; - case ENCODE_VARARGS_METHODDEF: - tkType = mdtMemberRef; - goto DataToTokenCore; -DataToTokenCore: - token = TokenFromRid(DacSigUncompressData(sig), tkType); - if (pImport != NULL) - AppendToken(token, buf, pImport); - else - buf.AppendPrintf( "", token ); - break; - - case ENCODE_METHOD_ENTRY: - buf.Append( W("Entrypoint for ") ); - goto EncodeMethod; - - case ENCODE_METHOD_ENTRY_DEF_TOKEN: - { - buf.Append( W("Entrypoint for ") ); - token = TokenFromRid(DacSigUncompressData(sig), mdtMethodDef); - AppendTokenName(token, buf, pImport); - } - break; - - case ENCODE_METHOD_ENTRY_REF_TOKEN: - { - buf.Append( W("Entrypoint for ref ") ); - token = TokenFromRid(DacSigUncompressData(sig), mdtMemberRef); - AppendTokenName(token, buf, pImport); - } - break; - - case ENCODE_VIRTUAL_ENTRY: - buf.Append( W("Entrypoint for ") ); - goto EncodeMethod; - - case ENCODE_VIRTUAL_ENTRY_DEF_TOKEN: - { - buf.Append( W("Virtual call for ") ); - token = TokenFromRid(DacSigUncompressData(sig), mdtMethodDef); - AppendTokenName(token, buf, pImport); - } - break; - - case ENCODE_VIRTUAL_ENTRY_REF_TOKEN: - { - buf.Append( W("Virtual call for ref ") ); - token = TokenFromRid(DacSigUncompressData(sig), mdtMemberRef); - AppendTokenName(token, buf, pImport); - } - break; - - case ENCODE_VIRTUAL_ENTRY_SLOT: - { - buf.Append( W("Virtual call for ") ); - int slot = DacSigUncompressData(sig); - buf.AppendPrintf( W("slot %d "), slot ); - goto EncodeType; - } - - case ENCODE_MODULE_ID_FOR_STATICS: - buf.Append( W("Module For Statics") ); - // No further info - break; - - case ENCODE_MODULE_ID_FOR_GENERIC_STATICS: - buf.Append( W("Module For Statics for ") ); - goto EncodeType; - - case ENCODE_CLASS_ID_FOR_STATICS: - buf.Append( W("Statics ID for ") ); - goto EncodeType; - - case ENCODE_STATIC_FIELD_ADDRESS: - buf.Append( W("Static field address for ") ); - goto EncodeField; - - case ENCODE_SYNC_LOCK: - buf.Append( W("Synchronization handle for ") ); - break; - - case ENCODE_INDIRECT_PINVOKE_TARGET: - buf.Append( W("Indirect P/Invoke target for ") ); - break; - - case ENCODE_PINVOKE_TARGET: - buf.Append( W("P/Invoke target for ") ); - break; - - case ENCODE_PROFILING_HANDLE: - buf.Append( W("Profiling handle for ") ); - goto EncodeMethod; - - case ENCODE_ACTIVE_DEPENDENCY: - { - buf.Append( W("Active dependency for ") ); - - int targetModuleIndex = DacSigUncompressData(sig); - Import *targetImport = OpenImport(targetModuleIndex); - - mdToken realRef = - MapAssemblyRefToManifest(TokenFromRid(targetImport->index, - mdtAssemblyRef), - m_assemblyImport); - AppendToken(realRef, buf, m_manifestImport); - buf.Append( W(" ") ); - } - break; - - default: - buf.Append( W("Unknown fixup kind") ); - _ASSERTE(!"Unknown fixup kind"); - } -} - -void NativeImageDumper::WriteElementsFixupTargetAndName(RVA rva) -{ - if( rva == NULL ) - { - /* XXX Tue 04/11/2006 - * This should only happen for static fields. If the field is - * unaligned, we need an extra cell for an indirection. - */ - m_display->WriteElementPointer( "FixupTargetValue", NULL ); - m_display->WriteElementStringW( "FixupTargetName", W("NULL") ); - return; - } - - m_display->WriteElementPointer( "FixupTargetValue", RvaToDisplay(rva) ); - - TempBuffer buf; - FixupBlobToString(rva, buf); - - m_display->WriteElementStringW( "FixupTargetName", (const WCHAR*)buf ); -} - -NativeImageDumper::Dependency * NativeImageDumper::GetDependency(mdAssemblyRef token, IMetaDataAssemblyImport *pImport) -{ - if (RidFromToken(token) == 0) - return OpenDependency(0); - - if (pImport == NULL) - pImport = m_assemblyImport; - - // Need to map from IL token to manifest token - mdAssemblyRef manifestToken = MapAssemblyRefToManifest(token, pImport); - - if( manifestToken == mdAssemblyNil ) - { - //this is "self" - return OpenDependency(0); - } - - COUNT_T count; - PTR_CORCOMPILE_DEPENDENCY deps(TO_TADDR(m_decoder.GetNativeDependencies(&count))); - - for (COUNT_T i = 0; i < count; i++) - { - if (deps[i].dwAssemblyRef == manifestToken) - return OpenDependency(i+1); - } - - TempBuffer buf; - AppendTokenName(manifestToken, buf, m_manifestImport); - m_display->ErrorPrintF("Error: unlisted assembly dependency %S\n", (const WCHAR*)buf); - - return NULL; -} - -mdAssemblyRef NativeImageDumper::MapAssemblyRefToManifest(mdAssemblyRef token, IMetaDataAssemblyImport *pAssemblyImport) -{ - // Reference may be to self - if (TypeFromToken(token) == mdtAssembly) - return token; - - // Additional tokens not originally present overflow to manifest automatically during emit - /* REVISIT_TODO Tue 01/31/2006 - * Factor this code out so that it is shared with the module index code in the CLR that looks - * exactly thes same - */ - //count the assembly refs. - ULONG count = 0; - - HCORENUM iter = NULL; - for (;;) - { - ULONG tokens = 0; - mdAssemblyRef tmp; - IfFailThrow(pAssemblyImport->EnumAssemblyRefs(&iter, &tmp, 1, - &tokens)); - if (tokens == 0) - break; - count ++; - } - pAssemblyImport->CloseEnum(iter); - - if( RidFromToken(token) > count ) - { - //out of range import. This means that it has spilled over. Subtract - //off the max number of assembly refs and return it as a manifest - //token. - return token - (count + 1); - } - - ULONG cchName; - ASSEMBLYMETADATA metadata; - - ZeroMemory(&metadata, sizeof(metadata)); - - IfFailThrow(pAssemblyImport->GetAssemblyRefProps(token, NULL, NULL, - NULL, 0, &cchName, - &metadata, NULL, NULL, - NULL)); - - LPWSTR szAssemblyName = NULL; - - if (cchName > 0) - szAssemblyName = (LPWSTR) _alloca(cchName * sizeof(WCHAR)); - - if (metadata.cbLocale > 0) - metadata.szLocale = (LPWSTR) _alloca(metadata.cbLocale * sizeof(WCHAR)); - if (metadata.ulProcessor > 0) - metadata.rProcessor = (DWORD*) _alloca(metadata.ulProcessor * sizeof(DWORD)); - if (metadata.ulOS > 0) - metadata.rOS = (OSINFO*) _alloca(metadata.ulOS * sizeof(OSINFO)); - - const void *pbPublicKey; - ULONG cbPublicKey; - DWORD flags; - const void *pbHashValue; - ULONG cbHashValue; - - - IfFailThrow(pAssemblyImport->GetAssemblyRefProps(token, &pbPublicKey, &cbPublicKey, - szAssemblyName, cchName, NULL, - &metadata, &pbHashValue, &cbHashValue, - &flags)); - - //Notice that we're searching for the provided metadata for the dependency info and then looking in the - //image we're dumping for the dependency. - // - //Also, sometimes we find "self" in these searches. If so, return mdAssemblyDefNil as a canary value. - - if( !wcscmp(szAssemblyName, m_name) ) - { - //we need "self". - return mdAssemblyNil; - } - - mdAssemblyRef ret = mdAssemblyRefNil; - /*HCORENUM*/ iter = NULL; - for(;;) - { - //Walk through all the assemblyRefs and search for a match. I would use DefineAssemblyRef here, but - //if I do it will create an assemblyRef is one is not found. Then I fail in a bad place. This - //way I can fail in a less bad place. - mdAssemblyRef currentRef; - //ULONG count; - IfFailThrow(m_manifestAssemblyImport->EnumAssemblyRefs(&iter, ¤tRef, 1, &count)); - if( 0 == count ) - break; - - //get the information about the assembly ref and compare. - const void * publicKeyToken; - ULONG pktSize = 0; - WCHAR name[128]; - /*ULONG*/ cchName = _countof(name); - ASSEMBLYMETADATA curMD = {0}; - - IfFailThrow(m_manifestAssemblyImport->GetAssemblyRefProps(currentRef, &publicKeyToken, &pktSize, name, - cchName, &cchName, &curMD, - NULL /*ppbHashValue*/, NULL/*pcbHashValue*/, - NULL/*pdwAssemblyRefFlags*/)); - if( !wcscmp(name, szAssemblyName) ) - { - if( cbPublicKey == pktSize && !memcmp(pbPublicKey, publicKeyToken, pktSize) - && curMD.usMajorVersion == metadata.usMajorVersion - && curMD.usMinorVersion == metadata.usMinorVersion) - { - ret = currentRef; - break; - } - else if (wcscmp(szAssemblyName, CoreLibName_W) == 0) - { - // CoreLib is special - version number and public key token are ignored. - ret = currentRef; - break; - } - else if (metadata.usMajorVersion == 255 && - metadata.usMinorVersion == 255 && - metadata.usBuildNumber == 255 && - metadata.usRevisionNumber == 255) - { - // WinMDs encode all assemblyrefs with version 255.255.255.255 including CLR assembly dependencies (corelib, System). - ret = currentRef; - } - else - { - //there was an assembly with the correct name, but with the wrong version number. Let the - //user know. - m_display->ErrorPrintF("MapAssemblyRefToManifest: found %S with version %d.%d in manifest. Wanted version %d.%d.\n", szAssemblyName, curMD.usMajorVersion, curMD.usMinorVersion, metadata.usMajorVersion, metadata.usMinorVersion); - // TritonTODO: why? - ret = currentRef; - break; - } - - } - } - pAssemblyImport->CloseEnum(iter); - if( ret == mdAssemblyRefNil ) - { - TempBuffer pkt; - appendByteArray(pkt, (const BYTE*)pbPublicKey, cbPublicKey); - m_display->ErrorPrintF("MapAssemblyRefToManifest could not find token for %S, Version=%d.%d, PublicKeyToken=%S\n", szAssemblyName, metadata.usMajorVersion, metadata.usMinorVersion, (const WCHAR *)pkt); - _ASSERTE(!"MapAssemblyRefToManifest failed to find a match"); - } - - return ret; -} - -NativeImageDumper::Import * NativeImageDumper::OpenImport(int i) -{ - if (m_imports == NULL) - { - COUNT_T count; - m_decoder.GetNativeDependencies(&count); - m_numImports = count; - m_imports = new Import [count]; - ZeroMemory(m_imports, count * sizeof(m_imports[0])); - } - - if (m_imports[i].index == 0) - { - //GetNativeImportFromIndex returns a host pointer. - m_imports[i].index = i; - - /* - mdToken tok = TokenFromRid(entry->index, mdtAssemblyRef); - Dependency * dependency = GetDependency( MapAssemblyRefToManifest(tok, - */ - Dependency *dependency = GetDependency(TokenFromRid(i, mdtAssemblyRef)); - m_imports[i].dependency = dependency; - _ASSERTE(dependency); //Why can this be null? - - } - - return &m_imports[i]; -} - - -const NativeImageDumper::Dependency *NativeImageDumper::GetDependencyForFixup(RVA rva) -{ - PTR_CCOR_SIGNATURE sig = (TADDR) m_decoder.GetRvaData(rva); - if (*sig++ & ENCODE_MODULE_OVERRIDE) - { - unsigned idx = DacSigUncompressData(sig); - - _ASSERTE(idx >= 0 && idx < m_numImports); - return OpenImport(idx)->dependency; - } - - return &m_dependencies[0]; -} - - -void NativeImageDumper::AppendToken(mdToken token, SString& buf) -{ - return NativeImageDumper::AppendToken(token, buf, NULL); -} -void NativeImageDumper::AppendToken(mdToken token, SString& buf, - IMetaDataImport2 *pImport) -{ - IF_OPT(DISABLE_NAMES) - { - buf.Append( W("Disabled") ); - return; - } - switch (TypeFromToken(token)) - { - case mdtTypeDef: - buf.Append( W("TypeDef ") ); - break; - - case mdtTypeRef: - buf.Append( W("TypeRef ") ); - break; - - case mdtTypeSpec: - buf.Append( W("TypeRef ") ); - break; - - case mdtFieldDef: - buf.Append( W("FieldDef ")); - break; - - case mdtMethodDef: - buf.Append( W("MethodDef ") ); - break; - - case mdtMemberRef: - buf.Append( W("MemberRef ") ); - break; - - case mdtAssemblyRef: - buf.Append( W("AssemblyRef ") ); - break; - - case mdtFile: - buf.Append( W("File ") ); - break; - - case mdtString: - buf.Append( W("String ") ); - break; - - case mdtSignature: - buf.Append( W("Signature ") ); - break; - - } - if( RidFromToken(token) == mdTokenNil ) - buf.Append( W("Nil") ); - else - AppendTokenName(token, buf, pImport); -} - -NativeImageDumper::Dependency *NativeImageDumper::OpenDependency(int index) -{ - CORCOMPILE_VERSION_INFO *info = m_decoder.GetNativeVersionInfo(); - - if (m_dependencies == NULL) - { - COUNT_T count; - m_decoder.GetNativeDependencies(&count); - - // Add one for self - count++; - - m_numDependencies = count; - m_dependencies = new Dependency [count]; - ZeroMemory(m_dependencies, count * sizeof (Dependency)); - } - - if (m_dependencies[index].entry == NULL) - { - CORCOMPILE_DEPENDENCY *entry; - - if (index == 0) - { - // Make dummy entry for self - entry = &m_self; - m_self.dwAssemblyRef = TokenFromRid(1, mdtAssembly); - m_self.dwAssemblyDef = TokenFromRid(1, mdtAssembly); - m_self.signAssemblyDef = info->sourceAssembly; - m_manifestImport->GetScopeProps(NULL, NULL, 0, &m_self.signNativeImage); - m_dependencies[index].pLoadedAddress = dac_cast(m_baseAddress); - m_dependencies[index].pPreferredBase = - TO_TADDR(m_decoder.GetNativePreferredBase()); - m_dependencies[index].size = m_imageSize; - m_dependencies[index].pImport = m_import; - m_dependencies[index].pMetadataStartTarget = - m_MetadataStartTarget; - m_dependencies[index].pMetadataStartHost = - m_MetadataStartHost; - m_dependencies[index].MetadataSize = m_MetadataSize; - m_dependencies[index].pModule = - (TADDR)m_decoder.GetPersistedModuleImage(); - m_dependencies[index].fIsHardbound = TRUE; - _ASSERTE( (m_dependencies[index].pModule - > m_dependencies[index].pLoadedAddress) - && (m_dependencies[index].pModule - < m_dependencies[index].pLoadedAddress - + m_dependencies[index].size) ); - // patch the Module vtable so that the DAC is able to instantiate it - TADDR vtbl = DacGetTargetVtForHostVt(Module::VPtrHostVTable(), true); - DacWriteAll( m_dependencies[index].pModule.GetAddr(), &vtbl, sizeof(vtbl), false ); - } - else - { - COUNT_T numDeps; - PTR_CORCOMPILE_DEPENDENCY deps(TO_TADDR(m_decoder.GetNativeDependencies(&numDeps))); - - entry = deps + (index-1); - - //load the dependency, get the pointer, and use the PEDecoder - //to open the metadata. - - TempBuffer buf; - TADDR loadedBase; - /* REVISIT_TODO Tue 11/22/2005 - * Is this the right name? - */ - Dependency& dependency = m_dependencies[index]; - AppendTokenName(entry->dwAssemblyRef, buf, m_manifestImport, true); - bool isHardBound = !!(entry->signNativeImage != INVALID_NGEN_SIGNATURE); - SString corelibStr(SString::Literal, CoreLibName_W); - bool isCoreLib = (0 == buf.Compare( corelibStr )); - dependency.fIsHardbound = isHardBound; - wcscpy_s(dependency.name, _countof(dependency.name), - (const WCHAR*)buf); - if( isHardBound ) - { - IfFailThrow(m_librarySupport->LoadHardboundDependency((const WCHAR*)buf, - entry->signNativeImage, &loadedBase)); - - dependency.pLoadedAddress = loadedBase; - } - else - { - ASSEMBLYMETADATA asmData = {0}; - const void * hashValue; - ULONG hashLength, size, flags; - IfFailThrow(m_manifestAssemblyImport->GetAssemblyRefProps(entry->dwAssemblyRef, &hashValue, &hashLength, bigBuffer, bigBufferSize, &size, &asmData, NULL, NULL, &flags)); - - - HRESULT hr = - m_librarySupport->LoadSoftboundDependency((const WCHAR*)buf, - (const BYTE*)&asmData, (const BYTE*)hashValue, hashLength, - &loadedBase); - if( FAILED(hr) ) - { - TempBuffer pkt; - if( hashLength > 0 ) - { - appendByteArray(pkt, (BYTE*)hashValue, hashLength); - } - else - { - pkt.Set( W("") ); - } - //try to continue without loading this softbound - //dependency. - m_display->ErrorPrintF( "WARNING Failed to load softbound dependency:\n\t%S,Version=%d.%d.0.0,PublicKeyToken=%S.\n\tAttempting to continue. May crash later in due to missing metadata\n", - (const WCHAR *)buf, asmData.usMajorVersion, - asmData.usMinorVersion, (const WCHAR *)pkt ); - m_dependencies[index].entry = entry; - return &m_dependencies[index]; - - } - //save this off to the side so OpenImport can find the metadata. - m_dependencies[index].pLoadedAddress = loadedBase; - } - /* REVISIT_TODO Wed 11/23/2005 - * Refactor this with OpenMetadata from above. - */ - //now load the metadata from the new image. - PEDecoder decoder(dac_cast(loadedBase)); - if( isHardBound ) - { - dependency.pPreferredBase = - TO_TADDR(decoder.GetNativePreferredBase()); - dependency.size = decoder.Has32BitNTHeaders() ? - decoder.GetNTHeaders32()->OptionalHeader.SizeOfImage : - decoder.GetNTHeaders64()->OptionalHeader.SizeOfImage; - } - ReleaseHolder pDispenser; - IfFailThrow(MetaDataGetDispenser(CLSID_CorMetaDataDispenser, - IID_IMetaDataDispenserEx, - (void **) &pDispenser)); - - VARIANT opt; - IfFailThrow(pDispenser->GetOption(MetaDataCheckDuplicatesFor, - &opt)); - V_UI4(&opt) |= MDDupAssemblyRef | MDDupFile; - IfFailThrow(pDispenser->SetOption(MetaDataCheckDuplicatesFor, - &opt)); - if( decoder.HasNativeHeader() ) - { - dependency.pModule = - TO_TADDR(decoder.GetPersistedModuleImage()); - _ASSERTE( (PTR_TO_TADDR(dependency.pModule) > loadedBase) - && (PTR_TO_TADDR(dependency.pModule) < loadedBase + - decoder.GetSize()) ); - // patch the Module vtable so that the DAC is able to instantiate it - TADDR vtbl = DacGetTargetVtForHostVt(Module::VPtrHostVTable(), true); - DacWriteAll( m_dependencies[index].pModule.GetAddr(), &vtbl, sizeof(vtbl), false ); - } - else - { - dependency.pModule = NULL; - } - - const void * data; - COUNT_T size; - - DACCOP_IGNORE(CastBetweenAddressSpaces,"nidump is in-proc and doesn't maintain a clean separation of address spaces (target and host are the same."); - data = reinterpret_cast(dac_cast(decoder.GetMetadata(&size))); - - dependency.pMetadataStartTarget = TO_TADDR(data); - dependency.MetadataSize = size; - data = PTR_READ(TO_TADDR(data), size); - dependency.pMetadataStartHost = TO_TADDR(data); - IfFailThrow(pDispenser->OpenScopeOnMemory(data, size, - ofRead, - IID_IMetaDataImport2, - (IUnknown **) &dependency.pImport)); - dependency.fIsCoreLib = isCoreLib; - } - - m_dependencies[index].entry = entry; - - } - - return &m_dependencies[index]; -} - -IMetaDataImport2* NativeImageDumper::TypeToString(PTR_CCOR_SIGNATURE &sig, SString& buf) -{ - return TypeToString(sig, buf, NULL); -} -#if 0 -void NativeImageDumper::TypeToString(PTR_CCOR_SIGNATURE &sig, - IMetaDataImport2 *pImport) -{ - CQuickBytes tmp; - - if (pImport == NULL) - pImport = m_import; - - LPCWSTR type = PrettyPrintSig( sig, INT_MAX, W(""), &tmp, pImport ); - _ASSERTE(type); - m_display->ErrorPrintF( "%S", type ); -} -#endif - -IMetaDataImport2 * NativeImageDumper::TypeToString(PTR_CCOR_SIGNATURE &sig, - SString& buf, - IMetaDataImport2 *pImport, - IMetaDataImport2 *pOrigImport /* =NULL */) - -{ - IF_OPT(DISABLE_NAMES) - { - buf.Append( W("Disabled") ); - return pImport; - } - - if (pImport == NULL) - pImport = m_import; - if (pOrigImport == NULL) - pOrigImport = pImport; - - IMetaDataImport2 * pRet = pImport; -#define TYPEINFO(enumName, classSpace, className, size, gcType, isArray, isPrim, isFloat, isModifier, isGenVar) \ - className, - static const char *elementNames[] = { -#include "cortypeinfo.h" - }; -#undef TYPEINFO - - CorElementType type = DacSigUncompressElementType(sig); - - if (type == (CorElementType) ELEMENT_TYPE_MODULE_ZAPSIG) - { - unsigned idx = DacSigUncompressData(sig); - buf.AppendPrintf( W("module %d "), idx ); - //switch module - const Import * import = OpenImport(idx); - pImport = import->dependency->pImport; - - //if there was a module switch, return the import for the new module. - //This is useful for singatures, where the module index applies to - //subsequent tokens. - pRet = pImport; - - type = DacSigUncompressElementType(sig); - } - if (type >= 0 && (size_t)type < _countof(elementNames) - && elementNames[type] != NULL) - { - buf.AppendPrintf( "%s", elementNames[type] ); - } - else switch ((DWORD)type) - { - case ELEMENT_TYPE_CANON_ZAPSIG: - buf.Append( W("System.__Canon") ); - break; - - case ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG: - { - buf.Append( W("native ") ); - TypeToString(sig, buf, pImport); - } - break; - - case ELEMENT_TYPE_VALUETYPE: - case ELEMENT_TYPE_CLASS: - { - if (type == ELEMENT_TYPE_VALUETYPE) - buf.Append( W("struct ") ); - - mdToken token = DacSigUncompressToken(sig); - AppendTokenName(token, buf, pImport); - } - break; - - case ELEMENT_TYPE_SZARRAY: - TypeToString(sig, buf, pImport); - buf.Append( W("[]") ); - break; - - case ELEMENT_TYPE_ARRAY: - { - TypeToString(sig, buf, pImport, pOrigImport); - unsigned rank = DacSigUncompressData(sig); - if (rank == 0) - buf.Append( W("[??]") ); - else - { - size_t cbLowerBounds; - if (!ClrSafeInt::multiply(rank, 2*sizeof(int), cbLowerBounds/* passed by ref */)) - ThrowHR(COR_E_OVERFLOW); - int* lowerBounds = (int*) _alloca(cbLowerBounds); - int* sizes = &lowerBounds[rank]; - memset(lowerBounds, 0, sizeof(int)*2*rank); - - unsigned numSizes = DacSigUncompressData(sig); - _ASSERTE(numSizes <= rank); - unsigned int i; - for(i =0; i < numSizes; i++) - sizes[i] = DacSigUncompressData(sig); - - unsigned numLowBounds = DacSigUncompressData(sig); - _ASSERTE(numLowBounds <= rank); - for(i = 0; i < numLowBounds; i++) - lowerBounds[i] = DacSigUncompressData(sig); - - buf.Append(W("[")); - for(i = 0; i < rank; i++) - { - if (sizes[i] != 0 && lowerBounds[i] != 0) - { - buf.AppendPrintf( W("%d ..."), lowerBounds[i] ); - if (sizes[i] != 0) - buf.AppendPrintf( W("%d"), - lowerBounds[i] + sizes[i] - + 1 ); - } - if (i < rank-1) - buf.Append( W(",") ); - } - buf.Append( W("]") ); - } - } - break; - - case ELEMENT_TYPE_MVAR: - buf.Append( W("!") ); - // fall through - case ELEMENT_TYPE_VAR: - buf.AppendPrintf( W("!%d"), DacSigUncompressData(sig)); - break; - - case ELEMENT_TYPE_VAR_ZAPSIG: - { - buf.Append( W("var ") ); - - mdToken token = TokenFromRid(DacSigUncompressData(sig), mdtGenericParam); - AppendTokenName(token, buf, pImport); - } - break; - - case ELEMENT_TYPE_GENERICINST: - { - TypeToString(sig, buf, pImport, pOrigImport); - unsigned ntypars = DacSigUncompressData(sig); - buf.Append( W("<") ); - for (unsigned i = 0; i < ntypars; i++) - { - if (i > 0) - buf.Append( W(",") ); - // switch pImport back to our original Metadata importer - TypeToString(sig, buf, pOrigImport, pOrigImport); - } - buf.Append( W(">") ); - } - break; - - case ELEMENT_TYPE_FNPTR: - buf.Append( W("(fnptr)") ); - break; - - // Modifiers or depedant types - case ELEMENT_TYPE_PINNED: - TypeToString(sig, buf, pImport, pOrigImport); - buf.Append( W(" pinned") ); - break; - - case ELEMENT_TYPE_PTR: - TypeToString(sig, buf, pImport, pOrigImport); - buf.Append( W("*") ); - break; - - case ELEMENT_TYPE_BYREF: - TypeToString(sig, buf, pImport, pOrigImport); - buf.Append( W("&") ); - break; - - case ELEMENT_TYPE_SENTINEL: - case ELEMENT_TYPE_END: - default: - _ASSERTE(!"Unknown Type"); - IfFailThrow(E_FAIL); - break; - } - return pRet; -} - -void NativeImageDumper::DumpMethods(PTR_Module module) -{ - COUNT_T hotCodeSize; - PCODE hotCode = m_decoder.GetNativeHotCode(&hotCodeSize); - - - COUNT_T codeSize; - PCODE code = m_decoder.GetNativeCode(&codeSize); - - COUNT_T coldCodeSize; - PCODE coldCode = m_decoder.GetNativeColdCode(&coldCodeSize); - - DisplayStartCategory( "Code", METHODS ); - DisplayWriteElementAddress( "HotCode", DataPtrToDisplay(hotCode), - hotCodeSize, METHODS ); - - DisplayWriteElementAddress( "UnprofiledCode", - DataPtrToDisplay(code), - codeSize, METHODS ); - DisplayWriteElementAddress( "ColdCode", - DataPtrToDisplay(coldCode), - coldCodeSize, METHODS ); - - PTR_CORCOMPILE_CODE_MANAGER_ENTRY codeEntry(m_decoder.GetNativeCodeManagerTable()); - - DisplayWriteElementAddress( "ROData", - RvaToDisplay(codeEntry->ROData.VirtualAddress), - codeEntry->ROData.Size, METHODS ); - - DisplayWriteElementAddress( "HotCommonCode", - DataPtrToDisplay(hotCode), - codeEntry->HotIBCMethodOffset, METHODS ); - - DisplayWriteElementAddress( "HotIBCMethodCode", - DataPtrToDisplay(hotCode - + codeEntry->HotIBCMethodOffset), - codeEntry->HotGenericsMethodOffset - - codeEntry->HotIBCMethodOffset, - METHODS ); - - DisplayWriteElementAddress( "HotGenericsMethodCode", - DataPtrToDisplay(hotCode - + codeEntry->HotGenericsMethodOffset), - hotCodeSize - codeEntry->HotGenericsMethodOffset, - METHODS ); - - DisplayWriteElementAddress( "ColdIBCMethodCode", - DataPtrToDisplay(coldCode), - codeEntry->ColdUntrainedMethodOffset, - METHODS ); - - MethodIterator mi(module, &m_decoder); - - DisplayStartArray( "Methods", NULL, METHODS ); - - while( mi.Next() ) - { - DumpCompleteMethod( module, mi ); - } - - DisplayEndArray( "Total Methods", METHODS ); //Methods - - /* REVISIT_TODO Wed 12/14/2005 - * I have this coverage read in here because there is some other data between the - * methods in debug builds. For now just whack the whole text section. Go - * back later and check out that I really got everything. - */ - CoverageRead( hotCode, hotCodeSize ); - CoverageRead( coldCode, coldCodeSize ); -#ifdef USE_CORCOMPILE_HEADER - CoverageRead( hotCodeTable, hotCodeTableSize ); - CoverageRead( coldCodeTable, coldCodeTableSize ); -#endif - - DisplayEndCategory( METHODS ); //Code - - //m_display->StartCategory( "Methods" ); -} - -static SString g_holdStringOutData; - -static void stringOut( const char* fmt, ... ) -{ - va_list args; - va_start(args, fmt); - g_holdStringOutData.AppendVPrintf(fmt, args); - va_end(args); -} - -static void nullStringOut( const char * fmt, ... ) { } - -const NativeImageDumper::EnumMnemonics s_CorExceptionFlags[] = -{ -#define CEF_ENTRY(f,v) NativeImageDumper::EnumMnemonics(f, v) - CEF_ENTRY(COR_ILEXCEPTION_CLAUSE_NONE, W("none")), - CEF_ENTRY(COR_ILEXCEPTION_CLAUSE_FILTER, W("filter")), - CEF_ENTRY(COR_ILEXCEPTION_CLAUSE_FINALLY, W("finally")), - CEF_ENTRY(COR_ILEXCEPTION_CLAUSE_FAULT, W("fault")), - CEF_ENTRY(COR_ILEXCEPTION_CLAUSE_DUPLICATED, W("duplicated")), -#undef CEF_ENTRY -}; - -void NativeImageDumper::DumpCompleteMethod(PTR_Module module, MethodIterator& mi) -{ - PTR_MethodDesc md = mi.GetMethodDesc(); - -#ifdef FEATURE_EH_FUNCLETS - PTR_RUNTIME_FUNCTION pRuntimeFunction = mi.GetRuntimeFunction(); -#endif - - //Read the GCInfo to get the total method size. - unsigned methodSize = 0; - unsigned gcInfoSize = UINT_MAX; - - //parse GCInfo for size information. - GCInfoToken gcInfoToken = mi.GetGCInfoToken(); - PTR_CBYTE gcInfo = dac_cast(gcInfoToken.Info); - - void (* stringOutFn)(const char *, ...); - IF_OPT(GC_INFO) - { - stringOutFn = stringOut; - } - else - { - stringOutFn = nullStringOut; - } - if (gcInfo != NULL) - { - PTR_CBYTE curGCInfoPtr = gcInfo; - g_holdStringOutData.Clear(); - GCDump gcDump(gcInfoToken.Version); - gcDump.gcPrintf = stringOutFn; -#if !defined(TARGET_X86) && defined(USE_GC_INFO_DECODER) - GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_CODE_LENGTH); - methodSize = gcInfoDecoder.GetCodeLength(); -#endif - - //dump the data to a string first so we can get the gcinfo size. -#ifdef TARGET_X86 - InfoHdr hdr; - stringOutFn( "method info Block:\n" ); - curGCInfoPtr += gcDump.DumpInfoHdr(curGCInfoPtr, &hdr, &methodSize, 0); - stringOutFn( "\n" ); -#endif - - IF_OPT(METHODS) - { -#ifdef TARGET_X86 - stringOutFn( "PointerTable:\n" ); - curGCInfoPtr += gcDump.DumpGCTable( curGCInfoPtr, - hdr, - methodSize, 0); - gcInfoSize = curGCInfoPtr - gcInfo; -#elif defined(USE_GC_INFO_DECODER) - stringOutFn( "PointerTable:\n" ); - curGCInfoPtr += gcDump.DumpGCTable( curGCInfoPtr, - methodSize, 0); - gcInfoSize = (unsigned)(curGCInfoPtr - gcInfo); -#endif - } - - //data is output below. - } - - TADDR hotCodePtr = mi.GetMethodStartAddress(); - TADDR coldCodePtr = mi.GetMethodColdStartAddress(); - - size_t hotCodeSize = methodSize; - size_t coldCodeSize = 0; - - if (coldCodePtr != NULL) - { - hotCodeSize = mi.GetHotCodeSize(); - coldCodeSize = methodSize - hotCodeSize; - } - - _ASSERTE(!CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(md))); - const Dependency* mdDep = GetDependencyFromMD(md); - TempBuffer buffer; - _ASSERTE(mdDep->pImport); - MethodDescToString(md, buffer); - - DisplayStartElement( "Method", METHODS ); - DisplayWriteElementStringW( "Name", (const WCHAR *)buffer, METHODS ); - - /* REVISIT_TODO Mon 10/24/2005 - * Do I have to annotate this? - */ - DisplayWriteElementPointer("m_methodDesc", - DPtrToPreferredAddr(md), - METHODS); - - DisplayStartStructure( "m_gcInfo", - DPtrToPreferredAddr(gcInfo), - gcInfoSize, - METHODS ); - - DisplayStartTextElement( "Contents", GC_INFO ); - DisplayWriteXmlTextBlock( ("%S", (const WCHAR *)g_holdStringOutData), GC_INFO ); - DisplayEndTextElement( GC_INFO ); //Contents - - DisplayEndStructure( METHODS ); //GCInfo - - PTR_CORCOMPILE_EXCEPTION_LOOKUP_TABLE pExceptionInfoTable (PTR_TO_TADDR(module->GetNGenLayoutInfo()->m_ExceptionInfoLookupTable.StartAddress())); - if (pExceptionInfoTable) - { - COUNT_T numLookupEntries = (COUNT_T) (module->GetNGenLayoutInfo()->m_ExceptionInfoLookupTable.Size() / sizeof(CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY)); - DWORD methodStartRVA = m_decoder.GetDataRva(TO_TADDR(hotCodePtr)); - - COUNT_T ehInfoSize = 0; - DWORD exceptionInfoRVA = NativeExceptionInfoLookupTable::LookupExceptionInfoRVAForMethod(pExceptionInfoTable, - numLookupEntries, - methodStartRVA, - &ehInfoSize); - - if( exceptionInfoRVA != 0 ) - { - PTR_CORCOMPILE_EXCEPTION_CLAUSE pExceptionInfoArray = dac_cast(PTR_TO_TADDR(m_decoder.GetBase()) + exceptionInfoRVA); - COUNT_T ehCount = ehInfoSize / sizeof(CORCOMPILE_EXCEPTION_CLAUSE); - _ASSERTE(ehCount > 0); - DisplayStartArray("EHClauses", NULL, METHODS ); - for( unsigned i = 0; i < ehCount; ++i ) - { - PTR_CORCOMPILE_EXCEPTION_CLAUSE host = pExceptionInfoArray + i; - - DisplayStartStructure( "Clause", DPtrToPreferredAddr(host), sizeof(PTR_CORCOMPILE_EXCEPTION_CLAUSE), METHODS); - DisplayWriteFieldEnumerated( Flags, host->Flags, - EE_ILEXCEPTION_CLAUSE, - s_CorExceptionFlags, W(", "), - METHODS ); - DisplayWriteFieldUInt( TryStartPC, host->TryStartPC, - EE_ILEXCEPTION_CLAUSE, METHODS ); - DisplayWriteFieldUInt( TryEndPC, host->TryEndPC, - EE_ILEXCEPTION_CLAUSE, METHODS ); - DisplayWriteFieldUInt( HandlerStartPC, - host->HandlerStartPC, - EE_ILEXCEPTION_CLAUSE, METHODS ); - DisplayWriteFieldUInt( HandlerEndPC, - host->HandlerEndPC, - EE_ILEXCEPTION_CLAUSE, METHODS ); - if( host->Flags & COR_ILEXCEPTION_CLAUSE_FILTER ) - { - DisplayWriteFieldUInt( FilterOffset, host->FilterOffset, - EE_ILEXCEPTION_CLAUSE, METHODS ); - } - else if( !(host->Flags & (COR_ILEXCEPTION_CLAUSE_FAULT | COR_ILEXCEPTION_CLAUSE_FINALLY)) ) - { - WriteFieldMDTokenImport( ClassToken, host->ClassToken, - EE_ILEXCEPTION_CLAUSE, METHODS, - mdDep->pImport ); - } - DisplayEndStructure( METHODS ); //Clause - } - DisplayEndArray("Total EHClauses", METHODS ); // Clauses - } - } - - TADDR fixupList = md->GetFixupList(); - if (fixupList != NULL) - { - DisplayStartArray( "Fixups", NULL, METHODS ); - DumpMethodFixups(module, fixupList); - DisplayEndArray(NULL, METHODS); //Fixups - } - - DisplayStartStructure( "Code", DataPtrToDisplay(hotCodePtr), hotCodeSize, - METHODS ); - - IF_OPT(DISASSEMBLE_CODE) - { - // Disassemble hot code. Read the code into the host process. - /* REVISIT_TODO Mon 10/24/2005 - * Is this align up right? - */ - BYTE * codeStartHost = - reinterpret_cast(PTR_READ(hotCodePtr, - (ULONG32)ALIGN_UP(hotCodeSize, - CODE_SIZE_ALIGN))); - DisassembleMethod( codeStartHost, hotCodeSize ); - } - else - { - CoverageRead(hotCodePtr, - (ULONG32)ALIGN_UP(hotCodeSize, CODE_SIZE_ALIGN)); - } - - DisplayEndStructure(METHODS); //HotCode - - if( coldCodePtr != NULL ) - { - DisplayStartStructure( "ColdCode", DataPtrToDisplay(coldCodePtr), - coldCodeSize, METHODS ); - IF_OPT(DISASSEMBLE_CODE) - { - // Disassemble cold code. Read the code into the host process. - BYTE * codeStartHost = - reinterpret_cast(PTR_READ(coldCodePtr, - (ULONG32)ALIGN_UP(coldCodeSize, - CODE_SIZE_ALIGN))); - DisassembleMethod( codeStartHost, coldCodeSize ); - } - else - { - CoverageRead(coldCodePtr, - (ULONG32)ALIGN_UP(coldCodeSize, CODE_SIZE_ALIGN)); - - } - DisplayEndStructure( METHODS ); //ColdCode - } - DisplayEndElement( METHODS ); //Method -} -#undef IDC_SWITCH - - - -void NativeImageDumper::DisassembleMethod(BYTE *code, SIZE_T size) -{ - _ASSERTE(CHECK_OPT(DISASSEMBLE_CODE)); - - m_display->StartTextElement( "NativeCode" ); - -#ifdef FEATURE_MSDIS - - BYTE *codeStart = code; - - /* XXX Wed 8/22/2007 - * The way I compute code size includes the switch tables at the end of the hot and/or cold section. - * When the disassembler gets there, it has a tendency to crash as it runs off the end of mapped - * memory. In order to properly compute this I need to look at the UnwindData (which is a - * kernel32!RUNTIME_FUNCTION structure that gives the address range for the code. However, I also need - * to chase through the list of funclets to make sure I disassemble everything. Instead of doing that, - * I'll just trap the AV. - */ - EX_TRY - { - while (code < (codeStart + size)) - { - const size_t count = m_dis->CbDisassemble(0, code, size); - - if (count == 0) - { - m_display->WriteXmlText( "%04x\tUnknown instruction (%02x)\n", code-codeStart, *code); - code++; - continue; - } - - /* XXX Fri 09/16/2005 - * PTR_HOST_TO_TADDR doesn't work on interior pointers. - */ - m_currentAddress = m_decoder.GetDataRva(PTR_HOST_TO_TADDR(codeStart) - + (code - codeStart)) - + PTR_TO_TADDR(m_decoder.GetBase()); - - const size_t cinstr = m_dis->Cinstruction(); - size_t inum = 0; - while (true) - { - WCHAR szOpcode[4096]; - size_t len = m_dis->CchFormatInstr(szOpcode, _countof(szOpcode)); - _ASSERTE(szOpcode[len-1] == 0); - m_display->WriteXmlText( "%04x\t%S\n", (code-codeStart) + (inum * 4), szOpcode ); - -NEXT_INSTR: - if (++inum >= cinstr) - break; - - _ASSERTE((inum * 4) < count); // IA64 has 3 instructions per bundle commonly - // referenced as offset 0, 4, and 8 - if (!m_dis->FSelectInstruction(inum)) - { - m_display->WriteXmlText( "%04x\tUnknown instruction within bundle\n", (code-codeStart) + (inum * 4)); - goto NEXT_INSTR; - } - } - - code += count; - } - } - EX_CATCH - { - - } - EX_END_CATCH(SwallowAllExceptions); - -#else // FEATURE_MSDIS - - m_display->WriteXmlText( "Disassembly not supported\n" ); - -#endif // FEATURE_MSDIS - - m_display->EndTextElement(); //NativeCode -} - -SIZE_T NativeImageDumper::TranslateAddressCallback(IXCLRDisassemblySupport *dis, - CLRDATA_ADDRESS addr, - __out_ecount(nameSize) WCHAR *name, SIZE_T nameSize, - DWORDLONG *offset) -{ - NativeImageDumper *pThis = (NativeImageDumper *) dis->PvClient(); - - SIZE_T ret = pThis->TranslateSymbol(dis, - addr+(SIZE_T)pThis->m_currentAddress, - name, nameSize, offset); -#ifdef _DEBUG - if( ret == 0 ) - { - _snwprintf_s(name, nameSize, _TRUNCATE, W("@TRANSLATED ADDRESS@ %p"), - (TADDR)(addr + (SIZE_T)pThis->m_currentAddress) ); - ret = wcslen(name); - *offset = -1; - } -#endif - return ret; -} -SIZE_T NativeImageDumper::TranslateFixupCallback(IXCLRDisassemblySupport *dis, - CLRDATA_ADDRESS addr, - SIZE_T size, __out_ecount(nameSize) WCHAR *name, - SIZE_T nameSize, - DWORDLONG *offset) -{ - NativeImageDumper *pThis = (NativeImageDumper *) dis->PvClient(); - if( !dis->TargetIsAddress() ) - return 0; - - TADDR taddr = TO_TADDR(pThis->m_currentAddress) + (TADDR)addr; - SSIZE_T targetOffset; - switch (size) - { - case sizeof(void*): - targetOffset = *PTR_SIZE_T(taddr); - break; -#ifdef HOST_64BIT - case sizeof(INT32): - targetOffset = *PTR_INT32(taddr); - break; -#endif - case sizeof(short): - targetOffset = *(short*)(WORD*)PTR_WORD(taddr); - break; - case sizeof(signed char): - targetOffset = *PTR_SBYTE(taddr); - break; - default: - return 0; - } - - CLRDATA_ADDRESS address = targetOffset + TO_TADDR(pThis->m_currentAddress) + addr + size; - - SIZE_T ret = pThis->TranslateSymbol(dis, address, name, nameSize, offset); - if( ret == 0 ) - { - _snwprintf_s(name, nameSize, _TRUNCATE, W("@TRANSLATED FIXUP@ %p"), (TADDR)address); - ret = wcslen(name); - *offset = -1; - } - return ret; -} - -size_t NativeImageDumper::TranslateSymbol(IXCLRDisassemblySupport *dis, - CLRDATA_ADDRESS addr, __out_ecount(nameSize) WCHAR *name, - SIZE_T nameSize, DWORDLONG *offset) -{ -#ifdef FEATURE_READYTORUN - if (m_pReadyToRunHeader != NULL) - return 0; -#endif - - if (isInRange((TADDR)addr)) - { - COUNT_T rva = (COUNT_T)(addr - PTR_TO_TADDR(m_decoder.GetBase())); - - COUNT_T helperTableSize; - void *helperTable = m_decoder.GetNativeHelperTable(&helperTableSize); - - if (rva >= m_decoder.GetDataRva(TO_TADDR(helperTable)) - && rva < (m_decoder.GetDataRva(TO_TADDR(helperTable)) - +helperTableSize)) - { - int helperIndex = (USHORT)*PTR_DWORD(TO_TADDR(addr)); -// _ASSERTE(helperIndex < CORINFO_HELP_COUNT); - // because of literal blocks we might have bogus values - if (helperIndex < CORINFO_HELP_COUNT) - _snwprintf_s(name, nameSize, _TRUNCATE, W("<%S>"), g_helperNames[helperIndex]); - else - _snwprintf_s(name, nameSize, _TRUNCATE, W("Illegal HelperIndex<%04X>"), helperIndex); - *offset = 0; - return wcslen(name); - } - - PTR_Module module = (TADDR)m_decoder.GetPersistedModuleImage(); - PTR_NGenLayoutInfo pNgenLayout = module->GetNGenLayoutInfo(); - - for (int iRange = 0; iRange < 2; iRange++) - { - if (pNgenLayout->m_CodeSections[iRange].IsInRange((TADDR)addr)) - { - int MethodIndex = NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod(rva, pNgenLayout->m_pRuntimeFunctions[iRange], 0, pNgenLayout->m_nRuntimeFunctions[iRange] - 1); - if (MethodIndex >= 0) - { -#ifdef FEATURE_EH_FUNCLETS - while (pNgenLayout->m_MethodDescs[iRange][MethodIndex] == 0) - MethodIndex--; -#endif - - PTR_RUNTIME_FUNCTION pRuntimeFunction = pNgenLayout->m_pRuntimeFunctions[iRange] + MethodIndex; - - PTR_MethodDesc pMD = NativeUnwindInfoLookupTable::GetMethodDesc(pNgenLayout, pRuntimeFunction, PTR_TO_TADDR(m_decoder.GetBase())); - TempBuffer buf; - MethodDescToString( pMD, buf ); - _snwprintf_s(name, nameSize, _TRUNCATE, W("%s "), (const WCHAR *)buf ); - *offset = rva - RUNTIME_FUNCTION__BeginAddress(pRuntimeFunction); - return wcslen(name); - } - } - } - - if (pNgenLayout->m_CodeSections[2].IsInRange((TADDR)addr)) - { - int ColdMethodIndex = NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod(rva, pNgenLayout->m_pRuntimeFunctions[2], 0, pNgenLayout->m_nRuntimeFunctions[2] - 1); - if (ColdMethodIndex >= 0) - { - PTR_RUNTIME_FUNCTION pRuntimeFunction; - - PTR_CORCOMPILE_COLD_METHOD_ENTRY pColdCodeMap = pNgenLayout->m_ColdCodeMap; - -#ifdef FEATURE_EH_FUNCLETS - while (pColdCodeMap[ColdMethodIndex].mainFunctionEntryRVA == 0) - ColdMethodIndex--; - - pRuntimeFunction = dac_cast(PTR_TO_TADDR(m_decoder.GetBase()) + pColdCodeMap[ColdMethodIndex].mainFunctionEntryRVA); -#else - DWORD ColdUnwindData = pNgenLayout->m_pRuntimeFunctions[2][ColdMethodIndex].UnwindData; - _ASSERTE((ColdUnwindData & RUNTIME_FUNCTION_INDIRECT) != 0); - pRuntimeFunction = dac_cast(PTR_TO_TADDR(m_decoder.GetBase()) + (ColdUnwindData & ~RUNTIME_FUNCTION_INDIRECT)); -#endif - - PTR_MethodDesc pMD = NativeUnwindInfoLookupTable::GetMethodDesc(pNgenLayout, pRuntimeFunction, PTR_TO_TADDR(m_decoder.GetBase())); - TempBuffer buf; - MethodDescToString( pMD, buf ); - _snwprintf_s(name, nameSize, _TRUNCATE, W("%s (cold region)"), (const WCHAR *)buf ); - *offset = rva - RUNTIME_FUNCTION__BeginAddress(&pNgenLayout->m_pRuntimeFunctions[2][ColdMethodIndex]); - return wcslen(name); - } - } - - //Dumping precodes by name requires some information from the module (the precode ranges). - IF_OPT_OR(PRECODES, MODULE) - { - TempBuffer precodeBuf; - //maybe it is a precode - PTR_Precode maybePrecode((TADDR)addr); - const char * precodeName = NULL; - if (isPrecode((TADDR)addr)) - { - switch(maybePrecode->GetType()) - { - case PRECODE_INVALID: - precodeName = "InvalidPrecode"; break; - case PRECODE_STUB: - precodeName = "StubPrecode"; break; -#ifdef HAS_NDIRECT_IMPORT_PRECODE - case PRECODE_NDIRECT_IMPORT: - precodeName = "NDirectImportPrecode"; break; -#endif // HAS_NDIRECT_IMPORT_PRECODE -#ifdef HAS_FIXUP_PRECODE - case PRECODE_FIXUP: - precodeName = "FixupPrecode"; break; -#endif // HAS_FIXUP_PRECODE -#ifdef HAS_THISPTR_RETBUF_PRECODE - case PRECODE_THISPTR_RETBUF: - precodeName = "ThisPtrRetBufPrecode"; break; -#endif // HAS_THISPTR_RETBUF_PRECODE - } - - if( precodeName ) - { - //hot or cold? - precodeBuf.AppendPrintf( W("%S (0x%p)"), precodeName, addr ); - } - //get MethodDesc from precode and dump the target - PTR_MethodDesc precodeMD(maybePrecode->GetMethodDesc()); - precodeBuf.Append( W(" for ") ); - MethodDescToString(precodeMD, precodeBuf); - - _snwprintf_s(name, nameSize, _TRUNCATE, W("%s"), (const WCHAR *)precodeBuf); - - *offset = 0; - return wcslen(name); - } - } - - PTR_CORCOMPILE_IMPORT_SECTION pImportSection = m_decoder.GetNativeImportSectionForRVA(rva); - if (pImportSection != NULL) - { - const char * wbRangeName = NULL; - switch (pImportSection->Type) - { - case CORCOMPILE_IMPORT_TYPE_EXTERNAL_METHOD: - wbRangeName = "ExternalMethod"; - break; - -#if 0 - case CORCOMPILE_IMPORT_TYPE_VIRTUAL_METHOD: - wbRangeName = "VirtualMethod"; - break; - - case CORCOMPILE_IMPORT_TYPE_STUB_DISPATCH: - wbRangeName = "StubDispatch"; - break; -#endif - - // This method is only ever called for targets of direct calls right now and so the only - // import that can meaninfully show up here is external method thunk. - default: - return 0; - } - - TempBuffer fixupThunkBuf; - fixupThunkBuf.AppendPrintf( W("%S (0x%p) for "), wbRangeName, addr ); - FixupThunkToString(pImportSection, (TADDR)addr, fixupThunkBuf); - - _snwprintf_s(name, nameSize, _TRUNCATE, W("%s"), (const WCHAR *)fixupThunkBuf); - - *offset = 0; - return wcslen(name); - } - } - else if( g_dacImpl->GetJitHelperFunctionName(addr, - _countof(bigByteBuffer), - (char*)bigByteBuffer, - NULL ) == S_OK ) - { - *offset = 0; - _snwprintf_s( name, nameSize, _TRUNCATE, W("%S"), bigByteBuffer ); - return wcslen(name); - } - else - { - //check mscorwks - if( m_mscorwksBase <= addr && - addr < (m_mscorwksBase + m_mscorwksSize) ) - { - *offset = addr - m_mscorwksBase; - _snwprintf_s( name, nameSize, _TRUNCATE, W("clr") ); - return wcslen(name); - } - for( COUNT_T i = 0; i < m_numDependencies; ++i ) - { - const Dependency& dep = m_dependencies[i]; - if( dep.pLoadedAddress <= addr && - addr < (dep.pLoadedAddress + dep.size) ) - { - *offset = addr - dep.pLoadedAddress; - _snwprintf_s( name, nameSize, _TRUNCATE, W("%s.ni"), dep.name ); - return wcslen(name); - } - } - } - - return 0; -} - -BOOL NativeImageDumper::HandleFixupForMethodDump(PTR_CORCOMPILE_IMPORT_SECTION pSection, SIZE_T fixupIndex, SIZE_T *fixupCell, BOOL mayUsePrecompiledNDirectMethods) -{ - PTR_SIZE_T fixupPtr(TO_TADDR(fixupCell)); - m_display->StartElement( "Fixup" ); - m_display->WriteElementPointer( "Address", - DataPtrToDisplay( TO_TADDR(fixupCell) ) ); - m_display->WriteElementUInt( "TaggedValue", (DWORD)*fixupPtr ); - WriteElementsFixupBlob(pSection, *fixupPtr); - m_display->EndElement(); - - return TRUE; -} - -void NativeImageDumper::DumpMethodFixups(PTR_Module module, - TADDR fixupList) -{ - _ASSERTE( CHECK_OPT(METHODS) ); - - COUNT_T nImportSections; - PTR_CORCOMPILE_IMPORT_SECTION pImportSections = m_decoder.GetNativeImportSections(&nImportSections); - - //create the first element outside of the callback. The callback creates - //subsequent elements. - module->FixupDelayListAux( fixupList, this, - &NativeImageDumper::HandleFixupForMethodDump, - pImportSections, nImportSections, - &m_decoder ); -} - -IMAGE_SECTION_HEADER * NativeImageDumper::FindSection( char const * name ) -{ - COUNT_T numberOfSections = m_decoder.GetNumberOfSections(); - PTR_IMAGE_SECTION_HEADER curSection( m_decoder.FindFirstSection() ); - - for ( ; numberOfSections > 0; --numberOfSections, ++curSection ) - { - if ( ! strncmp( reinterpret_cast< char * >( curSection->Name ), name, 8 ) ) - break; - } - - if ( ! numberOfSections ) - return NULL; - - return curSection; -} - -NativeImageDumper::EnumMnemonics NativeImageDumper::s_ModulePersistedFlags[] = -{ -#define MPF_ENTRY(f) NativeImageDumper::EnumMnemonics(Module::f, W(#f)) - MPF_ENTRY(COMPUTED_GLOBAL_CLASS), - - MPF_ENTRY(COMPUTED_STRING_INTERNING), - MPF_ENTRY(NO_STRING_INTERNING), - - MPF_ENTRY(COMPUTED_WRAP_EXCEPTIONS), - MPF_ENTRY(WRAP_EXCEPTIONS), - - MPF_ENTRY(COMPUTED_RELIABILITY_CONTRACT), - - MPF_ENTRY(COLLECTIBLE_MODULE), - MPF_ENTRY(COMPUTED_IS_PRE_V4_ASSEMBLY), - MPF_ENTRY(IS_PRE_V4_ASSEMBLY), - MPF_ENTRY(DEFAULT_DLL_IMPORT_SEARCH_PATHS_IS_CACHED), - MPF_ENTRY(DEFAULT_DLL_IMPORT_SEARCH_PATHS_STATUS), - - MPF_ENTRY(COMPUTED_METHODDEF_TO_PROPERTYINFO_MAP), - MPF_ENTRY(LOW_LEVEL_SYSTEM_ASSEMBLY_BY_NAME), -#undef MPF_ENTRY -}; - -//VirtualSectionTypes. -#define TEXTIFY(x) W(#x) -static const NativeImageDumper::EnumMnemonics s_virtualSectionFlags [] = -{ - -#define CORCOMPILE_SECTION_IBCTYPE(ibcType, _value) NativeImageDumper::EnumMnemonics(_value, TEXTIFY(ibcType)), - CORCOMPILE_SECTION_IBCTYPES() -#undef CORCOMPILE_SECTION_IBCTYPE - -#define CORCOMPILE_SECTION_RANGE_TYPE(rangeType, _value) NativeImageDumper::EnumMnemonics(_value, TEXTIFY(rangeType) W("Range")), - CORCOMPILE_SECTION_RANGE_TYPES() -#undef CORCOMPILE_SECTION_RANGE_TYPE -}; -const WCHAR * g_sectionNames[] = -{ - W("SECTION_DUMMY"), // the first section start at 0x1. Make the array 1 based. -#define CORCOMPILE_SECTION_TYPE(section) W("SECTION_") TEXTIFY(section), - CORCOMPILE_SECTION_TYPES() -#undef CORCOMPILE_SECTION - -}; -#undef TEXTIFY - - -#ifdef _PREFAST_ -#pragma warning(push) -#pragma warning(disable:21000) // Suppress PREFast warning about overly large function -#endif - -void NativeImageDumper::DumpModule( PTR_Module module ) -{ - - //the module is the fisrt thing in the .data section. We use this fact for - //the sectionBases down below. -// _ASSERTE(m_decoder.GetDataRva(PTR_TO_TADDR(module)) -// == FindSection(".data")->VirtualAddress ); - - DisplayStartStructure( "module", DPtrToPreferredAddr(module), - sizeof(*module), MODULE ); - PTR_PEFile file = module->m_file; - _ASSERTE(file == NULL); - DisplayWriteFieldPointer( m_file, DPtrToPreferredAddr(file), Module, - MODULE ); - - _ASSERTE(module->m_dwTransientFlags == 0U); - DisplayWriteFieldUInt(m_dwTransientFlags, module->m_dwTransientFlags, - Module, MODULE ); - - - - DisplayWriteFieldEnumerated( m_dwPersistedFlags, module->m_dwPersistedFlags, - Module, s_ModulePersistedFlags, W("|"), MODULE ); - - DisplayWriteFieldPointer( m_pAssembly, - DPtrToPreferredAddr(module->m_pAssembly), - Module, MODULE ); - _ASSERTE(module->m_pAssembly == NULL); //never appears in the image - - DisplayWriteFieldUInt( m_moduleRef, module->m_moduleRef, Module, MODULE ); - DisplayWriteFieldInt( m_dwDebuggerJMCProbeCount, - module->m_dwDebuggerJMCProbeCount, Module, MODULE ); - /* REVISIT_TODO Fri 10/14/2005 - * Dump the binder - */ - PTR_CoreLibBinder binder = module->m_pBinder; - if( NULL != binder ) - { - DisplayStartStructureWithOffset( m_pBinder, DPtrToPreferredAddr(binder), - sizeof(*binder), Module, - MODULE ); - - //these four fields don't have anything useful in ngen images. - DisplayWriteFieldPointer( m_classDescriptions, - DPtrToPreferredAddr(binder->m_classDescriptions), - CoreLibBinder, MODULE ); - DisplayWriteFieldPointer( m_methodDescriptions, - DPtrToPreferredAddr(binder->m_methodDescriptions), - CoreLibBinder, MODULE ); - DisplayWriteFieldPointer( m_fieldDescriptions, - DPtrToPreferredAddr(binder->m_fieldDescriptions), - CoreLibBinder, MODULE ); - DisplayWriteFieldPointer( m_pModule, - DPtrToPreferredAddr(binder->m_pModule), - CoreLibBinder, MODULE ); - - DisplayWriteFieldInt( m_cClasses, binder->m_cClasses, CoreLibBinder, - MODULE ); - DisplayWriteFieldAddress( m_pClasses, - DPtrToPreferredAddr(binder->m_pClasses), - sizeof(*binder->m_pClasses) - * binder->m_cClasses, - CoreLibBinder, MODULE ); - DisplayWriteFieldInt( m_cFields, binder->m_cFields, CoreLibBinder, - MODULE ); - DisplayWriteFieldAddress( m_pFields, - DPtrToPreferredAddr(binder->m_pFields), - sizeof(*binder->m_pFields) - * binder->m_cFields, - CoreLibBinder, MODULE ); - DisplayWriteFieldInt( m_cMethods, binder->m_cMethods, CoreLibBinder, - MODULE ); - DisplayWriteFieldAddress( m_pMethods, - DPtrToPreferredAddr(binder->m_pMethods), - sizeof(*binder->m_pMethods) - * binder->m_cMethods, - CoreLibBinder, MODULE ); - - DisplayEndStructure( MODULE ); //m_pBinder - } - else - { - DisplayWriteFieldPointer( m_pBinder, NULL, Module, MODULE ); - } - - - /* REVISIT_TODO Tue 10/25/2005 - * unconditional dependencies, activations, class dependencies, thunktable - */ - - - //round trip the LookupMap back through the DAC so that we don't have an - //interior host pointer. - PTR_LookupMapBase lookupMap( PTR_TO_TADDR(module) - + offsetof(Module, m_TypeDefToMethodTableMap) ); - TraverseMap( lookupMap, "m_TypeDefToMethodTableMap", - offsetof(Module, m_TypeDefToMethodTableMap), - fieldsize(Module, m_TypeDefToMethodTableMap), - &NativeImageDumper::IterateTypeDefToMTCallback ); - - lookupMap = PTR_LookupMapBase( PTR_TO_TADDR(module) - + offsetof(Module, m_TypeRefToMethodTableMap) ); - - TraverseMap( lookupMap, "m_TypeRefToMethodTableMap", - offsetof(Module, m_TypeRefToMethodTableMap), - fieldsize(Module, m_TypeRefToMethodTableMap), - &NativeImageDumper::IterateTypeRefToMTCallback ); - - lookupMap = PTR_LookupMapBase( PTR_TO_TADDR(module) - + offsetof(Module, m_MethodDefToDescMap) ); - TraverseMap( lookupMap, "m_MethodDefToDescMap", - offsetof(Module, m_MethodDefToDescMap), - fieldsize(Module, m_MethodDefToDescMap), - &NativeImageDumper::IterateMethodDefToMDCallback); - - lookupMap = PTR_LookupMapBase( PTR_TO_TADDR(module) - + offsetof(Module, m_FieldDefToDescMap) ); - TraverseMap( lookupMap, "m_FieldDefToDescMap", - offsetof(Module, m_FieldDefToDescMap), - fieldsize(Module, m_FieldDefToDescMap), - &NativeImageDumper::IterateFieldDefToFDCallback); - - TraverseMemberRefToDescHash(module->m_pMemberRefToDescHashTable, "m_pMemberRefToDescHashTable", - offsetof(Module, m_pMemberRefToDescHashTable), - fieldsize(Module, m_pMemberRefToDescHashTable), - FALSE); - - lookupMap = PTR_LookupMapBase( PTR_TO_TADDR(module) - + offsetof(Module, m_GenericParamToDescMap) ); - - TraverseMap( lookupMap, "m_GenericParamToDescMap", - offsetof(Module, m_GenericParamToDescMap), - fieldsize(Module, m_GenericParamToDescMap), - &NativeImageDumper::IterateGenericParamToDescCallback); - - lookupMap = PTR_LookupMapBase( PTR_TO_TADDR(module) - + offsetof(Module, m_GenericTypeDefToCanonMethodTableMap) ); - - TraverseMap( lookupMap, "m_GenericTypeDefToCanonMethodTableMap", - offsetof(Module, m_GenericTypeDefToCanonMethodTableMap), - fieldsize(Module, m_GenericTypeDefToCanonMethodTableMap), - &NativeImageDumper::IterateTypeDefToMTCallback ); - - lookupMap = PTR_LookupMapBase( PTR_TO_TADDR(module) - + offsetof(Module, m_FileReferencesMap) ); - TraverseMap( lookupMap, "m_FileReferencesMap", - offsetof(Module, m_FileReferencesMap), - fieldsize(Module, m_FileReferencesMap), - &NativeImageDumper::IterateMemberRefToDescCallback); - - lookupMap = PTR_LookupMapBase(PTR_TO_TADDR(module) - + offsetof(Module,m_ManifestModuleReferencesMap)); - - TraverseMap( lookupMap, "m_ManifestModuleReferencesMap", - offsetof(Module, m_ManifestModuleReferencesMap), - fieldsize(Module, m_ManifestModuleReferencesMap), - &NativeImageDumper::IterateManifestModules); - - TraverseClassHash( module->m_pAvailableClasses, "m_pAvailableClasses", - offsetof(Module, m_pAvailableClasses), - fieldsize(Module, m_pAvailableClasses), true ); - - TraverseTypeHash( module->m_pAvailableParamTypes, "m_pAvailableParamTypes", - offsetof(Module, m_pAvailableParamTypes), - fieldsize(Module, m_pAvailableParamTypes) ); - TraverseInstMethodHash( module->m_pInstMethodHashTable, - "m_pInstMethodHashTable", - offsetof(Module, m_pInstMethodHashTable), - fieldsize(Module, m_pInstMethodHashTable), - module ); - TraverseStubMethodHash( module->m_pStubMethodHashTable, - "m_pStubMethodHashTable", - offsetof(Module, m_pStubMethodHashTable), - fieldsize(Module, m_pStubMethodHashTable), - module ); - - IF_OPT(MODULE) - { - TraverseClassHash( module->m_pAvailableClassesCaseIns, - "m_pAvailableClassesCaseIns", - offsetof(Module, m_pAvailableClassesCaseIns), - fieldsize(Module, m_pAvailableClassesCaseIns), - false ); - } - - _ASSERTE(module->m_pProfilingBlobTable == NULL); - - DisplayWriteFieldFlag( m_nativeImageProfiling, - module->m_nativeImageProfiling, Module, MODULE ); - - DisplayWriteFieldPointer( m_methodProfileList, - DataPtrToDisplay((TADDR)module->m_methodProfileList), - Module, MODULE ); - _ASSERTE(module->m_methodProfileList == NULL); - - /* REVISIT_TODO Tue 10/04/2005 - * Dump module->m_moduleCtorInfo - */ - PTR_ModuleCtorInfo ctorInfo( PTR_HOST_MEMBER_TADDR(Module, module, - m_ModuleCtorInfo) ); - - DisplayStartStructureWithOffset( m_ModuleCtorInfo, - DPtrToPreferredAddr(ctorInfo), - sizeof(*ctorInfo), - Module, SLIM_MODULE_TBLS ); - DisplayWriteFieldInt( numElements, ctorInfo->numElements, ModuleCtorInfo, - SLIM_MODULE_TBLS ); - DisplayWriteFieldInt( numLastAllocated, ctorInfo->numLastAllocated, - ModuleCtorInfo, SLIM_MODULE_TBLS ); - DisplayWriteFieldInt( numElementsHot, ctorInfo->numElementsHot, - ModuleCtorInfo, SLIM_MODULE_TBLS ); - DisplayWriteFieldAddress( ppMT, DPtrToPreferredAddr(ctorInfo->ppMT), - ctorInfo->numElements * sizeof(RelativePointer), - ModuleCtorInfo, SLIM_MODULE_TBLS ); - /* REVISIT_TODO Tue 03/21/2006 - * is cctorInfoHot and cctorInfoCold actually have anything interesting - * inside of them? - */ - DisplayWriteFieldAddress( cctorInfoHot, - DPtrToPreferredAddr(ctorInfo->cctorInfoHot), - sizeof(*ctorInfo->cctorInfoHot) - * ctorInfo->numElementsHot, - ModuleCtorInfo, SLIM_MODULE_TBLS ); - DisplayWriteFieldAddress( cctorInfoCold, - DPtrToPreferredAddr(ctorInfo->cctorInfoCold), - sizeof(*ctorInfo->cctorInfoCold) - * (ctorInfo->numElements - - ctorInfo->numElementsHot), - ModuleCtorInfo, SLIM_MODULE_TBLS ); - /* XXX Thu 03/23/2006 - * See ModuleCtorInfo::Save for why these are +1. - */ - DisplayWriteFieldAddress( hotHashOffsets, - DPtrToPreferredAddr(ctorInfo->hotHashOffsets), - (ctorInfo->numHotHashes + 1) - * sizeof(*ctorInfo->hotHashOffsets), - ModuleCtorInfo, SLIM_MODULE_TBLS ); - DisplayWriteFieldAddress( coldHashOffsets, - DPtrToPreferredAddr(ctorInfo->coldHashOffsets), - (ctorInfo->numColdHashes + 1) - * sizeof(*ctorInfo->coldHashOffsets), - ModuleCtorInfo, SLIM_MODULE_TBLS ); - - DisplayWriteFieldInt( numHotHashes, ctorInfo->numHotHashes, ModuleCtorInfo, - SLIM_MODULE_TBLS ); - DisplayWriteFieldInt( numColdHashes, ctorInfo->numColdHashes, - ModuleCtorInfo, SLIM_MODULE_TBLS ); - - DisplayWriteFieldAddress( ppHotGCStaticsMTs, - DPtrToPreferredAddr(ctorInfo->ppHotGCStaticsMTs), - ctorInfo->numHotGCStaticsMTs - * sizeof(*ctorInfo->ppHotGCStaticsMTs), - ModuleCtorInfo, SLIM_MODULE_TBLS ); - DisplayWriteFieldAddress( ppColdGCStaticsMTs, - DPtrToPreferredAddr(ctorInfo->ppColdGCStaticsMTs), - ctorInfo->numColdGCStaticsMTs - * sizeof(*ctorInfo->ppColdGCStaticsMTs), - ModuleCtorInfo, SLIM_MODULE_TBLS ); - DisplayWriteFieldInt( numHotGCStaticsMTs, ctorInfo->numHotGCStaticsMTs, - ModuleCtorInfo, SLIM_MODULE_TBLS ); - DisplayWriteFieldInt( numColdGCStaticsMTs, ctorInfo->numColdGCStaticsMTs, - ModuleCtorInfo, SLIM_MODULE_TBLS ); - - DisplayEndStructure( SLIM_MODULE_TBLS ); //m_ModuleCtorInfo - - _ASSERTE(module->m_pNgenStats == NULL); - - DisplayWriteFieldPointer( m_pNgenStats, - DataPtrToDisplay((TADDR)module->m_pNgenStats), - Module, MODULE ); - - DisplayWriteFieldAddress(m_propertyNameSet, - DPtrToPreferredAddr(module->m_propertyNameSet), - sizeof(module->m_propertyNameSet[0]) * - module->m_nPropertyNameSet, - Module, MODULE); - - DisplayWriteFieldPointer( m_ModuleID, - DataPtrToDisplay(dac_cast(module->m_ModuleID)), - Module, MODULE ); - _ASSERTE(module->m_ModuleID == NULL); - - /* XXX Tue 04/11/2006 - * Value is either -1 or 0, so no need to rebase. - */ - DisplayWriteFieldPointer( m_pRegularStaticOffsets, - PTR_TO_TADDR(module->m_pRegularStaticOffsets), - Module, MODULE ); - _ASSERTE(module->m_pRegularStaticOffsets == (void*)-1 - || module->m_pRegularStaticOffsets == 0 ); - - DisplayWriteFieldInt( m_dwMaxGCRegularStaticHandles, - module->m_dwMaxGCRegularStaticHandles, Module, MODULE ); - DisplayWriteFieldInt( m_dwRegularStaticsBlockSize, module->m_dwRegularStaticsBlockSize, - Module, MODULE ); - DisplayWriteFieldAddress( m_pDynamicStaticsInfo, - DataPtrToDisplay((TADDR)module->m_pDynamicStaticsInfo), - module->m_maxDynamicEntries - * sizeof(*(module->m_pDynamicStaticsInfo)), - Module, MODULE ); - - DisplayWriteFieldInt( m_cDynamicEntries, - (int)module->m_cDynamicEntries, Module, MODULE ); - - CoverageRead(TO_TADDR(module->m_pDynamicStaticsInfo), - (int)(module->m_maxDynamicEntries - * sizeof(*(module->m_pDynamicStaticsInfo)))); - - - - _ASSERTE(module->m_debuggerSpecificData.m_pDynamicILCrst == NULL); - DisplayWriteFieldPointer( m_debuggerSpecificData.m_pDynamicILCrst, - DataPtrToDisplay(dac_cast(module->m_debuggerSpecificData.m_pDynamicILCrst)), - Module, MODULE ); - - - /* REVISIT_TODO Wed 09/21/2005 - * Get me in the debugger and look at the activations and module/class - * dependencies. - * As well as the thunks. - */ - - /* REVISIT_TODO Wed 09/21/2005 - * Dump the following - */ - //file - //assembly - - DisplayWriteFieldInt( m_DefaultDllImportSearchPathsAttributeValue, - module->m_DefaultDllImportSearchPathsAttributeValue, Module, MODULE ); - - - DisplayEndStructure(MODULE); //Module -} -#ifdef _PREFAST_ -#pragma warning(pop) -#endif - -bool NativeImageDumper::isPrecode(TADDR maybePrecode) -{ - PTR_Module module = (TADDR)m_decoder.GetPersistedModuleImage(); - - return !!module->IsZappedPrecode(maybePrecode); -} - - -void NativeImageDumper::IterateTypeDefToMTCallback( TADDR mtTarget, - TADDR flags, - PTR_LookupMapBase map, - DWORD rid ) -{ - DisplayStartElement( "Entry", MODULE_TABLES ); - - PTR_MethodTable mt(mtTarget); - - DisplayWriteElementUInt( "Token", rid | mdtTypeDef, MODULE_TABLES ); - /* REVISIT_TODO Fri 10/21/2005 - * Can I use WriteElementMethodTable here? - */ - DisplayWriteElementPointer( "MethodTable", DPtrToPreferredAddr(mt), - MODULE_TABLES ); - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - /* REVISIT_TODO Fri 09/30/2005 - * This handles the extra entries in the type table that shouldn't be there. - */ - if( rid == 0 || ((rid != 1) && (mtTarget == NULL)) ) - { - DisplayWriteElementString( "Name", "mdTypeDefNil", MODULE_TABLES ); - } - else - { - TempBuffer buf; - MethodTableToString( mt, buf ); - DisplayWriteElementStringW( "Name", (const WCHAR*)buf, MODULE_TABLES ); - } - DisplayWriteElementFlag( "hot", !!map->FindHotItemValuePtr(rid), - MODULE_TABLES ); - DisplayEndElement( MODULE_TABLES ); - - if( isInRange(PTR_TO_TADDR(mt)) ) - { - m_discoveredMTs.AppendEx(mt); - PTR_EEClass clazz = GetClassFromMT(mt); - if( isInRange(PTR_TO_TADDR(clazz)) ) - m_discoveredClasses.AppendEx(mt); - } -} - -void NativeImageDumper::IterateTypeRefToMTCallback( TADDR mtTarget, - TADDR flags, - PTR_LookupMapBase map, - DWORD rid ) -{ - DisplayStartElement( "Entry", MODULE_TABLES ); - - mtTarget = ((FixupPointer&)mtTarget).GetValue(); - - PTR_MethodTable mt(mtTarget); - -#if 0 - RecordTypeRef(rid | mdtTypeRef, mt); -#endif - - DisplayWriteElementUInt( "Token", rid | mdtTypeRef, MODULE_TABLES ); - - DisplayWriteElementPointer( "MethodTable", DPtrToPreferredAddr(mt), - MODULE_TABLES ); - - if( rid == 0 ) - { - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - DisplayWriteElementString( "Name", "mdtTypeRefNil", MODULE_TABLES ); - } - else if( mt == NULL ) - { - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - IF_OPT(MODULE_TABLES) - WriteElementMDToken( "Name", mdtTypeRef | rid ); - } - else if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(mt)) ) - { - RVA rva = CORCOMPILE_UNTAG_TOKEN(PTR_TO_TADDR(mt)); - // - // This writes two things FixupTargetValue and FixupTargetName - // - WriteElementsFixupBlob( NULL,PTR_TO_TADDR(mt)); - } - else - { - TempBuffer buf; - MethodTableToString( mt, buf ); - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - DisplayWriteElementStringW( "Name", (const WCHAR*)buf, MODULE_TABLES ); - } - DisplayWriteElementFlag( "hot", !!map->FindHotItemValuePtr(rid), - MODULE_TABLES ); - DisplayEndElement( MODULE_TABLES ); - if( isInRange(mtTarget) ) - { - m_discoveredMTs.AppendEx(mt); - PTR_EEClass clazz = GetClassFromMT(mt); - if( isInRange(PTR_TO_TADDR(clazz)) ) - m_discoveredClasses.AppendEx(mt); - } -} - -void NativeImageDumper::IterateMethodDefToMDCallback( TADDR mdTarget, - TADDR flags, - PTR_LookupMapBase map, - DWORD rid ) -{ - DisplayStartElement( "Entry", MODULE_TABLES ); - - PTR_MethodDesc md(mdTarget); - - DisplayWriteElementUInt( "Token", rid | mdtMethodDef, MODULE_TABLES ); - - DisplayWriteElementPointer( "MethodDesc", DPtrToPreferredAddr(md), - MODULE_TABLES ); - - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - if( rid == 0 ) - { - DisplayWriteElementString( "Name", "mdtMethodDefNil", MODULE_TABLES ); - } - else - { - TempBuffer buf; - MethodDescToString( md, buf ); - DisplayWriteElementStringW( "Name", (const WCHAR*)buf, MODULE_TABLES ); - } - DisplayWriteElementFlag( "hot", !!map->FindHotItemValuePtr(rid), - MODULE_TABLES ); - DisplayEndElement( MODULE_TABLES ); - //m_discoveredMDs.AppendEx(md); -} - -void NativeImageDumper::IterateFieldDefToFDCallback( TADDR fdTarget, - TADDR flags, - PTR_LookupMapBase map, - DWORD rid ) -{ - PTR_FieldDesc fd(fdTarget); - DisplayStartElement( "Entry", MODULE_TABLES ); - - - DisplayWriteElementUInt( "Token", rid | mdtFieldDef, MODULE_TABLES ); - - DisplayWriteElementPointer( "FieldDef", DPtrToPreferredAddr(fd), - MODULE_TABLES ); - - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - if( rid == 0 ) - { - DisplayWriteElementString( "Name", "mdtFieldDefNil", MODULE_TABLES ); - } - else - { - TempBuffer buf; - FieldDescToString( fd, mdtFieldDef | rid, buf ); - DisplayWriteElementStringW( "Name", (const WCHAR*)buf, MODULE_TABLES ); - } - DisplayWriteElementFlag( "hot", !!map->FindHotItemValuePtr(rid), - MODULE_TABLES ); - DisplayEndElement( MODULE_TABLES ); - /* XXX Mon 10/17/2005 - * All FieldDescs are reachable from the EEClasses - */ - //m_discoveredFDs.AppendEx(PTR_FieldDesc(fdTarget)); -} - -void NativeImageDumper::IterateMemberRefToDescCallback( TADDR mrTarget, - TADDR flags, - PTR_LookupMapBase map, - DWORD rid ) -{ - DisplayStartElement( "Entry", MODULE_TABLES ); - - - bool isFieldRef = (flags & IS_FIELD_MEMBER_REF) != 0; - mdToken targetToken = mdtMemberRef | rid; - mrTarget = ((FixupPointer&)mrTarget).GetValue(); - DisplayWriteElementUInt( "Token", targetToken, MODULE_TABLES ); - DisplayWriteElementPointer( isFieldRef ? "FieldDesc" : "MethodDesc", - DataPtrToDisplay(mrTarget), MODULE_TABLES ); - - TempBuffer buf; - if( rid == 0 ) - { - buf.Append( W("mdtMemberDefNil") ); - } - else if( CORCOMPILE_IS_POINTER_TAGGED(mrTarget) ) - { - WriteElementsFixupBlob( NULL, mrTarget ); - } - else if( isFieldRef ) - { - FieldDescToString( PTR_FieldDesc(mrTarget), buf ); - } - else - { - MethodDescToString( PTR_MethodDesc(mrTarget), buf ); - } - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - DisplayWriteElementStringW( "Name", (const WCHAR*)buf, MODULE_TABLES ); - - DisplayWriteElementFlag( "hot", !!map->FindHotItemValuePtr(rid), - MODULE_TABLES ); - DisplayEndElement(MODULE_TABLES); - //m_discoveredMTs.AppendEx(mt); -} - -void NativeImageDumper::IterateGenericParamToDescCallback( TADDR tdTarget, - TADDR flags, - PTR_LookupMapBase map, - DWORD rid ) -{ - PTR_TypeDesc td(tdTarget); - DisplayStartElement( "Entry", MODULE_TABLES ); - - - DisplayWriteElementUInt( "Token", rid | mdtGenericParam, MODULE_TABLES ); - - DisplayWriteElementPointer( "GenericParam", DPtrToPreferredAddr(td), - MODULE_TABLES ); - - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - if( rid == 0 || td == NULL ) - { - DisplayWriteElementString( "Name", "mdtGenericParamNil", MODULE_TABLES ); - } - else - { - TempBuffer buf; - TypeDescToString( td, buf ); - DisplayWriteElementStringW( "Name", (const WCHAR*)buf, MODULE_TABLES ); - } - DisplayWriteElementFlag( "hot", !!map->FindHotItemValuePtr(rid), - MODULE_TABLES ); - DisplayEndElement( MODULE_TABLES ); -} - -#if 0 -void NativeImageDumper::IterateFileReferencesCallback(TADDR moduleTarget, - TADDR flags, - PTR_LookupMapBase map, - DWORD rid) -{ - DisplayStartElement( "Entry", MODULE_TABLES ); - - PTR_Module module(moduleTarget); - - DisplayWriteElementUInt( "Token", rid | mdtFile, MODULE_TABLES ); - - DisplayWriteElementPointer( "Module", DPtrToPreferredAddr(module), - MODULE_TABLES ); - - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - if( rid == 0 || (module == NULL) ) - { - DisplayWriteElementString( "Name", "mdtFileNil", MODULE_TABLES ); - } - else - { - TempBuffer buf; - AppendTokenName(mdtFile | rid, buf); - DisplayWriteElementStringW( "Name", (const WCHAR*)buf, MODULE_TABLES ); - } - DisplayWriteElementFlag( "hot", !!map->FindHotItemValuePtr(rid), - MODULE_TABLES ); - DisplayEndElement( MODULE_TABLES ); - //m_discoveredFDs.AppendEx(mt); -} -#endif - -void NativeImageDumper::IterateManifestModules( TADDR moduleTarget, - TADDR flags, - PTR_LookupMapBase map, - DWORD rid ) -{ - DisplayStartElement( "Entry", MODULE_TABLES ); - - moduleTarget = ((FixupPointer&)moduleTarget).GetValue(); - - PTR_Module module(moduleTarget); - - DisplayWriteElementUInt( "Token", rid | mdtAssemblyRef, MODULE_TABLES ); - - DisplayWriteElementPointer( "Module", DPtrToPreferredAddr(module), - MODULE_TABLES ); - DisplayWriteElementFlag( "fake", false, MODULE_TABLES ); - if( rid == 0 || (module == NULL) ) - { - DisplayWriteElementString( "Name", "mdtAssemblyRefNil", MODULE_TABLES ); - } - else - { - TempBuffer buf; - AppendTokenName(mdtAssemblyRef | rid, buf, m_import); - DisplayWriteElementStringW( "Name", (const WCHAR*)buf, MODULE_TABLES ); - } - DisplayWriteElementFlag( "hot", !!map->FindHotItemValuePtr(rid), - MODULE_TABLES ); - DisplayEndElement( MODULE_TABLES ); - //m_discoveredFDs.AppendEx(mt); -} - -void NativeImageDumper::TraverseMap(PTR_LookupMapBase map, const char * name, - unsigned offset, unsigned fieldSize, - void(NativeImageDumper::*cb)(TADDR, - TADDR, - PTR_LookupMapBase, - DWORD)) -{ - if( map == NULL ) - { - IF_OPT(MODULE) - m_display->WriteFieldPointer( name, offset, fieldSize, NULL ); - return; - } - DisplayStartVStructure(name, MODULE); - - DisplayStartArray( "Tables", W("%s"), MODULE ); - PTR_LookupMapBase current = map; - do - { - DWORD cbTable = map->MapIsCompressed() ? map->cbTable : map->dwCount * sizeof(*map->pTable); - - IF_OPT(MODULE) - { - DisplayWriteElementAddress( "Table", - DPtrToPreferredAddr(map->pTable), - cbTable, - MODULE); - } - - CoverageRead( PTR_TO_TADDR(map->pTable), cbTable ); - _ASSERTE(current == map || current->hotItemList == NULL); - current = current->pNext; - }while( current != NULL ); - - DisplayEndArray( "Total Tables", MODULE ); //Tables - - DisplayWriteFieldAddress( hotItemList, - DPtrToPreferredAddr(map->hotItemList), - map->dwNumHotItems * sizeof(*map->hotItemList), - LookupMapBase, MODULE ); - - DisplayStartArray( "Map", W("[%s]: %s %s%s %s %s %s"), MODULE_TABLES ); - - IF_OPT_OR3(MODULE_TABLES, EECLASSES, METHODTABLES) - { - LookupMap::Iterator iter(dac_cast)>(map)); - DWORD rid = 0; - while(iter.Next()) - { - TADDR flags = 0; - TADDR element = iter.GetElementAndFlags(&flags); - (this->*cb)( element, flags, map, rid ); - rid++; - } - - } - CoverageRead( PTR_TO_TADDR(map->hotItemList), - map->dwNumHotItems * sizeof(*map->hotItemList) ); - DisplayEndArray( "Total" , MODULE_TABLES );//Map - - DisplayEndVStructure(MODULE); //name -} - -// Templated method containing the core code necessary to traverse hash tables based on NgenHash (see -// vm\NgenHash.h). -template -void NativeImageDumper::TraverseNgenHash(DPTR(HASH_CLASS) pTable, - const char * name, - unsigned offset, - unsigned fieldSize, - bool saveClasses, - void (NativeImageDumper::*DisplayEntryFunction)(void *, DPTR(HASH_ENTRY_CLASS), bool), - void *pContext) -{ - if (pTable == NULL) - { - IF_OPT(MODULE) - m_display->WriteFieldPointer(name, offset, fieldSize, NULL); - return; - } - IF_OPT(MODULE) - { - m_display->StartStructureWithOffset(name, offset, fieldSize, - DPtrToPreferredAddr(pTable), - sizeof(HASH_CLASS)); - } - - DisplayWriteFieldPointer(m_pModule, - DPtrToPreferredAddr(pTable->GetModule()), - HASH_CLASS, MODULE); - - // Dump warm (volatile) entries. - DisplayWriteFieldUInt(m_cWarmEntries, pTable->m_cWarmEntries, HASH_CLASS, MODULE); - DisplayWriteFieldUInt(m_cWarmBuckets, pTable->m_cWarmBuckets, HASH_CLASS, MODULE); - DisplayWriteFieldAddress(m_pWarmBuckets, - DPtrToPreferredAddr(pTable->GetWarmBuckets()), - sizeof(HASH_ENTRY_CLASS*) * pTable->m_cWarmBuckets, - HASH_CLASS, MODULE); - - // Dump hot (persisted) entries. - DPTR(typename HASH_CLASS::PersistedEntries) pHotEntries(PTR_HOST_MEMBER_TADDR(HASH_CLASS, pTable, m_sHotEntries)); - DisplayStartStructureWithOffset(m_sHotEntries, DPtrToPreferredAddr(pHotEntries), - sizeof(typename HASH_CLASS::PersistedEntries), - HASH_CLASS, MODULE); - TraverseNgenPersistedEntries(pTable, pHotEntries, saveClasses, DisplayEntryFunction, pContext); - DisplayEndStructure(MODULE); // Hot entries - - // Dump cold (persisted) entries. - DPTR(typename HASH_CLASS::PersistedEntries) pColdEntries(PTR_HOST_MEMBER_TADDR(HASH_CLASS, pTable, m_sColdEntries)); - DisplayStartStructureWithOffset(m_sColdEntries, DPtrToPreferredAddr(pColdEntries), - sizeof(typename HASH_CLASS::PersistedEntries), - HASH_CLASS, MODULE); - TraverseNgenPersistedEntries(pTable, pColdEntries, saveClasses, DisplayEntryFunction, pContext); - DisplayEndStructure(MODULE); // Cold entries - - DisplayEndStructure(MODULE); // pTable -} - -// Helper used by TraverseNgenHash above to traverse an ngen persisted section of a table (separated out here -// because NgenHash-based tables can have two such sections, one for hot and one for cold entries). -template -void NativeImageDumper::TraverseNgenPersistedEntries(DPTR(HASH_CLASS) pTable, - DPTR(typename HASH_CLASS::PersistedEntries) pEntries, - bool saveClasses, - void (NativeImageDumper::*DisplayEntryFunction)(void *, DPTR(HASH_ENTRY_CLASS), bool), - void *pContext) -{ - // Display top-level fields. - DisplayWriteFieldUInt(m_cEntries, pEntries->m_cEntries, typename HASH_CLASS::PersistedEntries, MODULE); - DisplayWriteFieldUInt(m_cBuckets, pEntries->m_cBuckets, typename HASH_CLASS::PersistedEntries, MODULE); - DisplayWriteFieldAddress(m_pBuckets, - DPtrToPreferredAddr(pTable->GetPersistedBuckets(pEntries)), - pEntries->m_cBuckets ? pTable->GetPersistedBuckets(pEntries)->GetSize(pEntries->m_cBuckets) : 0, - typename HASH_CLASS::PersistedEntries, MODULE); - DisplayWriteFieldAddress(m_pEntries, - DPtrToPreferredAddr(pTable->GetPersistedEntries(pEntries)), - sizeof(typename HASH_CLASS::PersistedEntry) * pEntries->m_cEntries, - typename HASH_CLASS::PersistedEntries, MODULE); - - // Display entries (or maybe just the classes referenced by those entries). - DisplayStartArray("Entries", NULL, SLIM_MODULE_TBLS); - - // Enumerate bucket list. - for (DWORD i = 0; i < pEntries->m_cBuckets; ++i) - { - // Get index of the first entry and the count of entries in the bucket. - DWORD dwEntryId, cEntries; - pTable->GetPersistedBuckets(pEntries)->GetBucket(i, &dwEntryId, &cEntries); - - // Loop over entries. - while (cEntries && (CHECK_OPT(SLIM_MODULE_TBLS) - || CHECK_OPT(EECLASSES) - || CHECK_OPT(METHODTABLES))) - { - // Lookup entry in the array via the index we have. - typename HASH_CLASS::PTR_PersistedEntry pEntry(PTR_TO_TADDR(pTable->GetPersistedEntries(pEntries)) + - (dwEntryId * sizeof(typename HASH_CLASS::PersistedEntry))); - - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayStartStructure("PersistedEntry", - DPtrToPreferredAddr(pEntry), - sizeof(typename HASH_CLASS::PersistedEntry), SLIM_MODULE_TBLS); - } - - // Display entry via a member function specific to the type of hash table we're traversing. Each - // sub-class of NgenHash hash its own entry structure that is embedded NgenHash's entry. The - // helper function expects a pointer to this inner entry. - DPTR(HASH_ENTRY_CLASS) pInnerEntry(PTR_TO_MEMBER_TADDR(typename HASH_CLASS::PersistedEntry, pEntry, m_sValue)); - (this->*DisplayEntryFunction)(pContext, pInnerEntry, saveClasses); - - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayWriteFieldUInt(m_iHashValue, pEntry->m_iHashValue, - typename HASH_CLASS::PersistedEntry, SLIM_MODULE_TBLS); - - DisplayEndStructure(SLIM_MODULE_TBLS); // Entry - } - - dwEntryId++; - cEntries--; - } - } - - DisplayEndArray("Total Entries", SLIM_MODULE_TBLS); // Entry array -} - -void NativeImageDumper::TraverseClassHashEntry(void *pContext, PTR_EEClassHashEntry pEntry, bool saveClasses) -{ - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayStartStructure("EEClassHashEntry", - DPtrToPreferredAddr(pEntry), - sizeof(EEClassHashEntry), SLIM_MODULE_TBLS); - } - - size_t datum = size_t(PTR_TO_TADDR(pEntry->GetData())); - - if (datum & EECLASSHASH_TYPEHANDLE_DISCR) - { - IF_OPT(SLIM_MODULE_TBLS) - { - /* REVISIT_TODO Tue 10/25/2005 - * Raw data with annotation? - */ - mdTypeDef tk; - tk = EEClassHashTable::UncompressModuleAndClassDef(pEntry->GetData()); - DoWriteFieldMDToken("Token", - offsetof(EEClassHashEntry, m_Data), - fieldsize(EEClassHashEntry, m_Data), - tk); - } - } - else - { - PTR_MethodTable pMT(TO_TADDR(datum)); - IF_OPT(SLIM_MODULE_TBLS) - { - DoWriteFieldMethodTable("MethodTable", - offsetof(EEClassHashEntry, m_Data), - fieldsize(EEClassHashEntry, m_Data), - pMT); - } - - if (saveClasses) - { - // These are MethodTables. Get back to the EEClass from there. - if (isInRange(PTR_TO_TADDR(pMT))) - m_discoveredMTs.AppendEx(pMT); - if (pMT != NULL) - { - PTR_EEClass pClass = GetClassFromMT(pMT); - if (isInRange(PTR_TO_TADDR(pClass))) - m_discoveredClasses.AppendEx(pMT); - } - } - } - - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayWriteFieldPointer(m_pEncloser, - DPtrToPreferredAddr(pEntry->GetEncloser()), - EEClassHashEntry, SLIM_MODULE_TBLS); - DisplayEndStructure(SLIM_MODULE_TBLS); - } -} - -void NativeImageDumper::TraverseClassHash(PTR_EEClassHashTable pTable, - const char * name, - unsigned offset, - unsigned fieldSize, - bool saveClasses) -{ - TraverseNgenHash(pTable, - name, - offset, - fieldSize, - saveClasses, - &NativeImageDumper::TraverseClassHashEntry, - NULL); -} - -#ifdef FEATURE_COMINTEROP - -void NativeImageDumper::TraverseGuidToMethodTableEntry(void *pContext, PTR_GuidToMethodTableEntry pEntry, bool saveClasses) -{ - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayStartStructure("GuidToMethodTableEntry", - DPtrToPreferredAddr(pEntry), - sizeof(GuidToMethodTableEntry), SLIM_MODULE_TBLS); - } - - WriteFieldMethodTable(m_pMT, pEntry->m_pMT, GuidToMethodTableEntry, ALWAYS); - - TempBuffer buf; - GuidToString( *(pEntry->m_Guid), buf ); - DisplayWriteFieldStringW( m_Guid, (const WCHAR *)buf, GuidToMethodTableEntry, ALWAYS ); - - DisplayEndStructure( SLIM_MODULE_TBLS ); -} - -void NativeImageDumper::TraverseGuidToMethodTableHash(PTR_GuidToMethodTableHashTable pTable, - const char * name, - unsigned offset, - unsigned fieldSize, - bool saveClasses) -{ - TraverseNgenHash(pTable, - name, - offset, - fieldSize, - saveClasses, - &NativeImageDumper::TraverseGuidToMethodTableEntry, - NULL); -} - -#endif // FEATURE_COMINTEROP - -void NativeImageDumper::TraverseMemberRefToDescHashEntry(void *pContext, PTR_MemberRefToDescHashEntry pEntry, bool saveClasses) -{ - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayStartStructure("MemberRefToDescHashEntry", - DPtrToPreferredAddr(pEntry), - sizeof(MemberRefToDescHashEntry), SLIM_MODULE_TBLS); - } - - if(pEntry->m_value & IS_FIELD_MEMBER_REF) - WriteFieldFieldDesc(m_value, dac_cast(pEntry->m_value & (~MEMBER_REF_MAP_ALL_FLAGS)), MemberRefToDescHashEntry, MODULE_TABLES); - else - WriteFieldMethodDesc(m_value, dac_cast(pEntry->m_value), MemberRefToDescHashEntry, MODULE_TABLES); - - DisplayEndStructure( SLIM_MODULE_TBLS ); -} - -void NativeImageDumper::TraverseMemberRefToDescHash(PTR_MemberRefToDescHashTable pTable, - const char * name, - unsigned offset, - unsigned fieldSize, - bool saveClasses) -{ - TraverseNgenHash(pTable, - name, - offset, - fieldSize, - saveClasses, - &NativeImageDumper::TraverseMemberRefToDescHashEntry, - NULL); -} - - -void NativeImageDumper::TraverseTypeHashEntry(void *pContext, PTR_EETypeHashEntry pEntry, bool saveClasses) -{ - TypeHandle th = pEntry->GetTypeHandle(); - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayStartStructure("EETypeHashEntry", - DPtrToPreferredAddr(pEntry), - sizeof(EETypeHashEntry), SLIM_MODULE_TBLS); - - DoWriteFieldTypeHandle("TypeHandle", - offsetof(EETypeHashEntry, m_data), - fieldsize(EETypeHashEntry, m_data), - th); - } - - if (!CORCOMPILE_IS_POINTER_TAGGED(th.AsTAddr()) && th.IsTypeDesc()) - { - PTR_TypeDesc td(th.AsTypeDesc()); - if (isInRange(PTR_TO_TADDR(td))) - m_discoveredTypeDescs.AppendEx(td); - if (td->HasTypeParam()) - { - PTR_ParamTypeDesc ptd(td); - - /* REVISIT_TODO Thu 12/15/2005 - * Check OwnsTemplateMethodTable. However, this asserts in - * this special completely unrestored and messed up state - * (also, it chases through MT->GetClass()). There isn't - * all that much harm here (bloats m_discoveredMTs though, - * but not by a huge amount. - */ - PTR_MethodTable mt(ptd->GetTemplateMethodTableInternal()); - if (isInRange(PTR_TO_TADDR(mt))) - { - m_discoveredMTs.AppendEx(mt); - if (mt->IsClassPointerValid()) - { - PTR_EEClass pClass = mt->GetClass(); - if (isInRange(PTR_TO_TADDR(pClass))) - m_discoveredClasses.AppendEx(mt); - } - } - } - } - else - { - PTR_MethodTable mt(th.AsTAddr()); - - if (isInRange( PTR_TO_TADDR(mt))) - m_discoveredMTs.AppendEx(mt); - //don't use GetClassFromMT here. mt->m_pEEClass might be a - //fixup. In that case, just skip it. - if (mt->IsClassPointerValid()) - { - PTR_EEClass pClass = mt->GetClass(); - if (isInRange(PTR_TO_TADDR(pClass))) - m_discoveredClasses.AppendEx(mt); - } - } - - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayEndStructure(SLIM_MODULE_TBLS); - } -} - -void NativeImageDumper::TraverseTypeHash(PTR_EETypeHashTable pTable, - const char * name, - unsigned offset, - unsigned fieldSize) -{ - TraverseNgenHash(pTable, - name, - offset, - fieldSize, - true, - &NativeImageDumper::TraverseTypeHashEntry, - NULL); -} - -void NativeImageDumper::TraverseInstMethodHashEntry(void *pContext, PTR_InstMethodHashEntry pEntry, bool saveClasses) -{ - PTR_Module pModule((TADDR)pContext); - - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayStartStructure("InstMethodHashEntry", - DPtrToPreferredAddr(pEntry), - sizeof(InstMethodHashEntry), SLIM_MODULE_TBLS); - } - - IF_OPT_OR(SLIM_MODULE_TBLS, METHODDESCS) - { - IF_OPT(METHODDESCS) - { - PTR_MethodDesc md = pEntry->GetMethod(); - _ASSERTE(md != NULL); - - //if we want methoddescs, write the data field as a - //structure with the whole contents of the method desc. - m_display->StartVStructureWithOffset("data", offsetof(InstMethodHashEntry, data), - sizeof(pEntry->data)); - DumpMethodDesc(md, pModule); - DisplayEndVStructure(ALWAYS); //data - } - else - { - PTR_MethodDesc md = pEntry->GetMethod(); - WriteFieldMethodDesc(data, md, - InstMethodHashEntry, ALWAYS); - } - } - else - CoverageRead(PTR_TO_TADDR(pEntry), sizeof(*pEntry)); - - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayEndStructure(SLIM_MODULE_TBLS); - } -} - -void NativeImageDumper::TraverseStubMethodHashEntry(void *pContext, PTR_StubMethodHashEntry pEntry, bool saveClasses) -{ - PTR_Module pModule((TADDR)pContext); - - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayStartStructure("StubMethodHashEntry", - DPtrToPreferredAddr(pEntry), - sizeof(StubMethodHashEntry), SLIM_MODULE_TBLS); - } - - IF_OPT_OR(SLIM_MODULE_TBLS, METHODDESCS) - { - PTR_MethodDesc md = pEntry->GetMethod(); - _ASSERTE(md != NULL); - - PTR_MethodDesc stub = pEntry->GetStubMethod(); - _ASSERTE(stub != NULL); - - IF_OPT(METHODDESCS) - { - //if we want methoddescs, write the data fields as a - //structure with the whole contents of the method desc. - m_display->StartVStructureWithOffset("pMD", offsetof(StubMethodHashEntry, pMD), - sizeof(pEntry->pMD)); - DumpMethodDesc(md, pModule); - DisplayEndVStructure(ALWAYS); //pMD - - m_display->StartVStructureWithOffset("pStubMD", offsetof(StubMethodHashEntry, pStubMD), - sizeof(pEntry->pStubMD)); - DumpMethodDesc(stub, pModule); - DisplayEndVStructure(ALWAYS); //pStubMD - } - else - { - WriteFieldMethodDesc(pMD, md, - StubMethodHashEntry, ALWAYS); - WriteFieldMethodDesc(pStubMD, stub, - StubMethodHashEntry, ALWAYS); - } - } - else - CoverageRead(PTR_TO_TADDR(pEntry), sizeof(*pEntry)); - - IF_OPT(SLIM_MODULE_TBLS) - { - DisplayEndStructure(SLIM_MODULE_TBLS); - } -} - -void NativeImageDumper::TraverseInstMethodHash(PTR_InstMethodHashTable pTable, - const char * name, - unsigned fieldOffset, - unsigned fieldSize, - PTR_Module module) -{ - TraverseNgenHash(pTable, - name, - fieldOffset, - fieldSize, - true, - &NativeImageDumper::TraverseInstMethodHashEntry, - (void*)dac_cast(module)); -} - -void NativeImageDumper::TraverseStubMethodHash(PTR_StubMethodHashTable pTable, - const char * name, - unsigned fieldOffset, - unsigned fieldSize, - PTR_Module module) -{ - TraverseNgenHash(pTable, - name, - fieldOffset, - fieldSize, - true, - &NativeImageDumper::TraverseStubMethodHashEntry, - (void*)dac_cast(module)); -} - -const NativeImageDumper::Dependency * -NativeImageDumper::GetDependencyForModule( PTR_Module module ) -{ - for( COUNT_T i = 0; i < m_numDependencies; ++i ) - { - if( m_dependencies[i].pModule == module ) - return &m_dependencies[i]; - } - return NULL; -} - -#if 0 -const NativeImageDumper::Import * -NativeImageDumper::GetImportForPointer( TADDR ptr ) -{ - for( int i = 0; i < m_numImports; ++i ) - { - const Import * import = &m_imports[i]; - if( import->dependency->pPreferredBase == NULL ) - continue; - if( import->dependency->pPreferredBase <= ptr - && ((import->dependency->pPreferredBase - + import->dependency->size) > ptr) ) - { - //found the right target - return import; - } - } - return NULL; -} -#endif -const NativeImageDumper::Dependency * -NativeImageDumper::GetDependencyForPointer( TADDR ptr ) -{ - for( COUNT_T i = 0; i < m_numDependencies; ++i ) - { - const Dependency * dependency = &m_dependencies[i]; - if( dependency->pLoadedAddress == NULL ) - continue; - if( dependency->pLoadedAddress <= ptr - && ((dependency->pLoadedAddress + dependency->size) > ptr) ) - { - //found the right target - return dependency; - } - } - return NULL; -} - -void NativeImageDumper::DictionaryToArgString( PTR_Dictionary dictionary, unsigned numArgs, SString& buf ) -{ - //this can be called with numArgs == 0 for value type instantiations. - buf.Append( W("<") ); - - for( unsigned i = 0; i < numArgs; ++i ) - { - if( i > 0 ) - buf.Append( W(",") ); - - TypeHandle th = dictionary->GetInstantiation()[i].GetValue(); - if( CORCOMPILE_IS_POINTER_TAGGED(th.AsTAddr()) ) - { - if (!isSelf(GetDependencyForPointer(PTR_TO_TADDR(dictionary)))) - { - //this is an RVA from another hardbound dependency. We cannot decode it - buf.Append(W("OUT_OF_MODULE_FIXUP")); - } - else - { - RVA rva = CORCOMPILE_UNTAG_TOKEN(th.AsTAddr()); - FixupBlobToString(rva, buf); - } - } - else - { - TypeHandleToString( th, buf ); - } - } - buf.Append( W(">") ); -} - -void NativeImageDumper::MethodTableToString( PTR_MethodTable mt, SString& buf ) -{ - bool hasCompleteExtents = true; - IF_OPT(DISABLE_NAMES) - { - buf.Append( W("Disabled") ); - return; - } - mdToken token = mdTokenNil; - if( mt == NULL ) - buf.Append( W("mdTypeDefNil") ); - else - { - _ASSERTE(!CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(mt))); - const Dependency * dependency; - if( !mt->IsClassPointerValid() ) - { - if( isSelf(GetDependencyForPointer(PTR_TO_TADDR(mt))) ) - { - - hasCompleteExtents = false; - RVA rva = CORCOMPILE_UNTAG_TOKEN(mt->GetCanonicalMethodTableFixup()); - PTR_CCOR_SIGNATURE sig = (TADDR) m_decoder.GetRvaData(rva); - - BYTE kind = *sig++; - - if (kind & ENCODE_MODULE_OVERRIDE) - { - /* int moduleIndex = */ DacSigUncompressData(sig); - kind &= ~ENCODE_MODULE_OVERRIDE; - } - - _ASSERTE(kind == ENCODE_TYPE_HANDLE); - CorElementType et = DacSigUncompressElementType(sig); - if( et == ELEMENT_TYPE_GENERICINST ) - { - //generic instances have another element type - et = DacSigUncompressElementType(sig); - } - if (et == ELEMENT_TYPE_VALUETYPE || et == ELEMENT_TYPE_CLASS) - { - token = DacSigUncompressToken(sig); - } - else - { - // Arrays, etc. - token = mdtTypeDef; - } - dependency = GetDependencyForFixup(rva); - } - else - { - //this is an RVA from another hardbound dependency. We cannot decode it - buf.Append(W("OUT_OF_MODULE_FIXUP")); - return; - } - } - else - { - token = mt->GetCl(); - dependency = GetDependencyFromMT(mt); - } - - if( !isSelf(dependency) ) - { - AppendTokenName( dependency->entry->dwAssemblyRef, buf, - m_manifestImport ); - buf.Append(W("!")); - } - - _ASSERTE(dependency->pImport); - if( token == mdtTypeDef ) - buf.Append( W("No Token") ); - else - AppendTokenName( token, buf, dependency->pImport ); - - if( mt->HasPerInstInfo() ) - { - unsigned numDicts; - if( hasCompleteExtents ) - { - numDicts = mt->GetNumDicts(); - _ASSERTE(numDicts == CountDictionariesInClass(token, dependency->pImport)); - } - else - { - numDicts = (DWORD)CountDictionariesInClass(token, dependency->pImport); - } - - TADDR base = dac_cast(&(mt->GetPerInstInfo()[numDicts-1])); - - PTR_Dictionary dictionary( MethodTable::PerInstInfoElem_t::GetValueAtPtr(base) ); - unsigned numArgs = mt->GetNumGenericArgs(); - - DictionaryToArgString( dictionary, numArgs, buf ); - } - } -} - -mdToken NativeImageDumper::ConvertToTypeDef( mdToken typeToken, IMetaDataImport2* (&pImport) ) -{ - _ASSERTE( (TypeFromToken(typeToken) == mdtTypeDef) || (TypeFromToken(typeToken) == mdtTypeRef) - || (TypeFromToken(typeToken) == mdtTypeSpec) ); - if( mdtTypeDef == TypeFromToken(typeToken) ) - return typeToken; - if( mdtTypeRef == TypeFromToken(typeToken) ) - { - //convert the ref to a def. - mdToken scope; - WCHAR trName[MAX_CLASS_NAME]; - ULONG trNameLen; - IfFailThrow(pImport->GetTypeRefProps(typeToken, &scope, trName, _countof(trName), &trNameLen)); - _ASSERTE(trName[trNameLen-1] == 0); - - //scope is now a moduleRef or assemblyRef. Find the IMetaData import for that Ref - /* REVISIT_TODO Fri 10/6/2006 - * How do I handle moduleRefs? - */ - _ASSERTE(TypeFromToken(scope) == mdtAssemblyRef); - ReleaseHolder pAssemblyImport; - IfFailThrow(pImport->QueryInterface(IID_IMetaDataAssemblyImport, - (void **)&pAssemblyImport)); - NativeImageDumper::Dependency * dep = GetDependency(scope, pAssemblyImport); - - pImport = dep->pImport; - - /* REVISIT_TODO Fri 10/6/2006 - * Does this work for inner types? - */ - //now I have the correct MetaData. Find the typeDef - HRESULT hr = pImport->FindTypeDefByName(trName, mdTypeDefNil, &typeToken); - while (hr == CLDB_E_RECORD_NOTFOUND) - { - // No matching TypeDef, try ExportedType - pAssemblyImport = NULL; - IfFailThrow(pImport->QueryInterface(IID_IMetaDataAssemblyImport, - (void **)&pAssemblyImport)); - mdExportedType tkExportedType = mdExportedTypeNil; - IfFailThrow(pAssemblyImport->FindExportedTypeByName(trName, mdExportedTypeNil, &tkExportedType)); - mdToken tkImplementation; - IfFailThrow(pAssemblyImport->GetExportedTypeProps(tkExportedType, NULL, 0, NULL, &tkImplementation, NULL, NULL)); - dep = GetDependency(tkImplementation, pAssemblyImport); - - pImport = dep->pImport; - hr = pImport->FindTypeDefByName(trName, mdTypeDefNil, &typeToken); - } - IfFailThrow(hr); - } - else - { - PCCOR_SIGNATURE pSig; - ULONG cbSig; - IfFailThrow(pImport->GetTypeSpecFromToken(typeToken, &pSig, &cbSig)); - //GENERICINST (CLASS|VALUETYPE) typeDefOrRef - CorElementType et = CorSigUncompressElementType(pSig); - _ASSERTE(et == ELEMENT_TYPE_GENERICINST); - et = CorSigUncompressElementType(pSig); - _ASSERTE((et == ELEMENT_TYPE_CLASS) || (et == ELEMENT_TYPE_VALUETYPE)); - typeToken = CorSigUncompressToken(pSig); - } - - //we just removed one level of indirection. We still might have a ref or spec. - typeToken = ConvertToTypeDef(typeToken, pImport); - _ASSERTE(TypeFromToken(typeToken) == mdtTypeDef); - return typeToken; -} - -SIZE_T NativeImageDumper::CountDictionariesInClass( mdToken typeToken, IMetaDataImport2 * pImport ) -{ - SIZE_T myDicts; //either 0 or 1 - - _ASSERTE((TypeFromToken(typeToken) == mdtTypeDef) || (TypeFromToken(typeToken) == mdtTypeRef) - || (TypeFromToken(typeToken) == mdtTypeSpec)); - - - //for refs and specs, convert to a def. This is a nop for defs. - typeToken = ConvertToTypeDef(typeToken, pImport); - - _ASSERTE(TypeFromToken(typeToken) == mdtTypeDef); - - - //count the number of generic arguments. If there are any, then we have a dictionary. - HCORENUM hEnum = NULL; - mdGenericParam params[2]; - ULONG numParams = 0; - IfFailThrow(pImport->EnumGenericParams(&hEnum, typeToken, params, _countof(params), &numParams)); - myDicts = (numParams > 0) ? 1 : 0; - - pImport->CloseEnum(hEnum); - - //get my parent for the recursive call. - mdToken parent; - IfFailThrow(pImport->GetTypeDefProps(typeToken, NULL, 0, NULL, NULL, &parent)); - return myDicts + (IsNilToken(parent) ? 0 : CountDictionariesInClass(parent, pImport)); -} - -const NativeImageDumper::EnumMnemonics s_Subsystems[] = -{ -#define S_ENTRY(f,v) NativeImageDumper::EnumMnemonics(f, 0, v) - S_ENTRY(IMAGE_SUBSYSTEM_UNKNOWN, W("Unknown")), - S_ENTRY(IMAGE_SUBSYSTEM_NATIVE, W("Native")), - S_ENTRY(IMAGE_SUBSYSTEM_WINDOWS_CUI, W("Windows CUI")), - S_ENTRY(IMAGE_SUBSYSTEM_WINDOWS_GUI, W("Windows GUI")), - S_ENTRY(IMAGE_SUBSYSTEM_OS2_CUI, W("OS/2 CUI")), - S_ENTRY(IMAGE_SUBSYSTEM_POSIX_CUI, W("POSIX CUI")), - S_ENTRY(IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, W("WinCE GUI")), - S_ENTRY(IMAGE_SUBSYSTEM_XBOX, W("XBox")) -#undef S_ENTRY -}; - -const NativeImageDumper::EnumMnemonics s_CorCompileHdrFlags[] = -{ -#define CCHF_ENTRY(f) NativeImageDumper::EnumMnemonics(f, W(#f)) - CCHF_ENTRY(CORCOMPILE_HEADER_HAS_SECURITY_DIRECTORY), - CCHF_ENTRY(CORCOMPILE_HEADER_IS_IBC_OPTIMIZED), - CCHF_ENTRY(CORCOMPILE_HEADER_IS_READY_TO_RUN), -#undef CCHF_ENTRY -}; - -const NativeImageDumper::EnumMnemonics s_CorPEKind[] = -{ -#define CPEK_ENTRY(f) NativeImageDumper::EnumMnemonics(f, W(#f)) - CPEK_ENTRY(peNot), - CPEK_ENTRY(peILonly), - CPEK_ENTRY(pe32BitRequired), - CPEK_ENTRY(pe32Plus), - CPEK_ENTRY(pe32Unmanaged), - CPEK_ENTRY(pe32BitPreferred) -#undef CPEK_ENTRY -}; -const NativeImageDumper::EnumMnemonics s_IFH_Machine[] = -{ -#define IFH_ENTRY(f) NativeImageDumper::EnumMnemonics(f, 0, W(#f)) - IFH_ENTRY(IMAGE_FILE_MACHINE_UNKNOWN), - IFH_ENTRY(IMAGE_FILE_MACHINE_I386), - IFH_ENTRY(IMAGE_FILE_MACHINE_AMD64), - IFH_ENTRY(IMAGE_FILE_MACHINE_ARMNT), -#undef IFH_ENTRY -}; - -const NativeImageDumper::EnumMnemonics s_IFH_Characteristics[] = -{ -#define IFH_ENTRY(f) NativeImageDumper::EnumMnemonics(f, W(#f)) - IFH_ENTRY(IMAGE_FILE_RELOCS_STRIPPED), - IFH_ENTRY(IMAGE_FILE_EXECUTABLE_IMAGE), - IFH_ENTRY(IMAGE_FILE_LINE_NUMS_STRIPPED), - IFH_ENTRY(IMAGE_FILE_LOCAL_SYMS_STRIPPED), - IFH_ENTRY(IMAGE_FILE_AGGRESIVE_WS_TRIM), - IFH_ENTRY(IMAGE_FILE_LARGE_ADDRESS_AWARE), - IFH_ENTRY(IMAGE_FILE_BYTES_REVERSED_LO), - IFH_ENTRY(IMAGE_FILE_32BIT_MACHINE), - IFH_ENTRY(IMAGE_FILE_DEBUG_STRIPPED), - IFH_ENTRY(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP), - IFH_ENTRY(IMAGE_FILE_NET_RUN_FROM_SWAP), - IFH_ENTRY(IMAGE_FILE_SYSTEM), - IFH_ENTRY(IMAGE_FILE_DLL), - IFH_ENTRY(IMAGE_FILE_UP_SYSTEM_ONLY), - IFH_ENTRY(IMAGE_FILE_BYTES_REVERSED_HI), -#undef IFH_ENTRY -}; - -const NativeImageDumper::EnumMnemonics s_ImportSectionType[] = -{ -#define IST_ENTRY(f) NativeImageDumper::EnumMnemonics(f, 0, W(#f)) - IST_ENTRY(CORCOMPILE_IMPORT_TYPE_UNKNOWN), - IST_ENTRY(CORCOMPILE_IMPORT_TYPE_EXTERNAL_METHOD), - IST_ENTRY(CORCOMPILE_IMPORT_TYPE_STUB_DISPATCH), - IST_ENTRY(CORCOMPILE_IMPORT_TYPE_STRING_HANDLE), - IST_ENTRY(CORCOMPILE_IMPORT_TYPE_TYPE_HANDLE), - IST_ENTRY(CORCOMPILE_IMPORT_TYPE_METHOD_HANDLE), - IST_ENTRY(CORCOMPILE_IMPORT_TYPE_VIRTUAL_METHOD), -#undef IST_ENTRY -}; - -const NativeImageDumper::EnumMnemonics s_ImportSectionFlags[] = -{ -#define IST_FLAGS(f) NativeImageDumper::EnumMnemonics(f, W(#f)) - IST_FLAGS(CORCOMPILE_IMPORT_FLAGS_EAGER), - IST_FLAGS(CORCOMPILE_IMPORT_FLAGS_CODE), - IST_FLAGS(CORCOMPILE_IMPORT_FLAGS_PCODE), -#undef IST_FLAGS -}; - -void NativeImageDumper::DumpNativeHeader() -{ - PTR_CORCOMPILE_HEADER nativeHeader(m_decoder.GetNativeHeader()); - - IF_OPT(NATIVE_INFO) - { - -#define WRITE_NATIVE_FIELD( name ) m_display->WriteFieldAddress(\ - # name, offsetof(CORCOMPILE_HEADER, name), \ - fieldsize(CORCOMPILE_HEADER, name), \ - RvaToDisplay( nativeHeader-> name . VirtualAddress ), \ - nativeHeader-> name . Size ) - - m_display->StartStructure( "CORCOMPILE_HEADER", - DPtrToPreferredAddr(nativeHeader), - sizeof(*nativeHeader) ); - - DisplayWriteFieldUInt( Signature, nativeHeader->Signature, CORCOMPILE_HEADER, ALWAYS ); - DisplayWriteFieldUInt( MajorVersion, nativeHeader->MajorVersion, CORCOMPILE_HEADER, ALWAYS ); - DisplayWriteFieldUInt( MinorVersion, nativeHeader->MinorVersion, CORCOMPILE_HEADER, ALWAYS ); - - WRITE_NATIVE_FIELD(HelperTable); - - WRITE_NATIVE_FIELD(ImportSections); - PTR_CORCOMPILE_IMPORT_SECTION pImportSections = - nativeHeader->ImportSections.VirtualAddress - + PTR_TO_TADDR(m_decoder.GetBase()); - DisplayStartArray( "ImportSections", NULL, ALWAYS ); - for( COUNT_T i = 0; i < nativeHeader->ImportSections.Size - / sizeof(*pImportSections); ++i ) - { - DisplayStartStructure( "CORCOMPILE_IMPORT_SECTION", - DPtrToPreferredAddr(pImportSections + i), - sizeof(pImportSections[i]), ALWAYS ); - DisplayWriteElementAddress( "Section", - RvaToDisplay(pImportSections[i].Section.VirtualAddress), - pImportSections[i].Section.Size, ALWAYS ); - - DisplayWriteFieldEnumerated( Flags, pImportSections[i].Flags, - CORCOMPILE_IMPORT_SECTION, s_ImportSectionFlags, W(", "), ALWAYS ); - DisplayWriteFieldEnumerated( Type, pImportSections[i].Type, - CORCOMPILE_IMPORT_SECTION, s_ImportSectionType, W(""), ALWAYS ); - - DisplayWriteFieldUInt( EntrySize, pImportSections[i].EntrySize, - CORCOMPILE_IMPORT_SECTION, ALWAYS ); - DisplayWriteFieldUInt( Signatures, pImportSections[i].Signatures, - CORCOMPILE_IMPORT_SECTION, ALWAYS ); - DisplayWriteFieldUInt( AuxiliaryData, pImportSections[i].AuxiliaryData, - CORCOMPILE_IMPORT_SECTION, ALWAYS ); - DisplayEndStructure( ALWAYS ); //PTR_CORCOMPILE_IMPORT_SECTION - - } - DisplayEndArray( NULL, ALWAYS ); //delayLoads - - WRITE_NATIVE_FIELD(VersionInfo); - WRITE_NATIVE_FIELD(DebugMap); - WRITE_NATIVE_FIELD(ModuleImage); - WRITE_NATIVE_FIELD(CodeManagerTable); - WRITE_NATIVE_FIELD(ProfileDataList); - WRITE_NATIVE_FIELD(ManifestMetaData); - - WRITE_NATIVE_FIELD(VirtualSectionsTable); - DisplayStartArray( "VirtualSections", W("%-48s%s"), SLIM_MODULE_TBLS ); - PTR_CORCOMPILE_VIRTUAL_SECTION_INFO sects( nativeHeader->VirtualSectionsTable.VirtualAddress + PTR_TO_TADDR(m_decoder.GetBase()) ); - COUNT_T numVirtualSections = nativeHeader->VirtualSectionsTable.Size / sizeof (CORCOMPILE_VIRTUAL_SECTION_INFO); - - for( COUNT_T i = 0; i < numVirtualSections; ++i ) - { - TempBuffer sectionNameBuf; - TempBuffer sectionFlags; - StackScratchBuffer scratch; - - sectionNameBuf.Append(g_sectionNames[VirtualSectionData::VirtualSectionType(sects[i].SectionType)]); - - EnumFlagsToString( sects[i].SectionType, s_virtualSectionFlags, dim(s_virtualSectionFlags), - W(" | "), sectionFlags); - - sectionNameBuf.Append(W(" [")); - sectionNameBuf.Append(sectionFlags); - sectionNameBuf.Append(W("]")); - - DisplayStartElement( "Section", SLIM_MODULE_TBLS ); - DisplayWriteElementString("Name", sectionNameBuf.GetANSI(scratch), SLIM_MODULE_TBLS); - - DisplayWriteElementAddress( "Address", - RvaToDisplay(sects[i].VirtualAddress), - sects[i].Size, - SLIM_MODULE_TBLS ); - DisplayEndElement( SLIM_MODULE_TBLS ); //Section - } - DisplayEndArray( "Total VirtualSections", SLIM_MODULE_TBLS ); - - WRITE_NATIVE_FIELD(EEInfoTable); - -#undef WRITE_NATIVE_FIELD - DisplayWriteFieldEnumerated( Flags, nativeHeader->Flags, - CORCOMPILE_HEADER, s_CorCompileHdrFlags, W(", "), - NATIVE_INFO ); - - DisplayWriteFieldEnumerated( PEKind, nativeHeader->PEKind, - CORCOMPILE_HEADER, s_CorPEKind, W(", "), - NATIVE_INFO ); - - DisplayWriteFieldEnumerated( COR20Flags, nativeHeader->COR20Flags, - CORCOMPILE_HEADER, s_CorHdrFlags, W(", "), - NATIVE_INFO ); - - DisplayWriteFieldEnumerated( Machine, nativeHeader->Machine, - CORCOMPILE_HEADER, s_IFH_Machine, - W(""), NATIVE_INFO ); - DisplayWriteFieldEnumerated( Characteristics, - nativeHeader->Characteristics, - CORCOMPILE_HEADER, s_IFH_Characteristics, - W(", "), NATIVE_INFO ); - - m_display->EndStructure(); //CORCOMPILE_HEADER - } -} - -const NativeImageDumper::EnumMnemonics s_RelocType[] = -{ -#define REL_ENTRY(x) NativeImageDumper::EnumMnemonics( x, 0, W(#x)) - REL_ENTRY(IMAGE_REL_BASED_ABSOLUTE), - REL_ENTRY(IMAGE_REL_BASED_HIGHLOW), - REL_ENTRY(IMAGE_REL_BASED_DIR64), - REL_ENTRY(IMAGE_REL_BASED_THUMB_MOV32), -#undef REL_ENTRY -}; - -void NativeImageDumper::DumpBaseRelocs() -{ - COUNT_T size; - TADDR data; - - data = m_decoder.GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_BASERELOC, &size); - - if (size != 0) - { - DisplayStartStructure( "Relocations", DataPtrToDisplay(data), size, - ALWAYS ); - - while (size != 0) - { - IMAGE_BASE_RELOCATION * pBaseRelocation = dac_cast(data); - _ASSERTE(size >= pBaseRelocation->SizeOfBlock); - - SIZE_T rel = sizeof(IMAGE_BASE_RELOCATION); - while (rel < pBaseRelocation->SizeOfBlock) - { - USHORT typeOffset = *PTR_USHORT(data + rel); - - DisplayStartElement( "Entry", ALWAYS ); - - DisplayWriteElementPointer( "Address", RvaToDisplay(pBaseRelocation->VirtualAddress + (typeOffset & 0xFFF)), ALWAYS ); - - DisplayWriteElementEnumerated( "Type", (typeOffset >> 12), - s_RelocType, W(", "), ALWAYS ); - - DisplayEndElement( ALWAYS ); //Entry - - rel += sizeof(USHORT); - } - - data += pBaseRelocation->SizeOfBlock; - size -= pBaseRelocation->SizeOfBlock; - } - - DisplayEndStructure( ALWAYS ); //Relocations - } -} - -void NativeImageDumper::DumpHelperTable() -{ - COUNT_T size; - TADDR data; - - data = TO_TADDR(m_decoder.GetNativeHelperTable(&size)); - if( size != 0 ) - { - DisplayStartStructure( "HelperTable", DataPtrToDisplay(data), size, - ALWAYS ); - - TADDR curEntry = data; - TADDR tableEnd = data + size; - - while (curEntry < tableEnd) - { - DWORD dwHelper = *PTR_DWORD(curEntry); - - int iHelper = (USHORT)dwHelper; - _ASSERTE(iHelper < CORINFO_HELP_COUNT); - - DisplayStartStructure( "Helper", - DataPtrToDisplay(curEntry), (dwHelper & CORCOMPILE_HELPER_PTR) ? sizeof(TADDR) : HELPER_TABLE_ENTRY_LEN, - ALWAYS ); - - DisplayWriteElementUInt( "dwHelper", dwHelper, ALWAYS ); - DisplayWriteElementString( "Name", g_helperNames[iHelper], ALWAYS ); - - DisplayEndStructure( ALWAYS ); //Helper - - curEntry += (dwHelper & CORCOMPILE_HELPER_PTR) ? sizeof(TADDR) : HELPER_TABLE_ENTRY_LEN; - } - - DisplayEndStructure( ALWAYS ); //HelperTable - } -} - -// TODO: fix these to work with the updated flags in MethodTable, AND to understand -// the new overloading of component size... - -NativeImageDumper::EnumMnemonics s_MTFlagsLow[] = -{ -#define MTFLAG_ENTRY(x) \ - NativeImageDumper::EnumMnemonics(MethodTable::enum_flag_ ## x, W(#x)) - - MTFLAG_ENTRY(UNUSED_ComponentSize_1), - MTFLAG_ENTRY(StaticsMask), - MTFLAG_ENTRY(StaticsMask_NonDynamic), - MTFLAG_ENTRY(StaticsMask_Dynamic), - MTFLAG_ENTRY(StaticsMask_Generics), - MTFLAG_ENTRY(StaticsMask_CrossModuleGenerics), - MTFLAG_ENTRY(NotInPZM), - MTFLAG_ENTRY(GenericsMask), - MTFLAG_ENTRY(GenericsMask_NonGeneric), - MTFLAG_ENTRY(GenericsMask_GenericInst), - MTFLAG_ENTRY(GenericsMask_SharedInst), - MTFLAG_ENTRY(GenericsMask_TypicalInst), - MTFLAG_ENTRY(HasVariance), - MTFLAG_ENTRY(HasDefaultCtor), - MTFLAG_ENTRY(HasPreciseInitCctors), -#if defined(FEATURE_HFA) - MTFLAG_ENTRY(IsHFA), -#endif // FEATURE_HFA -#if defined(UNIX_AMD64_ABI) - MTFLAG_ENTRY(IsRegStructPassed), -#endif // UNIX_AMD64_ABI - MTFLAG_ENTRY(IsByRefLike), - MTFLAG_ENTRY(UNUSED_ComponentSize_5), - MTFLAG_ENTRY(UNUSED_ComponentSize_6), - MTFLAG_ENTRY(UNUSED_ComponentSize_7), -#undef MTFLAG_ENTRY -}; - -NativeImageDumper::EnumMnemonics s_MTFlagsHigh[] = -{ -#define MTFLAG_ENTRY(x) \ - NativeImageDumper::EnumMnemonics(MethodTable::enum_flag_ ## x, W(#x)) - -#define MTFLAG_CATEGORY_ENTRY(x) \ - NativeImageDumper::EnumMnemonics(MethodTable::enum_flag_Category_ ## x, MethodTable::enum_flag_Category_Mask, W("Category_") W(#x)) - -#define MTFLAG_CATEGORY_ENTRY_WITH_MASK(x, m) \ - NativeImageDumper::EnumMnemonics(MethodTable::enum_flag_Category_ ## x, MethodTable::enum_flag_Category_ ## m, W("Category_") W(#x)) - - MTFLAG_CATEGORY_ENTRY(Class), - MTFLAG_CATEGORY_ENTRY(Unused_1), - MTFLAG_CATEGORY_ENTRY(Unused_2), - MTFLAG_CATEGORY_ENTRY(Unused_3), - MTFLAG_CATEGORY_ENTRY(ValueType), - MTFLAG_CATEGORY_ENTRY(Nullable), - MTFLAG_CATEGORY_ENTRY(PrimitiveValueType), - MTFLAG_CATEGORY_ENTRY(TruePrimitive), - - MTFLAG_CATEGORY_ENTRY(Interface), - MTFLAG_CATEGORY_ENTRY(Unused_4), - MTFLAG_CATEGORY_ENTRY(Unused_5), - MTFLAG_CATEGORY_ENTRY(Unused_6), - - MTFLAG_CATEGORY_ENTRY_WITH_MASK(Array, Array_Mask), - MTFLAG_CATEGORY_ENTRY_WITH_MASK(IfArrayThenSzArray, IfArrayThenSzArray), - -#undef MTFLAG_CATEGORY_ENTRY_WITH_MASK -#undef MTFLAG_CATEGORY_ENTRY - - MTFLAG_ENTRY(HasFinalizer), - MTFLAG_ENTRY(IfNotInterfaceThenMarshalable), - MTFLAG_ENTRY(IDynamicInterfaceCastable), -#if defined(FEATURE_ICASTABLE) - MTFLAG_ENTRY(ICastable), -#endif - MTFLAG_ENTRY(HasIndirectParent), - MTFLAG_ENTRY(ContainsPointers), - MTFLAG_ENTRY(HasTypeEquivalence), - MTFLAG_ENTRY(HasCriticalFinalizer), - MTFLAG_ENTRY(Collectible), - MTFLAG_ENTRY(ContainsGenericVariables), -#if defined(FEATURE_COMINTEROP) - MTFLAG_ENTRY(ComObject), -#endif - MTFLAG_ENTRY(HasComponentSize), -#undef MTFLAG_ENTRY -}; - - -NativeImageDumper::EnumMnemonics s_MTFlags2[] = -{ -#define MTFLAG2_ENTRY(x) \ - NativeImageDumper::EnumMnemonics(MethodTable::enum_flag_ ## x, W(#x)) - MTFLAG2_ENTRY(HasPerInstInfo), - MTFLAG2_ENTRY(HasInterfaceMap), - MTFLAG2_ENTRY(HasDispatchMapSlot), - MTFLAG2_ENTRY(HasNonVirtualSlots), - MTFLAG2_ENTRY(HasModuleOverride), - MTFLAG2_ENTRY(IsZapped), - MTFLAG2_ENTRY(IsPreRestored), - MTFLAG2_ENTRY(HasModuleDependencies), - MTFLAG2_ENTRY(IsIntrinsicType), - MTFLAG2_ENTRY(RequiresDispatchTokenFat), - MTFLAG2_ENTRY(HasCctor), -#ifdef FEATURE_64BIT_ALIGNMENT - MTFLAG2_ENTRY(RequiresAlign8), -#endif - MTFLAG2_ENTRY(HasBoxedRegularStatics), - MTFLAG2_ENTRY(HasSingleNonVirtualSlot), - MTFLAG2_ENTRY(DependsOnEquivalentOrForwardedStructs), -#undef MTFLAG2_ENTRY -}; - -NativeImageDumper::EnumMnemonics s_WriteableMTFlags[] = -{ -#define WMTFLAG_ENTRY(x) \ - NativeImageDumper::EnumMnemonics(MethodTableWriteableData::enum_flag_ ## x,\ - W(#x)) - - WMTFLAG_ENTRY(Unrestored), - WMTFLAG_ENTRY(HasApproxParent), - WMTFLAG_ENTRY(UnrestoredTypeKey), - WMTFLAG_ENTRY(IsNotFullyLoaded), - WMTFLAG_ENTRY(DependenciesLoaded), - -#ifdef _DEBUG - WMTFLAG_ENTRY(ParentMethodTablePointerValid), -#endif - - WMTFLAG_ENTRY(NGEN_IsFixedUp), - WMTFLAG_ENTRY(NGEN_IsNeedsRestoreCached), - WMTFLAG_ENTRY(NGEN_CachedNeedsRestore), -#undef WMTFLAG_ENTRY -}; - -static NativeImageDumper::EnumMnemonics s_CorElementType[] = -{ -#define CET_ENTRY(x) NativeImageDumper::EnumMnemonics(ELEMENT_TYPE_ ## x, 0, W("ELEMENT_TYPE_") W(#x)) - CET_ENTRY(END), - CET_ENTRY(VOID), - CET_ENTRY(BOOLEAN), - CET_ENTRY(CHAR), - CET_ENTRY(I1), - CET_ENTRY(U1), - CET_ENTRY(I2), - CET_ENTRY(U2), - CET_ENTRY(I4), - CET_ENTRY(U4), - CET_ENTRY(I8), - CET_ENTRY(U8), - CET_ENTRY(R4), - CET_ENTRY(R8), - CET_ENTRY(STRING), - CET_ENTRY(PTR), - CET_ENTRY(BYREF), - CET_ENTRY(VALUETYPE), - CET_ENTRY(CLASS), - CET_ENTRY(VAR), - CET_ENTRY(ARRAY), - CET_ENTRY(GENERICINST), - CET_ENTRY(TYPEDBYREF), - CET_ENTRY(VALUEARRAY_UNSUPPORTED), - CET_ENTRY(I), - CET_ENTRY(U), - CET_ENTRY(R_UNSUPPORTED), - CET_ENTRY(FNPTR), - CET_ENTRY(OBJECT), - CET_ENTRY(SZARRAY), - CET_ENTRY(MVAR), - CET_ENTRY(CMOD_REQD), - CET_ENTRY(CMOD_OPT), - CET_ENTRY(INTERNAL), - - CET_ENTRY(SENTINEL), - CET_ENTRY(PINNED), -#undef CET_ENTRY -}; - -void NativeImageDumper::DoWriteFieldCorElementType( const char * name, - unsigned offset, - unsigned fieldSize, - CorElementType type ) -{ - TempBuffer buf; - EnumFlagsToString( (int)type, s_CorElementType, dim(s_CorElementType), - W(""), buf ); - m_display->WriteFieldEnumerated( name, offset, fieldSize, (unsigned)type, - (const WCHAR *) buf ); - -} - -static NativeImageDumper::EnumMnemonics s_CorTypeAttr[] = -{ -#define CTA_ENTRY(x) NativeImageDumper::EnumMnemonics( x, W(#x) ) - -#define CTA_VISIBILITY_ENTRY(x) NativeImageDumper::EnumMnemonics( x, tdVisibilityMask, W(#x) ) - CTA_VISIBILITY_ENTRY(tdNotPublic), - CTA_VISIBILITY_ENTRY(tdPublic), - CTA_VISIBILITY_ENTRY(tdNestedPublic), - CTA_VISIBILITY_ENTRY(tdNestedPrivate), - CTA_VISIBILITY_ENTRY(tdNestedFamily), - CTA_VISIBILITY_ENTRY(tdNestedAssembly), - CTA_VISIBILITY_ENTRY(tdNestedFamANDAssem), - CTA_VISIBILITY_ENTRY(tdNestedFamORAssem), -#undef CTA_VISIBILITY_ENTRY - - CTA_ENTRY(tdSequentialLayout), - CTA_ENTRY(tdExplicitLayout), - - CTA_ENTRY(tdInterface), - - CTA_ENTRY(tdAbstract), - CTA_ENTRY(tdSealed), - CTA_ENTRY(tdSpecialName), - - CTA_ENTRY(tdImport), - CTA_ENTRY(tdSerializable), - - CTA_ENTRY(tdUnicodeClass), - CTA_ENTRY(tdAutoClass), - CTA_ENTRY(tdCustomFormatClass), - CTA_ENTRY(tdCustomFormatMask), - - CTA_ENTRY(tdBeforeFieldInit), - CTA_ENTRY(tdForwarder), - - CTA_ENTRY(tdRTSpecialName), - CTA_ENTRY(tdHasSecurity) -#undef CTA_ENTRY -}; -static NativeImageDumper::EnumMnemonics s_VMFlags[] = -{ -#define VMF_ENTRY(x) NativeImageDumper::EnumMnemonics( EEClass::VMFLAG_ ## x, W(#x) ) - -#ifdef FEATURE_READYTORUN - VMF_ENTRY(LAYOUT_DEPENDS_ON_OTHER_MODULES), -#endif - VMF_ENTRY(DELEGATE), - VMF_ENTRY(FIXED_ADDRESS_VT_STATICS), - VMF_ENTRY(HASLAYOUT), - VMF_ENTRY(ISNESTED), - VMF_ENTRY(IS_EQUIVALENT_TYPE), - - VMF_ENTRY(HASOVERLAYEDFIELDS), - VMF_ENTRY(HAS_FIELDS_WHICH_MUST_BE_INITED), - VMF_ENTRY(UNSAFEVALUETYPE), - - VMF_ENTRY(BESTFITMAPPING_INITED), - VMF_ENTRY(BESTFITMAPPING), - VMF_ENTRY(THROWONUNMAPPABLECHAR), - - VMF_ENTRY(NO_GUID), - VMF_ENTRY(HASNONPUBLICFIELDS), - VMF_ENTRY(PREFER_ALIGN8), - -#ifdef FEATURE_COMINTEROP - VMF_ENTRY(SPARSE_FOR_COMINTEROP), - VMF_ENTRY(HASCOCLASSATTRIB), - VMF_ENTRY(COMEVENTITFMASK), -#endif // FEATURE_COMINTEROP - - VMF_ENTRY(NOT_TIGHTLY_PACKED), - VMF_ENTRY(CONTAINS_METHODIMPLS), -#ifdef FEATURE_COMINTEROP - VMF_ENTRY(MARSHALINGTYPE_MASK), - VMF_ENTRY(MARSHALINGTYPE_INHIBIT), - VMF_ENTRY(MARSHALINGTYPE_FREETHREADED), - VMF_ENTRY(MARSHALINGTYPE_STANDARD), -#endif -#undef VMF_ENTRY -}; -static NativeImageDumper::EnumMnemonics s_CorFieldAttr[] = -{ -#define CFA_ENTRY(x) NativeImageDumper::EnumMnemonics( x, W(#x) ) - -#define CFA_ACCESS_ENTRY(x) NativeImageDumper::EnumMnemonics( x, fdFieldAccessMask, W(#x) ) - CFA_ENTRY(fdPrivateScope), - CFA_ENTRY(fdPrivate), - CFA_ENTRY(fdFamANDAssem), - CFA_ENTRY(fdAssembly), - CFA_ENTRY(fdFamily), - CFA_ENTRY(fdFamORAssem), - CFA_ENTRY(fdPublic), -#undef CFA_ACCESS_ENTRY - - CFA_ENTRY(fdStatic), - CFA_ENTRY(fdInitOnly), - CFA_ENTRY(fdLiteral), - CFA_ENTRY(fdNotSerialized), - - CFA_ENTRY(fdSpecialName), - - CFA_ENTRY(fdPinvokeImpl), - - CFA_ENTRY(fdRTSpecialName), - CFA_ENTRY(fdHasFieldMarshal), - CFA_ENTRY(fdHasDefault), - CFA_ENTRY(fdHasFieldRVA), -#undef CFA_ENTRY -}; - -NativeImageDumper::EnumMnemonics NativeImageDumper::s_MDFlag2[] = -{ -#define MDF2_ENTRY(x) NativeImageDumper::EnumMnemonics( MethodDesc::enum_flag2_ ## x, W("enum_flag2_") W(#x) ) - MDF2_ENTRY(HasStableEntryPoint), - MDF2_ENTRY(HasPrecode), - MDF2_ENTRY(IsUnboxingStub), - MDF2_ENTRY(HasNativeCodeSlot), -#undef MDF2_ENTRY -}; - -NativeImageDumper::EnumMnemonics NativeImageDumper::s_MDC[] = -{ -#define MDC_ENTRY(x) NativeImageDumper::EnumMnemonics( x, W(#x) ) - -#define MDC_ENTRY_CLASSIFICATION(x) NativeImageDumper::EnumMnemonics( x, mdcClassification, W(#x) ) - MDC_ENTRY_CLASSIFICATION(mcIL), - MDC_ENTRY_CLASSIFICATION(mcFCall), - MDC_ENTRY_CLASSIFICATION(mcNDirect), - MDC_ENTRY_CLASSIFICATION(mcEEImpl), - MDC_ENTRY_CLASSIFICATION(mcArray), - MDC_ENTRY_CLASSIFICATION(mcInstantiated), -#ifdef FEATURE_COMINTEROP - MDC_ENTRY_CLASSIFICATION(mcComInterop), -#endif // FEATURE_COMINTEROP - MDC_ENTRY_CLASSIFICATION(mcDynamic), -#undef MDC_ENTRY_CLASSIFICATION - - MDC_ENTRY(mdcHasNonVtableSlot), - MDC_ENTRY(mdcMethodImpl), - - // Method is static - MDC_ENTRY(mdcStatic), - - MDC_ENTRY(mdcDuplicate), - MDC_ENTRY(mdcVerifiedState), - MDC_ENTRY(mdcVerifiable), - MDC_ENTRY(mdcNotInline), - MDC_ENTRY(mdcSynchronized), - MDC_ENTRY(mdcRequiresFullSlotNumber), -#undef MDC_ENTRY -}; - - - -void NativeImageDumper::DumpTypes(PTR_Module module) -{ - _ASSERTE(CHECK_OPT(EECLASSES) || CHECK_OPT(METHODTABLES) - || CHECK_OPT(TYPEDESCS)); - - IF_OPT_OR3(METHODTABLES, EECLASSES, TYPEDESCS) - m_display->StartCategory( "Types" ); - IF_OPT(METHODTABLES) - { - //there may be duplicates in the list. Remove them before moving on. - COUNT_T mtCount = m_discoveredMTs.GetCount(); - -#if !defined(FEATURE_CORESYSTEM) // no STL right now - std::sort(&*m_discoveredMTs.Begin(), - (&*m_discoveredMTs.Begin()) - + (m_discoveredMTs.End() - m_discoveredMTs.Begin())); - PTR_MethodTable* newEnd = std::unique(&*m_discoveredMTs.Begin(), - (&*m_discoveredMTs.Begin()) - + (m_discoveredMTs.End() - - m_discoveredMTs.Begin())); - mtCount = (COUNT_T)(newEnd - &*m_discoveredMTs.Begin()); -#endif - - DisplayStartArray( "MethodTables", NULL, METHODTABLES ); - for(COUNT_T i = 0; i < mtCount; ++i ) - { - PTR_MethodTable mt = m_discoveredMTs[i]; - if( mt == NULL ) - continue; - DumpMethodTable( mt, "MethodTable", module ); - } - - DisplayEndArray( "Total MethodTables", METHODTABLES ); - - DisplayStartArray( "MethodTableSlotChunks", NULL, METHODTABLES ); - { - COUNT_T slotChunkCount = m_discoveredSlotChunks.GetCount(); -#if !defined(FEATURE_CORESYSTEM) // no STL right now - std::sort(&*m_discoveredSlotChunks.Begin(), - (&*m_discoveredSlotChunks.Begin()) - + (m_discoveredSlotChunks.End() - m_discoveredSlotChunks.Begin())); - SlotChunk *newEndChunks = std::unique(&*m_discoveredSlotChunks.Begin(), - (&*m_discoveredSlotChunks.Begin()) - + (m_discoveredSlotChunks.End() - m_discoveredSlotChunks.Begin())); - slotChunkCount = (COUNT_T)(newEndChunks - &*m_discoveredSlotChunks.Begin()); -#endif - - for (COUNT_T i = 0; i < slotChunkCount; ++i) - { - DumpMethodTableSlotChunk(m_discoveredSlotChunks[i].addr, - m_discoveredSlotChunks[i].nSlots, - m_discoveredSlotChunks[i].isRelative); - } - } - DisplayEndArray( "Total MethodTableSlotChunks", METHODTABLES ); - } - IF_OPT(EECLASSES) - { - DisplayStartArray( "EEClasses", NULL, EECLASSES ); - - //there may be duplicates in the list. Remove them before moving on. - COUNT_T clazzCount = m_discoveredClasses.GetCount(); -#if !defined(FEATURE_CORESYSTEM) // no STL right now - std::sort(&*m_discoveredClasses.Begin(), - (&*m_discoveredClasses.Begin()) - + (m_discoveredClasses.End() - m_discoveredClasses.Begin())); - PTR_MethodTable * newEndClazz = std::unique(&*m_discoveredClasses.Begin(), - (&*m_discoveredClasses.Begin()) - +(m_discoveredClasses.End() - -m_discoveredClasses.Begin())); - clazzCount = (COUNT_T)(newEndClazz - &*m_discoveredClasses.Begin()); -#endif - - for(COUNT_T i = 0; i < clazzCount; ++i ) - { - PTR_MethodTable mt = m_discoveredClasses[i]; - if( mt == NULL ) - continue; - DumpEEClassForMethodTable( mt ); - } - - DisplayEndArray( "Total EEClasses", EECLASSES ); //EEClasses - - } - IF_OPT(TYPEDESCS) - { - DisplayStartArray( "TypeDescs", NULL, TYPEDESCS ); - - //there may be duplicates in the list. Remove them before moving on. - COUNT_T tdCount = m_discoveredTypeDescs.GetCount(); -#if !defined(FEATURE_CORESYSTEM) // no STL right now - std::sort(&*m_discoveredTypeDescs.Begin(), - (&*m_discoveredTypeDescs.Begin()) - + (m_discoveredTypeDescs.End() - - m_discoveredTypeDescs.Begin())); - PTR_TypeDesc* newEndTD = std::unique(&*m_discoveredTypeDescs.Begin(), - (&*m_discoveredTypeDescs.Begin()) - +(m_discoveredTypeDescs.End() - -m_discoveredTypeDescs.Begin())); - tdCount = (COUNT_T)(newEndTD - &*m_discoveredTypeDescs.Begin()); -#endif - - for(COUNT_T i = 0; i < tdCount; ++i ) - { - PTR_TypeDesc td = m_discoveredTypeDescs[i]; - if( td == NULL ) - continue; - DumpTypeDesc( td ); - } - - DisplayEndArray( "Total TypeDescs", TYPEDESCS ); //EEClasses - - } - IF_OPT_OR3(EECLASSES, METHODTABLES, TYPEDESCS) - m_display->EndCategory(); //Types -} - -PTR_EEClass NativeImageDumper::GetClassFromMT( PTR_MethodTable mt ) -{ - /* REVISIT_TODO Tue 10/11/2005 - * Handle fixups - */ - _ASSERTE( mt->IsClassPointerValid() ); - PTR_EEClass clazz( mt->GetClass() ); - return clazz; -} -PTR_MethodTable NativeImageDumper::GetParent( PTR_MethodTable mt ) -{ - /* REVISIT_TODO Thu 12/01/2005 - * Handle fixups - */ - PTR_MethodTable parent( ReadPointerMaybeNull((MethodTable*) mt, &MethodTable::m_pParentMethodTable, mt->GetFlagHasIndirectParent()) ); - _ASSERTE(!CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(parent))); - return parent; -} - -//Counts the FieldDescs in a class. This is all of the non-static and static -//non-literal fields. -SIZE_T NativeImageDumper::CountFields( PTR_MethodTable mt ) -{ - SIZE_T fieldCount = 0; - - HCORENUM hEnum = NULL; - - const Dependency * dep = GetDependencyFromMT(mt); - mdToken classToken = mt->GetCl(); - - _ASSERTE(dep); - _ASSERTE(dep->pImport); - - //Arrays have no token. - if( RidFromToken(classToken) == 0 ) - return 0; - - for (;;) - { - mdToken fields[1]; - ULONG numFields; - - IfFailThrow(dep->pImport->EnumFields( &hEnum, classToken, fields, - 1, &numFields)); - - if (numFields == 0) - break; - - DWORD dwAttr; - IfFailThrow(dep->pImport->GetFieldProps( fields[0], NULL, NULL, 0, - NULL, & dwAttr, NULL, NULL, - NULL, NULL, NULL ) ); - if( !IsFdStatic(dwAttr) || !IsFdLiteral(dwAttr) ) - ++fieldCount; - } - dep->pImport->CloseEnum(hEnum); - return fieldCount; -} -const NativeImageDumper::Dependency* -NativeImageDumper::GetDependencyFromMT( PTR_MethodTable mt ) -{ - if( !mt->IsClassPointerValid() ) - { - //This code will not work for out of module dependencies. - _ASSERTE(isSelf(GetDependencyForPointer(PTR_TO_TADDR(mt)))); - - //the EEClass is a fixup. The home for that fixup tells us the - //home for the metadata. - unsigned rva = CORCOMPILE_UNTAG_TOKEN(mt->GetCanonicalMethodTableFixup()); - return GetDependencyForFixup(rva); - } - PTR_Module module = mt->GetModule(); - if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(module)) ) - { - unsigned rva = CORCOMPILE_UNTAG_TOKEN(PTR_TO_TADDR(module)); - return GetDependencyForFixup(rva); - } - return GetDependencyForModule(module); -} -const NativeImageDumper::Dependency* -NativeImageDumper::GetDependencyFromFD( PTR_FieldDesc fd ) -{ - PTR_MethodTable mt = fd->GetApproxEnclosingMethodTable(); - if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(mt)) ) - { - //This code will not work for out of module dependencies. - _ASSERTE(isSelf(GetDependencyForPointer(PTR_TO_TADDR(fd)))); - - //the MethodTable has a fixup. The home for that fixup tells us the - //home for the metadata. - unsigned rva = CORCOMPILE_UNTAG_TOKEN(PTR_TO_TADDR(mt)); - return GetDependencyForFixup(rva); - } - return GetDependencyFromMT(mt); -} -const NativeImageDumper::Dependency* -NativeImageDumper::GetDependencyFromMD( PTR_MethodDesc md ) -{ - PTR_MethodDescChunk chunk( md->GetMethodDescChunk() ); - PTR_MethodTable mt = chunk->GetMethodTable(); - if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(mt)) ) - { - //This code will not work for out of module dependencies. - _ASSERTE(isSelf(GetDependencyForPointer(PTR_TO_TADDR(md)))); - - //the MethodTable has a fixup. The home for that fixup tells us the - //home for the metadata. - unsigned rva = CORCOMPILE_UNTAG_TOKEN(PTR_TO_TADDR(mt)); - return GetDependencyForFixup(rva); - } - return GetDependencyFromMT(mt); -} - -BOOL NativeImageDumper::DoWriteFieldAsFixup( const char * name, - unsigned offset, - unsigned fieldSize, TADDR fixup) -{ - if( !CORCOMPILE_IS_POINTER_TAGGED(fixup) ) - return FALSE; - if( UINT_MAX == offset ) - m_display->StartVStructure( name ); - else - m_display->StartVStructureWithOffset( name, offset, fieldSize ); - - WriteElementsFixupBlob( NULL, fixup ); - m_display->EndVStructure(); //name - return TRUE; -} - -void AppendTypeQualifier( CorElementType kind, DWORD rank, SString& buf ) -{ - switch( kind ) - { - case ELEMENT_TYPE_BYREF : - buf.Append( W("&") ); - break; - case ELEMENT_TYPE_PTR : - buf.Append( W("*") ); - break; - case ELEMENT_TYPE_SZARRAY : - buf.Append( W("[]") ); - break; - case ELEMENT_TYPE_ARRAY : - if( rank == 1 ) - { - buf.Append( W("[*]") ); - } - else - { - buf.Append( W("[") ); - for( COUNT_T i = 0; i < rank; ++i ) - buf.Append( W(",")); - buf.Append( W("]") ); - } - break; - default : - break; - } -} -void NativeImageDumper::TypeDescToString( PTR_TypeDesc td, SString& buf ) -{ - _ASSERTE(!(PTR_TO_TADDR(td) & 0x2)); - if( td->IsGenericVariable() ) - { - PTR_TypeVarTypeDesc tvtd( PTR_TO_TADDR(td) ); - //From code:TypeString::AppendType - mdGenericParam token = tvtd->GetToken(); - PTR_Module module(tvtd->GetModule()); - IMetaDataImport2 * pImport; - if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(module)) ) - { - if (!isSelf(GetDependencyForPointer(PTR_TO_TADDR(td)))) - { - //this is an RVA from another hardbound dependency. We cannot decode it - buf.Append(W("OUT_OF_MODULE_FIXUP")); - return; - } - else - { - RVA rva = CORCOMPILE_UNTAG_TOKEN(PTR_TO_TADDR(module)); - pImport = GetDependencyForFixup(rva)->pImport; - } - } - else - { - pImport = GetDependencyForModule(module)->pImport; - } - AppendTokenName(token, buf, pImport); - } - else if( ELEMENT_TYPE_FNPTR == td->GetInternalCorElementType() ) - { - PTR_FnPtrTypeDesc fptd( PTR_TO_TADDR(td) ); - buf.Append( W("(fnptr)") ); - } - else if(td->HasTypeParam()) - { - PTR_ParamTypeDesc ptd(PTR_TO_TADDR(td)); - - _ASSERTE(td->HasTypeParam()); - TypeHandle th(ptd->GetTypeParam()); - _ASSERTE( !CORCOMPILE_IS_POINTER_TAGGED(th.AsTAddr()) ); - _ASSERTE( th.AsTAddr() ); - TypeHandleToString(th, buf); - - AppendTypeQualifier( td->GetInternalCorElementType(), /*rank*/ 0, buf ); - } - else - { - //generic typedesc? - EnumFlagsToString( (int)td->GetInternalCorElementType(), s_CorElementType, dim(s_CorElementType), - W(""), buf ); - } -} -void NativeImageDumper::TypeHandleToString( TypeHandle th, SString& buf ) -{ - TADDR arg = th.AsTAddr(); - /* REVISIT_TODO Thu 10/5/2006 - * Is this constant somewhere? - */ - //0x2 is the subtle hint that this is a typedesc. code:TypeHandle::AsTypeDesc - if( arg & 0x2 ) - { - PTR_TypeDesc argTD( arg & ~0x2 ); - TypeDescToString( argTD, buf ); - } - else - { - PTR_MethodTable argMT( th.AsTAddr() ); - MethodTableToString( argMT, buf ); - } -} - -void NativeImageDumper::DoWriteFieldTypeHandle( const char * name, - unsigned offset, - unsigned fieldSize, - TypeHandle th ) -{ - TempBuffer buf; - TADDR ptr = th.AsTAddr(); - if( DoWriteFieldAsFixup(name, offset, fieldSize, th.AsTAddr() ) ) - return; - else - { - TypeHandleToString(th, buf); - - buf.Append( W(" (from TypeHandle)") ); - /* REVISIT_TODO Fri 10/14/2005 - * Do a better job of this - */ - if( offset == UINT_MAX ) - { - m_display->WriteElementPointerAnnotated( name, - DataPtrToDisplay(ptr), - (const WCHAR*) buf ); - } - else - { - m_display->WriteFieldPointerAnnotated( name, offset, fieldSize, - DataPtrToDisplay(ptr), - (const WCHAR*) buf ); - } - } -} -void NativeImageDumper::WriteElementTypeHandle( const char * name, - TypeHandle th ) -{ - DoWriteFieldTypeHandle( name, UINT_MAX, UINT_MAX, th ); -} - -void NativeImageDumper::DoDumpFieldStub( PTR_Stub stub, unsigned offset, - unsigned fieldSize, const char * name ) -{ - _ASSERTE(CHECK_OPT(EECLASSES)); - if( stub == NULL ) - { - m_display->WriteFieldPointer( name, offset, fieldSize, NULL ); - } - else - { - m_display->StartStructureWithOffset( name, offset, fieldSize, - DPtrToPreferredAddr(stub), - sizeof(*stub) ); - /* REVISIT_TODO Fri 10/14/2005 - * Dump stub - */ - m_display->EndStructure(); - } -} - -#ifdef FEATURE_COMINTEROP -void NativeImageDumper::DoDumpComPlusCallInfo( PTR_ComPlusCallInfo compluscall ) -{ - m_display->StartStructure( "ComPlusCallInfo", - DPtrToPreferredAddr(compluscall), - sizeof(*compluscall) ); - - DisplayWriteFieldPointer( m_pILStub, compluscall->m_pILStub, - ComPlusCallInfo, ALWAYS); - /* REVISIT_TODO Fri 12/16/2005 - * Coverage read stub? - */ - WriteFieldMethodTable(m_pInterfaceMT, - compluscall->m_pInterfaceMT, - ComPlusCallInfo, ALWAYS); - - PTR_MethodDesc pEventProviderMD = PTR_MethodDesc((TADDR)compluscall->m_pEventProviderMD); - WriteFieldMethodDesc(m_pEventProviderMD, - pEventProviderMD, - ComPlusCallInfo, ALWAYS); - DisplayWriteFieldInt( m_cachedComSlot, compluscall->m_cachedComSlot, - ComPlusCallInfo, ALWAYS ); - - /* REVISIT_TODO Fri 12/16/2005 - * Dump these as mnemonics - */ - DisplayWriteFieldInt( m_flags, compluscall->m_flags, - ComPlusCallInfo, ALWAYS ); - WriteFieldMethodDesc( m_pStubMD, - compluscall->m_pStubMD.GetValueMaybeNull(PTR_HOST_MEMBER_TADDR(ComPlusCallInfo, compluscall, m_pStubMD)), - ComPlusCallInfo, ALWAYS ); - -#ifdef TARGET_X86 - DisplayWriteFieldInt( m_cbStackArgumentSize, compluscall->m_cbStackArgumentSize, - ComPlusCallInfo, ALWAYS ); - - DisplayWriteFieldPointer( m_pRetThunk, - DataPtrToDisplay((TADDR)compluscall->m_pRetThunk), - ComPlusCallInfo, ALWAYS ); -#endif - m_display->EndStructure(); //ComPlusCallInfo -} -#endif // FEATURE_COMINTEROP - -void NativeImageDumper::DoWriteFieldStr( PTR_BYTE ptr, const char * name, - unsigned offset, unsigned fieldSize ) -{ - if( ptr == NULL ) - { - if( UINT_MAX == offset ) - m_display->WriteElementPointer( name, NULL ); - else - m_display->WriteFieldPointer( name, offset, fieldSize, NULL ); - } - else - { - /* REVISIT_TODO Wed 03/22/2006 - * Obviously this does the wrong thing for UTF-8. - */ - TempBuffer buf; - BYTE b; - TADDR taddr = DPtrToPreferredAddr(ptr); - PTR_BYTE current = ptr; - /* REVISIT_TODO Mon 03/27/2006 - * Actually handle UTF-8 properly - */ - while( (b = *current++) != 0 ) - buf.Append( (WCHAR)b ); - /* REVISIT_TODO Wed 03/22/2006 - * This seems way way way more verbose than it needs to be. - */ - if( UINT_MAX == offset ) - { - m_display->StartStructure( name, DataPtrToDisplay(taddr), - current - ptr ); - } - else - { - m_display->StartStructureWithOffset( name, offset, fieldSize, - DataPtrToDisplay(taddr), - current - ptr ); - } - DisplayWriteElementStringW( "Value", (const WCHAR *)buf, ALWAYS ); - m_display->EndStructure(); - /* - m_display->WriteFieldPointerAnnotated( name, offset, fieldSize, - taddr, (const WCHAR *)buf ); - */ - } -} -void NativeImageDumper::WriteFieldDictionaryLayout(const char * name, - unsigned offset, - unsigned fieldSize, - PTR_DictionaryLayout layout, - IMetaDataImport2 * import) -{ - if( layout == NULL ) - { - m_display->WriteFieldPointer(name, NULL, offset, fieldSize); - return; - } - m_display->StartVStructureWithOffset( name, offset, fieldSize ); - DisplayStartArray( "DictionaryLayouts", NULL, ALWAYS ); - do - { - DisplayStartStructure( "DictionaryLayout", DPtrToPreferredAddr(layout), - sizeof(DictionaryLayout) - + sizeof(DictionaryEntryLayout) - * (layout->m_numSlots - 1), ALWAYS ); - - - DisplayWriteFieldPointer( m_pNext, DataPtrToDisplay((TADDR)layout->m_pNext), - DictionaryLayout, ALWAYS ); - DisplayWriteFieldInt( m_numSlots, layout->m_numSlots, - DictionaryLayout, ALWAYS ); - DisplayStartArrayWithOffset( m_slots, NULL, DictionaryLayout, ALWAYS ); - for( unsigned i = 0; i < layout->m_numSlots; ++i ) - { - PTR_DictionaryEntryLayout entry( PTR_HOST_MEMBER_TADDR(DictionaryLayout, layout, m_slots) + (i * sizeof(DictionaryEntryLayout)) ); - DisplayStartStructure( "DictionaryEntryLayout", - DPtrToPreferredAddr(entry), sizeof(*entry), - ALWAYS ); - const char * kind = NULL; - switch( entry->GetKind() ) - { -#define KIND_ENTRY(x) case x : kind = # x ; break - KIND_ENTRY(EmptySlot); - KIND_ENTRY(TypeHandleSlot); - KIND_ENTRY(MethodDescSlot); - KIND_ENTRY(MethodEntrySlot); - KIND_ENTRY(ConstrainedMethodEntrySlot); - KIND_ENTRY(DispatchStubAddrSlot); - KIND_ENTRY(FieldDescSlot); -#undef KIND_ENTRY - default: - _ASSERTE( !"unreachable" ); - } - DisplayWriteElementString( "Kind", kind, ALWAYS ); - DisplayWriteElementPointer( "Signature", DPtrToPreferredAddr(entry->m_signature), ALWAYS ); - DisplayEndStructure( ALWAYS ); //DictionaryEntryLayout - } - DisplayEndArray( "Total Dictionary Entries", ALWAYS ); //m_slots - DisplayEndStructure( ALWAYS ); //Layout - layout = PTR_DictionaryLayout(TO_TADDR(layout->m_pNext)); - }while( layout != NULL ); - DisplayEndArray( "Total Dictionary Layouts", ALWAYS ); //DictionaryLayouts - - - DisplayEndVStructure( ALWAYS ); // name -} -void NativeImageDumper::DoWriteFieldFieldDesc( const char * name, - unsigned offset, - unsigned fieldSize, - PTR_FieldDesc fd ) -{ - if( fd == NULL ) - { - m_display->WriteFieldPointer( name, offset, fieldSize, NULL ); - } - else - { - TempBuffer buf; - FieldDescToString( fd, buf ); - m_display->WriteFieldPointerAnnotated( name, offset, fieldSize, - DPtrToPreferredAddr(fd), - (const WCHAR*) buf ); - } - -} -void NativeImageDumper::DoWriteFieldMethodDesc( const char * name, - unsigned offset, - unsigned fieldSize, - PTR_MethodDesc md ) -{ - if( md == NULL ) - { - m_display->WriteFieldPointer( name, offset, fieldSize, NULL ); - } - else if( DoWriteFieldAsFixup(name, offset, fieldSize, PTR_TO_TADDR(md)) ) - { - return; - } - else - { - TempBuffer buf; - MethodDescToString( md, buf ); - m_display->WriteFieldPointerAnnotated( name, offset, fieldSize, - DPtrToPreferredAddr(md), - (const WCHAR*) buf ); - } -} - -void NativeImageDumper::EntryPointToString( TADDR pEntryPoint, - SString& buf ) -{ - const Dependency * dependency = GetDependencyForPointer(pEntryPoint); - - PTR_MethodDesc md; - if (dependency->pModule->IsZappedPrecode(pEntryPoint)) - { - md = dac_cast(Precode::GetPrecodeFromEntryPoint(pEntryPoint)->GetMethodDesc()); - } - else - { - PTR_Module module = (TADDR)m_decoder.GetPersistedModuleImage(); - PTR_NGenLayoutInfo pNgenLayout = module->GetNGenLayoutInfo(); - DWORD rva = (DWORD)(pEntryPoint - PTR_TO_TADDR(m_decoder.GetBase())); - - for (int iRange = 0; iRange < 2; iRange++) - { - if (pNgenLayout->m_CodeSections[iRange].IsInRange(pEntryPoint)) - { - int MethodIndex = NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod(rva, pNgenLayout->m_pRuntimeFunctions[iRange], 0, pNgenLayout->m_nRuntimeFunctions[iRange] - 1); - if (MethodIndex >= 0) - { -#ifdef FEATURE_EH_FUNCLETS - while (pNgenLayout->m_MethodDescs[iRange][MethodIndex] == 0) - MethodIndex--; -#endif - - PTR_RUNTIME_FUNCTION pRuntimeFunction = pNgenLayout->m_pRuntimeFunctions[iRange] + MethodIndex; - - md = NativeUnwindInfoLookupTable::GetMethodDesc(pNgenLayout, pRuntimeFunction, PTR_TO_TADDR(m_decoder.GetBase())); - break; - } - } - } - } - - MethodDescToString(md, buf); -} - -void NativeImageDumper::MethodDescToString( PTR_MethodDesc md, - SString& buf ) -{ - if( md == NULL ) - buf.Append( W("mdMethodDefNil") ); - else if( md->IsILStub() ) - buf.AppendUTF8(md->AsDynamicMethodDesc()->GetName()); - else - { - //write the name to a temporary location, since I'm going to insert it - //into the middle of a signature. - TempBuffer tempName; - - _ASSERTE(!CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(md))); - //work back to the EEClass. That gives us the context for the token. - PTR_MethodDescChunk chunk(md->GetMethodDescChunk()); - //chunk is implicitly remapped because it's calculated from the pointer - //to MD. - PTR_MethodTable mt = chunk->GetMethodTable(); - const Dependency * dependency; - if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(mt)) ) - { - //This code will not work for out of module dependencies. - _ASSERTE(isSelf(GetDependencyForPointer(PTR_TO_TADDR(md)))); - - RVA rva = CORCOMPILE_UNTAG_TOKEN(PTR_TO_TADDR(mt)); - dependency = GetDependencyForFixup(rva); - mt = NULL; //make sure we don't use this for anything. - } - else - dependency = GetDependencyFromMT(mt); - - _ASSERTE(dependency); - - - /* REVISIT_TODO Fri 10/13/2006 - * Don't I need the array type name here? - */ - _ASSERTE(dependency->pImport); - if( md->GetClassification() == mcArray ) - { - - //We don't need to append the dependency all the time. - //MethodTableToString() already appends it to the MethodTable. - //Only do it in cases where we don't call MethodTableToString. - if( !isSelf(dependency) ) - { - AppendTokenName( dependency->entry->dwAssemblyRef, tempName, - m_manifestImport ); - tempName.Append(W("!")); - } - - _ASSERTE(PTR_TO_TADDR(mt)); - MethodTableToString( mt, tempName ); - tempName.Append( W("::") ); - - //there are four hard coded names for array method descs, use these - //instead of the token. - PTR_ArrayMethodDesc amd(PTR_TO_TADDR(md)); - tempName.AppendUTF8( amd->GetMethodName() ); - } - else - { - //if we have a MethodTable, use that and compose the name - //ourselves. That way we can get generic arguments. - if( mt ) - { - ULONG size; - MethodTableToString( mt, tempName ); - tempName.Append( W("::") ); - IfFailThrow(dependency->pImport->GetMethodProps(md->GetMemberDef(), NULL, bigBuffer, - bigBufferSize, &size, NULL, NULL, NULL, NULL, - NULL)); - tempName.Append(bigBuffer); - } - else - { - //We don't need to append the dependency all the time. - //MethodTableToString() already appends it to the MethodTable. - //Only do it in cases where we don't call MethodTableToString. - if( !isSelf(dependency) ) - { - AppendTokenName( dependency->entry->dwAssemblyRef, tempName, - m_manifestImport ); - tempName.Append(W("!")); - } - AppendTokenName( md->GetMemberDef(), tempName, dependency->pImport ); - } - - if( mcInstantiated == md->GetClassification() ) - { - PTR_InstantiatedMethodDesc imd(PTR_TO_TADDR(md)); - unsigned numArgs = imd->m_wNumGenericArgs; - PTR_Dictionary dict(imd->IMD_GetMethodDictionary()); - if( dict != NULL ) - { - DictionaryToArgString( dict, numArgs, tempName ); - } - } - - PCCOR_SIGNATURE pvSigBlob; - ULONG cbSigBlob; - IfFailThrow(dependency->pImport->GetMethodProps(md->GetMemberDef(), - NULL, - NULL, - 0, - NULL, - NULL, - &pvSigBlob, - &cbSigBlob, - NULL, - NULL)); - - - CQuickBytes prettySig; - ReleaseHolder pInternal; - IfFailThrow(GetMDInternalInterfaceFromPublic(dependency->pImport, IID_IMDInternalImport, - (void**)&pInternal)); - StackScratchBuffer buffer; - const ANSI * ansi = tempName.GetANSI(buffer); - ansi = PrettyPrintSig(pvSigBlob, cbSigBlob, ansi, &prettySig, pInternal, NULL); - tempName.SetANSI( ansi ); - } - buf.Append(tempName); - } -} -void NativeImageDumper::WriteElementMethodDesc( const char * name, - PTR_MethodDesc md ) -{ - if( md == NULL ) - { - m_display->WriteElementPointer( name, NULL ); - } - else - { - TempBuffer buf; - MethodDescToString( md, buf ); - m_display->WriteElementPointerAnnotated( name, DPtrToPreferredAddr(md), - (const WCHAR*) buf ); - } -} -void NativeImageDumper::FieldDescToString( PTR_FieldDesc fd, SString& buf ) -{ - FieldDescToString( fd, mdFieldDefNil, buf ); -} -void NativeImageDumper::FieldDescToString( PTR_FieldDesc fd, mdFieldDef tok, - SString& buf ) -{ - IF_OPT(DISABLE_NAMES) - { - buf.Append( W("Disabled") ); - return; - } - if( fd == NULL ) - { - if( tok == mdFieldDefNil ) - buf.Append( W("mdFieldDefNil") ); - else - AppendTokenName( tok, buf ); - } - else - { - _ASSERTE(!CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(fd))); - IMetaDataImport2 * importMD = NULL; - if( !isInRange(PTR_TO_TADDR(fd)) ) - { - const Dependency * dependency = GetDependencyFromFD(fd); - _ASSERTE(dependency); - AppendTokenName( dependency->entry->dwAssemblyRef, buf, - m_manifestImport ); - buf.Append(W("!")); - importMD = dependency->pImport; - _ASSERTE(importMD); - - } - else - { - importMD = m_import; - } - AppendTokenName( fd->GetMemberDef(), buf, importMD ); - } -} - -void NativeImageDumper::DoWriteFieldAsHex( const char * name, unsigned offset, - unsigned fieldSize, PTR_BYTE ptr, - unsigned dataLen ) -{ - TempBuffer buffer; - for( unsigned i = 0; i < dataLen; ++i ) - { - unsigned char b = ptr[i]; - buffer.AppendPrintf( W("%02x%02x"), (b & 0xf0) >> 4, b & 0xf ); - } - if( offset == UINT_MAX ) - { - m_display->WriteElementStringW( name, (const WCHAR *)buffer ); - } - else - { - m_display->WriteFieldStringW( name, offset, fieldSize, - (const WCHAR *)buffer ); - } -} -void NativeImageDumper::WriteElementMDToken( const char * name, mdToken token ) -{ - DoWriteFieldMDToken( name, UINT_MAX, UINT_MAX, token ); -} -void NativeImageDumper::DoWriteFieldMDToken( const char * name, unsigned offset, - unsigned fieldSize, mdToken token, - IMetaDataImport2 * import ) -{ - TempBuffer buf; - if( RidFromToken(token) == mdTokenNil ) - { - AppendNilToken( token, buf ); - } - else - { - AppendToken( token, buf, import ); - } - if( UINT_MAX == offset ) - m_display->WriteElementEnumerated( name, token, (const WCHAR *)buf ); - else - { - m_display->WriteFieldEnumerated(name, offset, fieldSize, token, - (const WCHAR*)buf); - } -} - -void NativeImageDumper::WriteElementMethodTable( const char * name, - PTR_MethodTable mt ) -{ - DoWriteFieldMethodTable( name, UINT_MAX, UINT_MAX, mt ); -} -void NativeImageDumper::DoWriteFieldMethodTable( const char * name, - unsigned offset, - unsigned fieldSize, - PTR_MethodTable mt ) -{ - if( mt == NULL ) - { - if( UINT_MAX == offset ) - m_display->WriteElementPointer( name, NULL ); - else - m_display->WriteFieldPointer( name, offset, fieldSize, NULL ); - } - else if( DoWriteFieldAsFixup( name, offset, fieldSize, PTR_TO_TADDR(mt) ) ) - { - return; - } - else - { - TempBuffer buf; - MethodTableToString( mt, buf ); - if( UINT_MAX == offset ) - { - - m_display->WriteElementPointerAnnotated( name, - DPtrToPreferredAddr(mt), - (const WCHAR*) buf ); - } - else - { - m_display->WriteFieldPointerAnnotated( name, offset, fieldSize, - DPtrToPreferredAddr(mt), - (const WCHAR*) buf ); - } - } -} - -const char * s_VTSCallbackNames[] = -{ -#define VTSCB_ENTRY(x) # x - VTSCB_ENTRY(VTS_CALLBACK_ON_SERIALIZING), - VTSCB_ENTRY(VTS_CALLBACK_ON_SERIALIZED), - VTSCB_ENTRY(VTS_CALLBACK_ON_DESERIALIZING), - VTSCB_ENTRY(VTS_CALLBACK_ON_DESERIALIZED), -#undef VTSCB_ENTRY -}; -void NativeImageDumper::DumpFieldDesc( PTR_FieldDesc fd, const char * name ) -{ - DisplayStartStructure( name, DPtrToPreferredAddr(fd), sizeof(*fd), - ALWAYS ); - WriteFieldMethodTable( m_pMTOfEnclosingClass, - fd->GetApproxEnclosingMethodTable(), FieldDesc, ALWAYS ); - m_display->WriteFieldUInt( "m_mb", offsetof(FieldDesc, m_dword1), - fieldsize(FieldDesc, m_dword1), - fd->GetMemberDef() ); - m_display->WriteFieldFlag( "m_isStatic", - offsetof(FieldDesc, m_dword1), - fieldsize(FieldDesc, m_dword1), - fd->m_isStatic ); - m_display->WriteFieldFlag( "m_isThreadLocal", - offsetof(FieldDesc, m_dword1), - fieldsize(FieldDesc, m_dword1), - fd->m_isThreadLocal ); - m_display->WriteFieldFlag( "m_isRVA", offsetof(FieldDesc, m_dword1), - fieldsize(FieldDesc, m_dword1), - fd->m_isRVA ); - - { - TempBuffer buf; - EnumFlagsToString( fd->m_prot, s_CorFieldAttr, - _countof(s_CorFieldAttr), W(" "), buf ); - m_display->WriteFieldEnumerated( "m_prot", - offsetof(FieldDesc, m_dword1), - fieldsize(FieldDesc, m_dword1), - fd->m_prot, (const WCHAR *)buf ); - } - m_display->WriteFieldFlag( "m_requiresFullMbValue", - offsetof(FieldDesc, m_dword1), - fieldsize(FieldDesc, m_dword1), - fd->m_requiresFullMbValue ); - m_display->WriteFieldInt( "m_dwOffset", - offsetof(FieldDesc, m_dword2), - fieldsize(FieldDesc, m_dword2), - fd->m_dwOffset ); - DoWriteFieldCorElementType( "m_type", - offsetof(FieldDesc, m_dword2), - fieldsize(FieldDesc, m_dword2), - (CorElementType)fd->m_type ); -#ifdef _DEBUG - WriteFieldStr( m_debugName, PTR_BYTE(TO_TADDR(fd->m_debugName)), - FieldDesc, ALWAYS ); -#endif - DisplayEndStructure( ALWAYS ); //name -} - -#ifdef _PREFAST_ -#pragma warning(push) -#pragma warning(disable:21000) // Suppress PREFast warning about overly large function -#endif -void -NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name, - PTR_Module module ) -{ - _ASSERTE(NULL != mt); - TADDR start, end; - bool haveCompleteExtents = true; - PTR_EEClass clazz = NULL; - if( !mt->IsCanonicalMethodTable() && CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(mt->GetCanonicalMethodTable())) ) - { - /* REVISIT_TODO Wed 02/01/2006 - * GetExtent requires the class in order to compute GetInstAndDictSize. - * If the EEClass isn't present, I cannot compute the size. If we are - * in this case, skip all of the generic dictionaries. - */ - haveCompleteExtents = false; - TempBuffer buf; - MethodTableToString( mt, buf ); - m_display->ErrorPrintF( "WARNING! MethodTable %S is generic but is not hard bound to its EEClass. Cannot compute generic dictionary sizes.\n", (const WCHAR *)buf ); - } - else if( !m_isCoreLibHardBound ) - { - /* REVISIT_TODO Mon 8/20/2007 - * If we're not hard bound to CoreLib, most things don't work. They depend on knowing what - * g_pObjectClass is. Without the hard binding to CoreLib, I can't figure that out. - */ - haveCompleteExtents = false; - } - if( haveCompleteExtents ) - { - mt->GetSavedExtent(&start, &end); - clazz = mt->GetClass(); - } - else - { - start = PTR_TO_TADDR(mt); - end = start + sizeof(*mt); - } - IF_OPT(METHODTABLES) - { - m_display->StartStructureWithNegSpace( name, DPtrToPreferredAddr(mt), - DataPtrToDisplay(start), end - start ); - } - - IF_OPT(METHODTABLES) - { - { - TempBuffer buf; - MethodTableToString( mt, buf ); - DisplayWriteElementStringW( "Name", (const WCHAR *)buf, ALWAYS ); - } - if( mt->ContainsPointers() ) - { - PTR_CGCDesc cgc = CGCDesc::GetCGCDescFromMT(mt); - unsigned size = (unsigned)cgc->GetSize(); - /* REVISIT_TODO Tue 12/13/2005 - * Does anyone actually care about what's inside here? - */ - m_display->WriteFieldEmpty( "CGCDesc", ~size + 1, size ); - } - } - - /* XXX Mon 10/24/2005 - * The MT might have a component size as the low WORD of the m_dwFlags - * field, if it doesn't then that field instead represents a number of - * flags, which we know as the "low flags" - */ - if (mt->HasComponentSize()) - { - DisplayWriteElementInt( "ComponentSize", mt->RawGetComponentSize(), - METHODTABLES ); - } - else - { - DisplayWriteFieldEnumerated( m_dwFlags, mt->m_dwFlags & 0xFFFF, MethodTable, - s_MTFlagsLow, W(", "), METHODTABLES ); - } - - /* XXX Fri 10/07/2005 - * The low WORD of the flags is used for either a component size or flags - * (see above), the high WORD is always flags. If this changes then this - * might be busted. - */ - DisplayWriteFieldEnumerated( m_dwFlags, mt->m_dwFlags & ~0xFFFF, MethodTable, - s_MTFlagsHigh, W(", "), METHODTABLES ); - - DisplayWriteFieldInt( m_BaseSize, mt->m_BaseSize, MethodTable, - METHODTABLES ); - - DisplayWriteFieldEnumerated( m_wFlags2, mt->m_wFlags2, MethodTable, - s_MTFlags2, W(", "), METHODTABLES ); - - DisplayWriteFieldInt( m_wToken, mt->m_wToken, MethodTable, - METHODTABLES ); - DisplayWriteFieldInt( m_wNumVirtuals, mt->m_wNumVirtuals, MethodTable, - METHODTABLES ); - DisplayWriteFieldInt( m_wNumInterfaces, mt->m_wNumInterfaces, MethodTable, - METHODTABLES ); - - - - PTR_MethodTable parent = ReadPointerMaybeNull((MethodTable*) mt, &MethodTable::m_pParentMethodTable, mt->GetFlagHasIndirectParent()); - if( parent == NULL ) - { - DisplayWriteFieldPointer( m_pParentMethodTable, NULL, MethodTable, - METHODTABLES ); - } - else - { - IF_OPT(METHODTABLES) - { - DoWriteFieldMethodTable( "m_pParentMethodTable", - offsetof(MethodTable, m_pParentMethodTable), - fieldsize(MethodTable, m_pParentMethodTable), - mt->GetParentMethodTable() ); - } - } - DisplayWriteFieldPointer( m_pLoaderModule, - DPtrToPreferredAddr(mt->GetLoaderModule()), - MethodTable, METHODTABLES ); - - PTR_MethodTableWriteableData wd = ReadPointer((MethodTable *)mt, &MethodTable::m_pWriteableData); - _ASSERTE(wd != NULL); - DisplayStartStructureWithOffset( m_pWriteableData, DPtrToPreferredAddr(wd), - sizeof(*wd), MethodTable, METHODTABLES ); - DisplayWriteFieldEnumerated( m_dwFlags, wd->m_dwFlags, - MethodTableWriteableData, s_WriteableMTFlags, - W(", "), METHODTABLES ); - DisplayWriteFieldPointer( m_hExposedClassObject, - DataPtrToDisplay(wd->m_hExposedClassObject), - MethodTableWriteableData, METHODTABLES ); - _ASSERTE(wd->m_hExposedClassObject == 0); - DisplayEndStructure( METHODTABLES ); //m_pWriteableData - - if( !mt->IsCanonicalMethodTable() ) - { - WriteFieldMethodTable( m_pCanonMT, mt->GetCanonicalMethodTable(), - MethodTable, METHODTABLES ); - } - else - { - DisplayWriteFieldPointer( m_pEEClass, DPtrToPreferredAddr(mt->GetClass()), - MethodTable, METHODTABLES ); - } - - if( mt->IsArray() ) - { - WriteFieldTypeHandle( m_ElementTypeHnd, - mt->GetArrayElementTypeHandle(), - MethodTable, METHODTABLES ); - } - - if( mt->HasPerInstInfo() && haveCompleteExtents ) - { - //print out the generics dictionary info, and then print out - //the contents of those dictionaries. - PTR_GenericsDictInfo di = mt->GetGenericsDictInfo(); - _ASSERTE(NULL != di); - - DisplayStartStructure("GenericsDictInfo", DPtrToPreferredAddr(di), sizeof(*di), METHODTABLES); - - DisplayWriteFieldInt( m_wNumDicts, di->m_wNumDicts, GenericsDictInfo, - METHODTABLES ); - DisplayWriteFieldInt( m_wNumTyPars, di->m_wNumTyPars, - GenericsDictInfo, METHODTABLES); - DisplayEndStructure( METHODTABLES ); //GenericsDictInfo - - DPTR(MethodTable::PerInstInfoElem_t) perInstInfo = mt->GetPerInstInfo(); - - DisplayStartStructure( "PerInstInfo", - DPtrToPreferredAddr(perInstInfo), - mt->GetPerInstInfoSize(), - METHODTABLES ); - /* XXX Tue 10/11/2005 - * Only dump this type's dictionary, rather than the inherited - * dictionaries. (there are multiple entries in m_pPerInstInfo, but - * only print the last one, which is the one for this class). - * cloned from Genericdict.cpp - */ - PTR_Dictionary currentDictionary(mt->GetDictionary()); - if( currentDictionary != NULL ) - { - PTR_DictionaryEntry entry(currentDictionary->EntryAddr(0)); - - PTR_DictionaryLayout layout( clazz->GetDictionaryLayout() ); - - DisplayStartStructure( "Dictionary", - DPtrToPreferredAddr(currentDictionary), - //if there is a layout, use it to compute - //the size, otherwise there is just the one - //entry. - DictionaryLayout::GetDictionarySizeFromLayout(mt->GetNumGenericArgs(), layout), - METHODTABLES ); - - DisplayStartArrayWithOffset( m_pEntries, NULL, Dictionary, - METHODTABLES ); - - /* REVISIT_TODO Thu 12/15/2005 - * use VERBOSE_TYPES here. - */ - _ASSERTE(CHECK_OPT(METHODTABLES)); - - //for each generic arg, there is a type handle slot - for( unsigned i = 0; i < mt->GetNumGenericArgs(); ++i ) - DumpDictionaryEntry("Entry", TypeHandleSlot, entry + i); - - //now check for a layout. If it is present, then there are more - //entries. - if( layout != NULL && (layout->GetNumUsedSlots() > 0) ) - { - unsigned numUsedSlots = layout->GetNumUsedSlots(); - for( unsigned i = 0; i < numUsedSlots; ++i ) - { - //DictionaryLayout::GetEntryLayout - PTR_DictionaryEntryLayout entryLayout(layout->GetEntryLayout(i)); - - //Dictionary::GetSlotAddr - PTR_DictionaryEntry ent(currentDictionary->EntryAddr(mt->GetNumGenericArgs() + i)); - - DumpDictionaryEntry( "Entry", entryLayout->GetKind(), ent ); - } - } - if( layout != NULL ) - { - /* REVISIT_TODO Thu 12/15/2005 - * Where is this data? - */ - } - DisplayEndArray( "Total Per instance Info", - METHODTABLES ); //m_pEntries - DisplayEndStructure( METHODTABLES ); //Dictionary - } - DisplayEndStructure( METHODTABLES ); //m_pPerInstInfo - } - -#ifdef _DEBUG - WriteFieldStr( debug_m_szClassName, - PTR_BYTE(TO_TADDR(mt->debug_m_szClassName)), MethodTable, - METHODTABLES ); -#if 0 //already dumping the optional member - PTR_InterfaceInfo imap( TO_TADDR(mt->m_pIMapDEBUG) ); - /* REVISIT_TODO Mon 10/24/2005 - * Dump interface map - */ - DisplayStartArrayWithOffset( m_pIMapDEBUG, NULL, MethodTable, - METHODTABLES ); - DisplayEndArray( "Total Interfaces", METHODTABLES ); -#endif -#endif - - if( mt->HasDispatchMapSlot() ) - { - PTR_DispatchMap dispatchMap(mt->GetDispatchMap()); - - DisplayStartStructure( "DispatchMap", - DPtrToPreferredAddr(dispatchMap), - DispatchMap::GetObjectSize(dispatchMap->GetMapSize()), - METHODTABLES ); - - IF_OPT(VERBOSE_TYPES ) - { - DispatchMap::Iterator iter(mt); - DisplayStartArray( "DispatchMap", NULL, VERBOSE_TYPES ); - while( iter.Next() ) - { - DispatchMapEntry * ent = iter.Entry(); - - DisplayStartElement( "Entry", METHODTABLES ); - DisplayStartVStructure( "TypeID", METHODTABLES ); - DispatchMapTypeID typeID = ent->GetTypeID(); - if( typeID.IsThisClass() ) - DisplayWriteElementFlag("IsThisClass", true, METHODTABLES ); - else if( typeID.IsImplementedInterface() ) - { - DisplayWriteElementFlag( "IsImplementedInterface", - true, METHODTABLES ); - DisplayWriteElementInt( "GetInterfaceNum", - typeID.GetInterfaceNum(), METHODTABLES ); - } - DisplayEndStructure( METHODTABLES ); //TypeID - m_display->WriteElementInt( "SlotNumber", - ent->GetSlotNumber() ); - DisplayWriteElementInt( "TargetSlotNumber", - ent->GetSlotNumber(), METHODTABLES ); - - m_display->EndElement(); //Entry - } - //DispatchMap - DisplayEndArray("Total Dispatch Map Entries", METHODTABLES ); - } - else - { - CoverageRead(PTR_TO_TADDR(dispatchMap), - DispatchMap::GetObjectSize(dispatchMap->GetMapSize())); - } - - DisplayEndStructure( METHODTABLES ); //DispatchMap - } - - IF_OPT( METHODTABLES ) - { - m_display->StartStructureWithOffset("Vtable", - mt->GetVtableOffset(), - mt->GetNumVtableIndirections() * sizeof(MethodTable::VTableIndir_t), - DataPtrToDisplay(PTR_TO_TADDR(mt) + mt->GetVtableOffset()), - mt->GetNumVtableIndirections() * sizeof(MethodTable::VTableIndir_t)); - - - MethodTable::VtableIndirectionSlotIterator itIndirect = mt->IterateVtableIndirectionSlots(); - while (itIndirect.Next()) - { - SlotChunk sc; - sc.addr = dac_cast(itIndirect.GetIndirectionSlot()); - sc.nSlots = (WORD)itIndirect.GetNumSlots(); - sc.isRelative = MethodTable::VTableIndir2_t::isRelative; - m_discoveredSlotChunks.AppendEx(sc); - } - - IF_OPT(VERBOSE_TYPES) - { - DisplayStartList( W("[%-4s]: %s (%s)"), ALWAYS ); - for( unsigned i = 0; i < mt->GetNumVtableIndirections(); ++i ) - { - DisplayStartElement( "Slot", ALWAYS ); - DisplayWriteElementInt( "Index", i, ALWAYS ); - TADDR base = dac_cast(&(mt->GetVtableIndirections()[i])); - DPTR(MethodTable::VTableIndir2_t) tgt = MethodTable::VTableIndir_t::GetValueMaybeNullAtPtr(base); - DisplayWriteElementPointer( "Pointer", - DataPtrToDisplay(dac_cast(tgt)), - ALWAYS ); - DisplayWriteElementString( "Type", "chunk indirection", - ALWAYS ); - DisplayEndElement( ALWAYS ); //Slot - } - - if (mt->HasNonVirtualSlotsArray()) - { - DisplayStartElement( "Slot", ALWAYS ); - DisplayWriteElementInt( "Index", -1, ALWAYS ); - PTR_PCODE tgt = mt->GetNonVirtualSlotsArray(); - DisplayWriteElementPointer( "Pointer", - DataPtrToDisplay(dac_cast(tgt)), - ALWAYS ); - DisplayWriteElementString( "Type", "non-virtual chunk indirection", - ALWAYS ); - DisplayEndElement( ALWAYS ); //Slot - - SlotChunk sc; - sc.addr = dac_cast(tgt); - sc.nSlots = (mt->GetNumVtableSlots() - mt->GetNumVirtuals()); - sc.isRelative = false; - m_discoveredSlotChunks.AppendEx(sc); - } - else if (mt->HasSingleNonVirtualSlot()) - { - DumpSlot((unsigned)-1, mt->GetSlot(mt->GetNumVirtuals())); - } - - DisplayEndList( ALWAYS ); //vtable - } - else - { - CoverageRead( PTR_TO_TADDR(mt) + mt->GetVtableOffset(), - mt->GetNumVtableIndirections() * sizeof(MethodTable::VTableIndir_t) ); - - if (mt->HasNonVirtualSlotsArray()) - { - CoverageRead( PTR_TO_TADDR(mt->GetNonVirtualSlotsArray()), - mt->GetNonVirtualSlotsArraySize() ); - } - - } - DisplayEndStructure(ALWAYS); //Vtable - } - - if( mt->HasInterfaceMap() && CHECK_OPT(METHODTABLES) ) - { - PTR_InterfaceInfo ifMap = mt->GetInterfaceMap(); - m_display->StartArrayWithOffset( "InterfaceMap", - offsetof(MethodTable, m_pInterfaceMap), - sizeof(void*), - NULL ); - for( unsigned i = 0; i < mt->GetNumInterfaces(); ++i ) - { - PTR_InterfaceInfo info = ifMap + i; - DisplayStartStructure( "InterfaceInfo_t", DPtrToPreferredAddr(info), - sizeof(*info), METHODTABLES ); - WriteFieldMethodTable( m_pMethodTable, - info->GetMethodTable(), - InterfaceInfo_t, METHODTABLES ); - DisplayEndStructure( METHODTABLES ); //InterfaceInfo_t - } - DisplayEndArray( "Total InterfaceInfos", - METHODTABLES ); //InterfaceMap - } - - //rest of the optional members - - //GenericStatics comes after the generic dictionaries. So if I - //don't have extents, I can't print them. - if( haveCompleteExtents && - mt->HasGenericsStaticsInfo() && - CHECK_OPT(METHODTABLES) - ) - { - PTR_GenericsStaticsInfo genStatics = mt->GetGenericsStaticsInfo(); - m_display->StartStructureWithOffset( "OptionalMember_" - "GenericsStaticsInfo", - mt->GetOffsetOfOptionalMember(MethodTable::OptionalMember_GenericsStaticsInfo), - sizeof(*genStatics), - DPtrToPreferredAddr(genStatics), - sizeof(*genStatics) ); - - PTR_FieldDesc fieldDescs = ReadPointerMaybeNull((GenericsStaticsInfo *) genStatics, &GenericsStaticsInfo::m_pFieldDescs); - if( fieldDescs == NULL ) - { - DisplayWriteFieldPointer( m_pFieldDescs, NULL, GenericsStaticsInfo, - ALWAYS ); - } - else - { - DisplayStartArrayWithOffset( m_pFieldDescs, NULL, - GenericsStaticsInfo, ALWAYS ); - _ASSERTE(clazz == GetClassFromMT(mt)); - for( int i = 0; i < clazz->GetNumStaticFields(); ++i ) - { - PTR_FieldDesc fd = fieldDescs + i; - DumpFieldDesc( fd, "FieldDesc" ); - } - DisplayEndArray( "Total Static Fields", ALWAYS ); // m_pFieldDescs - } - DisplayWriteFieldUInt( m_DynamicTypeID, (DWORD)genStatics->m_DynamicTypeID, - GenericsStaticsInfo, METHODTABLES ); - - DisplayEndStructure( METHODTABLES );//OptionalMember_GenericsStaticsInfo - - } - - DisplayEndStructure( METHODTABLES ); //MethodTable -} // NativeImageDumper::DumpMethodTable -#ifdef _PREFAST_ -#pragma warning(pop) -#endif - -void -NativeImageDumper::DumpMethodTableSlotChunk( TADDR slotChunk, COUNT_T numSlots, bool isRelative ) -{ - IF_OPT( METHODTABLES ) - { - COUNT_T slotsSize; - if (isRelative) - { - slotsSize = numSlots * sizeof(RelativePointer); - } - else - { - slotsSize = numSlots * sizeof(PCODE); - } - DisplayStartStructure( "MethodTableSlotChunk", DataPtrToDisplay(slotChunk), slotsSize, METHODTABLES ); - - IF_OPT(VERBOSE_TYPES) - { - DisplayStartList( W("[%-4s]: %s (%s)"), ALWAYS ); - for( unsigned i = 0; i < numSlots; ++i ) - { - PCODE target; - if (isRelative) - { - target = RelativePointer::GetValueMaybeNullAtPtr(slotChunk + i * sizeof(RelativePointer)); - } - else - { - target = dac_cast(slotChunk)[i]; - } - - DumpSlot(i, target); - } - DisplayEndList( ALWAYS ); //Slot list - } - else - CoverageRead( slotChunk, slotsSize ); - DisplayEndStructure(ALWAYS); //Slot chunk - } -} - - -void -NativeImageDumper::DumpSlot( unsigned index, PCODE tgt ) -{ - IF_OPT(VERBOSE_TYPES) - { - DisplayStartElement( "Slot", ALWAYS ); - DisplayWriteElementInt( "Index", index, ALWAYS ); - DisplayWriteElementPointer( "Pointer", - DataPtrToDisplay(tgt), - ALWAYS ); - if( !isInRange(TO_TADDR(tgt)) ) - { - DisplayWriteElementString( "Type", "external", - ALWAYS ); - } - else if( isPrecode(TO_TADDR(tgt)) - && Precode::IsValidType(PTR_Precode(TO_TADDR(tgt))->GetType()) ) - { - PTR_Precode precode(TO_TADDR(tgt)); - DisplayWriteElementString( "Type", "precode", - ALWAYS ); - //DumpPrecode( precode, module ); - } - else - { - DisplayWriteElementString( "Type", "code pointer", - ALWAYS ); - } - DisplayEndElement( ALWAYS ); //Slot - } -} - -NativeImageDumper::EnumMnemonics NativeImageDumper::s_SSMDExtendedFlags[] = -{ -#define SSMD_ENTRY(x) NativeImageDumper::EnumMnemonics( x, W(#x) ) - -#define SSMD_ACCESS_ENTRY(x) NativeImageDumper::EnumMnemonics( x, mdMemberAccessMask, W(#x) ) - SSMD_ACCESS_ENTRY(mdPrivateScope), - SSMD_ACCESS_ENTRY(mdPrivate), - SSMD_ACCESS_ENTRY(mdFamANDAssem), - SSMD_ACCESS_ENTRY(mdAssem), - SSMD_ACCESS_ENTRY(mdFamily), - SSMD_ACCESS_ENTRY(mdFamORAssem), - SSMD_ACCESS_ENTRY(mdPublic), -#undef SSMD_ACCESS_ENTRY - - SSMD_ENTRY(mdStatic), - SSMD_ENTRY(mdFinal), - SSMD_ENTRY(mdVirtual), - SSMD_ENTRY(mdHideBySig), - - SSMD_ENTRY(mdVtableLayoutMask), - SSMD_ENTRY(mdNewSlot), - - SSMD_ENTRY(mdCheckAccessOnOverride), - SSMD_ENTRY(mdAbstract), - SSMD_ENTRY(mdSpecialName), - - SSMD_ENTRY(mdPinvokeImpl), - SSMD_ENTRY(mdUnmanagedExport), - - SSMD_ENTRY(mdRTSpecialName), - SSMD_ENTRY(mdHasSecurity), - SSMD_ENTRY(mdRequireSecObject), - - NativeImageDumper::EnumMnemonics( DynamicMethodDesc::nomdILStub, - W("nomdILStub") ), - NativeImageDumper::EnumMnemonics( DynamicMethodDesc::nomdLCGMethod, - W("nomdLCGMethod") ), -#undef SSMD_ENTRY -}; - -//maps MethodClassification to a name for a MethodDesc -const char * const s_MDTypeName[] = -{ - "MethodDesc", //mcIL - "FCallMethodDesc", //mcFCall - "NDirectMethodDesc", //mcNDirect - "EEImplMethodDesc", //mcEEImpl - //public StoredSigMethodDesc - "ArrayMethodDesc", //mcArray - //public StoredSigMethodDesc - "InstantiatedMethodDesc", //mcInstantiated -#if defined(FEATURE_COMINTEROP) - "ComPlusCallMethodDesc", //mcComInterop -#else - "", -#endif - "DynamicMethodDesc", //mcDynamic -- //public StoredSigMethodDesc -}; - -unsigned s_MDSizes[] = -{ - sizeof(MethodDesc), //mcIL - sizeof(FCallMethodDesc), //mcFCall - sizeof(NDirectMethodDesc), //mcNDirect - sizeof(EEImplMethodDesc), //mcEEImpl - sizeof(ArrayMethodDesc), //mcArray - sizeof(InstantiatedMethodDesc), //mcInstantiated -#if defined(FEATURE_COMINTEROP) - sizeof(ComPlusCallMethodDesc), //mcComInterop -#else - 0, -#endif - sizeof(DynamicMethodDesc), //mcDynamic -}; - -static NativeImageDumper::EnumMnemonics g_NDirectFlags[] = -{ -#define NDF_ENTRY(x) NativeImageDumper::EnumMnemonics( NDirectMethodDesc:: x, W(#x) ) - NDF_ENTRY(kEarlyBound), - NDF_ENTRY(kHasSuppressUnmanagedCodeAccess), - NDF_ENTRY(kIsMarshalingRequiredCached), - NDF_ENTRY(kCachedMarshalingRequired), - NDF_ENTRY(kNativeAnsi), - NDF_ENTRY(kLastError), - NDF_ENTRY(kNativeNoMangle), - NDF_ENTRY(kVarArgs), - NDF_ENTRY(kStdCall), - NDF_ENTRY(kThisCall), - NDF_ENTRY(kIsQCall), -#undef NDF_ENTRY -}; -NativeImageDumper::EnumMnemonics NativeImageDumper::s_IMDFlags[] = -{ -#define IMD_ENTRY(x) NativeImageDumper::EnumMnemonics( InstantiatedMethodDesc:: x, W(#x) ) - -#define IMD_KIND_ENTRY(x) NativeImageDumper::EnumMnemonics( InstantiatedMethodDesc:: x, InstantiatedMethodDesc::KindMask, W(#x) ) - IMD_KIND_ENTRY(GenericMethodDefinition), - IMD_KIND_ENTRY(UnsharedMethodInstantiation), - IMD_KIND_ENTRY(SharedMethodInstantiation), - IMD_KIND_ENTRY(WrapperStubWithInstantiations), -#undef IMD_KIND_ENTRY - -#ifdef EnC_SUPPORTED - // Method is a new virtual function added through EditAndContinue. - IMD_ENTRY(EnCAddedMethod), -#endif // EnC_SUPPORTED - - IMD_ENTRY(Unrestored), - -#ifdef FEATURE_COMINTEROP - IMD_ENTRY(HasComPlusCallInfo), -#endif // FEATURE_COMINTEROP - -#undef IMD_ENTRY -}; - -void NativeImageDumper::DumpPrecode( PTR_Precode precode, PTR_Module module ) -{ - _ASSERTE(isPrecode(PTR_TO_TADDR(precode))); - - PrecodeType pType = precode->GetType(); - switch(pType) - { -#define DISPLAY_PRECODE(type) \ - IF_OPT_AND(PRECODES, METHODDESCS) \ - { \ - PTR_ ## type p( precode->As ## type () ); \ - DisplayStartStructure( # type, \ - DPtrToPreferredAddr(p), \ - sizeof(*p), ALWAYS ); \ - WriteFieldMethodDesc( m_pMethodDesc, \ - p->m_pMethodDesc, \ - type, ALWAYS ); \ - TADDR target = p->GetTarget(); \ - DisplayWriteElementPointer("Target",\ - DataPtrToDisplay(target),\ - ALWAYS );\ - DisplayEndStructure( ALWAYS ); \ - } - - case PRECODE_STUB: - DISPLAY_PRECODE(StubPrecode); break; -#ifdef HAS_NDIRECT_IMPORT_PRECODE - case PRECODE_NDIRECT_IMPORT: - DISPLAY_PRECODE(NDirectImportPrecode); break; -#endif -#ifdef HAS_FIXUP_PRECODE - case PRECODE_FIXUP: - IF_OPT_AND(PRECODES, METHODDESCS) - { - PTR_FixupPrecode p( precode->AsFixupPrecode() ); - DisplayStartStructure( "FixupPrecode", - DPtrToPreferredAddr(p), - sizeof(*p), - ALWAYS ); - PTR_MethodDesc precodeMD(p->GetMethodDesc()); -#ifdef HAS_FIXUP_PRECODE_CHUNKS - { - DisplayWriteFieldInt( m_MethodDescChunkIndex, - p->m_MethodDescChunkIndex, FixupPrecode, - ALWAYS ); - DisplayWriteFieldInt( m_PrecodeChunkIndex, - p->m_PrecodeChunkIndex, FixupPrecode, - ALWAYS ); - if( p->m_PrecodeChunkIndex == 0 ) - { - //dump the location of the Base - DisplayWriteElementAddress( "PrecodeChunkBase", - DataPtrToDisplay(p->GetBase()), - sizeof(void*), ALWAYS ); - } - //Make sure I align up if there is no code slot to make - //sure that I get the padding - TADDR mdPtrStart = p->GetBase() - + (p->m_MethodDescChunkIndex * MethodDesc::ALIGNMENT); - TADDR mdPtrEnd = ALIGN_UP( mdPtrStart + sizeof(MethodDesc*), - 8 ); - CoverageRead( mdPtrStart, (ULONG32)(mdPtrEnd - mdPtrStart) ); - TADDR precodeMDSlot = p->GetBase() - + p->m_MethodDescChunkIndex * MethodDesc::ALIGNMENT; - DoWriteFieldMethodDesc( "MethodDesc", - (DWORD)(precodeMDSlot - PTR_TO_TADDR(p)), - sizeof(TADDR), precodeMD ); - } -#else //HAS_FIXUP_PRECODE_CHUNKS - WriteFieldMethodDesc( m_pMethodDesc, - p->m_pMethodDesc, - FixupPrecode, ALWAYS ); -#endif //HAS_FIXUP_PRECODE_CHUNKS - TADDR target = p->GetTarget(); - DisplayWriteElementPointer("Target", - DataPtrToDisplay(target), - ALWAYS ); - /* REVISIT_TODO Thu 01/05/2006 - * dump slot with offset if it is here - */ - DisplayEndStructure( ALWAYS ); //FixupPrecode - } - break; -#endif -#ifdef HAS_THISPTR_RETBUF_PRECODE - case PRECODE_THISPTR_RETBUF: - DISPLAY_PRECODE(ThisPtrRetBufPrecode); break; -#endif - default: - _ASSERTE( !"Unsupported precode type" ); -#undef DISPLAY_PRECODE -#undef PrecodeMDWrite - } -} - -#ifdef _PREFAST_ -#pragma warning(push) -#pragma warning(disable:21000) // Suppress PREFast warning about overly large function -#endif -void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) -{ - //StoredSigMethodDesc - - MethodClassification mc = - (MethodClassification)md->GetClassification(); - _ASSERTE(mc >= 0 && mc < mcCount); - const char * mdTypeName = s_MDTypeName[mc]; - unsigned mdSize = (unsigned)md->SizeOf(); - - DisplayStartStructure( mdTypeName, DPtrToPreferredAddr(md), - mdSize, METHODDESCS ); - IF_OPT(METHODDESCS) - { - TempBuffer buf; - MethodDescToString( md, buf ); - DisplayWriteElementStringW( "Name", (const WCHAR *)buf, METHODDESCS ); - } -#ifdef _DEBUG - IF_OPT(METHODDESCS) - { - WriteFieldStr(m_pszDebugMethodName, - PTR_BYTE(TO_TADDR(md->m_pszDebugMethodName)), - MethodDesc, METHODDESCS); - WriteFieldStr(m_pszDebugClassName, - PTR_BYTE(TO_TADDR(md->m_pszDebugClassName)), - MethodDesc, METHODDESCS); - WriteFieldStr(m_pszDebugMethodSignature, - PTR_BYTE(TO_TADDR(md->m_pszDebugMethodSignature)), - MethodDesc, METHODDESCS); - } - else - { - CoverageReadString(TO_TADDR(md->m_pszDebugMethodName)); - CoverageReadString(TO_TADDR(md->m_pszDebugClassName)); - CoverageReadString(TO_TADDR(md->m_pszDebugMethodSignature)); - } -#endif - - DisplayWriteFieldInt( m_wFlags3AndTokenRemainder, md->m_wFlags3AndTokenRemainder, - MethodDesc, METHODDESCS ); - - DisplayWriteFieldInt( m_chunkIndex, md->m_chunkIndex, - MethodDesc, METHODDESCS ); - - /* XXX Fri 03/24/2006 - * This is a workaround. The InstantiatedMethodDescs are in chunks, but there's - * no obvious place to display the chunk, so display the bounds here. - */ - if( mc == mcInstantiated && md->m_chunkIndex == 0 ) - { - PTR_MethodDescChunk chunk( md->GetMethodDescChunk() ); - DisplayWriteElementAddress( "MethodDescChunk", DPtrToPreferredAddr(chunk), - chunk->SizeOf(), METHODDESCS ); - } - - DisplayWriteFieldEnumerated( m_bFlags2, md->m_bFlags2, MethodDesc, - s_MDFlag2, W(", "), METHODDESCS ); - - DisplayWriteFieldInt( m_wSlotNumber, md->GetSlot(), MethodDesc, - METHODDESCS ); - DisplayWriteFieldEnumerated( m_wFlags, md->m_wFlags, MethodDesc, - s_MDC, W(", "), METHODDESCS ); - - IF_OPT(IL) - { - if( md->IsIL() ) - { - PTR_MethodDescChunk chunk(md->GetMethodDescChunk()); - //chunk is implicitly remapped because it's calculated from the pointer - //to MD. - PTR_MethodTable mt = chunk->GetMethodTable(); - if( !CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(mt)) ) - { - if ( md->IsTypicalMethodDefinition() ) - { - DWORD dwRVA = 0; - m_import->GetMethodProps(md->GetMemberDef(), NULL, NULL, NULL, 0, - NULL, NULL, NULL, &dwRVA, NULL); - - if (dwRVA != 0) - { - _ASSERTE(m_ILHostCopy); - _ASSERTE(m_ILSectionStart); - _ASSERTE(dwRVA >= m_ILSectionStart); - _ASSERTE(dwRVA < (m_ILSectionStart + m_ILSectionSize)); - //The RVA is from the start of the file, so convert it - //to an RVA to the start of the .text section. - TADDR pILTarget = (TADDR)m_decoder.GetRvaData(dwRVA); - COR_ILMETHOD * pILHeader = (COR_ILMETHOD*)(m_ILHostCopy + dwRVA - m_ILSectionStart); - - COR_ILMETHOD_DECODER decoder(pILHeader); - - DisplayStartStructure( "IL", - DataPtrToDisplay(pILTarget), - PEDecoder::ComputeILMethodSize(pILTarget), - ALWAYS ); - - DisplayWriteElementInt( "CodeSize", decoder.GetCodeSize(), ALWAYS ); - - // Dump the disassembled IL code? - - DisplayEndStructure( ALWAYS ); - } - } - } - } - } - if( md->HasPrecode() ) - { - PTR_Precode precode( md->GetPrecode() ); - - DumpPrecode( precode, module ); - } - if ( md->HasNonVtableSlot() ) - { - DisplayWriteElementInt( "Slot", (DWORD)(md->GetAddrOfSlot() - PTR_TO_TADDR(md)), ALWAYS); - } - if (md->HasNativeCodeSlot()) - { - DisplayWriteElementInt( "NativeCode", DWORD(md->GetAddrOfNativeCodeSlot() - PTR_TO_TADDR(md)), ALWAYS); - //m_display->WriteFieldPointer( "NativeCode", - // DWORD(md->GetAddrOfNativeCodeSlot() - PTR_TO_TADDR(md)), - // sizeof(TADDR), - // md->GetNativeCode() ); - } - if (md->HasMethodImplSlot()) - { - DisplayStartVStructure( "MethodImpl", METHODDESCS ); - PTR_MethodImpl impl(md->GetMethodImpl()); - PTR_DWORD slots = impl->GetSlots() - 1; // GetSlots returns the address of the first real slot (past the size) - unsigned numSlots = impl->GetSize(); - _ASSERTE(!numSlots || numSlots == slots[0]); - _ASSERTE(slots == NULL || isInRange(PTR_TO_TADDR(slots))); - if ((slots != NULL) && isInRange(PTR_TO_TADDR(slots))) - { - DisplayWriteFieldAddress(pdwSlots, DataPtrToDisplay(dac_cast(slots)), - (numSlots + 1) * sizeof(*slots), - MethodImpl, METHODDESCS); - } - else - { - DisplayWriteFieldPointer(pdwSlots, DataPtrToDisplay(dac_cast(slots)), - MethodImpl, METHODDESCS); - - } - _ASSERTE(impl->pImplementedMD.IsNull() - || isInRange(PTR_TO_TADDR(impl->GetImpMDsNonNull()))); - if (!impl->pImplementedMD.IsNull() && - isInRange(PTR_TO_TADDR(impl->GetImpMDsNonNull()))) - { - DisplayWriteFieldAddress( pImplementedMD, - DataPtrToDisplay(dac_cast(impl->GetImpMDsNonNull())), - numSlots * sizeof(RelativePointer ), - MethodImpl, METHODDESCS ); - } - else - { - DisplayWriteFieldPointer( pImplementedMD, - DataPtrToDisplay(dac_cast(impl->GetImpMDs())), - MethodImpl, METHODDESCS ); - } - DisplayEndVStructure( METHODDESCS ); - } - if (md->HasStoredSig()) - { - DisplayStartVStructure( "StoredSigMethodDesc", METHODDESCS ); - PTR_StoredSigMethodDesc ssmd(md); - //display signature information. - if( isInRange(ssmd->GetSigRVA()) ) - { - DisplayWriteFieldAddress(m_pSig, DataPtrToDisplay(ssmd->GetSigRVA()), - ssmd->m_cSig, StoredSigMethodDesc, - METHODDESCS); - } - else - { - DisplayWriteFieldPointer(m_pSig, DataPtrToDisplay(ssmd->GetSigRVA()), - StoredSigMethodDesc, METHODDESCS); - - } - CoverageRead(TO_TADDR(ssmd->GetSigRVA()), ssmd->m_cSig); - DisplayWriteFieldInt( m_cSig, ssmd->m_cSig, - StoredSigMethodDesc, METHODDESCS ); -#ifdef HOST_64BIT - DisplayWriteFieldEnumerated( m_dwExtendedFlags, - ssmd->m_dwExtendedFlags, - StoredSigMethodDesc, - s_SSMDExtendedFlags, W(", "), - METHODDESCS ); -#endif - DisplayEndVStructure( METHODDESCS ); //StoredSigMethodDesc - } - if( mc == mcDynamic ) - { - PTR_DynamicMethodDesc dmd(md); - DisplayStartVStructure( "DynamicMethodDesc", METHODDESCS ); - WriteFieldStr( m_pszMethodName, PTR_BYTE(dmd->GetMethodName()), - DynamicMethodDesc, METHODDESCS ); - if( !CHECK_OPT(METHODDESCS) ) - CoverageReadString( PTR_TO_TADDR(dmd->GetMethodName()) ); - DisplayWriteFieldPointer( m_pResolver, - DPtrToPreferredAddr(dmd->m_pResolver), - DynamicMethodDesc, METHODDESCS ); -#ifndef HOST_64BIT - DisplayWriteFieldEnumerated( m_dwExtendedFlags, - dmd->m_dwExtendedFlags, - DynamicMethodDesc, - s_SSMDExtendedFlags, W(", "), - METHODDESCS ); -#endif - DisplayEndVStructure( METHODDESCS ); - } - if (mc == mcFCall ) - { - PTR_FCallMethodDesc fcmd(md); - DisplayStartVStructure( "FCallMethodDesc", METHODDESCS ); - - DisplayWriteFieldInt( m_dwECallID, - fcmd->m_dwECallID, - FCallMethodDesc, - METHODDESCS ); - - DisplayEndVStructure( METHODDESCS ); //NDirectMethodDesc - } - if( mc == mcNDirect ) - { - PTR_NDirectMethodDesc ndmd(md); - DisplayStartVStructure( "NDirectMethodDesc", METHODDESCS ); - DPTR(NDirectMethodDesc::temp1) nd( PTR_HOST_MEMBER_TADDR(NDirectMethodDesc, ndmd, ndirect) ); - DisplayStartStructureWithOffset( ndirect, - DPtrToPreferredAddr(nd), - sizeof(*nd), NDirectMethodDesc, - METHODDESCS ); - DisplayWriteFieldPointer( m_pNativeNDirectTarget, - DataPtrToDisplay((TADDR)nd->m_pNativeNDirectTarget), - NDirectMethodDesc::temp1, - METHODDESCS ); - DisplayWriteFieldEnumerated( m_wFlags, nd->m_wFlags, - NDirectMethodDesc::temp1, - g_NDirectFlags, W(", "), - METHODDESCS ); - - WriteFieldStr( m_pszEntrypointName, - PTR_BYTE(dac_cast(ndmd->GetEntrypointName())), - NDirectMethodDesc::temp1, METHODDESCS ); - if( !CHECK_OPT(METHODDESCS) ) - CoverageReadString(dac_cast(ndmd->GetEntrypointName())); - if (md->IsQCall()) - { - DisplayWriteFieldInt( m_dwECallID, - nd->m_dwECallID, - NDirectMethodDesc::temp1, - METHODDESCS ); - } - else - { - WriteFieldStr( m_pszLibName, - PTR_BYTE(dac_cast(ndmd->GetLibNameRaw())), - NDirectMethodDesc::temp1, METHODDESCS ); - } - if( !CHECK_OPT(METHODDESCS) ) - CoverageReadString( dac_cast(ndmd->GetLibNameRaw()) ); - - PTR_NDirectWriteableData wnd( ndmd->GetWriteableData() ); - DisplayStartStructureWithOffset( m_pWriteableData, - DPtrToPreferredAddr(wnd), - sizeof(*wnd), - NDirectMethodDesc::temp1, - METHODDESCS ); - DisplayWriteFieldPointer( m_pNDirectTarget, - DataPtrToDisplay((TADDR)wnd->m_pNDirectTarget), NDirectWriteableData, METHODDESCS ); - if( !CHECK_OPT(METHODDESCS) ) - CoverageRead( PTR_TO_TADDR(wnd), sizeof(*wnd) ); - DisplayEndStructure( METHODDESCS ); //m_pWriteableData - - PTR_NDirectImportThunkGlue glue(ndmd->GetNDirectImportThunkGlue()); - -#ifdef HAS_NDIRECT_IMPORT_PRECODE - if (glue == NULL) - { - // import thunk glue is not needed for P/Invoke that is not inlinable - DisplayWriteFieldPointer( m_pImportThunkGlue, - NULL, - NDirectMethodDesc::temp1, - METHODDESCS ); - } - else - { - DisplayStartStructureWithOffset( m_pImportThunkGlue, - DPtrToPreferredAddr(glue), - sizeof(*glue), - NDirectMethodDesc::temp1, - METHODDESCS); -#else - DisplayStartStructureWithOffset( m_ImportThunkGlue, - DPtrToPreferredAddr(glue), - sizeof(*glue), - NDirectMethodDesc::temp1, - METHODDESCS); -#endif -#ifdef HAS_NDIRECT_IMPORT_PRECODE - /* REVISIT_TODO Thu 01/05/2006 - * Dump this properly as a precode - */ - WriteFieldMethodDesc( m_pMethodDesc, glue->m_pMethodDesc, - NDirectImportThunkGlue, METHODDESCS ); - { - PTR_Precode p(glue); - DumpPrecode( p, module ); - } - if( !CHECK_OPT(METHODDESCS) ) - CoverageRead(PTR_TO_TADDR(glue), sizeof(*glue)); - /* REVISIT_TODO Fri 12/16/2005 - * Factor out this code into some shared precode dumping code - */ -#else //!HAS_NDIRECT_IMPORT_PRECODE - /* REVISIT_TODO Fri 10/27/2006 - * For Whidbey AMD64 (!HAS_NDIRECT_IMPORT_PRECODE), I don't have this data structure in the output. - */ -#endif //HAS_NDIRECT_IMPORT_PRECODE - - DisplayEndStructure( METHODDESCS ); //m_pImportThunkGlue -#ifdef HAS_NDIRECT_IMPORT_PRECODE - } -#endif - -#ifdef TARGET_X86 - DisplayWriteFieldInt( m_cbStackArgumentSize, - nd->m_cbStackArgumentSize, - NDirectMethodDesc::temp1, METHODDESCS ); -#endif - - WriteFieldMethodDesc( m_pStubMD, - nd->m_pStubMD.GetValueMaybeNull(PTR_HOST_MEMBER_TADDR(NDirectMethodDesc::temp1, nd, m_pStubMD)), - NDirectMethodDesc::temp1, METHODDESCS ); - - DisplayEndStructure( METHODDESCS ); //ndirect - - - DisplayEndVStructure( METHODDESCS ); //NDirectMethodDesc - } - if( mc == mcEEImpl ) - { - DisplayStartVStructure( "EEImplMethodDesc", METHODDESCS ); - DisplayEndVStructure( METHODDESCS ); - } -#if defined(FEATURE_COMINTEROP) - if( mc == mcComInterop ) - { - PTR_ComPlusCallMethodDesc cpmd(md); - DisplayStartVStructure( "ComPlusCallMethodDesc", METHODDESCS ); - PTR_ComPlusCallInfo compluscall((TADDR)cpmd->m_pComPlusCallInfo); - - if (compluscall == NULL) - { - DisplayWriteFieldPointer( m_pComPlusCallInfo, - NULL, - ComPlusCallMethodDesc, - METHODDESCS ); - } - else - { - DumpComPlusCallInfo( compluscall, METHODDESCS ); - } - - DisplayEndVStructure( METHODDESCS ); //ComPlusCallMethodDesc - } -#endif - if( mc == mcInstantiated ) - { - PTR_InstantiatedMethodDesc imd(md); - DisplayStartVStructure( "InstantiatedMethodDesc", METHODDESCS ); - unsigned kind = imd->m_wFlags2 - & InstantiatedMethodDesc::KindMask; - if( kind == InstantiatedMethodDesc::SharedMethodInstantiation ) - { - PTR_DictionaryLayout layout(dac_cast(imd->GetDictLayoutRaw())); - IF_OPT(METHODDESCS) - { - WriteFieldDictionaryLayout( "m_pDictLayout", - offsetof(InstantiatedMethodDesc, m_pDictLayout ), - fieldsize(InstantiatedMethodDesc, m_pDictLayout), - layout, - GetDependencyFromMD(md)->pImport ); - } - else - { - while( layout != NULL ) - { - CoverageRead( PTR_TO_TADDR(layout), - sizeof(DictionaryLayout) - + sizeof(DictionaryEntryLayout) - * (layout->m_numSlots - 1) ); - layout = PTR_DictionaryLayout(TO_TADDR(layout->m_pNext)); - } - } - } - else if( kind == - InstantiatedMethodDesc::WrapperStubWithInstantiations ) - { - PTR_MethodDesc wimd(imd->IMD_GetWrappedMethodDesc()); - if( wimd == NULL || !DoWriteFieldAsFixup( "m_pWrappedMethodDesc", - offsetof(InstantiatedMethodDesc, m_pWrappedMethodDesc), - fieldsize(InstantiatedMethodDesc, m_pWrappedMethodDesc), - PTR_TO_TADDR(wimd) ) ) - { - WriteFieldMethodDesc( m_pWrappedMethodDesc, wimd, - InstantiatedMethodDesc, METHODDESCS ); - } - } - else - { - _ASSERTE(imd->m_pDictLayout.IsNull()); - DisplayWriteFieldPointer( m_pDictLayout, NULL, - InstantiatedMethodDesc, - METHODDESCS ); - } - //now handle the contents of the m_pMethInst/m_pPerInstInfo union. - unsigned numSlots = imd->m_wNumGenericArgs; - PTR_Dictionary inst(imd->IMD_GetMethodDictionary()); - unsigned dictSize; - if( kind == InstantiatedMethodDesc::SharedMethodInstantiation ) - { - dictSize = sizeof(TypeHandle); - } - else if( kind == InstantiatedMethodDesc::WrapperStubWithInstantiations ) - { - PTR_InstantiatedMethodDesc wrapped = - PTR_InstantiatedMethodDesc(imd->IMD_GetWrappedMethodDesc()); - if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(wrapped)) ) - { - /* XXX Mon 03/27/2006 - * Note that 4 is the correct answer for all IMDs at this time. - */ - TempBuffer buf; - MethodDescToString( md, buf ); - //m_display->ErrorPrintF( "WARNING! InstantiatedMethodDesc %S wraps a MethodDesc that is a fixup. I cannot accurately determine the size of the associated generic dictionary. Assuming 4.\n", (const WCHAR *)buf ); - dictSize = (imd->GetNumGenericMethodArgs() + 4) * sizeof(void*); - } - else - { - PTR_DictionaryLayout layout(wrapped->IsSharedByGenericMethodInstantiations() - ? dac_cast(wrapped->GetDictLayoutRaw()) : NULL ); - dictSize = DictionaryLayout::GetDictionarySizeFromLayout(imd->GetNumGenericMethodArgs(), - layout); - } - } - else - { - dictSize = sizeof(TypeHandle); - } - //instantiations has the number of slots of - //GetNumGenericMethodArgs. - if( inst == NULL ) - { - m_display->WriteFieldPointer( "m_pPerInstInfo", - offsetof(InstantiatedMethodDesc, m_pPerInstInfo), - fieldsize(InstantiatedMethodDesc, m_pPerInstInfo), - NULL ); - } - else - { - IF_OPT(METHODDESCS) - { - - m_display->StartStructureWithOffset( "m_pPerInstInfo", - offsetof(InstantiatedMethodDesc, m_pPerInstInfo), - fieldsize(InstantiatedMethodDesc, m_pPerInstInfo), - DPtrToPreferredAddr(inst), - dictSize ); - } - DisplayStartArray( "InstantiationInfo", W("[%-2s]: %s"), - METHODDESCS ); - /* REVISIT_TODO Thu 03/23/2006 - * This doesn't dump the contents of the dictionary which are - * hanging around after the real slots. Get around to doing that. - */ - for( unsigned i = 0; i < numSlots - && CHECK_OPT(METHODDESCS); ++i ) - { - DisplayStartElement( "Handle", METHODDESCS ); - DisplayWriteElementInt( "Index", i, METHODDESCS ); - - TypeHandle thArg = inst->GetInstantiation()[i].GetValue(); - IF_OPT(METHODDESCS) - WriteElementTypeHandle( "TypeHandle", thArg); - - /* XXX Fri 03/24/2006 - * There is no really good home for TypeDescs, so I gotta check - * lots of places for them. - */ - if( !CORCOMPILE_IS_POINTER_TAGGED(thArg.AsTAddr()) && - thArg.IsTypeDesc() ) - { - PTR_TypeDesc td(thArg.AsTypeDesc()); - if( isInRange(PTR_TO_TADDR(td)) ) - { - m_discoveredTypeDescs.AppendEx(td); - } - } - DisplayEndElement( METHODDESCS ); //Handle - } - //Instantiation Info - DisplayEndArray( "Total TypeHandles", METHODDESCS ); - - DisplayEndVStructure(METHODDESCS); //m_pPerInstInfo; - if( !CHECK_OPT(METHODDESCS) ) - CoverageRead(PTR_TO_TADDR(inst), numSlots * sizeof(*inst)); - } - - DisplayWriteFieldEnumerated( m_wFlags2, imd->m_wFlags2, - InstantiatedMethodDesc, s_IMDFlags, - W(", "), METHODDESCS ); - DisplayWriteFieldInt( m_wNumGenericArgs, imd->m_wNumGenericArgs, - InstantiatedMethodDesc, METHODDESCS ); - -#ifdef FEATURE_COMINTEROP - if (imd->IsGenericComPlusCall()) - { - PTR_ComPlusCallInfo compluscall = imd->IMD_GetComPlusCallInfo(); - DumpComPlusCallInfo( compluscall, METHODDESCS ); - } -#endif // FEATURE_COMINTEROP - - DisplayEndStructure( METHODDESCS ); - } - - DisplayEndStructure( METHODDESCS ); //MethodDesc (mdTypeName) - if( !CHECK_OPT(METHODDESCS) ) - CoverageRead( PTR_TO_TADDR(md), mdSize ); - -} -#ifdef _PREFAST_ -#pragma warning(pop) -#endif - -NativeImageDumper::EnumMnemonics NativeImageDumper::s_EECLIFlags[] = -{ -#define EECLI_FLAGS_ENTRY(x) NativeImageDumper::EnumMnemonics( EEClassLayoutInfo:: x, W(#x) ) - EECLI_FLAGS_ENTRY(e_BLITTABLE), - EECLI_FLAGS_ENTRY(e_MANAGED_SEQUENTIAL), - EECLI_FLAGS_ENTRY(e_ZERO_SIZED), - EECLI_FLAGS_ENTRY(e_HAS_EXPLICIT_SIZE), -#undef EECLI_FLAGS_ENTRY -}; - - -#ifdef _PREFAST_ -#pragma warning(push) -#pragma warning(disable:21000) // Suppress PREFast warning about overly large function -#endif -void -NativeImageDumper::DumpEEClassForMethodTable( PTR_MethodTable mt ) -{ - PTR_EEClass clazz = mt->GetClass(); - - _ASSERTE(CHECK_OPT(EECLASSES)); - _ASSERTE(clazz != NULL); - _ASSERTE(isInRange(PTR_TO_TADDR(clazz))); - - const char * eeClassType; - - if( clazz->HasLayout() ) - eeClassType = "LayoutEEClass"; - else if( mt->IsArray() ) - eeClassType = "ArrayClass"; - else if( clazz->IsDelegate() ) - eeClassType = "DelegateEEClass"; - else - eeClassType = "EEClass"; - - DisplayStartStructure( eeClassType, DPtrToPreferredAddr(clazz), clazz->GetSize(), - EECLASSES ); - { - TempBuffer buf; - MethodTableToString( mt, buf ); - DisplayWriteElementStringW( "Name", (const WCHAR *)buf, EECLASSES ); - } - - PTR_GuidInfo guidInfo = clazz->GetGuidInfo(); - if(guidInfo != NULL) - { - DisplayStartStructureWithOffset( m_pGuidInfo, - DPtrToPreferredAddr(guidInfo), - sizeof(*guidInfo), EEClass, - EECLASSES ); - TempBuffer buf; - GuidToString( guidInfo->m_Guid, buf ); - DisplayWriteFieldStringW( m_Guid, (const WCHAR *)buf, GuidInfo, - EECLASSES ); - DisplayWriteFieldFlag( m_bGeneratedFromName, - guidInfo->m_bGeneratedFromName, - GuidInfo, EECLASSES ); - DisplayEndStructure( EECLASSES ); //guidinfo - } - else - { - /* XXX Fri 10/14/2005 - * if Clazz isn't an interface, m_pGuidInfo is undefined. - */ - DisplayWriteFieldPointerAnnotated( m_pGuidInfo, PTR_TO_TADDR(guidInfo), - W("Invalid"), EEClass, EECLASSES ); - } - - -#ifdef _DEBUG - WriteFieldStr( m_szDebugClassName, - PTR_BYTE(TO_TADDR(clazz->m_szDebugClassName)), - EEClass, EECLASSES ); - DisplayWriteFieldFlag( m_fDebuggingClass, clazz->m_fDebuggingClass, - EEClass, EECLASSES ); -#endif - - WriteFieldMethodTable( m_pMethodTable, clazz->GetMethodTable(), EEClass, - EECLASSES ); - - WriteFieldCorElementType( m_NormType, (CorElementType)clazz->m_NormType, - EEClass, EECLASSES ); - - PTR_FieldDesc fdList = clazz->GetFieldDescList(); - - ULONG fieldCount = (ULONG)CountFields(mt); - _ASSERTE((fdList == NULL) == (fieldCount == 0)); - - IF_OPT(EECLASSES) - { - m_display->StartStructureWithOffset( "m_pFieldDescList", - offsetof(EEClass, m_pFieldDescList), - fieldsize(EEClass, m_pFieldDescList), - DPtrToPreferredAddr(fdList), - fdList != NULL ? - sizeof(*fdList) * fieldCount : - 0 ); - } - IF_OPT(VERBOSE_TYPES) - { - if( fdList != NULL ) - { - DisplayStartArray( "FieldDescs", NULL, EECLASSES ); - for( SIZE_T i = 0; i < fieldCount; ++i ) - { - PTR_FieldDesc fd = fdList + i; - IF_OPT(EECLASSES) - DumpFieldDesc( fd, "FieldDesc" ); - } - DisplayEndArray( "Total FieldDescs", EECLASSES ); //FieldDescs - } - } - else if( (fdList != NULL) && CHECK_OPT(DEBUG_COVERAGE) ) - { - for( SIZE_T i = 0; i < fieldCount; ++i ) - { - PTR_FieldDesc fd = fdList + i; -#ifdef _DEBUG - if( fd != NULL && fd->m_debugName != NULL ) - CoverageReadString( fd->m_debugName ); -#endif - } - CoverageRead( PTR_TO_TADDR(fdList), sizeof(*fdList) * fieldCount ); - } - - DisplayEndStructure( EECLASSES ); //FieldDescList - - DisplayWriteFieldEnumerated( m_dwAttrClass, clazz->GetAttrClass(), - EEClass, s_CorTypeAttr, W(" "), EECLASSES ); - DisplayWriteFieldEnumerated( m_VMFlags, clazz->m_VMFlags, EEClass, - s_VMFlags, W(", "), EECLASSES ); - - PTR_MethodDescChunk chunk = clazz->GetChunks(); - - DisplayStartArrayWithOffset( m_pChunks, NULL, EEClass, EECLASSES ); - while( chunk != NULL ) - { - DisplayStartStructure( "MethodDescChunk", - DPtrToPreferredAddr(chunk), - chunk->SizeOf(), EECLASSES ); - _ASSERTE(!CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(chunk->GetMethodTable()))); - PTR_MethodTable chunkMT = chunk->GetMethodTable(); - DisplayWriteFieldPointer( m_methodTable, - DPtrToPreferredAddr(chunkMT), - MethodDescChunk, EECLASSES ); - PTR_MethodDescChunk chunkNext = chunk->GetNextChunk(); - DisplayWriteFieldPointer( m_next, - DPtrToPreferredAddr(chunkNext), - MethodDescChunk, EECLASSES ); - DisplayWriteFieldInt( m_size, chunk->m_size, MethodDescChunk, - EECLASSES ); - DisplayWriteFieldInt( m_count, chunk->m_count, MethodDescChunk, - EECLASSES ); - DisplayWriteFieldInt( m_flagsAndTokenRange, chunk->m_flagsAndTokenRange, MethodDescChunk, - EECLASSES ); - /* XXX Wed 12/14/2005 - * Don't skip walking this array. I need to make sure I touch the - * precodes. - */ - DisplayStartArray( "MethodDescs", NULL, METHODDESCS ); - PTR_MethodDesc md(chunk->GetFirstMethodDesc()); - while (md != NULL) - { - IF_OPT_OR(METHODDESCS, DEBUG_COVERAGE) - { - PTR_Module module = mt->GetModule(); - if(CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(module) )) - DumpMethodDesc( md, PTR_Module((TADDR)0) ); - else - DumpMethodDesc( md, module ); - } - - // Check whether the next MethodDesc is within the bounds of the current chunks - TADDR pNext = PTR_HOST_TO_TADDR(md) + md->SizeOf(); - TADDR pEnd = PTR_HOST_TO_TADDR(chunk) + chunk->SizeOf(); - - md = (pNext < pEnd) ? PTR_MethodDesc(pNext) : NULL; - } - - DisplayEndArray( "Total MethodDescs", METHODDESCS); //MethodDescs - - chunk = chunk->GetNextChunk(); - - DisplayEndStructure( EECLASSES ); //MethodDescChunk - } - - DisplayEndArray( "Total MethodDescChunks", EECLASSES ); - /* REVISIT_TODO Fri 10/14/2005 - * Dump the class dependencies - */ - //_ASSERTE(!clazz->m_classDependencies.TestAnyBit()); - - /* REVISIT_TODO Mon 10/24/2005 - * Create vstructure for union? - */ - //decode union here -#ifdef FEATURE_COMINTEROP - if( clazz->IsBlittable() || clazz->HasLayout() ) - { - DisplayWriteFieldInt(m_cbNativeSize, clazz->m_cbNativeSize, EEClass, - EECLASSES ); - } - else if( clazz->IsInterface() ) - { - DisplayWriteFieldPointer( m_ohDelegate, - DataPtrToDisplay(clazz->m_ohDelegate), - EEClass, EECLASSES ); - } - else - { - static const WCHAR * ifnames[] ={W("Dual"),W("Vtable"),W("Dispatch")}; - m_display->WriteFieldEnumerated( "ComInterfaceType", - offsetof(EEClass, - m_ComInterfaceType), - fieldsize(EEClass, - m_ComInterfaceType), - (int)clazz->m_ComInterfaceType, - ifnames[(int)clazz->m_ComInterfaceType] ); - } -#else - DisplayWriteFieldInt( m_cbNativeSize, clazz->m_cbNativeSize, - EEClass, EECLASSES ); -#endif - -#if defined(FEATURE_COMINTEROP) - PTR_ComCallWrapperTemplate ccwTemplate(TO_TADDR(clazz->m_pccwTemplate)); - if( ccwTemplate != NULL ) - { - DisplayWriteFieldPointer( m_pccwTemplate, NULL, EEClass, - EECLASSES ); - } - else - { - /* REVISIT_TODO Fri 10/14/2005 - * Dump CcwTemplate - */ - DisplayWriteFieldPointer( m_pccwTemplate, - DPtrToPreferredAddr(ccwTemplate), EEClass, - EECLASSES ); - } -#endif // defined(FEATURE_COMINTEROP) - - //fields for classes that aren't just EEClasses. - if( clazz->HasLayout() ) - { - PTR_LayoutEEClass layoutClass(PTR_TO_TADDR(clazz)); - DisplayStartVStructure("LayoutEEClass", EECLASSES ); - - PTR_EEClassLayoutInfo eecli( PTR_HOST_MEMBER_TADDR( LayoutEEClass, - layoutClass, - m_LayoutInfo ) ); - DisplayStartStructureWithOffset( m_LayoutInfo, - DPtrToPreferredAddr(eecli), - sizeof(EEClassLayoutInfo), - LayoutEEClass, EECLASSES ); - /* REVISIT_TODO Fri 10/14/2005 - * Dump EEClassLayoutInfo - */ - DisplayWriteFieldInt( m_cbNativeSize, eecli->m_cbNativeSize, - EEClassLayoutInfo, VERBOSE_TYPES ); - DisplayWriteFieldInt( m_cbManagedSize, eecli->m_cbManagedSize, - EEClassLayoutInfo, VERBOSE_TYPES ); - DisplayWriteFieldInt( m_ManagedLargestAlignmentRequirementOfAllMembers, - eecli->m_ManagedLargestAlignmentRequirementOfAllMembers, - EEClassLayoutInfo, VERBOSE_TYPES ); - DisplayWriteFieldEnumerated( m_bFlags, eecli->m_bFlags, - EEClassLayoutInfo, s_EECLIFlags, W(", "), - VERBOSE_TYPES ); - DisplayWriteFieldInt( m_numCTMFields, eecli->m_numCTMFields, - EEClassLayoutInfo, VERBOSE_TYPES ); - PTR_NativeFieldDescriptor fmArray = eecli->GetNativeFieldDescriptors(); - DisplayWriteFieldAddress( m_pNativeFieldDescriptors, - DPtrToPreferredAddr(fmArray), - eecli->m_numCTMFields - * sizeof(NativeFieldDescriptor), - EEClassLayoutInfo, VERBOSE_TYPES ); - /* REVISIT_TODO Wed 03/22/2006 - * Dump the various types of NativeFieldDescriptors. - */ -#if 0 - DisplayStartArrayWithOffset( m_pNativeFieldDescriptors, NULL, - EEClassLayoutInfo, VERBOSE_TYPES ); - for( unsigned i = 0; i < eecli->m_numCTMFields; ++i ) - { - /* REVISIT_TODO Wed 03/22/2006 - * Try to display the type of the field marshaler in the future. - */ - PTR_NativeFieldDescriptor current = fmArray + i; - DisplayStartStructure( "NativeFieldDescriptor", - DPtrToPreferredAddr(current), - sizeof(*current), VERBOSE_TYPES ); - WriteFieldFieldDesc( m_pFD, PTR_FieldDesc(TO_TADDR(current->m_pFD)), - NativeFieldDescriptor, VERBOSE_TYPES ); - DisplayWriteFieldInt( m_offset, - current->m_offset, NativeFieldDescriptor, - VERBOSE_TYPES ); - DisplayEndStructure( VERBOSE_TYPES ); //FieldMarshaler - } - - DisplayEndArray( "Number of NativeFieldDescriptors", VERBOSE_TYPES ); //m_pNativeFieldDescriptors -#endif - - DisplayEndStructure( EECLASSES ); //LayoutInfo - - DisplayEndVStructure( EECLASSES ); //LayoutEEClass - } - else if( mt->IsArray() ) - { - PTR_ArrayClass arrayClass(PTR_TO_TADDR(clazz)); - DisplayStartVStructure( "ArrayClass", EECLASSES); - IF_OPT(EECLASSES) - { - m_display->WriteFieldInt( "m_rank", offsetof(ArrayClass, m_rank), - fieldsize(ArrayClass, m_rank), - arrayClass->GetRank() ); - } - DoWriteFieldCorElementType( "m_ElementType", - offsetof(ArrayClass, m_ElementType), - fieldsize(ArrayClass, m_ElementType), - arrayClass->GetArrayElementType() ); - - DisplayEndVStructure( EECLASSES ); //ArrayClass - } - else if( clazz->IsDelegate() ) - { - PTR_DelegateEEClass delegateClass(PTR_TO_TADDR(clazz)); - DisplayStartVStructure( "DelegateEEClass", EECLASSES ); - - DumpFieldStub( m_pStaticCallStub, delegateClass->m_pStaticCallStub, - DelegateEEClass, EECLASSES ); - DumpFieldStub( m_pInstRetBuffCallStub, - delegateClass->m_pInstRetBuffCallStub, - DelegateEEClass, EECLASSES ); - - WriteFieldMethodDesc( m_pInvokeMethod, - delegateClass->GetInvokeMethod(), - DelegateEEClass, EECLASSES ); - DumpFieldStub( m_pMultiCastInvokeStub, - delegateClass->m_pMultiCastInvokeStub, - DelegateEEClass, EECLASSES ); - - DPTR(UMThunkMarshInfo) - umInfo(TO_TADDR(delegateClass->m_pUMThunkMarshInfo)); - - if( umInfo == NULL ) - { - DisplayWriteFieldPointer( m_pUMThunkMarshInfo, NULL, - DelegateEEClass, EECLASSES ); - } - else - { - DisplayStartStructureWithOffset( m_pUMThunkMarshInfo, - DPtrToPreferredAddr(umInfo), - sizeof(*umInfo), - DelegateEEClass, EECLASSES ); - /* REVISIT_TODO Fri 10/14/2005 - * DumpUMThunkMarshInfo - */ - DisplayEndStructure( EECLASSES ); //UMThunkMarshInfo - } - - WriteFieldMethodDesc( m_pBeginInvokeMethod, - delegateClass->GetBeginInvokeMethod(), - DelegateEEClass, EECLASSES ); - WriteFieldMethodDesc( m_pEndInvokeMethod, - delegateClass->GetEndInvokeMethod(), - DelegateEEClass, EECLASSES ); - DisplayWriteFieldPointer( m_pMarshalStub, delegateClass->m_pMarshalStub, - DelegateEEClass, EECLASSES ); - - WriteFieldMethodDesc( m_pForwardStubMD, - PTR_MethodDesc(TO_TADDR(delegateClass->m_pForwardStubMD)), - DelegateEEClass, EECLASSES ); - WriteFieldMethodDesc( m_pReverseStubMD, - PTR_MethodDesc(TO_TADDR(delegateClass->m_pReverseStubMD)), - DelegateEEClass, EECLASSES ); - -#ifdef FEATURE_COMINTEROP - DPTR(ComPlusCallInfo) compluscall((TADDR)delegateClass->m_pComPlusCallInfo); - if (compluscall == NULL) - { - DisplayWriteFieldPointer( m_pComPlusCallInfo, - NULL, - DelegateEEClass, - EECLASSES ); - } - else - { - DumpComPlusCallInfo( compluscall, EECLASSES ); - } -#endif // FEATURE_COMINTEROP - - DisplayEndVStructure( EECLASSES ); //DelegateEEClass - } - - DisplayEndStructure( EECLASSES ); //eeClassType - - PTR_EEClassOptionalFields pClassOptional = clazz->GetOptionalFields(); - if (pClassOptional) - { - DisplayStartStructure( "EEClassOptionalFields", DPtrToPreferredAddr(pClassOptional), sizeof(EEClassOptionalFields), - EECLASSES ); - -#ifdef FEATURE_COMINTEROP - PTR_SparseVTableMap sparseVTMap(TO_TADDR(pClassOptional->m_pSparseVTableMap)); - if( sparseVTMap == NULL ) - { - DisplayWriteFieldPointer( m_pSparseVTableMap, NULL, EEClassOptionalFields, - EECLASSES ); - } - else - { - _ASSERTE( !"Untested code" ); - IF_OPT(EECLASSES) - { - m_display->StartStructure( "m_SparseVTableMap", - DPtrToPreferredAddr(sparseVTMap), - sizeof(*sparseVTMap) ); - } - _ASSERTE(sparseVTMap->m_MapList != NULL); - PTR_SparseVTableMap_Entry mapList(TO_TADDR(sparseVTMap->m_MapList)); - DisplayStartArray( "m_MapList", NULL, EECLASSES ); - for( WORD i = 0; i < sparseVTMap->m_MapEntries; ++i ) - { - DisplayWriteFieldInt( m_Start, mapList[i].m_Start, - SparseVTableMap::Entry, EECLASSES ); - DisplayWriteFieldInt( m_Span, mapList[i].m_Span, - SparseVTableMap::Entry, EECLASSES ); - DisplayWriteFieldInt( m_Span, mapList[i].m_MapTo, - SparseVTableMap::Entry, EECLASSES ); - } - - DisplayEndArray( "Total Entries", EECLASSES ); //m_MapList - - DisplayWriteFieldInt( m_MapEntries, sparseVTMap->m_MapEntries, - SparseVTableMap, EECLASSES ); - DisplayWriteFieldInt( m_Allocated, sparseVTMap->m_Allocated, - SparseVTableMap, EECLASSES ); - DisplayWriteFieldInt( m_LastUsed, sparseVTMap->m_LastUsed, - SparseVTableMap, EECLASSES ); - DisplayWriteFieldInt( m_VTSlot, sparseVTMap->m_VTSlot, - SparseVTableMap, EECLASSES ); - DisplayWriteFieldInt( m_MTSlot, sparseVTMap->m_MTSlot, - SparseVTableMap, EECLASSES ); - - DisplayEndStructure( EECLASSES ); //SparseVTableMap - } - - WriteFieldTypeHandle( m_pCoClassForIntf, pClassOptional->m_pCoClassForIntf, - EEClassOptionalFields, EECLASSES ); - - PTR_ClassFactoryBase classFactory(TO_TADDR(pClassOptional->m_pClassFactory)); - if( classFactory != NULL ) - { - DisplayWriteFieldPointer( m_pClassFactory, NULL, EEClassOptionalFields, - EECLASSES ); - } - else - { - /* REVISIT_TODO Fri 10/14/2005 - * Dump ComClassFactory - */ - DisplayWriteFieldPointer( m_pClassFactory, - DPtrToPreferredAddr(classFactory), - EEClassOptionalFields, EECLASSES ); - } -#endif // FEATURE_COMINTEROP - - PTR_DictionaryLayout layout = pClassOptional->m_pDictLayout; - if( layout == NULL ) - { - DisplayWriteFieldPointer( m_pDictLayout, NULL, EEClassOptionalFields, EECLASSES ); - } - else - { - IF_OPT(VERBOSE_TYPES) - { - WriteFieldDictionaryLayout( "m_pDictLayout", - offsetof(EEClassOptionalFields, m_pDictLayout), - fieldsize(EEClassOptionalFields, m_pDictLayout), - layout, GetDependencyFromMT(mt)->pImport ); - } - else - { - while( layout != NULL ) - { - CoverageRead( PTR_TO_TADDR(layout), - sizeof(DictionaryLayout) - + sizeof(DictionaryEntryLayout) - * (layout->m_numSlots - 1) ); - layout = PTR_DictionaryLayout(TO_TADDR(layout->m_pNext)); - } - } - } - PTR_BYTE varianceInfo = pClassOptional->GetVarianceInfo(); - if( varianceInfo == NULL ) - { - DisplayWriteFieldPointer( m_pVarianceInfo, NULL, - EEClassOptionalFields, EECLASSES ); - } - else - { - /* REVISIT_TODO Fri 10/14/2005 - * Dump variance info - */ - DisplayWriteFieldPointer( m_pVarianceInfo, - DPtrToPreferredAddr(varianceInfo), EEClassOptionalFields, - EECLASSES ); - } - - DisplayWriteFieldInt( m_cbModuleDynamicID, pClassOptional->m_cbModuleDynamicID, - EEClassOptionalFields, EECLASSES ); - - DisplayEndStructure( EECLASSES ); // EEClassOptionalFields - } -} // NativeImageDumper::DumpEEClassForMethodTable -#ifdef _PREFAST_ -#pragma warning(pop) -#endif - -enum TypeDescType -{ - TDT_IsTypeDesc, - TDT_IsParamTypeDesc, - TDT_IsTypeVarTypeDesc, - TDT_IsFnPtrTypeDesc -}; -const char * const g_typeDescTypeNames[] = -{ - "TypeDesc", - "ParamTypeDesc", - "TypeVarTypeDesc", - "FnPtrTypeDesc" -}; -int g_typeDescSizes[] = -{ - sizeof(TypeDesc), - sizeof(ParamTypeDesc), - sizeof(TypeVarTypeDesc), - -1//sizeof(FnPtrTypeDesc) -- variable size -}; -TypeDescType getTypeDescType( PTR_TypeDesc td ) -{ - _ASSERTE(td != NULL); - if( td->HasTypeParam() ) - return TDT_IsParamTypeDesc; - if( td->IsGenericVariable() ) - return TDT_IsTypeVarTypeDesc; - if( td->GetInternalCorElementType() == ELEMENT_TYPE_FNPTR ) - return TDT_IsFnPtrTypeDesc; - return TDT_IsTypeDesc; -} -NativeImageDumper::EnumMnemonics NativeImageDumper::s_TDFlags[] = -{ - -#define TDF_ENTRY(x) NativeImageDumper::EnumMnemonics(TypeDesc:: x, W(#x) ) - TDF_ENTRY(enum_flag_NeedsRestore), - TDF_ENTRY(enum_flag_PreRestored), - TDF_ENTRY(enum_flag_Unrestored), - TDF_ENTRY(enum_flag_UnrestoredTypeKey), - TDF_ENTRY(enum_flag_IsNotFullyLoaded), - TDF_ENTRY(enum_flag_DependenciesLoaded), -#undef TDF_ENTRY -}; - -NativeImageDumper::EnumMnemonics s_CConv[] = -{ -#define CC_ENTRY(x) NativeImageDumper::EnumMnemonics( x, W(#x) ) - -#define CC_CALLCONV_ENTRY(x) NativeImageDumper::EnumMnemonics( x, IMAGE_CEE_CS_CALLCONV_MASK, W(#x) ) - CC_CALLCONV_ENTRY(IMAGE_CEE_CS_CALLCONV_VARARG), - CC_CALLCONV_ENTRY(IMAGE_CEE_CS_CALLCONV_FIELD), - CC_CALLCONV_ENTRY(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG), - CC_CALLCONV_ENTRY(IMAGE_CEE_CS_CALLCONV_PROPERTY), - CC_CALLCONV_ENTRY(IMAGE_CEE_CS_CALLCONV_UNMANAGED), - CC_CALLCONV_ENTRY(IMAGE_CEE_CS_CALLCONV_GENERICINST), - CC_CALLCONV_ENTRY(IMAGE_CEE_CS_CALLCONV_NATIVEVARARG), -#undef CC_CALLCONV_ENTRY - - CC_ENTRY(IMAGE_CEE_CS_CALLCONV_HASTHIS), - CC_ENTRY(IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS), - CC_ENTRY(IMAGE_CEE_CS_CALLCONV_GENERIC) -}; - - -void NativeImageDumper::DumpTypeDesc( PTR_TypeDesc td ) -{ - _ASSERTE(CHECK_OPT(TYPEDESCS)); - TypeDescType tdt = getTypeDescType(td); - int size = g_typeDescSizes[(int)tdt]; - if( size == -1 ) - { - _ASSERTE(tdt == TDT_IsFnPtrTypeDesc); - size = FnPtrTypeDesc::DacSize(PTR_TO_TADDR(td)); - } - DisplayStartStructure( g_typeDescTypeNames[(int)tdt], - DPtrToPreferredAddr(td), size, TYPEDESCS ); - - //first handle the fields of typedesc - WriteFieldCorElementType( m_typeAndFlags, td->GetInternalCorElementType(), - TypeDesc, TYPEDESCS ); - DisplayWriteFieldEnumerated( m_typeAndFlags, td->m_typeAndFlags, TypeDesc, - s_TDFlags, W(", "), TYPEDESCS ); - if( tdt == TDT_IsParamTypeDesc ) - { - PTR_ParamTypeDesc ptd(td); - DisplayStartVStructure( "ParamTypeDesc", TYPEDESCS ); - WriteFieldMethodTable( m_TemplateMT, ptd->GetTemplateMethodTableInternal(), - ParamTypeDesc, TYPEDESCS ); - WriteFieldTypeHandle( m_Arg, ptd->m_Arg, - ParamTypeDesc, TYPEDESCS ); - DisplayWriteFieldPointer( m_hExposedClassObject, - DataPtrToDisplay(ptd->m_hExposedClassObject), - ParamTypeDesc, TYPEDESCS ); - - DisplayEndVStructure( TYPEDESCS ); //ParamTypeDesc - } - else if( tdt == TDT_IsFnPtrTypeDesc ) - { - PTR_FnPtrTypeDesc ftd(td); - DisplayStartVStructure( "FnPtrTypeDesc", TYPEDESCS ); - DisplayWriteFieldInt( m_NumArgs, ftd->m_NumArgs, FnPtrTypeDesc, - TYPEDESCS ); - DisplayWriteFieldEnumerated( m_CallConv, ftd->m_CallConv, - FnPtrTypeDesc, s_CConv, W(", "), - TYPEDESCS ); - DisplayStartArrayWithOffset( m_RetAndArgTypes, W("[%-4s]: %s"), - FnPtrTypeDesc, TYPEDESCS ); - PTR_TypeHandle args( PTR_HOST_MEMBER_TADDR(FnPtrTypeDesc, ftd, - m_RetAndArgTypes) ); - for( unsigned i = 0; i < ftd->m_NumArgs; ++i ) - { - DisplayStartElement( "Argument", TYPEDESCS ); - DisplayWriteElementInt( "Index", i, TYPEDESCS ); - IF_OPT( TYPEDESCS ) - WriteElementTypeHandle( "TypeHandle", args[i] ); - DisplayEndElement( TYPEDESCS ); - } - DisplayEndArray( "Total Arguments", TYPEDESCS ); - DisplayEndVStructure( TYPEDESCS ); - } - else if( tdt == TDT_IsTypeVarTypeDesc ) - { - PTR_TypeVarTypeDesc tvtd(td); - DisplayStartVStructure( "TypeVarTypeDesc", TYPEDESCS ); - DisplayWriteFieldPointer( m_pModule, - DPtrToPreferredAddr(tvtd->GetModule()), - TypeVarTypeDesc, TYPEDESCS ); - DisplayWriteFieldUInt( m_typeOrMethodDef, - tvtd->m_typeOrMethodDef, - TypeVarTypeDesc, TYPEDESCS ); - DisplayWriteFieldInt( m_numConstraints, tvtd->m_numConstraints, - TypeVarTypeDesc, TYPEDESCS ); - if( tvtd->m_constraints == NULL ) - { - DisplayWriteFieldPointer( m_constraints, NULL, TypeVarTypeDesc, - TYPEDESCS ); - } - else - { - DisplayStartStructureWithOffset( m_constraints, - DPtrToPreferredAddr(tvtd->m_constraints), - sizeof(*tvtd->m_constraints) * - tvtd->m_numConstraints, - TypeVarTypeDesc, TYPEDESCS ); - DisplayStartArray( "Constraints", NULL, TYPEDESCS ); - for( unsigned i = 0; i < tvtd->m_numConstraints; ++i ) - { - WriteElementTypeHandle( "TypeHandle", tvtd->m_constraints[i] ); - } - DisplayEndArray( "Total Constraints", TYPEDESCS ); //Constraints - DisplayEndStructure( TYPEDESCS ); //m_constraints - } - DisplayWriteFieldPointer( m_hExposedClassObject, - DataPtrToDisplay(tvtd->m_hExposedClassObject), - TypeVarTypeDesc, TYPEDESCS ); - DisplayWriteFieldUInt( m_token, tvtd->m_token, TypeVarTypeDesc, - TYPEDESCS ); - DisplayWriteFieldInt( m_index, tvtd->m_index, TypeVarTypeDesc, - TYPEDESCS ); - - DisplayEndVStructure( TYPEDESCS ); //TypeVarTypeDesc - } - - - DisplayEndStructure( TYPEDESCS ); // g_typeDescTypeNames - -} - -void NativeImageDumper::DumpDictionaryEntry( const char * elementName, - DictionaryEntryKind kind, - PTR_DictionaryEntry entry ) -{ - m_display->StartElement( elementName ); - const char * name = NULL; - switch(kind) - { - case EmptySlot: - m_display->WriteEmptyElement("EmptySlot"); - break; - case TypeHandleSlot: - { - TypeHandle th = dac_cast)>(entry)->GetValue(); - WriteElementTypeHandle( "TypeHandle", th ); - /* XXX Fri 03/24/2006 - * There is no straightforward home for these, so make sure to - * record them - */ - if( !CORCOMPILE_IS_POINTER_TAGGED(th.AsTAddr()) && th.IsTypeDesc() ) - { - PTR_TypeDesc td(th.AsTypeDesc()); - if( isInRange(PTR_TO_TADDR(td)) ) - { - m_discoveredTypeDescs.AppendEx(td); - } - } - } - break; - case MethodDescSlot: - { - TempBuffer buf; - PTR_MethodDesc md(TO_TADDR(*entry)); - WriteElementMethodDesc( "MethodDesc", md ); - } - break; - case MethodEntrySlot: - name = "MethodEntry"; - goto StandardEntryDisplay; - case ConstrainedMethodEntrySlot: - name = "ConstrainedMethodEntry"; - goto StandardEntryDisplay; - case DispatchStubAddrSlot: - name = "DispatchStubAddr"; - goto StandardEntryDisplay; - /* REVISIT_TODO Tue 10/11/2005 - * Print out name information here - */ - case FieldDescSlot: - name = "FieldDescSlot"; -StandardEntryDisplay: - m_display->WriteElementPointer(name, DataPtrToDisplay((TADDR)*entry)); - break; - default: - _ASSERTE( !"unreachable" ); - } - m_display->EndElement(); //elementName -} - -#ifdef FEATURE_READYTORUN -IMAGE_DATA_DIRECTORY * NativeImageDumper::FindReadyToRunSection(ReadyToRunSectionType type) -{ - PTR_READYTORUN_SECTION pSections = dac_cast(dac_cast(m_pReadyToRunHeader) + sizeof(READYTORUN_HEADER)); - for (DWORD i = 0; i < m_pReadyToRunHeader->NumberOfSections; i++) - { - // Verify that section types are sorted - _ASSERTE(i == 0 || (pSections[i - 1].Type < pSections[i].Type)); - - READYTORUN_SECTION * pSection = pSections + i; - if (pSection->Type == type) - return &pSection->Section; - } - return NULL; -} - -// -// Ready to Run specific dumping methods -// -void NativeImageDumper::DumpReadyToRun() -{ - m_pReadyToRunHeader = m_decoder.GetReadyToRunHeader(); - - m_nativeReader = NativeFormat::NativeReader(dac_cast(m_decoder.GetBase()), m_decoder.GetVirtualSize()); - - IMAGE_DATA_DIRECTORY * pRuntimeFunctionsDir = FindReadyToRunSection(ReadyToRunSectionType::RuntimeFunctions); - if (pRuntimeFunctionsDir != NULL) - { - m_pRuntimeFunctions = dac_cast(m_decoder.GetDirectoryData(pRuntimeFunctionsDir)); - m_nRuntimeFunctions = pRuntimeFunctionsDir->Size / sizeof(T_RUNTIME_FUNCTION); - } - else - { - m_nRuntimeFunctions = 0; - } - - IMAGE_DATA_DIRECTORY * pEntryPointsDir = FindReadyToRunSection(ReadyToRunSectionType::MethodDefEntryPoints); - if (pEntryPointsDir != NULL) - m_methodDefEntryPoints = NativeFormat::NativeArray((TADDR)&m_nativeReader, pEntryPointsDir->VirtualAddress); - - DisplayStartCategory("NativeInfo", NATIVE_INFO); - - IF_OPT(NATIVE_INFO) - DumpReadyToRunHeader(); - - DisplayEndCategory(NATIVE_INFO); //NativeInfo - - IF_OPT_OR3(METHODS, GC_INFO, DISASSEMBLE_CODE) - DumpReadyToRunMethods(); - - IF_OPT(RELOCATIONS) - DumpBaseRelocs(); -} - -const NativeImageDumper::EnumMnemonics s_ReadyToRunFlags[] = -{ -#define RTR_FLAGS(f) NativeImageDumper::EnumMnemonics(f, W(#f)) - RTR_FLAGS(READYTORUN_FLAG_PLATFORM_NEUTRAL_SOURCE), -#undef RTR_FLAGS -}; - -void NativeImageDumper::DumpReadyToRunHeader() -{ - IF_OPT(NATIVE_INFO) - { - m_display->StartStructure( "READYTORUN_HEADER", - DPtrToPreferredAddr(dac_cast(m_pReadyToRunHeader)), - sizeof(*m_pReadyToRunHeader) ); - - DisplayWriteFieldUInt( Signature, m_pReadyToRunHeader->Signature, READYTORUN_HEADER, ALWAYS ); - DisplayWriteFieldUInt( MajorVersion, m_pReadyToRunHeader->MajorVersion, READYTORUN_HEADER, ALWAYS ); - DisplayWriteFieldUInt( MinorVersion, m_pReadyToRunHeader->MinorVersion, READYTORUN_HEADER, ALWAYS ); - - DisplayWriteFieldEnumerated( Flags, m_pReadyToRunHeader->Flags, - READYTORUN_HEADER, s_ReadyToRunFlags, W(", "), - NATIVE_INFO ); - - m_display->EndStructure(); //READYTORUN_HEADER - } -} - -void NativeImageDumper::DumpReadyToRunMethods() -{ - DisplayStartArray("Methods", NULL, METHODS); - - for (uint rid = 1; rid <= m_methodDefEntryPoints.GetCount(); rid++) - { - uint offset; - if (!m_methodDefEntryPoints.TryGetAt(rid - 1, &offset)) - continue; - - uint id; - offset = m_nativeReader.DecodeUnsigned(offset, &id); - - if (id & 1) - { - if (id & 2) - { - uint val; - m_nativeReader.DecodeUnsigned(offset, &val); - offset -= val; - } - - // TODO: Dump fixups from dac_cast(m_pLayout->GetBase()) + offset - - id >>= 2; - } - else - { - id >>= 1; - } - - _ASSERTE(id < m_nRuntimeFunctions); - PTR_RUNTIME_FUNCTION pRuntimeFunction = m_pRuntimeFunctions + id; - PCODE pEntryPoint = dac_cast(m_decoder.GetBase()) + pRuntimeFunction->BeginAddress; - - SString buf; - AppendTokenName(TokenFromRid(rid, mdtMethodDef), buf, m_import); - - DumpReadyToRunMethod(pEntryPoint, pRuntimeFunction, buf); - } - - DisplayEndArray("Total Methods", METHODS); //Methods -} - -extern PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntimeFunction, /* out */ SIZE_T * pSize); - -void NativeImageDumper::DumpReadyToRunMethod(PCODE pEntryPoint, PTR_RUNTIME_FUNCTION pRuntimeFunction, SString& name) -{ - //Read the GCInfo to get the total method size. - unsigned methodSize = 0; - unsigned gcInfoSize = UINT_MAX; - - SIZE_T nUnwindDataSize; - PTR_VOID pUnwindData = GetUnwindDataBlob(dac_cast(m_decoder.GetBase()), pRuntimeFunction, &nUnwindDataSize); - - // GCInfo immediatelly follows unwind data - PTR_CBYTE gcInfo = dac_cast(pUnwindData) + nUnwindDataSize; - - void(*stringOutFn)(const char *, ...); - IF_OPT(GC_INFO) - { - stringOutFn = stringOut; - } - else - { - stringOutFn = nullStringOut; - } - if (gcInfo != NULL) - { - PTR_CBYTE curGCInfoPtr = gcInfo; - g_holdStringOutData.Clear(); - GCDump gcDump(GCINFO_VERSION); - gcDump.gcPrintf = stringOutFn; - UINT32 r2rversion = m_pReadyToRunHeader->MajorVersion; - UINT32 gcInfoVersion = GCInfoToken::ReadyToRunVersionToGcInfoVersion(r2rversion); - GCInfoToken gcInfoToken = { curGCInfoPtr, gcInfoVersion }; - -#if !defined(TARGET_X86) && defined(USE_GC_INFO_DECODER) - GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_CODE_LENGTH); - methodSize = gcInfoDecoder.GetCodeLength(); -#endif - - //dump the data to a string first so we can get the gcinfo size. -#ifdef TARGET_X86 - InfoHdr hdr; - stringOutFn("method info Block:\n"); - curGCInfoPtr += gcDump.DumpInfoHdr(curGCInfoPtr, &hdr, &methodSize, 0); - stringOutFn("\n"); -#endif - - IF_OPT(METHODS) - { -#ifdef TARGET_X86 - stringOutFn("PointerTable:\n"); - curGCInfoPtr += gcDump.DumpGCTable(curGCInfoPtr, - hdr, - methodSize, 0); - gcInfoSize = curGCInfoPtr - gcInfo; -#elif defined(USE_GC_INFO_DECODER) - stringOutFn("PointerTable:\n"); - curGCInfoPtr += gcDump.DumpGCTable(curGCInfoPtr, - methodSize, 0); - gcInfoSize = (unsigned)(curGCInfoPtr - gcInfo); -#endif - } - - //data is output below. - } - - DisplayStartElement("Method", METHODS); - DisplayWriteElementStringW("Name", (const WCHAR *)name, METHODS); - - DisplayStartStructure("GCInfo", - DPtrToPreferredAddr(gcInfo), - gcInfoSize, - METHODS); - - DisplayStartTextElement("Contents", GC_INFO); - DisplayWriteXmlTextBlock(("%S", (const WCHAR *)g_holdStringOutData), GC_INFO); - DisplayEndTextElement(GC_INFO); //Contents - - DisplayEndStructure(METHODS); //GCInfo - - DisplayStartStructure("Code", DataPtrToDisplay(pEntryPoint), methodSize, - METHODS); - - IF_OPT(DISASSEMBLE_CODE) - { - // Disassemble hot code. Read the code into the host process. - /* REVISIT_TODO Mon 10/24/2005 - * Is this align up right? - */ - BYTE * codeStartHost = - reinterpret_cast(PTR_READ(pEntryPoint, - (ULONG32)ALIGN_UP(methodSize, - CODE_SIZE_ALIGN))); - DisassembleMethod(codeStartHost, methodSize); - } - - DisplayEndStructure(METHODS); //Code - - DisplayEndElement(METHODS); //Method -} -#endif // FEATURE_READYTORUN - -#if 0 -void NativeImageDumper::RecordTypeRef( mdTypeRef token, PTR_MethodTable mt ) -{ - if( mt != NULL ) - m_mtToTypeRefMap.Add( mt, token ); -} -mdTypeRef NativeImageDumper::FindTypeRefForMT( PTR_MethodTable mt ) -{ - return m_mtToTypeRefMap.Find(mt); -} -#endif - -#else //!FEATURE_PREJIT //dummy implementation for dac HRESULT ClrDataAccess::DumpNativeImage(CLRDATA_ADDRESS loadedBase, LPCWSTR name, @@ -9004,7 +15,6 @@ HRESULT ClrDataAccess::DumpNativeImage(CLRDATA_ADDRESS loadedBase, { return E_FAIL; } -#endif //FEATURE_PREJIT /* REVISIT_TODO Mon 10/10/2005 * Here is where it gets bad. There is no DAC build of gcdump, so instead diff --git a/src/coreclr/debug/daccess/nidump.h b/src/coreclr/debug/daccess/nidump.h deleted file mode 100644 index f39b4db15a4377..00000000000000 --- a/src/coreclr/debug/daccess/nidump.h +++ /dev/null @@ -1,619 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -#ifndef _NIDUMP_H_ -#define _NIDUMP_H_ - - -#ifdef FEATURE_PREJIT -#include - -//some DPTR definitions that aren't elsewhere in the source -typedef DPTR(const COR_SIGNATURE) PTR_CCOR_SIGNATURE; -typedef DPTR(IMAGE_SECTION_HEADER) PTR_IMAGE_SECTION_HEADER; -typedef DPTR(struct CerRoot) PTR_CerRoot; -typedef DPTR(DictionaryEntry) PTR_DictionaryEntry; -typedef DPTR(GuidInfo) PTR_GuidInfo; -#if defined(FEATURE_COMINTEROP) -typedef DPTR(SparseVTableMap) PTR_SparseVTableMap; -#endif -#if defined(FEATURE_COMINTEROP) -typedef DPTR(ClassFactoryBase) PTR_ClassFactoryBase; -#endif -typedef DPTR(LayoutEEClass) PTR_LayoutEEClass; -typedef DPTR(ArrayClass) PTR_ArrayClass; -typedef DPTR(DelegateEEClass) PTR_DelegateEEClass; -typedef DPTR(UMThunkMarshInfo) PTR_UMThunkMarshInfo; -typedef DPTR(CORCOMPILE_DEPENDENCY) PTR_CORCOMPILE_DEPENDENCY; -typedef DPTR(struct ModuleCtorInfo) PTR_ModuleCtorInfo; -typedef DPTR(class EEImplMethodDesc) PTR_EEImplMethodDesc; -typedef DPTR(class EEClassLayoutInfo) PTR_EEClassLayoutInfo; -typedef DPTR(class FieldMarshaler) PTR_FieldMarshaler; -typedef DPTR(LPCUTF8) PTR_LPCUTF8; -typedef DPTR(struct STORAGESIGNATURE UNALIGNED) PTR_STORAGESIGNATURE; -typedef DPTR(struct STORAGEHEADER UNALIGNED) PTR_STORAGEHEADER; -typedef DPTR(struct STORAGESTREAM UNALIGNED) PTR_STORAGESTREAM; -typedef DPTR(ArrayMethodDesc) PTR_ArrayMethodDesc; - - -#if 0 -template -class TokenHashMap : CClosedHash< Pair > -{ -public: - typedef DPTR(PtrType) Key; - typedef mdTypeRef Data; - typedef Pair Entry; - typedef CClosedHash< Entry > Parent; - TokenHashMap(int buckets = 23) : Parent(buckets) - { - - } - ~TokenHashMap() { } - - void Add(const Key key, const Data data) - { - Entry * newEntry = Parent::Add((void*)PTR_HOST_TO_TADDR(key)); - newEntry->First() = key; - newEntry->Second() = data; - } - - Data Find(const Key key) - { - Entry * found = Parent::Find((void*)PTR_HOST_TO_TADDR(key)); - if( !found ) - return mdTokenNil; - else - return found->Second(); - } - inline Key GetKey(Entry * entry) { return entry->First(); } - Parent::ELEMENTSTATUS Status(Entry * entry) - { - if( entry->First() == 0xffffffff && entry->Second() == 0xffffffff ) - return Parent::DELETED; - else if( entry->First() == 0x00000000 && entry->Second() == 0x00000000 ) - return Parent::FREE; - else - return Parent::USED; - } - void SetStatus(Entry * entry, Parent::ELEMENTSTATUS status) - { - switch(status) - { - case Parent::FREE: - entry->First() = Key((TADDR)0x00000000); - entry->Second() = 0x00000000; - break; - case Parent::DELETED: - entry->First() = Key((TADDR)0xffffffff); - entry->Second() = 0xffffffff; - break; - } - } - - unsigned int Compare(const Entry * lhs, Entry * rhs) - { - return lhs->First() == rhs->First() && lhs->Second() == rhs->Second(); - } - - //parent methods - unsigned int Hash(const void *pData) - { - return (int)(INT_PTR)pData; - } - unsigned int Compare(const void * p1, BYTE * p2) - { - return Compare((const Entry *) p1, (Entry*) p2); - } - Parent::ELEMENTSTATUS Status(BYTE * p){ - return Status((Entry*)p); - } - void SetStatus(BYTE * p, Parent::ELEMENTSTATUS status) { - SetStatus((Entry*)p, status); - } - void * GetKey(BYTE *p) { return (void*)GetKey((Entry*)p); } -}; -typedef TokenHashMap EEClassToTypeRefMap; -typedef TokenHashMap MTToTypeRefMap; -#endif - -class NativeImageDumper -{ -public: - //DPTR to private field needs to be a member of NativeImageDumper -#if defined(FEATURE_COMINTEROP) - typedef DPTR(SparseVTableMap::Entry) PTR_SparseVTableMap_Entry; -#endif - - NativeImageDumper(PTR_VOID loadedBase, const WCHAR * const name, - IXCLRDataDisplay * display, IXCLRLibrarySupport *support, - IXCLRDisassemblySupport * dis); - ~NativeImageDumper(); - - //type dumping methods - void DumpNativeImage(); - - void ComputeMethodFixupHistogram( PTR_Module module ); - void DumpFixupTables( PTR_Module module); - - void WriteElementTypeHandle( const char * name, TypeHandle th ); - void DoWriteFieldFieldDesc( const char * name, unsigned offset, - unsigned fieldSize, PTR_FieldDesc fd ); - void DoWriteFieldMethodDesc( const char * name, unsigned offset, - unsigned fieldSize, PTR_MethodDesc md ); - void DoWriteFieldTypeHandle( const char * name, unsigned offset, - unsigned fieldSize, TypeHandle th ); - void DoWriteFieldMDToken( const char * name, unsigned offset, - unsigned fieldsize, mdToken token, - IMetaDataImport2 *pAssemblyImport = NULL); - void DoWriteFieldMethodTable( const char * name, unsigned offset, - unsigned fieldSize, PTR_MethodTable mt ); - //if fixup is a fixup, it writes the field as if it were a fixup (including - //subelements) and returns true. Otherwise, it returns false. - BOOL DoWriteFieldAsFixup( const char * name, unsigned offset, - unsigned fieldSize, TADDR fixup ); - - void WriteElementMethodTable( const char * name, PTR_MethodTable mt ); - void WriteElementMethodDesc( const char * name, PTR_MethodDesc md ); - - void DoWriteFieldCorElementType( const char * name, unsigned offset, - unsigned fieldSize, CorElementType type ); - void WriteElementMDToken( const char * name, mdToken token ); - - void DoWriteFieldAsHex( const char * name, unsigned offset, - unsigned fieldSize, PTR_BYTE data, - unsigned dataLen ); - - void DumpMethods(PTR_Module module); - - void DumpCompleteMethod(PTR_Module module, MethodIterator& mi); - - void DisassembleMethod(BYTE *method, SIZE_T size); - - void DumpModule( PTR_Module module ); - void DumpNative(); - void DumpNativeHeader(); - - void DumpBaseRelocs(); - void DumpHelperTable(); - - void DumpMethodFixups(PTR_Module module, - TADDR fixupList); - - void DumpTypes( PTR_Module module ); - - void DumpMethodTable( PTR_MethodTable mt, const char * name, - PTR_Module module ); - -#ifndef STUB_DISPATCH_ALL - void DumpMethodTableSlotChunk( TADDR slotChunk, COUNT_T size, bool ); -#endif - - void DumpSlot( unsigned index, PCODE tgt ); - void DumpFieldDesc( PTR_FieldDesc fd, const char * name ); - void DumpEEClassForMethodTable( PTR_MethodTable mt ); - void DumpTypeDesc( PTR_TypeDesc td ); - - void DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ); - void DumpPrecode( PTR_Precode precode, PTR_Module module ); - - - - - - - - //utility routines - void AppendTokenName(mdToken token, SString& str); - void AppendTokenName(mdToken token, SString& str, IMetaDataImport2 *pImport, - bool force = false); - void PrintManifestTokenName(mdToken token, SString& str); - void PrintManifestTokenName(mdToken token, SString& str, - IMetaDataAssemblyImport *pAssemblyImport, - bool force = false); - void WriteElementsFixupBlob(PTR_CORCOMPILE_IMPORT_SECTION pSection, SIZE_T fixup); - void WriteElementsFixupTargetAndName(RVA rva); - void FixupBlobToString(RVA rva, SString& buf); - - void AppendToken(mdToken token, SString& buf); - void AppendToken(mdToken token, SString& buf, IMetaDataImport2 *pImport); - IMetaDataImport2* TypeToString(PTR_CCOR_SIGNATURE &sig, SString& buf); // assumes pImport is m_import - IMetaDataImport2* TypeToString(PTR_CCOR_SIGNATURE &sig, SString& buf, - IMetaDataImport2 *pImport, - IMetaDataImport2 *pOrigImport =NULL); - void MethodTableToString( PTR_MethodTable mt, SString& buf ); - void TypeHandleToString( TypeHandle td, SString& buf ); - void TypeDescToString( PTR_TypeDesc td, SString& buf ); - void DictionaryToArgString( PTR_Dictionary dictionary, unsigned numArgs, SString& buf ); - - void EntryPointToString( PCODE pEntryPoint, SString& buf ); - void MethodDescToString( PTR_MethodDesc md, SString& buf ); - void FieldDescToString( PTR_FieldDesc fd, SString& buf ); - //uses tok to generate a name if fd == NULL - void FieldDescToString( PTR_FieldDesc fd, mdFieldDef tok, SString& buf ); - -#ifdef FEATURE_READYTORUN -private: - READYTORUN_HEADER * m_pReadyToRunHeader; - - PTR_RUNTIME_FUNCTION m_pRuntimeFunctions; - DWORD m_nRuntimeFunctions; - - NativeFormat::NativeReader m_nativeReader; - NativeFormat::NativeArray m_methodDefEntryPoints; - - IMAGE_DATA_DIRECTORY * FindReadyToRunSection(ReadyToRunSectionType type); - -public: - void DumpReadyToRun(); - void DumpReadyToRunHeader(); - void DumpReadyToRunMethods(); - void DumpReadyToRunMethod(PCODE pEntryPoint, PTR_RUNTIME_FUNCTION pRuntimeFunction, SString& name); -#endif // FEATURE_READYTORUN - -private: - PEDecoder m_decoder; - const WCHAR * const m_name; - PTR_VOID m_baseAddress; - SIZE_T m_imageSize; - IXCLRDataDisplay * m_display; - IXCLRLibrarySupport * m_librarySupport; - - bool isInRange(TADDR ptr) - { - return dac_cast(m_baseAddress) <= ptr - && ptr < (dac_cast(m_baseAddress) + m_imageSize); - } - - - COUNT_T ** m_fixupHistogram; - - #define COUNT_HISTOGRAM_SIZE 16 - COUNT_T m_fixupCountHistogram[COUNT_HISTOGRAM_SIZE]; - COUNT_T m_fixupCount; //used to track above counts - - // Primary image metadata - IMetaDataImport2 *m_import; - IMetaDataAssemblyImport *m_assemblyImport; - - // Installation manifest metadata. For native images this is metadata - // copied from the IL image. - IMetaDataImport2 *m_manifestImport; - IMetaDataAssemblyImport *m_manifestAssemblyImport; - - //helper for ComputeMethodFixupHistogram - BOOL HandleFixupForHistogram(PTR_CORCOMPILE_IMPORT_SECTION pSection, SIZE_T fixupIndex, SIZE_T *fixupCell, BOOL mayUsePrecompiledNDirectMethods = TRUE); - - //helper for DumpMethodFixups - BOOL HandleFixupForMethodDump(PTR_CORCOMPILE_IMPORT_SECTION pSection, SIZE_T fixupIndex, SIZE_T *fixupCell, BOOL mayUsePrecompiledNDirectMethods = TRUE); - - // Dependencies - -public: - struct Dependency - { - CORCOMPILE_DEPENDENCY * entry; - //CORINFO_ASSEMBLY_HANDLE assembly; - - TADDR pPreferredBase; - TADDR pLoadedAddress; - SIZE_T size; - - PTR_Module pModule; - IMetaDataImport2 *pImport; - TADDR pMetadataStartTarget; - TADDR pMetadataStartHost; - SIZE_T MetadataSize; - bool fIsCoreLib; - bool fIsHardbound; - WCHAR name[128]; - }; - - /* REVISIT_TODO Fri 12/09/2005 - * Perhaps the module and import should be in the dependency. In order to - * properly name tokens in modules w/o import entries. - */ - struct Import - { - DWORD index; - Dependency *dependency; - }; -private: - - Dependency *m_dependencies; - COUNT_T m_numDependencies; - Import *m_imports; - COUNT_T m_numImports; - CORCOMPILE_DEPENDENCY m_self; - - bool inline isSelf(const Dependency* dep) { - return &m_dependencies[0] == dep; - } - - - void OpenMetadata(); - void WriteElementsMetadata( const char * elementName, - TADDR data, SIZE_T size ); - NativeImageDumper::Dependency* - GetDependency(mdAssemblyRef token, IMetaDataAssemblyImport *pImport = NULL); - NativeImageDumper::Import *OpenImport(int i); - NativeImageDumper::Dependency * OpenDependency(int index); - void TraceDumpImport(int idx, NativeImageDumper::Import * import); - void TraceDumpDependency(int idx, NativeImageDumper::Dependency * dependency); - mdAssemblyRef MapAssemblyRefToManifest(mdAssemblyRef token, IMetaDataAssemblyImport *pAssemblyImport); - - const Dependency * GetDependencyForFixup(RVA rva); - const Dependency * GetDependencyForModule( PTR_Module module ); -#if 0 - const Import * GetImportForPointer( TADDR ptr ); -#endif - const Dependency * GetDependencyForPointer( TADDR ptr ); -#ifdef MANUAL_RELOCS - template< typename T > - inline T RemapPointerForReloc( T ptr ); - - inline TADDR RemapTAddrForReloc( TADDR ptr ); - - inline TADDR RemapTAddrForReloc( const NativeImageDumper::Dependency * d, - TADDR ptr ); - - template< typename T > - inline T RemapPointerForReloc( const NativeImageDumper::Dependency * d, - T ptr ); -#endif - - - // msdis support - -#if 0 - static size_t TranslateFixupCallback(const DIS *, DIS::ADDR, size_t, WCHAR *, size_t, DWORDLONG *); - static size_t TranslateRegrelCallback(const DIS *, DIS::REGA, DWORD, WCHAR *, size_t, DWORD *); - static size_t TranslateConstCallback(const DIS *, DWORD, WCHAR *, size_t); -#endif - IXCLRDisassemblySupport * m_dis; - static SIZE_T __stdcall TranslateFixupCallback(IXCLRDisassemblySupport *dis, - CLRDATA_ADDRESS addr, - SIZE_T size, __out_ecount(nameSize) WCHAR *name, - SIZE_T nameSize, - DWORDLONG *offset); - static SIZE_T __stdcall TranslateAddressCallback(IXCLRDisassemblySupport *dis, - CLRDATA_ADDRESS addr, - __out_ecount(nameSize) WCHAR *name, SIZE_T nameSize, - DWORDLONG *offset); - size_t TranslateSymbol(IXCLRDisassemblySupport *dis, - CLRDATA_ADDRESS addr, __out_ecount(nameSize) WCHAR *name, - SIZE_T nameSize, DWORDLONG *offset); - - CLRDATA_ADDRESS m_currentAddress; - bool m_currentIsAddress; - - //mscorwks sizes - TADDR m_mscorwksBase; - TADDR m_mscorwksPreferred; - SIZE_T m_mscorwksSize; - - - //internal type dumpers - void DumpDictionaryEntry( const char * name, DictionaryEntryKind kind, - PTR_DictionaryEntry entry ); - void WriteFieldDictionaryLayout( const char * name, unsigned offset, - unsigned fieldSize, - PTR_DictionaryLayout layout, - IMetaDataImport2 * import ); - - - IMAGE_SECTION_HEADER * FindSection( char const * name ); - - - //map traversal methods and helpers - void IterateTypeDefToMTCallback(TADDR taddrTarget, TADDR flags, PTR_LookupMapBase map, DWORD rid); - void IterateTypeRefToMTCallback(TADDR taddrTarget, TADDR flags, PTR_LookupMapBase map, DWORD rid); - void IterateMethodDefToMDCallback(TADDR taddrTarget, TADDR flags, PTR_LookupMapBase map, DWORD rid); - void IterateFieldDefToFDCallback(TADDR taddrTarget, TADDR flags, PTR_LookupMapBase map, DWORD rid); - void IterateMemberRefToDescCallback(TADDR taddrTarget, TADDR flags, PTR_LookupMapBase map, DWORD rid); - void IterateGenericParamToDescCallback(TADDR fdTarget, TADDR flags, PTR_LookupMapBase map, DWORD rid); - void IterateFileReferencesCallback(TADDR moduleTarget, TADDR flags, PTR_LookupMapBase map, DWORD rid); - void IterateManifestModules(TADDR moduleTarget, TADDR flags, PTR_LookupMapBase map, DWORD rid); - - void TraverseMap(PTR_LookupMapBase map, const char * name, unsigned offset, - unsigned fieldSize, - void(NativeImageDumper::*cb)(TADDR, TADDR, PTR_LookupMapBase, DWORD)); - - template - void TraverseNgenHash(DPTR(HASH_CLASS) pTable, const char * name, - unsigned offset, unsigned fieldSize, - bool saveClasses, - void (NativeImageDumper::*DisplayEntryFunction)(void *, DPTR(HASH_ENTRY_CLASS), bool), - void *pContext); - template - void TraverseNgenPersistedEntries(DPTR(HASH_CLASS) pTable, - DPTR(typename HASH_CLASS::PersistedEntries) pEntries, - bool saveClasses, - void (NativeImageDumper::*DisplayEntryFunction)(void *, DPTR(HASH_ENTRY_CLASS), bool), - void *pContext); - - void TraverseClassHashEntry(void *pContext, PTR_EEClassHashEntry pEntry, bool saveClasses); - void TraverseClassHash(PTR_EEClassHashTable pTable, const char * name, - unsigned offset, unsigned fieldSize, - bool saveClasses); - -#ifdef FEATURE_COMINTEROP - void TraverseGuidToMethodTableEntry(void *pContext, PTR_GuidToMethodTableEntry pEntry, bool saveClasses); - void TraverseGuidToMethodTableHash(PTR_GuidToMethodTableHashTable pTable, const char * name, - unsigned offset, unsigned fieldSize, bool saveClasses); -#endif // FEATURE_COMINTEROP - - void TraverseMemberRefToDescHashEntry(void *pContext, PTR_MemberRefToDescHashEntry pEntry, bool saveClasses); - - void TraverseMemberRefToDescHash(PTR_MemberRefToDescHashTable pTable, const char * name, - unsigned offset, unsigned fieldSize, bool saveClasses); - - - void TraverseTypeHashEntry(void *pContext, PTR_EETypeHashEntry pEntry, bool saveClasses); - void TraverseTypeHash(PTR_EETypeHashTable pTable, const char * name, - unsigned offset, unsigned fieldSize ); - - void TraverseInstMethodHashEntry(void *pContext, PTR_InstMethodHashEntry pEntry, bool saveClasses); - void TraverseInstMethodHash(PTR_InstMethodHashTable pTable, - const char * name, unsigned offset, - unsigned fieldSize, PTR_Module module); - - void TraverseStubMethodHashEntry(void *pContext, PTR_StubMethodHashEntry pEntry, bool saveClasses); - void TraverseStubMethodHash(PTR_StubMethodHashTable pTable, - const char * name, unsigned offset, - unsigned fieldSize, PTR_Module module); - - void DoWriteFieldStr( PTR_BYTE ptr, const char * name, unsigned offset, - unsigned fieldSize ); - - - template - TADDR DPtrToPreferredAddr( T ptr ); - - TADDR DPtrToPreferredAddr( TADDR tptr ); - - void DumpAssemblySignature(CORCOMPILE_ASSEMBLY_SIGNATURE & assemblySignature); - - SIZE_T CountFields( PTR_MethodTable mt ); - mdToken ConvertToTypeDef( mdToken typeSpecOrRef, IMetaDataImport2* (&pImport) ); - SIZE_T CountDictionariesInClass( mdToken typeDefOrRef, IMetaDataImport2 * pImport ); - PTR_EEClass GetClassFromMT( PTR_MethodTable mt ); - PTR_MethodTable GetParent( PTR_MethodTable mt ); - - const Dependency* GetDependencyFromFD( PTR_FieldDesc fd ); - const Dependency* GetDependencyFromMD( PTR_MethodDesc md ); - const Dependency* GetDependencyFromMT( PTR_MethodTable mt ); - - CLRNativeImageDumpOptions m_dumpOptions; - inline TADDR RvaToDisplay( SIZE_T rva ); - inline TADDR DataPtrToDisplay(TADDR ptr); - inline int CheckOptions( CLRNativeImageDumpOptions opt ); - - //support various LookupMap Iterators - SArray m_discoveredMTs; - - struct SlotChunk - { - TADDR addr; - WORD nSlots; - bool isRelative; - - inline bool operator==(const SlotChunk& sc) const - { - return (addr == sc.addr) && (nSlots == sc.nSlots) && (isRelative == sc.isRelative); - } - - inline bool operator<(const SlotChunk& sc) const - { - if (addr < sc.addr) - { - return TRUE; - } - else if (addr > sc.addr) - { - return FALSE; - } - else - { - return nSlots < sc.nSlots; - } - } - }; - - SArray m_discoveredSlotChunks; - //SArray m_discoveredMDs; - //SArray m_discoveredFDs; - SArray m_discoveredClasses; - SArray m_discoveredTypeDescs; - - typedef InlineSString<128> TempBuffer; - - /* XXX Mon 10/03/2005 - * When we encounter pointers from metadata they are already in the host - * process because we read all of metadata in as one big block (since the - * metadata api isn't dac-ized. Map the metadata pointers back to good DAC - * pointers for compatibility with certain sig parsing code. - */ - TADDR m_MetadataStartHost; - TADDR m_MetadataStartTarget; - COUNT_T m_MetadataSize; - - //Support dumping IL. The COR_ILMETHOD_DECODER is not DACized, so read the - //whole IL section in, and translate RVAs into host pointers into the IL - //section copy - RVA m_ILSectionStart; - BYTE * m_ILHostCopy; -#ifdef _DEBUG - COUNT_T m_ILSectionSize; -#endif - - //This is true if we are hard bound to corelib. This enables various forms of generics dumping and MT - //dumping that require g_pObjectClass to be set. - bool m_isCoreLibHardBound; - -#if 0 - PTR_CCOR_SIGNATURE metadataToHostDAC( PCCOR_SIGNATURE pSig, - IMetaDataImport2 * import ); -#endif - template - DPTR(T) metadataToHostDAC( T * pSig, IMetaDataImport2 * import); - - void DoDumpFieldStub( PTR_Stub stub, unsigned offset, unsigned fieldSize, - const char * name ); -#ifdef FEATURE_COMINTEROP - void DoDumpComPlusCallInfo( PTR_ComPlusCallInfo compluscall ); -#endif // FEATURE_COMINTEROP - - SIZE_T m_sectionAlignment; - inline SIZE_T GetSectionAlignment() const; - -public: - //this is the list of valid precode addresses for the current module. - struct PrecodeRange - { - PrecodeRange( CorCompileSection section, TADDR start, SIZE_T size ) - : m_sectionType(section), m_rangeStart(start), - m_rangeSize(size) { } - CorCompileSection m_sectionType; - TADDR m_rangeStart; - SIZE_T m_rangeSize; - }; -private: - bool isPrecode(TADDR maybePrecode); - void FixupThunkToString(PTR_CORCOMPILE_IMPORT_SECTION pImportSection, TADDR thunkAddr, SString& buf); - -#if 0 - MTToTypeRefMap m_mtToTypeRefMap; - EEClassToTypeRefMap m_eeClassToTypeRefMap; - void RecordTypeRef( mdTypeRef token, PTR_MethodTable mt ); - void RecordTypeRef( mdTypeRef token, PTR_EEClass clazz ); - mdTypeRef FindTypeRefForMT( PTR_MethodTable mt ); - mdTypeRef FindTypeRefForEEClass( PTR_EEClass clazz ); -#endif - - -public: - struct EnumMnemonics - { - EnumMnemonics( DWORD val, const WCHAR * m ) - : value(val), mask(val), mnemonic(m){ } - EnumMnemonics( DWORD val, DWORD msk, const WCHAR * m ) - : value(val), mask(msk), mnemonic(m) { } - DWORD value; - DWORD mask; - const WCHAR * mnemonic; - }; - - static EnumMnemonics s_ModulePersistedFlags[]; - static EnumMnemonics s_MDC[]; - static EnumMnemonics s_MDFlag2[]; - static EnumMnemonics s_TDFlags[]; - static EnumMnemonics s_SSMDExtendedFlags[]; - static EnumMnemonics s_IMDFlags[]; - static EnumMnemonics s_EECLIFlags[]; -}; -#include "nidump.inl" - -#endif //FEATURE_PREJIT -#endif diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index f075dbe29c4e2e..f79cfd5912d4c1 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -433,22 +433,10 @@ ClrDataAccess::GetJitManagerList(unsigned int count, struct DacpJitManagerInfo m EEJitManager *eeJitManager = PTR_EEJitManager(PTR_HOST_TO_TADDR(managerPtr)); currentPtr->ptrHeapList = HOST_CDADDR(eeJitManager->m_pCodeHeap); } -#ifdef FEATURE_PREJIT - if (count >= 2) - { - NativeImageJitManager * managerPtr = ExecutionManager::GetNativeImageJitManager(); - DacpJitManagerInfo *currentPtr = &managers[1]; - currentPtr->managerAddr = HOST_CDADDR(managerPtr); - currentPtr->codeType = managerPtr->GetCodeType(); - } -#endif } else if (pNeeded) { *pNeeded = 1; -#ifdef FEATURE_PREJIT - (*pNeeded)++; -#endif } SOSDacLeave(); diff --git a/src/coreclr/debug/daccess/task.cpp b/src/coreclr/debug/daccess/task.cpp index c3143bf243b710..83d0c2870c6f71 100644 --- a/src/coreclr/debug/daccess/task.cpp +++ b/src/coreclr/debug/daccess/task.cpp @@ -2835,12 +2835,6 @@ ClrDataModule::SetJITCompilerFlags( { hr = E_INVALIDARG; } -#ifdef FEATURE_PREJIT - else if (m_module->HasNativeImage()) - { - hr = CORDBG_E_CANT_CHANGE_JIT_SETTING_FOR_ZAP_MODULE; - } -#endif else { _ASSERTE(m_module != NULL); diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 791871946a1b24..134e3dbab4c963 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -14737,32 +14737,8 @@ HRESULT CordbProcess::SetDesiredNGENCompilerFlags(DWORD dwFlags) PUBLIC_API_ENTRY(this); FAIL_IF_NEUTERED(this); -#if defined(FEATURE_PREJIT) - if ((dwFlags != CORDEBUG_JIT_DEFAULT) && (dwFlags != CORDEBUG_JIT_DISABLE_OPTIMIZATION)) - { - return E_INVALIDARG; - } - - CordbProcess *pProcess = GetProcess(); - ATT_REQUIRE_STOPPED_MAY_FAIL(pProcess); - HRESULT hr = S_OK; - EX_TRY - { - // Left-side checks that this is a valid time to set the Ngen flags. - hr = pProcess->GetDAC()->SetNGENCompilerFlags(dwFlags); - if (!SUCCEEDED(hr) && GetShim() != NULL) - { - // Emulate V2 error semantics. - hr = GetShim()->FilterSetNgenHresult(hr); - } - } - EX_CATCH_HRESULT(hr); - return hr; - -#else // !FEATURE_PREJIT return CORDBG_E_NGEN_NOT_SUPPORTED; -#endif // FEATURE_PREJIT } HRESULT CordbProcess::GetDesiredNGENCompilerFlags(DWORD *pdwFlags ) diff --git a/src/coreclr/ildasm/dasm.cpp b/src/coreclr/ildasm/dasm.cpp index efe6652b3b0ada..0f7de27fa21da4 100644 --- a/src/coreclr/ildasm/dasm.cpp +++ b/src/coreclr/ildasm/dasm.cpp @@ -94,9 +94,6 @@ BOOL g_fThisIsInstanceMethod; BOOL g_fTryInCode = TRUE; BOOL g_fLimitedVisibility = FALSE; -#if defined(_DEBUG) && defined(FEATURE_PREJIT) -BOOL g_fNGenNativeMetadata = FALSE; -#endif BOOL g_fHidePub = TRUE; BOOL g_fHidePriv = TRUE; BOOL g_fHideFam = TRUE; @@ -7443,29 +7440,6 @@ BOOL DumpFile() g_tkEntryPoint = VAL32(IMAGE_COR20_HEADER_FIELD(*g_CORHeader, EntryPointToken)); // integration with MetaInfo -#if defined(_DEBUG) && defined(FEATURE_PREJIT) - if (g_fNGenNativeMetadata) - { - //if this is an ngen image, use the native metadata. - if( !g_CORHeader->ManagedNativeHeader.Size ) - { - printError( g_pFile, "/native only works on NGen images." ); - goto exit; - } - CORCOMPILE_HEADER * pNativeHeader; - g_pPELoader->getVAforRVA(VAL32(g_CORHeader->ManagedNativeHeader.VirtualAddress), (void**)&pNativeHeader); - - if (pNativeHeader->Signature != CORCOMPILE_SIGNATURE) - { - printError( g_pFile, "/native only works on NGen images." ); - goto exit; - } - - g_pPELoader->getVAforRVA(VAL32(pNativeHeader->ManifestMetaData.VirtualAddress), &g_pMetaData); - g_cbMetaData = VAL32(pNativeHeader->ManifestMetaData.Size); - } - else -#endif { if (g_pPELoader->getVAforRVA(VAL32(g_CORHeader->MetaData.VirtualAddress),&g_pMetaData) == FALSE) { diff --git a/src/coreclr/ildasm/windasm.cpp b/src/coreclr/ildasm/windasm.cpp index 94abfcdb0d8250..d0f090429ae71a 100644 --- a/src/coreclr/ildasm/windasm.cpp +++ b/src/coreclr/ildasm/windasm.cpp @@ -63,9 +63,6 @@ extern char* g_pszObjFileName; extern FILE* g_pFile; extern BOOL g_fLimitedVisibility; -#if defined(_DEBUG) && defined(FEATURE_PREJIT) -extern BOOL g_fNGenNativeMetadata; -#endif extern BOOL g_fHidePub; extern BOOL g_fHidePriv; extern BOOL g_fHideFam; @@ -248,12 +245,6 @@ int ProcessOneArg(__in __nullterminated char* szArg, __out char** ppszObjFileNam g_fLimitedVisibility = TRUE; g_fHidePub = FALSE; } -#if defined(_DEBUG) && defined(FEATURE_PREJIT) - else if (_stricmp(szOpt, "nat") == 0) - { - g_fNGenNativeMetadata = TRUE; - } -#endif else if (_stricmp(szOpt, "pre") == 0) { //g_fPrettyPrint = TRUE; diff --git a/src/coreclr/inc/corpriv.h b/src/coreclr/inc/corpriv.h index e480706e3d5537..42bb19135e7316 100644 --- a/src/coreclr/inc/corpriv.h +++ b/src/coreclr/inc/corpriv.h @@ -76,11 +76,8 @@ enum MDInternalImportFlags { MDInternalImport_Default = 0, MDInternalImport_NoCache = 1, // Do not share/cached the results of opening the image -#ifdef FEATURE_PREJIT - MDInternalImport_TrustedNativeImage = 2, // The image is a native image, and so its format can be trusted - MDInternalImport_ILMetaData = 4, // Open the IL metadata, even if this is a native image - MDInternalImport_TrustedNativeImage_and_IL = MDInternalImport_TrustedNativeImage | MDInternalImport_ILMetaData, -#endif + // unused = 2, + // unused = 4, MDInternalImport_OnlyLookInCache =0x20, // Only look in the cache. (If the cache does not have the image already loaded, return NULL) }; // enum MDInternalImportFlags @@ -470,57 +467,6 @@ DECLARE_INTERFACE_(IGetIMDInternalImport, IUnknown) ) PURE; }; -// =========================================================================== -#ifdef FEATURE_PREJIT -// =========================================================================== - -// Use the default JIT compiler -#define DEFAULT_NGEN_COMPILER_DLL_NAME W("clrjit.dll") - -#ifndef DACCESS_COMPILE - -/* --------------------------------------------------------------------------- * - * NGen logger - * --------------------------------------------------------------------------- */ - #include "mscorsvc.h" - -struct ICorSvcLogger; -class SvcLogger -{ -public: - - SvcLogger(); - ~SvcLogger(); - void ReleaseLogger(); - void SetSvcLogger(ICorSvcLogger *pCorSvcLoggerArg); - BOOL HasSvcLogger(); - ICorSvcLogger* GetSvcLogger(); - void Printf(const CHAR *format, ...); - void SvcPrintf(const CHAR *format, ...); - void Printf(const WCHAR *format, ...); - void Printf(CorSvcLogLevel logLevel, const WCHAR *format, ...); - void SvcPrintf(const WCHAR *format, ...); - void Log(const WCHAR *message, CorSvcLogLevel logLevel = LogLevel_Warning); - //Need to add this to allocate StackSString, as we don't want static class - -private: - - void LogHelper(SString s, CorSvcLogLevel logLevel = LogLevel_Success); - //instantiations that need VM services like contracts in dllmain. - void CheckInit(); - - StackSString* pss; - ICorSvcLogger *pCorSvcLogger; -}; // class SvcLogger - -SvcLogger *GetSvcLogger(); -BOOL HasSvcLogger(); -#endif // #ifndef DACCESS_COMPILE - -// =========================================================================== -#endif // #ifdef FEATURE_PREJIT -// =========================================================================== - struct CORCOMPILE_ASSEMBLY_SIGNATURE; struct CORCOMPILE_VERSION_INFO; struct CORCOMPILE_DEPENDENCY; diff --git a/src/coreclr/inc/daccess.h b/src/coreclr/inc/daccess.h index 71c5d2f376025a..82009b77890e24 100644 --- a/src/coreclr/inc/daccess.h +++ b/src/coreclr/inc/daccess.h @@ -619,10 +619,6 @@ typedef struct _DacGlobals ULONG fn__ThePreStubPatchLabel; ULONG fn__PrecodeFixupThunk; -#ifdef FEATURE_PREJIT - ULONG fn__StubDispatchFixupStub; - ULONG fn__StubDispatchFixupPatchLabel; -#endif #ifdef FEATURE_COMINTEROP ULONG fn__Unknown_AddRef; ULONG fn__Unknown_AddRefSpecial; diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h index e27c122b5645a2..fdae380a90cb4f 100644 --- a/src/coreclr/inc/dacvars.h +++ b/src/coreclr/inc/dacvars.h @@ -76,9 +76,6 @@ DEFINE_DACVAR(ULONG, LONG, ExecutionManager__m_dwReaderCount, ExecutionManager:: DEFINE_DACVAR(ULONG, LONG, ExecutionManager__m_dwWriterLock, ExecutionManager::m_dwWriterLock) DEFINE_DACVAR(ULONG, PTR_EEJitManager, ExecutionManager__m_pEEJitManager, ExecutionManager::m_pEEJitManager) -#ifdef FEATURE_PREJIT -DEFINE_DACVAR(ULONG, PTR_NativeImageJitManager, ExecutionManager__m_pNativeImageJitManager, ExecutionManager::m_pNativeImageJitManager) -#endif #ifdef FEATURE_READYTORUN DEFINE_DACVAR(ULONG, PTR_ReadyToRunJitManager, ExecutionManager__m_pReadyToRunJitManager, ExecutionManager::m_pReadyToRunJitManager) #endif @@ -121,11 +118,6 @@ DEFINE_DACVAR(ULONG, PTR_GcDacVars, dac__g_gcDacGlobals, g_gcDacGlobals) DEFINE_DACVAR(ULONG, PTR_AppDomain, AppDomain__m_pTheAppDomain, AppDomain::m_pTheAppDomain) DEFINE_DACVAR(ULONG, PTR_SystemDomain, SystemDomain__m_pSystemDomain, SystemDomain::m_pSystemDomain) -#ifdef FEATURE_PREJIT -DEFINE_DACVAR(ULONG, BOOL, SystemDomain__s_fForceDebug, SystemDomain::s_fForceDebug) -DEFINE_DACVAR(ULONG, BOOL, SystemDomain__s_fForceProfiling, SystemDomain::s_fForceProfiling) -DEFINE_DACVAR(ULONG, BOOL, SystemDomain__s_fForceInstrument, SystemDomain::s_fForceInstrument) -#endif #ifdef FEATURE_INTEROP_DEBUGGING DEFINE_DACVAR(ULONG, DWORD, dac__g_debuggerWordTLSIndex, g_debuggerWordTLSIndex) @@ -237,10 +229,6 @@ DEFINE_DACVAR(ULONG, DWORD, CorHost2__m_dwStartupFlags, CorHost2::m_dwStartupFla DEFINE_DACVAR(ULONG, HRESULT, dac__g_hrFatalError, ::g_hrFatalError) -#if defined(DEBUGGING_SUPPORTED) && defined (FEATURE_PREJIT) - DEFINE_DACVAR(ULONG, DWORD, PEFile__s_NGENDebugFlags, PEFile::s_NGENDebugFlags) -#endif //defined(DEBUGGING_SUPPORTED) && defined (FEATURE_PREJIT) - #ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS DEFINE_DACVAR(ULONG, DWORD, dac__g_MiniMetaDataBuffMaxSize, ::g_MiniMetaDataBuffMaxSize) DEFINE_DACVAR(ULONG, TADDR, dac__g_MiniMetaDataBuffAddress, ::g_MiniMetaDataBuffAddress) diff --git a/src/coreclr/inc/fixuppointer.h b/src/coreclr/inc/fixuppointer.h index 920f618527807f..10af5f8c32c48b 100644 --- a/src/coreclr/inc/fixuppointer.h +++ b/src/coreclr/inc/fixuppointer.h @@ -11,560 +11,6 @@ #include "daccess.h" -#ifdef FEATURE_PREJIT - -//---------------------------------------------------------------------------- -// RelativePointer is pointer encoded as relative offset. It is used to reduce size of -// relocation section in NGen images. Conversion from/to RelativePointer needs -// address of the pointer ("this") converted to TADDR passed in from outside. -// Converting "this" to TADDR is not possible in the DAC transparently because -// DAC is based on exact pointers, not ranges. -// There are several flavors of conversions from/to RelativePointer: -// - GetValue/SetValue: The most common version. Assumes that the pointer is not NULL. -// - GetValueMaybeNull/SetValueMaybeNull: Pointer can be NULL. -// - GetValueAtPtr: Static version of GetValue. It is -// meant to simplify access to arrays of RelativePointers. -// - GetValueMaybeNullAtPtr -template -class RelativePointer -{ -public: - - static constexpr bool isRelative = true; - typedef PTR_TYPE type; - -#ifndef DACCESS_COMPILE - RelativePointer() - { - m_delta = (TADDR)NULL; - - _ASSERTE (IsNull()); - } -#else // DACCESS_COMPILE - RelativePointer() =delete; -#endif // DACCESS_COMPILE - - // Implicit copy/move is not allowed - // Bitwise copy is implemented by BitwiseCopyTo method - RelativePointer(const RelativePointer &) =delete; - RelativePointer(RelativePointer &&) =delete; - RelativePointer& operator = (const RelativePointer &) =delete; - RelativePointer& operator = (RelativePointer &&) =delete; - - // Returns whether the encoded pointer is NULL. - BOOL IsNull() const - { - LIMITED_METHOD_DAC_CONTRACT; - // Pointer pointing to itself is treated as NULL - return m_delta == (TADDR)NULL; - } - - // Returns value of the encoded pointer. Assumes that the pointer is not NULL. - PTR_TYPE GetValue(TADDR base) const - { - LIMITED_METHOD_DAC_CONTRACT; - PRECONDITION(!IsNull()); - return dac_cast(base + m_delta); - } - -#ifndef DACCESS_COMPILE - // Returns value of the encoded pointer. Assumes that the pointer is not NULL. - // Does not need explicit base and thus can be used in non-DAC builds only. - FORCEINLINE PTR_TYPE GetValue() const - { - LIMITED_METHOD_CONTRACT; - return GetValue((TADDR)this); - } -#endif - - // Static version of GetValue. It is meant to simplify access to arrays of pointers. - FORCEINLINE static PTR_TYPE GetValueAtPtr(TADDR base) - { - LIMITED_METHOD_DAC_CONTRACT; - return dac_cast)>(base)->GetValue(base); - } - - // Returns value of the encoded pointer. The pointer can be NULL. - PTR_TYPE GetValueMaybeNull(TADDR base) const - { - LIMITED_METHOD_DAC_CONTRACT; - - // Cache local copy of delta to avoid races when the value is changing under us. - TADDR delta = m_delta; - - if (delta == 0) - return NULL; - - return dac_cast(base + delta); - } - -#ifndef DACCESS_COMPILE - // Returns value of the encoded pointer. The pointer can be NULL. - // Does not need explicit base and thus can be used in non-DAC builds only. - FORCEINLINE PTR_TYPE GetValueMaybeNull() const - { - LIMITED_METHOD_CONTRACT; - return GetValueMaybeNull((TADDR)this); - } -#endif - - // Static version of GetValueMaybeNull. It is meant to simplify access to arrays of pointers. - FORCEINLINE static PTR_TYPE GetValueMaybeNullAtPtr(TADDR base) - { - LIMITED_METHOD_DAC_CONTRACT; - return dac_cast)>(base)->GetValueMaybeNull(base); - } - -#ifndef DACCESS_COMPILE - // Set encoded value of the pointer. Assumes that the value is not NULL. - FORCEINLINE void SetValue(PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - PRECONDITION(addr != NULL); - m_delta = (TADDR)addr - (TADDR)this; - } - - // Set encoded value of the pointer. The value can be NULL. - void SetValueMaybeNull(TADDR base, PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - if (addr == NULL) - m_delta = NULL; - else - m_delta = (TADDR)addr - (TADDR)base; - } - - // Set encoded value of the pointer. The value can be NULL. - FORCEINLINE void SetValueMaybeNull(PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - SetValueMaybeNull((TADDR)this, addr); - } - - FORCEINLINE void SetValueVolatile(PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - SetValue(addr); - } -#endif - -#ifndef DACCESS_COMPILE - void BitwiseCopyTo(RelativePointer &dest) const - { - dest.m_delta = m_delta; - } -#endif // DACCESS_COMPILE - - static TADDR GetRelativeMaybeNull(TADDR base, TADDR addr) - { - LIMITED_METHOD_DAC_CONTRACT; - if (addr == NULL) - { - return NULL; - } - else - { - return addr - base; - } - } - - static TADDR GetRelative(TADDR base, TADDR addr) - { - LIMITED_METHOD_DAC_CONTRACT; - PRECONDITION(addr != NULL); - return addr - base; - } - -private: -#ifndef DACCESS_COMPILE - Volatile m_delta; -#else - TADDR m_delta; -#endif -}; - -//---------------------------------------------------------------------------- -// FixupPointer is pointer with optional indirection. It is used to reduce number -// of private pages in NGen images - cross-module pointers that written to at runtime -// are packed together and accessed via indirection. -// -// The direct flavor (lowest bit of m_addr is cleared) is user for intra-module pointers -// in NGen images, and in datastructuters allocated at runtime. -// -// The indirect mode (lowest bit of m_addr is set) is used for cross-module pointers -// in NGen images. -// - -// Friendly name for lowest bit that marks the indirection -#define FIXUP_POINTER_INDIRECTION 1 - -template -class FixupPointer -{ -public: - - static constexpr bool isRelative = false; - typedef PTR_TYPE type; - - // Returns whether the encoded pointer is NULL. - BOOL IsNull() const - { - LIMITED_METHOD_DAC_CONTRACT; - return m_addr == 0; - } - - // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet. - FORCEINLINE BOOL IsTagged() const - { - LIMITED_METHOD_DAC_CONTRACT; - TADDR addr = m_addr; - if ((addr & FIXUP_POINTER_INDIRECTION) != 0) - return (*PTR_TADDR(addr - FIXUP_POINTER_INDIRECTION) & 1) != 0; - return FALSE; - } - - // Returns value of the encoded pointer. - FORCEINLINE PTR_TYPE GetValue() const - { - LIMITED_METHOD_DAC_CONTRACT; - TADDR addr = m_addr; - if ((addr & FIXUP_POINTER_INDIRECTION) != 0) - addr = *PTR_TADDR(addr - FIXUP_POINTER_INDIRECTION); - return dac_cast(addr); - } - - // Returns value of the encoded pointer. - FORCEINLINE PTR_TYPE GetValueMaybeNull() const - { - LIMITED_METHOD_DAC_CONTRACT; - return GetValue(); - } - -#ifndef DACCESS_COMPILE - // Returns the pointer to the indirection cell. - PTR_TYPE * GetValuePtr() const - { - LIMITED_METHOD_CONTRACT; - TADDR addr = m_addr; - if ((addr & FIXUP_POINTER_INDIRECTION) != 0) - return (PTR_TYPE *)(addr - FIXUP_POINTER_INDIRECTION); - return (PTR_TYPE *)&m_addr; - } -#endif // !DACCESS_COMPILE - - // Static version of GetValue. It is meant to simplify access to arrays of pointers. - FORCEINLINE static PTR_TYPE GetValueAtPtr(TADDR base) - { - LIMITED_METHOD_DAC_CONTRACT; - return dac_cast)>(base)->GetValue(); - } - - // Static version of GetValueMaybeNull. It is meant to simplify access to arrays of pointers. - FORCEINLINE static PTR_TYPE GetValueMaybeNullAtPtr(TADDR base) - { - LIMITED_METHOD_DAC_CONTRACT; - return dac_cast)>(base)->GetValueMaybeNull(); - } - - // Returns value of the encoded pointer. - // Allows the value to be tagged. - FORCEINLINE TADDR GetValueMaybeTagged() const - { - LIMITED_METHOD_DAC_CONTRACT; - TADDR addr = m_addr; - if ((addr & FIXUP_POINTER_INDIRECTION) != 0) - addr = *PTR_TADDR(addr - FIXUP_POINTER_INDIRECTION); - return addr; - } - -#ifndef DACCESS_COMPILE - void SetValue(PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - m_addr = dac_cast(addr); - } - - void SetValueMaybeNull(PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - SetValue(addr); - } -#endif // !DACCESS_COMPILE - -private: - TADDR m_addr; -}; - -//---------------------------------------------------------------------------- -// RelativeFixupPointer is combination of RelativePointer and FixupPointer -template -class RelativeFixupPointer -{ -public: - - static constexpr bool isRelative = true; - typedef PTR_TYPE type; - -#ifndef DACCESS_COMPILE - RelativeFixupPointer() - { - SetValueMaybeNull(NULL); - } -#else // DACCESS_COMPILE - RelativeFixupPointer() =delete; -#endif // DACCESS_COMPILE - - // Implicit copy/move is not allowed - RelativeFixupPointer(const RelativeFixupPointer &) =delete; - RelativeFixupPointer(RelativeFixupPointer &&) =delete; - RelativeFixupPointer& operator = (const RelativeFixupPointer &) =delete; - RelativeFixupPointer& operator = (RelativeFixupPointer &&) =delete; - - // Returns whether the encoded pointer is NULL. - BOOL IsNull() const - { - LIMITED_METHOD_DAC_CONTRACT; - // Pointer pointing to itself is treated as NULL - return m_delta == (TADDR)NULL; - } - - // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet. - FORCEINLINE BOOL IsTagged(TADDR base) const - { - LIMITED_METHOD_DAC_CONTRACT; - TADDR addr = base + m_delta; - if ((addr & FIXUP_POINTER_INDIRECTION) != 0) - return (*PTR_TADDR(addr - FIXUP_POINTER_INDIRECTION) & 1) != 0; - return FALSE; - } - - // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet. - // Ignores isIndirect and offset values. - FORCEINLINE BOOL IsTaggedIndirect(TADDR base, bool isIndirect, intptr_t offset) const - { - LIMITED_METHOD_DAC_CONTRACT; - return IsTagged(base); - } - -#ifndef DACCESS_COMPILE - // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet. - // Does not need explicit base and thus can be used in non-DAC builds only. - FORCEINLINE BOOL IsTagged() const - { - LIMITED_METHOD_CONTRACT; - return IsTagged((TADDR)this); - } -#endif // !DACCESS_COMPILE - - // Returns value of the encoded pointer. Assumes that the pointer is not NULL. - FORCEINLINE PTR_TYPE GetValue(TADDR base) const - { - LIMITED_METHOD_DAC_CONTRACT; - PRECONDITION(!IsNull()); - PRECONDITION(!IsTagged(base)); - TADDR addr = base + m_delta; - if ((addr & FIXUP_POINTER_INDIRECTION) != 0) - addr = *PTR_TADDR(addr - FIXUP_POINTER_INDIRECTION); - return dac_cast(addr); - } - -#ifndef DACCESS_COMPILE - // Returns value of the encoded pointer. Assumes that the pointer is not NULL. - // Does not need explicit base and thus can be used in non-DAC builds only. - FORCEINLINE PTR_TYPE GetValue() const - { - LIMITED_METHOD_CONTRACT; - return GetValue((TADDR)this); - } -#endif - - // Static version of GetValue. It is meant to simplify access to arrays of pointers. - FORCEINLINE static PTR_TYPE GetValueAtPtr(TADDR base) - { - LIMITED_METHOD_DAC_CONTRACT; - return dac_cast)>(base)->GetValue(base); - } - - // Static version of GetValue. It is meant to simplify access to arrays of pointers. - // Ignores isIndirect and offset values. - FORCEINLINE static PTR_TYPE GetValueAtPtrIndirect(TADDR base, bool isIndirect, intptr_t offset) - { - LIMITED_METHOD_DAC_CONTRACT; - return GetValueAtPtr(base); - } - - // Returns value of the encoded pointer. The pointer can be NULL. - PTR_TYPE GetValueMaybeNull(TADDR base) const - { - LIMITED_METHOD_DAC_CONTRACT; - PRECONDITION(!IsTagged(base)); - - // Cache local copy of delta to avoid races when the value is changing under us. - TADDR delta = m_delta; - - if (delta == 0) - return NULL; - - TADDR addr = base + delta; - if ((addr & FIXUP_POINTER_INDIRECTION) != 0) - addr = *PTR_TADDR(addr - FIXUP_POINTER_INDIRECTION); - return dac_cast(addr); - } - -#ifndef DACCESS_COMPILE - // Returns value of the encoded pointer. The pointer can be NULL. - // Does not need explicit base and thus can be used in non-DAC builds only. - FORCEINLINE PTR_TYPE GetValueMaybeNull() const - { - LIMITED_METHOD_CONTRACT; - return GetValueMaybeNull((TADDR)this); - } -#endif - - // Static version of GetValueMaybeNull. It is meant to simplify access to arrays of pointers. - FORCEINLINE static PTR_TYPE GetValueMaybeNullAtPtr(TADDR base) - { - LIMITED_METHOD_DAC_CONTRACT; - return dac_cast)>(base)->GetValueMaybeNull(base); - } - - // Static version of GetValueMaybeNull. It is meant to simplify access to arrays of pointers. - // Ignores isIndirect and offset values. - FORCEINLINE static PTR_TYPE GetValueMaybeNullAtPtrIndirect(TADDR base, bool isIndirect, intptr_t offset) - { - LIMITED_METHOD_DAC_CONTRACT; - return GetValueMaybeNullAtPtr(base); - } - -#ifndef DACCESS_COMPILE - // Set encoded value of the pointer. Assumes that the value is not NULL. - FORCEINLINE void SetValue(PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - PRECONDITION(addr != NULL); - m_delta = dac_cast(addr) - (TADDR)this; - } - - // Set encoded value of the pointer. The value can be NULL. - void SetValueMaybeNull(TADDR base, PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - if (addr == NULL) - m_delta = NULL; - else - m_delta = dac_cast(addr) - (TADDR)base; - } - - // Set encoded value of the pointer. The value can be NULL. - FORCEINLINE void SetValueMaybeNull(PTR_TYPE addr) - { - LIMITED_METHOD_CONTRACT; - SetValueMaybeNull((TADDR)this, addr); - } -#endif - -#ifndef DACCESS_COMPILE - // Returns the pointer to the indirection cell. - PTR_TYPE * GetValuePtr() const - { - LIMITED_METHOD_CONTRACT; - TADDR addr = ((TADDR)this) + m_delta; - _ASSERTE((addr & FIXUP_POINTER_INDIRECTION) != 0); - return (PTR_TYPE *)(addr - FIXUP_POINTER_INDIRECTION); - } - - // Returns the pointer to the indirection cell. - // Ignores isIndirect and offset values. - PTR_TYPE * GetValuePtrIndirect(bool isIndirect, intptr_t offset) const - { - LIMITED_METHOD_CONTRACT; - return GetValuePtr(); - } -#endif // !DACCESS_COMPILE - - // Returns value of the encoded pointer. Assumes that the pointer is not NULL. - // Allows the value to be tagged. - FORCEINLINE TADDR GetValueMaybeTagged(TADDR base) const - { - LIMITED_METHOD_DAC_CONTRACT; - PRECONDITION(!IsNull()); - TADDR addr = base + m_delta; - if ((addr & FIXUP_POINTER_INDIRECTION) != 0) - addr = *PTR_TADDR(addr - FIXUP_POINTER_INDIRECTION); - return addr; - } - - // Returns whether pointer is indirect. Assumes that the value is not NULL. - bool IsIndirectPtr(TADDR base) const - { - LIMITED_METHOD_DAC_CONTRACT; - PRECONDITION(!IsNull()); - - TADDR addr = base + m_delta; - - return (addr & FIXUP_POINTER_INDIRECTION) != 0; - } - -#ifndef DACCESS_COMPILE - // Returns whether pointer is indirect. Assumes that the value is not NULL. - // Does not need explicit base and thus can be used in non-DAC builds only. - bool IsIndirectPtr() const - { - LIMITED_METHOD_CONTRACT; - return IsIndirectPtr((TADDR)this); - } - - // Returns whether pointer is indirect. Assumes that the value is not NULL. - // Ignores isIndirect and offset values. - bool IsIndirectPtrIndirect(bool isIndirect, intptr_t offset) const - { - LIMITED_METHOD_DAC_CONTRACT; - return IsIndirectPtr(); - } -#endif - - // Returns whether pointer is indirect. The value can be NULL. - bool IsIndirectPtrMaybeNull(TADDR base) const - { - LIMITED_METHOD_DAC_CONTRACT; - - if (m_delta == 0) - return false; - - return IsIndirectPtr(base); - } - -#ifndef DACCESS_COMPILE - // Returns whether pointer is indirect. The value can be NULL. - // Does not need explicit base and thus can be used in non-DAC builds only. - bool IsIndirectPtrMaybeNull() const - { - LIMITED_METHOD_CONTRACT; - return IsIndirectPtrMaybeNull((TADDR)this); - } - - // Returns whether pointer is indirect. The value can be NULL. - // Ignores isIndirect and offset values. - bool IsIndirectPtrMaybeNullIndirect(bool isIndirect, intptr_t offset) const - { - LIMITED_METHOD_DAC_CONTRACT; - return IsIndirectPtrMaybeNull(); - } -#endif - -private: -#ifndef DACCESS_COMPILE - Volatile m_delta; -#else - TADDR m_delta; -#endif -}; - -// Fixup used for RelativePointer -#define IMAGE_REL_BASED_RelativePointer IMAGE_REL_BASED_RELPTR - -#endif // FEATURE_PREJIT - //---------------------------------------------------------------------------- // PlainPointer is simple pointer wrapper to support compilation without indirections // This is useful for building size-constrained runtime without NGen support. @@ -765,14 +211,10 @@ class PlainPointer TADDR m_ptr; }; -#ifndef FEATURE_PREJIT - #define FixupPointer PlainPointer #define RelativePointer PlainPointer #define RelativeFixupPointer PlainPointer -#endif // !FEATURE_PREJIT - //---------------------------------------------------------------------------- // RelativePointer32 is pointer encoded as relative 32-bit offset. It is used // to reduce both the size of the pointer itself as well as size of relocation diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 3c42f0850850bb..259abc3e7b1b8d 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -276,17 +276,9 @@ JITHELPER(CORINFO_HELP_EE_PINVOKE_FIXUP, NDirectImportThunk, CORINFO_HELP_SIG_NO_ALIGN_STUB) -#ifdef FEATURE_PREJIT - JITHELPER(CORINFO_HELP_EE_VSD_FIXUP, StubDispatchFixupStub, CORINFO_HELP_SIG_NO_ALIGN_STUB) -#else JITHELPER(CORINFO_HELP_EE_VSD_FIXUP, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB) -#endif JITHELPER(CORINFO_HELP_EE_EXTERNAL_FIXUP, ExternalMethodFixupStub, CORINFO_HELP_SIG_NO_ALIGN_STUB) -#ifdef FEATURE_PREJIT - JITHELPER(CORINFO_HELP_EE_VTABLE_FIXUP, VirtualMethodFixupStub, CORINFO_HELP_SIG_NO_ALIGN_STUB) -#else JITHELPER(CORINFO_HELP_EE_VTABLE_FIXUP, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB) -#endif JITHELPER(CORINFO_HELP_EE_REMOTING_THUNK, NULL, CORINFO_HELP_SIG_UNDEF) diff --git a/src/coreclr/inc/metadata.h b/src/coreclr/inc/metadata.h index 4f119e2e9d6a5e..cf69f3a909999c 100644 --- a/src/coreclr/inc/metadata.h +++ b/src/coreclr/inc/metadata.h @@ -1178,32 +1178,6 @@ enum MetaDataReorderingOptions { ReArrangeStringPool=0x1 }; -#ifdef FEATURE_PREJIT - -// {0702E333-8D64-4ca7-B564-4AA56B1FCEA3} -EXTERN_GUID(IID_IMetaDataCorProfileData, 0x702e333, 0x8d64, 0x4ca7, 0xb5, 0x64, 0x4a, 0xa5, 0x6b, 0x1f, 0xce, 0xa3 ); - -#undef INTERFACE -#define INTERFACE IMetaDataCorProfileData -DECLARE_INTERFACE_(IMetaDataCorProfileData, IUnknown) -{ - STDMETHOD(SetCorProfileData)( - CorProfileData *pProfileData) PURE; // [IN] Pointer to profile data -}; - -// {2B464817-C0F6-454e-99E7-C352D8384D7B} -EXTERN_GUID(IID_IMDInternalMetadataReorderingOptions, 0x2B464817, 0xC0F6, 0x454e, 0x99, 0xE7, 0xC3, 0x52, 0xD8, 0x38, 0x4D, 0x7B ); - -#undef INTERFACE -#define INTERFACE IMDInternalMetadataReorderingOptions -DECLARE_INTERFACE_(IMDInternalMetadataReorderingOptions, IUnknown) -{ - STDMETHOD(SetMetaDataReorderingOptions)( - MetaDataReorderingOptions options) PURE; // [IN] metadata reordering options -}; - -#endif //FEATURE_PREJIT - #ifdef __HOLDER_H_ void DECLSPEC_NORETURN ThrowHR(HRESULT hr); diff --git a/src/coreclr/inc/metadatatracker.h b/src/coreclr/inc/metadatatracker.h index 6c732767862d5d..187a608f0b34ab 100644 --- a/src/coreclr/inc/metadatatracker.h +++ b/src/coreclr/inc/metadatatracker.h @@ -4,15 +4,6 @@ #ifndef _METADATATRACKER_H_ #define _METADATATRACKER_H_ -#ifdef FEATURE_PREJIT - -#define METADATATRACKER_DATA 1 -#if !defined(DACCESS_COMPILE) -#define METADATATRACKER_ENABLED 1 -#endif - -#endif - #if METADATATRACKER_ENABLED #define METADATATRACKER_ONLY(s) (s) diff --git a/src/coreclr/inc/pedecoder.h b/src/coreclr/inc/pedecoder.h index 66f25747317e65..5efba5c7410135 100644 --- a/src/coreclr/inc/pedecoder.h +++ b/src/coreclr/inc/pedecoder.h @@ -308,40 +308,6 @@ class PEDecoder PTR_CVOID GetNativeManifestMetadata(COUNT_T* pSize = NULL) const; -#ifdef FEATURE_PREJIT - CHECK CheckNativeHeaderVersion() const; - - // ManagedNative fields - CORCOMPILE_CODE_MANAGER_ENTRY *GetNativeCodeManagerTable() const; - CORCOMPILE_EE_INFO_TABLE *GetNativeEEInfoTable() const; - void *GetNativeHelperTable(COUNT_T *pSize = NULL) const; - CORCOMPILE_VERSION_INFO *GetNativeVersionInfo() const; - CORCOMPILE_VERSION_INFO *GetNativeVersionInfoMaybeNull(bool skipCheckNativeHeader = false) const; - BOOL HasNativeDebugMap() const; - TADDR GetNativeDebugMap(COUNT_T *pSize = NULL) const; - Module *GetPersistedModuleImage(COUNT_T *pSize = NULL) const; - PCODE GetNativeHotCode(COUNT_T * pSize = NULL) const; - PCODE GetNativeCode(COUNT_T * pSize = NULL) const; - PCODE GetNativeColdCode(COUNT_T * pSize = NULL) const; - - CORCOMPILE_METHOD_PROFILE_LIST *GetNativeProfileDataList(COUNT_T *pSize = NULL) const; - const void *GetNativePreferredBase() const; - BOOL GetNativeILHasSecurityDirectory() const; - BOOL GetNativeILIsIbcOptimized() const; - BOOL GetNativeILHasReadyToRunHeader() const; - BOOL IsNativeILILOnly() const; - BOOL IsNativeILDll() const; - void GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine) const; - CORCOMPILE_DEPENDENCY * GetNativeDependencies(COUNT_T *pCount = NULL) const; - - PTR_CORCOMPILE_IMPORT_SECTION GetNativeImportSections(COUNT_T *pCount = NULL) const; - PTR_CORCOMPILE_IMPORT_SECTION GetNativeImportSectionFromIndex(COUNT_T index) const; - PTR_CORCOMPILE_IMPORT_SECTION GetNativeImportSectionForRVA(RVA rva) const; - - TADDR GetStubsTable(COUNT_T *pSize = NULL) const; - TADDR GetVirtualSectionsTable(COUNT_T *pSize = NULL) const; -#endif // FEATURE_PREJIT - BOOL IsComponentAssembly() const; BOOL HasReadyToRunHeader() const; READYTORUN_HEADER *GetReadyToRunHeader() const; @@ -397,9 +363,6 @@ class PEDecoder enum METADATA_SECTION_TYPE { METADATA_SECTION_FULL, -#ifdef FEATURE_PREJIT - METADATA_SECTION_MANIFEST -#endif }; IMAGE_DATA_DIRECTORY *GetMetaDataHelper(METADATA_SECTION_TYPE type) const; diff --git a/src/coreclr/inc/pedecoder.inl b/src/coreclr/inc/pedecoder.inl index 1f4b3c513a4b23..270a1d30aa4bb2 100644 --- a/src/coreclr/inc/pedecoder.inl +++ b/src/coreclr/inc/pedecoder.inl @@ -985,141 +985,6 @@ inline CORCOMPILE_HEADER *PEDecoder::GetNativeHeader() const RETURN m_pNativeHeader; } -#ifdef FEATURE_PREJIT -inline const void * PEDecoder::GetNativePreferredBase() const -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - PREFIX_ASSUME (GetNativeHeader()!=NULL); - return (const void *) GetNativeHeader()->ImageBase; -} - -inline BOOL PEDecoder::GetNativeILHasSecurityDirectory() const -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - PREFIX_ASSUME (GetNativeHeader()!=NULL); - return (GetNativeHeader()->Flags & CORCOMPILE_HEADER_HAS_SECURITY_DIRECTORY) != 0; -} - -inline BOOL PEDecoder::GetNativeILIsIbcOptimized() const -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - PREFIX_ASSUME (GetNativeHeader()!=NULL); - return (GetNativeHeader()->Flags & CORCOMPILE_HEADER_IS_IBC_OPTIMIZED) != 0; -} - -inline BOOL PEDecoder::GetNativeILHasReadyToRunHeader() const -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - PREFIX_ASSUME (GetNativeHeader()!=NULL); - return (GetNativeHeader()->Flags & CORCOMPILE_HEADER_IS_READY_TO_RUN) != 0; -} - -inline BOOL PEDecoder::IsNativeILILOnly() const -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - CANNOT_TAKE_LOCK; - SUPPORTS_DAC; - } - CONTRACTL_END; - - PREFIX_ASSUME (GetNativeHeader()!=NULL); - return((GetNativeHeader()->COR20Flags & VAL32(COMIMAGE_FLAGS_ILONLY)) != 0); -} - -inline BOOL PEDecoder::IsNativeILDll() const -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - PREFIX_ASSUME (GetNativeHeader()!=NULL); - return((GetNativeHeader()->Characteristics & VAL16(IMAGE_FILE_DLL)) != 0); -} - - -inline void PEDecoder::GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine) const -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - CORCOMPILE_HEADER * pNativeHeader = GetNativeHeader(); - PREFIX_ASSUME (pNativeHeader!=NULL); - - if (pdwKind != NULL) - *pdwKind = pNativeHeader->PEKind; - if (pdwMachine != NULL) - *pdwMachine = pNativeHeader->Machine; -} - -inline CORCOMPILE_DEPENDENCY * PEDecoder::GetNativeDependencies(COUNT_T *pCount) const -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->Dependencies; - - if (pCount != NULL) - *pCount = VAL32(pDir->Size)/sizeof(CORCOMPILE_DEPENDENCY); - - return (CORCOMPILE_DEPENDENCY *) GetDirectoryData(pDir); -} - -#endif // FEATURE_PREJIT - // static inline PTR_IMAGE_SECTION_HEADER PEDecoder::FindFirstSection(IMAGE_NT_HEADERS * pNTHeaders) { diff --git a/src/coreclr/inc/stgpool.h b/src/coreclr/inc/stgpool.h index 688f1b9db2ac35..c28950e5589801 100644 --- a/src/coreclr/inc/stgpool.h +++ b/src/coreclr/inc/stgpool.h @@ -335,22 +335,6 @@ friend class VerifyLayoutsMD; UINT32 nOffset, // Offset of blob in pool. MetaData::DataBlob *pData); -#ifdef FEATURE_PREJIT - // Initialize hot data structures. - // Method can be called multiple time, e.g. to disable usage of hot data structures in certain scenarios - // (see code:CMiniMd::DisableHotDataUsage). - void InitHotData(MetaData::HotHeap hotHeap) - { - LIMITED_METHOD_CONTRACT; - -#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) - m_HotHeap = hotHeap; -#else - _ASSERTE(!"InitHotData(): Not supposed to exist in RoMetaData.dll"); -#endif //!(defined(FEATURE_UTILCODE_NO_DEPENDENCIES)) - } -#endif //FEATURE_PREJIT - protected: //***************************************************************************** @@ -377,21 +361,6 @@ friend class VerifyLayoutsMD; return CLDB_E_INDEX_NOTFOUND; } -#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) -#ifdef FEATURE_PREJIT - // try hot data first - if (!m_HotHeap.IsEmpty()) - { - HRESULT hr = m_HotHeap.GetData(nOffset, pData); - if ((hr == S_OK) || FAILED(hr)) - { - return hr; - } - _ASSERTE(hr == S_FALSE); - } -#endif //FEATURE_PREJIT -#endif //!(defined(FEATURE_UTILCODE_NO_DEPENDENCIES)) - pData->Init(m_pSegData + nOffset, m_cbSegSize - nOffset); diff --git a/src/coreclr/inc/vptr_list.h b/src/coreclr/inc/vptr_list.h index 1ca3b089fd6813..4e333217e18810 100644 --- a/src/coreclr/inc/vptr_list.h +++ b/src/coreclr/inc/vptr_list.h @@ -6,9 +6,6 @@ VPTR_CLASS(EEJitManager) -#ifdef FEATURE_PREJIT -VPTR_CLASS(NativeImageJitManager) -#endif // FEATURE_PREJIT #ifdef FEATURE_READYTORUN VPTR_CLASS(ReadyToRunJitManager) #endif diff --git a/src/coreclr/md/compiler/regmeta.cpp b/src/coreclr/md/compiler/regmeta.cpp index 3753d248aa2395..ffe28774334698 100644 --- a/src/coreclr/md/compiler/regmeta.cpp +++ b/src/coreclr/md/compiler/regmeta.cpp @@ -668,16 +668,6 @@ RegMeta::QueryInterface( } } #endif // FEATURE_COMINTEROP -#ifdef FEATURE_PREJIT - else if (riid == IID_IMetaDataCorProfileData) - { - *ppUnk = (IMetaDataCorProfileData *)this; - } - else if (riid == IID_IMDInternalMetadataReorderingOptions) - { - *ppUnk = (IMDInternalMetadataReorderingOptions *)this; - } -#endif //FEATURE_PREJIT #endif //FEATURE_METADATA_IN_VM else { diff --git a/src/coreclr/md/compiler/regmeta.h b/src/coreclr/md/compiler/regmeta.h index 82be41bbb4725e..40315d27eb72ff 100644 --- a/src/coreclr/md/compiler/regmeta.h +++ b/src/coreclr/md/compiler/regmeta.h @@ -170,10 +170,6 @@ class RegMeta : , public IMetaDataEmitHelper #endif -#if defined(FEATURE_METADATA_IN_VM) && defined(FEATURE_PREJIT) - , public IMetaDataCorProfileData - , public IMDInternalMetadataReorderingOptions -#endif , public IMDCommon { friend class CImportTlb; @@ -1534,24 +1530,6 @@ class RegMeta : DWORD * pdwMappingType); // [out] Type of file mapping (code:CorFileMapping). -#if defined(FEATURE_METADATA_IN_VM) && defined(FEATURE_PREJIT) - -//***************************************************************************** -// IMetaDataCorProfileData -//***************************************************************************** - - STDMETHOD(SetCorProfileData)( - CorProfileData *pProfileData); // [IN] Pointer to profile data - -//***************************************************************************** -// IMDInternalMetadataReorderingOptions -//***************************************************************************** - - STDMETHOD(SetMetaDataReorderingOptions)( - MetaDataReorderingOptions options); // [IN] metadata reordering options - -#endif //FEATURE_METADATA_IN_VM && FEATURE_PREJIT - //***************************************************************************** // IMDCommon methods //***************************************************************************** diff --git a/src/coreclr/md/compiler/regmeta_emit.cpp b/src/coreclr/md/compiler/regmeta_emit.cpp index 303b0c62e7a56a..6508dbb78d56b2 100644 --- a/src/coreclr/md/compiler/regmeta_emit.cpp +++ b/src/coreclr/md/compiler/regmeta_emit.cpp @@ -2013,30 +2013,3 @@ HRESULT RegMeta::_DefineTypeDef( // S_OK or error. #endif //FEATURE_METADATA_EMIT -#if defined(FEATURE_METADATA_IN_VM) && defined(FEATURE_PREJIT) - -//****************************************************************************** -//--- IMetaDataCorProfileData -//****************************************************************************** - -HRESULT RegMeta::SetCorProfileData( - CorProfileData *pProfileData) // [IN] Pointer to profile data -{ - m_pCorProfileData = pProfileData; - - return S_OK; -} - -//****************************************************************************** -//--- IMDInternalMetadataReorderingOptions -//****************************************************************************** - -HRESULT RegMeta::SetMetaDataReorderingOptions( - MetaDataReorderingOptions options) // [IN] Metadata reordering options -{ - m_ReorderingOptions = options; - - return S_OK; -} - -#endif //defined(FEATURE_METADATA_IN_VM) && defined(FEATURE_PREJIT) diff --git a/src/coreclr/md/enc/metamodelrw.cpp b/src/coreclr/md/enc/metamodelrw.cpp index ffa8fb730d82af..14ba844a033a15 100644 --- a/src/coreclr/md/enc/metamodelrw.cpp +++ b/src/coreclr/md/enc/metamodelrw.cpp @@ -1958,236 +1958,6 @@ CMiniMdRW::InitNew() return hr; } // CMiniMdRW::InitNew -#ifdef FEATURE_PREJIT -//***************************************************************************** -// Helper function to determine the size of hot tables -//***************************************************************************** -static int ShiftCount(ULONG itemCount, ULONG hotItemCount) -{ - // figure out how many bits are needed to represent the highest rid - ULONG highestRid = itemCount; - int bitCount = 0; - while ((1UL< 8 ? bitCount - 8 : 0; - - // tune the shift count so that we don't need to search more than 4 hot entries on average. - while ((hotItemCount >> shiftCount) > 4) - shiftCount++; - if (shiftCount > 16) - shiftCount = 16; - return shiftCount; -} // ShiftCount - -//***************************************************************************** -// Helper function to qsort hot tokens -//***************************************************************************** - -typedef struct _TokenIndexPair -{ - mdToken token; - WORD index; -} TokenIndexPair; - -static WORD shiftCount; -static int __cdecl TokenCmp(const void *a, const void *b) -{ - mdToken ta = ((const TokenIndexPair *)a)->token; - mdToken tb = ((const TokenIndexPair *)b)->token; - if (shiftCount > 0) - { - // shiftCount is the number of low order bits that are used to index - // into the first level table. The below swaps high and low order bits so - // the values with common low order bits end up together after the sort. - ta = (ta >> shiftCount) | ((ta & ((1<> shiftCount) | ((tb & ((1< tb) - return 1; - else - return 0; -} - -//***************************************************************************** -// A wrapper for metadata's use of CorProfileData::GetHotTokens that recognizes tokens -// flagged with ProfilingFlags_MetaDataSearch and reinterprets them into a corresponding -// set of ProfilingFlags_MetaData tokens. -// -// If you are reading this because you are changing the implementation of one of the searches -// in CMiniMdBase, it should be a mechanical process to copy the new search code below and -// change the row accesses into setting values in the rowFlags array. -// -// Doing so allows us to fix the problem that incremental IBC is fundamentally not suited to -// metadata searches. -// -// For instance, consider the following scenario: -// - You gather IBC data on a scenario that does a metadata binary search -// - The data comes from build X where the table is of size 100 and the target is in row 18 -// - This means the intermediate values touched are rows 50, 25, and 12 -// - You then apply this IBC data to build Y which has changed to include 20 new entries to start the table -// - Naively, incremental IBC would have remapped these tokens and predicted accesses at rows 70, 35, 32, and 38 -// - But this is wrong! And very bad for working set. The search will actually touch 60, 30, and 45 on the way to 38 -// -// The solution is to only store rows in IBC data that were touched intentionally, either as direct -// accesses (with ProfilingFlags_MetaData) or as the result of searches (ProfilingFlags_MetaDataSearch). -// We then expand these "search tokens" here into the set of accesses that would occur on the current -// table as we do our various types of metadata search for them. -// -// Currently, we infer touches for the following types of access: -// - Direct access (getRow) -// - Binary search (CMiniMdBase::vSearchTable or CMiniMdBase::vSearchTableNotGreater) -// - Bounds of a multi-element span (CMiniMdBase::SearchTableForMultipleRows) -// -// In theory, we could have different flags for each type of search (e.g. binary, multiple-row, etc) and -// avoid any over-reporting of intermediate tokens, but in practice the IBC flag bits are scarce and -// measurements show a minimal (<1%) amount of over-reporting. -// -//***************************************************************************** - -enum HotTokenFlags -{ - HotTokenFlags_Cold = 0x0, - HotTokenFlags_ProfiledAccess = 0x1, - HotTokenFlags_IntermediateInBinarySearch = 0x2, - HotTokenFlags_BoundingMultipleRowSearch = 0x4 -}; - -__checkReturn -HRESULT -CMiniMdRW::GetHotMetadataTokensSearchAware( - CorProfileData *pProfileData, - ULONG ixTbl, - ULONG *pResultCount, - mdToken *tokenBuffer, - ULONG maxCount) -{ - HRESULT hr = S_OK; - ULONG resultCount = 0; - - ULONG metadataAccessFlag = 1<GetHotTokens(ixTbl, metadataSearchFlag, metadataSearchFlag, NULL, 0); - ULONG cRecs = GetCountRecs(ixTbl); - - if (numSearchTokens == 0 || cRecs == 0) - { - // If there are none, we can simply return the hot access tokens without doing any interesting work - resultCount = pProfileData->GetHotTokens(ixTbl, metadataAccessFlag, metadataAccessFlag, tokenBuffer, maxCount); - } - else - { - // But if there are hot search tokens, we need to infer what intermediate rows will be touched by our various types of metadata searching. - // To do so, retrieve all hot tokens and allocate temporary storage to use to mark which rows should be considered hot and for what reason - // (i.e. an array of HotTokenFlags, one per entry in the table, indexed by RID). - ULONG numAccessTokens = pProfileData->GetHotTokens(ixTbl, metadataAccessFlag, metadataAccessFlag, NULL, 0); - - NewArrayHolder searchTokens = new (nothrow) mdToken[numSearchTokens]; - IfNullGo(searchTokens); - NewArrayHolder accessTokens = new (nothrow) mdToken[numAccessTokens]; - IfNullGo(accessTokens); - NewArrayHolder rowFlags = new (nothrow) BYTE[cRecs + 1]; - IfNullGo(rowFlags); - - pProfileData->GetHotTokens(ixTbl, metadataSearchFlag, metadataSearchFlag, searchTokens, numSearchTokens); - pProfileData->GetHotTokens(ixTbl, metadataAccessFlag, metadataAccessFlag, accessTokens, numAccessTokens); - - // Initially, consider all rows cold - memset(rowFlags, HotTokenFlags_Cold, cRecs + 1); - - // Category 1: Rows may have been touched directly (getRow) - // Simply mark the corresponding entry to each access token - for (ULONG i = 0; i < numAccessTokens; ++i) - { - RID rid = RidFromToken(accessTokens[i]); - - if (rid <= cRecs) - { - rowFlags[rid] |= HotTokenFlags_ProfiledAccess; - } - } - - // Category 2: Rows may have been intermediate touches in a binary search (CMiniMdBase::vSearchTable or CMiniMdBase::vSearchTableNotGreater) - // A search token may indicate where a binary search stopped, so for each of them compute and mark the intermediate set of rows that would have been touched - for (ULONG i = 0; i < numSearchTokens; ++i) - { - RID rid = RidFromToken(searchTokens[i]); - - ULONG lo = 1; - ULONG hi = cRecs; - - while (lo <= hi) - { - ULONG mid = (lo + hi) / 2; - - if (mid <= cRecs) - { - rowFlags[mid] |= HotTokenFlags_IntermediateInBinarySearch; - } - - if (mid == rid) - { - break; - } - - if (mid < rid) - lo = mid + 1; - else - hi = mid - 1; - } - } - - // Category 3: Rows may have been touched to find the bounds of a multiple element span (CMiniMdBase::SearchTableForMultipleRows) - // A search token will indicate where the search stopped, so mark the first row before and after each that was not itself touched - for (ULONG i = 0; i < numSearchTokens; ++i) - { - RID rid = RidFromToken(searchTokens[i]); - - for (RID r = rid - 1; r >= 1 && r <= cRecs; --r) - { - if ((rowFlags[r] & HotTokenFlags_ProfiledAccess) == 0) - { - rowFlags[r] |= HotTokenFlags_BoundingMultipleRowSearch; - break; - } - } - - for (RID r = rid + 1; r <= cRecs; ++r) - { - if ((rowFlags[r] & HotTokenFlags_ProfiledAccess) == 0) - { - rowFlags[r] |= HotTokenFlags_BoundingMultipleRowSearch; - break; - } - } - } - - // Now walk back over our temporary storage, counting and possibly returning the computed hot tokens - resultCount = 0; - for (ULONG i = 1; i <= cRecs; ++i) - { - if (rowFlags[i] != HotTokenFlags_Cold) - { - if (tokenBuffer != NULL && resultCount < maxCount) - tokenBuffer[resultCount] = TokenFromRid(i, ixTbl << 24); - resultCount++; - } - } - } - - if (pResultCount) - *pResultCount = resultCount; - - ErrExit: - return hr; -} // CMiniMdRW::GetHotMetadataTokensSearchAware - - -#endif //FEATURE_PREJIT - //***************************************************************************** // Determine how big the tables would be when saved. //***************************************************************************** @@ -2210,9 +1980,7 @@ CMiniMdRW::GetFullSaveSize( int i; // Loop control. _ASSERTE(m_bPreSaveDone); -#ifndef FEATURE_PREJIT _ASSERTE(pProfileData == NULL); -#endif //!FEATURE_PREJIT // Determine if the stream is "fully compressed", ie no pointer tables. *pbSaveCompressed = true; @@ -2287,57 +2055,6 @@ CMiniMdRW::GetFullSaveSize( cbTable = sTempTable.m_cbRec * GetCountRecs(ixTbl); -#ifdef FEATURE_PREJIT - if (pProfileData != NULL) - { - ULONG itemCount = GetCountRecs(ixTbl); - - // determine number of rows touched in this table as indicated by IBC profile data - ULONG hotItemCount = 0; - IfFailGo(GetHotMetadataTokensSearchAware(pProfileData, ixTbl, &hotItemCount, NULL, 0)); - - // assume ManifestResource table is touched completely if touched at all or any hot metadata at all so far - // this is because it's searched linearly, and IBC data misses an unsuccessful search - // after module load - if (ixTbl == TBL_ManifestResource && (hotItemCount > 0 || cbTotal != 0)) - hotItemCount = itemCount; - - // if the hot subset of the rows along with their side lookup tables will occupy more space - // than the full table, keep the full table to both save space and access time. - if (hotItemCount <= USHRT_MAX && itemCount <= USHRT_MAX && m_TableDefs[ixTbl].m_cbRec <= SHRT_MAX) - { - ULONG estimatedSizeUsingSubsetCopy = hotItemCount * (sizeof(WORD) + sizeof(BYTE) + m_TableDefs[ixTbl].m_cbRec); - ULONG estimatedSizeUsingFullCopy = itemCount * m_TableDefs[ixTbl].m_cbRec; - - if (estimatedSizeUsingSubsetCopy > estimatedSizeUsingFullCopy) - hotItemCount = itemCount; - } - - // first level table is array of WORD, so we can't handle more than 2**16 hot items - if (hotItemCount > USHRT_MAX) - hotItemCount = 0; - - cbTable = 0; - if (hotItemCount > 0) - { - cbTotal = Align4(cbTotal); - cbTable = 5*sizeof(DWORD) + sizeof(WORD); // header: count, 4 offsets, shift count - shiftCount = ShiftCount(itemCount, hotItemCount); - if (hotItemCount < itemCount) - { - cbTable += ((1<GetHR(); - } - EX_END_CATCH(SwallowAllExceptions) - IfFailRet(hr); - } -#endif // FEATURE_PREJIT - switch (m_OptionValue.m_UpdateMode & MDUpdateMask) { case MDUpdateFull: @@ -3492,9 +3146,7 @@ CMiniMdRW::SaveFullTablesToStream( UINT32 cbTotal; // Bytes written. static const unsigned char zeros[8] = {0}; // For padding and alignment. -#ifndef FEATURE_PREJIT _ASSERTE(pProfileData == NULL); -#endif //!FEATURE_PREJIT // Write the header. CMiniMdSchema Schema = m_Schema; @@ -3549,190 +3201,6 @@ CMiniMdRW::SaveFullTablesToStream( ULONG itemCount = GetCountRecs(ixTbl); if (itemCount) { -#ifdef FEATURE_PREJIT - ULONG hotItemCount = 0; - - NewArrayHolder hotItemList = NULL; - NewArrayHolder indexMapping = NULL; - - // check if we were asked to generate the hot tables - if (pProfileData != NULL) - { - // obtain the number of tokens in this table whose metadata was touched - IfFailGo(GetHotMetadataTokensSearchAware(pProfileData, ixTbl, &hotItemCount, NULL, 0)); - - // assume ManifestResource table is touched completely if touched at all or any hot metadata at all so far - // this is because it's searched linearly, and IBC data misses an unsuccessful search - // after module load - if (ixTbl == TBL_ManifestResource && (hotItemCount > 0 || cbTotal != 0)) - hotItemCount = itemCount; - - // if the hot subset of the rows along with their side lookup tables will occupy more space - // than the full table, keep the full table to save both space and access time. - if (hotItemCount <= USHRT_MAX && itemCount <= USHRT_MAX && m_TableDefs[ixTbl].m_cbRec <= SHRT_MAX) - { - ULONG estimatedSizeUsingSubsetCopy = hotItemCount * (sizeof(WORD) + sizeof(BYTE) + m_TableDefs[ixTbl].m_cbRec); - ULONG estimatedSizeUsingFullCopy = itemCount * m_TableDefs[ixTbl].m_cbRec; - - if (estimatedSizeUsingSubsetCopy > estimatedSizeUsingFullCopy) - hotItemCount = itemCount; - } - - // first level table is array of WORD, so we can't handle more than 2**16 hot items - if (hotItemCount > USHRT_MAX) - hotItemCount = 0; - - // only generate additional table if any hot items at all - if (hotItemCount > 0) - { - if ( (cbAlign = Align4(cbTotal) - cbTotal) != 0) - IfFailGo(pIStream->Write(&hr, cbAlign, 0)); - cbTotal += cbAlign; - - headerOffset[ixTbl] = cbTotal; - - // write first part of header: hot item count - IfFailGo(pIStream->Write(&hotItemCount, sizeof(hotItemCount), 0)); - cbTotal += sizeof(hotItemCount); - - ULONG offset = 0; - if (hotItemCount < itemCount) - { - // obtain the tokens whose metadata was touched - hotItemList = new (nothrow) mdToken[hotItemCount]; - IfNullGo(hotItemList); - IfFailGo(GetHotMetadataTokensSearchAware(pProfileData, ixTbl, NULL, hotItemList, hotItemCount)); - - // construct an array of token-index pairs and save the original order of the tokens in pProfileData->GetHotTokens - // we want to write hot rows in this order to preserve the ordering optimizations done by IbcMerge - indexMapping = new (nothrow) TokenIndexPair[hotItemCount]; - IfNullGo(indexMapping); - - for (DWORD i = 0; i < hotItemCount; i++) - { - indexMapping[i].token = hotItemList[i]; - indexMapping[i].index = (WORD)i; - } - - // figure out how big the first level table should be - // and sort tokens accordingly - shiftCount = ShiftCount(itemCount, hotItemCount); - qsort(indexMapping, hotItemCount, sizeof(indexMapping[0]), TokenCmp); - - // each table has a header that consists of the hotItemCount, offsets to - // the first and second level tables, an offset to the actual data, and the - // shiftCount that determines the size of the first level table. - // see class HotTableHeader in metamodelro.h - - // we have already written the hotItemCount above. - - // so now write the offset of the first level table (just after the header) - offset = sizeof(hotItemCount) + 4*sizeof(offset) + sizeof(shiftCount); - IfFailGo(pIStream->Write(&offset, sizeof(offset), 0)); - cbTotal += sizeof(offset); - - // figure out first level table size (1 extra entry at the end) - ULONG firstLevelCount = (1<Write(&offset, sizeof(offset), 0)); - cbTotal += sizeof(offset); - - // second level table has a byte-sized entry for each hot item - offset += hotItemCount*sizeof(BYTE); - - // write offset of index mapping table. - IfFailGo(pIStream->Write(&offset, sizeof(offset), 0)); - cbTotal += sizeof(offset); - - // index mapping table has a word-sized entry for each hot item - offset += hotItemCount*sizeof(WORD); - - // actual data is just behind it, but 4-byte aligned - offset = Align4(offset); - - // write offset of actual hot metadata - IfFailGo(pIStream->Write(&offset, sizeof(offset), 0)); - cbTotal += sizeof(offset); - - // write shiftCount - IfFailGo(pIStream->Write(&shiftCount, sizeof(shiftCount), 0)); - cbTotal += sizeof(shiftCount); - - // allocate tables - NewArrayHolder firstLevelTable = new (nothrow) WORD[firstLevelCount]; - IfNullGo(firstLevelTable); - NewArrayHolder secondLevelTable = new (nothrow) BYTE[hotItemCount]; - IfNullGo(secondLevelTable); - NewArrayHolder indexMappingTable = new (nothrow) WORD[hotItemCount]; - IfNullGo(indexMappingTable); - - // fill out the tables - ULONG nextFirstLevelIndex = 0; - for (DWORD i = 0; i < hotItemCount; i++) - { - // second level table contains the high order bits for each hot rid - secondLevelTable[i] = (BYTE)(RidFromToken(indexMapping[i].token) >> shiftCount); - - // the index into the first level table is the low order bits. - ULONG firstLevelIndex = indexMapping[i].token & ((1<Write(firstLevelTable, sizeof(firstLevelTable[0])*firstLevelCount, 0)); - cbTotal += sizeof(firstLevelTable[0])*firstLevelCount; - - // write second level table - IfFailGo(pIStream->Write(secondLevelTable, sizeof(secondLevelTable[0])*hotItemCount, 0)); - cbTotal += sizeof(secondLevelTable[0])*hotItemCount; - - // write index mapping table - IfFailGo(pIStream->Write(indexMappingTable, sizeof(indexMappingTable[0])*hotItemCount, 0)); - cbTotal += sizeof(indexMappingTable[0])*hotItemCount; - - // NewArrayHolder for firstLevelTable and secondLevelTable going out of scope - no delete[] necessary - } - else - { - // in case the whole table is touched, omit the tables - // we still have a full header though with zero offsets for these tables. - IfFailGo(pIStream->Write(&offset, sizeof(offset), 0)); - cbTotal += sizeof(offset); - IfFailGo(pIStream->Write(&offset, sizeof(offset), 0)); - cbTotal += sizeof(offset); - IfFailGo(pIStream->Write(&offset, sizeof(offset), 0)); - cbTotal += sizeof(offset); - - // offset for actual data points immediately after the header - offset += sizeof(hotItemCount) + 4*sizeof(offset) + sizeof(shiftCount); - offset = Align4(offset); - IfFailGo(pIStream->Write(&offset, sizeof(offset), 0)); - cbTotal += sizeof(offset); - shiftCount = 0; - - // write shift count - IfFailGo(pIStream->Write(&shiftCount, sizeof(shiftCount), 0)); - cbTotal += sizeof(shiftCount); - } - if ( (cbAlign = Align4(cbTotal) - cbTotal) != 0) - IfFailGo(pIStream->Write(&hr, cbAlign, 0)); - cbTotal += cbAlign; - _ASSERTE(cbTotal == headerOffset[ixTbl] + offset); - } - } -#endif //FEATURE_PREJIT // Compress the records by allocating a new, temporary, table and // copying the rows from the one to the new. @@ -3777,22 +3245,6 @@ CMiniMdRW::SaveFullTablesToStream( IfFailGo(PutCol(rTempCols[ixCol], pNew, ulVal)); } } // Persist the temp table to the stream. -#ifdef FEATURE_PREJIT - if (pProfileData != NULL) - { - // only write out the hot rows as indicated by profile data - for (DWORD i = 0; i < hotItemCount; i++) - { - BYTE *pRow; - IfFailGo(tempTable.GetRecord( - hotItemList != NULL ? RidFromToken(hotItemList[i]) : i + 1, - &pRow)); - IfFailGo(pIStream->Write(pRow, sTempTable.m_cbRec, 0)); - } - cbTable = sTempTable.m_cbRec*hotItemCount; - } - else -#endif //FEATURE_PREJIT { IfFailGo(tempTable.GetRecordsDataSize(&cbTable)); _ASSERTE(cbTable == sTempTable.m_cbRec * GetCountRecs(ixTbl)); @@ -3803,22 +3255,6 @@ CMiniMdRW::SaveFullTablesToStream( } else { // Didn't grow, so just persist directly to stream. -#ifdef FEATURE_PREJIT - if (pProfileData != NULL) - { - // only write out the hot rows as indicated by profile data - for (DWORD i = 0; i < hotItemCount; i++) - { - BYTE *pRow; - IfFailGo(m_Tables[ixTbl].GetRecord( - hotItemList != NULL ? RidFromToken(hotItemList[i]) : i + 1, - &pRow)); - IfFailGo(pIStream->Write(pRow, m_TableDefs[ixTbl].m_cbRec, 0)); - } - cbTable = m_TableDefs[ixTbl].m_cbRec*hotItemCount; - } - else -#endif //FEATURE_PREJIT { IfFailGo(m_Tables[ixTbl].GetRecordsDataSize(&cbTable)); _ASSERTE(cbTable == m_TableDefs[ixTbl].m_cbRec * GetCountRecs(ixTbl)); @@ -3839,46 +3275,6 @@ CMiniMdRW::SaveFullTablesToStream( cbTotal += cbAlign; _ASSERTE((m_cbSaveSize == 0) || (m_cbSaveSize == cbTotal) || (pProfileData != NULL)); -#ifdef FEATURE_PREJIT - if (pProfileData != NULL) - { - // #WritingHotMetaData write hot table directory (HotTableDirectory in MetaModelRO.h) - - // first write magic - ULONG magic = 0x484f4e44; - IfFailGo(pIStream->Write(&magic, sizeof(magic), 0)); - - // compute offsets to table headers - for (ixTbl=0; ixTblWrite(headerOffset, sizeof(headerOffset), 0)); - cbTotal += sizeof(magic) + sizeof(headerOffset); - - UINT32 cbPoolDirSize = 0; - UINT32 cbSavedHeapsSize = 0; - - IfFailGo(SaveHotPoolsToStream( - pIStream, - reorderingOptions, - pProfileData, - &cbPoolDirSize, - &cbSavedHeapsSize)); - - // write hot metadata (including pools) header - IfFailGo(StreamUtil::WriteToStream(pIStream, (DWORD)(cbSavedHeapsSize + cbPoolDirSize))); - IfFailGo(StreamUtil::WriteToStream(pIStream, (DWORD)cbPoolDirSize)); - } -#endif //FEATURE_PREJIT - ErrExit: return hr; } // CMiniMdRW::SaveFullTablesToStream @@ -3892,32 +3288,7 @@ CMiniMdRW::SaveFullTablesToStream( //***************************************************************************** BOOL CMiniMdRW::IsSafeToReorderStringPool() { -#ifdef FEATURE_PREJIT - BYTE lastColumnSize=0; - ULONG ixTbl=0, ixCol=0; - for (ixTbl=0; ixTblGetHotTokens( TBL_COUNT + MDPoolStrings, 1 << ProfilingFlags_MetaData, 1 << ProfilingFlags_MetaData, NULL, 0 ); - if(hotItemCount > 0) - { - NewArrayHolder< ULONG > hotItemList = new ULONG[hotItemCount]; - - // get hot tokens - pProfileData->GetHotTokens( TBL_COUNT + MDPoolStrings, 1 << ProfilingFlags_MetaData, 1 << ProfilingFlags_MetaData, reinterpret_cast(&hotItemList[0]), hotItemCount ); - - for ( ULONG i=0; i= poolSize) - ThrowHR(E_UNEXPECTED); - - pMarks[ulStringOffset] = ReorderData::ProfileData; - } - } - } -#endif // FEATURE_PREJIT } // CMiniMdRW::MarkHotStrings //******************************************************************************* @@ -3957,54 +3304,6 @@ VOID CMiniMdRW::MarkHotStrings(CorProfileData *pProfileData, BYTE * pMarks, ULON //******************************************************************************* VOID CMiniMdRW::MarkStringsInHotTables(CorProfileData *pProfileData, BYTE * pMarks, ULONG poolSize) { -#ifdef FEATURE_PREJIT - ULONG ixTbl=0, ixCol=0; - ULONG hotItemCount=0; - RID hotRID=0; - BYTE *pHotRow=NULL; - - if(pProfileData != NULL) - { - for (ixTbl=0; ixTbl hotItemList = NULL; - // obtain the number of tokens in this table whose metadata was touched - hotItemCount = pProfileData->GetHotTokens(ixTbl, 1< 0) - { - hotItemList = new mdToken[hotItemCount]; - pProfileData->GetHotTokens(ixTbl, 1<= poolSize) - ThrowHR(E_UNEXPECTED); - - pMarks[ulStringOffset] = ReorderData::ProfileData; - } - } - } - } - } -#endif // FEATURE_PREJIT } // CMiniMdRW::MarkStringsInHotTables //***************************************************************************** @@ -4012,74 +3311,6 @@ VOID CMiniMdRW::MarkStringsInHotTables(CorProfileData *pProfileData, BYTE * pMar //***************************************************************************** VOID CMiniMdRW::MarkStringsInTables(BYTE * pMarks, ULONG poolSize) { -#ifdef FEATURE_PREJIT - for (ULONG ixTbl=0; ixTbl= poolSize) - ThrowHR(E_UNEXPECTED); - - BYTE ulBucketType=0; - - switch(ixTbl) - { - case TBL_Method: - ulBucketType = IsMdPublic(GetCol(TBL_Method, MethodRec::COL_Flags, pOldRow)) - ? ReorderData::PublicData - : ReorderData::NonPublicData; - break; - case TBL_Field: - ulBucketType = IsFdPublic(GetCol(TBL_Field, FieldRec::COL_Flags, pOldRow)) - ? ReorderData::PublicData - : ReorderData::NonPublicData; - break; - case TBL_TypeDef: - ulBucketType = IsTdPublic(GetCol(TBL_TypeDef, TypeDefRec::COL_Flags, pOldRow)) - ? ReorderData::PublicData - : ReorderData::NonPublicData; - break; - case TBL_ManifestResource: - ulBucketType = IsMrPublic(GetCol(TBL_ManifestResource, ManifestResourceRec::COL_Flags, pOldRow)) - ? ReorderData::PublicData - : ReorderData::NonPublicData; - break; - default: - ulBucketType = ReorderData::OtherData; - break; - } - - if (pMarks[ulStringOffset] == ReorderData::Undefined || pMarks[ulStringOffset] > ulBucketType) - pMarks[ulStringOffset] = ulBucketType; - } - } - if (!fHasStringData) - break; - } - } -#endif // FEATURE_PREJIT } // CMiniMdRW::MarkStringsInTables // -------------------------------------------------------------------------------------- @@ -4090,37 +3321,6 @@ VOID CMiniMdRW::MarkStringsInTables(BYTE * pMarks, ULONG poolSize) // VOID CMiniMdRW::MarkDuplicateStrings(BYTE * pMarks, ULONG poolSize) { -#ifdef FEATURE_PREJIT - ULONG offset=1; - while (offsetGetHotTokens( - TBL_COUNT + MDPoolStrings, - 1 << ProfilingFlags_MetaData, - 1 << ProfilingFlags_MetaData, - NULL, - 0); - if ( hotItems ) - { - NewArrayHolder< ULONG > hotItemArr = new ULONG[ hotItems ]; - pProfileData->GetHotTokens( - TBL_COUNT + MDPoolStrings, - 1 << ProfilingFlags_MetaData, - 1 << ProfilingFlags_MetaData, - reinterpret_cast(&hotItemArr[0]), - hotItems); - - // convert tokens to rids - for ( ULONG i = 0; i < hotItems ; ++i ) - { - UINT32 newOffset=0, start=0, end=0; - hotItemArr[i] = RidFromToken(hotItemArr[i]); - - for (UINT32 offset = hotItemArr[i]; offset >= 1; offset--) - { - if(pMarks[offset] == ReorderData::ProfileData) - { - LPCSTR szString; - IfFailThrow(m_StringHeap.GetString(offset, &szString)); - IfFailThrow(pStringHeap->AddString(szString, &newOffset)); - start = offset; - end = start + (UINT32)strlen(szString); - break; - } - } - - for (UINT32 offset = start; offset = ReorderData::MinReorderBucketType && pMarks[offset] <= ReorderData::MaxReorderBucketType); - _ASSERTE(0 == ReorderData::MinReorderBucketType); - _ASSERTE(255 == ReorderData::MaxReorderBucketType); - _ASSERTE(sizeof(pMarks[0]) == 1); - - if (pMarks[offset] == priority) - { - UINT32 newOffset; - - if(!m_StringPoolOffsetHash.Lookup(offset, &newOffset)) - { - LPCSTR szString; - IfFailThrow(m_StringHeap.GetString(offset, &szString)); - IfFailThrow(pStringHeap->AddString(szString, &newOffset)); - m_StringPoolOffsetHash.Add(offset, newOffset); - - lastOldOffset = offset; - lastNewOffset = newOffset; - } - } - else - if (pMarks[offset] == ReorderData::Duplicate) - { - UINT32 newOffset; - if (lastNewOffset != 0 && !m_StringPoolOffsetHash.Lookup(offset, &newOffset)) - m_StringPoolOffsetHash.Add(offset, lastNewOffset + (offset - lastOldOffset)); - } - else - if (pMarks[offset] != ReorderData::Undefined) - { - lastNewOffset = 0; - } - } - } -#endif // FEATURE_PREJIT } // CMiniMdRW::CreateReorderedStringPool // -------------------------------------------------------------------------------------- @@ -4287,181 +3351,8 @@ CMiniMdRW::CreateReorderedStringPool( // VOID CMiniMdRW::OrganizeStringPool(CorProfileData *pProfileData) { -#if defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE) - if(!IsSafeToReorderStringPool()) - { - return; - } - - UINT32 cbStringHeapSize = m_StringHeap.GetUnalignedSize(); - - NewArrayHolder stringMarks = new BYTE[cbStringHeapSize]; - ZeroMemory(stringMarks, cbStringHeapSize); - - // Each string will be assigned a value based on its hotness in the Mark*() functions - // This list will be later traversed to place the strings in the right order in the string pool and also - // to update the references in the metadata tables - - // Mark all hot strings - MarkHotStrings(pProfileData, stringMarks, cbStringHeapSize); - - // Mark all strings in hot rows - MarkStringsInHotTables(pProfileData, stringMarks, cbStringHeapSize); - - // Mark all remaining strings - MarkStringsInTables(stringMarks, cbStringHeapSize); - - // Mark duplicates for interned strings - MarkDuplicateStrings(stringMarks, cbStringHeapSize); - - // Initalize the temporary string heap - MetaData::StringHeapRW tempStringHeap; - - IfFailThrow(tempStringHeap.InitializeEmpty( - cbStringHeapSize - COMMA_INDEBUG_MD(TRUE))); // fIsReadWrite - - // We will use this hash for fixing the string references in the profile data - m_StringPoolOffsetHash.Reallocate(cbStringHeapSize); - - // Create the temporary string pool using the mark arrays - CreateReorderedStringPool(&tempStringHeap, stringMarks, cbStringHeapSize, pProfileData); - - // Update the tables with string offsets into the temporary string pool - FixStringsInTables(); - - // Replace the existing string pool with the modified version - m_StringHeap.Delete(); - IfFailThrow(m_StringHeap.InitializeFromStringHeap( - &tempStringHeap, - TRUE)); // fCopyData -#endif // FEATURE_PREJIT } // CMiniMdRW::OrganizeStringPool -#ifdef FEATURE_PREJIT - -// write hot data of the pools -// -__checkReturn -HRESULT -CMiniMdRW::SaveHotPoolsToStream( - IStream *pStream, - MetaDataReorderingOptions reorderingOptions, - CorProfileData *pProfileData, - UINT32 *pnPoolDirSize, - UINT32 *pnHeapsSavedSize) -{ - HRESULT hr = S_OK; - UINT32 rgHeapSavedSize[MDPoolCount] = { 0, 0, 0, 0 }; - - // save pools in the order they are described in MDPools enum - // - // we skip the hot string pool when we reorganize the string pool - if (!(reorderingOptions & ReArrangeStringPool)) - { - MetaData::HotHeapWriter stringHotHeapWriter(&m_StringHeap); - IfFailRet(SaveHotPoolToStream( - pStream, - pProfileData, - &stringHotHeapWriter, - &rgHeapSavedSize[MDPoolStrings])); - } - - // Save guid heap hot data - MetaData::HotHeapWriter guidsHotHeapWriter(&m_GuidHeap); - IfFailRet(SaveHotPoolToStream( - pStream, - pProfileData, - &guidsHotHeapWriter, - &rgHeapSavedSize[MDPoolGuids])); - - // Save blob heap hot data - MetaData::HotHeapWriter blobsHotHeapWriter( - &m_BlobHeap, - FALSE); // fUserStringHeap - IfFailRet(SaveHotPoolToStream( - pStream, - pProfileData, - &blobsHotHeapWriter, - &rgHeapSavedSize[MDPoolBlobs])); - - // Save user string heap hot data - MetaData::HotHeapWriter userStringsHotHeapWriter( - &m_UserStringHeap, - TRUE); // fUserStringHeap - IfFailRet(SaveHotPoolToStream( - pStream, - pProfileData, - &userStringsHotHeapWriter, - &rgHeapSavedSize[MDPoolUSBlobs])); - - // fix pool offsets, they need to point to the header of each saved pool - UINT32 nHeapEndOffset = 0; - for (int i = MDPoolCount; i-- > 0; ) - { - if (rgHeapSavedSize[i] != 0) - { - UINT32 nHeapSavedSize = rgHeapSavedSize[i]; - // Change size of the heap to the (negative) offset of its header - rgHeapSavedSize[i] = sizeof(struct MetaData::HotHeapHeader) + nHeapEndOffset; - nHeapEndOffset += nHeapSavedSize; - } - } - // Store size of all heaps - *pnHeapsSavedSize = nHeapEndOffset; - - // save hot pool dirs - *pnPoolDirSize = 0; - for (int i = 0; i < MDPoolCount; i++) - { - if (rgHeapSavedSize[i] != 0) - { - IfFailRet(StreamUtil::WriteToStream(pStream, i, pnPoolDirSize)); - IfFailRet(StreamUtil::WriteToStream(pStream, (ULONG)rgHeapSavedSize[i], pnPoolDirSize)); - } - } - - return S_OK; -} // CMiniMdRW::SaveHotPoolsToStream - -// write hot data of specific blob -// -__checkReturn -HRESULT -CMiniMdRW::SaveHotPoolToStream( - IStream *pStream, - CorProfileData *pProfileData, - MetaData::HotHeapWriter *pHotHeapWriter, - UINT32 *pnSavedSize) -{ - - _ASSERTE(pProfileData != NULL); - - HRESULT hr = S_OK; - // #CallToGetHotTokens - // see code:CMiniMdRW.SaveFullTablesToStream#WritingHotMetaData for the main caller of this. - if (pProfileData->GetHotTokens( - pHotHeapWriter->GetTableIndex(), - 1 << ProfilingFlags_MetaData, - 1 << ProfilingFlags_MetaData, - NULL, - 0) != 0) - { - IfFailRet(pHotHeapWriter->SaveToStream( - pStream, - pProfileData, - pnSavedSize)); - } - else - { - *pnSavedSize = 0; - } - - return S_OK; -} // CMiniMdRW::SaveHotPoolToStream - -#endif //FEATURE_PREJIT - //***************************************************************************** // Save the tables to the stream. //***************************************************************************** diff --git a/src/coreclr/md/heaps/blobheap.h b/src/coreclr/md/heaps/blobheap.h index 7d9eaf1ec036e6..cfa68c72bb1376 100644 --- a/src/coreclr/md/heaps/blobheap.h +++ b/src/coreclr/md/heaps/blobheap.h @@ -52,15 +52,6 @@ class BlobHeapRO return m_BlobPool.InitOnMemReadOnly((void *)sourceData.GetDataPointer(), sourceData.GetSize()); } -#ifdef FEATURE_PREJIT - // Can be called multiple times. - inline void InitializeHotData( - HotHeap hotHeap) - { - m_BlobPool.InitHotData(hotHeap); - } -#endif //FEATURE_PREJIT - inline void Delete() { return m_BlobPool.Uninit(); diff --git a/src/coreclr/md/heaps/guidheap.h b/src/coreclr/md/heaps/guidheap.h index cb4dac2147ae55..0311617d75096a 100644 --- a/src/coreclr/md/heaps/guidheap.h +++ b/src/coreclr/md/heaps/guidheap.h @@ -58,15 +58,6 @@ class GuidHeapRO return m_GuidPool.InitOnMemReadOnly((void *)sourceData.GetDataPointer(), sourceData.GetSize()); } -#ifdef FEATURE_PREJIT - // Can be called multiple times. - inline void InitializeHotData( - HotHeap hotHeap) - { - m_GuidPool.InitHotData(hotHeap); - } -#endif //FEATURE_PREJIT - // Destroys the guid heap and all its allocated data. Can run on uninitialized guid heap. inline void Delete() { diff --git a/src/coreclr/md/heaps/stringheap.h b/src/coreclr/md/heaps/stringheap.h index 747fd196284f49..e7b92225c4ba7d 100644 --- a/src/coreclr/md/heaps/stringheap.h +++ b/src/coreclr/md/heaps/stringheap.h @@ -52,15 +52,6 @@ class StringHeapRO return m_StringPool.InitOnMemReadOnly((void *)sourceData.GetDataPointer(), sourceData.GetSize()); } -#ifdef FEATURE_PREJIT - // Can be called multiple times. - inline void InitializeHotData( - HotHeap hotHeap) - { - m_StringPool.InitHotData(hotHeap); - } -#endif //FEATURE_PREJIT - inline void Delete() { return m_StringPool.Uninit(); diff --git a/src/coreclr/md/hotdata/hotheapwriter.cpp b/src/coreclr/md/hotdata/hotheapwriter.cpp index 82a271dfdaf57d..5ae176cde8e511 100644 --- a/src/coreclr/md/hotdata/hotheapwriter.cpp +++ b/src/coreclr/md/hotdata/hotheapwriter.cpp @@ -101,116 +101,6 @@ HotHeapWriter::SaveToStream( _ASSERTE(pProfileData != NULL); _ASSERTE(pnSavedSize != NULL); -#ifdef FEATURE_PREJIT - HRESULT hr = S_OK; - UINT32 nOffset = 0; - UINT32 nValueHeapStart_PositiveOffset; - UINT32 nValueOffsetTableStart_PositiveOffset; - UINT32 nIndexTableStart_PositiveOffset; - - // data - // - - // number of hot tokens - UINT32 nHotItemsCount = pProfileData->GetHotTokens( - GetTableIndex(), - 1 << ProfilingFlags_MetaData, - 1 << ProfilingFlags_MetaData, - NULL, - 0); - CONSISTENCY_CHECK(nHotItemsCount != 0); - - NewArrayHolder hotItemArr = new (nothrow) UINT32[nHotItemsCount]; - IfNullRet(hotItemArr); - - // get hot tokens - static_assert_no_msg(sizeof(UINT32) == sizeof(mdToken)); - pProfileData->GetHotTokens( - GetTableIndex(), - 1 << ProfilingFlags_MetaData, - 1 << ProfilingFlags_MetaData, - reinterpret_cast(&hotItemArr[0]), - nHotItemsCount); - - // convert tokens to rids - for (UINT32 i = 0; i < nHotItemsCount; i++) - { - hotItemArr[i] = RidFromToken(hotItemArr[i]); - } - - NewArrayHolder offsetMapping = new (nothrow) RidOffsetPair[nHotItemsCount]; - IfNullRet(offsetMapping); - - // write data - nValueHeapStart_PositiveOffset = nOffset; - - // note that we write hot items in the order they appear in pProfileData->GetHotTokens - // this is so that we preserve the ordering optimizations done by IbcMerge - for (UINT32 i = 0; i < nHotItemsCount; i++) - { - DataBlob data; - IfFailRet(GetData( - hotItemArr[i], - &data)); - - // keep track of the offset at which each hot item is written - offsetMapping[i].rid = hotItemArr[i]; - offsetMapping[i].offset = nOffset; - - IfFailRet(StreamUtil::WriteToStream( - pStream, - data.GetDataPointer(), - data.GetSize(), - &nOffset)); - } - - IfFailRet(StreamUtil::AlignDWORD(pStream, &nOffset)); - - // sort by rid so that a hot rid can be looked up by binary search - qsort(offsetMapping, nHotItemsCount, sizeof(RidOffsetPair), RidOffsetPair::Compare); - - // initialize table of offsets to data - NewArrayHolder dataIndices = new (nothrow) UINT32[nHotItemsCount]; - IfNullRet(dataIndices); - - // fill in the hotItemArr (now sorted by rid) and dataIndices array with each offset - for (UINT32 i = 0; i < nHotItemsCount; i++) - { - hotItemArr[i] = offsetMapping[i].rid; - dataIndices[i] = offsetMapping[i].offset; - } - - // table of offsets to data - // - - nValueOffsetTableStart_PositiveOffset = nOffset; - IfFailRet(StreamUtil::WriteToStream(pStream, &dataIndices[0], sizeof(UINT32) * nHotItemsCount, &nOffset)); - - // rid table (sorted) - // - - nIndexTableStart_PositiveOffset = nOffset; - - IfFailRet(StreamUtil::WriteToStream(pStream, &hotItemArr[0], nHotItemsCount * sizeof(UINT32), &nOffset)); - IfFailRet(StreamUtil::AlignDWORD(pStream, &nOffset)); - - { - // hot pool header - struct HotHeapHeader header; - - // fix offsets - header.m_nIndexTableStart_NegativeOffset = nOffset - nIndexTableStart_PositiveOffset; - header.m_nValueOffsetTableStart_NegativeOffset = nOffset - nValueOffsetTableStart_PositiveOffset; - header.m_nValueHeapStart_NegativeOffset = nOffset - nValueHeapStart_PositiveOffset; - - // write header - IfFailRet(StreamUtil::WriteToStream(pStream, &header, sizeof(header), &nOffset)); - } - - *pnSavedSize = nOffset; - -#endif //FEATURE_PREJIT - return S_OK; } // HotHeapWriter::PersistHotToStream diff --git a/src/coreclr/md/inc/metamodelro.h b/src/coreclr/md/inc/metamodelro.h index 1f7b170d218c7e..9df8e01e5dc264 100644 --- a/src/coreclr/md/inc/metamodelro.h +++ b/src/coreclr/md/inc/metamodelro.h @@ -61,27 +61,10 @@ class CMiniMd final: public CMiniMdTemplate return m_UserStringHeap.GetBlob(nIndex, pData); } -#ifdef FEATURE_PREJIT - void DisableHotDataUsage() - { - MetaData::HotHeap emptyHotHeap; - // Initialize hot data again with empty heap to disable their usage - m_StringHeap.InitializeHotData(emptyHotHeap); - m_BlobHeap.InitializeHotData(emptyHotHeap); - m_UserStringHeap.InitializeHotData(emptyHotHeap); - m_GuidHeap.InitializeHotData(emptyHotHeap); - // Disable usage of hot table data (throw it away) - m_pHotTablesDirectory = NULL; - } -#endif //FEATURE_PREJIT - protected: DAC_ALIGNAS(CMiniMdTemplate) // Align the first member to the alignment of the base class // Table info. MetaData::TableRO m_Tables[TBL_COUNT]; -#ifdef FEATURE_PREJIT - struct MetaData::HotTablesDirectory * m_pHotTablesDirectory; -#endif //FEATURE_PREJIT __checkReturn HRESULT InitializeTables(MetaData::DataBlob tablesData); @@ -135,9 +118,6 @@ class CMiniMd final: public CMiniMdTemplate ppRecord, m_TableDefs[nTableIndex].m_cbRec, m_Schema.m_cRecs[nTableIndex], -#ifdef FEATURE_PREJIT - m_pHotTablesDirectory, -#endif //FEATURE_PREJIT nTableIndex); } diff --git a/src/coreclr/md/runtime/liteweightstgdb.cpp b/src/coreclr/md/runtime/liteweightstgdb.cpp index 5e110ddde6b1fc..ed0eb8df617ff4 100644 --- a/src/coreclr/md/runtime/liteweightstgdb.cpp +++ b/src/coreclr/md/runtime/liteweightstgdb.cpp @@ -46,10 +46,6 @@ CLiteWeightStgdb::InitOnMem( // Validate the signature of the format, or it isn't ours. IfFailGo(MDFormat::VerifySignature((PSTORAGESIGNATURE)pData, cbData)); -#ifdef FEATURE_PREJIT - m_MiniMd.m_pHotTablesDirectory = NULL; -#endif //FEATURE_PREJIT - // Remaining buffer size behind the stream header (pStream). cbStreamBuffer = cbData; // Get back the first stream. @@ -163,23 +159,8 @@ CLiteWeightStgdb::InitOnMem( // Found the hot meta data stream else if (strcmp(pStream->GetName(), HOT_MODEL_STREAM_A) == 0) { -#ifdef FEATURE_PREJIT - BYTE * hotStreamEnd = reinterpret_cast< BYTE * >( pvCurrentData ) + cbCurrentData; - ULONG * hotMetadataDir = reinterpret_cast< ULONG * >( hotStreamEnd ) - 2; - ULONG hotPoolsSize = *hotMetadataDir; - - m_MiniMd.m_pHotTablesDirectory = (struct MetaData::HotTablesDirectory *) - (reinterpret_cast(hotMetadataDir) - hotPoolsSize - sizeof(struct MetaData::HotTablesDirectory)); - MetaData::HotTable::CheckTables(m_MiniMd.m_pHotTablesDirectory); - - DataBuffer hotMetaData( - reinterpret_cast(pvCurrentData), - cbCurrentData); - IfFailGo(InitHotPools(hotMetaData)); -#else //!FEATURE_PREJIT Debug_ReportError("MetaData hot stream is peresent, but ngen is not supported."); // Ignore the stream -#endif //!FEATURE_PREJIT } // Pick off the next stream if there is one. pStream = pNext; diff --git a/src/coreclr/md/runtime/mdinternalro.h b/src/coreclr/md/runtime/mdinternalro.h index 2ac1c90680c01a..976a280ba1f835 100644 --- a/src/coreclr/md/runtime/mdinternalro.h +++ b/src/coreclr/md/runtime/mdinternalro.h @@ -70,14 +70,6 @@ class MDInternalRO : public IMDInternalImport, IMDCommon STDMETHODIMP SetOptimizeAccessForSpeed( BOOL fOptSpeed) { -#ifdef FEATURE_PREJIT - // The metadata cache of hot items is an optional working-set optimization - // that has a large speed cost relative to direct table lookup - if (fOptSpeed) - { // We want to disable usage of hot data (e.g. in ngen compilation process) - m_LiteWeightStgdb.m_MiniMd.DisableHotDataUsage(); - } -#endif return S_OK; } diff --git a/src/coreclr/md/tables/table.h b/src/coreclr/md/tables/table.h index 37897b07e51bfa..5c019cd7efd5a1 100644 --- a/src/coreclr/md/tables/table.h +++ b/src/coreclr/md/tables/table.h @@ -65,9 +65,6 @@ class TableRO __deref_out_opt BYTE **ppRecord, UINT32 cbRecordSize, UINT32 cRecordCount, -#ifdef FEATURE_PREJIT - struct HotTablesDirectory *pHotTablesDirectory, -#endif //FEATURE_PREJIT UINT32 nTableIndex) { if ((nRowIndex == 0) || (nRowIndex > cRecordCount)) @@ -76,31 +73,6 @@ class TableRO *ppRecord = NULL; return CLDB_E_INDEX_NOTFOUND; } -#ifdef FEATURE_PREJIT - if ((pHotTablesDirectory != NULL) && (pHotTablesDirectory->m_rgTableHeader_SignedOffset[nTableIndex] != 0)) - { - HRESULT hr = HotTable::GetData( - nRowIndex, - ppRecord, - cbRecordSize, - HotTable::GetTableHeader(pHotTablesDirectory, nTableIndex)); - - if (hr == S_OK) - { - _ASSERTE(memcmp( - *ppRecord, - m_pData + (nRowIndex - 1) * cbRecordSize, - cbRecordSize) == 0); - return S_OK; - } - if (FAILED(hr)) - { - *ppRecord = NULL; - return hr; - } - _ASSERTE(hr == S_FALSE); - } -#endif //FEATURE_PREJIT *ppRecord = m_pData + (nRowIndex - 1) * cbRecordSize; return S_OK; } // TableRO::GetRecord diff --git a/src/coreclr/utilcode/pedecoder.cpp b/src/coreclr/utilcode/pedecoder.cpp index 639cb02099bf4d..2f28b3f6378359 100644 --- a/src/coreclr/utilcode/pedecoder.cpp +++ b/src/coreclr/utilcode/pedecoder.cpp @@ -133,15 +133,7 @@ CHECK PEDecoder::CheckNativeFormat() const } CONTRACT_CHECK_END; -#ifdef FEATURE_PREJIT - CHECK(CheckFormat()); - CHECK(HasNTHeaders()); - CHECK(HasCorHeader()); - CHECK(!IsILOnly()); - CHECK(HasNativeHeader()); -#else // FEATURE_PREJIT CHECK(false); -#endif // FEATURE_PREJIT CHECK_OK; } @@ -1206,12 +1198,7 @@ IMAGE_DATA_DIRECTORY *PEDecoder::GetMetaDataHelper(METADATA_SECTION_TYPE type) c { INSTANCE_CHECK; PRECONDITION(CheckCorHeader()); -#ifdef FEATURE_PREJIT - PRECONDITION(type == METADATA_SECTION_FULL || type == METADATA_SECTION_MANIFEST); - PRECONDITION(type != METADATA_SECTION_MANIFEST || HasNativeHeader()); -#else // FEATURE_PREJIT PRECONDITION(type == METADATA_SECTION_FULL); -#endif // FEATURE_PREJIT NOTHROW; GC_NOTRIGGER; SUPPORTS_DAC; @@ -1220,46 +1207,6 @@ IMAGE_DATA_DIRECTORY *PEDecoder::GetMetaDataHelper(METADATA_SECTION_TYPE type) c IMAGE_DATA_DIRECTORY *pDirRet = &GetCorHeader()->MetaData; -#ifdef FEATURE_PREJIT - // For backward compatibility reasons, we must be able to locate the metadata in all v2 native images as - // well as current version of native images. This is needed by mdbg.exe for SxS debugging scenarios. - // Specifically, mdbg.exe can be used to debug v2 managed applications, and need to be able to find - // metadata in v2 native images. Therefore, the location of the data we need to locate the metadata must - // never be moved. Here are some asserts to ensure that. - // IMAGE_COR20_HEADER should be stable since it is defined in ECMA. Verify a coupld of fields we use: - _ASSERTE(offsetof(IMAGE_COR20_HEADER, MetaData) == 8); - _ASSERTE(offsetof(IMAGE_COR20_HEADER, ManagedNativeHeader) == 64); - // We use a couple of fields in CORCOMPILE_HEADER. - _ASSERTE(offsetof(CORCOMPILE_HEADER, VersionInfo) == 40); - _ASSERTE(offsetof(CORCOMPILE_HEADER, ManifestMetaData) == 88); - // And we use four version fields in CORCOMPILE_VERSION_INFO. - _ASSERTE(offsetof(CORCOMPILE_VERSION_INFO, wVersionMajor) == 4); - _ASSERTE(offsetof(CORCOMPILE_VERSION_INFO, wVersionMinor) == 6); - _ASSERTE(offsetof(CORCOMPILE_VERSION_INFO, wVersionBuildNumber) == 8); - _ASSERTE(offsetof(CORCOMPILE_VERSION_INFO, wVersionPrivateBuildNumber) == 10); - - // Visual Studio took dependency on crossgen /CreatePDB returning COR_E_NI_AND_RUNTIME_VERSION_MISMATCH - // when crossgen and the native image come from different runtimes. In order to reach error path that returns - // COR_E_NI_AND_RUNTIME_VERSION_MISMATCH in this case, size of CORCOMPILE_HEADER has to remain constant, - // and the offset of PEKind and Machine fields inside CORCOMPILE_HEADER also have to remain constant, to pass earlier - // checks that lead to different error codes. See Windows Phone Blue Bug #45406 for details. - _ASSERTE(sizeof(CORCOMPILE_HEADER) == 160 + sizeof(TADDR)); - _ASSERTE(offsetof(CORCOMPILE_HEADER, PEKind) == 108 + sizeof(TADDR)); - _ASSERTE(offsetof(CORCOMPILE_HEADER, Machine) == 116 + sizeof(TADDR)); - - // Handle NGEN format; otherwise, there is only one MetaData section in the - // COR_HEADER and so the value of pDirRet is correct - if (HasNativeHeader()) - { - - if (type == METADATA_SECTION_MANIFEST) - pDirRet = &GetNativeHeader()->ManifestMetaData; - - - } - -#endif // FEATURE_PREJIT - RETURN pDirRet; } @@ -2244,12 +2191,7 @@ BOOL PEDecoder::HasNativeHeader() const } CONTRACT_END; -#ifdef FEATURE_PREJIT - // Pretend that ready-to-run images do not have native header - RETURN (GetCorHeader() && ((GetCorHeader()->Flags & VAL32(COMIMAGE_FLAGS_IL_LIBRARY)) != 0) && !HasReadyToRunHeader()); -#else RETURN FALSE; -#endif } CHECK PEDecoder::CheckNativeHeader() const @@ -2262,75 +2204,7 @@ CHECK PEDecoder::CheckNativeHeader() const } CONTRACT_CHECK_END; -#ifdef FEATURE_PREJIT - if (m_flags & FLAG_NATIVE_CHECKED) - CHECK_OK; - - CHECK(CheckCorHeader()); - - CHECK(HasNativeHeader()); - - IMAGE_DATA_DIRECTORY *pDir = &GetCorHeader()->ManagedNativeHeader; - - CHECK(CheckDirectory(pDir)); - CHECK(VAL32(pDir->Size) == sizeof(CORCOMPILE_HEADER)); - -#if 0 - // We want to be sure to not trigger these checks when loading a native - // image in a retail build - - // And we do not want to trigger these checks in debug builds either to avoid debug/retail behavior - // differences. - - PTR_CORCOMPILE_HEADER pHeader = PTR_CORCOMPILE_HEADER((TADDR)GetDirectoryData(pDir)); - - CHECK(CheckDirectory(&pHeader->EEInfoTable)); - CHECK(pHeader->EEInfoTable.Size == sizeof(CORCOMPILE_EE_INFO_TABLE)); - - CHECK(CheckDirectory(&pHeader->HelperTable, 0, NULL_OK)); - // @todo: verify helper table size - - CHECK(CheckDirectory(&pHeader->ImportSections, 0, NULL_OK)); - // @todo verify import sections - - CHECK(CheckDirectory(&pHeader->ImportTable, 0, NULL_OK)); - // @todo verify import table - - CHECK(CheckDirectory(&pHeader->VersionInfo, 0, NULL_OK)); // no version header for precompiled netmodules - CHECK(pHeader->VersionInfo.Size == 0 - || (pHeader->VersionInfo.Size == sizeof(CORCOMPILE_VERSION_INFO) && - // Sanity check that we are not just pointing to zeroed-out memory - ((CORCOMPILE_VERSION_INFO*)PTR_READ(GetDirectoryData(&pHeader->VersionInfo), sizeof(CORCOMPILE_VERSION_INFO)))->wOSMajorVersion != 0)); - - CHECK(CheckDirectory(&pHeader->Dependencies, 0, NULL_OK)); // no version header for precompiled netmodules - CHECK(pHeader->Dependencies.Size % sizeof(CORCOMPILE_DEPENDENCY) == 0); - - CHECK(CheckDirectory(&pHeader->DebugMap, 0, NULL_OK)); - CHECK(pHeader->DebugMap.Size % sizeof(CORCOMPILE_DEBUG_RID_ENTRY) == 0); - - // GetPersistedModuleImage() - CHECK(CheckDirectory(&pHeader->ModuleImage)); - CHECK(pHeader->ModuleImage.Size > 0); // sizeof(Module) if we knew it here - - CHECK(CheckDirectory(&pHeader->CodeManagerTable)); - CHECK(pHeader->CodeManagerTable.Size == sizeof(CORCOMPILE_CODE_MANAGER_ENTRY)); - - PTR_CORCOMPILE_CODE_MANAGER_ENTRY pEntry = PTR_CORCOMPILE_CODE_MANAGER_ENTRY((TADDR)GetDirectoryData(&pHeader->CodeManagerTable)); - CHECK(CheckDirectory(&pEntry->HotCode, IMAGE_SCN_MEM_WRITE, NULL_OK)); - CHECK(CheckDirectory(&pEntry->Code, IMAGE_SCN_MEM_WRITE, NULL_OK)); - CHECK(CheckDirectory(&pEntry->ColdCode, IMAGE_SCN_MEM_WRITE, NULL_OK)); - - CHECK(CheckDirectory(&pHeader->ProfileDataList, 0, NULL_OK)); - CHECK(pHeader->ProfileDataList.Size >= sizeof(CORCOMPILE_METHOD_PROFILE_LIST) - || pHeader->ProfileDataList.Size == 0); - -#endif - - const_cast(this)->m_flags |= FLAG_NATIVE_CHECKED; - -#else // FEATURE_PREJIT CHECK(false); -#endif // FEATURE_PREJIT CHECK_OK; } @@ -2643,256 +2517,6 @@ PTR_IMAGE_DEBUG_DIRECTORY PEDecoder::GetDebugDirectoryEntry(UINT index) const } -#ifdef FEATURE_PREJIT - -CORCOMPILE_EE_INFO_TABLE *PEDecoder::GetNativeEEInfoTable() const -{ - CONTRACT(CORCOMPILE_EE_INFO_TABLE *) - { - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->EEInfoTable; - - // 403523: PREFIX correctly complained here. Fixed GetDirectoryData. - RETURN PTR_CORCOMPILE_EE_INFO_TABLE(GetDirectoryData(pDir)); -} - - -void *PEDecoder::GetNativeHelperTable(COUNT_T *pSize) const -{ - CONTRACT(void *) - { - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->HelperTable; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - RETURN (void *)GetDirectoryData(pDir); -} - -CORCOMPILE_VERSION_INFO *PEDecoder::GetNativeVersionInfoMaybeNull(bool skipCheckNativeHeader) const -{ - CONTRACT(CORCOMPILE_VERSION_INFO *) - { - PRECONDITION(skipCheckNativeHeader || CheckNativeHeader()); - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->VersionInfo; - - RETURN PTR_CORCOMPILE_VERSION_INFO(GetDirectoryData(pDir)); -} - -CORCOMPILE_VERSION_INFO *PEDecoder::GetNativeVersionInfo() const -{ - CONTRACT(CORCOMPILE_VERSION_INFO *) - { - POSTCONDITION(CheckPointer(RETVAL)); - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } - CONTRACT_END; - - RETURN GetNativeVersionInfoMaybeNull(); -} - -BOOL PEDecoder::HasNativeDebugMap() const -{ - CONTRACT(BOOL) - { - PRECONDITION(CheckNativeHeader()); - INSTANCE_CHECK; - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } - CONTRACT_END; - - // 403522: Prefix complained correctly here. - CORCOMPILE_HEADER *pNativeHeader = GetNativeHeader(); - if (!pNativeHeader) - RETURN FALSE; - else - RETURN (VAL32(pNativeHeader->DebugMap.VirtualAddress) != 0); -} - -TADDR PEDecoder::GetNativeDebugMap(COUNT_T *pSize) const -{ - CONTRACT(TADDR) - { - PRECONDITION(CheckNativeHeader()); - PRECONDITION(CheckPointer(pSize, NULL_OK)); - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->DebugMap; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - RETURN (GetDirectoryData(pDir)); -} - -Module *PEDecoder::GetPersistedModuleImage(COUNT_T *pSize) const -{ - CONTRACT(Module *) - { - PRECONDITION(CheckNativeHeader()); - PRECONDITION(CheckPointer(pSize, NULL_OK)); - POSTCONDITION(CheckPointer(RETVAL)); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->ModuleImage; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - RETURN (Module *) GetDirectoryData(pDir); -} - -CHECK PEDecoder::CheckNativeHeaderVersion() const -{ - CONTRACT_CHECK - { - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_CHECK_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetCorHeader()->ManagedNativeHeader; - CHECK(VAL32(pDir->Size) == sizeof(CORCOMPILE_HEADER)); - - CORCOMPILE_HEADER *pNativeHeader = GetNativeHeader(); - CHECK(pNativeHeader->Signature == CORCOMPILE_SIGNATURE); - CHECK(pNativeHeader->MajorVersion == CORCOMPILE_MAJOR_VERSION); - CHECK(pNativeHeader->MinorVersion == CORCOMPILE_MINOR_VERSION); - - CHECK_OK; -} - -CORCOMPILE_CODE_MANAGER_ENTRY *PEDecoder::GetNativeCodeManagerTable() const -{ - CONTRACT(CORCOMPILE_CODE_MANAGER_ENTRY *) - { - PRECONDITION(CheckNativeHeader()); - POSTCONDITION(CheckPointer(RETVAL)); - SUPPORTS_DAC; - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->CodeManagerTable; - - RETURN PTR_CORCOMPILE_CODE_MANAGER_ENTRY(GetDirectoryData(pDir)); -} - -PCODE PEDecoder::GetNativeHotCode(COUNT_T * pSize) const -{ - CONTRACT(PCODE) - { - PRECONDITION(CheckNativeHeader()); - PRECONDITION(CheckPointer(pSize, NULL_OK)); - SUPPORTS_DAC; - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeCodeManagerTable()->HotCode; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - RETURN GetDirectoryData(pDir); -} - -PCODE PEDecoder::GetNativeCode(COUNT_T * pSize) const -{ - CONTRACT(PCODE) - { - PRECONDITION(CheckNativeHeader()); - PRECONDITION(CheckPointer(pSize, NULL_OK)); - SUPPORTS_DAC; - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeCodeManagerTable()->Code; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - RETURN GetDirectoryData(pDir); -} - -PCODE PEDecoder::GetNativeColdCode(COUNT_T * pSize) const -{ - CONTRACT(PCODE) - { - PRECONDITION(CheckNativeHeader()); - PRECONDITION(CheckPointer(pSize, NULL_OK)); - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeCodeManagerTable()->ColdCode; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - RETURN GetDirectoryData(pDir); -} - - -CORCOMPILE_METHOD_PROFILE_LIST *PEDecoder::GetNativeProfileDataList(COUNT_T * pSize) const -{ - CONTRACT(CORCOMPILE_METHOD_PROFILE_LIST *) - { - PRECONDITION(CheckNativeHeader()); - PRECONDITION(CheckPointer(pSize, NULL_OK)); - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->ProfileDataList; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - RETURN PTR_CORCOMPILE_METHOD_PROFILE_LIST(GetDirectoryData(pDir)); -} - -#endif // FEATURE_PREJIT - PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const { CONTRACT(PTR_CVOID) @@ -2906,13 +2530,6 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const CONTRACT_END; IMAGE_DATA_DIRECTORY *pDir = NULL; -#ifdef FEATURE_PREJIT - if (!HasReadyToRunHeader()) - { - pDir = GetMetaDataHelper(METADATA_SECTION_MANIFEST); - } - else -#endif { READYTORUN_HEADER * pHeader = GetReadyToRunHeader(); @@ -2949,106 +2566,6 @@ PTR_CVOID PEDecoder::GetNativeManifestMetadata(COUNT_T *pSize) const RETURN dac_cast(GetDirectoryData(pDir)); } -#ifdef FEATURE_PREJIT - -PTR_CORCOMPILE_IMPORT_SECTION PEDecoder::GetNativeImportSections(COUNT_T *pCount) const -{ - CONTRACT(PTR_CORCOMPILE_IMPORT_SECTION) - { - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->ImportSections; - - if (pCount != NULL) - *pCount = VAL32(pDir->Size) / sizeof(CORCOMPILE_IMPORT_SECTION); - - RETURN dac_cast(GetDirectoryData(pDir)); -} - -PTR_CORCOMPILE_IMPORT_SECTION PEDecoder::GetNativeImportSectionFromIndex(COUNT_T index) const -{ - CONTRACT(PTR_CORCOMPILE_IMPORT_SECTION) - { - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->ImportSections; - - _ASSERTE(VAL32(pDir->Size) % sizeof(CORCOMPILE_IMPORT_SECTION) == 0); - _ASSERTE(index * sizeof(CORCOMPILE_IMPORT_SECTION) < VAL32(pDir->Size)); - - RETURN dac_cast(GetDirectoryData(pDir)) + index; -} - -PTR_CORCOMPILE_IMPORT_SECTION PEDecoder::GetNativeImportSectionForRVA(RVA rva) const -{ - CONTRACT(PTR_CORCOMPILE_IMPORT_SECTION) - { - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } - CONTRACT_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->ImportSections; - - _ASSERTE(VAL32(pDir->Size) % sizeof(CORCOMPILE_IMPORT_SECTION) == 0); - - PTR_CORCOMPILE_IMPORT_SECTION pSections = dac_cast(GetDirectoryData(pDir)); - PTR_CORCOMPILE_IMPORT_SECTION pEnd = dac_cast(dac_cast(pSections) + VAL32(pDir->Size)); - - for (PTR_CORCOMPILE_IMPORT_SECTION pSection = pSections; pSection < pEnd; pSection++) - { - if (rva >= VAL32(pSection->Section.VirtualAddress) && rva < VAL32(pSection->Section.VirtualAddress) + VAL32(pSection->Section.Size)) - RETURN pSection; - } - - RETURN NULL; -} - -TADDR PEDecoder::GetStubsTable(COUNT_T *pSize) const -{ - CONTRACTL { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->StubsData; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - return (GetDirectoryData(pDir)); -} - -TADDR PEDecoder::GetVirtualSectionsTable(COUNT_T *pSize) const -{ - CONTRACTL { - INSTANCE_CHECK; - PRECONDITION(CheckNativeHeader()); - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; - - IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->VirtualSectionsTable; - - if (pSize != NULL) - *pSize = VAL32(pDir->Size); - - return (GetDirectoryData(pDir)); -} - -#endif // FEATURE_PREJIT - // Get the SizeOfStackReserve and SizeOfStackCommit from the PE file that was used to create // the calling process (.exe file). void PEDecoder::GetEXEStackSizes(SIZE_T *PE_SizeOfStackReserve, SIZE_T *PE_SizeOfStackCommit) const diff --git a/src/coreclr/vm/.vscode/c_cpp_properties.json b/src/coreclr/vm/.vscode/c_cpp_properties.json index 6cf89552d9d2c6..3e0fa37196a654 100644 --- a/src/coreclr/vm/.vscode/c_cpp_properties.json +++ b/src/coreclr/vm/.vscode/c_cpp_properties.json @@ -63,7 +63,6 @@ "FEATURE_MULTICASTSTUB_AS_IL", "FEATURE_MULTICOREJIT", "FEATURE_PERFTRACING=1", - "FEATURE_PREJIT", "FEATURE_PROFAPI_ATTACH_DETACH", "FEATURE_READYTORUN", "FEATURE_REJIT", diff --git a/src/coreclr/vm/amd64/ExternalMethodFixupThunk.asm b/src/coreclr/vm/amd64/ExternalMethodFixupThunk.asm index 0fa438c8eb3ad8..1a0671e8f1c6a6 100644 --- a/src/coreclr/vm/amd64/ExternalMethodFixupThunk.asm +++ b/src/coreclr/vm/amd64/ExternalMethodFixupThunk.asm @@ -7,10 +7,6 @@ include AsmConstants.inc extern ExternalMethodFixupWorker:proc extern ProcessCLRException:proc -ifdef FEATURE_PREJIT - extern VirtualMethodFixupWorker:proc -endif - ifdef FEATURE_READYTORUN extern DynamicHelperWorker:proc endif @@ -89,23 +85,4 @@ DYNAMICHELPER SetFunction(pMD); - - ENTRY_POINT; - } - CONTRACTL_END; - - MAKE_CURRENT_THREAD_AVAILABLE(); - - PCODE pCode = NULL; - MethodDesc * pMD = NULL; - -#ifdef _DEBUG - Thread::ObjectRefFlush(CURRENT_THREAD); -#endif - - _ASSERTE(IS_ALIGNED((size_t)pThunk, sizeof(INT64))); - - FrameWithCookie frame(pTransitionBlock); - ExternalMethodFrame * pEMFrame = &frame; - - OBJECTREF pThisPtr = pEMFrame->GetThis(); - _ASSERTE(pThisPtr != NULL); - VALIDATEOBJECT(pThisPtr); - - MethodTable * pMT = pThisPtr->GetMethodTable(); - - WORD slotNumber = pThunk->slotNum; - _ASSERTE(slotNumber != (WORD)-1); - - pCode = pMT->GetRestoredSlot(slotNumber); - - if (!DoesSlotCallPrestub(pCode)) - { - pMD = MethodTable::GetMethodDescForSlotAddress(pCode); - - pEMFrame->SetFunction(pMD); // We will use the pMD to enumerate the GC refs in the arguments - pEMFrame->Push(CURRENT_THREAD); - - INSTALL_MANAGED_EXCEPTION_DISPATCHER; - INSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE; - - if (pMD->IsVersionableWithVtableSlotBackpatch()) - { - // The entry point for this method needs to be versionable, so use a FuncPtrStub similarly to what is done in - // MethodDesc::GetMultiCallableAddrOfCode() - GCX_COOP(); - pCode = pMD->GetLoaderAllocator()->GetFuncPtrStubs()->GetFuncPtrStub(pMD); - } - else - { - // Skip fixup precode jump for better perf - PCODE pDirectTarget = Precode::TryToSkipFixupPrecode(pCode); - if (pDirectTarget != NULL) - pCode = pDirectTarget; - } - - INT64 oldValue = *(INT64*)pThunk; - BYTE* pOldValue = (BYTE*)&oldValue; - - if (pOldValue[0] == X86_INSTR_CALL_REL32) - { - INT64 newValue = oldValue; - BYTE* pNewValue = (BYTE*)&newValue; - pNewValue[0] = X86_INSTR_JMP_REL32; - - *(INT32 *)(pNewValue+1) = rel32UsingJumpStub((INT32*)(&pThunk->callJmp[1]), pCode, pMD, NULL); - - _ASSERTE(IS_ALIGNED(pThunk, sizeof(INT64))); - - ExecutableWriterHolder thunkWriterHolder((INT64*)pThunk, sizeof(INT64)); - FastInterlockCompareExchangeLong(thunkWriterHolder.GetRW(), newValue, oldValue); - - FlushInstructionCache(GetCurrentProcess(), pThunk, 8); - } - - UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE; - UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; - pEMFrame->Pop(CURRENT_THREAD); - } - - // Ready to return - return pCode; -} -#endif // FEATURE_PREJIT - #ifdef FEATURE_READYTORUN // diff --git a/src/coreclr/vm/amd64/externalmethodfixupthunk.S b/src/coreclr/vm/amd64/externalmethodfixupthunk.S index f840a05c69afbf..217e9dde7b9b17 100644 --- a/src/coreclr/vm/amd64/externalmethodfixupthunk.S +++ b/src/coreclr/vm/amd64/externalmethodfixupthunk.S @@ -79,21 +79,3 @@ DYNAMICHELPER (DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_Objec #endif // FEATURE_READYTORUN -#ifdef FEATURE_PREJIT -//============================================================================================ -// EXTERN_C VOID __stdcall VirtualMethodFixupStub() - -NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler - - PROLOG_WITH_TRANSITION_BLOCK 0, 8, rsi, 0, 0 - - lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock - sub rsi, 5 // pThunk - call C_FUNC(VirtualMethodFixupWorker) - - EPILOG_WITH_TRANSITION_BLOCK_TAILCALL -PATCH_LABEL VirtualMethodFixupPatchLabel - TAILJMP_RAX - -NESTED_END VirtualMethodFixupStub, _TEXT -#endif // FEATURE_PREJIT diff --git a/src/coreclr/vm/amd64/virtualcallstubamd64.S b/src/coreclr/vm/amd64/virtualcallstubamd64.S index 79498a00359a51..55716fdd8b94b5 100644 --- a/src/coreclr/vm/amd64/virtualcallstubamd64.S +++ b/src/coreclr/vm/amd64/virtualcallstubamd64.S @@ -87,22 +87,3 @@ Fail_RWCLAS: LEAF_END ResolveWorkerChainLookupAsmStub, _TEXT -#ifdef FEATURE_PREJIT -NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler - - PROLOG_WITH_TRANSITION_BLOCK 0, 0, 0, 0, 0 - - lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock - mov rsi, r11 // indirection cell address - - mov rdx,0 // sectionIndex - mov rcx,0 // pModule - - call C_FUNC(StubDispatchFixupWorker) - - EPILOG_WITH_TRANSITION_BLOCK_TAILCALL -PATCH_LABEL StubDispatchFixupPatchLabel - TAILJMP_RAX - -NESTED_END StubDispatchFixupStub, _TEXT -#endif diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index 669dc918df854b..96b693f7c7a900 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -94,11 +94,6 @@ static const WCHAR OTHER_DOMAIN_FRIENDLY_NAME_PREFIX[] = W("Domain"); SPTR_IMPL(AppDomain, AppDomain, m_pTheAppDomain); SPTR_IMPL(SystemDomain, SystemDomain, m_pSystemDomain); -#ifdef FEATURE_PREJIT -SVAL_IMPL(BOOL, SystemDomain, s_fForceDebug); -SVAL_IMPL(BOOL, SystemDomain, s_fForceProfiling); -SVAL_IMPL(BOOL, SystemDomain, s_fForceInstrument); -#endif #ifndef DACCESS_COMPILE @@ -1013,34 +1008,6 @@ void SystemDomain::operator delete(void *pMem) // Do nothing - new() was in-place } -#ifdef FEATURE_PREJIT -void SystemDomain::SetCompilationOverrides(BOOL fForceDebug, - BOOL fForceProfiling, - BOOL fForceInstrument) -{ - LIMITED_METHOD_CONTRACT; - s_fForceDebug = fForceDebug; - s_fForceProfiling = fForceProfiling; - s_fForceInstrument = fForceInstrument; -} -#endif - -#endif //!DACCESS_COMPILE - -#ifdef FEATURE_PREJIT -void SystemDomain::GetCompilationOverrides(BOOL * fForceDebug, - BOOL * fForceProfiling, - BOOL * fForceInstrument) -{ - LIMITED_METHOD_DAC_CONTRACT; - *fForceDebug = s_fForceDebug; - *fForceProfiling = s_fForceProfiling; - *fForceInstrument = s_fForceInstrument; -} -#endif - -#ifndef DACCESS_COMPILE - void SystemDomain::Attach() { CONTRACTL @@ -1161,14 +1128,6 @@ void SystemDomain::PreallocateSpecialObjects() OBJECTREF pPreallocatedSentinalObject = AllocateObject(g_pObjectClass); g_pPreallocatedSentinelObject = CreatePinningHandle( pPreallocatedSentinalObject ); - -#ifdef FEATURE_PREJIT - if (SystemModule()->HasNativeImage()) - { - CORCOMPILE_EE_INFO_TABLE *pEEInfo = SystemModule()->GetNativeImage()->GetNativeEEInfoTable(); - pEEInfo->emptyString = (CORINFO_Object **)StringObject::GetEmptyStringRefPtr(); - } -#endif } void SystemDomain::CreatePreallocatedExceptions() @@ -1535,20 +1494,6 @@ void SystemDomain::LoadBaseSystemClasses() g_CoreLib.Check(); } #endif - -#if defined(HAVE_GCCOVER) && defined(FEATURE_PREJIT) - if (GCStress::IsEnabled()) - { - // Setting up gc coverage requires the base system classes - // to be initialized. So we have deferred it until now for CoreLib. - Module *pModule = CoreLibBinder::GetModule(); - _ASSERTE(pModule->IsSystem()); - if(pModule->HasNativeImage()) - { - SetupGcCoverageForNativeImage(pModule); - } - } -#endif // defined(HAVE_GCCOVER) && !defined(FEATURE_PREJIT) } /*static*/ @@ -2148,9 +2093,6 @@ AppDomain::AppDomain() m_pTypeEquivalenceTable = NULL; #endif // FEATURE_TYPEEQUIVALENCE -#ifdef FEATURE_PREJIT - m_pDomainFileWithNativeImageList = NULL; -#endif } // AppDomain::AppDomain AppDomain::~AppDomain() @@ -2254,9 +2196,6 @@ BOOL AppDomain::IsCompilationDomain() LIMITED_METHOD_CONTRACT; BOOL isCompilationDomain = (m_dwFlags & COMPILATION_DOMAIN) != 0; -#ifdef FEATURE_PREJIT - _ASSERTE(!isCompilationDomain || IsCompilationProcess()); -#endif // FEATURE_PREJIT return isCompilationDomain; } diff --git a/src/coreclr/vm/appdomain.hpp b/src/coreclr/vm/appdomain.hpp index 51872a5494a072..ea0f91b5e6061d 100644 --- a/src/coreclr/vm/appdomain.hpp +++ b/src/coreclr/vm/appdomain.hpp @@ -998,12 +998,6 @@ class BaseDomain // will be properly serialized) OBJECTREF *AllocateObjRefPtrsInLargeTable(int nRequested, OBJECTREF** ppLazyAllocate = NULL); -#ifdef FEATURE_PREJIT - // Ensures that the file for logging profile data is open (we only open it once) - // return false on failure - static BOOL EnsureNGenLogFileOpen(); -#endif - //**************************************************************************************** // Handles @@ -2467,16 +2461,6 @@ class AppDomain : public BaseDomain DomainAssembly* pAssembly); #endif // DACCESS_COMPILE -#ifdef FEATURE_PREJIT - friend void DomainFile::InsertIntoDomainFileWithNativeImageList(); - Volatile m_pDomainFileWithNativeImageList; -public: - DomainFile *GetDomainFilesWithNativeImagesList() - { - LIMITED_METHOD_CONTRACT; - return m_pDomainFileWithNativeImageList; - } -#endif }; // class AppDomain // Just a ref holder @@ -2786,17 +2770,6 @@ class SystemDomain : public BaseDomain static DWORD m_dwLowestFreeIndex; #endif // DACCESS_COMPILE -#ifdef FEATURE_PREJIT -protected: - - // These flags let the correct native image of CoreLib to be loaded. - // This is important for hardbinding to it - - SVAL_DECL(BOOL, s_fForceDebug); - SVAL_DECL(BOOL, s_fForceProfiling); - SVAL_DECL(BOOL, s_fForceInstrument); -#endif - public: static void SetCompilationOverrides(BOOL fForceDebug, BOOL fForceProfiling, diff --git a/src/coreclr/vm/arm/asmhelpers.S b/src/coreclr/vm/arm/asmhelpers.S index 2780f95912f173..d1695b2054d1d9 100644 --- a/src/coreclr/vm/arm/asmhelpers.S +++ b/src/coreclr/vm/arm/asmhelpers.S @@ -591,64 +591,6 @@ LOCAL_LABEL(stackProbe_loop): bx lr NESTED_END stackProbe, _TEXT -#ifdef FEATURE_PREJIT -//------------------------------------------------ -// VirtualMethodFixupStub -// -// In NGEN images, virtual slots inherited from cross-module dependencies -// point to a jump thunk that calls into the following function that will -// call into a VM helper. The VM helper is responsible for patching up -// thunk, upon executing the precode, so that all subsequent calls go directly -// to the actual method body. -// -// This is done lazily for performance reasons. -// -// On entry: -// -// R0 = "this" pointer -// R12 = Address of thunk + 4 - - NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler - - // Save arguments and return address - PROLOG_PUSH "{r0-r3, r7,r8, lr}" // keep increase by 8B for alignment - PROLOG_STACK_SAVE_OFFSET r7, #20 - - // Align stack - alloc_stack SIZEOF__FloatArgumentRegisters + 4 - vstm sp, {d0-d7} - - - CHECK_STACK_ALIGNMENT - - // R12 contains an address that is 4 bytes ahead of - // where the thunk starts. Refer to ZapImportVirtualThunk::Save - // for details on this. - // - // Move the correct thunk start address in R1 - sub r1, r12, #4 - - // Call the helper in the VM to perform the actual fixup - // and tell us where to tail call. R0 already contains - // the this pointer. - bl C_FUNC(VirtualMethodFixupWorker) - - // On return, R0 contains the target to tailcall to - mov r12, r0 - - // pop the stack and restore original register state - vldm sp, {d0-d7} - free_stack SIZEOF__FloatArgumentRegisters + 4 - EPILOG_POP "{r0-r3, r7,r8, lr}" - - PATCH_LABEL VirtualMethodFixupPatchLabel - - // and tailcall to the actual method - bx r12 - - NESTED_END VirtualMethodFixupStub, _TEXT -#endif // FEATURE_PREJIT - //------------------------------------------------ // ExternalMethodFixupStub // @@ -686,41 +628,6 @@ LOCAL_LABEL(stackProbe_loop): NESTED_END ExternalMethodFixupStub, _TEXT -#ifdef FEATURE_PREJIT -//------------------------------------------------ -// StubDispatchFixupStub -// -// In NGEN images, calls to interface methods initially -// point to a jump thunk that calls into the following function that will -// call into a VM helper. The VM helper is responsible for patching up the -// thunk with actual stub dispatch stub. -// -// On entry: -// -// R4 = Address of indirection cell - - NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler - - PROLOG_WITH_TRANSITION_BLOCK - - // address of StubDispatchFrame - add r0, sp, #__PWTB_TransitionBlock // pTransitionBlock - mov r1, r4 // siteAddrForRegisterIndirect - mov r2, #0 // sectionIndex - mov r3, #0 // pModule - - bl C_FUNC(StubDispatchFixupWorker) - - // mov the address we patched to in R12 so that we can tail call to it - mov r12, r0 - - EPILOG_WITH_TRANSITION_BLOCK_TAILCALL - PATCH_LABEL StubDispatchFixupPatchLabel - bx r12 - - NESTED_END StubDispatchFixupStub, _TEXT -#endif // FEATURE_PREJIT - //------------------------------------------------ // JIT_RareDisableHelper // diff --git a/src/coreclr/vm/arm/asmhelpers.asm b/src/coreclr/vm/arm/asmhelpers.asm index 82596e66693dce..db7584235e50e5 100644 --- a/src/coreclr/vm/arm/asmhelpers.asm +++ b/src/coreclr/vm/arm/asmhelpers.asm @@ -50,12 +50,6 @@ ;; Import to support cross-moodule external method invocation in ngen images IMPORT ExternalMethodFixupWorker -#ifdef FEATURE_PREJIT - ;; Imports to support virtual import fixup for ngen images - IMPORT VirtualMethodFixupWorker - IMPORT StubDispatchFixupWorker -#endif - #ifdef FEATURE_READYTORUN IMPORT DynamicHelperWorker #endif @@ -1034,63 +1028,6 @@ stackProbe_loop EPILOG_RETURN NESTED_END -#ifdef FEATURE_PREJIT -;------------------------------------------------ -; VirtualMethodFixupStub -; -; In NGEN images, virtual slots inherited from cross-module dependencies -; point to a jump thunk that calls into the following function that will -; call into a VM helper. The VM helper is responsible for patching up -; thunk, upon executing the precode, so that all subsequent calls go directly -; to the actual method body. -; -; This is done lazily for performance reasons. -; -; On entry: -; -; R0 = "this" pointer -; R12 = Address of thunk + 4 - - NESTED_ENTRY VirtualMethodFixupStub - - ; Save arguments and return address - PROLOG_PUSH {r0-r3, lr} - - ; Align stack - PROLOG_STACK_ALLOC SIZEOF__FloatArgumentRegisters + 4 - vstm sp, {d0-d7} - - - CHECK_STACK_ALIGNMENT - - ; R12 contains an address that is 4 bytes ahead of - ; where the thunk starts. Refer to ZapImportVirtualThunk::Save - ; for details on this. - ; - ; Move the correct thunk start address in R1 - sub r1, r12, #4 - - ; Call the helper in the VM to perform the actual fixup - ; and tell us where to tail call. R0 already contains - ; the this pointer. - bl VirtualMethodFixupWorker - - ; On return, R0 contains the target to tailcall to - mov r12, r0 - - ; pop the stack and restore original register state - vldm sp, {d0-d7} - EPILOG_STACK_FREE SIZEOF__FloatArgumentRegisters + 4 - EPILOG_POP {r0-r3, lr} - - PATCH_LABEL VirtualMethodFixupPatchLabel - - ; and tailcall to the actual method - EPILOG_BRANCH_REG r12 - - NESTED_END -#endif // FEATURE_PREJIT - ;------------------------------------------------ ; ExternalMethodFixupStub ; @@ -1128,41 +1065,6 @@ stackProbe_loop NESTED_END -#ifdef FEATURE_PREJIT -;------------------------------------------------ -; StubDispatchFixupStub -; -; In NGEN images, calls to interface methods initially -; point to a jump thunk that calls into the following function that will -; call into a VM helper. The VM helper is responsible for patching up the -; thunk with actual stub dispatch stub. -; -; On entry: -; -; R4 = Address of indirection cell - - NESTED_ENTRY StubDispatchFixupStub - - PROLOG_WITH_TRANSITION_BLOCK - - ; address of StubDispatchFrame - add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock - mov r1, r4 ; siteAddrForRegisterIndirect - mov r2, #0 ; sectionIndex - mov r3, #0 ; pModule - - bl StubDispatchFixupWorker - - ; mov the address we patched to in R12 so that we can tail call to it - mov r12, r0 - - EPILOG_WITH_TRANSITION_BLOCK_TAILCALL - PATCH_LABEL StubDispatchFixupPatchLabel - EPILOG_BRANCH_REG r12 - - NESTED_END -#endif // FEATURE_PREJIT - ;------------------------------------------------ ; JIT_RareDisableHelper ; diff --git a/src/coreclr/vm/arm/cgencpu.h b/src/coreclr/vm/arm/cgencpu.h index 425c286558432b..26abef2fcab73a 100644 --- a/src/coreclr/vm/arm/cgencpu.h +++ b/src/coreclr/vm/arm/cgencpu.h @@ -1098,9 +1098,6 @@ struct StubPrecode { } #endif // !DACCESS_COMPILE -#ifdef FEATURE_PREJIT - void Fixup(DataImage *image); -#endif }; typedef DPTR(StubPrecode) PTR_StubPrecode; @@ -1138,9 +1135,6 @@ struct NDirectImportPrecode { return (LPVOID)(dac_cast(this) + THUMB_CODE); } -#ifdef FEATURE_PREJIT - void Fixup(DataImage *image); -#endif }; typedef DPTR(NDirectImportPrecode) PTR_NDirectImportPrecode; @@ -1223,13 +1217,6 @@ struct FixupPrecode { (pInstr[2] == 0xf004); } -#ifdef FEATURE_PREJIT - // Partial initialization. Used to save regrouped chunks. - void InitForSave(int iPrecodeChunkIndex); - - void Fixup(DataImage *image, MethodDesc * pMD); -#endif - #ifdef DACCESS_COMPILE void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); #endif diff --git a/src/coreclr/vm/arm64/asmhelpers.S b/src/coreclr/vm/arm64/asmhelpers.S index 8ef66586cd22c9..cded1adab4fec1 100644 --- a/src/coreclr/vm/arm64/asmhelpers.S +++ b/src/coreclr/vm/arm64/asmhelpers.S @@ -500,56 +500,6 @@ LEAF_ENTRY JIT_PatchedCodeLast, _TEXT ret lr LEAF_END JIT_PatchedCodeLast, _TEXT -#ifdef FEATURE_PREJIT -//------------------------------------------------ -// VirtualMethodFixupStub -// -// In NGEN images, virtual slots inherited from cross-module dependencies -// point to a jump thunk that calls into the following function that will -// call into a VM helper. The VM helper is responsible for patching up -// thunk, upon executing the precode, so that all subsequent calls go directly -// to the actual method body. -// -// This is done lazily for performance reasons. -// -// On entry: -// -// x0 = "this" pointer -// x12 = Address of thunk - -NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler - - // Save arguments and return address - PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -224 - SAVE_ARGUMENT_REGISTERS sp, 16 - SAVE_FLOAT_ARGUMENT_REGISTERS sp, 96 - - // Refer to ZapImportVirtualThunk::Save - // for details on this. - // - // Move the thunk start address in x1 - mov x1, x12 - - // Call the helper in the VM to perform the actual fixup - // and tell us where to tail call. x0 already contains - // the this pointer. - bl C_FUNC(VirtualMethodFixupWorker) - // On return, x0 contains the target to tailcall to - mov x12, x0 - - // pop the stack and restore original register state - RESTORE_ARGUMENT_REGISTERS sp, 16 - RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 96 - EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 224 - - PATCH_LABEL VirtualMethodFixupPatchLabel - - // and tailcall to the actual method - EPILOG_BRANCH_REG x12 - -NESTED_END VirtualMethodFixupStub, _TEXT -#endif // FEATURE_PREJIT - //------------------------------------------------ // ExternalMethodFixupStub // @@ -1089,29 +1039,6 @@ DynamicHelper DynamicHelperFrameFlags_ObjectArg, _Obj DynamicHelper DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_ObjectArg2, _ObjObj #endif -#ifdef FEATURE_PREJIT -// ------------------------------------------------------------------ -// void StubDispatchFixupStub(args in regs x0-x7 & stack and possibly retbuff arg in x8, x11:IndirectionCellAndFlags) -// -// The stub dispatch thunk which transfers control to StubDispatchFixupWorker. -NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler - - PROLOG_WITH_TRANSITION_BLOCK - - add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock - and x1, x11, #-4 // Indirection cell - mov x2, #0 // sectionIndex - mov x3, #0 // pModule - bl C_FUNC(StubDispatchFixupWorker) - mov x12, x0 - - EPILOG_WITH_TRANSITION_BLOCK_TAILCALL - PATCH_LABEL StubDispatchFixupPatchLabel - EPILOG_BRANCH_REG x12 - -NESTED_END StubDispatchFixupStub, _TEXT -#endif - #ifdef FEATURE_COMINTEROP // Function used by COM interop to get floating point return value (since it's not in the same diff --git a/src/coreclr/vm/arm64/asmhelpers.asm b/src/coreclr/vm/arm64/asmhelpers.asm index 17d3a676940bd2..2017000eb783e9 100644 --- a/src/coreclr/vm/arm64/asmhelpers.asm +++ b/src/coreclr/vm/arm64/asmhelpers.asm @@ -10,10 +10,6 @@ #include "asmconstants.h" #include "asmmacros.h" -#ifdef FEATURE_PREJIT - IMPORT VirtualMethodFixupWorker - IMPORT StubDispatchFixupWorker -#endif IMPORT ExternalMethodFixupWorker IMPORT PreStubWorker IMPORT NDirectImportWorker @@ -554,56 +550,6 @@ Exit ret lr LEAF_END -#ifdef FEATURE_PREJIT -;------------------------------------------------ -; VirtualMethodFixupStub -; -; In NGEN images, virtual slots inherited from cross-module dependencies -; point to a jump thunk that calls into the following function that will -; call into a VM helper. The VM helper is responsible for patching up -; thunk, upon executing the precode, so that all subsequent calls go directly -; to the actual method body. -; -; This is done lazily for performance reasons. -; -; On entry: -; -; x0 = "this" pointer -; x12 = Address of thunk - - NESTED_ENTRY VirtualMethodFixupStub - - ; Save arguments and return address - PROLOG_SAVE_REG_PAIR fp, lr, #-224! - SAVE_ARGUMENT_REGISTERS sp, 16 - SAVE_FLOAT_ARGUMENT_REGISTERS sp, 96 - - ; Refer to ZapImportVirtualThunk::Save - ; for details on this. - ; - ; Move the thunk start address in x1 - mov x1, x12 - - ; Call the helper in the VM to perform the actual fixup - ; and tell us where to tail call. x0 already contains - ; the this pointer. - bl VirtualMethodFixupWorker - ; On return, x0 contains the target to tailcall to - mov x12, x0 - - ; pop the stack and restore original register state - RESTORE_ARGUMENT_REGISTERS sp, 16 - RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 96 - EPILOG_RESTORE_REG_PAIR fp, lr, #224! - - PATCH_LABEL VirtualMethodFixupPatchLabel - - ; and tailcall to the actual method - EPILOG_BRANCH_REG x12 - - NESTED_END -#endif // FEATURE_PREJIT - ;------------------------------------------------ ; ExternalMethodFixupStub ; @@ -1303,29 +1249,6 @@ Fail DynamicHelper DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_ObjectArg2, _ObjObj #endif // FEATURE_READYTORUN -#ifdef FEATURE_PREJIT -;; ------------------------------------------------------------------ -;; void StubDispatchFixupStub(args in regs x0-x7 & stack and possibly retbuff arg in x8, x11:IndirectionCellAndFlags) -;; -;; The stub dispatch thunk which transfers control to StubDispatchFixupWorker. - NESTED_ENTRY StubDispatchFixupStub - - PROLOG_WITH_TRANSITION_BLOCK - - add x0, sp, #__PWTB_TransitionBlock ; pTransitionBlock - and x1, x11, #-4 ; Indirection cell - mov x2, #0 ; sectionIndex - mov x3, #0 ; pModule - bl StubDispatchFixupWorker - mov x12, x0 - - EPILOG_WITH_TRANSITION_BLOCK_TAILCALL - PATCH_LABEL StubDispatchFixupPatchLabel - EPILOG_BRANCH_REG x12 - - NESTED_END -#endif - #ifdef FEATURE_COMINTEROP ; ------------------------------------------------------------------ ; Function used by COM interop to get floating point return value (since it's not in the same diff --git a/src/coreclr/vm/arm64/cgencpu.h b/src/coreclr/vm/arm64/cgencpu.h index 0641d89ff1a91b..957a6925b2da1f 100644 --- a/src/coreclr/vm/arm64/cgencpu.h +++ b/src/coreclr/vm/arm64/cgencpu.h @@ -626,9 +626,6 @@ struct StubPrecode { } #endif // !DACCESS_COMPILE -#ifdef FEATURE_PREJIT - void Fixup(DataImage *image); -#endif }; typedef DPTR(StubPrecode) PTR_StubPrecode; @@ -667,9 +664,6 @@ struct NDirectImportPrecode { return this; } -#ifdef FEATURE_PREJIT - void Fixup(DataImage *image); -#endif }; typedef DPTR(NDirectImportPrecode) PTR_NDirectImportPrecode; @@ -770,13 +764,6 @@ struct FixupPrecode { (pInstr[2] == 0xD61F0160); } -#ifdef FEATURE_PREJIT - // Partial initialization. Used to save regrouped chunks. - void InitForSave(int iPrecodeChunkIndex); - - void Fixup(DataImage *image, MethodDesc * pMD); -#endif - #ifdef DACCESS_COMPILE void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); #endif diff --git a/src/coreclr/vm/array.cpp b/src/coreclr/vm/array.cpp index ae91f700fbcd62..ef9917aee6035c 100644 --- a/src/coreclr/vm/array.cpp +++ b/src/coreclr/vm/array.cpp @@ -330,12 +330,7 @@ MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementTy // Inherit top level class's interface map cbMT += pParentClass->GetNumInterfaces() * sizeof(InterfaceInfo_t); -#ifdef FEATURE_PREJIT - Module* pComputedPZM = Module::ComputePreferredZapModule(NULL, Instantiation(&elemTypeHnd, 1)); - BOOL canShareVtableChunks = MethodTable::CanShareVtableChunksFrom(pParentClass, this, pComputedPZM); -#else BOOL canShareVtableChunks = MethodTable::CanShareVtableChunksFrom(pParentClass, this); -#endif // FEATURE_PREJIT size_t offsetOfUnsharedVtableChunks = cbMT; @@ -712,10 +707,6 @@ MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementTy // an array whose base type is not a value class was created and was larger then 0xffff (a word) _ASSERTE(dwComponentSize == pMT->GetComponentSize()); -#ifdef FEATURE_PREJIT - _ASSERTE(pComputedPZM == Module::GetPreferredZapModuleForMethodTable(pMT)); -#endif - return(pMT); } // Module::CreateArrayMethodTable diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp index 11e271a8ef6a87..dc9e3f8708164a 100644 --- a/src/coreclr/vm/assembly.cpp +++ b/src/coreclr/vm/assembly.cpp @@ -122,9 +122,9 @@ Assembly::Assembly(BaseDomain *pDomain, PEAssembly* pFile, DebuggerAssemblyContr #endif m_debuggerFlags(debuggerFlags), m_fTerminated(FALSE), -#if defined(FEATURE_PREJIT) || defined(FEATURE_READYTORUN) +#if FEATURE_READYTORUN m_isInstrumentedStatus(IS_INSTRUMENTED_UNSET) -#endif +#endif // FEATURE_READYTORUN { STANDARD_VM_CONTRACT; } @@ -242,24 +242,6 @@ Assembly::~Assembly() #endif // FEATURE_COMINTEROP } -#ifdef FEATURE_PREJIT -void Assembly::DeleteNativeCodeRanges() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - FORBID_FAULT; - } - CONTRACTL_END - - ModuleIterator i = IterateModules(); - while (i.Next()) - i.GetModule()->DeleteNativeCodeRanges(); -} -#endif - #ifdef PROFILING_SUPPORTED void ProfilerCallAssemblyUnloadStarted(Assembly* assemblyUnloaded) { @@ -1830,7 +1812,7 @@ BOOL Assembly::GetResource(LPCSTR szName, DWORD *cbResource, return result; } -#if defined(FEATURE_PREJIT) || defined(FEATURE_READYTORUN) +#ifdef FEATURE_READYTORUN BOOL Assembly::IsInstrumented() { STATIC_CONTRACT_THROWS; @@ -1940,7 +1922,7 @@ BOOL Assembly::IsInstrumentedHelper() return false; } -#endif // FEATURE_PREJIT +#endif // FEATURE_READYTORUN #ifdef FEATURE_COMINTEROP diff --git a/src/coreclr/vm/assembly.hpp b/src/coreclr/vm/assembly.hpp index 8b51cad630ca66..029309d5dc977e 100644 --- a/src/coreclr/vm/assembly.hpp +++ b/src/coreclr/vm/assembly.hpp @@ -404,9 +404,6 @@ class Assembly Assembly(); ~Assembly(); -#ifdef FEATURE_PREJIT - void DeleteNativeCodeRanges(); -#endif BOOL GetResource(LPCSTR szName, DWORD *cbResource, PBYTE *pbInMemoryResource, Assembly **pAssemblyRef, @@ -437,10 +434,10 @@ class Assembly OBJECTHANDLE GetLoaderAllocatorObjectHandle() { WRAPPER_NO_CONTRACT; return GetLoaderAllocator()->GetLoaderAllocatorObjectHandle(); } #endif // FEATURE_COLLECTIBLE_TYPES -#if defined(FEATURE_PREJIT) || defined(FEATURE_READYTORUN) +#ifdef FEATURE_READYTORUN BOOL IsInstrumented(); BOOL IsInstrumentedHelper(); -#endif // FEATURE_PREJIT +#endif // FEATURE_READYTORUN #ifdef FEATURE_COMINTEROP static ITypeLib * const InvalidTypeLib; @@ -592,14 +589,14 @@ class Assembly BOOL m_fTerminated; -#if defined(FEATURE_PREJIT) || defined(FEATURE_READYTORUN) +#ifdef FEATURE_READYTORUN enum IsInstrumentedStatus { IS_INSTRUMENTED_UNSET = 0, IS_INSTRUMENTED_FALSE = 1, IS_INSTRUMENTED_TRUE = 2, }; IsInstrumentedStatus m_isInstrumentedStatus; -#endif // FEATURE_PREJIT +#endif // FEATURE_READYTORUN }; diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp index 63846ce5401117..77b9b12f3af18d 100644 --- a/src/coreclr/vm/assemblynative.cpp +++ b/src/coreclr/vm/assemblynative.cpp @@ -238,31 +238,6 @@ void QCALLTYPE AssemblyNative::LoadFromPath(INT_PTR ptrNativeAssemblyLoadContext } } -#ifdef FEATURE_PREJIT - // Form the PEImage for the NI assembly, if specified - if (pwzNIPath != NULL) - { - pNIImage = PEImage::OpenImage(pwzNIPath, - MDInternalImport_TrustedNativeImage, - BundleFileLocation::Invalid()); - - if (pNIImage->HasReadyToRunHeader()) - { - // ReadyToRun images are treated as IL images by the rest of the system - if (!pNIImage->CheckILFormat()) - THROW_BAD_FORMAT(COR_E_BADIMAGEFORMAT, pNIImage.GetValue()); - - pILImage = pNIImage.Extract(); - pNIImage = NULL; - } - else - { - if (!pNIImage->CheckNativeFormat()) - THROW_BAD_FORMAT(COR_E_BADIMAGEFORMAT, pNIImage.GetValue()); - } - } -#endif // FEATURE_PREJIT - Assembly *pLoadedAssembly = AssemblyNative::LoadFromPEImage(pBinderContext, pILImage, pNIImage); { diff --git a/src/coreclr/vm/binder.cpp b/src/coreclr/vm/binder.cpp index cefa77c9cdbc77..7b8b8237b4b9dd 100644 --- a/src/coreclr/vm/binder.cpp +++ b/src/coreclr/vm/binder.cpp @@ -1138,22 +1138,6 @@ void CoreLibBinder::AttachModule(Module * pModule) c_rgCoreLibMethodDescriptions, c_nCoreLibMethodDescriptions, c_rgCoreLibFieldDescriptions, c_nCoreLibFieldDescriptions); -#if defined(FEATURE_PREJIT) && !defined(CROSSGEN_COMPILE) - CoreLibBinder * pPersistedBinder = pModule->m_pBinder; - - if (pPersistedBinder != NULL - // Do not use persisted binder for profiling native images. See comment in code:CoreLibBinder::Fixup. - && !(pModule->GetNativeImage()->GetNativeVersionInfo()->wConfigFlags & CORCOMPILE_CONFIG_PROFILING)) - { - pGlobalBinder->m_pClasses = pPersistedBinder->m_pClasses; - pGlobalBinder->m_pMethods = pPersistedBinder->m_pMethods; - pGlobalBinder->m_pFields = pPersistedBinder->m_pFields; - - pModule->m_pBinder = pGlobalBinder; - return; - } -#endif // FEATURE_PREJIT && CROSSGEN_COMPILE - pGlobalBinder->AllocateTables(); #ifdef CROSSGEN_COMPILE diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index 2af488d2d7d064..495f17df29cc1e 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -427,78 +427,24 @@ void Module::InitializeForProfiling() m_nativeImageProfiling = FALSE; -#ifdef FEATURE_PREJIT - if (HasNativeImage()) +#ifdef FEATURE_READYTORUN + // We already setup the m_methodProfileList in the ReadyToRunInfo constructor + if (m_methodProfileList != nullptr) { - PEImageLayout * pNativeImage = GetNativeImage(); - CORCOMPILE_VERSION_INFO * pNativeVersionInfo = pNativeImage->GetNativeVersionInfoMaybeNull(); - if ((pNativeVersionInfo != NULL) && (pNativeVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_INSTRUMENTATION)) - { - m_nativeImageProfiling = GetAssembly()->IsInstrumented(); - } + ReadyToRunInfo * pInfo = GetReadyToRunInfo(); + PEImageLayout * pImage = pInfo->GetImage(); - // Link the module to the profile data list if available. - m_methodProfileList = pNativeImage->GetNativeProfileDataList(&cbProfileList); + // Enable profiling if the ZapBBInstr value says to + m_nativeImageProfiling = GetAssembly()->IsInstrumented(); } - else // ReadyToRun image #endif - { -#ifdef FEATURE_READYTORUN - // We already setup the m_methodProfileList in the ReadyToRunInfo constructor - if (m_methodProfileList != nullptr) - { - ReadyToRunInfo * pInfo = GetReadyToRunInfo(); - PEImageLayout * pImage = pInfo->GetImage(); - - // Enable profiling if the ZapBBInstr value says to - m_nativeImageProfiling = GetAssembly()->IsInstrumented(); - } -#endif - } } -#ifdef FEATURE_PREJIT - -void Module::InitializeNativeImage(AllocMemTracker* pamTracker) -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - PRECONDITION(HasNativeImage()); - } - CONTRACTL_END; - - PEImageLayout * pNativeImage = GetNativeImage(); - - ExecutionManager::AddNativeImageRange(dac_cast(pNativeImage->GetBase()), pNativeImage->GetVirtualSize(), this); - -#ifndef CROSSGEN_COMPILE - LoadTokenTables(); - LoadHelperTable(); -#endif // CROSSGEN_COMPILE - -#if defined(HAVE_GCCOVER) - if (GCStress::IsEnabled()) - { - // Setting up gc coverage requires the base system classes - // to be initialized. So we must defer this for CoreLib. - if(!IsSystem()) - { - SetupGcCoverageForNativeImage(this); - } - } -#endif // defined(HAVE_GCCOVER) -} -#else // FEATURE_PREJIT BOOL Module::IsPersistedObject(void *address) { LIMITED_METHOD_CONTRACT; return FALSE; } -#endif // FEATURE_PREJIT uint32_t Module::GetNativeMetadataAssemblyCount() { @@ -666,14 +612,6 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName) // Prepare statics that are known at module load time AllocateStatics(pamTracker); -#ifdef FEATURE_PREJIT - // Set up native image - if (HasNativeImage()) - { - InitializeNativeImage(pamTracker); - } -#endif // FEATURE_PREJIT - if (HasNativeOrReadyToRunImage()) { InitializeForProfiling(); @@ -1041,37 +979,20 @@ Module *Module::Create(Assembly *pAssembly, mdFile moduleRef, PEFile *file, Allo // Create the module -#ifdef FEATURE_PREJIT - - if (file->HasNativeImage()) - { - pModule = file->GetLoadedNative()->GetPersistedModuleImage(); - PREFIX_ASSUME(pModule != NULL); - CONSISTENCY_CHECK_MSG(pModule->m_pAssembly == NULL || !pModule->IsTenured(), // if the module is not tenured it could be our previous attempt - "Native image can only be used once per process\n"); - pModule = new ((void*) pModule) Module(pAssembly, moduleRef, file); - PREFIX_ASSUME(pModule != NULL); - } - -#endif // FEATURE_PREJIT - - if (pModule == NULL) - { #ifdef EnC_SUPPORTED - if (IsEditAndContinueCapable(pAssembly, file)) - { - // if file is EnCCapable, always create an EnC-module, but EnC won't necessarily be enabled. - // Debugger enables this by calling SetJITCompilerFlags on LoadModule callback. + if (IsEditAndContinueCapable(pAssembly, file)) + { + // if file is EnCCapable, always create an EnC-module, but EnC won't necessarily be enabled. + // Debugger enables this by calling SetJITCompilerFlags on LoadModule callback. - void* pMemory = pamTracker->Track(pAssembly->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(EditAndContinueModule)))); - pModule = new (pMemory) EditAndContinueModule(pAssembly, moduleRef, file); - } - else + void* pMemory = pamTracker->Track(pAssembly->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(EditAndContinueModule)))); + pModule = new (pMemory) EditAndContinueModule(pAssembly, moduleRef, file); + } + else #endif // EnC_SUPPORTED - { - void* pMemory = pamTracker->Track(pAssembly->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(Module)))); - pModule = new (pMemory) Module(pAssembly, moduleRef, file); - } + { + void* pMemory = pamTracker->Track(pAssembly->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(Module)))); + pModule = new (pMemory) Module(pAssembly, moduleRef, file); } PREFIX_ASSUME(pModule != NULL); @@ -1253,44 +1174,13 @@ void Module::Destruct() delete m_debuggerSpecificData.m_pILOffsetMappingTable; } -#ifdef FEATURE_PREJIT - - if (HasNativeImage()) - { - m_file->Release(); - } - else -#endif // FEATURE_PREJIT - { - m_file->Release(); - } + m_file->Release(); // If this module was loaded as domain-specific, then // we must free its ModuleIndex so that it can be reused FreeModuleIndex(); } -#ifdef FEATURE_PREJIT -void Module::DeleteNativeCodeRanges() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - FORBID_FAULT; - } - CONTRACTL_END; - - if (HasNativeImage()) - { - PEImageLayout * pNativeImage = GetNativeImage(); - - ExecutionManager::DeleteRange(dac_cast(pNativeImage->GetBase())); - } -} -#endif - bool Module::NeedsGlobalMethodTable() { CONTRACTL @@ -1362,343 +1252,6 @@ MethodTable *Module::GetGlobalMethodTable() #endif // !DACCESS_COMPILE -#ifdef FEATURE_PREJIT - -/*static*/ -BOOL Module::IsAlwaysSavedInPreferredZapModule(Instantiation classInst, // the type arguments to the type (if any) - Instantiation methodInst) // the type arguments to the method (if any) -{ - LIMITED_METHOD_CONTRACT; - - return ClassLoader::IsTypicalSharedInstantiation(classInst) && - ClassLoader::IsTypicalSharedInstantiation(methodInst); -} - -//this gets called recursively for generics, so do a probe. -PTR_Module Module::ComputePreferredZapModule(Module * pDefinitionModule, - Instantiation classInst, - Instantiation methodInst) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - PTR_Module ret = NULL; - - ret = Module::ComputePreferredZapModuleHelper( pDefinitionModule, - classInst, - methodInst ); - return ret; -} - -// -// Is pModule likely a dependency of pOtherModule? Heuristic used by preferred zap module algorithm. -// It can return both false positives and negatives. -// -static bool IsLikelyDependencyOf(Module * pModule, Module * pOtherModule) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - FORBID_FAULT; - MODE_ANY; - SUPPORTS_DAC; - PRECONDITION(CheckPointer(pOtherModule)); - } - CONTRACTL_END - - // Every module has a dependency with itself - if (pModule == pOtherModule) - return true; - - // - // Explicit check for low level system assemblies is working around Win8P facades introducing extra layer between low level system assemblies - // (System.dll or System.Core.dll) and the app assemblies. Because of this extra layer, the check below won't see the direct - // reference between these low level system assemblies and the app assemblies. The prefererred zap module for instantiations of generic - // collections from these low level system assemblies (like LinkedList) should be module of AppType. It would be module of the generic - // collection without this check. - // - if (pModule->IsLowLevelSystemAssemblyByName()) - { - if (!pOtherModule->IsLowLevelSystemAssemblyByName()) - return true; - - // Every module depends upon CoreLib - if (pModule->IsSystem()) - return true; - - // CoreLib does not depend upon any other module - if (pOtherModule->IsSystem()) - return false; - } - else - { - if (pOtherModule->IsLowLevelSystemAssemblyByName()) - return false; - } - - // At this point neither pModule or pOtherModule is CoreLib - -#ifndef DACCESS_COMPILE - // - // We will check to see if the pOtherModule has a reference to pModule - // - - // If we can match the assembly ref in the ManifestModuleReferencesMap we can early out. - // This early out kicks in less than half of the time. It hurts performance on average. - // if (!IsNilToken(pOtherModule->FindAssemblyRef(pModule->GetAssembly()))) - // return true; - - if (pOtherModule->HasReferenceByName(pModule->GetSimpleName())) - return true; -#endif // DACCESS_COMPILE - - return false; -} - -// Determine the "preferred ngen home" for an instantiated type or method -// * This is the first ngen module that the loader will look in; -// * Also, we only hard bind to a type or method that lives in its preferred module -// The following properties must hold of the preferred module: -// - it must be one of the component type's declaring modules -// - if the type or method is open then the preferred module must be that of one of the type parameters -// (this ensures that we can always hard bind to open types and methods created during ngen) -// - for always-saved instantiations it must be the declaring module of the generic definition -// Otherwise, we try to pick a module that is likely to reference the type or method -// -/* static */ -PTR_Module Module::ComputePreferredZapModuleHelper( - Module * pDefinitionModule, // the module that declares the generic type or method - Instantiation classInst, // the type arguments to the type (if any) - Instantiation methodInst) // the type arguments to the method (if any) -{ - CONTRACT(PTR_Module) - { - NOTHROW; - GC_NOTRIGGER; - FORBID_FAULT; - MODE_ANY; - PRECONDITION(CheckPointer(pDefinitionModule, NULL_OK)); - // One of them will be non-null... Note we don't use CheckPointer - // because that raises a breakpoint in the debugger - PRECONDITION(pDefinitionModule != NULL || !classInst.IsEmpty() || !methodInst.IsEmpty()); - POSTCONDITION(CheckPointer(RETVAL)); - SUPPORTS_DAC; - } - CONTRACT_END - - DWORD totalArgs = classInst.GetNumArgs() + methodInst.GetNumArgs(); - - // The open type parameters takes precendence over closed type parameters since - // we always hardbind to open types. - for (DWORD i = 0; i < totalArgs; i++) - { - TypeHandle thArg = (i < classInst.GetNumArgs()) ? classInst[i] : methodInst[i - classInst.GetNumArgs()]; - - // Encoded types are never open - _ASSERTE(!thArg.IsEncodedFixup()); - Module * pOpenModule = thArg.GetDefiningModuleForOpenType(); - if (pOpenModule != NULL) - RETURN dac_cast(pOpenModule); - } - - // The initial value of pCurrentPZM is the pDefinitionModule or CoreLib - Module* pCurrentPZM = (pDefinitionModule != NULL) ? pDefinitionModule : CoreLibBinder::GetModule(); - bool preferredZapModuleBasedOnValueType = false; - - for (DWORD i = 0; i < totalArgs; i++) - { - TypeHandle pTypeParam = (i < classInst.GetNumArgs()) ? classInst[i] : methodInst[i - classInst.GetNumArgs()]; - - _ASSERTE(pTypeParam != NULL); - _ASSERTE(!pTypeParam.IsEncodedFixup()); - - Module * pParamPZM = GetPreferredZapModuleForTypeHandle(pTypeParam); - - // - // If pCurrentPZM is not a dependency of pParamPZM - // then we aren't going to update pCurrentPZM - // - if (IsLikelyDependencyOf(pCurrentPZM, pParamPZM)) - { - // If we have a type parameter that is a value type - // and we don't yet have a value type based pCurrentPZM - // then we will select it's module as the new pCurrentPZM. - // - if (pTypeParam.IsValueType() && !preferredZapModuleBasedOnValueType) - { - pCurrentPZM = pParamPZM; - preferredZapModuleBasedOnValueType = true; - } - else - { - // The normal rule is to replace the pCurrentPZM only when - // both of the following are true: - // pCurrentPZM is a dependency of pParamPZM - // and pParamPZM is not a dependency of pCurrentPZM - // - // note that the second condition is alway true when pCurrentPZM is CoreLib - // - if (!IsLikelyDependencyOf(pParamPZM, pCurrentPZM)) - { - pCurrentPZM = pParamPZM; - } - } - } - } - - RETURN dac_cast(pCurrentPZM); -} - -PTR_Module Module::ComputePreferredZapModule(TypeKey *pKey) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - if (pKey->GetKind() == ELEMENT_TYPE_CLASS) - { - return Module::ComputePreferredZapModule(pKey->GetModule(), - pKey->GetInstantiation()); - } - else if (pKey->GetKind() != ELEMENT_TYPE_FNPTR) - return Module::GetPreferredZapModuleForTypeHandle(pKey->GetElementType()); - else - return NULL; - -} - -/* see code:Module::ComputePreferredZapModuleHelper for more */ -/*static*/ -PTR_Module Module::GetPreferredZapModuleForMethodTable(MethodTable *pMT) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - PTR_Module pRet=NULL; - - if (pMT->IsArray()) - { - TypeHandle elemTH = pMT->GetArrayElementTypeHandle(); - pRet= ComputePreferredZapModule(NULL, Instantiation(&elemTH, 1)); - } - else if (pMT->HasInstantiation() && !pMT->IsGenericTypeDefinition()) - { - pRet= ComputePreferredZapModule(pMT->GetModule(), - pMT->GetInstantiation()); - } - else - { - // If it is uninstantiated or it is the generic type definition itself - // then its loader module is simply the module containing its TypeDef - pRet= pMT->GetModule(); - } - return pRet; -} - - -/*static*/ -PTR_Module Module::GetPreferredZapModuleForTypeDesc(PTR_TypeDesc pTD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - SUPPORTS_DAC; - if (pTD->HasTypeParam()) - return GetPreferredZapModuleForTypeHandle(pTD->GetTypeParam()); - else if (pTD->IsGenericVariable()) - return pTD->GetModule(); - - _ASSERTE(pTD->GetInternalCorElementType() == ELEMENT_TYPE_FNPTR); - PTR_FnPtrTypeDesc pFnPtrTD = dac_cast(pTD); - - // Result type of function type is used for preferred zap module - return GetPreferredZapModuleForTypeHandle(pFnPtrTD->GetRetAndArgTypesPointer()[0]); -} - -/*static*/ -PTR_Module Module::GetPreferredZapModuleForTypeHandle(TypeHandle t) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - SUPPORTS_DAC; - if (t.IsTypeDesc()) - return GetPreferredZapModuleForTypeDesc(t.AsTypeDesc()); - else - return GetPreferredZapModuleForMethodTable(t.AsMethodTable()); -} - -/*static*/ -PTR_Module Module::GetPreferredZapModuleForMethodDesc(const MethodDesc *pMD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if (pMD->IsTypicalMethodDefinition()) - { - return PTR_Module(pMD->GetModule()); - } - else if (pMD->IsGenericMethodDefinition()) - { - return GetPreferredZapModuleForMethodTable(pMD->GetMethodTable()); - } - else - { - return ComputePreferredZapModule(pMD->GetModule(), - pMD->GetClassInstantiation(), - pMD->GetMethodInstantiation()); - } -} - -/* see code:Module::ComputePreferredZapModuleHelper for more */ -/*static*/ -PTR_Module Module::GetPreferredZapModuleForFieldDesc(FieldDesc * pFD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - // The approx MT is sufficient: it's always the one that owns the FieldDesc - // data structure - return GetPreferredZapModuleForMethodTable(pFD->GetApproxEnclosingMethodTable()); -} -#endif // FEATURE_PREJIT - /*static*/ BOOL Module::IsEditAndContinueCapable(Assembly *pAssembly, PEFile *file) { @@ -2690,18 +2243,7 @@ void Module::AllocateStatics(AllocMemTracker *pamTracker) _ASSERTE(m_maxTypeRidStaticsAllocated == 0); return; } -#ifdef FEATURE_PREJIT - if (m_pRegularStaticOffsets == (PTR_DWORD) NGEN_STATICS_ALLCLASSES_WERE_LOADED) - { - _ASSERTE(HasNativeImage()); - // This is an ngen image and all the classes were loaded at ngen time, so we're done. - LOG((LF_CLASSLOADER, LL_INFO10000, "STATICS: 'Complete' Native image found, no statics parsing needed for module %s.\n", GetSimpleName())); - // typeDefs rids 0 and 1 aren't included in the count, thus X typeDefs means rid X+1 is valid - _ASSERTE(m_maxTypeRidStaticsAllocated == GetMDImport()->GetCountWithTokenKind(mdtTypeDef) + 1); - return; - } -#endif LOG((LF_CLASSLOADER, LL_INFO10000, "STATICS: Allocating statics for module %s\n", GetSimpleName())); // Build the offset table, which will tell us what the offsets for the statics of each class are (one offset for gc handles, one offset @@ -3691,11 +3233,6 @@ PTR_CORCOMPILE_IMPORT_SECTION Module::GetImportSections(COUNT_T *pCount) } CONTRACTL_END; -#ifdef FEATURE_PREJIT - if (!IsReadyToRun()) - return GetNativeImage()->GetNativeImportSections(pCount); -#endif - return GetReadyToRunInfo()->GetImportSections(pCount); } @@ -3708,11 +3245,6 @@ PTR_CORCOMPILE_IMPORT_SECTION Module::GetImportSectionFromIndex(COUNT_T index) } CONTRACTL_END; -#ifdef FEATURE_PREJIT - if (!IsReadyToRun()) - return GetNativeImage()->GetNativeImportSectionFromIndex(index); -#endif - return GetReadyToRunInfo()->GetImportSectionFromIndex(index); } @@ -3725,11 +3257,6 @@ PTR_CORCOMPILE_IMPORT_SECTION Module::GetImportSectionForRVA(RVA rva) } CONTRACTL_END; -#ifdef FEATURE_PREJIT - if (!IsReadyToRun()) - return GetNativeImage()->GetNativeImportSectionForRVA(rva); -#endif - return GetReadyToRunInfo()->GetImportSectionForRVA(rva); } @@ -3749,13 +3276,6 @@ PTR_VOID Module::GetRvaField(DWORD rva, BOOL fZapped) WRAPPER_NO_CONTRACT; SUPPORTS_DAC; -#ifdef FEATURE_PREJIT - if (fZapped && m_file->IsILOnly()) - { - return dac_cast(m_file->GetLoadedNative()->GetRvaData(rva,NULL_OK)); - } -#endif // FEATURE_PREJIT - return m_file->GetRvaField(rva); } @@ -3841,28 +3361,6 @@ BOOL Module::IsSigInIL(PCCOR_SIGNATURE signature) return m_file->IsPtrInILImage(signature); } -#ifdef FEATURE_PREJIT -StubMethodHashTable *Module::GetStubMethodHashTable() -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } - CONTRACTL_END - - if (m_pStubMethodHashTable == NULL && SystemDomain::GetCurrentDomain()->IsCompilationDomain()) - { - // we only need to create the hash table when NGENing, it is read-only at run-time - AllocMemTracker amTracker; - m_pStubMethodHashTable = StubMethodHashTable::Create(GetLoaderAllocator(), this, METHOD_STUBS_HASH_BUCKETS, &amTracker); - amTracker.SuppressRelease(); - } - - return m_pStubMethodHashTable; -} -#endif // FEATURE_PREJIT - void Module::InitializeStringData(DWORD token, EEStringData *pstrData, CQuickBytes *pqb) { CONTRACTL @@ -3909,71 +3407,6 @@ void Module::InitializeStringData(DWORD token, EEStringData *pstrData, CQuickByt #ifndef CROSSGEN_COMPILE -#ifdef FEATURE_PREJIT -OBJECTHANDLE Module::ResolveStringRefHelper(DWORD token, BaseDomain *pDomain, PTR_CORCOMPILE_IMPORT_SECTION pSection, EEStringData *pStrData) -{ - PEImageLayout *pNativeImage = GetNativeImage(); - - // Get the table - COUNT_T tableSize; - TADDR tableBase = pNativeImage->GetDirectoryData(&pSection->Section, &tableSize); - - // Walk the handle table. - // @TODO: If we ever care about the perf of this function, we could sort the tokens - // using as a key the string they point to, so we could do a binary search - for (SIZE_T * pEntry = (SIZE_T *)tableBase ; pEntry < (SIZE_T *)(tableBase + tableSize); pEntry++) - { - // Ensure that the compiler won't fetch the value twice - SIZE_T entry = VolatileLoadWithoutBarrier(pEntry); - - if (CORCOMPILE_IS_POINTER_TAGGED(entry)) - { - BYTE * pBlob = (BYTE *) pNativeImage->GetRvaData(CORCOMPILE_UNTAG_TOKEN(entry)); - - // Note that we only care about strings from current module, and so we do not check ENCODE_MODULE_OVERRIDE - if (*pBlob++ == ENCODE_STRING_HANDLE && - TokenFromRid(CorSigUncompressData((PCCOR_SIGNATURE&) pBlob), mdtString) == token) - { - // This string hasn't been fixed up. Synchronize the update with the normal - // fixup logic - { - CrstHolder ch(this->GetFixupCrst()); - - if (!CORCOMPILE_IS_POINTER_TAGGED(*pEntry)) - { - // We lost the race, just return current entry - } - else - { - *pEntry = (SIZE_T) ResolveStringRef(token, pDomain, false); - } - } - - return (OBJECTHANDLE) *pEntry; - } - } - else - { - OBJECTREF* pRef = (OBJECTREF*) entry; - _ASSERTE((*pRef)->GetMethodTable() == g_pStringClass); - - STRINGREF stringRef = (STRINGREF) *pRef; - - // Is this the string we are trying to resolve? - if (pStrData->GetCharCount() == stringRef->GetStringLength() && - memcmp((void*)pStrData->GetStringBuffer(), - (void*) stringRef->GetBuffer(), - pStrData->GetCharCount()*sizeof(WCHAR)) == 0) - { - // We found it, so we just have to return this instance - return (OBJECTHANDLE) entry; - } - } - } - return NULL; -} -#endif // FEATURE_PREJIT - OBJECTHANDLE Module::ResolveStringRef(DWORD token, BaseDomain *pDomain, bool bNeedToSyncWithFixups) { CONTRACTL @@ -4002,92 +3435,6 @@ OBJECTHANDLE Module::ResolveStringRef(DWORD token, BaseDomain *pDomain, bool bNe // We can only do this for native images as they guarantee that resolvestringref will be // called only once per string from this module. @TODO: We really dont have any way of asserting // this, which would be nice... (and is needed to guarantee correctness) -#ifdef FEATURE_PREJIT - if (HasNativeImage() && IsNoStringInterning()) - { - if (bNeedToSyncWithFixups) - { - // In an ngen image, it is possible that we get here but not be coming from a fixup, - // (FixupNativeEntry case). In that unfortunate case (ngen partial images, dynamic methods, - // lazy string inits) we will have to troll through the fixup list, and in the case the string is there, - // reuse it, if it's there but hasn't been fixed up, fix it up now, and in the case it isn't - // there at all, then go to our old style string interning. Going through this code path is - // guaranteed to be slow. If necessary, we can further optimize it by sorting the token table, - // Another way of solving this would be having a token to string table (would require knowing - // all our posible stings in the ngen case (this is possible by looking at the IL)) - - PEImageLayout * pNativeImage = GetNativeImage(); - - COUNT_T nSections; - PTR_CORCOMPILE_IMPORT_SECTION pSections = pNativeImage->GetNativeImportSections(&nSections); - - for (COUNT_T iSection = 0; iSection < nSections; iSection++) - { - PTR_CORCOMPILE_IMPORT_SECTION pSection = pSections + iSection; - - if (pSection->Type != CORCOMPILE_IMPORT_TYPE_STRING_HANDLE) - continue; - - OBJECTHANDLE oh = ResolveStringRefHelper(token, pDomain, pSection, &strData); - if (oh != NULL) - return oh; - } - - // The string is not in our fixup list, so just intern it old style (using hashtable) - goto INTERN_OLD_STYLE; - - } - /* Unfortunately, this assert won't work in some cases of generics, consider the following scenario: - - 1) Generic type in CoreLib. - 2) Instantiation of generic (1) (via valuetype) in another module - 3) other module now holds a copy of the code of the generic for that particular instantiation - however, it is resolving the string literals against CoreLib, which breaks the invariant - this assert was based on (no string fixups against other modules). In fact, with NoStringInterning, - our behavior is not very intuitive. - */ - /* - _ASSERTE(pDomain == GetAssembly()->GetDomain() && "If your are doing ldstr for a string" - "in another module, either the JIT is very smart or you have a bug, check INLINE_NO_CALLEE_LDSTR"); - - */ - /* - Dev10 804385 bugfix - - We should be using appdomain that the string token lives in (GetAssembly->GetDomain()) - to allocate the System.String object instead of the appdomain that first uses the ldstr (pDomain). - - Otherwise, it is possible to get into the situation that pDomain is unloaded but GetAssembly->GetDomain() is - still kicking around. Anything else that is still using that string will now be pointing to an object - that will be freed when the next GC happens. - */ - pDomain = GetAssembly()->GetDomain(); - - // The caller is going to update an ngen fixup entry. The fixup entry - // is used to reference the string and to ensure that the string is - // allocated only once. Hence, this operation needs to be done under a lock. - _ASSERTE(GetFixupCrst()->OwnedByCurrentThread()); - - // Allocate handle - OBJECTREF* pRef = pDomain->AllocateObjRefPtrsInLargeTable(1); - - STRINGREF str = AllocateStringObject(&strData); - SetObjectReference(pRef, str); - - #ifdef LOGGING - int length = strData.GetCharCount(); - length = min(length, 100); - WCHAR *szString = (WCHAR *)_alloca((length + 1) * sizeof(WCHAR)); - memcpyNoGCRefs((void*)szString, (void*)strData.GetStringBuffer(), length * sizeof(WCHAR)); - szString[length] = '\0'; - LOG((LF_APPDOMAIN, LL_INFO10000, "String literal \"%S\" won't be interned due to NoInterningAttribute\n", szString)); - #endif // LOGGING - - return (OBJECTHANDLE) pRef; - } - - -INTERN_OLD_STYLE: -#endif // Retrieve the string from the either the appropriate LoaderAllocator LoaderAllocator *pLoaderAllocator; @@ -4147,112 +3494,26 @@ BYTE *Module::GetProfilerBase() { RETURN NULL; } -} - -void Module::AddActiveDependency(Module *pModule, BOOL unconditional) -{ - CONTRACT_VOID - { - THROWS; - GC_TRIGGERS; - PRECONDITION(CheckPointer(pModule)); - PRECONDITION(pModule != this); - PRECONDITION(!IsSystem()); - // Postcondition about activation - } - CONTRACT_END; - - pModule->EnsureActive(); - RETURN; -} - -#endif //!DACCESS_COMPILE - -#if !defined(DACCESS_COMPILE) && defined(FEATURE_PREJIT) -// This function, given an AssemblyRef into the ngen generated native metadata section, will find the assembly referenced if -// 1. The Assembly is defined with a different name than the AssemblyRef provides -// 2. The Assembly has reached the stage of being loaded. -// This function is used as a helper function to assist GetAssemblyIfLoaded with its tasks in the conditions -// where GetAssemblyIfLoaded must succeed (or we violate various invariants in the system required for -// correct implementation of GC, Stackwalking, and generic type loading. -Assembly * Module::GetAssemblyIfLoadedFromNativeAssemblyRefWithRefDefMismatch(mdAssemblyRef kAssemblyRef, BOOL *pfDiscoveredAssemblyRefMatchesTargetDefExactly) -{ - CONTRACT(Assembly *) - { - INSTANCE_CHECK; - NOTHROW; - GC_NOTRIGGER; - FORBID_FAULT; - MODE_ANY; - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - } - CONTRACT_END; - - _ASSERTE(HasNativeImage()); - - Assembly *pAssembly = NULL; - IMDInternalImport *pImportFoundNativeImage = this->GetNativeAssemblyImport(FALSE); - - if (!pImportFoundNativeImage) - { - RETURN NULL; - } +} - if (kAssemblyRef != mdAssemblyRefNil) +void Module::AddActiveDependency(Module *pModule, BOOL unconditional) +{ + CONTRACT_VOID { - // Scan CORCOMPILE_DEPENDENCIES tables - PEImageLayout* pNativeLayout = this->GetNativeImage(); - COUNT_T dependencyCount; - CORCOMPILE_DEPENDENCY *pDependencies = pNativeLayout->GetNativeDependencies(&dependencyCount); - - // Find the assemblyDef that defines the exact target - mdAssemblyRef foundAssemblyDef = mdAssemblyRefNil; - - for (COUNT_T i = 0; i < dependencyCount; ++i) - { - CORCOMPILE_DEPENDENCY* pDependency = &(pDependencies[i]); - if (pDependency->dwAssemblyRef == kAssemblyRef) - { - foundAssemblyDef = pDependency->dwAssemblyDef; - break; - } - } - - // In this case we know there is no assembly redirection involved. Skip any additional work. - if (kAssemblyRef == foundAssemblyDef) - { - *pfDiscoveredAssemblyRefMatchesTargetDefExactly = true; - RETURN NULL; - } - - if (foundAssemblyDef != mdAssemblyRefNil) - { - // Find out if THIS reference is satisfied - // Specify fDoNotUtilizeExtraChecks to prevent recursion - Assembly *pAssemblyCandidate = this->GetAssemblyIfLoaded(foundAssemblyDef, pImportFoundNativeImage, TRUE /*fDoNotUtilizeExtraChecks*/); - - // This extended check is designed only to find assemblies loaded via an AssemblySpecBindingCache based binder. Verify that's what we found. - if(pAssemblyCandidate != NULL) - { - if (!pAssemblyCandidate->GetManifestFile()->HasHostAssembly()) - { - pAssembly = pAssemblyCandidate; - } - else - { - // This should only happen in the generic instantiation case when multiple threads are racing and - // the assembly found is one which we will determine is the wrong assembly. - // - // We can't assert that (as its possible under stress); however it shouldn't happen in the stack walk or GC case, so we assert in those cases. - _ASSERTE("Non-AssemblySpecBindingCache based assembly found with extended search" && !(IsStackWalkerThread() || IsGCThread()) && IsGenericInstantiationLookupCompareThread()); - } - } - } + THROWS; + GC_TRIGGERS; + PRECONDITION(CheckPointer(pModule)); + PRECONDITION(pModule != this); + PRECONDITION(!IsSystem()); + // Postcondition about activation } + CONTRACT_END; - RETURN pAssembly; + pModule->EnsureActive(); + RETURN; } -#endif // !defined(DACCESS_COMPILE) && defined(FEATURE_PREJIT) + +#endif //!DACCESS_COMPILE Assembly * Module::GetAssemblyIfLoaded( @@ -4281,10 +3542,6 @@ Module::GetAssemblyIfLoaded( fCanUseRidMap = fCanUseRidMap && (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GetAssemblyIfLoadedIgnoreRidMap) == 0); #endif - // If we're here due to a generic instantiation, then we should only be querying information from the ngen image we're finding the generic instantiation in. -#if !defined(DACCESS_COMPILE) && defined(FEATURE_PREJIT) - _ASSERTE(!IsGenericInstantiationLookupCompareThread() || HasNativeImage()); -#endif // Don't do a lookup if an override IMDInternalImport is provided, since the lookup is for the // standard IMDInternalImport and might result in an incorrect result. @@ -4366,134 +3623,6 @@ Module::GetAssemblyIfLoaded( } while (false); } -#if !defined(DACCESS_COMPILE) && defined(FEATURE_PREJIT) - if (pAssembly == NULL && (IsStackWalkerThread() || IsGCThread() || IsGenericInstantiationLookupCompareThread()) && !fDoNotUtilizeExtraChecks) - { - // The GetAssemblyIfLoaded function must succeed in finding assemblies which have already been loaded in a series of interesting cases - // (GC, Stackwalking, GenericInstantiationLookup). This logic is used to handle cases where the normal lookup done above - // may fail, and more extensive (and slow) lookups are necessary. This logic is gated by a long series of checks to ensure it doesn't - // run in cases which are not known to be problematic, or would not benefit from the logic here. - // - // This is logic which tries extra possibilities to find an assembly. It is believed this logic can only be hit in cases where an ngen - // image depends on an assembly through some sort of binding version/public key token adjustment (due to binding policy, unification, or portability rules) - // and the assembly depended on was loaded through a binder that utilizes the AssemblySpecBindingCache for binder caching. (The cache's in the other - // binder's successfully answer the GetAssemblyIfLoaded question in the case of non-exact matches where the match was discovered during - // ngen resolution.) - // This restricts the scenario to a somewhat restricted case. - - BOOL eligibleForAdditionalChecks = TRUE; - - AssemblySpec specSearchAssemblyRef; - - // Get the assembly ref information that we are attempting to satisfy. - if (eligibleForAdditionalChecks) - { - IMDInternalImport * pMDImport = (pMDImportOverride == NULL) ? (GetMDImport()) : (pMDImportOverride); - - if (FAILED(specSearchAssemblyRef.InitializeSpecInternal(kAssemblyRef, - pMDImport, - NULL, - FALSE /*fAllowAllocation*/))) - { - eligibleForAdditionalChecks = FALSE; // If an assemblySpec can't be constructed then we're not going to succeed - // This should not ever happen, due to the above checks, but this logic - // is intended to be defensive against unexpected behavior. - } - } - - if (eligibleForAdditionalChecks) - { - BOOL abortAdditionalChecks = false; - - // When working with an ngenn'd assembly, as an optimization we can scan only that module for dependency info. - bool onlyScanCurrentModule = HasNativeImage() && GetFile()->IsAssembly(); - mdAssemblyRef foundAssemblyRef = mdAssemblyRefNil; - - // In each AppDomain that might be interesting, scan for an ngen image that is loaded that has a dependency on the same - // assembly that is now being looked up. If that ngen image has the same dependency, then we can use the CORCOMPILE_DEPENDENCIES - // table to find the exact AssemblyDef that defines the assembly, and attempt a load based on that information. - // As this logic is expected to be used only in exceedingly rare situations, this code has not been tuned for performance - // in any way. - do - { - AppDomain * pAppDomainExamine = ::GetAppDomain(); // There is only 1 AppDomain on CoreCLR - - DomainAssembly * pCurAssemblyInExamineDomain = GetAssembly()->GetDomainAssembly(); - if (pCurAssemblyInExamineDomain == NULL) - { - continue; - } - - DomainFile *pDomainFileNativeImage; - - if (onlyScanCurrentModule) - { - pDomainFileNativeImage = pCurAssemblyInExamineDomain; - // Do not reset foundAssemblyRef. - // This will allow us to avoid scanning for foundAssemblyRef in each domain we iterate through - } - else - { - foundAssemblyRef = mdAssemblyRefNil; - pDomainFileNativeImage = pAppDomainExamine->GetDomainFilesWithNativeImagesList(); - } - - while (!abortAdditionalChecks && (pDomainFileNativeImage != NULL) && (pAssembly == NULL)) - { - Module *pNativeImageModule = pDomainFileNativeImage->GetCurrentModule(); - _ASSERTE(pNativeImageModule->HasNativeImage()); - IMDInternalImport *pImportFoundNativeImage = pNativeImageModule->GetNativeAssemblyImport(FALSE); - if (pImportFoundNativeImage != NULL) - { - if (IsNilToken(foundAssemblyRef)) - { - // Enumerate assembly refs in nmd space, and compare against held ref. - HENUMInternalHolder hAssemblyRefEnum(pImportFoundNativeImage); - if (FAILED(hAssemblyRefEnum.EnumInitNoThrow(mdtAssemblyRef, mdAssemblyRefNil))) - { - continue; - } - - mdAssemblyRef assemblyRef = mdAssemblyRefNil; - - // Find if the native image has a matching assembly ref in its compile dependencies. - while (pImportFoundNativeImage->EnumNext(&hAssemblyRefEnum, &assemblyRef) && (pAssembly == NULL)) - { - AssemblySpec specFoundAssemblyRef; - if (FAILED(specFoundAssemblyRef.InitializeSpecInternal(assemblyRef, - pImportFoundNativeImage, - NULL, - FALSE /*fAllowAllocation*/))) - { - continue; // If the spec cannot be loaded, it isn't the one we're looking for - } - - // Check for AssemblyRef equality - if (specSearchAssemblyRef.CompareEx(&specFoundAssemblyRef)) - { - foundAssemblyRef = assemblyRef; - break; - } - } - } - - pAssembly = pNativeImageModule->GetAssemblyIfLoadedFromNativeAssemblyRefWithRefDefMismatch(foundAssemblyRef, &abortAdditionalChecks); - - if (fCanUseRidMap && pAssembly) - StoreAssemblyRef(kAssemblyRef, pAssembly); - } - - // If we're only scanning one module for accurate dependency information, break the loop here. - if (onlyScanCurrentModule) - break; - - pDomainFileNativeImage = pDomainFileNativeImage->FindNextDomainFileWithNativeImage(); - } - } while (false); - } - } -#endif // !defined(DACCESS_COMPILE) && defined(FEATURE_PREJIT) - // When walking the stack or computing GC information this function should never fail. _ASSERTE((pAssembly != NULL) || !(IsStackWalkerThread() || IsGCThread())); @@ -4904,27 +4033,6 @@ PTR_TADDR LookupMapBase::GetElementPtr(DWORD rid) LookupMapBase * pMap = this; -#ifdef FEATURE_PREJIT - if (pMap->dwNumHotItems > 0) - { -#ifdef _DEBUG_IMPL - static DWORD counter = 0; - counter++; - if (counter >= pMap->dwNumHotItems) - { - CheckConsistentHotItemList(); - counter = 0; - } -#endif // _DEBUG_IMPL - - PTR_TADDR pHotItemValue = pMap->FindHotItemValuePtr(rid); - if (pHotItemValue) - { - return pHotItemValue; - } - } -#endif // FEATURE_PREJIT - DWORD dwIndex = rid; do { @@ -4941,186 +4049,6 @@ PTR_TADDR LookupMapBase::GetElementPtr(DWORD rid) } -#ifdef FEATURE_PREJIT - -// This method can only be called on a compressed map (MapIsCompressed() == true). Compressed rid maps store -// the array of values as packed deltas (each value is based on the accumulated of all the previous entries). -// So this method takes the bit stream of compressed data we're navigating and the value of the last entry -// retrieved allowing us to calculate the full value of the next entry. Note that the values passed in and out -// here aren't the final values the top-level caller sees. In order to avoid having to touch the compressed -// data on image base relocations we actually store a form of RVA (though relative to the map base rather than -// the module base). -INT32 LookupMapBase::GetNextCompressedEntry(BitStreamReader *pTableStream, INT32 iLastValue) -{ - CONTRACTL - { - INSTANCE_CHECK; - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - PRECONDITION(MapIsCompressed()); - } - CONTRACTL_END; - - // The next kLookupMapLengthBits bits in the stream are an index into a per-map table that tells us the - // length of the encoded delta. - DWORD dwValueLength = rgEncodingLengths[pTableStream->Read(kLookupMapLengthBits)]; - - // Then follows a single bit that indicates whether the delta should be added (1) or subtracted (0) from - // the previous entry value to recover the current entry value. - // Once we've read that bit we read the delta (encoded as an unsigned integer using the number of bits - // that we read from the encoding lengths table above). - if (pTableStream->ReadOneFast()) - return iLastValue + (INT32)(pTableStream->Read(dwValueLength)); - else - return iLastValue - (INT32)(pTableStream->Read(dwValueLength)); -} - -// This method can only be called on a compressed map (MapIsCompressed() == true). Retrieves the final value -// (e.g. MethodTable*, MethodDesc* etc. based on map type) given the rid of the entry. -TADDR LookupMapBase::GetValueFromCompressedMap(DWORD rid) -{ - CONTRACTL - { - INSTANCE_CHECK; - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - PRECONDITION(MapIsCompressed()); - } - CONTRACTL_END; - - // Normally to extract the nth entry in the table we have to linearly parse all (n - 1) preceding entries - // (since entries are stored as the delta from the previous entry). Obviously this can yield exceptionally - // poor performance for the later entries in large tables. So we also build an index of the compressed - // stream. This index has an entry for every kLookupMapIndexStride entries in the compressed table. Each - // index entry contains the full RVA (relative to the map) of the corresponding table entry plus the bit - // offset in the stream from which to start parsing the next entry's data. - // In this fashion we can get to within kLookupMapIndexStride entries of our target entry and then decode - // our way to the final target. - - // Ensure that index does not go beyond end of the saved table - if (rid >= dwCount) - return 0; - - // Calculate the nearest entry in the index that is lower than our target index in the full table. - DWORD dwIndexEntry = rid / kLookupMapIndexStride; - - // Then calculate how many additional entries we'll need to decode from the compressed streams to recover - // the target entry. - DWORD dwSubIndex = rid % kLookupMapIndexStride; - - // Open a bit stream reader on the index and skip all the entries prior to the one we're interested in. - BitStreamReader sIndexStream(pIndex); - sIndexStream.Skip(dwIndexEntry * cIndexEntryBits); - - // The first kBitsPerRVA of the index entry contain the RVA of the corresponding entry in the compressed - // table. If this is exactly the entry we want (dwSubIndex == 0) then we can use this RVA to recover the - // value the caller wants. Our RVAs are based on the map address rather than the module base (simply - // because we don't record the module base in LookupMapBase). A delta of zero encodes a null value, - // otherwise we simply add the RVA to the our map address to recover the full pointer. - // Note that most LookupMaps are embedded structures (in Module) so we can't directly dac_cast our - // "this" pointer for DAC builds. Instead we have to use the slightly slower (in DAC) but more flexible - // PTR_HOST_INT_TO_TADDR() which copes with interior host pointers. - INT32 iValue = (INT32)sIndexStream.Read(kBitsPerRVA); - if (dwSubIndex == 0) - return iValue ? PTR_HOST_INT_TO_TADDR(this) + iValue : 0; - - // Otherwise we must parse one or more entries in the compressed table to accumulate more deltas to the - // base RVA we read above. The remaining portion of the index entry has the bit offset into the compressed - // table at which to begin parsing. - BitStreamReader sTableStream(dac_cast(pTable)); - sTableStream.Skip(sIndexStream.Read(cIndexEntryBits - kBitsPerRVA)); - - // Parse all the entries up to our target entry. Each step takes the RVA from the previous cycle (or from - // the index entry we read above) and applies the compressed delta of the next table entry to it. - for (DWORD i = 0; i < dwSubIndex; i++) - iValue = GetNextCompressedEntry(&sTableStream, iValue); - - // We have the final RVA so recover the actual pointer from it (a zero RVA encodes a NULL pointer). Note - // the use of PTR_HOST_INT_TO_TADDR() rather than dac_cast, see previous comment on - // PTR_HOST_INT_TO_TADDR for an explanation. - return iValue ? PTR_HOST_INT_TO_TADDR(this) + iValue : 0; -} - -PTR_TADDR LookupMapBase::FindHotItemValuePtr(DWORD rid) -{ - LIMITED_METHOD_DAC_CONTRACT; - - if (dwNumHotItems < 5) - { - // do simple linear search if there are only a few hot items - for (DWORD i = 0; i < dwNumHotItems; i++) - { - if (hotItemList[i].rid == rid) - return dac_cast( - dac_cast(hotItemList) + i * sizeof(HotItem) + offsetof(HotItem, value)); - } - } - else - { - // otherwise do binary search - if (hotItemList[0].rid <= rid && rid <= hotItemList[dwNumHotItems-1].rid) - { - DWORD l = 0; - DWORD r = dwNumHotItems; - while (l + 1 < r) - { - // loop invariant: - _ASSERTE(hotItemList[l].rid <= rid && (r >= dwNumHotItems || rid < hotItemList[r].rid)); - - DWORD m = (l + r)/2; - // loop condition implies l < m < r, hence interval shrinks every iteration, hence loop terminates - _ASSERTE(l < m && m < r); - if (rid < hotItemList[m].rid) - r = m; - else - l = m; - } - // now we know l + 1 == r && hotItemList[l].rid <= rid < hotItemList[r].rid - // loop invariant: - _ASSERTE(hotItemList[l].rid <= rid && (r >= dwNumHotItems || rid < hotItemList[r].rid)); - if (hotItemList[l].rid == rid) - return dac_cast( - dac_cast(hotItemList) + l * sizeof(HotItem) + offsetof(HotItem, value)); - } - } - return NULL; -} - -#ifdef _DEBUG -void LookupMapBase::CheckConsistentHotItemList() -{ - LIMITED_METHOD_DAC_CONTRACT; - - for (DWORD i = 0; i < dwNumHotItems; i++) - { - DWORD rid = hotItemList[i].rid; - - PTR_TADDR pHotValue = dac_cast( - dac_cast(hotItemList) + i * sizeof(HotItem) + offsetof(HotItem, value)); - TADDR hotValue = RelativePointer::GetValueMaybeNullAtPtr(dac_cast(pHotValue)); - - TADDR value; - if (MapIsCompressed()) - { - value = GetValueFromCompressedMap(rid); - } - else - { - PTR_TADDR pValue = GetIndexPtr(rid); - value = RelativePointer::GetValueMaybeNullAtPtr(dac_cast(pValue)); - } - - _ASSERTE(hotValue == value || value == NULL); - } -} -#endif // _DEBUG - -#endif // FEATURE_PREJIT - // Get number of RIDs that this table can store DWORD LookupMapBase::GetSize() { @@ -5164,14 +4092,6 @@ void LookupMapBase::DebugGetRidMapOccupancy(DWORD *pdwOccupied, DWORD *pdwSize) for (DWORD i = 0; i < dwIterCount; i++) { -#ifdef FEATURE_PREJIT - if (pMap->MapIsCompressed()) - { - if (pMap->GetValueFromCompressedMap(i)) - (*pdwOccupied)++; - } - else -#endif // FEATURE_PREJIT if (pMap->pTable[i] != NULL) (*pdwOccupied)++; } @@ -5761,13 +4681,6 @@ void Module::FixupVTables() return; } -#ifdef FEATURE_PREJIT - // We delayed filling in this value until the LoadLibrary occurred - if (HasTls() && HasNativeImage()) { - CORCOMPILE_EE_INFO_TABLE *pEEInfo = GetNativeImage()->GetNativeEEInfoTable(); - pEEInfo->rvaStaticTlsIndex = GetTlsIndex(); - } -#endif // Get vtable fixup data COUNT_T cFixupRecords; IMAGE_COR_VTABLEFIXUP *pFixupTable = m_file->GetVTableFixups(&cFixupRecords); @@ -6126,14 +5039,6 @@ IMDInternalImport* Module::GetNativeAssemblyImport(BOOL loadAllowed) } CONTRACT_END; -#ifdef FEATURE_PREJIT - // Check if image is R2R - if (!GetFile()->IsILImageReadyToRun()) - { - RETURN GetFile()->GetPersistentNativeImage()->GetNativeMDImport(loadAllowed); - } -#endif - RETURN GetFile()->GetOpenedILimage()->GetNativeMDImport(loadAllowed); } @@ -6284,143 +5189,6 @@ void Module::RunEagerFixupsUnlocked() } #endif // !DACCESS_COMPILE -#ifdef FEATURE_PREJIT - -#ifndef DACCESS_COMPILE -void Module::LoadTokenTables() -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(HasNativeImage()); - } - CONTRACTL_END; - -#ifndef CROSSGEN_COMPILE - if (NingenEnabled()) - return; - - CORCOMPILE_EE_INFO_TABLE *pEEInfo = GetNativeImage()->GetNativeEEInfoTable(); - PREFIX_ASSUME(pEEInfo != NULL); - - pEEInfo->inlinedCallFrameVptr = InlinedCallFrame::GetMethodFrameVPtr(); - pEEInfo->addrOfCaptureThreadGlobal = (LONG *)&g_TrapReturningThreads; - - //CoreClr doesn't always have the debugger loaded - //patch up the ngen image to point to this address so that the JIT bypasses JMC if there is no debugger - static DWORD g_dummyJMCFlag = 0; - pEEInfo->addrOfJMCFlag = g_pDebugInterface ? g_pDebugInterface->GetJMCFlagAddr(this) : &g_dummyJMCFlag; - - pEEInfo->gsCookie = GetProcessGSCookie(); - - if (!IsSystem()) - { - pEEInfo->emptyString = (CORINFO_Object **)StringObject::GetEmptyStringRefPtr(); - } - - pEEInfo->threadTlsIndex = TLS_OUT_OF_INDEXES; - pEEInfo->rvaStaticTlsIndex = NULL; -#endif // CROSSGEN_COMPILE -} - -#endif // !DACCESS_COMPILE - -// Returns the RVA to the compressed debug information blob for the given method - -CORCOMPILE_DEBUG_ENTRY Module::GetMethodDebugInfoOffset(MethodDesc *pMD) -{ - CONTRACT(CORCOMPILE_DEBUG_ENTRY) - { - INSTANCE_CHECK; - PRECONDITION(HasNativeImage()); - PRECONDITION(CheckPointer(pMD) && pMD->IsPreImplemented()); - POSTCONDITION(GetNativeImage()->CheckRva(RETVAL, NULL_OK)); - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACT_END; - - if (!GetNativeImage()->HasNativeDebugMap() || pMD->IsRuntimeSupplied()) - RETURN 0; - - COUNT_T size; - PTR_CORCOMPILE_DEBUG_RID_ENTRY ridTable = - dac_cast(GetNativeImage()->GetNativeDebugMap(&size)); - - COUNT_T count = size / sizeof(CORCOMPILE_DEBUG_RID_ENTRY); - // The size should be odd for better hashing - _ASSERTE((count & 1) != 0); - - CORCOMPILE_DEBUG_RID_ENTRY ridEntry = ridTable[GetDebugRidEntryHash(pMD->GetMemberDef()) % count]; - - // Do we have multiple code corresponding to the same RID - if (!IsMultipleLabelledEntries(ridEntry)) - { - RETURN(ridEntry); - } - - PTR_CORCOMPILE_DEBUG_LABELLED_ENTRY pLabelledEntry = - PTR_CORCOMPILE_DEBUG_LABELLED_ENTRY - (GetNativeImage()->GetRvaData(ridEntry & - ~CORCOMPILE_DEBUG_MULTIPLE_ENTRIES)); - - DWORD codeRVA = GetNativeImage()-> - GetDataRva((const TADDR)pMD->GetNativeCode()); -#if defined(TARGET_ARM) - // Since the Thumb Bit is set on ARM, the RVA calculated above will have it set as well - // and will result in the failure of checks in the loop below. Hence, mask off the - // bit before proceeding ahead. - codeRVA = ThumbCodeToDataPointer(codeRVA); -#endif // TARGET_ARM - - for (;;) - { - if (pLabelledEntry->nativeCodeRVA == codeRVA) - { - RETURN (pLabelledEntry->debugInfoOffset & ~CORCOMPILE_DEBUG_MULTIPLE_ENTRIES); - } - - if (!IsMultipleLabelledEntries(pLabelledEntry->debugInfoOffset)) - { - break; - } - - pLabelledEntry++; - } - - _ASSERTE(!"Debug info not found - corrupted ngen image?"); - RETURN (0); -} - -PTR_BYTE Module::GetNativeDebugInfo(MethodDesc * pMD) -{ - CONTRACTL - { - INSTANCE_CHECK; - PRECONDITION(HasNativeImage()); - PRECONDITION(CheckPointer(pMD)); - PRECONDITION(pMD->GetZapModule() == this); - THROWS; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - CORCOMPILE_DEBUG_ENTRY debugInfoOffset = GetMethodDebugInfoOffset(pMD); - - if (debugInfoOffset == 0) - return NULL; - - return dac_cast(GetNativeImage()->GetRvaData(debugInfoOffset)); -} -#endif //FEATURE_PREJIT - #ifndef DACCESS_COMPILE //----------------------------------------------------------------------------- @@ -8500,10 +7268,6 @@ idTypeSpec Module::LogInstantiatedType(TypeHandle typeHnd, ULONG flagNum) // MethodTable can only live in its own loader module. // We can relax this if we allow a (duplicate) MethodTable to live // in any module (which might be needed for ngen of generics) -#ifdef FEATURE_PREJIT - // All callsites already do this... - // PRECONDITION(this == GetPreferredZapModuleForTypeHandle(typeHnd)); -#endif } CONTRACT_END; @@ -9058,28 +7822,9 @@ LookupMapBase::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, } if (pTable.IsValid()) { -#ifdef FEATURE_PREJIT - if (MapIsCompressed()) - { - // Compressed maps have tables whose size cannot be calculated cheaply. Plus they have an - // additional index blob. - DacEnumMemoryRegion(dac_cast(pTable), - cbTable); - DacEnumMemoryRegion(dac_cast(pIndex), - cbIndex); - } - else -#endif // FEATURE_PREJIT - DacEnumMemoryRegion(dac_cast(pTable), - dwCount * sizeof(TADDR)); - } -#ifdef FEATURE_PREJIT - if (dwNumHotItems && hotItemList.IsValid()) - { - DacEnumMemoryRegion(dac_cast(hotItemList), - dwNumHotItems * sizeof(HotItem)); + DacEnumMemoryRegion(dac_cast(pTable), + dwCount * sizeof(TADDR)); } -#endif // FEATURE_PREJIT } @@ -9254,19 +7999,10 @@ void Module::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, { m_pAvailableClassesCaseIns->EnumMemoryRegions(flags); } -#ifdef FEATURE_PREJIT - if (m_pStubMethodHashTable.IsValid()) - { - m_pStubMethodHashTable->EnumMemoryRegions(flags); - } -#endif // FEATURE_PREJIT if (m_pBinder.IsValid()) { m_pBinder->EnumMemoryRegions(flags); } -#ifdef FEATURE_PREJIT - m_ModuleCtorInfo.EnumMemoryRegions(flags); -#endif // Save the LookupMap structures. m_MethodDefToDescMap.ListEnumMemoryRegions(flags); diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index 92547019c5721c..57aa16607f6103 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -71,14 +71,6 @@ class CodeVersionManager; class TieredCompilationManager; class ProfileEmitter; class JITInlineTrackingMap; -#ifdef FEATURE_PREJIT -class TypeHandleList; -class TrackingMap; -struct MethodInModule; -class PersistentInlineTrackingMapNGen; - -extern VerboseLevel g_CorCompileVerboseLevel; -#endif // Hash table parameter of available classes (name -> module/class) hash #define AVAILABLE_CLASSES_HASH_BUCKETS 1024 @@ -113,99 +105,6 @@ typedef DPTR(JITInlineTrackingMap) PTR_JITInlineTrackingMap; typedef DPTR(struct LookupMapBase) PTR_LookupMapBase; -#ifdef FEATURE_PREJIT - -// -// LookupMap cold entry compression support -// -// A lookup map (the cold section) is notionally an array of pointer values indexed by rid. The pointers are -// generally to data structures such as MethodTables or MethodDescs. When we compress such a table (at ngen -// time) we wish to avoid direct pointers, since these would need to be fixed up due to image base -// relocations. Instead we store RVAs (Relative Virtual Addresses). Unlike regular RVAs our base address is -// the map address itself (as opposed to the module base). We do this purely out of convenience since -// LookupMaps don't store the module base address. -// -// It turns out that very often the value pointers (and hence the value RVAs) are related to each other: -// adjacent map entries often point to data structures that were allocated next to or close to each other. The -// compression algorithm takes advantage of this fact: instead of storing value RVAs we store the deltas -// between RVAs. So the nth value in the table is composed of the addition of the deltas from the preceding (n -// - 1) entries. Since the deltas are often small (especially when we take structure alignment into account -// and realize that we can discard the lower 2 or 3 bits of the delta) we can store them in a compressed -// manner by discarding the insignificant leading zero bits in each value. -// -// So now we imagine our compressed table to be a sequence of entries, each entry being a variably sized delta -// from the previous entry. As a result we need some means to encode how large each delta in the table is. We -// could use a fixed size field (a 5-bit length field would be able to encode any length between 1 and 32 -// bits, say). This is troublesome since although most entry values are close in value there are a few -// (usually a minority) that require much larger deltas (hot/cold data splitting based on profiling can cause -// this for instance). For most tables this would force us to use a large fixed-size length field for every -// entry, just to deal with the relatively uncommon worst case (5 bits would be enough, but many entry deltas -// can be encoded in 2 or 3 bits). -// -// Instead we utilize a compromise: we store all delta lengths with a small number of bits -// (kLookupMapLengthBits below). Instead of encoding the length directly this value indexes a per-map table of -// possible delta encoding lengths. During ngen we calculate the optimal value for each entry in this encoding -// length table. The advantage here is that it lets us encode both best case and worst case delta lengths with -// a fixed size but small field. The disadvantage is that some deltas will be encoded with more bits than they -// strictly need. -// -// This still leaves the problem of runtime lookup performance. Touches to the cold section of a LookupMap -// aren't all that critical (after all the data is meant to be cold), but looking up the last entry of a map -// with 22 thousand entries (roughly what the MethodDefToDesc map in CoreLib is sized at at the time of -// writing) is still likely to so inefficient as to be noticeable. Remember that the issue is that we have to -// decode all predecessor entries in order to compute the value of a given entry in the table. -// -// To address this we introduce an index to each compressed map. The index contains an entry for each -// kLookupMapIndexStride'th entry in the compressed map. The index entry consists of the RVA of the -// corresponding table value and the bit offset into the compressed map at which the data for the next entry -// commences. Thus we can use the index to find a value within kLookupMapIndexStride entries of our target and -// then proceed to decode only the last few compressed entries to finish the job. This reduces the lookup to a -// constant time operation once more (given a reasonable value for kLookupMapIndexStride). -// -// The main areas in which this algorithm can be tuned are the number of bits used as an index into the -// encoding lengths table (kLookupMapLengthBits) and the frequency with which entries are bookmarked in the -// index (kLookupMapIndexStride). The current values have been set based on looking at models of CoreLib, -// PresentationCore and PresentationFramework built from the actual ridmap data in their ngen images and -// methodically trying different values in order to maximize compression or balance size versus likely runtime -// performance. An alternative strategy was considered using direct (non-length prefix) encoding of the -// deltas with a couple of variantions on probability-based variable length encoding (completely unbalanced -// tree and completely balanced tree with pessimally encoded worst case escapes). But these were found to -// yield best case results similar to the above but with more complex processing required at ngen (optimal -// results for these algorithms are achieved when you have enough resources to build a probability map of your -// entire data). -// -// Note that not all lookup tables are suitable for compression. In fact we compress only TypeDefToMethodTable -// and MethodDefToDesc tables. For one thing this optimization only brings benefits to larger tables. But more -// importantly we cannot mutate compressed entries (for obvious reasons). Many of the lookup maps are only -// partially populated at ngen time or otherwise might be updated at runtime and thus are not candidates. -// -// In the threshhold timeframe (predicted to be .NET Framework 4.5.3 at the time of writing), we added profiler support -// for adding new types to NGEN images. Historically we could always do this for jitted images, but one of the -// blockers for NGEN were the compressed RID maps. We worked around that by supporting multi-node maps in which -// the first node is compressed, but all future nodes are uncompressed. The NGENed portion will all land in the -// compressed node, while the new profiler added data will land in the uncompressed portion. Note this could -// probably be leveraged for other dynamic scenarios such as a limited form of EnC, but nothing further has -// been implemented at this time. -// - -// Some useful constants used when compressing tables. -enum { - kLookupMapLengthBits = 2, // Bits used to encode an index into a table of possible value lengths - kLookupMapLengthEntries = 1 << kLookupMapLengthBits, // Number of entries in the encoding table above - kLookupMapIndexStride = 0x10, // The range of table entries covered by one index entry (power of two for faster hash lookup) - kBitsPerRVA = sizeof(DWORD) * 8, // Bits in an (uncompressed) table value RVA (RVAs - // currently still 32-bit even on 64-bit platforms) -#ifdef HOST_64BIT - kFlagBits = 3, // Number of bits at the bottom of a value - // pointer that may be used for flags -#else // HOST_64BIT - kFlagBits = 2, -#endif // HOST_64BIT - -}; - -#endif // FEATURE_PREJIT - struct LookupMapBase { DPTR(LookupMapBase) pNext; @@ -227,9 +126,6 @@ struct LookupMapBase PTR_TADDR GetIndexPtr(DWORD index) { LIMITED_METHOD_DAC_CONTRACT; -#ifdef FEATURE_PREJIT - _ASSERTE(!MapIsCompressed()); -#endif // FEATURE_PREJIT _ASSERTE(index < dwCount); return dac_cast(pTable) + index; } @@ -317,10 +213,6 @@ struct LookupMap : LookupMapBase WRAPPER_NO_CONTRACT; _ASSERTE((flag & supportedFlags) == flag); -#ifdef FEATURE_PREJIT - _ASSERTE(!MapIsCompressed()); - _ASSERTE(dwNumHotItems == 0); -#endif // FEATURE_PREJIT PTR_TADDR pElement = GetElementPtr(rid); _ASSERTE(pElement); @@ -427,11 +319,6 @@ struct LookupMap : LookupMapBase LookupMap* m_map; DWORD m_index; -#ifdef FEATURE_PREJIT - // Support for iterating compressed maps. - INT32 m_currentEntry; // RVA of current entry value - BitStreamReader m_tableStream; // Our current context in the compressed bit stream -#endif // FEATURE_PREJIT }; }; @@ -448,59 +335,6 @@ typedef DPTR(class MemberRef) PTR_MemberRef; #define IS_FIELD_MEMBER_REF ((TADDR)0x00000002) -#ifdef FEATURE_PREJIT -// -// NGen image layout information that we need to quickly access at runtime -// -typedef DPTR(struct NGenLayoutInfo) PTR_NGenLayoutInfo; -struct NGenLayoutInfo -{ - // One range for each hot, unprofiled, cold code sections - MemoryRange m_CodeSections[3]; - - // Pointer to the RUNTIME_FUNCTION table for hot, unprofiled, and cold code sections. - PTR_RUNTIME_FUNCTION m_pRuntimeFunctions[3]; - - // Number of RUNTIME_FUNCTIONs for hot, unprofiled, and cold code sections. - DWORD m_nRuntimeFunctions[3]; - - // A parallel arrays of MethodDesc RVAs for hot and unprofiled methods. Both of the array are parallel for m_pRuntimeFunctions - // The first array is for hot methods. The second array is for unprofiled methods. - PTR_DWORD m_MethodDescs[2]; - - // Lookup table to speed up RUNTIME_FUNCTION lookup. - // The first array is for hot methods. The second array is for unprofiled methods. - // Number of elements is m_UnwindInfoLookupTableEntryCount + 1. - // Last element of the lookup table is a sentinal entry that's good to cover the rest of the code section. - // Values are indices into m_pRuntimeFunctions array. - PTR_DWORD m_UnwindInfoLookupTable[2]; - - // Count of lookup entries in m_UnwindInfoLookupTable - DWORD m_UnwindInfoLookupTableEntryCount[2]; - - // Map for matching the cold code with hot code. Index is relative position of RUNTIME_FUNCTION within the section. - PTR_CORCOMPILE_COLD_METHOD_ENTRY m_ColdCodeMap; - - // One range for each hot, cold, write, hot writeable, and cold writeable precode sections - MemoryRange m_Precodes[4]; - - MemoryRange m_JumpStubs; - MemoryRange m_StubLinkStubs; - MemoryRange m_VirtualMethodThunks; - MemoryRange m_ExternalMethodThunks; - MemoryRange m_ExceptionInfoLookupTable; - - PCODE m_pPrestubJumpStub; -#ifdef HAS_FIXUP_PRECODE - PCODE m_pPrecodeFixupJumpStub; -#endif - PCODE m_pVirtualImportFixupJumpStub; - PCODE m_pExternalMethodFixupJumpStub; - DWORD m_rvaFilterPersonalityRoutine; -}; -#endif // FEATURE_PREJIT - - // // VASigCookies are allocated to encapsulate a varargs call signature. // A reference to the cookie is embedded in the code stream. Cookies @@ -619,62 +453,6 @@ struct ModuleCtorInfo return ppMT[i].GetValue(dac_cast(ppMT) + i * sizeof(RelativePointer)); } -#ifdef FEATURE_PREJIT - - void Save(DataImage *image, CorProfileData *profileData); - void Fixup(DataImage *image); - - class ClassCtorInfoEntryArraySort : public CQuickSort - { - private: - DPTR(RelativePointer) m_pBase1; - - public: - //Constructor - ClassCtorInfoEntryArraySort(DWORD *base, DPTR(RelativePointer) base1, int count) - : CQuickSort(base, count) - { - WRAPPER_NO_CONTRACT; - - m_pBase1 = base1; - } - - //Returns -1,0,or 1 if first's nativeStartOffset is less than, equal to, or greater than second's - FORCEINLINE int Compare(DWORD *first, DWORD *second) - { - LIMITED_METHOD_CONTRACT; - - if (*first < *second) - return -1; - else if (*first == *second) - return 0; - else - return 1; - } - -#ifndef DACCESS_COMPILE - // Swap is overwriten so that we can sort both the MethodTable pointer - // array and the ClassCtorInfoEntry array in parrallel. - FORCEINLINE void Swap(SSIZE_T iFirst, SSIZE_T iSecond) - { - LIMITED_METHOD_CONTRACT; - - DWORD sTemp; - PTR_MethodTable sTemp1; - - if (iFirst == iSecond) return; - - sTemp = m_pBase[iFirst]; - m_pBase[iFirst] = m_pBase[iSecond]; - m_pBase[iSecond] = sTemp; - - sTemp1 = m_pBase1[iFirst].GetValueMaybeNull(); - m_pBase1[iFirst].SetValueMaybeNull(m_pBase1[iSecond].GetValueMaybeNull()); - m_pBase1[iSecond].SetValueMaybeNull(sTemp1); - } -#endif // !DACCESS_COMPILE - }; -#endif // FEATURE_PREJIT }; @@ -939,44 +717,6 @@ class ProfilingBlobTraits : public NoRemoveSHashTraits ProfilingBlobTable; typedef DPTR(ProfilingBlobTable) PTR_ProfilingBlobTable; -#ifdef FEATURE_PREJIT -#define METHODTABLE_RESTORE_REASON() \ - RESTORE_REASON_FUNC(CanNotPreRestoreHardBindToParentMethodTable) \ - RESTORE_REASON_FUNC(CanNotPreRestoreHardBindToCanonicalMethodTable) \ - RESTORE_REASON_FUNC(CrossModuleNonCanonicalMethodTable) \ - RESTORE_REASON_FUNC(CanNotHardBindToInstanceMethodTableChain) \ - RESTORE_REASON_FUNC(GenericsDictionaryNeedsRestore) \ - RESTORE_REASON_FUNC(InterfaceIsGeneric) \ - RESTORE_REASON_FUNC(CrossModuleGenericsStatics) \ - RESTORE_REASON_FUNC(ComImportStructDependenciesNeedRestore) \ - RESTORE_REASON_FUNC(CrossAssembly) \ - RESTORE_REASON_FUNC(ArrayElement) \ - RESTORE_REASON_FUNC(ProfilingEnabled) - -#undef RESTORE_REASON_FUNC -#define RESTORE_REASON_FUNC(s) s , -typedef enum -{ - - METHODTABLE_RESTORE_REASON() - - TotalMethodTables -} MethodTableRestoreReason; -#undef RESTORE_REASON_FUNC - -class NgenStats -{ -public: - NgenStats() - { - LIMITED_METHOD_CONTRACT; - memset (MethodTableRestoreNumReasons, 0, sizeof(DWORD)*(TotalMethodTables+1)); - } - - DWORD MethodTableRestoreNumReasons[TotalMethodTables + 1]; -}; -#endif // FEATURE_PREJIT - // // A Module is the primary unit of code packaging in the runtime. It // corresponds mostly to an OS executable image, although other kinds @@ -1403,11 +1143,6 @@ class Module // Hashtable of instantiated methods and per-instantiation static methods PTR_InstMethodHashTable m_pInstMethodHashTable; -#ifdef FEATURE_PREJIT - // Mapping from tokens to IL marshaling stubs (NGEN only). - PTR_StubMethodHashTable m_pStubMethodHashTable; -#endif // FEATURE_PREJIT - // This is used by the Debugger. We need to store a dword // for a count of JMC functions. This is a count, not a pointer. // We'll pass the address of this field @@ -1491,13 +1226,6 @@ class Module DWORD m_dwCustomAttributeCount; #endif // PROFILING_SUPPORTED_DATA -#ifdef FEATURE_PREJIT - PTR_NGenLayoutInfo m_pNGenLayoutInfo; - // Module wide static fields information - ModuleCtorInfo m_ModuleCtorInfo; - -#endif // FEATURE_PREJIT - struct TokenProfileData { static TokenProfileData *CreateNoThrow(void); @@ -1525,11 +1253,6 @@ class Module } *m_tokenProfileData; -#ifdef FEATURE_PREJIT - // Stats for prejit log - NgenStats *m_pNgenStats; -#endif // FEATURE_PREJIT - protected: @@ -1542,9 +1265,6 @@ class Module #ifndef DACCESS_COMPILE virtual void Initialize(AllocMemTracker *pamTracker, LPCWSTR szName = NULL); void InitializeForProfiling(); -#ifdef FEATURE_PREJIT - void InitializeNativeImage(AllocMemTracker* pamTracker); -#endif #endif void AllocateMaps(); @@ -1565,9 +1285,6 @@ class Module public: #ifndef DACCESS_COMPILE virtual void Destruct(); -#ifdef FEATURE_PREJIT - void DeleteNativeCodeRanges(); -#endif #endif PTR_LoaderAllocator GetLoaderAllocator(); @@ -1943,11 +1660,6 @@ class Module return m_pInstMethodHashTable; } -#ifdef FEATURE_PREJIT - // Gets or creates the token -> IL stub MethodDesc hash. - StubMethodHashTable *GetStubMethodHashTable(); -#endif // FEATURE_PREJIT - // Creates a new Method table for an array. Used to make type handles // Note that if kind == SZARRAY or ARRAY, we get passed the GENERIC_ARRAY // needed to create the array. That way we dont need to load classes during @@ -1959,9 +1671,6 @@ class Module // Resolving OBJECTHANDLE ResolveStringRef(DWORD Token, BaseDomain *pDomain, bool bNeedToSyncWithFixups); -#ifdef FEATURE_PREJIT - OBJECTHANDLE ResolveStringRefHelper(DWORD token, BaseDomain *pDomain, PTR_CORCOMPILE_IMPORT_SECTION pSection, EEStringData *strData); -#endif CHECK CheckStringRef(RVA rva); @@ -2329,16 +2038,6 @@ class Module // Enregisters a VASig. VASigCookie *GetVASigCookie(Signature vaSignature); -#ifdef FEATURE_PREJIT - // This data is only valid for NGEN'd modules, and for modules we're creating at NGEN time. - ModuleCtorInfo* GetZapModuleCtorInfo() - { - LIMITED_METHOD_DAC_CONTRACT; - - return &m_ModuleCtorInfo; - } -#endif - public: #ifndef DACCESS_COMPILE BOOL Equals(Module *pModule) { WRAPPER_NO_CONTRACT; return m_file->Equals(pModule->m_file); } @@ -2359,31 +2058,6 @@ class Module LPCWSTR GetDebugName() { WRAPPER_NO_CONTRACT; return m_file->GetDebugName(); } #endif -#ifdef FEATURE_PREJIT - BOOL HasNativeImage() - { - WRAPPER_NO_CONTRACT; - SUPPORTS_DAC; - return m_file->HasNativeImage(); - } - - PEImageLayout *GetNativeImage() - { - CONTRACT(PEImageLayout *) - { - PRECONDITION(m_file->HasNativeImage()); - POSTCONDITION(CheckPointer(RETVAL)); - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - CANNOT_TAKE_LOCK; - } - CONTRACT_END; - - _ASSERTE(!IsCollectible()); - RETURN m_file->GetLoadedNative(); - } -#else BOOL HasNativeImage() { LIMITED_METHOD_CONTRACT; @@ -2396,8 +2070,6 @@ class Module PRECONDITION(HasNativeImage()); return NULL; } -#endif // FEATURE_PREJIT - BOOL HasNativeOrReadyToRunImage(); PEImageLayout * GetNativeOrReadyToRunImage(); @@ -2453,55 +2125,6 @@ class Module void AddActiveDependency(Module *pModule, BOOL unconditional); -#ifdef FEATURE_PREJIT - BOOL IsZappedCode(PCODE code); - BOOL IsZappedPrecode(PCODE code); - - CORCOMPILE_DEBUG_ENTRY GetMethodDebugInfoOffset(MethodDesc *pMD); - PTR_BYTE GetNativeDebugInfo(MethodDesc * pMD); - - // The methods below must be called when loading back an ngen'ed image for any fields that - // might be an encoded token (rather than a hard pointer) and/or need a restore operation - // - static void RestoreMethodTablePointerRaw(PTR_MethodTable * ppMT, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - static void RestoreTypeHandlePointerRaw(TypeHandle *pHandle, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - static void RestoreMethodDescPointerRaw(PTR_MethodDesc * ppMD, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - - static void RestoreMethodTablePointer(FixupPointer * ppMT, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - static void RestoreTypeHandlePointer(FixupPointer *pHandle, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - static void RestoreMethodDescPointer(FixupPointer * ppMD, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - - static void RestoreMethodTablePointer(RelativeFixupPointer * ppMT, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - static void RestoreTypeHandlePointer(RelativeFixupPointer *pHandle, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - static void RestoreMethodDescPointer(RelativeFixupPointer * ppMD, - Module *pContainingModule = NULL, - ClassLoadLevel level = CLASS_LOADED); - static void RestoreFieldDescPointer(RelativeFixupPointer * ppFD); - - static void RestoreModulePointer(RelativeFixupPointer * ppModule, Module *pContainingModule); - - static PTR_Module RestoreModulePointerIfLoaded(DPTR(RelativeFixupPointer) ppModule, Module *pContainingModule); - - PCCOR_SIGNATURE GetEncodedSig(RVA fixupRva, Module **ppDefiningModule); - PCCOR_SIGNATURE GetEncodedSigIfLoaded(RVA fixupRva, Module **ppDefiningModule); -#endif - BYTE* GetNativeFixupBlobData(RVA fixup); IMDInternalImport *GetNativeAssemblyImport(BOOL loadAllowed = TRUE); @@ -2524,115 +2147,6 @@ class Module Module *GetModuleFromIndex(DWORD ix); Module *GetModuleFromIndexIfLoaded(DWORD ix); -#ifdef FEATURE_PREJIT - // This is to rebuild stub dispatch maps to module-local values. - void UpdateStubDispatchTypeTable(DataImage *image); - - void SetProfileData(CorProfileData * profileData); - CorProfileData *GetProfileData(); - - mdTypeDef LookupIbcTypeToken( Module * pExternalModule, mdToken ibcToken, SString* optionalFullNameOut = NULL); - mdMethodDef LookupIbcMethodToken(TypeHandle enclosingType, mdToken ibcToken, SString* optionalFullNameOut = NULL); - - TypeHandle LoadIBCTypeHelper(DataImage *image, CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry); - MethodDesc * LoadIBCMethodHelper(DataImage *image, CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry); - - - void ExpandAll(DataImage *image); - // profileData may be different than the profileData passed in to - // ExpandAll() depending on more information that may now be available - // (after all the methods have been compiled) - - void Save(DataImage *image); - void Arrange(DataImage *image); - void PlaceType(DataImage *image, TypeHandle th, DWORD profilingFlags); - void PlaceMethod(DataImage *image, MethodDesc *pMD, DWORD profilingFlags); - void Fixup(DataImage *image); - - bool AreAllClassesFullyLoaded(); - - // Precompute type-specific auxiliary information saved into NGen image - void PrepareTypesForSave(DataImage *image); - - static void SaveMethodTable(DataImage *image, - MethodTable *pMT, - DWORD profilingFlags); - - static void SaveTypeHandle(DataImage *image, - TypeHandle t, - DWORD profilingFlags); - -private: - static BOOL CanEagerBindTo(Module *targetModule, Module *pPreferredZapModule, void *address); -public: - - static PTR_Module ComputePreferredZapModule(Module * pDefinitionModule, // the module that declares the generic type or method - Instantiation classInst, // the type arguments to the type (if any) - Instantiation methodInst = Instantiation()); // the type arguments to the method (if any) - - static PTR_Module ComputePreferredZapModuleHelper(Module * pDefinitionModule, - Instantiation classInst, - Instantiation methodInst); - - static PTR_Module ComputePreferredZapModule(TypeKey * pKey); - - // Return true if types or methods of this instantiation are *always* precompiled and saved - // in the preferred zap module - // At present, only true for <__Canon,...,__Canon> instantiation - static BOOL IsAlwaysSavedInPreferredZapModule(Instantiation classInst, - Instantiation methodInst = Instantiation()); - - static PTR_Module GetPreferredZapModuleForTypeHandle(TypeHandle t); - static PTR_Module GetPreferredZapModuleForMethodTable(MethodTable * pMT); - static PTR_Module GetPreferredZapModuleForMethodDesc(const MethodDesc * pMD); - static PTR_Module GetPreferredZapModuleForFieldDesc(FieldDesc * pFD); - static PTR_Module GetPreferredZapModuleForTypeDesc(PTR_TypeDesc pTD); - - void PrepopulateDictionaries(DataImage *image, BOOL nonExpansive); - - - void LoadTokenTables(); - void LoadHelperTable(); - - PTR_NGenLayoutInfo GetNGenLayoutInfo() - { - LIMITED_METHOD_DAC_CONTRACT; - return m_pNGenLayoutInfo; - } - - PCODE GetPrestubJumpStub() - { - LIMITED_METHOD_DAC_CONTRACT; - - if (!m_pNGenLayoutInfo) - return NULL; - - return m_pNGenLayoutInfo->m_pPrestubJumpStub; - } - -#ifdef HAS_FIXUP_PRECODE - PCODE GetPrecodeFixupJumpStub() - { - LIMITED_METHOD_DAC_CONTRACT; - - if (!m_pNGenLayoutInfo) - return NULL; - - return m_pNGenLayoutInfo->m_pPrecodeFixupJumpStub; - } -#endif - - BOOL IsVirtualImportThunk(PCODE code) - { - LIMITED_METHOD_DAC_CONTRACT; - - if (!m_pNGenLayoutInfo) - return FALSE; - - return m_pNGenLayoutInfo->m_VirtualMethodThunks.IsInRange(code); - } -#endif // FEATURE_PREJIT - ICorJitInfo::BlockCounts * AllocateMethodBlockCounts(mdToken _token, DWORD _size, DWORD _ILSize); HANDLE OpenMethodProfileDataLogFile(GUID mvid); static void ProfileDataAllocateTokenLists(ProfileEmitter * pEmitter, TokenProfileData* pTokenProfileData); @@ -2651,29 +2165,6 @@ class Module void LogTokenAccess(mdToken token, SectionFormat format, ULONG flagNum); void LogTokenAccess(mdToken token, ULONG flagNum); -#ifdef FEATURE_PREJIT - BOOL AreTypeSpecsTriaged() - { - return m_dwTransientFlags & TYPESPECS_TRIAGED; - } - - void SetTypeSpecsTriaged() - { - FastInterlockOr(&m_dwTransientFlags, TYPESPECS_TRIAGED); - } - - BOOL IsModuleSaved() - { - return m_dwTransientFlags & MODULE_SAVED; - } - - void SetIsModuleSaved() - { - FastInterlockOr(&m_dwTransientFlags, MODULE_SAVED); - } - -#endif // FEATURE_PREJIT - BOOL IsReadyToRun() const { LIMITED_METHOD_DAC_CONTRACT; @@ -2812,14 +2303,6 @@ class Module PTR_DomainLocalModule GetDomainLocalModule(); -#ifdef FEATURE_PREJIT - NgenStats *GetNgenStats() - { - LIMITED_METHOD_CONTRACT; - return m_pNgenStats; - } -#endif // FEATURE_PREJIT - // LoaderHeap for storing IJW thunks PTR_LoaderHeap m_pThunkHeap; diff --git a/src/coreclr/vm/ceeload.inl b/src/coreclr/vm/ceeload.inl index f71511cbb9ac3d..bc7bc604c0eccd 100644 --- a/src/coreclr/vm/ceeload.inl +++ b/src/coreclr/vm/ceeload.inl @@ -136,38 +136,6 @@ TYPE LookupMap::GetElement(DWORD rid, TADDR* pFlags) WRAPPER_NO_CONTRACT; SUPPORTS_DAC; -#ifdef FEATURE_PREJIT - if (MapIsCompressed()) -{ - // Can't access compressed entries directly: we need to go through the special helper. However we - // must still check the hot cache first (this would normally be done by GetElementPtr() below, but - // we can't integrate compressed support there since compressed entries don't have addresses, at - // least not byte-aligned ones). - PTR_TADDR pHotItemValue = FindHotItemValuePtr(rid); - if (pHotItemValue) - return GetValueAt(pHotItemValue, pFlags, supportedFlags); - - TADDR value = GetValueFromCompressedMap(rid); - - if (value == NULL) - { - if ((pNext == NULL) || (rid < dwCount)) - { - if (pFlags) - *pFlags = NULL; - return NULL; - } - - return dac_cast(pNext)->GetElement(rid - dwCount, pFlags); - } - - if (pFlags) - *pFlags = (value & supportedFlags); - - return (TYPE)(value & ~supportedFlags); - } -#endif // FEATURE_PREJIT - PTR_TADDR pElement = GetElementPtr(rid); return (pElement != NULL) ? GetValueAt(pElement, pFlags, supportedFlags) : NULL; } @@ -265,12 +233,6 @@ void LookupMap::EnsureElementCanBeStored(Module * pModule, DWORD rid) } CONTRACTL_END; -#ifdef FEATURE_PREJIT - // don't attempt to call GetElementPtr for rids inside the compressed portion of - // a multi-node map - if (MapIsCompressed() && rid < dwCount) - return; -#endif PTR_TADDR pElement = GetElementPtr(rid); if (pElement == NULL) GrowMap(pModule, rid); @@ -313,12 +275,6 @@ LookupMap::Iterator::Iterator(LookupMap* map) m_map = map; m_index = (DWORD) -1; -#ifdef FEATURE_PREJIT - // Compressed map support - m_currentEntry = 0; - if (map->pTable != NULL) - m_tableStream = BitStreamReader(dac_cast(map->pTable)); -#endif // FEATURE_PREJIT } template @@ -343,13 +299,6 @@ LookupMap::Iterator::Next() m_index = 0; } -#ifdef FEATURE_PREJIT - // For a compressed map we need to read the encoded delta for the next entry and apply it to our previous - // value to obtain the new current value. - if (m_map->MapIsCompressed()) - m_currentEntry = m_map->GetNextCompressedEntry(&m_tableStream, m_currentEntry); -#endif // FEATURE_PREJIT - return TRUE; } @@ -360,24 +309,7 @@ LookupMap::Iterator::GetElement(TADDR* pFlags) SUPPORTS_DAC; WRAPPER_NO_CONTRACT; -#ifdef FEATURE_PREJIT - // The current value for a compressed map is actually a map-based RVA. A zero RVA indicates a NULL pointer - // but otherwise we can recover the full pointer by adding the address of the map we're iterating. - // Note that most LookupMaps are embedded structures (in Module) so we can't directly dac_cast our - // "this" pointer for DAC builds. Instead we have to use the slightly slower (in DAC) but more flexible - // PTR_HOST_INT_TO_TADDR() which copes with interior host pointers. - if (m_map->MapIsCompressed()) - { - TADDR value = m_currentEntry ? PTR_HOST_INT_TO_TADDR(m_map) + m_currentEntry : 0; - - if (pFlags) - *pFlags = (value & m_map->supportedFlags); - - return (TYPE)(value & ~m_map->supportedFlags); - } - else -#endif // FEATURE_PREJIT - return GetValueAt(m_map->GetIndexPtr(m_index), pFlags, m_map->supportedFlags); + return GetValueAt(m_map->GetIndexPtr(m_index), pFlags, m_map->supportedFlags); } inline PTR_Assembly Module::GetAssembly() const diff --git a/src/coreclr/vm/cgensys.h b/src/coreclr/vm/cgensys.h index 18cbd3e1b46e7e..9689ca251eb400 100644 --- a/src/coreclr/vm/cgensys.h +++ b/src/coreclr/vm/cgensys.h @@ -120,17 +120,6 @@ inline bool TargetHasAVXSupport() return false; } -#ifdef FEATURE_PREJIT -// Can code compiled for "minReqdCpuType" be used on "actualCpuType" -inline BOOL IsCompatibleCpuInfo(const CORINFO_CPU * actualCpuInfo, - const CORINFO_CPU * minReqdCpuInfo) -{ - LIMITED_METHOD_CONTRACT; - return ((minReqdCpuInfo->dwFeatures & actualCpuInfo->dwFeatures) == - minReqdCpuInfo->dwFeatures); -} -#endif // FEATURE_PREJIT - #ifndef DACCESS_COMPILE // Given an address in a slot, figure out if the prestub will be called diff --git a/src/coreclr/vm/class.cpp b/src/coreclr/vm/class.cpp index 1ef7fd306d5ef0..ec9a2af2f857a5 100644 --- a/src/coreclr/vm/class.cpp +++ b/src/coreclr/vm/class.cpp @@ -912,21 +912,7 @@ ClassLoader::LoadExactParentAndInterfacesTransitively(MethodTable *pMT) } } -#ifdef FEATURE_PREJIT - // Restore action, not in MethodTable::Restore because we may have had approx parents at that point - if (pMT->IsZapped()) - { - MethodTable::InterfaceMapIterator it = pMT->IterateInterfaceMap(); - while (it.Next()) - { - Module::RestoreMethodTablePointer(&it.GetInterfaceInfo()->m_pMethodTable, pMT->GetLoaderModule(), CLASS_LOAD_EXACTPARENTS); - } - } - else -#endif - { - MethodTableBuilder::LoadExactInterfaceMap(pMT); - } + MethodTableBuilder::LoadExactInterfaceMap(pMT); #ifdef _DEBUG if (g_pConfig->ShouldDumpOnClassLoad(pMT->GetDebugClassName())) @@ -1057,11 +1043,7 @@ bool ClassLoader::IsMethodSignatureCompatibleWith(FnPtrTypeDesc* fn1TD, FnPtrTyp TypeHandle* pFn2ArgTH = fn2TD->GetRetAndArgTypes(); for (DWORD i = 0; i < fn1TD->GetNumArgs() + 1; i++) { -#ifdef FEATURE_PREJIT - if (!ZapSig::CompareTaggedPointerToTypeHandle(pFn1ArgTH->GetModule(), pFn1ArgTH[i].AsTAddr(), pFn2ArgTH[i])) -#else if (pFn1ArgTH[i] != pFn2ArgTH[i]) -#endif { return false; } @@ -2573,29 +2555,6 @@ MethodTable::GetSubstitutionForParent( #endif //!DACCESS_COMPILE - -//******************************************************************************* -#ifdef FEATURE_PREJIT -DWORD EEClass::GetSize() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - FORBID_FAULT; - } - CONTRACTL_END; - - // Total instance size consists of the fixed ("normal") fields, cached at construction time and dependent - // on whether we're a vanilla EEClass or DelegateEEClass etc., and a portion for the packed fields tacked on - // the end. The size of the packed fields can be retrieved from the fields themselves or, if we were - // unsuccessful in our attempts to compress the data, the full size of the EEClassPackedFields structure - // (which is essentially just a DWORD array of all the field values). - return m_cbFixedEEClassFields + - (m_fFieldsArePacked ? GetPackedFields()->GetPackedSize() : sizeof(EEClassPackedFields)); -} -#endif // FEATURE_PREJIT - #ifndef DACCESS_COMPILE #ifdef FEATURE_COMINTEROP diff --git a/src/coreclr/vm/class.h b/src/coreclr/vm/class.h index a5a12498a4e63a..9fe55a9e30c2b7 100644 --- a/src/coreclr/vm/class.h +++ b/src/coreclr/vm/class.h @@ -774,10 +774,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! return IsTdImport(m_dwAttrClass); } -#ifdef FEATURE_PREJIT - DWORD GetSize(); -#endif // FEATURE_PREJIT - EEClassLayoutInfo *GetLayoutInfo(); PTR_EEClassNativeLayoutInfo GetNativeLayoutInfo(); @@ -1074,10 +1070,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! * There are (m_wNumInstanceFields - GetParentClass()->m_wNumInstanceFields + m_wNumStaticFields) entries * in this array */ -#ifdef FEATURE_PREJIT - static DWORD FieldDescListSize(MethodTable * pMT); -#endif - inline PTR_FieldDesc GetFieldDescList() { LIMITED_METHOD_DAC_CONTRACT; @@ -1992,10 +1984,6 @@ typedef DPTR(ArrayClass) PTR_ArrayClass; // Dynamically generated array class structure class ArrayClass : public EEClass { -#ifdef FEATURE_PREJIT - friend void EEClass::Fixup(DataImage *image, MethodTable *pMethodTable); -#endif - friend MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementType arrayKind, unsigned Rank, AllocMemTracker *pamTracker); #ifndef DACCESS_COMPILE diff --git a/src/coreclr/vm/clsload.cpp b/src/coreclr/vm/clsload.cpp index c3bf71378ba54c..95f19192d0cdbb 100644 --- a/src/coreclr/vm/clsload.cpp +++ b/src/coreclr/vm/clsload.cpp @@ -1036,12 +1036,6 @@ void ClassLoader::EnsureLoaded(TypeHandle typeHnd, ClassLoadLevel level) if (typeHnd.GetLoadLevel() < level) { -#ifdef FEATURE_PREJIT - if (typeHnd.GetLoadLevel() == CLASS_LOAD_UNRESTOREDTYPEKEY) - { - typeHnd.DoRestoreTypeKey(); - } -#endif if (level > CLASS_LOAD_UNRESTORED) { TypeKey typeKey = typeHnd.GetTypeKey(); @@ -1122,38 +1116,6 @@ TypeHandle ClassLoader::LookupTypeKey(TypeKey *pKey, return th; } - -#ifdef FEATURE_PREJIT -/* static */ -TypeHandle ClassLoader::LookupInPreferredZapModule(TypeKey *pKey, BOOL fCheckUnderLock) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - FORBID_FAULT; - PRECONDITION(CheckPointer(pKey)); - PRECONDITION(pKey->IsConstructed()); - MODE_ANY; - SUPPORTS_DAC; - } CONTRACTL_END; - - // First look for an NGEN'd type in the preferred ngen module - TypeHandle th; - PTR_Module pPreferredZapModule = Module::ComputePreferredZapModule(pKey); - - if (pPreferredZapModule != NULL && pPreferredZapModule->HasNativeImage()) - { - th = LookupTypeKey(pKey, - pPreferredZapModule->GetAvailableParamTypes(), - &pPreferredZapModule->GetClassLoader()->m_AvailableTypesLock, - fCheckUnderLock); - } - - return th; -} -#endif // FEATURE_PREJIT - - /* static */ TypeHandle ClassLoader::LookupInLoaderModule(TypeKey *pKey, BOOL fCheckUnderLock) { @@ -1225,18 +1187,6 @@ TypeHandle ClassLoader::LookupTypeHandleForTypeKeyInner(TypeKey *pKey, BOOL fChe return TypeHandle(pKey->GetModule()->LookupTypeDef(pKey->GetTypeToken())); } -#ifdef FEATURE_PREJIT - // The following ways of finding a constructed type should be mutually exclusive! - // 1. Look for a zapped item in the PreferredZapModule - // 2. Look for a unzapped (JIT-loaded) item in the LoaderModule - - TypeHandle thPZM = LookupInPreferredZapModule(pKey, fCheckUnderLock); - if (!thPZM.IsNull()) - { - return thPZM; - } -#endif // FEATURE_PREJIT - // Next look in the loader module. This is where the item is guaranteed to live if // it is not latched from an NGEN image, i.e. if it is JIT loaded. // If the thing is not NGEN'd then this may @@ -2988,22 +2938,10 @@ TypeHandle ClassLoader::DoIncrementalLoad(TypeKey *pTypeKey, TypeHandle typeHnd, break; case CLASS_LOAD_UNRESTOREDTYPEKEY : -#ifdef FEATURE_PREJIT - typeHnd.DoRestoreTypeKey(); -#endif break; // Attain level CLASS_LOAD_APPROXPARENTS, starting with unrestored class case CLASS_LOAD_UNRESTORED : -#ifdef FEATURE_PREJIT - { - CONSISTENCY_CHECK(!typeHnd.IsRestored_NoLogging()); - if (typeHnd.IsTypeDesc()) - typeHnd.AsTypeDesc()->Restore(); - else - typeHnd.AsMethodTable()->Restore(); - } -#endif break; // Attain level CLASS_LOAD_EXACTPARENTS diff --git a/src/coreclr/vm/clsload.hpp b/src/coreclr/vm/clsload.hpp index 195fb4f62cdcb4..ac5107a6744254 100644 --- a/src/coreclr/vm/clsload.hpp +++ b/src/coreclr/vm/clsload.hpp @@ -909,9 +909,6 @@ class ClassLoader BOOL fCheckUnderLock); static TypeHandle LookupInLoaderModule(TypeKey* pKey, BOOL fCheckUnderLock); -#ifdef FEATURE_PREJIT - static TypeHandle LookupInPreferredZapModule(TypeKey* pKey, BOOL fCheckUnderLock); -#endif // FEATURE_PREJIT // Lookup a handle in the appropriate table // (declaring module for TypeDef or loader-module for constructed types) diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 78721292a3e9f5..f96613d07e4727 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -46,9 +46,6 @@ SPTR_IMPL(EECodeManager, ExecutionManager, m_pDefaultCodeMan); SPTR_IMPL(EEJitManager, ExecutionManager, m_pEEJitManager); -#ifdef FEATURE_PREJIT -SPTR_IMPL(NativeImageJitManager, ExecutionManager, m_pNativeImageJitManager); -#endif #ifdef FEATURE_READYTORUN SPTR_IMPL(ReadyToRunJitManager, ExecutionManager, m_pReadyToRunJitManager); #endif @@ -4214,9 +4211,6 @@ void ExecutionManager::Init() #ifndef CROSSGEN_COMPILE m_pEEJitManager = new EEJitManager(); #endif -#ifdef FEATURE_PREJIT - m_pNativeImageJitManager = new NativeImageJitManager(); -#endif #ifdef FEATURE_READYTORUN m_pReadyToRunJitManager = new ReadyToRunJitManager(); @@ -4402,24 +4396,6 @@ BOOL ExecutionManager::IsManagedCodeWorker(PCODE currentPC) return TRUE; } #endif - else - { -#ifdef FEATURE_PREJIT - // Check that we are in the range with true managed code. We don't - // consider jump stubs or precodes to be real managed code. - - Module * pModule = dac_cast(pRS->pHeapListOrZapModule); - - NGenLayoutInfo * pLayoutInfo = pModule->GetNGenLayoutInfo(); - - if (pLayoutInfo->m_CodeSections[0].IsInRange(currentPC) || - pLayoutInfo->m_CodeSections[1].IsInRange(currentPC) || - pLayoutInfo->m_CodeSections[2].IsInRange(currentPC)) - { - return TRUE; - } -#endif - } return FALSE; } @@ -4706,26 +4682,6 @@ void ExecutionManager::AddCodeRange(TADDR pStartRange, dac_cast(pHp)); } -#ifdef FEATURE_PREJIT - -void ExecutionManager::AddNativeImageRange(TADDR StartRange, - SIZE_T Size, - Module * pModule) -{ - CONTRACTL { - THROWS; - GC_NOTRIGGER; - PRECONDITION(CheckPointer(pModule)); - } CONTRACTL_END; - - AddRangeHelper(StartRange, - StartRange + Size, - GetNativeImageJitManager(), - RangeSection::RANGE_SECTION_NONE, - dac_cast(pModule)); -} -#endif - void ExecutionManager::AddRangeHelper(TADDR pStartRange, TADDR pEndRange, IJitManager * pJit, @@ -5395,1144 +5351,123 @@ static void EnumRuntimeFunctionEntriesToFindEntry(PTR_RUNTIME_FUNCTION pRtf, PTR } #endif // FEATURE_EH_FUNCLETS -#ifdef FEATURE_PREJIT -//*************************************************************************************** -//*************************************************************************************** - -#ifndef DACCESS_COMPILE - -NativeImageJitManager::NativeImageJitManager() -{ - WRAPPER_NO_CONTRACT; -} - -#endif // #ifndef DACCESS_COMPILE +#if defined(FEATURE_READYTORUN) -GCInfoToken NativeImageJitManager::GetGCInfoToken(const METHODTOKEN& MethodToken) +// Return start of exception info for a method, or 0 if the method has no EH info +DWORD NativeExceptionInfoLookupTable::LookupExceptionInfoRVAForMethod(PTR_CORCOMPILE_EXCEPTION_LOOKUP_TABLE pExceptionLookupTable, + COUNT_T numLookupEntries, + DWORD methodStartRVA, + COUNT_T* pSize) { CONTRACTL { NOTHROW; GC_NOTRIGGER; - HOST_NOCALLS; SUPPORTS_DAC; } CONTRACTL_END; - PTR_RUNTIME_FUNCTION pRuntimeFunction = dac_cast(MethodToken.m_pCodeHeader); - TADDR baseAddress = JitTokenToModuleBase(MethodToken); - -#ifndef DACCESS_COMPILE - if (g_IBCLogger.InstrEnabled()) - { - PTR_NGenLayoutInfo pNgenLayout = JitTokenToZapModule(MethodToken)->GetNGenLayoutInfo(); - PTR_MethodDesc pMD = NativeUnwindInfoLookupTable::GetMethodDesc(pNgenLayout, pRuntimeFunction, baseAddress); - g_IBCLogger.LogMethodGCInfoAccess(pMD); - } -#endif - - SIZE_T nUnwindDataSize; - PTR_VOID pUnwindData = GetUnwindDataBlob(baseAddress, pRuntimeFunction, &nUnwindDataSize); + _ASSERTE(pExceptionLookupTable != NULL); - // GCInfo immediatelly follows unwind data - // GCInfo from an NGEN-ed image is always the current version - return{ dac_cast(pUnwindData) + nUnwindDataSize, GCINFO_VERSION }; -} + COUNT_T start = 0; + COUNT_T end = numLookupEntries - 2; -unsigned NativeImageJitManager::InitializeEHEnumeration(const METHODTOKEN& MethodToken, EH_CLAUSE_ENUMERATOR* pEnumState) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; + // The last entry in the lookup table (end-1) points to a sentinal entry. + // The sentinal entry helps to determine the number of EH clauses for the last table entry. + _ASSERTE(pExceptionLookupTable->ExceptionLookupEntry(numLookupEntries-1)->MethodStartRVA == (DWORD)-1); - NGenLayoutInfo * pNgenLayout = JitTokenToZapModule(MethodToken)->GetNGenLayoutInfo(); + // Binary search the lookup table + // Using linear search is faster once we get down to small number of entries. + while (end - start > 10) + { + COUNT_T middle = start + (end - start) / 2; - //early out if the method doesn't have EH info bit set. - if (!NativeUnwindInfoLookupTable::HasExceptionInfo(pNgenLayout, PTR_RUNTIME_FUNCTION(MethodToken.m_pCodeHeader))) - return 0; + _ASSERTE(start < middle && middle < end); - PTR_CORCOMPILE_EXCEPTION_LOOKUP_TABLE pExceptionLookupTable = dac_cast(pNgenLayout->m_ExceptionInfoLookupTable.StartAddress()); - _ASSERTE(pExceptionLookupTable != NULL); + DWORD rva = pExceptionLookupTable->ExceptionLookupEntry(middle)->MethodStartRVA; - SIZE_T size = pNgenLayout->m_ExceptionInfoLookupTable.Size(); - COUNT_T numLookupTableEntries = (COUNT_T)(size / sizeof(CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY)); - // at least 2 entries (1 valid entry + 1 sentinal entry) - _ASSERTE(numLookupTableEntries >= 2); + if (methodStartRVA < rva) + { + end = middle - 1; + } + else + { + start = middle; + } + } - DWORD methodStartRVA = (DWORD)(JitTokenToStartAddress(MethodToken) - JitTokenToModuleBase(MethodToken)); + for (COUNT_T i = start; i <= end; ++i) + { + DWORD rva = pExceptionLookupTable->ExceptionLookupEntry(i)->MethodStartRVA; + if (methodStartRVA == rva) + { + CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY *pEntry = pExceptionLookupTable->ExceptionLookupEntry(i); - COUNT_T ehInfoSize = 0; - DWORD exceptionInfoRVA = NativeExceptionInfoLookupTable::LookupExceptionInfoRVAForMethod(pExceptionLookupTable, - numLookupTableEntries, - methodStartRVA, - &ehInfoSize); - if (exceptionInfoRVA == 0) - return 0; + //Get the count of EH Clause entries + CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY * pNextEntry = pExceptionLookupTable->ExceptionLookupEntry(i + 1); + *pSize = pNextEntry->ExceptionInfoRVA - pEntry->ExceptionInfoRVA; - pEnumState->iCurrentPos = 0; - pEnumState->pExceptionClauseArray = JitTokenToModuleBase(MethodToken) + exceptionInfoRVA; + return pEntry->ExceptionInfoRVA; + } + } - return ehInfoSize / sizeof(CORCOMPILE_EXCEPTION_CLAUSE); + // Not found + return 0; } -PTR_EXCEPTION_CLAUSE_TOKEN NativeImageJitManager::GetNextEHClause(EH_CLAUSE_ENUMERATOR* pEnumState, - EE_ILEXCEPTION_CLAUSE* pEHClauseOut) +int NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod(DWORD RelativePc, + PTR_RUNTIME_FUNCTION pRuntimeFunctionTable, + int Low, + int High) { CONTRACTL { NOTHROW; GC_NOTRIGGER; + SUPPORTS_DAC; } CONTRACTL_END; - unsigned iCurrentPos = pEnumState->iCurrentPos; - pEnumState->iCurrentPos++; - - CORCOMPILE_EXCEPTION_CLAUSE* pClause = &(dac_cast(pEnumState->pExceptionClauseArray)[iCurrentPos]); - - // copy to the input parmeter, this is a nice abstraction for the future - // if we want to compress the Clause encoding, we can do without affecting the call sites - pEHClauseOut->TryStartPC = pClause->TryStartPC; - pEHClauseOut->TryEndPC = pClause->TryEndPC; - pEHClauseOut->HandlerStartPC = pClause->HandlerStartPC; - pEHClauseOut->HandlerEndPC = pClause->HandlerEndPC; - pEHClauseOut->Flags = pClause->Flags; - pEHClauseOut->FilterOffset = pClause->FilterOffset; - - return dac_cast(pClause); -} - -#ifndef DACCESS_COMPILE - -TypeHandle NativeImageJitManager::ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause, - CrawlFrame* pCf) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - } CONTRACTL_END; - - _ASSERTE(NULL != pCf); - _ASSERTE(NULL != pEHClause); - _ASSERTE(IsTypedHandler(pEHClause)); - - MethodDesc *pMD = PTR_MethodDesc(pCf->GetFunction()); - _ASSERTE(pMD != NULL); +#ifdef TARGET_ARM + RelativePc |= THUMB_CODE; +#endif - Module* pModule = pMD->GetModule(); - PREFIX_ASSUME(pModule != NULL); + // Entries are sorted and terminated by sentinel value (DWORD)-1 - SigTypeContext typeContext(pMD); - VarKind k = hasNoVars; + // Binary search the RUNTIME_FUNCTION table + // Use linear search once we get down to a small number of elements + // to avoid Binary search overhead. + while (High - Low > 10) + { + int Middle = Low + (High - Low) / 2; - mdToken typeTok = pEHClause->ClassToken; + PTR_RUNTIME_FUNCTION pFunctionEntry = pRuntimeFunctionTable + Middle; + if (RelativePc < pFunctionEntry->BeginAddress) + { + High = Middle - 1; + } + else + { + Low = Middle; + } + } - // In the vast majority of cases the code under the "if" below - // will not be executed. - // - // First grab the representative instantiations. For code - // shared by multiple generic instantiations these are the - // canonical (representative) instantiation. - if (TypeFromToken(typeTok) == mdtTypeSpec) + for (int i = Low; i <= High; ++i) { - PCCOR_SIGNATURE pSig; - ULONG cSig; - IfFailThrow(pModule->GetMDImport()->GetTypeSpecFromToken(typeTok, &pSig, &cSig)); - - SigPointer psig(pSig, cSig); - k = psig.IsPolyType(&typeContext); + // This is safe because of entries are terminated by sentinel value (DWORD)-1 + PTR_RUNTIME_FUNCTION pNextFunctionEntry = pRuntimeFunctionTable + (i + 1); - // Grab the active class and method instantiation. This exact instantiation is only - // needed in the corner case of "generic" exception catching in shared - // generic code. We don't need the exact instantiation if the token - // doesn't contain E_T_VAR or E_T_MVAR. - if ((k & hasSharableVarsMask) != 0) + if (RelativePc < pNextFunctionEntry->BeginAddress) { - Instantiation classInst; - Instantiation methodInst; - pCf->GetExactGenericInstantiations(&classInst,&methodInst); - SigTypeContext::InitTypeContext(pMD,classInst, methodInst,&typeContext); + PTR_RUNTIME_FUNCTION pFunctionEntry = pRuntimeFunctionTable + i; + if (RelativePc >= pFunctionEntry->BeginAddress) + { + return i; + } + break; } } - return ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, typeTok, &typeContext, - ClassLoader::ReturnNullIfNotFound); -} - -#endif // #ifndef DACCESS_COMPILE - -//----------------------------------------------------------------------------- -// Ngen info manager -//----------------------------------------------------------------------------- -BOOL NativeImageJitManager::GetBoundariesAndVars( - const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, - OUT ULONG32 * pcMap, - OUT ICorDebugInfo::OffsetMapping **ppMap, - OUT ULONG32 * pcVars, - OUT ICorDebugInfo::NativeVarInfo **ppVars) -{ - CONTRACTL { - THROWS; // on OOM. - GC_NOTRIGGER; // getting vars shouldn't trigger - SUPPORTS_DAC; - } CONTRACTL_END; - - // We want the module that the code is instantiated in, not necessarily the one - // that it was declared in. This only matters for ngen-generics. - MethodDesc * pMD = request.GetMD(); - Module * pModule = pMD->GetZapModule(); - PREFIX_ASSUME(pModule != NULL); - - PTR_BYTE pDebugInfo = pModule->GetNativeDebugInfo(pMD); - - // No header created, which means no jit information is available. - if (pDebugInfo == NULL) - return FALSE; - - // Uncompress. This allocates memory and may throw. - CompressDebugInfo::RestoreBoundariesAndVars( - fpNew, pNewData, // allocators - pDebugInfo, // input - pcMap, ppMap, // output - pcVars, ppVars, // output - FALSE); // no patchpoint info - - return TRUE; -} - -#ifdef DACCESS_COMPILE -// -// Need to write out debug info -// -void NativeImageJitManager::EnumMemoryRegionsForMethodDebugInfo(CLRDataEnumMemoryFlags flags, MethodDesc * pMD) -{ - SUPPORTS_DAC; - - Module * pModule = pMD->GetZapModule(); - PREFIX_ASSUME(pModule != NULL); - PTR_BYTE pDebugInfo = pModule->GetNativeDebugInfo(pMD); - - if (pDebugInfo != NULL) - { - CompressDebugInfo::EnumMemoryRegions(flags, pDebugInfo); - } + return -1; } -#endif -PCODE NativeImageJitManager::GetCodeAddressForRelOffset(const METHODTOKEN& MethodToken, DWORD relOffset) -{ - WRAPPER_NO_CONTRACT; - - MethodRegionInfo methodRegionInfo; - JitTokenToMethodRegionInfo(MethodToken, &methodRegionInfo); - - if (relOffset < methodRegionInfo.hotSize) - return methodRegionInfo.hotStartAddress + relOffset; - - SIZE_T coldOffset = relOffset - methodRegionInfo.hotSize; - _ASSERTE(coldOffset < methodRegionInfo.coldSize); - return methodRegionInfo.coldStartAddress + coldOffset; -} - -BOOL NativeImageJitManager::JitCodeToMethodInfo(RangeSection * pRangeSection, - PCODE currentPC, - MethodDesc** ppMethodDesc, - EECodeInfo * pCodeInfo) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } CONTRACTL_END; - - TADDR currentInstr = PCODEToPINSTR(currentPC); - - Module * pModule = dac_cast(pRangeSection->pHeapListOrZapModule); - - NGenLayoutInfo * pLayoutInfo = pModule->GetNGenLayoutInfo(); - DWORD iRange = 0; - - if (pLayoutInfo->m_CodeSections[0].IsInRange(currentInstr)) - { - iRange = 0; - } - else - if (pLayoutInfo->m_CodeSections[1].IsInRange(currentInstr)) - { - iRange = 1; - } - else - if (pLayoutInfo->m_CodeSections[2].IsInRange(currentInstr)) - { - iRange = 2; - } - else - { - return FALSE; - } - - TADDR ImageBase = pRangeSection->LowAddress; - - DWORD RelativePc = (DWORD)(currentInstr - ImageBase); - - PTR_RUNTIME_FUNCTION FunctionEntry; - - if (iRange == 2) - { - int ColdMethodIndex = NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod(RelativePc, - pLayoutInfo->m_pRuntimeFunctions[2], - 0, - pLayoutInfo->m_nRuntimeFunctions[2] - 1); - - if (ColdMethodIndex < 0) - return FALSE; - -#ifdef FEATURE_EH_FUNCLETS - // Save the raw entry - int RawColdMethodIndex = ColdMethodIndex; - - PTR_CORCOMPILE_COLD_METHOD_ENTRY pColdCodeMap = pLayoutInfo->m_ColdCodeMap; - - while (pColdCodeMap[ColdMethodIndex].mainFunctionEntryRVA == 0) - ColdMethodIndex--; - - FunctionEntry = dac_cast(ImageBase + pColdCodeMap[ColdMethodIndex].mainFunctionEntryRVA); -#else - DWORD ColdUnwindData = pLayoutInfo->m_pRuntimeFunctions[2][ColdMethodIndex].UnwindData; - _ASSERTE((ColdUnwindData & RUNTIME_FUNCTION_INDIRECT) != 0); - FunctionEntry = dac_cast(ImageBase + (ColdUnwindData & ~RUNTIME_FUNCTION_INDIRECT)); -#endif - - if (ppMethodDesc) - { - DWORD methodDescRVA; - - COUNT_T iIndex = (COUNT_T)(FunctionEntry - pLayoutInfo->m_pRuntimeFunctions[0]); - if (iIndex >= pLayoutInfo->m_nRuntimeFunctions[0]) - { - iIndex = (COUNT_T)(FunctionEntry - pLayoutInfo->m_pRuntimeFunctions[1]); - _ASSERTE(iIndex < pLayoutInfo->m_nRuntimeFunctions[1]); - methodDescRVA = pLayoutInfo->m_MethodDescs[1][iIndex]; - } - else - { - methodDescRVA = pLayoutInfo->m_MethodDescs[0][iIndex]; - } - _ASSERTE(methodDescRVA != NULL); - - // Note that the MethodDesc does not have to be restored. (It happens when we are called - // from SetupGcCoverageForNativeMethod.) - *ppMethodDesc = PTR_MethodDesc((methodDescRVA & ~HAS_EXCEPTION_INFO_MASK) + ImageBase); - } - - if (pCodeInfo) - { - PTR_RUNTIME_FUNCTION ColdFunctionTable = pLayoutInfo->m_pRuntimeFunctions[2]; - - PTR_RUNTIME_FUNCTION ColdFunctionEntry = ColdFunctionTable + ColdMethodIndex; - DWORD coldCodeOffset = (DWORD)(RelativePc - RUNTIME_FUNCTION__BeginAddress(ColdFunctionEntry)); - pCodeInfo->m_relOffset = pLayoutInfo->m_ColdCodeMap[ColdMethodIndex].hotCodeSize + coldCodeOffset; - - // We are using RUNTIME_FUNCTION as METHODTOKEN - pCodeInfo->m_methodToken = METHODTOKEN(pRangeSection, dac_cast(FunctionEntry)); - -#ifdef FEATURE_EH_FUNCLETS - PTR_RUNTIME_FUNCTION RawColdFunctionEntry = ColdFunctionTable + RawColdMethodIndex; -#ifdef TARGET_AMD64 - if ((RawColdFunctionEntry->UnwindData & RUNTIME_FUNCTION_INDIRECT) != 0) - { - RawColdFunctionEntry = PTR_RUNTIME_FUNCTION(ImageBase + (RawColdFunctionEntry->UnwindData & ~RUNTIME_FUNCTION_INDIRECT)); - } -#endif // TARGET_AMD64 - pCodeInfo->m_pFunctionEntry = RawColdFunctionEntry; -#endif - } - } - else - { - PTR_DWORD pRuntimeFunctionLookupTable = dac_cast(pLayoutInfo->m_UnwindInfoLookupTable[iRange]); - - _ASSERTE(pRuntimeFunctionLookupTable != NULL); - - DWORD RelativeToCodeStart = (DWORD)(currentInstr - dac_cast(pLayoutInfo->m_CodeSections[iRange].StartAddress())); - COUNT_T iStrideIndex = RelativeToCodeStart / RUNTIME_FUNCTION_LOOKUP_STRIDE; - - // The lookup table may not be big enough to cover the entire code range if there was padding inserted during NGen image layout. - // The last entry is lookup table entry covers the rest of the code range in this case. - if (iStrideIndex >= pLayoutInfo->m_UnwindInfoLookupTableEntryCount[iRange]) - iStrideIndex = pLayoutInfo->m_UnwindInfoLookupTableEntryCount[iRange] - 1; - - int Low = pRuntimeFunctionLookupTable[iStrideIndex]; - int High = pRuntimeFunctionLookupTable[iStrideIndex+1]; - - PTR_RUNTIME_FUNCTION FunctionTable = pLayoutInfo->m_pRuntimeFunctions[iRange]; - PTR_DWORD pMethodDescs = pLayoutInfo->m_MethodDescs[iRange]; - - int MethodIndex = NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod(RelativePc, - FunctionTable, - Low, - High); - - if (MethodIndex < 0) - return FALSE; - -#ifdef FEATURE_EH_FUNCLETS - // Save the raw entry - PTR_RUNTIME_FUNCTION RawFunctionEntry = FunctionTable + MethodIndex;; - - // Skip funclets to get the method desc - while (pMethodDescs[MethodIndex] == 0) - MethodIndex--; -#endif - - FunctionEntry = FunctionTable + MethodIndex; - - if (ppMethodDesc) - { - DWORD methodDescRVA = pMethodDescs[MethodIndex]; - _ASSERTE(methodDescRVA != NULL); - - // Note that the MethodDesc does not have to be restored. (It happens when we are called - // from SetupGcCoverageForNativeMethod.) - *ppMethodDesc = PTR_MethodDesc((methodDescRVA & ~HAS_EXCEPTION_INFO_MASK) + ImageBase); - - // We are likely executing the code already or going to execute it soon. However, there are a few cases like - // code:MethodTable::GetMethodDescForSlot where it is not the case. Log the code access here to avoid these - // cases from touching cold code maps. - g_IBCLogger.LogMethodCodeAccess(*ppMethodDesc); - } - - // Get the function entry that corresponds to the real method desc. - _ASSERTE((RelativePc >= RUNTIME_FUNCTION__BeginAddress(FunctionEntry))); - - if (pCodeInfo) - { - pCodeInfo->m_relOffset = (DWORD) - (RelativePc - RUNTIME_FUNCTION__BeginAddress(FunctionEntry)); - - // We are using RUNTIME_FUNCTION as METHODTOKEN - pCodeInfo->m_methodToken = METHODTOKEN(pRangeSection, dac_cast(FunctionEntry)); - -#ifdef FEATURE_EH_FUNCLETS - AMD64_ONLY(_ASSERTE((RawFunctionEntry->UnwindData & RUNTIME_FUNCTION_INDIRECT) == 0)); - pCodeInfo->m_pFunctionEntry = RawFunctionEntry; -#endif - } - } - - return TRUE; -} - -#if defined(FEATURE_EH_FUNCLETS) -PTR_RUNTIME_FUNCTION NativeImageJitManager::LazyGetFunctionEntry(EECodeInfo * pCodeInfo) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; - - if (!pCodeInfo->IsValid()) - { - return NULL; - } - - // code:NativeImageJitManager::JitCodeToMethodInfo computes PTR_RUNTIME_FUNCTION eagerly. This path is only - // reachable via EECodeInfo::GetMainFunctionInfo, and so we can just return the main entry. - _ASSERTE(pCodeInfo->GetRelOffset() == 0); - - return dac_cast(pCodeInfo->GetMethodToken().m_pCodeHeader); -} - -TADDR NativeImageJitManager::GetFuncletStartAddress(EECodeInfo * pCodeInfo) -{ - LIMITED_METHOD_DAC_CONTRACT; - -#if defined(TARGET_ARM) || defined(TARGET_ARM64) - NGenLayoutInfo * pLayoutInfo = JitTokenToZapModule(pCodeInfo->GetMethodToken())->GetNGenLayoutInfo(); - - if (pLayoutInfo->m_CodeSections[2].IsInRange(pCodeInfo->GetCodeAddress())) - { - // If the address is in the cold section, then we assume it is cold main function - // code, NOT a funclet. So, don't do the backward walk: just return the start address - // of the main function. - // @ARMTODO: Handle hot/cold splitting with EH funclets - return pCodeInfo->GetStartAddress(); - } -#endif - - return IJitManager::GetFuncletStartAddress(pCodeInfo); -} - -DWORD NativeImageJitManager::GetFuncletStartOffsets(const METHODTOKEN& MethodToken, DWORD* pStartFuncletOffsets, DWORD dwLength) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - PTR_RUNTIME_FUNCTION pFirstFuncletFunctionEntry = dac_cast(MethodToken.m_pCodeHeader) + 1; - - TADDR moduleBase = JitTokenToModuleBase(MethodToken); - DWORD nFunclets = 0; - MethodRegionInfo regionInfo; - JitTokenToMethodRegionInfo(MethodToken, ®ionInfo); - - // pFirstFuncletFunctionEntry will work for ARM when passed to GetFuncletStartOffsetsHelper() - // even if it is a fragment of the main body and not a RUNTIME_FUNCTION for the beginning - // of the first hot funclet, because GetFuncletStartOffsetsHelper() will skip all the function - // fragments until the first funclet, if any, is found. - - GetFuncletStartOffsetsHelper(regionInfo.hotStartAddress, regionInfo.hotSize, 0, - pFirstFuncletFunctionEntry, moduleBase, - &nFunclets, pStartFuncletOffsets, dwLength); - - // There are no funclets in cold section on ARM yet - // @ARMTODO: support hot/cold splitting in functions with EH -#if !defined(TARGET_ARM) && !defined(TARGET_ARM64) - if (regionInfo.coldSize != NULL) - { - NGenLayoutInfo * pLayoutInfo = JitTokenToZapModule(MethodToken)->GetNGenLayoutInfo(); - - int iColdMethodIndex = NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod( - (DWORD)(regionInfo.coldStartAddress - moduleBase), - pLayoutInfo->m_pRuntimeFunctions[2], - 0, - pLayoutInfo->m_nRuntimeFunctions[2] - 1); - - PTR_RUNTIME_FUNCTION pFunctionEntry = pLayoutInfo->m_pRuntimeFunctions[2] + iColdMethodIndex; - - _ASSERTE(regionInfo.coldStartAddress == moduleBase + RUNTIME_FUNCTION__BeginAddress(pFunctionEntry)); - -#ifdef TARGET_AMD64 - // Skip cold part of the method body - if ((pFunctionEntry->UnwindData & RUNTIME_FUNCTION_INDIRECT) != 0) - pFunctionEntry++; -#endif - - GetFuncletStartOffsetsHelper(regionInfo.coldStartAddress, regionInfo.coldSize, regionInfo.hotSize, - pFunctionEntry, moduleBase, - &nFunclets, pStartFuncletOffsets, dwLength); - } -#endif // !TARGET_ARM && !_TARGET_ARM64 - - return nFunclets; -} - -BOOL NativeImageJitManager::IsFilterFunclet(EECodeInfo * pCodeInfo) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if (!pCodeInfo->IsFunclet()) - return FALSE; - - // - // The generic IsFilterFunclet implementation is touching exception handling tables. - // It is bad for working set because of it is sometimes called during GC stackwalks. - // The optimized version for native images does not touch exception handling tables. - // - - NGenLayoutInfo * pLayoutInfo = JitTokenToZapModule(pCodeInfo->GetMethodToken())->GetNGenLayoutInfo(); - - SIZE_T size; - PTR_VOID pUnwindData = GetUnwindDataBlob(pCodeInfo->GetModuleBase(), pCodeInfo->GetFunctionEntry(), &size); - _ASSERTE(pUnwindData != NULL); - - // Personality routine is always the last element of the unwind data - DWORD rvaPersonalityRoutine = *(dac_cast(dac_cast(pUnwindData) + size) - 1); - - BOOL fRet = (pLayoutInfo->m_rvaFilterPersonalityRoutine == rvaPersonalityRoutine); - - // Verify that the optimized implementation is in sync with the slow implementation - _ASSERTE(fRet == IJitManager::IsFilterFunclet(pCodeInfo)); - - return fRet; -} - -#endif // FEATURE_EH_FUNCLETS - -StubCodeBlockKind NativeImageJitManager::GetStubCodeBlockKind(RangeSection * pRangeSection, PCODE currentPC) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - Module * pZapModule = dac_cast(pRangeSection->pHeapListOrZapModule); - - if (pZapModule->IsZappedPrecode(currentPC)) - { - return STUB_CODE_BLOCK_PRECODE; - } - - NGenLayoutInfo * pLayoutInfo = pZapModule->GetNGenLayoutInfo(); - _ASSERTE(pLayoutInfo != NULL); - - if (pLayoutInfo->m_JumpStubs.IsInRange(currentPC)) - { - return STUB_CODE_BLOCK_JUMPSTUB; - } - - if (pLayoutInfo->m_StubLinkStubs.IsInRange(currentPC)) - { - return STUB_CODE_BLOCK_STUBLINK; - } - - if (pLayoutInfo->m_VirtualMethodThunks.IsInRange(currentPC)) - { - return STUB_CODE_BLOCK_VIRTUAL_METHOD_THUNK; - } - - if (pLayoutInfo->m_ExternalMethodThunks.IsInRange(currentPC)) - { - return STUB_CODE_BLOCK_EXTERNAL_METHOD_THUNK; - } - - return STUB_CODE_BLOCK_UNKNOWN; -} - -PTR_Module NativeImageJitManager::JitTokenToZapModule(const METHODTOKEN& MethodToken) -{ - LIMITED_METHOD_DAC_CONTRACT; - return dac_cast(MethodToken.m_pRangeSection->pHeapListOrZapModule); -} -void NativeImageJitManager::JitTokenToMethodRegionInfo(const METHODTOKEN& MethodToken, - MethodRegionInfo * methodRegionInfo) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } CONTRACTL_END; - - _ASSERTE(methodRegionInfo != NULL); - - // - // Initialize methodRegionInfo assuming that the method is entirely hot. This is the common - // case (either binary is not procedure split or the current method is all hot). We can - // adjust these values later if necessary. - // - - methodRegionInfo->hotStartAddress = JitTokenToStartAddress(MethodToken); - methodRegionInfo->hotSize = GetCodeManager()->GetFunctionSize(GetGCInfoToken(MethodToken)); - methodRegionInfo->coldStartAddress = 0; - methodRegionInfo->coldSize = 0; - - RangeSection *rangeSection = MethodToken.m_pRangeSection; - PREFIX_ASSUME(rangeSection != NULL); - - Module * pModule = dac_cast(rangeSection->pHeapListOrZapModule); - - NGenLayoutInfo * pLayoutInfo = pModule->GetNGenLayoutInfo(); - - // - // If this module is not procedure split, then we're done. - // - if (pLayoutInfo->m_CodeSections[2].Size() == 0) - return; - - // - // Perform a binary search in the cold range section until we find our method - // - - TADDR ImageBase = rangeSection->LowAddress; - - int Low = 0; - int High = pLayoutInfo->m_nRuntimeFunctions[2] - 1; - - PTR_RUNTIME_FUNCTION pRuntimeFunctionTable = pLayoutInfo->m_pRuntimeFunctions[2]; - PTR_CORCOMPILE_COLD_METHOD_ENTRY pColdCodeMap = pLayoutInfo->m_ColdCodeMap; - - while (Low <= High) - { - int Middle = Low + (High - Low) / 2; - - int ColdMethodIndex = Middle; - - PTR_RUNTIME_FUNCTION FunctionEntry; - -#ifdef FEATURE_EH_FUNCLETS - while (pColdCodeMap[ColdMethodIndex].mainFunctionEntryRVA == 0) - ColdMethodIndex--; - - FunctionEntry = dac_cast(ImageBase + pColdCodeMap[ColdMethodIndex].mainFunctionEntryRVA); -#else - DWORD ColdUnwindData = pRuntimeFunctionTable[ColdMethodIndex].UnwindData; - _ASSERTE((ColdUnwindData & RUNTIME_FUNCTION_INDIRECT) != 0); - FunctionEntry = dac_cast(ImageBase + (ColdUnwindData & ~RUNTIME_FUNCTION_INDIRECT)); -#endif - - if (FunctionEntry == dac_cast(MethodToken.m_pCodeHeader)) - { - PTR_RUNTIME_FUNCTION ColdFunctionEntry = pRuntimeFunctionTable + ColdMethodIndex; - - methodRegionInfo->coldStartAddress = ImageBase + RUNTIME_FUNCTION__BeginAddress(ColdFunctionEntry); - - // - // At this point methodRegionInfo->hotSize is set to the total size of - // the method obtained from the GC info (we set that in the init code above). - // Use that and coldHeader->hotCodeSize to compute the hot and cold code sizes. - // - - ULONG hotCodeSize = pColdCodeMap[ColdMethodIndex].hotCodeSize; - - methodRegionInfo->coldSize = methodRegionInfo->hotSize - hotCodeSize; - methodRegionInfo->hotSize = hotCodeSize; - - return; - } - else if (FunctionEntry < dac_cast(MethodToken.m_pCodeHeader)) - { - Low = Middle + 1; - } - else - { - // Use ColdMethodIndex to take advantage of entries skipped while looking for method start - High = ColdMethodIndex - 1; - } - } - - // - // We didn't find it. Therefore this method doesn't have a cold section. - // - - return; -} - -#ifdef DACCESS_COMPILE - -void NativeImageJitManager::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) -{ - IJitManager::EnumMemoryRegions(flags); -} - -#if defined(FEATURE_EH_FUNCLETS) - -// -// EnumMemoryRegionsForMethodUnwindInfo - enumerate the memory necessary to read the unwind info for the -// specified method. -// -// Note that in theory, a dump generation library could save the unwind information itself without help -// from us, since it's stored in the image in the standard function table layout for Win64. However, -// dump-generation libraries assume that the image will be available at debug time, and if the image -// isn't available then it is acceptable for stackwalking to break. For ngen images (which are created -// on the client), it usually isn't possible to have the image available at debug time, and so for minidumps -// we must explicitly ensure the unwind information is saved into the dump. -// -// Arguments: -// flags - EnumMem flags -// pMD - MethodDesc for the method in question -// -void NativeImageJitManager::EnumMemoryRegionsForMethodUnwindInfo(CLRDataEnumMemoryFlags flags, EECodeInfo * pCodeInfo) -{ - // Get the RUNTIME_FUNCTION entry for this method - PTR_RUNTIME_FUNCTION pRtf = pCodeInfo->GetFunctionEntry(); - - if (pRtf==NULL) - { - return; - } - - // Enumerate the function entry and other entries needed to locate it in the program exceptions directory - Module * pModule = JitTokenToZapModule(pCodeInfo->GetMethodToken()); - EnumRuntimeFunctionEntriesToFindEntry(pRtf, pModule->GetFile()->GetLoadedNative()); - - SIZE_T size; - PTR_VOID pUnwindData = GetUnwindDataBlob(pCodeInfo->GetModuleBase(), pRtf, &size); - if (pUnwindData != NULL) - DacEnumMemoryRegion(PTR_TO_TADDR(pUnwindData), size); -} - -#endif //FEATURE_EH_FUNCLETS -#endif // #ifdef DACCESS_COMPILE - -#endif // FEATURE_PREJIT - -#if defined(FEATURE_PREJIT) || defined(FEATURE_READYTORUN) - -// Return start of exception info for a method, or 0 if the method has no EH info -DWORD NativeExceptionInfoLookupTable::LookupExceptionInfoRVAForMethod(PTR_CORCOMPILE_EXCEPTION_LOOKUP_TABLE pExceptionLookupTable, - COUNT_T numLookupEntries, - DWORD methodStartRVA, - COUNT_T* pSize) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } CONTRACTL_END; - - _ASSERTE(pExceptionLookupTable != NULL); - - COUNT_T start = 0; - COUNT_T end = numLookupEntries - 2; - - // The last entry in the lookup table (end-1) points to a sentinal entry. - // The sentinal entry helps to determine the number of EH clauses for the last table entry. - _ASSERTE(pExceptionLookupTable->ExceptionLookupEntry(numLookupEntries-1)->MethodStartRVA == (DWORD)-1); - - // Binary search the lookup table - // Using linear search is faster once we get down to small number of entries. - while (end - start > 10) - { - COUNT_T middle = start + (end - start) / 2; - - _ASSERTE(start < middle && middle < end); - - DWORD rva = pExceptionLookupTable->ExceptionLookupEntry(middle)->MethodStartRVA; - - if (methodStartRVA < rva) - { - end = middle - 1; - } - else - { - start = middle; - } - } - - for (COUNT_T i = start; i <= end; ++i) - { - DWORD rva = pExceptionLookupTable->ExceptionLookupEntry(i)->MethodStartRVA; - if (methodStartRVA == rva) - { - CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY *pEntry = pExceptionLookupTable->ExceptionLookupEntry(i); - - //Get the count of EH Clause entries - CORCOMPILE_EXCEPTION_LOOKUP_TABLE_ENTRY * pNextEntry = pExceptionLookupTable->ExceptionLookupEntry(i + 1); - *pSize = pNextEntry->ExceptionInfoRVA - pEntry->ExceptionInfoRVA; - - return pEntry->ExceptionInfoRVA; - } - } - - // Not found - return 0; -} - -int NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod(DWORD RelativePc, - PTR_RUNTIME_FUNCTION pRuntimeFunctionTable, - int Low, - int High) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - SUPPORTS_DAC; - } CONTRACTL_END; - - -#ifdef TARGET_ARM - RelativePc |= THUMB_CODE; -#endif - - // Entries are sorted and terminated by sentinel value (DWORD)-1 - - // Binary search the RUNTIME_FUNCTION table - // Use linear search once we get down to a small number of elements - // to avoid Binary search overhead. - while (High - Low > 10) - { - int Middle = Low + (High - Low) / 2; - - PTR_RUNTIME_FUNCTION pFunctionEntry = pRuntimeFunctionTable + Middle; - if (RelativePc < pFunctionEntry->BeginAddress) - { - High = Middle - 1; - } - else - { - Low = Middle; - } - } - - for (int i = Low; i <= High; ++i) - { - // This is safe because of entries are terminated by sentinel value (DWORD)-1 - PTR_RUNTIME_FUNCTION pNextFunctionEntry = pRuntimeFunctionTable + (i + 1); - - if (RelativePc < pNextFunctionEntry->BeginAddress) - { - PTR_RUNTIME_FUNCTION pFunctionEntry = pRuntimeFunctionTable + i; - if (RelativePc >= pFunctionEntry->BeginAddress) - { - return i; - } - break; - } - } - - return -1; -} - -#ifdef FEATURE_PREJIT -BOOL NativeUnwindInfoLookupTable::HasExceptionInfo(NGenLayoutInfo * pNgenLayout, PTR_RUNTIME_FUNCTION pMainRuntimeFunction) -{ - LIMITED_METHOD_DAC_CONTRACT; - DWORD methodDescRVA = NativeUnwindInfoLookupTable::GetMethodDescRVA(pNgenLayout, pMainRuntimeFunction); - return (methodDescRVA & HAS_EXCEPTION_INFO_MASK); -} - -PTR_MethodDesc NativeUnwindInfoLookupTable::GetMethodDesc(NGenLayoutInfo * pNgenLayout, PTR_RUNTIME_FUNCTION pMainRuntimeFunction, TADDR moduleBase) -{ - LIMITED_METHOD_DAC_CONTRACT; - DWORD methodDescRVA = NativeUnwindInfoLookupTable::GetMethodDescRVA(pNgenLayout, pMainRuntimeFunction); - return PTR_MethodDesc((methodDescRVA & ~HAS_EXCEPTION_INFO_MASK) + moduleBase); -} - -DWORD NativeUnwindInfoLookupTable::GetMethodDescRVA(NGenLayoutInfo * pNgenLayout, PTR_RUNTIME_FUNCTION pMainRuntimeFunction) -{ - LIMITED_METHOD_DAC_CONTRACT; - - COUNT_T iIndex = (COUNT_T)(pMainRuntimeFunction - pNgenLayout->m_pRuntimeFunctions[0]); - DWORD rva = 0; - if (iIndex >= pNgenLayout->m_nRuntimeFunctions[0]) - { - iIndex = (COUNT_T)(pMainRuntimeFunction - pNgenLayout->m_pRuntimeFunctions[1]); - _ASSERTE(iIndex < pNgenLayout->m_nRuntimeFunctions[1]); - rva = pNgenLayout->m_MethodDescs[1][iIndex]; - } - else - { - rva = pNgenLayout->m_MethodDescs[0][iIndex]; - } - _ASSERTE(rva != 0); - - return rva; -} -#endif // FEATURE_PREJIT - -#endif // FEATURE_PREJIT || FEATURE_READYTORUN - - - -#ifdef FEATURE_PREJIT - -MethodIterator::MethodIterator(PTR_Module pModule, MethodIteratorOptions mio) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } CONTRACTL_END; - - Init(pModule, pModule->GetNativeImage(), mio); -} - -MethodIterator::MethodIterator(PTR_Module pModule, PEDecoder * pPEDecoder, MethodIteratorOptions mio) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } CONTRACTL_END; - - Init(pModule, pPEDecoder, mio); -} - -void MethodIterator::Init(PTR_Module pModule, PEDecoder * pPEDecoder, MethodIteratorOptions mio) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } CONTRACTL_END; - - m_ModuleBase = dac_cast(pPEDecoder->GetBase()); - - methodIteratorOptions = mio; - - m_pNgenLayout = pModule->GetNGenLayoutInfo(); - - m_fHotMethodsDone = FALSE; - m_CurrentRuntimeFunctionIndex = -1; - m_CurrentColdRuntimeFunctionIndex = 0; -} - -BOOL MethodIterator::Next() -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; - - m_CurrentRuntimeFunctionIndex ++; - - if (!m_fHotMethodsDone) - { - //iterate the hot methods - if (methodIteratorOptions & Hot) - { -#ifdef FEATURE_EH_FUNCLETS - //Skip to the next method. - // skip over method fragments and funclets. - while (m_CurrentRuntimeFunctionIndex < m_pNgenLayout->m_nRuntimeFunctions[0]) - { - if (m_pNgenLayout->m_MethodDescs[0][m_CurrentRuntimeFunctionIndex] != 0) - return TRUE; - m_CurrentRuntimeFunctionIndex++; - } -#else - if (m_CurrentRuntimeFunctionIndex < m_pNgenLayout->m_nRuntimeFunctions[0]) - return TRUE; -#endif - } - m_CurrentRuntimeFunctionIndex = 0; - m_fHotMethodsDone = TRUE; - } - - if (methodIteratorOptions & Unprofiled) - { -#ifdef FEATURE_EH_FUNCLETS - //Skip to the next method. - // skip over method fragments and funclets. - while (m_CurrentRuntimeFunctionIndex < m_pNgenLayout->m_nRuntimeFunctions[1]) - { - if (m_pNgenLayout->m_MethodDescs[1][m_CurrentRuntimeFunctionIndex] != 0) - return TRUE; - m_CurrentRuntimeFunctionIndex++; - } -#else - if (m_CurrentRuntimeFunctionIndex < m_pNgenLayout->m_nRuntimeFunctions[1]) - return TRUE; -#endif - } - - return FALSE; -} - -PTR_MethodDesc MethodIterator::GetMethodDesc() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - return NativeUnwindInfoLookupTable::GetMethodDesc(m_pNgenLayout, GetRuntimeFunction(), m_ModuleBase); -} - -GCInfoToken MethodIterator::GetGCInfoToken() -{ - LIMITED_METHOD_CONTRACT; - - // get the gc info from the RT function - SIZE_T size; - PTR_VOID pUnwindData = GetUnwindDataBlob(m_ModuleBase, GetRuntimeFunction(), &size); - PTR_VOID gcInfo = (PTR_VOID)((PTR_BYTE)pUnwindData + size); - // MethodIterator is used to iterate over methods of an NgenImage. - // So, GcInfo version is always current - return{ gcInfo, GCINFO_VERSION }; -} - -TADDR MethodIterator::GetMethodStartAddress() -{ - LIMITED_METHOD_CONTRACT; - - return m_ModuleBase + RUNTIME_FUNCTION__BeginAddress(GetRuntimeFunction()); -} - -TADDR MethodIterator::GetMethodColdStartAddress() -{ - LIMITED_METHOD_CONTRACT; - - PTR_RUNTIME_FUNCTION CurrentFunctionEntry = GetRuntimeFunction(); - - // - // Catch up with hot code - // - for ( ; m_CurrentColdRuntimeFunctionIndex < m_pNgenLayout->m_nRuntimeFunctions[2]; m_CurrentColdRuntimeFunctionIndex++) - { - PTR_RUNTIME_FUNCTION ColdFunctionEntry = m_pNgenLayout->m_pRuntimeFunctions[2] + m_CurrentColdRuntimeFunctionIndex; - - PTR_RUNTIME_FUNCTION FunctionEntry; - -#ifdef FEATURE_EH_FUNCLETS - DWORD MainFunctionEntryRVA = m_pNgenLayout->m_ColdCodeMap[m_CurrentColdRuntimeFunctionIndex].mainFunctionEntryRVA; - - if (MainFunctionEntryRVA == 0) - continue; - - FunctionEntry = dac_cast(m_ModuleBase + MainFunctionEntryRVA); -#else - DWORD ColdUnwindData = ColdFunctionEntry->UnwindData; - _ASSERTE((ColdUnwindData & RUNTIME_FUNCTION_INDIRECT) != 0); - FunctionEntry = dac_cast(m_ModuleBase + (ColdUnwindData & ~RUNTIME_FUNCTION_INDIRECT)); -#endif - - if (CurrentFunctionEntry == FunctionEntry) - { - // we found a match - return m_ModuleBase + RUNTIME_FUNCTION__BeginAddress(ColdFunctionEntry); - } - else - if (CurrentFunctionEntry < FunctionEntry) - { - // method does not have cold code - return NULL; - } - } - - return NULL; -} - -PTR_RUNTIME_FUNCTION MethodIterator::GetRuntimeFunction() -{ - LIMITED_METHOD_DAC_CONTRACT; - _ASSERTE(m_CurrentRuntimeFunctionIndex >= 0); - _ASSERTE(m_CurrentRuntimeFunctionIndex < (m_fHotMethodsDone ? m_pNgenLayout->m_nRuntimeFunctions[1] : m_pNgenLayout->m_nRuntimeFunctions[0])); - return (m_fHotMethodsDone ? m_pNgenLayout->m_pRuntimeFunctions[1] : m_pNgenLayout->m_pRuntimeFunctions[0]) + m_CurrentRuntimeFunctionIndex; -} - -ULONG MethodIterator::GetHotCodeSize() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(GetMethodColdStartAddress() != NULL); - return m_pNgenLayout->m_ColdCodeMap[m_CurrentColdRuntimeFunctionIndex].hotCodeSize; -} - -void MethodIterator::GetMethodRegionInfo(IJitManager::MethodRegionInfo *methodRegionInfo) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; - - methodRegionInfo->hotStartAddress = GetMethodStartAddress(); - methodRegionInfo->coldStartAddress = GetMethodColdStartAddress(); - GCInfoToken gcInfoToken = GetGCInfoToken(); - methodRegionInfo->hotSize = ExecutionManager::GetNativeImageJitManager()->GetCodeManager()->GetFunctionSize(gcInfoToken); - methodRegionInfo->coldSize = 0; - - if (methodRegionInfo->coldStartAddress != NULL) - { - // - // At this point methodRegionInfo->hotSize is set to the total size of - // the method obtained from the GC info (we set that in the init code above). - // Use that and pCMH->hotCodeSize to compute the hot and cold code sizes. - // - - ULONG hotCodeSize = GetHotCodeSize(); - - methodRegionInfo->coldSize = methodRegionInfo->hotSize - hotCodeSize; - methodRegionInfo->hotSize = hotCodeSize; - } -} - -#endif // FEATURE_PREJIT - - - -#ifdef FEATURE_READYTORUN //*************************************************************************************** //*************************************************************************************** diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index e5b9e6fb2205b7..ae55cdc367c8bd 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -1263,14 +1263,6 @@ class ExecutionManager return m_pEEJitManager; } -#ifdef FEATURE_PREJIT - static NativeImageJitManager * GetNativeImageJitManager() - { - LIMITED_METHOD_DAC_CONTRACT; - return m_pNativeImageJitManager; - } -#endif - #ifdef FEATURE_READYTORUN static ReadyToRunJitManager * GetReadyToRunJitManager() { @@ -1336,9 +1328,6 @@ class ExecutionManager SPTR_DECL(EECodeManager, m_pDefaultCodeMan); SPTR_DECL(EEJitManager, m_pEEJitManager); -#ifdef FEATURE_PREJIT - SPTR_DECL(NativeImageJitManager, m_pNativeImageJitManager); -#endif #ifdef FEATURE_READYTORUN SPTR_DECL(ReadyToRunJitManager, m_pReadyToRunJitManager); #endif @@ -1509,96 +1498,7 @@ inline void EEJitManager::JitTokenToMethodRegionInfo(const METHODTOKEN& MethodTo methodRegionInfo->coldSize = 0; } - -//----------------------------------------------------------------------------- -#ifdef FEATURE_PREJIT - -//***************************************************************************** -// Stub JitManager for Managed native. - -class NativeImageJitManager : public IJitManager -{ - VPTR_VTABLE_CLASS(NativeImageJitManager, IJitManager) - -public: -#ifndef DACCESS_COMPILE - NativeImageJitManager(); -#endif // #ifndef DACCESS_COMPILE - - virtual DWORD GetCodeType() - { - LIMITED_METHOD_DAC_CONTRACT; - return (miManaged | miNative); - } - - // Used to read debug info. - virtual BOOL GetBoundariesAndVars( - const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, - OUT ULONG32 * pcMap, - OUT ICorDebugInfo::OffsetMapping **ppMap, - OUT ULONG32 * pcVars, - OUT ICorDebugInfo::NativeVarInfo **ppVars); - - virtual BOOL JitCodeToMethodInfo(RangeSection * pRangeSection, - PCODE currentPC, - MethodDesc ** ppMethodDesc, - EECodeInfo * pCodeInfo); - - virtual PCODE GetCodeAddressForRelOffset(const METHODTOKEN& MethodToken, DWORD relOffset); - - static PTR_Module JitTokenToZapModule(const METHODTOKEN& MethodToken); - virtual TADDR JitTokenToStartAddress(const METHODTOKEN& MethodToken); - virtual void JitTokenToMethodRegionInfo(const METHODTOKEN& MethodToken, MethodRegionInfo * methodRegionInfo); - - virtual unsigned InitializeEHEnumeration(const METHODTOKEN& MethodToken, EH_CLAUSE_ENUMERATOR* pEnumState); - - virtual PTR_EXCEPTION_CLAUSE_TOKEN GetNextEHClause(EH_CLAUSE_ENUMERATOR* pEnumState, - EE_ILEXCEPTION_CLAUSE* pEHclause); - -#ifndef DACCESS_COMPILE - virtual TypeHandle ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause, - CrawlFrame *pCf); -#endif // #ifndef DACCESS_COMPILE - - virtual GCInfoToken GetGCInfoToken(const METHODTOKEN& MethodToken); - -#if defined(FEATURE_EH_FUNCLETS) - virtual PTR_RUNTIME_FUNCTION LazyGetFunctionEntry(EECodeInfo * pCodeInfo); - - virtual TADDR GetFuncletStartAddress(EECodeInfo * pCodeInfo); - virtual DWORD GetFuncletStartOffsets(const METHODTOKEN& MethodToken, DWORD* pStartFuncletOffsets, DWORD dwLength); - virtual BOOL IsFilterFunclet(EECodeInfo * pCodeInfo); -#endif // FEATURE_EH_FUNCLETS - - virtual StubCodeBlockKind GetStubCodeBlockKind(RangeSection * pRangeSection, PCODE currentPC); - -#if defined(DACCESS_COMPILE) - virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); - virtual void EnumMemoryRegionsForMethodDebugInfo(CLRDataEnumMemoryFlags flags, MethodDesc * pMD); -#if defined(FEATURE_EH_FUNCLETS) - // Enumerate the memory necessary to retrieve the unwind info for a specific method - virtual void EnumMemoryRegionsForMethodUnwindInfo(CLRDataEnumMemoryFlags flags, EECodeInfo * pCodeInfo); -#endif //FEATURE_EH_FUNCLETS -#endif //DACCESS_COMPILE -}; - -inline TADDR NativeImageJitManager::JitTokenToStartAddress(const METHODTOKEN& MethodToken) -{ - CONTRACTL{ - NOTHROW; - GC_NOTRIGGER; - HOST_NOCALLS; - SUPPORTS_DAC; - } CONTRACTL_END; - - return JitTokenToModuleBase(MethodToken) + - RUNTIME_FUNCTION__BeginAddress(dac_cast(MethodToken.m_pCodeHeader)); -} - -#endif // FEATURE_PREJIT - -#if defined(FEATURE_PREJIT) || defined(FEATURE_READYTORUN) +#if defined(FEATURE_READYTORUN) class NativeExceptionInfoLookupTable { @@ -1616,17 +1516,9 @@ class NativeUnwindInfoLookupTable PTR_RUNTIME_FUNCTION pRuntimeFunctionTable, int StartIndex, int EndIndex); - -#ifdef FEATURE_PREJIT - static BOOL HasExceptionInfo(NGenLayoutInfo * pNgenLayout, PTR_RUNTIME_FUNCTION pMainRuntimeFunction); - static PTR_MethodDesc GetMethodDesc(NGenLayoutInfo * pNgenLayout, PTR_RUNTIME_FUNCTION pMainRuntimeFunction, TADDR moduleBase); - -private: - static DWORD GetMethodDescRVA(NGenLayoutInfo * pNgenLayout, PTR_RUNTIME_FUNCTION pMainRuntimeFunction); -#endif }; -#endif // FEATURE_PREJIT || FEATURE_READYTORUN +#endif // FEATURE_READYTORUN #ifdef FEATURE_READYTORUN @@ -1715,9 +1607,6 @@ class ReadyToRunJitManager final: public IJitManager class EECodeInfo { friend BOOL EEJitManager::JitCodeToMethodInfo(RangeSection * pRangeSection, PCODE currentPC, MethodDesc** ppMethodDesc, EECodeInfo * pCodeInfo); -#ifdef FEATURE_PREJIT - friend BOOL NativeImageJitManager::JitCodeToMethodInfo(RangeSection * pRangeSection, PCODE currentPC, MethodDesc** ppMethodDesc, EECodeInfo * pCodeInfo); -#endif #ifdef FEATURE_READYTORUN friend BOOL ReadyToRunJitManager::JitCodeToMethodInfo(RangeSection * pRangeSection, PCODE currentPC, MethodDesc** ppMethodDesc, EECodeInfo * pCodeInfo); #endif @@ -1853,52 +1742,6 @@ class EECodeInfo #include "codeman.inl" - -#ifdef FEATURE_PREJIT -class MethodSectionIterator; - -// -// MethodIterator class is used to iterate all the methods in an ngen image. -// It will match and report hot (and cold, if any) sections of a method at the same time. -// GcInfo version is always current -class MethodIterator -{ -public: - enum MethodIteratorOptions - { - Hot = 0x1, - Unprofiled =0x2, - All = Hot | Unprofiled - }; -private: - TADDR m_ModuleBase; - MethodIteratorOptions methodIteratorOptions; - - NGenLayoutInfo * m_pNgenLayout; - BOOL m_fHotMethodsDone; - COUNT_T m_CurrentRuntimeFunctionIndex; - COUNT_T m_CurrentColdRuntimeFunctionIndex; - - void Init(PTR_Module pModule, PEDecoder * pPEDecoder, MethodIteratorOptions mio); - - public: - MethodIterator(PTR_Module pModule, MethodIteratorOptions mio = All); - MethodIterator(PTR_Module pModule, PEDecoder * pPEDecoder, MethodIteratorOptions mio = All); - - BOOL Next(); - - PTR_MethodDesc GetMethodDesc(); - GCInfoToken GetGCInfoToken(); - TADDR GetMethodStartAddress(); - TADDR GetMethodColdStartAddress(); - ULONG GetHotCodeSize(); - - PTR_RUNTIME_FUNCTION GetRuntimeFunction(); - - void GetMethodRegionInfo(IJitManager::MethodRegionInfo *methodRegionInfo); -}; -#endif //FEATURE_PREJIT - void ThrowOutOfMemoryWithinRange(); #endif // !__CODEMAN_HPP__ diff --git a/src/coreclr/vm/coreassemblyspec.cpp b/src/coreclr/vm/coreassemblyspec.cpp index dc0b00779ae194..dde610bb36c2ce 100644 --- a/src/coreclr/vm/coreassemblyspec.cpp +++ b/src/coreclr/vm/coreassemblyspec.cpp @@ -169,30 +169,13 @@ STDAPI BinderAcquirePEImage(LPCWSTR wszAssemblyPath, PEImageHolder pImage = NULL; PEImageHolder pNativeImage = NULL; -#ifdef FEATURE_PREJIT - // fExplicitBindToNativeImage is set on Phone when we bind to a list of native images and have no IL on device for an assembly - if (fExplicitBindToNativeImage) - { - pNativeImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_TrustedNativeImage, bundleFileLocation); + pImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_Default, bundleFileLocation); - // Make sure that the IL image can be opened if the native image is not available. - hr=pNativeImage->TryOpenFile(); - if (FAILED(hr)) - { - goto Exit; - } - } - else -#endif + // Make sure that the IL image can be opened if the native image is not available. + hr=pImage->TryOpenFile(); + if (FAILED(hr)) { - pImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_Default, bundleFileLocation); - - // Make sure that the IL image can be opened if the native image is not available. - hr=pImage->TryOpenFile(); - if (FAILED(hr)) - { - goto Exit; - } + goto Exit; } if (pImage) @@ -259,16 +242,7 @@ STDAPI BinderAcquireImport(PEImage *pPEImage, if (!pLayout->CheckFormat()) IfFailGo(COR_E_BADIMAGEFORMAT); -#ifdef FEATURE_PREJIT - if (bNativeImage && pPEImage->IsNativeILILOnly()) - { - pPEImage->GetNativeILPEKindAndMachine(&pdwPAFlags[0], &pdwPAFlags[1]); - } - else -#endif - { - pPEImage->GetPEKindAndMachine(&pdwPAFlags[0], &pdwPAFlags[1]); - } + pPEImage->GetPEKindAndMachine(&pdwPAFlags[0], &pdwPAFlags[1]); *ppIAssemblyMetaDataImport = pPEImage->GetMDImport(); if (!*ppIAssemblyMetaDataImport) diff --git a/src/coreclr/vm/coreclr/corebindresult.h b/src/coreclr/vm/coreclr/corebindresult.h index d47f84eb498dac..6bdab23e42a057 100644 --- a/src/coreclr/vm/coreclr/corebindresult.h +++ b/src/coreclr/vm/coreclr/corebindresult.h @@ -42,15 +42,9 @@ struct CoreBindResult : public IUnknown PEImage* GetPEImage(); BOOL IsCoreLib(); void GetBindAssembly(BINDER_SPACE::Assembly** ppAssembly); -#ifdef FEATURE_PREJIT - BOOL HasNativeImage(); - PEImage* GetNativeImage(); - void SetNativeImage(PEImage * pNativeImage); - PEImage* GetILImage(); -#else BOOL HasNativeImage() { return FALSE; } PEImage* GetNativeImage() { return NULL; } -#endif + void SetHRBindResult(HRESULT hrBindResult); HRESULT GetHRBindResult(); }; diff --git a/src/coreclr/vm/coreclr/corebindresult.inl b/src/coreclr/vm/coreclr/corebindresult.inl index c40f3810d23dcf..2302b1cd24b284 100644 --- a/src/coreclr/vm/coreclr/corebindresult.inl +++ b/src/coreclr/vm/coreclr/corebindresult.inl @@ -73,27 +73,6 @@ inline void CoreBindResult::Reset() m_pAssembly=NULL; m_hrBindResult = S_OK; } -#ifdef FEATURE_PREJIT -inline BOOL CoreBindResult::HasNativeImage() -{ - LIMITED_METHOD_CONTRACT; - return m_pAssembly->GetNativePEImage() != NULL; -} -inline PEImage* CoreBindResult::GetNativeImage() -{ - WRAPPER_NO_CONTRACT; - _ASSERTE(HasNativeImage()); - return m_pAssembly->GetNativePEImage(); -} - -inline PEImage* CoreBindResult::GetILImage() -{ - WRAPPER_NO_CONTRACT; - return m_pAssembly ? - m_pAssembly->GetPEImage(): - NULL; -}; -#endif inline void CoreBindResult::SetHRBindResult(HRESULT hrBindResult) { diff --git a/src/coreclr/vm/dataimage.h b/src/coreclr/vm/dataimage.h index 3e23e031906e1d..8f447acc211d5f 100644 --- a/src/coreclr/vm/dataimage.h +++ b/src/coreclr/vm/dataimage.h @@ -16,513 +16,4 @@ // Special NGEN-specific relocation type for relative pointer (used to make NGen relocation section smaller) #define IMAGE_REL_BASED_RELPTR 0x7D -#if defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE) - -// All we really need is to pre-declare the PrecodeType enum, but g++ doesn't -// support enum pre-declaration, so we need to include the declaration itself. -/*#include "cgensys.h" // needed to include precode.h*/ -#include "precode.h" - -typedef BYTE ZapRelocationType; // IMAGE_REL_XXX enum - -class CEEPreloader; - -class ZapImage; -class TypeHandleList; - -class ZapNode; -class ZapStoredStructure; - -class ZapHeap; -void *operator new(size_t size, ZapHeap * pZapHeap); -void *operator new[](size_t size, ZapHeap * pZapHeap); - -class InternedStructureTraits; -typedef SHash InternedStructureHashTable; - -struct LookupMapBase; -class InlineTrackingMap; - -class DataImage -{ -public: - // - // As items are recorded for saving we note some information about the item - // to help guide later heuristics. - // - enum ItemKind - { - #define DEFINE_ITEM_KIND(id) id, - #include "dataimagesection.h" - - ITEM_COUNT, - }; - - Module *m_module; - CEEPreloader *m_preloader; - ZapImage * m_pZapImage; - - struct StructureEntry - { - const void * ptr; - ZapNode * pNode; - SSIZE_T offset; - }; - - class StructureTraits : public NoRemoveSHashTraits< DefaultSHashTraits > - { - public: - typedef const void * key_t; - - static key_t GetKey(element_t e) - { - LIMITED_METHOD_CONTRACT; - return e.ptr; - } - static BOOL Equals(key_t k1, key_t k2) - { - LIMITED_METHOD_CONTRACT; - return (k1 == k2); - } - static count_t Hash(key_t k) - { - LIMITED_METHOD_CONTRACT; - return (count_t)(size_t)k; - } - - static const element_t Null() { LIMITED_METHOD_CONTRACT; StructureEntry e; e.ptr = NULL; return e; } - static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.ptr == NULL; } - }; - typedef SHash StructureHashTable; - - StructureHashTable m_structures; - const StructureEntry * m_pLastLookup; // Cached result of last lookup - - #define MAINTAIN_SAVE_ORDER (0xFFFFFFFF) - - struct SavedNodeEntry - { - ZapNode * pNode; - DWORD dwAssociatedOrder; - }; - - // These are added in save order, however after PlaceRemainingStructures they may have been - // rearranged based on the class layout order stored in the dwAssociatedOrder field. - SArray m_structuresInOrder; - - void AddStructureInOrder(ZapNode *pNode, BOOL fMaintainSaveOrder = FALSE); - - struct FixupEntry - { - ZapRelocationType m_type; - DWORD m_offset; -#ifdef _DEBUG - DWORD m_ordinal; -#endif // _DEBUG - - ZapStoredStructure * m_pLocation; - ZapNode * m_pTargetNode; - }; - - SArray m_Fixups; - COUNT_T m_iCurrentFixup; - - void AppendFixup(FixupEntry entry) - { -#ifdef _DEBUG - static DWORD s_ordinal = 1; - entry.m_ordinal = s_ordinal++; -#endif // _DEBUG - m_Fixups.Append(entry); - } - - static int __cdecl fixupEntryCmp(const void* a_, const void* b_); - - void FixupSectionRange(SIZE_T offset, ZapNode * pNode); - void FixupSectionPtr(SIZE_T offset, ZapNode * pNode); - void FixupJumpStubPtr(SIZE_T offset, CorInfoHelpFunc ftnNum); - - void FixupModuleRVAs(); - - InternedStructureHashTable * m_pInternedStructures; - SetSHash m_reusedStructures; - - struct RvaInfoStructure - { - FieldDesc * pFD; - DWORD rva; - UINT size; - UINT align; - }; - - SArray m_rvaInfoVector; - - static int __cdecl rvaInfoVectorEntryCmp(const void* a_, const void* b_); - - MapSHash m_surrogates; - - // Often set while a class is being saved in order to associate - // stored structures with the class, and therefore its layout order. - // Note that it is a best guess and not always set. - MethodTable * m_pCurrentAssociatedMethodTable; - - struct MethodProfilingData - { - MethodDesc *pMD; - DWORD flags; - }; - - class MethodProfilingDataTraits : public NoRemoveSHashTraits< DefaultSHashTraits > - { - public: - typedef const MethodDesc * key_t; - - static key_t GetKey(element_t e) - { - LIMITED_METHOD_CONTRACT; - return e.pMD; - } - static BOOL Equals(key_t k1, key_t k2) - { - LIMITED_METHOD_CONTRACT; - return (k1 == k2); - } - static count_t Hash(key_t k) - { - LIMITED_METHOD_CONTRACT; - return (count_t)(size_t)k; - } - - static const element_t Null() { LIMITED_METHOD_CONTRACT; MethodProfilingData e; e.pMD = NULL; e.flags = 0; return e; } - static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pMD == NULL; } - }; - typedef SHash MethodProfilingDataHashTable; - - MethodProfilingDataHashTable m_methodProfilingData; - - // This is a hashmap from inlinee method to an array of inliner methods - // So it can answer question: "where did this method get inlined ?" - InlineTrackingMap *m_inlineTrackingMap; - - public: - DataImage(Module *module, CEEPreloader *preloader); - ~DataImage(); - - void Preallocate(); - - void PreSave(); - void PostSave(); - - Module *GetModule() { LIMITED_METHOD_CONTRACT; return m_module; } - - DWORD GetMethodProfilingFlags(MethodDesc * pMD); - void SetMethodProfilingFlags(MethodDesc * pMD, DWORD flags); - - CEEPreloader *GetPreloader() { LIMITED_METHOD_CONTRACT; return m_preloader; } - - ZapHeap * GetHeap(); - - // - // Data is stored in the image store in three phases. - // - - // - // In the first phase, all objects are assigned locations in the - // data store. This is done by calling StoreStructure on all - // structures which are being stored into the image. - // - // This would typically done by methods on the objects themselves, - // each of which stores itself and any objects it references. - // Reference loops must be explicitly tested for using IsStored. - // (Each structure can be stored only once.) - // - // Note that StoreStructure makes no guarantees about layout order. - // If you want structures of a particular kind to be laid out in - // the order they are saved, use StoreStructureInOrder. - // - - inline ZapStoredStructure * StoreStructure(const void *data, SIZE_T size, - ItemKind kind, - int align = sizeof(TADDR)) - { - return StoreStructureHelper(data, size, kind, align, FALSE); - } - - inline ZapStoredStructure * StoreStructureInOrder(const void *data, SIZE_T size, - ItemKind kind, - int align = sizeof(TADDR)) - { - return StoreStructureHelper(data, size, kind, align, TRUE); - } - - ZapStoredStructure * StoreStructureHelper(const void *data, SIZE_T size, - ItemKind kind, - int align, - BOOL fMaintainSaveOrder); - - // Often set while a class is being saved in order to associate - // stored structures with the class, and therefore its layout order. - // Note that it is a best guess and not always set. - inline void BeginAssociatingStoredObjectsWithMethodTable(MethodTable *pMT) - { - m_pCurrentAssociatedMethodTable = pMT; - } - - inline void EndAssociatingStoredObjectsWithMethodTable() - { - m_pCurrentAssociatedMethodTable = NULL; - } - - // Bind pointer to the relative offset in ZapNode - void BindPointer(const void *p, ZapNode * pNode, SSIZE_T offset); - - void BindPointer(const void *p, ZapStoredStructure * pNode, SSIZE_T offset) - { - BindPointer(p, (ZapNode *)pNode, offset); - } - - void CopyData(ZapStoredStructure * pNode, const void * p, ULONG size); - void CopyDataToOffset(ZapStoredStructure * pNode, ULONG offset, const void * p, ULONG size); - - // - // In the second phase, data is arranged in the image by successive calls - // to PlaceMappedRange. Items are arranged using pointers to data structures in the - // original heap, or by giving a StoredStructure along with the original - // mapping. - // - - // Concrete mapped ranges are the ones that actually correspond to allocations - // of new space within the image. They should be placed first. We do not - // necessarily populate the space in the image (i.e. copy the data to the image) - // from the concrete range: for example the space associated with a - // combo structure gets filled by copying the data from the individual items - // that make up the parts of the combo structure. - // - // These can tolerate placing the same item multiple times - // PlaceInternedStructureForAddress allows a different section to be used depending on - // whether an interned structure actually had duplicates in this image. - // - void PlaceStructureForAddress(const void * data, CorCompileSection section); - void PlaceInternedStructureForAddress(const void * data, CorCompileSection sectionIfReused, CorCompileSection sectionIfSingleton); - - void FixupPointerField(PVOID p, SSIZE_T offset); - void FixupRelativePointerField(PVOID p, SSIZE_T offset); - - template - void FixupPlainOrRelativePointerField(const T *base, const RelativePointer T::* pPointerFieldMember) - { - STANDARD_VM_CONTRACT; - SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; - FixupRelativePointerField((PVOID)base, offset); - } - - template - void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const RelativePointer C::* pSecondPointerFieldMember) - { - STANDARD_VM_CONTRACT; - const RelativePointer *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember); - SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base; - FixupRelativePointerField((PVOID)base, offset); - } - - template - void FixupPlainOrRelativePointerField(const T *base, const PlainPointer T::* pPointerFieldMember) - { - STANDARD_VM_CONTRACT; - SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; - FixupPointerField((PVOID)base, offset); - } - - template - void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const PlainPointer C::* pSecondPointerFieldMember) - { - STANDARD_VM_CONTRACT; - const PlainPointer *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember); - SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base; - FixupPointerField((PVOID)base, offset); - } - - void FixupField(PVOID p, SSIZE_T offset, PVOID pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR); - - template - void FixupPlainOrRelativeField(const T *base, const RelativePointer T::* pPointerFieldMember, PVOID pTarget, SSIZE_T targetOffset = 0) - { - STANDARD_VM_CONTRACT; - SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; - FixupField((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_RELPTR); - } - - template - void FixupPlainOrRelativeField(const T *base, const PlainPointer T::* pPointerFieldMember, PVOID pTarget, SSIZE_T targetOffset = 0) - { - STANDARD_VM_CONTRACT; - SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; - FixupField((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_PTR); - } - - void FixupFieldToNode(PVOID p, SSIZE_T offset, ZapNode * pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR); - - void FixupFieldToNode(PVOID p, SSIZE_T offset, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR) - { - return FixupFieldToNode(p, offset, (ZapNode *)pTarget, targetOffset, type); - } - - template - void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer T::* pPointerFieldMember, ZapNode * pTarget, SSIZE_T targetOffset = 0) - { - STANDARD_VM_CONTRACT; - SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; - FixupFieldToNode((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_RELPTR); - } - - template - void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0) - { - return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset); - } - - template - void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer T::* pPointerFieldMember, ZapNode * pTarget, SSIZE_T targetOffset = 0) - { - STANDARD_VM_CONTRACT; - SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; - FixupFieldToNode((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_PTR); - } - - template - void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0) - { - return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset); - } - - BOOL IsStored(const void *data) - { WRAPPER_NO_CONTRACT; return m_structures.LookupPtr(data) != NULL; } - - DWORD GetRVA(const void *data); - - void ZeroField(PVOID p, SSIZE_T offset, SIZE_T size); - void *GetImagePointer(ZapStoredStructure * pNode); - void *GetImagePointer(PVOID p, SSIZE_T offset = 0); - ZapNode * GetNodeForStructure(PVOID p, SSIZE_T * pOffset); - - void ZeroPointerField(PVOID p, SSIZE_T offset) - { WRAPPER_NO_CONTRACT; ZeroField(p, offset, sizeof(void*)); } - - - ZapStoredStructure * StoreInternedStructure(const void *data, ULONG size, - ItemKind kind, - int align = sizeof(TADDR)); - - void NoteReusedStructure(const void *data); - - void StoreRvaInfo(FieldDesc * pFD, - DWORD rva, - UINT size, - UINT align); - - void SaveRvaStructure(); - void FixupRvaStructure(); - - // Surrogates are used to reorganize the data before they are saved. RegisterSurrogate and LookupSurrogate - // maintains mapping from the original data to the reorganized data. - void RegisterSurrogate(PVOID ptr, PVOID surrogate); - PVOID LookupSurrogate(PVOID ptr); - - void PlaceRemainingStructures(); - - void FixupRVAs(); - - void SetRVAsForFields(IMetaDataEmit * pEmit); - - // Called when data contains a function address. The data store - // can return a fixed compiled code address if it is compiling - // code for the module. - ZapNode * GetCodeAddress(MethodDesc * method); - - // Returns TRUE if the method can be called directly without going through prestub - BOOL CanDirectCall(MethodDesc * method, CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY); - - // Returns the method fixup info if it has one, NULL if method has no fixup info - ZapNode * GetFixupList(MethodDesc * method); - - ZapNode * GetHelperThunk(CorInfoHelpFunc ftnNum); - - // pUniqueId is used to allocate unique cells for cases where we cannot use the shared cell. - ZapNode * GetTypeHandleImport(TypeHandle th, PVOID pUniqueId = NULL); - ZapNode * GetMethodHandleImport(MethodDesc * pMD); - ZapNode * GetFieldHandleImport(FieldDesc * pFD); - ZapNode * GetModuleHandleImport(Module * pModule); - DWORD GetModuleImportIndex(Module * pModule); - - ZapNode * GetExistingTypeHandleImport(TypeHandle th); - ZapNode * GetExistingMethodHandleImport(MethodDesc * pMD); - ZapNode * GetExistingFieldHandleImport(FieldDesc * pFD); - - ZapNode * GetVirtualImportThunk(MethodTable * pMT, MethodDesc * pMD, int slotNumber); - - ZapNode * GetGenericSignature(PVOID signature, BOOL fMethod); - - void SavePrecode(PVOID ptr, MethodDesc * pMD, PrecodeType t, ItemKind kind, BOOL fIsPrebound = FALSE); - - void StoreCompressedLayoutMap(LookupMapBase *pMap, ItemKind kind); - - // "Fixup" here means "save the pointer either as a poiter or indirection" - void FixupModulePointer(Module * pModule, PVOID p, SSIZE_T offset, ZapRelocationType type); - void FixupMethodTablePointer(MethodTable * pMT, PVOID p, SSIZE_T offset, ZapRelocationType type); - void FixupTypeHandlePointer(TypeHandle th, PVOID p, SSIZE_T offset, ZapRelocationType type); - void FixupMethodDescPointer(MethodDesc * pMD, PVOID p, SSIZE_T offset, ZapRelocationType type); - void FixupFieldDescPointer(FieldDesc * pFD, PVOID p, SSIZE_T offset, ZapRelocationType type); - - void FixupModulePointer(PVOID p, FixupPointer * ppModule); - void FixupMethodTablePointer(PVOID p, FixupPointer * ppMT); - void FixupTypeHandlePointer(PVOID p, FixupPointer * pth); - void FixupMethodDescPointer(PVOID p, FixupPointer * ppMD); - void FixupFieldDescPointer(PVOID p, FixupPointer * ppFD); - - void FixupModulePointer(PVOID p, RelativeFixupPointer * ppModule); - void FixupMethodTablePointer(PVOID p, RelativeFixupPointer * ppMT); - void FixupTypeHandlePointer(PVOID p, RelativeFixupPointer * pth); - void FixupMethodDescPointer(PVOID p, RelativeFixupPointer * ppMD); - void FixupFieldDescPointer(PVOID p, RelativeFixupPointer * ppFD); - - // "HardBind" here means "save a reference using a (relocatable) pointer, - // where the object we're referring to lives either in an external hard-bound DLL - // or in the image currently being saved" - // - BOOL CanHardBindToZapModule(Module *targetModule); - - void ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee); - InlineTrackingMap *GetInlineTrackingMap(); - -private: - BOOL CanEagerBindTo(Module *targetModule, Module *pPreferredZapModule, void *address); - -public: - // "EagerBind" here means "save a reference using pointer in the image currently being saved - // or indirection cell refering to to external DLL - BOOL CanEagerBindToTypeHandle(TypeHandle th, BOOL fRequirePrerestore = FALSE, TypeHandleList *pVisited = NULL); - BOOL CanEagerBindToMethodTable(MethodTable *pMT, BOOL fRequirePrerestore = FALSE, TypeHandleList *pVisited = NULL); - BOOL CanEagerBindToMethodDesc(MethodDesc *pMD, BOOL fRequirePrerestore = FALSE, TypeHandleList *pVisited = NULL); - BOOL CanEagerBindToFieldDesc(FieldDesc *pFD, BOOL fRequirePrerestore = FALSE, TypeHandleList *pVisited = NULL); - BOOL CanEagerBindToModule(Module *pModule); - - // These also check that the target object doesn't need a restore action - // upon reload. - BOOL CanPrerestoreEagerBindToTypeHandle(TypeHandle th, TypeHandleList *pVisited); - BOOL CanPrerestoreEagerBindToMethodTable(MethodTable *pMT, TypeHandleList *pVisited); - BOOL CanPrerestoreEagerBindToMethodDesc(MethodDesc *pMD, TypeHandleList *pVisited); - - void HardBindTypeHandlePointer(PVOID p, SSIZE_T offset); - - // This is obsolete in-place fixup that we should get rid of. For now, it is used for: - // - FnPtrTypeDescs. These should not be stored in NGen images at all. - // - stubs-as-il signatures. These should use tokens when stored in NGen image. - void FixupTypeHandlePointerInPlace(PVOID p, SSIZE_T offset, BOOL fForceFixup = FALSE); - - void BeginRegion(CorInfoRegionKind regionKind); - void EndRegion(CorInfoRegionKind regionKind); -}; - -#endif // FEATURE_PREJIT && !DACCESS_COMPILE - #endif // _DATAIMAGE_H_ diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index aefb674d37e24a..405e009bd4777e 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -5475,13 +5475,7 @@ MethodDesc* GetStubMethodDescFromInteropMethodDesc(MethodDesc* pMD, DWORD dwStub #ifdef FEATURE_COMINTEROP if (SF_IsReverseCOMStub(dwStubFlags)) { -#ifdef FEATURE_PREJIT - // reverse COM stubs live in a hash table - StubMethodHashTable *pHash = pMD->GetLoaderModule()->GetStubMethodHashTable(); - return (pHash == NULL ? NULL : pHash->FindMethodDesc(pMD)); -#else return NULL; -#endif } else #endif // FEATURE_COMINTEROP @@ -5757,37 +5751,6 @@ MethodDesc* RestoreNGENedStub(MethodDesc* pStubMD) } CONTRACTL_END; -#ifdef FEATURE_PREJIT - pStubMD->CheckRestore(); - - PCODE pCode = pStubMD->GetPreImplementedCode(); - if (pCode != NULL) - { - TADDR pFixupList = pStubMD->GetFixupList(); - if (pFixupList != NULL) - { - Module* pZapModule = pStubMD->GetZapModule(); - _ASSERTE(pZapModule != NULL); - if (!pZapModule->FixupDelayList(pFixupList)) - { - _ASSERTE(!"FixupDelayList failed"); - ThrowHR(COR_E_BADIMAGEFORMAT); - } - } - -#if defined(HAVE_GCCOVER) - if (GCStress::IsEnabled()) - SetupGcCoverage(NativeCodeVersion(pStubMD), (BYTE*)pCode); -#endif // HAVE_GCCOVER - - } - else - { - // We only pass a non-NULL pStubMD to GetStubForILStub() below if pStubMD is preimplemeneted. - pStubMD = NULL; - } -#endif // FEATURE_PREJIT - return pStubMD; } diff --git a/src/coreclr/vm/domainfile.cpp b/src/coreclr/vm/domainfile.cpp index 646bc10fee1192..fb334f8fc5610a 100644 --- a/src/coreclr/vm/domainfile.cpp +++ b/src/coreclr/vm/domainfile.cpp @@ -358,26 +358,6 @@ BOOL DomainAssembly::IsVisibleToDebugger() } #ifndef DACCESS_COMPILE -#ifdef FEATURE_PREJIT -void DomainFile::ExternalLog(DWORD level, const WCHAR *fmt, ...) -{ - WRAPPER_NO_CONTRACT; - - va_list args; - va_start(args, fmt); - - GetOriginalFile()->ExternalVLog(LF_ZAP, level, fmt, args); - - va_end(args); -} - -void DomainFile::ExternalLog(DWORD level, const char *msg) -{ - WRAPPER_NO_CONTRACT; - - GetOriginalFile()->ExternalLog(level, msg); -} -#endif #ifndef CROSSGEN_COMPILE //--------------------------------------------------------------------------------------- @@ -468,15 +448,9 @@ BOOL DomainFile::DoIncrementalLoad(FileLoadLevel level) break; case FILE_LOAD_FIND_NATIVE_IMAGE: -#ifdef FEATURE_PREJIT - FindNativeImage(); -#endif break; case FILE_LOAD_VERIFY_NATIVE_IMAGE_DEPENDENCIES: -#ifdef FEATURE_PREJIT - VerifyNativeImageDependencies(); -#endif break; case FILE_LOAD_ALLOCATE: @@ -537,280 +511,6 @@ BOOL DomainFile::DoIncrementalLoad(FileLoadLevel level) return TRUE; } -#ifdef FEATURE_PREJIT - -void DomainFile::VerifyNativeImageDependencies(bool verifyOnly) -{ - CONTRACTL - { - INSTANCE_CHECK; - STANDARD_VM_CHECK; - PRECONDITION(verifyOnly || (m_pDomain->GetDomainFileLoadLevel(this) == - FILE_LOAD_FIND_NATIVE_IMAGE)); - } - CONTRACTL_END; - - // This function gets called multiple times. The first call is the real work. - // Subsequent calls are only to verify that everything still looks OK. - if (!verifyOnly) - ClearNativeImageStress(); - - if (!m_pFile->HasNativeImage()) - { - CheckZapRequired(); - return; - } - - { - // Go through native dependencies & make sure they still have their prejit images after - // the security check. - // NOTE: we could theoretically do this without loading the dependencies, if we cache the - // COR_TRUST structures from the dependencies in the version information. - // - // Verify that all of our hard dependencies are loaded at the right base address. - // If not, abandon prejit image (or fix ours up) - // Also, if there are any hard dependencies, then our native image also needs to be - // loaded at the right base address - - // Note: we will go through all of our dependencies, call Load on them, and check the base - // addresses & identity. - // It is important to note that all of those dependencies are also going to do the - // same thing, so we might conceivably check a base address as OK, and then have that image - // abandoned by that assembly during its VerifyNativeImageDependencies phase. - // However, we avoid this problem since the hard depedencies stored are a closure of the - // hard dependencies of an image. This effectively means that our check here is a superset - // of the check that the dependencies will perform. Even if we hit a dependency loop, we - // will still guarantee that we've examined all of our dependencies. - - ReleaseHolder pNativeImage = m_pFile->GetNativeImageWithRef(); - if(pNativeImage==NULL) - { - CheckZapRequired(); - return; - } - - PEImageLayout* pNativeLayout = pNativeImage->GetLoadedLayout(); - - // reuse same codepath for both manifest and non-manifest modules - ReleaseHolder pManifestNativeImage(NULL); - - PEFile* pManifestFile = m_pFile; - PEImageLayout* pManifestNativeLayout = pNativeLayout; - - if (!IsAssembly()) - { - pManifestFile = GetDomainAssembly()->GetCurrentAssembly() - ->GetManifestModule()->GetFile(); - - pManifestNativeImage = pManifestFile->GetNativeImageWithRef(); - - if (pManifestNativeImage == NULL) - { - ExternalLog(LL_ERROR, "Rejecting native image because there is no " - "ngen image for manifest module. Check why the manifest module " - "does not have an ngen image"); - m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_NoNiForManifestModule; - STRESS_LOG3(LF_ZAP,LL_INFO100,"Rejecting native file %p, because its manifest module %p has no NI - reason 0x%x\n",pNativeImage.GetValue(),pManifestFile,m_dwReasonForRejectingNativeImage); - goto NativeImageRejected; - } - - return; - } - - COUNT_T cDependencies; - CORCOMPILE_DEPENDENCY *pDependencies = pManifestNativeLayout->GetNativeDependencies(&cDependencies); - - LOG((LF_ZAP, LL_INFO100, "ZAP: Checking native image dependencies for %S.\n", - pNativeImage->GetPath().GetUnicode())); - - for (COUNT_T iDependency = 0; iDependency < cDependencies; iDependency++) - { - CORCOMPILE_DEPENDENCY *pDependency = &(pDependencies[iDependency]); - - // Later, for domain neutral assemblies, we will also want to verify security policy - // in such cases, the prejit image should store the publisher info for the dependencies - // for us. - - // If this is not a hard-bound dependency, then skip to the next dependency - if (pDependency->signNativeImage == INVALID_NGEN_SIGNATURE) - continue; - - - // - // CoreCLR hard binds to CoreLib only. Avoid going through the full load. - // - -#ifdef _DEBUG - AssemblySpec name; - name.InitializeSpec(pDependency->dwAssemblyRef, - ((pManifestNativeImage != NULL) ? pManifestNativeImage : pNativeImage)->GetNativeMDImport(), - GetDomainAssembly()); - _ASSERTE(name.IsCoreLib()); -#endif - - PEAssembly * pDependencyFile = SystemDomain::SystemFile(); - - - ReleaseHolder pDependencyNativeImage = pDependencyFile->GetNativeImageWithRef(); - if (pDependencyNativeImage == NULL) - { - ExternalLog(LL_ERROR, W("Rejecting native image because dependency %s is not native"), - pDependencyFile->GetPath().GetUnicode()); - m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_DependencyNotNative; - STRESS_LOG3(LF_ZAP,LL_INFO100,"Rejecting native file %p, because dependency %p is not NI - reason 0x%x\n",pNativeImage.GetValue(),pDependencyFile,m_dwReasonForRejectingNativeImage); - goto NativeImageRejected; - } - - PTR_PEImageLayout pDependencyNativeLayout = pDependencyNativeImage->GetLoadedLayout(); - // Assert that the native image signature is as expected - // Fusion will ensure this - CORCOMPILE_VERSION_INFO * pDependencyNativeVersion = - pDependencyNativeLayout->GetNativeVersionInfo(); - - if (!RuntimeVerifyNativeImageDependency(pDependency, pDependencyNativeVersion, pDependencyFile)) - goto NativeImageRejected; - } - LOG((LF_ZAP, LL_INFO100, "ZAP: Native image dependencies for %S OK.\n", - pNativeImage->GetPath().GetUnicode())); - - return; -} - -NativeImageRejected: - m_pFile->ClearNativeImage(); - - CheckZapRequired(); - - return; -} - -BOOL DomainFile::IsZapRequired() -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - if (!m_pFile->HasMetadata() || !g_pConfig->RequireZap(GetSimpleName())) - return FALSE; - -#if defined(_DEBUG) - // If we're intentionally treating NIs as if they were MSIL assemblies, and the test - // is flexible enough to accept that (e.g., complus_zaprequired=2), then zaps are not - // required (i.e., it's ok for m_pFile->m_nativeImage to be NULL), but only if we - // loaded an actual NI to be treated as an IL assembly - if (PEFile::ShouldTreatNIAsMSIL()) - { - // Since the RequireZap() call above returned true, we know that some level of - // zap requiredness was configured - _ASSERTE(g_pConfig->RequireZaps() != EEConfig::REQUIRE_ZAPS_NONE); - - // If config uses this special value (2), zaps are not required, so long as - // we're using an actual NI as IL - if ((g_pConfig->RequireZaps() == EEConfig::REQUIRE_ZAPS_ALL_JIT_OK) && - m_pFile->HasOpenedILimage() && - m_pFile->GetOpenedILimage()->HasNativeHeader()) - { - return FALSE; - } - } -#endif // defined(_DEBUG) - - // Does this look like a resource-only assembly? We assume an assembly is resource-only - // if it contains no TypeDef (other than the TypeDef) and no MethodDef. - // Note that pMD->GetCountWithTokenKind(mdtTypeDef) doesn't count the type. - IMDInternalImportHolder pMD = m_pFile->GetMDImport(); - if (pMD->GetCountWithTokenKind(mdtTypeDef) == 0 && pMD->GetCountWithTokenKind(mdtMethodDef) == 0) - return FALSE; - - return TRUE; -} - -void DomainFile::CheckZapRequired() -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - if (m_pFile->HasNativeImage() || !IsZapRequired()) - return; - -#ifdef FEATURE_READYTORUN - if(m_pFile->GetLoaded()->HasReadyToRunHeader()) - return; -#endif - - // Flush any log messages - GetFile()->FlushExternalLog(); - - StackSString ss; - ss.Printf("ZapRequire: Could not get native image for %s.\n", - GetSimpleName()); - -#if defined(_DEBUG) - // Assert as some test may not check their error codes well. So throwing an - // exception may not cause a test failure (as it should). - StackScratchBuffer scratch; - DbgAssertDialog(__FILE__, __LINE__, (char*)ss.GetUTF8(scratch)); -#endif // defined(_DEBUG) - - COMPlusThrowNonLocalized(kFileNotFoundException, ss.GetUnicode()); -} - -// Discarding an ngen image can cause problems. For more coverage, -// this stress-mode discards ngen images even if not needed. - -void DomainFile::ClearNativeImageStress() -{ - WRAPPER_NO_CONTRACT; - -#ifdef _DEBUG - static ConfigDWORD clearNativeImageStress; - DWORD stressPercentage = clearNativeImageStress.val(CLRConfig::INTERNAL_clearNativeImageStress); - _ASSERTE(stressPercentage <= 100); - if (stressPercentage == 0 || !GetFile()->HasNativeImage()) - return; - - // Note that discarding a native image can affect dependencies. So its not enough - // to only check DomainFile::IsZapRequired() here. - if (g_pConfig->RequireZaps() != EEConfig::REQUIRE_ZAPS_NONE) - return; - - if (g_IBCLogger.InstrEnabled()) - return; - - ULONG hash = HashStringA(GetSimpleName()); - - // Hash in the FileLoadLevel so that we make a different decision for every level. - FileLoadLevel fileLoadLevel = m_pDomain->GetDomainFileLoadLevel(this); - hash ^= ULONG(fileLoadLevel); - // We do not discard native images after this level - _ASSERTE(fileLoadLevel < FILE_LOAD_VERIFY_NATIVE_IMAGE_DEPENDENCIES); - - // Different app-domains should make different decisions - hash ^= HashString(this->GetAppDomain()->GetFriendlyName()); - - if (DbgRandomOnHashAndExe(hash, float(stressPercentage)/100)) - { - GetFile()->ClearNativeImage(); - ExternalLog(LL_ERROR, "Rejecting native image for **clearNativeImageStress**"); - } -#endif -} - -#endif // FEATURE_PREJIT - void DomainFile::PreLoadLibrary() { CONTRACTL @@ -847,12 +547,6 @@ void DomainFile::PostLoadLibrary() } CONTRACTL_END; -#ifdef FEATURE_PREJIT - if (GetFile()->HasNativeImage()) - { - InsertIntoDomainFileWithNativeImageList(); - } -#endif #ifdef PROFILING_SUPPORTED // After this point, it is possible to load types. // We need to notify the profiler now because the profiler may need to inject methods into @@ -890,13 +584,6 @@ void DomainFile::EagerFixups() { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_PREJIT - if (GetCurrentModule()->HasNativeImage()) - { - GetCurrentModule()->RunEagerFixups(); - } - else -#endif // FEATURE_PREJIT #ifdef FEATURE_READYTORUN if (GetCurrentModule()->IsReadyToRun()) { @@ -935,27 +622,6 @@ void DomainFile::FinishLoad() } CONTRACTL_END; -#ifdef FEATURE_PREJIT - - if (m_pFile->HasNativeImage()) - { - - LOG((LF_ZAP, LL_INFO10, "Using native image %S.\n", m_pFile->GetPersistentNativeImage()->GetPath().GetUnicode())); - ExternalLog(LL_INFO10, "Native image successfully used."); - - // Inform metadata that it has been loaded from a native image - // (and so there was an opportunity to check for or fix inconsistencies in the original IL metadata) - m_pFile->GetMDImport()->SetVerifiedByTrustedSource(TRUE); - } - - // Are we absolutely required to use a native image? - CheckZapRequired(); -#endif // FEATURE_PREJIT - - // Flush any log messages -#ifdef FEATURE_PREJIT - GetFile()->FlushExternalLog(); -#endif // Must set this a bit prematurely for the DAC stuff to work m_level = FILE_LOADED; @@ -1037,27 +703,6 @@ void DomainFile::Activate() RETURN; } -#ifdef FEATURE_PREJIT -DomainFile *DomainFile::FindNextDomainFileWithNativeImage() -{ - LIMITED_METHOD_CONTRACT; - return m_pNextDomainFileWithNativeImage; -} - -void DomainFile::InsertIntoDomainFileWithNativeImageList() -{ - LIMITED_METHOD_CONTRACT; - - while (true) - { - DomainFile *pLastDomainFileFoundWithNativeImage = m_pDomain->m_pDomainFileWithNativeImageList; - m_pNextDomainFileWithNativeImage = pLastDomainFileFoundWithNativeImage; - if (pLastDomainFileFoundWithNativeImage == InterlockedCompareExchangeT(&m_pDomain->m_pDomainFileWithNativeImageList, this, pLastDomainFileFoundWithNativeImage)) - break; - } -} -#endif - //-------------------------------------------------------------------------------- // DomainAssembly //-------------------------------------------------------------------------------- @@ -1242,98 +887,6 @@ void DomainAssembly::Begin() m_fHostAssemblyPublished = true; } -#ifdef FEATURE_PREJIT -void DomainAssembly::FindNativeImage() -{ - CONTRACTL - { - INSTANCE_CHECK; - STANDARD_VM_CHECK; - } - CONTRACTL_END; - - ClearNativeImageStress(); - - // We already have an image - we just need to do a few more checks - - if (GetFile()->HasNativeImage()) - { -#if defined(_DEBUG) - if (g_pConfig->ForbidZap(GetSimpleName())) - { - SString sbuf; - StackScratchBuffer scratch; - sbuf.Printf("COMPlus_NgenBind_ZapForbid violation: %s.", GetSimpleName()); - DbgAssertDialog(__FILE__, __LINE__, sbuf.GetUTF8(scratch)); - } -#endif - - ReleaseHolder pNativeImage = GetFile()->GetNativeImageWithRef(); - - if (!CheckZapDependencyIdentities(pNativeImage)) - { - m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_DependencyIdentityMismatch; - STRESS_LOG2(LF_ZAP,LL_INFO100,"Rejecting native file %p, because dependency identity mismatch - reason 0x%x\n",pNativeImage.GetValue(),m_dwReasonForRejectingNativeImage); - ExternalLog(LL_ERROR, "Rejecting native image because of identity mismatch " - "with one or more of its assembly dependencies. The assembly needs " - "to be ngenned again"); - - GetFile()->ClearNativeImage(); - - // Always throw exceptions when we throw the NI out - ThrowHR(CLR_E_BIND_NI_DEP_IDENTITY_MISMATCH); - } - else - { - Module * pNativeModule = pNativeImage->GetLoadedLayout()->GetPersistedModuleImage(); - PEFile ** ppNativeFile = (PEFile **) (PBYTE(pNativeModule) + Module::GetFileOffset()); - - PEAssembly * pFile = (PEAssembly *)FastInterlockCompareExchangePointer((void **)ppNativeFile, (void *)GetFile(), (void *)NULL); - STRESS_LOG3(LF_ZAP,LL_INFO100,"Attempted to set new native file %p, old file was %p, location in the image=%p\n",GetFile(),pFile,ppNativeFile); - if (pFile!=NULL) - { - // The non-shareable native image has already been used in this process by another Module. - // We have to abandon the native image. (Note that it isn't enough to - // just abandon the preload image, since the code in the file will - // reference the image directly). - m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_CannotShareNiAssemblyNotDomainNeutral; - STRESS_LOG3(LF_ZAP,LL_INFO100,"Rejecting native file %p, because it is already used by file %p - reason 0x%x\n",GetFile(),pFile,m_dwReasonForRejectingNativeImage); - - ExternalLog(LL_WARNING, "ZAP: An ngen image of an assembly which " - "is not loaded as domain-neutral cannot be used in multiple appdomains " - "- abandoning ngen image. The assembly will be JIT-compiled in " - "the second appdomain. See System.LoaderOptimization.MultiDomain " - "for information about domain-neutral loading."); - GetFile()->ClearNativeImage(); - } - else - { - GetFile()->AddRef(); - - LOG((LF_ZAP, LL_INFO100, "ZAP: Found a candidate native image for %s\n", GetSimpleName())); - } - } - } - - if (!GetFile()->HasNativeImage()) - { - // - // Verify that the IL image is consistent with the NGen images loaded into appdomain - // - - AssemblySpec spec; - spec.InitializeSpec(GetFile()); - - GUID mvid; - GetFile()->GetMVID(&mvid); - - GetAppDomain()->CheckForMismatchedNativeImages(&spec, &mvid); - } - - CheckZapRequired(); -} -#endif // FEATURE_PREJIT - void DomainAssembly::Allocate() { CONTRACTL @@ -1371,16 +924,6 @@ void DomainAssembly::Allocate() SetAssembly(pAssembly); -#ifdef FEATURE_PREJIT - // Insert AssemblyDef details into AssemblySpecBindingCache - AssemblySpec specAssemblyDef; - specAssemblyDef.InitializeSpec(GetFile()); - if (specAssemblyDef.IsStrongNamed() && specAssemblyDef.HasPublicKey()) - { - specAssemblyDef.ConvertPublicKeyToToken(); - } - m_pDomain->AddAssemblyToCache(&specAssemblyDef, this); -#endif } // DomainAssembly::Allocate void DomainAssembly::DeliverAsyncEvents() @@ -1469,290 +1012,6 @@ BOOL DomainAssembly::GetResource(LPCSTR szName, DWORD *cbResource, } -#ifdef FEATURE_PREJIT - -// -------------------------------------------------------------------------------- -// Remember the timestamp of the CLR DLLs used to compile the ngen image. -// These will be checked at runtime by PEFile::CheckNativeImageTimeStamp(). -// - -void GetTimeStampsForNativeImage(CORCOMPILE_VERSION_INFO * pNativeVersionInfo) -{ - CONTRACTL - { - STANDARD_VM_CHECK; - PRECONDITION(::GetAppDomain()->IsCompilationDomain()); - } - CONTRACTL_END; - - // Do not store runtime timestamps into NGen image for cross-platform NGen determinism -} - -// -// Which processor should ngen target? -// This is needed when ngen wants to target for "reach" if the ngen images will be -// used on other machines (the Operating System or the OEM build lab can do this). -// It can also be used to reduce the testing matrix -// -void GetNGenCpuInfo(CORINFO_CPU * cpuInfo) -{ - LIMITED_METHOD_CONTRACT; - -#ifdef TARGET_X86 - - static CORINFO_CPU ngenCpuInfo = - { - (CPU_X86_PENTIUM_PRO << 8), // dwCPUType - 0x00000000, // dwFeatures - 0 // dwExtendedFeatures - }; - - // We always generate P3-compatible code on CoreCLR - *cpuInfo = ngenCpuInfo; - -#else // TARGET_X86 - cpuInfo->dwCPUType = 0; - cpuInfo->dwFeatures = 0; - cpuInfo->dwExtendedFeatures = 0; -#endif // TARGET_X86 -} - -// -------------------------------------------------------------------------------- - -void DomainAssembly::GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pNativeVersionInfo) -{ - CONTRACTL - { - INSTANCE_CHECK; - STANDARD_VM_CHECK; - } - CONTRACTL_END; - - // Clear memory so that we won't write random data into the zapped file - ZeroMemory(pNativeVersionInfo, sizeof(CORCOMPILE_VERSION_INFO)); - - // Pick up any compilation directives for code flavor - - BOOL fForceDebug, fForceProfiling, fForceInstrument; - SystemDomain::GetCompilationOverrides(&fForceDebug, - &fForceProfiling, - &fForceInstrument); - -#ifndef TARGET_UNIX - pNativeVersionInfo->wOSPlatformID = VER_PLATFORM_WIN32_NT; -#else - pNativeVersionInfo->wOSPlatformID = VER_PLATFORM_UNIX; -#endif - - // The native images should be OS-version agnostic. Do not store the actual OS version for determinism. - // pNativeVersionInfo->wOSMajorVersion = (WORD) osInfo.dwMajorVersion; - pNativeVersionInfo->wOSMajorVersion = 4; - - pNativeVersionInfo->wMachine = IMAGE_FILE_MACHINE_NATIVE_NI; - - pNativeVersionInfo->wVersionMajor = RuntimeFileMajorVersion; - pNativeVersionInfo->wVersionMinor = RuntimeFileMinorVersion; - pNativeVersionInfo->wVersionBuildNumber = RuntimeFileBuildVersion; - pNativeVersionInfo->wVersionPrivateBuildNumber = RuntimeFileRevisionVersion; - - GetNGenCpuInfo(&pNativeVersionInfo->cpuInfo); - -#if _DEBUG - pNativeVersionInfo->wBuild = CORCOMPILE_BUILD_CHECKED; -#else - pNativeVersionInfo->wBuild = CORCOMPILE_BUILD_FREE; -#endif - -#ifdef DEBUGGING_SUPPORTED - if (fForceDebug || !CORDebuggerAllowJITOpts(GetDebuggerInfoBits())) - { - pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_DEBUGGING; - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG; - } - else -#endif // DEBUGGING_SUPPORTED - { - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG_NONE; - } - -#if defined (PROFILING_SUPPORTED_DATA) || defined(PROFILING_SUPPORTED) - if (fForceProfiling || CORProfilerUseProfileImages()) - { - pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_PROFILING; - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_PROFILING; -#ifdef DEBUGGING_SUPPORTED - // Note that we have hardwired profiling to also imply optimized debugging - // info. This cuts down on one permutation of prejit files. - pNativeVersionInfo->wCodegenFlags &= ~CORCOMPILE_CODEGEN_DEBUGGING; - pNativeVersionInfo->wConfigFlags &= ~(CORCOMPILE_CONFIG_DEBUG| - CORCOMPILE_CONFIG_DEBUG_DEFAULT); - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG_NONE; -#endif // DEBUGGING_SUPPORTED - } - else -#endif // PROFILING_SUPPORTED_DATA || PROFILING_SUPPORTED - { - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_PROFILING_NONE; - } - -#ifdef DEBUGGING_SUPPORTED - - // Note the default assembly flags (from the custom attributes & INI file) , so we can - // set determine whether or not the current settings - // match the "default" setting or not. - - // Note that the INI file settings are considered a part of the - // assembly, even though they could theoretically change between - // ngen time and runtime. It is just too expensive and awkward to - // look up the INI file before binding to the native image at - // runtime, so we effectively snapshot it at ngen time. - - DWORD defaultFlags = ComputeDebuggingConfig(); - - if (CORDebuggerAllowJITOpts(defaultFlags)) - { - // Default is optimized code - if ((pNativeVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_DEBUGGING) == 0) - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG_DEFAULT; - } - else - { - // Default is non-optimized debuggable code - if ((pNativeVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_DEBUGGING) != 0) - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG_DEFAULT; - } - -#endif // DEBUGGING_SUPPORTED - - if (fForceInstrument || GetAssembly()->IsInstrumented()) - { - pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_PROF_INSTRUMENTING; - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_INSTRUMENTATION; - } - else - { - pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_INSTRUMENTATION_NONE; - } - - - GetTimeStampsForNativeImage(pNativeVersionInfo); - - // Store signature of source assembly. - GetOptimizedIdentitySignature(&pNativeVersionInfo->sourceAssembly); - - // signature will is hash of the whole file. It is written by zapper. - // IfFailThrow(CoCreateGuid(&pNativeVersionInfo->signature)); -} - -void DomainAssembly::GetOptimizedIdentitySignature(CORCOMPILE_ASSEMBLY_SIGNATURE *pSignature) -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - // - // Write the MVID into the version header. - // - - // - // If this assembly has skip verification permission, then we store its - // mvid. If at load time the assembly still has skip verification - // permission, then we can base the matches purely on mvid values and - // skip the perf-heavy hashing of the file. - // - - // - // The reason that we tell IsFullyTrusted to do a quick check - // only is because that allows us make a determination for the most - // common full trust scenarios (local machine) without actually - // resolving policy and bringing in a whole list of assembly - // dependencies. - // - ReleaseHolder scope (GetFile()->GetMDImportWithRef()); - IfFailThrow(scope->GetScopeProps(NULL, &pSignature->mvid)); - - // Use the NGen image if possible. IL image does not even have to be present on CoreCLR. - if (GetFile()->HasNativeImage()) - { - PEImageHolder pNativeImage(GetFile()->GetNativeImageWithRef()); - - CORCOMPILE_VERSION_INFO* pVersionInfo = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo(); - pSignature->timeStamp = pVersionInfo->sourceAssembly.timeStamp; - pSignature->ilImageSize = pVersionInfo->sourceAssembly.ilImageSize; - - return; - } - - // Write the time stamp - PEImageLayoutHolder ilLayout(GetFile()->GetAnyILWithRef()); - pSignature->timeStamp = ilLayout->GetTimeDateStamp(); - pSignature->ilImageSize = ilLayout->GetVirtualSize(); -} - -BOOL DomainAssembly::CheckZapDependencyIdentities(PEImage *pNativeImage) -{ - CONTRACTL - { - INSTANCE_CHECK; - STANDARD_VM_CHECK; - } - CONTRACTL_END; - - AssemblySpec spec; - spec.InitializeSpec(this->GetFile()); - - // The assembly spec should have the binding context associated with it - _ASSERTE(spec.GetBindingContext() || spec.IsAssemblySpecForCoreLib()); - - CORCOMPILE_VERSION_INFO *pVersionInfo = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo(); - - // Check our own assembly first - GetAppDomain()->CheckForMismatchedNativeImages(&spec, &pVersionInfo->sourceAssembly.mvid); - - // Check MVID in metadata against MVID in CORCOMPILE_VERSION_INFO - important when metadata is loaded from IL instead of NI - ReleaseHolder pImport(this->GetFile()->GetMDImportWithRef()); - GUID mvid; - IfFailThrow(pImport->GetScopeProps(NULL, &mvid)); - GetAppDomain()->CheckForMismatchedNativeImages(&spec, &mvid); - - // Now Check dependencies - COUNT_T cDependencies; - CORCOMPILE_DEPENDENCY *pDependencies = pNativeImage->GetLoadedLayout()->GetNativeDependencies(&cDependencies); - CORCOMPILE_DEPENDENCY *pDependenciesEnd = pDependencies + cDependencies; - - while (pDependencies < pDependenciesEnd) - { - if (pDependencies->dwAssemblyDef != mdAssemblyRefNil) - { - AssemblySpec name; - name.InitializeSpec(pDependencies->dwAssemblyDef, pNativeImage->GetNativeMDImport(), this); - - if (!name.IsAssemblySpecForCoreLib()) - { - // We just initialized the assembly spec for the NI dependency. This will not have binding context - // associated with it, so set it from that of the parent. - _ASSERTE(!name.GetBindingContext()); - AssemblyBinder *pParentAssemblyBindingContext = name.GetBindingContextFromParentAssembly(name.GetAppDomain()); - _ASSERTE(pParentAssemblyBindingContext); - name.SetBindingContext(pParentAssemblyBindingContext); - } - - GetAppDomain()->CheckForMismatchedNativeImages(&name, &pDependencies->signAssemblyDef.mvid); - } - - pDependencies++; - } - - return TRUE; -} -#endif // FEATURE_PREJIT - DWORD DomainAssembly::ComputeDebuggingConfig() { CONTRACTL @@ -1812,27 +1071,6 @@ HRESULT DomainAssembly::GetDebuggingCustomAttributes(DWORD *pdwFlags) HRESULT hr = S_OK; -#ifdef FEATURE_PREJIT - ReleaseHolder pNativeImage=GetFile()->GetNativeImageWithRef(); - if (pNativeImage) - { - CORCOMPILE_VERSION_INFO * pVersion = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo(); - PREFIX_ASSUME(pVersion != NULL); - - WORD codegen = pVersion->wCodegenFlags; - - if (codegen & CORCOMPILE_CODEGEN_DEBUGGING) - { - *pdwFlags &= (~DACF_ALLOW_JIT_OPTS); - } - else - { - *pdwFlags |= DACF_ALLOW_JIT_OPTS; - } - - } - else -#endif // FEATURE_PREJIT { ULONG size; BYTE *blob; diff --git a/src/coreclr/vm/domainfile.h b/src/coreclr/vm/domainfile.h index 8ed8774c70ac67..6f98f32e68ca4b 100644 --- a/src/coreclr/vm/domainfile.h +++ b/src/coreclr/vm/domainfile.h @@ -260,14 +260,6 @@ class DomainFile Module* GetLoadedModule(); Module* GetModule(); -#ifdef FEATURE_PREJIT - BOOL IsZapRequired(); // Are we absolutely required to use a native image? -#endif - // The format string is intentionally unicode to avoid globalization bugs -#ifdef FEATURE_PREJIT - void ExternalLog(DWORD level, const WCHAR *fmt, ...); - void ExternalLog(DWORD level, const char *msg); -#endif #ifdef DACCESS_COMPILE virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); #endif @@ -311,20 +303,6 @@ class DomainFile // This should be used to permanently set the load to fail. Do not use with transient conditions void SetError(Exception *ex); -#ifdef FEATURE_PREJIT - -#ifndef DACCESS_COMPILE - virtual void FindNativeImage() = 0; -#endif - void VerifyNativeImageDependencies(bool verifyOnly = FALSE); - - // Are we absolutely required to use a native image? - void CheckZapRequired(); - - void ClearNativeImageStress(); - -#endif // FEATURE_PREJIT - void SetProfilerNotified() { LIMITED_METHOD_CONTRACT; m_notifyflags|= PROFILER_NOTIFIED; } void SetDebuggerNotified() { LIMITED_METHOD_CONTRACT; m_notifyflags|=DEBUGGER_NOTIFIED; } void SetShouldNotifyDebugger() { LIMITED_METHOD_CONTRACT; m_notifyflags|=DEBUGGER_NEEDNOTIFICATION; } @@ -408,14 +386,6 @@ class DomainFile m_pError->ConvertToHResult(); }; -#ifdef FEATURE_PREJIT - // Lock-free enumeration of DomainFiles in an AppDomain. -public: - DomainFile *FindNextDomainFileWithNativeImage(); -private: - void InsertIntoDomainFileWithNativeImageList(); -#endif // FEATURE_PREJIT - DWORD m_notifyflags; BOOL m_loading; // m_pDynamicMethodTable is used by the light code generation to allow method @@ -429,12 +399,6 @@ class DomainFile // See Dev11 bug 358184 for more details public: DWORD m_dwReasonForRejectingNativeImage; // See code:g_dwLoaderReasonForNotSharing in Assembly.cpp for a similar variable. -private: - -#ifdef FEATURE_PREJIT - // This value is to allow lock-free enumeration of all native images in an AppDomain - Volatile m_pNextDomainFileWithNativeImage; -#endif }; // These will sometimes result in a crash with error code 0x80131506 COR_E_EXECUTIONENGINE @@ -606,18 +570,6 @@ class DomainAssembly : public DomainFile LPCSTR *szFileName, DWORD *dwLocation, BOOL fSkipRaiseResolveEvent); -#ifdef FEATURE_PREJIT - // ------------------------------------------------------------ - // Prejitting API - // ------------------------------------------------------------ - - void GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pZapVersionInfo); - - void GetOptimizedIdentitySignature(CORCOMPILE_ASSEMBLY_SIGNATURE *pSignature); - BOOL CheckZapDependencyIdentities(PEImage *pNativeImage); - -#endif // FEATURE_PREJIT - // ------------------------------------------------------------ // Debugger control API // ------------------------------------------------------------ @@ -675,12 +627,6 @@ class DomainAssembly : public DomainFile void UpdatePEFile(PTR_PEFile pFile); -#ifdef FEATURE_PREJIT -#ifndef DACCESS_COMPILE - void FindNativeImage(); -#endif -#endif // FEATURE_PREJIT - BOOL IsInstrumented(); public: diff --git a/src/coreclr/vm/dwbucketmanager.hpp b/src/coreclr/vm/dwbucketmanager.hpp index b4309df6de4637..cf360ac7322a5a 100644 --- a/src/coreclr/vm/dwbucketmanager.hpp +++ b/src/coreclr/vm/dwbucketmanager.hpp @@ -960,23 +960,6 @@ bool BaseBucketParamsManager::GetFileVersionInfoForModule(Module* pModule, USHOR PEFile* pFile = pModule->GetFile(); if (pFile) { -#ifdef FEATURE_PREJIT - // if we have a native imaged loaded for this module then get the version information from that. - if (pFile->IsNativeLoaded()) - { - PEImage* pNativeImage = pFile->GetPersistentNativeImage(); - - if (pNativeImage) - { - LPCWSTR niPath = pNativeImage->GetPath().GetUnicode(); - if (niPath != NULL && niPath != SString::Empty() && SUCCEEDED(DwGetFileVersionInfo(niPath, major, minor, build, revision))) - { - succeeded = true; - } - } - } -#endif - // if we failed to get the version info from the native image then fall back to the IL image. if (!succeeded) { diff --git a/src/coreclr/vm/ecall.cpp b/src/coreclr/vm/ecall.cpp index 3dd1c44aa26498..7779aaa1cf9760 100644 --- a/src/coreclr/vm/ecall.cpp +++ b/src/coreclr/vm/ecall.cpp @@ -117,14 +117,9 @@ void ECall::PopulateManagedCastHelpers() // array cast uses the "ANY" helper SetJitHelperFunction(CORINFO_HELP_ISINSTANCEOFARRAY, pDest); -#ifdef FEATURE_PREJIT - // When interface table uses indirect references, just set interface casts to "ANY" helper - SetJitHelperFunction(CORINFO_HELP_ISINSTANCEOFINTERFACE, pDest); -#else pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__ISINSTANCEOFINTERFACE)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_ISINSTANCEOFINTERFACE, pDest); -#endif pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__ISINSTANCEOFCLASS)); pDest = pMD->GetMultiCallableAddrOfCode(); @@ -136,14 +131,9 @@ void ECall::PopulateManagedCastHelpers() // array cast uses the "ANY" helper SetJitHelperFunction(CORINFO_HELP_CHKCASTARRAY, pDest); -#ifdef FEATURE_PREJIT - // When interface table uses indirect references, just set interface casts to "ANY" handler - SetJitHelperFunction(CORINFO_HELP_CHKCASTINTERFACE, pDest); -#else pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTINTERFACE)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_CHKCASTINTERFACE, pDest); -#endif pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__CASTHELPERS__CHKCASTCLASS)); pDest = pMD->GetMultiCallableAddrOfCode(); diff --git a/src/coreclr/vm/eeconfig.cpp b/src/coreclr/vm/eeconfig.cpp index dd180f3abe760e..dcab5a53af3adb 100644 --- a/src/coreclr/vm/eeconfig.cpp +++ b/src/coreclr/vm/eeconfig.cpp @@ -739,14 +739,6 @@ HRESULT EEConfig::sync() m_fInteropValidatePinnedObjects = (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_InteropValidatePinnedObjects) != 0); m_fInteropLogArguments = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_InteropLogArguments) != 0); -#ifdef FEATURE_PREJIT -#ifdef _DEBUG - dwNgenForceFailureMask = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenForceFailureMask); - dwNgenForceFailureCount = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenForceFailureCount); - dwNgenForceFailureKind = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenForceFailureKind); -#endif -#endif // FEATURE_PREJIT - #if defined(_DEBUG) && defined(FEATURE_EH_FUNCLETS) fSuppressLockViolationsOnReentryFromOS = (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_SuppressLockViolationsOnReentryFromOS) != 0); #endif diff --git a/src/coreclr/vm/eedbginterface.h b/src/coreclr/vm/eedbginterface.h index 1ce5b8b928eabc..07666d607a2a3c 100644 --- a/src/coreclr/vm/eedbginterface.h +++ b/src/coreclr/vm/eedbginterface.h @@ -345,14 +345,6 @@ class EEDebugInterface virtual CorDebugUserState GetPartialUserState( Thread *pThread ) = 0; -#ifdef FEATURE_PREJIT -#ifndef DACCESS_COMPILE - virtual void SetNGENDebugFlags(BOOL fAllowOpt) = 0; - - virtual void GetNGENDebugFlags(BOOL *fAllowOpt) = 0; -#endif -#endif // FEATURE_PREJIT - #endif // #ifndef DACCESS_COMPILE #ifdef DACCESS_COMPILE diff --git a/src/coreclr/vm/eedbginterfaceimpl.h b/src/coreclr/vm/eedbginterfaceimpl.h index 647db4639f597c..d4d790c9e886f8 100644 --- a/src/coreclr/vm/eedbginterfaceimpl.h +++ b/src/coreclr/vm/eedbginterfaceimpl.h @@ -305,22 +305,6 @@ class EEDbgInterfaceImpl : public EEDebugInterface // to both functions CorDebugUserState GetPartialUserState( Thread *pThread ); -#ifdef FEATURE_PREJIT -#ifndef DACCESS_COMPILE - virtual void SetNGENDebugFlags(BOOL fAllowOpt) - { - LIMITED_METHOD_CONTRACT; - PEFile::SetNGENDebugFlags(fAllowOpt); - } - - virtual void GetNGENDebugFlags(BOOL *fAllowOpt) - { - LIMITED_METHOD_CONTRACT; - PEFile::GetNGENDebugFlags(fAllowOpt); - } -#endif -#endif // FEATURE_PREJIT - #ifdef DACCESS_COMPILE virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); #endif diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp index f204d9ad63763d..7f8b403178494e 100644 --- a/src/coreclr/vm/eventtrace.cpp +++ b/src/coreclr/vm/eventtrace.cpp @@ -6099,60 +6099,6 @@ ETW_INLINE { ULONG Result = ERROR_SUCCESS; -#ifdef FEATURE_PREJIT - // do not fire the ETW event when: - // 1. We did not load the native image - // 2. We do not have IBC data for the native image - if( !pModule || !pModule->HasNativeImage() || !pModule->IsIbcOptimized() ) - { - return Result; - } - - // get information about the hot sections from the native image that has been loaded - COUNT_T cbSizeOfSectionTable; - CORCOMPILE_VIRTUAL_SECTION_INFO* pVirtualSectionsTable = (CORCOMPILE_VIRTUAL_SECTION_INFO* )pModule->GetNativeImage()->GetVirtualSectionsTable(&cbSizeOfSectionTable); - - COUNT_T RangeCount = cbSizeOfSectionTable/sizeof(CORCOMPILE_VIRTUAL_SECTION_INFO); - - // if we do not have any hot ranges, we do not fire the ETW event - - // Figure out the rest of the event data - UINT16 ClrInstanceId = GetClrInstanceId(); - UINT64 ModuleID = (ULONGLONG)(TADDR) pModule; - - for (COUNT_T i = 0; i < RangeCount; ++i) - { - DWORD rangeBegin = pVirtualSectionsTable[i].VirtualAddress; - DWORD rangeSize = pVirtualSectionsTable[i].Size; - DWORD sectionType = pVirtualSectionsTable[i].SectionType; - - UINT8 ibcType = VirtualSectionData::IBCType(sectionType); - UINT8 rangeType = VirtualSectionData::RangeType(sectionType); - UINT16 virtualSectionType = VirtualSectionData::VirtualSectionType(sectionType); - BOOL isIBCProfiledColdSection = VirtualSectionData::IsIBCProfiledColdSection(sectionType); - if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoad) - { - if (isIBCProfiledColdSection) - Result &= FireEtwModuleRangeLoad(ClrInstanceId, ModuleID, rangeBegin, rangeSize, rangeType); - } - else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCStart) - { - if (isIBCProfiledColdSection) - Result &= FireEtwModuleRangeDCStart(ClrInstanceId, ModuleID, rangeBegin, rangeSize, rangeType); - } - else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCEnd) - { - if (isIBCProfiledColdSection) - Result &= FireEtwModuleRangeDCEnd(ClrInstanceId, ModuleID, rangeBegin, rangeSize, rangeType); - } - // Fire private events if they are requested. - if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoadPrivate) - { - Result &= FireEtwModuleRangeLoadPrivate(ClrInstanceId, ModuleID, rangeBegin, rangeSize, rangeType, ibcType, virtualSectionType); - } - } -#endif - return Result; } @@ -6362,9 +6308,6 @@ VOID ETW::LoaderLog::SendModuleEvent(Module *pModule, DWORD dwEventOptions, BOOL PCWSTR szDtraceOutput1=W(""),szDtraceOutput2=W(""); BOOL bIsDynamicAssembly = pModule->GetAssembly()->IsDynamic(); BOOL bHasNativeImage = FALSE; -#ifdef FEATURE_PREJIT - bHasNativeImage = pModule->HasNativeImage(); -#endif // FEATURE_PREJIT BOOL bIsManifestModule = pModule->IsManifest(); ULONGLONG ullAppDomainId = 0; // This is used only with DomainModule events ULONGLONG ullModuleId = (ULONGLONG)(TADDR) pModule; @@ -6409,11 +6352,6 @@ VOID ETW::LoaderLog::SendModuleEvent(Module *pModule, DWORD dwEventOptions, BOOL { ModuleILPath = (PWCHAR)pModule->GetAssembly()->GetManifestFile()->GetILimage()->GetPath().GetUnicode(); ModuleNativePath = (PWCHAR)pEmptyString; - -#ifdef FEATURE_PREJIT - if(bHasNativeImage) - ModuleNativePath = (PWCHAR)pModule->GetNativeImage()->GetPath().GetUnicode(); -#endif // FEATURE_PREJIT } // if we do not have a module path yet, we put the module name @@ -6701,9 +6639,6 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio } pModule = pMethodDesc->GetModule_NoLogging(); -#ifdef FEATURE_PREJIT - bHasNativeImage = pModule->HasNativeImage(); -#endif // FEATURE_PREJIT bIsDynamicMethod = (BOOL)pMethodDesc->IsDynamicMethod(); bHasSharedGenericCode = pMethodDesc->IsSharedByGenericInstantiations(); @@ -7187,19 +7122,6 @@ VOID ETW::MethodLog::SendEventsForNgenMethods(Module *pModule, DWORD dwEventOpti return; } #endif // FEATURE_READYTORUN - -#ifdef FEATURE_PREJIT - if (pModule->HasNativeImage()) - { - MethodIterator mi(pModule); - - while (mi.Next()) - { - MethodDesc *hotDesc = (MethodDesc *)mi.GetMethodDesc(); - ETW::MethodLog::SendMethodEvent(hotDesc, dwEventOptions, FALSE); - } - } -#endif // FEATURE_PREJIT } // Called be ETW::MethodLog::SendEventsForJitMethods diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 74a1f9f6be7822..271a4fd0185b1f 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -7615,17 +7615,7 @@ BOOL IsIPInEE(void *ip) { WRAPPER_NO_CONTRACT; -#if defined(FEATURE_PREJIT) && !defined(TARGET_UNIX) - if ((TADDR)ip > g_runtimeLoadedBaseAddress && - (TADDR)ip < g_runtimeLoadedBaseAddress + g_runtimeVirtualSize) - { - return TRUE; - } - else -#endif // FEATURE_PREJIT && !TARGET_UNIX - { - return FALSE; - } + return FALSE; } #if defined(FEATURE_HIJACK) && (!defined(TARGET_X86) || defined(TARGET_UNIX)) diff --git a/src/coreclr/vm/gccover.cpp b/src/coreclr/vm/gccover.cpp index 9ce0cc676f7a7f..8c5a0501306855 100644 --- a/src/coreclr/vm/gccover.cpp +++ b/src/coreclr/vm/gccover.cpp @@ -230,79 +230,6 @@ void SetupGcCoverage(NativeCodeVersion nativeCodeVersion, BYTE* methodStartPtr) SetupAndSprinkleBreakpointsForJittedMethod(nativeCodeVersion, codeStart); } -#ifdef FEATURE_PREJIT - -void SetupGcCoverageForNativeMethod(NativeCodeVersion nativeCodeVersion, - PCODE codeStart, - IJitManager::MethodRegionInfo& methodRegionInfo - ) -{ - _ASSERTE(!nativeCodeVersion.IsNull()); - - EECodeInfo codeInfo(codeStart); - _ASSERTE(codeInfo.IsValid()); - _ASSERTE(codeInfo.GetRelOffset() == 0); - - _ASSERTE(PCODEToPINSTR(codeStart) == methodRegionInfo.hotStartAddress); - - SetupAndSprinkleBreakpoints(nativeCodeVersion, - &codeInfo, - methodRegionInfo, - TRUE - ); -} - -void SetupGcCoverageForNativeImage(Module* module) -{ - // Disable IBC logging here because of NGen image is not fully initialized yet. Eager bound - // indirection cells are not initialized yet and so IBC logging would crash while attempting to dereference them. - IBCLoggingDisabler disableLogging; - -#if 0 - // Debug code - LPWSTR wszSetupGcCoverage = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_SetupGcCoverage); - - if (!wszSetupGcCoverage) - { - printf("wszSetupGcCoverage is NULL. Will not SetupGcCoverage for any module.\n"); - return; - } - else - { - if ((wcscmp(W("*"), wszSetupGcCoverage) == 0) || // "*" means will gcstress all modules - (wcsstr(module->GetDebugName(), wszSetupGcCoverage) != NULL)) - { - printf("[%ws] matched %ws\n", wszSetupGcCoverage, module->GetDebugName()); - // Fall through - } - else - { - printf("[%ws] NOT match %ws\n", wszSetupGcCoverage, module->GetDebugName()); - return; - } - } -#endif - -#ifdef _DEBUG - if (g_pConfig->SkipGCCoverage(module->GetSimpleName())) - return; -#endif - - MethodIterator mi(module); - while (mi.Next()) - { - PTR_MethodDesc pMD = mi.GetMethodDesc(); - PCODE pMethodStart = mi.GetMethodStartAddress(); - - IJitManager::MethodRegionInfo methodRegionInfo; - mi.GetMethodRegionInfo(&methodRegionInfo); - - SetupGcCoverageForNativeMethod(NativeCodeVersion(pMD), pMethodStart, methodRegionInfo); - } -} -#endif - - void ReplaceInstrAfterCall(PBYTE instrToReplace, MethodDesc* callMD) { ReturnKind returnKind = callMD->GetReturnKind(true); diff --git a/src/coreclr/vm/genericdict.cpp b/src/coreclr/vm/genericdict.cpp index 78dced0f48f2bd..554c2301a8492e 100644 --- a/src/coreclr/vm/genericdict.cpp +++ b/src/coreclr/vm/genericdict.cpp @@ -494,34 +494,6 @@ DictionaryEntryLayout::GetKind() #ifndef DACCESS_COMPILE -#ifdef FEATURE_PREJIT -//--------------------------------------------------------------------------------------- -// -void -Dictionary::Restore( - DWORD numGenericArgs, - ClassLoadLevel level) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - INSTANCE_CHECK; - } - CONTRACTL_END - - // First restore the type handles in the instantiation itself - FixupPointer *inst = GetInstantiation(); - for (DWORD j = 0; j < numGenericArgs; j++) - { - Module::RestoreTypeHandlePointer(&inst[j], NULL, level); - } - - // We don't restore the remainder of the dictionary - see - // long comment at the start of this file as to why -} -#endif // FEATURE_PREJIT - #if !defined(CROSSGEN_COMPILE) Dictionary* Dictionary::GetMethodDictionaryWithSizeCheck(MethodDesc* pMD, ULONG slotIndex) { diff --git a/src/coreclr/vm/genericdict.h b/src/coreclr/vm/genericdict.h index d68f5d71d95ff7..fe68dba1194ee1 100644 --- a/src/coreclr/vm/genericdict.h +++ b/src/coreclr/vm/genericdict.h @@ -301,12 +301,6 @@ class Dictionary static Dictionary* GetMethodDictionaryWithSizeCheck(MethodDesc* pMD, ULONG slotIndex); #endif // #ifndef DACCESS_COMPILE - -public: - -#ifdef FEATURE_PREJIT - void Restore(DWORD numGenericArgs, ClassLoadLevel level); -#endif // FEATURE_PREJIT }; #endif diff --git a/src/coreclr/vm/generics.cpp b/src/coreclr/vm/generics.cpp index 35f5ebd66d7344..a3322b355737ce 100644 --- a/src/coreclr/vm/generics.cpp +++ b/src/coreclr/vm/generics.cpp @@ -281,12 +281,7 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation( ThrowHR(COR_E_OVERFLOW); } -#ifdef FEATURE_PREJIT - Module *pComputedPZM = Module::ComputePreferredZapModule(pTypeKey); - BOOL canShareVtableChunks = MethodTable::CanShareVtableChunksFrom(pOldMT, pLoaderModule, pComputedPZM); -#else BOOL canShareVtableChunks = MethodTable::CanShareVtableChunksFrom(pOldMT, pLoaderModule); -#endif // FEATURE_PREJIT SIZE_T offsetOfUnsharedVtableChunks = allocSize.Value(); @@ -330,14 +325,6 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation( pMT->ClearFlag(MethodTable::enum_flag_GenericsMask); pMT->SetFlag(MethodTable::enum_flag_GenericsMask_GenericInst); -#ifdef FEATURE_PREJIT - // Freshly allocated - does not need restore - pMT->ClearFlag(MethodTable::enum_flag_IsZapped); - pMT->ClearFlag(MethodTable::enum_flag_IsPreRestored); - - pMT->ClearFlag(MethodTable::enum_flag_HasIndirectParent); -#endif - pMT->m_pParentMethodTable.SetValueMaybeNull(NULL); // Non non-virtual slots @@ -591,10 +578,6 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation( } #endif //_DEBUG -#ifdef FEATURE_PREJIT - _ASSERTE(pComputedPZM == Module::GetPreferredZapModuleForMethodTable(pMT)); -#endif //FEATURE_PREJIT - // We never have non-virtual slots in this method table (set SetNumVtableSlots and SetNumVirtuals above) _ASSERTE(!pMT->HasNonVirtualSlots()); diff --git a/src/coreclr/vm/genmeth.cpp b/src/coreclr/vm/genmeth.cpp index 5e9193b641fdc7..f88f0982cd1762 100644 --- a/src/coreclr/vm/genmeth.cpp +++ b/src/coreclr/vm/genmeth.cpp @@ -607,24 +607,6 @@ InstantiatedMethodDesc::FindLoadedInstantiatedMethodDesc(MethodTable *pExactOrRe if (resultMD != NULL) RETURN((InstantiatedMethodDesc*) resultMD); -#ifdef FEATURE_PREJIT - // Next look in the preferred zap module - Module *pPreferredZapModule = Module::ComputePreferredZapModule(pExactOrRepMT->GetModule(), - pExactOrRepMT->GetInstantiation(), - methodInst); - if (pPreferredZapModule->HasNativeImage()) - { - resultMD = pPreferredZapModule->GetInstMethodHashTable()->FindMethodDesc(TypeHandle(pExactOrRepMT), - methodDef, - FALSE /* not forceBoxedEntryPoint */, - methodInst, - getWrappedCode); - - if (resultMD != NULL) - RETURN((InstantiatedMethodDesc*) resultMD); - } -#endif // FEATURE_PREJIT - RETURN(NULL); } @@ -1625,22 +1607,6 @@ void MethodDesc::LoadConstraintsForTypicalMethodDefinition(BOOL *pfHasCircularCl } -#ifdef FEATURE_PREJIT - -void MethodDesc::PrepopulateDictionary(DataImage * image, BOOL nonExpansive) -{ - STANDARD_VM_CONTRACT; - - // Note the strong similarity to MethodTable::PrepopulateDictionary - if (GetMethodDictionary()) - { - LOG((LF_JIT, LL_INFO10000, "GENERICS: Prepopulating dictionary for MD %s\n", this)); - GetMethodDictionary()->PrepopulateDictionary(this, NULL, nonExpansive); - } -} - -#endif // FEATURE_PREJIT - #ifndef DACCESS_COMPILE BOOL MethodDesc::SatisfiesMethodConstraints(TypeHandle thParent, BOOL fThrowIfNotSatisfied/* = FALSE*/) diff --git a/src/coreclr/vm/i386/asmhelpers.S b/src/coreclr/vm/i386/asmhelpers.S index e6c76662a352df..502c56adbc908e 100644 --- a/src/coreclr/vm/i386/asmhelpers.S +++ b/src/coreclr/vm/i386/asmhelpers.S @@ -707,38 +707,6 @@ LOCAL_LABEL(GoCallCalliWorker): jmp C_FUNC(GenericPInvokeCalliHelper) LEAF_END GenericPInvokeCalliHelper, _TEXT -#ifdef FEATURE_PREJIT -// ========================================================================= -NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler - STUB_PROLOG - - mov esi, esp - -.att_syntax - pushl $0 - pushl $0 - pushl $0 -.intel_syntax noprefix - - push eax // siteAddrForRegisterIndirect (for tailcalls) - push esi // pTransitionBlock - - CHECK_STACK_ALIGNMENT - call C_FUNC(StubDispatchFixupWorker) - - mov esp, esi - STUB_EPILOG - -PATCH_LABEL StubDispatchFixupPatchLabel - // Tailcall target - jmp eax - - // This will never be executed. It is just to help out stack-walking logic - // which disassembles the epilog to unwind the stack. - ret -NESTED_END StubDispatchFixupStub, _TEXT -#endif // FEATURE_PREJIT - // ========================================================================== NESTED_ENTRY ExternalMethodFixupStub, _TEXT_ NoHandler // pop off the return address to the stub @@ -825,58 +793,6 @@ NESTED_END DelayLoad_MethodCall, _TEXT #endif // FEATURE_READYTORUN -#ifdef FEATURE_PREJIT -// ======================================================================================= -// The call in softbound vtable slots initially points to this function. -// The pupose of this function is to transfer the control to right target and -// to optionally patch the target of the jump so that we do not take this slow path again. -// -NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler - // Get the return address. It points right after the call instruction in the thunk. - mov eax, [esp] - // Calculate the address of the thunk - sub eax, 5 - - // Push ebp frame to get good callstack under debugger - PROLOG_BEG - - // Preserve argument registers - PROLOG_PUSH ecx - PROLOG_PUSH edx - - // Set frame pointer - PROLOG_END - - sub esp, 8 - push eax // address of the thunk - push ecx // this ptr - CHECK_STACK_ALIGNMENT - call C_FUNC(VirtualMethodFixupWorker) - add esp, 8 - - // Restore stack pointer - EPILOG_BEG - - // Restore argument registers - EPILOG_POP edx - EPILOG_POP ecx - - // Pop ebp frame - EPILOG_END - - // Pop return address - add esp, 4 - -PATCH_LABEL VirtualMethodFixupPatchLabel - // Proceed to execute the actual method. - jmp eax - - // This will never be executed. It is just to help out stack-walking logic - // which disassembles the epilog to unwind the stack. - ret -NESTED_END VirtualMethodFixupStub, _TEXT -#endif // FEATURE_PREJIT - NESTED_ENTRY ThePreStub, _TEXT, NoHandler STUB_PROLOG diff --git a/src/coreclr/vm/i386/asmhelpers.asm b/src/coreclr/vm/i386/asmhelpers.asm index 987f5b0c7717dc..2eb6620fe279a7 100644 --- a/src/coreclr/vm/i386/asmhelpers.asm +++ b/src/coreclr/vm/i386/asmhelpers.asm @@ -60,11 +60,6 @@ endif EXTERN _ExternalMethodFixupWorker@16:PROC -ifdef FEATURE_PREJIT -EXTERN _VirtualMethodFixupWorker@8:PROC -EXTERN _StubDispatchFixupWorker@16:PROC -endif - ifdef FEATURE_COMINTEROP EXTERN _ComPreStubWorker@8:PROC endif @@ -1367,39 +1362,6 @@ _CopyCtorCallStub@0 endp endif ; !FEATURE_CORECLR -ifdef FEATURE_PREJIT - -;========================================================================== -_StubDispatchFixupStub@0 proc public - - STUB_PROLOG - - mov esi, esp - - push 0 - push 0 - - push eax ; siteAddrForRegisterIndirect (for tailcalls) - push esi ; pTransitionBlock - - call _StubDispatchFixupWorker@16 - - STUB_EPILOG - -_StubDispatchFixupPatchLabel@0: -public _StubDispatchFixupPatchLabel@0 - - ; Tailcall target - jmp eax - - ; This will never be executed. It is just to help out stack-walking logic - ; which disassembles the epilog to unwind the stack. - ret - -_StubDispatchFixupStub@0 endp - -endif ; FEATURE_PREJIT - ;========================================================================== _ExternalMethodFixupStub@0 proc public @@ -1477,49 +1439,6 @@ _DelayLoad_MethodCall@0 proc public _DelayLoad_MethodCall@0 endp endif -ifdef FEATURE_PREJIT -;======================================================================================= -; The call in softbound vtable slots initially points to this function. -; The pupose of this function is to transfer the control to right target and -; to optionally patch the target of the jump so that we do not take this slow path again. -; -_VirtualMethodFixupStub@0 proc public - - pop eax ; Pop the return address. It points right after the call instruction in the thunk. - sub eax,5 ; Calculate the address of the thunk - - ; Push ebp frame to get good callstack under debugger - push ebp - mov ebp, esp - - ; Preserve argument registers - push ecx - push edx - - push eax ; address of the thunk - push ecx ; this ptr - call _VirtualMethodFixupWorker@8 - - ; Restore argument registers - pop edx - pop ecx - - ; Pop ebp frame - pop ebp - -_VirtualMethodFixupPatchLabel@0: -public _VirtualMethodFixupPatchLabel@0 - - ; Proceed to execute the actual method. - jmp eax - - ; This will never be executed. It is just to help out stack-walking logic - ; which disassembles the epilog to unwind the stack. - ret - -_VirtualMethodFixupStub@0 endp -endif - ;========================================================================== ; The prestub _ThePreStub@0 proc public diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp index 7e3ef1f5a2a70a..ff47aa3b71cd9b 100644 --- a/src/coreclr/vm/i386/cgenx86.cpp +++ b/src/coreclr/vm/i386/cgenx86.cpp @@ -1294,77 +1294,6 @@ BOOL DoesSlotCallPrestub(PCODE pCode) return pCode == GetPreStubEntryPoint(); } -#ifdef FEATURE_PREJIT -//========================================================================================== -// In NGen image, virtual slots inherited from cross-module dependencies point to jump thunks. -// These jump thunk initially point to VirtualMethodFixupStub which transfers control here. -// This method 'VirtualMethodFixupWorker' will patch the jump thunk to point to the actual -// inherited method body after we have execute the precode and a stable entry point. -// -EXTERN_C PVOID STDCALL VirtualMethodFixupWorker(Object * pThisPtr, CORCOMPILE_VIRTUAL_IMPORT_THUNK *pThunk) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_COOPERATIVE; - ENTRY_POINT; - } - CONTRACTL_END; - - _ASSERTE(pThisPtr != NULL); - VALIDATEOBJECT(pThisPtr); - - MethodTable * pMT = pThisPtr->GetMethodTable(); - - WORD slotNumber = pThunk->slotNum; - _ASSERTE(slotNumber != (WORD)-1); - - PCODE pCode = pMT->GetRestoredSlot(slotNumber); - - if (!DoesSlotCallPrestub(pCode)) - { - MethodDesc *pMD = MethodTable::GetMethodDescForSlotAddress(pCode); - if (pMD->IsVersionableWithVtableSlotBackpatch()) - { - // The entry point for this method needs to be versionable, so use a FuncPtrStub similarly to what is done in - // MethodDesc::GetMultiCallableAddrOfCode() - GCX_COOP(); - pCode = pMD->GetLoaderAllocator()->GetFuncPtrStubs()->GetFuncPtrStub(pMD); - } - else - { - // Skip fixup precode jump for better perf - PCODE pDirectTarget = Precode::TryToSkipFixupPrecode(pCode); - if (pDirectTarget != NULL) - pCode = pDirectTarget; - } - - INT64 oldValue = *(INT64*)pThunk; - BYTE* pOldValue = (BYTE*)&oldValue; - - if (pOldValue[0] == X86_INSTR_CALL_REL32) - { - INT64 newValue = oldValue; - BYTE* pNewValue = (BYTE*)&newValue; - pNewValue[0] = X86_INSTR_JMP_REL32; - - INT_PTR pcRelOffset = (BYTE*)pCode - &pThunk->callJmp[5]; - *(INT32 *)(&pNewValue[1]) = (INT32) pcRelOffset; - - _ASSERTE(IS_ALIGNED(pThunk, sizeof(INT64))); - - ExecutableWriterHolder thunkWriterHolder((INT64*)pThunk, sizeof(INT64)); - FastInterlockCompareExchangeLong(thunkWriterHolder.GetRW(), newValue, oldValue); - - FlushInstructionCache(GetCurrentProcess(), pThunk, 8); - } - } - - return PVOID(pCode); -} -#endif // FEATURE_PREJIT - #ifdef FEATURE_READYTORUN // diff --git a/src/coreclr/vm/i386/stublinkerx86.h b/src/coreclr/vm/i386/stublinkerx86.h index 564c999975e7c9..c916e1e1224c82 100644 --- a/src/coreclr/vm/i386/stublinkerx86.h +++ b/src/coreclr/vm/i386/stublinkerx86.h @@ -685,13 +685,6 @@ struct FixupPrecode { return *dac_cast(addr) == X86_INSTR_JMP_REL32; } -#ifdef FEATURE_PREJIT - // Partial initialization. Used to save regrouped chunks. - void InitForSave(int iPrecodeChunkIndex); - - void Fixup(DataImage *image, MethodDesc * pMD); -#endif - #ifdef DACCESS_COMPILE void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); #endif diff --git a/src/coreclr/vm/ibclogger.cpp b/src/coreclr/vm/ibclogger.cpp index e564c9a8eb7706..cbb49a8d9268da 100644 --- a/src/coreclr/vm/ibclogger.cpp +++ b/src/coreclr/vm/ibclogger.cpp @@ -522,10 +522,6 @@ void IBCLogger::LogMethodAccessHelper(const MethodDesc* pMD, ULONG flagNum) if (!pMT->IsRestored_NoLogging()) goto DelayCallback; -#ifdef FEATURE_PREJIT - LogMethodTableAccessHelper(pMT); -#endif - Module *pModule = pMT->GetModule(); if (MethodDescAccessInstrEnabled()) @@ -554,15 +550,6 @@ void IBCLogger::LogMethodAccessHelper(const MethodDesc* pMD, ULONG flagNum) if (thArg.IsNull() || thArg.IsEncodedFixup() || !thArg.IsRestored_NoLogging()) goto DelayCallback; } - -#ifdef FEATURE_PREJIT - Module *pPZModule = Module::GetPreferredZapModuleForMethodDesc(pMD); - token = pPZModule->LogInstantiatedMethod(pMD, flagNum); - if (!IsNilToken(token)) - { - pPZModule->LogTokenAccess(token, MethodProfilingData, flagNum); - } -#endif } else { @@ -608,479 +595,6 @@ void IBCLogger::LogMethodGCInfoAccessHelper(MethodDesc* pMD) LogMethodAccessHelper(pMD, CommonReadGCInfo); } -#ifdef FEATURE_PREJIT -void IBCLogger::LogMethodDescAccessHelper(const MethodDesc *pMD) -{ - WRAPPER_NO_CONTRACT; - - LogMethodAccessHelper(pMD, ReadMethodDesc); -} - -void IBCLogger::LogMethodDescWriteAccessHelper(MethodDesc *pMD) -{ - WRAPPER_NO_CONTRACT; - - LogMethodAccessHelper(pMD, ReadMethodDesc); - LogMethodAccessHelper(pMD, WriteMethodDesc); -} - -void IBCLogger::LogMethodPrecodeAccessHelper(MethodDesc *pMD) -{ - WRAPPER_NO_CONTRACT; - - LogMethodAccessHelper(pMD, ReadMethodPrecode); -} - -void IBCLogger::LogMethodPrecodeWriteAccessHelper(MethodDesc *pMD) -{ - WRAPPER_NO_CONTRACT; - - LogMethodAccessHelper(pMD, ReadMethodPrecode); - LogMethodAccessHelper(pMD, WriteMethodPrecode); -} - -// Log access to the method code and method header for NDirect calls -void IBCLogger::LogNDirectCodeAccessHelper(MethodDesc *pMD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(g_IBCLogger.InstrEnabled()); - } - CONTRACTL_END; - - LogMethodAccessHelper(pMD, ReadMethodDesc); - LogMethodAccessHelper(pMD, ReadMethodCode); -} - -// Log access to method table -void IBCLogger::LogMethodTableAccessHelper(MethodTable const * pMT) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(pMT, ReadMethodTable); -} - -// Log access to method table -void IBCLogger::LogTypeMethodTableAccessHelper(const TypeHandle *th) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(*th, ReadMethodTable); -} - -// Log write access to method table -void IBCLogger::LogTypeMethodTableWriteableAccessHelper(const TypeHandle *th) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(*th, ReadTypeDesc); - LogTypeAccessHelper(*th, WriteTypeDesc); -} - -// Log access via method table, to a token-based type or an instantiated type. -void IBCLogger::LogTypeAccessHelper(TypeHandle th, ULONG flagNum) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(g_IBCLogger.InstrEnabled()); - } - CONTRACTL_END; - - CONTRACT_VIOLATION( ThrowsViolation ); - - idTypeSpec token = idTypeSpecNil; - Module* pPreferredZapModule = NULL; - - if (th.IsNull() || th.IsEncodedFixup()) - return; - - // we cannot do any logging before the ObjectClass and StringClass are loaded - if (g_pObjectClass == NULL || g_pStringClass == NULL) - goto DelayCallback; - - if (!th.IsRestored_NoLogging()) - goto DelayCallback; - - // - // We assign the pPreferredZapModule and the token, then fall out to the LogTokenAccess - // - // Logging accesses to TypeDescs is done by blob and we create a special IBC token for the blob - if (th.IsTypeDesc()) - { - pPreferredZapModule = Module::GetPreferredZapModuleForTypeHandle(th); - - token = pPreferredZapModule->LogInstantiatedType(th, flagNum); - } - else - { - MethodTable *pMT = th.AsMethodTable(); - - if (pMT->IsArray()) - { - pPreferredZapModule = Module::GetPreferredZapModuleForMethodTable(pMT); - - token = pPreferredZapModule->LogInstantiatedType(th, flagNum); - } - else - { - Module* pModule = pMT->GetModule(); - - // Instantiations of generic types (like other parameterized types like arrays) - // need to be handled specially. Generic instantiations do not have a ready-made token - // in the loader module and need special handling - // - if (pMT->HasInstantiation() && // Is this any of List, List>, or List? - !pMT->IsGenericTypeDefinition() && // Ignore the type definition (List) as it corresponds to the typeDef token - !pMT->ContainsGenericVariables()) // We more or less don't save these anyway, apart from the GenericTypeDefinition - { - Instantiation inst = pMT->GetInstantiation(); - - // This function can get called from BuildMethodTableThrowing(). The instantiation info is not yet set then - if (!inst.IsEmpty() && !inst[0].IsNull()) - { - pPreferredZapModule = Module::GetPreferredZapModuleForMethodTable(pMT); - - token = pPreferredZapModule->LogInstantiatedType(th, flagNum); - } - } - else - { - pPreferredZapModule = pModule; - token = pMT->GetCl_NoLogging(); - } - } - } - - if (!IsNilToken(token)) - pPreferredZapModule->LogTokenAccess(token, TypeProfilingData, flagNum); - - return; - -DelayCallback: - DelayedCallbackPtr(LogTypeAccessWrapper, th.AsPtr(), (void *)(SIZE_T)flagNum); -} - -void IBCLogger::LogTypeAccessWrapper(IBCLogger* pLogger, const void * pValue, const void * pValue2) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - pLogger->LogTypeAccessHelper(TypeHandle::FromPtr((void *)pValue), (ULONG)(SIZE_T)pValue2); -} - -// Log access to method tables which are private (i.e. methodtables that are updated in the ngen image) -void IBCLogger::LogMethodTableWriteableDataAccessHelper(MethodTable const * pMT) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(pMT, ReadMethodTable); - LogTypeAccessHelper(pMT, ReadMethodTableWriteableData); -} - -// Log access to method tables which are private (i.e. methodtables that are updated in the ngen image) -void IBCLogger::LogMethodTableWriteableDataWriteAccessHelper(MethodTable *pMT) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(pMT, ReadMethodTable); - LogTypeAccessHelper(pMT, WriteMethodTableWriteableData); -} - -void IBCLogger::LogMethodTableNonVirtualSlotsAccessHelper(MethodTable const * pMT) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(pMT, ReadMethodTable); - LogTypeAccessHelper(pMT, ReadNonVirtualSlots); -} - -// Log access to EEClass -void IBCLogger::LogEEClassAndMethodTableAccessHelper(MethodTable * pMT) -{ - WRAPPER_NO_CONTRACT; - - if (pMT == NULL) - return; - - LogTypeAccessHelper(pMT, ReadMethodTable); - - if (!pMT->IsCanonicalMethodTable()) { - pMT = pMT->GetCanonicalMethodTable(); - LogTypeAccessHelper(pMT, ReadMethodTable); - } - - LogTypeAccessHelper(pMT, ReadEEClass); -} - -// Log write to EEClass -void IBCLogger::LogEEClassCOWTableAccessHelper(MethodTable * pMT) -{ - WRAPPER_NO_CONTRACT; - - if (pMT == NULL) - return; - - LogTypeAccessHelper(pMT, ReadMethodTable); - - if (!pMT->IsCanonicalMethodTable()) { - pMT = pMT->GetCanonicalMethodTable(); - LogTypeAccessHelper(pMT, ReadMethodTable); - } - - LogTypeAccessHelper(pMT, ReadEEClass); - LogTypeAccessHelper(pMT, WriteEEClass); -} - -// Log access to FieldDescs list in EEClass -void IBCLogger::LogFieldDescsAccessHelper(FieldDesc * pFD) -{ - WRAPPER_NO_CONTRACT; - - MethodTable * pMT = pFD->GetApproxEnclosingMethodTable_NoLogging(); - - LogTypeAccessHelper(pMT, ReadMethodTable); - - if (!pMT->IsCanonicalMethodTable()) { - pMT = pMT->GetCanonicalMethodTable(); - LogTypeAccessHelper(pMT, ReadMethodTable); - } - - LogTypeAccessHelper(pMT, ReadFieldDescs); -} - -void IBCLogger::LogDispatchMapAccessHelper(MethodTable *pMT) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(pMT, ReadMethodTable); - LogTypeAccessHelper(pMT, ReadDispatchMap); -} - -void IBCLogger::LogDispatchTableAccessHelper(MethodTable *pMT) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(pMT, ReadMethodTable); - LogTypeAccessHelper(pMT, ReadDispatchMap); - LogTypeAccessHelper(pMT, ReadDispatchTable); -} - -void IBCLogger::LogDispatchTableSlotAccessHelper(DispatchSlot *pDS) -{ - WRAPPER_NO_CONTRACT; - - if (pDS->IsNull()) - return; - - MethodDesc *pMD = MethodTable::GetMethodDescForSlotAddress(pDS->GetTarget()); - MethodTable *pMT = pMD->GetMethodTable_NoLogging(); - LogDispatchTableAccessHelper(pMT); -} - -// Log access to cctor info table -void IBCLogger::LogCCtorInfoReadAccessHelper(MethodTable *pMT) -{ - WRAPPER_NO_CONTRACT; - LogTypeAccessHelper(pMT, ReadCCtorInfo); -} - - -void IBCLogger::LogTypeHashTableAccessHelper(const TypeHandle *th) -{ - WRAPPER_NO_CONTRACT; - - LogTypeAccessHelper(*th, ReadTypeHashTable); -} - -// Log access to class hash table -void IBCLogger::LogClassHashTableAccessHelper(EEClassHashEntry *pEntry) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(g_IBCLogger.InstrEnabled()); - } - CONTRACTL_END; - - // ExecutionManager::FindZapModule may enter the host (if we were hosted), but it's - // ok since we're just logging IBC data. - CONTRACT_VIOLATION( HostViolation ); - - Module *pModule = ExecutionManager::FindZapModule(dac_cast(pEntry)); - if (pModule == NULL) - { - // if FindZapModule returns NULL, it always will return NULL - // so there is no point in adding a DelayedCallback here. - return; - } - - // we cannot log before the ObjectClass or StringClass are loaded - if (g_pObjectClass == NULL || g_pStringClass == NULL) - goto DelayCallback; - - HashDatum datum; - datum = pEntry->GetData(); - mdToken token; - if ((((ULONG_PTR) datum) & EECLASSHASH_TYPEHANDLE_DISCR) == 0) - { - TypeHandle t = TypeHandle::FromPtr(datum); - _ASSERTE(!t.IsNull()); - MethodTable *pMT = t.GetMethodTable(); - if (pMT == NULL) - goto DelayCallback; - - token = pMT->GetCl_NoLogging(); - } - else if (((ULONG_PTR)datum & EECLASSHASH_MDEXPORT_DISCR) == 0) - { - DWORD dwDatum = (DWORD)(DWORD_PTR)(datum); // WIN64 - Pointer Truncation - token = ((dwDatum >> 1) & 0x00ffffff) | mdtTypeDef; - } - else - return; - - pModule->LogTokenAccess(token, TypeProfilingData, ReadClassHashTable); - return; - -DelayCallback: - DelayedCallbackPtr(LogClassHashTableAccessWrapper, pEntry); -} - -// Log access to meta data -void IBCLogger::LogMetaDataAccessHelper(const void * addr) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(g_IBCLogger.InstrEnabled()); - } - CONTRACTL_END; - - // ExecutionManager::FindZapModule may enter the host (if we were hosted), but it's - // ok since we're just logging IBC data. - CONTRACT_VIOLATION( HostViolation ); - -#if METADATATRACKER_ENABLED - if (Module *pModule = ExecutionManager::FindZapModule(dac_cast(addr))) - { - mdToken token = MetaDataTracker::MapAddrToToken(addr); - - pModule->LogTokenAccess(token, ProfilingFlags_MetaData); - pModule->LogTokenAccess(token, CommonMetaData); - return; - } -#endif //METADATATRACKER_ENABLED - - // if FindZapModule returns NULL, it always will return NULL - // so there is no point in adding a DelayedCallback here. -} - -// Log a search to meta data -// See the comment above CMiniMdRW::GetHotMetadataTokensSearchAware -void IBCLogger::LogMetaDataSearchAccessHelper(const void * result) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(g_IBCLogger.InstrEnabled()); - } - CONTRACTL_END; - - // ExecutionManager::FindZapModule may enter the host (if we were hosted), but it's - // ok since we're just logging IBC data. - CONTRACT_VIOLATION( HostViolation ); - -#if METADATATRACKER_ENABLED - if (Module *pModule = ExecutionManager::FindZapModule(dac_cast(result))) - { - mdToken token = MetaDataTracker::MapAddrToToken(result); - - pModule->LogTokenAccess(token, ProfilingFlags_MetaData); - pModule->LogTokenAccess(token, CommonMetaData); - pModule->LogTokenAccess(token, ProfilingFlags_MetaDataSearch); - return; - } -#endif //METADATATRACKER_ENABLED - - // if FindZapModule returns NULL, it always will return NULL - // so there is no point in adding a DelayedCallback here. -} - -// Log access to method list associated with a CER -void IBCLogger::LogCerMethodListReadAccessHelper(MethodDesc *pMD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(g_IBCLogger.InstrEnabled()); - } - CONTRACTL_END; - - LogMethodAccessHelper(pMD, ReadCerMethodList); -} - -void IBCLogger::LogRidMapAccessHelper( RidMapLogData data ) -{ - WRAPPER_NO_CONTRACT; - - data.First()->LogTokenAccess( data.Second(), RidMap ); -} - -// Log access to RVA data -void IBCLogger::LogRVADataAccessHelper(FieldDesc *pFD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(g_IBCLogger.InstrEnabled()); - } - CONTRACTL_END; - - // we cannot log before the ObjectClass or StringClass are loaded - if (g_pObjectClass == NULL || g_pStringClass == NULL) - goto DelayCallback; - - if (CORCOMPILE_IS_POINTER_TAGGED(SIZE_T(pFD))) - return; - - MethodTable * pMT; - pMT = pFD->GetApproxEnclosingMethodTable(); - - if (!pMT->IsRestored_NoLogging()) - goto DelayCallback; - - if (pMT->HasInstantiation()) - return; - - pMT->GetModule()->LogTokenAccess(pFD->GetMemberDef(), TypeProfilingData, RVAFieldData); - return; - -DelayCallback: - DelayedCallbackPtr(LogRVADataAccessWrapper, pFD); -} - -#endif // FEATURE_PREJIT - #define LOADORDER_INSTR 0x00000001 #define RID_ACCESSORDER_INSTR 0x00000002 #define METHODDESC_ACCESS_INSTR 0x00000004 diff --git a/src/coreclr/vm/ibclogger.h b/src/coreclr/vm/ibclogger.h index bde07e9f22a0ed..64d0fc2d279b5f 100644 --- a/src/coreclr/vm/ibclogger.h +++ b/src/coreclr/vm/ibclogger.h @@ -473,9 +473,6 @@ public: \ // Implemented by : code:IBCLogger.LogMethodGCInfoAccessHelper LOGACCESS_PTR(MethodGCInfo, MethodDesc) -// The accesses to individual datastructures matter for fragile NGen only -#ifndef FEATURE_PREJIT - #undef LOGACCESS_PTR #undef LOGACCESS_VALUE @@ -487,8 +484,6 @@ public: \ public: \ void Log##name##Access(type p) { SUPPORTS_DAC; } \ -#endif // FEATURE_PREJIT - // Log access to method desc (which adds the method desc to the required list) // Implemented by : code:IBCLogger.LogMethodDescAccessHelper LOGACCESS_PTR(MethodDesc, const MethodDesc) diff --git a/src/coreclr/vm/ilstubcache.cpp b/src/coreclr/vm/ilstubcache.cpp index 065630c9dc784e..b573c2c117fdb7 100644 --- a/src/coreclr/vm/ilstubcache.cpp +++ b/src/coreclr/vm/ilstubcache.cpp @@ -587,157 +587,3 @@ bool ILStubCache::ILStubCacheTraits::Equals(_In_ key_t lhs, _In_ key_t rhs) size_t blobDataSize = lhs->m_cbSizeOfBlob - sizeof(ILStubHashBlobBase); return memcmp(lhs->m_rgbBlobData, rhs->m_rgbBlobData, blobDataSize) == 0; } - -#ifdef FEATURE_PREJIT - -// ============================================================================ -// Stub method hash entry methods -// ============================================================================ -PTR_MethodDesc StubMethodHashEntry::GetMethod() -{ - LIMITED_METHOD_DAC_CONTRACT; - return pMD; -} - -PTR_MethodDesc StubMethodHashEntry::GetStubMethod() -{ - LIMITED_METHOD_DAC_CONTRACT; - return pStubMD; -} - -#ifndef DACCESS_COMPILE - -void StubMethodHashEntry::SetMethodAndStub(MethodDesc *pMD, MethodDesc *pStubMD) -{ - LIMITED_METHOD_CONTRACT; - this->pMD = pMD; - this->pStubMD = pStubMD; -} - -// ============================================================================ -// Stub method hash table methods -// ============================================================================ -/* static */ StubMethodHashTable *StubMethodHashTable::Create(LoaderAllocator *pAllocator, Module *pModule, DWORD dwNumBuckets, AllocMemTracker *pamTracker) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END - - LoaderHeap *pHeap = pAllocator->GetLowFrequencyHeap(); - StubMethodHashTable *pThis = (StubMethodHashTable *)pamTracker->Track(pHeap->AllocMem((S_SIZE_T)sizeof(StubMethodHashTable))); - - new (pThis) StubMethodHashTable(pModule, pHeap, dwNumBuckets); - - return pThis; -} - -// Calculate a hash value for a key -static DWORD Hash(MethodDesc *pMD) -{ - LIMITED_METHOD_CONTRACT; - - DWORD dwHash = 0x87654321; -#define INST_HASH_ADD(_value) dwHash = ((dwHash << 5) + dwHash) ^ (_value) - - INST_HASH_ADD(pMD->GetMemberDef()); - - Instantiation inst = pMD->GetClassInstantiation(); - for (DWORD i = 0; i < inst.GetNumArgs(); i++) - { - TypeHandle thArg = inst[i]; - - if (thArg.GetMethodTable()) - { - INST_HASH_ADD(thArg.GetCl()); - - Instantiation sArgInst = thArg.GetInstantiation(); - for (DWORD j = 0; j < sArgInst.GetNumArgs(); j++) - { - TypeHandle thSubArg = sArgInst[j]; - if (thSubArg.GetMethodTable()) - INST_HASH_ADD(thSubArg.GetCl()); - else - INST_HASH_ADD(thSubArg.GetSignatureCorElementType()); - } - } - else - INST_HASH_ADD(thArg.GetSignatureCorElementType()); - } - - return dwHash; -} - -MethodDesc *StubMethodHashTable::FindMethodDesc(MethodDesc *pMD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - FORBID_FAULT; - } - CONTRACTL_END - - MethodDesc *pMDResult = NULL; - - DWORD dwHash = Hash(pMD); - StubMethodHashEntry_t* pSearch; - LookupContext sContext; - - for (pSearch = BaseFindFirstEntryByHash(dwHash, &sContext); - pSearch != NULL; - pSearch = BaseFindNextEntryByHash(&sContext)) - { - if (pSearch->GetMethod() == pMD) - { - pMDResult = pSearch->GetStubMethod(); - break; - } - } - - return pMDResult; -} - -// Add method desc to the hash table; must not be present already -void StubMethodHashTable::InsertMethodDesc(MethodDesc *pMD, MethodDesc *pStubMD) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - INJECT_FAULT(COMPlusThrowOM();); - PRECONDITION(CheckPointer(pMD)); - PRECONDITION(CheckPointer(pStubMD)); - } - CONTRACTL_END - - StubMethodHashEntry_t *pNewEntry = (StubMethodHashEntry_t *)BaseAllocateEntry(NULL); - pNewEntry->SetMethodAndStub(pMD, pStubMD); - - DWORD dwHash = Hash(pMD); - BaseInsertEntry(dwHash, pNewEntry); -} - -#endif // !DACCESS_COMPILE - -#ifdef DACCESS_COMPILE - -void StubMethodHashTable::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) -{ - SUPPORTS_DAC; - BaseEnumMemoryRegions(flags); -} - -void StubMethodHashTable::EnumMemoryRegionsForEntry(StubMethodHashEntry_t *pEntry, CLRDataEnumMemoryFlags flags) -{ - SUPPORTS_DAC; - if (pEntry->GetMethod().IsValid()) - pEntry->GetMethod()->EnumMemoryRegions(flags); -} - -#endif // DACCESS_COMPILE - -#endif // FEATURE_PREJIT diff --git a/src/coreclr/vm/ilstubcache.h b/src/coreclr/vm/ilstubcache.h index 4b304e85c8b13c..6d33e8cb43e9b3 100644 --- a/src/coreclr/vm/ilstubcache.h +++ b/src/coreclr/vm/ilstubcache.h @@ -118,69 +118,4 @@ class ILStubCache final SHash m_hashMap; }; -#ifdef FEATURE_PREJIT -//======================================================================================== -// -// This hash table is used by interop to lookup NGENed marshaling stubs for methods -// in cases where the MethodDesc cannot point to the stub directly. -// -// Keys are arbitrary MethodDesc's, values are IL stub MethodDescs. -// -//======================================================================================== - -typedef DPTR(struct StubMethodHashEntry) PTR_StubMethodHashEntry; -typedef struct StubMethodHashEntry -{ - PTR_MethodDesc GetMethod(); - PTR_MethodDesc GetStubMethod(); -#ifndef DACCESS_COMPILE - void SetMethodAndStub(MethodDesc *pMD, MethodDesc *pStubMD); -#endif // !DACCESS_COMPILE - -private: - friend class StubMethodHashTable; -#ifdef DACCESS_COMPILE - friend class NativeImageDumper; -#endif - - PTR_MethodDesc pMD; - PTR_MethodDesc pStubMD; - -} StubMethodHashEntry_t; - - -// The hash table itself -typedef DPTR(class StubMethodHashTable) PTR_StubMethodHashTable; -class StubMethodHashTable : public NgenHashTable -{ -#ifndef DACCESS_COMPILE - StubMethodHashTable(); - - StubMethodHashTable(Module *pModule, LoaderHeap *pHeap, DWORD cInitialBuckets) : - NgenHashTable(pModule, pHeap, cInitialBuckets) {} - - ~StubMethodHashTable(); -#endif -public: - static StubMethodHashTable *Create(LoaderAllocator *pAllocator, Module *pModule, DWORD dwNumBuckets, AllocMemTracker *pamTracker); - -private: - void operator delete(void *p); - -public: - // Looks up a stub MethodDesc in the hash table, returns NULL if not found - MethodDesc *FindMethodDesc(MethodDesc *pMD); - -#ifndef DACCESS_COMPILE - // Inserts a method-stub pair into the hash table - VOID InsertMethodDesc(MethodDesc *pMD, MethodDesc *pStubMD); -#endif // !DACCESS_COMPILE - -#ifdef DACCESS_COMPILE - void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); - void EnumMemoryRegionsForEntry(StubMethodHashEntry_t *pEntry, CLRDataEnumMemoryFlags flags); -#endif -}; -#endif // FEATURE_PREJIT - #endif //_ILSTUBCACHE_H diff --git a/src/coreclr/vm/instmethhash.cpp b/src/coreclr/vm/instmethhash.cpp index 95986550f866b9..fc04afa4b66b56 100644 --- a/src/coreclr/vm/instmethhash.cpp +++ b/src/coreclr/vm/instmethhash.cpp @@ -157,11 +157,6 @@ MethodDesc* InstMethodHashTable::FindMethodDesc(TypeHandle declaringType, pSearch != NULL; pSearch = BaseFindNextEntryByHash(&sContext)) { -#ifdef FEATURE_PREJIT - // This ensures that GetAssemblyIfLoaded operations that may be triggered by signature walks will succeed if at all possible. - ClrFlsThreadTypeSwitch genericInstantionCompareHolder(ThreadType_GenericInstantiationCompare); -#endif - MethodDesc *pMD = pSearch->GetMethod(); if (pMD->GetMemberDef() != token) @@ -178,16 +173,7 @@ MethodDesc* InstMethodHashTable::FindMethodDesc(TypeHandle declaringType, if ( ((dwKeyFlags & InstMethodHashEntry::UnboxingStub) == 0) != (unboxingStub == 0) ) continue; -#ifdef FEATURE_PREJIT - // Note pMD->GetMethodTable() might not be restored at this point. - - RelativeFixupPointer * ppMT = pMD->GetMethodTablePtr(); - TADDR pMT = ppMT->GetValueMaybeTagged((TADDR)ppMT); - - if (!ZapSig::CompareTaggedPointerToTypeHandle(GetModule(), pMT, declaringType)) -#else if (TypeHandle(pMD->GetMethodTable()) != declaringType) -#endif { continue; // Next iteration of the for loop } @@ -203,15 +189,7 @@ MethodDesc* InstMethodHashTable::FindMethodDesc(TypeHandle declaringType, for (DWORD i = 0; i < inst.GetNumArgs(); i++) { -#ifdef FEATURE_PREJIT - // Fetch the type handle as TADDR. It may be may be encoded fixup - TypeHandle debug-only validation - // asserts on encoded fixups. - TADDR candidateArg = ((FixupPointer *)candidateInst.GetRawArgs())[i].GetValue(); - - if (!ZapSig::CompareTaggedPointerToTypeHandle(GetModule(), candidateArg, inst[i])) -#else if (candidateInst[i] != inst[i]) -#endif { match = false; break; diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index 24b69fe6c8aa0d..4a9e7ca83e6895 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -2749,91 +2749,6 @@ BOOL IsTypeVisibleFromCom(TypeHandle hndType) return SpecialIsGenericTypeVisibleFromCom(hndType); } -#ifdef FEATURE_PREJIT -//--------------------------------------------------------------------------- -// Determines if a method is likely to be used for forward COM/WinRT interop. -BOOL MethodNeedsForwardComStub(MethodDesc *pMD, DataImage *pImage) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - MethodTable *pMT = pMD->GetMethodTable(); - - if (pMT->HasInstantiation()) - { - // method is declared on an unsupported generic type -> stub not needed - return FALSE; - } - - GUID guid; - pMT->GetGuid(&guid, FALSE); - - if (guid != GUID_NULL) - { - // explicit GUID defined in metadata -> stub needed - return TRUE; - } - - return FALSE; -} - -//--------------------------------------------------------------------------- -// Determines if a method is visible from COM in a way that requires a marshaling -// stub, i.e. it allows early binding. -BOOL MethodNeedsReverseComStub(MethodDesc *pMD) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(pMD)); - } - CONTRACTL_END; - - BOOL fIsAllowedCtorOrStatic = FALSE; - MethodTable *pMT = pMD->GetMethodTable(); - - if (pMT->IsInterface()) - { - if (!pMT->IsComImport() && !IsTypeVisibleFromCom(TypeHandle(pMT))) - return FALSE; - - if (pMT->HasInstantiation()) - return FALSE; - - // declaring interface must be InterfaceIsIUnknown or InterfaceIsDual - if (pMT->GetComInterfaceType() == ifDispatch) - return FALSE; - } - else - { - if (!IsTypeVisibleFromCom(TypeHandle(pMT))) - return FALSE; - - if (pMT->IsDelegate()) - { - return FALSE; - } - - // declaring class must be AutoDual - if (pMT->GetComClassInterfaceType() != clsIfAutoDual) - return FALSE; - } - - // NGen can't compile stubs for var arg methods - if (pMD->IsVarArg()) - return FALSE; - - return IsMethodVisibleFromCom(pMD); -} -#endif // FEATURE_PREJIT - #ifndef CROSSGEN_COMPILE diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index e668841a93f76d..6fcbff25c06973 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -2441,25 +2441,6 @@ OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken meta _ASSERTE(TypeFromToken(metaTok) == mdtString); Module* module = GetModule(scopeHnd); - - - // If our module is ngenned and we're calling this API, it means that we're not going through - // the fixup mechanism for strings. This can happen 2 ways: - // - // a) Lazy string object construction: This happens when JIT decides that initizalizing a - // string via fixup on method entry is very expensive. This is normally done for strings - // that appear in rarely executed blocks, such as throw blocks. - // - // b) The ngen image isn't complete (it's missing classes), therefore we're jitting methods. - // - // If we went ahead and called ResolveStringRef directly, we would be breaking the per module - // interning we're guaranteeing, so we will have to detect the case and handle it appropriately. -#ifdef FEATURE_PREJIT - if (module->HasNativeImage() && module->IsNoStringInterning()) - { - return module->ResolveStringRef(metaTok, module->GetAssembly()->Parent(), true); - } -#endif return module->ResolveStringRef(metaTok, module->GetAssembly()->Parent(), false); } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 883eb1ceb1883d..0bc1f826aaedbc 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3023,11 +3023,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr { pResult->indirections = 2; pResult->testForNull = 0; -#ifdef FEATURE_PREJIT - pResult->testForFixup = 1; -#else pResult->testForFixup = 0; -#endif pResult->offsets[0] = offsetof(InstantiatedMethodDesc, m_pPerInstInfo); if (decltype(InstantiatedMethodDesc::m_pPerInstInfo)::isRelative) @@ -3109,11 +3105,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr { pResult->indirections = 3; pResult->testForNull = 0; -#ifdef FEATURE_PREJIT - pResult->testForFixup = 1; -#else pResult->testForFixup = 0; -#endif pResult->offsets[0] = MethodTable::GetOffsetOfPerInstInfo(); pResult->offsets[1] = sizeof(TypeHandle*) * (pContextMT->GetNumDicts() - 1); uint32_t data; @@ -6037,16 +6029,6 @@ CorInfoHelpFunc CEEInfo::getCastingHelperStatic(TypeHandle clsHnd, bool fThrowin _ASSERTE(helper == CORINFO_HELP_ISINSTANCEOFANY); } -#ifdef FEATURE_PREJIT - BOOL t1, t2, forceInstr; - SystemDomain::GetCompilationOverrides(&t1, &t2, &forceInstr); - if (forceInstr) - { - // If we're compiling for instrumentation, use the slowest but instrumented cast helper - helper = CORINFO_HELP_ISINSTANCEOFANY; - } -#endif - if (fThrowing) { const int delta = CORINFO_HELP_CHKCASTANY - CORINFO_HELP_ISINSTANCEOFANY; @@ -11820,17 +11802,12 @@ HRESULT CEEJitInfo::allocPgoInstrumentationBySchema( codeSize = m_ILHeader->GetCodeSize(); } -#ifdef FEATURE_PREJIT - *pBlockCounts = m_pMethodBeingCompiled->GetLoaderModule()->AllocateMethodBlockCounts(m_pMethodBeingCompiled->GetMemberDef(), count, codeSize); - hr = (*pBlockCounts != nullptr) ? S_OK : E_OUTOFMEMORY; -#else // FEATURE_PREJIT #ifdef FEATURE_PGO hr = PgoManager::allocPgoInstrumentationBySchema(m_pMethodBeingCompiled, pSchema, countSchemaItems, pInstrumentationData); #else _ASSERTE(!"allocMethodBlockCounts not implemented on CEEJitInfo!"); hr = E_NOTIMPL; #endif // !FEATURE_PGO -#endif // !FEATURE_PREJIT EE_TO_JIT_TRANSITION(); @@ -12680,31 +12657,6 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, timer.Start(); -#ifdef FEATURE_PREJIT - - if (g_pConfig->RequireZaps() == EEConfig::REQUIRE_ZAPS_ALL && - ftn->GetModule()->GetDomainFile()->IsZapRequired() && - PartialNGenStressPercentage() == 0 && -#ifdef FEATURE_STACK_SAMPLING - !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND) && -#endif - !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) - { - StackSString ss(SString::Ascii, "ZapRequire: JIT compiler invoked for "); - TypeString::AppendMethodInternal(ss, ftn); - -#ifdef _DEBUG - // Assert as some test may not check their error codes well. So throwing an - // exception may not cause a test failure (as it should). - StackScratchBuffer scratch; - DbgAssertDialog(__FILE__, __LINE__, (char*)ss.GetUTF8(scratch)); -#endif // _DEBUG - - COMPlusThrowNonLocalized(kFileNotFoundException, ss.GetUnicode()); - } - -#endif // FEATURE_PREJIT - EEJitManager *jitMgr = ExecutionManager::GetEEJitManager(); if (!jitMgr->LoadJIT()) { @@ -13071,86 +13023,6 @@ extern "C" unsigned __stdcall PartialNGenStressPercentage() #endif // _DEBUG } -#ifdef FEATURE_PREJIT -/*********************************************************************/ - -// -// Table loading functions -// -void Module::LoadHelperTable() -{ - STANDARD_VM_CONTRACT; - -#ifndef CROSSGEN_COMPILE - COUNT_T tableSize; - BYTE * table = (BYTE *) GetNativeImage()->GetNativeHelperTable(&tableSize); - - if (tableSize == 0) - return; - - BYTE * curEntry = table; - BYTE * tableEnd = table + tableSize; - -#ifdef FEATURE_PERFMAP - PerfMap::LogStubs(__FUNCTION__, GetSimpleName(), (PCODE)table, tableSize); -#endif - -#ifdef LOGGING - int iEntryNumber = 0; -#endif // LOGGING - - // - // Fill in helpers - // - - while (curEntry < tableEnd) - { - DWORD dwHelper = *(DWORD *)curEntry; - - int iHelper = (USHORT)dwHelper; - _ASSERTE(iHelper < CORINFO_HELP_COUNT); - - LOG((LF_JIT, LL_INFO1000000, "JIT helper %3d (%-40s: table @ %p, size 0x%x, entry %3d @ %p, pfnHelper %p)\n", - iHelper, hlpFuncTable[iHelper].name, table, tableSize, iEntryNumber, curEntry, hlpFuncTable[iHelper].pfnHelper)); - - PCODE pfnHelper = CEEJitInfo::getHelperFtnStatic((CorInfoHelpFunc)iHelper); - - if (dwHelper & CORCOMPILE_HELPER_PTR) - { - // - // Indirection cell - // - *(TADDR *)curEntry = pfnHelper; - curEntry = curEntry + sizeof(TADDR); - } - else - { - // - // Jump thunk - // - -#if defined(TARGET_AMD64) - *curEntry = X86_INSTR_JMP_REL32; - *(INT32 *)(curEntry + 1) = rel32UsingJumpStub((INT32 *)(curEntry + 1), pfnHelper, NULL, GetLoaderAllocator()); -#else // all other platforms - emitJump(curEntry, curEntry, (LPVOID)pfnHelper); - _ASSERTE(HELPER_TABLE_ENTRY_LEN >= JUMP_ALLOCATE_SIZE); -#endif - - curEntry = curEntry + HELPER_TABLE_ENTRY_LEN; - } - -#ifdef LOGGING - // Note that some table entries are sizeof(TADDR) in length, and some are HELPER_TABLE_ENTRY_LEN in length - ++iEntryNumber; -#endif // LOGGING - } - - ClrFlushInstructionCache(table, tableSize); -#endif // CROSSGEN_COMPILE -} -#endif // FEATURE_PREJIT - #ifdef FEATURE_READYTORUN CorInfoHelpFunc MapReadyToRunHelper(ReadyToRunHelper helperNum) { @@ -14791,21 +14663,6 @@ LPVOID EECodeInfo::findNextFunclet (LPVOID pvFuncletStart, SIZE_T if (pFunctionEntry != NULL) { -#ifdef FEATURE_PREJIT - // workaround: Check for indirect entry that is generated for cold part of main method body. - if ((TADDR)pvFuncletStart < (TADDR)uImageBase + pFunctionEntry->BeginAddress || - (TADDR)uImageBase + pFunctionEntry->EndAddress <= (TADDR)pvFuncletStart) - { - Module * pZapModule = ExecutionManager::FindZapModule((TADDR)pvFuncletStart); - NGenLayoutInfo * pLayoutInfo = pZapModule->GetNGenLayoutInfo(); - - int ColdFunctionIndex = NativeUnwindInfoLookupTable::LookupUnwindInfoForMethod((DWORD)((TADDR)pvFuncletStart - uImageBase), - pLayoutInfo->m_pRuntimeFunctions[2], - 0, pLayoutInfo->m_nRuntimeFunctions[2] - 1); - - pFunctionEntry = pLayoutInfo->m_pRuntimeFunctions[2] + ColdFunctionIndex; - } -#endif _ASSERTE((TADDR)pvFuncletStart == (TADDR)uImageBase + pFunctionEntry->BeginAddress); _ASSERTE((TADDR)uImageBase + pFunctionEntry->EndAddress <= (TADDR)pvFuncletStart + cbCode); diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 961d9c76fd0081..1f92db9a93a20e 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -146,14 +146,6 @@ SIZE_T MethodDesc::SizeOf() #endif | mdcHasNativeCodeSlot)]; -#ifdef FEATURE_PREJIT - if (HasNativeCodeSlot()) - { - size += (*dac_cast(GetAddrOfNativeCodeSlot()) & FIXUP_LIST_MASK) ? - sizeof(FixupListSlot) : 0; - } -#endif - return size; } @@ -459,10 +451,6 @@ void MethodDesc::GetSig(PCCOR_SIGNATURE *ppSig, DWORD *pcSig) *ppSig = pSMD->GetStoredMethodSig(pcSig); PREFIX_ASSUME(*ppSig != NULL); -#if defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE) - _ASSERTE_MSG((**ppSig & IMAGE_CEE_CS_CALLCONV_NEEDSRESTORE) == 0 || !IsILStub() || (strncmp(m_pszDebugMethodName,"IL_STUB_Array", 13)==0) , - "CheckRestore must be called on IL stub MethodDesc"); -#endif // FEATURE_PREJIT && !DACCESS_COMPILE return; } } @@ -1040,22 +1028,7 @@ PCODE MethodDesc::GetPreImplementedCode() } CONTRACTL_END; -#ifdef FEATURE_PREJIT - PCODE pNativeCode = GetNativeCode(); - if (pNativeCode == NULL) - return NULL; - - Module* pZapModule = GetZapModule(); - if (pZapModule == NULL) - return NULL; - - if (!pZapModule->IsZappedCode(pNativeCode)) - return NULL; - - return pNativeCode; -#else // !FEATURE_PREJIT return NULL; -#endif // !FEATURE_PREJIT } //******************************************************************************* @@ -1443,23 +1416,7 @@ Module* MethodDesc::GetZapModule() } CONTRACTL_END -#ifdef FEATURE_PREJIT - if (!IsZapped()) - { - return NULL; - } - else - if (!IsTightlyBoundToMethodTable()) - { - return ExecutionManager::FindZapModule(dac_cast(this)); - } - else - { - return GetMethodTable()->GetLoaderModule(); - } -#else return NULL; -#endif } //******************************************************************************* @@ -2519,149 +2476,9 @@ BOOL MethodDesc::MayHaveNativeCode() #ifndef DACCESS_COMPILE -#ifdef FEATURE_PREJIT -//--------------------------------------------------------------------------------------- -// -// Restores ET_INTERNAL TypeHandles in an IL stub signature. -// This function will parse one type and expects psig to be pointing to the element type. If -// the type is a generic instantiation, we will recursively parse it. -// -void -RestoreSignatureContainingInternalTypesParseType( - SigPointer & psig) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - } - CONTRACTL_END; - - SigPointer sigOrig = psig; - - CorElementType eType; - IfFailThrow(psig.GetElemType(&eType)); - - switch (eType) - { - case ELEMENT_TYPE_INTERNAL: - { - TypeHandle * pTypeHandle = (TypeHandle *)psig.GetPtr(); - - void * ptr; - IfFailThrow(psig.GetPointer(&ptr)); - - Module::RestoreTypeHandlePointerRaw(pTypeHandle); - } - break; - - case ELEMENT_TYPE_GENERICINST: - { - RestoreSignatureContainingInternalTypesParseType(psig); - - // Get generic arg count - uint32_t nArgs; - IfFailThrow(psig.GetData(&nArgs)); - - for (uint32_t i = 0; i < nArgs; i++) - { - RestoreSignatureContainingInternalTypesParseType(psig); - } - } - break; - - case ELEMENT_TYPE_BYREF: - case ELEMENT_TYPE_PTR: - case ELEMENT_TYPE_PINNED: - case ELEMENT_TYPE_SZARRAY: - // Call recursively - RestoreSignatureContainingInternalTypesParseType(psig); - break; - - default: - IfFailThrow(sigOrig.SkipExactlyOne()); - psig = sigOrig; - break; - } -} - -//--------------------------------------------------------------------------------------- -// -// Restores ET_INTERNAL TypeHandles in an IL stub signature. -// -static -void -RestoreSignatureContainingInternalTypes( - PCCOR_SIGNATURE pSig, - DWORD cSig) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - } - CONTRACTL_END; - - Volatile * pVolatileSig = (Volatile *)pSig; - if (*pVolatileSig & IMAGE_CEE_CS_CALLCONV_NEEDSRESTORE) - { - uint32_t nArgs; - SigPointer psig(pSig, cSig); - - // Skip calling convention - BYTE uCallConv; - IfFailThrow(psig.GetByte(&uCallConv)); - - if ((uCallConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD) - { - ThrowHR(META_E_BAD_SIGNATURE); - } - - // Skip type parameter count - if (uCallConv & IMAGE_CEE_CS_CALLCONV_GENERIC) - { - IfFailThrow(psig.GetData(NULL)); - } - - // Get arg count - IfFailThrow(psig.GetData(&nArgs)); - - nArgs++; // be sure to handle the return type - - for (ULONG i = 0; i < nArgs; i++) - { - RestoreSignatureContainingInternalTypesParseType(psig); - } - - // clear the needs-restore bit - *pVolatileSig &= (BYTE)~IMAGE_CEE_CS_CALLCONV_NEEDSRESTORE; - } -} // RestoreSignatureContainingInternalTypes - void DynamicMethodDesc::Restore() { - CONTRACTL - { - THROWS; - GC_TRIGGERS; - } - CONTRACTL_END; - - if (IsSignatureNeedsRestore()) - { - _ASSERTE(IsILStub()); - - DWORD cSigLen; - PCCOR_SIGNATURE pSig = GetStoredMethodSig(&cSigLen); - - RestoreSignatureContainingInternalTypes(pSig, cSigLen); - } } -#else // FEATURE_PREJIT -void DynamicMethodDesc::Restore() -{ -} -#endif // FEATURE_PREJIT #endif // !DACCESS_COMPILE @@ -2683,23 +2500,7 @@ void MethodDesc::CheckRestore(ClassLoadLevel level) // First restore method table pointer in singleton chunk; // it might be out-of-module -#ifdef FEATURE_PREJIT - GetMethodDescChunk()->RestoreMTPointer(level); -#ifdef _DEBUG - Module::RestoreMethodTablePointer(&m_pDebugMethodTable, NULL, level); -#endif - // Now restore wrapped method desc if present; we need this for the dictionary layout too - if (pIMD->IMD_IsWrapperStubWithInstantiations()) - Module::RestoreMethodDescPointer(&pIMD->m_pWrappedMethodDesc); - - // Finally restore the dictionary itself (including instantiation) - if (GetMethodDictionary()) - { - GetMethodDictionary()->Restore(GetNumGenericMethodArgs(), level); - } -#else ClassLoader::EnsureLoaded(TypeHandle(GetMethodTable()), level); -#endif g_IBCLogger.LogMethodDescWriteAccess(this); @@ -2770,93 +2571,6 @@ MethodDesc* MethodDesc::GetMethodDescFromStubAddr(PCODE addr, BOOL fSpeculative RETURN(NULL); // Not found } -#ifdef FEATURE_PREJIT -//******************************************************************************* -TADDR MethodDesc::GetFixupList() -{ - LIMITED_METHOD_CONTRACT; - - if (HasNativeCodeSlot()) - { - TADDR pSlot = GetAddrOfNativeCodeSlot(); - if (*dac_cast(pSlot) & FIXUP_LIST_MASK) - return FixupListSlot::GetValueAtPtr(pSlot + sizeof(NativeCodeSlot)); - } - - return NULL; -} - -//******************************************************************************* -BOOL MethodDesc::IsRestored_NoLogging() -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - STATIC_CONTRACT_SUPPORTS_DAC; - - DPTR(RelativeFixupPointer) ppMT = GetMethodTablePtr(); - - if (ppMT->IsTagged(dac_cast(ppMT))) - return FALSE; - - if (!ppMT->GetValue(dac_cast(ppMT))->IsRestored_NoLogging()) - return FALSE; - - if (GetClassification() == mcInstantiated) - { - InstantiatedMethodDesc *pIMD = AsInstantiatedMethodDesc(); - return (pIMD->m_wFlags2 & InstantiatedMethodDesc::Unrestored) == 0; - } - - if (IsILStub()) // the only stored-sig MD type that uses ET_INTERNAL - { - PTR_DynamicMethodDesc pDynamicMD = AsDynamicMethodDesc(); - return pDynamicMD->IsRestored(); - } - - return TRUE; -} - -BOOL MethodDesc::IsRestored() -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - STATIC_CONTRACT_SUPPORTS_DAC; - -#ifdef DACCESS_COMPILE - - return IsRestored_NoLogging(); - -#else // not DACCESS_COMPILE - - DPTR(RelativeFixupPointer) ppMT = GetMethodTablePtr(); - - if (ppMT->IsTagged(dac_cast(ppMT))) - return FALSE; - - if (!ppMT->GetValue(dac_cast(ppMT))->IsRestored()) - return FALSE; - - if (GetClassification() == mcInstantiated) - { - InstantiatedMethodDesc *pIMD = AsInstantiatedMethodDesc(); - return (pIMD->m_wFlags2 & InstantiatedMethodDesc::Unrestored) == 0; - } - - if (IsILStub()) // the only stored-sig MD type that uses ET_INTERNAL - { - PTR_DynamicMethodDesc pDynamicMD = AsDynamicMethodDesc(); - return pDynamicMD->IsRestored(); - } - - return TRUE; - -#endif // DACCESS_COMPILE - -} - -#else // !FEATURE_PREJIT //******************************************************************************* BOOL MethodDesc::IsRestored_NoLogging() { @@ -2870,7 +2584,6 @@ BOOL MethodDesc::IsRestored() SUPPORTS_DAC; return TRUE; } -#endif // !FEATURE_PREJIT #ifdef HAS_COMPACT_ENTRYPOINTS diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 299abe8436e257..3478e5a36ecc5d 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -23,9 +23,7 @@ #include "eeconfig.h" #include "precode.h" -#ifndef FEATURE_PREJIT #include "fixuppointer.h" -#endif class Stub; class FCallMethodDesc; @@ -1660,26 +1658,6 @@ class MethodDesc MethodImpl *GetMethodImpl(); - -#if defined(FEATURE_PREJIT ) && !defined(DACCESS_COMPILE) - //================================================================ - // Precompilation (NGEN) - - // - // After the zapper compiles all code in a module it may attempt - // to populate entries in all dictionaries - // associated with instantiations of generic methods. This is an optional step - nothing will - // go wrong at runtime except we may get more one-off calls to JIT_GenericHandle. - // Although these are one-off we prefer to avoid them since they touch metadata - // pages. - // - // Fully populating a dictionary may in theory load more types, methods etc. However - // for the moment only those entries that refer to things that - // are already loaded will be filled in. - void PrepopulateDictionary(DataImage * image, BOOL nonExpansive); - -#endif // FEATURE_PREJIT && !DACCESS_COMPILE - TADDR GetFixupList(); BOOL IsRestored_NoLogging(); @@ -1943,7 +1921,6 @@ class MethodDesc private: PCODE PrepareILBasedCode(PrepareCodeConfig* pConfig); PCODE GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier); - PCODE GetPrecompiledNgenCode(PrepareCodeConfig* pConfig); PCODE GetPrecompiledR2RCode(PrepareCodeConfig* pConfig); PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0); COR_ILMETHOD_DECODER* GetAndVerifyILHeader(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory); @@ -2254,9 +2231,6 @@ class MethodDescChunk { friend class MethodDesc; friend class CheckAsmOffsets; -#if defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE) - friend class MethodDesc::SaveChunk; -#endif #ifdef DACCESS_COMPILE friend class NativeImageDumper; #endif // DACCESS_COMPILE @@ -2373,19 +2347,7 @@ class MethodDescChunk m_count = static_cast(methodDescCount - 1); _ASSERTE(GetCount() == methodDescCount); } -#endif // !DACCESS_COMPILE -#ifdef FEATURE_PREJIT -#ifndef DACCESS_COMPILE - inline void RestoreMTPointer(ClassLoadLevel level = CLASS_LOADED) - { - LIMITED_METHOD_CONTRACT; - Module::RestoreMethodTablePointer(&m_methodTable, NULL, level); - } -#endif // !DACCESS_COMPILE -#endif // FEATURE_PREJIT - -#ifndef DACCESS_COMPILE void SetNextChunk(MethodDescChunk *chunk) { LIMITED_METHOD_CONTRACT; @@ -2408,11 +2370,7 @@ class MethodDescChunk BOOL IsZapped() { LIMITED_METHOD_DAC_CONTRACT; -#ifdef FEATURE_PREJIT - return (m_flagsAndTokenRange & enum_flag_IsZapped) != 0; -#else return FALSE; -#endif } inline BOOL HasCompactEntryPoints() @@ -2833,9 +2791,6 @@ class NDirectImportThunkGlue LIMITED_METHOD_CONTRACT; } }; -#ifdef FEATURE_PREJIT -PORTABILITY_WARNING("NDirectImportThunkGlue"); -#endif // FEATURE_PREJIT #endif // HAS_NDIRECT_IMPORT_PRECODE @@ -3547,14 +3502,6 @@ class InstantiatedMethodDesc : public MethodDesc _ASSERTE(IsGenericComPlusCall()); SIZE_T size = s_ClassificationSizeTable[m_wFlags & (mdcClassification | mdcHasNonVtableSlot | mdcMethodImpl | mdcHasNativeCodeSlot)]; -#ifdef FEATURE_PREJIT - if (HasNativeCodeSlot()) - { - size += (*dac_cast(GetAddrOfNativeCodeSlot()) & FIXUP_LIST_MASK) ? - sizeof(FixupListSlot) : 0; - } -#endif - return dac_cast(dac_cast(this) + size); } #endif // FEATURE_COMINTEROP diff --git a/src/coreclr/vm/method.inl b/src/coreclr/vm/method.inl index 1175d2bd3aeb73..cf96ce127ff19e 100644 --- a/src/coreclr/vm/method.inl +++ b/src/coreclr/vm/method.inl @@ -24,11 +24,7 @@ inline InstantiatedMethodDesc* MethodDesc::AsInstantiatedMethodDesc() const inline BOOL MethodDesc::IsZapped() { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_PREJIT - return GetMethodDescChunk()->IsZapped(); -#else return FALSE; -#endif } inline PTR_DynamicResolver DynamicMethodDesc::GetResolver() diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 6a5a670f26b8f0..7314726ffe3115 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -42,9 +42,6 @@ #include "customattribute.h" #include "virtualcallstub.h" #include "contractimpl.h" -#ifdef FEATURE_PREJIT -#include "zapsig.h" -#endif //FEATURE_PREJIT #ifdef FEATURE_COMINTEROP #include "comcallablewrapper.h" @@ -448,17 +445,7 @@ PTR_Module MethodTable::GetModuleIfLoaded() } CONTRACTL_END; -#ifdef FEATURE_PREJIT - g_IBCLogger.LogMethodTableAccess(this); - - MethodTable * pMTForModule = IsArray() ? this : GetCanonicalMethodTable(); - if (!pMTForModule->HasModuleOverride()) - return pMTForModule->GetLoaderModule(); - - return Module::RestoreModulePointerIfLoaded(pMTForModule->GetModuleOverridePtr(), pMTForModule->GetLoaderModule()); -#else return GetModule(); -#endif } #ifndef DACCESS_COMPILE @@ -693,30 +680,7 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule MODE_ANY; } CONTRACTL_END; -#ifdef FEATURE_PREJIT - if (m_pMethodTable.IsTagged()) - { - // Ideally, we would use Module::RestoreMethodTablePointer here. Unfortunately, it is not - // possible because of the current type loader architecture that restores types incrementally - // even in the NGen case. - MethodTable * pItfMT = *(m_pMethodTable.GetValuePtr()); - - // Restore the method table, but do not write it back if it has instantiation. We do not want - // to write back the approximate instantiations. - Module::RestoreMethodTablePointerRaw(&pItfMT, pContainingModule, CLASS_LOAD_APPROXPARENTS); - - if (!pItfMT->HasInstantiation()) - { - // m_pMethodTable.SetValue() is not used here since we want to update the indirection cell - *m_pMethodTable.GetValuePtr() = pItfMT; - } - - return pItfMT; - } - MethodTable * pItfMT = m_pMethodTable.GetValue(); -#else MethodTable * pItfMT = GetMethodTable(); -#endif ClassLoader::EnsureLoaded(TypeHandle(pItfMT), CLASS_LOAD_APPROXPARENTS); return pItfMT; } @@ -1820,29 +1784,6 @@ MethodTable::IsExternallyVisible() return bIsVisible; } // MethodTable::IsExternallyVisible -#ifdef FEATURE_PREJIT - -BOOL MethodTable::CanShareVtableChunksFrom(MethodTable *pTargetMT, Module *pCurrentLoaderModule, Module *pCurrentPreferredZapModule) -{ - WRAPPER_NO_CONTRACT; - - // These constraints come from two places: - // 1. A non-zapped MT cannot share with a zapped MT since it may result in SetSlot() on a read-only slot - // 2. Zapping this MT in MethodTable::Save cannot "unshare" something we decide to share now - // - // We could fix both of these and allow non-zapped MTs to share chunks fully by doing the following - // 1. Fix the few dangerous callers of SetSlot to first check whether the chunk itself is zapped - // (see MethodTableBuilder::CopyExactParentSlots, or we could use ExecutionManager::FindZapModule) - // 2. Have this function return FALSE if IsCompilationProcess and rely on MethodTable::Save to do all sharing for the NGen case - - return !pTargetMT->IsZapped() && - pTargetMT->GetLoaderModule() == pCurrentLoaderModule && - pCurrentLoaderModule == pCurrentPreferredZapModule && - pCurrentPreferredZapModule == Module::GetPreferredZapModuleForMethodTable(pTargetMT); -} - -#else - BOOL MethodTable::CanShareVtableChunksFrom(MethodTable *pTargetMT, Module *pCurrentLoaderModule) { WRAPPER_NO_CONTRACT; @@ -1850,8 +1791,6 @@ BOOL MethodTable::CanShareVtableChunksFrom(MethodTable *pTargetMT, Module *pCurr return pTargetMT->GetLoaderModule() == pCurrentLoaderModule; } -#endif - #ifdef _DEBUG void @@ -2998,35 +2937,6 @@ void MethodTable::AllocateRegularStaticBoxes() GCPROTECT_BEGININTERIOR(pStaticBase); -#ifdef FEATURE_PREJIT - // In ngened case, we have cached array with boxed statics MTs. In JITed case, we have just the FieldDescs - ClassCtorInfoEntry *pClassCtorInfoEntry = GetClassCtorInfoIfExists(); - if (pClassCtorInfoEntry != NULL) - { - OBJECTREF* pStaticSlots = (OBJECTREF*)(pStaticBase + pClassCtorInfoEntry->firstBoxedStaticOffset); - GCPROTECT_BEGININTERIOR(pStaticSlots); - - ArrayDPTR(RelativeFixupPointer) ppMTs = GetLoaderModule()->GetZapModuleCtorInfo()-> - GetGCStaticMTs(pClassCtorInfoEntry->firstBoxedStaticMTIndex); - - DWORD numBoxedStatics = pClassCtorInfoEntry->numBoxedStatics; - for (DWORD i = 0; i < numBoxedStatics; i++) - { - Module::RestoreMethodTablePointer(&(ppMTs[i]), GetLoaderModule()); - - MethodTable *pFieldMT = ppMTs[i].GetValue(); - - _ASSERTE(pFieldMT); - - LOG((LF_CLASSLOADER, LL_INFO10000, "\tInstantiating static of type %s\n", pFieldMT->GetDebugClassName())); - OBJECTREF obj = AllocateStaticBox(pFieldMT, pClassCtorInfoEntry->hasFixedAddressVTStatics); - - SetObjectReference( &(pStaticSlots[i]), obj); - } - GCPROTECT_END(); - } - else -#endif { // We should never take this codepath in zapped images. _ASSERTE(!IsZapped()); @@ -4449,12 +4359,6 @@ void MethodTable::DoFullyLoad(Generics::RecursionGraph * const pVisited, const pMD->SetDoesNotHaveEquivalentValuetypeParameters(); } #else -#ifdef FEATURE_PREJIT - if (!IsZapped() && pMD->IsVirtual() && !IsCompilationProcess() ) - { - pMD->PrepareForUseAsADependencyOfANativeImage(); - } -#endif #endif //FEATURE_TYPEEQUIVALENCE } } @@ -4597,148 +4501,6 @@ void MethodTable::DoFullyLoad(Generics::RecursionGraph * const pVisited, const #ifndef DACCESS_COMPILE -#ifdef FEATURE_PREJIT - -// For a MethodTable in a native image, decode sufficient encoded pointers -// that the TypeKey for this type is recoverable. -// -// For instantiated generic types, we need the generic type arguments, -// the EEClass pointer, and its Module pointer. -// (For non-generic types, the EEClass and Module are always hard bound). -// -// The process is applied recursively e.g. consider C[]>. -// It is guaranteed to terminate because types cannot contain cycles in their structure. -// -// Also note that no lock is required; the process of restoring this information is idempotent. -// (Note the atomic action at the end though) -// -void MethodTable::DoRestoreTypeKey() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - } - CONTRACTL_END; - - // If we have an indirection cell then restore the m_pCanonMT and its module pointer - // - if (union_getLowBits(m_pCanonMT.GetValue()) == UNION_INDIRECTION) - { - Module::RestoreMethodTablePointerRaw((MethodTable **)(union_getPointer(m_pCanonMT.GetValue())), - GetLoaderModule(), CLASS_LOAD_UNRESTORED); - } - - MethodTable * pMTForModule = IsArray() ? this : GetCanonicalMethodTable(); - if (pMTForModule->HasModuleOverride()) - { - Module::RestoreModulePointer(pMTForModule->GetModuleOverridePtr(), pMTForModule->GetLoaderModule()); - } - - if (IsArray()) - { - // - // Restore array element type handle - // - Module::RestoreTypeHandlePointerRaw(GetArrayElementTypeHandlePtr(), - GetLoaderModule(), CLASS_LOAD_UNRESTORED); - } - - // Next restore the instantiation and recurse - Instantiation inst = GetInstantiation(); - for (DWORD j = 0; j < inst.GetNumArgs(); j++) - { - Module::RestoreTypeHandlePointer(&inst.GetRawArgs()[j], GetLoaderModule(), CLASS_LOAD_UNRESTORED); - } - - FastInterlockAnd(&GetWriteableDataForWrite()->m_dwFlags, ~MethodTableWriteableData::enum_flag_UnrestoredTypeKey); -} - -//========================================================================================== -// For a MethodTable in a native image, apply Restore actions -// * Decode any encoded pointers -// * Instantiate static handles -// * Propagate Restore to EEClass -// For array method tables, Restore MUST BE IDEMPOTENT as it can be entered from multiple threads -// For other classes, restore cannot be entered twice because the loader maintains locks -// -// When you actually restore the MethodTable for a generic type, the generic -// dictionary is restored. That means: -// * Parent slots in the PerInstInfo are restored by this method eagerly. They are copied down from the -// parent in code:ClassLoader.LoadExactParentAndInterfacesTransitively -// * Instantiation parameters in the dictionary are restored eagerly when the type is restored. These are -// either hard bound pointers, or tagged tokens (fixups). -// * All other dictionary entries are either hard bound pointers or they are NULL (they are cleared when we -// freeze the Ngen image). They are *never* tagged tokens. -void MethodTable::Restore() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - PRECONDITION(IsZapped()); - PRECONDITION(!IsRestored_NoLogging()); - PRECONDITION(!HasUnrestoredTypeKey()); - } - CONTRACTL_END; - - g_IBCLogger.LogMethodTableAccess(this); - - STRESS_LOG1(LF_ZAP, LL_INFO10000, "MethodTable::Restore: Restoring type %pT\n", this); - LOG((LF_ZAP, LL_INFO10000, - "Restoring methodtable %s at " FMT_ADDR ".\n", GetDebugClassName(), DBG_ADDR(this))); - - // Class pointer should be restored already (in DoRestoreTypeKey) - CONSISTENCY_CHECK(IsClassPointerValid()); - - // If this isn't the canonical method table itself, then restore the canonical method table - // We will load the canonical method table to level EXACTPARENTS in LoadExactParents - if (!IsCanonicalMethodTable()) - { - ClassLoader::EnsureLoaded(GetCanonicalMethodTable(), CLASS_LOAD_APPROXPARENTS); - } - - // - // Restore parent method table - // - if (IsParentMethodTableIndirectPointerMaybeNull()) - { - Module::RestoreMethodTablePointerRaw(GetParentMethodTableValuePtr(), GetLoaderModule(), CLASS_LOAD_APPROXPARENTS); - } - else - { - ClassLoader::EnsureLoaded(ReadPointer(this, &MethodTable::m_pParentMethodTable, GetFlagHasIndirectParent()), - CLASS_LOAD_APPROXPARENTS); - } - - // - // Restore interface classes - // - InterfaceMapIterator it = IterateInterfaceMap(); - while (it.Next()) - { - // Just make sure that approximate interface is loaded. LoadExactParents fill in the exact interface later. - MethodTable * pIftMT; - pIftMT = it.GetInterfaceInfo()->GetApproxMethodTable(GetLoaderModule()); - _ASSERTE(pIftMT != NULL); - } - - if (HasCrossModuleGenericStaticsInfo()) - { - MethodTableWriteableData * pWriteableData = GetWriteableDataForWrite(); - CrossModuleGenericsStaticsInfo * pInfo = pWriteableData->GetCrossModuleGenericsStaticsInfo(); - - pInfo->m_pModuleForStatics = GetLoaderModule(); - } - - LOG((LF_ZAP, LL_INFO10000, - "Restored methodtable %s at " FMT_ADDR ".\n", GetDebugClassName(), DBG_ADDR(this))); - - // This has to be last! - SetIsRestored(); -} -#endif // FEATURE_PREJIT - #ifdef FEATURE_COMINTEROP //========================================================================================== @@ -6557,51 +6319,6 @@ ClassCtorInfoEntry* MethodTable::GetClassCtorInfoIfExists() { LIMITED_METHOD_CONTRACT; -#ifdef FEATURE_PREJIT - if (!IsZapped()) - return NULL; - - g_IBCLogger.LogCCtorInfoReadAccess(this); - - if (HasBoxedRegularStatics()) - { - ModuleCtorInfo *pModuleCtorInfo = GetZapModule()->GetZapModuleCtorInfo(); - DPTR(RelativePointer) ppMT = pModuleCtorInfo->ppMT; - PTR_DWORD hotHashOffsets = pModuleCtorInfo->hotHashOffsets; - PTR_DWORD coldHashOffsets = pModuleCtorInfo->coldHashOffsets; - - if (pModuleCtorInfo->numHotHashes) - { - DWORD hash = pModuleCtorInfo->GenerateHash(PTR_MethodTable(this), ModuleCtorInfo::HOT); - _ASSERTE(hash < pModuleCtorInfo->numHotHashes); - - for (DWORD i = hotHashOffsets[hash]; i != hotHashOffsets[hash + 1]; i++) - { - _ASSERTE(!ppMT[i].IsNull()); - if (dac_cast(pModuleCtorInfo->GetMT(i)) == dac_cast(this)) - { - return pModuleCtorInfo->cctorInfoHot + i; - } - } - } - - if (pModuleCtorInfo->numColdHashes) - { - DWORD hash = pModuleCtorInfo->GenerateHash(PTR_MethodTable(this), ModuleCtorInfo::COLD); - _ASSERTE(hash < pModuleCtorInfo->numColdHashes); - - for (DWORD i = coldHashOffsets[hash]; i != coldHashOffsets[hash + 1]; i++) - { - _ASSERTE(!ppMT[i].IsNull()); - if (dac_cast(pModuleCtorInfo->GetMT(i)) == dac_cast(this)) - { - return pModuleCtorInfo->cctorInfoCold + (i - pModuleCtorInfo->numElementsHot); - } - } - } - } -#endif // FEATURE_PREJIT - return NULL; } @@ -7930,11 +7647,7 @@ PCODE MethodTable::GetRestoredSlot(DWORD slotNumber) PCODE slot = pMT->GetSlot(slotNumber); - if ((slot != NULL) -#ifdef FEATURE_PREJIT - && !pMT->GetLoaderModule()->IsVirtualImportThunk(slot) -#endif - ) + if (slot != NULL) { return slot; } @@ -7970,11 +7683,7 @@ MethodTable * MethodTable::GetRestoredSlotMT(DWORD slotNumber) PCODE slot = pMT->GetSlot(slotNumber); - if ((slot != NULL) -#ifdef FEATURE_PREJIT - && !pMT->GetLoaderModule()->IsVirtualImportThunk(slot) -#endif - ) + if (slot != NULL) { return pMT; } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index a108253936baee..52e4ae94c2bf49 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -105,32 +105,20 @@ struct InterfaceInfo_t #endif // Method table of the interface -#ifdef FEATURE_PREJIT - FixupPointer m_pMethodTable; -#else PTR_MethodTable m_pMethodTable; -#endif public: FORCEINLINE PTR_MethodTable GetMethodTable() { LIMITED_METHOD_CONTRACT; -#ifdef FEATURE_PREJIT - return ReadPointerMaybeNull(this, &InterfaceInfo_t::m_pMethodTable); -#else return VolatileLoadWithoutBarrier(&m_pMethodTable); -#endif } #ifndef DACCESS_COMPILE void SetMethodTable(MethodTable * pMT) { LIMITED_METHOD_CONTRACT; -#ifdef FEATURE_PREJIT - m_pMethodTable.SetValueMaybeNull(pMT); -#else return VolatileStoreWithoutBarrier(&m_pMethodTable, pMT); -#endif } // Get approximate method table. This is used by the type loader before the type is fully loaded. @@ -140,11 +128,7 @@ struct InterfaceInfo_t #ifndef DACCESS_COMPILE InterfaceInfo_t(InterfaceInfo_t &right) { -#ifdef FEATURE_PREJIT - m_pMethodTable.SetValueMaybeNull(right.m_pMethodTable.GetValueMaybeNull()); -#else VolatileStoreWithoutBarrier(&m_pMethodTable, VolatileLoadWithoutBarrier(&right.m_pMethodTable)); -#endif } #else // !DACCESS_COMPILE private: @@ -324,22 +308,14 @@ struct MethodTableWriteableData enum_flag_CanCompareBitsOrUseFastGetHashCode = 0x00000200, // Is any field type or sub field type overrode Equals or GetHashCode enum_flag_HasCheckedCanCompareBitsOrUseFastGetHashCode = 0x00000400, // Whether we have checked the overridden Equals or GetHashCode -#ifdef FEATURE_PREJIT - // These flags are used only at ngen time. We store them here since - // we are running out of available flags in MethodTable. They may eventually - // go into ngen speficic state. - enum_flag_NGEN_IsFixedUp = 0x00010000, // This MT has been fixed up during NGEN - enum_flag_NGEN_IsNeedsRestoreCached = 0x00020000, // Set if we have cached the results of needs restore computation - enum_flag_NGEN_CachedNeedsRestore = 0x00040000, // The result of the needs restore computation - // enum_unused = 0x00080000, - - // enum_unused = 0x0010000, + // enum_unused = 0x00010000, + // enum_unused = 0x00020000, + // enum_unused = 0x00040000, + // enum_unused = 0x00080000, // enum_unused = 0x0010000, // enum_unused = 0x0020000, // enum_unused = 0x0040000, // enum_unused = 0x0080000, -#endif // FEATURE_PREJIT - #ifdef _DEBUG enum_flag_ParentMethodTablePointerValid = 0x40000000, enum_flag_HasInjectedInterfaceDuplicates = 0x80000000, @@ -384,45 +360,6 @@ struct MethodTableWriteableData } #endif -#ifdef FEATURE_PREJIT - inline BOOL IsFixedUp() const - { - LIMITED_METHOD_CONTRACT; - - return (m_dwFlags & enum_flag_NGEN_IsFixedUp); - } - inline void SetFixedUp() - { - LIMITED_METHOD_CONTRACT; - - m_dwFlags |= enum_flag_NGEN_IsFixedUp; - } - - inline BOOL IsNeedsRestoreCached() const - { - LIMITED_METHOD_CONTRACT; - - return (m_dwFlags & enum_flag_NGEN_IsNeedsRestoreCached); - } - - inline BOOL GetCachedNeedsRestore() const - { - LIMITED_METHOD_CONTRACT; - - _ASSERTE(IsNeedsRestoreCached()); - return (m_dwFlags & enum_flag_NGEN_CachedNeedsRestore); - } - - inline void SetCachedNeedsRestore(BOOL fNeedsRestore) - { - LIMITED_METHOD_CONTRACT; - - _ASSERTE(!IsNeedsRestoreCached()); - m_dwFlags |= enum_flag_NGEN_IsNeedsRestoreCached; - if (fNeedsRestore) m_dwFlags |= enum_flag_NGEN_CachedNeedsRestore; - } -#endif // FEATURE_PREJIT - inline LOADERHANDLE GetExposedClassObjectHandle() const { @@ -1483,11 +1420,7 @@ class MethodTable VtableIndirectionSlotIterator IterateVtableIndirectionSlots(); VtableIndirectionSlotIterator IterateVtableIndirectionSlotsFrom(DWORD index); -#ifdef FEATURE_PREJIT - static BOOL CanShareVtableChunksFrom(MethodTable *pTargetMT, Module *pCurrentLoaderModule, Module *pCurrentPreferredZapModule); -#else static BOOL CanShareVtableChunksFrom(MethodTable *pTargetMT, Module *pCurrentLoaderModule); -#endif inline BOOL HasNonVirtualSlots() { @@ -1951,11 +1884,7 @@ class MethodTable bool GetFlagHasIndirectParent() { -#ifdef FEATURE_PREJIT - return !!GetFlag(enum_flag_HasIndirectParent); -#else return false; -#endif } #ifndef DACCESS_COMPILE @@ -2926,11 +2855,7 @@ class MethodTable { LIMITED_METHOD_DAC_CONTRACT; -#ifdef FEATURE_PREJIT - return GetFlag(enum_flag_IsPreRestored); -#else return FALSE; -#endif } //------------------------------------------------------------------- diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index b1af313a29556b..b487040477760a 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -36,14 +36,6 @@ FORCEINLINE PTR_EEClass MethodTable::GetClass_NoLogging() TADDR canonicalMethodTable = union_getPointer(addr); return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT)); } -#ifdef FEATURE_PREJIT - else if (lowBits == UNION_INDIRECTION) - { - // pointer to indirection cell that points to canonical MethodTable - TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(addr)); - return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT)); - } -#endif #ifdef DACCESS_COMPILE // Minidumps don't guarantee that every member of every class will be able to work here. #else @@ -59,15 +51,6 @@ FORCEINLINE PTR_EEClass MethodTable::GetClass_NoLogging() return PTR_EEClass(addr); } -#ifdef FEATURE_PREJIT - if ((addr & 1) != 0) - { - // pointer to indirection cell that points to canonical MethodTable - TADDR canonicalMethodTable = *PTR_TADDR(addr - 3); - return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT)); - } -#endif - // pointer to canonical MethodTable. return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(addr - 2), &MethodTable::m_pCanonMT)); #endif @@ -124,16 +107,6 @@ inline BOOL MethodTable::IsClassPointerValid() TADDR canonicalMethodTable = union_getPointer(addr); return !PTR_MethodTable(canonicalMethodTable)->m_pEEClass.IsNull(); } -#ifdef FEATURE_PREJIT - else if (lowBits == UNION_INDIRECTION) - { - // pointer to indirection cell that points to canonical MethodTable - TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(addr)); - if (CORCOMPILE_IS_POINTER_TAGGED(canonicalMethodTable)) - return FALSE; - return !PTR_MethodTable(canonicalMethodTable)->m_pEEClass.IsNull(); - } -#endif _ASSERTE(!"Malformed m_pEEClass in MethodTable"); return FALSE; } @@ -144,11 +117,7 @@ inline BOOL MethodTable::IsZapped() { LIMITED_METHOD_DAC_CONTRACT; -#ifdef FEATURE_PREJIT - return GetFlag(enum_flag_IsZapped); -#else return FALSE; -#endif } //========================================================================================== @@ -974,12 +943,6 @@ inline PTR_MethodTable MethodTable::GetCanonicalMethodTable() // pointer to canonical MethodTable. return PTR_MethodTable(union_getPointer(addr)); } -#ifdef FEATURE_PREJIT - else if (lowBits == UNION_INDIRECTION) - { - return PTR_MethodTable(*PTR_TADDR(union_getPointer(addr))); - } -#endif _ASSERTE(!"Malformed m_pCanonMT in MethodTable"); return NULL; #else @@ -987,11 +950,6 @@ inline PTR_MethodTable MethodTable::GetCanonicalMethodTable() if ((addr & 2) == 0) return dac_cast(this); -#ifdef FEATURE_PREJIT - if ((addr & 1) != 0) - return PTR_MethodTable(*PTR_TADDR(addr - 3)); -#endif - return PTR_MethodTable(addr - 2); #endif } @@ -1001,19 +959,7 @@ inline TADDR MethodTable::GetCanonicalMethodTableFixup() { LIMITED_METHOD_DAC_CONTRACT; -#ifdef FEATURE_PREJIT - TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT); - LowBits lowBits = union_getLowBits(addr); - if (lowBits == UNION_INDIRECTION) - { - // pointer to canonical MethodTable. - return *PTR_TADDR(union_getPointer(addr)); - } - else -#endif - { - return NULL; - } + return NULL; } //========================================================================================== @@ -1469,19 +1415,6 @@ FORCEINLINE PTR_Module MethodTable::GetGenericsStaticsModuleAndID(DWORD * pID) _ASSERTE(HasGenericsStaticsInfo()); -#ifdef FEATURE_PREJIT - // This is performance sensitive codepath inlined into JIT helpers. Test the flag directly without - // checking IsStringOrArray() first. IsStringOrArray() will always be false here. - _ASSERTE(!IsStringOrArray()); - if (m_dwFlags & enum_flag_StaticsMask_IfGenericsThenCrossModule) - { - CrossModuleGenericsStaticsInfo *pInfo = ReadPointer(this, &MethodTable::m_pWriteableData)->GetCrossModuleGenericsStaticsInfo(); - _ASSERTE(FitsIn(pInfo->m_DynamicTypeID) || pInfo->m_DynamicTypeID == (SIZE_T)-1); - *pID = static_cast(pInfo->m_DynamicTypeID); - return pInfo->m_pModuleForStatics; - } -#endif // FEATURE_PREJIT - _ASSERTE(FitsIn(GetGenericsStaticsInfo()->m_DynamicTypeID) || GetGenericsStaticsInfo()->m_DynamicTypeID == (SIZE_T)-1); *pID = static_cast(GetGenericsStaticsInfo()->m_DynamicTypeID); return GetLoaderModule(); diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 40b037e6a6b25f..d563e21b359913 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -1801,18 +1801,7 @@ MethodTableBuilder::BuildMethodTableThrowing( // Now setup the method table -#ifdef FEATURE_PREJIT - Module *pComputedPZM = pLoaderModule; - - if (bmtGenerics->GetNumGenericArgs() > 0) - { - pComputedPZM = Module::ComputePreferredZapModule(pModule, bmtGenerics->GetInstantiation()); - } - - SetupMethodTable2(pLoaderModule, pComputedPZM); -#else // FEATURE_PREJIT SetupMethodTable2(pLoaderModule); -#endif // FEATURE_PREJIT MethodTable * pMT = GetHalfBakedMethodTable(); @@ -2074,10 +2063,6 @@ MethodTableBuilder::BuildMethodTableThrowing( GetCl(), GetHalfBakedMethodTable()); -#ifdef FEATURE_PREJIT - _ASSERTE(pComputedPZM == Module::GetPreferredZapModuleForMethodTable(pMT)); -#endif // FEATURE_PREJIT - return GetHalfBakedMethodTable(); } // MethodTableBuilder::BuildMethodTableThrowing #ifdef _PREFAST_ @@ -9007,11 +8992,7 @@ void MethodTableBuilder::CopyExactParentSlots(MethodTable *pMT, MethodTable *pAp // The slot lives in a chunk shared from the approximate parent MT // If so, we need to change to share the chunk from the exact parent MT -#ifdef FEATURE_PREJIT - _ASSERTE(MethodTable::CanShareVtableChunksFrom(pParentMT, pMT->GetLoaderModule(), Module::GetPreferredZapModuleForMethodTable(pMT))); -#else _ASSERTE(MethodTable::CanShareVtableChunksFrom(pParentMT, pMT->GetLoaderModule())); -#endif pMT->GetVtableIndirections()[indirectionIndex].SetValueMaybeNull(pParentMT->GetVtableIndirections()[indirectionIndex].GetValueMaybeNull()); @@ -9973,9 +9954,6 @@ MethodTable * MethodTableBuilder::AllocateNewMT( #ifdef FEATURE_COMINTEROP , BOOL fHasDynamicInterfaceMap #endif -#ifdef FEATURE_PREJIT - , Module *pComputedPZM -#endif // FEATURE_PREJIT , AllocMemTracker *pamTracker ) { @@ -10041,9 +10019,6 @@ MethodTable * MethodTableBuilder::AllocateNewMT( S_SIZE_T offsetOfUnsharedVtableChunks = cbTotalSize; BOOL canShareVtableChunks = pMTParent && MethodTable::CanShareVtableChunksFrom(pMTParent, pLoaderModule -#ifdef FEATURE_PREJIT - , pComputedPZM -#endif //FEATURE_PREJIT ); // If pMTParent has a generic instantiation, we cannot share its vtable chunks @@ -10224,11 +10199,7 @@ MethodTable * MethodTableBuilder::AllocateNewMT( VOID MethodTableBuilder::SetupMethodTable2( - Module * pLoaderModule -#ifdef FEATURE_PREJIT - , Module * pComputedPZM -#endif // FEATURE_PREJIT - ) + Module * pLoaderModule) { CONTRACTL { @@ -10297,9 +10268,6 @@ MethodTableBuilder::SetupMethodTable2( #ifdef FEATURE_COMINTEROP fHasDynamicInterfaceMap, #endif -#ifdef FEATURE_PREJIT - pComputedPZM, -#endif //FEATURE_PREJIT GetMemTracker()); pMT->SetClass(pClass); diff --git a/src/coreclr/vm/methodtablebuilder.h b/src/coreclr/vm/methodtablebuilder.h index e3b861293a32a2..289fd512793648 100644 --- a/src/coreclr/vm/methodtablebuilder.h +++ b/src/coreclr/vm/methodtablebuilder.h @@ -2893,11 +2893,7 @@ class MethodTableBuilder CheckForSystemTypes(); VOID SetupMethodTable2( - Module* pLoaderModule -#ifdef FEATURE_PREJIT - , Module* pComputedPZM -#endif // FEATURE_PREJIT - ); + Module* pLoaderModule); VOID HandleGCForValueClasses( MethodTable **); @@ -3003,9 +2999,6 @@ class MethodTableBuilder #ifdef FEATURE_COMINTEROP , BOOL bHasDynamicInterfaceMap #endif -#ifdef FEATURE_PREJIT - , Module *pComputedPZM -#endif // FEATURE_PREJIT , AllocMemTracker *pamTracker ); diff --git a/src/coreclr/vm/pefile.cpp b/src/coreclr/vm/pefile.cpp index 3fd27bcfc57639..b812cb64458fd8 100644 --- a/src/coreclr/vm/pefile.cpp +++ b/src/coreclr/vm/pefile.cpp @@ -39,9 +39,6 @@ PEFile::PEFile(PEImage *identity) : #endif m_identity(NULL), m_openedILimage(NULL), -#ifdef FEATURE_PREJIT - m_nativeImage(NULL), -#endif m_MDImportIsRW_Debugger_Use_Only(FALSE), m_bHasPersistentMDImport(FALSE), m_pMDImport(NULL), @@ -94,15 +91,6 @@ PEFile::~PEFile() ReleaseMetadataInterfaces(TRUE); -#ifdef FEATURE_PREJIT - if (m_nativeImage != NULL) - { - MarkNativeImageInvalidIfOwned(); - - m_nativeImage->Release(); - } -#endif //FEATURE_PREJIT - if (m_openedILimage != NULL) m_openedILimage->Release(); @@ -238,71 +226,36 @@ void PEFile::LoadLibrary(BOOL allowNativeSkip/*=TRUE*/) // if allowNativeSkip==F EnsureImageOpened(); } -#ifdef FEATURE_PREJIT - // For on-disk Dlls, we can call LoadLibrary - if (IsDll() && !((HasNativeImage()?m_nativeImage:GetILimage())->GetPath().IsEmpty())) + // Since we couldn't call LoadLibrary, we must be an IL only image + // or the image may still contain unfixed up stuff + // Note that we make an exception for CompilationDomains, since PEImage + // will map non-ILOnly images in a compilation domain. + if (!GetILimage()->IsILOnly() && !GetAppDomain()->IsCompilationDomain()) { - // Note that we may get a DllMain notification inside here. - if (allowNativeSkip && HasNativeImage()) - { - m_nativeImage->Load(); - if(!m_nativeImage->IsNativeILILOnly()) - GetILimage()->Load(); // For IJW we have to load IL also... - } - else - GetILimage()->Load(); + if (!GetILimage()->HasV1Metadata()) + ThrowHR(COR_E_FIXUPSINEXE); // @todo: better error } - else -#endif // FEATURE_PREJIT - { - - // Since we couldn't call LoadLibrary, we must be an IL only image - // or the image may still contain unfixed up stuff - // Note that we make an exception for CompilationDomains, since PEImage - // will map non-ILOnly images in a compilation domain. - if (!GetILimage()->IsILOnly() && !GetAppDomain()->IsCompilationDomain()) - { - if (!GetILimage()->HasV1Metadata()) - ThrowHR(COR_E_FIXUPSINEXE); // @todo: better error - } - - - // If we are already mapped, we can just use the current image. -#ifdef FEATURE_PREJIT - if (allowNativeSkip && HasNativeImage()) + if (GetILimage()->IsFile()) + { +#ifdef TARGET_UNIX + bool loadILImage = GetILimage()->IsILOnly(); +#else // TARGET_UNIX + bool loadILImage = GetILimage()->IsILOnly() && GetILimage()->IsInBundle(); +#endif // TARGET_UNIX + if (loadILImage) { - m_nativeImage->LoadFromMapped(); - - if( !m_nativeImage->IsNativeILILOnly()) - GetILimage()->LoadFromMapped(); // For IJW we have to load IL also... + GetILimage()->Load(); } else -#endif { - if (GetILimage()->IsFile()) - { -#ifdef TARGET_UNIX - bool loadILImage = GetILimage()->IsILOnly(); -#else // TARGET_UNIX - bool loadILImage = GetILimage()->IsILOnly() && GetILimage()->IsInBundle(); -#endif // TARGET_UNIX - if (loadILImage) - { - GetILimage()->Load(); - } - else - { - GetILimage()->LoadFromMapped(); - } - } - else - { - GetILimage()->LoadNoFile(); - } + GetILimage()->LoadFromMapped(); } } - + else + { + GetILimage()->LoadNoFile(); + } RETURN; } @@ -438,10 +391,6 @@ BOOL PEFile::Equals(PEImage *pImage) if (pImage == m_identity || pImage == m_openedILimage) return TRUE; -#ifdef FEATURE_PREJIT - if(pImage == m_nativeImage) - return TRUE; -#endif // Same identity is equal if (m_identity != NULL && m_identity->Equals(pImage)) @@ -528,13 +477,6 @@ PTR_CVOID PEFile::GetMetadata(COUNT_T *pSize) } CONTRACT_END; -#ifdef FEATURE_PREJIT - if (HasNativeImageMetadata()) - { - RETURN m_nativeImage->GetMetadata(pSize); - } -#endif - if (IsDynamic() || !GetILimage()->HasNTHeaders() || !GetILimage()->HasCorHeader()) @@ -564,13 +506,6 @@ PTR_CVOID PEFile::GetLoadedMetadata(COUNT_T *pSize) } CONTRACT_END; -#ifdef FEATURE_PREJIT - if (HasNativeImageMetadata()) - { - RETURN GetLoadedNative()->GetMetadata(pSize); - } -#endif - if (!HasLoadedIL() || !GetLoadedIL()->HasNTHeaders() || !GetLoadedIL()->HasCorHeader()) @@ -606,30 +541,13 @@ TADDR PEFile::GetIL(RVA il) PEImageLayout *image = NULL; -#ifdef FEATURE_PREJIT - // Note it is important to get the IL from the native image if - // available, since we are using the metadata from the native image - // which has different IL rva's. - if (HasNativeImageMetadata()) - { - image = GetLoadedNative(); + image = GetLoadedIL(); #ifndef DACCESS_COMPILE - // NGen images are trusted to be well-formed. - _ASSERTE(image->CheckILMethod(il)); + // Verify that the IL blob is valid before giving it out + if (!image->CheckILMethod(il)) + COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL_RANGE); #endif - } - else -#endif // FEATURE_PREJIT - { - image = GetLoadedIL(); - -#ifndef DACCESS_COMPILE - // Verify that the IL blob is valid before giving it out - if (!image->CheckILMethod(il)) - COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL_RANGE); -#endif - } RETURN image->GetRvaData(il); } @@ -743,32 +661,19 @@ void PEFile::OpenMDImport_Unsafe() if (m_pMDImport != NULL) return; -#ifdef FEATURE_PREJIT - if (m_nativeImage != NULL - && m_nativeImage->GetMDImport() != NULL - ) + if (!IsDynamic() + && GetILimage()->HasNTHeaders() + && GetILimage()->HasCorHeader()) { - // Use native image for metadata - m_flags |= PEFILE_HAS_NATIVE_IMAGE_METADATA; - m_pMDImport=m_nativeImage->GetMDImport(); + m_pMDImport=GetILimage()->GetMDImport(); } else -#endif { -#ifdef FEATURE_PREJIT - m_flags &= ~PEFILE_HAS_NATIVE_IMAGE_METADATA; -#endif - if (!IsDynamic() - && GetILimage()->HasNTHeaders() - && GetILimage()->HasCorHeader()) - { - m_pMDImport=GetILimage()->GetMDImport(); - } - else - ThrowHR(COR_E_BADIMAGEFORMAT); - - m_bHasPersistentMDImport=TRUE; + ThrowHR(COR_E_BADIMAGEFORMAT); } + + m_bHasPersistentMDImport=TRUE; + _ASSERTE(m_pMDImport); m_pMDImport->AddRef(); } @@ -842,537 +747,6 @@ void PEFile::ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData/*= #endif //!DACCESS_COMPILE -#ifdef FEATURE_PREJIT -#ifndef DACCESS_COMPILE -// ------------------------------------------------------------ -// Native image access -// ------------------------------------------------------------ - -void PEFile::SetNativeImage(PEImage *image) -{ - CONTRACT_VOID - { - INSTANCE_CHECK; - PRECONDITION(!HasNativeImage()); - STANDARD_VM_CHECK; - } - CONTRACT_END; - - _ASSERTE(image != NULL); - PREFIX_ASSUME(image != NULL); - - if (image->GetLoadedLayout()->GetBase() != image->GetLoadedLayout()->GetPreferredBase()) - { - ExternalLog(LL_WARNING, - W("Native image loaded at base address") LFMT_ADDR - W("rather than preferred address:") LFMT_ADDR , - DBG_ADDR(image->GetLoadedLayout()->GetBase()), - DBG_ADDR(image->GetLoadedLayout()->GetPreferredBase())); - } - - // First ask if we're supposed to be ignoring the prejitted code & - // structures in NGENd images. If so, bail now and do not set m_nativeImage. We've - // already set m_identity & m_openedILimage), and will use those PEImages to find - // and JIT IL. - if (ShouldTreatNIAsMSIL()) - RETURN; - - m_nativeImage = image; - m_nativeImage->AddRef(); - m_nativeImage->Load(); - -#if defined(TARGET_AMD64) && !defined(CROSSGEN_COMPILE) - static ConfigDWORD configNGenReserveForJumpStubs; - int percentReserveForJumpStubs = configNGenReserveForJumpStubs.val(CLRConfig::INTERNAL_NGenReserveForJumpStubs); - if (percentReserveForJumpStubs != 0) - { - PEImageLayout * pLayout = image->GetLoadedLayout(); - ExecutionManager::GetEEJitManager()->EnsureJumpStubReserve((BYTE *)pLayout->GetBase(), pLayout->GetVirtualSize(), - percentReserveForJumpStubs * (pLayout->GetVirtualSize() / 100)); - } -#endif - - ExternalLog(LL_INFO100, W("Attempting to use native image %s."), image->GetPath().GetUnicode()); - RETURN; -} - -void PEFile::ClearNativeImage() -{ - CONTRACT_VOID - { - INSTANCE_CHECK; - PRECONDITION(HasNativeImage()); - POSTCONDITION(!HasNativeImage()); - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACT_END; - - ExternalLog(LL_WARNING, "Discarding native image."); - - - MarkNativeImageInvalidIfOwned(); - - { - GCX_PREEMP(); - SafeComHolderPreemp pOldImport=GetMDImportWithRef(); - SimpleWriteLockHolder lock(m_pMetadataLock); - - EX_TRY - { - ReleaseMetadataInterfaces(FALSE); - m_flags &= ~PEFILE_HAS_NATIVE_IMAGE_METADATA; - if (m_nativeImage) - m_nativeImage->Release(); - m_nativeImage = NULL; - // Make sure our normal image is open - EnsureImageOpened(); - - // Reopen metadata from normal image - OpenMDImport(); - } - EX_HOOK - { - RestoreMDImport(pOldImport); - } - EX_END_HOOK; - } - - RETURN; -} - - -extern DWORD g_dwLogLevel; - -//=========================================================================================================== -// Encapsulates CLR and Fusion logging for runtime verification of native images. -//=========================================================================================================== -static void RuntimeVerifyVLog(DWORD level, PEAssembly *pLogAsm, const WCHAR *fmt, va_list args) -{ - STANDARD_VM_CONTRACT; - - BOOL fOutputToDebugger = (level == LL_ERROR && IsDebuggerPresent()); - BOOL fOutputToLogging = LoggingOn(LF_ZAP, level); - - StackSString message; - message.VPrintf(fmt, args); - - if (fOutputToLogging) - { - SString displayString = pLogAsm->GetPath(); - LOG((LF_ZAP, level, "%s: \"%S\"\n", "ZAP", displayString.GetUnicode())); - LOG((LF_ZAP, level, "%S", message.GetUnicode())); - LOG((LF_ZAP, level, "\n")); - } - - if (fOutputToDebugger) - { - SString displayString = pLogAsm->GetPath(); - WszOutputDebugString(W("CLR:(")); - WszOutputDebugString(displayString.GetUnicode()); - WszOutputDebugString(W(") ")); - WszOutputDebugString(message); - WszOutputDebugString(W("\n")); - } - -} - - -//=========================================================================================================== -// Encapsulates CLR and Fusion logging for runtime verification of native images. -//=========================================================================================================== -static void RuntimeVerifyLog(DWORD level, PEAssembly *pLogAsm, const WCHAR *fmt, ...) -{ - STANDARD_VM_CONTRACT; - - // Avoid calling RuntimeVerifyVLog unless logging is on - if ( ((level == LL_ERROR) && IsDebuggerPresent()) - || LoggingOn(LF_ZAP, level) - ) - { - va_list args; - va_start(args, fmt); - - RuntimeVerifyVLog(level, pLogAsm, fmt, args); - - va_end(args); - } -} - -//============================================================================== - -static const LPCWSTR CorCompileRuntimeDllNames[NUM_RUNTIME_DLLS] = -{ - MAKEDLLNAME_W(W("coreclr")), - MAKEDLLNAME_W(W("clrjit")) -}; - - -LPCWSTR CorCompileGetRuntimeDllName(CorCompileRuntimeDlls id) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - - return CorCompileRuntimeDllNames[id]; -} - -//=========================================================================================================== -// Validates that an NI matches the running CLR, OS, CPU, etc. -// -// For historial reasons, some versions of the runtime perform this check at native bind time (preferrred), -// while others check at CLR load time. -// -// This is the common funnel for both versions and is agnostic to whether the "assembly" is represented -// by a CLR object or Fusion object. -//=========================================================================================================== -BOOL RuntimeVerifyNativeImageVersion(const CORCOMPILE_VERSION_INFO *info, PEAssembly *pLogAsm) -{ - STANDARD_VM_CONTRACT; - - // - // Check that the EE version numbers are the same. - // - - if (info->wVersionMajor != RuntimeFileMajorVersion - || info->wVersionMinor != RuntimeFileMinorVersion - || info->wVersionBuildNumber != RuntimeFileBuildVersion - || info->wVersionPrivateBuildNumber != RuntimeFileRevisionVersion) - { - RuntimeVerifyLog(LL_ERROR, pLogAsm, W("CLR version recorded in native image doesn't match the current CLR.")); - return FALSE; - } - - // - // Check checked/free status - // - - if (info->wBuild != -#if _DEBUG - CORCOMPILE_BUILD_CHECKED -#else - CORCOMPILE_BUILD_FREE -#endif - ) - { - RuntimeVerifyLog(LL_ERROR, pLogAsm, W("Checked/free mismatch with native image.")); - return FALSE; - } - - // - // Check processor - // - - if (info->wMachine != IMAGE_FILE_MACHINE_NATIVE_NI) - { - RuntimeVerifyLog(LL_ERROR, pLogAsm, W("Processor type recorded in native image doesn't match this machine's processor.")); - return FALSE; - } - -#ifndef CROSSGEN_COMPILE - // - // Check the processor specific ID - // - - CORINFO_CPU cpuInfo; - GetSpecificCpuInfo(&cpuInfo); - - if (!IsCompatibleCpuInfo(&cpuInfo, &info->cpuInfo)) - { - RuntimeVerifyLog(LL_ERROR, pLogAsm, W("Required CPU features recorded in native image don't match this machine's processor.")); - return FALSE; - } -#endif // CROSSGEN_COMPILE - - - // - // The zap is up to date. - // - - RuntimeVerifyLog(LL_INFO100, pLogAsm, W("Native image has correct version information.")); - return TRUE; -} - -//=========================================================================================================== -// Validates that an NI matches the running CLR, OS, CPU, etc. This is the entrypoint used by the CLR loader. -// -//=========================================================================================================== -BOOL PEAssembly::CheckNativeImageVersion(PEImage *peimage) -{ - STANDARD_VM_CONTRACT; - - // - // Get the zap version header. Note that modules will not have version - // headers - they add no additional versioning constraints from their - // assemblies. - // - PEImageLayoutHolder image = peimage->GetLayout(PEImageLayout::LAYOUT_ANY, PEImage::LAYOUT_CREATEIFNEEDED); - - if (!image->HasNativeHeader()) - return FALSE; - - if (!image->CheckNativeHeaderVersion()) - { - // Wrong native image version is fatal error on CoreCLR - ThrowHR(COR_E_NI_AND_RUNTIME_VERSION_MISMATCH); - } - - CORCOMPILE_VERSION_INFO *info = image->GetNativeVersionInfo(); - if (info == NULL) - return FALSE; - - if (!RuntimeVerifyNativeImageVersion(info, this)) - { - // Wrong native image version is fatal error on CoreCLR - ThrowHR(COR_E_NI_AND_RUNTIME_VERSION_MISMATCH); - } - - CorCompileConfigFlags configFlags = PEFile::GetNativeImageConfigFlagsWithOverrides(); - - // Otherwise, match regardless of the instrumentation flags - configFlags = (CorCompileConfigFlags)(configFlags & ~(CORCOMPILE_CONFIG_INSTRUMENTATION_NONE | CORCOMPILE_CONFIG_INSTRUMENTATION)); - - if ((info->wConfigFlags & configFlags) != configFlags) - { - return FALSE; - } - - return TRUE; -} - -#endif // !DACCESS_COMPILE - -/* static */ -CorCompileConfigFlags PEFile::GetNativeImageConfigFlags(BOOL fForceDebug/*=FALSE*/, - BOOL fForceProfiling/*=FALSE*/, - BOOL fForceInstrument/*=FALSE*/) -{ - LIMITED_METHOD_DAC_CONTRACT; - - CorCompileConfigFlags result = (CorCompileConfigFlags)0; - - // Debugging - -#ifdef DEBUGGING_SUPPORTED - // if these have been set, the take precedence over anything else - if (s_NGENDebugFlags) - { - if ((s_NGENDebugFlags & CORCOMPILE_CONFIG_DEBUG_NONE) != 0) - { - result = (CorCompileConfigFlags) (result|CORCOMPILE_CONFIG_DEBUG_NONE); - } - else - { - if ((s_NGENDebugFlags & CORCOMPILE_CONFIG_DEBUG) != 0) - { - result = (CorCompileConfigFlags) (result|CORCOMPILE_CONFIG_DEBUG); - } - } - } - else -#endif // DEBUGGING_SUPPORTED - { - if (fForceDebug) - { - result = (CorCompileConfigFlags) (result|CORCOMPILE_CONFIG_DEBUG); - } - else - { - result = (CorCompileConfigFlags) (result|CORCOMPILE_CONFIG_DEBUG_DEFAULT); - } - } - - // Profiling - -#ifdef PROFILING_SUPPORTED - if (fForceProfiling || CORProfilerUseProfileImages()) - { - result = (CorCompileConfigFlags) (result|CORCOMPILE_CONFIG_PROFILING); - - result = (CorCompileConfigFlags) (result & ~(CORCOMPILE_CONFIG_DEBUG_NONE| - CORCOMPILE_CONFIG_DEBUG| - CORCOMPILE_CONFIG_DEBUG_DEFAULT)); - } - else -#endif //PROFILING_SUPPORTED - result = (CorCompileConfigFlags) (result|CORCOMPILE_CONFIG_PROFILING_NONE); - - // Instrumentation -#ifndef DACCESS_COMPILE - BOOL instrumented = (!IsCompilationProcess() && g_pConfig->GetZapBBInstr()); -#else - BOOL instrumented = FALSE; -#endif - if (instrumented || fForceInstrument) - { - result = (CorCompileConfigFlags) (result|CORCOMPILE_CONFIG_INSTRUMENTATION); - } - else - { - result = (CorCompileConfigFlags) (result|CORCOMPILE_CONFIG_INSTRUMENTATION_NONE); - } - - // NOTE: Right now we are not taking instrumentation into account when binding. - - return result; -} - -CorCompileConfigFlags PEFile::GetNativeImageConfigFlagsWithOverrides() -{ - LIMITED_METHOD_DAC_CONTRACT; - - BOOL fForceDebug, fForceProfiling, fForceInstrument; - SystemDomain::GetCompilationOverrides(&fForceDebug, - &fForceProfiling, - &fForceInstrument); - return PEFile::GetNativeImageConfigFlags(fForceDebug, - fForceProfiling, - fForceInstrument); -} - -#ifndef DACCESS_COMPILE - - - -//=========================================================================================================== -// Validates that a hard-dep matches the a parent NI's compile-time hard-dep. -// -// For historial reasons, some versions of the runtime perform this check at native bind time (preferrred), -// while others check at CLR load time. -// -// This is the common funnel for both versions and is agnostic to whether the "assembly" is represented -// by a CLR object or Fusion object. -// -//=========================================================================================================== -BOOL RuntimeVerifyNativeImageDependency(const CORCOMPILE_NGEN_SIGNATURE &ngenSigExpected, - const CORCOMPILE_VERSION_INFO *pActual, - PEAssembly *pLogAsm) -{ - STANDARD_VM_CONTRACT; - - if (ngenSigExpected != pActual->signature) - { - // Signature did not match - SString displayString = pLogAsm->GetPath(); - RuntimeVerifyLog(LL_ERROR, - pLogAsm, - W("Rejecting native image because native image dependency %s ") - W("had a different identity than expected"), - displayString.GetUnicode()); - - return FALSE; - } - return TRUE; -} -// Wrapper function for use by parts of the runtime that actually have a CORCOMPILE_DEPENDENCY to work with. -BOOL RuntimeVerifyNativeImageDependency(const CORCOMPILE_DEPENDENCY *pExpected, - const CORCOMPILE_VERSION_INFO *pActual, - PEAssembly *pLogAsm) -{ - WRAPPER_NO_CONTRACT; - - return RuntimeVerifyNativeImageDependency(pExpected->signNativeImage, - pActual, - pLogAsm); -} - -#endif // !DACCESS_COMPILE - -#ifdef DEBUGGING_SUPPORTED -// -// Called through ICorDebugAppDomain2::SetDesiredNGENCompilerFlags to specify -// which kinds of ngen'd images fusion should load wrt debugging support -// Overrides any previous settings -// -void PEFile::SetNGENDebugFlags(BOOL fAllowOpt) -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - if (fAllowOpt) - s_NGENDebugFlags = CORCOMPILE_CONFIG_DEBUG_NONE; - else - s_NGENDebugFlags = CORCOMPILE_CONFIG_DEBUG; - } - -// -// Called through ICorDebugAppDomain2::GetDesiredNGENCompilerFlags to determine -// which kinds of ngen'd images fusion should load wrt debugging support -// -void PEFile::GetNGENDebugFlags(BOOL *fAllowOpt) -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - CorCompileConfigFlags configFlags = PEFile::GetNativeImageConfigFlagsWithOverrides(); - - *fAllowOpt = ((configFlags & CORCOMPILE_CONFIG_DEBUG) == 0); -} -#endif // DEBUGGING_SUPPORTED - - - -#ifndef DACCESS_COMPILE - -//--------------------------------------------------------------------------------------- -// -// Used in Apollo, this method determines whether profiling or debugging has requested -// the runtime to provide debuggable / profileable code. In other CLR builds, this would -// normally result in requiring the appropriate NGEN scenario be loaded (/Debug or -// /Profile) and to JIT if unavailable. In Apollo, however, these NGEN scenarios are -// never available, and even MSIL assemblies are often not available. So this function -// tells its caller to use the NGENd assembly as if it were an MSIL assembly--ignore the -// prejitted code and prebaked structures, and just JIT code and load classes from -// scratch. -// -// Return Value: -// nonzero iff NGENd images should be treated as MSIL images. -// - -// static -BOOL PEFile::ShouldTreatNIAsMSIL() -{ - LIMITED_METHOD_CONTRACT; - - // Ask profiling API & config vars whether NGENd images should be avoided - // completely. - if (!NGENImagesAllowed()) - return TRUE; - - // Ask profiling and debugging if they're requesting us to use ngen /Debug or - // /Profile images (which aren't available under Apollo) - - CorCompileConfigFlags configFlags = PEFile::GetNativeImageConfigFlagsWithOverrides(); - - if ((configFlags & (CORCOMPILE_CONFIG_DEBUG | CORCOMPILE_CONFIG_PROFILING)) != 0) - return TRUE; - - return FALSE; -} - -#endif //!DACCESS_COMPILE -#endif // FEATURE_PREJIT - #ifndef DACCESS_COMPILE // ------------------------------------------------------------ @@ -1395,17 +769,8 @@ void PEFile::GetEmbeddedResource(DWORD dwOffset, DWORD *cbResource, PBYTE *pbInM // m_loadedImage is probably preferable, but this may be called by security // before the image is loaded. - PEImage *image; - -#ifdef FEATURE_PREJIT - if (m_nativeImage != NULL) - image = m_nativeImage; - else -#endif - { - EnsureImageOpened(); - image = GetILimage(); - } + EnsureImageOpened(); + PEImage* image = GetILimage(); PEImageLayoutHolder theImage(image->GetLayout(PEImageLayout::LAYOUT_ANY,PEImage::LAYOUT_CREATEIFNEEDED)); if (!theImage->CheckResource(dwOffset)) @@ -1455,93 +820,6 @@ PEFile::LoadAssembly( RETURN GetAppDomain()->BindAssemblySpec(&spec, TRUE); } -// ------------------------------------------------------------ -// Logging -// ------------------------------------------------------------ -#ifdef FEATURE_PREJIT -void PEFile::ExternalLog(DWORD facility, DWORD level, const WCHAR *fmt, ...) -{ - WRAPPER_NO_CONTRACT; - - va_list args; - va_start(args, fmt); - - ExternalVLog(facility, level, fmt, args); - - va_end(args); -} - -void PEFile::ExternalLog(DWORD level, const WCHAR *fmt, ...) -{ - WRAPPER_NO_CONTRACT; - - va_list args; - va_start(args, fmt); - - ExternalVLog(LF_ZAP, level, fmt, args); - - va_end(args); -} - -void PEFile::ExternalLog(DWORD level, const char *msg) -{ - WRAPPER_NO_CONTRACT; - - // It is OK to use %S here. We know that msg is ASCII-only. - ExternalLog(level, W("%S"), msg); -} - -void PEFile::ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) -{ - CONTRACT_VOID - { - THROWS; - GC_TRIGGERS; - } - CONTRACT_END; - - BOOL fOutputToDebugger = (level == LL_ERROR && IsDebuggerPresent()); - BOOL fOutputToLogging = LoggingOn(facility, level); - - if (!fOutputToDebugger && !fOutputToLogging) - return; - - StackSString message; - message.VPrintf(fmt, args); - - if (fOutputToLogging) - { - if (GetMDImport() != NULL) - LOG((facility, level, "%s: \"%s\"\n", (facility == LF_ZAP ? "ZAP" : "LOADER"), GetSimpleName())); - else - LOG((facility, level, "%s: \"%S\"\n", (facility == LF_ZAP ? "ZAP" : "LOADER"), ((const WCHAR *)GetPath()))); - - LOG((facility, level, "%S", message.GetUnicode())); - LOG((facility, level, "\n")); - } - - if (fOutputToDebugger) - { - WszOutputDebugString(W("CLR:(")); - - StackSString codebase; - GetCodeBaseOrName(codebase); - WszOutputDebugString(codebase); - - WszOutputDebugString(W(") ")); - - WszOutputDebugString(message); - WszOutputDebugString(W("\n")); - } - - RETURN; -} - -void PEFile::FlushExternalLog() -{ - LIMITED_METHOD_CONTRACT; -} -#endif BOOL PEFile::GetResource(LPCSTR szName, DWORD *cbResource, PBYTE *pbInMemoryResource, DomainAssembly** pAssemblyRef, @@ -1674,28 +952,6 @@ void PEFile::GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine) return; } -#ifdef FEATURE_PREJIT - if (IsNativeLoaded()) - { - CONSISTENCY_CHECK(HasNativeImage()); - - m_nativeImage->GetNativeILPEKindAndMachine(pdwKind, pdwMachine); - return; - } -#ifndef DACCESS_COMPILE - if (!HasOpenedILimage()) - { - //don't want to touch the IL image unless we already have - ReleaseHolder pNativeImage = GetNativeImageWithRef(); - if (pNativeImage) - { - pNativeImage->GetNativeILPEKindAndMachine(pdwKind, pdwMachine); - return; - } - } -#endif // DACCESS_COMPILE -#endif // FEATURE_PREJIT - GetILimage()->GetPEKindAndMachine(pdwKind, pdwMachine); return; } @@ -1710,24 +966,6 @@ ULONG PEFile::GetILImageTimeDateStamp() } CONTRACTL_END; -#ifdef FEATURE_PREJIT - if (IsNativeLoaded()) - { - CONSISTENCY_CHECK(HasNativeImage()); - - // The IL image's time stamp is copied to the native image. - CORCOMPILE_VERSION_INFO* pVersionInfo = GetLoadedNative()->GetNativeVersionInfoMaybeNull(); - if (pVersionInfo == NULL) - { - return 0; - } - else - { - return pVersionInfo->sourceAssembly.timeStamp; - } - } -#endif // FEATURE_PREJIT - return GetLoadedIL()->GetTimeDateStamp(); } @@ -1772,18 +1010,6 @@ PEAssembly::PEAssembly( if (system) m_flags |= PEFILE_SYSTEM; -#ifdef FEATURE_PREJIT - // We check the precondition above that either pBindResultInfo is null or both pPEImageIL and pPEImageNI are, - // so we'll only get a max of one native image passed in. - if (pPEImageNI != NULL) - { - SetNativeImage(pPEImageNI); - } - - if (pBindResultInfo && pBindResultInfo->HasNativeImage()) - SetNativeImage(pBindResultInfo->GetNativeImage()); -#endif - // If we have no native image, we require a mapping for the file. if (!HasNativeImage() || !IsILOnly()) EnsureImageOpened(); @@ -1954,51 +1180,6 @@ PEAssembly *PEAssembly::Create(PEAssembly *pParentAssembly, } -#ifdef FEATURE_PREJIT - - -void PEAssembly::SetNativeImage(PEImage * image) -{ - CONTRACTL - { - INSTANCE_CHECK; - STANDARD_VM_CHECK; - } - CONTRACTL_END; - - image->Load(); - - if (CheckNativeImageVersion(image)) - { - PEFile::SetNativeImage(image); -#if 0 - //Enable this code if you want to make sure we never touch the flat layout in the presence of the - //ngen image. -//#if defined(_DEBUG) - //find all the layouts in the il image and make sure we never touch them. - unsigned ignored = 0; - PTR_PEImageLayout layout = m_ILimage->GetLayout(PEImageLayout::LAYOUT_FLAT, 0); - if (layout != NULL) - { - //cache a bunch of PE metadata in the PEDecoder - m_ILimage->CheckILFormat(); - - //fudge this by a few pages to make sure we can still mess with the PE headers - const size_t fudgeSize = 4096 * 4; - ClrVirtualProtect((void*)(((char *)layout->GetBase()) + fudgeSize), - layout->GetSize() - fudgeSize, 0, &ignored); - layout->Release(); - } -#endif - } - else - { - ExternalLog(LL_WARNING, "Native image is not correct version."); - } -} - -#endif // FEATURE_PREJIT - #endif // #ifndef DACCESS_COMPILE @@ -2161,39 +1342,6 @@ BOOL PEAssembly::FindLastPathSeparator(const SString &path, SString::Iterator &i #endif //TARGET_UNIX } - -// ------------------------------------------------------------ -// Logging -// ------------------------------------------------------------ -#ifdef FEATURE_PREJIT -void PEAssembly::ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) -{ - CONTRACT_VOID - { - THROWS; - GC_TRIGGERS; - } - CONTRACT_END; - - PEFile::ExternalVLog(facility, level, fmt, args); - - - RETURN; -} - -void PEAssembly::FlushExternalLog() -{ - CONTRACT_VOID - { - THROWS; - GC_TRIGGERS; - } - CONTRACT_END; - - - RETURN; -} -#endif //FEATURE_PREJIT // ------------------------------------------------------------ // Metadata access // ------------------------------------------------------------ @@ -2246,12 +1394,8 @@ void PEFile::EnsureImageOpened() WRAPPER_NO_CONTRACT; if (IsDynamic()) return; -#ifdef FEATURE_PREJIT - if(HasNativeImage()) - m_nativeImage->GetLayout(PEImageLayout::LAYOUT_ANY,PEImage::LAYOUT_CREATEIFNEEDED)->Release(); - else -#endif - GetILimage()->GetLayout(PEImageLayout::LAYOUT_ANY,PEImage::LAYOUT_CREATEIFNEEDED)->Release(); + + GetILimage()->GetLayout(PEImageLayout::LAYOUT_ANY,PEImage::LAYOUT_CREATEIFNEEDED)->Release(); } void PEFile::SetupAssemblyLoadContext() @@ -2290,13 +1434,6 @@ PEFile::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) { GetILimage()->EnumMemoryRegions(flags); } -#ifdef FEATURE_PREJIT - if (m_nativeImage.IsValid()) - { - m_nativeImage->EnumMemoryRegions(flags); - DacEnumHostDPtrMem(m_nativeImage->GetLoadedLayout()->GetNativeVersionInfo()); - } -#endif } void diff --git a/src/coreclr/vm/pefile.h b/src/coreclr/vm/pefile.h index 1c7ddfd236cdc4..2ec7d49355f573 100644 --- a/src/coreclr/vm/pefile.h +++ b/src/coreclr/vm/pefile.h @@ -320,11 +320,6 @@ class PEFile // Does the loader support using a native image for this file? // Some implementation restrictions prevent native images from being used // in some cases. -#ifdef FEATURE_PREJIT - BOOL IsNativeLoaded(); - PEImage *GetNativeImageWithRef(); - PEImage *GetPersistentNativeImage(); -#endif BOOL HasNativeOrReadyToRunImage(); BOOL HasNativeImage(); PTR_PEImageLayout GetLoaded(); @@ -340,34 +335,10 @@ class PEFile PEImage *GetNativeImage() { LIMITED_METHOD_DAC_CONTRACT; -#ifdef FEATURE_PREJIT - return m_nativeImage; -#else return NULL; -#endif } #endif -#ifdef FEATURE_PREJIT - // ------------------------------------------------------------ - // Native image config utilities - // ------------------------------------------------------------ - - static CorCompileConfigFlags GetNativeImageConfigFlags(BOOL fForceDebug = FALSE, - BOOL fForceProfiling = FALSE, - BOOL fForceInstrument = FALSE); - - static CorCompileConfigFlags GetNativeImageConfigFlagsWithOverrides(); - -#ifdef DEBUGGING_SUPPORTED - static void SetNGENDebugFlags(BOOL fAllowOpt); - static void GetNGENDebugFlags(BOOL *fAllowOpt); -#endif - - static BOOL ShouldTreatNIAsMSIL(); - -#endif // FEATURE_PREJIT - // ------------------------------------------------------------ // Resource access // ------------------------------------------------------------ @@ -382,19 +353,6 @@ class PEFile mdAssemblyRef kAssemblyRef, IMDInternalImport * pImport = NULL); - // ------------------------------------------------------------ - // Logging - // ------------------------------------------------------------ - - // The format string is intentionally unicode to avoid globalization bugs -#ifdef FEATURE_PREJIT - void ExternalLog(DWORD facility, DWORD level, const WCHAR *fmt, ...) DAC_EMPTY(); - void ExternalLog(DWORD level, const WCHAR *fmt, ...) DAC_EMPTY(); - void ExternalLog(DWORD level, const char *msg) DAC_EMPTY(); - virtual void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY(); - virtual void FlushExternalLog() DAC_EMPTY(); -#endif - protected: // ------------------------------------------------------------ // Internal constants @@ -405,10 +363,6 @@ class PEFile PEFILE_SYSTEM = 0x01, PEFILE_ASSEMBLY = 0x02, PEFILE_MODULE = 0x04, - -#ifdef FEATURE_PREJIT - PEFILE_HAS_NATIVE_IMAGE_METADATA = 0x200, -#endif }; // ------------------------------------------------------------ @@ -432,12 +386,6 @@ class PEFile friend class Module; -#ifdef FEATURE_PREJIT - void SetNativeImage(PEImage *nativeImage); -#ifndef DACCESS_COMPILE - virtual void ClearNativeImage(); -#endif -#endif #ifndef DACCESS_COMPILE void EnsureImageOpened(); @@ -459,10 +407,6 @@ class PEFile PTR_PEImage m_identity; // IL image, NULL if we didn't need to open the file PTR_PEImage m_openedILimage; -#ifdef FEATURE_PREJIT - // Native image - PTR_PEImage m_nativeImage; -#endif // This flag is not updated atomically with m_pMDImport. Its fine for debugger usage // but don't rely on it in the runtime. In runtime try QI'ing the m_pMDImport for // IID_IMDInternalImportENC @@ -483,11 +427,6 @@ class PEFile // AssemblyLoadContext that this PEFile is associated with PTR_AssemblyLoadContext m_pAssemblyLoadContext; -#ifdef DEBUGGING_SUPPORTED -#ifdef FEATURE_PREJIT - SVAL_DECL(DWORD, s_NGENDebugFlags); -#endif -#endif public: PTR_PEImage GetILimage() @@ -679,15 +618,6 @@ class PEAssembly : public PEFile static void UrlToPath(SString &string); static BOOL FindLastPathSeparator(const SString &path, SString::Iterator &i); - // ------------------------------------------------------------ - // Logging - // ------------------------------------------------------------ -#ifdef FEATURE_PREJIT - void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY(); - void FlushExternalLog() DAC_EMPTY(); -#endif - - protected: #ifndef DACCESS_COMPILE @@ -703,18 +633,6 @@ class PEAssembly : public PEFile virtual ~PEAssembly(); #endif - // ------------------------------------------------------------ - // Loader access API - // ------------------------------------------------------------ - -#ifdef FEATURE_PREJIT - - void SetNativeImage(PEImage *image); - - BOOL CheckNativeImageVersion(PEImage *image); - -#endif // FEATURE_PREJIT - private: // ------------------------------------------------------------ // Instance fields diff --git a/src/coreclr/vm/pefile.inl b/src/coreclr/vm/pefile.inl index a4faf63922672b..5b776732fbfb02 100644 --- a/src/coreclr/vm/pefile.inl +++ b/src/coreclr/vm/pefile.inl @@ -30,9 +30,6 @@ inline CHECK PEFile::Invariant() { // dynamic module case CHECK(m_openedILimage == NULL); -#ifdef FEATURE_PREJIT - CHECK(m_nativeImage == NULL); -#endif CHECK(CheckPointer(m_pEmitter)); } else @@ -40,9 +37,6 @@ inline CHECK PEFile::Invariant() // If m_image is null, then we should have a native image. However, this is not valid initially // during construction. We should find a way to assert this. CHECK(CheckPointer((PEImage*) m_openedILimage, NULL_OK)); -#ifdef FEATURE_PREJIT - CHECK(CheckPointer((PEImage*) m_nativeImage, NULL_OK)); -#endif } CHECK_OK; } @@ -526,15 +520,6 @@ inline BOOL PEFile::IsIbcOptimized() { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_PREJIT - if (IsNativeLoaded()) - { - CONSISTENCY_CHECK(HasNativeImage()); - - return m_nativeImage->IsIbcOptimized(); - } -#endif - return FALSE; } @@ -549,15 +534,6 @@ inline BOOL PEFile::IsILImageReadyToRun() } CONTRACTL_END; -#ifdef FEATURE_PREJIT - if (IsNativeLoaded()) - { - CONSISTENCY_CHECK(HasNativeImage()); - - return GetLoadedNative()->GetNativeILHasReadyToRunHeader(); - } - else -#endif // FEATURE_PREJIT if (HasOpenedILimage()) { return GetLoadedIL()->HasReadyToRunHeader(); @@ -575,24 +551,6 @@ inline WORD PEFile::GetSubsystem() if (IsResource() || IsDynamic()) return 0; -#ifdef FEATURE_PREJIT - if (IsNativeLoaded()) - { - CONSISTENCY_CHECK(HasNativeImage()); - - return GetLoadedNative()->GetSubsystem(); - } -#ifndef DACCESS_COMPILE - if (!HasOpenedILimage()) - { - //don't want to touch the IL image unless we already have - ReleaseHolder pNativeImage = GetNativeImageWithRef(); - if (pNativeImage) - return pNativeImage->GetSubsystem(); - } -#endif // DACCESS_COMPILE -#endif // FEATURE_PREJIT - return GetLoadedIL()->GetSubsystem(); } @@ -607,52 +565,10 @@ inline mdToken PEFile::GetEntryPointToken( if (IsResource() || IsDynamic()) return mdTokenNil; - -#ifdef FEATURE_PREJIT - if (IsNativeLoaded()) - { - CONSISTENCY_CHECK(HasNativeImage()); - _ASSERTE (!bAssumeLoaded || m_nativeImage->HasLoadedLayout ()); - return m_nativeImage->GetEntryPointToken(); - } -#ifndef DACCESS_COMPILE - if (!HasOpenedILimage()) - { - //don't want to touch the IL image unless we already have - ReleaseHolder pNativeImage = GetNativeImageWithRef(); - if (pNativeImage) { - _ASSERTE (!bAssumeLoaded || pNativeImage->HasLoadedLayout ()); - return pNativeImage->GetEntryPointToken(); - } - } -#endif // DACCESS_COMPILE -#endif // FEATURE_PREJIT _ASSERTE (!bAssumeLoaded || HasLoadedIL ()); return GetOpenedILimage()->GetEntryPointToken(); } -#ifdef FEATURE_PREJIT -inline BOOL PEFile::IsNativeLoaded() -{ - WRAPPER_NO_CONTRACT; - return (m_nativeImage && m_bHasPersistentMDImport && m_nativeImage->HasLoadedLayout()); -} -inline void PEFile::MarkNativeImageInvalidIfOwned() -{ - WRAPPER_NO_CONTRACT; - // If owned, mark the PEFile as dummy, so the image does not get reused - PEImageHolder nativeImage(GetNativeImageWithRef()); - Module * pNativeModule = nativeImage->GetLoadedLayout()->GetPersistedModuleImage(); - PEFile ** ppNativeFile = (PEFile**) (PBYTE(pNativeModule) + Module::GetFileOffset()); - - // Attempt to write only if we claimed the ownership. - if (*ppNativeFile == this) - FastInterlockCompareExchangePointer(ppNativeFile, Dummy(), this); -} - - -#endif - inline BOOL PEFile::IsILOnly() { WRAPPER_NO_CONTRACT; @@ -663,30 +579,6 @@ inline BOOL PEFile::IsILOnly() if (IsResource() || IsDynamic()) return FALSE; -#ifdef FEATURE_PREJIT - if (IsNativeLoaded()) - { - CONSISTENCY_CHECK(HasNativeImage()); - - return m_nativeImage->IsNativeILILOnly(); - } -#ifndef DACCESS_COMPILE - if (!HasOpenedILimage()) - { - BOOL retVal = FALSE; - - //don't want to touch the IL image unless we already have - ReleaseHolder pNativeImage = GetNativeImageWithRef(); - if (pNativeImage) - { - retVal = pNativeImage->IsNativeILILOnly(); - } - - return retVal; - } -#endif // DACCESS_COMPILE -#endif // FEATURE_PREJIT - return GetOpenedILimage()->IsILOnly(); } @@ -697,25 +589,6 @@ inline BOOL PEFile::IsDll() if (IsResource() || IsDynamic()) return TRUE; -#ifdef FEATURE_PREJIT - if (IsNativeLoaded()) - { - CONSISTENCY_CHECK(HasNativeImage()); - - return m_nativeImage->IsNativeILDll(); - } -#ifndef DACCESS_COMPILE - if (!HasOpenedILimage()) - { - //don't want to touch the IL image unless we already have - ReleaseHolder pNativeImage =GetNativeImageWithRef(); - if (pNativeImage) - return pNativeImage->IsNativeILDll(); - } - EnsureImageOpened(); -#endif // DACCESS_COMPILE -#endif // FEATURE_PREJIT - return GetOpenedILimage()->IsDll(); } @@ -1071,21 +944,6 @@ inline BOOL PEFile::IsPtrInILImage(PTR_CVOID data) if (HasOpenedILimage()) { -#if defined(FEATURE_PREJIT) - if (m_openedILimage == m_nativeImage) - { - // On Apollo builds, we sometimes open the native image into the slot - // normally reserved for the IL image (as the IL image is often not available - // on the disk at all). In such a case, data is not coming directly from an - // actual IL image, but see if it's coming from the metadata that we copied - // from the IL image into the NI. - TADDR taddrData = dac_cast(data); - PEDecoder * pDecoder = m_nativeImage->GetLoadedLayout(); - COUNT_T cbILMetadata; - TADDR taddrILMetadata = dac_cast(pDecoder->GetMetadata(&cbILMetadata)); - return ((taddrILMetadata <= taddrData) && (taddrData < taddrILMetadata + cbILMetadata)); - } -#endif // defined(FEATURE_PREJIT) return GetOpenedILimage()->IsPtrInImage(data); } else @@ -1107,11 +965,7 @@ inline BOOL PEFile::HasNativeImage() } CONTRACTL_END; -#ifdef FEATURE_PREJIT - return (m_nativeImage != NULL); -#else return FALSE; -#endif } inline BOOL PEFile::HasNativeOrReadyToRunImage() @@ -1158,15 +1012,7 @@ inline BOOL PEFile::IsLoaded(BOOL bAllowNative/*=TRUE*/) CONTRACTL_END; if(IsDynamic()) return TRUE; -#ifdef FEATURE_PREJIT - if (bAllowNative && HasNativeImage()) - { - PEImage *pNativeImage = GetPersistentNativeImage(); - return pNativeImage->HasLoadedLayout() && (pNativeImage->GetLoadedLayout()->IsNativeILILOnly() || (HasLoadedIL())); - } - else -#endif - return HasLoadedIL(); + return HasLoadedIL(); }; @@ -1188,73 +1034,11 @@ inline PTR_PEImageLayout PEFile::GetLoadedNative() } CONTRACTL_END; -#ifdef FEATURE_PREJIT - PEImage* pImage=GetPersistentNativeImage(); - _ASSERTE(pImage && pImage->GetLoadedLayout()); - return pImage->GetLoadedLayout(); -#else // Should never get here PRECONDITION(HasNativeImage()); return NULL; -#endif }; -#ifdef FEATURE_PREJIT -inline PEImage *PEFile::GetPersistentNativeImage() -{ - CONTRACT(PEImage *) - { - INSTANCE_CHECK; - PRECONDITION(HasNativeImage()); - POSTCONDITION(CheckPointer(RETVAL)); - PRECONDITION(m_bHasPersistentMDImport); - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - CANNOT_TAKE_LOCK; - SUPPORTS_DAC; - } - CONTRACT_END; - - RETURN m_nativeImage; -} - -#ifndef DACCESS_COMPILE -inline PEImage *PEFile::GetNativeImageWithRef() -{ - CONTRACT(PEImage *) - { - INSTANCE_CHECK; - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - POSTCONDITION(CheckPointer(RETVAL,NULL_OK)); - } - CONTRACT_END; - GCX_PREEMP(); - SimpleReadLockHolder mdlock(m_pMetadataLock); - if(m_nativeImage) - m_nativeImage->AddRef(); - RETURN m_nativeImage; -} -#endif // DACCESS_COMPILE - -inline BOOL PEFile::HasNativeImageMetadata() -{ - CONTRACT(BOOL) - { - INSTANCE_CHECK; - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACT_END; - - RETURN ((m_flags & PEFILE_HAS_NATIVE_IMAGE_METADATA) != 0); -} -#endif - // ------------------------------------------------------------ // Descriptive strings diff --git a/src/coreclr/vm/peimage.cpp b/src/coreclr/vm/peimage.cpp index 915b7920a3279a..57842fc18c538e 100644 --- a/src/coreclr/vm/peimage.cpp +++ b/src/coreclr/vm/peimage.cpp @@ -109,20 +109,7 @@ CHECK PEImage::CheckILFormat() pLayoutToCheck = pLayoutHolder; } -#ifdef FEATURE_PREJIT - if (PEFile::ShouldTreatNIAsMSIL()) - { - // This PEImage may intentionally be an NI image, being used as if it were an - // MSIL image. In that case, rather than using CheckILFormat on its layout, - // do CheckCORFormat(), which is the same as CheckILFormat, except it allows for - // a native header. (CheckILFormat() fails if it finds a native header.) - CHECK(pLayoutToCheck->CheckCORFormat()); - } - else -#endif - { - CHECK(pLayoutToCheck->CheckILFormat()); - } + CHECK(pLayoutToCheck->CheckILFormat()); CHECK_OK; }; @@ -610,18 +597,7 @@ void PEImage::VerifyIsILOrNIAssembly(BOOL fIL) ThrowFormat(COR_E_ASSEMBLYEXPECTED); CHECK checkGoodFormat; -#ifdef FEATURE_PREJIT - if (fIL) - { - checkGoodFormat = CheckILFormat(); - } - else - { - checkGoodFormat = CheckNativeFormat(); - } -#else checkGoodFormat = CheckILFormat(); -#endif if (!checkGoodFormat) ThrowFormat(COR_E_BADIMAGEFORMAT); diff --git a/src/coreclr/vm/peimage.h b/src/coreclr/vm/peimage.h index 51b9dbc216b2a6..f9f8b4dacf0b16 100644 --- a/src/coreclr/vm/peimage.h +++ b/src/coreclr/vm/peimage.h @@ -171,9 +171,6 @@ class PEImage // Check utilites CHECK CheckILFormat(); -#ifdef FEATURE_PREJIT - CHECK CheckNativeFormat(); -#endif // FEATURE_PREJIT static CHECK CheckCanonicalFullPath(const SString &path); static CHECK CheckStartup(); PTR_CVOID GetMetadata(COUNT_T *pSize = NULL); @@ -196,11 +193,6 @@ class PEImage BOOL HasReadyToRunHeader(); BOOL IsReferenceAssembly(); BOOL IsComponentAssembly(); -#ifdef FEATURE_PREJIT - BOOL IsNativeILILOnly(); - BOOL IsNativeILDll(); - void GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine); -#endif PTR_CVOID GetNativeManifestMetadata(COUNT_T *pSize = NULL); BOOL HasDirectoryEntry(int entry); mdToken GetEntryPointToken(); diff --git a/src/coreclr/vm/peimage.inl b/src/coreclr/vm/peimage.inl index 50cd4555c4ca6d..0b9fec52620cf6 100644 --- a/src/coreclr/vm/peimage.inl +++ b/src/coreclr/vm/peimage.inl @@ -168,21 +168,6 @@ inline BOOL PEImage::IsOpened() } -#ifdef FEATURE_PREJIT -inline CHECK PEImage::CheckNativeFormat() -{ - WRAPPER_NO_CONTRACT; - if (HasLoadedLayout()) - CHECK(GetLoadedLayout()->CheckNativeFormat()); - else - { - PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED)); - CHECK(pLayout->CheckNativeFormat()); - } - CHECK_OK; -}; -#endif // FEATURE_PREJIT - inline BOOL PEImage::IsReferenceAssembly() { CONTRACTL @@ -337,44 +322,6 @@ inline WORD PEImage::GetSubsystem() } } -#ifdef FEATURE_PREJIT -inline BOOL PEImage::IsNativeILILOnly() -{ - WRAPPER_NO_CONTRACT; - if (HasLoadedLayout()) - return GetLoadedLayout()->IsNativeILILOnly(); - else - { - PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED)); - return pLayout->IsNativeILILOnly(); - } -} - -inline void PEImage::GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine) -{ - WRAPPER_NO_CONTRACT; - if (HasLoadedLayout()) - GetLoadedLayout()->GetNativeILPEKindAndMachine(pdwKind, pdwMachine); - else - { - PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED)); - pLayout->GetNativeILPEKindAndMachine(pdwKind, pdwMachine); - } -} - -inline BOOL PEImage::IsNativeILDll() -{ - WRAPPER_NO_CONTRACT; - if (HasLoadedLayout()) - return GetLoadedLayout()->IsNativeILDll(); - else - { - PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED)); - return pLayout->IsNativeILDll(); - } -} -#endif // FEATURE_PREJIT - inline BOOL PEImage::IsDll() { WRAPPER_NO_CONTRACT; @@ -389,18 +336,7 @@ inline BOOL PEImage::IsDll() inline BOOL PEImage::IsIbcOptimized() { -#ifdef FEATURE_PREJIT - WRAPPER_NO_CONTRACT; - if (HasLoadedLayout()) - return GetLoadedLayout()->GetNativeILIsIbcOptimized(); - else - { - PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED)); - return pLayout->GetNativeILIsIbcOptimized(); - } -#else return false; -#endif } inline PTR_CVOID PEImage::GetNativeManifestMetadata(COUNT_T *pSize) @@ -534,10 +470,6 @@ inline PTR_PEImage PEImage::OpenImage(LPCWSTR pPath, MDInternalImportFlags flags } PEImageHolder pImage(new PEImage); -#ifdef FEATURE_PREJIT - if (flags & MDInternalImport_TrustedNativeImage) - pImage->SetIsTrustedNativeImage(); -#endif pImage->Init(pPath, bundleFileLocation); pImage->AddToHashMap(); diff --git a/src/coreclr/vm/perfmap.cpp b/src/coreclr/vm/perfmap.cpp index 8eb8925f7e0b7d..01e716e31d018c 100644 --- a/src/coreclr/vm/perfmap.cpp +++ b/src/coreclr/vm/perfmap.cpp @@ -425,21 +425,6 @@ void NativeImagePerfMap::LogDataForModule(Module * pModule) PEImageLayout * pLoadedLayout = pModule->GetFile()->GetLoaded(); _ASSERTE(pLoadedLayout != nullptr); -#ifdef FEATURE_PREJIT - if (!pLoadedLayout->HasReadyToRunHeader()) - { - MethodIterator mi((PTR_Module)pModule); - while (mi.Next()) - { - MethodDesc *hotDesc = mi.GetMethodDesc(); - hotDesc->CheckRestore(); - - LogPreCompiledMethod(hotDesc, mi.GetMethodStartAddress(), pLoadedLayout, nullptr); - } - return; - } -#endif - ReadyToRunInfo::MethodIterator mi(pModule->GetReadyToRunInfo()); while (mi.Next()) { diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 3896c7e36b5906..6fbbe7f0f404d1 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -203,20 +203,6 @@ BOOL Precode::IsPointingToPrestub(PCODE target) return TRUE; #endif -#ifdef FEATURE_PREJIT - Module *pZapModule = GetMethodDesc()->GetZapModule(); - if (pZapModule != NULL) - { - if (IsPointingTo(target, pZapModule->GetPrestubJumpStub())) - return TRUE; - -#ifdef HAS_FIXUP_PRECODE - if (IsPointingTo(target, pZapModule->GetPrecodeFixupJumpStub())) - return TRUE; -#endif - } -#endif // FEATURE_PREJIT - return FALSE; } @@ -230,37 +216,6 @@ PCODE Precode::TryToSkipFixupPrecode(PCODE addr) PCODE pTarget = NULL; -#if defined(FEATURE_PREJIT) && defined(HAS_FIXUP_PRECODE) - // Early out for common cases - if (!FixupPrecode::IsFixupPrecodeByASM(addr)) - return NULL; - - // This optimization makes sense in NGened code only. - Module * pModule = ExecutionManager::FindZapModule(addr); - if (pModule == NULL) - return NULL; - - // Verify that the address is in precode section - if (!pModule->IsZappedPrecode(addr)) - return NULL; - - pTarget = GetPrecodeFromEntryPoint(addr)->GetTarget(); - - // Verify that the target is in code section - if (!pModule->IsZappedCode(pTarget)) - return NULL; - -#if defined(_DEBUG) - MethodDesc * pMD_orig = MethodTable::GetMethodDescForSlotAddress(addr); - MethodDesc * pMD_direct = MethodTable::GetMethodDescForSlotAddress(pTarget); - - // Both the original and direct entrypoint should map to same MethodDesc - // Some FCalls are remapped to private methods (see System.String.CtorCharArrayStartLength) - _ASSERTE((pMD_orig == pMD_direct) || pMD_orig->IsRuntimeSupplied()); -#endif - -#endif // defined(FEATURE_PREJIT) && defined(HAS_FIXUP_PRECODE) - return pTarget; } diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index c074fa04a74393..ae9e9331c23ba0 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -449,10 +449,6 @@ PCODE MethodDesc::GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier STANDARD_VM_CONTRACT; PCODE pCode = NULL; -#ifdef FEATURE_PREJIT - pCode = GetPrecompiledNgenCode(pConfig); -#endif - if (pCode != NULL) { #ifdef FEATURE_CODE_VERSIONING @@ -512,94 +508,6 @@ PCODE MethodDesc::GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier return pCode; } -PCODE MethodDesc::GetPrecompiledNgenCode(PrepareCodeConfig* pConfig) -{ - STANDARD_VM_CONTRACT; - PCODE pCode = NULL; - -#ifdef FEATURE_PREJIT - pCode = GetPreImplementedCode(); - -#ifdef PROFILING_SUPPORTED - - // The pre-existing cache search callbacks aren't implemented as you might expect. - // Instead of sending a cache search started for all methods, we only send the notification - // when we already know a pre-compiled version of the method exists. In the NGEN case we also - // don't send callbacks unless the method triggers the prestub which excludes a lot of methods. - // From the profiler's perspective this technique is only reliable/predictable when using profiler - // instrumented NGEN images (that virtually no profilers use). As-is the callback only - // gives an opportunity for the profiler to say whether or not it wants to use the ngen'ed - // code. - // - // Despite those oddities I am leaving this behavior as-is during refactoring because trying to - // improve it probably offers little value vs. the potential for compat issues and creating more - // complexity reasoning how the API behavior changed across runtime releases. - if (pCode != NULL) - { - BOOL fShouldSearchCache = TRUE; - { - BEGIN_PROFILER_CALLBACK(CORProfilerTrackCacheSearches()); - (&g_profControlBlock)->JITCachedFunctionSearchStarted((FunctionID)this, &fShouldSearchCache); - END_PROFILER_CALLBACK(); - } - - if (!fShouldSearchCache) - { - SetNativeCodeInterlocked(NULL, pCode); - _ASSERTE(!IsPreImplemented()); - pConfig->SetProfilerRejectedPrecompiledCode(); - pCode = NULL; - } - } -#endif // PROFILING_SUPPORTED - - if (pCode != NULL) - { - LOG((LF_ZAP, LL_INFO10000, - "ZAP: Using NGEN precompiled code " FMT_ADDR " for %s.%s sig=\"%s\" (token %x).\n", - DBG_ADDR(pCode), - m_pszDebugClassName, - m_pszDebugMethodName, - m_pszDebugMethodSignature, - GetMemberDef())); - - TADDR pFixupList = GetFixupList(); - if (pFixupList != NULL) - { - Module *pZapModule = GetZapModule(); - _ASSERTE(pZapModule != NULL); - if (!pZapModule->FixupDelayList(pFixupList)) - { - _ASSERTE(!"FixupDelayList failed"); - ThrowHR(COR_E_BADIMAGEFORMAT); - } - } - -#ifdef HAVE_GCCOVER - if (GCStress::IsEnabled()) - SetupGcCoverage(pConfig->GetCodeVersion(), (BYTE*)pCode); -#endif // HAVE_GCCOVER - -#ifdef PROFILING_SUPPORTED - /* - * This notifies the profiler that a search to find a - * cached jitted function has been made. - */ - { - BEGIN_PROFILER_CALLBACK(CORProfilerTrackCacheSearches()); - (&g_profControlBlock)-> - JITCachedFunctionSearchFinished((FunctionID)this, COR_PRF_CACHED_FUNCTION_FOUND); - END_PROFILER_CALLBACK(); - } -#endif // PROFILING_SUPPORTED - - } -#endif // FEATURE_PREJIT - - return pCode; -} - - PCODE MethodDesc::GetPrecompiledR2RCode(PrepareCodeConfig* pConfig) { STANDARD_VM_CONTRACT; @@ -2810,64 +2718,6 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl } -#if !defined(TARGET_X86) && !defined(TARGET_AMD64) && defined(FEATURE_PREJIT) - -//========================================================================================== -// In NGen image, virtual slots inherited from cross-module dependencies point to jump thunks. -// These jump thunk initially point to VirtualMethodFixupStub which transfers control here. -// This method 'VirtualMethodFixupWorker' will patch the jump thunk to point to the actual -// inherited method body after we have execute the precode and a stable entry point. -// -EXTERN_C PCODE VirtualMethodFixupWorker(Object * pThisPtr, CORCOMPILE_VIRTUAL_IMPORT_THUNK *pThunk) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_COOPERATIVE; - ENTRY_POINT; - } - CONTRACTL_END; - - _ASSERTE(pThisPtr != NULL); - VALIDATEOBJECT(pThisPtr); - - MethodTable * pMT = pThisPtr->GetMethodTable(); - - WORD slotNumber = pThunk->slotNum; - _ASSERTE(slotNumber != (WORD)-1); - - PCODE pCode = pMT->GetRestoredSlot(slotNumber); - - if (!DoesSlotCallPrestub(pCode)) - { - MethodDesc *pMD = MethodTable::GetMethodDescForSlotAddress(pCode); - if (pMD->IsVersionableWithVtableSlotBackpatch()) - { - // The entry point for this method needs to be versionable, so use a FuncPtrStub similarly to what is done in - // MethodDesc::GetMultiCallableAddrOfCode() - GCX_COOP(); - pCode = pMD->GetLoaderAllocator()->GetFuncPtrStubs()->GetFuncPtrStub(pMD); - } - else - { - // Skip fixup precode jump for better perf - PCODE pDirectTarget = Precode::TryToSkipFixupPrecode(pCode); - if (pDirectTarget != NULL) - pCode = pDirectTarget; - } - - // Patch the thunk to the actual method body - pThunk->m_pTarget = pCode; - } -#if defined(TARGET_ARM) - // The target address should have the thumb bit set - _ASSERTE(pCode & THUMB_CODE); -#endif - return pCode; -} -#endif // !defined(TARGET_X86) && !defined(TARGET_AMD64) && defined(FEATURE_PREJIT) - #ifdef FEATURE_READYTORUN static PCODE getHelperForInitializedStatic(Module * pModule, CORCOMPILE_FIXUP_BLOB_KIND kind, MethodTable * pMT, FieldDesc * pFD) diff --git a/src/coreclr/vm/siginfo.cpp b/src/coreclr/vm/siginfo.cpp index e65525225e731d..d2d52170f0d0ab 100644 --- a/src/coreclr/vm/siginfo.cpp +++ b/src/coreclr/vm/siginfo.cpp @@ -1417,13 +1417,11 @@ TypeHandle SigPointer::GetTypeHandleThrowing( Instantiation genericLoadInst(thisinst, ntypars); -#ifndef FEATURE_PREJIT // PREJIT doesn't support the volatile update semantics in the interface map that this requires if (pMTInterfaceMapOwner != NULL && genericLoadInst.ContainsAllOneType(pMTInterfaceMapOwner)) { thRet = ClassLoader::LoadTypeDefThrowing(pGenericTypeModule, tkGenericType, ClassLoader::ThrowIfNotFound, ClassLoader::PermitUninstDefOrRef, 0, level); } else -#endif // FEATURE_PREJIT { // Group together the current signature type context and substitution chain, which // we may later use to instantiate constraints of type arguments that turn out to be diff --git a/src/coreclr/vm/stubmgr.cpp b/src/coreclr/vm/stubmgr.cpp index b94741e784f61b..65fe6665879f6c 100644 --- a/src/coreclr/vm/stubmgr.cpp +++ b/src/coreclr/vm/stubmgr.cpp @@ -1420,40 +1420,6 @@ BOOL RangeSectionStubManager::DoTraceStub(PCODE stubStartAddress, TraceDestinati case STUB_CODE_BLOCK_STUBLINK: return StubLinkStubManager::g_pManager->DoTraceStub(stubStartAddress, trace); -#ifdef FEATURE_PREJIT - case STUB_CODE_BLOCK_VIRTUAL_METHOD_THUNK: - { - PCODE pTarget = GetMethodThunkTarget(stubStartAddress); - if (pTarget == ExecutionManager::FindZapModule(stubStartAddress)-> - GetNGenLayoutInfo()->m_pVirtualImportFixupJumpStub) - { -#ifdef DACCESS_COMPILE - DacNotImpl(); -#else - trace->InitForManagerPush(GetEEFuncEntryPoint(VirtualMethodFixupPatchLabel), this); -#endif - } - else - { - trace->InitForStub(pTarget); - } - return TRUE; - } - - case STUB_CODE_BLOCK_EXTERNAL_METHOD_THUNK: - { - PCODE pTarget = GetMethodThunkTarget(stubStartAddress); - if (pTarget != ExecutionManager::FindZapModule(stubStartAddress)-> - GetNGenLayoutInfo()->m_pExternalMethodFixupJumpStub) - { - trace->InitForStub(pTarget); - return TRUE; - } - } - - FALLTHROUGH; -#endif - case STUB_CODE_BLOCK_METHOD_CALL_THUNK: #ifdef DACCESS_COMPILE DacNotImpl(); @@ -1483,14 +1449,7 @@ BOOL RangeSectionStubManager::TraceManager(Thread *thread, } CONTRACTL_END; -#ifdef FEATURE_PREJIT - // Both virtual and external import thunks have the same structure. We can use - // common code to handle them. - _ASSERTE(GetIP(pContext) == GetEEFuncEntryPoint(VirtualMethodFixupPatchLabel) - || GetIP(pContext) == GetEEFuncEntryPoint(ExternalMethodFixupPatchLabel)); -#else _ASSERTE(GetIP(pContext) == GetEEFuncEntryPoint(ExternalMethodFixupPatchLabel)); -#endif *pRetAddr = (BYTE *)StubManagerHelpers::GetReturnAddress(pContext); diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index b38dc33185afbf..05b70a215923ba 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -8540,18 +8540,6 @@ Thread::EnumMemoryRegionsWorker(CLRDataEnumMemoryFlags flags) if (pMD != NULL) { pMD->EnumMemoryRegions(flags); -#if defined(FEATURE_EH_FUNCLETS) && defined(FEATURE_PREJIT) - // Enumerate unwind info - // Note that we don't do this based on the MethodDesc because in theory there isn't a 1:1 correspondence - // between MethodDesc and code (and so unwind info, and even debug info). Eg., EnC creates new versions - // of the code, but the MethodDesc always points at the latest version (which isn't necessarily - // the one on the stack). In practice this is unlikely to be a problem since wanting a minidump - // and making EnC edits are usually mutually exclusive. - if (frameIter.m_crawl.IsFrameless()) - { - frameIter.m_crawl.GetJitManager()->EnumMemoryRegionsForMethodUnwindInfo(flags, frameIter.m_crawl.GetCodeInfo()); - } -#endif // defined(FEATURE_EH_FUNCLETS) && defined(FEATURE_PREJIT) } previousSP = currentSP; diff --git a/src/coreclr/vm/typedesc.cpp b/src/coreclr/vm/typedesc.cpp index f880850a178dd2..5e747ce104ea14 100644 --- a/src/coreclr/vm/typedesc.cpp +++ b/src/coreclr/vm/typedesc.cpp @@ -751,83 +751,6 @@ void TypeDesc::DoFullyLoad(Generics::RecursionGraph *pVisited, ClassLoadLevel le #endif } - -#ifdef FEATURE_PREJIT -void TypeDesc::DoRestoreTypeKey() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - } - CONTRACTL_END - -#ifndef DACCESS_COMPILE - if (HasTypeParam()) - { - ParamTypeDesc* pPTD = (ParamTypeDesc*) this; - - // Must have the same loader module, so not encoded - CONSISTENCY_CHECK(!pPTD->m_Arg.IsEncodedFixup()); - ClassLoader::EnsureLoaded(pPTD->m_Arg, CLASS_LOAD_UNRESTORED); - - // Might live somewhere else e.g. Object[] is shared across all ref array types - Module::RestoreMethodTablePointer(&(pPTD->m_TemplateMT), NULL, CLASS_LOAD_UNRESTORED); - } - - FastInterlockAnd(&m_typeAndFlags, ~TypeDesc::enum_flag_UnrestoredTypeKey); -#endif -} - -#ifndef DACCESS_COMPILE - -void TypeDesc::SetIsRestored() -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - STATIC_CONTRACT_CANNOT_TAKE_LOCK; - - TypeHandle th = TypeHandle(this); - FastInterlockAnd(&m_typeAndFlags, ~TypeDesc::enum_flag_Unrestored); -} - -#endif // #ifndef DACCESS_COMPILE - -void TypeDesc::Restore() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - INJECT_FAULT(COMPlusThrowOM();); - CONSISTENCY_CHECK(!HasUnrestoredTypeKey()); - } - CONTRACTL_END; - -#ifndef DACCESS_COMPILE - if (HasTypeParam()) - { - ParamTypeDesc *pPTD = dac_cast(this); - - OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOAD_EXACTPARENTS); - - // Must have the same loader module - ClassLoader::EnsureLoaded(pPTD->m_Arg, CLASS_LOAD_EXACTPARENTS); - - // Method-table pointer must have been restored by DoRestoreTypeKey - Module::RestoreMethodTablePointer(&pPTD->m_TemplateMT, NULL, CLASS_LOAD_EXACTPARENTS); - } - - SetIsRestored(); -#else - DacNotImpl(); -#endif // #ifndef DACCESS_COMPILE -} - -#endif // FEATURE_PREJIT - - #ifndef DACCESS_COMPILE MethodDesc * TypeVarTypeDesc::LoadOwnerMethod() @@ -1776,13 +1699,6 @@ FnPtrTypeDesc::GetRetAndArgTypes() } CONTRACTL_END; - // Decode encoded type handles on demand -#if defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE) - for (DWORD i = 0; i <= m_NumArgs; i++) - { - Module::RestoreTypeHandlePointerRaw(&m_RetAndArgTypes[i]); - } -#endif //defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE) return m_RetAndArgTypes; } // FnPtrTypeDesc::GetRetAndArgTypes diff --git a/src/coreclr/vm/typehandle.cpp b/src/coreclr/vm/typehandle.cpp index e33c6db733b106..9c5ebb8dda32ad 100644 --- a/src/coreclr/vm/typehandle.cpp +++ b/src/coreclr/vm/typehandle.cpp @@ -16,10 +16,6 @@ #include "array.h" #include "castcache.h" -#ifdef FEATURE_PREJIT -#include "zapsig.h" -#endif - #ifdef _DEBUG_IMPL BOOL TypeHandle::Verify() @@ -1037,46 +1033,6 @@ BOOL TypeHandle::HasUnrestoredTypeKey() const return AsMethodTable()->HasUnrestoredTypeKey(); } -#ifdef FEATURE_PREJIT -void TypeHandle::DoRestoreTypeKey() -{ - CONTRACT_VOID - { - THROWS; - GC_TRIGGERS; - PRECONDITION(!IsEncodedFixup()); - } - CONTRACT_END - -#ifndef DACCESS_COMPILE - if (IsTypeDesc()) - { - AsTypeDesc()->DoRestoreTypeKey(); - } - else - { - MethodTable* pMT = AsMethodTable(); - PREFIX_ASSUME(pMT != NULL); - pMT->DoRestoreTypeKey(); - } -#endif - -#ifdef _DEBUG -#ifndef DACCESS_COMPILE - if (LoggingOn(LF_CLASSLOADER, LL_INFO10000)) - { - StackSString name; - TypeString::AppendTypeDebug(name, *this); - LOG((LF_CLASSLOADER, LL_INFO10000, "GENERICS:RestoreTypeKey: type %S at %p\n", name.GetUnicode(), AsPtr())); - } -#endif -#endif - - - RETURN; -} -#endif - void TypeHandle::CheckRestore() const { CONTRACTL @@ -1621,13 +1577,8 @@ CHECK TypeHandle::CheckMatchesKey(TypeKey *pKey) const { for (DWORD i = 0; i < pMT->GetNumGenericArgs(); i++) { -#ifdef FEATURE_PREJIT - CHECK_MSGF(ZapSig::CompareTypeHandleFieldToTypeHandle(pMT->GetInstantiation().GetRawArgs()[i].GetValuePtr(), pKey->GetInstantiation()[i]), - ("Generic argument %d in MethodTable does not match key %S", i, typeKeyString.GetUnicode())); -#else CHECK_MSGF(pMT->GetInstantiation()[i] == pKey->GetInstantiation()[i], ("Generic argument %d in MethodTable does not match key %S", i, typeKeyString.GetUnicode())); -#endif } } } diff --git a/src/coreclr/vm/typehandle.inl b/src/coreclr/vm/typehandle.inl index e566d7c831e085..97b78e6a708b7a 100644 --- a/src/coreclr/vm/typehandle.inl +++ b/src/coreclr/vm/typehandle.inl @@ -70,11 +70,7 @@ inline BOOL TypeHandle::IsZapped() const { LIMITED_METHOD_DAC_CONTRACT; -#ifdef FEATURE_PREJIT - return (GetZapModule() != NULL); -#else return FALSE; -#endif } // Methods to allow you get get a the two possible representations diff --git a/src/coreclr/vm/typehash.cpp b/src/coreclr/vm/typehash.cpp index 14a62fa3cfdd98..a8f8a01618c5d7 100644 --- a/src/coreclr/vm/typehash.cpp +++ b/src/coreclr/vm/typehash.cpp @@ -378,40 +378,6 @@ EETypeHashEntry_t *EETypeHashTable::FindItem(TypeKey* pKey) if (kind == ELEMENT_TYPE_ARRAY) { TypeHandle th = pSearch->GetTypeHandle(); -#ifdef FEATURE_PREJIT - // This ensures that GetAssemblyIfLoaded operations that may be triggered by signature walks will succeed if at all possible. - ClrFlsThreadTypeSwitch genericInstantionCompareHolder(ThreadType_GenericInstantiationCompare); - - TADDR fixup = dac_cast(th.GetMethodTable()); - if (!CORCOMPILE_IS_POINTER_TAGGED(fixup)) - { - TADDR canonFixup = th.GetMethodTable()->GetCanonicalMethodTableFixup(); - if (CORCOMPILE_IS_POINTER_TAGGED(canonFixup)) - fixup = canonFixup; - } - - if (CORCOMPILE_IS_POINTER_TAGGED(fixup)) - { - Module *pDefiningModule; - PCCOR_SIGNATURE pSig = GetModule()->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule); - if (pDefiningModule == NULL) - break; - - _ASSERTE(*pSig == ELEMENT_TYPE_ARRAY); - pSig++; - SigPointer sp(pSig); - if (FAILED(sp.SkipExactlyOne())) - break; // return NULL; - - uint32_t data; - if (FAILED(sp.GetData(&data))) - break; // return NULL; - - if (data != pKey->GetRank()) - continue; - } - else -#endif //FEATURE_PREJIT { if (th.GetRank() != pKey->GetRank()) continue; @@ -450,38 +416,6 @@ BOOL EETypeHashTable::CompareInstantiatedType(TypeHandle t, Module *pModule, mdT if (pMT->GetNumGenericArgs() != inst.GetNumArgs()) return FALSE; -#ifdef FEATURE_PREJIT - // This ensures that GetAssemblyIfLoaded operations that may be triggered by signature walks will succeed if at all possible. - ClrFlsThreadTypeSwitch genericInstantionCompareHolder(ThreadType_GenericInstantiationCompare); - - TADDR fixup = pMT->GetCanonicalMethodTableFixup(); - - // The EEClass pointer is actually an encoding. - if (CORCOMPILE_IS_POINTER_TAGGED(fixup)) - { - Module *pDefiningModule; - - PCCOR_SIGNATURE pSig = GetModule()->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule); - - // First check that the modules for the generic type defs match - if (dac_cast(pDefiningModule) != - dac_cast(pModule)) - return FALSE; - - // Now crack the signature encoding, expected to be an instantiated type - _ASSERTE(*pSig == ELEMENT_TYPE_GENERICINST); - pSig++; - _ASSERTE(*pSig == ELEMENT_TYPE_CLASS || *pSig == ELEMENT_TYPE_VALUETYPE); - pSig++; - - // Check that the tokens of the generic type def match - if (CorSigUncompressToken(pSig) != token) - return FALSE; - } - - // The EEClass pointer is a real pointer - else -#endif //FEATURE_PREJIT { // First check that the typedef tokens match if (pMT->GetCl() != token) @@ -505,16 +439,7 @@ BOOL EETypeHashTable::CompareInstantiatedType(TypeHandle t, Module *pModule, mdT // Now check the instantiations. Some type arguments might be encoded. for (DWORD i = 0; i < inst.GetNumArgs(); i++) { -#ifdef FEATURE_PREJIT - // Fetch the type handle as TADDR. It may be may be encoded fixup - TypeHandle debug-only validation - // asserts on encoded fixups. - DACCOP_IGNORE(CastOfMarshalledType, "Dual mode DAC problem, but since the size is the same, the cast is safe"); - TADDR candidateArg = ((FixupPointer *)candidateInst.GetRawArgs())[i].GetValue(); - - if (!ZapSig::CompareTaggedPointerToTypeHandle(GetModule(), candidateArg, inst[i])) -#else if (candidateInst[i] != inst[i]) -#endif { return FALSE; } @@ -541,10 +466,6 @@ BOOL EETypeHashTable::CompareFnPtrType(TypeHandle t, BYTE callConv, DWORD numArg return FALSE; #ifndef DACCESS_COMPILE -#ifdef FEATURE_PREJIT - // This ensures that GetAssemblyIfLoaded operations that may be triggered by signature walks will succeed if at all possible. - ClrFlsThreadTypeSwitch genericInstantionCompareHolder(ThreadType_GenericInstantiationCompare); -#endif FnPtrTypeDesc* pTD = t.AsFnPtrType(); @@ -555,12 +476,7 @@ BOOL EETypeHashTable::CompareFnPtrType(TypeHandle t, BYTE callConv, DWORD numArg TypeHandle *retAndArgTypes2 = pTD->GetRetAndArgTypesPointer(); for (DWORD i = 0; i <= numArgs; i++) { -#ifdef FEATURE_PREJIT - TADDR candidateArg = retAndArgTypes2[i].AsTAddr(); - if (!ZapSig::CompareTaggedPointerToTypeHandle(GetModule(), candidateArg, retAndArgTypes[i])) -#else if (retAndArgTypes2[i] != retAndArgTypes[i]) -#endif { return FALSE; } @@ -680,29 +596,6 @@ void EETypeHashEntry::SetTypeHandle(TypeHandle handle) } #endif // !DACCESS_COMPILE -#ifdef FEATURE_PREJIT -bool EETypeHashEntry::IsHot() -{ - LIMITED_METHOD_CONTRACT; - - // Low order bit of data field indicates a hot entry. - TADDR data = dac_cast(GetData()); - return (data & 1) != 0; -} - -#ifndef DACCESS_COMPILE -void EETypeHashEntry::MarkAsHot() -{ - LIMITED_METHOD_CONTRACT; - - // Low order bit of data field indicates a hot entry. - TADDR data = dac_cast(GetData()); - data |= 0x1; - m_data.SetValueMaybeNull(dac_cast(data)); -} -#endif // !DACCESS_COMPILE -#endif // FEATURE_PREJIT - #ifdef _MSC_VER #pragma warning(pop) #endif // _MSC_VER: warning C4244 diff --git a/src/coreclr/vm/typehash.h b/src/coreclr/vm/typehash.h index b923754a39faa2..0dffc7e32bac35 100644 --- a/src/coreclr/vm/typehash.h +++ b/src/coreclr/vm/typehash.h @@ -34,13 +34,6 @@ typedef struct EETypeHashEntry TypeHandle GetTypeHandle(); void SetTypeHandle(TypeHandle handle); -#ifdef FEATURE_PREJIT - // To make ngen saving much more efficient we support marking individual entries as hot (as determined by - // profile data). - bool IsHot(); - void MarkAsHot(); -#endif // FEATURE_PREJIT - #ifndef DACCESS_COMPILE EETypeHashEntry& operator=(const EETypeHashEntry& src) { diff --git a/src/coreclr/vm/virtualcallstub.cpp b/src/coreclr/vm/virtualcallstub.cpp index 776c4b2cbda367..fe3035466da2ed 100644 --- a/src/coreclr/vm/virtualcallstub.cpp +++ b/src/coreclr/vm/virtualcallstub.cpp @@ -1026,13 +1026,6 @@ BOOL VirtualCallStubManager::CheckIsStub_Internal(PCODE stubStartAddress) BOOL fIsOwner = isStub(stubStartAddress); -#if defined(TARGET_X86) && defined(FEATURE_PREJIT) - if (!fIsOwner) - { - fIsOwner = (stubStartAddress == GetEEFuncEntryPoint(StubDispatchFixupStub)); - } -#endif // defined(TARGET_X86) && defined(FEATURE_PREJIT) - return fIsOwner; } @@ -1049,14 +1042,6 @@ BOOL VirtualCallStubManager::DoTraceStub(PCODE stubStartAddress, TraceDestinatio _ASSERTE(CheckIsStub_Internal(stubStartAddress)); -#ifdef FEATURE_PREJIT - if (stubStartAddress == GetEEFuncEntryPoint(StubDispatchFixupStub)) - { - trace->InitForManagerPush(GetEEFuncEntryPoint(StubDispatchFixupPatchLabel), this); - return TRUE; - } -#endif - // @workaround: Well, we really need the context to figure out where we're going, so // we'll do a TRACE_MGR_PUSH so that TraceManager gets called and we can use // the provided context to figure out where we're going. @@ -1078,17 +1063,6 @@ BOOL VirtualCallStubManager::TraceManager(Thread *thread, } CONTRACTL_END -#ifdef FEATURE_PREJIT - // This is the case for the lazy slot fixup - if (GetIP(pContext) == GetEEFuncEntryPoint(StubDispatchFixupPatchLabel)) { - - *pRetAddr = (BYTE *)StubManagerHelpers::GetReturnAddress(pContext); - - // The destination for the virtual invocation - return StubManager::TraceStub(StubManagerHelpers::GetTailCallTarget(pContext), trace); - } -#endif // FEATURE_PREJIT - TADDR pStub = GetIP(pContext); // The return address should be on the top of the stack @@ -1226,131 +1200,6 @@ VTableCallHolder* VirtualCallStubManager::GenerateVTableCallStub(DWORD slot) RETURN(pHolder); } -#ifdef FEATURE_PREJIT -extern "C" PCODE STDCALL StubDispatchFixupWorker(TransitionBlock * pTransitionBlock, - TADDR siteAddrForRegisterIndirect, - DWORD sectionIndex, - Module * pModule) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - ENTRY_POINT; - } CONTRACTL_END; - - PCODE pTarget = NULL; - - MAKE_CURRENT_THREAD_AVAILABLE(); - -#ifdef _DEBUG - Thread::ObjectRefFlush(CURRENT_THREAD); -#endif - - FrameWithCookie frame(pTransitionBlock); - StubDispatchFrame * pSDFrame = &frame; - - PCODE returnAddress = pSDFrame->GetUnadjustedReturnAddress(); - - StubCallSite callSite(siteAddrForRegisterIndirect, returnAddress); - - TADDR pIndirectCell = (TADDR)callSite.GetIndirectCell(); - - // FUTURE: Consider always passing in module and section index to avoid the lookups - if (pModule == NULL) - { - pModule = ExecutionManager::FindZapModule(pIndirectCell); - sectionIndex = (DWORD)-1; - } - _ASSERTE(pModule != NULL); - - pSDFrame->SetCallSite(pModule, pIndirectCell); - - pSDFrame->Push(CURRENT_THREAD); - INSTALL_MANAGED_EXCEPTION_DISPATCHER; - INSTALL_UNWIND_AND_CONTINUE_HANDLER; - - PEImageLayout *pNativeImage = pModule->GetNativeOrReadyToRunImage(); - - DWORD rva = pNativeImage->GetDataRva(pIndirectCell); - - PTR_CORCOMPILE_IMPORT_SECTION pImportSection; - if (sectionIndex != (DWORD) -1) - { - pImportSection = pModule->GetImportSectionFromIndex(sectionIndex); - _ASSERTE(pImportSection == pModule->GetImportSectionForRVA(rva)); - } - else - { - pImportSection = pModule->GetImportSectionForRVA(rva); - } - _ASSERTE(pImportSection != NULL); - - _ASSERTE(pImportSection->EntrySize == sizeof(TADDR)); - - COUNT_T index = (rva - VAL32(pImportSection->Section.VirtualAddress)) / sizeof(TADDR); - - // Get the stub manager for this module - VirtualCallStubManager *pMgr = pModule->GetLoaderAllocator()->GetVirtualCallStubManager(); - - // Force a GC on every jit if the stress level is high enough - GCStress::MaybeTrigger(); - - // Get the data section - PTR_DWORD pSignatures = dac_cast(pNativeImage->GetRvaData(pImportSection->Signatures)); - - PCCOR_SIGNATURE pBlob = (BYTE *)pNativeImage->GetRvaData(pSignatures[index]); - - BYTE kind = *pBlob++; - - Module * pInfoModule = pModule; - if (kind & ENCODE_MODULE_OVERRIDE) - { - DWORD moduleIndex = CorSigUncompressData(pBlob); - pInfoModule = pModule->GetModuleFromIndex(moduleIndex); - kind &= ~ENCODE_MODULE_OVERRIDE; - } - _ASSERTE(kind == ENCODE_VIRTUAL_ENTRY_SLOT); - - DWORD slot = CorSigUncompressData(pBlob); - - TypeHandle ownerType = ZapSig::DecodeType(pModule, pInfoModule, pBlob); - - MethodTable * pMT = ownerType.GetMethodTable(); - - DispatchToken token; - if (pMT->IsInterface()) - token = pMT->GetLoaderAllocator()->GetDispatchToken(pMT->GetTypeID(), slot); - else - token = DispatchToken::CreateDispatchToken(slot); - - OBJECTREF *protectedObj = pSDFrame->GetThisPtr(); - _ASSERTE(protectedObj != NULL); - if (*protectedObj == NULL) { - COMPlusThrow(kNullReferenceException); - } - - pTarget = pMgr->ResolveWorker(&callSite, protectedObj, token, VirtualCallStubManager::SK_LOOKUP); - _ASSERTE(pTarget != NULL); - -#if _DEBUG - if (pSDFrame->GetGCRefMap() != NULL) - { - GCX_PREEMP(); - _ASSERTE(CheckGCRefMapEqual(pSDFrame->GetGCRefMap(), pSDFrame->GetFunction(), true)); - } -#endif // _DEBUG - - // Ready to return - - UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; - UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; - pSDFrame->Pop(CURRENT_THREAD); - - return pTarget; -} -#endif // FEATURE_PREJIT - //+---------------------------------------------------------------------------- // // Method: VirtualCallStubManager::GenerateStubIndirection diff --git a/src/coreclr/vm/virtualcallstub.h b/src/coreclr/vm/virtualcallstub.h index 48f81cc13eb1c7..9a0657b4f256bc 100644 --- a/src/coreclr/vm/virtualcallstub.h +++ b/src/coreclr/vm/virtualcallstub.h @@ -43,13 +43,6 @@ struct VTableCallHolder; // Forward function declarations extern "C" void InContextTPQuickDispatchAsmStub(); -#ifdef FEATURE_PREJIT -extern "C" PCODE STDCALL StubDispatchFixupWorker(TransitionBlock * pTransitionBlock, - TADDR siteAddrForRegisterIndirect, - DWORD sectionIndex, - Module * pModule); -#endif - extern "C" PCODE STDCALL VSD_ResolveWorker(TransitionBlock * pTransitionBlock, TADDR siteAddrForRegisterIndirect, size_t token @@ -155,10 +148,6 @@ struct StubCallSite PCODE GetReturnAddress() { LIMITED_METHOD_CONTRACT; return m_returnAddr; } }; -#ifdef FEATURE_PREJIT -extern "C" void StubDispatchFixupStub(); // for lazy fixup of ngen call sites -#endif - // These are the assembly language entry points that the stubs use when they want to go into the EE extern "C" void ResolveWorkerAsmStub(); // resolve a token and transfer control to that method diff --git a/src/coreclr/vm/zapsig.cpp b/src/coreclr/vm/zapsig.cpp index 744acbeec56975..827c40c7c8b25d 100644 --- a/src/coreclr/vm/zapsig.cpp +++ b/src/coreclr/vm/zapsig.cpp @@ -544,31 +544,6 @@ BOOL ZapSig::GetSignatureForTypeHandle(TypeHandle handle, RETURN(TRUE); } -#ifdef FEATURE_PREJIT -/*static*/ -BOOL ZapSig::CompareFixupToTypeHandle(Module * pModule, TADDR fixup, TypeHandle handle) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - FORBID_FAULT; - PRECONDITION(CORCOMPILE_IS_POINTER_TAGGED(fixup)); - PRECONDITION(CheckPointer(pModule)); - } - CONTRACTL_END - - Module *pDefiningModule; - PCCOR_SIGNATURE pSig = pModule->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule); - if (pDefiningModule == NULL) - return FALSE; - - ZapSig::Context zapSigContext(pDefiningModule, pModule); - return ZapSig::CompareSignatureToTypeHandle(pSig, pDefiningModule, handle, &zapSigContext); -} -#endif // FEATURE_PREJIT - /*static*/ BOOL ZapSig::CompareTypeHandleFieldToTypeHandle(TypeHandle *pTypeHnd, TypeHandle typeHnd2) { @@ -587,26 +562,7 @@ BOOL ZapSig::CompareTypeHandleFieldToTypeHandle(TypeHandle *pTypeHnd, TypeHandle // Ensure that the compiler won't fetch the value twice SIZE_T fixup = VolatileLoadWithoutBarrier((SIZE_T *)pTypeHnd); -#ifdef FEATURE_PREJIT - if (CORCOMPILE_IS_POINTER_TAGGED(fixup)) - { - Module *pContainingModule = ExecutionManager::FindZapModule(dac_cast(pTypeHnd)); - CONSISTENCY_CHECK(pContainingModule != NULL); - - Module *pDefiningModule; - PCCOR_SIGNATURE pSig = pContainingModule->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule); - if (pDefiningModule == NULL) - return FALSE; - else - { - ZapSig::Context zapSigContext(pDefiningModule, pContainingModule); - ZapSig::Context * pZapSigContext = &zapSigContext; - return CompareSignatureToTypeHandle(pSig, pDefiningModule, typeHnd2, pZapSigContext); - } - } - else -#endif // FEATURE_PREJIT - return TypeHandle::FromTAddr(fixup) == typeHnd2; + return TypeHandle::FromTAddr(fixup) == typeHnd2; } #ifndef DACCESS_COMPILE diff --git a/src/coreclr/vm/zapsig.h b/src/coreclr/vm/zapsig.h index bff06fd1585b26..daf76ca23d15bd 100644 --- a/src/coreclr/vm/zapsig.h +++ b/src/coreclr/vm/zapsig.h @@ -106,21 +106,6 @@ class ZapSig BOOL GetSignatureForTypeHandle(TypeHandle typeHandle, SigBuilder * pSigBuilder); -#ifdef FEATURE_PREJIT - // Compare a type handle with a tagged pointer. Ensure that the common path is inlined into the caller. - static FORCEINLINE BOOL CompareTaggedPointerToTypeHandle(Module * pModule, TADDR addr, TypeHandle handle) - { - WRAPPER_NO_CONTRACT; - if (handle.AsTAddr() == addr) - return TRUE; - if (!CORCOMPILE_IS_POINTER_TAGGED(addr)) - return FALSE; - return CompareFixupToTypeHandle(pModule, addr, handle); - } - - static BOOL CompareFixupToTypeHandle(Module * pModule, TADDR fixup, TypeHandle handle); -#endif - static BOOL CompareTypeHandleFieldToTypeHandle(TypeHandle *pTypeHnd, TypeHandle typeHnd2); private: