Changeset 286516 in webkit


Ignore:
Timestamp:
Dec 3, 2021 2:48:23 PM (2 years ago)
Author:
fpizlo@apple.com
Message:

[libpas] Bitfit allocator has a wrong assertion when a page's max_free is enough for the size of an allocation, not enough for that allocation's size class, and the object of that size is not aligned to the currently requested alignment
https://bugs.webkit.org/show_bug.cgi?id=233831

Reviewed by Yusuke Suzuki.

What a combination of conditions:

  • We just failed bitfit allocation in a page, which gives us some max_free (aka largest_available), and the allocation had nontrivial alignment.
  • The max_free is smaller than the size class.
  • The max_free is larger than the requested size.
  • The max_free object is not aligned to the requested alignment.


The code handles this fine, but has a wrong assertion about it.

This change fixes the assertion and adds a test that deterministically reproduced the issue.

  • libpas/libpas.xcodeproj/project.pbxproj:
  • libpas/src/libpas/pas_bitfit_allocator.c:

(pas_bitfit_allocator_finish_failing):

  • libpas/src/libpas/pas_bitfit_allocator_inlines.h:

(pas_bitfit_allocator_try_allocate):

  • libpas/src/test/BitfitTests.cpp: Added.

(std::getBitfitSizeClasses):
(std::assertSizeClasses):
(std::testAllocateAlignedSmallerThanSizeClassAndSmallerThanLargestAvailable):
(addBitfitTests):

  • libpas/src/test/TestHarness.cpp:

(main):

Location:
trunk/Source/bmalloc
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/bmalloc/ChangeLog

    r286493 r286516  
     12021-12-03  Filip Pizlo  <fpizlo@apple.com>
     2
     3        [libpas] Bitfit allocator has a wrong assertion when a page's max_free is enough for the size of an allocation, not enough for that allocation's size class, and the object of that size is not aligned to the currently requested alignment
     4        https://bugs.webkit.org/show_bug.cgi?id=233831
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        What a combination of conditions:
     9       
     10        - We just failed bitfit allocation in a page, which gives us some max_free (aka largest_available), and the allocation had nontrivial alignment.
     11        - The max_free is smaller than the size class.
     12        - The max_free is larger than the requested size.
     13        - The max_free object is not aligned to the requested alignment.
     14       
     15        The code handles this fine, but has a wrong assertion about it.
     16
     17        This change fixes the assertion and adds a test that deterministically reproduced the issue.
     18
     19        * libpas/libpas.xcodeproj/project.pbxproj:
     20        * libpas/src/libpas/pas_bitfit_allocator.c:
     21        (pas_bitfit_allocator_finish_failing):
     22        * libpas/src/libpas/pas_bitfit_allocator_inlines.h:
     23        (pas_bitfit_allocator_try_allocate):
     24        * libpas/src/test/BitfitTests.cpp: Added.
     25        (std::getBitfitSizeClasses):
     26        (std::assertSizeClasses):
     27        (std::testAllocateAlignedSmallerThanSizeClassAndSmallerThanLargestAvailable):
     28        (addBitfitTests):
     29        * libpas/src/test/TestHarness.cpp:
     30        (main):
     31
    1322021-12-02  Filip Pizlo  <fpizlo@apple.com>
    233
  • trunk/Source/bmalloc/libpas/libpas.xcodeproj/project.pbxproj

    r286493 r286516  
    569569                2C85DC4127128F0F00367905 /* pas_try_allocate_intrinsic.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C85DC4027128F0F00367905 /* pas_try_allocate_intrinsic.h */; };
    570570                2C91E5502718DA9A00D67FF9 /* pas_size_lookup_mode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C91E54F2718DA9A00D67FF9 /* pas_size_lookup_mode.h */; };
     571                2CE2AE35275A953E00D02BBC /* BitfitTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CE2AE34275A953E00D02BBC /* BitfitTests.cpp */; };
    571572/* End PBXBuildFile section */
    572573
     
    12531254                2C85DC4027128F0F00367905 /* pas_try_allocate_intrinsic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pas_try_allocate_intrinsic.h; sourceTree = "<group>"; };
    12541255                2C91E54F2718DA9A00D67FF9 /* pas_size_lookup_mode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pas_size_lookup_mode.h; sourceTree = "<group>"; };
     1256                2CE2AE34275A953E00D02BBC /* BitfitTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitfitTests.cpp; sourceTree = "<group>"; };
    12551257/* End PBXFileReference section */
    12561258
     
    13451347                        children = (
    13461348                                0FDEA45D228B651B0085E340 /* BitfieldVectorTests.cpp */,
     1349                                2CE2AE34275A953E00D02BBC /* BitfitTests.cpp */,
    13471350                                0F53181022C954ED003F7B6A /* BitvectorTests.cpp */,
    13481351                                0F31A66723E8B336002C0CA3 /* CartesianTreeTests.cpp */,
     
    25852588                                0FD48B6723B589910026C46D /* IsoHeapPartialAndBaselineTests.cpp in Sources */,
    25862589                                0F5B6094235E919900CAE629 /* IsoHeapReservedMemoryTests.cpp in Sources */,
     2590                                2CE2AE35275A953E00D02BBC /* BitfitTests.cpp in Sources */,
    25872591                                0F5193E7266AE5D400483A2C /* JITHeapTests.cpp in Sources */,
    25882592                                0FC64191213745FA0040CE5E /* LargeFreeHeapTests.cpp in Sources */,
  • trunk/Source/bmalloc/libpas/src/libpas/pas_bitfit_allocator.c

    r286493 r286516  
    206206                                                     pas_bitfit_page_config* config)
    207207{
     208    static const bool verbose = false;
     209   
    208210    pas_bitfit_directory* directory;
    209211    pas_bitfit_size_class* size_class;
     
    222224
    223225    view_index = view->index;
     226
     227    if (verbose) {
     228        pas_log("Finishing failing in view %p, size = %zu, alignment = %zu, largest_available = %zu\n",
     229                view, size, alignment, largest_available);
     230    }
    224231
    225232    /* If we're still on the view that the allocator was on and we found that this view no longer
     
    243250            directory, index, largest_available >> config->base.min_align_shift,
    244251            "processing on finish_failing");
    245        
    246         PAS_TESTING_ASSERT(largest_available < size);
     252
     253        /* If we're doing an aligned allocation, then we might now skip over this view even though the
     254           size we were allocating would have fit. The reason why we're doing it is that the largest size
     255           we could have fit is smaller than the size class, and although it's big enough for the size being
     256           requested, it's not aligned properly. */
     257        PAS_TESTING_ASSERT(largest_available < size
     258                           || alignment > pas_page_base_config_min_align(config->base));
     259       
    247260        PAS_TESTING_ASSERT(largest_available < size_class->size);
    248261       
  • trunk/Source/bmalloc/libpas/src/libpas/pas_bitfit_allocator_inlines.h

    r286493 r286516  
    8888            allocator->view = view;
    8989        }
     90
     91        if (verbose)
     92            pas_log("Allocating in view %p\n", view);
    9093
    9194        bytes_committed = 0;
     
    179182        if (verbose)
    180183            pas_log("bitfit allocation succeeded with %p\n", (void*)bitfit_result.u.result);
     184
     185        PAS_TESTING_ASSERT(pas_is_aligned(bitfit_result.u.result, alignment));
    181186       
    182187        return pas_fast_path_allocation_result_create_success(bitfit_result.u.result);
  • trunk/Source/bmalloc/libpas/src/test/TestHarness.cpp

    r285789 r286516  
    336336
    337337void addBitfieldVectorTests();
     338void addBitfitTests();
    338339void addBitvectorTests();
    339340void addCartesianTreeTests();
     
    698699    // Run the rest of the tests in alphabetical order.
    699700    ADD_SUITE(BitfieldVector);
     701    ADD_SUITE(Bitfit);
    700702    ADD_SUITE(Bitvector);
    701703    ADD_SUITE(CartesianTree);
Note: See TracChangeset for help on using the changeset viewer.