//***************************************************************************** // Pull the PEKind and Machine out of PE headers -- if we have PE headers. //***************************************************************************** HRESULT CLiteWeightStgdbRW::GetPEKind( // S_OK or error. MAPPINGTYPE mtMapping, // The type of mapping the image has DWORD *pdwPEKind, // [OUT] The kind of PE (0 - not a PE) DWORD *pdwMachine) // [OUT] Machine as defined in NT header { HRESULT hr = NOERROR; DWORD dwKind=0; // Working copy of pe kind. DWORD dwMachine=0; // Working copy of machine. #ifndef DACCESS_COMPILE // Do we already have cached information? if (m_dwPEKind != (DWORD)(-1)) { dwKind = m_dwPEKind; dwMachine = m_dwMachine; } else if (m_pImage) { NewHolder<PEDecoder> pe; EX_TRY { // We need to use different PEDecoder constructors based on the type of data we give it. // We use the one with a 'bool' as the second argument when dealing with a mapped file, // and we use the one that takes a COUNT_T as the second argument when dealing with a // flat file. if (mtMapping == MTYPE_IMAGE) pe = new (nothrow) PEDecoder(m_pImage, false); else pe = new (nothrow) PEDecoder(m_pImage, (COUNT_T)(m_dwImageSize)); } EX_CATCH { hr = COR_E_BADIMAGEFORMAT; } EX_END_CATCH(SwallowAllExceptions) IfFailRet(hr); IfNullRet(pe); if (pe->HasContents() && pe->HasNTHeaders()) { pe->GetPEKindAndMachine(&dwKind,&dwMachine); // Cache entries. m_dwPEKind = dwKind; m_dwMachine = dwMachine; } else // if (pe.HasContents()... hr = COR_E_BADIMAGEFORMAT; } // if (m_pImage) else
// -------------------------------------------------------------------------------------- // // Stores hot data reported by IBC in profile data (code:CorProfileData) to a stream. // Aligns output stream to 4-bytes. // __checkReturn HRESULT HotHeapWriter::SaveToStream( IStream *pStream, CorProfileData *pProfileData, UINT32 *pnSavedSize) const { _ASSERTE(pStream != NULL); _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<UINT32> 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<mdToken *>(&hotItemArr[0]), nHotItemsCount); // convert tokens to rids for (UINT32 i = 0; i < nHotItemsCount; i++) { hotItemArr[i] = RidFromToken(hotItemArr[i]); } NewArrayHolder<RidOffsetPair> 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<UINT32> 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