Mark Relocation Section as NotNeeded (#25715)
authorDong-Heon Jung <dheon.jung@samsung.com>
Fri, 30 Aug 2019 21:05:53 +0000 (06:05 +0900)
committer정동헌/Common Platform Lab(SR)/Principal Engineer/삼성전자 <dheon.jung@samsung.com>
Tue, 3 Dec 2019 05:57:12 +0000 (14:57 +0900)
- 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.

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

index 11b434d..5a4e758 100644 (file)
@@ -2755,6 +2755,22 @@ Return value:
 BOOL
 PAL_LOADUnloadPreloadedPEFiles();
 
+/*++
+    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 16ee58e..a2d8e2b 100644 (file)
@@ -138,6 +138,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 78069b8..35c51ac 100644 (file)
@@ -1000,6 +1000,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 05cfd61..2e57bdd 100644 (file)
@@ -3147,3 +3147,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 1d08558..719c90e 100644 (file)
@@ -296,6 +296,9 @@ void PEImageLayout::ApplyBaseRelocations(BOOL isRelocated)
                 ThrowLastError();
         }
     }
+#ifdef FEATURE_PAL
+    PAL_LOADMarkSectionAsNotNeeded((void*)dir);
+#endif // FEATURE_PAL
 #endif // CROSSGEN_COMPILE
 
     if (pFlushRegion != NULL)