Chromium Code Reviews| Index: third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp |
| diff --git a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp |
| index 6ded783a981de097db3e6563388ac6f197bae47a..2596482954ad967612566ecaf5c798d76fb613e5 100644 |
| --- a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp |
| +++ b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp |
| @@ -148,6 +148,99 @@ class MinorGCUnmodifiedWrapperVisitor : public v8::PersistentHandleVisitor { |
| v8::Isolate* m_isolate; |
| }; |
| +class HeapSnaphotWrapperVisitor : public ScriptWrappableVisitor { |
| + public: |
| + explicit HeapSnaphotWrapperVisitor(v8::Isolate* isolate) |
| + : ScriptWrappableVisitor(isolate) {} |
| + |
| + // Trace through the blink heap to find all V8 wrappers reachable from |
| + // ActiveScriptWrappables. |
| + WTF::HashSet<const v8::PersistentBase<v8::Value>*> findPendingWrappers() { |
| + m_foundV8Wrappers.clear(); |
| + |
| + TracePrologue(); |
| + ActiveScriptWrappableBase::traceActiveScriptWrappables(m_isolate, this); |
| + AdvanceTracing( |
| + 0, |
| + v8::EmbedderHeapTracer::AdvanceTracingActions( |
| + v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION)); |
| + // Abort instead of Epilogue as we want to finish synchronously. |
| + AbortTracing(); |
| + |
| + return std::move(m_foundV8Wrappers); |
| + } |
| + |
| + // Trace through the blink heap to find all V8 wrappers reachable from |
| + // |traceable|. |
| + WTF::HashSet<const v8::PersistentBase<v8::Value>*> |
| + findV8WrappersReachableFrom(ScriptWrappable* traceable) { |
| + m_foundV8Wrappers.clear(); |
| + |
| + TracePrologue(); |
| + traceable->wrapperTypeInfo()->traceWrappers(this, traceable); |
| + AdvanceTracing( |
| + 0, |
| + v8::EmbedderHeapTracer::AdvanceTracingActions( |
| + v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION)); |
| + // Abort instead of Epilogue as we want to finish synchronously. |
| + AbortTracing(); |
| + |
| + return std::move(m_foundV8Wrappers); |
| + } |
| + |
| + void markWrapper(const v8::PersistentBase<v8::Value>* value) const override { |
| + if (!m_tracingInProgress || m_foundV8Wrappers.contains(value)) |
| + return; |
| + m_foundV8Wrappers.add(value); |
| + } |
| + |
| + private: |
| + mutable WTF::HashSet<const v8::PersistentBase<v8::Value>*> m_foundV8Wrappers; |
|
alph
2017/01/12 08:59:00
I wonder why not std::unordered_set ?
Michael Lippautz
2017/01/12 12:23:19
Done. Actually I changed the API type to unodred_s
|
| +}; |
| + |
| +class HeapSnapshotHandlesVisitor : public v8::PersistentHandleVisitor { |
| + public: |
| + explicit HeapSnapshotHandlesVisitor(v8::Isolate* isolate) {} |
| + |
| + void VisitPersistentHandle(v8::Persistent<v8::Value>* value, |
| + uint16_t classId) override { |
| + // TODO: Fill m_nodesRequiringTracing. |
| + } |
| + |
| + WTF::HashSet<UntracedMember<Node>> nodesRequiringTracing() { |
| + return std::move(m_nodesRequiringTracing); |
| + } |
| + |
| + private: |
| + WTF::HashSet<UntracedMember<Node>> m_nodesRequiringTracing; |
| +}; |
| + |
| +v8::HeapProfiler::RetainerInfos V8GCController::getRetainerInfos( |
| + v8::Isolate* isolate) { |
| + v8::HeapProfiler::RetainerInfos infos; |
| + HeapSnaphotWrapperVisitor tracer(isolate); |
| + |
| + // Find wrappers for pending activities. |
| + { |
| + V8PerIsolateData::TemporaryScriptWrappableVisitorScope scope(isolate, |
| + &tracer); |
| + std::vector<const v8::PersistentBase<v8::Value>*> wrappers; |
| + for (auto& wrapper : tracer.findPendingWrappers()) { |
| + wrappers.push_back(wrapper); |
| + } |
| + infos.push_back(std::make_pair(new SuspendableObjectsInfo(wrappers.size()), |
| + std::move(wrappers))); |
| + } |
| + |
| + // Find wrappers for DOM trees. |
| + { |
| + HeapSnapshotHandlesVisitor visitor(isolate); |
| + // TODO |
| + } |
| + |
| + return infos; |
| +} |
| + |
| class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor { |
| public: |
| explicit MajorGCWrapperVisitor(v8::Isolate* isolate, |