Mark Relocation Section as NotNeeded (dotnet/coreclr#25715)
authorDong-Heon Jung <dheon.jung@samsung.com>
Fri, 30 Aug 2019 21:05:53 +0000 (06:05 +0900)
committerJan Kotas <jkotas@microsoft.com>
Fri, 30 Aug 2019 21:05:53 +0000 (14:05 -0700)
- After relocation, relocation section in zap image is not necessary.
- Mark the section as NotNeeded by giving advice(madvise with MADV_DONTNEED)
- It reduces 120~150KB PSS in tizen sample apps.

Commit migrated from https://github.com/dotnet/coreclr/commit/4036c492d23ec3322b01573aab6190233db1f149

src/coreclr/src/pal/inc/pal.h
src/coreclr/src/pal/src/include/pal/map.hpp
src/coreclr/src/pal/src/loader/module.cpp
src/coreclr/src/pal/src/map/map.cpp
src/coreclr/src/vm/peimagelayout.cpp

index facb2a6..6cd1012 100644 (file)
@@ -2690,6 +2690,22 @@ BOOL
 PALAPI
 PAL_LOADUnloadPEFile(PVOID ptr);
 
+/*++
+    PAL_LOADMarkSectionAsNotNeeded
+
+    Mark a section as NotNeeded that was loaded by PAL_LOADLoadPEFile().
+
+Parameters:
+    IN ptr - the section address mapped by PAL_LOADLoadPEFile()
+
+Return value:
+    TRUE - success
+    FALSE - failure (incorrect ptr, etc.)
+--*/
+BOOL
+PALAPI
+PAL_LOADMarkSectionAsNotNeeded(void * ptr);
+
 #ifdef UNICODE
 #define LoadLibrary LoadLibraryW
 #define LoadLibraryEx LoadLibraryExW
index 7bcb20a..0709268 100644 (file)
@@ -94,6 +94,13 @@ extern "C"
         returns TRUE if successful, FALSE otherwise
     --*/
     BOOL MAPUnmapPEFile(LPCVOID lpAddress);
+
+    /*++
+    Function :
+        MAPMarkSectionAsNotNeeded - mark a section as NotNeeded
+        returns TRUE if successful, FALSE otherwise
+    --*/
+    BOOL MAPMarkSectionAsNotNeeded(LPCVOID lpAddress);
 }
 
 namespace CorUnix
index 0ebee1e..8ad2ae2 100644 (file)
@@ -825,6 +825,39 @@ PAL_LOADUnloadPEFile(PVOID ptr)
 }
 
 /*++
+    PAL_LOADMarkSectionAsNotNeeded
+
+    Mark a section as NotNeeded that was loaded by PAL_LOADLoadPEFile().
+
+Parameters:
+    IN ptr - the section address mapped by PAL_LOADLoadPEFile()
+
+Return value:
+    TRUE - success
+    FALSE - failure (incorrect ptr, etc.)
+--*/
+BOOL
+PALAPI
+PAL_LOADMarkSectionAsNotNeeded(void * ptr)
+{
+    BOOL retval = FALSE;
+
+    ENTRY("PAL_LOADMarkSectionAsNotNeeded (ptr=%p)\n", ptr);
+
+    if (nullptr == ptr)
+    {
+        ERROR( "Invalid pointer value\n" );
+    }
+    else
+    {
+        retval = MAPMarkSectionAsNotNeeded(ptr);
+    }
+
+    LOGEXIT("PAL_LOADMarkSectionAsNotNeeded returns %d\n", retval);
+    return retval;
+}
+
+/*++
     PAL_GetSymbolModuleBase
 
     Get base address of the module containing a given symbol
index e8f7cba..48ef576 100644 (file)
@@ -2673,3 +2673,54 @@ BOOL MAPUnmapPEFile(LPCVOID lpAddress)
     TRACE_(LOADER)("MAPUnmapPEFile returning %d\n", retval);
     return retval;
 }
+
+/*++
+Function :
+    MAPMarkSectionAsNotNeeded - Mark a section as NotNeeded
+    returns TRUE if successful, FALSE otherwise
+--*/
+BOOL MAPMarkSectionAsNotNeeded(LPCVOID lpAddress)
+{
+    TRACE_(LOADER)("MAPMarkSectionAsNotNeeded(lpAddress=%p)\n", lpAddress);
+
+    if ( NULL == lpAddress )
+    {
+        ERROR_(LOADER)( "lpAddress cannot be NULL\n" );
+        return FALSE;
+    }
+
+    BOOL retval = TRUE;
+    CPalThread * pThread = InternalGetCurrentThread();
+    InternalEnterCriticalSection(pThread, &mapping_critsec);
+    PLIST_ENTRY pLink, pLinkNext = NULL;
+
+    // Look through the entire MappedViewList for all mappings associated with the
+    // section with an address 'lpAddress' which we want to mark as NotNeeded.
+
+    for(pLink = MappedViewList.Flink;
+            pLink != &MappedViewList;
+            pLink = pLinkNext)
+    {
+        pLinkNext = pLink->Flink;
+        PMAPPED_VIEW_LIST pView = CONTAINING_RECORD(pLink, MAPPED_VIEW_LIST, Link);
+
+        if (pView->lpAddress == lpAddress) // this entry is associated with the section
+        {
+            if (-1 == madvise(pView->lpAddress, pView->NumberOfBytesToMap, MADV_DONTNEED))
+            {
+                ERROR_(LOADER)("Unable to mark the section as NotNeeded.\n");
+                retval = FALSE;
+            }
+            else
+            {
+                pView->dwDesiredAccess = 0;
+            }
+            break;
+        }
+    }
+
+    InternalLeaveCriticalSection(pThread, &mapping_critsec);
+
+    TRACE_(LOADER)("MAPMarkSectionAsNotNeeded returning %d\n", retval);
+    return retval;
+}
index 906e443..3ceae66 100644 (file)
@@ -285,6 +285,9 @@ void PEImageLayout::ApplyBaseRelocations()
                                dwOldProtection, &dwOldProtection))
             ThrowLastError();
     }
+#ifdef FEATURE_PAL
+    PAL_LOADMarkSectionAsNotNeeded((void*)dir);
+#endif // FEATURE_PAL
 #endif // CROSSGEN_COMPILE
 
     if (pFlushRegion != NULL)