diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/HeapSnapshotBuilder.h')
-rw-r--r-- | Source/JavaScriptCore/heap/HeapSnapshotBuilder.h | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/heap/HeapSnapshotBuilder.h b/Source/JavaScriptCore/heap/HeapSnapshotBuilder.h new file mode 100644 index 000000000..0ed85d19f --- /dev/null +++ b/Source/JavaScriptCore/heap/HeapSnapshotBuilder.h @@ -0,0 +1,140 @@ +/* + * 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. + */ + +#pragma once + +#include <functional> +#include <wtf/Lock.h> +#include <wtf/Vector.h> +#include <wtf/text/UniquedStringImpl.h> +#include <wtf/text/WTFString.h> + +namespace JSC { + +class HeapProfiler; +class HeapSnapshot; +class JSCell; + +struct HeapSnapshotNode { + HeapSnapshotNode(JSCell* cell, unsigned identifier) + : cell(cell) + , identifier(identifier) + { } + + JSCell* cell; + unsigned identifier; +}; + +enum class EdgeType : uint8_t { + Internal, // Normal strong reference. No name. + Property, // Named property. In `object.property` the name is "property" + Index, // Indexed property. In `array[0]` name is index "0". + Variable, // Variable held by a scope. In `let x, f=() => x++` name is "x" in f's captured scope. + // FIXME: <https://webkit.org/b/154934> Heap Snapshot should include "Weak" edges +}; + +struct HeapSnapshotEdge { + HeapSnapshotEdge(JSCell* fromCell, JSCell* toCell) + : type(EdgeType::Internal) + { + from.cell = fromCell; + to.cell = toCell; + } + + HeapSnapshotEdge(JSCell* fromCell, JSCell* toCell, EdgeType type, UniquedStringImpl* name) + : type(type) + { + ASSERT(type == EdgeType::Property || type == EdgeType::Variable); + from.cell = fromCell; + to.cell = toCell; + u.name = name; + } + + HeapSnapshotEdge(JSCell* fromCell, JSCell* toCell, uint32_t index) + : type(EdgeType::Index) + { + from.cell = fromCell; + to.cell = toCell; + u.index = index; + } + + union { + JSCell *cell; + unsigned identifier; + } from; + + union { + JSCell *cell; + unsigned identifier; + } to; + + union { + UniquedStringImpl* name; + uint32_t index; + } u; + + EdgeType type; +}; + +class JS_EXPORT_PRIVATE HeapSnapshotBuilder { + WTF_MAKE_FAST_ALLOCATED; +public: + HeapSnapshotBuilder(HeapProfiler&); + ~HeapSnapshotBuilder(); + + static unsigned nextAvailableObjectIdentifier; + static unsigned getNextObjectIdentifier(); + static void resetNextAvailableObjectIdentifier(); + + // Performs a garbage collection that builds a snapshot of all live cells. + void buildSnapshot(); + + // A marked cell. + void appendNode(JSCell*); + + // A reference from one cell to another. + void appendEdge(JSCell* from, JSCell* to); + void appendPropertyNameEdge(JSCell* from, JSCell* to, UniquedStringImpl* propertyName); + void appendVariableNameEdge(JSCell* from, JSCell* to, UniquedStringImpl* variableName); + void appendIndexEdge(JSCell* from, JSCell* to, uint32_t index); + + String json(); + String json(std::function<bool (const HeapSnapshotNode&)> allowNodeCallback); + +private: + // Finalized snapshots are not modified during building. So searching them + // for an existing node can be done concurrently without a lock. + bool hasExistingNodeForCell(JSCell*); + + HeapProfiler& m_profiler; + + // SlotVisitors run in parallel. + Lock m_buildingNodeMutex; + std::unique_ptr<HeapSnapshot> m_snapshot; + Lock m_buildingEdgeMutex; + Vector<HeapSnapshotEdge> m_edges; +}; + +} // namespace JSC |