Index: Source/core/dom/Node.cpp |
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp |
index 6ee07157989533cb9597f31627e14b435f3bfc4e..edb5db109c18172385a5760721b9121b41aef6e4 100644 |
--- a/Source/core/dom/Node.cpp |
+++ b/Source/core/dom/Node.cpp |
@@ -96,6 +96,9 @@ |
#include "wtf/text/CString.h" |
#include "wtf/text/StringBuilder.h" |
+#include "base/debug/stack_trace.h" |
+#include "bindings/v8/ScriptCallStackFactory.h" |
+ |
using namespace std; |
namespace WebCore { |
@@ -699,8 +702,43 @@ void Node::markAncestorsWithChildNeedsDistributionRecalc() |
document().scheduleStyleRecalc(); |
} |
+size_t subtreeSize(Node* rootNode) |
+{ |
+ size_t subtreeSize = 1; |
+ Node* currentNode = rootNode; |
+ while ((currentNode = NodeTraversal::next(*currentNode, rootNode))) |
+ subtreeSize++; |
+ return subtreeSize; |
+} |
+ |
+static void printJSStackTrace() |
+{ |
+ RefPtr<ScriptCallStack> stack = createScriptCallStack(10); |
+ if (!stack) { |
+ // The last function in the JS stack always seems to be an empty string? |
+ // to compensate, print an extra \n here. |
+ printf("Not JS triggered.\n\n"); |
+ return; |
+ } |
+ printf("JS Stack:\n"); |
+ for (size_t i = 0; i < stack->size(); i++) |
+ printf("%s\n", stack->at(i).functionName().ascii().data()); |
+ printf("\n"); |
+} |
+ |
inline void Node::setStyleChange(StyleChangeType changeType) |
{ |
+ static const size_t kMinLoggedSize = 100; |
+ if (changeType >= SubtreeStyleChange) { |
+ size_t nodeCount = subtreeSize(this); |
+ if (nodeCount >= kMinLoggedSize) { |
+ printf("\n\nINVALIDATED style on tree of %zu nodes (threshold: %zu)\n", nodeCount, kMinLoggedSize); |
+ printf("Root: %s\n\n", debugName().ascii().data()); |
+ printJSStackTrace(); |
+ printf("C++ Stack:\n"); |
+ base::debug::StackTrace().Print(); |
+ } |
+ } |
m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType; |
} |