⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 244666 in webkit


Ignore:
Timestamp:
Apr 25, 2019, 2:52:59 PM (7 years ago)
Author:
ysuzuki@apple.com
Message:

[bmalloc] Follow-up and fixing bug after r244481
https://bugs.webkit.org/show_bug.cgi?id=197294

Reviewed by Saam Barati.

This patch includes follow-up after r244481 and bug fixes which is introduced in the refactoring.

  • bmalloc/IsoAllocator.h: Remove unused function.
  • bmalloc/IsoAllocatorInlines.h:

(bmalloc::IsoAllocator<Config>::allocateSlow):

  • bmalloc/IsoDeallocatorInlines.h:

(bmalloc::IsoDeallocator<Config>::deallocate):

  • bmalloc/IsoHeapImpl.h: Rename m_usableBits to m_availableShared and add static_assert.
  • bmalloc/IsoHeapImplInlines.h: Do not clear m_numberOfAllocationsFromSharedInOneCycle etc. in scavenge since IsoHeapImpl::scavenge

is not related to thread-local IsoAllocator's status.
(bmalloc::IsoHeapImpl<Config>::scavenge):
(bmalloc::IsoHeapImpl<Config>::forEachLiveObject):
(bmalloc::IsoHeapImpl<Config>::updateAllocationMode): Update m_allocationMode correctly.
(bmalloc::IsoHeapImpl<Config>::allocateFromShared):

  • bmalloc/IsoSharedHeapInlines.h:

(bmalloc::computeObjectSizeForSharedCell):
(bmalloc::IsoSharedHeap::allocateNew):
(bmalloc::IsoSharedHeap::allocateSlow): Add computeObjectSizeForSharedCell.

  • bmalloc/IsoSharedPage.h:
  • bmalloc/IsoSharedPageInlines.h:

(bmalloc::IsoSharedPage::free): Pass const std::lock_guard<Mutex>& in its parameter.

Location:
trunk/Source/bmalloc
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/bmalloc/ChangeLog

    r244653 r244666  
     12019-04-25  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [bmalloc] Follow-up and fixing bug after r244481
     4        https://bugs.webkit.org/show_bug.cgi?id=197294
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch includes follow-up after r244481 and bug fixes which is introduced in the refactoring.
     9
     10        * bmalloc/IsoAllocator.h: Remove unused function.
     11        * bmalloc/IsoAllocatorInlines.h:
     12        (bmalloc::IsoAllocator<Config>::allocateSlow):
     13        * bmalloc/IsoDeallocatorInlines.h:
     14        (bmalloc::IsoDeallocator<Config>::deallocate):
     15        * bmalloc/IsoHeapImpl.h: Rename m_usableBits to m_availableShared and add static_assert.
     16        * bmalloc/IsoHeapImplInlines.h: Do not clear m_numberOfAllocationsFromSharedInOneCycle etc. in scavenge since IsoHeapImpl::scavenge
     17        is not related to thread-local IsoAllocator's status.
     18        (bmalloc::IsoHeapImpl<Config>::scavenge):
     19        (bmalloc::IsoHeapImpl<Config>::forEachLiveObject):
     20        (bmalloc::IsoHeapImpl<Config>::updateAllocationMode): Update m_allocationMode correctly.
     21        (bmalloc::IsoHeapImpl<Config>::allocateFromShared):
     22        * bmalloc/IsoSharedHeapInlines.h:
     23        (bmalloc::computeObjectSizeForSharedCell):
     24        (bmalloc::IsoSharedHeap::allocateNew):
     25        (bmalloc::IsoSharedHeap::allocateSlow): Add computeObjectSizeForSharedCell.
     26        * bmalloc/IsoSharedPage.h:
     27        * bmalloc/IsoSharedPageInlines.h:
     28        (bmalloc::IsoSharedPage::free): Pass `const std::lock_guard<Mutex>&` in its parameter.
     29
    1302019-04-25  Alex Christensen  <achristensen@webkit.org>
    231
  • trunk/Source/bmalloc/bmalloc/IsoAllocator.h

    r244481 r244666  
    4141    ~IsoAllocator();
    4242   
    43     AllocationMode considerUsingSharedAllocation();
    44 
    4543    void* allocate(bool abortOnFailure);
    4644    void scavenge();
  • trunk/Source/bmalloc/bmalloc/IsoAllocatorInlines.h

    r244481 r244666  
    7070            m_freeList.clear();
    7171        }
    72         return m_heap->allocateFromShared(abortOnFailure);
     72        return m_heap->allocateFromShared(locker, abortOnFailure);
    7373    }
    7474
  • trunk/Source/bmalloc/bmalloc/IsoDeallocatorInlines.h

    r244481 r244666  
    6161    if (page->isShared()) {
    6262        std::lock_guard<Mutex> locker(*m_lock);
    63         static_cast<IsoSharedPage*>(page)->free<Config>(handle, ptr);
     63        static_cast<IsoSharedPage*>(page)->free<Config>(locker, handle, ptr);
    6464        return;
    6565    }
  • trunk/Source/bmalloc/bmalloc/IsoHeapImpl.h

    r244481 r244666  
    6161   
    6262    IsoHeapImplBase* m_next { nullptr };
    63     std::chrono::steady_clock::time_point m_slowPathTimePoint;
     63    std::chrono::steady_clock::time_point m_lastSlowPathTime;
    6464    std::array<void*, maxAllocationFromShared> m_sharedCells { };
    6565    unsigned m_numberOfAllocationsFromSharedInOneCycle { 0 };
    66     unsigned m_usableBits { maxAllocationFromSharedMask };
     66    unsigned m_availableShared { maxAllocationFromSharedMask };
    6767    AllocationMode m_allocationMode { AllocationMode::Init };
     68   
     69    static_assert(sizeof(m_availableShared) * 8 >= maxAllocationFromShared, "");
    6870};
    6971
     
    112114
    113115    AllocationMode updateAllocationMode();
    114     void* allocateFromShared(bool abortOnFailure);
     116    void* allocateFromShared(const std::lock_guard<Mutex>&, bool abortOnFailure);
    115117   
    116118    // It's almost always the caller's responsibility to grab the lock. This lock comes from the
  • trunk/Source/bmalloc/bmalloc/IsoHeapImplInlines.h

    r244634 r244666  
    110110        });
    111111    m_directoryHighWatermark = 0;
    112     m_numberOfAllocationsFromSharedInOneCycle = 0;
    113     m_allocationMode = AllocationMode::Init;
    114112}
    115113
     
    183181    for (unsigned index = 0; index < maxAllocationFromShared; ++index) {
    184182        void* pointer = m_sharedCells[index];
    185         if (pointer && !(m_usableBits & (1U << index)))
     183        if (pointer && !(m_availableShared & (1U << index)))
    186184            func(pointer);
    187185    }
     
    234232AllocationMode IsoHeapImpl<Config>::updateAllocationMode()
    235233{
    236     // Exhaust shared free cells, which means we should start activating the fast allocation mode for this type.
    237     if (!m_usableBits) {
    238         m_slowPathTimePoint = std::chrono::steady_clock::now();
    239         return AllocationMode::Fast;
    240     }
    241 
    242     switch (m_allocationMode) {
    243     case AllocationMode::Shared:
    244         // Currently in the shared allocation mode. Until we exhaust shared free cells, continue using the shared allocation mode.
    245         // But if we allocate so many shared cells within very short period, we should use the fast allocation mode instead.
    246         // This avoids the following pathological case.
    247         //
    248         //     for (int i = 0; i < 1e6; ++i) {
    249         //         auto* ptr = allocate();
    250         //         ...
    251         //         free(ptr);
    252         //     }
    253         if (m_numberOfAllocationsFromSharedInOneCycle <= IsoPage<Config>::numObjects)
    254             return AllocationMode::Shared;
    255         BFALLTHROUGH;
    256 
    257     case AllocationMode::Fast: {
    258         // The allocation pattern may change. We should check the allocation rate and decide which mode is more appropriate.
    259         // If we don't go to the allocation slow path during 1~ seconds, we think the allocation becomes quiescent state.
    260         auto now = std::chrono::steady_clock::now();
    261         if ((now - m_slowPathTimePoint) < std::chrono::seconds(1)) {
    262             m_slowPathTimePoint = now;
     234    auto getNewAllocationMode = [&] {
     235        // Exhaust shared free cells, which means we should start activating the fast allocation mode for this type.
     236        if (!m_availableShared) {
     237            m_lastSlowPathTime = std::chrono::steady_clock::now();
    263238            return AllocationMode::Fast;
    264239        }
    265240
    266         m_numberOfAllocationsFromSharedInOneCycle = 0;
    267         m_slowPathTimePoint = now;
     241        switch (m_allocationMode) {
     242        case AllocationMode::Shared:
     243            // Currently in the shared allocation mode. Until we exhaust shared free cells, continue using the shared allocation mode.
     244            // But if we allocate so many shared cells within very short period, we should use the fast allocation mode instead.
     245            // This avoids the following pathological case.
     246            //
     247            //     for (int i = 0; i < 1e6; ++i) {
     248            //         auto* ptr = allocate();
     249            //         ...
     250            //         free(ptr);
     251            //     }
     252            if (m_numberOfAllocationsFromSharedInOneCycle <= IsoPage<Config>::numObjects)
     253                return AllocationMode::Shared;
     254            BFALLTHROUGH;
     255
     256        case AllocationMode::Fast: {
     257            // The allocation pattern may change. We should check the allocation rate and decide which mode is more appropriate.
     258            // If we don't go to the allocation slow path during ~1 seconds, we think the allocation becomes quiescent state.
     259            auto now = std::chrono::steady_clock::now();
     260            if ((now - m_lastSlowPathTime) < std::chrono::seconds(1)) {
     261                m_lastSlowPathTime = now;
     262                return AllocationMode::Fast;
     263            }
     264
     265            m_numberOfAllocationsFromSharedInOneCycle = 0;
     266            m_lastSlowPathTime = now;
     267            return AllocationMode::Shared;
     268        }
     269
     270        case AllocationMode::Init:
     271            m_lastSlowPathTime = std::chrono::steady_clock::now();
     272            return AllocationMode::Shared;
     273        }
     274
    268275        return AllocationMode::Shared;
    269     }
    270 
    271     case AllocationMode::Init:
    272         m_slowPathTimePoint = std::chrono::steady_clock::now();
    273         return AllocationMode::Shared;
    274     }
    275 
    276     return AllocationMode::Shared;
    277 }
    278 
    279 template<typename Config>
    280 void* IsoHeapImpl<Config>::allocateFromShared(bool abortOnFailure)
     276    };
     277    AllocationMode allocationMode = getNewAllocationMode();
     278    m_allocationMode = allocationMode;
     279    return allocationMode;
     280}
     281
     282template<typename Config>
     283void* IsoHeapImpl<Config>::allocateFromShared(const std::lock_guard<Mutex>&, bool abortOnFailure)
    281284{
    282285    static constexpr bool verbose = false;
    283286
    284     unsigned indexPlusOne = __builtin_ffs(m_usableBits);
     287    unsigned indexPlusOne = __builtin_ffs(m_availableShared);
    285288    BASSERT(indexPlusOne);
    286289    unsigned index = indexPlusOne - 1;
     
    301304    }
    302305    BASSERT(result);
    303     m_usableBits &= (~(1U << index));
     306    m_availableShared &= ~(1U << index);
    304307    ++m_numberOfAllocationsFromSharedInOneCycle;
    305308    return result;
  • trunk/Source/bmalloc/bmalloc/IsoSharedHeapInlines.h

    r244481 r244666  
    4444}
    4545
     46inline constexpr unsigned computeObjectSizeForSharedCell(unsigned objectSize)
     47{
     48    return roundUpToMultipleOf<alignmentForIsoSharedAllocation>(static_cast<uintptr_t>(objectSize));
     49}
     50
    4651template<unsigned passedObjectSize>
    4752void* IsoSharedHeap::allocateNew(bool abortOnFailure)
    4853{
    4954    std::lock_guard<Mutex> locker(mutex());
    50     constexpr unsigned objectSize = roundUpToMultipleOf<alignmentForIsoSharedAllocation>(static_cast<uintptr_t>(passedObjectSize));
     55    constexpr unsigned objectSize = computeObjectSizeForSharedCell(passedObjectSize);
    5156    return m_allocator.template allocate<objectSize>(
    5257        [&] () -> void* {
     
    7479    m_allocator = m_currentPage->startAllocating();
    7580
    76     constexpr unsigned objectSize = roundUpToMultipleOf<alignmentForIsoSharedAllocation>(static_cast<uintptr_t>(passedObjectSize));
     81    constexpr unsigned objectSize = computeObjectSizeForSharedCell(passedObjectSize);
    7782    return m_allocator.allocate<objectSize>([] () { BCRASH(); return nullptr; });
    7883}
  • trunk/Source/bmalloc/bmalloc/IsoSharedPage.h

    r244481 r244666  
    3939
    4040    template<typename Config, typename Type>
    41     void free(api::IsoHeap<Type>&, void*);
     41    void free(const std::lock_guard<Mutex>&, api::IsoHeap<Type>&, void*);
    4242    VariadicBumpAllocator startAllocating();
    4343    void stopAllocating();
  • trunk/Source/bmalloc/bmalloc/IsoSharedPageInlines.h

    r244481 r244666  
    3636// We cannot set up bump allocation for such a page. Not freeing IsoSharedPages are OK since IsoSharedPage is only used for the lower tier of IsoHeap.
    3737template<typename Config, typename Type>
    38 void IsoSharedPage::free(api::IsoHeap<Type>& handle, void* ptr)
     38void IsoSharedPage::free(const std::lock_guard<Mutex>&, api::IsoHeap<Type>& handle, void* ptr)
    3939{
    4040    auto& heapImpl = handle.impl();
     
    4444    // To harden that, we validate that this pointer is actually allocated for a specific HeapImplBase here by checking whether this pointer is listed in HeapImplBase's shared cells.
    4545    RELEASE_BASSERT(heapImpl.m_sharedCells[index] == ptr);
    46     heapImpl.m_usableBits |= (1U << index);
     46    heapImpl.m_availableShared |= (1U << index);
    4747}
    4848
Note: See TracChangeset for help on using the changeset viewer.