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

Changeset 196845 in webkit


Ignore:
Timestamp:
Feb 19, 2016, 4:03:56 PM (11 years ago)
Author:
ggaren@apple.com
Message:

bmalloc: Remove the concept of medium objects
​https://bugs.webkit.org/show_bug.cgi?id=154436

Reviewed by Sam Weinig.

There's no need to distinguish medium objects from small: Small object
metadata works naturally for both as long as we allow an object to
span more than two small lines. (We already allow an object to span
more than one small line.)

This change reduces memory use because it eliminates the 1kB line size,
so we don't have to hold down 1kB lines for individual 264+ byte objects.

1kB lines were always a bit of a compromise. The main point of bump
allocation is to take advantage of cache lines. Cache lines are usually
64 bytes, so line sizes above 256 bytes are a bit of a stretch.

This change speeds up small object benchmarks because it eliminates the
branch to detect medium objects in deallocation log processing.

This change reduces virtual memory use from worst cast 4X to worst case
2X because the medium chunk is gone. iOS cares about virtual memory use
and terminates apps above ~1GB, so this change gives us more breathing room.

This change slows down medium benchmarks a bit because we end up doing
more work to recycle fragmented medium objects. Overall, the tradeoff
seems justified, since we have a net speedup and a memory use savings.

  • bmalloc.xcodeproj/project.pbxproj: Removed all the medium files. We

can simplify even further in a follow-up patch, removing the base class
templates for Chunk, Page, and Line as well.

  • bmalloc/Allocator.cpp:

(bmalloc::Allocator::Allocator):
(bmalloc::Allocator::allocate):
(bmalloc::Allocator::reallocate):
(bmalloc::Allocator::scavenge):
(bmalloc::Allocator::refillAllocatorSlowCase):
(bmalloc::Allocator::refillAllocator):
(bmalloc::Allocator::allocateSlowCase): Medium is gone. Small max is the
new medium max.

  • bmalloc/Allocator.h:

(bmalloc::Allocator::allocateFastCase): Ditto.

  • bmalloc/BumpAllocator.h:

(bmalloc::BumpAllocator::validate):
(bmalloc::BumpAllocator::allocate): No more medium.

  • bmalloc/Chunk.h: No more medium.
  • bmalloc/Deallocator.cpp:

(bmalloc::Deallocator::processObjectLog): No check for medium. This is
a speedup.

(bmalloc::Deallocator::deallocateSlowCase): No more medium.

  • bmalloc/Deallocator.h:

(bmalloc::Deallocator::deallocateFastCase): Ditto.

  • bmalloc/Heap.cpp:

(bmalloc::Heap::initializeLineMetadata): The algorithm here changed from
iterating each line to iterating each object. This helps us accomodate
objects that might span more than two lines -- i.e., all objects between
(512 bytes, 1024 bytes].

(bmalloc::Heap::scavenge):
(bmalloc::Heap::scavengeSmallPages):
(bmalloc::Heap::scavengeLargeObjects): Medium is gone.

(bmalloc::Heap::allocateSmallBumpRanges): Allow for lines that allocate
zero objects. This happens when an object spans more than two lines --
the middle lines allocate zero objects.

Also set the "has free lines" bit to false if we consume the last free
line. This needs to be a bit now because not all pages agree on their
maximum refcount anymore, so we need an explicit signal for the transition
from maximum to maximum - 1.

(bmalloc::Heap::allocateSmallPage): This code didn't change; I just removed
the medium code.

(bmalloc::Heap::deallocateSmallLine): Changed the algorithm to check
hasFreeLines. See allocateSmallBumpRanges.

(bmalloc::Heap::scavengeMediumPages): Deleted.
(bmalloc::Heap::allocateMediumBumpRanges): Deleted.
(bmalloc::Heap::allocateMediumPage): Deleted.
(bmalloc::Heap::deallocateMediumLine): Deleted.

  • bmalloc/Heap.h:

(bmalloc::Heap::derefMediumLine): Deleted.

  • bmalloc/LargeChunk.h:

(bmalloc::LargeChunk::get):
(bmalloc::LargeChunk::endTag):

  • bmalloc/Line.h: No more medium.
  • bmalloc/MediumChunk.h: Removed.
  • bmalloc/MediumLine.h: Removed.
  • bmalloc/MediumPage.h: Removed.
  • bmalloc/MediumTraits.h: Removed.
  • bmalloc/ObjectType.cpp:

(bmalloc::objectType):

  • bmalloc/ObjectType.h:

(bmalloc::isSmall):
(bmalloc::isXLarge):
(bmalloc::isSmallOrMedium): Deleted.
(bmalloc::isMedium): Deleted. No more medium.

  • bmalloc/Page.h:

(bmalloc::Page::sizeClass):
(bmalloc::Page::setSizeClass):
(bmalloc::Page::hasFreeLines):
(bmalloc::Page::setHasFreeLines): Add the free lines bit. You get better
codegen if you make it the low bit, since ref / deref can then add / sub

  1. So do that.
  • bmalloc/Sizes.h:

(bmalloc::Sizes::sizeClass): Expand the small size class to include the
medium size class.

  • bmalloc/SuperChunk.h:

(bmalloc::SuperChunk::SuperChunk):
(bmalloc::SuperChunk::smallChunk):
(bmalloc::SuperChunk::largeChunk):
(bmalloc::SuperChunk::mediumChunk): Deleted. No more medium.

  • bmalloc/VMHeap.cpp:

(bmalloc::VMHeap::grow):

  • bmalloc/VMHeap.h:

(bmalloc::VMHeap::allocateSmallPage): Set the has free lines bit before
returning a Page to the Heap since this is the correct default state
when we first allocate a page.

(bmalloc::VMHeap::allocateMediumPage): Deleted.
(bmalloc::VMHeap::deallocateMediumPage): Deleted.

Location:
trunk/Source/bmalloc
Files:
4 deleted
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/bmalloc/ChangeLog

    r196840 r196845  
     12016-02-18  Geoffrey Garen  <ggaren@apple.com>
     2
     3        bmalloc: Remove the concept of medium objects
     4        https://bugs.webkit.org/show_bug.cgi?id=154436
     5
     6        Reviewed by Sam Weinig.
     7
     8        There's no need to distinguish medium objects from small: Small object
     9        metadata works naturally for both as long as we allow an object to
     10        span more than two small lines. (We already allow an object to span
     11        more than one small line.)
     12
     13        This change reduces memory use because it eliminates the 1kB line size,
     14        so we don't have to hold down 1kB lines for individual 264+ byte objects.
     15
     16        1kB lines were always a bit of a compromise. The main point of bump
     17        allocation is to take advantage of cache lines. Cache lines are usually
     18        64 bytes, so line sizes above 256 bytes are a bit of a stretch.
     19
     20        This change speeds up small object benchmarks because it eliminates the
     21        branch to detect medium objects in deallocation log processing.
     22
     23        This change reduces virtual memory use from worst cast 4X to worst case
     24        2X because the medium chunk is gone. iOS cares about virtual memory use
     25        and terminates apps above ~1GB, so this change gives us more breathing room.
     26
     27        This change slows down medium benchmarks a bit because we end up doing
     28        more work to recycle fragmented medium objects. Overall, the tradeoff
     29        seems justified, since we have a net speedup and a memory use savings.
     30
     31        * bmalloc.xcodeproj/project.pbxproj: Removed all the medium files. We
     32        can simplify even further in a follow-up patch, removing the base class
     33        templates for Chunk, Page, and Line as well.
     34
     35        * bmalloc/Allocator.cpp:
     36        (bmalloc::Allocator::Allocator):
     37        (bmalloc::Allocator::allocate):
     38        (bmalloc::Allocator::reallocate):
     39        (bmalloc::Allocator::scavenge):
     40        (bmalloc::Allocator::refillAllocatorSlowCase):
     41        (bmalloc::Allocator::refillAllocator):
     42        (bmalloc::Allocator::allocateSlowCase): Medium is gone. Small max is the
     43        new medium max.
     44
     45        * bmalloc/Allocator.h:
     46        (bmalloc::Allocator::allocateFastCase): Ditto.
     47
     48        * bmalloc/BumpAllocator.h:
     49        (bmalloc::BumpAllocator::validate):
     50        (bmalloc::BumpAllocator::allocate): No more medium.
     51
     52        * bmalloc/Chunk.h: No more medium.
     53
     54        * bmalloc/Deallocator.cpp:
     55        (bmalloc::Deallocator::processObjectLog): No check for medium. This is
     56        a speedup.
     57
     58        (bmalloc::Deallocator::deallocateSlowCase): No more medium.
     59
     60        * bmalloc/Deallocator.h:
     61        (bmalloc::Deallocator::deallocateFastCase): Ditto.
     62
     63        * bmalloc/Heap.cpp:
     64        (bmalloc::Heap::initializeLineMetadata): The algorithm here changed from
     65        iterating each line to iterating each object. This helps us accomodate
     66        objects that might span more than two lines -- i.e., all objects between
     67        (512 bytes, 1024 bytes].
     68
     69        (bmalloc::Heap::scavenge):
     70        (bmalloc::Heap::scavengeSmallPages):
     71        (bmalloc::Heap::scavengeLargeObjects): Medium is gone.
     72
     73        (bmalloc::Heap::allocateSmallBumpRanges): Allow for lines that allocate
     74        zero objects. This happens when an object spans more than two lines --
     75        the middle lines allocate zero objects.
     76
     77        Also set the "has free lines" bit to false if we consume the last free
     78        line. This needs to be a bit now because not all pages agree on their
     79        maximum refcount anymore, so we need an explicit signal for the transition
     80        from maximum to maximum - 1.
     81
     82        (bmalloc::Heap::allocateSmallPage): This code didn't change; I just removed
     83        the medium code.
     84
     85        (bmalloc::Heap::deallocateSmallLine): Changed the algorithm to check
     86        hasFreeLines. See allocateSmallBumpRanges.
     87
     88        (bmalloc::Heap::scavengeMediumPages): Deleted.
     89        (bmalloc::Heap::allocateMediumBumpRanges): Deleted.
     90        (bmalloc::Heap::allocateMediumPage): Deleted.
     91        (bmalloc::Heap::deallocateMediumLine): Deleted.
     92        * bmalloc/Heap.h:
     93        (bmalloc::Heap::derefMediumLine): Deleted.
     94
     95        * bmalloc/LargeChunk.h:
     96        (bmalloc::LargeChunk::get):
     97        (bmalloc::LargeChunk::endTag):
     98        * bmalloc/Line.h: No more medium.
     99
     100        * bmalloc/MediumChunk.h: Removed.
     101        * bmalloc/MediumLine.h: Removed.
     102        * bmalloc/MediumPage.h: Removed.
     103        * bmalloc/MediumTraits.h: Removed.
     104
     105        * bmalloc/ObjectType.cpp:
     106        (bmalloc::objectType):
     107        * bmalloc/ObjectType.h:
     108        (bmalloc::isSmall):
     109        (bmalloc::isXLarge):
     110        (bmalloc::isSmallOrMedium): Deleted.
     111        (bmalloc::isMedium): Deleted. No more medium.
     112
     113        * bmalloc/Page.h:
     114        (bmalloc::Page::sizeClass):
     115        (bmalloc::Page::setSizeClass):
     116        (bmalloc::Page::hasFreeLines):
     117        (bmalloc::Page::setHasFreeLines): Add the free lines bit. You get better
     118        codegen if you make it the low bit, since ref / deref can then add / sub
     119        2. So do that.
     120
     121        * bmalloc/Sizes.h:
     122        (bmalloc::Sizes::sizeClass): Expand the small size class to include the
     123        medium size class.
     124
     125        * bmalloc/SuperChunk.h:
     126        (bmalloc::SuperChunk::SuperChunk):
     127        (bmalloc::SuperChunk::smallChunk):
     128        (bmalloc::SuperChunk::largeChunk):
     129        (bmalloc::SuperChunk::mediumChunk): Deleted. No more medium.
     130
     131        * bmalloc/VMHeap.cpp:
     132        (bmalloc::VMHeap::grow):
     133        * bmalloc/VMHeap.h:
     134        (bmalloc::VMHeap::allocateSmallPage): Set the has free lines bit before
     135        returning a Page to the Heap since this is the correct default state
     136        when we first allocate a page.
     137
     138        (bmalloc::VMHeap::allocateMediumPage): Deleted.
     139        (bmalloc::VMHeap::deallocateMediumPage): Deleted.
     140
    11412016-02-19  Michael Saboff  <msaboff@apple.com>
    2142
  • trunk/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj

    r196840 r196845  
    4040                14DD78B418F48D6B00950702 /* Chunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 147AAA9418CE5CA6002201E4 /* Chunk.h */; settings = {ATTRIBUTES = (Private, ); }; };
    4141                14DD78B518F48D6B00950702 /* Line.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA32071885F9E6007269E0 /* Line.h */; settings = {ATTRIBUTES = (Private, ); }; };
    42                 14DD78B618F48D6B00950702 /* MediumChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 147AAA8E18CD89E3002201E4 /* MediumChunk.h */; settings = {ATTRIBUTES = (Private, ); }; };
    43                 14DD78B718F48D6B00950702 /* MediumLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1452478518BC757C00F80098 /* MediumLine.h */; settings = {ATTRIBUTES = (Private, ); }; };
    44                 14DD78B818F48D6B00950702 /* MediumPage.h in Headers */ = {isa = PBXBuildFile; fileRef = 143E29E918CAE8BE00FE8A0F /* MediumPage.h */; settings = {ATTRIBUTES = (Private, ); }; };
    45                 14DD78B918F48D6B00950702 /* MediumTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 147AAA9618CE5FB6002201E4 /* MediumTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
    4642                14DD78BA18F48D6B00950702 /* Page.h in Headers */ = {isa = PBXBuildFile; fileRef = 146BEE2318C980D60002D5A2 /* Page.h */; settings = {ATTRIBUTES = (Private, ); }; };
    4743                14DD78BB18F48D6B00950702 /* SmallChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 147AAA8C18CD36A7002201E4 /* SmallChunk.h */; settings = {ATTRIBUTES = (Private, ); }; };
    … …  
    9490                143CB81A19022BC900B16A45 /* StaticMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StaticMutex.cpp; path = bmalloc/StaticMutex.cpp; sourceTree = "<group>"; };
    9591                143CB81B19022BC900B16A45 /* StaticMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StaticMutex.h; path = bmalloc/StaticMutex.h; sourceTree = "<group>"; };
    96                 143E29E918CAE8BE00FE8A0F /* MediumPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediumPage.h; path = bmalloc/MediumPage.h; sourceTree = "<group>"; };
    9792                143E29ED18CAE90500FE8A0F /* SmallPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SmallPage.h; path = bmalloc/SmallPage.h; sourceTree = "<group>"; };
    9893                143EF9AD1A9FABF6004F5C77 /* FreeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FreeList.cpp; path = bmalloc/FreeList.cpp; sourceTree = "<group>"; };
    … …  
    110105                144F7BFB18BFC517003537F3 /* VMHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VMHeap.cpp; path = bmalloc/VMHeap.cpp; sourceTree = "<group>"; };
    111106                144F7BFC18BFC517003537F3 /* VMHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VMHeap.h; path = bmalloc/VMHeap.h; sourceTree = "<group>"; };
    112                 1452478518BC757C00F80098 /* MediumLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediumLine.h; path = bmalloc/MediumLine.h; sourceTree = "<group>"; };
    113107                1452478618BC757C00F80098 /* SmallLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SmallLine.h; path = bmalloc/SmallLine.h; sourceTree = "<group>"; };
    114108                145F6855179DC8CA00D65598 /* Allocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Allocator.cpp; path = bmalloc/Allocator.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
    … …  
    125119                147AAA8818CD17CE002201E4 /* LargeChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LargeChunk.h; path = bmalloc/LargeChunk.h; sourceTree = "<group>"; };
    126120                147AAA8C18CD36A7002201E4 /* SmallChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SmallChunk.h; path = bmalloc/SmallChunk.h; sourceTree = "<group>"; };
    127                 147AAA8E18CD89E3002201E4 /* MediumChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediumChunk.h; path = bmalloc/MediumChunk.h; sourceTree = "<group>"; };
    128121                147AAA9418CE5CA6002201E4 /* Chunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Chunk.h; path = bmalloc/Chunk.h; sourceTree = "<group>"; };
    129                 147AAA9618CE5FB6002201E4 /* MediumTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediumTraits.h; path = bmalloc/MediumTraits.h; sourceTree = "<group>"; };
    130122                147AAA9718CE5FB6002201E4 /* SmallTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SmallTraits.h; path = bmalloc/SmallTraits.h; sourceTree = "<group>"; };
    131123                1485655E18A43AF900ED6942 /* BoundaryTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BoundaryTag.h; path = bmalloc/BoundaryTag.h; sourceTree = "<group>"; };
    … …  
    181173                                1448C2FD18F3752B00502839 /* api */,
    182174                                14D9DB4D17F2865C00EAAB79 /* cache */,
    183                                 147AAA9C18CE6010002201E4 /* heap: large | xlarge */,
     175                                147AAA9C18CE6010002201E4 /* heap: large */,
    184176                                147AAA9A18CE5FD3002201E4 /* heap: small | medium */,
    185177                                14D9DB4E17F2866E00EAAB79 /* heap */,
    … …  
    204196                                147AAA9418CE5CA6002201E4 /* Chunk.h */,
    205197                                14DA32071885F9E6007269E0 /* Line.h */,
    206                                 147AAA8E18CD89E3002201E4 /* MediumChunk.h */,
    207                                 1452478518BC757C00F80098 /* MediumLine.h */,
    208                                 143E29E918CAE8BE00FE8A0F /* MediumPage.h */,
    209                                 147AAA9618CE5FB6002201E4 /* MediumTraits.h */,
    210198                                146BEE2318C980D60002D5A2 /* Page.h */,
    211199                                147AAA8C18CD36A7002201E4 /* SmallChunk.h */,
    … …  
    217205                        sourceTree = "<group>";
    218206                };
    219                 147AAA9C18CE6010002201E4 /* heap: large | xlarge */ = {
     207                147AAA9C18CE6010002201E4 /* heap: large */ = {
    220208                        isa = PBXGroup;
    221209                        children = (
    … …  
    231219                                14D2CD9A1AA12CFB00770440 /* VMState.h */,
    232220                        );
    233                         name = "heap: large | xlarge";
     221                        name = "heap: large";
    234222                        sourceTree = "<group>";
    235223                };
    … …  
    327315                                14DD78CA18F48D7500950702 /* Mutex.h in Headers */,
    328316                                143CB81D19022BC900B16A45 /* StaticMutex.h in Headers */,
    329                                 14DD78B918F48D6B00950702 /* MediumTraits.h in Headers */,
    330317                                1448C30118F3754C00502839 /* bmalloc.h in Headers */,
    331318                                14C6216F1A9A9A6200E72293 /* LargeObject.h in Headers */,
    … …  
    350337                                1400274A18F89C2300115C97 /* VMHeap.h in Headers */,
    351338                                1400274918F89C1300115C97 /* Heap.h in Headers */,
    352                                 14DD78B818F48D6B00950702 /* MediumPage.h in Headers */,
    353339                                140FA00319CE429C00FFD3C8 /* BumpRange.h in Headers */,
    354340                                14DD78C518F48D7500950702 /* Algorithm.h in Headers */,
    … …  
    356342                                14DD788E18F48CCD00950702 /* BoundaryTag.h in Headers */,
    357343                                14DD78C818F48D7500950702 /* FixedVector.h in Headers */,
    358                                 14DD78B718F48D6B00950702 /* MediumLine.h in Headers */,
    359344                                14D2CD9B1AA12CFB00770440 /* VMState.h in Headers */,
    360                                 14DD78B618F48D6B00950702 /* MediumChunk.h in Headers */,
    361345                                14DD78BC18F48D6B00950702 /* SmallLine.h in Headers */,
    362346                                14DD789818F48D4A00950702 /* Allocator.h in Headers */,
  • trunk/Source/bmalloc/bmalloc/Allocator.cpp

    r193373 r196845  
    4343    , m_deallocator(deallocator)
    4444{
    45     for (unsigned short size = alignment; size <= mediumMax; size += alignment)
     45    for (unsigned short size = alignment; size <= smallMax; size += alignment)
    4646        m_bumpAllocators[sizeClass(size)].init(size);
    4747}
    … …  
    8888    }
    8989
    90     if (size <= mediumMax && alignment <= mediumLineSize) {
    91         size = std::max(size, smallMax + Sizes::alignment);
    92         size_t alignmentMask = alignment - 1;
    93         while (void* p = allocate(size)) {
    94             if (!test(p, alignmentMask))
    95                 return p;
    96             m_deallocator.deallocate(p);
    97         }
    98     }
    99 
    10090    if (size <= largeMax && alignment <= largeMax) {
    10191        size = std::max(largeMin, roundUpToMultipleOf<largeAlignment>(size));
    … …  
    131121        break;
    132122    }
    133     case Medium: {
    134         MediumPage* page = MediumPage::get(MediumLine::get(object));
    135         oldSize = objectSize(page->sizeClass());
    136         break;
    137     }
    138123    case Large: {
    139124        std::unique_lock<StaticMutex> lock(PerProcess<Heap>::mutex());
    … …  
    141126        oldSize = largeObject.size();
    142127
    143         if (newSize < oldSize && newSize > mediumMax) {
     128        if (newSize < oldSize && newSize > smallMax) {
    144129            newSize = roundUpToMultipleOf<largeAlignment>(newSize);
    145130            if (oldSize - newSize >= largeMin) {
    … …  
    203188void Allocator::scavenge()
    204189{
    205     for (unsigned short i = alignment; i <= mediumMax; i += alignment) {
     190    for (unsigned short i = alignment; i <= smallMax; i += alignment) {
    206191        BumpAllocator& allocator = m_bumpAllocators[sizeClass(i)];
    207192        BumpRangeCache& bumpRangeCache = m_bumpRangeCaches[sizeClass(i)];
    … …  
    225210
    226211    std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
    227     if (sizeClass <= bmalloc::sizeClass(smallMax))
    228         PerProcess<Heap>::getFastCase()->allocateSmallBumpRanges(lock, sizeClass, allocator, bumpRangeCache);
    229     else
    230         PerProcess<Heap>::getFastCase()->allocateMediumBumpRanges(lock, sizeClass, allocator, bumpRangeCache);
     212    PerProcess<Heap>::getFastCase()->allocateSmallBumpRanges(lock, sizeClass, allocator, bumpRangeCache);
    231213}
    232214
    … …  
    258240        return malloc(size);
    259241
    260     if (size <= mediumMax) {
     242    if (size <= smallMax) {
    261243        size_t sizeClass = bmalloc::sizeClass(size);
    262244        BumpAllocator& allocator = m_bumpAllocators[sizeClass];
  • trunk/Source/bmalloc/bmalloc/Allocator.h

    r191196 r196845  
    5353    void* allocateSlowCase(size_t);
    5454   
    55     void* allocateMedium(size_t);
    5655    void* allocateLarge(size_t);
    5756    void* allocateXLarge(size_t);
    … …  
    6059    void refillAllocatorSlowCase(BumpAllocator&, size_t sizeClass);
    6160   
    62     std::array<BumpAllocator, mediumMax / alignment> m_bumpAllocators;
    63     std::array<BumpRangeCache, mediumMax / alignment> m_bumpRangeCaches;
     61    std::array<BumpAllocator, smallMax / alignment> m_bumpAllocators;
     62    std::array<BumpRangeCache, smallMax / alignment> m_bumpRangeCaches;
    6463
    6564    bool m_isBmallocEnabled;
    … …  
    6968inline bool Allocator::allocateFastCase(size_t size, void*& object)
    7069{
    71     if (size > mediumMax)
     70    if (size > smallMax)
    7271        return false;
    7372
  • trunk/Source/bmalloc/bmalloc/BumpAllocator.h

    r173881 r196845  
    3333namespace bmalloc {
    3434
    35 // Helper object for allocating small and medium objects.
     35// Helper object for allocating small objects.
    3636
    3737class BumpAllocator {
    … …  
    8080    }
    8181   
    82     BASSERT(m_size <= mediumMax);
    83     BASSERT(isMedium(ptr));
     82    BASSERT(m_size <= smallMax);
     83    BASSERT(isSmall(ptr));
    8484}
    8585
  • trunk/Source/bmalloc/bmalloc/Chunk.h

    r180037 r196845  
    7878inline auto Chunk<Traits>::get(void* object) -> Chunk*
    7979{
    80     BASSERT(isSmallOrMedium(object));
     80    BASSERT(isSmall(object));
    8181    return static_cast<Chunk*>(mask(object, chunkMask));
    8282}
  • trunk/Source/bmalloc/bmalloc/Deallocator.cpp

    r191002 r196845  
    7878   
    7979    for (auto* object : m_objectLog) {
    80         if (isSmall(object)) {
    81             SmallLine* line = SmallLine::get(object);
    82             heap->derefSmallLine(lock, line);
    83         } else {
    84             BASSERT(isMedium(object));
    85             MediumLine* line = MediumLine::get(object);
    86             heap->derefMediumLine(lock, line);
    87         }
     80        SmallLine* line = SmallLine::get(object);
     81        heap->derefSmallLine(lock, line);
    8882    }
    8983   
    … …  
    10498        return;
    10599
    106     if (isSmallOrMedium(object)) {
     100    if (isSmall(object)) {
    107101        processObjectLog();
    108102        m_objectLog.push(object);
  • trunk/Source/bmalloc/bmalloc/Deallocator.h

    r177181 r196845  
    5757inline bool Deallocator::deallocateFastCase(void* object)
    5858{
    59     if (!isSmallOrMedium(object))
     59    if (!isSmall(object))
    6060        return false;
    6161
  • trunk/Source/bmalloc/bmalloc/Heap.cpp

    r196840 r196845  
    2929#include "LargeObject.h"
    3030#include "Line.h"
    31 #include "MediumChunk.h"
    3231#include "Page.h"
    3332#include "PerProcess.h"
    … …  
    4746void Heap::initializeLineMetadata()
    4847{
    49     for (unsigned short size = alignment; size <= smallMax; size += alignment) {
    50         unsigned short startOffset = 0;
    51         for (size_t lineNumber = 0; lineNumber < SmallPage::lineCount - 1; ++lineNumber) {
    52             unsigned short objectCount;
    53             unsigned short remainder;
    54             divideRoundingUp(static_cast<unsigned short>(SmallPage::lineSize - startOffset), size, objectCount, remainder);
    55             BASSERT(objectCount);
    56             m_smallLineMetadata[sizeClass(size)][lineNumber] = { startOffset, objectCount };
    57             startOffset = remainder ? size - remainder : 0;
     48    // We assume that m_smallLineMetadata is zero-filled.
     49
     50    for (size_t size = alignment; size <= smallMax; size += alignment) {
     51        size_t sizeClass = bmalloc::sizeClass(size);
     52        auto& metadata = m_smallLineMetadata[sizeClass];
     53
     54        size_t object = 0;
     55        size_t line = 0;
     56        while (object < vmPageSize) {
     57            line = object / SmallPage::lineSize;
     58            size_t leftover = object % SmallPage::lineSize;
     59
     60            size_t objectCount;
     61            size_t remainder;
     62            divideRoundingUp(SmallPage::lineSize - leftover, size, objectCount, remainder);
     63
     64            metadata[line] = { static_cast<unsigned short>(leftover), static_cast<unsigned short>(objectCount) };
     65
     66            object += objectCount * size;
    5867        }
    5968
    60         // The last line in the page rounds down instead of up because it's not allowed to overlap into its neighbor.
    61         unsigned short objectCount = static_cast<unsigned short>((SmallPage::lineSize - startOffset) / size);
    62         m_smallLineMetadata[sizeClass(size)][SmallPage::lineCount - 1] = { startOffset, objectCount };
    63     }
    64 
    65     for (unsigned short size = smallMax + alignment; size <= mediumMax; size += alignment) {
    66         unsigned short startOffset = 0;
    67         for (size_t lineNumber = 0; lineNumber < MediumPage::lineCount - 1; ++lineNumber) {
    68             unsigned short objectCount;
    69             unsigned short remainder;
    70             divideRoundingUp(static_cast<unsigned short>(MediumPage::lineSize - startOffset), size, objectCount, remainder);
    71             BASSERT(objectCount);
    72             m_mediumLineMetadata[sizeClass(size)][lineNumber] = { startOffset, objectCount };
    73             startOffset = remainder ? size - remainder : 0;
     69        // Don't allow the last object in a page to escape the page.
     70        if (object > vmPageSize) {
     71            BASSERT(metadata[line].objectCount);
     72            --metadata[line].objectCount;
    7473        }
    75 
    76         // The last line in the page rounds down instead of up because it's not allowed to overlap into its neighbor.
    77         unsigned short objectCount = static_cast<unsigned short>((MediumPage::lineSize - startOffset) / size);
    78         m_mediumLineMetadata[sizeClass(size)][MediumPage::lineCount - 1] = { startOffset, objectCount };
    7974    }
    8075}
    … …  
    9186
    9287    scavengeSmallPages(lock, sleepDuration);
    93     scavengeMediumPages(lock, sleepDuration);
    9488    scavengeLargeObjects(lock, sleepDuration);
    9589
    … …  
    10599}
    106100
    107 void Heap::scavengeMediumPages(std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds sleepDuration)
    108 {
    109     while (m_mediumPages.size()) {
    110         m_vmHeap.deallocateMediumPage(lock, m_mediumPages.pop());
    111         waitUntilFalse(lock, sleepDuration, m_isAllocatingPages);
    112     }
    113 }
    114 
    115101void Heap::scavengeLargeObjects(std::unique_lock<StaticMutex>& lock, std::chrono::milliseconds sleepDuration)
    116102{
    … …  
    126112    SmallPage* page = allocateSmallPage(lock, sizeClass);
    127113    SmallLine* lines = page->begin();
    128 
    129     // Due to overlap from the previous line, the last line in the page may not be able to fit any objects.
    130     size_t end = SmallPage::lineCount;
    131     if (!m_smallLineMetadata[sizeClass][SmallPage::lineCount - 1].objectCount)
    132         --end;
     114    BASSERT(page->hasFreeLines(lock));
    133115
    134116    // Find a free line.
    135     for (size_t lineNumber = 0; lineNumber < end; ++lineNumber) {
     117    for (size_t lineNumber = 0; lineNumber < SmallPage::lineCount; ++lineNumber) {
    136118        if (lines[lineNumber].refCount(lock))
     119            continue;
     120
     121        LineMetadata& lineMetadata = m_smallLineMetadata[sizeClass][lineNumber];
     122        if (!lineMetadata.objectCount)
    137123            continue;
    138124
    … …  
    143129        }
    144130
    145         LineMetadata& lineMetadata = m_smallLineMetadata[sizeClass][lineNumber];
    146131        char* begin = lines[lineNumber].begin() + lineMetadata.startOffset;
    147132        unsigned short objectCount = lineMetadata.objectCount;
    … …  
    150135
    151136        // Merge with subsequent free lines.
    152         while (++lineNumber < end) {
     137        while (++lineNumber < SmallPage::lineCount) {
    153138            if (lines[lineNumber].refCount(lock))
    154139                break;
    155140
    156141            LineMetadata& lineMetadata = m_smallLineMetadata[sizeClass][lineNumber];
     142            if (!lineMetadata.objectCount)
     143                continue;
     144
    157145            objectCount += lineMetadata.objectCount;
    158146            lines[lineNumber].ref(lock, lineMetadata.objectCount);
    … …  
    165153            rangeCache.push({ begin, objectCount });
    166154    }
    167 }
    168 
    169 void Heap::allocateMediumBumpRanges(std::lock_guard<StaticMutex>& lock, size_t sizeClass, BumpAllocator& allocator, BumpRangeCache& rangeCache)
    170 {
    171     MediumPage* page = allocateMediumPage(lock, sizeClass);
    172     BASSERT(!rangeCache.size());
    173     MediumLine* lines = page->begin();
    174 
    175     // Due to overlap from the previous line, the last line in the page may not be able to fit any objects.
    176     size_t end = MediumPage::lineCount;
    177     if (!m_mediumLineMetadata[sizeClass][MediumPage::lineCount - 1].objectCount)
    178         --end;
    179 
    180     // Find a free line.
    181     for (size_t lineNumber = 0; lineNumber < end; ++lineNumber) {
    182         if (lines[lineNumber].refCount(lock))
    183             continue;
    184 
    185         // In a fragmented page, some free ranges might not fit in the cache.
    186         if (rangeCache.size() == rangeCache.capacity()) {
    187             m_mediumPagesWithFreeLines[sizeClass].push(page);
    188             return;
    189         }
    190 
    191         LineMetadata& lineMetadata = m_mediumLineMetadata[sizeClass][lineNumber];
    192         char* begin = lines[lineNumber].begin() + lineMetadata.startOffset;
    193         unsigned short objectCount = lineMetadata.objectCount;
    194         lines[lineNumber].ref(lock, lineMetadata.objectCount);
    195         page->ref(lock);
    196        
    197         // Merge with subsequent free lines.
    198         while (++lineNumber < end) {
    199             if (lines[lineNumber].refCount(lock))
    200                 break;
    201 
    202             LineMetadata& lineMetadata = m_mediumLineMetadata[sizeClass][lineNumber];
    203             objectCount += lineMetadata.objectCount;
    204             lines[lineNumber].ref(lock, lineMetadata.objectCount);
    205             page->ref(lock);
    206         }
    207 
    208         if (!allocator.canAllocate())
    209             allocator.refill({ begin, objectCount });
    210         else
    211             rangeCache.push({ begin, objectCount });
    212     }
     155
     156    page->setHasFreeLines(lock, false);
    213157}
    214158
    … …  
    223167    }
    224168
    225     SmallPage* page = [this, sizeClass]() {
     169    SmallPage* page = [this, &lock]() {
    226170        if (m_smallPages.size())
    227171            return m_smallPages.pop();
    228172
    229173        m_isAllocatingPages = true;
    230         return m_vmHeap.allocateSmallPage();
     174        SmallPage* page = m_vmHeap.allocateSmallPage(lock);
     175        return page;
    231176    }();
    232177
    … …  
    235180}
    236181
    237 MediumPage* Heap::allocateMediumPage(std::lock_guard<StaticMutex>& lock, size_t sizeClass)
    238 {
    239     Vector<MediumPage*>& mediumPagesWithFreeLines = m_mediumPagesWithFreeLines[sizeClass];
    240     while (mediumPagesWithFreeLines.size()) {
    241         MediumPage* page = mediumPagesWithFreeLines.pop();
    242         if (!page->refCount(lock) || page->sizeClass() != sizeClass) // Page was promoted to the pages list.
    243             continue;
    244         return page;
    245     }
    246 
    247     MediumPage* page = [this, sizeClass]() {
    248         if (m_mediumPages.size())
    249             return m_mediumPages.pop();
    250 
    251         m_isAllocatingPages = true;
    252         return m_vmHeap.allocateMediumPage();
    253     }();
    254 
    255     page->setSizeClass(sizeClass);
    256     return page;
    257 }
    258 
    259182void Heap::deallocateSmallLine(std::lock_guard<StaticMutex>& lock, SmallLine* line)
    260183{
    261184    BASSERT(!line->refCount(lock));
    262185    SmallPage* page = SmallPage::get(line);
    263     size_t refCount = page->refCount(lock);
    264186    page->deref(lock);
    265187
    266     switch (refCount) {
    267     case SmallPage::lineCount: {
    268         // First free line in the page.
     188    if (!page->hasFreeLines(lock)) {
     189        page->setHasFreeLines(lock, true);
    269190        m_smallPagesWithFreeLines[page->sizeClass()].push(page);
    270         break;
    271     }
    272     case 1: {
    273         // Last free line in the page.
    274         m_smallPages.push(page);
    275         m_scavenger.run();
    276         break;
    277     }
    278     }
    279 }
    280 
    281 void Heap::deallocateMediumLine(std::lock_guard<StaticMutex>& lock, MediumLine* line)
    282 {
    283     BASSERT(!line->refCount(lock));
    284     MediumPage* page = MediumPage::get(line);
    285     size_t refCount = page->refCount(lock);
    286     page->deref(lock);
    287 
    288     switch (refCount) {
    289     case MediumPage::lineCount: {
    290         // First free line in the page.
    291         m_mediumPagesWithFreeLines[page->sizeClass()].push(page);
    292         break;
    293     }
    294     case 1: {
    295         // Last free line in the page.
    296         m_mediumPages.push(page);
    297         m_scavenger.run();
    298         break;
    299     }
    300     }
     191
     192        BASSERT(page->refCount(lock));
     193        return;
     194    }
     195
     196    if (page->refCount(lock))
     197        return;
     198
     199    m_smallPages.push(page);
     200    m_scavenger.run();
    301201}
    302202
  • trunk/Source/bmalloc/bmalloc/Heap.h

    r196840 r196845  
    3030#include "Environment.h"
    3131#include "LineMetadata.h"
    32 #include "MediumChunk.h"
    33 #include "MediumLine.h"
    34 #include "MediumPage.h"
    3532#include "Mutex.h"
    3633#include "SegregatedFreeList.h"
    … …  
    5855    void derefSmallLine(std::lock_guard<StaticMutex>&, SmallLine*);
    5956
    60     void allocateMediumBumpRanges(std::lock_guard<StaticMutex>&, size_t sizeClass, BumpAllocator&, BumpRangeCache&);
    61     void derefMediumLine(std::lock_guard<StaticMutex>&, MediumLine*);
    62 
    6357    void* allocateLarge(std::lock_guard<StaticMutex>&, size_t);
    6458    void* allocateLarge(std::lock_guard<StaticMutex>&, size_t alignment, size_t, size_t unalignedSize);
    … …  
    7973
    8074    SmallPage* allocateSmallPage(std::lock_guard<StaticMutex>&, size_t sizeClass);
    81     MediumPage* allocateMediumPage(std::lock_guard<StaticMutex>&, size_t sizeClass);
    8275
    8376    void deallocateSmallLine(std::lock_guard<StaticMutex>&, SmallLine*);
    84     void deallocateMediumLine(std::lock_guard<StaticMutex>&, MediumLine*);
    85 
    8677    void deallocateLarge(std::lock_guard<StaticMutex>&, const LargeObject&);
    8778
    … …  
    9485    void concurrentScavenge();
    9586    void scavengeSmallPages(std::unique_lock<StaticMutex>&, std::chrono::milliseconds);
    96     void scavengeMediumPages(std::unique_lock<StaticMutex>&, std::chrono::milliseconds);
    9787    void scavengeLargeObjects(std::unique_lock<StaticMutex>&, std::chrono::milliseconds);
    9888
    9989    std::array<std::array<LineMetadata, SmallPage::lineCount>, smallMax / alignment> m_smallLineMetadata;
    100     std::array<std::array<LineMetadata, MediumPage::lineCount>, mediumMax / alignment> m_mediumLineMetadata;
    10190
    10291    std::array<Vector<SmallPage*>, smallMax / alignment> m_smallPagesWithFreeLines;
    103     std::array<Vector<MediumPage*>, mediumMax / alignment> m_mediumPagesWithFreeLines;
    10492
    10593    Vector<SmallPage*> m_smallPages;
    106     Vector<MediumPage*> m_mediumPages;
    10794
    10895    SegregatedFreeList m_largeObjects;
    … …  
    124111}
    125112
    126 inline void Heap::derefMediumLine(std::lock_guard<StaticMutex>& lock, MediumLine* line)
    127 {
    128     if (!line->deref(lock))
    129         return;
    130     deallocateMediumLine(lock, line);
    131 }
    132 
    133113} // namespace bmalloc
    134114
  • trunk/Source/bmalloc/bmalloc/LargeChunk.h

    r196186 r196845  
    8484inline LargeChunk* LargeChunk::get(void* object)
    8585{
    86     BASSERT(!isSmallOrMedium(object));
     86    BASSERT(!isSmall(object));
    8787    return static_cast<LargeChunk*>(mask(object, largeChunkMask));
    8888}
    … …  
    9797inline EndTag* LargeChunk::endTag(void* object, size_t size)
    9898{
    99     BASSERT(!isSmallOrMedium(object));
     99    BASSERT(!isSmall(object));
    100100
    101101    LargeChunk* chunk = get(object);
  • trunk/Source/bmalloc/bmalloc/Line.h

    r179923 r196845  
    6161inline auto Line<Traits>::get(void* object) -> Line*
    6262{
    63     BASSERT(isSmallOrMedium(object));
     63    BASSERT(isSmall(object));
    6464    Chunk* chunk = Chunk::get(object);
    6565    size_t lineNumber = (reinterpret_cast<char*>(object) - reinterpret_cast<char*>(chunk)) / lineSize;
  • trunk/Source/bmalloc/bmalloc/ObjectType.cpp

    r178621 r196845  
    3131ObjectType objectType(void* object)
    3232{
    33     if (isSmallOrMedium(object)) {
    34         if (isSmall(object))
    35             return Small;
    36         return Medium;
    37     }
     33    if (isSmall(object))
     34        return Small;
    3835   
    3936    if (!isXLarge(object))
  • trunk/Source/bmalloc/bmalloc/ObjectType.h

    r178621 r196845  
    3232namespace bmalloc {
    3333
    34 enum ObjectType { Small, Medium, Large, XLarge };
     34enum ObjectType { Small, Large, XLarge };
    3535
    3636ObjectType objectType(void*);
    3737
    38 inline bool isSmallOrMedium(void* object)
     38inline bool isSmall(void* object)
    3939{
    40     return test(object, smallOrMediumTypeMask);
    41 }
    42 
    43 inline bool isSmall(void* smallOrMedium)
    44 {
    45     BASSERT(isSmallOrMedium(smallOrMedium));
    46     return test(smallOrMedium, smallOrMediumSmallTypeMask);
    47 }
    48 
    49 inline bool isMedium(void* smallOrMedium)
    50 {
    51     return !isSmall(smallOrMedium);
     40    return test(object, smallMask);
    5241}
    5342
    5443inline bool isXLarge(void* object)
    5544{
    56     return !test(object, superChunkSize - 1);
     45    return !test(object, ~superChunkMask);
    5746}
    5847
  • trunk/Source/bmalloc/bmalloc/Page.h

    r179923 r196845  
    5555    void setSizeClass(size_t sizeClass) { m_sizeClass = sizeClass; }
    5656   
     57    bool hasFreeLines(std::lock_guard<StaticMutex>&) const { return m_hasFreeLines; }
     58    void setHasFreeLines(std::lock_guard<StaticMutex>&, bool hasFreeLines) { m_hasFreeLines = hasFreeLines; }
     59   
    5760    Line* begin();
    5861    Line* end();
    5962
    6063private:
    61     unsigned char m_refCount;
     64    unsigned char m_hasFreeLines: 1;
     65    unsigned char m_refCount: 7;
    6266    unsigned char m_sizeClass;
    6367};
  • trunk/Source/bmalloc/bmalloc/Sizes.h

    r196186 r196845  
    5555   
    5656    static const size_t superChunkSize = 2 * MB;
     57    static const size_t superChunkMask = ~(superChunkSize - 1);
    5758
    58     static const size_t smallMax = 256;
     59    static const size_t smallMax = 1024;
    5960    static const size_t smallLineSize = 256;
    6061    static const size_t smallLineMask = ~(smallLineSize - 1ul);
    6162
    62     static const size_t smallChunkSize = superChunkSize / 4;
    63     static const size_t smallChunkOffset = superChunkSize * 3 / 4;
     63    static const size_t smallChunkSize = superChunkSize / 2;
     64    static const size_t smallChunkOffset = superChunkSize / 2;
    6465    static const size_t smallChunkMask = ~(smallChunkSize - 1ul);
    65 
    66     static const size_t mediumMax = 1024;
    67     static const size_t mediumLineSize = 1024;
    68     static const size_t mediumLineMask = ~(mediumLineSize - 1ul);
    69 
    70     static const size_t mediumChunkSize = superChunkSize / 4;
    71     static const size_t mediumChunkOffset = superChunkSize * 2 / 4;
    72     static const size_t mediumChunkMask = ~(mediumChunkSize - 1ul);
    7366
    7467    static const size_t largeChunkSize = superChunkSize / 2;
    … …  
    8376    static const size_t largeAlignment = 64;
    8477    static const size_t largeMax = largeChunkSize - largeChunkMetadataSize;
    85     static const size_t largeMin = mediumMax;
     78    static const size_t largeMin = smallMax;
    8679   
    8780    static const size_t xLargeAlignment = vmPageSize;
    … …  
    9184    static const size_t freeListGrowFactor = 2;
    9285
    93     static const uintptr_t typeMask = (superChunkSize - 1) & ~((superChunkSize / 4) - 1); // 4 taggable chunks
    94     static const uintptr_t smallType = (superChunkSize + smallChunkOffset) & typeMask;
    95     static const uintptr_t mediumType = (superChunkSize + mediumChunkOffset) & typeMask;
    96     static const uintptr_t largeTypeMask = ~(mediumType & smallType);
    97     static const uintptr_t smallOrMediumTypeMask = mediumType & smallType;
    98     static const uintptr_t smallOrMediumSmallTypeMask = smallType ^ mediumType; // Only valid if object is known to be small or medium.
     86    static const uintptr_t typeMask = (superChunkSize - 1) & ~((superChunkSize / 2) - 1); // 2 taggable chunks
     87    static const uintptr_t largeMask = typeMask & (superChunkSize + largeChunkOffset);
     88    static const uintptr_t smallMask = typeMask & (superChunkSize + smallChunkOffset);
    9989
    10090    static const size_t deallocatorLogCapacity = 256;
    … …  
    10595    inline size_t sizeClass(size_t size)
    10696    {
    107         static const size_t sizeClassMask = (mediumMax / alignment) - 1;
     97        static const size_t sizeClassMask = (smallMax / alignment) - 1;
    10898        return mask((size - 1) / alignment, sizeClassMask);
    10999    }
  • trunk/Source/bmalloc/bmalloc/SuperChunk.h

    r180272 r196845  
    2828
    2929#include "LargeChunk.h"
    30 #include "MediumChunk.h"
    3130#include "SmallChunk.h"
    3231
    … …  
    3837
    3938    SmallChunk* smallChunk();
    40     MediumChunk* mediumChunk();
    4139    LargeChunk* largeChunk();
    4240
    … …  
    5452{
    5553    new (smallChunk()) SmallChunk;
    56     new (mediumChunk()) MediumChunk;
    5754    new (largeChunk()) LargeChunk;
    5855}
    … …  
    6259    return reinterpret_cast<SmallChunk*>(
    6360        reinterpret_cast<char*>(this) + smallChunkOffset);
    64 }
    65 
    66 inline MediumChunk* SuperChunk::mediumChunk()
    67 {
    68     return reinterpret_cast<MediumChunk*>(
    69         reinterpret_cast<char*>(this) + mediumChunkOffset);
    7061}
    7162
  • trunk/Source/bmalloc/bmalloc/VMHeap.cpp

    r196840 r196845  
    2525
    2626#include "LargeObject.h"
    27 #include "Line.h"
    2827#include "PerProcess.h"
    2928#include "SuperChunk.h"
    … …  
    4948        m_smallPages.push(it);
    5049
    51     MediumChunk* mediumChunk = superChunk->mediumChunk();
    52     for (auto* it = mediumChunk->begin(); it != mediumChunk->end(); ++it)
    53         m_mediumPages.push(it);
    54 
    5550    LargeChunk* largeChunk = superChunk->largeChunk();
    5651    LargeObject result(LargeObject::init(largeChunk).begin());
  • trunk/Source/bmalloc/bmalloc/VMHeap.h

    r196840 r196845  
    3131#include "LargeChunk.h"
    3232#include "LargeObject.h"
    33 #include "MediumChunk.h"
    3433#include "Range.h"
    3534#include "SegregatedFreeList.h"
    … …  
    5251    VMHeap();
    5352
    54     SmallPage* allocateSmallPage();
    55     MediumPage* allocateMediumPage();
     53    SmallPage* allocateSmallPage(std::lock_guard<StaticMutex>&);
    5654    LargeObject allocateLargeObject(size_t);
    5755    LargeObject allocateLargeObject(size_t, size_t, size_t);
    5856
    5957    void deallocateSmallPage(std::unique_lock<StaticMutex>&, SmallPage*);
    60     void deallocateMediumPage(std::unique_lock<StaticMutex>&, MediumPage*);
    6158    void deallocateLargeObject(std::unique_lock<StaticMutex>&, LargeObject);
    6259
    … …  
    6562
    6663    Vector<SmallPage*> m_smallPages;
    67     Vector<MediumPage*> m_mediumPages;
    6864    SegregatedFreeList m_largeObjects;
    6965#if BOS(DARWIN)
    … …  
    7268};
    7369
    74 inline SmallPage* VMHeap::allocateSmallPage()
     70inline SmallPage* VMHeap::allocateSmallPage(std::lock_guard<StaticMutex>& lock)
    7571{
    7672    if (!m_smallPages.size())
    … …  
    7874
    7975    SmallPage* page = m_smallPages.pop();
    80     vmAllocatePhysicalPages(page->begin()->begin(), vmPageSize);
    81     return page;
    82 }
    83 
    84 inline MediumPage* VMHeap::allocateMediumPage()
    85 {
    86     if (!m_mediumPages.size())
    87         grow();
    88 
    89     MediumPage* page = m_mediumPages.pop();
     76    page->setHasFreeLines(lock, true);
    9077    vmAllocatePhysicalPages(page->begin()->begin(), vmPageSize);
    9178    return page;
    … …  
    125112}
    126113
    127 inline void VMHeap::deallocateMediumPage(std::unique_lock<StaticMutex>& lock, MediumPage* page)
    128 {
    129     lock.unlock();
    130     vmDeallocatePhysicalPages(page->begin()->begin(), vmPageSize);
    131     lock.lock();
    132    
    133     m_mediumPages.push(page);
    134 }
    135 
    136114inline void VMHeap::deallocateLargeObject(std::unique_lock<StaticMutex>& lock, LargeObject largeObject)
    137115{
Note: See TracChangeset for help on using the changeset viewer.