Move m_rootEditableElementForSelectionOnMouseDown off of HTMLAnchorElement.
authorkling@webkit.org <kling@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Jan 2012 17:00:38 +0000 (17:00 +0000)
committerkling@webkit.org <kling@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Jan 2012 17:00:38 +0000 (17:00 +0000)
<http://webkit.org/b/76833>

Reviewed by Antti Koivisto.

Move HTMLAnchorElement::m_rootEditableElementForSelectionOnMouseDown to a rare
data-style hashmap, effectively shrinking HTMLAnchorElement by one CPU word.

The pointer is only used during interactive event handling, so it shouldn't have
any noticeable effects on web performance.

This reduces memory consumption by 256 kB (on 64-bit) when viewing the full
HTML5 spec at <http://whatwg.org/c>.

* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::HTMLAnchorElement):
(WebCore::HTMLAnchorElement::~HTMLAnchorElement):
(WebCore::HTMLAnchorElement::defaultEventHandler):
(WebCore::HTMLAnchorElement::treatLinkAsLiveForEventType):
(WebCore::rootEditableElementMap):
(WebCore::HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown):
(WebCore::HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown):
* html/HTMLAnchorElement.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105631 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/html/HTMLAnchorElement.cpp
Source/WebCore/html/HTMLAnchorElement.h

index 0ee7369..ef4ad75 100644 (file)
@@ -1,3 +1,29 @@
+2012-01-23  Andreas Kling  <awesomekling@apple.com>
+
+        Move m_rootEditableElementForSelectionOnMouseDown off of HTMLAnchorElement.
+        <http://webkit.org/b/76833>
+
+        Reviewed by Antti Koivisto.
+
+        Move HTMLAnchorElement::m_rootEditableElementForSelectionOnMouseDown to a rare
+        data-style hashmap, effectively shrinking HTMLAnchorElement by one CPU word.
+
+        The pointer is only used during interactive event handling, so it shouldn't have
+        any noticeable effects on web performance.
+
+        This reduces memory consumption by 256 kB (on 64-bit) when viewing the full
+        HTML5 spec at <http://whatwg.org/c>.
+
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::HTMLAnchorElement):
+        (WebCore::HTMLAnchorElement::~HTMLAnchorElement):
+        (WebCore::HTMLAnchorElement::defaultEventHandler):
+        (WebCore::HTMLAnchorElement::treatLinkAsLiveForEventType):
+        (WebCore::rootEditableElementMap):
+        (WebCore::HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown):
+        (WebCore::HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown):
+        * html/HTMLAnchorElement.h:
+
 2012-01-23  Antti Koivisto  <antti@apple.com>
 
         Eliminate CSSElementStyleDeclaration subclasses
index d601852..d02f8b2 100644 (file)
@@ -48,6 +48,7 @@ using namespace HTMLNames;
 
 HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* document)
     : HTMLElement(tagName, document)
+    , m_hasRootEditableElementForSelectionOnMouseDown(false)
     , m_wasShiftKeyDownOnMouseDown(false)
     , m_linkRelations(0)
     , m_cachedVisitedLinkHash(0)
@@ -64,6 +65,11 @@ PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tag
     return adoptRef(new HTMLAnchorElement(tagName, document));
 }
 
+HTMLAnchorElement::~HTMLAnchorElement()
+{
+    clearRootEditableElementForSelectionOnMouseDown();
+}
+
 // This function does not allow leading spaces before the port number.
 static unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd)
 {
@@ -158,12 +164,12 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
             // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
             // for the LiveWhenNotFocused editable link behavior
             if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() != RightButton && document()->frame() && document()->frame()->selection()) {
-                m_rootEditableElementForSelectionOnMouseDown = document()->frame()->selection()->rootEditableElement();
+                setRootEditableElementForSelectionOnMouseDown(document()->frame()->selection()->rootEditableElement());
                 m_wasShiftKeyDownOnMouseDown = static_cast<MouseEvent*>(event)->shiftKey();
             } else if (event->type() == eventNames().mouseoverEvent) {
                 // These are cleared on mouseover and not mouseout because their values are needed for drag events,
                 // but drag events happen after mouse out events.
-                m_rootEditableElementForSelectionOnMouseDown = 0;
+                clearRootEditableElementForSelectionOnMouseDown();
                 m_wasShiftKeyDownOnMouseDown = false;
             }
         }
@@ -546,7 +552,7 @@ bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
     // If the selection prior to clicking on this link resided in the same editable block as this link,
     // and the shift key isn't pressed, we don't want to follow the link.
     case EditableLinkLiveWhenNotFocused:
-        return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && m_rootEditableElementForSelectionOnMouseDown != rootEditableElement());
+        return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && rootEditableElementForSelectionOnMouseDown() != rootEditableElement());
 
     case EditableLinkOnlyLiveWithShiftKey:
         return eventType == MouseEventWithShiftKey;
@@ -593,4 +599,38 @@ void HTMLAnchorElement::setItemValueText(const String& value, ExceptionCode& ec)
 }
 #endif
 
+typedef HashMap<const HTMLAnchorElement*, RefPtr<Element> > RootEditableElementMap;
+
+static RootEditableElementMap& rootEditableElementMap()
+{
+    DEFINE_STATIC_LOCAL(RootEditableElementMap, map, ());
+    return map;
+}
+
+Element* HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown() const
+{
+    if (!m_hasRootEditableElementForSelectionOnMouseDown)
+        return 0;
+    return rootEditableElementMap().get(this).get();
+}
+
+void HTMLAnchorElement::clearRootEditableElementForSelectionOnMouseDown()
+{
+    if (!m_hasRootEditableElementForSelectionOnMouseDown)
+        return;
+    rootEditableElementMap().remove(this);
+    m_hasRootEditableElementForSelectionOnMouseDown = false;
+}
+
+void HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown(Element* element)
+{
+    if (!element) {
+        clearRootEditableElementForSelectionOnMouseDown();
+        return;
+    }
+
+    rootEditableElementMap().set(this, element);
+    m_hasRootEditableElementForSelectionOnMouseDown = true;
+}
+
 }
index cbda841..99a6332 100644 (file)
@@ -58,6 +58,8 @@ public:
     static PassRefPtr<HTMLAnchorElement> create(Document*);
     static PassRefPtr<HTMLAnchorElement> create(const QualifiedName&, Document*);
 
+    virtual ~HTMLAnchorElement();
+
     KURL href() const;
     void setHref(const AtomicString&);
 
@@ -133,9 +135,13 @@ private:
     virtual void setItemValueText(const String&, ExceptionCode&) OVERRIDE;
 #endif
 
-    RefPtr<Element> m_rootEditableElementForSelectionOnMouseDown;
+    Element* rootEditableElementForSelectionOnMouseDown() const;
+    void setRootEditableElementForSelectionOnMouseDown(Element*);
+    void clearRootEditableElementForSelectionOnMouseDown();
+
+    bool m_hasRootEditableElementForSelectionOnMouseDown : 1;
     bool m_wasShiftKeyDownOnMouseDown : 1;
-    uint32_t m_linkRelations : 31;
+    uint32_t m_linkRelations : 30;
     mutable LinkHash m_cachedVisitedLinkHash;
 };