Changeset 197489 in webkit
- Timestamp:
- Mar 2, 2016 9:15:56 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 12 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r197468 r197489 444 444 heap/Heap.cpp 445 445 heap/HeapHelperPool.cpp 446 heap/HeapProfiler.cpp 447 heap/HeapSnapshot.cpp 448 heap/HeapSnapshotBuilder.cpp 446 449 heap/HeapStatistics.cpp 447 450 heap/HeapTimer.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r197485 r197489 1 2016-03-02 Joseph Pecoraro <pecoraro@apple.com> 2 3 Add ability to generate a Heap Snapshot 4 https://bugs.webkit.org/show_bug.cgi?id=154847 5 6 Reviewed by Mark Lam. 7 8 This adds HeapSnapshot, HeapSnapshotBuilder, and HeapProfiler. 9 10 HeapProfiler hangs off of the VM and holds the list of snapshots. 11 I expect to add other HeapProfiling features, such as allocation 12 tracking, to the profiler. 13 14 HeapSnapshot contains a collection of live cells and their identifiers. 15 It can point to a previous HeapSnapshot, to ensure that a cell that 16 already received an identifier maintains the same identifier across 17 multiple snapshots. When a snapshotted cell gets garbage collected, 18 the cell will be swept from the HeapSnapshot at the end of collection 19 to ensure the list contains only live cells. 20 21 When building a HeapSnapshot nodes are added in increasing node 22 identifier order. When done building, the list of nodes is complete 23 and the snapshot is finalized. At this point the nodes are sorted 24 by JSCell* address to allow for quick lookup of a JSCell*. 25 26 HeapSnapshotBuilder is where snapshotting begins. The builder 27 will initiate a specialized heap snapshotting garbage collection. 28 During this collection the builder will be notified of all marked 29 (live) cells, and connections between cells, as seen by SlotVisitors. 30 The builder can reference the previous, readonly, HeapSnapshots to 31 avoid creating new nodes for cells that have already been snapshotted. 32 When it is determined that we are visiting a live cell for the first 33 time, we give the cell a unique identifier and add it to the the 34 snapshot we are building. 35 36 Since edge data is costly, and of little long term utility, this 37 data is only held by the builder for serialization, and not stored 38 long term with the HeapSnapshot node data. 39 40 The goals of HeapSnapshotting at this time are: 41 - minimal impact on performance when not profiling the heap 42 - unique identifier for cells, so they may be identified across multiple snapshots 43 - nodes and edges to be able to construct a graph of which nodes reference/retain which other nodes 44 - node data - identifier, type (class name), size 45 - edge data - from cell, to cell, type / data (to come in a follow-up patch) 46 47 * CMakeLists.txt: 48 * JavaScriptCore.xcodeproj/project.pbxproj: 49 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: 50 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: 51 Add new files to the build. 52 53 * heap/Heap.cpp: 54 (JSC::Heap::isHeapSnapshotting): 55 (JSC::RemoveDeadHeapSnapshotNodes::RemoveDeadHeapSnapshotNodes): 56 (JSC::RemoveDeadHeapSnapshotNodes::operator()): 57 (JSC::Heap::removeDeadHeapSnapshotNodes): 58 (JSC::Heap::collectImpl): 59 After every collection, sweep dead cells from in memory snapshots. 60 61 * runtime/VM.cpp: 62 (JSC::VM::ensureHeapProfiler): 63 * runtime/VM.h: 64 (JSC::VM::heapProfiler): 65 * heap/Heap.h: 66 * heap/HeapProfiler.cpp: Added. 67 (JSC::HeapProfiler::HeapProfiler): 68 (JSC::HeapProfiler::~HeapProfiler): 69 (JSC::HeapProfiler::mostRecentSnapshot): 70 (JSC::HeapProfiler::appendSnapshot): 71 (JSC::HeapProfiler::clearSnapshots): 72 (JSC::HeapProfiler::setActiveSnapshotBuilder): 73 * heap/HeapProfiler.h: Added. 74 (JSC::HeapProfiler::vm): 75 (JSC::HeapProfiler::activeSnapshotBuilder): 76 VM and Heap can look at the profiler to determine if we are building a 77 snapshot, or the "head" snapshot to use for sweeping. 78 79 * heap/HeapSnapshot.cpp: Added. 80 (JSC::HeapSnapshot::HeapSnapshot): 81 (JSC::HeapSnapshot::~HeapSnapshot): 82 (JSC::HeapSnapshot::appendNode): 83 Add a node to the unfinalized list of new cells. 84 85 (JSC::HeapSnapshot::sweepCell): 86 (JSC::HeapSnapshot::shrinkToFit): 87 Collect a list of cells for sweeping and then remove them all at once 88 in shrinkToFit. This is done to avoid thrashing of individual removes 89 that could cause many overlapping moves within the Vector. 90 91 (JSC::HeapSnapshot::finalize): 92 Sort the list, and also cache the bounding start/stop identifiers. 93 No other snapshot can contain an identifier in this range, so it will 94 improve lookup of a node from an identifier. 95 96 (JSC::HeapSnapshot::nodeForCell): 97 (JSC::HeapSnapshot::nodeForObjectIdentifier): 98 Search helpers. 99 100 * heap/HeapSnapshotBuilder.h: Added. 101 (JSC::HeapSnapshotNode::HeapSnapshotNode): 102 (JSC::HeapSnapshotEdge::HeapSnapshotEdge): 103 Node and Edge struct types the builder creates. 104 105 * heap/HeapSnapshotBuilder.cpp: Added. 106 (JSC::HeapSnapshotBuilder::getNextObjectIdentifier): 107 (JSC::HeapSnapshotBuilder::HeapSnapshotBuilder): 108 (JSC::HeapSnapshotBuilder::~HeapSnapshotBuilder): 109 (JSC::HeapSnapshotBuilder::buildSnapshot): 110 (JSC::HeapSnapshotBuilder::appendNode): 111 (JSC::HeapSnapshotBuilder::appendEdge): 112 When building the snapshot, generating the next identifier, and 113 appending to any of the lists must be guarded by a lock because 114 SlotVisitors running in parallel may be accessing the builder. 115 116 (JSC::HeapSnapshotBuilder::hasExistingNodeForCell): 117 Looking up if a node already exists in a previous snapshot can be 118 done without a lock because at this point the data is readonly. 119 120 (JSC::edgeTypeToNumber): 121 (JSC::edgeTypeToString): 122 (JSC::HeapSnapshotBuilder::json): 123 JSON serialization of a heap snapshot contains node and edge data. 124 125 * heap/SlotVisitor.h: 126 * heap/SlotVisitor.cpp: 127 (JSC::SlotVisitor::didStartMarking): 128 (JSC::SlotVisitor::reset): 129 Set/clear the active snapshot builder to know if this will be a 130 snapshotting GC or not. 131 132 (JSC::SlotVisitor::append): 133 (JSC::SlotVisitor::setMarkedAndAppendToMarkStack): 134 Inform the builder of a new node or edge. 135 136 (JSC::SlotVisitor::visitChildren): 137 Remember the current cell we are visiting so that if we need to 138 inform the builder of edges we know the "from" cell. 139 140 * jsc.cpp: 141 (SimpleObject::SimpleObject): 142 (SimpleObject::create): 143 (SimpleObject::finishCreation): 144 (SimpleObject::visitChildren): 145 (SimpleObject::createStructure): 146 (SimpleObject::hiddenValue): 147 (SimpleObject::setHiddenValue): 148 Create a new class "SimpleObject" that can be used by heap snapshotting 149 tests. It is easy to filter for this new class name and test internal 150 edge relationships created by garbage collection visiting the cell. 151 152 (functionCreateSimpleObject): 153 (functionGetHiddenValue): 154 (functionSetHiddenValue): 155 Expose methods to create and interact with a SimpleObject. 156 157 (functionGenerateHeapSnapshot): 158 Expose methods to create a heap snapshot. This currently automatically 159 turns the serialized string into a JSON object. That may change. 160 161 * tests/heapProfiler.yaml: Added. 162 * tests/heapProfiler/basic-edges.js: Added. 163 (excludeStructure): 164 * tests/heapProfiler/basic-nodes.js: Added. 165 (hasDifferentSizeNodes): 166 (hasAllInternalNodes): 167 Add tests for basic node and edge data. 168 169 * tests/heapProfiler/driver/driver.js: Added. 170 (assert): 171 (CheapHeapSnapshotNode): 172 (CheapHeapSnapshotEdge): 173 (CheapHeapSnapshotEdge.prototype.get from): 174 (CheapHeapSnapshotEdge.prototype.get to): 175 (CheapHeapSnapshot): 176 (CheapHeapSnapshot.prototype.get nodes): 177 (CheapHeapSnapshot.prototype.get edges): 178 (CheapHeapSnapshot.prototype.nodeWithIdentifier): 179 (CheapHeapSnapshot.prototype.nodesWithClassName): 180 (CheapHeapSnapshot.prototype.classNameFromTableIndex): 181 (CheapHeapSnapshot.prototype.edgeTypeFromTableIndex): 182 (createCheapHeapSnapshot): 183 (HeapSnapshotNode): 184 (HeapSnapshotEdge): 185 (HeapSnapshot): 186 (HeapSnapshot.prototype.nodesWithClassName): 187 (createHeapSnapshot): 188 Add two HeapSnapshot representations. 189 CheapHeapSnapshot creates two lists of node and edge data that 190 lazily creates objects as needed. 191 HeapSnapshot creates an object for each node and edge. This 192 is wasteful but easier to use. 193 1 194 2016-03-02 Filip Pizlo <fpizlo@apple.com> 2 195 -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
r197441 r197489 576 576 <ClCompile Include="..\heap\Heap.cpp" /> 577 577 <ClCompile Include="..\heap\HeapHelperPool.cpp" /> 578 <ClCompile Include="..\heap\HeapProfiler.cpp" /> 579 <ClCompile Include="..\heap\HeapSnapshot.cpp" /> 580 <ClCompile Include="..\heap\HeapSnapshotBuilder.cpp" /> 578 581 <ClCompile Include="..\heap\HeapStatistics.cpp" /> 579 582 <ClCompile Include="..\heap\HeapTimer.cpp" /> … … 1387 1390 <ClInclude Include="..\heap\HeapOperation.h" /> 1388 1391 <ClInclude Include="..\heap\HeapRootVisitor.h" /> 1392 <ClInclude Include="..\heap\HeapProfiler.h" /> 1393 <ClInclude Include="..\heap\HeapSnapshot.h" /> 1394 <ClInclude Include="..\heap\HeapSnapshotBuilder.h" /> 1389 1395 <ClInclude Include="..\heap\HeapStatistics.h" /> 1390 1396 <ClInclude Include="..\heap\HeapTimer.h" /> -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
r197441 r197489 295 295 <Filter>heap</Filter> 296 296 </ClCompile> 297 <ClCompile Include="..\heap\HeapProfiler.cpp"> 298 <Filter>heap</Filter> 299 </ClCompile> 300 <ClCompile Include="..\heap\HeapSnapshot.cpp"> 301 <Filter>heap</Filter> 302 </ClCompile> 303 <ClCompile Include="..\heap\HeapSnapshotBuilder.cpp"> 304 <Filter>heap</Filter> 305 </ClCompile> 297 306 <ClCompile Include="..\heap\HeapStatistics.cpp"> 298 307 <Filter>heap</Filter> … … 2367 2376 </ClInclude> 2368 2377 <ClInclude Include="..\heap\HeapRootVisitor.h"> 2378 <Filter>heap</Filter> 2379 </ClInclude> 2380 <ClInclude Include="..\heap\HeapProfiler.h"> 2381 <Filter>heap</Filter> 2382 </ClInclude> 2383 <ClInclude Include="..\heap\HeapSnapshot.h"> 2384 <Filter>heap</Filter> 2385 </ClInclude> 2386 <ClInclude Include="..\heap\HeapSnapshotBuilder.h"> 2369 2387 <Filter>heap</Filter> 2370 2388 </ClInclude> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r197441 r197489 1549 1549 A514B2C2185A684400F3C7CB /* InjectedScriptBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A514B2C0185A684400F3C7CB /* InjectedScriptBase.cpp */; }; 1550 1550 A514B2C3185A684400F3C7CB /* InjectedScriptBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A514B2C1185A684400F3C7CB /* InjectedScriptBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1551 A5311C361C77CEC500E6B1B6 /* HeapSnapshotBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A5311C351C77CEAC00E6B1B6 /* HeapSnapshotBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1552 A5311C371C77CECA00E6B1B6 /* HeapSnapshotBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5311C341C77CEAC00E6B1B6 /* HeapSnapshotBuilder.cpp */; }; 1551 1553 A532438718568335002ED692 /* InspectorBackendDispatchers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A532438118568317002ED692 /* InspectorBackendDispatchers.cpp */; }; 1552 1554 A532438818568335002ED692 /* InspectorBackendDispatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = A532438218568317002ED692 /* InspectorBackendDispatchers.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1559 1561 A5339EC71BB399A90054F005 /* InspectorHeapAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5339EC41BB399900054F005 /* InspectorHeapAgent.cpp */; }; 1560 1562 A5339EC91BB4B4600054F005 /* HeapObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = A5339EC81BB4B4510054F005 /* HeapObserver.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1563 A5398FAB1C750DA40060A963 /* HeapProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = A5398FAA1C750D950060A963 /* HeapProfiler.h */; }; 1564 A5398FAC1C750DA60060A963 /* HeapProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5398FA91C750D950060A963 /* HeapProfiler.cpp */; }; 1561 1565 A53CE08518BC1A5600BEDF76 /* ConsolePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A53CE08118BC1A5600BEDF76 /* ConsolePrototype.cpp */; }; 1562 1566 A53CE08618BC1A5600BEDF76 /* ConsolePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */; }; … … 1567 1571 A54982031891D0B00081E5B8 /* EventLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54982011891D0B00081E5B8 /* EventLoop.cpp */; }; 1568 1572 A54982041891D0B00081E5B8 /* EventLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = A54982021891D0B00081E5B8 /* EventLoop.h */; }; 1573 A54C2AB01C6544EE00A18D78 /* HeapSnapshot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54C2AAE1C6544D100A18D78 /* HeapSnapshot.cpp */; }; 1574 A54C2AB11C6544F200A18D78 /* HeapSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = A54C2AAF1C6544D100A18D78 /* HeapSnapshot.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1569 1575 A54CF2F5184EAB2400237F19 /* ScriptValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54CF2F2184EAB2400237F19 /* ScriptValue.cpp */; }; 1570 1576 A54CF2F6184EAB2400237F19 /* ScriptValue.h in Headers */ = {isa = PBXBuildFile; fileRef = A54CF2F3184EAB2400237F19 /* ScriptValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 3744 3750 A514B2C0185A684400F3C7CB /* InjectedScriptBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedScriptBase.cpp; sourceTree = "<group>"; }; 3745 3751 A514B2C1185A684400F3C7CB /* InjectedScriptBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedScriptBase.h; sourceTree = "<group>"; }; 3752 A5311C341C77CEAC00E6B1B6 /* HeapSnapshotBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapSnapshotBuilder.cpp; sourceTree = "<group>"; }; 3753 A5311C351C77CEAC00E6B1B6 /* HeapSnapshotBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapSnapshotBuilder.h; sourceTree = "<group>"; }; 3746 3754 A532438118568317002ED692 /* InspectorBackendDispatchers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorBackendDispatchers.cpp; sourceTree = "<group>"; }; 3747 3755 A532438218568317002ED692 /* InspectorBackendDispatchers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InspectorBackendDispatchers.h; sourceTree = "<group>"; }; … … 3756 3764 A5339EC51BB399900054F005 /* InspectorHeapAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorHeapAgent.h; sourceTree = "<group>"; }; 3757 3765 A5339EC81BB4B4510054F005 /* HeapObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapObserver.h; sourceTree = "<group>"; }; 3766 A5398FA91C750D950060A963 /* HeapProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapProfiler.cpp; sourceTree = "<group>"; }; 3767 A5398FAA1C750D950060A963 /* HeapProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapProfiler.h; sourceTree = "<group>"; }; 3758 3768 A53CE08118BC1A5600BEDF76 /* ConsolePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsolePrototype.cpp; sourceTree = "<group>"; }; 3759 3769 A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsolePrototype.h; sourceTree = "<group>"; }; … … 3764 3774 A54982011891D0B00081E5B8 /* EventLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventLoop.cpp; sourceTree = "<group>"; }; 3765 3775 A54982021891D0B00081E5B8 /* EventLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventLoop.h; sourceTree = "<group>"; }; 3776 A54C2AAE1C6544D100A18D78 /* HeapSnapshot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapSnapshot.cpp; sourceTree = "<group>"; }; 3777 A54C2AAF1C6544D100A18D78 /* HeapSnapshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapSnapshot.h; sourceTree = "<group>"; }; 3766 3778 A54CF2F2184EAB2400237F19 /* ScriptValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptValue.cpp; sourceTree = "<group>"; }; 3767 3779 A54CF2F3184EAB2400237F19 /* ScriptValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptValue.h; sourceTree = "<group>"; }; … … 5094 5106 A5339EC81BB4B4510054F005 /* HeapObserver.h */, 5095 5107 2A6F462517E959CE00C45C98 /* HeapOperation.h */, 5108 A5398FA91C750D950060A963 /* HeapProfiler.cpp */, 5109 A5398FAA1C750D950060A963 /* HeapProfiler.h */, 5096 5110 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */, 5111 A54C2AAE1C6544D100A18D78 /* HeapSnapshot.cpp */, 5112 A54C2AAF1C6544D100A18D78 /* HeapSnapshot.h */, 5113 A5311C341C77CEAC00E6B1B6 /* HeapSnapshotBuilder.cpp */, 5114 A5311C351C77CEAC00E6B1B6 /* HeapSnapshotBuilder.h */, 5097 5115 C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */, 5098 5116 C24D31E1161CD695002AA4DB /* HeapStatistics.h */, … … 6919 6937 996B73171BDA067F00331B84 /* ArrayConstructor.lut.h in Headers */, 6920 6938 0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */, 6939 A5311C361C77CEC500E6B1B6 /* HeapSnapshotBuilder.h in Headers */, 6921 6940 A7BDAEC917F4EA1400F6140C /* ArrayIteratorPrototype.h in Headers */, 6922 6941 996B73181BDA068000331B84 /* ArrayIteratorPrototype.lut.h in Headers */, … … 7091 7110 BC1166020E1997B4008066DD /* DateInstance.h in Headers */, 7092 7111 14A1563210966365006FA260 /* DateInstanceCache.h in Headers */, 7112 A54C2AB11C6544F200A18D78 /* HeapSnapshot.h in Headers */, 7093 7113 BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */, 7094 7114 BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */, … … 7503 7523 A1587D701B4DC14100D69849 /* IntlDateTimeFormatConstructor.h in Headers */, 7504 7524 A1587D751B4DC1C600D69849 /* IntlDateTimeFormatConstructor.lut.h in Headers */, 7525 A5398FAB1C750DA40060A963 /* HeapProfiler.h in Headers */, 7505 7526 A1587D721B4DC14100D69849 /* IntlDateTimeFormatPrototype.h in Headers */, 7506 7527 A1587D761B4DC1C600D69849 /* IntlDateTimeFormatPrototype.lut.h in Headers */, … … 8823 8844 0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */, 8824 8845 0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */, 8846 A5398FAC1C750DA60060A963 /* HeapProfiler.cpp in Sources */, 8825 8847 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */, 8826 8848 0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */, … … 8996 9018 0F2B66E617B6B5AB00A7AE3F /* JSArrayBufferPrototype.cpp in Sources */, 8997 9019 0F2B66E817B6B5AB00A7AE3F /* JSArrayBufferView.cpp in Sources */, 9020 A5311C371C77CECA00E6B1B6 /* HeapSnapshotBuilder.cpp in Sources */, 8998 9021 A7BDAECA17F4EA1400F6140C /* JSArrayIterator.cpp in Sources */, 8999 9022 1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */, … … 9248 9271 7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */, 9249 9272 2AF7382C18BBBF92008A5A37 /* StructureIDTable.cpp in Sources */, 9273 A54C2AB01C6544EE00A18D78 /* HeapSnapshot.cpp in Sources */, 9250 9274 C2F0F2D116BAEEE900187C19 /* StructureRareData.cpp in Sources */, 9251 9275 0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */, -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r195905 r197489 34 34 #include "HeapHelperPool.h" 35 35 #include "HeapIterationScope.h" 36 #include "HeapProfiler.h" 36 37 #include "HeapRootVisitor.h" 38 #include "HeapSnapshot.h" 37 39 #include "HeapStatistics.h" 38 40 #include "HeapVerifier.h" … … 759 761 } 760 762 763 bool Heap::isHeapSnapshotting() const 764 { 765 HeapProfiler* heapProfiler = m_vm->heapProfiler(); 766 if (UNLIKELY(heapProfiler)) 767 return heapProfiler->activeSnapshotBuilder(); 768 return false; 769 } 770 771 struct RemoveDeadHeapSnapshotNodes : MarkedBlock::CountFunctor { 772 RemoveDeadHeapSnapshotNodes(HeapSnapshot& snapshot) 773 : m_snapshot(snapshot) 774 { 775 } 776 777 IterationStatus operator()(JSCell* cell) 778 { 779 m_snapshot.sweepCell(cell); 780 return IterationStatus::Continue; 781 } 782 783 HeapSnapshot& m_snapshot; 784 }; 785 786 void Heap::removeDeadHeapSnapshotNodes() 787 { 788 GCPHASE(RemoveDeadHeapSnapshotNodes); 789 HeapProfiler* heapProfiler = m_vm->heapProfiler(); 790 if (UNLIKELY(heapProfiler)) { 791 if (HeapSnapshot* snapshot = heapProfiler->mostRecentSnapshot()) { 792 HeapIterationScope heapIterationScope(*this); 793 RemoveDeadHeapSnapshotNodes functor(*snapshot); 794 m_objectSpace.forEachDeadCell(heapIterationScope, functor); 795 snapshot->shrinkToFit(); 796 } 797 } 798 } 799 761 800 void Heap::visitProtectedObjects(HeapRootVisitor& heapRootVisitor) 762 801 { … … 1125 1164 deleteUnmarkedCompiledCode(); 1126 1165 deleteSourceProviderCaches(); 1166 removeDeadHeapSnapshotNodes(); 1127 1167 notifyIncrementalSweeper(); 1128 1168 writeBarrierCurrentlyExecutingCodeBlocks(); -
trunk/Source/JavaScriptCore/heap/Heap.h
r195644 r197489 164 164 bool isSafeToCollect() const { return m_isSafeToCollect; } 165 165 166 JS_EXPORT_PRIVATE bool isHeapSnapshotting() const; 167 166 168 JS_EXPORT_PRIVATE void collectAllGarbageIfNotDoneRecently(); 167 169 void collectAllGarbage() { collectAndSweep(FullCollection); } … … 328 330 void snapshotMarkedSpace(); 329 331 void deleteSourceProviderCaches(); 332 void removeDeadHeapSnapshotNodes(); 330 333 void notifyIncrementalSweeper(); 331 334 void writeBarrierCurrentlyExecutingCodeBlocks(); -
trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp
r190569 r197489 32 32 #include "CopiedSpace.h" 33 33 #include "CopiedSpaceInlines.h" 34 #include "HeapProfiler.h" 35 #include "HeapSnapshotBuilder.h" 34 36 #include "JSArray.h" 35 37 #include "JSDestructibleObject.h" … … 95 97 if (heap()->operationInProgress() == FullCollection) 96 98 ASSERT(m_opaqueRoots.isEmpty()); // Should have merged by now. 99 100 if (HeapProfiler* heapProfiler = vm().heapProfiler()) 101 m_heapSnapshotBuilder = heapProfiler->activeSnapshotBuilder(); 97 102 } 98 103 … … 102 107 m_bytesCopied = 0; 103 108 m_visitCount = 0; 109 m_heapSnapshotBuilder = nullptr; 110 ASSERT(!m_currentCell); 104 111 ASSERT(m_stack.isEmpty()); 105 112 } … … 122 129 if (!value || !value.isCell()) 123 130 return; 131 132 if (m_heapSnapshotBuilder) 133 m_heapSnapshotBuilder->appendEdge(m_currentCell, value.asCell()); 134 124 135 setMarkedAndAppendToMarkStack(value.asCell()); 125 136 } … … 156 167 m_bytesVisited += MarkedBlock::blockFor(cell)->cellSize(); 157 168 m_stack.append(cell); 158 } 169 170 if (m_heapSnapshotBuilder) 171 m_heapSnapshotBuilder->appendNode(cell); 172 } 173 174 class SetCurrentCellScope { 175 public: 176 SetCurrentCellScope(SlotVisitor& visitor, const JSCell* cell) 177 : m_visitor(visitor) 178 { 179 ASSERT(!m_visitor.m_currentCell); 180 m_visitor.m_currentCell = const_cast<JSCell*>(cell); 181 } 182 183 ~SetCurrentCellScope() 184 { 185 ASSERT(m_visitor.m_currentCell); 186 m_visitor.m_currentCell = nullptr; 187 } 188 189 private: 190 SlotVisitor& m_visitor; 191 }; 192 159 193 160 194 ALWAYS_INLINE void SlotVisitor::visitChildren(const JSCell* cell) 161 195 { 162 196 ASSERT(Heap::isMarked(cell)); 197 198 SetCurrentCellScope currentCellScope(*this, cell); 163 199 164 200 m_currentObjectCellStateBeforeVisiting = cell->cellState(); -
trunk/Source/JavaScriptCore/heap/SlotVisitor.h
r196369 r197489 38 38 class GCThreadSharedData; 39 39 class Heap; 40 class HeapSnapshotBuilder; 40 41 template<typename T> class JITWriteBarrier; 41 42 class UnconditionalFinalizer; … … 48 49 WTF_MAKE_FAST_ALLOCATED; 49 50 51 friend class SetCurrentCellScope; 50 52 friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly. 51 53 friend class Heap; … … 112 114 void dump(PrintStream&) const; 113 115 116 bool isBuildingHeapSnapshot() const { return !!m_heapSnapshotBuilder; } 117 114 118 private: 115 119 friend class ParallelModeEnabler; … … 137 141 138 142 Heap& m_heap; 143 144 HeapSnapshotBuilder* m_heapSnapshotBuilder { nullptr }; 145 JSCell* m_currentCell { nullptr }; 139 146 140 147 CellState m_currentObjectCellStateBeforeVisiting { CellState::NewWhite }; -
trunk/Source/JavaScriptCore/jsc.cpp
r197261 r197489 33 33 #include "Exception.h" 34 34 #include "ExceptionHelpers.h" 35 #include "HeapProfiler.h" 36 #include "HeapSnapshotBuilder.h" 35 37 #include "HeapStatistics.h" 36 38 #include "InitializeThreading.h" … … 466 468 }; 467 469 470 class SimpleObject : public JSNonFinalObject { 471 public: 472 SimpleObject(VM& vm, Structure* structure) 473 : Base(vm, structure) 474 { 475 } 476 477 typedef JSNonFinalObject Base; 478 static const bool needsDestruction = false; 479 480 static SimpleObject* create(VM& vm, JSGlobalObject* globalObject) 481 { 482 Structure* structure = createStructure(vm, globalObject, jsNull()); 483 SimpleObject* simpleObject = new (NotNull, allocateCell<SimpleObject>(vm.heap, sizeof(SimpleObject))) SimpleObject(vm, structure); 484 simpleObject->finishCreation(vm); 485 return simpleObject; 486 } 487 488 void finishCreation(VM& vm) 489 { 490 Base::finishCreation(vm); 491 } 492 493 static void visitChildren(JSCell* cell, SlotVisitor& visitor) 494 { 495 SimpleObject* thisObject = jsCast<SimpleObject*>(cell); 496 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 497 Base::visitChildren(thisObject, visitor); 498 visitor.append(&thisObject->m_hiddenValue); 499 } 500 501 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 502 { 503 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 504 } 505 506 JSValue hiddenValue() 507 { 508 return m_hiddenValue.get(); 509 } 510 511 void setHiddenValue(VM& vm, JSValue value) 512 { 513 ASSERT(value.isCell()); 514 m_hiddenValue.set(vm, this, value); 515 } 516 517 DECLARE_INFO; 518 519 private: 520 WriteBarrier<Unknown> m_hiddenValue; 521 }; 522 523 468 524 const ClassInfo Element::s_info = { "Element", &Base::s_info, 0, CREATE_METHOD_TABLE(Element) }; 469 525 const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, 0, CREATE_METHOD_TABLE(Masquerader) }; … … 472 528 const ClassInfo CustomGetter::s_info = { "CustomGetter", &Base::s_info, 0, CREATE_METHOD_TABLE(CustomGetter) }; 473 529 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, 0, CREATE_METHOD_TABLE(RuntimeArray) }; 530 const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, 0, CREATE_METHOD_TABLE(SimpleObject) }; 474 531 475 532 ElementHandleOwner* Element::handleOwner() … … 502 559 static EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState*); 503 560 static EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState*); 561 static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState*); 562 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState*); 563 static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState*); 504 564 static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*); 505 565 static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*); … … 556 616 static EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState*); 557 617 static EncodedJSValue JSC_HOST_CALL functionPlatformSupportsSamplingProfiler(ExecState*); 618 static EncodedJSValue JSC_HOST_CALL functionGenerateHeapSnapshot(ExecState*); 558 619 #if ENABLE(SAMPLING_PROFILER) 559 620 static EncodedJSValue JSC_HOST_CALL functionStartSamplingProfiler(ExecState*); … … 709 770 addFunction(vm, "setElementRoot", functionSetElementRoot, 2); 710 771 772 addConstructableFunction(vm, "SimpleObject", functionCreateSimpleObject, 0); 773 addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1); 774 addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2); 775 711 776 putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "DFGTrue"), 0, functionFalse1, DFGTrueIntrinsic, DontEnum); 712 777 putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "OSRExit"), 0, functionUndefined1, OSRExitIntrinsic, DontEnum); … … 748 813 749 814 addFunction(vm, "platformSupportsSamplingProfiler", functionPlatformSupportsSamplingProfiler, 0); 815 addFunction(vm, "generateHeapSnapshot", functionGenerateHeapSnapshot, 0); 750 816 #if ENABLE(SAMPLING_PROFILER) 751 817 addFunction(vm, "startSamplingProfiler", functionStartSamplingProfiler, 0); … … 1134 1200 } 1135 1201 1202 EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState* exec) 1203 { 1204 JSLockHolder lock(exec); 1205 return JSValue::encode(SimpleObject::create(exec->vm(), exec->lexicalGlobalObject())); 1206 } 1207 1208 EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState* exec) 1209 { 1210 JSLockHolder lock(exec); 1211 SimpleObject* simpleObject = jsCast<SimpleObject*>(exec->argument(0).asCell()); 1212 return JSValue::encode(simpleObject->hiddenValue()); 1213 } 1214 1215 EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState* exec) 1216 { 1217 JSLockHolder lock(exec); 1218 SimpleObject* simpleObject = jsCast<SimpleObject*>(exec->argument(0).asCell()); 1219 JSValue value = exec->argument(1); 1220 simpleObject->setHiddenValue(exec->vm(), value); 1221 return JSValue::encode(jsUndefined()); 1222 } 1223 1136 1224 EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState* exec) 1137 1225 { … … 1645 1733 return JSValue::encode(JSValue(JSC::JSValue::JSFalse)); 1646 1734 #endif 1735 } 1736 1737 EncodedJSValue JSC_HOST_CALL functionGenerateHeapSnapshot(ExecState* exec) 1738 { 1739 JSLockHolder lock(exec); 1740 1741 HeapSnapshotBuilder snapshotBuilder(exec->vm().ensureHeapProfiler()); 1742 snapshotBuilder.buildSnapshot(); 1743 1744 String jsonString = snapshotBuilder.json(); 1745 EncodedJSValue result = JSValue::encode(JSONParse(exec, jsonString)); 1746 RELEASE_ASSERT(!exec->hadException()); 1747 return result; 1647 1748 } 1648 1749 -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r196308 r197489 51 51 #include "Heap.h" 52 52 #include "HeapIterationScope.h" 53 #include "HeapProfiler.h" 53 54 #include "HostCallReturnValue.h" 54 55 #include "Identifier.h" … … 444 445 } 445 446 447 HeapProfiler& VM::ensureHeapProfiler() 448 { 449 if (!m_heapProfiler) 450 m_heapProfiler = std::make_unique<HeapProfiler>(*this); 451 return *m_heapProfiler; 452 } 453 446 454 #if ENABLE(SAMPLING_PROFILER) 447 455 void VM::ensureSamplingProfiler(RefPtr<Stopwatch>&& stopwatch) -
trunk/Source/JavaScriptCore/runtime/VM.h
r196308 r197489 88 88 class TypeProfiler; 89 89 class TypeProfilerLog; 90 class HeapProfiler; 90 91 class Identifier; 91 92 class Interpreter; … … 249 250 JS_EXPORT_PRIVATE Watchdog& ensureWatchdog(); 250 251 JS_EXPORT_PRIVATE Watchdog* watchdog() { return m_watchdog.get(); } 252 253 JS_EXPORT_PRIVATE HeapProfiler* heapProfiler() const { return m_heapProfiler.get(); } 254 JS_EXPORT_PRIVATE HeapProfiler& ensureHeapProfiler(); 251 255 252 256 #if ENABLE(SAMPLING_PROFILER) … … 673 677 MallocPtr<EncodedJSValue> m_exceptionFuzzBuffer; 674 678 RefPtr<Watchdog> m_watchdog; 679 std::unique_ptr<HeapProfiler> m_heapProfiler; 675 680 #if ENABLE(SAMPLING_PROFILER) 676 681 RefPtr<SamplingProfiler> m_samplingProfiler;
Note: See TracChangeset
for help on using the changeset viewer.