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 <alexeif@chromium.org> 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
+2012-07-02 Alexei Filippov <alexeif@chromium.org>
+
+ 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 <tzik@chromium.org>
Web Inspector: Add requestFileContent command and fileContentReceived event
#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
namespace WebCore {
}
template <typename HashMapType> void reportHashMap(const HashMapType&, ObjectType);
+protected:
+ class InstrumentedPointerBase {
+ public:
+ virtual ~InstrumentedPointerBase() { }
+
+ virtual void process(MemoryInstrumentation*) = 0;
+ };
+
private:
friend class MemoryObjectInfo;
+ template <typename T>
+ 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<InstrumentedPointerBase>) = 0;
virtual bool visited(const void*) = 0;
};
{
if (!object || visited(object))
return;
- MemoryObjectInfo memoryObjectInfo(this);
- object->reportMemoryUsage(&memoryObjectInfo);
- countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
+ deferInstrumentedPointer(adoptPtr(new InstrumentedPointer<T>(object)));
}
template<typename T>
object.reportMemoryUsage(&memoryObjectInfo);
}
-
template<typename HashMapType>
void MemoryInstrumentation::reportHashMap(const HashMapType& hashMap, ObjectType objectType)
{
countObjectSize(objectType, size);
}
+template<typename T>
+void MemoryInstrumentation::InstrumentedPointer<T>::process(MemoryInstrumentation* memoryInstrumentation)
+{
+ MemoryObjectInfo memoryObjectInfo(memoryInstrumentation);
+ m_pointer->reportMemoryUsage(&memoryObjectInfo);
+ memoryInstrumentation->countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
+}
+
} // namespace WebCore
#endif // !defined(MemoryInstrumentation_h)
#include <wtf/ArrayBuffer.h>
#include <wtf/ArrayBufferView.h>
#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringImpl.h>
#include <wtf/text/WTFString.h>
return dom.release();
}
+ void processDeferredInstrumentedPointers()
+ {
+ while (!m_deferredInstrumentedPointers.isEmpty()) {
+ OwnPtr<InstrumentedPointerBase> pointer = m_deferredInstrumentedPointers.last().release();
+ m_deferredInstrumentedPointers.removeLast();
+ pointer->process(this);
+ }
+ }
+
private:
virtual void reportString(ObjectType objectType, const String& string)
{
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<InstrumentedPointerBase> 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<OwnPtr<InstrumentedPointerBase> > m_deferredInstrumentedPointers;
};
class DOMTreesIterator : public NodeWrapperVisitor {
{
}
- 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()