Experiment: create lots of different malloc zones for easier accounting of memory use
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 Jan 2020 02:36:43 +0000 (02:36 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 Jan 2020 02:36:43 +0000 (02:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186422

Patch by Yusuke Suzuki  <ysuzuki@apple.com> and Simon Fraser <simon.fraser@apple.com> on 2020-01-02
Reviewed by Saam Barati.

Source/bmalloc:

* bmalloc/BPlatform.h:
* bmalloc/Environment.cpp:
(bmalloc::Environment::computeIsDebugHeapEnabled):
* bmalloc/IsoHeap.h:
(bmalloc::api::IsoHeap::IsoHeap):
* bmalloc/IsoHeapInlines.h:
(bmalloc::api::IsoHeap<Type>::IsoHeap):
* bmalloc/IsoTLSInlines.h:
(bmalloc::IsoTLS::allocateSlow):
(bmalloc::IsoTLS::deallocateSlow):

Source/JavaScriptCore:

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/AssemblerBuffer.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* assembler/AssemblerBuffer.h:
(JSC::AssemblerData::AssemblerData):
(JSC::AssemblerData::operator=):
(JSC::AssemblerData::~AssemblerData):
(JSC::AssemblerData::grow):
* bytecode/AccessCase.cpp:
* bytecode/AccessCase.h:
* bytecode/BytecodeBasicBlock.cpp:
* bytecode/BytecodeBasicBlock.h:
* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
* bytecode/InstructionStream.cpp:
* bytecode/InstructionStream.h:
* bytecode/PolymorphicAccess.cpp:
* bytecode/PolymorphicAccess.h:
* bytecode/UnlinkedMetadataTable.cpp:
(JSC::UnlinkedMetadataTable::finalize):
* bytecode/UnlinkedMetadataTable.h:
* bytecode/UnlinkedMetadataTableInlines.h:
(JSC::UnlinkedMetadataTable::UnlinkedMetadataTable):
(JSC::UnlinkedMetadataTable::~UnlinkedMetadataTable):
(JSC::UnlinkedMetadataTable::link):
(JSC::UnlinkedMetadataTable::unlink):
* bytecode/ValueProfile.h:
(JSC::ValueProfileAndVirtualRegisterBuffer::ValueProfileAndVirtualRegisterBuffer):
* bytecode/Watchpoint.cpp:
* bytecode/Watchpoint.h:
* dfg/DFGBasicBlock.cpp:
* dfg/DFGBasicBlock.h:
* dfg/DFGNode.cpp:
* dfg/DFGNode.h:
* dfg/DFGSpeculativeJIT.cpp:
* dfg/DFGSpeculativeJIT.h:
* heap/BlockDirectory.cpp:
* heap/BlockDirectory.h:
* heap/FastMallocAlignedMemoryAllocator.cpp:
(JSC::FastMallocAlignedMemoryAllocator::FastMallocAlignedMemoryAllocator):
(JSC::FastMallocAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::FastMallocAlignedMemoryAllocator::freeAlignedMemory):
(JSC::FastMallocAlignedMemoryAllocator::tryAllocateMemory):
(JSC::FastMallocAlignedMemoryAllocator::freeMemory):
(JSC::FastMallocAlignedMemoryAllocator::tryReallocateMemory):
* heap/FastMallocAlignedMemoryAllocator.h:
* heap/GCSegmentedArray.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* heap/GCSegmentedArray.h:
* heap/GCSegmentedArrayInlines.h:
(JSC::GCArraySegment<T>::create):
(JSC::GCArraySegment<T>::destroy):
* heap/GigacageAlignedMemoryAllocator.cpp:
(JSC::GigacageAlignedMemoryAllocator::GigacageAlignedMemoryAllocator):
(JSC::GigacageAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::GigacageAlignedMemoryAllocator::freeAlignedMemory):
(JSC::GigacageAlignedMemoryAllocator::tryAllocateMemory):
(JSC::GigacageAlignedMemoryAllocator::freeMemory):
(JSC::GigacageAlignedMemoryAllocator::tryReallocateMemory):
* heap/GigacageAlignedMemoryAllocator.h:
* heap/IsoAlignedMemoryAllocator.cpp:
(JSC::IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator):
(JSC::IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator):
(JSC::IsoAlignedMemoryAllocator::tryAllocateAlignedMemory):
(JSC::IsoAlignedMemoryAllocator::freeAlignedMemory):
(JSC::IsoAlignedMemoryAllocator::tryAllocateMemory):
(JSC::IsoAlignedMemoryAllocator::freeMemory):
* heap/IsoAlignedMemoryAllocator.h:
* heap/IsoSubspace.cpp:
(JSC::IsoSubspace::IsoSubspace):
* heap/MarkedBlock.cpp:
* heap/MarkedBlock.h:
* heap/WeakBlock.cpp:
(JSC::WeakBlock::create):
(JSC::WeakBlock::destroy):
* heap/WeakBlock.h:
* jit/JITCode.cpp:
* jit/JITCode.h:
* jit/RegisterAtOffsetList.cpp:
* jit/RegisterAtOffsetList.h:
* parser/Nodes.cpp:
* parser/Nodes.h:
* parser/ParserArena.cpp:
(JSC::ParserArena::deallocateObjects):
(JSC::ParserArena::allocateFreeablePool):
* parser/ParserArena.h:
* parser/SourceProvider.cpp:
* parser/SourceProvider.h:
* parser/SourceProviderCache.cpp:
* parser/SourceProviderCache.h:
* parser/SourceProviderCacheItem.h:
(JSC::SourceProviderCacheItem::create):
* runtime/CachePayload.cpp:
(JSC::CachePayload::makeMallocPayload):
* runtime/CachePayload.h:
* runtime/CachedBytecode.h:
(JSC::CachedBytecode::create):
* runtime/CachedTypes.cpp:
(JSC::Encoder::release):
(JSC::Encoder::Page::Page):
(JSC::CachedVector::encode):
(JSC::CachedVector::decode const):
(JSC::CachedInstructionStream::decode const):
* runtime/PropertyMapHashTable.h:
(JSC::PropertyTable::rehash):
* runtime/PropertyTable.cpp:
(JSC::PropertyTable::PropertyTable):
(JSC::PropertyTable::~PropertyTable):
* runtime/SymbolTable.cpp:
* runtime/SymbolTable.h:
* runtime/VM.cpp:
(JSC::VM::~VM):
* runtime/VM.h:
(JSC::ScratchBuffer::create):
(JSC::VM::exceptionFuzzingBuffer):
* wasm/WasmInstance.cpp:
(JSC::Wasm::Instance::Instance):
* wasm/WasmInstance.h:
* wasm/WasmTable.cpp:
(JSC::Wasm::Table::Table):
(JSC::Wasm::FuncRefTable::FuncRefTable):
* wasm/WasmTable.h:

Source/WebCore:

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/SerializedScriptValue.cpp:
* bindings/js/SerializedScriptValue.h:
* css/CSSFontFace.cpp:
* css/CSSFontFace.h:
* css/CSSSelector.cpp:
* css/CSSSelector.h:
* css/CSSValue.cpp:
* css/CSSValue.h:
* css/StyleProperties.cpp:
(WebCore::ImmutableStyleProperties::create):
* css/StyleProperties.h:
* css/StyleRule.cpp:
* css/StyleRule.h:
* dom/ElementData.cpp:
(WebCore::ShareableElementData::createWithAttributes):
(WebCore::UniqueElementData::makeShareableCopy const):
* dom/ElementData.h:
* dom/NodeRareData.cpp:
* dom/NodeRareData.h:
* dom/QualifiedName.cpp:
* dom/QualifiedName.h:
* html/parser/HTMLDocumentParser.cpp:
* html/parser/HTMLDocumentParser.h:
* loader/DocumentLoader.cpp:
* loader/DocumentLoader.h:
* loader/ResourceLoader.cpp:
* loader/ResourceLoader.h:
* loader/cache/CachedResource.cpp:
* loader/cache/CachedResource.h:
* page/PerformanceEntry.cpp:
* page/PerformanceEntry.h:
* platform/graphics/Font.cpp:
* platform/graphics/Font.h:
* platform/graphics/FontCascadeFonts.cpp:
* platform/graphics/FontCascadeFonts.h:
* platform/graphics/Region.cpp:
* platform/graphics/Region.h:
* platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
(WebCore::releaseUint8Vector):
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::ImageBuffer):
* platform/graphics/nicosia/NicosiaBuffer.cpp:
(Nicosia::Buffer::Buffer):
* platform/network/ResourceHandle.cpp:
* platform/network/ResourceHandleInternal.h:
* platform/network/cf/FormDataStreamCFNet.cpp:
(WebCore::closeCurrentStream):
(WebCore::advanceCurrentStream):
* rendering/RenderLayer.cpp:
* rendering/RenderLayer.h:
* rendering/TableLayout.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* rendering/TableLayout.h:
* rendering/style/RenderStyle.cpp:
* rendering/style/RenderStyle.h:
* rendering/style/SVGRenderStyle.cpp:
* rendering/style/SVGRenderStyle.h:
* rendering/style/SVGRenderStyleDefs.cpp:
* rendering/style/SVGRenderStyleDefs.h:
* rendering/style/StyleBoxData.cpp:
* rendering/style/StyleBoxData.h:
* rendering/style/StyleInheritedData.cpp:
* rendering/style/StyleInheritedData.h:
* rendering/style/StyleRareInheritedData.cpp:
* rendering/style/StyleRareInheritedData.h:
* rendering/style/StyleRareNonInheritedData.cpp:
* rendering/style/StyleRareNonInheritedData.h:
* rendering/style/StyleSurroundData.cpp:
* rendering/style/StyleSurroundData.h:
* rendering/style/StyleTransformData.cpp:
* rendering/style/StyleTransformData.h:
* style/StyleTreeResolver.cpp:
* style/StyleTreeResolver.h:
* svg/animation/SMILTimeContainer.cpp:
* svg/animation/SMILTimeContainer.h:

Source/WebKit:

* Shared/ShareableBitmap.cpp:
(WebKit::ShareableBitmap::create):
(WebKit::ShareableBitmap::~ShareableBitmap):
* UIProcess/mac/LegacySessionStateCoding.cpp:
(WebKit::HistoryEntryDataEncoder::HistoryEntryDataEncoder):
(WebKit::HistoryEntryDataEncoder::finishEncoding):
(WebKit::encodeSessionHistoryEntryData):
(WebKit::encodeLegacySessionState):

Source/WTF:

This patch introduces ENABLE(MALLOC_HEAP_BREAKDOWN). If this is enabled, we allocate malloc_zone per malloc kind.
This offers the way to investigate the usage of memory per kind by using vmmap, like the following.

    VIRTUAL   RESIDENT      DIRTY    SWAPPED ALLOCATION      BYTES DIRTY+SWAP          REGION
    MALLOC ZONE                                                      SIZE       SIZE       SIZE       SIZE      COUNT  ALLOCATED  FRAG SIZE  % FRAG   COUNT
    ===========                                                   =======  =========  =========  =========  =========  =========  =========  ======  ======
    StringImpl_0x116efd000                                         188.0M      69.3M      30.9M         0K     139456      18.0M      12.9M     42%      34
    DefaultMallocZone_0x10f487000                                  176.0M      53.9M      14.1M         0K     115956      9955K      4497K     32%      22
    Vector_0x116eff000                                             162.0M      56.3M      55.3M         0K     140715      17.3M      37.9M     69%      36
    MetadataTable_0x11843b000                                      152.0M      17.5M      17.5M         0K      14200      2353K      15.2M     87%      26
    WebKit Using System Malloc_0x114cbe000                         150.0M      31.6M      21.8M         0K      87422      16.7M      5278K     24%      23
    InstructionStream_0x118469000                                  150.0M      5764K      5764K         0K      14470      4688K      1076K     19%      24
    AssemblerData_0x117ee6000                                      150.0M      1928K      1928K         0K          1         16      1928K    100%      24

To achieve this goal without making very large change, we put a template type in various containers.
For example, Vector will take Malloc parameter (the default one is FastMalloc allocator). If ENABLE(MALLOC_HEAP_BREAKDOWN) is enabled, we change this to
specific VectorMalloc allocator, and vmmap can show memory usage of this allocator. This patch also supports malloc_zone per IsoHeap. So we can see memory
allocation per IsoHeap in vmmap.

To use this feature, we need to flip two compile time flags, ENABLE(MALLOC_HEAP_BREAKDOWN) in WTF and BENABLE_MALLOC_HEAP_BREAKDOWN in bmalloc.
And use `vmmap $PID` to dump malloc zones. To allocate objects of a class with a specific malloc-zone, use WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(HeapIdentifier) for the class,
and define allocator by DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HeapIdentifier) in a header and DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HeapIdentifier) in a cpp file.

This patch also introduce callstack collector for malloc. Vector, HashMap etc. are used to allocate various things, but the above malloc_zone feature only tells thing like "Vector
takes XXX MB memory". But what we want to know in this case is what Vector is consuming memory. We collect StackShot for each malloc call, and combine these information to tell
which callsite is consuming much memory, which tell us that what Vector is consuming memory.

* WTF.xcodeproj/project.pbxproj:
* wtf/Bag.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* wtf/Bag.h:
(WTF::Private::BagNode::BagNode): Deleted.
* wtf/BitVector.cpp:
(WTF::BitVector::OutOfLineBits::create):
(WTF::BitVector::OutOfLineBits::destroy):
* wtf/CMakeLists.txt:
* wtf/ConcurrentBuffer.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
* wtf/ConcurrentBuffer.h:
* wtf/DebugHeap.cpp: Copied from Source/JavaScriptCore/runtime/CachePayload.cpp.
(WTF::DebugHeap::DebugHeap):
(WTF::DebugHeap::malloc):
(WTF::DebugHeap::calloc):
(WTF::DebugHeap::memalign):
(WTF::DebugHeap::realloc):
(WTF::DebugHeap::free):
* wtf/DebugHeap.h: Added.
* wtf/FastBitVector.cpp:
(WTF::FastBitVectorWordOwner::setEqualsSlow):
(WTF::FastBitVectorWordOwner::resizeSlow):
* wtf/FastBitVector.h:
(WTF::FastBitVectorWordOwner::~FastBitVectorWordOwner):
* wtf/FastMalloc.cpp:
(WTF::fastMallocDumpMallocStats):
(WTF::AvoidRecordingScope::AvoidRecordingScope):
(WTF::AvoidRecordingScope::~AvoidRecordingScope):
(WTF::MallocCallTracker::MallocSiteData::MallocSiteData):
(WTF::MallocCallTracker::singleton):
(WTF::MallocCallTracker::MallocCallTracker):
(WTF::MallocCallTracker::recordMalloc):
(WTF::MallocCallTracker::recordRealloc):
(WTF::MallocCallTracker::recordFree):
(WTF::MallocCallTracker::dumpStats):
(WTF::fastMalloc):
(WTF::fastRealloc):
(WTF::fastFree):
(WTF::fastAlignedMalloc):
(WTF::tryFastAlignedMalloc):
(WTF::fastAlignedFree):
* wtf/FastMalloc.h:
(WTF::FastMalloc::zeroedMalloc):
(WTF::FastMalloc::tryZeroedMalloc):
* wtf/Forward.h:
* wtf/HashTable.cpp:
* wtf/HashTable.h:
(WTF::KeyTraits>::allocateTable):
(WTF::KeyTraits>::deallocateTable):
(WTF::KeyTraits>::rehash):
* wtf/MallocPtr.h:
(WTF::MallocPtr::MallocPtr):
(WTF::MallocPtr::malloc):
(WTF::MallocPtr::zeroedMalloc):
(WTF::MallocPtr::tryMalloc):
(WTF::MallocPtr::tryZeroedMalloc):
(WTF::adoptMallocPtr):
* wtf/MetaAllocator.cpp:
(WTF::MetaAllocator::allocFreeSpaceNode):
(WTF::MetaAllocator::freeFreeSpaceNode):
* wtf/MetaAllocatorHandle.h:
* wtf/Platform.h:
* wtf/RefCountedArray.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/RefCountedArray.h:
(WTF::RefCountedArray::RefCountedArray):
(WTF::RefCountedArray::~RefCountedArray):
(WTF::RefCountedArray::assign):
* wtf/SegmentedVector.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/SegmentedVector.h:
* wtf/SmallPtrSet.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/SmallPtrSet.h:
(WTF::SmallPtrSet::~SmallPtrSet):
(WTF::SmallPtrSet::grow):
* wtf/UniqueArray.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/UniqueArray.h:
(WTF::UniqueArrayFree::operator() const):
(WTF::UniqueArrayFree<T::operator() const):
* wtf/Vector.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/Vector.h:
(WTF::VectorBufferBase::allocateBuffer):
(WTF::VectorBufferBase::tryAllocateBuffer):
(WTF::VectorBufferBase::reallocateBuffer):
(WTF::VectorBufferBase::deallocateBuffer):
(WTF::VectorBufferBase::releaseBuffer):
(WTF::VectorBuffer::releaseBuffer):
(WTF::Vector::swap):
(WTF::Malloc>::Vector):
(WTF::=):
(WTF::Malloc>::contains const):
(WTF::Malloc>::findMatching const):
(WTF::Malloc>::find const):
(WTF::Malloc>::reverseFind const):
(WTF::Malloc>::appendIfNotContains):
(WTF::Malloc>::fill):
(WTF::Malloc>::appendRange):
(WTF::Malloc>::expandCapacity):
(WTF::Malloc>::tryExpandCapacity):
(WTF::Malloc>::resize):
(WTF::Malloc>::resizeToFit):
(WTF::Malloc>::shrink):
(WTF::Malloc>::grow):
(WTF::Malloc>::asanSetInitialBufferSizeTo):
(WTF::Malloc>::asanSetBufferSizeToFullCapacity):
(WTF::Malloc>::asanBufferSizeWillChangeTo):
(WTF::Malloc>::reserveCapacity):
(WTF::Malloc>::tryReserveCapacity):
(WTF::Malloc>::reserveInitialCapacity):
(WTF::Malloc>::shrinkCapacity):
(WTF::Malloc>::append):
(WTF::Malloc>::tryAppend):
(WTF::Malloc>::constructAndAppend):
(WTF::Malloc>::tryConstructAndAppend):
(WTF::Malloc>::appendSlowCase):
(WTF::Malloc>::constructAndAppendSlowCase):
(WTF::Malloc>::tryConstructAndAppendSlowCase):
(WTF::Malloc>::uncheckedAppend):
(WTF::Malloc>::uncheckedConstructAndAppend):
(WTF::Malloc>::appendVector):
(WTF::Malloc>::insert):
(WTF::Malloc>::insertVector):
(WTF::Malloc>::remove):
(WTF::Malloc>::removeFirst):
(WTF::Malloc>::removeFirstMatching):
(WTF::Malloc>::removeAll):
(WTF::Malloc>::removeAllMatching):
(WTF::Malloc>::reverse):
(WTF::Malloc>::map const):
(WTF::Malloc>::releaseBuffer):
(WTF::Malloc>::checkConsistency):
(WTF::swap):
(WTF::operator==):
(WTF::operator!=):
(WTF::Malloc>::isolatedCopy const):
(WTF::removeRepeatedElements):
(WTF::minCapacity>::Vector): Deleted.
(WTF::minCapacity>::contains const): Deleted.
(WTF::minCapacity>::findMatching const): Deleted.
(WTF::minCapacity>::find const): Deleted.
(WTF::minCapacity>::reverseFind const): Deleted.
(WTF::minCapacity>::appendIfNotContains): Deleted.
(WTF::minCapacity>::fill): Deleted.
(WTF::minCapacity>::appendRange): Deleted.
(WTF::minCapacity>::expandCapacity): Deleted.
(WTF::minCapacity>::tryExpandCapacity): Deleted.
(WTF::minCapacity>::resize): Deleted.
(WTF::minCapacity>::resizeToFit): Deleted.
(WTF::minCapacity>::shrink): Deleted.
(WTF::minCapacity>::grow): Deleted.
(WTF::minCapacity>::asanSetInitialBufferSizeTo): Deleted.
(WTF::minCapacity>::asanSetBufferSizeToFullCapacity): Deleted.
(WTF::minCapacity>::asanBufferSizeWillChangeTo): Deleted.
(WTF::minCapacity>::reserveCapacity): Deleted.
(WTF::minCapacity>::tryReserveCapacity): Deleted.
(WTF::minCapacity>::reserveInitialCapacity): Deleted.
(WTF::minCapacity>::shrinkCapacity): Deleted.
(WTF::minCapacity>::append): Deleted.
(WTF::minCapacity>::tryAppend): Deleted.
(WTF::minCapacity>::constructAndAppend): Deleted.
(WTF::minCapacity>::tryConstructAndAppend): Deleted.
(WTF::minCapacity>::appendSlowCase): Deleted.
(WTF::minCapacity>::constructAndAppendSlowCase): Deleted.
(WTF::minCapacity>::tryConstructAndAppendSlowCase): Deleted.
(WTF::minCapacity>::uncheckedAppend): Deleted.
(WTF::minCapacity>::uncheckedConstructAndAppend): Deleted.
(WTF::minCapacity>::appendVector): Deleted.
(WTF::minCapacity>::insert): Deleted.
(WTF::minCapacity>::insertVector): Deleted.
(WTF::minCapacity>::remove): Deleted.
(WTF::minCapacity>::removeFirst): Deleted.
(WTF::minCapacity>::removeFirstMatching): Deleted.
(WTF::minCapacity>::removeAll): Deleted.
(WTF::minCapacity>::removeAllMatching): Deleted.
(WTF::minCapacity>::reverse): Deleted.
(WTF::minCapacity>::map const): Deleted.
(WTF::minCapacity>::releaseBuffer): Deleted.
(WTF::minCapacity>::checkConsistency): Deleted.
(WTF::minCapacity>::isolatedCopy const): Deleted.
* wtf/text/CString.cpp:
(WTF::CStringBuffer::createUninitialized):
* wtf/text/CString.h:
* wtf/text/StringBuffer.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
* wtf/text/StringBuffer.h:
(WTF::StringBuffer::StringBuffer):
(WTF::StringBuffer::~StringBuffer):
(WTF::StringBuffer::resize):
(WTF::StringBuffer::release):
* wtf/text/StringImpl.cpp:
(WTF::StringImpl::~StringImpl):
(WTF::StringImpl::destroy):
(WTF::StringImpl::createUninitializedInternalNonEmpty):
(WTF::StringImpl::reallocateInternal):
* wtf/text/StringImpl.h:
(WTF::StringImpl::StringImpl):
(WTF::StringImpl::createSubstringSharingImpl):
(WTF::StringImpl::tryCreateUninitialized):
(WTF::StringImpl::adopt):
* wtf/text/cf/StringImplCF.cpp:
(WTF::StringWrapperCFAllocator::allocate):
(WTF::StringWrapperCFAllocator::reallocate):
(WTF::StringWrapperCFAllocator::deallocate):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@253987 268f45cc-cd09-0410-ab3c-d52691b4dbfc

187 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Sources.txt
Source/JavaScriptCore/assembler/AssemblerBuffer.cpp [new file with mode: 0644]
Source/JavaScriptCore/assembler/AssemblerBuffer.h
Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
Source/JavaScriptCore/bytecode/AccessCase.cpp
Source/JavaScriptCore/bytecode/AccessCase.h
Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp
Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/bytecode/InstructionStream.cpp
Source/JavaScriptCore/bytecode/InstructionStream.h
Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
Source/JavaScriptCore/bytecode/PolymorphicAccess.h
Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp
Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h
Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h
Source/JavaScriptCore/bytecode/ValueProfile.h
Source/JavaScriptCore/bytecode/Watchpoint.cpp
Source/JavaScriptCore/bytecode/Watchpoint.h
Source/JavaScriptCore/dfg/DFGBasicBlock.cpp
Source/JavaScriptCore/dfg/DFGBasicBlock.h
Source/JavaScriptCore/dfg/DFGNode.cpp
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/heap/BlockDirectory.cpp
Source/JavaScriptCore/heap/BlockDirectory.h
Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.cpp
Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.h
Source/JavaScriptCore/heap/GCSegmentedArray.cpp [new file with mode: 0644]
Source/JavaScriptCore/heap/GCSegmentedArray.h
Source/JavaScriptCore/heap/GCSegmentedArrayInlines.h
Source/JavaScriptCore/heap/GigacageAlignedMemoryAllocator.cpp
Source/JavaScriptCore/heap/GigacageAlignedMemoryAllocator.h
Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp
Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h
Source/JavaScriptCore/heap/IsoSubspace.cpp
Source/JavaScriptCore/heap/MarkedBlock.cpp
Source/JavaScriptCore/heap/MarkedBlock.h
Source/JavaScriptCore/heap/WeakBlock.cpp
Source/JavaScriptCore/heap/WeakBlock.h
Source/JavaScriptCore/jit/JITCode.cpp
Source/JavaScriptCore/jit/JITCode.h
Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp
Source/JavaScriptCore/jit/RegisterAtOffsetList.h
Source/JavaScriptCore/parser/Nodes.cpp
Source/JavaScriptCore/parser/Nodes.h
Source/JavaScriptCore/parser/ParserArena.cpp
Source/JavaScriptCore/parser/ParserArena.h
Source/JavaScriptCore/parser/SourceProvider.cpp
Source/JavaScriptCore/parser/SourceProvider.h
Source/JavaScriptCore/parser/SourceProviderCache.cpp
Source/JavaScriptCore/parser/SourceProviderCache.h
Source/JavaScriptCore/parser/SourceProviderCacheItem.h
Source/JavaScriptCore/runtime/CachePayload.cpp
Source/JavaScriptCore/runtime/CachePayload.h
Source/JavaScriptCore/runtime/CachedBytecode.h
Source/JavaScriptCore/runtime/CachedTypes.cpp
Source/JavaScriptCore/runtime/PropertyMapHashTable.h
Source/JavaScriptCore/runtime/PropertyTable.cpp
Source/JavaScriptCore/runtime/SymbolTable.cpp
Source/JavaScriptCore/runtime/SymbolTable.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/wasm/WasmInstance.cpp
Source/JavaScriptCore/wasm/WasmInstance.h
Source/JavaScriptCore/wasm/WasmTable.cpp
Source/JavaScriptCore/wasm/WasmTable.h
Source/WTF/ChangeLog
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/Bag.cpp [new file with mode: 0644]
Source/WTF/wtf/Bag.h
Source/WTF/wtf/BitVector.cpp
Source/WTF/wtf/CMakeLists.txt
Source/WTF/wtf/ConcurrentBuffer.cpp [new file with mode: 0644]
Source/WTF/wtf/ConcurrentBuffer.h
Source/WTF/wtf/DebugHeap.cpp [new file with mode: 0644]
Source/WTF/wtf/DebugHeap.h [new file with mode: 0644]
Source/WTF/wtf/FastBitVector.cpp
Source/WTF/wtf/FastBitVector.h
Source/WTF/wtf/FastMalloc.cpp
Source/WTF/wtf/FastMalloc.h
Source/WTF/wtf/Forward.h
Source/WTF/wtf/HashTable.cpp
Source/WTF/wtf/HashTable.h
Source/WTF/wtf/MallocPtr.h
Source/WTF/wtf/MetaAllocator.cpp
Source/WTF/wtf/MetaAllocatorHandle.h
Source/WTF/wtf/Platform.h
Source/WTF/wtf/RefCountedArray.cpp [new file with mode: 0644]
Source/WTF/wtf/RefCountedArray.h
Source/WTF/wtf/SegmentedVector.cpp [new file with mode: 0644]
Source/WTF/wtf/SegmentedVector.h
Source/WTF/wtf/SmallPtrSet.cpp [new file with mode: 0644]
Source/WTF/wtf/SmallPtrSet.h
Source/WTF/wtf/UniqueArray.cpp [new file with mode: 0644]
Source/WTF/wtf/UniqueArray.h
Source/WTF/wtf/Vector.cpp [new file with mode: 0644]
Source/WTF/wtf/Vector.h
Source/WTF/wtf/text/CString.cpp
Source/WTF/wtf/text/CString.h
Source/WTF/wtf/text/StringBuffer.cpp [new file with mode: 0644]
Source/WTF/wtf/text/StringBuffer.h
Source/WTF/wtf/text/StringImpl.cpp
Source/WTF/wtf/text/StringImpl.h
Source/WTF/wtf/text/cf/StringImplCF.cpp
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/SerializedScriptValue.cpp
Source/WebCore/bindings/js/SerializedScriptValue.h
Source/WebCore/css/CSSFontFace.cpp
Source/WebCore/css/CSSFontFace.h
Source/WebCore/css/CSSSelector.cpp
Source/WebCore/css/CSSSelector.h
Source/WebCore/css/CSSValue.cpp
Source/WebCore/css/CSSValue.h
Source/WebCore/css/StyleProperties.cpp
Source/WebCore/css/StyleProperties.h
Source/WebCore/css/StyleRule.cpp
Source/WebCore/css/StyleRule.h
Source/WebCore/dom/ElementData.cpp
Source/WebCore/dom/ElementData.h
Source/WebCore/dom/NodeRareData.cpp
Source/WebCore/dom/NodeRareData.h
Source/WebCore/dom/QualifiedName.cpp
Source/WebCore/dom/QualifiedName.h
Source/WebCore/html/parser/HTMLDocumentParser.cpp
Source/WebCore/html/parser/HTMLDocumentParser.h
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/loader/ResourceLoader.cpp
Source/WebCore/loader/ResourceLoader.h
Source/WebCore/loader/cache/CachedResource.cpp
Source/WebCore/loader/cache/CachedResource.h
Source/WebCore/page/PerformanceEntry.cpp
Source/WebCore/page/PerformanceEntry.h
Source/WebCore/platform/graphics/Font.cpp
Source/WebCore/platform/graphics/Font.h
Source/WebCore/platform/graphics/FontCascadeFonts.cpp
Source/WebCore/platform/graphics/FontCascadeFonts.h
Source/WebCore/platform/graphics/Region.cpp
Source/WebCore/platform/graphics/Region.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm
Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
Source/WebCore/platform/graphics/nicosia/NicosiaBuffer.cpp
Source/WebCore/platform/network/ResourceHandle.cpp
Source/WebCore/platform/network/ResourceHandleInternal.h
Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/TableLayout.cpp [new file with mode: 0644]
Source/WebCore/rendering/TableLayout.h
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/SVGRenderStyle.cpp
Source/WebCore/rendering/style/SVGRenderStyle.h
Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp
Source/WebCore/rendering/style/SVGRenderStyleDefs.h
Source/WebCore/rendering/style/StyleBoxData.cpp
Source/WebCore/rendering/style/StyleBoxData.h
Source/WebCore/rendering/style/StyleInheritedData.cpp
Source/WebCore/rendering/style/StyleInheritedData.h
Source/WebCore/rendering/style/StyleRareInheritedData.cpp
Source/WebCore/rendering/style/StyleRareInheritedData.h
Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
Source/WebCore/rendering/style/StyleRareNonInheritedData.h
Source/WebCore/rendering/style/StyleSurroundData.cpp
Source/WebCore/rendering/style/StyleSurroundData.h
Source/WebCore/rendering/style/StyleTransformData.cpp
Source/WebCore/rendering/style/StyleTransformData.h
Source/WebCore/style/StyleTreeResolver.cpp
Source/WebCore/style/StyleTreeResolver.h
Source/WebCore/svg/animation/SMILTimeContainer.cpp
Source/WebCore/svg/animation/SMILTimeContainer.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/ShareableBitmap.cpp
Source/WebKit/UIProcess/mac/LegacySessionStateCoding.cpp
Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc/BPlatform.h
Source/bmalloc/bmalloc/Environment.cpp
Source/bmalloc/bmalloc/IsoHeap.h
Source/bmalloc/bmalloc/IsoHeapInlines.h
Source/bmalloc/bmalloc/IsoTLSInlines.h

index 03a398d..3e5966f 100644 (file)
@@ -1,3 +1,132 @@
+2020-01-02  Yusuke Suzuki  <ysuzuki@apple.com> and Simon Fraser  <simon.fraser@apple.com>
+
+        Experiment: create lots of different malloc zones for easier accounting of memory use
+        https://bugs.webkit.org/show_bug.cgi?id=186422
+
+        Reviewed by Saam Barati.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * assembler/AssemblerBuffer.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
+        * assembler/AssemblerBuffer.h:
+        (JSC::AssemblerData::AssemblerData):
+        (JSC::AssemblerData::operator=):
+        (JSC::AssemblerData::~AssemblerData):
+        (JSC::AssemblerData::grow):
+        * bytecode/AccessCase.cpp:
+        * bytecode/AccessCase.h:
+        * bytecode/BytecodeBasicBlock.cpp:
+        * bytecode/BytecodeBasicBlock.h:
+        * bytecode/CodeBlock.cpp:
+        * bytecode/CodeBlock.h:
+        * bytecode/InstructionStream.cpp:
+        * bytecode/InstructionStream.h:
+        * bytecode/PolymorphicAccess.cpp:
+        * bytecode/PolymorphicAccess.h:
+        * bytecode/UnlinkedMetadataTable.cpp:
+        (JSC::UnlinkedMetadataTable::finalize):
+        * bytecode/UnlinkedMetadataTable.h:
+        * bytecode/UnlinkedMetadataTableInlines.h:
+        (JSC::UnlinkedMetadataTable::UnlinkedMetadataTable):
+        (JSC::UnlinkedMetadataTable::~UnlinkedMetadataTable):
+        (JSC::UnlinkedMetadataTable::link):
+        (JSC::UnlinkedMetadataTable::unlink):
+        * bytecode/ValueProfile.h:
+        (JSC::ValueProfileAndVirtualRegisterBuffer::ValueProfileAndVirtualRegisterBuffer):
+        * bytecode/Watchpoint.cpp:
+        * bytecode/Watchpoint.h:
+        * dfg/DFGBasicBlock.cpp:
+        * dfg/DFGBasicBlock.h:
+        * dfg/DFGNode.cpp:
+        * dfg/DFGNode.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        * dfg/DFGSpeculativeJIT.h:
+        * heap/BlockDirectory.cpp:
+        * heap/BlockDirectory.h:
+        * heap/FastMallocAlignedMemoryAllocator.cpp:
+        (JSC::FastMallocAlignedMemoryAllocator::FastMallocAlignedMemoryAllocator):
+        (JSC::FastMallocAlignedMemoryAllocator::tryAllocateAlignedMemory):
+        (JSC::FastMallocAlignedMemoryAllocator::freeAlignedMemory):
+        (JSC::FastMallocAlignedMemoryAllocator::tryAllocateMemory):
+        (JSC::FastMallocAlignedMemoryAllocator::freeMemory):
+        (JSC::FastMallocAlignedMemoryAllocator::tryReallocateMemory):
+        * heap/FastMallocAlignedMemoryAllocator.h:
+        * heap/GCSegmentedArray.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
+        * heap/GCSegmentedArray.h:
+        * heap/GCSegmentedArrayInlines.h:
+        (JSC::GCArraySegment<T>::create):
+        (JSC::GCArraySegment<T>::destroy):
+        * heap/GigacageAlignedMemoryAllocator.cpp:
+        (JSC::GigacageAlignedMemoryAllocator::GigacageAlignedMemoryAllocator):
+        (JSC::GigacageAlignedMemoryAllocator::tryAllocateAlignedMemory):
+        (JSC::GigacageAlignedMemoryAllocator::freeAlignedMemory):
+        (JSC::GigacageAlignedMemoryAllocator::tryAllocateMemory):
+        (JSC::GigacageAlignedMemoryAllocator::freeMemory):
+        (JSC::GigacageAlignedMemoryAllocator::tryReallocateMemory):
+        * heap/GigacageAlignedMemoryAllocator.h:
+        * heap/IsoAlignedMemoryAllocator.cpp:
+        (JSC::IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator):
+        (JSC::IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator):
+        (JSC::IsoAlignedMemoryAllocator::tryAllocateAlignedMemory):
+        (JSC::IsoAlignedMemoryAllocator::freeAlignedMemory):
+        (JSC::IsoAlignedMemoryAllocator::tryAllocateMemory):
+        (JSC::IsoAlignedMemoryAllocator::freeMemory):
+        * heap/IsoAlignedMemoryAllocator.h:
+        * heap/IsoSubspace.cpp:
+        (JSC::IsoSubspace::IsoSubspace):
+        * heap/MarkedBlock.cpp:
+        * heap/MarkedBlock.h:
+        * heap/WeakBlock.cpp:
+        (JSC::WeakBlock::create):
+        (JSC::WeakBlock::destroy):
+        * heap/WeakBlock.h:
+        * jit/JITCode.cpp:
+        * jit/JITCode.h:
+        * jit/RegisterAtOffsetList.cpp:
+        * jit/RegisterAtOffsetList.h:
+        * parser/Nodes.cpp:
+        * parser/Nodes.h:
+        * parser/ParserArena.cpp:
+        (JSC::ParserArena::deallocateObjects):
+        (JSC::ParserArena::allocateFreeablePool):
+        * parser/ParserArena.h:
+        * parser/SourceProvider.cpp:
+        * parser/SourceProvider.h:
+        * parser/SourceProviderCache.cpp:
+        * parser/SourceProviderCache.h:
+        * parser/SourceProviderCacheItem.h:
+        (JSC::SourceProviderCacheItem::create):
+        * runtime/CachePayload.cpp:
+        (JSC::CachePayload::makeMallocPayload):
+        * runtime/CachePayload.h:
+        * runtime/CachedBytecode.h:
+        (JSC::CachedBytecode::create):
+        * runtime/CachedTypes.cpp:
+        (JSC::Encoder::release):
+        (JSC::Encoder::Page::Page):
+        (JSC::CachedVector::encode):
+        (JSC::CachedVector::decode const):
+        (JSC::CachedInstructionStream::decode const):
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::rehash):
+        * runtime/PropertyTable.cpp:
+        (JSC::PropertyTable::PropertyTable):
+        (JSC::PropertyTable::~PropertyTable):
+        * runtime/SymbolTable.cpp:
+        * runtime/SymbolTable.h:
+        * runtime/VM.cpp:
+        (JSC::VM::~VM):
+        * runtime/VM.h:
+        (JSC::ScratchBuffer::create):
+        (JSC::VM::exceptionFuzzingBuffer):
+        * wasm/WasmInstance.cpp:
+        (JSC::Wasm::Instance::Instance):
+        * wasm/WasmInstance.h:
+        * wasm/WasmTable.cpp:
+        (JSC::Wasm::Table::Table):
+        (JSC::Wasm::FuncRefTable::FuncRefTable):
+        * wasm/WasmTable.h:
+
 2020-01-02  Yusuke Suzuki  <ysuzuki@apple.com>
 
         REGRESSION (r253867): Six test262 tests broken
index b264f4e..0e9089d 100644 (file)
                0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNodeFlags.cpp; path = dfg/DFGNodeFlags.cpp; sourceTree = "<group>"; };
                0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeFlags.h; path = dfg/DFGNodeFlags.h; sourceTree = "<group>"; };
                0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeType.h; path = dfg/DFGNodeType.h; sourceTree = "<group>"; };
+               0FA6F38C20CC2C9500A03DCD /* GCSegmentedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCSegmentedArray.cpp; sourceTree = "<group>"; };
+               0FA6F39620CCB7A600A03DCD /* AssemblerBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AssemblerBuffer.cpp; sourceTree = "<group>"; };
                0FA762001DB9242300B7A2FD /* CollectionScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CollectionScope.cpp; sourceTree = "<group>"; };
                0FA762011DB9242300B7A2FD /* CollectionScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionScope.h; sourceTree = "<group>"; };
                0FA762021DB9242300B7A2FD /* MutatorState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MutatorState.cpp; sourceTree = "<group>"; };
                                5272987B235FC8BA005C982C /* GCMemoryOperations.h */,
                                0F97152E1EB28BE900A1645D /* GCRequest.cpp */,
                                0F97152F1EB28BE900A1645D /* GCRequest.h */,
+                               0FA6F38C20CC2C9500A03DCD /* GCSegmentedArray.cpp */,
                                2A343F7418A1748B0039B085 /* GCSegmentedArray.h */,
                                2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */,
                                0F86A26E1D6F7B3100CB0C92 /* GCTypeMap.h */,
                                8640923B156EED3B00566CC2 /* ARM64Registers.h */,
                                86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */,
                                86ADD1430FDDEA980006FFCC /* ARMv7Registers.h */,
+                               0FA6F39620CCB7A600A03DCD /* AssemblerBuffer.cpp */,
                                9688CB130ED12B4E001D649F /* AssemblerBuffer.h */,
                                86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */,
                                43C392AA1C3BEB0000241F53 /* AssemblerCommon.h */,
index 47b0ca7..acb9624 100644 (file)
@@ -43,6 +43,7 @@ API/JSWeakValue.cpp
 API/OpaqueJSString.cpp
 
 assembler/AbstractMacroAssembler.cpp
+assembler/AssemblerBuffer.cpp
 assembler/CPU.cpp
 assembler/LinkBuffer.cpp
 assembler/MacroAssembler.cpp
@@ -512,6 +513,7 @@ heap/GCActivityCallback.cpp
 heap/GCConductor.cpp
 heap/GCLogging.cpp
 heap/GCRequest.cpp
+heap/GCSegmentedArray.cpp
 heap/GigacageAlignedMemoryAllocator.cpp
 heap/HandleSet.cpp
 heap/Heap.cpp
diff --git a/Source/JavaScriptCore/assembler/AssemblerBuffer.cpp b/Source/JavaScriptCore/assembler/AssemblerBuffer.cpp
new file mode 100644 (file)
index 0000000..3793d39
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AssemblerBuffer.h"
+
+#include <wtf/NeverDestroyed.h>
+
+namespace JSC {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AssemblerData);
+
+} // namespace JSC
index c677c4f..8ebc688 100644 (file)
@@ -43,6 +43,8 @@ namespace JSC {
 
     class LinkBuffer;
 
+    DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AssemblerData);
+
     struct AssemblerLabel {
         AssemblerLabel()
             : m_offset(std::numeric_limits<uint32_t>::max())
@@ -83,7 +85,7 @@ namespace JSC {
                 m_buffer = m_inlineBuffer;
             } else {
                 m_capacity = initialCapacity;
-                m_buffer = static_cast<char*>(fastMalloc(m_capacity));
+                m_buffer = static_cast<char*>(AssemblerDataMalloc::malloc(m_capacity));
             }
         }
 
@@ -104,7 +106,7 @@ namespace JSC {
         AssemblerData& operator=(AssemblerData&& other)
         {
             if (m_buffer && !isInlineBuffer())
-                fastFree(m_buffer);
+                AssemblerDataMalloc::free(m_buffer);
 
             if (other.isInlineBuffer()) {
                 ASSERT(other.m_capacity == InlineCapacity);
@@ -122,7 +124,7 @@ namespace JSC {
         ~AssemblerData()
         {
             if (m_buffer && !isInlineBuffer())
-                fastFree(m_buffer);
+                AssemblerDataMalloc::free(m_buffer);
         }
 
         char* buffer() const { return m_buffer; }
@@ -133,10 +135,10 @@ namespace JSC {
         {
             m_capacity = m_capacity + m_capacity / 2 + extraCapacity;
             if (isInlineBuffer()) {
-                m_buffer = static_cast<char*>(fastMalloc(m_capacity));
+                m_buffer = static_cast<char*>(AssemblerDataMalloc::malloc(m_capacity));
                 memcpy(m_buffer, m_inlineBuffer, InlineCapacity);
             } else
-                m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
+                m_buffer = static_cast<char*>(AssemblerDataMalloc::realloc(m_buffer, m_capacity));
         }
 
     private:
index 3b63288..086a77e 100644 (file)
@@ -104,14 +104,14 @@ public:
         , m_maxDistance(maxPoolSize)
         , m_lastConstDelta(0)
     {
-        m_pool = static_cast<uint32_t*>(fastMalloc(maxPoolSize));
-        m_mask = static_cast<char*>(fastMalloc(maxPoolSize / sizeof(uint32_t)));
+        m_pool = static_cast<uint32_t*>(AssemblerDataMalloc::malloc(maxPoolSize));
+        m_mask = static_cast<char*>(AssemblerDataMalloc::malloc(maxPoolSize / sizeof(uint32_t)));
     }
 
     ~AssemblerBufferWithConstantPool()
     {
-        fastFree(m_mask);
-        fastFree(m_pool);
+        AssemblerDataMalloc::free(m_mask);
+        AssemblerDataMalloc::free(m_pool);
     }
 
     void ensureSpace(int space)
index 55485b0..9899362 100644 (file)
@@ -54,6 +54,8 @@ namespace AccessCaseInternal {
 static constexpr bool verbose = false;
 }
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AccessCase);
+
 AccessCase::AccessCase(VM& vm, JSCell* owner, AccessType type, const Identifier& identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
     : m_type(type)
     , m_offset(offset)
index 219d5ac..3d2a74d 100644 (file)
@@ -37,6 +37,8 @@ namespace JSC {
 
 struct AccessGenerationState;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AccessCase);
+
 // An AccessCase describes one of the cases of a PolymorphicAccess. A PolymorphicAccess represents a
 // planned (to generate in future) or generated stub for some inline cache. That stub contains fast
 // path code for some finite number of fast cases, each described by an AccessCase object.
@@ -78,7 +80,7 @@ struct AccessGenerationState;
 // code. This allows us to only regenerate once we've accumulated (hopefully) more than one new
 // AccessCase.
 class AccessCase {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(AccessCase);
 public:
     enum AccessType : uint8_t {
         Load,
index 02d644b..a4fee66 100644 (file)
@@ -33,6 +33,8 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BytecodeBasicBlock);
+
 void BytecodeBasicBlock::shrinkToFit()
 {
     m_offsets.shrinkToFit();
index 20e124c..adfc3c7 100644 (file)
@@ -36,8 +36,10 @@ class CodeBlock;
 class UnlinkedCodeBlock;
 struct Instruction;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BytecodeBasicBlock);
+
 class BytecodeBasicBlock {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(BytecodeBasicBlock);
 public:
     enum SpecialBlockType { EntryBlock, ExitBlock };
     BytecodeBasicBlock(const InstructionStream::Ref&);
index 602dd52..c63dbdc 100644 (file)
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CodeBlockRareData);
+
 const ClassInfo CodeBlock::s_info = {
     "CodeBlock", nullptr, nullptr, nullptr,
     CREATE_METHOD_TABLE(CodeBlock)
index 2506726..68fd01f 100644 (file)
@@ -96,6 +96,8 @@ class PCToCodeOriginMap;
 class RegisterAtOffsetList;
 class StructureStubInfo;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CodeBlockRareData);
+
 enum class AccessType : int8_t;
 
 struct OpCatch;
@@ -867,7 +869,7 @@ public:
     NO_RETURN_DUE_TO_CRASH void endValidationDidFail();
 
     struct RareData {
-        WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(CodeBlockRareData);
     public:
         Vector<HandlerInfo> m_exceptionHandlers;
 
index 514cf11..41fcc1d 100644 (file)
@@ -31,6 +31,8 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(InstructionStream);
+
 InstructionStream::InstructionStream(InstructionBuffer&& instructions)
     : m_instructions(WTFMove(instructions))
 { }
index 5963dea..1966ffa 100644 (file)
 
 namespace JSC {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(InstructionStream);
+
 class InstructionStream {
     WTF_MAKE_FAST_ALLOCATED;
 
-    using InstructionBuffer = Vector<uint8_t, 0, UnsafeVectorOverflow>;
+    using InstructionBuffer = Vector<uint8_t, 0, UnsafeVectorOverflow, 16, InstructionStreamMalloc>;
 
     friend class InstructionStreamWriter;
     friend class CachedInstructionStream;
index e8f6b5c..cb57809 100644 (file)
@@ -48,6 +48,8 @@ namespace PolymorphicAccessInternal {
 static constexpr bool verbose = false;
 }
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(PolymorphicAccess);
+
 void AccessGenerationResult::dump(PrintStream& out) const
 {
     out.print(m_kind);
@@ -221,7 +223,6 @@ void AccessGenerationState::emitExplicitExceptionHandler()
     }
 }
 
-
 PolymorphicAccess::PolymorphicAccess() { }
 PolymorphicAccess::~PolymorphicAccess() { }
 
index 51c88f5..7c4f832 100644 (file)
@@ -45,6 +45,8 @@ class StructureStubInfo;
 class WatchpointsOnStructureStubInfo;
 class ScratchRegisterAllocator;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(PolymorphicAccess);
+
 class AccessGenerationResult {
 public:
     enum Kind {
@@ -129,7 +131,7 @@ private:
 
 class PolymorphicAccess {
     WTF_MAKE_NONCOPYABLE(PolymorphicAccess);
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(PolymorphicAccess);
 public:
     PolymorphicAccess();
     ~PolymorphicAccess();
index e7f782a..074158f 100644 (file)
@@ -35,6 +35,8 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MetadataTable);
+
 #define JSC_ALIGNMENT_CHECK(size) static_assert(size <= UnlinkedMetadataTable::s_maxMetadataAlignment);
 FOR_EACH_BYTECODE_METADATA_ALIGNMENT(JSC_ALIGNMENT_CHECK)
 #undef JSC_ALIGNMENT_CHECK
@@ -44,7 +46,7 @@ void UnlinkedMetadataTable::finalize()
     ASSERT(!m_isFinalized);
     m_isFinalized = true;
     if (!m_hasMetadata) {
-        fastFree(m_rawBuffer);
+        MetadataTableMalloc::free(m_rawBuffer);
         m_rawBuffer = nullptr;
         return;
     }
@@ -69,7 +71,7 @@ void UnlinkedMetadataTable::finalize()
     }
 
     if (m_is32Bit) {
-        m_rawBuffer = reinterpret_cast<uint8_t*>(fastRealloc(m_rawBuffer, s_offset16TableSize + s_offset32TableSize + sizeof(LinkingData)));
+        m_rawBuffer = reinterpret_cast<uint8_t*>(MetadataTableMalloc::realloc(m_rawBuffer, s_offset16TableSize + s_offset32TableSize + sizeof(LinkingData)));
         memmove(m_rawBuffer + sizeof(LinkingData) + s_offset16TableSize, m_rawBuffer + sizeof(LinkingData), s_offset32TableSize);
         memset(m_rawBuffer + sizeof(LinkingData), 0, s_offset16TableSize);
         Offset32* buffer = bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData) + s_offset16TableSize);
@@ -81,7 +83,7 @@ void UnlinkedMetadataTable::finalize()
         Offset16* buffer = bitwise_cast<Offset16*>(m_rawBuffer + sizeof(LinkingData));
         for (unsigned i = 0; i < s_offsetTableEntries; i++)
             buffer[i] = oldBuffer[i];
-        m_rawBuffer = static_cast<uint8_t*>(fastRealloc(m_rawBuffer, s_offset16TableSize + sizeof(LinkingData)));
+        m_rawBuffer = static_cast<uint8_t*>(MetadataTableMalloc::realloc(m_rawBuffer, s_offset16TableSize + sizeof(LinkingData)));
     }
 }
 
index 280a632..223d57c 100644 (file)
 
 namespace JSC {
 
+class VM;
+
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MetadataTable);
+
 class MetadataTable;
 
 class UnlinkedMetadataTable : public RefCounted<UnlinkedMetadataTable> {
index e797f7e..9822dbd 100644 (file)
 
 namespace JSC {
 
+
 ALWAYS_INLINE UnlinkedMetadataTable::UnlinkedMetadataTable()
     : m_hasMetadata(false)
     , m_isFinalized(false)
     , m_isLinked(false)
     , m_is32Bit(false)
-    , m_rawBuffer(static_cast<uint8_t*>(fastZeroedMalloc(sizeof(LinkingData) + s_offset32TableSize)))
+    , m_rawBuffer(static_cast<uint8_t*>(MetadataTableMalloc::zeroedMalloc(sizeof(LinkingData) + s_offset32TableSize)))
 {
 }
 
@@ -45,7 +46,7 @@ ALWAYS_INLINE UnlinkedMetadataTable::UnlinkedMetadataTable(bool is32Bit)
     , m_isFinalized(false)
     , m_isLinked(false)
     , m_is32Bit(is32Bit)
-    , m_rawBuffer(static_cast<uint8_t*>(fastZeroedMalloc(sizeof(LinkingData) + (is32Bit ? s_offset16TableSize + s_offset32TableSize : s_offset16TableSize))))
+    , m_rawBuffer(static_cast<uint8_t*>(MetadataTableMalloc::zeroedMalloc(sizeof(LinkingData) + (is32Bit ? s_offset16TableSize + s_offset32TableSize : s_offset16TableSize))))
 {
 }
 
@@ -62,7 +63,7 @@ ALWAYS_INLINE UnlinkedMetadataTable::~UnlinkedMetadataTable()
 {
     ASSERT(!m_isLinked);
     if (m_hasMetadata || !m_isFinalized)
-        fastFree(m_rawBuffer);
+        MetadataTableMalloc::free(m_rawBuffer);
 }
 
 ALWAYS_INLINE unsigned UnlinkedMetadataTable::addEntry(OpcodeID opcodeID)
@@ -113,9 +114,9 @@ ALWAYS_INLINE RefPtr<MetadataTable> UnlinkedMetadataTable::link()
     uint8_t* buffer;
     if (!m_isLinked) {
         m_isLinked = true;
-        m_rawBuffer = buffer = reinterpret_cast<uint8_t*>(fastRealloc(m_rawBuffer, sizeof(LinkingData) + totalSize));
+        m_rawBuffer = buffer = reinterpret_cast<uint8_t*>(MetadataTableMalloc::realloc(m_rawBuffer, sizeof(LinkingData) + totalSize));
     } else {
-        buffer = reinterpret_cast<uint8_t*>(fastMalloc(sizeof(LinkingData) + totalSize));
+        buffer = reinterpret_cast<uint8_t*>(MetadataTableMalloc::malloc(sizeof(LinkingData) + totalSize));
         memcpy(buffer, m_rawBuffer, sizeof(LinkingData) + offsetTableSize);
     }
     memset(buffer + sizeof(LinkingData) + offsetTableSize, 0, totalSize - offsetTableSize);
@@ -131,10 +132,10 @@ ALWAYS_INLINE void UnlinkedMetadataTable::unlink(MetadataTable& metadataTable)
     if (metadataTable.buffer() == buffer()) {
         ASSERT(m_isLinked);
         m_isLinked = false;
-        m_rawBuffer = static_cast<uint8_t*>(fastRealloc(m_rawBuffer, sizeof(LinkingData) + offsetTableSize()));
+        m_rawBuffer = static_cast<uint8_t*>(MetadataTableMalloc::realloc(m_rawBuffer, sizeof(LinkingData) + offsetTableSize()));
         return;
     }
-    fastFree(&metadataTable.linkingData());
+    MetadataTableMalloc::free(&metadataTable.linkingData());
 }
 
 } // namespace JSC
index eb91794..90f93dd 100644 (file)
@@ -189,7 +189,7 @@ struct ValueProfileAndVirtualRegisterBuffer {
         // FIXME: ValueProfile has more stuff than we need. We could optimize these value profiles
         // to be more space efficient.
         // https://bugs.webkit.org/show_bug.cgi?id=175413
-        m_buffer = MallocPtr<ValueProfileAndVirtualRegister>::malloc(m_size * sizeof(ValueProfileAndVirtualRegister));
+        m_buffer = MallocPtr<ValueProfileAndVirtualRegister, VMMalloc>::malloc(m_size * sizeof(ValueProfileAndVirtualRegister));
         for (unsigned i = 0; i < m_size; ++i)
             new (&m_buffer.get()[i]) ValueProfileAndVirtualRegister();
     }
@@ -208,7 +208,7 @@ struct ValueProfileAndVirtualRegisterBuffer {
     }
 
     unsigned m_size;
-    MallocPtr<ValueProfileAndVirtualRegister> m_buffer;
+    MallocPtr<ValueProfileAndVirtualRegister, VMMalloc> m_buffer;
 };
 
 } // namespace JSC
index 3d70df4..c20de9b 100644 (file)
@@ -39,6 +39,9 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Watchpoint);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(WatchpointSet);
+
 void StringFireDetail::dump(PrintStream& out) const
 {
     out.print(m_string);
index 740d1b5..cef9c0c 100644 (file)
@@ -135,11 +135,12 @@ class WatchpointSet;
     type member; \
     static_assert(std::is_trivially_destructible<type>::value, ""); \
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Watchpoint);
 
 class Watchpoint : public PackedRawSentinelNode<Watchpoint> {
     WTF_MAKE_NONCOPYABLE(Watchpoint);
     WTF_MAKE_NONMOVABLE(Watchpoint);
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(Watchpoint);
 public:
 #define JSC_DEFINE_WATCHPOINT_TYPES(type, _) type,
     enum class Type : uint8_t {
@@ -172,7 +173,10 @@ class InlineWatchpointSet;
 class DeferredWatchpointFire;
 class VM;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(WatchpointSet);
+
 class WatchpointSet : public ThreadSafeRefCounted<WatchpointSet> {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(WatchpointSet);
     friend class LLIntOffsetsExtractor;
     friend class DeferredWatchpointFire;
 public:
index e21b28b..99fda62 100644 (file)
@@ -32,6 +32,8 @@
 
 namespace JSC { namespace DFG {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BasicBlock);
+
 BasicBlock::BasicBlock(BytecodeIndex bytecodeBegin, unsigned numArguments, unsigned numLocals, unsigned numTmps, float executionCount)
     : bytecodeBegin(bytecodeBegin)
     , index(NoBlock)
index 1dd38c7..7f5b395 100644 (file)
@@ -44,7 +44,10 @@ class InsertionSet;
 typedef Vector<BasicBlock*, 2> PredecessorList;
 typedef Vector<Node*, 8> BlockNodeList;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BasicBlock);
+
 struct BasicBlock : RefCounted<BasicBlock> {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(BasicBlock);
     BasicBlock(
         BytecodeIndex bytecodeBegin, unsigned numArguments, unsigned numLocals, unsigned numTmps,
         float executionCount);
index 760aa58..7dfb5ae 100644 (file)
@@ -37,6 +37,8 @@ namespace JSC { namespace DFG {
 
 const char Node::HashSetTemplateInstantiationString[] = "::JSC::DFG::Node*";
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(DFGNode);
+
 bool MultiPutByOffsetData::writesStructures() const
 {
     for (unsigned i = variants.size(); i--;) {
index b80155e..7f6e595 100644 (file)
@@ -55,6 +55,7 @@
 #include "TypeLocation.h"
 #include "ValueProfile.h"
 #include <type_traits>
+#include <wtf/FastMalloc.h>
 #include <wtf/ListDump.h>
 #include <wtf/LoggingHashSet.h>
 
@@ -278,8 +279,9 @@ enum class BucketOwnerType : uint32_t {
 // === Node ===
 //
 // Node represents a single operation in the data flow graph.
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(DFGNode);
 struct Node {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(DFGNode);
 public:
     static const char HashSetTemplateInstantiationString[];
     
index 9cc2e9f..7ce376a 100644 (file)
@@ -71,6 +71,8 @@
 
 namespace JSC { namespace DFG {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SpeculativeJIT);
+
 SpeculativeJIT::SpeculativeJIT(JITCompiler& jit)
     : m_jit(jit)
     , m_graph(m_jit.graph())
index 356f1e1..4b90a05 100644 (file)
@@ -68,9 +68,9 @@ enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger
 // a speculative check has failed. This allows the SpeculativeJIT
 // to propagate type information (including information that has
 // only speculatively been asserted) through the dataflow.
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SpeculativeJIT);
 class SpeculativeJIT {
-    WTF_MAKE_FAST_ALLOCATED;
-
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(SpeculativeJIT);
     friend struct OSRExit;
 private:
     typedef JITCompiler::TrustedImm32 TrustedImm32;
index 0cc4b47..86a275c 100644 (file)
@@ -38,6 +38,8 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BlockDirectory);
+
 BlockDirectory::BlockDirectory(size_t cellSize)
     : m_cellSize(static_cast<unsigned>(cellSize))
 {
index cb72cb1..5baffc2 100644 (file)
@@ -45,9 +45,11 @@ class IsoCellSet;
 class MarkedSpace;
 class LLIntOffsetsExtractor;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BlockDirectory);
+
 class BlockDirectory {
     WTF_MAKE_NONCOPYABLE(BlockDirectory);
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(BlockDirectory);
     
     friend class LLIntOffsetsExtractor;
 
index cee66b0..89c6cf5 100644 (file)
@@ -32,6 +32,9 @@
 namespace JSC {
 
 FastMallocAlignedMemoryAllocator::FastMallocAlignedMemoryAllocator()
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    : m_heap("WebKit FastMallocAlignedMemoryAllocator")
+#endif
 {
 }
 
@@ -41,12 +44,22 @@ FastMallocAlignedMemoryAllocator::~FastMallocAlignedMemoryAllocator()
 
 void* FastMallocAlignedMemoryAllocator::tryAllocateAlignedMemory(size_t alignment, size_t size)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.memalign(alignment, size, true);
+#else
     return tryFastAlignedMalloc(alignment, size);
+#endif
+
 }
 
 void FastMallocAlignedMemoryAllocator::freeAlignedMemory(void* basePtr)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.free(basePtr);
+#else
     fastAlignedFree(basePtr);
+#endif
+
 }
 
 void FastMallocAlignedMemoryAllocator::dump(PrintStream& out) const
@@ -56,17 +69,29 @@ void FastMallocAlignedMemoryAllocator::dump(PrintStream& out) const
 
 void* FastMallocAlignedMemoryAllocator::tryAllocateMemory(size_t size)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.malloc(size);
+#else
     return FastMalloc::tryMalloc(size);
+#endif
 }
 
 void FastMallocAlignedMemoryAllocator::freeMemory(void* pointer)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.free(pointer);
+#else
     FastMalloc::free(pointer);
+#endif
 }
 
 void* FastMallocAlignedMemoryAllocator::tryReallocateMemory(void* pointer, size_t size)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.realloc(pointer, size);
+#else
     return FastMalloc::tryRealloc(pointer, size);
+#endif
 }
 
 } // namespace JSC
index cfa770b..372af41 100644 (file)
 
 #include "AlignedMemoryAllocator.h"
 
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+#include <wtf/DebugHeap.h>
+#endif
+
 namespace JSC {
 
 class FastMallocAlignedMemoryAllocator : public AlignedMemoryAllocator {
@@ -42,6 +46,11 @@ public:
     void* tryAllocateMemory(size_t) override;
     void freeMemory(void*) override;
     void* tryReallocateMemory(void*, size_t) override;
+
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+private:
+    WTF::DebugHeap m_heap;
+#endif
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/heap/GCSegmentedArray.cpp b/Source/JavaScriptCore/heap/GCSegmentedArray.cpp
new file mode 100644 (file)
index 0000000..a974f00
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GCSegmentedArray.h"
+
+#include <wtf/NeverDestroyed.h>
+
+namespace JSC {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(GCSegmentedArray);
+
+} // namespace JSC
+
index 0aaa157..b0c92af 100644 (file)
 
 #pragma once
 
+#include <wtf/DebugHeap.h>
 #include <wtf/DoublyLinkedList.h>
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 
 namespace JSC {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(GCSegmentedArray);
+
 template <typename T>
 class GCArraySegment : public DoublyLinkedListNode<GCArraySegment<T>> {
     friend class WTF::DoublyLinkedListNode<GCArraySegment<T>>;
index b4638f9..46858e6 100644 (file)
@@ -126,14 +126,14 @@ void GCSegmentedArray<T>::fillVector(Vector<T>& vector)
 template <typename T>
 inline GCArraySegment<T>* GCArraySegment<T>::create()
 {
-    return new (NotNull, fastMalloc(blockSize)) GCArraySegment<T>();
+    return new (NotNull, GCSegmentedArrayMalloc::malloc(blockSize)) GCArraySegment<T>();
 }
 
 template <typename T>
 inline void GCArraySegment<T>::destroy(GCArraySegment* segment)
 {
     segment->~GCArraySegment();
-    fastFree(segment);
+    GCSegmentedArrayMalloc::free(segment);
 }
 
 template <typename T>
index 8a1f636..e66c8f9 100644 (file)
@@ -30,6 +30,9 @@ namespace JSC {
 
 GigacageAlignedMemoryAllocator::GigacageAlignedMemoryAllocator(Gigacage::Kind kind)
     : m_kind(kind)
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    , m_heap(makeString("WebKit GigacageAlignedMemoryAllocator ", Gigacage::name(m_kind)).utf8().data())
+#endif
 {
 }
 
@@ -39,12 +42,20 @@ GigacageAlignedMemoryAllocator::~GigacageAlignedMemoryAllocator()
 
 void* GigacageAlignedMemoryAllocator::tryAllocateAlignedMemory(size_t alignment, size_t size)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.memalign(alignment, size, true);
+#else
     return Gigacage::tryAlignedMalloc(m_kind, alignment, size);
+#endif
 }
 
 void GigacageAlignedMemoryAllocator::freeAlignedMemory(void* basePtr)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.free(basePtr);
+#else
     Gigacage::alignedFree(m_kind, basePtr);
+#endif
 }
 
 void GigacageAlignedMemoryAllocator::dump(PrintStream& out) const
@@ -54,17 +65,29 @@ void GigacageAlignedMemoryAllocator::dump(PrintStream& out) const
 
 void* GigacageAlignedMemoryAllocator::tryAllocateMemory(size_t size)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.malloc(size);
+#else
     return Gigacage::tryMalloc(m_kind, size);
+#endif
 }
 
 void GigacageAlignedMemoryAllocator::freeMemory(void* pointer)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    m_heap.free(pointer);
+#else
     Gigacage::free(m_kind, pointer);
+#endif
 }
 
 void* GigacageAlignedMemoryAllocator::tryReallocateMemory(void* pointer, size_t size)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_heap.realloc(pointer, size);
+#else
     return Gigacage::tryRealloc(m_kind, pointer, size);
+#endif
 }
 
 } // namespace JSC
index 129d008..d453540 100644 (file)
 #include "AlignedMemoryAllocator.h"
 #include <wtf/Gigacage.h>
 
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+#include <wtf/DebugHeap.h>
+#endif
+
 namespace JSC {
 
 class GigacageAlignedMemoryAllocator : public AlignedMemoryAllocator {
@@ -46,6 +50,9 @@ public:
 
 private:
     Gigacage::Kind m_kind;
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    WTF::DebugHeap m_heap;
+#endif
 };
 
 } // namespace JSC
index 1774200..e3772a4 100644 (file)
 
 namespace JSC {
 
-IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator()
+IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator(CString name)
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    : m_debugHeap(name.data())
+#endif
 {
+    UNUSED_PARAM(name);
 }
 
 IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator()
 {
+#if !ENABLE(MALLOC_HEAP_BREAKDOWN)
     for (unsigned i = 0; i < m_blocks.size(); ++i) {
         void* block = m_blocks[i];
         if (!m_committed[i])
             WTF::fastCommitAlignedMemory(block, MarkedBlock::blockSize);
         fastAlignedFree(block);
     }
+#endif
 }
 
 void* IsoAlignedMemoryAllocator::tryAllocateAlignedMemory(size_t alignment, size_t size)
@@ -49,7 +55,10 @@ void* IsoAlignedMemoryAllocator::tryAllocateAlignedMemory(size_t alignment, size
     // allocate MarkedBlocks.
     RELEASE_ASSERT(alignment == MarkedBlock::blockSize);
     RELEASE_ASSERT(size == MarkedBlock::blockSize);
-    
+
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_debugHeap.memalign(MarkedBlock::blockSize, MarkedBlock::blockSize, true);
+#else
     auto locker = holdLock(m_lock);
     
     m_firstUncommitted = m_committed.findBit(m_firstUncommitted, false);
@@ -70,10 +79,14 @@ void* IsoAlignedMemoryAllocator::tryAllocateAlignedMemory(size_t alignment, size
         m_committed.resize(m_blocks.capacity());
     m_committed[index] = true;
     return result;
+#endif
 }
 
 void IsoAlignedMemoryAllocator::freeAlignedMemory(void* basePtr)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    m_debugHeap.free(basePtr);
+#else
     auto locker = holdLock(m_lock);
     
     auto iter = m_blockIndices.find(basePtr);
@@ -82,6 +95,7 @@ void IsoAlignedMemoryAllocator::freeAlignedMemory(void* basePtr)
     m_committed[index] = false;
     m_firstUncommitted = std::min(index, m_firstUncommitted);
     WTF::fastDecommitAlignedMemory(basePtr, MarkedBlock::blockSize);
+#endif
 }
 
 void IsoAlignedMemoryAllocator::dump(PrintStream& out) const
@@ -91,12 +105,20 @@ void IsoAlignedMemoryAllocator::dump(PrintStream& out) const
 
 void* IsoAlignedMemoryAllocator::tryAllocateMemory(size_t size)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    return m_debugHeap.malloc(size);
+#else
     return FastMalloc::tryMalloc(size);
+#endif
 }
 
 void IsoAlignedMemoryAllocator::freeMemory(void* pointer)
 {
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    m_debugHeap.free(pointer);
+#else
     FastMalloc::free(pointer);
+#endif
 }
 
 void* IsoAlignedMemoryAllocator::tryReallocateMemory(void*, size_t)
index e585d82..cdb7992 100644 (file)
 #pragma once
 
 #include "AlignedMemoryAllocator.h"
+#include <wtf/DebugHeap.h>
 #include <wtf/FastBitVector.h>
 #include <wtf/HashMap.h>
 #include <wtf/Vector.h>
 
+
 namespace JSC {
 
 class IsoAlignedMemoryAllocator : public AlignedMemoryAllocator {
 public:
-    IsoAlignedMemoryAllocator();
+    IsoAlignedMemoryAllocator(CString);
     ~IsoAlignedMemoryAllocator();
 
     void* tryAllocateAlignedMemory(size_t alignment, size_t size) override;
@@ -47,11 +49,16 @@ public:
     void* tryReallocateMemory(void*, size_t) override;
 
 private:
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+    // If breakdown is enabled, we do not ensure Iso-feature. This is totally OK since breakdown is memory bloat debugging feature.
+    WTF::DebugHeap m_debugHeap;
+#else
     Vector<void*> m_blocks;
     HashMap<void*, unsigned> m_blockIndices;
     FastBitVector m_committed;
     unsigned m_firstUncommitted { 0 };
     Lock m_lock;
+#endif
 };
 
 } // namespace JSC
index d1cf61f..6ec6211 100644 (file)
@@ -40,7 +40,7 @@ IsoSubspace::IsoSubspace(CString name, Heap& heap, HeapCellType* heapCellType, s
     : Subspace(name, heap)
     , m_directory(WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size))
     , m_localAllocator(&m_directory)
-    , m_isoAlignedMemoryAllocator(makeUnique<IsoAlignedMemoryAllocator>())
+    , m_isoAlignedMemoryAllocator(makeUnique<IsoAlignedMemoryAllocator>(name))
 {
     m_remainingLowerTierCellCount = numberOfLowerTierCells;
     ASSERT(WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size) == cellSize());
index 8e4f9bf..297024b 100644 (file)
@@ -45,6 +45,9 @@ static constexpr bool verbose = false;
 static constexpr bool computeBalance = false;
 static size_t balance;
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MarkedBlock);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MarkedBlockHandle);
+
 MarkedBlock::Handle* MarkedBlock::tryCreate(Heap& heap, AlignedMemoryAllocator* alignedMemoryAllocator)
 {
     if (computeBalance) {
index afccb8b..2ef0df1 100644 (file)
@@ -52,9 +52,11 @@ typedef uint32_t HeapVersion;
 // allocation suffers from internal fragmentation: wasted space whose
 // size is equal to the difference between the cell size and the object
 // size.
-
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MarkedBlock);
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MarkedBlockHandle);
 class MarkedBlock {
     WTF_MAKE_NONCOPYABLE(MarkedBlock);
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(MarkedBlock);
     friend class LLIntOffsetsExtractor;
     friend struct VerifyMarked;
 
@@ -105,7 +107,7 @@ public:
         
     class Handle {
         WTF_MAKE_NONCOPYABLE(Handle);
-        WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(MarkedBlockHandle);
         friend class LLIntOffsetsExtractor;
         friend class MarkedBlock;
         friend struct VerifyMarked;
index db21d03..0dc4cfa 100644 (file)
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(WeakBlock);
+
 WeakBlock* WeakBlock::create(Heap& heap, CellContainer container)
 {
     heap.didAllocateBlock(WeakBlock::blockSize);
-    return new (NotNull, fastMalloc(blockSize)) WeakBlock(container);
+    return new (NotNull, WeakBlockMalloc::malloc(blockSize)) WeakBlock(container);
+
 }
 
 void WeakBlock::destroy(Heap& heap, WeakBlock* block)
 {
     block->~WeakBlock();
-    fastFree(block);
+    WeakBlockMalloc::free(block);
     heap.didFreeBlock(WeakBlock::blockSize);
 }
 
index 1b25767..9d4b573 100644 (file)
@@ -35,6 +35,8 @@ namespace JSC {
 class Heap;
 class SlotVisitor;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(WeakBlock);
+
 class WeakBlock : public DoublyLinkedListNode<WeakBlock> {
 public:
     friend class WTF::DoublyLinkedListNode<WeakBlock>;
index 703b319..e3e0e69 100644 (file)
@@ -32,6 +32,8 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(DirectJITCode);
+
 JITCode::JITCode(JITType jitType, ShareAttribute shareAttribute)
     : m_jitType(jitType)
     , m_shareAttribute(shareAttribute)
index e8c4c46..4dd00ee 100644 (file)
@@ -237,7 +237,9 @@ protected:
     CodeRef<JSEntryPtrTag> m_ref;
 };
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(DirectJITCode);
 class DirectJITCode : public JITCodeWithCodeRef {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(DirectJITCode);
 public:
     DirectJITCode(JITType);
     DirectJITCode(CodeRef<JSEntryPtrTag>, CodePtr<JSEntryPtrTag> withArityCheck, JITType, JITCode::ShareAttribute = JITCode::ShareAttribute::NotShared);
index eb1f283..7b73b64 100644 (file)
@@ -31,7 +31,9 @@
 #include <wtf/ListDump.h>
 
 namespace JSC {
-    
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(RegisterAtOffsetList);
+
 RegisterAtOffsetList::RegisterAtOffsetList() { }
 
 RegisterAtOffsetList::RegisterAtOffsetList(RegisterSet registerSet, OffsetBaseType offsetBaseType)
index 173cf94..1bf8968 100644 (file)
@@ -32,8 +32,9 @@
 
 namespace JSC {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(RegisterAtOffsetList);
 class RegisterAtOffsetList {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(RegisterAtOffsetList);
 public:
     enum OffsetBaseType { FramePointerBased, ZeroBased };
 
index 15bdb56..30d7d6a 100644 (file)
@@ -33,6 +33,8 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ParserArenaRoot);
+
 // ------------------------------ StatementNode --------------------------------
 
 void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
index fad5328..39be52a 100644 (file)
@@ -128,8 +128,9 @@ namespace JSC {
     private: \
         typedef int __thisIsHereToForceASemicolonAfterThisMacro
 
+    DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ParserArenaRoot);
     class ParserArenaRoot {
-        WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(ParserArenaRoot);
     protected:
         ParserArenaRoot(ParserArena&);
 
index a276887..26be041 100644 (file)
@@ -31,6 +31,9 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(IdentifierArena);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ParserArena);
+
 ParserArena::ParserArena()
     : m_freeableMemory(0)
     , m_freeablePoolEnd(0)
@@ -50,11 +53,11 @@ inline void ParserArena::deallocateObjects()
         m_deletableObjects[i]->~ParserArenaDeletable();
 
     if (m_freeablePoolEnd)
-        fastFree(freeablePool());
+        ParserArenaMalloc::free(freeablePool());
 
     size = m_freeablePools.size();
     for (size_t i = 0; i < size; ++i)
-        fastFree(m_freeablePools[i]);
+        ParserArenaMalloc::free(m_freeablePools[i]);
 }
 
 ParserArena::~ParserArena()
@@ -67,7 +70,7 @@ void ParserArena::allocateFreeablePool()
     if (m_freeablePoolEnd)
         m_freeablePools.append(freeablePool());
 
-    char* pool = static_cast<char*>(fastMalloc(freeablePoolSize));
+    char* pool = static_cast<char*>(ParserArenaMalloc::malloc(freeablePoolSize));
     m_freeableMemory = pool;
     m_freeablePoolEnd = pool + freeablePoolSize;
     ASSERT(freeablePool() == pool);
index 1bef9ee..36dbbd4 100644 (file)
@@ -35,8 +35,9 @@ namespace JSC {
 
     class ParserArenaDeletable;
 
+    DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(IdentifierArena);
     class IdentifierArena {
-        WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(IdentifierArena);
     public:
         IdentifierArena()
         {
@@ -136,6 +137,8 @@ namespace JSC {
         return m_identifiers.last();
     }
 
+    DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ParserArena);
+
     class ParserArena {
         WTF_MAKE_NONCOPYABLE(ParserArena);
     public:
index 15f00f3..b3d2527 100644 (file)
@@ -31,6 +31,8 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StringSourceProvider);
+
 SourceProvider::SourceProvider(const SourceOrigin& sourceOrigin, URL&& url, const TextPosition& startPosition, SourceProviderSourceType sourceType)
     : m_sourceType(sourceType)
     , m_url(WTFMove(url))
index aabf007..33e39d1 100644 (file)
@@ -100,7 +100,9 @@ class UnlinkedFunctionCodeBlock;
         uintptr_t m_id { 0 };
     };
 
+    DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StringSourceProvider);
     class StringSourceProvider : public SourceProvider {
+        WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(StringSourceProvider);
     public:
         static Ref<StringSourceProvider> create(const String& source, const SourceOrigin& sourceOrigin, URL&& url, const TextPosition& startPosition = TextPosition(), SourceProviderSourceType sourceType = SourceProviderSourceType::Program)
         {
index ccc6727..e60b3df 100644 (file)
@@ -30,6 +30,9 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SourceProviderCache);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SourceProviderCacheItem);
+
 SourceProviderCache::~SourceProviderCache()
 {
     clear();
index 05a851f..bac379f 100644 (file)
@@ -31,8 +31,9 @@
 
 namespace JSC {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SourceProviderCache);
 class SourceProviderCache : public RefCounted<SourceProviderCache> {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(SourceProviderCache);
 public:
     SourceProviderCache() { }
     JS_EXPORT_PRIVATE ~SourceProviderCache();
index 7775b69..629a3fb 100644 (file)
@@ -57,8 +57,9 @@ struct SourceProviderCacheItemCreationParameters {
 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
 #endif
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SourceProviderCacheItem);
 class SourceProviderCacheItem {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(SourceProviderCacheItem);
 public:
     static std::unique_ptr<SourceProviderCacheItem> create(const SourceProviderCacheItemCreationParameters&);
     ~SourceProviderCacheItem();
@@ -112,7 +113,7 @@ inline std::unique_ptr<SourceProviderCacheItem> SourceProviderCacheItem::create(
 {
     size_t variableCount = parameters.usedVariables.size();
     size_t objectSize = sizeof(SourceProviderCacheItem) + sizeof(UniquedStringImpl*) * variableCount;
-    void* slot = fastMalloc(objectSize);
+    void* slot = SourceProviderCacheItemMalloc::malloc(objectSize);
     return std::unique_ptr<SourceProviderCacheItem>(new (slot) SourceProviderCacheItem(parameters));
 }
 
index f4ab9bc..78f3e9e 100644 (file)
@@ -37,7 +37,7 @@ CachePayload CachePayload::makeMappedPayload(FileSystem::MappedFileData&& data)
     return CachePayload(true, data.leakHandle(), data.size());
 }
 
-CachePayload CachePayload::makeMallocPayload(MallocPtr<uint8_t>&& data, size_t size)
+CachePayload CachePayload::makeMallocPayload(MallocPtr<uint8_t, VMMalloc>&& data, size_t size)
 {
     return CachePayload(false, data.leakPtr(), size);
 }
index 7eab589..1dca117 100644 (file)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "VM.h"
 #include <wtf/FileSystem.h>
 #include <wtf/MallocPtr.h>
 
@@ -33,7 +34,7 @@ namespace JSC {
 class CachePayload {
 public:
     JS_EXPORT_PRIVATE static CachePayload makeMappedPayload(FileSystem::MappedFileData&&);
-    JS_EXPORT_PRIVATE static CachePayload makeMallocPayload(MallocPtr<uint8_t>&&, size_t);
+    JS_EXPORT_PRIVATE static CachePayload makeMallocPayload(MallocPtr<uint8_t, VMMalloc>&&, size_t);
     JS_EXPORT_PRIVATE static CachePayload makeEmptyPayload();
 
     JS_EXPORT_PRIVATE CachePayload(CachePayload&&);
index d756139..b3cd1f8 100644 (file)
@@ -51,7 +51,7 @@ public:
         return adoptRef(*new CachedBytecode(CachePayload::makeMappedPayload(WTFMove(data)), WTFMove(leafExecutables)));
     }
 
-    static Ref<CachedBytecode> create(MallocPtr<uint8_t>&& data, size_t size, LeafExecutableMap&& leafExecutables)
+    static Ref<CachedBytecode> create(MallocPtr<uint8_t, VMMalloc>&& data, size_t size, LeafExecutableMap&& leafExecutables)
     {
         return adoptRef(*new CachedBytecode(CachePayload::makeMallocPayload(WTFMove(data), size), WTFMove(leafExecutables)));
     }
index ffb7459..9ad75ed 100644 (file)
@@ -40,6 +40,7 @@
 #include "UnlinkedModuleProgramCodeBlock.h"
 #include "UnlinkedProgramCodeBlock.h"
 #include <wtf/FastMalloc.h>
+#include <wtf/MallocPtr.h>
 #include <wtf/Optional.h>
 #include <wtf/UUID.h>
 #include <wtf/text/AtomStringImpl.h>
@@ -161,7 +162,7 @@ public:
         }
 
         size_t size = m_baseOffset + m_currentPage->size();
-        MallocPtr<uint8_t> buffer = MallocPtr<uint8_t>::malloc(size);
+        MallocPtr<uint8_t, VMMalloc> buffer = MallocPtr<uint8_t, VMMalloc>::malloc(size);
         unsigned offset = 0;
         for (const auto& page : m_pages) {
             memcpy(buffer.get() + offset, page.buffer(), page.size());
@@ -206,10 +207,9 @@ private:
     class Page {
     public:
         Page(size_t size)
-            : m_offset(0)
+            : m_buffer(MallocPtr<uint8_t, VMMalloc>::malloc(size))
             , m_capacity(size)
         {
-            m_buffer = MallocPtr<uint8_t>::malloc(size);
         }
 
         bool malloc(size_t size, ptrdiff_t& result)
@@ -248,8 +248,8 @@ private:
         }
 
     private:
-        MallocPtr<uint8_t> m_buffer;
-        ptrdiff_t m_offset;
+        MallocPtr<uint8_t, VMMalloc> m_buffer;
+        ptrdiff_t m_offset { 0 };
         size_t m_capacity;
     };
 
@@ -597,10 +597,10 @@ ptrdiff_t CachedWriteBarrierOffsets::ptrOffset()
     return OBJECT_OFFSETOF(CachedWriteBarrier<void>, m_ptr);
 }
 
-template<typename T, size_t InlineCapacity = 0, typename OverflowHandler = CrashOnOverflow>
-class CachedVector : public VariableLengthObject<Vector<SourceType<T>, InlineCapacity, OverflowHandler>> {
+template<typename T, size_t InlineCapacity = 0, typename OverflowHandler = CrashOnOverflow, typename Malloc = WTF::VectorMalloc>
+class CachedVector : public VariableLengthObject<Vector<SourceType<T>, InlineCapacity, OverflowHandler, 16, Malloc>> {
 public:
-    void encode(Encoder& encoder, const Vector<SourceType<T>, InlineCapacity, OverflowHandler>& vector)
+    void encode(Encoder& encoder, const Vector<SourceType<T>, InlineCapacity, OverflowHandler, 16, Malloc>& vector)
     {
         m_size = vector.size();
         if (!m_size)
@@ -611,7 +611,7 @@ public:
     }
 
     template<typename... Args>
-    void decode(Decoder& decoder, Vector<SourceType<T>, InlineCapacity, OverflowHandler>& vector, Args... args) const
+    void decode(Decoder& decoder, Vector<SourceType<T>, InlineCapacity, OverflowHandler, 16, Malloc>& vector, Args... args) const
     {
         if (!m_size)
             return;
@@ -1362,13 +1362,13 @@ public:
 
     InstructionStream* decode(Decoder& decoder) const
     {
-        Vector<uint8_t, 0, UnsafeVectorOverflow> instructionsVector;
+        Vector<uint8_t, 0, UnsafeVectorOverflow, 16, InstructionStreamMalloc> instructionsVector;
         m_instructions.decode(decoder, instructionsVector);
         return new InstructionStream(WTFMove(instructionsVector));
     }
 
 private:
-    CachedVector<uint8_t, 0, UnsafeVectorOverflow> m_instructions;
+    CachedVector<uint8_t, 0, UnsafeVectorOverflow, InstructionStreamMalloc> m_instructions;
 };
 
 class CachedMetadataTable : public CachedObject<UnlinkedMetadataTable> {
index e6734fa..cb6015c 100644 (file)
@@ -37,6 +37,8 @@
 
 namespace JSC {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(PropertyTable);
+
 #if DUMP_PROPERTYMAP_STATS
 
 struct PropertyMapHashTableStats {
@@ -514,14 +516,15 @@ inline void PropertyTable::rehash(unsigned newCapacity)
     m_indexMask = m_indexSize - 1;
     m_keyCount = 0;
     m_deletedCount = 0;
-    m_index = static_cast<unsigned*>(fastZeroedMalloc(dataSize()));
+
+    m_index = static_cast<unsigned*>(PropertyTableMalloc::zeroedMalloc(dataSize()));
 
     for (; iter != end; ++iter) {
         ASSERT(canInsert());
         reinsert(*iter);
     }
 
-    fastFree(oldEntryIndices);
+    PropertyTableMalloc::free(oldEntryIndices);
 }
 
 inline unsigned PropertyTable::tableCapacity() const { return m_indexSize >> 1; }
index b1bb679..da2a814 100644 (file)
@@ -30,6 +30,8 @@
 
 namespace JSC {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(PropertyTable);
+
 const ClassInfo PropertyTable::s_info = { "PropertyTable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(PropertyTable) };
 
 PropertyTable* PropertyTable::create(VM& vm, unsigned initialCapacity)
@@ -57,7 +59,7 @@ PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity)
     : JSCell(vm, vm.propertyTableStructure.get())
     , m_indexSize(sizeForCapacity(initialCapacity))
     , m_indexMask(m_indexSize - 1)
-    , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
+    , m_index(static_cast<unsigned*>(PropertyTableMalloc::zeroedMalloc(dataSize())))
     , m_keyCount(0)
     , m_deletedCount(0)
 {
@@ -68,7 +70,7 @@ PropertyTable::PropertyTable(VM& vm, const PropertyTable& other)
     : JSCell(vm, vm.propertyTableStructure.get())
     , m_indexSize(other.m_indexSize)
     , m_indexMask(other.m_indexMask)
-    , m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
+    , m_index(static_cast<unsigned*>(PropertyTableMalloc::malloc(dataSize())))
     , m_keyCount(other.m_keyCount)
     , m_deletedCount(other.m_deletedCount)
 {
@@ -90,7 +92,7 @@ PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity, const PropertyTab
     : JSCell(vm, vm.propertyTableStructure.get())
     , m_indexSize(sizeForCapacity(initialCapacity))
     , m_indexMask(m_indexSize - 1)
-    , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
+    , m_index(static_cast<unsigned*>(PropertyTableMalloc::zeroedMalloc(dataSize())))
     , m_keyCount(0)
     , m_deletedCount(0)
 {
@@ -121,7 +123,8 @@ PropertyTable::~PropertyTable()
     for (iterator iter = begin(); iter != end; ++iter)
         iter->key->deref();
 
-    fastFree(m_index);
+    PropertyTableMalloc::free(m_index);
+
 }
 
 } // namespace JSC
index b036377..bc49dc9 100644 (file)
@@ -39,6 +39,8 @@ namespace JSC {
 
 const ClassInfo SymbolTable::s_info = { "SymbolTable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(SymbolTable) };
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SymbolTableEntryFatEntry);
+
 SymbolTableEntry& SymbolTableEntry::copySlow(const SymbolTableEntry& other)
 {
     ASSERT(other.isFat());
index 1e4c64c..1c386ec 100644 (file)
@@ -44,6 +44,8 @@ namespace JSC {
 
 class SymbolTable;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SymbolTableEntryFatEntry);
+
 static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
 
 // The bit twiddling in this class assumes that every register index is a
@@ -332,7 +334,7 @@ private:
     static const intptr_t FlagBits = 6;
     
     class FatEntry {
-        WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(SymbolTableEntryFatEntry);
     public:
         FatEntry(intptr_t bits)
             : m_bits(bits & ~SlimFlag)
index 81d4064..52b7bbd 100644 (file)
@@ -227,6 +227,8 @@ bool VM::s_canUseJIT = false;
 
 Atomic<unsigned> VM::s_numberOfIDs;
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(VM);
+
 // Note: Platform.h will enforce that ENABLE(ASSEMBLER) is true if either
 // ENABLE(JIT) or ENABLE(YARR_JIT) or both are enabled. The code below
 // just checks for ENABLE(JIT) or ENABLE(YARR_JIT) with this premise in mind.
@@ -654,7 +656,7 @@ VM::~VM()
 
 #if ENABLE(DFG_JIT)
     for (unsigned i = 0; i < m_scratchBuffers.size(); ++i)
-        fastFree(m_scratchBuffers[i]);
+        VMMalloc::free(m_scratchBuffers[i]);
 #endif
 }
 
index f658382..c9ad516 100644 (file)
@@ -251,6 +251,8 @@ private:
 
 class ConservativeRoots;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(VM);
+
 #if COMPILER(MSVC)
 #pragma warning(push)
 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
@@ -263,8 +265,7 @@ struct ScratchBuffer {
 
     static ScratchBuffer* create(size_t size)
     {
-        ScratchBuffer* result = new (fastMalloc(ScratchBuffer::allocationSize(size))) ScratchBuffer;
-
+        ScratchBuffer* result = new (VMMalloc::malloc(ScratchBuffer::allocationSize(size))) ScratchBuffer;
         return result;
     }
 
@@ -952,7 +953,7 @@ public:
     {
         ASSERT(Options::useExceptionFuzz());
         if (!m_exceptionFuzzBuffer)
-            m_exceptionFuzzBuffer = MallocPtr<EncodedJSValue>::malloc(size);
+            m_exceptionFuzzBuffer = MallocPtr<EncodedJSValue, VMMalloc>::malloc(size);
         return m_exceptionFuzzBuffer.get();
     }
 
@@ -1220,7 +1221,7 @@ private:
     std::unique_ptr<ControlFlowProfiler> m_controlFlowProfiler;
     unsigned m_controlFlowProfilerEnabledCount;
     Deque<std::unique_ptr<QueuedTask>> m_microtaskQueue;
-    MallocPtr<EncodedJSValue> m_exceptionFuzzBuffer;
+    MallocPtr<EncodedJSValue, VMMalloc> m_exceptionFuzzBuffer;
     VMTraps m_traps;
     RefPtr<Watchdog> m_watchdog;
     std::unique_ptr<HeapProfiler> m_heapProfiler;
index 9b2db41..a6ed9c0 100644 (file)
@@ -47,7 +47,7 @@ size_t globalMemoryByteSize(Module& module)
 Instance::Instance(Context* context, Ref<Module>&& module, EntryFrame** pointerToTopEntryFrame, void** pointerToActualStackLimit, StoreTopCallFrameCallback&& storeTopCallFrame)
     : m_context(context)
     , m_module(WTFMove(module))
-    , m_globals(MallocPtr<Global::Value>::malloc(globalMemoryByteSize(m_module.get())))
+    , m_globals(MallocPtr<Global::Value, VMMalloc>::malloc(globalMemoryByteSize(m_module.get())))
     , m_globalsToMark(m_module.get().moduleInformation().globals.size())
     , m_globalsToBinding(m_module.get().moduleInformation().globals.size())
     , m_pointerToTopEntryFrame(pointerToTopEntryFrame)
index 76a884c..60e5619 100644 (file)
@@ -206,7 +206,7 @@ private:
     RefPtr<CodeBlock> m_codeBlock;
     RefPtr<Memory> m_memory;
 
-    MallocPtr<Global::Value> m_globals;
+    MallocPtr<Global::Value, VMMalloc> m_globals;
     FunctionWrapperMap m_functionWrappers;
     BitVector m_globalsToMark;
     BitVector m_globalsToBinding;
index 5f60ae2..6a913e1 100644 (file)
@@ -59,7 +59,7 @@ Table::Table(uint32_t initial, Optional<uint32_t> maximum, TableElementType type
     // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
     // But for now, we're not doing that.
     // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425
-    m_jsValues = MallocPtr<WriteBarrier<Unknown>>::malloc((sizeof(WriteBarrier<Unknown>) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());
+    m_jsValues = MallocPtr<WriteBarrier<Unknown>, VMMalloc>::malloc((sizeof(WriteBarrier<Unknown>) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());
     for (uint32_t i = 0; i < allocatedLength(m_length); ++i) {
         new (&m_jsValues.get()[i]) WriteBarrier<Unknown>();
         m_jsValues.get()[i].setStartingValue(jsNull());
@@ -177,9 +177,9 @@ FuncRefTable::FuncRefTable(uint32_t initial, Optional<uint32_t> maximum)
 {
     // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
     // But for now, we're not doing that.
-    m_importableFunctions = MallocPtr<WasmToWasmImportableFunction>::malloc((sizeof(WasmToWasmImportableFunction) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());
+    m_importableFunctions = MallocPtr<WasmToWasmImportableFunction, VMMalloc>::malloc((sizeof(WasmToWasmImportableFunction) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());
     // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425
-    m_instances = MallocPtr<Instance*>::malloc((sizeof(Instance*) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());
+    m_instances = MallocPtr<Instance*, VMMalloc>::malloc((sizeof(Instance*) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());
     for (uint32_t i = 0; i < allocatedLength(m_length); ++i) {
         new (&m_importableFunctions.get()[i]) WasmToWasmImportableFunction();
         ASSERT(m_importableFunctions.get()[i].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
index 1a610e5..164e6ae 100644 (file)
@@ -89,7 +89,7 @@ protected:
     const TableElementType m_type;
     const Optional<uint32_t> m_maximum;
 
-    MallocPtr<WriteBarrier<Unknown>> m_jsValues;
+    MallocPtr<WriteBarrier<Unknown>, VMMalloc> m_jsValues;
     JSObject* m_owner;
 };
 
@@ -107,9 +107,9 @@ public:
 private:
     FuncRefTable(uint32_t initial, Optional<uint32_t> maximum);
 
-    MallocPtr<WasmToWasmImportableFunction> m_importableFunctions;
+    MallocPtr<WasmToWasmImportableFunction, VMMalloc> m_importableFunctions;
     // call_indirect needs to do an Instance check to potentially context switch when calling a function to another instance. We can hold raw pointers to Instance here because the embedder ensures that Table keeps all the instances alive. We couldn't hold a Ref here because it would cause cycles.
-    MallocPtr<Instance*> m_instances;
+    MallocPtr<Instance*, VMMalloc> m_instances;
 
     friend class Table;
 };
index 4eadcac..df2dbdc 100644 (file)
@@ -1,3 +1,237 @@
+2020-01-02  Yusuke Suzuki  <ysuzuki@apple.com> and Simon Fraser  <simon.fraser@apple.com>
+
+        Experiment: create lots of different malloc zones for easier accounting of memory use
+        https://bugs.webkit.org/show_bug.cgi?id=186422
+
+        Reviewed by Saam Barati.
+
+        This patch introduces ENABLE(MALLOC_HEAP_BREAKDOWN). If this is enabled, we allocate malloc_zone per malloc kind.
+        This offers the way to investigate the usage of memory per kind by using vmmap, like the following.
+
+            VIRTUAL   RESIDENT      DIRTY    SWAPPED ALLOCATION      BYTES DIRTY+SWAP          REGION
+            MALLOC ZONE                                                      SIZE       SIZE       SIZE       SIZE      COUNT  ALLOCATED  FRAG SIZE  % FRAG   COUNT
+            ===========                                                   =======  =========  =========  =========  =========  =========  =========  ======  ======
+            StringImpl_0x116efd000                                         188.0M      69.3M      30.9M         0K     139456      18.0M      12.9M     42%      34
+            DefaultMallocZone_0x10f487000                                  176.0M      53.9M      14.1M         0K     115956      9955K      4497K     32%      22
+            Vector_0x116eff000                                             162.0M      56.3M      55.3M         0K     140715      17.3M      37.9M     69%      36
+            MetadataTable_0x11843b000                                      152.0M      17.5M      17.5M         0K      14200      2353K      15.2M     87%      26
+            WebKit Using System Malloc_0x114cbe000                         150.0M      31.6M      21.8M         0K      87422      16.7M      5278K     24%      23
+            InstructionStream_0x118469000                                  150.0M      5764K      5764K         0K      14470      4688K      1076K     19%      24
+            AssemblerData_0x117ee6000                                      150.0M      1928K      1928K         0K          1         16      1928K    100%      24
+
+        To achieve this goal without making very large change, we put a template type in various containers.
+        For example, Vector will take Malloc parameter (the default one is FastMalloc allocator). If ENABLE(MALLOC_HEAP_BREAKDOWN) is enabled, we change this to
+        specific VectorMalloc allocator, and vmmap can show memory usage of this allocator. This patch also supports malloc_zone per IsoHeap. So we can see memory
+        allocation per IsoHeap in vmmap.
+
+        To use this feature, we need to flip two compile time flags, ENABLE(MALLOC_HEAP_BREAKDOWN) in WTF and BENABLE_MALLOC_HEAP_BREAKDOWN in bmalloc.
+        And use `vmmap $PID` to dump malloc zones. To allocate objects of a class with a specific malloc-zone, use WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(HeapIdentifier) for the class,
+        and define allocator by DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HeapIdentifier) in a header and DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HeapIdentifier) in a cpp file.
+
+        This patch also introduce callstack collector for malloc. Vector, HashMap etc. are used to allocate various things, but the above malloc_zone feature only tells thing like "Vector
+        takes XXX MB memory". But what we want to know in this case is what Vector is consuming memory. We collect StackShot for each malloc call, and combine these information to tell
+        which callsite is consuming much memory, which tell us that what Vector is consuming memory.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/Bag.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
+        * wtf/Bag.h:
+        (WTF::Private::BagNode::BagNode): Deleted.
+        * wtf/BitVector.cpp:
+        (WTF::BitVector::OutOfLineBits::create):
+        (WTF::BitVector::OutOfLineBits::destroy):
+        * wtf/CMakeLists.txt:
+        * wtf/ConcurrentBuffer.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
+        * wtf/ConcurrentBuffer.h:
+        * wtf/DebugHeap.cpp: Copied from Source/JavaScriptCore/runtime/CachePayload.cpp.
+        (WTF::DebugHeap::DebugHeap):
+        (WTF::DebugHeap::malloc):
+        (WTF::DebugHeap::calloc):
+        (WTF::DebugHeap::memalign):
+        (WTF::DebugHeap::realloc):
+        (WTF::DebugHeap::free):
+        * wtf/DebugHeap.h: Added.
+        * wtf/FastBitVector.cpp:
+        (WTF::FastBitVectorWordOwner::setEqualsSlow):
+        (WTF::FastBitVectorWordOwner::resizeSlow):
+        * wtf/FastBitVector.h:
+        (WTF::FastBitVectorWordOwner::~FastBitVectorWordOwner):
+        * wtf/FastMalloc.cpp:
+        (WTF::fastMallocDumpMallocStats):
+        (WTF::AvoidRecordingScope::AvoidRecordingScope):
+        (WTF::AvoidRecordingScope::~AvoidRecordingScope):
+        (WTF::MallocCallTracker::MallocSiteData::MallocSiteData):
+        (WTF::MallocCallTracker::singleton):
+        (WTF::MallocCallTracker::MallocCallTracker):
+        (WTF::MallocCallTracker::recordMalloc):
+        (WTF::MallocCallTracker::recordRealloc):
+        (WTF::MallocCallTracker::recordFree):
+        (WTF::MallocCallTracker::dumpStats):
+        (WTF::fastMalloc):
+        (WTF::fastRealloc):
+        (WTF::fastFree):
+        (WTF::fastAlignedMalloc):
+        (WTF::tryFastAlignedMalloc):
+        (WTF::fastAlignedFree):
+        * wtf/FastMalloc.h:
+        (WTF::FastMalloc::zeroedMalloc):
+        (WTF::FastMalloc::tryZeroedMalloc):
+        * wtf/Forward.h:
+        * wtf/HashTable.cpp:
+        * wtf/HashTable.h:
+        (WTF::KeyTraits>::allocateTable):
+        (WTF::KeyTraits>::deallocateTable):
+        (WTF::KeyTraits>::rehash):
+        * wtf/MallocPtr.h:
+        (WTF::MallocPtr::MallocPtr):
+        (WTF::MallocPtr::malloc):
+        (WTF::MallocPtr::zeroedMalloc):
+        (WTF::MallocPtr::tryMalloc):
+        (WTF::MallocPtr::tryZeroedMalloc):
+        (WTF::adoptMallocPtr):
+        * wtf/MetaAllocator.cpp:
+        (WTF::MetaAllocator::allocFreeSpaceNode):
+        (WTF::MetaAllocator::freeFreeSpaceNode):
+        * wtf/MetaAllocatorHandle.h:
+        * wtf/Platform.h:
+        * wtf/RefCountedArray.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
+        * wtf/RefCountedArray.h:
+        (WTF::RefCountedArray::RefCountedArray):
+        (WTF::RefCountedArray::~RefCountedArray):
+        (WTF::RefCountedArray::assign):
+        * wtf/SegmentedVector.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
+        * wtf/SegmentedVector.h:
+        * wtf/SmallPtrSet.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
+        * wtf/SmallPtrSet.h:
+        (WTF::SmallPtrSet::~SmallPtrSet):
+        (WTF::SmallPtrSet::grow):
+        * wtf/UniqueArray.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
+        * wtf/UniqueArray.h:
+        (WTF::UniqueArrayFree::operator() const):
+        (WTF::UniqueArrayFree<T::operator() const):
+        * wtf/Vector.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
+        * wtf/Vector.h:
+        (WTF::VectorBufferBase::allocateBuffer):
+        (WTF::VectorBufferBase::tryAllocateBuffer):
+        (WTF::VectorBufferBase::reallocateBuffer):
+        (WTF::VectorBufferBase::deallocateBuffer):
+        (WTF::VectorBufferBase::releaseBuffer):
+        (WTF::VectorBuffer::releaseBuffer):
+        (WTF::Vector::swap):
+        (WTF::Malloc>::Vector):
+        (WTF::=):
+        (WTF::Malloc>::contains const):
+        (WTF::Malloc>::findMatching const):
+        (WTF::Malloc>::find const):
+        (WTF::Malloc>::reverseFind const):
+        (WTF::Malloc>::appendIfNotContains):
+        (WTF::Malloc>::fill):
+        (WTF::Malloc>::appendRange):
+        (WTF::Malloc>::expandCapacity):
+        (WTF::Malloc>::tryExpandCapacity):
+        (WTF::Malloc>::resize):
+        (WTF::Malloc>::resizeToFit):
+        (WTF::Malloc>::shrink):
+        (WTF::Malloc>::grow):
+        (WTF::Malloc>::asanSetInitialBufferSizeTo):
+        (WTF::Malloc>::asanSetBufferSizeToFullCapacity):
+        (WTF::Malloc>::asanBufferSizeWillChangeTo):
+        (WTF::Malloc>::reserveCapacity):
+        (WTF::Malloc>::tryReserveCapacity):
+        (WTF::Malloc>::reserveInitialCapacity):
+        (WTF::Malloc>::shrinkCapacity):
+        (WTF::Malloc>::append):
+        (WTF::Malloc>::tryAppend):
+        (WTF::Malloc>::constructAndAppend):
+        (WTF::Malloc>::tryConstructAndAppend):
+        (WTF::Malloc>::appendSlowCase):
+        (WTF::Malloc>::constructAndAppendSlowCase):
+        (WTF::Malloc>::tryConstructAndAppendSlowCase):
+        (WTF::Malloc>::uncheckedAppend):
+        (WTF::Malloc>::uncheckedConstructAndAppend):
+        (WTF::Malloc>::appendVector):
+        (WTF::Malloc>::insert):
+        (WTF::Malloc>::insertVector):
+        (WTF::Malloc>::remove):
+        (WTF::Malloc>::removeFirst):
+        (WTF::Malloc>::removeFirstMatching):
+        (WTF::Malloc>::removeAll):
+        (WTF::Malloc>::removeAllMatching):
+        (WTF::Malloc>::reverse):
+        (WTF::Malloc>::map const):
+        (WTF::Malloc>::releaseBuffer):
+        (WTF::Malloc>::checkConsistency):
+        (WTF::swap):
+        (WTF::operator==):
+        (WTF::operator!=):
+        (WTF::Malloc>::isolatedCopy const):
+        (WTF::removeRepeatedElements):
+        (WTF::minCapacity>::Vector): Deleted.
+        (WTF::minCapacity>::contains const): Deleted.
+        (WTF::minCapacity>::findMatching const): Deleted.
+        (WTF::minCapacity>::find const): Deleted.
+        (WTF::minCapacity>::reverseFind const): Deleted.
+        (WTF::minCapacity>::appendIfNotContains): Deleted.
+        (WTF::minCapacity>::fill): Deleted.
+        (WTF::minCapacity>::appendRange): Deleted.
+        (WTF::minCapacity>::expandCapacity): Deleted.
+        (WTF::minCapacity>::tryExpandCapacity): Deleted.
+        (WTF::minCapacity>::resize): Deleted.
+        (WTF::minCapacity>::resizeToFit): Deleted.
+        (WTF::minCapacity>::shrink): Deleted.
+        (WTF::minCapacity>::grow): Deleted.
+        (WTF::minCapacity>::asanSetInitialBufferSizeTo): Deleted.
+        (WTF::minCapacity>::asanSetBufferSizeToFullCapacity): Deleted.
+        (WTF::minCapacity>::asanBufferSizeWillChangeTo): Deleted.
+        (WTF::minCapacity>::reserveCapacity): Deleted.
+        (WTF::minCapacity>::tryReserveCapacity): Deleted.
+        (WTF::minCapacity>::reserveInitialCapacity): Deleted.
+        (WTF::minCapacity>::shrinkCapacity): Deleted.
+        (WTF::minCapacity>::append): Deleted.
+        (WTF::minCapacity>::tryAppend): Deleted.
+        (WTF::minCapacity>::constructAndAppend): Deleted.
+        (WTF::minCapacity>::tryConstructAndAppend): Deleted.
+        (WTF::minCapacity>::appendSlowCase): Deleted.
+        (WTF::minCapacity>::constructAndAppendSlowCase): Deleted.
+        (WTF::minCapacity>::tryConstructAndAppendSlowCase): Deleted.
+        (WTF::minCapacity>::uncheckedAppend): Deleted.
+        (WTF::minCapacity>::uncheckedConstructAndAppend): Deleted.
+        (WTF::minCapacity>::appendVector): Deleted.
+        (WTF::minCapacity>::insert): Deleted.
+        (WTF::minCapacity>::insertVector): Deleted.
+        (WTF::minCapacity>::remove): Deleted.
+        (WTF::minCapacity>::removeFirst): Deleted.
+        (WTF::minCapacity>::removeFirstMatching): Deleted.
+        (WTF::minCapacity>::removeAll): Deleted.
+        (WTF::minCapacity>::removeAllMatching): Deleted.
+        (WTF::minCapacity>::reverse): Deleted.
+        (WTF::minCapacity>::map const): Deleted.
+        (WTF::minCapacity>::releaseBuffer): Deleted.
+        (WTF::minCapacity>::checkConsistency): Deleted.
+        (WTF::minCapacity>::isolatedCopy const): Deleted.
+        * wtf/text/CString.cpp:
+        (WTF::CStringBuffer::createUninitialized):
+        * wtf/text/CString.h:
+        * wtf/text/StringBuffer.cpp: Copied from Source/JavaScriptCore/bytecode/InstructionStream.cpp.
+        * wtf/text/StringBuffer.h:
+        (WTF::StringBuffer::StringBuffer):
+        (WTF::StringBuffer::~StringBuffer):
+        (WTF::StringBuffer::resize):
+        (WTF::StringBuffer::release):
+        * wtf/text/StringImpl.cpp:
+        (WTF::StringImpl::~StringImpl):
+        (WTF::StringImpl::destroy):
+        (WTF::StringImpl::createUninitializedInternalNonEmpty):
+        (WTF::StringImpl::reallocateInternal):
+        * wtf/text/StringImpl.h:
+        (WTF::StringImpl::StringImpl):
+        (WTF::StringImpl::createSubstringSharingImpl):
+        (WTF::StringImpl::tryCreateUninitialized):
+        (WTF::StringImpl::adopt):
+        * wtf/text/cf/StringImplCF.cpp:
+        (WTF::StringWrapperCFAllocator::allocate):
+        (WTF::StringWrapperCFAllocator::reallocate):
+        (WTF::StringWrapperCFAllocator::deallocate):
+
 2020-01-02  Dean Jackson  <dino@apple.com>
 
         REGRESSION(r253926): Crash at libANGLE-shared.dylib: gl::LogMessage::~LogMessage
index 7f43daf..d0040c9 100644 (file)
                0F824A681B7443A0002E345D /* ParkingLot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F824A641B7443A0002E345D /* ParkingLot.cpp */; };
                0F8E85DB1FD485B000691889 /* CountingLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8E85DA1FD485B000691889 /* CountingLock.cpp */; };
                0F8F2B92172E0103007DBDA5 /* CompilationThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F2B8F172E00F0007DBDA5 /* CompilationThread.cpp */; };
+               0F95B63320CB4B7700479635 /* DebugHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F95B63220CB4B7700479635 /* DebugHeap.cpp */; };
+               0F95B63720CB5EFD00479635 /* StringBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F95B63620CB5EFD00479635 /* StringBuffer.cpp */; };
                0F9D3360165DBA73005AD387 /* FilePrintStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D335B165DBA73005AD387 /* FilePrintStream.cpp */; };
                0F9D3362165DBA73005AD387 /* PrintStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D335D165DBA73005AD387 /* PrintStream.cpp */; };
+               0FA6F38F20CC580F00A03DCD /* SegmentedVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA6F38E20CC580E00A03DCD /* SegmentedVector.cpp */; };
+               0FA6F39320CC73A300A03DCD /* SmallPtrSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA6F39220CC73A200A03DCD /* SmallPtrSet.cpp */; };
+               0FA6F39520CCACE900A03DCD /* UniqueArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA6F39420CCACE900A03DCD /* UniqueArray.cpp */; };
                0FDDBFA71666DFA300C55FEF /* StringPrintStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDDBFA51666DFA300C55FEF /* StringPrintStream.cpp */; };
                0FE1646A1B6FFC9600400E7C /* Lock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE164681B6FFC9600400E7C /* Lock.cpp */; };
                0FE4479C1B7AAA03009498EB /* WordLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE4479A1B7AAA03009498EB /* WordLock.cpp */; };
                DCEE22011CEA7551000C2396 /* BlockObjCExceptions.mm in Sources */ = {isa = PBXBuildFile; fileRef = DCEE21FD1CEA7551000C2396 /* BlockObjCExceptions.mm */; };
                E15556F518A0CC18006F48FB /* CryptographicUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E15556F318A0CC18006F48FB /* CryptographicUtilities.cpp */; };
                E311FB171F0A568B003C08DE /* ThreadGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E311FB151F0A568B003C08DE /* ThreadGroup.cpp */; };
+               E3149A37228BB42200BFA6C7 /* Bag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEBA64120CF37100074941C /* Bag.cpp */; };
+               E3149A38228BB42C00BFA6C7 /* RefCountedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA6F39020CC61EB00A03DCD /* RefCountedArray.cpp */; };
+               E3149A39228BB43500BFA6C7 /* Vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F95B63420CB53C100479635 /* Vector.cpp */; };
+               E3149A3B228BDCAC00BFA6C7 /* ConcurrentBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3149A3A228BDCAB00BFA6C7 /* ConcurrentBuffer.cpp */; };
                E388886F20C9095100E632BC /* WorkerPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E388886D20C9095100E632BC /* WorkerPool.cpp */; };
                E38C41251EB4E04C0042957D /* CPUTimeCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38C41241EB4E04C0042957D /* CPUTimeCocoa.cpp */; };
                E38C41281EB4E0680042957D /* CPUTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38C41261EB4E0680042957D /* CPUTime.cpp */; };
                0F8F2B9B172F2594007DBDA5 /* ConversionMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConversionMode.h; sourceTree = "<group>"; };
                0F93274A1C17F4B700CF6564 /* Box.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box.h; sourceTree = "<group>"; };
                0F9495831C571CC900413A48 /* OrderMaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OrderMaker.h; sourceTree = "<group>"; };
+               0F95B63120CB4B7700479635 /* DebugHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugHeap.h; sourceTree = "<group>"; };
+               0F95B63220CB4B7700479635 /* DebugHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebugHeap.cpp; sourceTree = "<group>"; };
+               0F95B63420CB53C100479635 /* Vector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vector.cpp; sourceTree = "<group>"; };
+               0F95B63620CB5EFD00479635 /* StringBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringBuffer.cpp; sourceTree = "<group>"; };
                0F9D335B165DBA73005AD387 /* FilePrintStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilePrintStream.cpp; sourceTree = "<group>"; };
                0F9D335C165DBA73005AD387 /* FilePrintStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilePrintStream.h; sourceTree = "<group>"; };
                0F9D335D165DBA73005AD387 /* PrintStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrintStream.cpp; sourceTree = "<group>"; };
                0F9D335E165DBA73005AD387 /* PrintStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrintStream.h; sourceTree = "<group>"; };
                0F9DAA041FD1C37B0079C5B2 /* StackShot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackShot.h; sourceTree = "<group>"; };
                0F9DAA051FD1C37B0079C5B2 /* StackShotProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackShotProfiler.h; sourceTree = "<group>"; };
+               0FA6F38E20CC580E00A03DCD /* SegmentedVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SegmentedVector.cpp; sourceTree = "<group>"; };
+               0FA6F39020CC61EB00A03DCD /* RefCountedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefCountedArray.cpp; sourceTree = "<group>"; };
+               0FA6F39220CC73A200A03DCD /* SmallPtrSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SmallPtrSet.cpp; sourceTree = "<group>"; };
+               0FA6F39420CCACE900A03DCD /* UniqueArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UniqueArray.cpp; sourceTree = "<group>"; };
                0FB14E18180FA218009B6B4D /* Bag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bag.h; sourceTree = "<group>"; };
                0FB14E1A1810E1DA009B6B4D /* BagToHashMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BagToHashMap.h; sourceTree = "<group>"; };
                0FB317C31C488001007E395A /* SystemTracing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemTracing.h; sourceTree = "<group>"; };
                0FE4479B1B7AAA03009498EB /* WordLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WordLock.h; sourceTree = "<group>"; };
                0FEB3DCE1BB5D684009D7AAD /* SharedTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedTask.h; sourceTree = "<group>"; };
                0FEB3DD01BB7366B009D7AAD /* ParallelVectorIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParallelVectorIterator.h; sourceTree = "<group>"; };
+               0FEBA64120CF37100074941C /* Bag.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Bag.cpp; sourceTree = "<group>"; };
                0FEC3C4F1F323C6800F59B6C /* CagedPtr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CagedPtr.h; sourceTree = "<group>"; };
                0FEC3C5C1F368A9700F59B6C /* ReadWriteLock.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ReadWriteLock.cpp; sourceTree = "<group>"; };
                0FEC3C5D1F368A9700F59B6C /* ReadWriteLock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReadWriteLock.h; sourceTree = "<group>"; };
                E300E521203D645F00DA79BE /* UniqueArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UniqueArray.h; sourceTree = "<group>"; };
                E311FB151F0A568B003C08DE /* ThreadGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadGroup.cpp; sourceTree = "<group>"; };
                E311FB161F0A568B003C08DE /* ThreadGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadGroup.h; sourceTree = "<group>"; };
+               E3149A3A228BDCAB00BFA6C7 /* ConcurrentBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConcurrentBuffer.cpp; sourceTree = "<group>"; };
                E31BDE2822E913CC0029B105 /* MachVMSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachVMSPI.h; sourceTree = "<group>"; };
                E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRegisters.h; sourceTree = "<group>"; };
                E33D5F871FBED66700BF625E /* RecursableLambda.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecursableLambda.h; sourceTree = "<group>"; };
                                0F43D8EF1DB5ADDC00108FB6 /* AutomaticThread.cpp */,
                                0F43D8F01DB5ADDC00108FB6 /* AutomaticThread.h */,
                                DCEE22041CEB9869000C2396 /* BackwardsGraph.h */,
+                               0FEBA64120CF37100074941C /* Bag.cpp */,
                                0FB14E18180FA218009B6B4D /* Bag.h */,
                                0FB14E1A1810E1DA009B6B4D /* BagToHashMap.h */,
                                A8A4725F151A825A004123FF /* Bitmap.h */,
                                0F8F2B90172E00F0007DBDA5 /* CompilationThread.h */,
                                A8A47270151A825A004123FF /* Compiler.h */,
                                46BA9EAB1F4CD61E009A2BBC /* CompletionHandler.h */,
+                               E3149A3A228BDCAB00BFA6C7 /* ConcurrentBuffer.cpp */,
                                0FB467821FDE282B003FCB09 /* ConcurrentBuffer.h */,
                                0F30CB581FCDF133004B5323 /* ConcurrentPtrHashSet.cpp */,
                                0F30CB591FCDF133004B5323 /* ConcurrentPtrHashSet.h */,
                                A8A47278151A825A004123FF /* DataLog.h */,
                                A8A47279151A825A004123FF /* DateMath.cpp */,
                                A8A4727A151A825A004123FF /* DateMath.h */,
+                               0F95B63220CB4B7700479635 /* DebugHeap.cpp */,
+                               0F95B63120CB4B7700479635 /* DebugHeap.h */,
                                996B17841EBA441C007E10EB /* DebugUtilities.h */,
                                0F2B66A417B6B4F700A7AE3F /* DeferrableRefCounted.h */,
                                A8A4727E151A825A004123FF /* Deque.h */,
                                26299B6D17A9E5B800ADEBE5 /* Ref.h */,
                                46BEB6E922FFDDD500269867 /* RefCounted.cpp */,
                                A8A472FF151A825B004123FF /* RefCounted.h */,
+                               0FA6F39020CC61EB00A03DCD /* RefCountedArray.cpp */,
                                A8A47300151A825B004123FF /* RefCountedArray.h */,
                                A8A47301151A825B004123FF /* RefCountedLeakCounter.cpp */,
                                A8A47302151A825B004123FF /* RefCountedLeakCounter.h */,
                                0FEC84B01BDACD390080FF74 /* ScopedLambda.h */,
                                0F66B2841DC97BAB004A1D3F /* Seconds.cpp */,
                                0F66B2851DC97BAB004A1D3F /* Seconds.h */,
+                               0FA6F38E20CC580E00A03DCD /* SegmentedVector.cpp */,
                                A8A47306151A825B004123FF /* SegmentedVector.h */,
                                A8A47307151A825B004123FF /* SentinelLinkedList.h */,
                                A8A4731A151A825B004123FF /* SetForScope.h */,
                                A748744F17A0BDAE00FA04CB /* SixCharacterHash.cpp */,
                                A748745017A0BDAE00FA04CB /* SixCharacterHash.h */,
                                A8A4730C151A825B004123FF /* SizeLimits.cpp */,
+                               0FA6F39220CC73A200A03DCD /* SmallPtrSet.cpp */,
                                7936D6A91C99F8AE000D1AED /* SmallPtrSet.h */,
                                A30D412D1F0DE13F00B71954 /* SoftLinking.h */,
                                79038E05224B05A7004C0738 /* SpanningTree.h */,
                                E360C7642127B85B00C90F0E /* UnalignedAccess.h */,
                                E360C7652127B85C00C90F0E /* Unexpected.h */,
                                A8A4735C151A825B004123FF /* UnionFind.h */,
+                               0FA6F39420CCACE900A03DCD /* UniqueArray.cpp */,
                                E300E521203D645F00DA79BE /* UniqueArray.h */,
                                5C7C88D31D0A3A0A009D2F6D /* UniqueRef.h */,
                                CD7600FF1F90A3CA00026E26 /* UnsafePointer.h */,
                                7AFEC6AE1EB22AC600DADE36 /* UUID.h */,
                                A8A4736F151A825B004123FF /* ValueCheck.h */,
                                7CD0D5A71D55322A000CC9E1 /* Variant.h */,
+                               0F95B63420CB53C100479635 /* Vector.cpp */,
                                A8A47370151A825B004123FF /* Vector.h */,
                                E419F2E623AB9E2300B26129 /* VectorHash.h */,
                                A8A47371151A825B004123FF /* VectorTraits.h */,
                                C2BCFC531F621F3F00C9222C /* LineEnding.cpp */,
                                C2BCFC541F621F3F00C9222C /* LineEnding.h */,
                                14E785E71DFB330100209BD1 /* OrdinalNumber.h */,
+                               0F95B63620CB5EFD00479635 /* StringBuffer.cpp */,
                                A8A47323151A825B004123FF /* StringBuffer.h */,
                                A8A47324151A825B004123FF /* StringBuilder.cpp */,
                                A8A47325151A825B004123FF /* StringBuilder.h */,
                                9BC70F05176C379D00101DEC /* AtomStringTable.cpp in Sources */,
                                1469419D16EAB10A0024E146 /* AutodrainedPool.cpp in Sources */,
                                0F43D8F11DB5ADDC00108FB6 /* AutomaticThread.cpp in Sources */,
+                               E3149A37228BB42200BFA6C7 /* Bag.cpp in Sources */,
                                8134013815B092FD001FF0B8 /* Base64.cpp in Sources */,
                                A8A473A8151A825B004123FF /* bignum-dtoa.cc in Sources */,
                                A8A473AA151A825B004123FF /* bignum.cc in Sources */,
                                A8A47460151A825B004123FF /* CollatorDefault.cpp in Sources */,
                                A8A47463151A825B004123FF /* CollatorICU.cpp in Sources */,
                                0F8F2B92172E0103007DBDA5 /* CompilationThread.cpp in Sources */,
+                               E3149A3B228BDCAC00BFA6C7 /* ConcurrentBuffer.cpp in Sources */,
                                0F30CB5A1FCDF134004B5323 /* ConcurrentPtrHashSet.cpp in Sources */,
                                0F8E85DB1FD485B000691889 /* CountingLock.cpp in Sources */,
                                E38C41281EB4E0680042957D /* CPUTime.cpp in Sources */,
                                A8A4739C151A825B004123FF /* CurrentTime.cpp in Sources */,
                                A8A4739E151A825B004123FF /* DataLog.cpp in Sources */,
                                A8A473A0151A825B004123FF /* DateMath.cpp in Sources */,
+                               0F95B63320CB4B7700479635 /* DebugHeap.cpp in Sources */,
                                1ACADD841884480100D8B71D /* DeprecatedSymbolsUsedBySafari.mm in Sources */,
                                A8A473AE151A825B004123FF /* diy-fp.cc in Sources */,
                                A8A473B0151A825B004123FF /* double-conversion.cc in Sources */,
                                A8A47414151A825B004123FF /* RandomNumber.cpp in Sources */,
                                0FEC3C5E1F368A9700F59B6C /* ReadWriteLock.cpp in Sources */,
                                46BEB6EB22FFE24900269867 /* RefCounted.cpp in Sources */,
+                               E3149A38228BB42C00BFA6C7 /* RefCountedArray.cpp in Sources */,
                                A8A4741A151A825B004123FF /* RefCountedLeakCounter.cpp in Sources */,
                                E392FA2722E92BFF00ECDC73 /* ResourceUsageCocoa.cpp in Sources */,
                                2CDED0F318115C85004DBA70 /* RunLoop.cpp in Sources */,
                                A3EE5C3D21FFAC7D00FABD61 /* SchedulePairCF.cpp in Sources */,
                                A3EE5C4021FFACA200FABD61 /* SchedulePairMac.mm in Sources */,
                                0F66B28E1DC97BAB004A1D3F /* Seconds.cpp in Sources */,
+                               0FA6F38F20CC580F00A03DCD /* SegmentedVector.cpp in Sources */,
                                A8A47421151A825B004123FF /* SHA1.cpp in Sources */,
                                5311BD531EA71CAD00525281 /* Signals.cpp in Sources */,
                                A748745217A0BDAE00FA04CB /* SixCharacterHash.cpp in Sources */,
                                A8A47425151A825B004123FF /* SizeLimits.cpp in Sources */,
+                               0FA6F39320CC73A300A03DCD /* SmallPtrSet.cpp in Sources */,
                                A8A47427151A825B004123FF /* StackBounds.cpp in Sources */,
                                FEEA4DF9216D7BE400AC0602 /* StackPointer.cpp in Sources */,
                                FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */,
                                3337DB9CE743410FAF076E17 /* StackTrace.cpp in Sources */,
+                               0F95B63720CB5EFD00479635 /* StringBuffer.cpp in Sources */,
                                A8A4743C151A825B004123FF /* StringBuilder.cpp in Sources */,
                                E38D6E271F5522E300A75CC4 /* StringBuilderJSON.cpp in Sources */,
                                A5BA15FB182435A600A82E69 /* StringCF.cpp in Sources */,
                                5311BD5C1EA822F900525281 /* ThreadMessage.cpp in Sources */,
                                0F66B2901DC97BAB004A1D3F /* TimeWithDynamicClockType.cpp in Sources */,
                                0F7075F51FBF53CD00489AF0 /* TimingScope.cpp in Sources */,
+                               0FA6F39520CCACE900A03DCD /* UniqueArray.cpp in Sources */,
                                5CC0EE7621629F1900A1A842 /* URL.cpp in Sources */,
                                5C1F0595216437B30039302C /* URLCF.cpp in Sources */,
                                5CC0EE892162BC2200A1A842 /* URLCocoa.mm in Sources */,
                                1C181C931D307AB800F5FA16 /* UTextProviderUTF16.cpp in Sources */,
                                A8A47469151A825B004123FF /* UTF8Conversion.cpp in Sources */,
                                7AFEC6B11EB22B5900DADE36 /* UUID.cpp in Sources */,
+                               E3149A39228BB43500BFA6C7 /* Vector.cpp in Sources */,
                                0F66B2921DC97BAB004A1D3F /* WallTime.cpp in Sources */,
                                1FA47C8A152502DA00568D1B /* WebCoreThread.cpp in Sources */,
                                0FE4479C1B7AAA03009498EB /* WordLock.cpp in Sources */,
diff --git a/Source/WTF/wtf/Bag.cpp b/Source/WTF/wtf/Bag.cpp
new file mode 100644 (file)
index 0000000..05f9905
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/Bag.h>
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WTF {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BagNode);
+
+} // namespace WTF
index 49cf29e..d5061a6 100644 (file)
 
 namespace WTF {
 
-namespace Private {
-
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BagNode);
 template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>>
 class BagNode {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(BagNode);
 public:
     using PtrTraits = typename PassedPtrTraits::template RebindTraits<BagNode>;
 
@@ -49,13 +48,11 @@ public:
     typename PtrTraits::StorageType m_next { nullptr };
 };
 
-} // namespace Private
-
 template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>>
 class Bag final {
     WTF_MAKE_NONCOPYABLE(Bag);
     WTF_MAKE_FAST_ALLOCATED;
-    using Node = Private::BagNode<T, PassedPtrTraits>;
+    using Node = BagNode<T, PassedPtrTraits>;
     using PtrTraits = typename PassedPtrTraits::template RebindTraits<Node>;
 
 public:
index e125a95..431c04f 100644 (file)
 #include <string.h>
 #include <wtf/Assertions.h>
 #include <wtf/FastMalloc.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/StdLibExtras.h>
 
 namespace WTF {
 
+
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BitVector);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BitVector);
+
 void BitVector::setSlow(const BitVector& other)
 {
     uintptr_t newBitsOrPointer;
@@ -76,13 +81,13 @@ BitVector::OutOfLineBits* BitVector::OutOfLineBits::create(size_t numBits)
 {
     numBits = (numBits + bitsInPointer() - 1) & ~(static_cast<size_t>(bitsInPointer()) - 1);
     size_t size = sizeof(OutOfLineBits) + sizeof(uintptr_t) * (numBits / bitsInPointer());
-    OutOfLineBits* result = new (NotNull, fastMalloc(size)) OutOfLineBits(numBits);
+    OutOfLineBits* result = new (NotNull, BitVectorMalloc::malloc(size)) OutOfLineBits(numBits);
     return result;
 }
 
 void BitVector::OutOfLineBits::destroy(OutOfLineBits* outOfLineBits)
 {
-    fastFree(outOfLineBits);
+    BitVectorMalloc::free(outOfLineBits);
 }
 
 void BitVector::resizeOutOfLine(size_t numBits)
index fa06b31..6a82682 100644 (file)
@@ -47,6 +47,7 @@ set(WTF_PUBLIC_HEADERS
     DataLog.h
     DataMutex.h
     DateMath.h
+    DebugHeap.h
     DebugUtilities.h
     DeferrableRefCounted.h
     Deque.h
@@ -351,10 +352,12 @@ set(WTF_SOURCES
     ASCIICType.cpp
     Assertions.cpp
     AutomaticThread.cpp
+    Bag.cpp
     BitVector.cpp
     CPUTime.cpp
     ClockType.cpp
     CompilationThread.cpp
+    ConcurrentBuffer.cpp
     ConcurrentPtrHashSet.cpp
     CountingLock.cpp
     CrossThreadCopier.cpp
@@ -364,6 +367,7 @@ set(WTF_SOURCES
     CurrentTime.cpp
     DataLog.cpp
     DateMath.cpp
+    DebugHeap.cpp
     FastBitVector.cpp
     FastMalloc.cpp
     FilePrintStream.cpp
@@ -400,11 +404,14 @@ set(WTF_SOURCES
     RandomNumber.cpp
     ReadWriteLock.cpp
     RefCounted.cpp
+    RefCountedArray.cpp
     RefCountedLeakCounter.cpp
     RunLoop.cpp
     SHA1.cpp
     Seconds.cpp
+    SegmentedVector.cpp
     SixCharacterHash.cpp
+    SmallPtrSet.cpp
     StackBounds.cpp
     StackPointer.cpp
     StackStats.cpp
@@ -419,6 +426,8 @@ set(WTF_SOURCES
     URLHelpers.cpp
     URLParser.cpp
     UUID.cpp
+    UniqueArray.cpp
+    Vector.cpp
     WTFAssertions.cpp
     WallTime.cpp
     WordLock.cpp
@@ -447,6 +456,7 @@ set(WTF_SOURCES
     text/CString.cpp
     text/ExternalStringImpl.cpp
     text/LineEnding.cpp
+    text/StringBuffer.cpp
     text/StringBuilder.cpp
     text/StringBuilderJSON.cpp
     text/StringImpl.cpp
diff --git a/Source/WTF/wtf/ConcurrentBuffer.cpp b/Source/WTF/wtf/ConcurrentBuffer.cpp
new file mode 100644 (file)
index 0000000..28e2e42
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/ConcurrentBuffer.h>
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WTF {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ConcurrentBuffer);
+
+} // namespace WTF
+
index fca29fd..f5748f1 100644 (file)
@@ -34,6 +34,8 @@
 
 namespace WTF {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ConcurrentBuffer);
+
 // ConcurrentBuffer is suitable for when you plan to store immutable data and sometimes append to it.
 // It supports storing data that is not copy-constructable but bit-copyable.
 template<typename T>
@@ -53,7 +55,7 @@ public:
                 array->data[i].~T();
         }
         for (Array* array : m_allArrays)
-            fastFree(array);
+            ConcurrentBufferMalloc::free(array);
     }
 
     // Growing is not concurrent. This assumes you are holding some other lock before you do this.
@@ -98,7 +100,7 @@ private:
         Checked<size_t> objectSize = sizeof(T);
         objectSize *= size;
         objectSize += static_cast<size_t>(OBJECT_OFFSETOF(Array, data));
-        Array* result = static_cast<Array*>(fastMalloc(objectSize.unsafeGet()));
+        Array* result = static_cast<Array*>(ConcurrentBufferMalloc::malloc(objectSize.unsafeGet()));
         result->size = size;
         return result;
     }
diff --git a/Source/WTF/wtf/DebugHeap.cpp b/Source/WTF/wtf/DebugHeap.cpp
new file mode 100644 (file)
index 0000000..ea3563b
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/DebugHeap.h>
+
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+
+#include <cstdlib>
+#include <thread>
+
+namespace WTF {
+
+DebugHeap::DebugHeap(const char* heapName)
+    : m_zone(malloc_create_zone(0, 0))
+{
+    malloc_set_zone_name(m_zone, heapName);
+}
+
+void* DebugHeap::malloc(size_t size)
+{
+    void* result = malloc_zone_malloc(m_zone, size);
+    if (!result)
+        CRASH();
+    return result;
+}
+
+void* DebugHeap::calloc(size_t numElements, size_t elementSize)
+{
+    void* result = malloc_zone_calloc(m_zone, numElements, elementSize);
+    if (!result)
+        CRASH();
+    return result;
+}
+
+void* DebugHeap::memalign(size_t alignment, size_t size, bool crashOnFailure)
+{
+    void* result = malloc_zone_memalign(m_zone, alignment, size);
+    if (!result && crashOnFailure)
+        CRASH();
+    return result;
+}
+
+void* DebugHeap::realloc(void* object, size_t size)
+{
+    void* result = malloc_zone_realloc(m_zone, object, size);
+    if (!result)
+        CRASH();
+    return result;
+}
+
+void DebugHeap::free(void* object)
+{
+    malloc_zone_free(m_zone, object);
+}
+
+} // namespace WTF
+
+#endif // ENABLE(MALLOC_HEAP_BREAKDOWN)
diff --git a/Source/WTF/wtf/DebugHeap.h b/Source/WTF/wtf/DebugHeap.h
new file mode 100644 (file)
index 0000000..562a367
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/ExportMacros.h>
+#include <wtf/Platform.h>
+
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+#include <mutex>
+#if OS(DARWIN)
+#include <malloc/malloc.h>
+#endif
+#endif
+
+namespace WTF {
+
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+
+class DebugHeap {
+public:
+    WTF_EXPORT_PRIVATE DebugHeap(const char* heapName);
+
+    WTF_EXPORT_PRIVATE void* malloc(size_t);
+    WTF_EXPORT_PRIVATE void* calloc(size_t numElements, size_t elementSize);
+    WTF_EXPORT_PRIVATE void* memalign(size_t alignment, size_t, bool crashOnFailure);
+    WTF_EXPORT_PRIVATE void* realloc(void*, size_t);
+    WTF_EXPORT_PRIVATE void free(void*);
+
+private:
+#if OS(DARWIN)
+    malloc_zone_t* m_zone;
+#endif
+};
+
+#define DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Type) \
+    struct Type##Malloc { \
+        static WTF_EXPORT_PRIVATE WTF::DebugHeap& debugHeap(); \
+\
+        static void* malloc(size_t size) { return debugHeap().malloc(size); } \
+\
+        static void* tryMalloc(size_t size) { return debugHeap().malloc(size); } \
+\
+        static void* zeroedMalloc(size_t size) { return debugHeap().calloc(1, size); } \
+\
+        static void* tryZeroedMalloc(size_t size) { return debugHeap().calloc(1, size); } \
+\
+        static void* realloc(void* p, size_t size) { return debugHeap().realloc(p, size); } \
+\
+        static void* tryRealloc(void* p, size_t size) { return debugHeap().realloc(p, size); } \
+\
+        static void free(void* p) { debugHeap().free(p); } \
+    }
+
+#define DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Type) \
+    WTF::DebugHeap& Type##Malloc::debugHeap() \
+    { \
+        static LazyNeverDestroyed<WTF::DebugHeap> heap; \
+        static std::once_flag onceKey; \
+        std::call_once(onceKey, [&] { \
+            heap.construct(#Type); \
+        }); \
+        return heap; \
+    } \
+    struct MakeDebugHeapMallocedImplMacroSemicolonifier##Type { }
+
+#else // ENABLE(MALLOC_HEAP_BREAKDOWN)
+
+#define DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Type) \
+    using Type##Malloc = FastMalloc
+
+#define DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Type) \
+    struct MakeDebugHeapMallocedImplMacroSemicolonifier##Type { }
+
+#endif
+
+} // namespace WTF
index 0f0e487..d64a988 100644 (file)
 #include "config.h"
 #include <wtf/FastBitVector.h>
 
+#include <wtf/NeverDestroyed.h>
+
 namespace WTF {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(FastBitVector);
+
 void FastBitVectorWordOwner::setEqualsSlow(const FastBitVectorWordOwner& other)
 {
     uint32_t* newArray = static_cast<uint32_t*>(
-        fastCalloc(other.arrayLength(), sizeof(uint32_t)));
+        FastBitVectorMalloc::zeroedMalloc(other.arrayLength() * sizeof(uint32_t)));
     memcpy(newArray, other.m_words, other.arrayLength() * sizeof(uint32_t));
     if (m_words)
-        fastFree(m_words);
+        FastBitVectorMalloc::free(m_words);
     m_words = newArray;
     m_numBits = other.m_numBits;
 }
@@ -48,10 +52,10 @@ void FastBitVectorWordOwner::resizeSlow(size_t numBits)
     // Use fastCalloc instead of fastRealloc because we expect the common
     // use case for this method to be initializing the size of the bitvector.
     
-    uint32_t* newArray = static_cast<uint32_t*>(fastCalloc(newLength, sizeof(uint32_t)));
+    uint32_t* newArray = static_cast<uint32_t*>(FastBitVectorMalloc::zeroedMalloc(newLength * sizeof(uint32_t)));
     memcpy(newArray, m_words, arrayLength() * sizeof(uint32_t));
     if (m_words)
-        fastFree(m_words);
+        FastBitVectorMalloc::free(m_words);
     m_words = newArray;
 }
 
index 920895f..96dcce1 100644 (file)
@@ -35,6 +35,8 @@ namespace WTF {
 
 class PrintStream;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(FastBitVector);
+
 inline constexpr size_t fastBitVectorArrayLength(size_t numBits) { return (numBits + 31) / 32; }
 
 class FastBitVectorWordView {
@@ -87,7 +89,7 @@ public:
     ~FastBitVectorWordOwner()
     {
         if (m_words)
-            fastFree(m_words);
+            FastBitVectorMalloc::free(m_words);
     }
     
     FastBitVectorWordView view() const { return FastBitVectorWordView(m_words, m_numBits); }
index cdffc75..a6e6e44 100644 (file)
 #include <malloc/malloc.h>
 #endif
 
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+#include <wtf/Atomics.h>
+#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/SetForScope.h>
+#include <wtf/StackShot.h>
+
+#if PLATFORM(COCOA)
+#include <notify.h>
+#endif
+
+#endif
+
 namespace WTF {
 
 #if !defined(NDEBUG)
@@ -229,7 +243,7 @@ TryMallocReturnValue tryFastRealloc(void* p, size_t n)
 
 void releaseFastMallocFreeMemory() { }
 void releaseFastMallocFreeMemoryForThisThread() { }
-    
+
 FastMallocStatistics fastMallocStatistics()
 {
     FastMallocStatistics statistics = { 0, 0, 0 };
@@ -260,6 +274,8 @@ void fastDecommitAlignedMemory(void* ptr, size_t size)
 
 void fastEnableMiniMode() { }
 
+void fastMallocDumpMallocStats() { }
+
 } // namespace WTF
 
 #else // defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC
@@ -268,6 +284,194 @@ void fastEnableMiniMode() { }
 
 namespace WTF {
 
+#define TRACK_MALLOC_CALLSTACK 0
+
+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOC_CALLSTACK
+
+static ThreadSpecificKey avoidRecordingCountKey { InvalidThreadSpecificKey };
+class AvoidRecordingScope {
+public:
+    AvoidRecordingScope();
+    ~AvoidRecordingScope();
+
+    static uintptr_t avoidRecordingCount()
+    {
+        return bitwise_cast<uintptr_t>(threadSpecificGet(avoidRecordingCountKey));
+    }
+};
+
+AvoidRecordingScope::AvoidRecordingScope()
+{
+    static std::once_flag onceKey;
+    std::call_once(onceKey, [] {
+        // The value stored in TLS is initially 0.
+        threadSpecificKeyCreate(&avoidRecordingCountKey, [](void*) { });
+    });
+    threadSpecificSet(avoidRecordingCountKey, bitwise_cast<void*>(avoidRecordingCount() + 1));
+}
+
+AvoidRecordingScope::~AvoidRecordingScope()
+{
+    threadSpecificSet(avoidRecordingCountKey, bitwise_cast<void*>(avoidRecordingCount() - 1));
+}
+
+class MallocCallTracker {
+public:
+    MallocCallTracker();
+
+    void recordMalloc(void*, size_t);
+    void recordRealloc(void* oldAddress, void* newAddress, size_t);
+    void recordFree(void*);
+
+    void dumpStats();
+
+    static MallocCallTracker& singleton();
+
+private:
+    struct MallocSiteData {
+        StackShot stack;
+        size_t size;
+
+        MallocSiteData(size_t stackSize, size_t allocationSize)
+            : stack(stackSize)
+            , size(allocationSize)
+        {
+        }
+    };
+
+    HashMap<void*, std::unique_ptr<MallocSiteData>> m_addressMallocSiteData;
+    Lock m_mutex;
+};
+
+MallocCallTracker& MallocCallTracker::singleton()
+{
+    AvoidRecordingScope avoidRecording;
+    static NeverDestroyed<MallocCallTracker> tracker;
+    return tracker;
+}
+
+
+MallocCallTracker::MallocCallTracker()
+{
+    int token;
+    notify_register_dispatch("com.apple.WebKit.dumpUntrackedMallocs", &token, dispatch_get_main_queue(), ^(int) {
+        MallocCallTracker::singleton().dumpStats();
+    });
+}
+
+void MallocCallTracker::recordMalloc(void* address, size_t allocationSize)
+{
+    AvoidRecordingScope avoidRecording;
+
+    // Intentionally using std::make_unique not to use FastMalloc for data structure tracking FastMalloc.
+    const size_t stackSize = 10;
+    auto siteData = std::make_unique<MallocSiteData>(stackSize, allocationSize);
+
+    auto locker = holdLock(m_mutex);
+    auto addResult = m_addressMallocSiteData.add(address, WTFMove(siteData));
+    UNUSED_PARAM(addResult);
+}
+
+void MallocCallTracker::recordRealloc(void* oldAddress, void* newAddress, size_t newSize)
+{
+    AvoidRecordingScope avoidRecording;
+
+    auto locker = holdLock(m_mutex);
+
+    auto it = m_addressMallocSiteData.find(oldAddress);
+    if (it == m_addressMallocSiteData.end()) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    it->value->size = newSize;
+    if (oldAddress != newAddress) {
+        auto value = WTFMove(it->value);
+        m_addressMallocSiteData.remove(it);
+        auto addResult = m_addressMallocSiteData.add(newAddress, WTFMove(value));
+        ASSERT_UNUSED(addResult, addResult.isNewEntry);
+    }
+}
+
+void MallocCallTracker::recordFree(void* address)
+{
+    AvoidRecordingScope avoidRecording;
+
+    auto locker = holdLock(m_mutex);
+    bool removed = m_addressMallocSiteData.remove(address);
+    UNUSED_PARAM(removed);
+}
+
+void MallocCallTracker::dumpStats()
+{
+    AvoidRecordingScope avoidRecording;
+
+    {
+        auto locker = holdLock(m_mutex);
+
+        // Build a hash of stack to address vector
+        struct MallocSiteTotals {
+            Vector<MallocSiteData*> siteData;
+            size_t count { 0 };
+            size_t totalSize { 0 };
+        };
+
+        size_t totalUntrackedSize = 0;
+        size_t totalUntrackedCount = 0;
+
+        HashMap<unsigned, std::unique_ptr<MallocSiteTotals>> callSiteToMallocData;
+        for (const auto& it : m_addressMallocSiteData) {
+            auto result = callSiteToMallocData.ensure(it.value->stack.hash(), [] () {
+                // Intentionally using std::make_unique not to use FastMalloc for data structure tracking FastMalloc.
+                return std::make_unique<MallocSiteTotals>();
+            });
+            auto& siteTotal = result.iterator->value;
+            siteTotal->siteData.append(it.value.get());
+            ++siteTotal->count;
+            siteTotal->totalSize += it.value->size;
+            totalUntrackedSize += it.value->size;
+            ++totalUntrackedCount;
+        }
+
+        Vector<unsigned> stackHashes;
+        auto stackKeys = callSiteToMallocData.keys();
+        for (auto key : stackKeys)
+            stackHashes.append(key);
+
+        // Sort by reverse total size.
+        std::sort(stackHashes.begin(), stackHashes.end(), [&] (unsigned a, unsigned b) {
+            const auto& aSiteTotals = callSiteToMallocData.get(a);
+            const auto& bSiteTotals = callSiteToMallocData.get(b);
+
+            return aSiteTotals->totalSize > bSiteTotals->totalSize;
+        });
+
+        WTFLogAlways("Total untracked bytes: %lu (%lu allocations)\n", totalUntrackedSize, totalUntrackedCount);
+
+        const size_t numStacksToDump = 100;
+        for (size_t i = 0; i < std::min(numStacksToDump, stackHashes.size()); ++i) {
+            const auto& mallocDataForStack = callSiteToMallocData.get(stackHashes[i]);
+
+            WTFLogAlways("Total allocation size: %lu (%lu allocations)\n", mallocDataForStack->totalSize, mallocDataForStack->count);
+            // FIXME: Add a way to remove some entries in StackShot in a programable way.
+            // https://bugs.webkit.org/show_bug.cgi?id=205701
+            const size_t framesToSkip = 6;
+            WTFPrintBacktrace(mallocDataForStack->siteData[0]->stack.array() + framesToSkip, mallocDataForStack->siteData[0]->stack.size() - framesToSkip);
+            WTFLogAlways("\n");
+        }
+    }
+}
+void fastMallocDumpMallocStats()
+{
+    MallocCallTracker::singleton().dumpStats();
+}
+#else
+void fastMallocDumpMallocStats()
+{
+}
+#endif
+
+
 bool isFastMallocEnabled()
 {
     return bmalloc::api::isEnabled();
@@ -276,7 +480,12 @@ bool isFastMallocEnabled()
 void* fastMalloc(size_t size)
 {
     ASSERT_IS_WITHIN_LIMIT(size);
-    return bmalloc::api::malloc(size);
+    void* result = bmalloc::api::malloc(size);
+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOC_CALLSTACK
+    if (!AvoidRecordingScope::avoidRecordingCount())
+        MallocCallTracker::singleton().recordMalloc(result, size);
+#endif
+    return result;
 }
 
 void* fastCalloc(size_t numElements, size_t elementSize)
@@ -293,12 +502,21 @@ void* fastCalloc(size_t numElements, size_t elementSize)
 void* fastRealloc(void* object, size_t size)
 {
     ASSERT_IS_WITHIN_LIMIT(size);
-    return bmalloc::api::realloc(object, size);
+    void* result = bmalloc::api::realloc(object, size);
+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOC_CALLSTACK
+    if (!AvoidRecordingScope::avoidRecordingCount())
+        MallocCallTracker::singleton().recordRealloc(object, result, size);
+#endif
+    return result;
 }
 
 void fastFree(void* object)
 {
     bmalloc::api::free(object);
+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOC_CALLSTACK
+    if (!AvoidRecordingScope::avoidRecordingCount())
+        MallocCallTracker::singleton().recordFree(object);
+#endif
 }
 
 size_t fastMallocSize(const void*)
@@ -314,19 +532,29 @@ size_t fastMallocGoodSize(size_t size)
     return size;
 }
 
-void* fastAlignedMalloc(size_t alignment, size_t size) 
+void* fastAlignedMalloc(size_t alignment, size_t size)
 {
     ASSERT_IS_WITHIN_LIMIT(size);
-    return bmalloc::api::memalign(alignment, size);
+    void* result = bmalloc::api::memalign(alignment, size);
+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOC_CALLSTACK
+    if (!AvoidRecordingScope::avoidRecordingCount())
+        MallocCallTracker::singleton().recordMalloc(result, size);
+#endif
+    return result;
 }
 
-void* tryFastAlignedMalloc(size_t alignment, size_t size) 
+void* tryFastAlignedMalloc(size_t alignment, size_t size)
 {
     FAIL_IF_EXCEEDS_LIMIT(size);
-    return bmalloc::api::tryMemalign(alignment, size);
+    void* result = bmalloc::api::tryMemalign(alignment, size);
+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOC_CALLSTACK
+    if (!AvoidRecordingScope::avoidRecordingCount())
+        MallocCallTracker::singleton().recordMalloc(result, size);
+#endif
+    return result;
 }
 
-void fastAlignedFree(void* p) 
+void fastAlignedFree(void* p)
 {
     bmalloc::api::free(p);
 }
@@ -336,7 +564,7 @@ TryMallocReturnValue tryFastMalloc(size_t size)
     FAIL_IF_EXCEEDS_LIMIT(size);
     return bmalloc::api::tryMalloc(size);
 }
-    
+
 TryMallocReturnValue tryFastCalloc(size_t numElements, size_t elementSize)
 {
     FAIL_IF_EXCEEDS_LIMIT(numElements * elementSize);
@@ -346,7 +574,7 @@ TryMallocReturnValue tryFastCalloc(size_t numElements, size_t elementSize)
         return nullptr;
     return tryFastZeroedMalloc(checkedSize.unsafeGet());
 }
-    
+
 TryMallocReturnValue tryFastRealloc(void* object, size_t newSize)
 {
     FAIL_IF_EXCEEDS_LIMIT(newSize);
index 8e4d8ec..1f3a311 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <new>
 #include <stdlib.h>
+#include <wtf/DebugHeap.h>
 #include <wtf/StdLibExtras.h>
 
 namespace WTF {
@@ -82,6 +83,8 @@ struct FastMallocStatistics {
 };
 WTF_EXPORT_PRIVATE FastMallocStatistics fastMallocStatistics();
 
+WTF_EXPORT_PRIVATE void fastMallocDumpMallocStats();
+
 // This defines a type which holds an unsigned integer and is the same
 // size as the minimally aligned memory allocation.
 typedef unsigned long long AllocAlignmentInteger;
@@ -199,6 +202,17 @@ struct FastMalloc {
             return realResult;
         return nullptr;
     }
+
+    static void* zeroedMalloc(size_t size) { return fastZeroedMalloc(size); }
+
+    static void* tryZeroedMalloc(size_t size)
+    {
+        auto result = tryFastZeroedMalloc(size);
+        void* realResult;
+        if (result.getValue(realResult))
+            return realResult;
+        return nullptr;
+    }
     
     static void* realloc(void* p, size_t size) { return fastRealloc(p, size); }
 
@@ -299,6 +313,8 @@ using WTF::fastAlignedFree;
     } \
     using webkitFastMalloced = int; \
 
+// FIXME: WTF_MAKE_FAST_ALLOCATED should take class name so that we can create malloc_zone per this macro.
+// https://bugs.webkit.org/show_bug.cgi?id=205702
 #define WTF_MAKE_FAST_ALLOCATED \
 public: \
     WTF_MAKE_FAST_ALLOCATED_IMPL \
@@ -308,3 +324,67 @@ using __thisIsHereToForceASemicolonAfterThisMacro = int
 #define WTF_MAKE_STRUCT_FAST_ALLOCATED \
     WTF_MAKE_FAST_ALLOCATED_IMPL \
 using __thisIsHereToForceASemicolonAfterThisMacro = int
+
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+
+#define WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER_IMPL(classname) \
+    void* operator new(size_t, void* p) { return p; } \
+    void* operator new[](size_t, void* p) { return p; } \
+    \
+    void* operator new(size_t size) \
+    { \
+        return classname##Malloc::malloc(size); \
+    } \
+    \
+    void operator delete(void* p) \
+    { \
+        classname##Malloc::free(p); \
+    } \
+    \
+    void* operator new[](size_t size) \
+    { \
+        return classname##Malloc::malloc(size); \
+    } \
+    \
+    void operator delete[](void* p) \
+    { \
+        classname##Malloc::free(p); \
+    } \
+    void* operator new(size_t, NotNullTag, void* location) \
+    { \
+        ASSERT(location); \
+        return location; \
+    } \
+    using webkitFastMalloced = int; \
+
+#define WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(classname) \
+public: \
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER_IMPL(classname) \
+private: \
+    WTF_EXPORT_PRIVATE static WTF::DebugHeap& debugHeap(const char*); \
+using __thisIsHereToForceASemicolonAfterThisMacro = int
+
+#define WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(className) \
+private: \
+    WTF_EXPORT_PRIVATE static WTF::DebugHeap& debugHeap(const char*); \
+public: \
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER_IMPL(className) \
+using __thisIsHereToForceASemicolonAfterThisMacro = int
+
+#else
+
+#define WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER_IMPL(classname) \
+    WTF_MAKE_FAST_ALLOCATED_IMPL
+
+#define WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(classname) \
+public: \
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER_IMPL(classname) \
+private: \
+using __thisIsHereToForceASemicolonAfterThisMacro = int
+
+#define WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(className) \
+public: \
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER_IMPL(className) \
+using __thisIsHereToForceASemicolonAfterThisMacro = int
+
+#endif
index f603912..fe2dd45 100644 (file)
@@ -21,6 +21,7 @@
 #pragma once
 
 #include <stddef.h>
+#include <wtf/Platform.h>
 
 namespace WTF {
 
@@ -47,6 +48,11 @@ class URL;
 class WallTime;
 
 struct FastMalloc;
+#if ENABLE(MALLOC_HEAP_BREAKDOWN)
+struct VectorMalloc;
+#else
+using VectorMalloc = FastMalloc;
+#endif
 
 template<typename> class CompletionHandler;
 template<typename T> struct DumbPtrTraits;
@@ -69,7 +75,7 @@ template<typename> struct EnumTraits;
 template<typename E, E...> struct EnumValues;
 
 template<typename...> class Variant;
-template<typename, size_t = 0, typename = CrashOnOverflow, size_t = 16> class Vector;
+template<typename, size_t = 0, typename = CrashOnOverflow, size_t = 16, typename Malloc = VectorMalloc> class Vector;
 template<typename Value, typename = typename DefaultHash<Value>::Hash, typename = HashTraits<Value>> class HashCountedSet;
 template<typename KeyArg, typename MappedArg, typename = typename DefaultHash<KeyArg>::Hash, typename = HashTraits<KeyArg>, typename = HashTraits<MappedArg>> class HashMap;
 template<typename ValueArg, typename = typename DefaultHash<ValueArg>::Hash, typename = HashTraits<ValueArg>> class HashSet;
index 8ccdf84..53b4cdb 100644 (file)
 
 #include <mutex>
 #include <wtf/DataLog.h>
+#include <wtf/NeverDestroyed.h>
 
 namespace WTF {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HashTable);
+
 #if DUMP_HASHTABLE_STATS
 
 std::atomic<unsigned> HashTableStats::numAccesses;
index 560de79..4c282e6 100644 (file)
@@ -28,6 +28,7 @@
 #include <type_traits>
 #include <utility>
 #include <wtf/Assertions.h>
+#include <wtf/DebugHeap.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/HashTraits.h>
 #include <wtf/Lock.h>
@@ -45,6 +46,8 @@
 
 namespace WTF {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HashTable);
+
 // Enables internal WTF consistency checks that are invoked automatically. Non-WTF callers can call checkTableConsistency() even if internal checks are disabled.
 #define CHECK_HASHTABLE_CONSISTENCY 0
 
@@ -1181,8 +1184,9 @@ namespace WTF {
         // would use a template member function with explicit specializations here, but
         // gcc doesn't appear to support that
         if (Traits::emptyValueIsZero)
-            return static_cast<ValueType*>(fastZeroedMalloc(size * sizeof(ValueType)));
-        ValueType* result = static_cast<ValueType*>(fastMalloc(size * sizeof(ValueType)));
+            return static_cast<ValueType*>(HashTableMalloc::zeroedMalloc(size * sizeof(ValueType)));
+
+        ValueType* result = static_cast<ValueType*>(HashTableMalloc::malloc(size * sizeof(ValueType)));
         for (unsigned i = 0; i < size; i++)
             initializeBucket(result[i]);
         return result;
@@ -1195,7 +1199,7 @@ namespace WTF {
             if (!isDeletedBucket(table[i]))
                 table[i].~ValueType();
         }
-        fastFree(table);
+        HashTableMalloc::free(table);
     }
 
     template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
@@ -1304,7 +1308,7 @@ namespace WTF {
 
         m_deletedCount = 0;
 
-        fastFree(oldTable);
+        HashTableMalloc::free(oldTable);
 
         internalCheckTableConsistency();
         return newEntry;
index 83b3a51..f1bbe23 100644 (file)
@@ -35,13 +35,9 @@ namespace WTF {
 
 template<typename T, typename Malloc = FastMalloc> class MallocPtr {
 public:
-    MallocPtr()
-        : m_ptr(nullptr)
-    {
-    }
+    MallocPtr() = default;
 
-    MallocPtr(std::nullptr_t)
-        : m_ptr(nullptr)
+    constexpr MallocPtr(std::nullptr_t)
     {
     }
 
@@ -99,16 +95,34 @@ public:
         std::swap(m_ptr, other.m_ptr);
     }
 
-    template<typename U> friend MallocPtr<U> adoptMallocPtr(U*);
+    template<typename U, typename OtherMalloc> friend MallocPtr<U, OtherMalloc> adoptMallocPtr(U*);
 
     static MallocPtr malloc(size_t size)
     {
-        return MallocPtr { static_cast<T*>(Malloc::malloc(size)) };
+        return MallocPtr {
+            static_cast<T*>(Malloc::malloc(size))
+        };
+    }
+
+    static MallocPtr zeroedMalloc(size_t size)
+    {
+        return MallocPtr {
+            static_cast<T*>(Malloc::zeroedMalloc(size))
+        };
     }
 
     static MallocPtr tryMalloc(size_t size)
     {
-        return MallocPtr { static_cast<T*>(Malloc::tryMalloc(size)) };
+        return MallocPtr {
+            static_cast<T*>(Malloc::tryMalloc(size))
+        };
+    }
+
+    static MallocPtr tryZeroedMalloc(size_t size)
+    {
+        return MallocPtr {
+            static_cast<T*>(Malloc::tryZeroedMalloc(size))
+        };
     }
 
     void realloc(size_t newSize)
@@ -122,14 +136,14 @@ private:
     {
     }
 
-    T* m_ptr;
+    T* m_ptr { nullptr };
 };
 
 static_assert(sizeof(MallocPtr<int>) == sizeof(int*), "");
 
-template<typename U> MallocPtr<U> adoptMallocPtr(U* ptr)
+template<typename U, typename OtherMalloc> MallocPtr<U, OtherMalloc> adoptMallocPtr(U* ptr)
 {
-    return MallocPtr<U>(ptr);
+    return MallocPtr<U, OtherMalloc>(ptr);
 }
 
 } // namespace WTF
index 11f3cbc..9695392 100644 (file)
 
 #include <wtf/DataLog.h>
 #include <wtf/FastMalloc.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/ProcessID.h>
 
 namespace WTF {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MetaAllocatorHandle);
+
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MetaAllocatorFreeSpace);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MetaAllocatorFreeSpace);
+
 MetaAllocator::~MetaAllocator()
 {
     for (FreeSpaceNode* node = m_freeSpaceSizeMap.first(); node;) {
@@ -472,7 +478,7 @@ MetaAllocator::FreeSpaceNode* MetaAllocator::allocFreeSpaceNode()
 #ifndef NDEBUG
     m_mallocBalance++;
 #endif
-    return new (NotNull, fastMalloc(sizeof(FreeSpaceNode))) FreeSpaceNode();
+    return new (NotNull, MetaAllocatorFreeSpaceMalloc::malloc(sizeof(FreeSpaceNode))) FreeSpaceNode();
 }
 
 void MetaAllocator::freeFreeSpaceNode(FreeSpaceNode* node)
@@ -480,7 +486,7 @@ void MetaAllocator::freeFreeSpaceNode(FreeSpaceNode* node)
 #ifndef NDEBUG
     m_mallocBalance--;
 #endif
-    fastFree(node);
+    MetaAllocatorFreeSpaceMalloc::free(node);
 }
 
 #if ENABLE(META_ALLOCATOR_PROFILE)
index d8c30e9..fa24c55 100644 (file)
@@ -38,7 +38,9 @@ namespace WTF {
 class MetaAllocator;
 class PrintStream;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MetaAllocatorHandle);
 class MetaAllocatorHandle : public ThreadSafeRefCounted<MetaAllocatorHandle>, public RedBlackTree<MetaAllocatorHandle, void*>::Node {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(MetaAllocatorHandle);
 private:
     MetaAllocatorHandle(MetaAllocator*, void* start, size_t sizeInBytes, void* ownerUID);
 
index 349fbd0..2219d03 100644 (file)
 #endif
 #endif
 
+/*
+ * Enable this to put each IsoHeap and other allocation categories into their own malloc heaps, so that tools like vmmap can show how big each heap is.
+ * Turn BENABLE_MALLOC_HEAP_BREAKDOWN on in bmalloc together when using this.
+ */
+#if !defined(ENABLE_MALLOC_HEAP_BREAKDOWN)
+#define ENABLE_MALLOC_HEAP_BREAKDOWN 0
+#endif
+
 #if PLATFORM(COCOA)
 #define USE_COREMEDIA 1
 #define USE_VIDEOTOOLBOX 1
diff --git a/Source/WTF/wtf/RefCountedArray.cpp b/Source/WTF/wtf/RefCountedArray.cpp
new file mode 100644 (file)
index 0000000..f617ac1
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/RefCountedArray.h>
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WTF {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(RefCountedArray);
+
+} // namespace WTF
index 63cd1ed..d0765dc 100644 (file)
@@ -43,6 +43,8 @@
 
 namespace WTF {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(RefCountedArray);
+
 template<typename T, typename PtrTraits = DumbPtrTraits<T>>
 class RefCountedArray {
     enum CommonCopyConstructorTag { CommonCopyConstructor };
@@ -67,7 +69,7 @@ public:
             return;
         }
 
-        T* data = (static_cast<Header*>(fastMalloc(Header::size() + sizeof(T) * size)))->payload();
+        T* data = (static_cast<Header*>(RefCountedArrayMalloc::malloc(Header::size() + sizeof(T) * size)))->payload();
         m_data = data;
         Header::fromPayload(data)->refCount = 1;
         Header::fromPayload(data)->length = size;
@@ -94,7 +96,7 @@ public:
             return;
         }
         
-        T* data = (static_cast<Header*>(fastMalloc(Header::size() + sizeof(T) * other.size())))->payload();
+        T* data = (static_cast<Header*>(RefCountedArrayMalloc::malloc(Header::size() + sizeof(T) * other.size())))->payload();
         m_data = data;
         Header::fromPayload(data)->refCount = 1;
         Header::fromPayload(data)->length = other.size();
@@ -121,7 +123,7 @@ public:
         if (--Header::fromPayload(data)->refCount)
             return;
         VectorTypeOperations<T>::destruct(begin(), end());
-        fastFree(Header::fromPayload(data));
+        RefCountedArrayMalloc::free(Header::fromPayload(data));
     }
     
     unsigned refCount() const
@@ -205,7 +207,8 @@ private:
         if (--Header::fromPayload(oldData)->refCount)
             return *this;
         VectorTypeOperations<T>::destruct(oldData, oldData + Header::fromPayload(oldData)->length);
-        fastFree(Header::fromPayload(oldData));
+
+        RefCountedArrayMalloc::free(Header::fromPayload(oldData));
         return *this;
     }
 
diff --git a/Source/WTF/wtf/SegmentedVector.cpp b/Source/WTF/wtf/SegmentedVector.cpp
new file mode 100644 (file)
index 0000000..1a867c9
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/SegmentedVector.h>
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WTF {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SegmentedVector);
+
+} // namespace WTF
index 3babdf8..83c1729 100644 (file)
@@ -33,6 +33,8 @@
 
 namespace WTF {
 
+    DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SegmentedVector);
+
     // An iterator for SegmentedVector. It supports only the pre ++ operator
     template <typename T, size_t SegmentSize = 8> class SegmentedVector;
     template <typename T, size_t SegmentSize = 8> class SegmentedVectorIterator {
@@ -227,7 +229,7 @@ namespace WTF {
             for (size_t i = 0; i < m_size; ++i)
                 at(i).~T();
             for (size_t i = 0; i < m_segments.size(); ++i)
-                fastFree(m_segments[i]);
+                SegmentedVectorMalloc::free(m_segments[i]);
         }
 
         bool segmentExistsFor(size_t index)
@@ -263,7 +265,7 @@ namespace WTF {
 
         void allocateSegment()
         {
-            m_segments.append(static_cast<Segment*>(fastMalloc(sizeof(T) * SegmentSize)));
+            m_segments.append(static_cast<Segment*>(SegmentedVectorMalloc::malloc(sizeof(T) * SegmentSize)));
         }
 
         size_t m_size { 0 };
diff --git a/Source/WTF/wtf/SmallPtrSet.cpp b/Source/WTF/wtf/SmallPtrSet.cpp
new file mode 100644 (file)
index 0000000..42048e7
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/SmallPtrSet.h>
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WTF {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SmallPtrSet);
+
+} // namespace WTF
index 9447fe8..4c6e461 100644 (file)
@@ -32,6 +32,8 @@
 
 namespace WTF {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SmallPtrSet);
+
 template<typename PtrType, unsigned SmallArraySize = 8>
 class SmallPtrSet {
     WTF_MAKE_FAST_ALLOCATED;
@@ -72,7 +74,7 @@ public:
     ~SmallPtrSet()
     {
         if (!isSmall())
-            fastFree(m_buffer);
+            SmallPtrSetMalloc::free(m_buffer);
     }
 
     inline void add(PtrType ptr)
@@ -209,7 +211,7 @@ private:
         bool wasSmall = isSmall();
         void** oldBuffer = wasSmall ? m_smallStorage : m_buffer;
         unsigned oldCapacity = m_capacity;
-        m_buffer = static_cast<void**>(fastMalloc(allocationSize));
+        m_buffer = static_cast<void**>(SmallPtrSetMalloc::malloc(allocationSize));
         memset(m_buffer, -1, allocationSize);
         m_capacity = size;
 
@@ -221,7 +223,7 @@ private:
         }
 
         if (!wasSmall)
-            fastFree(oldBuffer);
+            SmallPtrSetMalloc::free(oldBuffer);
     }
 
 
diff --git a/Source/WTF/wtf/UniqueArray.cpp b/Source/WTF/wtf/UniqueArray.cpp
new file mode 100644 (file)
index 0000000..f889f99
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/UniqueArray.h>
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WTF {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(UniqueArray);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(UniqueArrayElement);
+
+} // namespace WTF
index a2b8585..544b8df 100644 (file)
 
 namespace WTF {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(UniqueArray);
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(UniqueArrayElement);
+
 template<bool isTriviallyDestructible, typename T> struct UniqueArrayMaker;
 
 template<typename T>
+struct UniqueArrayFree {
+    static_assert(std::is_trivially_destructible<T>::value, "");
+
+    void operator()(T* pointer) const
+    {
+        UniqueArrayMalloc::free(const_cast<typename std::remove_cv<T>::type*>(pointer));
+    }
+};
+
+template<typename T>
+struct UniqueArrayFree<T[]> {
+    static_assert(std::is_trivially_destructible<T>::value, "");
+
+    void operator()(T* pointer) const
+    {
+        UniqueArrayMalloc::free(const_cast<typename std::remove_cv<T>::type*>(pointer));
+    }
+};
+
+
+template<typename T>
 struct UniqueArrayMaker<true, T> {
-    using ResultType = typename std::unique_ptr<T[], FastFree<T[]>>;
+    using ResultType = typename std::unique_ptr<T[], UniqueArrayFree<T[]>>;
 
     static ResultType make(size_t size)
     {
@@ -49,7 +73,7 @@ struct UniqueArrayMaker<true, T> {
         // Do not use placement new like `new (storage) T[size]()`. `new T[size]()` requires
         // larger storage than the `sizeof(T) * size` storage since it want to store `size`
         // to somewhere.
-        T* storage = static_cast<T*>(fastMalloc((Checked<size_t>(sizeof(T)) * size).unsafeGet()));
+        T* storage = static_cast<T*>(UniqueArrayMalloc::malloc((Checked<size_t>(sizeof(T)) * size).unsafeGet()));
         VectorTypeOperations<T>::initialize(storage, storage + size);
         return ResultType(storage);
     }
@@ -62,7 +86,7 @@ struct UniqueArrayMaker<false, T> {
     // UniqueArrayElement has new [] and delete [] operators for FastMalloc. We allocate UniqueArrayElement[] and cast
     // it to T[]. When deleting, the custom deleter casts T[] to UniqueArrayElement[] and deletes it.
     class UniqueArrayElement {
-        WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(UniqueArrayElement);
     public:
         struct Deleter {
             void operator()(T* pointer)
diff --git a/Source/WTF/wtf/Vector.cpp b/Source/WTF/wtf/Vector.cpp
new file mode 100644 (file)
index 0000000..6a2b47c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Vector.h"
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WTF {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Vector);
+
+} // namespace WTF
index 5935033..9dd4b41 100644 (file)
@@ -46,6 +46,8 @@ class LLIntOffsetsExtractor;
 
 namespace WTF {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Vector);
+
 template <bool needsDestruction, typename T>
 struct VectorDestructor;
 
@@ -276,7 +278,7 @@ struct VectorTypeOperations
     }
 };
 
-template<typename T>
+template<typename T, typename Malloc>
 class VectorBufferBase {
     WTF_MAKE_NONCOPYABLE(VectorBufferBase);
 public:
@@ -287,7 +289,7 @@ public:
             CRASH();
         size_t sizeToAllocate = newCapacity * sizeof(T);
         m_capacity = sizeToAllocate / sizeof(T);
-        m_buffer = static_cast<T*>(fastMalloc(sizeToAllocate));
+        m_buffer = static_cast<T*>(Malloc::malloc(sizeToAllocate));
     }
 
     bool tryAllocateBuffer(size_t newCapacity)
@@ -297,13 +299,12 @@ public:
             return false;
 
         size_t sizeToAllocate = newCapacity * sizeof(T);
-        T* newBuffer;
-        if (tryFastMalloc(sizeToAllocate).getValue(newBuffer)) {
-            m_capacity = sizeToAllocate / sizeof(T);
-            m_buffer = newBuffer;
-            return true;
-        }
-        return false;
+        T* newBuffer = static_cast<T*>(Malloc::tryMalloc(sizeToAllocate));
+        if (!newBuffer)
+            return false;
+        m_capacity = sizeToAllocate / sizeof(T);
+        m_buffer = newBuffer;
+        return true;
     }
 
     bool shouldReallocateBuffer(size_t newCapacity) const
@@ -318,7 +319,7 @@ public:
             CRASH();
         size_t sizeToAllocate = newCapacity * sizeof(T);
         m_capacity = sizeToAllocate / sizeof(T);
-        m_buffer = static_cast<T*>(fastRealloc(m_buffer, sizeToAllocate));
+        m_buffer = static_cast<T*>(Malloc::realloc(m_buffer, sizeToAllocate));
     }
 
     void deallocateBuffer(T* bufferToDeallocate)
@@ -331,7 +332,7 @@ public:
             m_capacity = 0;
         }
 
-        fastFree(bufferToDeallocate);
+        Malloc::free(bufferToDeallocate);
     }
 
     T* buffer() { return m_buffer; }
@@ -339,12 +340,12 @@ public:
     static ptrdiff_t bufferMemoryOffset() { return OBJECT_OFFSETOF(VectorBufferBase, m_buffer); }
     size_t capacity() const { return m_capacity; }
 
-    MallocPtr<T> releaseBuffer()
+    MallocPtr<T, Malloc> releaseBuffer()
     {
         T* buffer = m_buffer;
         m_buffer = 0;
         m_capacity = 0;
-        return adoptMallocPtr(buffer);
+        return adoptMallocPtr<T, Malloc>(buffer);
     }
 
 protected:
@@ -372,13 +373,12 @@ protected:
     unsigned m_size; // Only used by the Vector subclass, but placed here to avoid padding the struct.
 };
 
-template<typename T, size_t inlineCapacity>
-class VectorBuffer;
+template<typename T, size_t inlineCapacity, typename Malloc = VectorMalloc> class VectorBuffer;
 
-template<typename T>
-class VectorBuffer<T, 0> : private VectorBufferBase<T> {
+template<typename T, typename Malloc>
+class VectorBuffer<T, 0, Malloc> : private VectorBufferBase<T, Malloc> {
 private:
-    typedef VectorBufferBase<T> Base;
+    typedef VectorBufferBase<T, Malloc> Base;
 public:
     VectorBuffer()
     {
@@ -398,7 +398,7 @@ public:
         deallocateBuffer(buffer());
     }
     
-    void swap(VectorBuffer<T, 0>& other, size_t, size_t)
+    void swap(VectorBuffer<T, 0, Malloc>& other, size_t, size_t)
     {
         std::swap(m_buffer, other.m_buffer);
         std::swap(m_capacity, other.m_capacity);
@@ -434,11 +434,11 @@ private:
     using Base::m_capacity;
 };
 
-template<typename T, size_t inlineCapacity>
-class VectorBuffer : private VectorBufferBase<T> {
+template<typename T, size_t inlineCapacity, typename Malloc>
+class VectorBuffer : private VectorBufferBase<T, Malloc> {
     WTF_MAKE_NONCOPYABLE(VectorBuffer);
 private:
-    typedef VectorBufferBase<T> Base;
+    typedef VectorBufferBase<T, Malloc> Base;
 public:
     VectorBuffer()
         : Base(inlineBuffer(), inlineCapacity, 0)
@@ -545,10 +545,10 @@ public:
     using Base::capacity;
     using Base::bufferMemoryOffset;
 
-    MallocPtr<T> releaseBuffer()
+    MallocPtr<T, Malloc> releaseBuffer()
     {
         if (buffer() == inlineBuffer())
-            return nullptr;
+            return { };
         return Base::releaseBuffer();
     }
 
@@ -603,11 +603,11 @@ struct UnsafeVectorOverflow {
 };
 
 // Template default values are in Forward.h.
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-class Vector : private VectorBuffer<T, inlineCapacity> {
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+class Vector : private VectorBuffer<T, inlineCapacity, Malloc> {
     WTF_MAKE_FAST_ALLOCATED;
 private:
-    typedef VectorBuffer<T, inlineCapacity> Base;
+    typedef VectorBuffer<T, inlineCapacity, Malloc> Base;
     typedef VectorTypeOperations<T> TypeOperations;
     friend class JSC::LLIntOffsetsExtractor;
 
@@ -680,12 +680,12 @@ public:
     }
 
     Vector(const Vector&);
-    template<size_t otherCapacity, typename otherOverflowBehaviour, size_t otherMinimumCapacity>
-    explicit Vector(const Vector<T, otherCapacity, otherOverflowBehaviour, otherMinimumCapacity>&);
+    template<size_t otherCapacity, typename otherOverflowBehaviour, size_t otherMinimumCapacity, typename OtherMalloc>
+    explicit Vector(const Vector<T, otherCapacity, otherOverflowBehaviour, otherMinimumCapacity, OtherMalloc>&);
 
     Vector& operator=(const Vector&);
-    template<size_t otherCapacity, typename otherOverflowBehaviour, size_t otherMinimumCapacity>
-    Vector& operator=(const Vector<T, otherCapacity, otherOverflowBehaviour, otherMinimumCapacity>&);
+    template<size_t otherCapacity, typename otherOverflowBehaviour, size_t otherMinimumCapacity, typename OtherMalloc>
+    Vector& operator=(const Vector<T, otherCapacity, otherOverflowBehaviour, otherMinimumCapacity, OtherMalloc>&);
 
     Vector(Vector&&);
     Vector& operator=(Vector&&);
@@ -786,7 +786,7 @@ public:
 
     template<typename U> void insert(size_t position, const U*, size_t);
     template<typename U> void insert(size_t position, U&&);
-    template<typename U, size_t c, typename OH> void insertVector(size_t position, const Vector<U, c, OH>&);
+    template<typename U, size_t c, typename OH, size_t m, typename M> void insertVector(size_t position, const Vector<U, c, OH, m, M>&);
 
     void remove(size_t position);
     void remove(size_t position, size_t length);
@@ -807,9 +807,9 @@ public:
 
     template<typename Iterator> void appendRange(Iterator start, Iterator end);
 
-    MallocPtr<T> releaseBuffer();
+    MallocPtr<T, Malloc> releaseBuffer();
 
-    void swap(Vector<T, inlineCapacity, OverflowHandler, minCapacity>& other)
+    void swap(Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& other)
     {
 #if ASAN_ENABLED
         if (this == std::addressof(other)) // ASan will crash if we try to restrict access to the same buffer twice.
@@ -881,8 +881,8 @@ private:
 #endif
 };
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-Vector<T, inlineCapacity, OverflowHandler, minCapacity>::Vector(const Vector& other)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::Vector(const Vector& other)
     : Base(other.capacity(), other.size())
 {
     asanSetInitialBufferSizeTo(other.size());
@@ -891,9 +891,9 @@ Vector<T, inlineCapacity, OverflowHandler, minCapacity>::Vector(const Vector& ot
         TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-template<size_t otherCapacity, typename otherOverflowBehaviour, size_t otherMinimumCapacity>
-Vector<T, inlineCapacity, OverflowHandler, minCapacity>::Vector(const Vector<T, otherCapacity, otherOverflowBehaviour, otherMinimumCapacity>& other)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+template<size_t otherCapacity, typename otherOverflowBehaviour, size_t otherMinimumCapacity, typename OtherMalloc>
+Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::Vector(const Vector<T, otherCapacity, otherOverflowBehaviour, otherMinimumCapacity, OtherMalloc>& other)
     : Base(other.capacity(), other.size())
 {
     asanSetInitialBufferSizeTo(other.size());
@@ -902,8 +902,8 @@ Vector<T, inlineCapacity, OverflowHandler, minCapacity>::Vector(const Vector<T,
         TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-Vector<T, inlineCapacity, OverflowHandler, minCapacity>& Vector<T, inlineCapacity, OverflowHandler, minCapacity>::operator=(const Vector<T, inlineCapacity, OverflowHandler, minCapacity>& other)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::operator=(const Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& other)
 {
     if (&other == this)
         return *this;
@@ -927,9 +927,9 @@ Vector<T, inlineCapacity, OverflowHandler, minCapacity>& Vector<T, inlineCapacit
 
 inline bool typelessPointersAreEqual(const void* a, const void* b) { return a == b; }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-template<size_t otherCapacity, typename otherOverflowBehaviour, size_t otherMinimumCapacity>
-Vector<T, inlineCapacity, OverflowHandler, minCapacity>& Vector<T, inlineCapacity, OverflowHandler, minCapacity>::operator=(const Vector<T, otherCapacity, otherOverflowBehaviour, otherMinimumCapacity>& other)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+template<size_t otherCapacity, typename otherOverflowBehaviour, size_t otherMinimumCapacity, typename OtherMalloc>
+Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::operator=(const Vector<T, otherCapacity, otherOverflowBehaviour, otherMinimumCapacity, OtherMalloc>& other)
 {
     // If the inline capacities match, we should call the more specific
     // template.  If the inline capacities don't match, the two objects
@@ -953,29 +953,29 @@ Vector<T, inlineCapacity, OverflowHandler, minCapacity>& Vector<T, inlineCapacit
     return *this;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline Vector<T, inlineCapacity, OverflowHandler, minCapacity>::Vector(Vector<T, inlineCapacity, OverflowHandler, minCapacity>&& other)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::Vector(Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>&& other)
 {
     swap(other);
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline Vector<T, inlineCapacity, OverflowHandler, minCapacity>& Vector<T, inlineCapacity, OverflowHandler, minCapacity>::operator=(Vector<T, inlineCapacity, OverflowHandler, minCapacity>&& other)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::operator=(Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>&& other)
 {
     swap(other);
     return *this;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::contains(const U& value) const
+bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::contains(const U& value) const
 {
     return find(value) != notFound;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename MatchFunction>
-size_t Vector<T, inlineCapacity, OverflowHandler, minCapacity>::findMatching(const MatchFunction& matches) const
+size_t Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::findMatching(const MatchFunction& matches) const
 {
     for (size_t i = 0; i < size(); ++i) {
         if (matches(at(i)))
@@ -984,18 +984,18 @@ size_t Vector<T, inlineCapacity, OverflowHandler, minCapacity>::findMatching(con
     return notFound;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-size_t Vector<T, inlineCapacity, OverflowHandler, minCapacity>::find(const U& value) const
+size_t Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::find(const U& value) const
 {
     return findMatching([&](auto& item) {
         return item == value;
     });
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-size_t Vector<T, inlineCapacity, OverflowHandler, minCapacity>::reverseFind(const U& value) const
+size_t Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::reverseFind(const U& value) const
 {
     for (size_t i = 1; i <= size(); ++i) {
         const size_t index = size() - i;
@@ -1005,9 +1005,9 @@ size_t Vector<T, inlineCapacity, OverflowHandler, minCapacity>::reverseFind(cons
     return notFound;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appendIfNotContains(const U& value)
+bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::appendIfNotContains(const U& value)
 {
     if (contains(value))
         return false;
@@ -1015,8 +1015,8 @@ bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appendIfNotContain
     return true;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::fill(const T& val, size_t newSize)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::fill(const T& val, size_t newSize)
 {
     if (size() > newSize)
         shrink(newSize);
@@ -1033,22 +1033,22 @@ void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::fill(const T& val,
     m_size = newSize;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename Iterator>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appendRange(Iterator start, Iterator end)
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::appendRange(Iterator start, Iterator end)
 {
     for (Iterator it = start; it != end; ++it)
         append(*it);
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::expandCapacity(size_t newMinCapacity)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::expandCapacity(size_t newMinCapacity)
 {
     reserveCapacity(std::max(newMinCapacity, std::max(static_cast<size_t>(minCapacity), capacity() + capacity() / 4 + 1)));
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-NEVER_INLINE T* Vector<T, inlineCapacity, OverflowHandler, minCapacity>::expandCapacity(size_t newMinCapacity, T* ptr)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+NEVER_INLINE T* Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::expandCapacity(size_t newMinCapacity, T* ptr)
 {
     if (ptr < begin() || ptr >= end()) {
         expandCapacity(newMinCapacity);
@@ -1059,14 +1059,14 @@ NEVER_INLINE T* Vector<T, inlineCapacity, OverflowHandler, minCapacity>::expandC
     return begin() + index;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryExpandCapacity(size_t newMinCapacity)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::tryExpandCapacity(size_t newMinCapacity)
 {
     return tryReserveCapacity(std::max(newMinCapacity, std::max(static_cast<size_t>(minCapacity), capacity() + capacity() / 4 + 1)));
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-const T* Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryExpandCapacity(size_t newMinCapacity, const T* ptr)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+const T* Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::tryExpandCapacity(size_t newMinCapacity, const T* ptr)
 {
     if (ptr < begin() || ptr >= end()) {
         if (!tryExpandCapacity(newMinCapacity))
@@ -1079,16 +1079,16 @@ const T* Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryExpandCapac
     return begin() + index;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-inline U* Vector<T, inlineCapacity, OverflowHandler, minCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
+inline U* Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::expandCapacity(size_t newMinCapacity, U* ptr)
 {
     expandCapacity(newMinCapacity);
     return ptr;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::resize(size_t size)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::resize(size_t size)
 {
     if (size <= m_size) {
         TypeOperations::destruct(begin() + size, end());
@@ -1104,15 +1104,15 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::resize(size
     m_size = size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::resizeToFit(size_t size)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::resizeToFit(size_t size)
 {
     reserveCapacity(size);
     resize(size);
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::shrink(size_t size)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::shrink(size_t size)
 {
     ASSERT(size <= m_size);
     TypeOperations::destruct(begin() + size, end());
@@ -1120,8 +1120,8 @@ void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::shrink(size_t size
     m_size = size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::grow(size_t size)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::grow(size_t size)
 {
     ASSERT(size >= m_size);
     if (size > capacity())
@@ -1132,8 +1132,8 @@ void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::grow(size_t size)
     m_size = size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::asanSetInitialBufferSizeTo(size_t size)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::asanSetInitialBufferSizeTo(size_t size)
 {
 #if ASAN_ENABLED
     if (!buffer())
@@ -1148,8 +1148,8 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::asanSetInit
 #endif
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::asanSetBufferSizeToFullCapacity(size_t size)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::asanSetBufferSizeToFullCapacity(size_t size)
 {
 #if ASAN_ENABLED
     if (!buffer())
@@ -1162,8 +1162,8 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::asanSetBuff
 #endif
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::asanBufferSizeWillChangeTo(size_t newSize)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::asanBufferSizeWillChangeTo(size_t newSize)
 {
 #if ASAN_ENABLED
     if (!buffer())
@@ -1176,8 +1176,8 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::asanBufferS
 #endif
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::reserveCapacity(size_t newCapacity)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::reserveCapacity(size_t newCapacity)
 {
     if (newCapacity <= capacity())
         return;
@@ -1195,8 +1195,8 @@ void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::reserveCapacity(si
     Base::deallocateBuffer(oldBuffer);
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryReserveCapacity(size_t newCapacity)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::tryReserveCapacity(size_t newCapacity)
 {
     if (newCapacity <= capacity())
         return true;
@@ -1218,8 +1218,8 @@ bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryReserveCapacity
     return true;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::reserveInitialCapacity(size_t initialCapacity)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::reserveInitialCapacity(size_t initialCapacity)
 {
     ASSERT(!m_size);
     ASSERT(capacity() == inlineCapacity);
@@ -1227,8 +1227,8 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::reserveInit
         Base::allocateBuffer(initialCapacity);
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::shrinkCapacity(size_t newCapacity)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::shrinkCapacity(size_t newCapacity)
 {
     if (newCapacity >= capacity())
         return;
@@ -1258,9 +1258,9 @@ void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::shrinkCapacity(siz
     asanSetInitialBufferSizeTo(size());
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::append(const U* data, size_t dataSize)
+ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::append(const U* data, size_t dataSize)
 {
     size_t newSize = m_size + dataSize;
     if (newSize > capacity()) {
@@ -1275,9 +1275,9 @@ ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appe
     m_size = newSize;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-ALWAYS_INLINE bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryAppend(const U* data, size_t dataSize)
+ALWAYS_INLINE bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::tryAppend(const U* data, size_t dataSize)
 {
     size_t newSize = m_size + dataSize;
     if (newSize > capacity()) {
@@ -1295,9 +1295,9 @@ ALWAYS_INLINE bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryA
     return true;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::append(U&& value)
+ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::append(U&& value)
 {
     if (size() != capacity()) {
         asanBufferSizeWillChangeTo(m_size + 1);
@@ -1309,9 +1309,9 @@ ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appe
     appendSlowCase(std::forward<U>(value));
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename... Args>
-ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::constructAndAppend(Args&&... args)
+ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::constructAndAppend(Args&&... args)
 {
     if (size() != capacity()) {
         asanBufferSizeWillChangeTo(m_size + 1);
@@ -1323,9 +1323,9 @@ ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::cons
     constructAndAppendSlowCase(std::forward<Args>(args)...);
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename... Args>
-ALWAYS_INLINE bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryConstructAndAppend(Args&&... args)
+ALWAYS_INLINE bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::tryConstructAndAppend(Args&&... args)
 {
     if (size() != capacity()) {
         asanBufferSizeWillChangeTo(m_size + 1);
@@ -1337,9 +1337,9 @@ ALWAYS_INLINE bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryC
     return tryConstructAndAppendSlowCase(std::forward<Args>(args)...);
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appendSlowCase(U&& value)
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::appendSlowCase(U&& value)
 {
     ASSERT(size() == capacity());
 
@@ -1352,9 +1352,9 @@ void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appendSlowCase(U&&
     ++m_size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename... Args>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::constructAndAppendSlowCase(Args&&... args)
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::constructAndAppendSlowCase(Args&&... args)
 {
     ASSERT(size() == capacity());
 
@@ -1366,9 +1366,9 @@ void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::constructAndAppend
     ++m_size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename... Args>
-bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryConstructAndAppendSlowCase(Args&&... args)
+bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::tryConstructAndAppendSlowCase(Args&&... args)
 {
     ASSERT(size() == capacity());
     
@@ -1385,9 +1385,9 @@ bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::tryConstructAndApp
 // This version of append saves a branch in the case where you know that the
 // vector's capacity is large enough for the append to succeed.
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::uncheckedAppend(U&& value)
+ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::uncheckedAppend(U&& value)
 {
     ASSERT(size() < capacity());
 
@@ -1397,9 +1397,9 @@ ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::unch
     ++m_size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename... Args>
-ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::uncheckedConstructAndAppend(Args&&... args)
+ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::uncheckedConstructAndAppend(Args&&... args)
 {
     ASSERT(size() < capacity());
 
@@ -1409,16 +1409,16 @@ ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::unch
     ++m_size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U, size_t otherCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appendVector(const Vector<U, otherCapacity>& val)
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::appendVector(const Vector<U, otherCapacity>& val)
 {
     append(val.begin(), val.size());
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U, size_t otherCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appendVector(Vector<U, otherCapacity>&& val)
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::appendVector(Vector<U, otherCapacity>&& val)
 {
     size_t newSize = m_size + val.size();
     if (newSize > capacity())
@@ -1427,9 +1427,9 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::appendVecto
         uncheckedAppend(WTFMove(item));
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::insert(size_t position, const U* data, size_t dataSize)
+void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::insert(size_t position, const U* data, size_t dataSize)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(position <= size());
     size_t newSize = m_size + dataSize;
@@ -1446,9 +1446,9 @@ void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::insert(size_t posi
     m_size = newSize;
 }
  
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::insert(size_t position, U&& value)
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::insert(size_t position, U&& value)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(position <= size());
 
@@ -1466,15 +1466,15 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::insert(size
     ++m_size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-template<typename U, size_t c, typename OH>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::insertVector(size_t position, const Vector<U, c, OH>& val)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+template<typename U, size_t c, typename OH, size_t m, typename M>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::insertVector(size_t position, const Vector<U, c, OH, m, M>& val)
 {
     insert(position, val.begin(), val.size());
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::remove(size_t position)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::remove(size_t position)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(position < size());
     T* spot = begin() + position;
@@ -1484,8 +1484,8 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::remove(size
     --m_size;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::remove(size_t position, size_t length)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::remove(size_t position, size_t length)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(position <= size());
     ASSERT_WITH_SECURITY_IMPLICATION(position + length <= size());
@@ -1497,18 +1497,18 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::remove(size
     m_size -= length;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-inline bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::removeFirst(const U& value)
+inline bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::removeFirst(const U& value)
 {
     return removeFirstMatching([&value] (const T& current) {
         return current == value;
     });
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename MatchFunction>
-inline bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::removeFirstMatching(const MatchFunction& matches, size_t startIndex)
+inline bool Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::removeFirstMatching(const MatchFunction& matches, size_t startIndex)
 {
     for (size_t i = startIndex; i < size(); ++i) {
         if (matches(at(i))) {
@@ -1519,18 +1519,18 @@ inline bool Vector<T, inlineCapacity, OverflowHandler, minCapacity>::removeFirst
     return false;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-inline unsigned Vector<T, inlineCapacity, OverflowHandler, minCapacity>::removeAll(const U& value)
+inline unsigned Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::removeAll(const U& value)
 {
     return removeAllMatching([&value] (const T& current) {
         return current == value;
     });
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename MatchFunction>
-inline unsigned Vector<T, inlineCapacity, OverflowHandler, minCapacity>::removeAllMatching(const MatchFunction& matches, size_t startIndex)
+inline unsigned Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::removeAllMatching(const MatchFunction& matches, size_t startIndex)
 {
     iterator holeBegin = end();
     iterator holeEnd = end();
@@ -1555,16 +1555,16 @@ inline unsigned Vector<T, inlineCapacity, OverflowHandler, minCapacity>::removeA
     return matchCount;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::reverse()
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::reverse()
 {
     for (size_t i = 0; i < m_size / 2; ++i)
         std::swap(at(i), at(m_size - 1 - i));
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename MapFunction, typename R>
-inline Vector<R> Vector<T, inlineCapacity, OverflowHandler, minCapacity>::map(MapFunction mapFunction) const
+inline Vector<R> Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::map(MapFunction mapFunction) const
 {
     Vector<R> result;
     result.reserveInitialCapacity(size());
@@ -1573,8 +1573,8 @@ inline Vector<R> Vector<T, inlineCapacity, OverflowHandler, minCapacity>::map(Ma
     return result;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline MallocPtr<T> Vector<T, inlineCapacity, OverflowHandler, minCapacity>::releaseBuffer()
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline MallocPtr<T, Malloc> Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::releaseBuffer()
 {
     // FIXME: Find a way to preserve annotations on the returned buffer.
     // ASan requires that all annotations are removed before deallocation,
@@ -1587,7 +1587,7 @@ inline MallocPtr<T> Vector<T, inlineCapacity, OverflowHandler, minCapacity>::rel
         // that means it was using the inline buffer. In that case,
         // we create a brand new buffer so the caller always gets one.
         size_t bytes = m_size * sizeof(T);
-        buffer = adoptMallocPtr(static_cast<T*>(fastMalloc(bytes)));
+        buffer = adoptMallocPtr<T, Malloc>(static_cast<T*>(Malloc::malloc(bytes)));
         memcpy(buffer.get(), data(), bytes);
     }
     m_size = 0;
@@ -1595,8 +1595,8 @@ inline MallocPtr<T> Vector<T, inlineCapacity, OverflowHandler, minCapacity>::rel
     return buffer;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::checkConsistency()
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::checkConsistency()
 {
 #if !ASSERT_DISABLED
     for (size_t i = 0; i < size(); ++i)
@@ -1604,14 +1604,14 @@ inline void Vector<T, inlineCapacity, OverflowHandler, minCapacity>::checkConsis
 #endif
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline void swap(Vector<T, inlineCapacity, OverflowHandler, minCapacity>& a, Vector<T, inlineCapacity, OverflowHandler, minCapacity>& b)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline void swap(Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& a, Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& b)
 {
     a.swap(b);
 }
 
-template<typename T, size_t inlineCapacityA, typename OverflowHandlerA, size_t minCapacityA, size_t inlineCapacityB, typename OverflowHandlerB, size_t minCapacityB>
-bool operator==(const Vector<T, inlineCapacityA, OverflowHandlerA, minCapacityA>& a, const Vector<T, inlineCapacityB, OverflowHandlerB, minCapacityB>& b)
+template<typename T, size_t inlineCapacityA, typename OverflowHandlerA, size_t minCapacityA, typename MallocA, size_t inlineCapacityB, typename OverflowHandlerB, size_t minCapacityB, typename MallocB>
+bool operator==(const Vector<T, inlineCapacityA, OverflowHandlerA, minCapacityA, MallocA>& a, const Vector<T, inlineCapacityB, OverflowHandlerB, minCapacityB, MallocB>& b)
 {
     if (a.size() != b.size())
         return false;
@@ -1619,8 +1619,8 @@ bool operator==(const Vector<T, inlineCapacityA, OverflowHandlerA, minCapacityA>
     return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size());
 }
 
-template<typename T, size_t inlineCapacityA, typename OverflowHandlerA, size_t minCapacityA, size_t inlineCapacityB, typename OverflowHandlerB, size_t minCapacityB>
-inline bool operator!=(const Vector<T, inlineCapacityA, OverflowHandlerA, minCapacityA>& a, const Vector<T, inlineCapacityB, OverflowHandlerB, minCapacityB>& b)
+template<typename T, size_t inlineCapacityA, typename OverflowHandlerA, size_t minCapacityA, typename MallocA, size_t inlineCapacityB, typename OverflowHandlerB, size_t minCapacityB, typename MallocB>
+inline bool operator!=(const Vector<T, inlineCapacityA, OverflowHandlerA, minCapacityA, MallocA>& a, const Vector<T, inlineCapacityB, OverflowHandlerB, minCapacityB, MallocB>& b)
 {
     return !(a == b);
 }
@@ -1635,9 +1635,9 @@ template<typename T> struct ValueCheck<Vector<T>> {
 };
 #endif
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
 template<typename U>
-inline Vector<U> Vector<T, inlineCapacity, OverflowHandler, minCapacity>::isolatedCopy() const
+inline Vector<U> Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>::isolatedCopy() const
 {
     Vector<U> copy;
     copy.reserveInitialCapacity(size());
@@ -1655,8 +1655,8 @@ size_t removeRepeatedElements(VectorType& vector, const Func& func)
     return newSize;
 }
 
-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-size_t removeRepeatedElements(Vector<T, inlineCapacity, OverflowHandler, minCapacity>& vector)
+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+size_t removeRepeatedElements(Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& vector)
 {
     return removeRepeatedElements(vector, [] (T& a, T& b) { return a == b; });
 }
index e99778f..032df65 100644 (file)
 #include <wtf/text/CString.h>
 
 #include <string.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/StringHasher.h>
 
 namespace WTF {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CStringBuffer);
+
 Ref<CStringBuffer> CStringBuffer::createUninitialized(size_t length)
 {
     RELEASE_ASSERT(length < (std::numeric_limits<unsigned>::max() - sizeof(CStringBuffer)));
 
     // The +1 is for the terminating null character.
     size_t size = sizeof(CStringBuffer) + length + 1;
-    CStringBuffer* stringBuffer = static_cast<CStringBuffer*>(fastMalloc(size));
+    CStringBuffer* stringBuffer = static_cast<CStringBuffer*>(CStringBufferMalloc::malloc(size));
     return adoptRef(*new (NotNull, stringBuffer) CStringBuffer(length));
 }
 
index 29c5975..cdbeaa3 100644 (file)
 
 namespace WTF {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CStringBuffer);
+
 // CStringBuffer is the ref-counted storage class for the characters in a CString.
 // The data is implicitly allocated 1 character longer than length(), as it is zero-terminated.
 class CStringBuffer final : public RefCounted<CStringBuffer> {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(CStringBuffer);
 public:
     const char* data() { return mutableData(); }
     size_t length() const { return m_length; }
diff --git a/Source/WTF/wtf/text/StringBuffer.cpp b/Source/WTF/wtf/text/StringBuffer.cpp
new file mode 100644 (file)
index 0000000..2f0ba93
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/text/StringBuffer.h>
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WTF {
+
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StringBuffer);
+
+} // namespace WTF
index af49ebb..62cb396 100644 (file)
 #include <limits>
 #include <unicode/utypes.h>
 #include <wtf/Assertions.h>
+#include <wtf/DebugHeap.h>
 #include <wtf/MallocPtr.h>
+#include <wtf/Noncopyable.h>
 
 namespace WTF {
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StringBuffer);
+
 template <typename CharType>
 class StringBuffer {
     WTF_MAKE_NONCOPYABLE(StringBuffer);
@@ -42,13 +46,13 @@ class StringBuffer {
 public:
     explicit StringBuffer(unsigned length)
         : m_length(length)
-        , m_data(m_length ? static_cast<CharType*>(fastMalloc((Checked<size_t>(m_length) * sizeof(CharType)).unsafeGet())) : nullptr)
+        , m_data(m_length ? static_cast<CharType*>(StringBufferMalloc::malloc((Checked<size_t>(m_length) * sizeof(CharType)).unsafeGet())) : nullptr)
     {
     }
 
     ~StringBuffer()
     {
-        fastFree(m_data);
+        StringBufferMalloc::free(m_data);
     }
 
     void shrink(unsigned newLength)
@@ -62,7 +66,7 @@ public:
         if (newLength > m_length) {
             if (newLength > std::numeric_limits<unsigned>::max() / sizeof(UChar))
                 CRASH();
-            m_data = static_cast<UChar*>(fastRealloc(m_data, newLength * sizeof(UChar)));
+            m_data = static_cast<UChar*>(StringBufferMalloc::realloc(m_data, newLength * sizeof(UChar)));
         }
         m_length = newLength;
     }
@@ -72,11 +76,11 @@ public:
 
     CharType& operator[](unsigned i) { ASSERT_WITH_SECURITY_IMPLICATION(i < m_length); return m_data[i]; }
 
-    MallocPtr<CharType> release()
+    MallocPtr<CharType, StringBufferMalloc> release()
     {
         CharType* data = m_data;
         m_data = 0;
-        return adoptMallocPtr(data);
+        return adoptMallocPtr<CharType, StringBufferMalloc>(data);
     }
 
 private:
index 0e2f9b0..9f253bc 100644 (file)
@@ -102,6 +102,8 @@ void StringStats::printStats()
 }
 #endif
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StringImpl);
+
 StringImpl::StaticStringImpl StringImpl::s_emptyAtomString("", StringImpl::StringAtom);
 
 StringImpl::~StringImpl()
@@ -130,7 +132,7 @@ StringImpl::~StringImpl()
     if (ownership == BufferOwned) {
         // We use m_data8, but since it is a union with m_data16 this works either way.
         ASSERT(m_data8);
-        fastFree(const_cast<LChar*>(m_data8));
+        StringImplMalloc::free(const_cast<LChar*>(m_data8));
         return;
     }
     if (ownership == BufferExternal) {
@@ -148,7 +150,7 @@ StringImpl::~StringImpl()
 void StringImpl::destroy(StringImpl* stringImpl)
 {
     stringImpl->~StringImpl();
-    fastFree(stringImpl);
+    StringImplMalloc::free(stringImpl);
 }
 
 Ref<StringImpl> StringImpl::createFromLiteral(const char* characters, unsigned length)
@@ -195,8 +197,7 @@ template<typename CharacterType> inline Ref<StringImpl> StringImpl::createUninit
     // heap allocation from this call.
     if (length > maxInternalLength<CharacterType>())
         CRASH();
-    StringImpl* string = static_cast<StringImpl*>(fastMalloc(allocationSize<CharacterType>(length)));
-
+    StringImpl* string = static_cast<StringImpl*>(StringImplMalloc::malloc(allocationSize<CharacterType>(length)));
     data = string->tailPointer<CharacterType>();
     return constructInternal<CharacterType>(*string, length);
 }
@@ -226,8 +227,8 @@ template<typename CharacterType> inline Expected<Ref<StringImpl>, UTF8Conversion
         return makeUnexpected(UTF8ConversionError::OutOfMemory);
 
     originalString->~StringImpl();
-    StringImpl* string;
-    if (!tryFastRealloc(&originalString.leakRef(), allocationSize<CharacterType>(length)).getValue(string))
+    auto* string = static_cast<StringImpl*>(StringImplMalloc::tryRealloc(&originalString.leakRef(), allocationSize<CharacterType>(length)));
+    if (!string)
         return makeUnexpected(UTF8ConversionError::OutOfMemory);
 
     data = string->tailPointer<CharacterType>();
index 2f31f21..0df182c 100644 (file)
@@ -26,6 +26,7 @@
 #include <unicode/ustring.h>
 #include <wtf/ASCIICType.h>
 #include <wtf/CheckedArithmetic.h>
+#include <wtf/DebugHeap.h>
 #include <wtf/Expected.h>
 #include <wtf/MathExtras.h>
 #include <wtf/StdLibExtras.h>
@@ -160,8 +161,10 @@ protected:
 // Or we could say that "const" doesn't make sense at all and use "StringImpl&" and "StringImpl*" everywhere.
 // Right now we use a mix of both, which makes code more confusing and has no benefit.
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StringImpl);
 class StringImpl : private StringImplShape {
-    WTF_MAKE_NONCOPYABLE(StringImpl); WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(StringImpl);
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(StringImpl);
 
     friend class AtomStringImpl;
     friend class JSC::LLInt::Data;
@@ -187,6 +190,7 @@ public:
 
     // The bottom 6 bits in the hash are flags.
     static constexpr const unsigned s_flagCount = 6;
+
 private:
     static constexpr const unsigned s_flagMask = (1u << s_flagCount) - 1;
     static_assert(s_flagCount <= StringHasher::flagCount, "StringHasher reserves enough bits for StringImpl flags");
@@ -213,8 +217,8 @@ private:
     explicit StringImpl(unsigned length);
 
     // Create a StringImpl adopting ownership of the provided buffer (BufferOwned).
-    StringImpl(MallocPtr<LChar>, unsigned length);
-    StringImpl(MallocPtr<UChar>, unsigned length);
+    template<typename Malloc> StringImpl(MallocPtr<LChar, Malloc>, unsigned length);
+    template<typename Malloc> StringImpl(MallocPtr<UChar, Malloc>, unsigned length);
     enum ConstructWithoutCopyingTag { ConstructWithoutCopying };
     StringImpl(const UChar*, unsigned length, ConstructWithoutCopyingTag);
     StringImpl(const LChar*, unsigned length, ConstructWithoutCopyingTag);
@@ -265,8 +269,8 @@ public:
     static constexpr unsigned maskStringKind() { return s_hashMaskStringKind; }
     static unsigned dataOffset() { return OBJECT_OFFSETOF(StringImpl, m_data8); }
 
-    template<typename CharacterType, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-    static Ref<StringImpl> adopt(Vector<CharacterType, inlineCapacity, OverflowHandler, minCapacity>&&);
+    template<typename CharacterType, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+    static Ref<StringImpl> adopt(Vector<CharacterType, inlineCapacity, OverflowHandler, minCapacity, Malloc>&&);
 
     WTF_EXPORT_PRIVATE static Ref<StringImpl> adopt(StringBuffer<UChar>&&);
     WTF_EXPORT_PRIVATE static Ref<StringImpl> adopt(StringBuffer<LChar>&&);
@@ -857,9 +861,17 @@ inline StringImpl::StringImpl(unsigned length)
     STRING_STATS_ADD_16BIT_STRING(m_length);
 }
 
-inline StringImpl::StringImpl(MallocPtr<LChar> characters, unsigned length)
-    : StringImplShape(s_refCountIncrement, length, characters.leakPtr(), s_hashFlag8BitBuffer | StringNormal | BufferOwned)
+template<typename Malloc>
+inline StringImpl::StringImpl(MallocPtr<LChar, Malloc> characters, unsigned length)
+    : StringImplShape(s_refCountIncrement, length, static_cast<const LChar*>(nullptr), s_hashFlag8BitBuffer | StringNormal | BufferOwned)
 {
+    if constexpr (std::is_same<Malloc, StringImplMalloc>::value)
+        m_data8 = characters.leakPtr();
+    else {
+        m_data8 = static_cast<const LChar*>(StringImplMalloc::malloc(length));
+        memcpy((void*)m_data8, characters.get(), length);
+    }
+
     ASSERT(m_data8);
     ASSERT(m_length);
 
@@ -884,9 +896,17 @@ inline StringImpl::StringImpl(const LChar* characters, unsigned length, Construc
     STRING_STATS_ADD_8BIT_STRING(m_length);
 }
 
-inline StringImpl::StringImpl(MallocPtr<UChar> characters, unsigned length)
-    : StringImplShape(s_refCountIncrement, length, characters.leakPtr(), StringNormal | BufferOwned)
+template<typename Malloc>
+inline StringImpl::StringImpl(MallocPtr<UChar, Malloc> characters, unsigned length)
+    : StringImplShape(s_refCountIncrement, length, static_cast<const UChar*>(nullptr), StringNormal | BufferOwned)
 {
+    if constexpr (std::is_same<Malloc, StringImplMalloc>::value)
+        m_data16 = characters.leakPtr();
+    else {
+        m_data16 = static_cast<const UChar*>(StringImplMalloc::malloc(length * sizeof(UChar)));
+        memcpy((void*)m_data16, characters.get(), length * sizeof(UChar));
+    }
+
     ASSERT(m_data16);
     ASSERT(m_length);
 
@@ -944,7 +964,7 @@ ALWAYS_INLINE Ref<StringImpl> StringImpl::createSubstringSharingImpl(StringImpl&
     auto* ownerRep = ((rep.bufferOwnership() == BufferSubstring) ? rep.substringBuffer() : &rep);
 
     // We allocate a buffer that contains both the StringImpl struct as well as the pointer to the owner string.
-    auto* stringImpl = static_cast<StringImpl*>(fastMalloc(substringSize));
+    auto* stringImpl = static_cast<StringImpl*>(StringImplMalloc::malloc(substringSize));
     if (rep.is8Bit())
         return adoptRef(*new (NotNull, stringImpl) StringImpl(rep.m_data8 + offset, length, *ownerRep));
     return adoptRef(*new (NotNull, stringImpl) StringImpl(rep.m_data16 + offset, length, *ownerRep));
@@ -970,7 +990,9 @@ template<typename CharacterType> ALWAYS_INLINE RefPtr<StringImpl> StringImpl::tr
         return nullptr;
     }
     StringImpl* result;
-    if (!tryFastMalloc(allocationSize<CharacterType>(length)).getValue(result)) {
+
+    result = (StringImpl*)StringImplMalloc::tryMalloc(allocationSize<CharacterType>(length));
+    if (!result) {
         output = nullptr;
         return nullptr;
     }
@@ -979,14 +1001,23 @@ template<typename CharacterType> ALWAYS_INLINE RefPtr<StringImpl> StringImpl::tr
     return constructInternal<CharacterType>(*result, length);
 }
 
-template<typename CharacterType, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity>
-inline Ref<StringImpl> StringImpl::adopt(Vector<CharacterType, inlineCapacity, OverflowHandler, minCapacity>&& vector)
+template<typename CharacterType, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc>
+inline Ref<StringImpl> StringImpl::adopt(Vector<CharacterType, inlineCapacity, OverflowHandler, minCapacity, Malloc>&& vector)
 {
     if (size_t size = vector.size()) {
         ASSERT(vector.data());
         if (size > MaxLength)
             CRASH();
-        return adoptRef(*new StringImpl(vector.releaseBuffer(), size));
+
+        if constexpr (std::is_same<Malloc, StringImplMalloc>::value)
+            return adoptRef(*new StringImpl(vector.releaseBuffer(), size));
+        else {
+            // We have to copy between malloc zones.
+            auto vectorBuffer = vector.releaseBuffer();
+            auto stringImplBuffer = MallocPtr<CharacterType, StringImplMalloc>::malloc(size);
+            memcpy(stringImplBuffer.get(), vectorBuffer.get(), size);
+            return adoptRef(*new StringImpl(WTFMove(stringImplBuffer), size));
+        }
     }
     return *empty();
 }
index 53f4983..0d66c61 100644 (file)
@@ -24,7 +24,9 @@
 #if USE(CF)
 
 #include <CoreFoundation/CoreFoundation.h>
+#include <wtf/DebugHeap.h>
 #include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/Threading.h>
 
@@ -32,6 +34,9 @@ namespace WTF {
 
 namespace StringWrapperCFAllocator {
 
+    DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StringWrapperCFAllocator);
+    DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StringWrapperCFAllocator);
+
     static StringImpl* currentString;
 
     static const void* retain(const void* info)
@@ -60,7 +65,7 @@ namespace StringWrapperCFAllocator {
                 underlyingString->ref(); // Balanced by call to deref in deallocate below.
             }
         }
-        StringImpl** header = static_cast<StringImpl**>(fastMalloc(sizeof(StringImpl*) + size));
+        StringImpl** header = static_cast<StringImpl**>(StringWrapperCFAllocatorMalloc::malloc(sizeof(StringImpl*) + size));
         *header = underlyingString;
         return header + 1;
     }
@@ -70,7 +75,7 @@ namespace StringWrapperCFAllocator {
         size_t newAllocationSize = sizeof(StringImpl*) + newSize;
         StringImpl** header = static_cast<StringImpl**>(pointer) - 1;
         ASSERT(!*header);
-        header = static_cast<StringImpl**>(fastRealloc(header, newAllocationSize));
+        header = static_cast<StringImpl**>(StringWrapperCFAllocatorMalloc::realloc(header, newAllocationSize));
         return header + 1;
     }
 
@@ -79,11 +84,11 @@ namespace StringWrapperCFAllocator {
         StringImpl** header = static_cast<StringImpl**>(pointer) - 1;
         StringImpl* underlyingString = *header;
         if (!underlyingString)
-            fastFree(header);
+            StringWrapperCFAllocatorMalloc::free(header);
         else {
             if (isMainThread()) {
                 underlyingString->deref(); // Balanced by call to ref in allocate above.
-                fastFree(header);
+                StringWrapperCFAllocatorMalloc::free(header);
                 return;
             }
 
@@ -91,7 +96,7 @@ namespace StringWrapperCFAllocator {
                 StringImpl* underlyingString = *header;
                 ASSERT(underlyingString);
                 underlyingString->deref(); // Balanced by call to ref in allocate above.
-                fastFree(header);
+                StringWrapperCFAllocatorMalloc::free(header);
             });
         }
     }
index 961cbe8..b4d9c57 100644 (file)
@@ -1,3 +1,87 @@
+2020-01-02  Yusuke Suzuki  <ysuzuki@apple.com> and Simon Fraser  <simon.fraser@apple.com>
+
+        Experiment: create lots of different malloc zones for easier accounting of memory use
+        https://bugs.webkit.org/show_bug.cgi?id=186422
+
+        Reviewed by Saam Barati.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/SerializedScriptValue.cpp:
+        * bindings/js/SerializedScriptValue.h:
+        * css/CSSFontFace.cpp:
+        * css/CSSFontFace.h:
+        * css/CSSSelector.cpp:
+        * css/CSSSelector.h:
+        * css/CSSValue.cpp:
+        * css/CSSValue.h:
+        * css/StyleProperties.cpp:
+        (WebCore::ImmutableStyleProperties::create):
+        * css/StyleProperties.h:
+        * css/StyleRule.cpp:
+        * css/StyleRule.h:
+        * dom/ElementData.cpp:
+        (WebCore::ShareableElementData::createWithAttributes):
+        (WebCore::UniqueElementData::makeShareableCopy const):
+        * dom/ElementData.h:
+        * dom/NodeRareData.cpp:
+        * dom/NodeRareData.h:
+        * dom/QualifiedName.cpp:
+        * dom/QualifiedName.h:
+        * html/parser/HTMLDocumentParser.cpp:
+        * html/parser/HTMLDocumentParser.h:
+        * loader/DocumentLoader.cpp:
+        * loader/DocumentLoader.h:
+        * loader/ResourceLoader.cpp:
+        * loader/ResourceLoader.h:
+        * loader/cache/CachedResource.cpp:
+        * loader/cache/CachedResource.h:
+        * page/PerformanceEntry.cpp:
+        * page/PerformanceEntry.h:
+        * platform/graphics/Font.cpp:
+        * platform/graphics/Font.h:
+        * platform/graphics/FontCascadeFonts.cpp:
+        * platform/graphics/FontCascadeFonts.h:
+        * platform/graphics/Region.cpp:
+        * platform/graphics/Region.h:
+        * platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
+        (WebCore::releaseUint8Vector):
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageBuffer::ImageBuffer):
+        * platform/graphics/nicosia/NicosiaBuffer.cpp:
+        (Nicosia::Buffer::Buffer):
+        * platform/network/ResourceHandle.cpp:
+        * platform/network/ResourceHandleInternal.h:
+        * platform/network/cf/FormDataStreamCFNet.cpp:
+        (WebCore::closeCurrentStream):
+        (WebCore::advanceCurrentStream):
+        * rendering/RenderLayer.cpp:
+        * rendering/RenderLayer.h:
+        * rendering/TableLayout.cpp: Copied from Source/JavaScriptCore/parser/SourceProviderCache.cpp.
+        * rendering/TableLayout.h:
+        * rendering/style/RenderStyle.cpp:
+        * rendering/style/RenderStyle.h:
+        * rendering/style/SVGRenderStyle.cpp:
+        * rendering/style/SVGRenderStyle.h:
+        * rendering/style/SVGRenderStyleDefs.cpp:
+        * rendering/style/SVGRenderStyleDefs.h:
+        * rendering/style/StyleBoxData.cpp:
+        * rendering/style/StyleBoxData.h:
+        * rendering/style/StyleInheritedData.cpp:
+        * rendering/style/StyleInheritedData.h:
+        * rendering/style/StyleRareInheritedData.cpp:
+        * rendering/style/StyleRareInheritedData.h:
+        * rendering/style/StyleRareNonInheritedData.cpp:
+        * rendering/style/StyleRareNonInheritedData.h:
+        * rendering/style/StyleSurroundData.cpp:
+        * rendering/style/StyleSurroundData.h:
+        * rendering/style/StyleTransformData.cpp:
+        * rendering/style/StyleTransformData.h:
+        * style/StyleTreeResolver.cpp:
+        * style/StyleTreeResolver.h:
+        * svg/animation/SMILTimeContainer.cpp:
+        * svg/animation/SMILTimeContainer.h:
+
 2020-01-02  Andy Estes  <aestes@apple.com>
 
         [Payment Request] Perform payment method data IDL conversion in the PaymentRequest constructor
index fb323b6..775a9b6 100644 (file)
@@ -2197,6 +2197,7 @@ rendering/SimpleLineLayoutFunctions.cpp
 rendering/SimpleLineLayoutPagination.cpp
 rendering/SimpleLineLayoutResolver.cpp
 rendering/SimpleLineLayoutTextFragmentIterator.cpp
+rendering/TableLayout.cpp
 rendering/TextDecorationPainter.cpp
 rendering/TextPaintStyle.cpp
 rendering/TextPainter.cpp
index e65e06f..ac71653 100644 (file)
                E307DED21D81E4ED00141CAF /* LoadableModuleScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableModuleScript.cpp; sourceTree = "<group>"; };
                E307DED31D81E4ED00141CAF /* LoadableModuleScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableModuleScript.h; sourceTree = "<group>"; };
                E3150EA51DA7218D00194012 /* DOMJITHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITHelpers.h; sourceTree = "<group>"; };
+               E31CD750229F749500FBDA19 /* TableLayout.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableLayout.cpp; sourceTree = "<group>"; };
                E323CFF91E5AF6A500F0B4A0 /* JSDOMConvertPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertPromise.h; sourceTree = "<group>"; };
                E329275E22543F5700308A9A /* TypedOMCSSStyleValue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypedOMCSSStyleValue.cpp; sourceTree = "<group>"; };
                E329276022543F5800308A9A /* TypedOMCSSImageValue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypedOMCSSImageValue.cpp; sourceTree = "<group>"; };
                                E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */,
                                582CB0541A78A2B200AFFCC4 /* SimpleLineLayoutTextFragmentIterator.cpp */,
                                582CB0521A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h */,
+                               E31CD750229F749500FBDA19 /* TableLayout.cpp */,
                                A8CFF04C0A154F09000A4234 /* TableLayout.h */,
                                0F54DCE31881051D003EEDBB /* TextAutoSizing.cpp */,
                                0F54DCE41881051D003EEDBB /* TextAutoSizing.h */,
index a7fe671..1817515 100644 (file)
@@ -96,6 +96,8 @@
 namespace WebCore {
 using namespace JSC;
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SerializedScriptValue);
+
 static const unsigned maximumFilterRecursion = 40000;
 
 enum class SerializationReturnCode {
index a4b9f66..e288f29 100644 (file)
@@ -61,7 +61,9 @@ using ArrayBufferContentsArray = Vector<JSC::ArrayBufferContents>;
 using WasmModuleArray = Vector<RefPtr<JSC::Wasm::Module>>;
 #endif
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(SerializedScriptValue);
 class SerializedScriptValue : public ThreadSafeRefCounted<SerializedScriptValue> {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(SerializedScriptValue);
 public:
     WEBCORE_EXPORT static RefPtr<SerializedScriptValue> create(JSC::JSGlobalObject&, JSC::JSValue, SerializationErrorMode = SerializationErrorMode::Throwing);
 
index 2d429bc..a99f611 100644 (file)
@@ -47,6 +47,8 @@
 
 namespace WebCore {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSFontFace);
+
 template<typename T> void iterateClients(HashSet<CSSFontFace::Client*>& clients, T callback)
 {
     Vector<Ref<CSSFontFace::Client>> clientsCopy;
index 85997ad..909bb2e 100644 (file)
@@ -54,7 +54,9 @@ class Font;
 class FontFace;
 enum class ExternalResourceDownloadPolicy;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSFontFace);
 class CSSFontFace final : public RefCounted<CSSFontFace> {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(CSSFontFace);
 public:
     static Ref<CSSFontFace> create(CSSFontSelector* fontSelector, StyleRuleFontFace* cssConnection = nullptr, FontFace* wrapper = nullptr, bool isLocalFallback = false)
     {
index ca989dd..f1680b2 100644 (file)
@@ -49,6 +49,8 @@ struct SameSizeAsCSSSelector {
 static_assert(CSSSelector::RelationType::Subselector == 0, "Subselector must be 0 for consumeCombinator.");
 static_assert(sizeof(CSSSelector) == sizeof(SameSizeAsCSSSelector), "CSSSelector should remain small.");
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSSelectorRareData);
+
 CSSSelector::CSSSelector(const QualifiedName& tagQName, bool tagIsForNamespaceRule)
     : m_relation(DescendantSpace)
     , m_match(Tag)
index f4c335f..2043947 100644 (file)
@@ -34,6 +34,7 @@ namespace WebCore {
     };
 
     // this class represents a selector for a StyleRule
+    DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSSelectorRareData);
     class CSSSelector {
         WTF_MAKE_FAST_ALLOCATED;
     public:
@@ -348,6 +349,7 @@ namespace WebCore {
         CSSSelector& operator=(const CSSSelector&);
 
         struct RareData : public RefCounted<RareData> {
+            WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(CSSSelectorRareData);
             static Ref<RareData> create(AtomString&& value) { return adoptRef(*new RareData(WTFMove(value))); }
             ~RareData();
 
index 50d2a97..6fa660a 100644 (file)
@@ -85,6 +85,8 @@ bool CSSValue::isImplicitInitialValue() const
     return m_classType == InitialClass && downcast<CSSInitialValue>(*this).isImplicit();
 }
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSValue);
+
 CSSValue::Type CSSValue::cssValueType() const
 {
     if (isInheritedValue())
index aca7afe..9428a95 100644 (file)
@@ -38,7 +38,9 @@ class StyleSheetContents;
 
 enum CSSPropertyID : uint16_t;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSValue);
 class CSSValue : public RefCounted<CSSValue> {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(CSSValue);
 public:
     enum Type {
         CSS_INHERIT = 0,
index 5e9974f..a0aefa5 100644 (file)
 
 namespace WebCore {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StyleProperties);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ImmutableStyleProperties);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MutableStyleProperties);
+
 static size_t sizeForImmutableStylePropertiesWithPropertyCount(unsigned count)
 {
     return sizeof(ImmutableStyleProperties) - sizeof(void*) + sizeof(CSSValue*) * count + sizeof(StylePropertyMetadata) * count;
@@ -61,7 +65,7 @@ static bool isInitialOrInherit(const String& value)
 
 Ref<ImmutableStyleProperties> ImmutableStyleProperties::create(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode)
 {
-    void* slot = WTF::fastMalloc(sizeForImmutableStylePropertiesWithPropertyCount(count));
+    void* slot = ImmutableStylePropertiesMalloc::malloc(sizeForImmutableStylePropertiesWithPropertyCount(count));
     return adoptRef(*new (NotNull, slot) ImmutableStyleProperties(properties, count, cssParserMode));
 }
 
index 37ae564..260f43d 100644 (file)
@@ -74,7 +74,9 @@ protected:
     unsigned m_arraySize : 27;
 };
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StyleProperties);
 class StyleProperties : public StylePropertiesBase {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(StyleProperties);
     friend class PropertyReference;
 public:
     class PropertyReference {
@@ -177,7 +179,9 @@ private:
     friend class PropertySetCSSStyleDeclaration;
 };
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ImmutableStyleProperties);
 class ImmutableStyleProperties final : public StyleProperties {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(ImmutableStyleProperties);
 public:
     WEBCORE_EXPORT ~ImmutableStyleProperties();
     static Ref<ImmutableStyleProperties> create(const CSSProperty* properties, unsigned count, CSSParserMode);
@@ -207,7 +211,9 @@ inline const StylePropertyMetadata* ImmutableStyleProperties::metadataArray() co
     return reinterpret_cast_ptr<const StylePropertyMetadata*>(&reinterpret_cast_ptr<const char*>(&(this->m_storage))[m_arraySize * sizeof(CSSValue*)]);
 }
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MutableStyleProperties);
 class MutableStyleProperties final : public StyleProperties {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(MutableStyleProperties);
 public:
     WEBCORE_EXPORT static Ref<MutableStyleProperties> create(CSSParserMode = HTMLQuirksMode);
     static Ref<MutableStyleProperties> create(Vector<CSSProperty>&&);
@@ -350,3 +356,4 @@ SPECIALIZE_TYPE_TRAITS_END()
 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DeferredStyleProperties)
     static bool isType(const WebCore::StylePropertiesBase& set) { return set.type() == WebCore::DeferredPropertiesType; }
 SPECIALIZE_TYPE_TRAITS_END()
+
index 1f99fdf..d46babe 100644 (file)
@@ -45,6 +45,9 @@ struct SameSizeAsStyleRuleBase : public WTF::RefCountedBase {
 
 COMPILE_ASSERT(sizeof(StyleRuleBase) == sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StyleRuleBase);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StyleRule);
+
 Ref<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
 {
     return createCSSOMWrapper(parentSheet, nullptr);
index 562d3e8..c50c79e 100644 (file)
@@ -40,8 +40,9 @@ class StyleRuleKeyframe;
 class StyleProperties;
 class StyleRuleKeyframes;
     
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StyleRuleBase);
 class StyleRuleBase : public WTF::RefCountedBase {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(StyleRuleBase);
 public:
     StyleRuleType type() const { return static_cast<StyleRuleType>(m_type); }
     
@@ -99,8 +100,9 @@ private:
     unsigned m_hasDocumentSecurityOrigin : 1;
 };
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(StyleRule);
 class StyleRule final : public StyleRuleBase {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(StyleRule);
 public:
     static Ref<StyleRule> create(Ref<StylePropertiesBase>&& properties, bool hasDocumentSecurityOrigin, CSSSelectorList&& selectors)
     {
index 9515305..bed6f3c 100644 (file)
@@ -33,6 +33,9 @@
 
 namespace WebCore {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ElementData);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ShareableElementData);
+
 void ElementData::destroy()
 {
     if (is<UniqueElementData>(*this))
@@ -65,7 +68,7 @@ static size_t sizeForShareableElementDataWithAttributeCount(unsigned count)
 
 Ref<ShareableElementData> ShareableElementData::createWithAttributes(const Vector<Attribute>& attributes)
 {
-    void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(attributes.size()));
+    void* slot = ShareableElementDataMalloc::malloc(sizeForShareableElementDataWithAttributeCount(attributes.size()));
     return adoptRef(*new (NotNull, slot) ShareableElementData(attributes));
 }
 
@@ -157,7 +160,7 @@ Ref<UniqueElementData> ElementData::makeUniqueCopy() const
 
 Ref<ShareableElementData> UniqueElementData::makeShareableCopy() const
 {
-    void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size()));
+    void* slot = ShareableElementDataMalloc::malloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size()));
     return adoptRef(*new (NotNull, slot) ShareableElementData(*this));
 }
 
index 7158d1d..a454999 100644 (file)
@@ -75,8 +75,9 @@ private:
     unsigned m_size;
 };
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ElementData);
 class ElementData : public RefCounted<ElementData> {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(ElementData);
 public:
     // Override RefCounted's deref() to ensure operator delete is called on
     // the appropriate subclass type.
@@ -183,7 +184,9 @@ private:
 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
 #endif
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ShareableElementData);
 class ShareableElementData : public ElementData {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(ShareableElementData);
 public:
     static Ref<ShareableElementData> createWithAttributes(const Vector<Attribute>&);
 
index ea906d6..4eb631c 100644 (file)
@@ -45,4 +45,7 @@ COMPILE_ASSERT(sizeof(NodeRareData) == sizeof(SameSizeAsNodeRareData), NodeRareD
 // Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
 static_assert(Page::maxNumberOfFrames < 1024, "Frame limit should fit in rare data count");
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(NodeListsNodeData);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(NodeRareData);
+
 } // namespace WebCore
index 376412b..2712d1e 100644 (file)
@@ -38,9 +38,10 @@ class RadioNodeList;
 
 template<typename ListType> struct NodeListTypeIdentifier;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(NodeListsNodeData);
 class NodeListsNodeData {
     WTF_MAKE_NONCOPYABLE(NodeListsNodeData);
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(NodeListsNodeData);
 public:
     NodeListsNodeData() = default;
 
@@ -237,8 +238,10 @@ public:
     NodeMutationObserverData() { }
 };
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(NodeRareData);
 class NodeRareData {
-    WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(NodeRareData);
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(NodeRareData);
 public:
 #if defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS
     enum class UseType : uint16_t {
index 46a9566..66008cf 100644 (file)
@@ -26,6 +26,9 @@
 
 namespace WebCore {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(QualifiedName);
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(QualifiedNameQualifiedNameImpl);
+
 QualifiedName::QualifiedName(const AtomString& p, const AtomString& l, const AtomString& n)
     : m_impl(threadGlobalData().qualifiedNameCache().getOrCreate(QualifiedNameComponents { p.impl(), l.impl(), n.isEmpty() ? nullptr : n.impl() }))
 {
index 20f1244..7d80b62 100644 (file)
@@ -32,10 +32,14 @@ struct QualifiedNameComponents {
     StringImpl* m_namespace;
 };
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(QualifiedName);
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(QualifiedNameQualifiedNameImpl);
+
 class QualifiedName {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(QualifiedName);
 public:
     class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> {
+        WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(QualifiedNameQualifiedNameImpl);
     public:
         static Ref<QualifiedNameImpl> create(const AtomString& prefix, const AtomString& localName, const AtomString& namespaceURI)
         {
index 5a632d8..e66a0f3 100644 (file)
@@ -49,6 +49,8 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HTMLDocumentParser);
+
 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document)
     : ScriptableDocumentParser(document)
     , m_options(document)
index 9990d8b..e1eb45c 100644 (file)
@@ -47,8 +47,9 @@ class HTMLTreeBuilder;
 class HTMLResourcePreloader;
 class PumpSession;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(HTMLDocumentParser);
 class HTMLDocumentParser : public ScriptableDocumentParser, private HTMLScriptRunnerHost, private PendingScriptClient {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(HTMLDocumentParser);
 public:
     static Ref<HTMLDocumentParser> create(HTMLDocument&);
     virtual ~HTMLDocumentParser();
index 11b92f4..5d12564 100644 (file)
@@ -136,6 +136,8 @@ DocumentLoader* DocumentLoader::fromTemporaryDocumentIdentifier(DocumentIdentifi
     return temporaryIdentifierToLoaderMap().get(identifier);
 }
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(DocumentLoader);
+
 DocumentLoader::DocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
     : FrameDestructionObserver(nullptr)
     , m_cachedResourceLoader(CachedResourceLoader::create(this))
index e8763bf..05f4c14 100644 (file)
@@ -137,12 +137,13 @@ enum class LegacyOverflowScrollingTouchPolicy : uint8_t {
     Enable,
 };
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(DocumentLoader);
 class DocumentLoader
     : public RefCounted<DocumentLoader>
     , public FrameDestructionObserver
     , public ContentSecurityPolicyClient
     , private CachedRawResourceClient {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(DocumentLoader);
     friend class ContentFilter;
 public:
     static Ref<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data)
index 5c3d418..df7e571 100644 (file)
@@ -68,6 +68,8 @@
 
 namespace WebCore {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ResourceLoader);
+
 ResourceLoader::ResourceLoader(Frame& frame, ResourceLoaderOptions options)
     : m_frame { &frame }
     , m_documentLoader { frame.loader().activeDocumentLoader() }
index 5ad6660..057102e 100644 (file)
@@ -54,7 +54,9 @@ class FrameLoader;
 class LegacyPreviewLoader;
 class NetworkLoadMetrics;
 
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ResourceLoader);
 class ResourceLoader : public CanMakeWeakPtr<ResourceLoader>, public RefCounted<ResourceLoader>, protected ResourceHandleClient {
+    WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(ResourceLoader);
 public:
     virtual ~ResourceLoader() = 0;
 
index fc9cbbc..c75b3dc 100644 (file)
@@ -65,6 +65,8 @@
 
 namespace WebCore {
 
+DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CachedResource);
+
 ResourceLoadPriority CachedResource::defaultPriorityForResourceType(Type type)
 {
     switch (type) {
index 7f8cb1f..183a656 100644 (file)
@@ -56,8 +56,10 @@ class TextResourceDecoder;
 // A resource that is held in the cache. Classes who want to use this object should derive
 // from CachedResourceClient, to get the function calls in case the requested data has arrived.
 // This class also does the actual communication with the loader to obtain the resource from the network.
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CachedResource);
 class CachedResource {
-    WTF_MAKE_NONCOPYABLE(CachedResource); WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(CachedResource);