Changeset 180953 in webkit


Ignore:
Timestamp:
Mar 3, 2015 1:47:49 PM (9 years ago)
Author:
ggaren@apple.com
Message:

bmalloc: Miscellaneous cleanup
https://bugs.webkit.org/show_bug.cgi?id=142231

Reviewed by Andreas Kling.

No performance change -- maybe a tiny reduction in memory use.

  • bmalloc/Heap.cpp: Moved the sleep function into StaticMutex, since

it's a helper for working with mutexes.

(bmalloc::Heap::scavenge): Make sure to wait before we start any
scavenging, since individual scavenging functions now always scavenge
at least one page before waiting themselves.

(bmalloc::Heap::scavengeSmallPages):
(bmalloc::Heap::scavengeMediumPages):
(bmalloc::Heap::scavengeLargeObjects): Use the new wait helper to
simplify this code. Also, we now require our caller to wait until at
least one deallocation is desirable. This simplifies our loop.

(bmalloc::Heap::allocateSmallPage):
(bmalloc::Heap::allocateMediumPage):
(bmalloc::Heap::allocateXLarge):
(bmalloc::Heap::allocateLarge): Don't freak out any time the heap does
an allocation. Only consider the heap to be growing if it actually needs
to allocate new VM. This allows us to shrink the heap back down from a
high water mark more reliably even if heap activity continues.

(bmalloc::sleep): Deleted.
(bmalloc::Heap::scavengeLargeRanges): Renamed to match our use of
"LargeObject".

  • bmalloc/Heap.h:
  • bmalloc/LargeObject.h:

(bmalloc::LargeObject::operator bool): Added to simplify a while loop.

  • bmalloc/StaticMutex.h:

(bmalloc::sleep):
(bmalloc::waitUntilFalse): New helper for waiting until a condition
becomes reliably false.

  • bmalloc/Vector.h:

(bmalloc::Vector<T>::~Vector): Oops! Don't deallocate the null pointer.
We don't actually run any Vector destructors, but an iteration of this
patch did, and then crashed. So, let's fix that.

Location:
trunk/Source/bmalloc
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/bmalloc/ChangeLog

    r180908 r180953  
     12015-03-03  Geoffrey Garen  <ggaren@apple.com>
     2
     3        bmalloc: Miscellaneous cleanup
     4        https://bugs.webkit.org/show_bug.cgi?id=142231
     5
     6        Reviewed by Andreas Kling.
     7
     8        No performance change -- maybe a tiny reduction in memory use.
     9
     10        * bmalloc/Heap.cpp: Moved the sleep function into StaticMutex, since
     11        it's a helper for working with mutexes.
     12
     13        (bmalloc::Heap::scavenge): Make sure to wait before we start any
     14        scavenging, since individual scavenging functions now always scavenge
     15        at least one page before waiting themselves.
     16
     17        (bmalloc::Heap::scavengeSmallPages):
     18        (bmalloc::Heap::scavengeMediumPages):
     19        (bmalloc::Heap::scavengeLargeObjects): Use the new wait helper to
     20        simplify this code. Also, we now require our caller to wait until at
     21        least one deallocation is desirable. This simplifies our loop.
     22
     23        (bmalloc::Heap::allocateSmallPage):
     24        (bmalloc::Heap::allocateMediumPage):
     25        (bmalloc::Heap::allocateXLarge):
     26        (bmalloc::Heap::allocateLarge): Don't freak out any time the heap does
     27        an allocation. Only consider the heap to be growing if it actually needs
     28        to allocate new VM. This allows us to shrink the heap back down from a
     29        high water mark more reliably even if heap activity continues.
     30
     31        (bmalloc::sleep): Deleted.
     32        (bmalloc::Heap::scavengeLargeRanges): Renamed to match our use of
     33        "LargeObject".
     34
     35        * bmalloc/Heap.h:
     36
     37        * bmalloc/LargeObject.h:
     38        (bmalloc::LargeObject::operator bool): Added to simplify a while loop.
     39
     40        * bmalloc/StaticMutex.h:
     41        (bmalloc::sleep):
     42        (bmalloc::waitUntilFalse): New helper for waiting until a condition
     43        becomes reliably false.
     44
     45        * bmalloc/Vector.h:
     46        (bmalloc::Vector<T>::~Vector): Oops! Don't deallocate the null pointer.
     47        We don't actually run any Vector destructors, but an iteration of this
     48        patch did, and then crashed. So, let's fix that.
     49
    1502015-03-02  Geoffrey Garen  <ggaren@apple.com>
    251
  • trunk/Source/bmalloc/bmalloc/Heap.cpp

    r180797 r180953  
    3636namespace bmalloc {
    3737
    38 static inline void sleep(std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds duration)
    39 {
    40     if (duration == std::chrono::milliseconds(0))
    41         return;
    42    
    43     lock.unlock();
    44     std::this_thread::sleep_for(duration);
    45     lock.lock();
    46 }
    47 
    4838Heap::Heap(std::lock_guard<StaticMutex>&)
    4939    : m_largeObjects(Owner::Heap)
     
    9484    scavenge(lock, scavengeSleepDuration);
    9585}
    96    
     86
    9787void Heap::scavenge(std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds sleepDuration)
    9888{
     89    waitUntilFalse(lock, sleepDuration, m_isAllocatingPages);
     90
    9991    scavengeSmallPages(lock, sleepDuration);
    10092    scavengeMediumPages(lock, sleepDuration);
    101     scavengeLargeRanges(lock, sleepDuration);
     93    scavengeLargeObjects(lock, sleepDuration);
    10294
    10395    sleep(lock, sleepDuration);
     
    10698void Heap::scavengeSmallPages(std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds sleepDuration)
    10799{
    108     while (1) {
    109         if (m_isAllocatingPages) {
    110             m_isAllocatingPages = false;
    111 
    112             sleep(lock, sleepDuration);
    113             continue;
    114         }
    115 
    116         if (!m_smallPages.size())
    117             return;
     100    while (m_smallPages.size()) {
    118101        m_vmHeap.deallocateSmallPage(lock, m_smallPages.pop());
     102        waitUntilFalse(lock, sleepDuration, m_isAllocatingPages);
    119103    }
    120104}
     
    122106void Heap::scavengeMediumPages(std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds sleepDuration)
    123107{
    124     while (1) {
    125         if (m_isAllocatingPages) {
    126             m_isAllocatingPages = false;
    127 
    128             sleep(lock, sleepDuration);
    129             continue;
    130         }
    131 
    132         if (!m_mediumPages.size())
    133             return;
     108    while (m_mediumPages.size()) {
    134109        m_vmHeap.deallocateMediumPage(lock, m_mediumPages.pop());
    135     }
    136 }
    137 
    138 void Heap::scavengeLargeRanges(std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds sleepDuration)
    139 {
    140     while (1) {
    141         if (m_isAllocatingPages) {
    142             m_isAllocatingPages = false;
    143 
    144             sleep(lock, sleepDuration);
    145             continue;
    146         }
    147 
    148         LargeObject largeObject = m_largeObjects.takeGreedy();
    149         if (!largeObject)
    150             return;
     110        waitUntilFalse(lock, sleepDuration, m_isAllocatingPages);
     111    }
     112}
     113
     114void Heap::scavengeLargeObjects(std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds sleepDuration)
     115{
     116    while (LargeObject largeObject = m_largeObjects.takeGreedy()) {
    151117        m_vmHeap.deallocateLargeObject(lock, largeObject);
     118        waitUntilFalse(lock, sleepDuration, m_isAllocatingPages);
    152119    }
    153120}
     
    236203        return page;
    237204    }
    238    
    239     m_isAllocatingPages = true;
    240205
    241206    SmallPage* page = [this, sizeClass]() {
    242207        if (m_smallPages.size())
    243208            return m_smallPages.pop();
     209
     210        m_isAllocatingPages = true;
    244211        return m_vmHeap.allocateSmallPage();
    245212    }();
     
    258225        return page;
    259226    }
    260    
    261     m_isAllocatingPages = true;
    262227
    263228    MediumPage* page = [this, sizeClass]() {
    264229        if (m_mediumPages.size())
    265230            return m_mediumPages.pop();
     231
     232        m_isAllocatingPages = true;
    266233        return m_vmHeap.allocateMediumPage();
    267234    }();
     
    321288    BASSERT(size == roundUpToMultipleOf<xLargeAlignment>(size));
    322289
    323     m_isAllocatingPages = true;
    324 
    325290    void* result = vmAllocate(alignment, size);
    326291    m_xLargeObjects.push(Range(result, size));
     
    380345    BASSERT(size == roundUpToMultipleOf<largeAlignment>(size));
    381346   
    382     m_isAllocatingPages = true;
    383 
    384347    LargeObject largeObject = m_largeObjects.take(size);
    385     if (!largeObject)
     348    if (!largeObject) {
     349        m_isAllocatingPages = true;
    386350        largeObject = m_vmHeap.allocateLargeObject(size);
     351    }
    387352
    388353    return allocateLarge(lock, largeObject, size);
     
    401366    BASSERT(isPowerOfTwo(alignment));
    402367
    403     m_isAllocatingPages = true;
    404 
    405368    LargeObject largeObject = m_largeObjects.take(alignment, size, unalignedSize);
    406     if (!largeObject)
     369    if (!largeObject) {
     370        m_isAllocatingPages = true;
    407371        largeObject = m_vmHeap.allocateLargeObject(alignment, size, unalignedSize);
     372    }
    408373
    409374    size_t alignmentMask = alignment - 1;
  • trunk/Source/bmalloc/bmalloc/Heap.h

    r180797 r180953  
    9393    void scavengeSmallPages(std::unique_lock<StaticMutex>&, std::chrono::milliseconds);
    9494    void scavengeMediumPages(std::unique_lock<StaticMutex>&, std::chrono::milliseconds);
    95     void scavengeLargeRanges(std::unique_lock<StaticMutex>&, std::chrono::milliseconds);
     95    void scavengeLargeObjects(std::unique_lock<StaticMutex>&, std::chrono::milliseconds);
    9696
    9797    std::array<std::array<LineMetadata, SmallPage::lineCount>, smallMax / alignment> m_smallLineMetadata;
  • trunk/Source/bmalloc/bmalloc/LargeObject.h

    r180797 r180953  
    4444    LargeObject(DoNotValidateTag, void*);
    4545   
     46    operator bool() { return !!*this; }
    4647    bool operator!() { return !m_object; }
    4748
  • trunk/Source/bmalloc/bmalloc/StaticMutex.h

    r177181 r180953  
    2929#include "BAssert.h"
    3030#include <atomic>
     31#include <mutex>
     32#include <thread>
    3133
    3234// A fast replacement for std::mutex, for use in static storage.
     
    5254    std::atomic_flag m_flag;
    5355};
     56
     57static inline void sleep(
     58    std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds duration)
     59{
     60    if (duration == std::chrono::milliseconds(0))
     61        return;
     62   
     63    lock.unlock();
     64    std::this_thread::sleep_for(duration);
     65    lock.lock();
     66}
     67
     68static inline void waitUntilFalse(
     69    std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds sleepDuration,
     70    bool& condition)
     71{
     72    while (condition) {
     73        condition = false;
     74        sleep(lock, sleepDuration);
     75    }
     76}
    5477
    5578inline void StaticMutex::init()
  • trunk/Source/bmalloc/bmalloc/Vector.h

    r179923 r180953  
    8989Vector<T>::~Vector()
    9090{
    91     vmDeallocate(m_buffer, vmSize(m_capacity * sizeof(T)));
     91    if (m_buffer)
     92        vmDeallocate(m_buffer, vmSize(m_capacity * sizeof(T)));
    9293}
    9394
Note: See TracChangeset for help on using the changeset viewer.