Changeset 247368 in webkit


Ignore:
Timestamp:
Jul 11, 2019 2:56:32 PM (5 years ago)
Author:
ysuzuki@apple.com
Message:

Flaky API Test TestWTF.bmalloc.ScavengedMemoryShouldBeReused
https://bugs.webkit.org/show_bug.cgi?id=199524
<rdar://problem/52783816>

Reviewed by Saam Barati.

This test is white-box one and it has strong assumption how IsoHeap allocates pages.
But this test has several problems.

  1. IsoPage::numObjects is not the exact number of how many we allocate objects. This number is calculated by pageSize / sizeof(T), and this does not account the header size of IsoPage. So, # of objects per IsoPage is less than numObjects. Since sizeof(double) is very small, we can have many objects in one IsoPage. As a result, we need a large bitmap in IsoPage. This reduces # of objects in IsoPage largely. So, ptrs.size() becomes less than numObjects.
  1. We now have lower tier of allocation in IsoHeap. It means that we allocate 8 objects in shared page (page is shared, but memory is pinned for a specific type) before using IsoHeap's page. This also makes the intention of this test wrong.

Due to (1), we access OoB of ptrs vector, passing a garbage to IsoHeap::deallocate, and crashing.

We make this test robust while we still keep this test white-box one to test the critical feature
of IsoHeap. We first exhaust lower tier of IsoHeap, and after that, start testing the memory. We
allocate many pointers, deallocate them, allocate one pointer while keeping pointers in the lower
tier live, and check whether the deallocated memory is reused.

  • TestWebKitAPI/Tests/WTF/bmalloc/IsoHeap.cpp:

(TEST):

Location:
trunk/Tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r247367 r247368  
     12019-07-11  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Flaky API Test TestWTF.bmalloc.ScavengedMemoryShouldBeReused
     4        https://bugs.webkit.org/show_bug.cgi?id=199524
     5        <rdar://problem/52783816>
     6
     7        Reviewed by Saam Barati.
     8
     9        This test is white-box one and it has strong assumption how IsoHeap allocates pages.
     10        But this test has several problems.
     11
     12        1. IsoPage::numObjects is not the exact number of how many we allocate objects. This
     13           number is calculated by pageSize / sizeof(T), and this does not account the header
     14           size of IsoPage. So, # of objects per IsoPage is less than numObjects. Since sizeof(double)
     15           is very small, we can have many objects in one IsoPage. As a result, we need a large
     16           bitmap in IsoPage. This reduces # of objects in IsoPage largely. So, `ptrs.size()` becomes
     17           less than numObjects.
     18
     19        2. We now have lower tier of allocation in IsoHeap. It means that we allocate 8 objects in
     20           shared page (page is shared, but memory is pinned for a specific type) before using IsoHeap's
     21           page. This also makes the intention of this test wrong.
     22
     23        Due to (1), we access OoB of ptrs vector, passing a garbage to IsoHeap::deallocate, and crashing.
     24
     25        We make this test robust while we still keep this test white-box one to test the critical feature
     26        of IsoHeap. We first exhaust lower tier of IsoHeap, and after that, start testing the memory. We
     27        allocate many pointers, deallocate them, allocate one pointer while keeping pointers in the lower
     28        tier live, and check whether the deallocated memory is reused.
     29
     30        * TestWebKitAPI/Tests/WTF/bmalloc/IsoHeap.cpp:
     31        (TEST):
     32
    1332019-07-11  Pablo Saavedra  <psaavedra@igalia.com>
    234
  • trunk/Tools/TestWebKitAPI/Tests/WTF/bmalloc/IsoHeap.cpp

    r246630 r247368  
    314314
    315315    auto run = [] (unsigned numPagesToCommit) {
    316         auto* ptr1 = heap.allocate();
    317 
     316        std::vector<void*> lowerTierPtrs;
    318317        std::vector<void*> ptrs;
    319318
     319        // Let's exhaust the capacity of the lower tier.
     320        for (unsigned i = 0; i < IsoPage<decltype(heap)::Config>::numObjects; ++i) {
     321            void* ptr = heap.allocate();
     322            CHECK(ptr);
     323            lowerTierPtrs.push_back(ptr);
     324        }
     325
     326        // After that, allocating pointers in the upper tier.
    320327        for (unsigned i = 0; ;i++) {
    321328            void* ptr = heap.allocate();
     
    326333        }
    327334
    328         std::set<void*> uniquedPtrs = toptrset(ptrs);
    329 
    330         heap.deallocate(ptr1);
    331         for (unsigned i = 0; i < IsoPage<decltype(heap)::Config>::numObjects - 1; i++) {
    332             heap.deallocate(ptrs[i]);
    333             uniquedPtrs.erase(ptrs[i]);
     335        std::set<void*> uniquedPtrsOfUpperTiers = toptrset(ptrs);
     336        CHECK(ptrs.size() == uniquedPtrsOfUpperTiers.size());
     337
     338        std::set<void*> uniquedPtrs = uniquedPtrsOfUpperTiers;
     339        for (void* ptr : lowerTierPtrs)
     340            uniquedPtrs.insert(ptr);
     341
     342        // We do keep pointers in the lower tier while deallocating pointers in the upper tier.
     343        // Then, after the scavenge, the pages of the upper tier should be reused.
     344
     345        for (void* ptr : ptrs) {
     346            heap.deallocate(ptr);
     347            uniquedPtrs.erase(ptr);
    334348        }
    335349
     
    337351        assertHasOnlyObjects(heap, uniquedPtrs);
    338352
    339         // FIXME: This only seems to pass when lldb is attached but the scavenger thread isn't running...
    340         // see: https://bugs.webkit.org/show_bug.cgi?id=198384
    341         // auto* ptr2 = heap.allocate();
    342         // CHECK(ptr1 == ptr2);
     353        auto* ptr2 = heap.allocate();
     354        CHECK(uniquedPtrsOfUpperTiers.find(ptr2) != uniquedPtrsOfUpperTiers.end());
     355        heap.deallocate(ptr2);
     356
     357        for (void* ptr : lowerTierPtrs)
     358            heap.deallocate(ptr);
    343359    };
    344360
    345     run(2);
     361    run(5);
    346362}
    347363
Note: See TracChangeset for help on using the changeset viewer.