Changeset 73570 in webkit


Ignore:
Timestamp:
Dec 8, 2010 5:30:18 PM (13 years ago)
Author:
ggaren@apple.com
Message:

Migrated OS-specific allocation code from PageReservation and PageAllocation to OSAllocator
https://bugs.webkit.org/show_bug.cgi?id=50653

Reviewed by Sam Weinig.

  • interpreter/RegisterFile.h:

(JSC::RegisterFile::RegisterFile):
(JSC::RegisterFile::grow):

  • jit/ExecutableAllocatorFixedVMPool.cpp:

(JSC::FixedVMPoolAllocator::reuse):
(JSC::FixedVMPoolAllocator::FixedVMPoolAllocator): Removed checkAllocatedOkay.
OSAllocator is now the central location for verifying that allocation succeeds.
This allowed me to remove some complicating cross-platform cruft.

  • runtime/AlignedMemoryAllocator.h:

(JSC::::allocate): Updated for code motion.

  • wtf/OSAllocator.h: Added Usage, writable, and executable parameters, to

support VM features required by clients of PageAllocation and PageReservation.

  • wtf/OSAllocatorPosix.cpp:

(WTF::OSAllocator::reserve):
(WTF::OSAllocator::reserveAndCommit):
(WTF::OSAllocator::commit): Moved PageAllocation support for randomizing
executable memory here.

  • wtf/OSAllocatorSymbian.cpp:

(WTF::OSAllocator::reserve):
(WTF::OSAllocator::reserveAndCommit):
(WTF::OSAllocator::commit): Updated for new function signatures.

  • wtf/OSAllocatorWin.cpp:

(WTF::protection):
(WTF::OSAllocator::reserve):
(WTF::OSAllocator::reserveAndCommit):
(WTF::OSAllocator::commit):
(WTF::OSAllocator::release): Updated for new function signatures. Moved
some protection-related and WINCE-related code from PageAllocation here.

  • wtf/PageAllocation.cpp: Nixed cross-platform lastError abstraction, since

it was only used by checkAllocatedOkay, which is now gone.

  • wtf/PageAllocation.h:

(WTF::PageAllocation::allocate):
(WTF::PageAllocation::allocateAligned):
(WTF::PageAllocation::deallocate):
(WTF::PageAllocation::isPowerOfTwo):
(WTF::PageAllocation::systemAllocateAligned): Removed system* functions,
and replaced calls to them with calls to OSAllocator.

  • wtf/PageReservation.h:

(WTF::PageReservation::commit):
(WTF::PageReservation::decommit):
(WTF::PageReservation::reserve):
(WTF::PageReservation::deallocate):
(WTF::PageReservation::PageReservation): Ditto. Added m_writable and
m_executable because these flags are now required when committing memory.

Location:
trunk/JavaScriptCore
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r73568 r73570  
     12010-12-07  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        Migrated OS-specific allocation code from PageReservation and PageAllocation to OSAllocator
     6        https://bugs.webkit.org/show_bug.cgi?id=50653
     7
     8        * JavaScriptCore.exp: Updated for new function signature.
     9
     10        * interpreter/RegisterFile.h:
     11        (JSC::RegisterFile::RegisterFile):
     12        (JSC::RegisterFile::grow):
     13        * jit/ExecutableAllocatorFixedVMPool.cpp:
     14        (JSC::FixedVMPoolAllocator::reuse):
     15        (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator): Removed checkAllocatedOkay.
     16        OSAllocator is now the central location for verifying that allocation succeeds.
     17        This allowed me to remove some complicating cross-platform cruft.
     18
     19        * runtime/AlignedMemoryAllocator.h:
     20        (JSC::::allocate): Updated for code motion.
     21
     22        * wtf/OSAllocator.h: Added Usage, writable, and executable parameters, to
     23        support VM features required by clients of PageAllocation and PageReservation.
     24
     25        * wtf/OSAllocatorPosix.cpp:
     26        (WTF::OSAllocator::reserve):
     27        (WTF::OSAllocator::reserveAndCommit):
     28        (WTF::OSAllocator::commit): Moved PageAllocation support for randomizing
     29        executable memory here.
     30
     31        * wtf/OSAllocatorSymbian.cpp:
     32        (WTF::OSAllocator::reserve):
     33        (WTF::OSAllocator::reserveAndCommit):
     34        (WTF::OSAllocator::commit): Updated for new function signatures.
     35
     36        * wtf/OSAllocatorWin.cpp:
     37        (WTF::protection):
     38        (WTF::OSAllocator::reserve):
     39        (WTF::OSAllocator::reserveAndCommit):
     40        (WTF::OSAllocator::commit):
     41        (WTF::OSAllocator::release): Updated for new function signatures. Moved
     42        some protection-related and WINCE-related code from PageAllocation here.
     43
     44        * wtf/PageAllocation.cpp: Nixed cross-platform lastError abstraction, since
     45        it was only used by checkAllocatedOkay, which is now gone.
     46
     47        * wtf/PageAllocation.h:
     48        (WTF::PageAllocation::allocate):
     49        (WTF::PageAllocation::allocateAligned):
     50        (WTF::PageAllocation::deallocate):
     51        (WTF::PageAllocation::isPowerOfTwo):
     52        (WTF::PageAllocation::systemAllocateAligned): Removed system* functions,
     53        and replaced calls to them with calls to OSAllocator.
     54
     55        * wtf/PageReservation.h:
     56        (WTF::PageReservation::commit):
     57        (WTF::PageReservation::decommit):
     58        (WTF::PageReservation::reserve):
     59        (WTF::PageReservation::deallocate):
     60        (WTF::PageReservation::PageReservation): Ditto. Added m_writable and
     61        m_executable because these flags are now required when committing memory.
     62
    1632010-12-08  Chris Rogers  <crogers@google.com>
    264
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r73201 r73570  
    360360__ZN3WTF10fastMallocEm
    361361__ZN3WTF10fastStrDupEPKc
    362 __ZN3WTF11OSAllocator16reserveAndCommitEm
     362__ZN3WTF11OSAllocator16reserveAndCommitEmNS0_5UsageEbb
    363363__ZN3WTF11OSAllocator7releaseEPvm
    364364__ZN3WTF11commentAtomE
  • trunk/JavaScriptCore/interpreter/RegisterFile.h

    r67130 r73570  
    139139
    140140    private:
    141         void checkAllocatedOkay(bool okay);
    142141        void releaseExcessCapacity();
    143142        void addToCommittedByteCount(long);
     
    165164
    166165        size_t bufferLength = (capacity + maxGlobals) * sizeof(Register);
    167         m_reservation = PageReservation::reserve(roundUpAllocationSize(bufferLength, commitSize), PageAllocation::JSVMStackPages);
     166        m_reservation = PageReservation::reserve(roundUpAllocationSize(bufferLength, commitSize), OSAllocator::JSVMStackPages);
    168167        void* base = m_reservation.base();
    169         checkAllocatedOkay(base);
    170168        size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize);
    171         checkAllocatedOkay(m_reservation.commit(base, committedSize));
     169        m_reservation.commit(base, committedSize);
    172170        addToCommittedByteCount(static_cast<long>(committedSize));
    173171        m_commitEnd = reinterpret_cast_ptr<Register*>(reinterpret_cast<char*>(base) + committedSize);
     
    197195        if (newEnd > m_commitEnd) {
    198196            size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize);
    199             checkAllocatedOkay(m_reservation.commit(m_commitEnd, size));
     197            m_reservation.commit(m_commitEnd, size);
    200198            addToCommittedByteCount(static_cast<long>(size));
    201199            m_commitEnd = reinterpret_cast_ptr<Register*>(reinterpret_cast<char*>(m_commitEnd) + size);
     
    209207    }
    210208
    211     inline void RegisterFile::checkAllocatedOkay(bool okay)
    212     {
    213         if (!okay) {
    214 #ifndef NDEBUG
    215             fprintf(stderr, "Could not allocate register file: %d\n", PageReservation::lastError());
    216 #endif
    217             CRASH();
    218         }
    219     }
    220 
    221209} // namespace JSC
    222210
  • trunk/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp

    r73417 r73570  
    134134    void reuse(void* position, size_t size)
    135135    {
    136         bool okay = m_allocation.commit(position, size);
    137         ASSERT_UNUSED(okay, okay);
     136        m_allocation.commit(position, size);
    138137        addToCommittedByteCount(static_cast<long>(size));
    139138    }
     
    280279        , m_countFreedSinceLastCoalesce(0)
    281280    {
    282         m_allocation = PageReservation::reserve(totalHeapSize, PageAllocation::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
     281        m_allocation = PageReservation::reserve(totalHeapSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
    283282
    284283        if (!!m_allocation)
  • trunk/JavaScriptCore/runtime/AlignedMemoryAllocator.h

    r64695 r73570  
    7777inline AlignedMemory<blockSize> AlignedMemoryAllocator<blockSize>::allocate()
    7878{
    79     return AlignedMemory<blockSize>(PageAllocation::allocateAligned(blockSize, PageAllocation::JSGCHeapPages));
     79    return AlignedMemory<blockSize>(PageAllocation::allocateAligned(blockSize, OSAllocator::JSGCHeapPages));
    8080}
    8181
  • trunk/JavaScriptCore/wtf/OSAllocator.h

    r73091 r73570  
    2727#define OSAllocator_h
    2828
     29#include <wtf/VMTags.h>
     30
    2931namespace WTF {
    3032
    3133class OSAllocator {
    3234public:
    33     static void* reserve(size_t);
    34     static void* reserveAndCommit(size_t);
     35    enum Usage {
     36        UnknownUsage = -1,
     37        FastMallocPages = VM_TAG_FOR_TCMALLOC_MEMORY,
     38        JSGCHeapPages = VM_TAG_FOR_COLLECTOR_MEMORY,
     39        JSVMStackPages = VM_TAG_FOR_REGISTERFILE_MEMORY,
     40        JSJITCodePages = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY,
     41    };
    3542
    36     static void commit(void*, size_t);
     43    static void* reserve(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
     44    static void* reserveAndCommit(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
     45
     46    static void commit(void*, size_t, bool writable, bool executable);
    3747    static void decommit(void*, size_t);
    3848
  • trunk/JavaScriptCore/wtf/OSAllocatorPosix.cpp

    r73405 r73570  
    3434namespace WTF {
    3535
    36 void* OSAllocator::reserve(size_t bytes)
     36void* OSAllocator::reserve(size_t bytes, Usage usage, bool writable, bool executable)
    3737{
    38     void* result = mmap(0, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
    39     if (result == MAP_FAILED)
    40         CRASH();
     38    void* result = reserveAndCommit(bytes, usage, writable, executable);
    4139#if HAVE(MADV_FREE_REUSE)
    4240    // To support the "reserve then commit" model, we have to initially decommit.
     
    4644}
    4745
    48 void* OSAllocator::reserveAndCommit(size_t bytes)
     46void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable)
    4947{
    5048    // All POSIX reservations start out logically committed.
    51     void* result = mmap(0, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
     49    int protection = PROT_READ;
     50    if (writable)
     51        protection |= PROT_WRITE;
     52    if (executable)
     53        protection |= PROT_EXEC;
     54
     55    int flags = MAP_PRIVATE | MAP_ANON;
     56
     57#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
     58    int fd = usage;
     59#else
     60    int fd = -1;
     61#endif
     62
     63    void* result = 0;
     64#if (OS(DARWIN) && CPU(X86_64))
     65    if (executable) {
     66        // Cook up an address to allocate at, using the following recipe:
     67        //   17 bits of zero, stay in userspace kids.
     68        //   26 bits of randomness for ASLR.
     69        //   21 bits of zero, at least stay aligned within one level of the pagetables.
     70        //
     71        // But! - as a temporary workaround for some plugin problems (rdar://problem/6812854),
     72        // for now instead of 2^26 bits of ASLR lets stick with 25 bits of randomization plus
     73        // 2^24, which should put up somewhere in the middle of userspace (in the address range
     74        // 0x200000000000 .. 0x5fffffffffff).
     75        intptr_t randomLocation = 0;
     76        randomLocation = arc4random() & ((1 << 25) - 1);
     77        randomLocation += (1 << 24);
     78        randomLocation <<= 21;
     79        result = reinterpret_cast<void*>(randomLocation);
     80    }
     81#endif
     82
     83    result = mmap(result, bytes, protection, flags, fd, 0);
    5284    if (result == MAP_FAILED)
    5385        CRASH();
     
    5587}
    5688
    57 void OSAllocator::commit(void* address, size_t bytes)
     89void OSAllocator::commit(void* address, size_t bytes, bool, bool)
    5890{
    5991#if HAVE(MADV_FREE_REUSE)
  • trunk/JavaScriptCore/wtf/OSAllocatorSymbian.cpp

    r73179 r73570  
    3131namespace WTF {
    3232
    33 void* OSAllocator::reserve(size_t bytes)
     33void* OSAllocator::reserve(size_t, Usage, bool, bool)
    3434{
    3535    return fastMalloc(bytes);
    3636}
    3737
    38 void* OSAllocator::reserveAndCommit(size_t bytes)
     38void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool, bool)
    3939{
    4040    return reserve(bytes);
    4141}
    4242
    43 void OSAllocator::commit(void*, size_t)
     43void OSAllocator::commit(void*, size_t, Usage, bool, bool)
    4444{
    4545}
  • trunk/JavaScriptCore/wtf/OSAllocatorWin.cpp

    r73198 r73570  
    3232namespace WTF {
    3333
    34 void* OSAllocator::reserve(size_t bytes)
     34static inline DWORD protection(bool writable, bool executable)
    3535{
    36     void* result = VirtualAlloc(0, bytes, MEM_RESERVE, PAGE_READWRITE);
     36    return executable ?
     37        (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
     38        (writable ? PAGE_READWRITE : PAGE_READONLY);
     39}
     40
     41void* OSAllocator::reserve(size_t bytes, Usage, bool writable, bool executable)
     42{
     43    void* result = VirtualAlloc(0, bytes, MEM_RESERVE, protection(writable, executable));
    3744    if (!result)
    3845        CRASH();
     
    4047}
    4148
    42 void* OSAllocator::reserveAndCommit(size_t bytes)
     49void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool writable, bool executable)
    4350{
    44     void* result = VirtualAlloc(0, bytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
     51    void* result = VirtualAlloc(0, bytes, MEM_RESERVE | MEM_COMMIT, protection(writable, executable));
    4552    if (!result)
    4653        CRASH();
     
    4855}
    4956
    50 void OSAllocator::commit(void* address, size_t bytes)
     57void OSAllocator::commit(void* address, size_t bytes, bool writable, bool executable)
    5158{
    52     void* result = VirtualAlloc(address, bytes, MEM_COMMIT, PAGE_READWRITE);
     59    void* result = VirtualAlloc(address, bytes, MEM_COMMIT, protection(writable, executable));
    5360    if (!result)
    5461        CRASH();
     
    6471void OSAllocator::release(void* address, size_t bytes)
    6572{
     73#if OS(WINCE)
     74    decommit(address, bytes);
     75#endif
    6676    // According to http://msdn.microsoft.com/en-us/library/aa366892(VS.85).aspx,
    6777    // dwSize must be 0 if dwFreeType is MEM_RELEASE.
  • trunk/JavaScriptCore/wtf/PageAllocation.cpp

    r64782 r73570  
    3333size_t PageAllocation::s_pageSize = 0;
    3434
    35 #ifndef NDEBUG
    36 
    37 int PageAllocation::lastError()
    38 {
    39 #if OS(WINCE)
    40     return GetLastError();
    41 #else
    42     return errno;
    43 #endif
    4435}
    45 
    46 #endif
    47 
    48 }
  • trunk/JavaScriptCore/wtf/PageAllocation.h

    r73417 r73570  
    2828
    2929#include <wtf/Assertions.h>
     30#include <wtf/OSAllocator.h>
    3031#include <wtf/UnusedParam.h>
    3132#include <wtf/VMTags.h>
     
    8384class PageAllocation {
    8485public:
    85     enum Usage {
    86         UnknownUsage = -1,
    87         FastMallocPages = VM_TAG_FOR_TCMALLOC_MEMORY,
    88         JSGCHeapPages = VM_TAG_FOR_COLLECTOR_MEMORY,
    89         JSVMStackPages = VM_TAG_FOR_REGISTERFILE_MEMORY,
    90         JSJITCodePages = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY,
    91     };
    92 
    9386    PageAllocation()
    9487        : m_base(0)
     
    10497    size_t size() const { return m_size; }
    10598
    106     static PageAllocation allocate(size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
     99    static PageAllocation allocate(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
    107100    {
    108101        ASSERT(isPageAligned(size));
    109         return systemAllocate(size, usage, writable, executable);
     102        return PageAllocation(OSAllocator::reserveAndCommit(size, usage, writable, executable), size);
    110103    }
    111104
    112105#if HAVE(PAGE_ALLOCATE_ALIGNED)
    113     static PageAllocation allocateAligned(size_t size, Usage usage = UnknownUsage)
     106    static PageAllocation allocateAligned(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage)
    114107    {
    115108        ASSERT(isPageAligned(size));
     
    122115    {
    123116        ASSERT(m_base);
    124         systemDeallocate(true);
     117        void* tmp = 0;
     118        std::swap(tmp, m_base);
     119        OSAllocator::release(tmp, m_size);
    125120    }
    126121
     
    137132    static bool isPageAligned(size_t size) { return !(size & (pageSize() - 1)); }
    138133    static bool isPowerOfTwo(size_t size) { return !(size & (size - 1)); }
    139     static int lastError();
    140134#endif
    141135
     
    156150#endif
    157151
    158     static PageAllocation systemAllocate(size_t, Usage, bool, bool);
    159152#if HAVE(PAGE_ALLOCATE_ALIGNED)
    160     static PageAllocation systemAllocateAligned(size_t, Usage);
    161 #endif
    162     // systemDeallocate takes a parameter indicating whether memory is currently committed
    163     // (this should always be true for PageAllocation, false for PageReservation).
    164     void systemDeallocate(bool committed);
     153    static PageAllocation systemAllocateAligned(size_t, OSAllocator::Usage);
     154#endif
    165155    static size_t systemPageSize();
    166156
     
    178168
    179169
    180 inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage usage, bool writable, bool executable)
    181 {
    182     int protection = PROT_READ;
    183     if (writable)
    184         protection |= PROT_WRITE;
    185     if (executable)
    186         protection |= PROT_EXEC;
    187 
    188     int flags = MAP_PRIVATE | MAP_ANON;
    189 
    190 #if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
    191     int fd = usage;
    192 #else
    193     int fd = -1;
    194 #endif
    195 
    196     void* base = 0;
    197 #if (OS(DARWIN) && CPU(X86_64))
    198     if (executable) {
    199         // Cook up an address to allocate at, using the following recipe:
    200         //   17 bits of zero, stay in userspace kids.
    201         //   26 bits of randomness for ASLR.
    202         //   21 bits of zero, at least stay aligned within one level of the pagetables.
    203         //
    204         // But! - as a temporary workaround for some plugin problems (rdar://problem/6812854),
    205         // for now instead of 2^26 bits of ASLR lets stick with 25 bits of randomization plus
    206         // 2^24, which should put up somewhere in the middle of userspace (in the address range
    207         // 0x200000000000 .. 0x5fffffffffff).
    208         intptr_t randomLocation = 0;
    209         randomLocation = arc4random() & ((1 << 25) - 1);
    210         randomLocation += (1 << 24);
    211         randomLocation <<= 21;
    212         base = reinterpret_cast<void*>(randomLocation);
    213     }
    214 #endif
    215 
    216     base = mmap(base, size, protection, flags, fd, 0);
    217     if (base == MAP_FAILED)
    218         base = 0;
    219     return PageAllocation(base, size);
    220 }
    221 
    222 inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, Usage usage)
     170inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, OSAllocator::Usage usage)
    223171{
    224172#if OS(DARWIN)
     
    263211}
    264212
    265 inline void PageAllocation::systemDeallocate(bool)
    266 {
    267     void* tmp = 0;
    268     std::swap(tmp, m_base);
    269 
    270     int result = munmap(tmp, m_size);
    271     ASSERT_UNUSED(result, !result);
    272 }
    273 
    274213inline size_t PageAllocation::systemPageSize()
    275214{
     
    281220
    282221
    283 inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage, bool writable, bool executable)
    284 {
    285     DWORD protection = executable ?
    286         (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
    287         (writable ? PAGE_READWRITE : PAGE_READONLY);
    288     return PageAllocation(VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, protection), size);
    289 }
    290 
    291222#if HAVE(ALIGNED_MALLOC)
    292 inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, Usage usage)
     223inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, OSAllocator::Usage usage)
    293224{
    294225#if COMPILER(MINGW) && !COMPILER(MINGW64)
     
    301232}
    302233#endif
    303 
    304 inline void PageAllocation::systemDeallocate(bool committed)
    305 {
    306     void* tmp = 0;
    307     std::swap(tmp, m_base);
    308 
    309 #if OS(WINCE)
    310     if (committed)
    311         VirtualFree(tmp, m_size, MEM_DECOMMIT);
    312 #else
    313     UNUSED_PARAM(committed);
    314 #endif
    315     VirtualFree(tmp, 0, MEM_RELEASE);
    316 }
    317234
    318235inline size_t PageAllocation::systemPageSize()
     
    329246
    330247
    331 inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage usage, bool writable, bool executable)
    332 {
    333     RChunk* rchunk = new RChunk();
    334     if (executable)
    335         rchunk->CreateLocalCode(size, size);
    336     else
    337         rchunk->CreateLocal(size, size);
    338     return PageAllocation(rchunk->Base(), size, rchunk);
    339 }
    340 
    341 inline void PageAllocation::systemDeallocate(bool)
    342 {
    343     void* tmp = 0;
    344     std::swap(tmp, m_base);
    345 
    346     m_chunk->Close();
    347     delete m_chunk;
    348 }
    349 
    350248inline size_t PageAllocation::systemPageSize()
    351249{
  • trunk/JavaScriptCore/wtf/PageReservation.h

    r73417 r73570  
    5353    is changed on memory while it is committed it should be returned to the orignal
    5454    protection before decommit is called.
    55 
    56     Note: Inherits from PageAllocation privately to prevent clients accidentally
    57     calling PageAllocation::deallocate on a PageReservation.
    5855*/
    5956class PageReservation : private PageAllocation {
     
    6764    using PageAllocation::size;
    6865
    69     bool commit(void* start, size_t size)
     66    void commit(void* start, size_t size)
    7067    {
    7168        ASSERT(m_base);
     
    7370        ASSERT(isPageAligned(size));
    7471
    75         bool commited = systemCommit(start, size);
    7672#ifndef NDEBUG
    77         if (commited)
    78             m_committed += size;
     73        m_committed += size;
    7974#endif
    80         return commited;
     75        OSAllocator::commit(start, size, m_writable, m_executable);
    8176    }
     77
    8278    void decommit(void* start, size_t size)
    8379    {
     
    8985        m_committed -= size;
    9086#endif
    91         systemDecommit(start, size);
     87        OSAllocator::decommit(start, size);
    9288    }
    9389
    94     static PageReservation reserve(size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
     90    static PageReservation reserve(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
    9591    {
    9692        ASSERT(isPageAligned(size));
    97         return systemReserve(size, usage, writable, executable);
     93        return PageReservation(OSAllocator::reserve(size, usage, writable, executable), size, writable, executable);
    9894    }
    9995
    10096    void deallocate()
    10197    {
    102         ASSERT(m_base);
    10398        ASSERT(!m_committed);
    104         systemDeallocate(false);
     99        PageAllocation::deallocate();
    105100    }
    106 
    107 #ifndef NDEBUG
    108     using PageAllocation::lastError;
    109 #endif
    110101
    111102private:
     
    114105        : PageAllocation(base, size, chunk)
    115106#else
    116     PageReservation(void* base, size_t size)
     107    PageReservation(void* base, size_t size, bool writable, bool executable)
    117108        : PageAllocation(base, size)
    118109#endif
     
    120111        , m_committed(0)
    121112#endif
     113        , m_writable(writable)
     114        , m_executable(executable)
    122115    {
    123116    }
    124117
    125     bool systemCommit(void*, size_t);
    126     void systemDecommit(void*, size_t);
    127     static PageReservation systemReserve(size_t, Usage, bool, bool);
    128 
    129 #if HAVE(VIRTUALALLOC)
    130     DWORD m_protection;
    131 #endif
    132118#ifndef NDEBUG
    133119    size_t m_committed;
    134120#endif
     121    bool m_writable;
     122    bool m_executable;
    135123};
    136 
    137 
    138 #if HAVE(MMAP)
    139 
    140 
    141 inline bool PageReservation::systemCommit(void* start, size_t size)
    142 {
    143 #if HAVE(MADV_FREE_REUSE)
    144     while (madvise(start, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
    145 #else
    146     UNUSED_PARAM(start);
    147     UNUSED_PARAM(size);
    148 #endif
    149     return true;
    150 }
    151 
    152 inline void PageReservation::systemDecommit(void* start, size_t size)
    153 {
    154 #if HAVE(MADV_FREE_REUSE)
    155     while (madvise(start, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
    156 #elif HAVE(MADV_FREE)
    157     while (madvise(start, size, MADV_FREE) == -1 && errno == EAGAIN) { }
    158 #elif HAVE(MADV_DONTNEED)
    159     while (madvise(start, size, MADV_DONTNEED) == -1 && errno == EAGAIN) { }
    160 #else
    161     UNUSED_PARAM(start);
    162     UNUSED_PARAM(size);
    163 #endif
    164 }
    165 
    166 inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
    167 {
    168     void* base = systemAllocate(size, usage, writable, executable).base();
    169 #if HAVE(MADV_FREE_REUSE)
    170     // When using MADV_FREE_REUSE we keep all decommitted memory marked as REUSABLE.
    171     // We call REUSE on commit, and REUSABLE on decommit.
    172     if (base)
    173         while (madvise(base, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
    174 #endif
    175     return PageReservation(base, size);
    176 }
    177 
    178 
    179 #elif HAVE(VIRTUALALLOC)
    180 
    181 
    182 inline bool PageReservation::systemCommit(void* start, size_t size)
    183 {
    184     return VirtualAlloc(start, size, MEM_COMMIT, m_protection) == start;
    185 }
    186 
    187 inline void PageReservation::systemDecommit(void* start, size_t size)
    188 {
    189     VirtualFree(start, size, MEM_DECOMMIT);
    190 }
    191 
    192 inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
    193 {
    194     // Record the protection for use during commit.
    195     DWORD protection = executable ?
    196         (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
    197         (writable ? PAGE_READWRITE : PAGE_READONLY);
    198     PageReservation reservation(VirtualAlloc(0, size, MEM_RESERVE, protection), size);
    199     reservation.m_protection = protection;
    200     return reservation;
    201 }
    202 
    203 
    204 #elif OS(SYMBIAN)
    205 
    206 
    207 inline bool PageReservation::systemCommit(void* start, size_t size)
    208 {
    209     intptr_t offset = reinterpret_cast<intptr_t>(start) - reinterpret_cast<intptr_t>(m_base);
    210     m_chunk->Commit(offset, size);
    211     return true;
    212 }
    213 
    214 inline void PageReservation::systemDecommit(void* start, size_t size)
    215 {
    216     intptr_t offset = reinterpret_cast<intptr_t>(start) - reinterpret_cast<intptr_t>(m_base);
    217     m_chunk->Decommit(offset, size);
    218 }
    219 
    220 inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
    221 {
    222     RChunk* rchunk = new RChunk();
    223     if (executable)
    224         rchunk->CreateLocalCode(0, size);
    225     else
    226         rchunk->CreateDisconnectedLocal(0, 0, size);
    227     return PageReservation(rchunk->Base(), size, rchunk);
    228 }
    229 
    230 
    231 #endif
    232 
    233124
    234125}
Note: See TracChangeset for help on using the changeset viewer.