diff options
Diffstat (limited to 'src/vm/readytoruninfo.cpp')
-rw-r--r-- | src/vm/readytoruninfo.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp index f867036823..a0e44ceaf3 100644 --- a/src/vm/readytoruninfo.cpp +++ b/src/vm/readytoruninfo.cpp @@ -401,6 +401,55 @@ static void LogR2r(const char *msg, PEFile *pFile) #define DoLog(msg) if (s_r2rLogFile != NULL) LogR2r(msg, pFile) +// Try to acquire an R2R image for exclusive use by a particular module. +// Returns true if successful. Returns false if the image is already been used +// by another module. Each R2R image has a space to store a pointer to the +// module that owns it. We set this pointer unless it has already be +// initialized to point to another Module. +static bool AcquireImage(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader) +{ + STANDARD_VM_CONTRACT; + + // First find the import sections of the image. + READYTORUN_IMPORT_SECTION * pImportSections = NULL; + READYTORUN_IMPORT_SECTION * pImportSectionsEnd = NULL; + READYTORUN_SECTION * pSections = (READYTORUN_SECTION*)(pHeader + 1); + for (DWORD i = 0; i < pHeader->NumberOfSections; i++) + { + if (pSections[i].Type == READYTORUN_SECTION_IMPORT_SECTIONS) + { + pImportSections = (READYTORUN_IMPORT_SECTION*)((PBYTE)pLayout->GetBase() + pSections[i].Section.VirtualAddress); + pImportSectionsEnd = (READYTORUN_IMPORT_SECTION*)((PBYTE)pImportSections + pSections[i].Section.Size); + break; + } + } + + // Go through the import sections to find the import for the module pointer. + for (READYTORUN_IMPORT_SECTION * pCurSection = pImportSections; pCurSection < pImportSectionsEnd; pCurSection++) + { + // The import for the module pointer is always in an eager fixup section, so skip delayed fixup sections. + if ((pCurSection->Flags & READYTORUN_IMPORT_SECTION_FLAGS_EAGER) == 0) + continue; + + // Found an eager fixup section. Check the signature of each fixup in this section. + PVOID *pFixups = (PVOID *)((PBYTE)pLayout->GetBase() + pCurSection->Section.VirtualAddress); + DWORD nFixups = pCurSection->Section.Size / sizeof(PVOID); + DWORD *pSignatures = (DWORD *)((PBYTE)pLayout->GetBase() + pCurSection->Signatures); + for (DWORD i = 0; i < nFixups; i++) + { + // See if we found the fixup for the Module pointer. + PBYTE pSig = (PBYTE)pLayout->GetBase() + pSignatures[i]; + if (pSig[0] == READYTORUN_FIXUP_Helper && pSig[1] == READYTORUN_HELPER_Module) + { + Module * pPrevious = InterlockedCompareExchangeT(EnsureWritablePages((Module **)(pFixups + i)), pModule, NULL); + return pPrevious == NULL || pPrevious == pModule; + } + } + } + + return false; +} + PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker *pamTracker) { STANDARD_VM_CONTRACT; @@ -478,6 +527,12 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker return NULL; } + if (!AcquireImage(pModule, pLayout, pHeader)) + { + DoLog("Ready to Run disabled - module already loaded in another AppDomain"); + return NULL; + } + LoaderHeap *pHeap = pModule->GetLoaderAllocator()->GetHighFrequencyHeap(); void * pMemory = pamTracker->Track(pHeap->AllocMem((S_SIZE_T)sizeof(ReadyToRunInfo))); @@ -636,6 +691,22 @@ PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, BOOL fFixups /*=TRUE*/) return NULL; } +#ifndef CROSSGEN_COMPILE +#ifdef PROFILING_SUPPORTED + BOOL fShouldSearchCache = TRUE; + { + BEGIN_PIN_PROFILER(CORProfilerTrackCacheSearches()); + g_profControlBlock.pProfInterface-> + JITCachedFunctionSearchStarted((FunctionID)pMD, &fShouldSearchCache); + END_PIN_PROFILER(); + } + if (!fShouldSearchCache) + { + return NULL; + } +#endif // PROFILING_SUPPORTED +#endif // CROSSGEN_COMPILE + uint id; offset = m_nativeReader.DecodeUnsigned(offset, &id); @@ -671,6 +742,17 @@ PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, BOOL fFixups /*=TRUE*/) m_entryPointToMethodDescMap.InsertValue(PCODEToPINSTR(pEntryPoint), pMD); } +#ifndef CROSSGEN_COMPILE +#ifdef PROFILING_SUPPORTED + { + BEGIN_PIN_PROFILER(CORProfilerTrackCacheSearches()); + g_profControlBlock.pProfInterface-> + JITCachedFunctionSearchFinished((FunctionID)pMD, COR_PRF_CACHED_FUNCTION_FOUND); + END_PIN_PROFILER(); + } +#endif // PROFILING_SUPPORTED +#endif // CROSSGEN_COMPILE + if (g_pDebugInterface != NULL) { g_pDebugInterface->JITComplete(pMD, pEntryPoint); |