From: commit-queue@webkit.org Date: Mon, 2 Jul 2012 14:18:25 +0000 (+0000) Subject: Web Inspector: replace recursion with a stack in DOM nodes snapshot traversal. X-Git-Tag: 070512121124~219 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=91c4e47c02a28881e515d91c58a6648b18f04216;p=profile%2Fivi%2Fwebkit-efl.git Web Inspector: replace recursion with a stack in DOM nodes snapshot traversal. https://bugs.webkit.org/show_bug.cgi?id=89889 Number of DOM nodes native snapshots can handle was limited by the process stack size because of recursion used to traverse the nodes. The patch changes the recursion to a stack based algorithm. Patch by Alexei Filippov on 2012-07-02 Reviewed by Yury Semikhatsky. * dom/MemoryInstrumentation.h: (MemoryInstrumentation): (InstrumentedPointerBase): (WebCore::MemoryInstrumentation::InstrumentedPointerBase::~InstrumentedPointerBase): (InstrumentedPointer): (WebCore::MemoryInstrumentation::InstrumentedPointer::InstrumentedPointer): (WebCore::MemoryInstrumentation::reportInstrumentedPointer): (WebCore): (WebCore::::process): * inspector/InspectorMemoryAgent.cpp: (WebCore): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121677 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 850c7c0..cc0c957 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,26 @@ +2012-07-02 Alexei Filippov + + Web Inspector: replace recursion with a stack in DOM nodes snapshot traversal. + https://bugs.webkit.org/show_bug.cgi?id=89889 + + Number of DOM nodes native snapshots can handle was limited + by the process stack size because of recursion used to traverse the nodes. + The patch changes the recursion to a stack based algorithm. + + Reviewed by Yury Semikhatsky. + + * dom/MemoryInstrumentation.h: + (MemoryInstrumentation): + (InstrumentedPointerBase): + (WebCore::MemoryInstrumentation::InstrumentedPointerBase::~InstrumentedPointerBase): + (InstrumentedPointer): + (WebCore::MemoryInstrumentation::InstrumentedPointer::InstrumentedPointer): + (WebCore::MemoryInstrumentation::reportInstrumentedPointer): + (WebCore): + (WebCore::::process): + * inspector/InspectorMemoryAgent.cpp: + (WebCore): + 2012-07-02 Taiju Tsuiki Web Inspector: Add requestFileContent command and fileContentReceived event diff --git a/Source/WebCore/dom/MemoryInstrumentation.h b/Source/WebCore/dom/MemoryInstrumentation.h index b81f5be..50a8a6d 100644 --- a/Source/WebCore/dom/MemoryInstrumentation.h +++ b/Source/WebCore/dom/MemoryInstrumentation.h @@ -33,6 +33,7 @@ #include #include +#include #include namespace WebCore { @@ -62,11 +63,31 @@ public: } template void reportHashMap(const HashMapType&, ObjectType); +protected: + class InstrumentedPointerBase { + public: + virtual ~InstrumentedPointerBase() { } + + virtual void process(MemoryInstrumentation*) = 0; + }; + private: friend class MemoryObjectInfo; + template + class InstrumentedPointer : public InstrumentedPointerBase { + public: + explicit InstrumentedPointer(const T* pointer) : m_pointer(pointer) { } + + virtual void process(MemoryInstrumentation*) OVERRIDE; + + private: + const T* m_pointer; + }; + virtual void reportString(ObjectType, const String&) = 0; virtual void countObjectSize(ObjectType, size_t) = 0; + virtual void deferInstrumentedPointer(PassOwnPtr) = 0; virtual bool visited(const void*) = 0; }; @@ -127,9 +148,7 @@ void MemoryInstrumentation::reportInstrumentedPointer(const T* const object) { if (!object || visited(object)) return; - MemoryObjectInfo memoryObjectInfo(this); - object->reportMemoryUsage(&memoryObjectInfo); - countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize()); + deferInstrumentedPointer(adoptPtr(new InstrumentedPointer(object))); } template @@ -141,7 +160,6 @@ void MemoryInstrumentation::reportInstrumentedObject(const T& object) object.reportMemoryUsage(&memoryObjectInfo); } - template void MemoryInstrumentation::reportHashMap(const HashMapType& hashMap, ObjectType objectType) { @@ -149,6 +167,14 @@ void MemoryInstrumentation::reportHashMap(const HashMapType& hashMap, ObjectType countObjectSize(objectType, size); } +template +void MemoryInstrumentation::InstrumentedPointer::process(MemoryInstrumentation* memoryInstrumentation) +{ + MemoryObjectInfo memoryObjectInfo(memoryInstrumentation); + m_pointer->reportMemoryUsage(&memoryObjectInfo); + memoryInstrumentation->countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize()); +} + } // namespace WebCore #endif // !defined(MemoryInstrumentation_h) diff --git a/Source/WebCore/inspector/InspectorMemoryAgent.cpp b/Source/WebCore/inspector/InspectorMemoryAgent.cpp index b5fd836..ce46685 100644 --- a/Source/WebCore/inspector/InspectorMemoryAgent.cpp +++ b/Source/WebCore/inspector/InspectorMemoryAgent.cpp @@ -54,6 +54,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -456,6 +459,15 @@ public: return dom.release(); } + void processDeferredInstrumentedPointers() + { + while (!m_deferredInstrumentedPointers.isEmpty()) { + OwnPtr pointer = m_deferredInstrumentedPointers.last().release(); + m_deferredInstrumentedPointers.removeLast(); + pointer->process(this); + } + } + private: virtual void reportString(ObjectType objectType, const String& string) { @@ -464,18 +476,25 @@ private: countObjectSize(objectType, stringSize(string.impl())); } - virtual void countObjectSize(ObjectType objectType, size_t size) + virtual void countObjectSize(ObjectType objectType, size_t size) OVERRIDE { ASSERT(objectType >= 0 && objectType < LastTypeEntry); m_totalSizes[objectType] += size; } - virtual bool visited(const void* object) + virtual void deferInstrumentedPointer(PassOwnPtr pointer) OVERRIDE + { + m_deferredInstrumentedPointers.append(pointer); + } + + virtual bool visited(const void* object) OVERRIDE { return !m_visitedObjects.add(object).isNewEntry; } + size_t m_totalSizes[LastTypeEntry]; VisitedObjects& m_visitedObjects; + Vector > m_deferredInstrumentedPointers; }; class DOMTreesIterator : public NodeWrapperVisitor { @@ -486,12 +505,13 @@ public: { } - virtual void visitNode(Node* node) + virtual void visitNode(Node* node) OVERRIDE { if (node->document() && node->document()->frame() && m_page != node->document()->frame()->page()) return; m_domMemoryUsage.reportInstrumentedPointer(node); + m_domMemoryUsage.processDeferredInstrumentedPointers(); } void visitBindings()