Skip to content
Permalink
Browse files
Source/WebCore:
Use BumpArena for style sheet object tree.
<https://webkit.org/b/152696>

Reviewed by Antti Koivisto.

Give each StyleSheetContents its own BumpArena, and plumb it down through CSSParser
to allocate StyleRule, StyleProperties and CSSSelectorList's selector arrays there.

This basically means that most objects that make up a given style sheet will end up
in one (or a few) contiguous region(s) of memory, instead of being scattered all
over the malloc heap.

In the common case (no CSSOM manipulation), the lifetimes of these objects are very
predictable: everything tends to die when the StyleSheetContents dies.
This dramatically improves space-efficiency in those cases, and allows us to return
contiguous chunks of memory to the system once a style sheet is no longer needed.

One-off CSS parses that don't work within a StyleSheetContents context will have
their StyleRules & co allocated through FastMalloc just like before.

Bonus: give SelectorQueryCache a dedicated BumpArena as well, since it has very
predictable lifetime.

* css/CSSGrammar.y.in:
* css/CSSKeyframesRule.h:
(WebCore::StyleRuleKeyframes::create):
* css/CSSParser.cpp:
(WebCore::CSSParser::createStyleProperties):
(WebCore::CSSParser::createMediaRule):
(WebCore::CSSParser::createSupportsRule):
(WebCore::CSSParser::createKeyframesRule):
(WebCore::CSSParser::setArena):
(WebCore::CSSParser::arena):
(WebCore::CSSParser::createStyleRule):
(WebCore::CSSParser::createFontFaceRule):
(WebCore::CSSParser::createPageRule):
(WebCore::CSSParser::createRegionRule):
(WebCore::CSSParser::createViewportRule):
* css/CSSParser.h:
* css/CSSParserValues.cpp:
(WebCore::CSSParserSelector::parsePseudoElementCueFunctionSelector):
(WebCore::CSSParserSelector::adoptSelectorVector):
* css/CSSParserValues.h:
* css/CSSSelectorList.cpp:
(WebCore::CSSSelectorList::CSSSelectorList):
(WebCore::CSSSelectorList::adoptSelectorVector):
(WebCore::CSSSelectorList::deleteSelectors):
* css/CSSSelectorList.h:
* css/StyleProperties.cpp:
(WebCore::ImmutableStyleProperties::create):
(WebCore::StyleProperties::immutableCopyIfNeeded):
* css/StyleProperties.h:
* css/StyleRule.cpp:
(WebCore::StyleRule::create):
(WebCore::StyleRule::splitIntoMultipleRulesWithMaximumSelectorComponentCount):
(WebCore::StyleRuleRegion::StyleRuleRegion):
* css/StyleRule.h:
(WebCore::StyleRule::create):
(WebCore::StyleRule::parserAdoptSelectorVector):
(WebCore::StyleRuleFontFace::create):
(WebCore::StyleRulePage::create):
(WebCore::StyleRulePage::parserAdoptSelectorVector):
(WebCore::StyleRuleMedia::create):
(WebCore::StyleRuleSupports::create):
(WebCore::StyleRuleRegion::create):
(WebCore::StyleRuleViewport::create):
* css/StyleSheetContents.cpp:
(WebCore::StyleSheetContents::StyleSheetContents):
(WebCore::StyleSheetContents::parseAuthorStyleSheet):
(WebCore::StyleSheetContents::parseStringAtPosition):
* css/StyleSheetContents.h:
* dom/SelectorQuery.cpp:
(WebCore::SelectorQueryCache::SelectorQueryCache):
(WebCore::SelectorQueryCache::add):
* dom/SelectorQuery.h:
* svg/SVGFontFaceElement.cpp:
(WebCore::SVGFontFaceElement::SVGFontFaceElement):

Source/WTF:
Fragmentation-free allocator for timeless and/or coupled allocations.
<https://webkit.org/b/152696>

Reviewed by Antti Koivisto.

Introduce BumpArena, a space-efficient memory allocator for situations where
you feel pretty confident betting on allocation lifetimes.

Basic design:

    - Reserves 128MB range of memory at startup.
    - Allocates 4kB-aligned blocks of 4kB from VM at a time.
    - Bump-pointer allocates out of a block until it reaches end.
    - Each allocation increments the ref-count of its block.
    - Each deallocation decrements the ref-count of its block.
    - Transparently falls back to fastMalloc()/fastFree() when needed.

Interface:

    - BumpArena::create()

        Create your very own BumpArena!

    - BumpArena::allocate(BumpArena* arena, size_t size)

        Allocates 'size' bytes of memory from 'arena'.
        If 'arena' is null, falls back to fastMalloc().

    - BumpArena::deallocate(void* ptr)

        If 'ptr' is BumpArena allocation, decrements block ref-count.
        If 'ptr' is FastMalloc allocation, calls fastFree() on it.

    - WTF_MAKE_BUMPARENA_ALLOCATED;

        Macro that gives a class or struct custom operators new and delete
        for allocation out of BumpArena. Just like WTF_MAKE_FAST_ALLOCATED;

Note that while the name of this patch says "fragmentation-free allocator"
it will only be fragmentation-free when used for appropriate things.
This is not meant to be a general-purpose allocator. Only use it for sets of
allocations that are known to die roughly at the same time.

BumpArena will never resume allocating from a block that has been filled,
so it's even more important than usual that everything gets deallocated.

BumpArena redirects allocations to FastMalloc in three cases:

    - When invoked with a null BumpArena*
    - When allocation request is larger than BumpArena's block size (4kB)
    - When BumpArena has exhausted all of its pre-reserved VM. (128MB)

The VM allocator will eagerly return blocks of VM to the kernel by calling
madvise(). Average time spent in madvise is around 0.007ms on my box.

* WTF.vcxproj/WTF.vcxproj:
* WTF.vcxproj/WTF.vcxproj.filters:
* WTF.xcodeproj/project.pbxproj:
* wtf/BumpArena.cpp: Added.
(WTF::BumpArena::Block::capacity):
(WTF::BumpArena::Block::arena):
(WTF::BumpArena::Block::payloadStart):
(WTF::arenas):
(WTF::BumpArena::Block::Block):
(WTF::BumpArena::Block::~Block):
(WTF::BumpArena::Block::ref):
(WTF::BlockAllocator::BlockAllocator):
(WTF::BlockAllocator::isAllocation):
(WTF::blockAllocator):
(WTF::BlockAllocator::allocateBlock):
(WTF::BlockAllocator::deallocateBlock):
(WTF::BumpArena::Block::deref):
(WTF::BumpArena::Block::create):
(WTF::BumpArena::Block::dump):
(WTF::BumpArena::dump):
(WTF::BumpArena::create):
(WTF::BumpArena::BumpArena):
(WTF::BumpArena::~BumpArena):
(WTF::BumpArena::allocateSlow):
(WTF::BumpArena::allocate):
(WTF::BumpArena::deallocate):
(WTF::BumpArena::Block::blockFor):
(WTF::BumpArena::arenaFor):
* wtf/BumpArena.h: Added.
* wtf/CMakeLists.txt:


Canonical link: https://commits.webkit.org/171225@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@195141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Andreas Kling committed Jan 15, 2016
1 parent 8dc0cfc commit a2899989d3d389432abceb85ebab4edae905ae5b
@@ -1,3 +1,91 @@
2016-01-15 Andreas Kling <akling@apple.com>

Fragmentation-free allocator for timeless and/or coupled allocations.
<https://webkit.org/b/152696>

Reviewed by Antti Koivisto.

Introduce BumpArena, a space-efficient memory allocator for situations where
you feel pretty confident betting on allocation lifetimes.

Basic design:

- Reserves 128MB range of memory at startup.
- Allocates 4kB-aligned blocks of 4kB from VM at a time.
- Bump-pointer allocates out of a block until it reaches end.
- Each allocation increments the ref-count of its block.
- Each deallocation decrements the ref-count of its block.
- Transparently falls back to fastMalloc()/fastFree() when needed.

Interface:

- BumpArena::create()

Create your very own BumpArena!

- BumpArena::allocate(BumpArena* arena, size_t size)

Allocates 'size' bytes of memory from 'arena'.
If 'arena' is null, falls back to fastMalloc().

- BumpArena::deallocate(void* ptr)

If 'ptr' is BumpArena allocation, decrements block ref-count.
If 'ptr' is FastMalloc allocation, calls fastFree() on it.

- WTF_MAKE_BUMPARENA_ALLOCATED;

Macro that gives a class or struct custom operators new and delete
for allocation out of BumpArena. Just like WTF_MAKE_FAST_ALLOCATED;

Note that while the name of this patch says "fragmentation-free allocator"
it will only be fragmentation-free when used for appropriate things.
This is not meant to be a general-purpose allocator. Only use it for sets of
allocations that are known to die roughly at the same time.

BumpArena will never resume allocating from a block that has been filled,
so it's even more important than usual that everything gets deallocated.

BumpArena redirects allocations to FastMalloc in three cases:

- When invoked with a null BumpArena*
- When allocation request is larger than BumpArena's block size (4kB)
- When BumpArena has exhausted all of its pre-reserved VM. (128MB)

The VM allocator will eagerly return blocks of VM to the kernel by calling
madvise(). Average time spent in madvise is around 0.007ms on my box.

* WTF.vcxproj/WTF.vcxproj:
* WTF.vcxproj/WTF.vcxproj.filters:
* WTF.xcodeproj/project.pbxproj:
* wtf/BumpArena.cpp: Added.
(WTF::BumpArena::Block::capacity):
(WTF::BumpArena::Block::arena):
(WTF::BumpArena::Block::payloadStart):
(WTF::arenas):
(WTF::BumpArena::Block::Block):
(WTF::BumpArena::Block::~Block):
(WTF::BumpArena::Block::ref):
(WTF::BlockAllocator::BlockAllocator):
(WTF::BlockAllocator::isAllocation):
(WTF::blockAllocator):
(WTF::BlockAllocator::allocateBlock):
(WTF::BlockAllocator::deallocateBlock):
(WTF::BumpArena::Block::deref):
(WTF::BumpArena::Block::create):
(WTF::BumpArena::Block::dump):
(WTF::BumpArena::dump):
(WTF::BumpArena::create):
(WTF::BumpArena::BumpArena):
(WTF::BumpArena::~BumpArena):
(WTF::BumpArena::allocateSlow):
(WTF::BumpArena::allocate):
(WTF::BumpArena::deallocate):
(WTF::BumpArena::Block::blockFor):
(WTF::BumpArena::arenaFor):
* wtf/BumpArena.h: Added.
* wtf/CMakeLists.txt:

2016-01-15 Konstantin Tokarev <annulen@yandex.ru>

[EFL] WorkQueue methods should be defined inside WTF namespace.
@@ -53,6 +53,7 @@
<ItemGroup>
<ClCompile Include="..\wtf\Assertions.cpp" />
<ClCompile Include="..\wtf\BitVector.cpp" />
<ClCompile Include="..\wtf\BumpArena.cpp" />
<ClCompile Include="..\wtf\CompilationThread.cpp" />
<ClCompile Include="..\wtf\CryptographicUtilities.cpp" />
<ClCompile Include="..\wtf\CryptographicallyRandomNumber.cpp" />
@@ -120,6 +120,9 @@
<ClCompile Include="..\wtf\BitVector.cpp">
<Filter>wtf</Filter>
</ClCompile>
<ClCompile Include="..\wtf\BumpArena.cpp">
<Filter>wtf</Filter>
</ClCompile>
<ClCompile Include="..\wtf\CryptographicUtilities.cpp">
<Filter>wtf</Filter>
</ClCompile>
@@ -287,6 +287,8 @@
A8A47486151A825B004123FF /* WTFThreadData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A4737A151A825B004123FF /* WTFThreadData.cpp */; };
A8A47487151A825B004123FF /* WTFThreadData.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4737B151A825B004123FF /* WTFThreadData.h */; };
A8A4748C151A8264004123FF /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4748B151A8264004123FF /* config.h */; };
AD9C50C11C3C1D5D005FBF1E /* BumpArena.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD9C50BF1C3C1D5D005FBF1E /* BumpArena.cpp */; };
AD9C50C21C3C1D5D005FBF1E /* BumpArena.h in Headers */ = {isa = PBXBuildFile; fileRef = AD9C50C01C3C1D5D005FBF1E /* BumpArena.h */; settings = {ATTRIBUTES = (Private, ); }; };
B38FD7BD168953E80065C969 /* FeatureDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = B38FD7BC168953E80065C969 /* FeatureDefines.h */; };
C4F8A93719C65EB400B2B15D /* Stopwatch.h in Headers */ = {isa = PBXBuildFile; fileRef = C4F8A93619C65EB400B2B15D /* Stopwatch.h */; };
CD5497AC15857D0300B5BC30 /* MediaTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5497AA15857D0300B5BC30 /* MediaTime.cpp */; };
@@ -600,6 +602,8 @@
A8A4737A151A825B004123FF /* WTFThreadData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WTFThreadData.cpp; sourceTree = "<group>"; };
A8A4737B151A825B004123FF /* WTFThreadData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFThreadData.h; sourceTree = "<group>"; };
A8A4748B151A8264004123FF /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
AD9C50BF1C3C1D5D005FBF1E /* BumpArena.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BumpArena.cpp; sourceTree = "<group>"; };
AD9C50C01C3C1D5D005FBF1E /* BumpArena.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BumpArena.h; sourceTree = "<group>"; };
B38FD7BC168953E80065C969 /* FeatureDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeatureDefines.h; sourceTree = "<group>"; };
C4F8A93619C65EB400B2B15D /* Stopwatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stopwatch.h; sourceTree = "<group>"; };
CD5497AA15857D0300B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaTime.cpp; sourceTree = "<group>"; };
@@ -757,6 +761,8 @@
A8A47265151A825A004123FF /* BloomFilter.h */,
0F93274A1C17F4B700CF6564 /* Box.h */,
0F4570441BE834410062A629 /* BubbleSort.h */,
AD9C50BF1C3C1D5D005FBF1E /* BumpArena.cpp */,
AD9C50C01C3C1D5D005FBF1E /* BumpArena.h */,
A8A47267151A825A004123FF /* BumpPointerAllocator.h */,
EB95E1EF161A72410089A2F5 /* ByteOrder.h */,
A8A4726A151A825A004123FF /* CheckedArithmetic.h */,
@@ -1261,6 +1267,7 @@
A8A4742C151A825B004123FF /* StringExtras.h in Headers */,
A8A4743F151A825B004123FF /* StringHash.h in Headers */,
A748745417A0BDAE00FA04CB /* StringHashDumpContext.h in Headers */,
AD9C50C21C3C1D5D005FBF1E /* BumpArena.h in Headers */,
A8A47441151A825B004123FF /* StringImpl.h in Headers */,
A8A47442151A825B004123FF /* StringOperators.h in Headers */,
0FDDBFA81666DFA300C55FEF /* StringPrintStream.h in Headers */,
@@ -1404,6 +1411,7 @@
A5BA15FA182435A600A82E69 /* AtomicStringImplCF.cpp in Sources */,
9BC70F05176C379D00101DEC /* AtomicStringTable.cpp in Sources */,
1469419D16EAB10A0024E146 /* AutodrainedPoolMac.mm in Sources */,
AD9C50C11C3C1D5D005FBF1E /* BumpArena.cpp in Sources */,
8134013815B092FD001FF0B8 /* Base64.cpp in Sources */,
A8A473A8151A825B004123FF /* bignum-dtoa.cc in Sources */,
A8A473AA151A825B004123FF /* bignum.cc in Sources */,

0 comments on commit a289998

Please sign in to comment.