Changeset 137994 in webkit


Ignore:
Timestamp:
Dec 18, 2012 12:37:24 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Implement uncommitted memory for Linux.
https://bugs.webkit.org/show_bug.cgi?id=65766

Patch by Uli Schlachter <psychon@znc.in> on 2012-12-18
Reviewed by Simon Hausmann.

The old approach used MAP_NORESERVE to allocate address space without
committing it. However, that flag gets ignored if
/proc/sys/vm/overcommit_memory is set to 2. The new approach uses a
mapping with PROT_NONE. This works because mappings which aren't even
readable don't get accounted as committed on Linux.

  • wtf/OSAllocatorPosix.cpp:

(WTF::OSAllocator::reserveUncommitted):
(WTF::OSAllocator::reserveAndCommit):
(WTF::OSAllocator::commit):
(WTF::OSAllocator::decommit):

Location:
trunk/Source/WTF
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r137911 r137994  
     12012-12-18  Uli Schlachter  <psychon@znc.in>
     2
     3        Implement uncommitted memory for Linux.
     4        https://bugs.webkit.org/show_bug.cgi?id=65766
     5
     6        Reviewed by Simon Hausmann.
     7
     8        The old approach used MAP_NORESERVE to allocate address space without
     9        committing it. However, that flag gets ignored if
     10        /proc/sys/vm/overcommit_memory is set to 2. The new approach uses a
     11        mapping with PROT_NONE. This works because mappings which aren't even
     12        readable don't get accounted as committed on Linux.
     13
     14        * wtf/OSAllocatorPosix.cpp:
     15        (WTF::OSAllocator::reserveUncommitted):
     16        (WTF::OSAllocator::reserveAndCommit):
     17        (WTF::OSAllocator::commit):
     18        (WTF::OSAllocator::decommit):
     19
    1202012-12-17  Ilya Tikhonovsky  <loislo@chromium.org>
    221
  • trunk/Source/WTF/wtf/OSAllocatorPosix.cpp

    r129453 r137994  
    4242    if (result == MAP_FAILED)
    4343        CRASH();
    44 #else // OS(QNX)
    45 
     44#elif OS(LINUX)
     45    void* result = mmap(0, bytes, PROT_NONE, MAP_NORESERVE | MAP_PRIVATE | MAP_ANON, -1, 0);
     46    if (result == MAP_FAILED)
     47        CRASH();
     48    madvise(result, bytes, MADV_DONTNEED);
     49#else
    4650    void* result = reserveAndCommit(bytes, usage, writable, executable, includesGuardPages);
    47 #if OS(LINUX)
    48     madvise(result, bytes, MADV_DONTNEED);
    49 #elif HAVE(MADV_FREE_REUSE)
     51#if HAVE(MADV_FREE_REUSE)
    5052    // To support the "reserve then commit" model, we have to initially decommit.
    5153    while (madvise(result, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
     
    7072    if (executable)
    7173        flags |= MAP_JIT;
    72 #endif
    73 
    74 #if (OS(LINUX) && CPU(X86_64))
    75     // Linux distros usually do not allow overcommit by default, so
    76     // JSC's strategy of mmaping a large amount of memory upfront
    77     // won't work very well on some systems. Fortunately there's a
    78     // flag we can pass to mmap to disable the overcommit check for
    79     // this particular call, so we can get away with it as long as the
    80     // overcommit flag value in /proc/sys/vm/overcommit_memory is 0
    81     // ('heuristic') and not 2 (always check). 0 is the usual default
    82     // value, so this should work well in general.
    83     flags |= MAP_NORESERVE;
    8474#endif
    8575
     
    143133        CRASH();
    144134#elif OS(LINUX)
    145     UNUSED_PARAM(writable);
    146     UNUSED_PARAM(executable);
     135    int protection = PROT_READ;
     136    if (writable)
     137        protection |= PROT_WRITE;
     138    if (executable)
     139        protection |= PROT_EXEC;
     140    if (mprotect(address, bytes, protection))
     141        CRASH();
    147142    madvise(address, bytes, MADV_WILLNEED);
    148143#elif HAVE(MADV_FREE_REUSE)
     
    166161#elif OS(LINUX)
    167162    madvise(address, bytes, MADV_DONTNEED);
     163    if (mprotect(address, bytes, PROT_NONE))
     164        CRASH();
    168165#elif HAVE(MADV_FREE_REUSE)
    169166    while (madvise(address, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
Note: See TracChangeset for help on using the changeset viewer.