WebKit Bugzilla
Attachment 370923 Details for
Bug 186422
: Experiment: create lots of different malloc zones for easier accounting of memory use
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186422-20190529222420.patch (text/plain), 285.20 KB, created by
Yusuke Suzuki
on 2019-05-29 22:24:21 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2019-05-29 22:24:21 PDT
Size:
285.20 KB
patch
obsolete
>Subversion Revision: 245880 >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index bda0c56cba220d6dbf3e462ef86d803576f78644..ce48f26da9da25a5b1c3f9805588b5a0e275215a 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -496,6 +496,8 @@ > 0FA2C17C17D7CF84009D015F /* TestRunnerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA2C17A17D7CF84009D015F /* TestRunnerUtils.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0FA581BB150E953000B9A2D9 /* DFGNodeFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */; }; > 0FA581BC150E953000B9A2D9 /* DFGNodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */; }; >+ 0FA6F38D20CC2C9600A03DCD /* GCSegmentedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA6F38C20CC2C9500A03DCD /* GCSegmentedArray.cpp */; }; >+ 0FA6F39720CCB7A600A03DCD /* AssemblerBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA6F39620CCB7A600A03DCD /* AssemblerBuffer.cpp */; }; > 0FA762051DB9242900B7A2FD /* CollectionScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA762011DB9242300B7A2FD /* CollectionScope.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0FA762071DB9243300B7A2FD /* MutatorState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA762031DB9242300B7A2FD /* MutatorState.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0FA7620B1DB959F900B7A2FD /* AllocatingScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7620A1DB959F600B7A2FD /* AllocatingScope.h */; }; >@@ -2724,6 +2726,8 @@ > 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>"; }; >@@ -4727,6 +4731,7 @@ > E3060128228F978100FAABDF /* UnlinkedMetadataTable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedMetadataTable.cpp; sourceTree = "<group>"; }; > E30677971B8BC6F5003F87F0 /* ModuleLoader.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = ModuleLoader.js; sourceTree = "<group>"; }; > E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SymbolTableOrScopeDepth.h; sourceTree = "<group>"; }; >+ E3149A3C228BE14700BFA6C7 /* UnlinkedMetadataTable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedMetadataTable.cpp; sourceTree = "<group>"; }; > E31618101EC5FE080006A218 /* DOMAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMAnnotation.h; sourceTree = "<group>"; }; > E31618111EC5FE080006A218 /* DOMAttributeGetterSetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMAttributeGetterSetter.cpp; sourceTree = "<group>"; }; > E31618121EC5FE080006A218 /* DOMAttributeGetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMAttributeGetterSetter.h; sourceTree = "<group>"; }; >@@ -5958,6 +5963,7 @@ > 2AABCDE618EF294200002096 /* GCLogging.h */, > 0F97152E1EB28BE900A1645D /* GCRequest.cpp */, > 0F97152F1EB28BE900A1645D /* GCRequest.h */, >+ 0FA6F38C20CC2C9500A03DCD /* GCSegmentedArray.cpp */, > 2A343F7418A1748B0039B085 /* GCSegmentedArray.h */, > 2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */, > 0F86A26E1D6F7B3100CB0C92 /* GCTypeMap.h */, >@@ -7829,6 +7835,7 @@ > 8640923B156EED3B00566CB2 /* ARM64Assembler.h */, > FE1E2C3D2240D2F600F6B729 /* ARM64EAssembler.h */, > 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */, >+ 0FA6F39620CCB7A600A03DCD /* AssemblerBuffer.cpp */, > 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */, > 86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */, > 43C392AA1C3BEB0000241F53 /* AssemblerCommon.h */, >@@ -10739,11 +10746,13 @@ > isa = PBXSourcesBuildPhase; > buildActionMask = 2147483647; > files = ( >+ 0FA6F39720CCB7A600A03DCD /* AssemblerBuffer.cpp in Sources */, > FE05FAFD1FE4CEDA00093230 /* DeprecatedInspectorValues.cpp in Sources */, > 5333BBDC2110F7D9007618EC /* DFGSpeculativeJIT.cpp in Sources */, > 5333BBDB2110F7D2007618EC /* DFGSpeculativeJIT32_64.cpp in Sources */, > 5333BBDD2110F7E1007618EC /* DFGSpeculativeJIT64.cpp in Sources */, > 33B2A548226543BF005A0F79 /* FTLLowerDFGToB3.cpp in Sources */, >+ 0FA6F38D20CC2C9600A03DCD /* GCSegmentedArray.cpp in Sources */, > 5C4196622270E0000047B7CD /* InspectorBackendDispatcherCompatibility.cpp in Sources */, > 536B319E1F735F160037FC33 /* LowLevelInterpreter.cpp in Sources */, > 0FF4274A158EBE91004CB9FF /* udis86.c in Sources */, >diff --git a/Source/JavaScriptCore/assembler/AssemblerBuffer.cpp b/Source/JavaScriptCore/assembler/AssemblerBuffer.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..ae5a61eb93bd3b4c4f1aa27af1d9cac54e6969a2 >--- /dev/null >+++ b/Source/JavaScriptCore/assembler/AssemblerBuffer.cpp >@@ -0,0 +1,35 @@ >+/* >+ * Copyright (C) 2018 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_DEBUG_HEAP_ALLOCATOR(AssemblerData); >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/assembler/AssemblerBuffer.h b/Source/JavaScriptCore/assembler/AssemblerBuffer.h >index 59131326ac9f10944ae488fd96d971c04b121277..c6603692fe49d181169be53ac1368c360f38e909 100644 >--- a/Source/JavaScriptCore/assembler/AssemblerBuffer.h >+++ b/Source/JavaScriptCore/assembler/AssemblerBuffer.h >@@ -43,6 +43,8 @@ namespace JSC { > > class LinkBuffer; > >+ DECLARE_DEBUG_HEAP_ALLOCATOR(AssemblerData); >+ > struct AssemblerLabel { > AssemblerLabel() > : m_offset(std::numeric_limits<uint32_t>::max()) >@@ -83,7 +85,8 @@ 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 +107,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 +125,7 @@ namespace JSC { > ~AssemblerData() > { > if (m_buffer && !isInlineBuffer()) >- fastFree(m_buffer); >+ AssemblerDataMalloc::free(m_buffer); > } > > char* buffer() const { return m_buffer; } >@@ -133,10 +136,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: >diff --git a/Source/JavaScriptCore/bytecode/AccessCase.cpp b/Source/JavaScriptCore/bytecode/AccessCase.cpp >index c10859aced3db78b664976a08b8e5b48d652b2f3..93a029dc0a58d3022084a6fcea164872de1e0977 100644 >--- a/Source/JavaScriptCore/bytecode/AccessCase.cpp >+++ b/Source/JavaScriptCore/bytecode/AccessCase.cpp >@@ -54,6 +54,8 @@ namespace AccessCaseInternal { > static const bool verbose = false; > } > >+DEFINE_DEBUG_HEAP_ALLOCATOR(AccessCase); >+ > AccessCase::AccessCase(VM& vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain) > : m_type(type) > , m_offset(offset) >diff --git a/Source/JavaScriptCore/bytecode/AccessCase.h b/Source/JavaScriptCore/bytecode/AccessCase.h >index 170af5d0e52d03f31fadb12981930a538fdcb071..36a7664da839929595a3fa2baefa3ad129a8fc56 100644 >--- a/Source/JavaScriptCore/bytecode/AccessCase.h >+++ b/Source/JavaScriptCore/bytecode/AccessCase.h >@@ -36,6 +36,8 @@ namespace JSC { > > struct AccessGenerationState; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(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. >@@ -77,7 +79,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_FROM_DEBUG_HEAP(AccessCase); > public: > enum AccessType : uint8_t { > Load, >diff --git a/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp b/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp >index 33bb0c06635381e898f65a874f1f36a8c94823af..70715e83fb874a9b57503619b6357c177a298af0 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp >@@ -33,6 +33,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(BytecodeBasicBlock); >+ > void BytecodeBasicBlock::shrinkToFit() > { > m_offsets.shrinkToFit(); >diff --git a/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h b/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h >index 20e124c585bf6af82a4c4cf8c718afe4f3484b64..1b563007ccd9aae882db0bde53699fa5d8db3700 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h >+++ b/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h >@@ -36,8 +36,10 @@ class CodeBlock; > class UnlinkedCodeBlock; > struct Instruction; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(BytecodeBasicBlock); >+ > class BytecodeBasicBlock { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(BytecodeBasicBlock); > public: > enum SpecialBlockType { EntryBlock, ExitBlock }; > BytecodeBasicBlock(const InstructionStream::Ref&); >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index 18ba96a239bef08d458b2f36232520306f7488eb..8510323979a258e869327434dce461afe2658e41 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -109,6 +109,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(CodeBlockRareData); >+ > const ClassInfo CodeBlock::s_info = { > "CodeBlock", nullptr, nullptr, nullptr, > CREATE_METHOD_TABLE(CodeBlock) >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h >index 98dbf647549c789c24858c224157cc467e7cc7fb..eaa01c207f371571a266d211dbce1da574895947 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h >@@ -94,6 +94,8 @@ class PCToCodeOriginMap; > class RegisterAtOffsetList; > class StructureStubInfo; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(CodeBlockRareData); >+ > enum class AccessType : int8_t; > > struct ArithProfile; >@@ -840,7 +842,7 @@ class CodeBlock : public JSCell { > NO_RETURN_DUE_TO_CRASH void endValidationDidFail(); > > struct RareData { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(CodeBlockRareData); > public: > Vector<HandlerInfo> m_exceptionHandlers; > >@@ -883,6 +885,8 @@ class CodeBlock : public JSCell { > return m_unlinkedCode->metadataSizeInBytes(); > } > >+ MetadataTable* metadataTable() const { return m_metadata.get(); } >+ > protected: > void finalizeLLIntInlineCaches(); > #if ENABLE(JIT) >diff --git a/Source/JavaScriptCore/bytecode/InstructionStream.cpp b/Source/JavaScriptCore/bytecode/InstructionStream.cpp >index 514cf11253eb4a28694c80fe8e522a6233fd9773..a121edc01349f0d163ed7e1ee4335e51207381e7 100644 >--- a/Source/JavaScriptCore/bytecode/InstructionStream.cpp >+++ b/Source/JavaScriptCore/bytecode/InstructionStream.cpp >@@ -31,6 +31,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(InstructionStream); >+ > InstructionStream::InstructionStream(InstructionBuffer&& instructions) > : m_instructions(WTFMove(instructions)) > { } >diff --git a/Source/JavaScriptCore/bytecode/InstructionStream.h b/Source/JavaScriptCore/bytecode/InstructionStream.h >index ce9607b372f3bda529a9b5e1fbc74ab60f5c2584..1c13d767e31a847dca277d7841b0c0706e1b2093 100644 >--- a/Source/JavaScriptCore/bytecode/InstructionStream.h >+++ b/Source/JavaScriptCore/bytecode/InstructionStream.h >@@ -33,10 +33,12 @@ namespace JSC { > > struct Instruction; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(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; >diff --git a/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp b/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp >index c695f7e36dc376c5553bb30bebb7e53ec1b19186..876b4b16f77ed6b3a8deff52ba25c6097d56bcce 100644 >--- a/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp >+++ b/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp >@@ -48,6 +48,8 @@ namespace PolymorphicAccessInternal { > static const bool verbose = false; > } > >+DEFINE_DEBUG_HEAP_ALLOCATOR(PolymorphicAccess); >+ > void AccessGenerationResult::dump(PrintStream& out) const > { > out.print(m_kind); >@@ -212,7 +214,6 @@ void AccessGenerationState::emitExplicitExceptionHandler() > } > } > >- > PolymorphicAccess::PolymorphicAccess() { } > PolymorphicAccess::~PolymorphicAccess() { } > >diff --git a/Source/JavaScriptCore/bytecode/PolymorphicAccess.h b/Source/JavaScriptCore/bytecode/PolymorphicAccess.h >index 30558551cbcab019f458f739d569ceee1c0462ae..60c3b8f7da2c6181c9bc900e6fbf7539a07dc783 100644 >--- a/Source/JavaScriptCore/bytecode/PolymorphicAccess.h >+++ b/Source/JavaScriptCore/bytecode/PolymorphicAccess.h >@@ -45,6 +45,8 @@ class StructureStubInfo; > class WatchpointsOnStructureStubInfo; > class ScratchRegisterAllocator; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(PolymorphicAccess); >+ > class AccessGenerationResult { > public: > enum Kind { >@@ -129,7 +131,7 @@ class AccessGenerationResult { > > class PolymorphicAccess { > WTF_MAKE_NONCOPYABLE(PolymorphicAccess); >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(PolymorphicAccess); > public: > PolymorphicAccess(); > ~PolymorphicAccess(); >diff --git a/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp b/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp >index 30a1f055259e3ded1a7168ee3526f72c084bee5a..ae8e091f886bf1fa65d06b3da61c491b33fba0f1 100644 >--- a/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp >+++ b/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp >@@ -34,6 +34,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StructureStubClearingWatchpoint); >+ > void StructureStubClearingWatchpoint::fireInternal(VM& vm, const FireDetail&) > { > if (!m_holder->isValid()) >diff --git a/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h b/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h >index 31f6aa4885e4abda12b47038d5383e373b9a1d80..5f792ed8c792d31fdaa5735e77663a940278a51d 100644 >--- a/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h >+++ b/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h >@@ -40,9 +40,11 @@ class CodeBlock; > class StructureStubInfo; > class WatchpointsOnStructureStubInfo; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StructureStubClearingWatchpoint); >+ > class StructureStubClearingWatchpoint final : public Watchpoint { > WTF_MAKE_NONCOPYABLE(StructureStubClearingWatchpoint); >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(StructureStubClearingWatchpoint); > public: > StructureStubClearingWatchpoint(const ObjectPropertyCondition& key, WatchpointsOnStructureStubInfo& holder) > : Watchpoint(Watchpoint::Type::StructureStubClearing) >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp b/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp >index e7f782a0f91386f1ec75bb2953b615c3720a72d0..ad42145ed072c90740e2699d36b8115ef6d0655d 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp >+++ b/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp >@@ -33,8 +33,22 @@ > #include "UnlinkedMetadataTableInlines.h" > #include <wtf/FastMalloc.h> > >+#include "Instruction.h" >+#include "Opcode.h" >+#include "VM.h" >+#include "CodeBlock.h" >+#include "HeapIterationScope.h" >+#include "SubspaceInlines.h" >+ >+#include <syslog.h> >+ > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(MetadataTable); >+ >+static std::atomic<unsigned> liveUnlinkedMetadataTableWithTable { 0 }; >+static std::atomic<unsigned> liveMetadataTable { 0 }; >+ > #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 +58,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 +83,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 +95,50 @@ 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))); >+ } >+} >+ >+void UnlinkedMetadataTable::dumpStatus(VM& vm) >+{ >+ syslog(LOG_WARNING, "UNLINKED METADATA TABLES %u", liveUnlinkedMetadataTableWithTable.load()); >+ syslog(LOG_WARNING, "METADATA TABLES %u", liveMetadataTable.load()); >+ { >+ HeapIterationScope iterationScope(vm.heap); >+ HashSet<MetadataTable*> tables; >+ size_t sumOfMetadataTable = 0; >+ vm.codeBlockSpace.space.forEachLiveCell([&] (HeapCell* cell, HeapCell::Kind) { >+ CodeBlock* codeBlock = static_cast<CodeBlock*>(cell); >+ if (auto* metadataTable = codeBlock->metadataTable()) >+ tables.add(metadataTable); >+ }); >+ for (auto* metadataTable : tables) >+ sumOfMetadataTable += metadataTable->sizeInBytes(); >+ >+ syslog(LOG_WARNING, "METADATA TABLES SIZE %lu", sumOfMetadataTable); >+ if (sumOfMetadataTable) { >+ std::array<size_t, NUMBER_OF_BYTECODE_WITH_METADATA> histogram { }; >+ >+ for (auto* metadataTable : tables) { >+ for (unsigned i = 0; i < NUMBER_OF_BYTECODE_WITH_METADATA; i++) { >+#define CASE(__Op) \ >+ case __Op::opcodeID: \ >+ metadataTable->forEach<__Op>([&] (auto&) { histogram[i] += 1; }); \ >+ break; \ >+ >+ switch (static_cast<OpcodeID>(i)) { >+ FOR_EACH_BYTECODE_STRUCT(CASE) >+ default: >+ ASSERT_NOT_REACHED(); >+ } >+ >+#undef CASE >+ } >+ } >+ for (unsigned i = 0; i < NUMBER_OF_BYTECODE_WITH_METADATA; i++) { >+ syslog(LOG_WARNING, "METADATA[%s] = %lu", opcodeNames[i], histogram[i]); >+ } >+ } > } > } > >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h b/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h >index 17f173fd4e7aaab104cf4e8ea3e59ab960711bb1..85aa20304562b7eca17bf8ea9acea7148a90ee1b 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h >@@ -31,6 +31,10 @@ > > namespace JSC { > >+class VM; >+ >+DECLARE_DEBUG_HEAP_ALLOCATOR(MetadataTable); >+ > class MetadataTable; > > class UnlinkedMetadataTable : public RefCounted<UnlinkedMetadataTable> { >@@ -60,6 +64,8 @@ class UnlinkedMetadataTable : public RefCounted<UnlinkedMetadataTable> { > return adoptRef(*new UnlinkedMetadataTable); > } > >+ JS_EXPORT_PRIVATE static void dumpStatus(VM&); >+ > private: > UnlinkedMetadataTable(); > UnlinkedMetadataTable(bool is32Bit); >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h b/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h >index 32450da1e580c2e4f3b216dabf5e441a5bbc4a66..4faa67aa07767bf4715c5792d7b54fcbb513f908 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h >@@ -31,12 +31,13 @@ > > 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,15 +46,16 @@ 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)))) > { > } > >+ > 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) >@@ -101,9 +103,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); >@@ -119,10 +121,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 >diff --git a/Source/JavaScriptCore/bytecode/ValueProfile.h b/Source/JavaScriptCore/bytecode/ValueProfile.h >index 4883b4b3d21bbfc8ed66cfb947590d7095ab61ef..13f1263cf03f4acda5c827ee211a836950d6021f 100644 >--- a/Source/JavaScriptCore/bytecode/ValueProfile.h >+++ b/Source/JavaScriptCore/bytecode/ValueProfile.h >@@ -183,11 +183,18 @@ struct ValueProfileAndOperand : public ValueProfile { > struct ValueProfileAndOperandBuffer { > ValueProfileAndOperandBuffer(unsigned size) > : m_size(size) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , m_buffer(VMDebugHeap()) >+#endif > { > // 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<ValueProfileAndOperand>::malloc(m_size * sizeof(ValueProfileAndOperand)); >+ m_buffer = MallocPtr<ValueProfileAndOperand>::malloc(m_size * sizeof(ValueProfileAndOperand) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , VMDebugHeap() >+#endif >+ ); > for (unsigned i = 0; i < m_size; ++i) > new (&m_buffer.get()[i]) ValueProfileAndOperand(); > } >diff --git a/Source/JavaScriptCore/bytecode/Watchpoint.cpp b/Source/JavaScriptCore/bytecode/Watchpoint.cpp >index 3d70df42aa33cb369364d93fdb4a2468f33cc30c..9a1baac5d47e90f250a961d2b2057325ba54c7f8 100644 >--- a/Source/JavaScriptCore/bytecode/Watchpoint.cpp >+++ b/Source/JavaScriptCore/bytecode/Watchpoint.cpp >@@ -39,6 +39,9 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(Watchpoint); >+DEFINE_DEBUG_HEAP_ALLOCATOR(WatchpointSet); >+ > void StringFireDetail::dump(PrintStream& out) const > { > out.print(m_string); >diff --git a/Source/JavaScriptCore/bytecode/Watchpoint.h b/Source/JavaScriptCore/bytecode/Watchpoint.h >index ee8dd75ea1e2d5d76e8ba905814f763c8905b7ba..99705494e3c2de4e903063c70f3985e901fbd9b3 100644 >--- a/Source/JavaScriptCore/bytecode/Watchpoint.h >+++ b/Source/JavaScriptCore/bytecode/Watchpoint.h >@@ -135,11 +135,12 @@ class WatchpointSet; > type member; \ > static_assert(std::is_trivially_destructible<type>::value, ""); \ > >+DECLARE_DEBUG_HEAP_ALLOCATOR(Watchpoint); > > class Watchpoint : public PackedRawSentinelNode<Watchpoint> { > WTF_MAKE_NONCOPYABLE(Watchpoint); > WTF_MAKE_NONMOVABLE(Watchpoint); >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(Watchpoint); > public: > #define JSC_DEFINE_WATCHPOINT_TYPES(type, _) type, > enum class Type : uint8_t { >@@ -171,7 +172,10 @@ class InlineWatchpointSet; > class DeferredWatchpointFire; > class VM; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(WatchpointSet); >+ > class WatchpointSet : public ThreadSafeRefCounted<WatchpointSet> { >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(WatchpointSet); > friend class LLIntOffsetsExtractor; > friend class DeferredWatchpointFire; > public: >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >index 667dac047e187ed7e6db983af30611b4efd7ae39..8c2c4b303bc2e5dca191d35e92c958e723e14628 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >@@ -71,6 +71,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(BytecodeGenerator); >+ > template<typename CallOp, typename = std::true_type> > struct VarArgsOp; > >@@ -85,7 +87,6 @@ struct VarArgsOp<CallOp, std::enable_if_t<!std::is_same<CallOp, OpTailCall>::val > using type = OpCallVarargs; > }; > >- > template<typename T> > static inline void shrinkToFit(T& segmentedVector) > { >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >index 1c90313c1affb5950ba5dc69afbffac8ce4aa6d8..e8f217437bfc640e32d92b3e058d8f883e45b446 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >@@ -360,8 +360,10 @@ namespace JSC { > TryData* tryData; > }; > >+ DECLARE_DEBUG_HEAP_ALLOCATOR(BytecodeGenerator); >+ > class BytecodeGenerator { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(BytecodeGenerator); > WTF_MAKE_NONCOPYABLE(BytecodeGenerator); > > friend class BoundLabel; >diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp b/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp >index 1ddc62e33573adc23e4befef548b2aca3ce201a8..59d66eee61199a82817a4dd35c82774504b50b97 100644 >--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp >+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp >@@ -32,6 +32,8 @@ > > namespace JSC { namespace DFG { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(BasicBlock); >+ > BasicBlock::BasicBlock( > unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals, float executionCount) > : bytecodeBegin(bytecodeBegin) >diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.h b/Source/JavaScriptCore/dfg/DFGBasicBlock.h >index 4c58c9c5e784f85d9828159fbf0bdd4713cc9aba..43203834a1a74c6d5fbcf42eef8c9ad3033a327a 100644 >--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.h >+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.h >@@ -44,7 +44,10 @@ class InsertionSet; > typedef Vector<BasicBlock*, 2> PredecessorList; > typedef Vector<Node*, 8> BlockNodeList; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(BasicBlock); >+ > struct BasicBlock : RefCounted<BasicBlock> { >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(BasicBlock); > BasicBlock( > unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals, > float executionCount); >diff --git a/Source/JavaScriptCore/dfg/DFGNode.cpp b/Source/JavaScriptCore/dfg/DFGNode.cpp >index 760aa587979fa19c3393825b7c51920ed585988b..37fa9d6575b9c1ecd8c15470fc00b979cecf17cf 100644 >--- a/Source/JavaScriptCore/dfg/DFGNode.cpp >+++ b/Source/JavaScriptCore/dfg/DFGNode.cpp >@@ -37,6 +37,8 @@ namespace JSC { namespace DFG { > > const char Node::HashSetTemplateInstantiationString[] = "::JSC::DFG::Node*"; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(DFGNode); >+ > bool MultiPutByOffsetData::writesStructures() const > { > for (unsigned i = variants.size(); i--;) { >diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h >index 28b1d4982f05c82fc67770e0c22f78013c81a3cd..f2fe758eca40c940bd780f4967aa778204ba3d84 100644 >--- a/Source/JavaScriptCore/dfg/DFGNode.h >+++ b/Source/JavaScriptCore/dfg/DFGNode.h >@@ -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_DEBUG_HEAP_ALLOCATOR(DFGNode); > struct Node { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(DFGNode); > public: > static const char HashSetTemplateInstantiationString[]; > >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >index d0410b35d39017f80db5905ed492d3e33868bc5c..b8beaf9cd1a00c7896c46c8734dc477a9daaaf47 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >@@ -71,6 +71,8 @@ > > namespace JSC { namespace DFG { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(SpeculativeJIT); >+ > SpeculativeJIT::SpeculativeJIT(JITCompiler& jit) > : m_jit(jit) > , m_graph(m_jit.graph()) >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >index d9ce5baf25f0c493215e6a65904ad4beced0a77d..e0256fa6ebcbd17ed09bedd46b8e7fb9da56d530 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >@@ -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_DEBUG_HEAP_ALLOCATOR(SpeculativeJIT); > class SpeculativeJIT { >- WTF_MAKE_FAST_ALLOCATED; >- >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(SpeculativeJIT); > friend struct OSRExit; > private: > typedef JITCompiler::TrustedImm32 TrustedImm32; >diff --git a/Source/JavaScriptCore/heap/BlockDirectory.cpp b/Source/JavaScriptCore/heap/BlockDirectory.cpp >index 7eee4a8746b6bd18852a7ab62874bbaf57abe289..3942817eeed922e2190a8e1e573fab58f07db671 100644 >--- a/Source/JavaScriptCore/heap/BlockDirectory.cpp >+++ b/Source/JavaScriptCore/heap/BlockDirectory.cpp >@@ -38,6 +38,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(BlockDirectory); >+ > BlockDirectory::BlockDirectory(Heap* heap, size_t cellSize) > : m_cellSize(static_cast<unsigned>(cellSize)) > , m_heap(heap) >diff --git a/Source/JavaScriptCore/heap/BlockDirectory.h b/Source/JavaScriptCore/heap/BlockDirectory.h >index a7bcaa6b9ebd4bad63d7e78110918e3e436387d1..83301fbf252a83a9949890f96103d32614dbe8e5 100644 >--- a/Source/JavaScriptCore/heap/BlockDirectory.h >+++ b/Source/JavaScriptCore/heap/BlockDirectory.h >@@ -70,11 +70,11 @@ class LLIntOffsetsExtractor; > // improve perf since it would not change the collector's behavior, and either way the directory > // has to look at both bitvectors. > // https://bugs.webkit.org/show_bug.cgi?id=162121 >- >+DECLARE_DEBUG_HEAP_ALLOCATOR(BlockDirectory); > class BlockDirectory { > WTF_MAKE_NONCOPYABLE(BlockDirectory); >- WTF_MAKE_FAST_ALLOCATED; >- >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(BlockDirectory); >+ > friend class LLIntOffsetsExtractor; > > public: >diff --git a/Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.cpp b/Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.cpp >index cee66b0be01c1f3d2b9b6470e7cd0076010d9835..06431c994ae86061a053da6f7abd5b8997681796 100644 >--- a/Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.cpp >+++ b/Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.cpp >@@ -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 >@@ -61,12 +74,20 @@ void* FastMallocAlignedMemoryAllocator::tryAllocateMemory(size_t size) > > 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 >diff --git a/Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.h b/Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.h >index cfa770b0ecf31dc147db4cceedeacaf0114124f5..372af41db5886f7176f1b492dc900c201fea673f 100644 >--- a/Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.h >+++ b/Source/JavaScriptCore/heap/FastMallocAlignedMemoryAllocator.h >@@ -27,6 +27,10 @@ > > #include "AlignedMemoryAllocator.h" > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+#include <wtf/DebugHeap.h> >+#endif >+ > namespace JSC { > > class FastMallocAlignedMemoryAllocator : public AlignedMemoryAllocator { >@@ -42,6 +46,11 @@ class FastMallocAlignedMemoryAllocator : public AlignedMemoryAllocator { > 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 >index 0000000000000000000000000000000000000000..831ad7d2f2fee03778244c3d1f2a05966e05aa88 >--- /dev/null >+++ b/Source/JavaScriptCore/heap/GCSegmentedArray.cpp >@@ -0,0 +1,36 @@ >+/* >+ * Copyright (C) 2018 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_DEBUG_HEAP_ALLOCATOR(GCSegmentedArray); >+ >+} // namespace JSC >+ >diff --git a/Source/JavaScriptCore/heap/GCSegmentedArray.h b/Source/JavaScriptCore/heap/GCSegmentedArray.h >index af2c9621613b2d9799906711ce3fbc44496dd2e2..dbafe136e00d118b8846775e81515d3df817f648 100644 >--- a/Source/JavaScriptCore/heap/GCSegmentedArray.h >+++ b/Source/JavaScriptCore/heap/GCSegmentedArray.h >@@ -25,12 +25,15 @@ > > #pragma once > >+#include <wtf/DebugHeap.h> > #include <wtf/DoublyLinkedList.h> > #include <wtf/Forward.h> > #include <wtf/Noncopyable.h> > > namespace JSC { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(GCSegmentedArray); >+ > template <typename T> > class GCArraySegment : public DoublyLinkedListNode<GCArraySegment<T>> { > friend class WTF::DoublyLinkedListNode<GCArraySegment<T>>; >diff --git a/Source/JavaScriptCore/heap/GCSegmentedArrayInlines.h b/Source/JavaScriptCore/heap/GCSegmentedArrayInlines.h >index b4638f928e6ab089e4147d3e36c43b717b61e7f6..46858e6261f905cfddf0360d8b36c88db8c2cc15 100644 >--- a/Source/JavaScriptCore/heap/GCSegmentedArrayInlines.h >+++ b/Source/JavaScriptCore/heap/GCSegmentedArrayInlines.h >@@ -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> >diff --git a/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp b/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp >index 6912870c26f552837a9f3bfbdf714ba398922884..bf70706d7c5899351bc975dc14917fe98abb7df0 100644 >--- a/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp >+++ b/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.cpp >@@ -27,10 +27,23 @@ > #include "IsoAlignedMemoryAllocator.h" > #include "MarkedBlock.h" > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+#include <wtf/DebugHeap.h> >+#endif >+ > namespace JSC { > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+static WTF::DebugHeap& debugHeap() >+{ >+ static NeverDestroyed<WTF::DebugHeap> heap = WTF::DebugHeap("WebKit IsoAlignedMemoryAllocator"); >+ return heap; >+} >+#endif >+ > IsoAlignedMemoryAllocator::IsoAlignedMemoryAllocator() > { >+ > } > > IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator() >@@ -39,7 +52,12 @@ IsoAlignedMemoryAllocator::~IsoAlignedMemoryAllocator() > void* block = m_blocks[i]; > if (!m_committed[i]) > WTF::fastCommitAlignedMemory(block, MarkedBlock::blockSize); >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ debugHeap().free(block); >+#else > fastAlignedFree(block); >+#endif >+ > } > } > >@@ -60,7 +78,11 @@ void* IsoAlignedMemoryAllocator::tryAllocateAlignedMemory(size_t alignment, size > return result; > } > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ void* result = debugHeap().memalign(MarkedBlock::blockSize, MarkedBlock::blockSize, true); >+#else > void* result = tryFastAlignedMalloc(MarkedBlock::blockSize, MarkedBlock::blockSize); >+#endif > if (!result) > return nullptr; > unsigned index = m_blocks.size(); >diff --git a/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h b/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h >index e585d82c5ab68c45752b9a270c20017e2b3ae68e..358fcb3a94cb80dcd060e917f3a1ad4e1950b302 100644 >--- a/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h >+++ b/Source/JavaScriptCore/heap/IsoAlignedMemoryAllocator.h >@@ -30,6 +30,7 @@ > #include <wtf/HashMap.h> > #include <wtf/Vector.h> > >+ > namespace JSC { > > class IsoAlignedMemoryAllocator : public AlignedMemoryAllocator { >diff --git a/Source/JavaScriptCore/heap/MarkedBlock.cpp b/Source/JavaScriptCore/heap/MarkedBlock.cpp >index 4954348738a789d237be7182934078c175189053..de822751179e08d857f0385d879b1a9395bb5086 100644 >--- a/Source/JavaScriptCore/heap/MarkedBlock.cpp >+++ b/Source/JavaScriptCore/heap/MarkedBlock.cpp >@@ -47,6 +47,9 @@ const size_t MarkedBlock::blockSize; > static const bool computeBalance = false; > static size_t balance; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(MarkedBlock); >+DEFINE_DEBUG_HEAP_ALLOCATOR(MarkedBlockHandle); >+ > MarkedBlock::Handle* MarkedBlock::tryCreate(Heap& heap, AlignedMemoryAllocator* alignedMemoryAllocator) > { > if (computeBalance) { >diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h >index 4392932aec70fcf220848afe657e80f54b5799a1..03002dd4b74fa09f20faa126eaf3266b973e80b6 100644 >--- a/Source/JavaScriptCore/heap/MarkedBlock.h >+++ b/Source/JavaScriptCore/heap/MarkedBlock.h >@@ -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_DEBUG_HEAP_ALLOCATOR(MarkedBlock); >+DECLARE_DEBUG_HEAP_ALLOCATOR(MarkedBlockHandle); > class MarkedBlock { > WTF_MAKE_NONCOPYABLE(MarkedBlock); >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(MarkedBlock); > friend class LLIntOffsetsExtractor; > friend struct VerifyMarked; > >@@ -102,7 +104,7 @@ class MarkedBlock { > > class Handle { > WTF_MAKE_NONCOPYABLE(Handle); >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(MarkedBlockHandle); > friend class LLIntOffsetsExtractor; > friend class MarkedBlock; > friend struct VerifyMarked; >diff --git a/Source/JavaScriptCore/heap/WeakBlock.cpp b/Source/JavaScriptCore/heap/WeakBlock.cpp >index 323ce6ffac688ae14b10dc84c85d122df021fba8..e099ca64a7c80a20d64e9d9274c3bc842cdff524 100644 >--- a/Source/JavaScriptCore/heap/WeakBlock.cpp >+++ b/Source/JavaScriptCore/heap/WeakBlock.cpp >@@ -35,16 +35,19 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(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); > } > >diff --git a/Source/JavaScriptCore/heap/WeakBlock.h b/Source/JavaScriptCore/heap/WeakBlock.h >index 6d4ff0709d3ebd063bfd35b16bfcb77c42f9a447..a1e42f30891f013bf8e56b720eafe77ecf8710d3 100644 >--- a/Source/JavaScriptCore/heap/WeakBlock.h >+++ b/Source/JavaScriptCore/heap/WeakBlock.h >@@ -35,6 +35,8 @@ namespace JSC { > class Heap; > class SlotVisitor; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(WeakBlock); >+ > class WeakBlock : public DoublyLinkedListNode<WeakBlock> { > public: > friend class WTF::DoublyLinkedListNode<WeakBlock>; >diff --git a/Source/JavaScriptCore/jit/JITCode.cpp b/Source/JavaScriptCore/jit/JITCode.cpp >index 703b319526ab2df391b3b0367236f07415e6feac..9cfb0cf8752a735731da596be182ad026eb6d5da 100644 >--- a/Source/JavaScriptCore/jit/JITCode.cpp >+++ b/Source/JavaScriptCore/jit/JITCode.cpp >@@ -32,6 +32,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(DirectJITCode); >+ > JITCode::JITCode(JITType jitType, ShareAttribute shareAttribute) > : m_jitType(jitType) > , m_shareAttribute(shareAttribute) >diff --git a/Source/JavaScriptCore/jit/JITCode.h b/Source/JavaScriptCore/jit/JITCode.h >index e8c4c46464225f739532099af63142867a084483..3a526702095d6ce8b5b9f172c8628a6d9cd1b2c7 100644 >--- a/Source/JavaScriptCore/jit/JITCode.h >+++ b/Source/JavaScriptCore/jit/JITCode.h >@@ -237,7 +237,9 @@ class JITCodeWithCodeRef : public JITCode { > CodeRef<JSEntryPtrTag> m_ref; > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(DirectJITCode); > class DirectJITCode : public JITCodeWithCodeRef { >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(DirectJITCode); > public: > DirectJITCode(JITType); > DirectJITCode(CodeRef<JSEntryPtrTag>, CodePtr<JSEntryPtrTag> withArityCheck, JITType, JITCode::ShareAttribute = JITCode::ShareAttribute::NotShared); >diff --git a/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp b/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp >index eb1f28378c3ce5436c5c97ed8da24c066a5756d7..fe73ac4e0ac978a9a760f0f0bd4436db94a60950 100644 >--- a/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp >+++ b/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp >@@ -31,7 +31,9 @@ > #include <wtf/ListDump.h> > > namespace JSC { >- >+ >+DEFINE_DEBUG_HEAP_ALLOCATOR(RegisterAtOffsetList); >+ > RegisterAtOffsetList::RegisterAtOffsetList() { } > > RegisterAtOffsetList::RegisterAtOffsetList(RegisterSet registerSet, OffsetBaseType offsetBaseType) >diff --git a/Source/JavaScriptCore/jit/RegisterAtOffsetList.h b/Source/JavaScriptCore/jit/RegisterAtOffsetList.h >index 173cf949866cc0961c40574f2c2f999d4e4dd610..aaccf2764862a715ed57231d7521b9d9bf6528ba 100644 >--- a/Source/JavaScriptCore/jit/RegisterAtOffsetList.h >+++ b/Source/JavaScriptCore/jit/RegisterAtOffsetList.h >@@ -32,8 +32,9 @@ > > namespace JSC { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(RegisterAtOffsetList); > class RegisterAtOffsetList { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(RegisterAtOffsetList); > public: > enum OffsetBaseType { FramePointerBased, ZeroBased }; > >diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp >index c110dc43f1763866489ca44882a56c19c29531ce..3b746997446dd9057771b8159bdc39352dc7bb37 100644 >--- a/Source/JavaScriptCore/jsc.cpp >+++ b/Source/JavaScriptCore/jsc.cpp >@@ -1401,6 +1401,7 @@ class JSCMemoryFootprint : public JSDestructibleObject { > > addProperty(vm, "current", jsNumber(footprint.current)); > addProperty(vm, "peak", jsNumber(footprint.peak)); >+ WTF::fastMallocDumpMallocStats(); > } > > DECLARE_INFO; >diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp >index 15bdb56dab60e7fe435c2c4adad742a1e79fe351..6ff73616cc98e76fb75b768737936c180b531614 100644 >--- a/Source/JavaScriptCore/parser/Nodes.cpp >+++ b/Source/JavaScriptCore/parser/Nodes.cpp >@@ -33,6 +33,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(ParserArenaRoot); >+ > // ------------------------------ StatementNode -------------------------------- > > void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset) >diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h >index 60ba5eea2d509a438848fd8d9fc2f324e812967c..dc12e2fa76e36cc5950553a0d2f730e3f75d6720 100644 >--- a/Source/JavaScriptCore/parser/Nodes.h >+++ b/Source/JavaScriptCore/parser/Nodes.h >@@ -128,8 +128,9 @@ namespace JSC { > private: \ > typedef int __thisIsHereToForceASemicolonAfterThisMacro > >+ DECLARE_DEBUG_HEAP_ALLOCATOR(ParserArenaRoot); > class ParserArenaRoot { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(ParserArenaRoot); > protected: > ParserArenaRoot(ParserArena&); > >diff --git a/Source/JavaScriptCore/parser/ParserArena.cpp b/Source/JavaScriptCore/parser/ParserArena.cpp >index a276887708c409644db81bcced8ae71b5c04e9a8..75221ced978cf7a7d9cdc198fd1bd95145867f6d 100644 >--- a/Source/JavaScriptCore/parser/ParserArena.cpp >+++ b/Source/JavaScriptCore/parser/ParserArena.cpp >@@ -31,6 +31,9 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(IdentifierArena); >+DEFINE_DEBUG_HEAP_ALLOCATOR(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); >diff --git a/Source/JavaScriptCore/parser/ParserArena.h b/Source/JavaScriptCore/parser/ParserArena.h >index 67b782dd3dc6cb52c178f336df338a726d986969..b38ac3e05e14b546562b9f303e7ddfb4bdc62fb9 100644 >--- a/Source/JavaScriptCore/parser/ParserArena.h >+++ b/Source/JavaScriptCore/parser/ParserArena.h >@@ -35,8 +35,9 @@ namespace JSC { > > class ParserArenaDeletable; > >+ DECLARE_DEBUG_HEAP_ALLOCATOR(IdentifierArena); > class IdentifierArena { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(IdentifierArena); > public: > IdentifierArena() > { >@@ -134,6 +135,8 @@ namespace JSC { > return m_identifiers.last(); > } > >+ DECLARE_DEBUG_HEAP_ALLOCATOR(ParserArena); >+ > class ParserArena { > WTF_MAKE_NONCOPYABLE(ParserArena); > public: >diff --git a/Source/JavaScriptCore/parser/SourceProvider.cpp b/Source/JavaScriptCore/parser/SourceProvider.cpp >index 15f00f306a3063adedc38a8fd1677b5bb9abb996..e3d92ab316c32335084b90654ad2c4b5eb3e9b26 100644 >--- a/Source/JavaScriptCore/parser/SourceProvider.cpp >+++ b/Source/JavaScriptCore/parser/SourceProvider.cpp >@@ -31,6 +31,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StringSourceProvider); >+ > SourceProvider::SourceProvider(const SourceOrigin& sourceOrigin, URL&& url, const TextPosition& startPosition, SourceProviderSourceType sourceType) > : m_sourceType(sourceType) > , m_url(WTFMove(url)) >diff --git a/Source/JavaScriptCore/parser/SourceProvider.h b/Source/JavaScriptCore/parser/SourceProvider.h >index d8e04156907183ba94074718b989857b62b5aab5..0a1ad57bc879e5cc85cbd707c55389539f6d1c12 100644 >--- a/Source/JavaScriptCore/parser/SourceProvider.h >+++ b/Source/JavaScriptCore/parser/SourceProvider.h >@@ -100,7 +100,9 @@ class UnlinkedFunctionCodeBlock; > uintptr_t m_id { 0 }; > }; > >+ DECLARE_DEBUG_HEAP_ALLOCATOR(StringSourceProvider); > class StringSourceProvider : public SourceProvider { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StringSourceProvider); > public: > static Ref<StringSourceProvider> create(const String& source, const SourceOrigin& sourceOrigin, URL&& url, const TextPosition& startPosition = TextPosition(), SourceProviderSourceType sourceType = SourceProviderSourceType::Program) > { >diff --git a/Source/JavaScriptCore/parser/SourceProviderCache.cpp b/Source/JavaScriptCore/parser/SourceProviderCache.cpp >index ccc67272c81b4153a6e67dd4018e2d276830d2c3..132fb58de4f5afa426ea341d76ef596611003a92 100644 >--- a/Source/JavaScriptCore/parser/SourceProviderCache.cpp >+++ b/Source/JavaScriptCore/parser/SourceProviderCache.cpp >@@ -30,6 +30,9 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(SourceProviderCache); >+DEFINE_DEBUG_HEAP_ALLOCATOR(SourceProviderCacheItem); >+ > SourceProviderCache::~SourceProviderCache() > { > clear(); >diff --git a/Source/JavaScriptCore/parser/SourceProviderCache.h b/Source/JavaScriptCore/parser/SourceProviderCache.h >index 05a851f9ae5bfeea201ec8ddb82c194a7980db9e..0da01186370c03ab05b245aa1cf41b232da8dda3 100644 >--- a/Source/JavaScriptCore/parser/SourceProviderCache.h >+++ b/Source/JavaScriptCore/parser/SourceProviderCache.h >@@ -31,8 +31,9 @@ > > namespace JSC { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(SourceProviderCache); > class SourceProviderCache : public RefCounted<SourceProviderCache> { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(SourceProviderCache); > public: > SourceProviderCache() { } > JS_EXPORT_PRIVATE ~SourceProviderCache(); >diff --git a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h >index 7775b69e9bdcd00955cb909b8a139734b8ff5640..deb0533152813a1a2ef62d2879f9342aba995eef 100644 >--- a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h >+++ b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h >@@ -57,8 +57,9 @@ struct SourceProviderCacheItemCreationParameters { > #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning > #endif > >+DECLARE_DEBUG_HEAP_ALLOCATOR(SourceProviderCacheItem); > class SourceProviderCacheItem { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(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)); > } > >diff --git a/Source/JavaScriptCore/runtime/CachedTypes.cpp b/Source/JavaScriptCore/runtime/CachedTypes.cpp >index dc280ce2c460c892ff454844d25accf11aa1f8ab..ad70b844f27dd5fdaa6ab15778742bec226ddcd2 100644 >--- a/Source/JavaScriptCore/runtime/CachedTypes.cpp >+++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp >@@ -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/AtomicStringImpl.h> >@@ -151,7 +152,11 @@ class Encoder { > > m_currentPage->alignEnd(); > size_t size = m_baseOffset + m_currentPage->size(); >- MallocPtr<uint8_t> buffer = MallocPtr<uint8_t>::malloc(size); >+ MallocPtr<uint8_t> buffer = MallocPtr<uint8_t>::malloc(size >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , VMDebugHeap() >+#endif >+ ); > unsigned offset = 0; > for (const auto& page : m_pages) { > memcpy(buffer.get() + offset, page.buffer(), page.size()); >@@ -165,10 +170,18 @@ class Encoder { > class Page { > public: > Page(size_t size) >- : m_offset(0) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ : m_buffer(VMDebugHeap()) > , m_capacity(size) >+#else >+ : m_capacity(size) >+#endif > { >- m_buffer = MallocPtr<uint8_t>::malloc(size); >+ m_buffer = MallocPtr<uint8_t>::malloc(size >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , VMDebugHeap() >+#endif >+ ); > } > > bool malloc(size_t size, ptrdiff_t& result) >@@ -208,7 +221,7 @@ class Encoder { > > private: > MallocPtr<uint8_t> m_buffer; >- ptrdiff_t m_offset; >+ ptrdiff_t m_offset { 0 }; > size_t m_capacity; > }; > >@@ -558,10 +571,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) >@@ -572,7 +585,7 @@ class CachedVector : public VariableLengthObject<Vector<SourceType<T>, InlineCap > } > > 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; >@@ -1331,13 +1344,13 @@ class CachedInstructionStream : public CachedObject<InstructionStream> { > > 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> { >diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h >index 70e9a71d0ddb064cc255b4e3e22a90abdeaf3828..d380ad0d4e2dd1bd0b2d37f4b2239e7da053178d 100644 >--- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h >+++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h >@@ -37,6 +37,8 @@ > > namespace JSC { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(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; } >diff --git a/Source/JavaScriptCore/runtime/PropertyTable.cpp b/Source/JavaScriptCore/runtime/PropertyTable.cpp >index 59ec41c49ae82f47f6986806dd6143944a42b5d6..741bd2626cfc49514af1695a80090e6286a962cd 100644 >--- a/Source/JavaScriptCore/runtime/PropertyTable.cpp >+++ b/Source/JavaScriptCore/runtime/PropertyTable.cpp >@@ -30,6 +30,8 @@ > > namespace JSC { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(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 >diff --git a/Source/JavaScriptCore/runtime/SymbolTable.cpp b/Source/JavaScriptCore/runtime/SymbolTable.cpp >index c93607e891447d6ace3d80c2e4e373f5685d726b..f81be743d22cacc6121855c35f156fefd4de78b0 100644 >--- a/Source/JavaScriptCore/runtime/SymbolTable.cpp >+++ b/Source/JavaScriptCore/runtime/SymbolTable.cpp >@@ -39,6 +39,8 @@ namespace JSC { > > const ClassInfo SymbolTable::s_info = { "SymbolTable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(SymbolTable) }; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(SymbolTableEntryFatEntry); >+ > SymbolTableEntry& SymbolTableEntry::copySlow(const SymbolTableEntry& other) > { > ASSERT(other.isFat()); >diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h >index 3fd1c46e1adf7ceade4e16b11ba7c10000274fb0..ceda0eeaf239d829d88b41bfe5bbcd253efe958f 100644 >--- a/Source/JavaScriptCore/runtime/SymbolTable.h >+++ b/Source/JavaScriptCore/runtime/SymbolTable.h >@@ -44,6 +44,8 @@ namespace JSC { > > class SymbolTable; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(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 @@ struct SymbolTableEntry { > static const intptr_t FlagBits = 6; > > class FatEntry { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(SymbolTableEntryFatEntry); > public: > FatEntry(intptr_t bits) > : m_bits(bits & ~SlimFlag) >diff --git a/Source/JavaScriptCore/runtime/VM.cpp b/Source/JavaScriptCore/runtime/VM.cpp >index 2b06a3bed934c588df87fc9f859222d8670e4e50..b559ab5a5b1ed2afcc3deb632b899d5702b9fb3c 100644 >--- a/Source/JavaScriptCore/runtime/VM.cpp >+++ b/Source/JavaScriptCore/runtime/VM.cpp >@@ -250,6 +250,14 @@ inline unsigned VM::nextID() > > static bool vmCreationShouldCrash = false; > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+WTF::DebugHeap& VMDebugHeap() >+{ >+ static NeverDestroyed<WTF::DebugHeap> heap = WTF::DebugHeap("WebKit VM"); >+ return heap; >+} >+#endif >+ > VM::VM(VMType vmType, HeapType heapType) > : m_id(nextID()) > , m_apiLock(adoptRef(new JSLock(this))) >@@ -321,6 +329,9 @@ VM::VM(VMType vmType, HeapType heapType) > , m_typeProfilerEnabledCount(0) > , m_primitiveGigacageEnabled(IsWatched) > , m_controlFlowProfilerEnabledCount(0) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , m_exceptionFuzzBuffer(VMDebugHeap()) >+#endif > { > if (UNLIKELY(vmCreationShouldCrash)) > CRASH_WITH_INFO(0x4242424220202020, 0xbadbeef0badbeef, 0x1234123412341234, 0x1337133713371337); >@@ -558,8 +569,13 @@ VM::~VM() > #endif > > #if ENABLE(DFG_JIT) >- for (unsigned i = 0; i < m_scratchBuffers.size(); ++i) >+ for (unsigned i = 0; i < m_scratchBuffers.size(); ++i) { >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ VMDebugHeap().free(m_scratchBuffers[i]); >+#else > fastFree(m_scratchBuffers[i]); >+#endif >+ } > #endif > } > >diff --git a/Source/JavaScriptCore/runtime/VM.h b/Source/JavaScriptCore/runtime/VM.h >index 918827ffa88b626b208abf26c1be16e1db570563..e62907546dd5dc35165335bdd116055cb225fdf4 100644 >--- a/Source/JavaScriptCore/runtime/VM.h >+++ b/Source/JavaScriptCore/runtime/VM.h >@@ -223,6 +223,10 @@ class QueuedTask { > > class ConservativeRoots; > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+WTF::DebugHeap& VMDebugHeap(); >+#endif >+ > #if COMPILER(MSVC) > #pragma warning(push) > #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning >@@ -235,8 +239,11 @@ struct ScratchBuffer { > > static ScratchBuffer* create(size_t size) > { >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ ScratchBuffer* result = new (VMDebugHeap().malloc(ScratchBuffer::allocationSize(size))) ScratchBuffer; >+#else > ScratchBuffer* result = new (fastMalloc(ScratchBuffer::allocationSize(size))) ScratchBuffer; >- >+#endif > return result; > } > >@@ -781,8 +788,13 @@ class VM : public ThreadSafeRefCounted<VM>, public DoublyLinkedListNode<VM> { > EncodedJSValue* exceptionFuzzingBuffer(size_t size) > { > ASSERT(Options::useExceptionFuzz()); >- if (!m_exceptionFuzzBuffer) >+ if (!m_exceptionFuzzBuffer) { >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ m_exceptionFuzzBuffer = MallocPtr<EncodedJSValue>::malloc(size, VMDebugHeap()); >+#else > m_exceptionFuzzBuffer = MallocPtr<EncodedJSValue>::malloc(size); >+#endif >+ } > return m_exceptionFuzzBuffer.get(); > } > >diff --git a/Source/JavaScriptCore/runtime/WeakMapImpl.h b/Source/JavaScriptCore/runtime/WeakMapImpl.h >index 8b45ffe15912937d01c8bb10a767ec93d3ded65a..e44048999da40597a9208e11ce7f3668c4d795e1 100644 >--- a/Source/JavaScriptCore/runtime/WeakMapImpl.h >+++ b/Source/JavaScriptCore/runtime/WeakMapImpl.h >@@ -180,7 +180,11 @@ class WeakMapBuffer { > static MallocPtr<WeakMapBuffer, JSValueMalloc> create(uint32_t capacity) > { > size_t allocationSize = WeakMapBuffer::allocationSize(capacity); >- auto buffer = MallocPtr<WeakMapBuffer, JSValueMalloc>::malloc(allocationSize); >+ auto buffer = MallocPtr<WeakMapBuffer, JSValueMalloc>::malloc(allocationSize >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , VMDebugHeap() >+#endif >+ ); > buffer->reset(capacity); > return buffer; > } >@@ -207,6 +211,9 @@ class WeakMapImpl : public JSDestructibleObject { > > WeakMapImpl(VM& vm, Structure* structure) > : Base(vm, structure) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , m_buffer(VMDebugHeap()) >+#endif > { > } > >diff --git a/Source/JavaScriptCore/wasm/WasmInstance.cpp b/Source/JavaScriptCore/wasm/WasmInstance.cpp >index a5e0fcd83d5b23d395dcbe976c4d6d58a2ecebd1..3a36077e0763327225e770468aa109d4ad12408a 100644 >--- a/Source/JavaScriptCore/wasm/WasmInstance.cpp >+++ b/Source/JavaScriptCore/wasm/WasmInstance.cpp >@@ -46,7 +46,11 @@ 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<GlobalValue>::malloc(globalMemoryByteSize(m_module.get()))) >+ , m_globals(MallocPtr<GlobalValue>::malloc(globalMemoryByteSize(m_module.get()) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , VMDebugHeap() >+#endif >+ )) > , m_globalsToMark(m_module.get().moduleInformation().globals.size()) > , m_pointerToTopEntryFrame(pointerToTopEntryFrame) > , m_pointerToActualStackLimit(pointerToActualStackLimit) >diff --git a/Source/JavaScriptCore/wasm/WasmTable.cpp b/Source/JavaScriptCore/wasm/WasmTable.cpp >index e5c608cb1f028c8644399c59a07d23790d4e37a9..597bf876b5a249b29041f5825ec7210fa037ed35 100644 >--- a/Source/JavaScriptCore/wasm/WasmTable.cpp >+++ b/Source/JavaScriptCore/wasm/WasmTable.cpp >@@ -59,6 +59,10 @@ Table::~Table() > } > > Table::Table(uint32_t initial, Optional<uint32_t> maximum) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ : m_importableFunctions(VMDebugHeap()) >+ , m_instances(VMDebugHeap()) >+#endif > { > setLength(initial); > m_maximum = maximum; >@@ -66,9 +70,17 @@ Table::Table(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>::malloc((sizeof(WasmToWasmImportableFunction) * Checked<size_t>(allocatedLength(m_length))).unsafeGet() >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , VMDebugHeap() >+#endif >+ ); > // 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*>::malloc((sizeof(Instance*) * Checked<size_t>(allocatedLength(m_length))).unsafeGet() >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , VMDebugHeap() >+#endif >+ ); > 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. >diff --git a/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp b/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp >index 5be49dd76ad4e3e4b40f971289cf15b7b6b269d7..36d021d9e86ce7ed22c4ff4f646a78a5592e335f 100644 >--- a/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp >+++ b/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp >@@ -59,11 +59,18 @@ Structure* JSWebAssemblyTable::createStructure(VM& vm, JSGlobalObject* globalObj > JSWebAssemblyTable::JSWebAssemblyTable(VM& vm, Structure* structure, Ref<Wasm::Table>&& table) > : Base(vm, structure) > , m_table(WTFMove(table)) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , m_jsFunctions(VMDebugHeap()) >+#endif > { > // 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_jsFunctions = MallocPtr<WriteBarrier<JSObject>>::malloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(allocatedLength())).unsafeGet()); >+ m_jsFunctions = MallocPtr<WriteBarrier<JSObject>>::malloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(allocatedLength())).unsafeGet() >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , VMDebugHeap() >+#endif >+ ); > for (uint32_t i = 0; i < allocatedLength(); ++i) > new(&m_jsFunctions.get()[i]) WriteBarrier<JSObject>(); > } >diff --git a/Source/WTF/WTF.xcodeproj/project.pbxproj b/Source/WTF/WTF.xcodeproj/project.pbxproj >index 8824535a3622581a8d87144b6b10700d47117203..c2c498e5b26ae1d1ca5acfcb7eeec619d5e52e25 100644 >--- a/Source/WTF/WTF.xcodeproj/project.pbxproj >+++ b/Source/WTF/WTF.xcodeproj/project.pbxproj >@@ -36,8 +36,13 @@ > 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 */; }; >@@ -159,6 +164,10 @@ > 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 */; }; >@@ -240,12 +249,20 @@ > 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>"; }; >@@ -265,6 +282,7 @@ > 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>"; }; >@@ -657,6 +675,7 @@ > 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>"; }; > 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>"; }; > E34CD0D022810A020020D299 /* Packed.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Packed.h; sourceTree = "<group>"; }; >@@ -874,6 +893,7 @@ > 0F43D8EF1DB5ADDC00108FB6 /* AutomaticThread.cpp */, > 0F43D8F01DB5ADDC00108FB6 /* AutomaticThread.h */, > DCEE22041CEB9869000C2396 /* BackwardsGraph.h */, >+ 0FEBA64120CF37100074941C /* Bag.cpp */, > 0FB14E18180FA218009B6B4D /* Bag.h */, > 0FB14E1A1810E1DA009B6B4D /* BagToHashMap.h */, > A8A4725F151A825A004123FF /* Bitmap.h */, >@@ -902,6 +922,7 @@ > 0F8F2B90172E00F0007DBDA5 /* CompilationThread.h */, > A8A47270151A825A004123FF /* Compiler.h */, > 46BA9EAB1F4CD61E009A2BBC /* CompletionHandler.h */, >+ E3149A3A228BDCAB00BFA6C7 /* ConcurrentBuffer.cpp */, > 0FB467821FDE282B003FCB09 /* ConcurrentBuffer.h */, > 0F30CB581FCDF133004B5323 /* ConcurrentPtrHashSet.cpp */, > 0F30CB591FCDF133004B5323 /* ConcurrentPtrHashSet.h */, >@@ -926,6 +947,8 @@ > A8A47278151A825A004123FF /* DataLog.h */, > A8A47279151A825A004123FF /* DateMath.cpp */, > A8A4727A151A825A004123FF /* DateMath.h */, >+ 0F95B63220CB4B7700479635 /* DebugHeap.cpp */, >+ 0F95B63120CB4B7700479635 /* DebugHeap.h */, > 996B17841EBA441C007E10EB /* DebugUtilities.h */, > 0F2B66A417B6B4F700A7AE3F /* DeferrableRefCounted.h */, > A8A4727E151A825A004123FF /* Deque.h */, >@@ -1101,6 +1124,7 @@ > A8A472FE151A825B004123FF /* RedBlackTree.h */, > 26299B6D17A9E5B800ADEBE5 /* Ref.h */, > A8A472FF151A825B004123FF /* RefCounted.h */, >+ 0FA6F39020CC61EB00A03DCD /* RefCountedArray.cpp */, > A8A47300151A825B004123FF /* RefCountedArray.h */, > A8A47301151A825B004123FF /* RefCountedLeakCounter.cpp */, > A8A47302151A825B004123FF /* RefCountedLeakCounter.h */, >@@ -1116,6 +1140,7 @@ > 0FEC84B01BDACD390080FF74 /* ScopedLambda.h */, > 0F66B2841DC97BAB004A1D3F /* Seconds.cpp */, > 0F66B2851DC97BAB004A1D3F /* Seconds.h */, >+ 0FA6F38E20CC580E00A03DCD /* SegmentedVector.cpp */, > A8A47306151A825B004123FF /* SegmentedVector.h */, > A8A47307151A825B004123FF /* SentinelLinkedList.h */, > A8A4731A151A825B004123FF /* SetForScope.h */, >@@ -1129,6 +1154,7 @@ > A748744F17A0BDAE00FA04CB /* SixCharacterHash.cpp */, > A748745017A0BDAE00FA04CB /* SixCharacterHash.h */, > A8A4730C151A825B004123FF /* SizeLimits.cpp */, >+ 0FA6F39220CC73A200A03DCD /* SmallPtrSet.cpp */, > 7936D6A91C99F8AE000D1AED /* SmallPtrSet.h */, > A30D412D1F0DE13F00B71954 /* SoftLinking.h */, > 79038E05224B05A7004C0738 /* SpanningTree.h */, >@@ -1179,6 +1205,7 @@ > E360C7642127B85B00C90F0E /* UnalignedAccess.h */, > E360C7652127B85C00C90F0E /* Unexpected.h */, > A8A4735C151A825B004123FF /* UnionFind.h */, >+ 0FA6F39420CCACE900A03DCD /* UniqueArray.cpp */, > E300E521203D645F00DA79BE /* UniqueArray.h */, > 5C7C88D31D0A3A0A009D2F6D /* UniqueRef.h */, > CD7600FF1F90A3CA00026E26 /* UnsafePointer.h */, >@@ -1194,6 +1221,7 @@ > 7AFEC6AE1EB22AC600DADE36 /* UUID.h */, > A8A4736F151A825B004123FF /* ValueCheck.h */, > 7CD0D5A71D55322A000CC9E1 /* Variant.h */, >+ 0F95B63420CB53C100479635 /* Vector.cpp */, > A8A47370151A825B004123FF /* Vector.h */, > A8A47371151A825B004123FF /* VectorTraits.h */, > A8A47372151A825B004123FF /* VMTags.h */, >@@ -1285,6 +1313,7 @@ > C2BCFC531F621F3F00C9222C /* LineEnding.cpp */, > C2BCFC541F621F3F00C9222C /* LineEnding.h */, > 14E785E71DFB330100209BD1 /* OrdinalNumber.h */, >+ 0F95B63620CB5EFD00479635 /* StringBuffer.cpp */, > A8A47323151A825B004123FF /* StringBuffer.h */, > A8A47324151A825B004123FF /* StringBuilder.cpp */, > A8A47325151A825B004123FF /* StringBuilder.h */, >@@ -1506,6 +1535,7 @@ > 9BC70F05176C379D00101DEC /* AtomicStringTable.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 */, >@@ -1518,6 +1548,7 @@ > 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 */, >@@ -1530,6 +1561,7 @@ > 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 */, >@@ -1590,6 +1622,7 @@ > A3B725EC987446AD93F1A440 /* RandomDevice.cpp in Sources */, > A8A47414151A825B004123FF /* RandomNumber.cpp in Sources */, > 0FEC3C5E1F368A9700F59B6C /* ReadWriteLock.cpp in Sources */, >+ E3149A38228BB42C00BFA6C7 /* RefCountedArray.cpp in Sources */, > A8A4741A151A825B004123FF /* RefCountedLeakCounter.cpp in Sources */, > 2CDED0F318115C85004DBA70 /* RunLoop.cpp in Sources */, > 2CDED0EF18115C38004DBA70 /* RunLoopCF.cpp in Sources */, >@@ -1597,14 +1630,17 @@ > 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 */, >@@ -1628,6 +1664,7 @@ > 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 */, >@@ -1638,6 +1675,7 @@ > 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 >index 0000000000000000000000000000000000000000..a42bd39505164c9091eff8091ba4a3c8ffce6160 >--- /dev/null >+++ b/Source/WTF/wtf/Bag.cpp >@@ -0,0 +1,35 @@ >+/* >+ * Copyright (C) 2018 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_DEBUG_HEAP_ALLOCATOR(BagNode); >+ >+} // namespace WTF >diff --git a/Source/WTF/wtf/Bag.h b/Source/WTF/wtf/Bag.h >index 7490ddd5b64cbda70dd3ccfbcaae490da16333a1..768935610ef6f21e48d7505b08d5e21ea8456e08 100644 >--- a/Source/WTF/wtf/Bag.h >+++ b/Source/WTF/wtf/Bag.h >@@ -32,11 +32,10 @@ > > namespace WTF { > >-namespace Private { >- >+DECLARE_DEBUG_HEAP_ALLOCATOR(BagNode); > template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>> > class BagNode { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(BagNode); > public: > using PtrTraits = typename PassedPtrTraits::template RebindTraits<BagNode>; > >@@ -49,13 +48,11 @@ class BagNode { > typename PtrTraits::StorageType m_next { nullptr }; > }; > >-} // namespace Private >- > template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>> > class Bag { > 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: >diff --git a/Source/WTF/wtf/BitVector.cpp b/Source/WTF/wtf/BitVector.cpp >index e125a950c846dfba7c54c14453a4fa46e4aa3b04..09349f238de7d6ac27a1e7d5643e35812481712f 100644 >--- a/Source/WTF/wtf/BitVector.cpp >+++ b/Source/WTF/wtf/BitVector.cpp >@@ -30,10 +30,15 @@ > #include <string.h> > #include <wtf/Assertions.h> > #include <wtf/FastMalloc.h> >+#include <wtf/NeverDestroyed.h> > #include <wtf/StdLibExtras.h> > > namespace WTF { > >+ >+DECLARE_DEBUG_HEAP_ALLOCATOR(BitVector); >+DEFINE_DEBUG_HEAP_ALLOCATOR(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) >diff --git a/Source/WTF/wtf/ConcurrentBuffer.cpp b/Source/WTF/wtf/ConcurrentBuffer.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..27578a4a5db36ab5952113ed351642b8a659626f >--- /dev/null >+++ b/Source/WTF/wtf/ConcurrentBuffer.cpp >@@ -0,0 +1,36 @@ >+/* >+ * Copyright (C) 2018 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_DEBUG_HEAP_ALLOCATOR(ConcurrentBuffer); >+ >+} // namespace WTF >+ >diff --git a/Source/WTF/wtf/ConcurrentBuffer.h b/Source/WTF/wtf/ConcurrentBuffer.h >index 6da7e28be57a22c1e0345e6464dbd2ae63b2af95..441309a12893f3334924b1f75d1f4b950c7b6b0c 100644 >--- a/Source/WTF/wtf/ConcurrentBuffer.h >+++ b/Source/WTF/wtf/ConcurrentBuffer.h >@@ -34,6 +34,8 @@ > > namespace WTF { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(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 @@ class ConcurrentBuffer { > 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 @@ class ConcurrentBuffer { > 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 >index 0000000000000000000000000000000000000000..9e5bac5fea05fdfcdb85099c5cd46ee22684e45c >--- /dev/null >+++ b/Source/WTF/wtf/DebugHeap.cpp >@@ -0,0 +1,81 @@ >+/* >+ * Copyright (C) 2018 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 "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); >+} >+ >+#endif // ENABLE(MALLOC_HEAP_BREAKDOWN) >+ >+} // namespace WTF >diff --git a/Source/WTF/wtf/DebugHeap.h b/Source/WTF/wtf/DebugHeap.h >new file mode 100644 >index 0000000000000000000000000000000000000000..5b84be12e24e92fbed460a0d614107173935ae0c >--- /dev/null >+++ b/Source/WTF/wtf/DebugHeap.h >@@ -0,0 +1,94 @@ >+/* >+ * Copyright (C) 2018 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. >+ */ >+ >+#ifndef DebugHeap_h >+#define DebugHeap_h >+ >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+#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_DEBUG_HEAP_ALLOCATOR(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_DEBUG_HEAP_ALLOCATOR(Type) \ >+ WTF::DebugHeap& Type##Malloc::debugHeap() \ >+ { \ >+ static NeverDestroyed<WTF::DebugHeap> heap { WTF::DebugHeap(#Type) }; \ >+ return heap; \ >+ } \ >+ struct MakeDebugHeapMallocedImplMacroSemicolonifier##Type { } >+ >+#else // ENABLE(MALLOC_HEAP_BREAKDOWN) >+ >+#define DECLARE_DEBUG_HEAP_ALLOCATOR(Type) \ >+ using Type##Malloc = FastMalloc >+ >+#define DEFINE_DEBUG_HEAP_ALLOCATOR(Type) \ >+ struct MakeDebugHeapMallocedImplMacroSemicolonifier##Type { } >+ >+#endif >+ >+} // namespace WTF >+ >+#endif // DebugHeap_h >diff --git a/Source/WTF/wtf/FastBitVector.cpp b/Source/WTF/wtf/FastBitVector.cpp >index 0f0e4876ad39afda1745e4145d025f2255b48ab1..d41c27001eeebf80f987420ec4a2f200bd5ecb03 100644 >--- a/Source/WTF/wtf/FastBitVector.cpp >+++ b/Source/WTF/wtf/FastBitVector.cpp >@@ -26,15 +26,19 @@ > #include "config.h" > #include <wtf/FastBitVector.h> > >+#include <wtf/NeverDestroyed.h> >+ > namespace WTF { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(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; > } > >diff --git a/Source/WTF/wtf/FastBitVector.h b/Source/WTF/wtf/FastBitVector.h >index 9119a1d5112866dcb52702c3f15792a883d30f7f..0161a273cb942af43df60bbd174ce794de34572d 100644 >--- a/Source/WTF/wtf/FastBitVector.h >+++ b/Source/WTF/wtf/FastBitVector.h >@@ -35,6 +35,8 @@ namespace WTF { > > class PrintStream; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(FastBitVector); >+ > inline size_t fastBitVectorArrayLength(size_t numBits) { return (numBits + 31) / 32; } > > class FastBitVectorWordView { >@@ -85,7 +87,7 @@ class FastBitVectorWordOwner { > ~FastBitVectorWordOwner() > { > if (m_words) >- fastFree(m_words); >+ FastBitVectorMalloc::free(m_words); > } > > FastBitVectorWordView view() const { return FastBitVectorWordView(m_words, m_numBits); } >diff --git a/Source/WTF/wtf/FastMalloc.cpp b/Source/WTF/wtf/FastMalloc.cpp >index cdffc75e35738c79d0b58f0a2bbf9529bc380bf9..981823d9174c0367572ea0053cc4369b928fa39a 100644 >--- a/Source/WTF/wtf/FastMalloc.cpp >+++ b/Source/WTF/wtf/FastMalloc.cpp >@@ -45,6 +45,20 @@ > #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) >@@ -268,6 +282,181 @@ void fastEnableMiniMode() { } > > namespace WTF { > >+#define TRACK_MALLOCS 1 >+ >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOCS >+ >+static std::atomic<unsigned> avoidRecordingCount; >+ >+class AvoidRecordingScope { >+public: >+ AvoidRecordingScope() >+ { >+ ++avoidRecordingCount; >+ } >+ >+ ~AvoidRecordingScope() >+ { >+ --avoidRecordingCount; >+ } >+}; >+ >+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; >+ >+ const size_t stackSize = 10; >+ auto siteData = std::make_unique<MallocSiteData>(stackSize, allocationSize); >+ >+ LockHolder lockHolder(m_mutex); >+ auto addResult = m_addressMallocSiteData.add(address, WTFMove(siteData)); >+// if (!addResult.isNewEntry) >+// WTFLogAlways("recordMalloc saw address %p for the second time", address); >+ UNUSED_PARAM(addResult); >+} >+ >+void MallocCallTracker::recordRealloc(void* oldAddress, void* newAddress, size_t newSize) >+{ >+ AvoidRecordingScope avoidRecording; >+ >+ LockHolder lockHolder(m_mutex); >+ >+ auto it = m_addressMallocSiteData.find(oldAddress); >+ if (it == m_addressMallocSiteData.end()) { >+ ASSERT_NOT_REACHED(); >+ return; >+ } >+ >+ it->value->size = newSize; >+ auto addResult = m_addressMallocSiteData.add(newAddress, WTFMove(it->value)); >+ ASSERT_UNUSED(addResult, addResult.isNewEntry); >+ >+ m_addressMallocSiteData.remove(it); >+} >+ >+void MallocCallTracker::recordFree(void* address) >+{ >+ AvoidRecordingScope avoidRecording; >+ >+ LockHolder lockHolder(m_mutex); >+ bool removed = m_addressMallocSiteData.remove(address); >+ UNUSED_PARAM(removed); >+// if (!removed) >+// WTFLogAlways("recordFree got address %p for which there is no entry", address); >+} >+ >+void MallocCallTracker::dumpStats() >+{ >+ AvoidRecordingScope avoidRecording; >+ >+ { >+ LockHolder lockHolder(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(), [] () { >+ 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); >+ 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(); >@@ -275,8 +464,19 @@ bool isFastMallocEnabled() > > void* fastMalloc(size_t size) > { >+// if (size > 255) { >+// WTFLogAlways("fastMalloc %lu\n", size); >+// WTFReportBacktrace(); >+// WTFLogAlways("\n"); >+// } >+ > ASSERT_IS_WITHIN_LIMIT(size); >- return bmalloc::api::malloc(size); >+ void* result = bmalloc::api::malloc(size); >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOCS >+ if (!avoidRecordingCount) >+ MallocCallTracker::singleton().recordMalloc(result, size); >+#endif >+ return result; > } > > void* fastCalloc(size_t numElements, size_t elementSize) >@@ -293,12 +493,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_MALLOCS >+ if (!avoidRecordingCount) >+ MallocCallTracker::singleton().recordRealloc(object, result, size); >+#endif >+ return result; > } > > void fastFree(void* object) > { > bmalloc::api::free(object); >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) && TRACK_MALLOCS >+ if (!avoidRecordingCount) >+ MallocCallTracker::singleton().recordFree(object); >+#endif > } > > size_t fastMallocSize(const void*) >@@ -317,13 +526,23 @@ size_t fastMallocGoodSize(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_MALLOCS >+ if (!avoidRecordingCount) >+ MallocCallTracker::singleton().recordMalloc(result, size); >+#endif >+ return result; > } > > 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_MALLOCS >+ if (!avoidRecordingCount) >+ MallocCallTracker::singleton().recordMalloc(result, size); >+#endif >+ return result; > } > > void fastAlignedFree(void* p) >diff --git a/Source/WTF/wtf/FastMalloc.h b/Source/WTF/wtf/FastMalloc.h >index efefb3a3133e83f64336fd2ec2da52a54832e621..e7031cb9429db4d298e943246564e33756c19279 100644 >--- a/Source/WTF/wtf/FastMalloc.h >+++ b/Source/WTF/wtf/FastMalloc.h >@@ -24,6 +24,10 @@ > #include <stdlib.h> > #include <wtf/StdLibExtras.h> > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+#include <wtf/DebugHeap.h> >+#endif >+ > namespace WTF { > > #if !defined(NDEBUG) >@@ -82,6 +86,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 +205,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); } > >@@ -307,3 +324,46 @@ typedef int __thisIsHereToForceASemicolonAfterThisMacro > #define WTF_MAKE_STRUCT_FAST_ALLOCATED \ > WTF_MAKE_FAST_ALLOCATED_IMPL \ > typedef int __thisIsHereToForceASemicolonAfterThisMacro >+ >+#define WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP_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; \ >+ } \ >+ >+#define WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(classname) \ >+public: \ >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP_IMPL(classname) \ >+private: \ >+ WTF_EXPORT static WTF::DebugHeap& debugHeap(const char*); \ >+typedef int __thisIsHereToForceASemicolonAfterThisMacro >+ >+#define WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(className) \ >+private: \ >+ WTF_EXPORT static WTF::DebugHeap& debugHeap(const char*); \ >+public: \ >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP_IMPL(className) \ >+typedef int __thisIsHereToForceASemicolonAfterThisMacro >diff --git a/Source/WTF/wtf/Forward.h b/Source/WTF/wtf/Forward.h >index f6a0c0e5829951a21d69f4a65363600d336dd4b2..f3bf9ae843a0cec82d2ade69a35229d412ac28df 100644 >--- a/Source/WTF/wtf/Forward.h >+++ b/Source/WTF/wtf/Forward.h >@@ -21,6 +21,7 @@ > #pragma once > > #include <stddef.h> >+#include <wtf/Platform.h> > > namespace WTF { > >@@ -47,6 +48,7 @@ class URL; > class WallTime; > > struct FastMalloc; >+struct VectorMalloc; > > template<typename> class CompletionHandler; > template<typename T> struct DumbPtrTraits; >@@ -69,7 +71,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; >diff --git a/Source/WTF/wtf/HashTable.cpp b/Source/WTF/wtf/HashTable.cpp >index 8ccdf8454d8324bc737ad54c493776b61e439b8a..5f3a821b8c040bb510660ab505149d79c183b738 100644 >--- a/Source/WTF/wtf/HashTable.cpp >+++ b/Source/WTF/wtf/HashTable.cpp >@@ -20,11 +20,14 @@ > #include "config.h" > #include <wtf/HashTable.h> > >+#include "NeverDestroyed.h" > #include <mutex> > #include <wtf/DataLog.h> > > namespace WTF { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(HashTable); >+ > #if DUMP_HASHTABLE_STATS > > std::atomic<unsigned> HashTableStats::numAccesses; >diff --git a/Source/WTF/wtf/HashTable.h b/Source/WTF/wtf/HashTable.h >index 2281d1f28ed858994fe6f9ab7663b0ff2cb2cebc..f24a8f7a54a6b7cf69e47e93779f92a6e9355786 100644 >--- a/Source/WTF/wtf/HashTable.h >+++ b/Source/WTF/wtf/HashTable.h >@@ -43,8 +43,14 @@ > #include <wtf/DataLog.h> > #endif > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+#include <wtf/DebugHeap.h> >+#endif >+ > namespace WTF { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(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 > >@@ -1163,8 +1169,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; >@@ -1177,7 +1184,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> >@@ -1286,7 +1293,7 @@ namespace WTF { > > m_deletedCount = 0; > >- fastFree(oldTable); >+ HashTableMalloc::free(oldTable); > > internalCheckTableConsistency(); > return newEntry; >diff --git a/Source/WTF/wtf/MallocPtr.h b/Source/WTF/wtf/MallocPtr.h >index 83b3a51fba102890274f4ecead768ae643e36bba..8b9c1ba2a3c09f9774fb944323c02b1cdc8406c3 100644 >--- a/Source/WTF/wtf/MallocPtr.h >+++ b/Source/WTF/wtf/MallocPtr.h >@@ -27,6 +27,10 @@ > > #include <wtf/FastMalloc.h> > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+#include <wtf/DebugHeap.h> >+#endif >+ > // MallocPtr is a smart pointer class that calls fastFree in its destructor. > // It is intended to be used for pointers where the C++ lifetime semantics > // (calling constructors and destructors) is not desired. >@@ -35,24 +39,46 @@ namespace WTF { > > template<typename T, typename Malloc = FastMalloc> class MallocPtr { > public: >- MallocPtr() >+ MallocPtr( >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ DebugHeap& heap >+#endif >+ ) > : m_ptr(nullptr) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , m_heap(heap) >+#endif > { > } > >- MallocPtr(std::nullptr_t) >+ MallocPtr(std::nullptr_t >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , DebugHeap& heap >+#endif >+ ) > : m_ptr(nullptr) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , m_heap(heap) >+#endif > { > } > > MallocPtr(MallocPtr&& other) > : m_ptr(other.leakPtr()) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , m_heap(other.m_heap) >+#endif > { > } > > ~MallocPtr() > { >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ m_heap.free(m_ptr); >+#else > Malloc::free(m_ptr); >+#endif >+ > } > > T* get() const >@@ -97,39 +123,91 @@ template<typename T, typename Malloc = FastMalloc> class MallocPtr { > void swap(MallocPtr& other) > { > std::swap(m_ptr, other.m_ptr); >+ std::swap(m_heap, other.m_heap); > } > >- template<typename U> friend MallocPtr<U> adoptMallocPtr(U*); >+ template<typename U> friend MallocPtr<U> adoptMallocPtr(U* >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , DebugHeap& >+#endif >+ ); > >- static MallocPtr malloc(size_t size) >+ static MallocPtr malloc(size_t size >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , DebugHeap& heap >+#endif >+ ) > { >- return MallocPtr { static_cast<T*>(Malloc::malloc(size)) }; >+ return MallocPtr { >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ static_cast<T*>(heap.malloc(size)), heap >+#else >+ static_cast<T*>(Malloc::malloc(size)) >+#endif >+ }; > } > >- static MallocPtr tryMalloc(size_t size) >+ static MallocPtr tryMalloc(size_t size >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , DebugHeap& heap >+#endif >+ ) > { >- return MallocPtr { static_cast<T*>(Malloc::tryMalloc(size)) }; >+ return MallocPtr { >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ static_cast<T*>(heap.malloc(size)), heap >+#else >+ static_cast<T*>(Malloc::tryMalloc(size)) >+#endif >+ }; > } > > void realloc(size_t newSize) > { >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ m_ptr = static_cast<T*>(m_heap.realloc(m_ptr, newSize)); >+#else > m_ptr = static_cast<T*>(Malloc::realloc(m_ptr, newSize)); >+#endif >+ > } > > private: >- explicit MallocPtr(T* ptr) >+ explicit MallocPtr(T* ptr >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , DebugHeap& heap >+#endif >+ ) > : m_ptr(ptr) >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , m_heap(heap) >+#endif > { > } > > T* m_ptr; >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ DebugHeap& m_heap; >+#endif > }; > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+static_assert(sizeof(MallocPtr<int>) == 2 * sizeof(int*), ""); >+#else > static_assert(sizeof(MallocPtr<int>) == sizeof(int*), ""); >+#endif > >-template<typename U> MallocPtr<U> adoptMallocPtr(U* ptr) >+template<typename U> MallocPtr<U> adoptMallocPtr(U* ptr >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , DebugHeap& heap >+#endif >+) > { >- return MallocPtr<U>(ptr); >+ return MallocPtr<U>(ptr >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , heap >+#endif >+ ); > } > > } // namespace WTF >diff --git a/Source/WTF/wtf/MetaAllocator.cpp b/Source/WTF/wtf/MetaAllocator.cpp >index c3b6937828c57f55b64fbe349e5e5cc7b7796c94..8d87166355652263757a1d2fd1bcd81eca3946a9 100644 >--- a/Source/WTF/wtf/MetaAllocator.cpp >+++ b/Source/WTF/wtf/MetaAllocator.cpp >@@ -31,10 +31,16 @@ > > #include <wtf/DataLog.h> > #include <wtf/FastMalloc.h> >+#include <wtf/NeverDestroyed.h> > #include <wtf/ProcessID.h> > > namespace WTF { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(MetaAllocatorHandle); >+ >+DECLARE_DEBUG_HEAP_ALLOCATOR(MetaAllocatorFreeSpace); >+DEFINE_DEBUG_HEAP_ALLOCATOR(MetaAllocatorFreeSpace); >+ > MetaAllocator::~MetaAllocator() > { > for (FreeSpaceNode* node = m_freeSpaceSizeMap.first(); node;) { >@@ -444,7 +450,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) >@@ -452,7 +458,7 @@ void MetaAllocator::freeFreeSpaceNode(FreeSpaceNode* node) > #ifndef NDEBUG > m_mallocBalance--; > #endif >- fastFree(node); >+ MetaAllocatorFreeSpaceMalloc::free(node); > } > > #if ENABLE(META_ALLOCATOR_PROFILE) >diff --git a/Source/WTF/wtf/MetaAllocatorHandle.h b/Source/WTF/wtf/MetaAllocatorHandle.h >index d8c30e996b4810ddb6c33d05cc874b4ec48e654d..1b2db04b0c8918288aa2ed351e8a9568e2e092b6 100644 >--- a/Source/WTF/wtf/MetaAllocatorHandle.h >+++ b/Source/WTF/wtf/MetaAllocatorHandle.h >@@ -38,7 +38,9 @@ namespace WTF { > class MetaAllocator; > class PrintStream; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(MetaAllocatorHandle); > class MetaAllocatorHandle : public ThreadSafeRefCounted<MetaAllocatorHandle>, public RedBlackTree<MetaAllocatorHandle, void*>::Node { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(MetaAllocatorHandle); > private: > MetaAllocatorHandle(MetaAllocator*, void* start, size_t sizeInBytes, void* ownerUID); > >diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h >index 447bb18a8f028c29501d3931fb9557a8d53a2607..73e8d8384eb0169d5645d5b818202aabd172a55c 100644 >--- a/Source/WTF/wtf/Platform.h >+++ b/Source/WTF/wtf/Platform.h >@@ -1180,6 +1180,11 @@ > #endif > #endif > >+#if !defined(ENABLE_MALLOC_HEAP_BREAKDOWN) // &&&& && !defined(NDEBUG) >+/* 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. */ >+#define ENABLE_MALLOC_HEAP_BREAKDOWN 1 >+#endif >+ > #if PLATFORM(IOS_FAMILY) || PLATFORM(MAC) > #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 >index 0000000000000000000000000000000000000000..79514dcffcb69d075f4d42c5a023f49dc195ebee >--- /dev/null >+++ b/Source/WTF/wtf/RefCountedArray.cpp >@@ -0,0 +1,34 @@ >+/* >+ * Copyright (C) 2011-2018 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 "RefCountedArray.h" >+#include <wtf/NeverDestroyed.h> >+ >+namespace WTF { >+ >+DEFINE_DEBUG_HEAP_ALLOCATOR(RefCountedArray); >+ >+} // namespace WTF >diff --git a/Source/WTF/wtf/RefCountedArray.h b/Source/WTF/wtf/RefCountedArray.h >index 63cd1ed949bf9ae151455d0ba38c548985318198..0ac6eeafe00ad9fec672cf67bfad7475c95546c7 100644 >--- a/Source/WTF/wtf/RefCountedArray.h >+++ b/Source/WTF/wtf/RefCountedArray.h >@@ -43,6 +43,8 @@ > > namespace WTF { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(RefCountedArray); >+ > template<typename T, typename PtrTraits = DumbPtrTraits<T>> > class RefCountedArray { > enum CommonCopyConstructorTag { CommonCopyConstructor }; >@@ -67,7 +69,7 @@ class RefCountedArray { > 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 @@ class RefCountedArray { > 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 @@ class RefCountedArray { > 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 @@ class RefCountedArray { > 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 >index 0000000000000000000000000000000000000000..78b23a46ce7647b3513e3feb3822182f5a1c9c0b >--- /dev/null >+++ b/Source/WTF/wtf/SegmentedVector.cpp >@@ -0,0 +1,39 @@ >+/* >+ * Copyright (C) 2018 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. >+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of >+ * its contributors may be used to endorse or promote products derived >+ * from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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/SegmentedVector.h> >+ >+#include <wtf/NeverDestroyed.h> >+ >+namespace WTF { >+ >+DEFINE_DEBUG_HEAP_ALLOCATOR(SegmentedVector); >+ >+} // namespace WTF >diff --git a/Source/WTF/wtf/SegmentedVector.h b/Source/WTF/wtf/SegmentedVector.h >index e87939efcfbd55a2c8d2c48c51a67740963237d7..5c165f67fb294ef3cbd20ca7f5def18b535806e7 100644 >--- a/Source/WTF/wtf/SegmentedVector.h >+++ b/Source/WTF/wtf/SegmentedVector.h >@@ -33,6 +33,8 @@ > > namespace WTF { > >+ DECLARE_DEBUG_HEAP_ALLOCATOR(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 { >@@ -226,7 +228,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) >@@ -262,7 +264,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 >index 0000000000000000000000000000000000000000..15e5100f102101019e7f50d1a10ede7da7d4849d >--- /dev/null >+++ b/Source/WTF/wtf/SmallPtrSet.cpp >@@ -0,0 +1,35 @@ >+/* >+ * Copyright (C) 2016 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_DEBUG_HEAP_ALLOCATOR(SmallPtrSet); >+ >+} // namespace WTF >diff --git a/Source/WTF/wtf/SmallPtrSet.h b/Source/WTF/wtf/SmallPtrSet.h >index d4a6e210dc2dc4deb5603b8931218af491d218d5..62dfe4ec842c6250745cedb6da76cb4745f2f353 100644 >--- a/Source/WTF/wtf/SmallPtrSet.h >+++ b/Source/WTF/wtf/SmallPtrSet.h >@@ -32,6 +32,8 @@ > > namespace WTF { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(SmallPtrSet); >+ > template<typename PtrType, unsigned SmallArraySize = 8> > class SmallPtrSet { > WTF_MAKE_NONCOPYABLE(SmallPtrSet); >@@ -71,7 +73,7 @@ class SmallPtrSet { > ~SmallPtrSet() > { > if (!isSmall()) >- fastFree(m_buffer); >+ SmallPtrSetMalloc::free(m_buffer); > } > > inline void add(PtrType ptr) >@@ -207,7 +209,7 @@ class SmallPtrSet { > 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; > >@@ -219,7 +221,7 @@ class SmallPtrSet { > } > > 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 >index 0000000000000000000000000000000000000000..6c68842d38974fa7f591f0b65abd211bb8e689e2 >--- /dev/null >+++ b/Source/WTF/wtf/UniqueArray.cpp >@@ -0,0 +1,31 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Library General Public >+ * License as published by the Free Software Foundation; either >+ * version 2 of the License, or (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Library General Public License for more details. >+ * >+ * You should have received a copy of the GNU Library General Public License >+ * along with this library; see the file COPYING.LIB. If not, write to >+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ * >+ */ >+ >+#include "config.h" >+#include <wtf/UniqueArray.h> >+ >+#include <wtf/NeverDestroyed.h> >+ >+namespace WTF { >+ >+DEFINE_DEBUG_HEAP_ALLOCATOR(UniqueArray); >+DEFINE_DEBUG_HEAP_ALLOCATOR(UniqueArrayElement); >+ >+} // namespace WTF >diff --git a/Source/WTF/wtf/UniqueArray.h b/Source/WTF/wtf/UniqueArray.h >index a2b85853529311db46298535d3262c211a10426c..f9ccd9fe44182cbf92cb52b6f2042ee920375a98 100644 >--- a/Source/WTF/wtf/UniqueArray.h >+++ b/Source/WTF/wtf/UniqueArray.h >@@ -31,11 +31,35 @@ > > namespace WTF { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(UniqueArray); >+DECLARE_DEBUG_HEAP_ALLOCATOR(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_FROM_DEBUG_HEAP(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 >index 0000000000000000000000000000000000000000..f996e65ff1cdec19cbfd7815ff5179169f1e8c8f >--- /dev/null >+++ b/Source/WTF/wtf/Vector.cpp >@@ -0,0 +1,29 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Library General Public >+ * License as published by the Free Software Foundation; either >+ * version 2 of the License, or (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Library General Public License for more details. >+ * >+ * You should have received a copy of the GNU Library General Public License >+ * along with this library; see the file COPYING.LIB. If not, write to >+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ * >+ */ >+ >+#include "config.h" >+#include "Vector.h" >+#include "NeverDestroyed.h" >+ >+namespace WTF { >+ >+DEFINE_DEBUG_HEAP_ALLOCATOR(Vector); >+ >+} // namespace WTF >diff --git a/Source/WTF/wtf/Vector.h b/Source/WTF/wtf/Vector.h >index e4e1b6288541157a24bdb3b06b88ab565c94e412..abdd06a4cc2ce2ead507f3cbf1112c446096c08b 100644 >--- a/Source/WTF/wtf/Vector.h >+++ b/Source/WTF/wtf/Vector.h >@@ -35,6 +35,7 @@ > #include <wtf/StdLibExtras.h> > #include <wtf/ValueCheck.h> > #include <wtf/VectorTraits.h> >+#include <wtf/DebugHeap.h> > > #if ASAN_ENABLED > extern "C" void __sanitizer_annotate_contiguous_container(const void* begin, const void* end, const void* old_mid, const void* new_mid); >@@ -46,6 +47,8 @@ class LLIntOffsetsExtractor; > > namespace WTF { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(Vector); >+ > template <bool needsDestruction, typename T> > struct VectorDestructor; > >@@ -279,7 +282,7 @@ struct VectorTypeOperations > } > }; > >-template<typename T> >+template<typename T, typename Malloc> > class VectorBufferBase { > WTF_MAKE_NONCOPYABLE(VectorBufferBase); > public: >@@ -290,7 +293,7 @@ class VectorBufferBase { > 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) >@@ -300,13 +303,12 @@ class VectorBufferBase { > 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 >@@ -321,7 +323,7 @@ class VectorBufferBase { > 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) >@@ -334,7 +336,7 @@ class VectorBufferBase { > m_capacity = 0; > } > >- fastFree(bufferToDeallocate); >+ Malloc::free(bufferToDeallocate); > } > > T* buffer() { return m_buffer; } >@@ -347,7 +349,11 @@ class VectorBufferBase { > T* buffer = m_buffer; > m_buffer = 0; > m_capacity = 0; >- return adoptMallocPtr(buffer); >+ return adoptMallocPtr(buffer >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , Malloc::debugHeap() >+#endif >+ ); > } > > protected: >@@ -375,13 +381,12 @@ class VectorBufferBase { > 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() > { >@@ -401,7 +406,7 @@ class VectorBuffer<T, 0> : private VectorBufferBase<T> { > 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); >@@ -437,11 +442,11 @@ class VectorBuffer<T, 0> : private VectorBufferBase<T> { > 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) >@@ -551,7 +556,7 @@ class VectorBuffer : private VectorBufferBase<T> { > MallocPtr<T> releaseBuffer() > { > if (buffer() == inlineBuffer()) >- return nullptr; >+ return { Malloc::debugHeap() }; > return Base::releaseBuffer(); > } > >@@ -606,11 +611,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; > >@@ -678,12 +683,12 @@ class Vector : private VectorBuffer<T, inlineCapacity> { > } > > 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&&); >@@ -783,7 +788,7 @@ class Vector : private VectorBuffer<T, inlineCapacity> { > > 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); >@@ -806,7 +811,7 @@ class Vector : private VectorBuffer<T, inlineCapacity> { > > MallocPtr<T> 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. >@@ -876,8 +881,8 @@ class Vector : private VectorBuffer<T, inlineCapacity> { > #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()); >@@ -886,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()); >@@ -897,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; >@@ -922,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 >@@ -948,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))) >@@ -979,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; >@@ -1000,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; >@@ -1010,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); >@@ -1028,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); >@@ -1054,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)) >@@ -1074,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()); >@@ -1099,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()); >@@ -1115,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()) >@@ -1127,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()) >@@ -1143,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()) >@@ -1157,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()) >@@ -1171,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; >@@ -1190,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; >@@ -1213,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); >@@ -1222,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; >@@ -1253,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()) { >@@ -1270,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()) { >@@ -1290,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); >@@ -1304,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); >@@ -1318,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); >@@ -1332,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()); > >@@ -1347,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()); > >@@ -1361,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()); > >@@ -1380,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()); > >@@ -1392,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()); > >@@ -1404,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> >-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; >@@ -1430,9 +1435,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()); > >@@ -1450,15 +1455,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; >@@ -1468,8 +1473,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()); >@@ -1481,18 +1486,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))) { >@@ -1503,18 +1508,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(); >@@ -1539,16 +1544,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()); >@@ -1557,8 +1562,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> 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, >@@ -1571,7 +1576,11 @@ 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))); >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ buffer = adoptMallocPtr(static_cast<T*>(Malloc::malloc(bytes)), Malloc::debugHeap()); >+#else >+ buffer = adoptMallocPtr(static_cast<T*>(Malloc::malloc(bytes))); >+#endif > memcpy(buffer.get(), data(), bytes); > } > m_size = 0; >@@ -1579,8 +1588,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) >@@ -1588,14 +1597,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 inlineCapacity, typename OverflowHandler, size_t minCapacity> >-bool operator==(const Vector<T, inlineCapacity, OverflowHandler, minCapacity>& a, const Vector<T, inlineCapacity, OverflowHandler, minCapacity>& b) >+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc> >+bool operator==(const Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& a, const Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& b) > { > if (a.size() != b.size()) > return false; >@@ -1603,8 +1612,8 @@ bool operator==(const Vector<T, inlineCapacity, OverflowHandler, minCapacity>& a > return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size()); > } > >-template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity> >-inline bool operator!=(const Vector<T, inlineCapacity, OverflowHandler, minCapacity>& a, const Vector<T, inlineCapacity, OverflowHandler, minCapacity>& b) >+template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc> >+inline bool operator!=(const Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& a, const Vector<T, inlineCapacity, OverflowHandler, minCapacity, Malloc>& b) > { > return !(a == b); > } >@@ -1619,9 +1628,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()); >@@ -1639,8 +1648,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; }); > } >diff --git a/Source/WTF/wtf/text/CString.cpp b/Source/WTF/wtf/text/CString.cpp >index e99778f17a723c90fab763b64cb13b3058a4307e..cbc8f54c9f3e910b64a6fe8251b11b12bde219bd 100644 >--- a/Source/WTF/wtf/text/CString.cpp >+++ b/Source/WTF/wtf/text/CString.cpp >@@ -28,17 +28,20 @@ > #include <wtf/text/CString.h> > > #include <string.h> >+#include <wtf/NeverDestroyed.h> > #include <wtf/text/StringHasher.h> > > namespace WTF { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(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)); > } > >diff --git a/Source/WTF/wtf/text/CString.h b/Source/WTF/wtf/text/CString.h >index be697c2bb8b629cce1a5d2e06dcb9d5a192b9cca..f9094a16523c1d144718039cbcf7e901866bad01 100644 >--- a/Source/WTF/wtf/text/CString.h >+++ b/Source/WTF/wtf/text/CString.h >@@ -32,9 +32,12 @@ > > namespace WTF { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(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 : public RefCounted<CStringBuffer> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(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 >index 0000000000000000000000000000000000000000..b34b11bb21c4fa404c7787df140de57e9c5a0816 >--- /dev/null >+++ b/Source/WTF/wtf/text/StringBuffer.cpp >@@ -0,0 +1,38 @@ >+/* >+ * Copyright (C) 2018 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. >+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of its >+ * contributors may be used to endorse or promote products derived >+ * from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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/text/StringBuffer.h> >+ >+#include <wtf/NeverDestroyed.h> >+ >+namespace WTF { >+ >+DEFINE_DEBUG_HEAP_ALLOCATOR(StringBuffer); >+ >+} // namespace WTF >diff --git a/Source/WTF/wtf/text/StringBuffer.h b/Source/WTF/wtf/text/StringBuffer.h >index 5dcfecdfaa89a1683522b842c30941df572b85fc..15543d9439bcc1b6c7300e3eaf4d1ab3ff7b5211 100644 >--- a/Source/WTF/wtf/text/StringBuffer.h >+++ b/Source/WTF/wtf/text/StringBuffer.h >@@ -31,23 +31,29 @@ > #include <limits> > #include <unicode/utypes.h> > #include <wtf/Assertions.h> >+#include <wtf/DebugHeap.h> >+#include <wtf/Noncopyable.h> > #include <wtf/MallocPtr.h> > > namespace WTF { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StringBuffer); >+ > template <typename CharType> > class StringBuffer { > WTF_MAKE_NONCOPYABLE(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) >@@ -61,7 +67,7 @@ class StringBuffer { > 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; > } >@@ -75,7 +81,11 @@ class StringBuffer { > { > CharType* data = m_data; > m_data = 0; >- return adoptMallocPtr(data); >+ return adoptMallocPtr(data >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , StringBufferMalloc::debugHeap() >+#endif >+ ); > } > > private: >diff --git a/Source/WTF/wtf/text/StringImpl.cpp b/Source/WTF/wtf/text/StringImpl.cpp >index 0d80c32c7485d8f9c62934bb36efddefa475dde4..33fe07ccb8ee661bd2b56edba71bfa8ffde4ebcb 100644 >--- a/Source/WTF/wtf/text/StringImpl.cpp >+++ b/Source/WTF/wtf/text/StringImpl.cpp >@@ -102,6 +102,8 @@ void StringStats::printStats() > } > #endif > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StringImpl); >+ > StringImpl::StaticStringImpl StringImpl::s_atomicEmptyString("", StringImpl::StringAtomic); > > 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>(); >diff --git a/Source/WTF/wtf/text/StringImpl.h b/Source/WTF/wtf/text/StringImpl.h >index e564648c543cd823de8f223c4237cc9269519304..212d5ea29c32d405c78cbeb16e511a312f83b9b8 100644 >--- a/Source/WTF/wtf/text/StringImpl.h >+++ b/Source/WTF/wtf/text/StringImpl.h >@@ -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> >@@ -165,8 +166,10 @@ class StringImplShape { > // 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_DEBUG_HEAP_ALLOCATOR(StringImpl); > class StringImpl : private StringImplShape { >- WTF_MAKE_NONCOPYABLE(StringImpl); WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(StringImpl); >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StringImpl); > > friend class AtomicStringImpl; > friend class JSC::LLInt::Data; >@@ -192,6 +195,7 @@ class StringImpl : private StringImplShape { > > // 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"); >@@ -863,6 +867,19 @@ inline StringImpl::StringImpl(unsigned length) > STRING_STATS_ADD_16BIT_STRING(m_length); > } > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+inline StringImpl::StringImpl(MallocPtr<LChar> characters, unsigned length) >+ : StringImplShape(s_refCountIncrement, length, static_cast<const LChar*>(nullptr), s_hashFlag8BitBuffer | StringNormal | BufferOwned) >+{ >+ m_data8 = static_cast<const LChar*>(StringImplMalloc::malloc(length)); >+ memcpy((void*)m_data8, characters.get(), length); >+ >+ ASSERT(m_data8); >+ ASSERT(m_length); >+ >+ STRING_STATS_ADD_8BIT_STRING(m_length); >+} >+#else > inline StringImpl::StringImpl(MallocPtr<LChar> characters, unsigned length) > : StringImplShape(s_refCountIncrement, length, characters.leakPtr(), s_hashFlag8BitBuffer | StringNormal | BufferOwned) > { >@@ -871,6 +888,7 @@ inline StringImpl::StringImpl(MallocPtr<LChar> characters, unsigned length) > > STRING_STATS_ADD_8BIT_STRING(m_length); > } >+#endif > > inline StringImpl::StringImpl(const UChar* characters, unsigned length, ConstructWithoutCopyingTag) > : StringImplShape(s_refCountIncrement, length, characters, StringNormal | BufferInternal) >@@ -890,6 +908,19 @@ inline StringImpl::StringImpl(const LChar* characters, unsigned length, Construc > STRING_STATS_ADD_8BIT_STRING(m_length); > } > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+inline StringImpl::StringImpl(MallocPtr<UChar> characters, unsigned length) >+ : StringImplShape(s_refCountIncrement, length, static_cast<const UChar*>(nullptr), StringNormal | BufferOwned) >+{ >+ 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); >+ >+ STRING_STATS_ADD_16BIT_STRING(m_length); >+} >+#else > inline StringImpl::StringImpl(MallocPtr<UChar> characters, unsigned length) > : StringImplShape(s_refCountIncrement, length, characters.leakPtr(), StringNormal | BufferOwned) > { >@@ -898,6 +929,7 @@ inline StringImpl::StringImpl(MallocPtr<UChar> characters, unsigned length) > > STRING_STATS_ADD_16BIT_STRING(m_length); > } >+#endif > > inline StringImpl::StringImpl(const LChar* characters, unsigned length, Ref<StringImpl>&& base) > : StringImplShape(s_refCountIncrement, length, characters, s_hashFlag8BitBuffer | StringNormal | BufferSubstring) >@@ -950,7 +982,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)); >@@ -976,10 +1008,8 @@ template<typename CharacterType> ALWAYS_INLINE RefPtr<StringImpl> StringImpl::tr > return nullptr; > } > StringImpl* result; >- if (!tryFastMalloc(allocationSize<CharacterType>(length)).getValue(result)) { >- output = nullptr; >- return nullptr; >- } >+ >+ result = (StringImpl*)StringImplMalloc::tryMalloc(allocationSize<CharacterType>(length)); > output = result->tailPointer<CharacterType>(); > > return constructInternal<CharacterType>(*result, length); >@@ -992,7 +1022,17 @@ inline Ref<StringImpl> StringImpl::adopt(Vector<CharacterType, inlineCapacity, O > ASSERT(vector.data()); > if (size > MaxLength) > CRASH(); >+ >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ // We have to copy between malloc zones. >+ auto vectorBuffer = vector.releaseBuffer(); >+ auto stringImplBuffer = MallocPtr<CharacterType>::malloc(size, StringImplMalloc::debugHeap()); >+ memcpy(stringImplBuffer.get(), vectorBuffer.get(), size); >+ return adoptRef(*new StringImpl(WTFMove(stringImplBuffer), size)); >+#else > return adoptRef(*new StringImpl(vector.releaseBuffer(), size)); >+#endif >+ > } > return *empty(); > } >diff --git a/Source/WTF/wtf/text/cf/StringImplCF.cpp b/Source/WTF/wtf/text/cf/StringImplCF.cpp >index c3003abf2322182d8cefd6ddba4dbde056e354b2..7ad804b86339d70c2e0f68af838ccddfc9a55367 100644 >--- a/Source/WTF/wtf/text/cf/StringImplCF.cpp >+++ b/Source/WTF/wtf/text/cf/StringImplCF.cpp >@@ -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_DEBUG_HEAP_ALLOCATOR(StringWrapperCFAllocator); >+ DEFINE_DEBUG_HEAP_ALLOCATOR(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); > }); > } > } >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 03171255ca0e024d4f4f4cec53cfc64f7cf50175..d740978c80ed5552d7db65b29ea2e78188412d36 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -2078,6 +2078,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 >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index c00186322788a119275fff4569a71c952db8e890..bb025518e4c4decdd29dad5a04a90c18287cba68 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -14796,6 +14796,7 @@ > 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>"; }; >@@ -16383,8 +16384,6 @@ > 115CFA9A208BC140001E6991 /* inlineformatting */ = { > isa = PBXGroup; > children = ( >- 6F0CD694229ED32700C5994E /* InlineLine.h */, >- 6F0CD692229ED31900C5994E /* InlineLine.cpp */, > 6FE7DDDD20EC6E8B008B5B4E /* text */, > 6F7CA3C9208C2B2E002F29AB /* InlineFormattingContext.cpp */, > 6F7CA3C8208C2B2E002F29AB /* InlineFormattingContext.h */, >@@ -16395,6 +16394,8 @@ > 1123AFDD209ABBBA00736ACC /* InlineInvalidation.cpp */, > 1123AFDC209ABBBA00736ACC /* InlineInvalidation.h */, > 6FE7CFA02177EEF1005B1573 /* InlineItem.h */, >+ 6F0CD692229ED31900C5994E /* InlineLine.cpp */, >+ 6F0CD694229ED32700C5994E /* InlineLine.h */, > 6FB47E612277425A00C7BCB0 /* InlineLineBox.h */, > 6FE198132178397B00446F08 /* InlineLineBreaker.cpp */, > 6FE198152178397C00446F08 /* InlineLineBreaker.h */, >@@ -27146,6 +27147,7 @@ > E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */, > 582CB0541A78A2B200AFFCC4 /* SimpleLineLayoutTextFragmentIterator.cpp */, > 582CB0521A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h */, >+ E31CD750229F749500FBDA19 /* TableLayout.cpp */, > A8CFF04C0A154F09000A4234 /* TableLayout.h */, > 0F54DCE31881051D003EEDBB /* TextAutoSizing.cpp */, > 0F54DCE41881051D003EEDBB /* TextAutoSizing.h */, >@@ -28185,7 +28187,6 @@ > 714C7C661FDAD2A100F2BEE1 /* AnimationPlaybackEvent.h in Headers */, > 714C7C671FDAD2A900F2BEE1 /* AnimationPlaybackEventInit.h in Headers */, > 71025ECD1F99F0CE004A250C /* AnimationTimeline.h in Headers */, >- 6F0CD695229ED32700C5994E /* InlineLine.h in Headers */, > 0F580FAF149800D400FB5BD8 /* AnimationUtilities.h in Headers */, > 57152B5A21CB3E88000C37CA /* ApduCommand.h in Headers */, > 57152B5C21CC1902000C37CA /* ApduResponse.h in Headers */, >@@ -29491,6 +29492,7 @@ > 11310CF820BA4A6A0065A8D0 /* InlineInvalidation.h in Headers */, > 6FE7CFA22177EEF2005B1573 /* InlineItem.h in Headers */, > BCE789161120D6080060ECE5 /* InlineIterator.h in Headers */, >+ 6F0CD695229ED32700C5994E /* InlineLine.h in Headers */, > 6FB47E632277425A00C7BCB0 /* InlineLineBox.h in Headers */, > 6FE198172178397C00446F08 /* InlineLineBreaker.h in Headers */, > AA4C3A770B2B1679002334A2 /* InlineStyleSheetOwner.h in Headers */, >diff --git a/Source/WebCore/bindings/js/GCController.cpp b/Source/WebCore/bindings/js/GCController.cpp >index 8a83c4b6f6f59607dfa77048429d02b1e429733b..ae7e7bac71ab8a2bfce3c4d1dc67e9a5405d6e2e 100644 >--- a/Source/WebCore/bindings/js/GCController.cpp >+++ b/Source/WebCore/bindings/js/GCController.cpp >@@ -32,6 +32,7 @@ > #include <JavaScriptCore/Heap.h> > #include <JavaScriptCore/HeapSnapshotBuilder.h> > #include <JavaScriptCore/JSLock.h> >+#include <JavaScriptCore/UnlinkedMetadataTable.h> > #include <JavaScriptCore/VM.h> > #include <pal/Logging.h> > #include <wtf/FastMalloc.h> >@@ -62,6 +63,9 @@ GCController::GCController() > PAL::registerNotifyCallback("com.apple.WebKit.dumpGCHeap", [] { > GCController::singleton().dumpHeap(); > }); >+ PAL::registerNotifyCallback("com.apple.WebKit.dumpMetadataStatus", [] { >+ JSC::UnlinkedMetadataTable::dumpStatus(commonVM()); >+ }); > }); > } > >diff --git a/Source/WebCore/bindings/js/SerializedScriptValue.cpp b/Source/WebCore/bindings/js/SerializedScriptValue.cpp >index c4600f859d28e3635c98e5124075493a54602db5..0f9acb06430f0631ba2754314b4b37605367707b 100644 >--- a/Source/WebCore/bindings/js/SerializedScriptValue.cpp >+++ b/Source/WebCore/bindings/js/SerializedScriptValue.cpp >@@ -96,6 +96,8 @@ > namespace WebCore { > using namespace JSC; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(SerializedScriptValue); >+ > static const unsigned maximumFilterRecursion = 40000; > > enum class SerializationReturnCode { >diff --git a/Source/WebCore/bindings/js/SerializedScriptValue.h b/Source/WebCore/bindings/js/SerializedScriptValue.h >index 7633bfd70821ade7bc9171a0757c14994fadc20c..3dbf205bc9511b75d47a73134cb268c769b04768 100644 >--- a/Source/WebCore/bindings/js/SerializedScriptValue.h >+++ b/Source/WebCore/bindings/js/SerializedScriptValue.h >@@ -62,7 +62,9 @@ using ArrayBufferContentsArray = Vector<JSC::ArrayBufferContents>; > using WasmModuleArray = Vector<RefPtr<JSC::Wasm::Module>>; > #endif > >+DECLARE_DEBUG_HEAP_ALLOCATOR(SerializedScriptValue); > class SerializedScriptValue : public ThreadSafeRefCounted<SerializedScriptValue> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(SerializedScriptValue); > public: > WEBCORE_EXPORT static RefPtr<SerializedScriptValue> create(JSC::ExecState&, JSC::JSValue, SerializationErrorMode = SerializationErrorMode::Throwing); > >diff --git a/Source/WebCore/css/CSSFontFace.cpp b/Source/WebCore/css/CSSFontFace.cpp >index 7377adba929feb57b5b37e98260f29e8535ccd5b..ac248dced2118a79cf2daecc18a0f985f2a58563 100644 >--- a/Source/WebCore/css/CSSFontFace.cpp >+++ b/Source/WebCore/css/CSSFontFace.cpp >@@ -48,6 +48,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(CSSFontFace); >+ > template<typename T> void iterateClients(HashSet<CSSFontFace::Client*>& clients, T callback) > { > Vector<Ref<CSSFontFace::Client>> clientsCopy; >diff --git a/Source/WebCore/css/CSSFontFace.h b/Source/WebCore/css/CSSFontFace.h >index a39a926ff8b3b765028605419bdd0e8c7d7e5b18..4bd5dbdb197024dea1a47b2ce61c47476744d09f 100644 >--- a/Source/WebCore/css/CSSFontFace.h >+++ b/Source/WebCore/css/CSSFontFace.h >@@ -54,7 +54,9 @@ class Font; > class FontFace; > enum class ExternalResourceDownloadPolicy; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(CSSFontFace); > class CSSFontFace final : public RefCounted<CSSFontFace> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(CSSFontFace); > public: > static Ref<CSSFontFace> create(CSSFontSelector* fontSelector, StyleRuleFontFace* cssConnection = nullptr, FontFace* wrapper = nullptr, bool isLocalFallback = false) > { >diff --git a/Source/WebCore/css/CSSSelector.cpp b/Source/WebCore/css/CSSSelector.cpp >index f365a85e74db82657fbab888c0635541c0b6006f..16d7b8ad7685c6b43e069234d175327fe58c640e 100644 >--- a/Source/WebCore/css/CSSSelector.cpp >+++ b/Source/WebCore/css/CSSSelector.cpp >@@ -48,6 +48,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_DEBUG_HEAP_ALLOCATOR(CSSSelectorRareData); >+ > CSSSelector::CSSSelector(const QualifiedName& tagQName, bool tagIsForNamespaceRule) > : m_relation(DescendantSpace) > , m_match(Tag) >diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h >index 544cc2cd58abea8044435b16485c23858853ea55..63ead3c4a0b710dc3e001276d658337896c497aa 100644 >--- a/Source/WebCore/css/CSSSelector.h >+++ b/Source/WebCore/css/CSSSelector.h >@@ -34,6 +34,7 @@ namespace WebCore { > }; > > // this class represents a selector for a StyleRule >+ DECLARE_DEBUG_HEAP_ALLOCATOR(CSSSelectorRareData); > class CSSSelector { > WTF_MAKE_FAST_ALLOCATED; > public: >@@ -341,6 +342,7 @@ namespace WebCore { > CSSSelector& operator=(const CSSSelector&); > > struct RareData : public RefCounted<RareData> { >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(CSSSelectorRareData); > static Ref<RareData> create(AtomicString&& value) { return adoptRef(*new RareData(WTFMove(value))); } > ~RareData(); > >diff --git a/Source/WebCore/css/CSSValue.cpp b/Source/WebCore/css/CSSValue.cpp >index 50d2a97b71519f6bb0fd1c2194cc51f4f60db136..0ef89b73e0970280c688858a3b1b6e63acacb4d6 100644 >--- a/Source/WebCore/css/CSSValue.cpp >+++ b/Source/WebCore/css/CSSValue.cpp >@@ -85,6 +85,8 @@ bool CSSValue::isImplicitInitialValue() const > return m_classType == InitialClass && downcast<CSSInitialValue>(*this).isImplicit(); > } > >+DEFINE_DEBUG_HEAP_ALLOCATOR(CSSValue); >+ > CSSValue::Type CSSValue::cssValueType() const > { > if (isInheritedValue()) >diff --git a/Source/WebCore/css/CSSValue.h b/Source/WebCore/css/CSSValue.h >index 7d4b118fb7be1b20f34c50ddeab84ff6d210efbe..6aa1e86e93f3a89ddeb09992f3f72361969c3610 100644 >--- a/Source/WebCore/css/CSSValue.h >+++ b/Source/WebCore/css/CSSValue.h >@@ -38,7 +38,9 @@ class StyleSheetContents; > > enum CSSPropertyID : uint16_t; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(CSSValue); > class CSSValue : public RefCounted<CSSValue> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(CSSValue); > public: > enum Type { > CSS_INHERIT = 0, >diff --git a/Source/WebCore/css/ElementRuleCollector.cpp b/Source/WebCore/css/ElementRuleCollector.cpp >index 05d385a558c48c48ee8da90f6a18cb4e75a6a95a..b566d97e8b54ae27134559c209fcd7cd302e9a26 100644 >--- a/Source/WebCore/css/ElementRuleCollector.cpp >+++ b/Source/WebCore/css/ElementRuleCollector.cpp >@@ -225,7 +225,7 @@ void ElementRuleCollector::matchHostPseudoClassRules(bool includeEmptyRules, Sty > > auto& shadowAuthorStyle = m_element.shadowRoot()->styleScope().resolver().ruleSets().authorStyle(); > auto& shadowHostRules = shadowAuthorStyle.hostPseudoClassRules(); >- if (shadowHostRules.isEmpty()) >+ if (shadowHostRules.data.isEmpty()) > return; > > SetForScope<bool> change(m_isMatchingHostPseudoClass, true); >@@ -292,9 +292,9 @@ std::unique_ptr<RuleSet::RuleDataVector> ElementRuleCollector::collectSlottedPse > return { }; > > auto ruleDataVector = std::make_unique<RuleSet::RuleDataVector>(); >- ruleDataVector->reserveInitialCapacity(m_matchedRules.size()); >+ ruleDataVector->data.reserveInitialCapacity(m_matchedRules.size()); > for (auto& matchedRule : m_matchedRules) >- ruleDataVector->uncheckedAppend(*matchedRule.ruleData); >+ ruleDataVector->data.uncheckedAppend(*matchedRule.ruleData); > > return ruleDataVector; > } >@@ -455,8 +455,8 @@ void ElementRuleCollector::collectMatchingRulesForList(const RuleSet::RuleDataVe > if (!rules) > return; > >- for (unsigned i = 0, size = rules->size(); i < size; ++i) { >- const RuleData& ruleData = rules->data()[i]; >+ for (unsigned i = 0, size = rules->data.size(); i < size; ++i) { >+ const RuleData& ruleData = rules->data.data()[i]; > > if (!ruleData.canMatchPseudoElement() && m_pseudoStyleRequest.pseudoId != PseudoId::None) > continue; >diff --git a/Source/WebCore/css/RuleSet.cpp b/Source/WebCore/css/RuleSet.cpp >index 0eba42df452e8f2dec9a08d2ec8a4c0de688e232..78e6c2563246b1c2d75d6d11a4ff429c46f74361 100644 >--- a/Source/WebCore/css/RuleSet.cpp >+++ b/Source/WebCore/css/RuleSet.cpp >@@ -52,6 +52,9 @@ namespace WebCore { > > using namespace HTMLNames; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(RuleSet); >+DEFINE_DEBUG_HEAP_ALLOCATOR(RuleDataVector); >+ > // ----------------------------------------------------------------- > > static inline MatchBasedOnRuleHash computeMatchBasedOnRuleHash(const CSSSelector& selector) >@@ -183,13 +186,13 @@ void RuleSet::addToRuleSet(const AtomicString& key, AtomRuleMap& map, const Rule > auto& rules = map.add(key, nullptr).iterator->value; > if (!rules) > rules = std::make_unique<RuleDataVector>(); >- rules->append(ruleData); >+ rules->data.append(ruleData); > } > > static unsigned rulesCountForName(const RuleSet::AtomRuleMap& map, const AtomicString& name) > { > if (const auto* rules = map.get(name)) >- return rules->size(); >+ return rules->data.size(); > return 0; > } > >@@ -302,7 +305,7 @@ void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, unsigned selector > > #if ENABLE(VIDEO_TRACK) > if (cuePseudoElementSelector) { >- m_cuePseudoRules.append(ruleData); >+ m_cuePseudoRules.data.append(ruleData); > return; > } > #endif >@@ -310,7 +313,7 @@ void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, unsigned selector > if (slottedPseudoElementSelector) { > // ::slotted pseudo elements work accross shadow boundary making filtering difficult. > ruleData.disableSelectorFiltering(); >- m_slottedPseudoElementRules.append(ruleData); >+ m_slottedPseudoElementRules.data.append(ruleData); > return; > } > >@@ -325,7 +328,7 @@ void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, unsigned selector > m_hasHostPseudoClassRulesMatchingInShadowTree = isHostSelectorMatchingInShadowTree(*ruleData.selector()); > > if (hostPseudoClassSelector) { >- m_hostPseudoClassRules.append(ruleData); >+ m_hostPseudoClassRules.data.append(ruleData); > return; > } > >@@ -340,12 +343,12 @@ void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, unsigned selector > } > > if (linkSelector) { >- m_linkPseudoClassRules.append(ruleData); >+ m_linkPseudoClassRules.data.append(ruleData); > return; > } > > if (focusSelector) { >- m_focusPseudoClassRules.append(ruleData); >+ m_focusPseudoClassRules.data.append(ruleData); > return; > } > >@@ -356,7 +359,7 @@ void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, unsigned selector > } > > // If we didn't find a specialized map to stick it in, file under universal rules. >- m_universalRules.append(ruleData); >+ m_universalRules.data.append(ruleData); > } > > void RuleSet::addPageRule(StyleRulePage* rule) >@@ -419,7 +422,7 @@ bool RuleSet::hasShadowPseudoElementRules() const > if (!m_shadowPseudoElementRules.isEmpty()) > return true; > #if ENABLE(VIDEO_TRACK) >- if (!m_cuePseudoRules.isEmpty()) >+ if (!m_cuePseudoRules.data.isEmpty()) > return true; > #endif > return false; >@@ -428,7 +431,7 @@ bool RuleSet::hasShadowPseudoElementRules() const > static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map) > { > for (auto& vector : map.values()) >- vector->shrinkToFit(); >+ vector->data.shrinkToFit(); > } > > void RuleSet::shrinkToFit() >@@ -438,14 +441,14 @@ void RuleSet::shrinkToFit() > shrinkMapVectorsToFit(m_tagLocalNameRules); > shrinkMapVectorsToFit(m_tagLowercaseLocalNameRules); > shrinkMapVectorsToFit(m_shadowPseudoElementRules); >- m_linkPseudoClassRules.shrinkToFit(); >+ m_linkPseudoClassRules.data.shrinkToFit(); > #if ENABLE(VIDEO_TRACK) >- m_cuePseudoRules.shrinkToFit(); >+ m_cuePseudoRules.data.shrinkToFit(); > #endif >- m_hostPseudoClassRules.shrinkToFit(); >- m_slottedPseudoElementRules.shrinkToFit(); >- m_focusPseudoClassRules.shrinkToFit(); >- m_universalRules.shrinkToFit(); >+ m_hostPseudoClassRules.data.shrinkToFit(); >+ m_slottedPseudoElementRules.data.shrinkToFit(); >+ m_focusPseudoClassRules.data.shrinkToFit(); >+ m_universalRules.data.shrinkToFit(); > m_pageRules.shrinkToFit(); > m_features.shrinkToFit(); > } >diff --git a/Source/WebCore/css/RuleSet.h b/Source/WebCore/css/RuleSet.h >index ba5dc60fe34c6b7678246734d322ac2f7a02f57f..644fbf1c85abfa6d93afbfaff91aac3c902f5933 100644 >--- a/Source/WebCore/css/RuleSet.h >+++ b/Source/WebCore/css/RuleSet.h >@@ -100,8 +100,11 @@ struct SameSizeAsRuleData { > > COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small); > >+DECLARE_DEBUG_HEAP_ALLOCATOR(RuleSet); >+DECLARE_DEBUG_HEAP_ALLOCATOR(RuleDataVector); > class RuleSet { >- WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(RuleSet); >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(RuleSet); > public: > struct RuleSetSelectorPair { > RuleSetSelectorPair(const CSSSelector* selector, std::unique_ptr<RuleSet> ruleSet) : selector(selector), ruleSet(WTFMove(ruleSet)) { } >@@ -114,7 +117,10 @@ class RuleSet { > RuleSet(); > ~RuleSet(); > >- typedef Vector<RuleData, 1> RuleDataVector; >+ struct RuleDataVector { >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(RuleDataVector); >+ Vector<RuleData, 1> data; >+ }; > typedef HashMap<AtomicString, std::unique_ptr<RuleDataVector>> AtomRuleMap; > > void addRulesFromSheet(StyleSheetContents&, const MediaQueryEvaluator&, StyleResolver* = 0); >diff --git a/Source/WebCore/css/StyleProperties.cpp b/Source/WebCore/css/StyleProperties.cpp >index 4cf6c6f7ab7df9fc04334bbe8dd05a3b559e935c..f38de80cc7af2dab4cd78bafa1fa3815937e6a27 100644 >--- a/Source/WebCore/css/StyleProperties.cpp >+++ b/Source/WebCore/css/StyleProperties.cpp >@@ -49,6 +49,10 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleProperties); >+DEFINE_DEBUG_HEAP_ALLOCATOR(ImmutableStyleProperties); >+DEFINE_DEBUG_HEAP_ALLOCATOR(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)); > } > >diff --git a/Source/WebCore/css/StyleProperties.h b/Source/WebCore/css/StyleProperties.h >index 0ca7e613468b5a78cca6b8e7692352b71e431a3f..d13e5d13b60de81ac6ba16d54c45a8b2245c17dc 100644 >--- a/Source/WebCore/css/StyleProperties.h >+++ b/Source/WebCore/css/StyleProperties.h >@@ -74,7 +74,9 @@ class StylePropertiesBase : public RefCounted<StylePropertiesBase> { > unsigned m_arraySize : 27; > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleProperties); > class StyleProperties : public StylePropertiesBase { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleProperties); > friend class PropertyReference; > public: > class PropertyReference { >@@ -176,7 +178,9 @@ class StyleProperties : public StylePropertiesBase { > friend class PropertySetCSSStyleDeclaration; > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(ImmutableStyleProperties); > class ImmutableStyleProperties final : public StyleProperties { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(ImmutableStyleProperties); > public: > WEBCORE_EXPORT ~ImmutableStyleProperties(); > static Ref<ImmutableStyleProperties> create(const CSSProperty* properties, unsigned count, CSSParserMode); >@@ -206,7 +210,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_DEBUG_HEAP_ALLOCATOR(MutableStyleProperties); > class MutableStyleProperties final : public StyleProperties { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(MutableStyleProperties); > public: > WEBCORE_EXPORT static Ref<MutableStyleProperties> create(CSSParserMode = HTMLQuirksMode); > static Ref<MutableStyleProperties> create(const CSSProperty* properties, unsigned count); >@@ -349,3 +355,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() >+ >diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp >index fb8f87d1faa6619ee484f072983bf82a0e19ce87..b3819133bf9708f2a989e34d87a0a526d218c2f6 100644 >--- a/Source/WebCore/css/StyleResolver.cpp >+++ b/Source/WebCore/css/StyleResolver.cpp >@@ -128,6 +128,8 @@ static const CSSPropertyID firstLowPriorityProperty = static_cast<CSSPropertyID> > > static void extractDirectionAndWritingMode(const RenderStyle&, const StyleResolver::MatchResult&, TextDirection&, WritingMode&); > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleResolver); >+ > inline void StyleResolver::State::cacheBorderAndBackground() > { > m_hasUAAppearance = m_style->hasAppearance(); >diff --git a/Source/WebCore/css/StyleResolver.h b/Source/WebCore/css/StyleResolver.h >index ee1207c60dfee7f1b78a1e0a0a539b5630238fc4..a74f9163dd78e71bd0a03a5fc4cb7e3878d70fc3 100644 >--- a/Source/WebCore/css/StyleResolver.h >+++ b/Source/WebCore/css/StyleResolver.h >@@ -123,8 +123,10 @@ struct ElementStyle { > }; > > // This class selects a RenderStyle for a given element based on a collection of stylesheets. >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleResolver); > class StyleResolver { >- WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(StyleResolver); >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleResolver); > public: > StyleResolver(Document&); > ~StyleResolver(); >diff --git a/Source/WebCore/css/StyleRule.cpp b/Source/WebCore/css/StyleRule.cpp >index 1eefeb8bd10c254b824bc06cd5b8aef06602184f..6f29a4f7c905e12006a63961f0f9c444ca62df35 100644 >--- a/Source/WebCore/css/StyleRule.cpp >+++ b/Source/WebCore/css/StyleRule.cpp >@@ -45,6 +45,9 @@ struct SameSizeAsStyleRuleBase : public WTF::RefCountedBase { > > COMPILE_ASSERT(sizeof(StyleRuleBase) == sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small); > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleRuleBase); >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleRule); >+ > Ref<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const > { > return createCSSOMWrapper(parentSheet, nullptr); >diff --git a/Source/WebCore/css/StyleRule.h b/Source/WebCore/css/StyleRule.h >index 401d04942c31e13108b0bde8544541cca8feec08..9de6110c61a464604d23d298aa66b63ce275239f 100644 >--- a/Source/WebCore/css/StyleRule.h >+++ b/Source/WebCore/css/StyleRule.h >@@ -39,8 +39,9 @@ class StyleRuleKeyframe; > class StyleProperties; > class StyleRuleKeyframes; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleRuleBase); > class StyleRuleBase : public WTF::RefCountedBase { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleRuleBase); > public: > enum Type { > Unknown, // Not used. >@@ -115,8 +116,9 @@ class StyleRuleBase : public WTF::RefCountedBase { > unsigned m_hasDocumentSecurityOrigin : 1; > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleRule); > class StyleRule final : public StyleRuleBase { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleRule); > public: > static Ref<StyleRule> create(Ref<StylePropertiesBase>&& properties, bool hasDocumentSecurityOrigin, CSSSelectorList&& selectors) > { >diff --git a/Source/WebCore/dom/ElementData.cpp b/Source/WebCore/dom/ElementData.cpp >index 9515305584ba41e6af47aa3944f1918bdcd2df82..7758cef439d3440a362721bdaa3f22e58bc31fc6 100644 >--- a/Source/WebCore/dom/ElementData.cpp >+++ b/Source/WebCore/dom/ElementData.cpp >@@ -33,6 +33,9 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(ElementData); >+DEFINE_DEBUG_HEAP_ALLOCATOR(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)); > } > >diff --git a/Source/WebCore/dom/ElementData.h b/Source/WebCore/dom/ElementData.h >index f6d1eafd736b2aa826beb2b7fe054ffc2d59b653..b75b7003124625caf70717b2c50081bb735b6d73 100644 >--- a/Source/WebCore/dom/ElementData.h >+++ b/Source/WebCore/dom/ElementData.h >@@ -75,8 +75,9 @@ class AttributeIteratorAccessor { > unsigned m_size; > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(ElementData); > class ElementData : public RefCounted<ElementData> { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(ElementData); > public: > // Override RefCounted's deref() to ensure operator delete is called on > // the appropriate subclass type. >@@ -183,7 +184,9 @@ class ElementData : public RefCounted<ElementData> { > #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning > #endif > >+DECLARE_DEBUG_HEAP_ALLOCATOR(ShareableElementData); > class ShareableElementData : public ElementData { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(ShareableElementData); > public: > static Ref<ShareableElementData> createWithAttributes(const Vector<Attribute>&); > >diff --git a/Source/WebCore/dom/MessageEvent.cpp b/Source/WebCore/dom/MessageEvent.cpp >index afb24e5b76bec8baead175f79d081111ccab0881..4335a91e2d8657f7b4e8ee106ebcfca6444b2040 100644 >--- a/Source/WebCore/dom/MessageEvent.cpp >+++ b/Source/WebCore/dom/MessageEvent.cpp >@@ -36,6 +36,8 @@ namespace WebCore { > > using namespace JSC; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(MessageEvent); >+ > MessageEvent::MessageEvent() = default; > > inline MessageEvent::MessageEvent(const AtomicString& type, Init&& initializer, IsTrusted isTrusted) >diff --git a/Source/WebCore/dom/MessageEvent.h b/Source/WebCore/dom/MessageEvent.h >index 9216968263260d51047fcf62683abad24547187d..056dcea686abad4e2b41ec2f8a68a0b0a9458a61 100644 >--- a/Source/WebCore/dom/MessageEvent.h >+++ b/Source/WebCore/dom/MessageEvent.h >@@ -45,7 +45,9 @@ using MessageEventSource = Variant<RefPtr<WindowProxy>, RefPtr<MessagePort>, Ref > using MessageEventSource = Variant<RefPtr<WindowProxy>, RefPtr<MessagePort>>; > #endif > >+DECLARE_DEBUG_HEAP_ALLOCATOR(MessageEvent); > class MessageEvent final : public Event { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(MessageEvent); > public: > static Ref<MessageEvent> create(Vector<RefPtr<MessagePort>>&&, Ref<SerializedScriptValue>&&, const String& origin = { }, const String& lastEventId = { }, Optional<MessageEventSource>&& source = WTF::nullopt); > static Ref<MessageEvent> create(const AtomicString& type, Ref<SerializedScriptValue>&&, const String& origin, const String& lastEventId); >diff --git a/Source/WebCore/dom/NodeRareData.cpp b/Source/WebCore/dom/NodeRareData.cpp >index a723eaf879a278703b29247bc88bd40f5d1e85d4..0f9662df3dfb18f693bf7d3e1c2c3b3ac47849fc 100644 >--- a/Source/WebCore/dom/NodeRareData.cpp >+++ b/Source/WebCore/dom/NodeRareData.cpp >@@ -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_DEBUG_HEAP_ALLOCATOR(NodeListsNodeData); >+DEFINE_DEBUG_HEAP_ALLOCATOR(NodeRareData); >+ > } // namespace WebCore >diff --git a/Source/WebCore/dom/NodeRareData.h b/Source/WebCore/dom/NodeRareData.h >index 4f8502bf8f5f2e4787d4511635107b49cd597ee5..ef9a6bd0144360358f0f41a4f85f5279d127258e 100644 >--- a/Source/WebCore/dom/NodeRareData.h >+++ b/Source/WebCore/dom/NodeRareData.h >@@ -43,8 +43,10 @@ template <> struct NodeListTypeIdentifier<NameNodeList> { static int value() { r > template <> struct NodeListTypeIdentifier<RadioNodeList> { static int value() { return 1; } }; > template <> struct NodeListTypeIdentifier<LabelsNodeList> { static int value() { return 2; } }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(NodeListsNodeData); > class NodeListsNodeData { >- WTF_MAKE_NONCOPYABLE(NodeListsNodeData); WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(NodeListsNodeData); >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(NodeListsNodeData); > public: > NodeListsNodeData() > : m_childNodeList(nullptr) >@@ -246,8 +248,10 @@ class NodeMutationObserverData { > NodeMutationObserverData() { } > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(NodeRareData); > class NodeRareData : public NodeRareDataBase { >- WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(NodeRareData); >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(NodeRareData); > public: > #if defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS > enum class UseType : uint16_t { >diff --git a/Source/WebCore/dom/QualifiedName.cpp b/Source/WebCore/dom/QualifiedName.cpp >index 986292ff951cb4ffac1ada6a5798601682b5cd3e..663f83ae774f89fd1dc384867e278199c4bcad4c 100644 >--- a/Source/WebCore/dom/QualifiedName.cpp >+++ b/Source/WebCore/dom/QualifiedName.cpp >@@ -26,6 +26,9 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(QualifiedName); >+DEFINE_DEBUG_HEAP_ALLOCATOR(QualifiedNameQualifiedNameImpl); >+ > QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n) > : m_impl(threadGlobalData().qualifiedNameCache().getOrCreate(QualifiedNameComponents { p.impl(), l.impl(), n.isEmpty() ? nullptr : n.impl() })) > { >diff --git a/Source/WebCore/dom/QualifiedName.h b/Source/WebCore/dom/QualifiedName.h >index 8b762e5e89f78d24f17e8f8049106d27b1985d7e..bc0b99ff044dbde26a4534755930afd8cea69634 100644 >--- a/Source/WebCore/dom/QualifiedName.h >+++ b/Source/WebCore/dom/QualifiedName.h >@@ -32,10 +32,14 @@ struct QualifiedNameComponents { > StringImpl* m_namespace; > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(QualifiedName); >+DECLARE_DEBUG_HEAP_ALLOCATOR(QualifiedNameQualifiedNameImpl); >+ > class QualifiedName { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(QualifiedName); > public: > class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> { >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(QualifiedNameQualifiedNameImpl); > public: > static Ref<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI) > { >diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp >index 4ff4e2b8788a919bf42d17ad9fd651b9b03ad19b..c67d87bcc6567c1287ce31d59aa0404a21eebac5 100644 >--- a/Source/WebCore/html/parser/HTMLDocumentParser.cpp >+++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp >@@ -49,6 +49,8 @@ namespace WebCore { > > using namespace HTMLNames; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(HTMLDocumentParser); >+ > HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document) > : ScriptableDocumentParser(document) > , m_options(document) >diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.h b/Source/WebCore/html/parser/HTMLDocumentParser.h >index 9990d8b8d0c120f3f4cdb98b92464d3a1a04471f..10986cc82dc51d692de733b1538058da8a06b499 100644 >--- a/Source/WebCore/html/parser/HTMLDocumentParser.h >+++ b/Source/WebCore/html/parser/HTMLDocumentParser.h >@@ -47,8 +47,9 @@ class HTMLTreeBuilder; > class HTMLResourcePreloader; > class PumpSession; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(HTMLDocumentParser); > class HTMLDocumentParser : public ScriptableDocumentParser, private HTMLScriptRunnerHost, private PendingScriptClient { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(HTMLDocumentParser); > public: > static Ref<HTMLDocumentParser> create(HTMLDocument&); > virtual ~HTMLDocumentParser(); >diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp >index d1d98138d0e7f3b97a04749299edb5c0e5540fcd..6fdd73cbf0c373e784e41220d670e75ce750f198 100644 >--- a/Source/WebCore/loader/DocumentLoader.cpp >+++ b/Source/WebCore/loader/DocumentLoader.cpp >@@ -143,6 +143,8 @@ static bool areAllLoadersPageCacheAcceptable(const ResourceLoaderMap& loaders) > return true; > } > >+DEFINE_DEBUG_HEAP_ALLOCATOR(DocumentLoader); >+ > DocumentLoader::DocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) > : FrameDestructionObserver(nullptr) > , m_cachedResourceLoader(CachedResourceLoader::create(this)) >diff --git a/Source/WebCore/loader/DocumentLoader.h b/Source/WebCore/loader/DocumentLoader.h >index 7f2697bc5675f56930b52498f2cc08e7ebe485bf..3d9270a682adf51cf9f973cade8792e60adf0cb0 100644 >--- a/Source/WebCore/loader/DocumentLoader.h >+++ b/Source/WebCore/loader/DocumentLoader.h >@@ -137,12 +137,13 @@ enum class LegacyOverflowScrollingTouchPolicy : uint8_t { > Enable, > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(DocumentLoader); > class DocumentLoader > : public RefCounted<DocumentLoader> > , public FrameDestructionObserver > , public ContentSecurityPolicyClient > , private CachedRawResourceClient { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(DocumentLoader); > friend class ContentFilter; > public: > static Ref<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data) >diff --git a/Source/WebCore/loader/ResourceLoader.cpp b/Source/WebCore/loader/ResourceLoader.cpp >index 4e9cc30e819989712060783f54eff9f51a690a90..af55e317e7bd18a9382e1f468c036f968f6e5771 100644 >--- a/Source/WebCore/loader/ResourceLoader.cpp >+++ b/Source/WebCore/loader/ResourceLoader.cpp >@@ -68,6 +68,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(ResourceLoader); >+ > ResourceLoader::ResourceLoader(Frame& frame, ResourceLoaderOptions options) > : m_frame { &frame } > , m_documentLoader { frame.loader().activeDocumentLoader() } >diff --git a/Source/WebCore/loader/ResourceLoader.h b/Source/WebCore/loader/ResourceLoader.h >index d17e58d6bd0449225c13b1a338fd1010f572eec6..c53b0410d007772e40e29a52fb79a908632ca0d4 100644 >--- a/Source/WebCore/loader/ResourceLoader.h >+++ b/Source/WebCore/loader/ResourceLoader.h >@@ -54,7 +54,9 @@ class FrameLoader; > class NetworkLoadMetrics; > class PreviewLoader; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(ResourceLoader); > class ResourceLoader : public CanMakeWeakPtr<ResourceLoader>, public RefCounted<ResourceLoader>, protected ResourceHandleClient { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(ResourceLoader); > public: > virtual ~ResourceLoader() = 0; > >diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp >index e430e447ac494636c984e74d40b91e65cdebb50b..2c01244e87644c9d671b110a7f3593bbbea6392d 100644 >--- a/Source/WebCore/loader/cache/CachedResource.cpp >+++ b/Source/WebCore/loader/cache/CachedResource.cpp >@@ -64,6 +64,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(CachedResource); >+ > ResourceLoadPriority CachedResource::defaultPriorityForResourceType(Type type) > { > switch (type) { >diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h >index 9bf51e0b22744aa62e775d9ee75537f31ba88204..03826f5fea75c3111e8107ecefade54da5262194 100644 >--- a/Source/WebCore/loader/cache/CachedResource.h >+++ b/Source/WebCore/loader/cache/CachedResource.h >@@ -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_DEBUG_HEAP_ALLOCATOR(CachedResource); > class CachedResource { >- WTF_MAKE_NONCOPYABLE(CachedResource); WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(CachedResource); >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(CachedResource); > friend class MemoryCache; > > public: >diff --git a/Source/WebCore/page/PerformanceEntry.cpp b/Source/WebCore/page/PerformanceEntry.cpp >index 1381f807f0a4141c5f977faf840ae7ca3ed5625b..264478ca34e25bf2a5ac5ce526c83dc7c87d49fc 100644 >--- a/Source/WebCore/page/PerformanceEntry.cpp >+++ b/Source/WebCore/page/PerformanceEntry.cpp >@@ -36,6 +36,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(PerformanceEntry); >+ > PerformanceEntry::PerformanceEntry(Type type, const String& name, const String& entryType, double startTime, double finishTime) > : m_name(name) > , m_entryType(entryType) >diff --git a/Source/WebCore/page/PerformanceEntry.h b/Source/WebCore/page/PerformanceEntry.h >index ed876bb2edbfc0c3fcb1d8de602e7a6dc4eeab87..a6816fc251e25f31d1c578afbc7d3c74599ebe8d 100644 >--- a/Source/WebCore/page/PerformanceEntry.h >+++ b/Source/WebCore/page/PerformanceEntry.h >@@ -37,7 +37,9 @@ > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(PerformanceEntry); > class PerformanceEntry : public RefCounted<PerformanceEntry> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(PerformanceEntry); > public: > virtual ~PerformanceEntry(); > >diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp >index a743e9cc031744c87392e26574507ed05f311881..fc56632f198843c696346089b0385fd9b791f7f6 100644 >--- a/Source/WebCore/platform/graphics/Font.cpp >+++ b/Source/WebCore/platform/graphics/Font.cpp >@@ -56,6 +56,8 @@ unsigned GlyphPage::s_count = 0; > const float smallCapsFontSizeMultiplier = 0.7f; > const float emphasisMarkFontSizeMultiplier = 0.5f; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(Font); >+ > Font::Font(const FontPlatformData& platformData, Origin origin, Interstitial interstitial, Visibility visibility, OrientationFallback orientationFallback) > : m_platformData(platformData) > , m_origin(origin) >diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h >index 3ca978862d9e39da13a626d76e53655f2d561219..ec48e33a8291eb93c85f235eaa010dcbb3ab040c 100644 >--- a/Source/WebCore/platform/graphics/Font.h >+++ b/Source/WebCore/platform/graphics/Font.h >@@ -67,7 +67,9 @@ enum FontVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVar > enum Pitch { UnknownPitch, FixedPitch, VariablePitch }; > enum class IsForPlatformFont : uint8_t { No, Yes }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(Font); > class Font : public RefCounted<Font> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(Font); > public: > // Used to create platform fonts. > enum class Origin : uint8_t { >diff --git a/Source/WebCore/platform/graphics/FontCascadeFonts.cpp b/Source/WebCore/platform/graphics/FontCascadeFonts.cpp >index a9f41e1773b0014d5cbbd2f7ee1446dad4dd821d..e67eae1751588ddb53b84cc79a2de0f070df5ce4 100644 >--- a/Source/WebCore/platform/graphics/FontCascadeFonts.cpp >+++ b/Source/WebCore/platform/graphics/FontCascadeFonts.cpp >@@ -96,6 +96,8 @@ void FontCascadeFonts::GlyphPageCacheEntry::setSingleFontPage(RefPtr<GlyphPage>& > m_singleFont = page; > } > >+DEFINE_DEBUG_HEAP_ALLOCATOR(FontCascadeFonts); >+ > FontCascadeFonts::FontCascadeFonts(RefPtr<FontSelector>&& fontSelector) > : m_cachedPrimaryFont(nullptr) > , m_fontSelector(fontSelector) >diff --git a/Source/WebCore/platform/graphics/FontCascadeFonts.h b/Source/WebCore/platform/graphics/FontCascadeFonts.h >index 206c48e34a398b4d717f7dabd0ae997d63478fc4..b6c1f7c30014f22167edbce149febeb4d848b999 100644 >--- a/Source/WebCore/platform/graphics/FontCascadeFonts.h >+++ b/Source/WebCore/platform/graphics/FontCascadeFonts.h >@@ -42,8 +42,10 @@ class GraphicsContext; > class IntRect; > class MixedFontGlyphPage; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(FontCascadeFonts); > class FontCascadeFonts : public RefCounted<FontCascadeFonts> { > WTF_MAKE_NONCOPYABLE(FontCascadeFonts); >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(FontCascadeFonts); > public: > static Ref<FontCascadeFonts> create(RefPtr<FontSelector>&& fontSelector) { return adoptRef(*new FontCascadeFonts(WTFMove(fontSelector))); } > static Ref<FontCascadeFonts> createForPlatformFont(const FontPlatformData& platformData) { return adoptRef(*new FontCascadeFonts(platformData)); } >diff --git a/Source/WebCore/platform/graphics/Region.cpp b/Source/WebCore/platform/graphics/Region.cpp >index 9dcee8761625c01488b4d90d1af22e35435d4a5e..a980f09b9462da3714cf796e802467030a5fac30 100644 >--- a/Source/WebCore/platform/graphics/Region.cpp >+++ b/Source/WebCore/platform/graphics/Region.cpp >@@ -37,6 +37,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(Region); >+ > Region::Region() > { > } >diff --git a/Source/WebCore/platform/graphics/Region.h b/Source/WebCore/platform/graphics/Region.h >index 79633fdb6adf34fffee8f8267483b8cff5ce1f3c..0ad1ac72b1bffa4ebcf249e675a476e12fd86e6d 100644 >--- a/Source/WebCore/platform/graphics/Region.h >+++ b/Source/WebCore/platform/graphics/Region.h >@@ -33,9 +33,9 @@ > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(Region); > class Region { >- WTF_MAKE_FAST_ALLOCATED; >- >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(Region); > public: > WEBCORE_EXPORT Region(); > WEBCORE_EXPORT Region(const IntRect&); >diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm b/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm >index 5c0f3dc061f05fc693a3787361efd8928f2209aa..d680e616e189b1f1c0450bded0c2b15d866b54c9 100644 >--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm >+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm >@@ -43,7 +43,8 @@ namespace WebCore { > > static inline void releaseUint8Vector(void *array, const void*) > { >- adoptMallocPtr(static_cast<uint8_t*>(array)); >+ // Is this really vector backing memory? >+ WTF::VectorMalloc::free(array); > } > > RefPtr<MediaSampleAVFObjC> MediaSampleAVFObjC::createImageSample(Vector<uint8_t>&& array, unsigned long width, unsigned long height) >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp >index 80b5d4fbd272dee435b5ce7c084ee359a501ed64..7e1de2502889a6ddd75cb3b86b8dcbe8126264ef 100644 >--- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp >+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp >@@ -42,6 +42,7 @@ > #include <ImageIO/ImageIO.h> > #include <wtf/Assertions.h> > #include <wtf/CheckedArithmetic.h> >+#include <wtf/DebugHeap.h> > #include <wtf/MainThread.h> > #include <wtf/RetainPtr.h> > #include <wtf/text/Base64.h> >@@ -61,6 +62,9 @@ > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(ImageBuffer); >+DEFINE_DEBUG_HEAP_ALLOCATOR(ImageBuffer); >+ > static FloatSize scaleSizeToUserSpace(const FloatSize& logicalSize, const IntSize& backingStoreSize, const IntSize& internalSize) > { > float xMagnification = static_cast<float>(backingStoreSize.width()) / internalSize.width(); >@@ -167,7 +171,8 @@ ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, CGColorSp > } > > if (!accelerateRendering) { >- if (!tryFastCalloc(m_data.backingStoreSize.height(), m_data.bytesPerRow.unsafeGet()).getValue(m_data.data)) >+ m_data.data = ImageBufferMalloc::zeroedMalloc(m_data.backingStoreSize.height() * m_data.bytesPerRow.unsafeGet()); >+ if (!m_data.data) > return; > ASSERT(!(reinterpret_cast<intptr_t>(m_data.data) & 3)); > >@@ -178,7 +183,7 @@ ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, CGColorSp > #endif > cgContext = adoptCF(CGBitmapContextCreate(m_data.data, m_data.backingStoreSize.width(), m_data.backingStoreSize.height(), 8, m_data.bytesPerRow.unsafeGet(), m_data.colorSpace, m_data.bitmapInfo)); > const auto releaseImageData = [] (void*, const void* data, size_t) { >- fastFree(const_cast<void*>(data)); >+ ImageBufferMalloc::free(const_cast<void*>(data)); > }; > // Create a live image that wraps the data. > verifyImageBufferIsBigEnough(m_data.data, numBytes.unsafeGet()); >diff --git a/Source/WebCore/platform/network/ResourceHandle.cpp b/Source/WebCore/platform/network/ResourceHandle.cpp >index 70ee4e7711fd748b68f7d9a0f2aa36bb03dc35b0..ae8cd501a250b7d554297e79f67e9c8b755a82f6 100644 >--- a/Source/WebCore/platform/network/ResourceHandle.cpp >+++ b/Source/WebCore/platform/network/ResourceHandle.cpp >@@ -43,6 +43,8 @@ namespace WebCore { > > static bool shouldForceContentSniffing; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(ResourceHandleInternal); >+ > typedef HashMap<AtomicString, ResourceHandle::BuiltinConstructor> BuiltinResourceHandleConstructorMap; > static BuiltinResourceHandleConstructorMap& builtinResourceHandleConstructorMap() > { >diff --git a/Source/WebCore/platform/network/ResourceHandleInternal.h b/Source/WebCore/platform/network/ResourceHandleInternal.h >index 243de9f8265aa9d033c7fb1aee3493417a19f5f1..aa41dd9d710bf5e9af89601b52abeb82a3dedc20 100644 >--- a/Source/WebCore/platform/network/ResourceHandleInternal.h >+++ b/Source/WebCore/platform/network/ResourceHandleInternal.h >@@ -58,8 +58,10 @@ typedef const struct __CFURLStorageSession* CFURLStorageSessionRef; > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(ResourceHandleInternal); > class ResourceHandleInternal { >- WTF_MAKE_NONCOPYABLE(ResourceHandleInternal); WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(ResourceHandleInternal); >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(ResourceHandleInternal); > public: > ResourceHandleInternal(ResourceHandle* loader, NetworkingContext* context, const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff) > : m_context(context) >diff --git a/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp b/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp >index dfdde71a1f0b918671265504ac7a3fad919fd7e1..c4f022e677cb7dbd616374f2402c4deb6ade0027 100644 >--- a/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp >+++ b/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp >@@ -96,6 +96,14 @@ struct FormCreationContext { > unsigned long long streamLength; > }; > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+static WTF::DebugHeap& debugHeap() >+{ >+ static NeverDestroyed<WTF::DebugHeap> heap = WTF::DebugHeap("WebKit FormStreamFields"); >+ return heap; >+} >+#endif >+ > struct FormStreamFields { > RefPtr<FormData> formData; > SchedulePairHashSet scheduledRunLoopPairs; >@@ -107,6 +115,13 @@ struct FormStreamFields { > unsigned long long streamLength; > unsigned long long bytesSent; > Lock streamIsBeingOpenedOrClosedLock; >+ >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ FormStreamFields() >+ : currentData(debugHeap()) >+ { >+ } >+#endif > }; > > static void closeCurrentStream(FormStreamFields* form) >@@ -121,7 +136,7 @@ static void closeCurrentStream(FormStreamFields* form) > form->currentStreamRangeLength = BlobDataItem::toEndOfFile; > } > >- form->currentData = nullptr; >+ form->currentData = { debugHeap() }; > } > > // Return false if we cannot advance the stream. Currently the only possible failure is that the underlying file has been removed or changed since File.slice. >diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp >index 3a0d23c4620e47e06e01d11730b1b1507293abc5..7bf1ffd3182989903e36e2e3c43b2744efb42b5a 100644 >--- a/Source/WebCore/rendering/RenderLayer.cpp >+++ b/Source/WebCore/rendering/RenderLayer.cpp >@@ -282,6 +282,8 @@ static TextStream& operator<<(TextStream& ts, const ClipRects& clipRects) > > #endif > >+DEFINE_DEBUG_HEAP_ALLOCATOR(RenderLayer); >+ > RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject) > : m_isRenderViewLayer(rendererLayerModelObject.isRenderView()) > , m_forcedStackingContext(rendererLayerModelObject.isMedia()) >diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h >index 5e07bc775f22be480fde242c58c78da46373a32d..6d019304a9c61ccd700a4fba7028e1bc4383dcb5 100644 >--- a/Source/WebCore/rendering/RenderLayer.h >+++ b/Source/WebCore/rendering/RenderLayer.h >@@ -135,8 +135,9 @@ struct ScrollRectToVisibleOptions { > ShouldAllowCrossOriginScrolling shouldAllowCrossOriginScrolling { ShouldAllowCrossOriginScrolling::No }; > }; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(RenderLayer); > class RenderLayer final : public ScrollableArea { >- WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(RenderLayer); > public: > friend class RenderReplica; > friend class RenderLayerFilters; >diff --git a/Source/WebCore/rendering/TableLayout.cpp b/Source/WebCore/rendering/TableLayout.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..a8eda84abf01feb851002ad6d5b66de5d937e287 >--- /dev/null >+++ b/Source/WebCore/rendering/TableLayout.cpp >@@ -0,0 +1,35 @@ >+/* >+ * Copyright (C) 2019 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 "TableLayout.h" >+ >+#include <wtf/NeverDestroyed.h> >+ >+namespace WebCore { >+ >+DEFINE_DEBUG_HEAP_ALLOCATOR(TableLayout); >+ >+} // namespace WebCore >diff --git a/Source/WebCore/rendering/TableLayout.h b/Source/WebCore/rendering/TableLayout.h >index 5b6cd01d18ba91d940689f6f1ff7d6bd810ca385..46fe3f5fc39945150b78436242b0873247f3b9af 100644 >--- a/Source/WebCore/rendering/TableLayout.h >+++ b/Source/WebCore/rendering/TableLayout.h >@@ -28,8 +28,10 @@ namespace WebCore { > > class RenderTable; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(TableLayout); > class TableLayout { >- WTF_MAKE_NONCOPYABLE(TableLayout); WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(TableLayout); >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(TableLayout); > public: > explicit TableLayout(RenderTable* table) > : m_table(table) >diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp >index 2e2d6583021c78a165f36240340609c9b63eb9d2..428e56f24fc8b22351eba190158de16be5831712 100644 >--- a/Source/WebCore/rendering/style/RenderStyle.cpp >+++ b/Source/WebCore/rendering/style/RenderStyle.cpp >@@ -86,6 +86,8 @@ struct SameSizeAsRenderStyle { > > static_assert(sizeof(RenderStyle) == sizeof(SameSizeAsRenderStyle), "RenderStyle should stay small"); > >+DEFINE_DEBUG_HEAP_ALLOCATOR(RenderStyle); >+ > RenderStyle& RenderStyle::defaultStyle() > { > static NeverDestroyed<RenderStyle> style { CreateDefaultStyle }; >diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h >index fcf069ce472281ef6cb8498da5542db833163a7c..d895e2d43a31ecb778898bc44c8979e012f4d486 100644 >--- a/Source/WebCore/rendering/style/RenderStyle.h >+++ b/Source/WebCore/rendering/style/RenderStyle.h >@@ -129,9 +129,9 @@ using PseudoStyleCache = Vector<std::unique_ptr<RenderStyle>, 4>; > > template<typename T, typename U> inline bool compareEqual(const T& t, const U& u) { return t == static_cast<const T&>(u); } > >+DECLARE_DEBUG_HEAP_ALLOCATOR(RenderStyle); > class RenderStyle { >- WTF_MAKE_FAST_ALLOCATED; >- >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(RenderStyle); > private: > enum CloneTag { Clone }; > enum CreateDefaultStyleTag { CreateDefaultStyle }; >diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.cpp b/Source/WebCore/rendering/style/SVGRenderStyle.cpp >index cd9f364b286271b17e651f71a3b25af38f556970..32ea522444107b7c2c540ce31f3ab71ea2ebcc1d 100644 >--- a/Source/WebCore/rendering/style/SVGRenderStyle.cpp >+++ b/Source/WebCore/rendering/style/SVGRenderStyle.cpp >@@ -43,6 +43,8 @@ static const SVGRenderStyle& defaultSVGStyle() > return *style.get(); > } > >+DEFINE_DEBUG_HEAP_ALLOCATOR(SVGRenderStyle); >+ > Ref<SVGRenderStyle> SVGRenderStyle::createDefaultStyle() > { > return adoptRef(*new SVGRenderStyle(CreateDefault)); >diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.h b/Source/WebCore/rendering/style/SVGRenderStyle.h >index 4244ca601448f1b10a8f1fcbf9170234d3a0179b..5b27bd253885a35ac8727e43c41321ff6ccf3e37 100644 >--- a/Source/WebCore/rendering/style/SVGRenderStyle.h >+++ b/Source/WebCore/rendering/style/SVGRenderStyle.h >@@ -30,7 +30,9 @@ > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(SVGRenderStyle); > class SVGRenderStyle : public RefCounted<SVGRenderStyle> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(SVGRenderStyle); > public: > static Ref<SVGRenderStyle> createDefaultStyle(); > static Ref<SVGRenderStyle> create() { return adoptRef(*new SVGRenderStyle); } >diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp b/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp >index 20b2a8114b0c8e9ebd4827079a9820f2ec0dcdc2..54bd49c5d9dc3c6f8a9774627913c98a85440272 100644 >--- a/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp >+++ b/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp >@@ -35,6 +35,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleFillData); >+ > StyleFillData::StyleFillData() > : opacity(SVGRenderStyle::initialFillOpacity()) > , paintColor(SVGRenderStyle::initialFillPaintColor()) >diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h >index d87a8d3730c6431d715b3dfa277c0450e1ce01c2..b52e3ab4735bfff6fb30a39bdb4ab638ae04c427 100644 >--- a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h >+++ b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h >@@ -137,7 +137,9 @@ enum class MaskType : uint8_t { > }; > > // Inherited/Non-Inherited Style Datastructures >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleFillData); > class StyleFillData : public RefCounted<StyleFillData> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleFillData); > public: > static Ref<StyleFillData> create() { return adoptRef(*new StyleFillData); } > Ref<StyleFillData> copy() const; >diff --git a/Source/WebCore/rendering/style/StyleBoxData.cpp b/Source/WebCore/rendering/style/StyleBoxData.cpp >index a8b35e136fb08b31caec094e788d7ce645102421..8c1b7093198c39b86bc8ab03a32cd1a13255dc40 100644 >--- a/Source/WebCore/rendering/style/StyleBoxData.cpp >+++ b/Source/WebCore/rendering/style/StyleBoxData.cpp >@@ -35,6 +35,8 @@ struct SameSizeAsStyleBoxData : public RefCounted<SameSizeAsStyleBoxData> { > > COMPILE_ASSERT(sizeof(StyleBoxData) == sizeof(SameSizeAsStyleBoxData), StyleBoxData_should_not_grow); > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleBoxData); >+ > StyleBoxData::StyleBoxData() > : m_minWidth(RenderStyle::initialMinSize()) > , m_maxWidth(RenderStyle::initialMaxSize()) >diff --git a/Source/WebCore/rendering/style/StyleBoxData.h b/Source/WebCore/rendering/style/StyleBoxData.h >index 89170374b34b084146d06398f65d059cd4d82cfd..7b00e60877562feafd1f7b4ed9ab0904cb4b40b4 100644 >--- a/Source/WebCore/rendering/style/StyleBoxData.h >+++ b/Source/WebCore/rendering/style/StyleBoxData.h >@@ -31,7 +31,9 @@ > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleBoxData); > class StyleBoxData : public RefCounted<StyleBoxData> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleBoxData); > public: > static Ref<StyleBoxData> create() { return adoptRef(*new StyleBoxData); } > Ref<StyleBoxData> copy() const; >diff --git a/Source/WebCore/rendering/style/StyleInheritedData.cpp b/Source/WebCore/rendering/style/StyleInheritedData.cpp >index a5e357ee93123f12d7426f07300675a121fab557..c901f1ed84a541211f38041c0e823b0cd7b87410 100644 >--- a/Source/WebCore/rendering/style/StyleInheritedData.cpp >+++ b/Source/WebCore/rendering/style/StyleInheritedData.cpp >@@ -26,6 +26,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleInheritedData); >+ > StyleInheritedData::StyleInheritedData() > : horizontalBorderSpacing(RenderStyle::initialHorizontalBorderSpacing()) > , verticalBorderSpacing(RenderStyle::initialVerticalBorderSpacing()) >diff --git a/Source/WebCore/rendering/style/StyleInheritedData.h b/Source/WebCore/rendering/style/StyleInheritedData.h >index d6555835ac8e0930506055dfc8b19a2889280166..555b0ce1f7b7c107f5ea093f26a7ab2eca45d6cf 100644 >--- a/Source/WebCore/rendering/style/StyleInheritedData.h >+++ b/Source/WebCore/rendering/style/StyleInheritedData.h >@@ -30,7 +30,9 @@ > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleInheritedData); > class StyleInheritedData : public RefCounted<StyleInheritedData> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleInheritedData); > public: > static Ref<StyleInheritedData> create() { return adoptRef(*new StyleInheritedData); } > Ref<StyleInheritedData> copy() const; >diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp >index 899873da3b32f316317313292ade8fdaed04a749..a1bdb0a8fca903f3e497600412bf4ee992daf4b8 100644 >--- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp >+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp >@@ -77,6 +77,8 @@ struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<Greater > > COMPILE_ASSERT(sizeof(StyleRareInheritedData) <= sizeof(GreaterThanOrSameSizeAsStyleRareInheritedData), StyleRareInheritedData_should_bit_pack); > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleRareInheritedData); >+ > StyleRareInheritedData::StyleRareInheritedData() > : listStyleImage(RenderStyle::initialListStyleImage()) > , textStrokeWidth(RenderStyle::initialTextStrokeWidth()) >diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.h b/Source/WebCore/rendering/style/StyleRareInheritedData.h >index a0332d8d857280924941652269150f2813673ec7..380c73b755ee92763ee29c1159a873882a129c66 100644 >--- a/Source/WebCore/rendering/style/StyleRareInheritedData.h >+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.h >@@ -52,7 +52,9 @@ class StyleImage; > // This struct is for rarely used inherited CSS3, CSS2, and WebKit-specific properties. > // By grouping them together, we save space, and only allocate this object when someone > // actually uses one of these properties. >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleRareInheritedData); > class StyleRareInheritedData : public RefCounted<StyleRareInheritedData> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleRareInheritedData); > public: > static Ref<StyleRareInheritedData> create() { return adoptRef(*new StyleRareInheritedData); } > Ref<StyleRareInheritedData> copy() const; >diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp >index e560a925bcfa9291f75bacfd6e520ef8b6c1a66b..7a434fa402126385e1da49b134a08502e786b9aa 100644 >--- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp >+++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp >@@ -37,6 +37,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleRareNonInheritedData); >+ > StyleRareNonInheritedData::StyleRareNonInheritedData() > : opacity(RenderStyle::initialOpacity()) > , aspectRatioDenominator(RenderStyle::initialAspectRatioDenominator()) >diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h >index 395849215baec6208a9dda9fd52e194b21d7c238..3842f4d06bd93779a576ce6256cdb8bfa83fd5e2 100644 >--- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h >+++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h >@@ -75,7 +75,9 @@ enum PageSizeType { > // This struct is for rarely used non-inherited CSS3, CSS2, and WebKit-specific properties. > // By grouping them together, we save space, and only allocate this object when someone > // actually uses one of these properties. >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleRareNonInheritedData); > class StyleRareNonInheritedData : public RefCounted<StyleRareNonInheritedData> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleRareNonInheritedData); > public: > static Ref<StyleRareNonInheritedData> create() { return adoptRef(*new StyleRareNonInheritedData); } > Ref<StyleRareNonInheritedData> copy() const; >diff --git a/Source/WebCore/rendering/style/StyleSurroundData.cpp b/Source/WebCore/rendering/style/StyleSurroundData.cpp >index 5c9bbdbecd4696806742608334012bc4af2af053..06b9297c155603959842cf9016558832d2000b62 100644 >--- a/Source/WebCore/rendering/style/StyleSurroundData.cpp >+++ b/Source/WebCore/rendering/style/StyleSurroundData.cpp >@@ -24,6 +24,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleSurroundData); >+ > StyleSurroundData::StyleSurroundData() > : margin(Fixed) > , padding(Fixed) >diff --git a/Source/WebCore/rendering/style/StyleSurroundData.h b/Source/WebCore/rendering/style/StyleSurroundData.h >index 1f618a04486446d7b0a0f8c0736aa77a02b69ab9..085a5f7f5b0d9cfb35c21faa211eeed8c31e9eee 100644 >--- a/Source/WebCore/rendering/style/StyleSurroundData.h >+++ b/Source/WebCore/rendering/style/StyleSurroundData.h >@@ -31,7 +31,9 @@ > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleSurroundData); > class StyleSurroundData : public RefCounted<StyleSurroundData> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleSurroundData); > public: > static Ref<StyleSurroundData> create() { return adoptRef(*new StyleSurroundData); } > Ref<StyleSurroundData> copy() const; >diff --git a/Source/WebCore/rendering/style/StyleTransformData.cpp b/Source/WebCore/rendering/style/StyleTransformData.cpp >index eba3222d4740d9e3c319bda8c8049d45586f6040..8d6f8094786c176368d57906e232305f11441117 100644 >--- a/Source/WebCore/rendering/style/StyleTransformData.cpp >+++ b/Source/WebCore/rendering/style/StyleTransformData.cpp >@@ -26,6 +26,8 @@ > > namespace WebCore { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(StyleTransformData); >+ > StyleTransformData::StyleTransformData() > : operations(RenderStyle::initialTransform()) > , x(RenderStyle::initialTransformOriginX()) >diff --git a/Source/WebCore/rendering/style/StyleTransformData.h b/Source/WebCore/rendering/style/StyleTransformData.h >index a36c9fad6b4a5309fafae087ba3f0fc600270850..8ae557cca11bdc7ca324535754d005d6399c5247 100644 >--- a/Source/WebCore/rendering/style/StyleTransformData.h >+++ b/Source/WebCore/rendering/style/StyleTransformData.h >@@ -32,7 +32,9 @@ > > namespace WebCore { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(StyleTransformData); > class StyleTransformData : public RefCounted<StyleTransformData> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(StyleTransformData); > public: > static Ref<StyleTransformData> create() { return adoptRef(*new StyleTransformData); } > Ref<StyleTransformData> copy() const; >diff --git a/Source/WebCore/style/StyleInvalidationFunctions.h b/Source/WebCore/style/StyleInvalidationFunctions.h >index 02ffd4064cfc5ab1759303c30054dff1a9cf8b82..b0a4001a78757e8dc2f2004b101451a3eba9510b 100644 >--- a/Source/WebCore/style/StyleInvalidationFunctions.h >+++ b/Source/WebCore/style/StyleInvalidationFunctions.h >@@ -42,7 +42,7 @@ inline void traverseRuleFeaturesInShadowTree(Element& element, TraverseFunction& > auto& shadowRuleSets = element.shadowRoot()->styleScope().resolver().ruleSets(); > auto& authorStyle = shadowRuleSets.authorStyle(); > bool hasHostPseudoClassRulesMatchingInShadowTree = authorStyle.hasHostPseudoClassRulesMatchingInShadowTree(); >- if (authorStyle.hostPseudoClassRules().isEmpty() && !hasHostPseudoClassRulesMatchingInShadowTree) >+ if (authorStyle.hostPseudoClassRules().data.isEmpty() && !hasHostPseudoClassRulesMatchingInShadowTree) > return; > function(shadowRuleSets.features(), hasHostPseudoClassRulesMatchingInShadowTree); > } >@@ -53,7 +53,7 @@ inline void traverseRuleFeaturesForSlotted(Element& element, TraverseFunction&& > auto assignedShadowRoots = assignedShadowRootsIfSlotted(element); > for (auto& assignedShadowRoot : assignedShadowRoots) { > auto& ruleSets = assignedShadowRoot->styleScope().resolver().ruleSets(); >- if (ruleSets.authorStyle().slottedPseudoElementRules().isEmpty()) >+ if (ruleSets.authorStyle().slottedPseudoElementRules().data.isEmpty()) > continue; > function(ruleSets.features(), false); > } >@@ -67,7 +67,7 @@ inline void traverseRuleFeatures(Element& element, TraverseFunction&& function) > auto mayAffectShadowTree = [&] { > if (element.shadowRoot() && ruleSets.authorStyle().hasShadowPseudoElementRules()) > return true; >- if (is<HTMLSlotElement>(element) && !ruleSets.authorStyle().slottedPseudoElementRules().isEmpty()) >+ if (is<HTMLSlotElement>(element) && !ruleSets.authorStyle().slottedPseudoElementRules().data.isEmpty()) > return true; > return false; > }; >diff --git a/Source/WebCore/style/StyleInvalidator.cpp b/Source/WebCore/style/StyleInvalidator.cpp >index dae11cb2f6289918453a12809ae43b8124b6b12b..29f866fce37e7bf13eb8d818819d4405e79a6a44 100644 >--- a/Source/WebCore/style/StyleInvalidator.cpp >+++ b/Source/WebCore/style/StyleInvalidator.cpp >@@ -106,7 +106,7 @@ Invalidator::CheckDescendants Invalidator::invalidateIfNeeded(Element& element, > element.invalidateStyleForSubtreeInternal(); > } > >- bool shouldCheckForSlots = !m_ruleSet.slottedPseudoElementRules().isEmpty() && !m_didInvalidateHostChildren; >+ bool shouldCheckForSlots = !m_ruleSet.slottedPseudoElementRules().data.isEmpty() && !m_didInvalidateHostChildren; > if (shouldCheckForSlots && is<HTMLSlotElement>(element)) { > auto* containingShadowRoot = element.containingShadowRoot(); > if (containingShadowRoot && containingShadowRoot->host()) { >@@ -192,7 +192,7 @@ void Invalidator::invalidateStyle(ShadowRoot& shadowRoot) > { > ASSERT(!m_dirtiesAllStyle); > >- if (!m_ruleSet.hostPseudoClassRules().isEmpty() && shadowRoot.host()) >+ if (!m_ruleSet.hostPseudoClassRules().data.isEmpty() && shadowRoot.host()) > shadowRoot.host()->invalidateStyleInternal(); > > for (auto& child : childrenOfType<Element>(shadowRoot)) { >diff --git a/Source/WebCore/style/StyleScope.cpp b/Source/WebCore/style/StyleScope.cpp >index a4fe9a2586278cd5731c67bfde7dbe241ee1d306..4009d5404e4c5f90cbae6408cf8075f4b9d2c728 100644 >--- a/Source/WebCore/style/StyleScope.cpp >+++ b/Source/WebCore/style/StyleScope.cpp >@@ -456,10 +456,10 @@ static void filterEnabledNonemptyCSSStyleSheets(Vector<RefPtr<CSSStyleSheet>>& r > static void invalidateHostAndSlottedStyleIfNeeded(ShadowRoot& shadowRoot, StyleResolver& resolver) > { > auto& host = *shadowRoot.host(); >- if (!resolver.ruleSets().authorStyle().hostPseudoClassRules().isEmpty()) >+ if (!resolver.ruleSets().authorStyle().hostPseudoClassRules().data.isEmpty()) > host.invalidateStyle(); > >- if (!resolver.ruleSets().authorStyle().slottedPseudoElementRules().isEmpty()) { >+ if (!resolver.ruleSets().authorStyle().slottedPseudoElementRules().data.isEmpty()) { > for (auto& shadowChild : childrenOfType<Element>(host)) > shadowChild.invalidateStyle(); > } >diff --git a/Source/WebCore/style/StyleSharingResolver.cpp b/Source/WebCore/style/StyleSharingResolver.cpp >index 1052aa6feeb3ac322a71aa226a9c66ed8ca68ed3..c83f9a253838285e43b7de48a7796bd446500fd0 100644 >--- a/Source/WebCore/style/StyleSharingResolver.cpp >+++ b/Source/WebCore/style/StyleSharingResolver.cpp >@@ -99,7 +99,7 @@ std::unique_ptr<RenderStyle> SharingResolver::resolve(const Element& searchEleme > return nullptr; > if (elementHasDirectionAuto(element)) > return nullptr; >- if (element.shadowRoot() && !element.shadowRoot()->styleScope().resolver().ruleSets().authorStyle().hostPseudoClassRules().isEmpty()) >+ if (element.shadowRoot() && !element.shadowRoot()->styleScope().resolver().ruleSets().authorStyle().hostPseudoClassRules().data.isEmpty()) > return nullptr; > > Context context { >@@ -289,7 +289,7 @@ bool SharingResolver::canShareStyleWithElement(const Context& context, const Sty > if (candidateElement.matchesDefaultPseudoClass() != element.matchesDefaultPseudoClass()) > return false; > >- if (candidateElement.shadowRoot() && !candidateElement.shadowRoot()->styleScope().resolver().ruleSets().authorStyle().hostPseudoClassRules().isEmpty()) >+ if (candidateElement.shadowRoot() && !candidateElement.shadowRoot()->styleScope().resolver().ruleSets().authorStyle().hostPseudoClassRules().data.isEmpty()) > return false; > > #if ENABLE(FULLSCREEN_API) >diff --git a/Source/WebCore/style/StyleTreeResolver.cpp b/Source/WebCore/style/StyleTreeResolver.cpp >index 34edb5387d45d652527fad4ec881c5e0daed044c..c4543bccd924b231a6e0e7be5336fa58a7a4222d 100644 >--- a/Source/WebCore/style/StyleTreeResolver.cpp >+++ b/Source/WebCore/style/StyleTreeResolver.cpp >@@ -58,6 +58,8 @@ namespace WebCore { > > namespace Style { > >+DEFINE_DEBUG_HEAP_ALLOCATOR(TreeResolverScope); >+ > TreeResolver::TreeResolver(Document& document) > : m_document(document) > { >diff --git a/Source/WebCore/style/StyleTreeResolver.h b/Source/WebCore/style/StyleTreeResolver.h >index 899a9f68ea651f9fc340e8c25a1b89e37ad1add9..dcfd3347728dd81275fcd6d71df520769f5a9b71 100644 >--- a/Source/WebCore/style/StyleTreeResolver.h >+++ b/Source/WebCore/style/StyleTreeResolver.h >@@ -44,6 +44,7 @@ class StyleResolver; > > namespace Style { > >+DECLARE_DEBUG_HEAP_ALLOCATOR(TreeResolverScope); > class TreeResolver { > public: > TreeResolver(Document&); >@@ -62,6 +63,7 @@ class TreeResolver { > ElementUpdate resolvePseudoStyle(Element&, const ElementUpdate&, PseudoId); > > struct Scope : RefCounted<Scope> { >+ WTF_MAKE_STRUCT_FAST_ALLOCATED_FROM_DEBUG_HEAP(TreeResolverScope); > StyleResolver& styleResolver; > SelectorFilter selectorFilter; > SharingResolver sharingResolver; >diff --git a/Source/WebCore/svg/animation/SMILTimeContainer.cpp b/Source/WebCore/svg/animation/SMILTimeContainer.cpp >index e0423ce9815fa0f25563a3b54314086ac356ff44..0e6b980c4184d15aca77093e9139470e28045363 100644 >--- a/Source/WebCore/svg/animation/SMILTimeContainer.cpp >+++ b/Source/WebCore/svg/animation/SMILTimeContainer.cpp >@@ -38,6 +38,8 @@ namespace WebCore { > static const Seconds SMILAnimationFrameDelay { 1_s / 60. }; > static const Seconds SMILAnimationFrameThrottledDelay { 1_s / 30. }; > >+DEFINE_DEBUG_HEAP_ALLOCATOR(SMILTimeContainer); >+ > SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) > : m_timer(*this, &SMILTimeContainer::timerFired) > , m_ownerSVGElement(owner) >diff --git a/Source/WebCore/svg/animation/SMILTimeContainer.h b/Source/WebCore/svg/animation/SMILTimeContainer.h >index d8fc4f805ad99c618df3bb58baf9ba46c82c9ae1..972c14f404cdc3a43a18c5c46bed564e9e13c97f 100644 >--- a/Source/WebCore/svg/animation/SMILTimeContainer.h >+++ b/Source/WebCore/svg/animation/SMILTimeContainer.h >@@ -39,7 +39,9 @@ class SVGElement; > class SVGSMILElement; > class SVGSVGElement; > >+DECLARE_DEBUG_HEAP_ALLOCATOR(SMILTimeContainer); > class SMILTimeContainer final : public RefCounted<SMILTimeContainer> { >+ WTF_MAKE_FAST_ALLOCATED_FROM_DEBUG_HEAP(SMILTimeContainer); > public: > static Ref<SMILTimeContainer> create(SVGSVGElement& owner) { return adoptRef(*new SMILTimeContainer(owner)); } > ~SMILTimeContainer(); >diff --git a/Source/WebKit/Shared/ShareableBitmap.cpp b/Source/WebKit/Shared/ShareableBitmap.cpp >index 8fc5ad6c1b29a92c2cfa58cf312848f116e1b991..388c96caf3016f189e41a9bc0265fbb2b70ce0d0 100644 >--- a/Source/WebKit/Shared/ShareableBitmap.cpp >+++ b/Source/WebKit/Shared/ShareableBitmap.cpp >@@ -29,10 +29,14 @@ > #include "SharedMemory.h" > #include "WebCoreArgumentCoders.h" > #include <WebCore/GraphicsContext.h> >+#include <wtf/DebugHeap.h> > > namespace WebKit { > using namespace WebCore; >- >+ >+DECLARE_DEBUG_HEAP_ALLOCATOR(ShareableBitmap); >+DEFINE_DEBUG_HEAP_ALLOCATOR(ShareableBitmap); >+ > ShareableBitmap::Handle::Handle() > { > } >@@ -88,9 +92,9 @@ RefPtr<ShareableBitmap> ShareableBitmap::create(const IntSize& size, Configurati > return nullptr; > > void* data = 0; >- if (!tryFastMalloc(numBytes.unsafeGet()).getValue(data)) >+ data = ShareableBitmapMalloc::tryMalloc(numBytes.unsafeGet()); >+ if (!data) > return nullptr; >- > return adoptRef(new ShareableBitmap(size, configuration, data)); > } > >@@ -161,7 +165,7 @@ ShareableBitmap::ShareableBitmap(const IntSize& size, Configuration configuratio > ShareableBitmap::~ShareableBitmap() > { > if (!isBackedBySharedMemory()) >- fastFree(m_data); >+ ShareableBitmapMalloc::free(m_data); > } > > void* ShareableBitmap::data() const >diff --git a/Source/WebKit/UIProcess/mac/LegacySessionStateCoding.cpp b/Source/WebKit/UIProcess/mac/LegacySessionStateCoding.cpp >index ea6c3777e50136cca586c3740c7ca4b2966e9943..9990fedda06e4ae05bf237d47d87ce998a2a51e9 100644 >--- a/Source/WebKit/UIProcess/mac/LegacySessionStateCoding.cpp >+++ b/Source/WebKit/UIProcess/mac/LegacySessionStateCoding.cpp >@@ -68,12 +68,24 @@ static const uint32_t maximumSessionStateDataSize = std::numeric_limits<uint32_t > > template<typename T> void isValidEnum(T); > >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+static WTF::DebugHeap& debugHeap() >+{ >+ static NeverDestroyed<WTF::DebugHeap> heap = WTF::DebugHeap("WebKit HistoryEntryDataEncoder"); >+ return heap; >+} >+#endif >+ > class HistoryEntryDataEncoder { > public: > HistoryEntryDataEncoder() > : m_bufferSize(0) > , m_bufferCapacity(512) >- , m_buffer(MallocPtr<uint8_t>::malloc(m_bufferCapacity)) >+ , m_buffer(MallocPtr<uint8_t>::malloc(m_bufferCapacity >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , debugHeap() >+#endif >+ )) > , m_bufferPointer(m_buffer.get()) > { > // Keep format compatibility by encoding an unused uint64_t here. >@@ -505,7 +517,11 @@ RefPtr<API::Data> encodeLegacySessionState(const SessionState& sessionState) > CFIndex length = CFDataGetLength(data.get()); > > size_t bufferSize = length + sizeof(uint32_t); >- auto buffer = MallocPtr<uint8_t>::malloc(bufferSize); >+ auto buffer = MallocPtr<uint8_t>::malloc(bufferSize >+#if ENABLE(MALLOC_HEAP_BREAKDOWN) >+ , debugHeap() >+#endif >+ ); > > // Put the session state version number at the start of the buffer > buffer.get()[0] = (sessionStateDataVersion & 0xff000000) >> 24; >diff --git a/Source/bmalloc/bmalloc/BPlatform.h b/Source/bmalloc/bmalloc/BPlatform.h >index f7a4af43d3eb8291f9482f50594f142926ce303d..5e2a75d995e22ded359d7d981d3897f33569bf50 100644 >--- a/Source/bmalloc/bmalloc/BPlatform.h >+++ b/Source/bmalloc/bmalloc/BPlatform.h >@@ -245,6 +245,9 @@ > #define BUNUSED_PARAM(variable) (void)variable > #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. */ >+#define BENABLE_MALLOC_HEAP_BREAKDOWN 1 >+ > /* This is used for debugging when hacking on how bmalloc calculates its physical footprint. */ > #define ENABLE_PHYSICAL_PAGE_MAP 0 > >diff --git a/Source/bmalloc/bmalloc/DebugHeap.cpp b/Source/bmalloc/bmalloc/DebugHeap.cpp >index cd9910256a8cacc2d5adca27790ab11e928db1c0..4ddcaf78726032279dc0d0833e2cb77a5eb9f406 100644 >--- a/Source/bmalloc/bmalloc/DebugHeap.cpp >+++ b/Source/bmalloc/bmalloc/DebugHeap.cpp >@@ -47,8 +47,17 @@ DebugHeap::DebugHeap(std::lock_guard<Mutex>&) > malloc_set_zone_name(m_zone, "WebKit Using System Malloc"); > } > >+void DebugHeap::setZoneName(const char* name) >+{ >+ malloc_set_zone_name(m_zone, name); >+} >+ > void* DebugHeap::malloc(size_t size, bool crashOnFailure) > { >+ if (m_logMallocs && size > 1024) { >+ fprintf(stderr, "DebugHeap::malloc %lu\n", size); >+ } >+ > void* result = malloc_zone_malloc(m_zone, size); > if (!result && crashOnFailure) > BCRASH(); >@@ -57,6 +66,10 @@ void* DebugHeap::malloc(size_t size, bool crashOnFailure) > > void* DebugHeap::memalign(size_t alignment, size_t size, bool crashOnFailure) > { >+ if (m_logMallocs && size > 1024) { >+ fprintf(stderr, "DebugHeap::memalign %lu\n", size); >+ } >+ > void* result = malloc_zone_memalign(m_zone, alignment, size); > if (!result && crashOnFailure) > BCRASH(); >@@ -65,6 +78,10 @@ void* DebugHeap::memalign(size_t alignment, size_t size, bool crashOnFailure) > > void* DebugHeap::realloc(void* object, size_t size, bool crashOnFailure) > { >+ if (m_logMallocs && size > 1024) { >+ fprintf(stderr, "DebugHeap::realloc %lu\n", size); >+ } >+ > void* result = malloc_zone_realloc(m_zone, object, size); > if (!result && crashOnFailure) > BCRASH(); >@@ -143,6 +160,10 @@ void DebugHeap::dump() > > void* DebugHeap::memalignLarge(size_t alignment, size_t size) > { >+ if (size > 1024) { >+ fprintf(stderr, "DebugHeap::memalignLarge %lu\n", size); >+ } >+ > alignment = roundUpToMultipleOf(m_pageSize, alignment); > size = roundUpToMultipleOf(m_pageSize, size); > void* result = tryVMAllocate(alignment, size); >diff --git a/Source/bmalloc/bmalloc/DebugHeap.h b/Source/bmalloc/bmalloc/DebugHeap.h >index 617dd69d2c186fce331b8a9f8a26b68fb2179d25..6f7a74bc0fdc114c8b95e2b410d1b91ae7df8221 100644 >--- a/Source/bmalloc/bmalloc/DebugHeap.h >+++ b/Source/bmalloc/bmalloc/DebugHeap.h >@@ -40,6 +40,9 @@ namespace bmalloc { > class DebugHeap : private StaticPerProcess<DebugHeap> { > public: > DebugHeap(std::lock_guard<Mutex>&); >+ >+ void setZoneName(const char*); >+ void setLogMallocs(bool f) { m_logMallocs = f; } > > void* malloc(size_t, bool crashOnFailure); > void* memalign(size_t alignment, size_t, bool crashOnFailure); >@@ -62,6 +65,7 @@ class DebugHeap : private StaticPerProcess<DebugHeap> { > // This is the debug heap. We can use whatever data structures we like. It doesn't matter. > size_t m_pageSize { 0 }; > std::unordered_map<void*, size_t> m_sizeMap; >+ bool m_logMallocs { true }; > }; > DECLARE_STATIC_PER_PROCESS_STORAGE(DebugHeap); > >diff --git a/Source/bmalloc/bmalloc/Heap.cpp b/Source/bmalloc/bmalloc/Heap.cpp >index faee2d5182a4570b30af106faf6d79e79fe34304..3a6aaacc5982eaa7349f5815294ed3d6e7bf0e2d 100644 >--- a/Source/bmalloc/bmalloc/Heap.cpp >+++ b/Source/bmalloc/bmalloc/Heap.cpp >@@ -44,6 +44,34 @@ > > namespace bmalloc { > >+class PrimaryDebugHeap : public DebugHeap >+{ >+public: >+ PrimaryDebugHeap(std::lock_guard<Mutex>& mutex) >+ : DebugHeap(mutex) >+ { >+ } >+}; >+ >+class PrimitiveGigacageDebugHeap : public DebugHeap >+{ >+public: >+ PrimitiveGigacageDebugHeap(std::lock_guard<Mutex>& mutex) >+ : DebugHeap(mutex) >+ { >+ } >+}; >+ >+class JSValueGigacageDebugHeap : public DebugHeap >+{ >+public: >+ JSValueGigacageDebugHeap(std::lock_guard<Mutex>& mutex) >+ : DebugHeap(mutex) >+ { >+ } >+}; >+ >+ > Heap::Heap(HeapKind kind, std::lock_guard<Mutex>&) > : m_kind(kind) > , m_vmPageSizePhysical(vmPageSizePhysical()) >diff --git a/Source/bmalloc/bmalloc/IsoHeap.h b/Source/bmalloc/bmalloc/IsoHeap.h >index 35643e194ac2de4592f19580d400fc57999e9d9f..9c463a9fd33e9a9b91104eb198da79eeb744700d 100644 >--- a/Source/bmalloc/bmalloc/IsoHeap.h >+++ b/Source/bmalloc/bmalloc/IsoHeap.h >@@ -28,6 +28,10 @@ > #include "IsoConfig.h" > #include "Mutex.h" > >+#if BENABLE_MALLOC_HEAP_BREAKDOWN >+#include <malloc/malloc.h> >+#endif >+ > namespace bmalloc { > > template<typename Config> class IsoHeapImpl; >@@ -44,6 +48,8 @@ template<typename Type> > struct IsoHeap { > typedef IsoConfig<sizeof(Type)> Config; > >+ IsoHeap(const char*); >+ > void* allocate(); > void* tryAllocate(); > void deallocate(void* p); >@@ -64,6 +70,11 @@ struct IsoHeap { > unsigned m_allocatorOffsetPlusOne; > unsigned m_deallocatorOffsetPlusOne; > IsoHeapImpl<Config>* m_impl; >+ >+#if BENABLE_MALLOC_HEAP_BREAKDOWN >+ const char* m_heapClass; >+ malloc_zone_t* m_zone; >+#endif > }; > > // Use this together with MAKE_BISO_MALLOCED_IMPL. >diff --git a/Source/bmalloc/bmalloc/IsoHeapInlines.h b/Source/bmalloc/bmalloc/IsoHeapInlines.h >index b0e8b988ef369af8ccf297bb5b8eda544f98ff75..50d7ef55e899a8d6addc8ccd76ea6dfdbbea6835 100644 >--- a/Source/bmalloc/bmalloc/IsoHeapInlines.h >+++ b/Source/bmalloc/bmalloc/IsoHeapInlines.h >@@ -43,6 +43,17 @@ > > namespace bmalloc { namespace api { > >+template<typename Type> >+IsoHeap<Type>::IsoHeap(const char* heapClass) >+#if BENABLE_MALLOC_HEAP_BREAKDOWN >+ : m_zone(malloc_create_zone(0, 0)) >+#endif >+{ >+#if BENABLE_MALLOC_HEAP_BREAKDOWN >+ malloc_set_zone_name(m_zone, heapClass); >+#endif >+} >+ > template<typename Type> > void* IsoHeap<Type>::allocate() > { >@@ -89,7 +100,7 @@ auto IsoHeap<Type>::impl() -> IsoHeapImpl<Config>& > public: \ > static ::bmalloc::api::IsoHeap<isoType>& bisoHeap() \ > { \ >- static ::bmalloc::api::IsoHeap<isoType> heap; \ >+ static ::bmalloc::api::IsoHeap<isoType> heap("WebKit_"#isoType); \ > return heap; \ > } \ > \ >@@ -115,7 +126,7 @@ typedef int __makeBisoMallocedInlineMacroSemicolonifier > #define MAKE_BISO_MALLOCED_IMPL(isoType) \ > ::bmalloc::api::IsoHeap<isoType>& isoType::bisoHeap() \ > { \ >- static ::bmalloc::api::IsoHeap<isoType> heap; \ >+ static ::bmalloc::api::IsoHeap<isoType> heap("WebKit "#isoType); \ > return heap; \ > } \ > \ >@@ -136,7 +147,7 @@ struct MakeBisoMallocedImplMacroSemicolonifier##isoType { } > template<> \ > ::bmalloc::api::IsoHeap<isoType>& isoType::bisoHeap() \ > { \ >- static ::bmalloc::api::IsoHeap<isoType> heap; \ >+ static ::bmalloc::api::IsoHeap<isoType> heap("WebKit_"#isoType); \ > return heap; \ > } \ > \ >diff --git a/Source/bmalloc/bmalloc/IsoTLSInlines.h b/Source/bmalloc/bmalloc/IsoTLSInlines.h >index 1d14b7af686411d7856872b96c0fc25c8179c14f..783daa209f03bea31cfc9e3e8c194b761322270b 100644 >--- a/Source/bmalloc/bmalloc/IsoTLSInlines.h >+++ b/Source/bmalloc/bmalloc/IsoTLSInlines.h >@@ -30,6 +30,10 @@ > #include "IsoTLS.h" > #include "bmalloc.h" > >+#if BOS(DARWIN) >+#include <malloc/malloc.h> >+#endif >+ > namespace bmalloc { > > template<typename Type> >@@ -88,7 +92,11 @@ BNO_INLINE void* IsoTLS::allocateSlow(api::IsoHeap<Type>& handle, bool abortOnFa > determineMallocFallbackState(); > continue; > case MallocFallbackState::FallBackToMalloc: >+#if BENABLE_MALLOC_HEAP_BREAKDOWN >+ return malloc_zone_malloc(handle.m_zone, Config::objectSize); >+#else > return api::tryMalloc(Config::objectSize); >+#endif > case MallocFallbackState::DoNotFallBack: > break; > } >@@ -131,7 +139,11 @@ BNO_INLINE void IsoTLS::deallocateSlow(api::IsoHeap<Type>& handle, void* p) > determineMallocFallbackState(); > continue; > case MallocFallbackState::FallBackToMalloc: >+#if BENABLE_MALLOC_HEAP_BREAKDOWN >+ return malloc_zone_free(handle.m_zone, p); >+#else > return api::free(p); >+#endif > case MallocFallbackState::DoNotFallBack: > break; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186422
:
342237
|
342911
|
342912
|
352402
|
369931
|
369938
|
369939
|
369940
|
369941
|
370089
|
370092
|
370901
|
370923
|
370927
|
370930
|
370998
|
371234
|
371238
|
386485
|
386486
|
386487
|
386488
|
386497
|
386503
|
386506
|
386507
|
386508
|
386550
|
386632