Bug 1249927 - devirtualize CanHavaAnonymousChildren, r=davdib
authorAlexander Surkov <surkov.alexander@gmail.com>
Mon, 22 Feb 2016 12:32:03 -0500
changeset 321392 5e301a8b9efe2dfa0efc21b44d46e1a921a08610
parent 321391 27070ffbbac79e66353ec035cafe85bea1343200
child 321393 cfaec1c77ae38d071284c61294ea70a59a3b7e09
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavdib
bugs1249927
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1249927 - devirtualize CanHavaAnonymousChildren, r=davdib
accessible/base/TreeWalker.cpp
accessible/generic/Accessible.cpp
accessible/generic/Accessible.h
accessible/xul/XULComboboxAccessible.cpp
accessible/xul/XULComboboxAccessible.h
accessible/xul/XULListboxAccessible.cpp
accessible/xul/XULListboxAccessible.h
accessible/xul/XULMenuAccessible.cpp
accessible/xul/XULMenuAccessible.h
accessible/xul/XULSliderAccessible.cpp
accessible/xul/XULSliderAccessible.h
--- a/accessible/base/TreeWalker.cpp
+++ b/accessible/base/TreeWalker.cpp
@@ -22,18 +22,18 @@ using namespace mozilla::a11y;
 
 TreeWalker::
   TreeWalker(Accessible* aContext, nsIContent* aContent, uint32_t aFlags) :
   mDoc(aContext->Document()), mContext(aContext), mAnchorNode(aContent),
   mFlags(aFlags)
 {
   NS_ASSERTION(aContent, "No node for the accessible tree walker!");
 
-  mChildFilter = mContext->CanHaveAnonChildren() ?
-    nsIContent::eAllChildren : nsIContent::eAllButXBL;
+  mChildFilter = mContext->NoXBLKids() ?
+    nsIContent::eAllButXBL : nsIContent::eAllChildren;
   mChildFilter |= nsIContent::eSkipPlaceholderContent;
 
   if (aContent)
     PushState(aContent);
 
   MOZ_COUNT_CTOR(TreeWalker);
 }
 
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -297,22 +297,16 @@ Accessible::AccessKey() const
 }
 
 KeyBinding
 Accessible::KeyboardShortcut() const
 {
   return KeyBinding();
 }
 
-bool
-Accessible::CanHaveAnonChildren()
-{
-  return true;
-}
-
 void
 Accessible::TranslateString(const nsString& aKey, nsAString& aStringOut)
 {
   nsCOMPtr<nsIStringBundleService> stringBundleService =
     services::GetStringBundleService();
   if (!stringBundleService)
     return;
 
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -490,21 +490,16 @@ public:
 
   /**
    * Handle accessible event, i.e. process it, notifies observers and fires
    * platform specific event.
    */
   virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
 
   /**
-   * Return true if this accessible allows accessible children from anonymous subtree.
-   */
-  virtual bool CanHaveAnonChildren();
-
-  /**
    * Return true if the accessible is an acceptable child.
    */
   virtual bool IsAcceptableChild(Accessible* aPossibleChild) const { return true; }
 
   /**
    * Returns text of accessible if accessible has text role otherwise empty
    * string.
    *
@@ -926,16 +921,22 @@ public:
   {
     if (aRelocated)
       mStateFlags |= eRelocated;
     else
       mStateFlags &= ~eRelocated;
   }
 
   /**
+   * Return true if the accessible doesn't allow accessible children from XBL
+   * anonymous subtree.
+   */
+  bool NoXBLKids() { return mStateFlags & eNoXBLKids; }
+
+  /**
    * Return true if this accessible has a parent whose name depends on this
    * accessible.
    */
   bool HasNameDependentParent() const
     { return mContextFlags & eHasNameDependentParent; }
 
   /**
    * Return true if aria-hidden="true" is applied to the accessible or inherited
@@ -1016,18 +1017,19 @@ protected:
     eSharedNode = 1 << 2, // accessible shares DOM node from another accessible
     eNotNodeMapEntry = 1 << 3, // accessible shouldn't be in document node map
     eHasNumericValue = 1 << 4, // accessible has a numeric value
     eGroupInfoDirty = 1 << 5, // accessible needs to update group info
     eSubtreeMutating = 1 << 6, // subtree is being mutated
     eIgnoreDOMUIEvent = 1 << 7, // don't process DOM UI events for a11y events
     eSurvivingInUpdate = 1 << 8, // parent drops children to recollect them
     eRelocated = 1 << 9, // accessible was moved in tree
+    eNoXBLKids = 1 << 10, // accessible don't allows XBL children
 
-    eLastStateFlag = eRelocated
+    eLastStateFlag = eNoXBLKids
   };
 
   /**
    * Flags used for contextual information about the accessible.
    */
   enum ContextFlags {
     eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible.
     eARIAHidden = 1 << 1,
@@ -1132,17 +1134,17 @@ protected:
   nsCOMPtr<nsIContent> mContent;
   DocAccessible* mDoc;
 
   RefPtr<Accessible> mParent;
   nsTArray<RefPtr<Accessible> > mChildren;
   int32_t mIndexInParent;
 
   static const uint8_t kChildrenFlagsBits = 2;
-  static const uint8_t kStateFlagsBits = 10;
+  static const uint8_t kStateFlagsBits = 11;
   static const uint8_t kContextFlagsBits = 2;
   static const uint8_t kTypeBits = 6;
   static const uint8_t kGenericTypesBits = 14;
 
   /**
    * Keep in sync with ChildrenFlags, StateFlags, ContextFlags, and AccTypes.
    */
   uint32_t mChildrenFlags : kChildrenFlagsBits;
--- a/accessible/xul/XULComboboxAccessible.cpp
+++ b/accessible/xul/XULComboboxAccessible.cpp
@@ -26,16 +26,25 @@ XULComboboxAccessible::
   XULComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   AccessibleWrap(aContent, aDoc)
 {
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                             nsGkAtoms::autocomplete, eIgnoreCase))
     mGenericTypes |= eAutoComplete;
   else
     mGenericTypes |= eCombobox;
+
+  // Both the XUL <textbox type="autocomplete"> and <menulist editable="true">
+  // widgets use XULComboboxAccessible. We need to walk the anonymous children
+  // for these so that the entry field is a child. Otherwise no XBL children.
+  if (!mContent->NodeInfo()->Equals(nsGkAtoms::textbox, kNameSpaceID_XUL) &&
+      !mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
+                             nsGkAtoms::_true, eIgnoreCase)) {
+    mStateFlags |= eNoXBLKids;
+  }
 }
 
 role
 XULComboboxAccessible::NativeRole()
 {
   return IsAutoComplete() ? roles::AUTOCOMPLETE : roles::COMBOBOX;
 }
 
@@ -91,33 +100,16 @@ XULComboboxAccessible::Value(nsString& a
   aValue.Truncate();
 
   // The value is the option or text shown entered in the combobox.
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
   if (menuList)
     menuList->GetLabel(aValue);
 }
 
-bool
-XULComboboxAccessible::CanHaveAnonChildren()
-{
-  if (mContent->NodeInfo()->Equals(nsGkAtoms::textbox, kNameSpaceID_XUL) ||
-      mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
-                            nsGkAtoms::_true, eIgnoreCase)) {
-    // Both the XUL <textbox type="autocomplete"> and <menulist editable="true"> widgets
-    // use XULComboboxAccessible. We need to walk the anonymous children for these
-    // so that the entry field is a child
-    return true;
-  }
-
-  // Argument of false indicates we don't walk anonymous children for
-  // menuitems
-  return false;
-}
-
 uint8_t
 XULComboboxAccessible::ActionCount()
 {
   // Just one action (click).
   return 1;
 }
 
 bool
--- a/accessible/xul/XULComboboxAccessible.h
+++ b/accessible/xul/XULComboboxAccessible.h
@@ -21,17 +21,16 @@ public:
 
   XULComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual void Description(nsString& aDescription) override;
   virtual void Value(nsString& aValue) override;
   virtual a11y::role NativeRole() override;
   virtual uint64_t NativeState() override;
-  virtual bool CanHaveAnonChildren() override;
 
   // ActionAccessible
   virtual uint8_t ActionCount() override;
   virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override;
   virtual bool DoAction(uint8_t aIndex) override;
 
   // Widgets
   virtual bool IsActiveWidget() const override;
--- a/accessible/xul/XULListboxAccessible.cpp
+++ b/accessible/xul/XULListboxAccessible.cpp
@@ -539,16 +539,20 @@ XULListitemAccessible::
   XULListitemAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   XULMenuitemAccessible(aContent, aDoc)
 {
   mIsCheckbox = mContent->AttrValueIs(kNameSpaceID_None,
                                       nsGkAtoms::type,
                                       nsGkAtoms::checkbox,
                                       eCaseMatters);
   mType = eXULListItemType;
+
+  // Walk XBL anonymous children for list items. Overrides the flag value from
+  // base XULMenuitemAccessible class.
+  mStateFlags &= ~eNoXBLKids;
 }
 
 XULListitemAccessible::~XULListitemAccessible()
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(XULListitemAccessible, Accessible)
 
@@ -663,23 +667,16 @@ XULListitemAccessible::ActionNameAt(uint
     uint64_t states = NativeState();
     if (states & states::CHECKED)
       aName.AssignLiteral("uncheck");
     else
       aName.AssignLiteral("check");
   }
 }
 
-bool
-XULListitemAccessible::CanHaveAnonChildren()
-{
-  // That indicates we should walk anonymous children for listitems
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // XULListitemAccessible: Widgets
 
 Accessible*
 XULListitemAccessible::ContainerWidget() const
 {
   return Parent();
 }
--- a/accessible/xul/XULListboxAccessible.h
+++ b/accessible/xul/XULListboxAccessible.h
@@ -110,17 +110,16 @@ public:
 
   XULListitemAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual void Description(nsString& aDesc) override;
   virtual a11y::role NativeRole() override;
   virtual uint64_t NativeState() override;
   virtual uint64_t NativeInteractiveState() const override;
-  virtual bool CanHaveAnonChildren() override;
 
   // Actions
   virtual void ActionNameAt(uint8_t index, nsAString& aName) override;
 
   // Widgets
   virtual Accessible* ContainerWidget() const override;
 
 protected:
--- a/accessible/xul/XULMenuAccessible.cpp
+++ b/accessible/xul/XULMenuAccessible.cpp
@@ -36,16 +36,17 @@ using namespace mozilla::a11y;
 ////////////////////////////////////////////////////////////////////////////////
 // XULMenuitemAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 XULMenuitemAccessible::
   XULMenuitemAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   AccessibleWrap(aContent, aDoc)
 {
+  mStateFlags |= eNoXBLKids;
 }
 
 uint64_t
 XULMenuitemAccessible::NativeState()
 {
   uint64_t state = Accessible::NativeState();
 
   // Has Popup?
@@ -263,23 +264,16 @@ XULMenuitemAccessible::NativeRole()
 
 int32_t
 XULMenuitemAccessible::GetLevelInternal()
 {
   return nsAccUtils::GetLevelForXULContainerItem(mContent);
 }
 
 bool
-XULMenuitemAccessible::CanHaveAnonChildren()
-{
-  // That indicates we don't walk anonymous children for menuitems
-  return false;
-}
-
-bool
 XULMenuitemAccessible::DoAction(uint8_t index)
 {
   if (index == eAction_Click) {   // default action
     DoCommand();
     return true;
   }
 
   return false;
--- a/accessible/xul/XULMenuAccessible.h
+++ b/accessible/xul/XULMenuAccessible.h
@@ -25,18 +25,16 @@ public:
 
   // Accessible
   virtual void Description(nsString& aDescription) override;
   virtual a11y::role NativeRole() override;
   virtual uint64_t NativeState() override;
   virtual uint64_t NativeInteractiveState() const override;
   virtual int32_t GetLevelInternal() override;
 
-  virtual bool CanHaveAnonChildren() override;
-
   // ActionAccessible
   virtual uint8_t ActionCount() override;
   virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override;
   virtual bool DoAction(uint8_t aIndex) override;
   virtual KeyBinding AccessKey() const override;
   virtual KeyBinding KeyboardShortcut() const override;
 
   // Widgets
--- a/accessible/xul/XULSliderAccessible.cpp
+++ b/accessible/xul/XULSliderAccessible.cpp
@@ -18,17 +18,17 @@ using namespace mozilla::a11y;
 ////////////////////////////////////////////////////////////////////////////////
 // XULSliderAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 XULSliderAccessible::
   XULSliderAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   AccessibleWrap(aContent, aDoc)
 {
-  mStateFlags |= eHasNumericValue;
+  mStateFlags |= eHasNumericValue | eNoXBLKids;
 }
 
 // Accessible
 
 role
 XULSliderAccessible::NativeRole()
 {
   return roles::SLIDER;
@@ -122,23 +122,16 @@ bool
 XULSliderAccessible::SetCurValue(double aValue)
 {
   if (AccessibleWrap::SetCurValue(aValue))
     return true;
 
   return SetSliderAttr(nsGkAtoms::curpos, aValue);
 }
 
-bool
-XULSliderAccessible::CanHaveAnonChildren()
-{
-  // Do not allow anonymous xul:slider be accessible.
-  return false;
-}
-
 // Utils
 
 nsIContent*
 XULSliderAccessible::GetSliderElement() const
 {
   if (!mSliderNode) {
     // XXX: we depend on anonymous content.
     mSliderNode = mContent->OwnerDoc()->
--- a/accessible/xul/XULSliderAccessible.h
+++ b/accessible/xul/XULSliderAccessible.h
@@ -21,17 +21,16 @@ class XULSliderAccessible : public Acces
 public:
   XULSliderAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual void Value(nsString& aValue) override;
   virtual a11y::role NativeRole() override;
   virtual uint64_t NativeInteractiveState() const override;
   virtual bool NativelyUnavailable() const override;
-  virtual bool CanHaveAnonChildren() override;
 
   // Value
   virtual double MaxValue() const override;
   virtual double MinValue() const override;
   virtual double CurValue() const override;
   virtual double Step() const override;
   virtual bool SetCurValue(double aValue) override;