Back out 83a33626d965:6e9330f5a9bd (bug 732667 and bug 705877) for Windows build bustage
authorPhil Ringnalda <philringnalda@gmail.com>
Mon, 12 Mar 2012 22:12:41 -0700
changeset 91785 f925f2f8d1fd474de2463ce949d03403714a23ac
parent 91784 83a33626d9658fd26deef1f8141a525033bd9223
child 91786 6799a5e6912f834ebbd8e94c74c34c34f20a92f5
push id783
push userlsblakk@mozilla.com
push dateTue, 24 Apr 2012 17:33:42 +0000
treeherdermozilla-beta@11faed19f136 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs732667, 705877
milestone13.0a1
backs out83a33626d9658fd26deef1f8141a525033bd9223
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
Back out 83a33626d965:6e9330f5a9bd (bug 732667 and bug 705877) for Windows build bustage
content/base/public/nsINode.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsFrameManager.cpp
layout/generic/nsIFrame.h
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsRuleProcessorData.h
mfbt/BloomFilter.h
xpcom/tests/TestBloomFilter.cpp
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -170,24 +170,21 @@ enum {
   NODE_DESCENDANTS_NEED_FRAMES = 0x00010000U,
 
   // Set if the node has the accesskey attribute set.
   NODE_HAS_ACCESSKEY           = 0x00020000U,
 
   // Set if the node is handling a click.
   NODE_HANDLING_CLICK          = 0x00040000U,
 
-  // Set if the node has had :hover selectors matched against it
-  NODE_HAS_RELEVANT_HOVER_RULES = 0x00080000U,
-
   // Two bits for the script-type ID.  Not enough to represent all
   // nsIProgrammingLanguage values, but we don't care.  In practice,
   // we can represent the ones we want, and we can fail the others at
   // runtime.
-  NODE_SCRIPT_TYPE_OFFSET =               20,
+  NODE_SCRIPT_TYPE_OFFSET =               19,
 
   NODE_SCRIPT_TYPE_SIZE =                  2,
 
   NODE_SCRIPT_TYPE_MASK =  (1 << NODE_SCRIPT_TYPE_SIZE) - 1,
 
   // Remaining bits are node type specific.
   NODE_TYPE_SPECIFIC_BITS_OFFSET =
     NODE_SCRIPT_TYPE_OFFSET + NODE_SCRIPT_TYPE_SIZE
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2308,19 +2308,16 @@ nsCSSFrameConstructor::ConstructDocEleme
     PropagateScrollToViewport();
 
   SetUpDocElementContainingBlock(aDocElement);
 
   NS_ASSERTION(mDocElementContainingBlock, "Should have parent by now");
 
   nsFrameConstructorState state(mPresShell, mFixedContainingBlock, nsnull,
                                 nsnull, aFrameState);
-  // Initialize the ancestor filter with null for now; we'll push
-  // aDocElement once we finish resolving style for it.
-  state.mTreeMatchContext.mAncestorFilter.Init(nsnull);
 
   // XXXbz why, exactly?
   if (!mTempFrameTreeState)
     state.mPresShell->CaptureHistoryState(getter_AddRefs(mTempFrameTreeState));
 
   // Make sure that we'll handle restyles for this document element in
   // the future.  We need this, because the document element might
   // have stale restyle bits from a previous frame constructor for
@@ -2377,19 +2374,16 @@ nsCSSFrameConstructor::ConstructDocEleme
                "Scrollbars should have been propagated to the viewport");
 #endif
 
   if (NS_UNLIKELY(display->mDisplay == NS_STYLE_DISPLAY_NONE)) {
     SetUndisplayedContent(aDocElement, styleContext);
     return NS_OK;
   }
 
-  AncestorFilter::AutoAncestorPusher
-    ancestorPusher(true, state.mTreeMatchContext.mAncestorFilter, aDocElement);
-
   // Make sure to start any background image loads for the root element now.
   styleContext->StartBackgroundImageLoads();
 
   nsFrameConstructorSaveState absoluteSaveState;
   if (mHasRootAbsPosContainingBlock) {
     // Push the absolute containing block now so we can absolutely position
     // the root element
     state.PushAbsoluteContainingBlock(mDocElementContainingBlock,
@@ -3599,43 +3593,31 @@ nsCSSFrameConstructor::ConstructFrameFro
   if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
       aItem.mContent->Tag() == nsGkAtoms::iframe)
   {
     return NS_OK;
   }
 
   nsStyleContext* const styleContext = aItem.mStyleContext;
   const nsStyleDisplay* display = styleContext->GetStyleDisplay();
-  nsIContent* const content = aItem.mContent;
-
-  // Push the content as a style ancestor now, so we don't have to do
-  // it in our various full-constructor functions.  In particular,
-  // since a number of full-constructor functions don't actually call
-  // ProcessChildren in some cases (e.g. for CSS anonymous table boxes
-  // or for situations where only anonymouse children are having
-  // frames constructed), this is the best place to bottleneck the
-  // pushing of the content instead of having to do it in multiple
-  // places.
-  AncestorFilter::AutoAncestorPusher
-    ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
-                   aState.mTreeMatchContext.mAncestorFilter,
-                   content->IsElement() ? content->AsElement() : nsnull);
 
   nsIFrame* newFrame;
   nsIFrame* primaryFrame;
   if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
     nsresult rv =
       (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
                                         display, aFrameItems, &newFrame);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     primaryFrame = newFrame;
   } else {
+    nsIContent* const content = aItem.mContent;
+
     newFrame =
       (*data->mFunc.mCreationFunc)(mPresShell, styleContext);
     if (!newFrame) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     bool allowOutOfFlow = !(bits & FCDATA_DISALLOW_OUT_OF_FLOW);
     bool isPopup = aItem.mIsPopup;
@@ -3836,20 +3818,16 @@ nsCSSFrameConstructor::CreateAnonymousFr
 
   PRUint32 count = newAnonymousItems.Length();
   if (count == 0) {
     return NS_OK;
   }
 
   nsFrameConstructorState::PendingBindingAutoPusher pusher(aState,
                                                            aPendingBinding);
-  AncestorFilter::AutoAncestorPusher
-    ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
-                   aState.mTreeMatchContext.mAncestorFilter,
-                   aParent->AsElement());
 
   nsIAnonymousContentCreator* creator = do_QueryFrame(aParentFrame);
   NS_ASSERTION(creator,
                "How can that happen if we have nodes to construct frames for?");
 
   for (PRUint32 i=0; i < count; i++) {
     nsIContent* content = newAnonymousItems[i].mContent;
     NS_ASSERTION(content, "null anonymous content?");
@@ -6528,17 +6506,16 @@ nsCSSFrameConstructor::ContentAppended(n
     ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
                                         aContainer, parentFrame,
                                         &parentAfterFrame);
   
   // Create some new frames
   nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                 GetAbsoluteContainingBlock(parentFrame),
                                 GetFloatContainingBlock(parentFrame));
-  state.mTreeMatchContext.mAncestorFilter.Init(aContainer->AsElement());
 
   // See if the containing block has :first-letter style applied.
   bool haveFirstLetterStyle = false, haveFirstLineStyle = false;
   nsIFrame* containingBlock = state.mFloatedItems.containingBlock;
   if (containingBlock) {
     haveFirstLetterStyle = HasFirstLetterStyle(containingBlock);
     haveFirstLineStyle =
       ShouldHaveFirstLineStyle(containingBlock->GetContent(),
@@ -6956,19 +6933,17 @@ nsCSSFrameConstructor::ContentRangeInser
     LAYOUT_PHASE_TEMP_REENTER();
     return rv;
   }
 
   nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                 GetAbsoluteContainingBlock(parentFrame),
                                 GetFloatContainingBlock(parentFrame),
                                 aFrameState);
-  state.mTreeMatchContext.mAncestorFilter.Init(aContainer ?
-                                                 aContainer->AsElement() :
-                                                 nsnull);
+
 
   // Recover state for the containing block - we need to know if
   // it has :first-letter or :first-line style applied to it. The
   // reason we care is that the internal structure in these cases
   // is not the normal structure and requires custom updating
   // logic.
   nsIFrame* containingBlock = state.mFloatedItems.containingBlock;
   bool haveFirstLetterStyle = false;
@@ -8080,24 +8055,18 @@ nsCSSFrameConstructor::ContentStateChang
           }
         }
       }
     }
 
     primaryFrame->ContentStatesChanged(aStateMask);
   }
 
-  if (aStateMask.HasState(NS_EVENT_STATE_HOVER) &&
-      !aElement->HasFlag(NODE_HAS_RELEVANT_HOVER_RULES)) {
-    aStateMask &= ~NS_EVENT_STATE_HOVER;
-  }
-
-  nsRestyleHint rshint = aStateMask.IsEmpty() ?
-      nsRestyleHint(0) :
-      styleSet->HasStateDependentStyle(presContext, aElement, aStateMask);
+  nsRestyleHint rshint = 
+    styleSet->HasStateDependentStyle(presContext, aElement, aStateMask);
       
   if (aStateMask.HasState(NS_EVENT_STATE_HOVER) && rshint != 0) {
     ++mHoverGeneration;
   }
 
   if (aStateMask.HasState(NS_EVENT_STATE_VISITED)) {
     // Exposing information to the page about whether the link is
     // visited or not isn't really something we can worry about here.
@@ -8684,21 +8653,16 @@ nsCSSFrameConstructor::ReplicateFixedFra
   // This should not normally be possible (because fixed-pos elements should
   // be absolute containers) but fixed-pos tables currently aren't abs-pos
   // containers.
   nsFrameConstructorState state(mPresShell, aParentFrame,
                                 nsnull,
                                 mRootElementFrame);
   state.mCreatingExtraFrames = true;
 
-  // We can't use an ancestor filter here, because we're not going to
-  // be usefully recurring down the tree.  This means that other
-  // places in frame construction can't assume a filter is
-  // initialized!
-
   // Iterate across fixed frames and replicate each whose placeholder is a
   // descendant of aFrame. (We don't want to explicitly copy placeholders that
   // are within fixed frames, because that would cause duplicates on the new
   // page - bug 389619)
   for (nsIFrame* fixed = firstFixed; fixed; fixed = fixed->GetNextSibling()) {
     nsIFrame* prevPlaceholder = GetPlaceholderFrameFor(fixed);
     if (prevPlaceholder &&
         nsLayoutUtils::IsProperAncestorFrame(prevCanvasFrame, prevPlaceholder)) {
@@ -10515,19 +10479,16 @@ nsCSSFrameConstructor::CreateListBoxCont
   // Construct a new frame
   if (nsnull != aParentFrame) {
     nsFrameItems            frameItems;
     nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                   GetAbsoluteContainingBlock(aParentFrame),
                                   GetFloatContainingBlock(aParentFrame), 
                                   mTempFrameTreeState);
 
-    // If we ever initialize the ancestor filter on |state|, make sure
-    // to push the right parent!
-
     nsRefPtr<nsStyleContext> styleContext;
     styleContext = ResolveStyleContext(aParentFrame, aChild, &state);
 
     // Pre-check for display "none" - only if we find that, do we create
     // any frame at all
     const nsStyleDisplay* display = styleContext->GetStyleDisplay();
 
     if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
@@ -10862,22 +10823,16 @@ nsCSSFrameConstructor::BuildInlineChildI
   // XXXbz should we preallocate aParentItem.mChildItems to some sane
   // length?  Maybe even to parentContent->GetChildCount()?
   nsFrameConstructorState::PendingBindingAutoPusher
     pusher(aState, aParentItem.mPendingBinding);
 
   // Probe for generated content before
   nsStyleContext* const parentStyleContext = aParentItem.mStyleContext;
   nsIContent* const parentContent = aParentItem.mContent;
-
-  AncestorFilter::AutoAncestorPusher
-    ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
-                   aState.mTreeMatchContext.mAncestorFilter,
-                   parentContent->AsElement());
-  
   CreateGeneratedContentItem(aState, nsnull, parentContent, parentStyleContext,
                              nsCSSPseudoElements::ePseudo_before,
                              aParentItem.mChildItems);
 
   ChildIterator iter, last;
   for (ChildIterator::Init(parentContent, &iter, &last);
        iter != last;
        ++iter) {
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -1136,21 +1136,16 @@ nsFrameManager::ReResolveStyleContext(ns
     bool isChild = providerFrame && providerFrame->GetParent() == aFrame;
     if (!isChild) {
       if (providerFrame)
         parentContext = providerFrame->GetStyleContext();
       else
         parentContext = nsnull;
     }
     else {
-      MOZ_ASSERT(providerFrame->GetContent() == aFrame->GetContent(),
-                 "Postcondition for GetParentStyleContextFrame() violated. "
-                 "That means we need to add the current element to the "
-                 "ancestor filter.");
-
       // resolve the provider here (before aFrame below).
 
       // assumeDifferenceHint forces the parent's change to be also
       // applied to this frame, no matter what
       // nsStyleContext::CalcStyleDifference says. CalcStyleDifference
       // can't be trusted because it assumes any changes to the parent
       // style context provider will be automatically propagated to
       // the frame(s) with child style contexts.
@@ -1389,22 +1384,18 @@ nsFrameManager::ReResolveStyleContext(ns
       checkUndisplayed = aFrame == mPresShell->FrameConstructor()->
                                      GetDocElementContainingBlock();
       undisplayedParent = nsnull;
     } else {
       checkUndisplayed = !!localContent;
       undisplayedParent = localContent;
     }
     if (checkUndisplayed && mUndisplayedMap) {
-      UndisplayedNode* undisplayed =
-        mUndisplayedMap->GetFirstNode(undisplayedParent);
-      for (AncestorFilter::AutoAncestorPusher
-             pushAncestor(undisplayed, aTreeMatchContext.mAncestorFilter,
-                          undisplayedParent ? undisplayedParent->AsElement()
-                                            : nsnull);
+      for (UndisplayedNode* undisplayed =
+                              mUndisplayedMap->GetFirstNode(undisplayedParent);
            undisplayed; undisplayed = undisplayed->mNext) {
         NS_ASSERTION(undisplayedParent ||
                      undisplayed->mContent ==
                        mPresShell->GetDocument()->GetRootElement(),
                      "undisplayed node child of null must be root");
         NS_ASSERTION(!undisplayed->mStyle->GetPseudo(),
                      "Shouldn't have random pseudo style contexts in the "
                      "undisplayed map");
@@ -1542,22 +1533,17 @@ nsFrameManager::ReResolveStyleContext(ns
 
       // There is no need to waste time crawling into a frame's children on a frame change.
       // The act of reconstructing frames will force new style contexts to be resolved on all
       // of this frame's descendants anyway, so we want to avoid wasting time processing
       // style contexts that we're just going to throw away anyway. - dwh
 
       // now do children
       nsIFrame::ChildListIterator lists(aFrame);
-      for (AncestorFilter::AutoAncestorPusher
-             pushAncestor(!lists.IsDone(),
-                          aTreeMatchContext.mAncestorFilter,
-                          content && content->IsElement() ? content->AsElement()
-                                                          : nsnull);
-           !lists.IsDone(); lists.Next()) {
+      for (; !lists.IsDone(); lists.Next()) {
         nsFrameList::Enumerator childFrames(lists.CurrentList());
         for (; !childFrames.AtEnd(); childFrames.Next()) {
           nsIFrame* child = childFrames.get();
           if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
               || (child->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
             // only do frames that don't have placeholders
             if (nsGkAtoms::placeholderFrame == child->GetType()) { // placeholder
               // get out of flow frame and recur there
@@ -1658,19 +1644,18 @@ nsFrameManager::ReResolveStyleContext(ns
 
 void
 nsFrameManager::ComputeStyleChangeFor(nsIFrame          *aFrame, 
                                       nsStyleChangeList *aChangeList,
                                       nsChangeHint       aMinChange,
                                       RestyleTracker&    aRestyleTracker,
                                       bool               aRestyleDescendants)
 {
-  nsIContent *content = aFrame->GetContent();
   if (aMinChange) {
-    aChangeList->AppendChange(aFrame, content, aMinChange);
+    aChangeList->AppendChange(aFrame, aFrame->GetContent(), aMinChange);
   }
 
   nsChangeHint topLevelChange = aMinChange;
 
   nsIFrame* frame = aFrame;
   nsIFrame* frame2 = aFrame;
 
   NS_ASSERTION(!frame->GetPrevContinuation(), "must start with the first in flow");
@@ -1679,20 +1664,16 @@ nsFrameManager::ComputeStyleChangeFor(ns
   // as well as all its special siblings and their next-in-flows,
   // reresolving style on all the frames we encounter in this walk.
 
   FramePropertyTable *propTable = GetPresContext()->PropertyTable();
 
   TreeMatchContext treeMatchContext(true,
                                     nsRuleWalker::eRelevantLinkUnvisited,
                                     mPresShell->GetDocument());
-  nsIContent *parent = content ? content->GetParent() : nsnull;
-  Element *parentElement =
-    parent && parent->IsElement() ? parent->AsElement() : nsnull;
-  treeMatchContext.mAncestorFilter.Init(parentElement);
   nsTArray<nsIContent*> visibleKidsOfHiddenElement;
   do {
     // Outer loop over special siblings
     do {
       // Inner loop over next-in-flows of the current frame
       nsChangeHint frameChange =
         ReResolveStyleContext(GetPresContext(), frame, nsnull,
                               aChangeList, topLevelChange,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2419,19 +2419,18 @@ public:
 #ifdef ACCESSIBILITY
   virtual already_AddRefed<nsAccessible> CreateAccessible() = 0;
 #endif
 
   /**
    * Get the frame whose style context should be the parent of this
    * frame's style context (i.e., provide the parent style context).
    * This frame must either be an ancestor of this frame or a child.  If
-   * this returns a child frame, then the child frame must be sure to
-   * return a grandparent or higher!  Furthermore, if a child frame is
-   * returned it must have the same GetContent() as this frame.
+   * this frame returns a child frame, then the child frame must be sure
+   * to return a grandparent or higher!
    *
    * @return The frame whose style context should be the parent of this frame's
    *         style context.  Null is permitted, and means that this frame's
    *         style context should be the root of the style context tree.
    */
   virtual nsIFrame* GetParentStyleContextFrame() const = 0;
 
   /**
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -119,90 +119,27 @@ struct RuleSelectorPair {
     : mRule(aRule), mSelector(aSelector) {}
   // If this class ever grows a destructor, deal with
   // PerWeightDataListItem appropriately.
 
   css::StyleRule*   mRule;
   nsCSSSelector*    mSelector; // which of |mRule|'s selectors
 };
 
-#define NS_IS_ANCESTOR_OPERATOR(ch) \
-  ((ch) == PRUnichar(' ') || (ch) == PRUnichar('>'))
-
 /**
  * A struct representing a particular rule in an ordered list of rules
  * (the ordering depending on the weight of mSelector and the order of
  * our rules to start with).
  */
 struct RuleValue : RuleSelectorPair {
-  enum {
-    eMaxAncestorHashes = 4
-  };
-
   RuleValue(const RuleSelectorPair& aRuleSelectorPair, PRInt32 aIndex) :
     RuleSelectorPair(aRuleSelectorPair),
     mIndex(aIndex)
-  {
-    CollectAncestorHashes();
-  }
-
+  {}
   PRInt32 mIndex; // High index means high weight/order.
-  uint32_t mAncestorSelectorHashes[eMaxAncestorHashes];
-
-private:
-  void CollectAncestorHashes() {
-    // Collect up our mAncestorSelectorHashes.  It's not clear whether it's
-    // better to stop once we've found eMaxAncestorHashes of them or to keep
-    // going and preferentially collect information from selectors higher up the
-    // chain...  Let's do the former for now.
-    size_t hashIndex = 0;
-    for (nsCSSSelector* sel = mSelector->mNext; sel; sel = sel->mNext) {
-      if (!NS_IS_ANCESTOR_OPERATOR(sel->mOperator)) {
-        // |sel| is going to select something that's not actually one of our
-        // ancestors, so don't add it to mAncestorSelectorHashes.  But keep
-        // going, because it'll select a sibling of one of our ancestors, so its
-        // ancestors would be our ancestors too.
-        continue;
-      }
-
-      // Now sel is supposed to select one of our ancestors.  Grab whatever info
-      // we can from it into mAncestorSelectorHashes.
-      nsAtomList* ids = sel->mIDList;
-      while (ids) {
-        mAncestorSelectorHashes[hashIndex++] = ids->mAtom->hash();
-        if (hashIndex == eMaxAncestorHashes) {
-          return;
-        }
-        ids = ids->mNext;
-      }
-
-      nsAtomList* classes = sel->mClassList;
-      while (classes) {
-        mAncestorSelectorHashes[hashIndex++] = classes->mAtom->hash();
-        if (hashIndex == eMaxAncestorHashes) {
-          return;
-        }
-        classes = classes->mNext;
-      }
-
-      // Only put in the tag name if it's all-lowercase.  Otherwise we run into
-      // trouble because we may test the wrong one of mLowercaseTag and
-      // mCasedTag against the filter.
-      if (sel->mLowercaseTag && sel->mCasedTag == sel->mLowercaseTag) {
-        mAncestorSelectorHashes[hashIndex++] = sel->mLowercaseTag->hash();
-        if (hashIndex == eMaxAncestorHashes) {
-          return;
-        }
-      }
-    }
-
-    while (hashIndex != eMaxAncestorHashes) {
-      mAncestorSelectorHashes[hashIndex++] = 0;
-    }
-  }
 };
 
 // ------------------------------
 // Rule hash table
 //
 
 // Uses any of the sets of ops below.
 struct RuleHashTableEntry : public PLDHashEntryHdr {
@@ -708,19 +645,18 @@ void RuleHash::AppendRule(const RuleSele
 #define RULE_HASH_STAT_INCREMENT_LIST_COUNT(list_, var_) \
   (var_) += (list_).Length()
 #else
 #define RULE_HASH_STAT_INCREMENT_LIST_COUNT(list_, var_) \
   PR_BEGIN_MACRO PR_END_MACRO
 #endif
 
 static inline
-void ContentEnumFunc(const RuleValue &value, nsCSSSelector* selector,
-                     RuleProcessorData* data, NodeMatchContext& nodeContext,
-                     AncestorFilter *ancestorFilter);
+void ContentEnumFunc(css::StyleRule* aRule, nsCSSSelector* aSelector,
+                     RuleProcessorData* data, NodeMatchContext& nodeContext);
 
 void RuleHash::EnumerateAllRules(Element* aElement, RuleProcessorData* aData,
                                  NodeMatchContext& aNodeContext)
 {
   PRInt32 nameSpace = aElement->GetNameSpaceID();
   nsIAtom* tag = aElement->Tag();
   nsIAtom* id = aElement->GetID();
   const nsAttrValue* classList = aElement->GetClasses();
@@ -781,50 +717,42 @@ void RuleHash::EnumerateAllRules(Element
         mEnumList[valueCount++] = ToEnumData(entry->mRules);
         RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementClassCalls);
       }
     }
   }
   NS_ASSERTION(valueCount <= testCount, "values exceeded list size");
 
   if (valueCount > 0) {
-    AncestorFilter *filter =
-      aData->mTreeMatchContext.mAncestorFilter.HasFilter() ?
-        &aData->mTreeMatchContext.mAncestorFilter : nsnull;
-#ifdef DEBUG
-    if (filter) {
-      filter->AssertHasAllAncestors(aElement);
-    }
-#endif
     // Merge the lists while there are still multiple lists to merge.
     while (valueCount > 1) {
       PRInt32 valueIndex = 0;
       PRInt32 lowestRuleIndex = mEnumList[valueIndex].mCurValue->mIndex;
       for (PRInt32 index = 1; index < valueCount; ++index) {
         PRInt32 ruleIndex = mEnumList[index].mCurValue->mIndex;
         if (ruleIndex < lowestRuleIndex) {
           valueIndex = index;
           lowestRuleIndex = ruleIndex;
         }
       }
       const RuleValue *cur = mEnumList[valueIndex].mCurValue;
-      ContentEnumFunc(*cur, cur->mSelector, aData, aNodeContext, filter);
+      ContentEnumFunc(cur->mRule, cur->mSelector, aData, aNodeContext);
       cur++;
       if (cur == mEnumList[valueIndex].mEnd) {
         mEnumList[valueIndex] = mEnumList[--valueCount];
       } else {
         mEnumList[valueIndex].mCurValue = cur;
       }
     }
 
     // Fast loop over single value.
     for (const RuleValue *value = mEnumList[0].mCurValue,
                          *end = mEnumList[0].mEnd;
          value != end; ++value) {
-      ContentEnumFunc(*value, value->mSelector, aData, aNodeContext, filter);
+      ContentEnumFunc(value->mRule, value->mSelector, aData, aNodeContext);
     }
   }
 }
 
 static size_t
 SizeOfRuleHashTableEntry(PLDHashEntryHdr* aHdr, nsMallocSizeOfFun aMallocSizeOf, void *)
 {
   RuleHashTableEntry* entry = static_cast<RuleHashTableEntry*>(aHdr);
@@ -2109,21 +2037,16 @@ static bool SelectorMatches(Element* aEl
           !isNegated &&
           // important for |IsQuirkEventSensitive|:
           aElement->IsHTML() && !nsCSSRuleProcessor::IsLink(aElement) &&
           !IsQuirkEventSensitive(aElement->Tag())) {
         // In quirks mode, only make certain elements sensitive to
         // selectors ":hover" and ":active".
         return false;
       } else {
-        if (aTreeMatchContext.mForStyling &&
-            statesToCheck.HasAtLeastOneOfStates(NS_EVENT_STATE_HOVER)) {
-          // Mark the element as having :hover-dependent style
-          aElement->SetFlags(NODE_HAS_RELEVANT_HOVER_RULES);
-        }
         if (aNodeMatchContext.mStateMask.HasAtLeastOneOfStates(statesToCheck)) {
           if (aDependence)
             *aDependence = true;
         } else {
           nsEventStates contentState =
             nsCSSRuleProcessor::GetContentStateForVisitedHandling(
                                          aElement,
                                          aTreeMatchContext.VisitedHandling(),
@@ -2307,17 +2230,18 @@ static bool SelectorMatchesTree(Element*
       // descendant or general sibling combinator and the next
       // combinator is different, but we can make an exception for
       // sibling, then parent, since a sibling's parent is always the
       // same.
       if (NS_IS_GREEDY_OPERATOR(selector->mOperator) &&
           selector->mNext &&
           selector->mNext->mOperator != selector->mOperator &&
           !(selector->mOperator == '~' &&
-            NS_IS_ANCESTOR_OPERATOR(selector->mNext->mOperator))) {
+            (selector->mNext->mOperator == PRUnichar(' ') ||
+             selector->mNext->mOperator == PRUnichar('>')))) {
 
         // pretend the selector didn't match, and step through content
         // while testing the same selector
 
         // This approach is slightly strange in that when it recurs
         // it tests from the top of the content tree, down.  This
         // doesn't matter much for performance since most selectors
         // don't match.  (If most did, it might be faster...)
@@ -2336,39 +2260,30 @@ static bool SelectorMatchesTree(Element*
       }
     }
     prevElement = element;
   }
   return true; // all the selectors matched.
 }
 
 static inline
-void ContentEnumFunc(const RuleValue& value, nsCSSSelector* aSelector,
-                     RuleProcessorData* data, NodeMatchContext& nodeContext,
-                     AncestorFilter *ancestorFilter)
+void ContentEnumFunc(css::StyleRule* aRule, nsCSSSelector* aSelector,
+                     RuleProcessorData* data, NodeMatchContext& nodeContext)
 {
   if (nodeContext.mIsRelevantLink) {
     data->mTreeMatchContext.SetHaveRelevantLink();
   }
-  if (ancestorFilter &&
-      !ancestorFilter->MightHaveMatchingAncestor<
-        NS_ARRAY_LENGTH(value.mAncestorSelectorHashes)>(
-          value.mAncestorSelectorHashes)) {
-    // We won't match; nothing else to do here
-    return;
-  }
   if (SelectorMatches(data->mElement, aSelector, nodeContext,
                       data->mTreeMatchContext)) {
     nsCSSSelector *next = aSelector->mNext;
     if (!next || SelectorMatchesTree(data->mElement, next,
                                      data->mTreeMatchContext,
                                      !nodeContext.mIsRelevantLink)) {
-      css::StyleRule *rule = value.mRule;
-      rule->RuleMatched();
-      data->mRuleWalker->Forward(rule);
+      aRule->RuleMatched();
+      data->mRuleWalker->Forward(aRule);
       // nsStyleSet will deal with the !important rule
     }
   }
 }
 
 /* virtual */ void
 nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData)
 {
@@ -2428,18 +2343,18 @@ nsCSSRuleProcessor::RulesMatching(XULTre
                             PL_DHASH_LOOKUP));
     if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
       NodeMatchContext nodeContext(nsEventStates(),
                                    nsCSSRuleProcessor::IsLink(aData->mElement));
       nsTArray<RuleValue>& rules = entry->mRules;
       for (RuleValue *value = rules.Elements(), *end = value + rules.Length();
            value != end; ++value) {
         if (aData->mComparator->PseudoMatches(value->mSelector)) {
-          ContentEnumFunc(*value, value->mSelector->mNext, aData, nodeContext,
-                          nsnull);
+          ContentEnumFunc(value->mRule, value->mSelector->mNext, aData,
+                          nodeContext);
         }
       }
     }
   }
 }
 #endif
 
 static inline nsRestyleHint RestyleHintForOp(PRUnichar oper)
@@ -3260,104 +3175,8 @@ nsCSSRuleProcessor::SelectorListMatches(
       }
     }
 
     aSelectorList = aSelectorList->mNext;
   }
 
   return false;
 }
-
-// AncestorFilter out of line methods
-void
-AncestorFilter::Init(Element *aElement)
-{
-  MOZ_ASSERT(!mFilter);
-  MOZ_ASSERT(mHashes.IsEmpty());
-
-  mFilter = new Filter();
-
-  if (NS_LIKELY(aElement)) {
-    MOZ_ASSERT(aElement->IsInDoc(),
-               "aElement must be in the document for the assumption that "
-               "GetNodeParent() is non-null on all element ancestors of "
-               "aElement to be true");
-    // Collect up the ancestors
-    nsAutoTArray<Element*, 50> ancestors;
-    Element* cur = aElement;
-    do {
-      ancestors.AppendElement(cur);
-      nsINode* parent = cur->GetNodeParent();
-      if (!parent->IsElement()) {
-        break;
-      }
-      cur = parent->AsElement();
-    } while (true);
-
-    // Now push them in reverse order.
-    for (PRUint32 i = ancestors.Length(); i-- != 0; ) {
-      PushAncestor(ancestors[i]);
-    }
-  }
-}
-
-void
-AncestorFilter::PushAncestor(Element *aElement)
-{
-  MOZ_ASSERT(mFilter);
-
-  PRUint32 oldLength = mHashes.Length();
-
-  mPopTargets.AppendElement(oldLength);
-#ifdef DEBUG
-  mElements.AppendElement(aElement);
-#endif
-  mHashes.AppendElement(aElement->Tag()->hash());
-  nsIAtom *id = aElement->GetID();
-  if (id) {
-    mHashes.AppendElement(id->hash());
-  }
-  const nsAttrValue *classes = aElement->GetClasses();
-  if (classes) {
-    PRUint32 classCount = classes->GetAtomCount();
-    for (PRUint32 i = 0; i < classCount; ++i) {
-      mHashes.AppendElement(classes->AtomAt(i)->hash());
-    }
-  }
-
-  PRUint32 newLength = mHashes.Length();
-  for (PRUint32 i = oldLength; i < newLength; ++i) {
-    mFilter->add(mHashes[i]);
-  }
-}
-
-void
-AncestorFilter::PopAncestor()
-{
-  MOZ_ASSERT(!mPopTargets.IsEmpty());
-  MOZ_ASSERT(mPopTargets.Length() == mElements.Length());
-
-  PRUint32 popTargetLength = mPopTargets.Length();
-  PRUint32 newLength = mPopTargets[popTargetLength-1];
-
-  mPopTargets.TruncateLength(popTargetLength-1);
-#ifdef DEBUG
-  mElements.TruncateLength(popTargetLength-1);
-#endif
-
-  PRUint32 oldLength = mHashes.Length();
-  for (PRUint32 i = newLength; i < oldLength; ++i) {
-    mFilter->remove(mHashes[i]);
-  }
-  mHashes.TruncateLength(newLength);
-}
-
-#ifdef DEBUG
-void
-AncestorFilter::AssertHasAllAncestors(Element *aElement) const
-{
-  nsINode* cur = aElement->GetNodeParent();
-  while (cur && cur->IsElement()) {
-    MOZ_ASSERT(mElements.Contains(cur));
-    cur = cur->GetNodeParent();
-  }
-}
-#endif
--- a/layout/style/nsRuleProcessorData.h
+++ b/layout/style/nsRuleProcessorData.h
@@ -46,113 +46,23 @@
 
 #include "nsPresContext.h" // for nsCompatibility
 #include "nsString.h"
 #include "nsChangeHint.h"
 #include "nsIContent.h"
 #include "nsCSSPseudoElements.h"
 #include "nsRuleWalker.h"
 #include "nsNthIndexCache.h"
-#include "mozilla/BloomFilter.h"
-#include "mozilla/GuardObjects.h"
 
 class nsIStyleSheet;
 class nsIAtom;
 class nsICSSPseudoComparator;
 class nsAttrValue;
 
 /**
- * An AncestorFilter is used to keep track of ancestors so that we can
- * quickly tell that a particular selector is not relevant to a given
- * element.
- */
-class NS_STACK_CLASS AncestorFilter {
- public:
-  /**
-   * Initialize the filter.  If aElement is not null, it and all its
-   * ancestors will be passed to PushAncestor, starting from the root
-   * and going down the tree.
-   */
-  void Init(mozilla::dom::Element *aElement);
-
-  /* Maintenance of our ancestor state */
-  void PushAncestor(mozilla::dom::Element *aElement);
-  void PopAncestor();
-
-  /* Helper class for maintaining the ancestor state */
-  class NS_STACK_CLASS AutoAncestorPusher {
-  public:
-    AutoAncestorPusher(bool aDoPush,
-                       AncestorFilter &aFilter,
-                       mozilla::dom::Element *aElement
-                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : mPushed(aDoPush && aElement), mFilter(aFilter)
-    {
-      MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-      if (mPushed) {
-        mFilter.PushAncestor(aElement);
-      }
-    }
-    ~AutoAncestorPusher() {
-      if (mPushed) {
-        mFilter.PopAncestor();
-      }
-    }
-
-  private:
-    bool mPushed;
-    AncestorFilter &mFilter;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-  };
-
-  /* Check whether we might have an ancestor matching one of the given
-     atom hashes.  |hashes| must have length hashListLength */
-  template<size_t hashListLength>
-    bool MightHaveMatchingAncestor(const uint32_t* aHashes) const
-  {
-    MOZ_ASSERT(mFilter);
-    for (size_t i = 0; i < hashListLength && aHashes[i]; ++i) {
-      if (!mFilter->mightContain(aHashes[i])) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  bool HasFilter() const { return mFilter; }
-
-#ifdef DEBUG
-  void AssertHasAllAncestors(mozilla::dom::Element *aElement) const;
-#endif
-  
- private:
-  // Using 2^12 slots makes the Bloom filter a nice round page in
-  // size, so let's do that.  We get a false positive rate of 1% or
-  // less even with several hundred things in the filter.  Note that
-  // we allocate the filter lazily, because not all tree match
-  // contexts can use one effectively.
-  typedef mozilla::BloomFilter<12, nsIAtom> Filter;
-  nsAutoPtr<Filter> mFilter;
-
-  // Stack of indices to pop to.  These are indices into mHashes.
-  nsTArray<PRUint32> mPopTargets;
-
-  // List of hashes; this is what we pop using mPopTargets.  We store
-  // hashes of our ancestor element tag names, ids, and classes in
-  // here.
-  nsTArray<uint32_t> mHashes;
-
-  // A debug-only stack of Elements for use in assertions
-#ifdef DEBUG
-  nsTArray<mozilla::dom::Element*> mElements;
-#endif
-};
-
-/**
  * A |TreeMatchContext| has data about a matching operation.  The
  * data are not node-specific but are invariants of the DOM tree the
  * nodes being matched against are in.
  *
  * Most of the members are in parameters to selector matching.  The
  * one out parameter is mHaveRelevantLink.  Consumers that use a
  * TreeMatchContext for more than one matching operation and care
  * about :visited and mHaveRelevantLink need to
@@ -213,19 +123,16 @@ struct NS_STACK_CLASS TreeMatchContext {
 
   // Possibly remove use of mCompatMode in SelectorMatches?
   // XXX XBL2 issue: Should we be caching this?  What should it be for XBL2?
   const nsCompatibility mCompatMode;
 
   // The nth-index cache we should use
   nsNthIndexCache mNthIndexCache;
 
-  // An ancestor filter
-  AncestorFilter mAncestorFilter;
-
   // Constructor to use when creating a tree match context for styling
   TreeMatchContext(bool aForStyling,
                    nsRuleWalker::VisitedHandlingType aVisitedHandling,
                    nsIDocument* aDocument)
     : mForStyling(aForStyling)
     , mHaveRelevantLink(false)
     , mVisitedHandling(aVisitedHandling)
     , mDocument(aDocument)
--- a/mfbt/BloomFilter.h
+++ b/mfbt/BloomFilter.h
@@ -128,24 +128,24 @@ public:
     void remove(const T* t);
 
     /*
      * Check whether the filter might contain an item.  This can
      * sometimes return true even if the item is not in the filter,
      * but will never return false for items that are actually in the
      * filter.
      */
-    bool mightContain(const T* t) const;
+    bool mayContain(const T* t) const;
 
     /*
      * Methods for add/remove/contain when we already have a hash computed
      */
     void add(uint32_t hash);
     void remove(uint32_t hash);
-    bool mightContain(uint32_t hash) const;
+    bool mayContain(uint32_t hash) const;
 
 private:
     static const size_t arraySize = (1 << KeySize);
     static const uint32_t keyMask = (1 << KeySize) - 1;
     static const uint32_t keyShift = 16;
 
     static uint32_t hash1(uint32_t hash) { return hash & keyMask; }
     static uint32_t hash2(uint32_t hash) { return (hash >> keyShift) & keyMask; }
@@ -208,25 +208,25 @@ MOZ_ALWAYS_INLINE void
 BloomFilter<KeySize, T>::remove(const T* t)
 {
     uint32_t hash = t->hash();
     remove(hash);
 }
 
 template<unsigned KeySize, class T>
 MOZ_ALWAYS_INLINE bool
-BloomFilter<KeySize, T>::mightContain(uint32_t hash) const
+BloomFilter<KeySize, T>::mayContain(uint32_t hash) const
 {
     // Check that all the slots for this hash contain something
     return firstSlot(hash) && secondSlot(hash);
 }
 
 template<unsigned KeySize, class T>
 MOZ_ALWAYS_INLINE bool
-BloomFilter<KeySize, T>::mightContain(const T* t) const
+BloomFilter<KeySize, T>::mayContain(const T* t) const
 {
     uint32_t hash = t->hash();
-    return mightContain(hash);
+    return mayContain(hash);
 }
 
 } // namespace mozilla
 
 #endif /* mozilla_BloomFilter_h_ */
--- a/xpcom/tests/TestBloomFilter.cpp
+++ b/xpcom/tests/TestBloomFilter.cpp
@@ -27,94 +27,94 @@ int main()
   BloomFilter<12, FilterChecker> *filter = new BloomFilter<12, FilterChecker>();
 
   FilterChecker one(1);
   FilterChecker two(0x20000);
   FilterChecker many(0x10000);
   FilterChecker multiple(0x20001);
 
   filter->add(&one);
-  if (!filter->mightContain(&one)) {
+  if (!filter->mayContain(&one)) {
     fail("Filter should contain 'one'");
     return -1;
   }
 
-  if (filter->mightContain(&multiple)) {
+  if (filter->mayContain(&multiple)) {
     fail("Filter claims to contain 'multiple' when it should not");
     return -1;
   }
 
-  if (!filter->mightContain(&many)) {
+  if (!filter->mayContain(&many)) {
     fail("Filter should contain 'many' (false positive)");
     return -1;
   }
 
   filter->add(&two);
-  if (!filter->mightContain(&multiple)) {
+  if (!filter->mayContain(&multiple)) {
     fail("Filter should contain 'multiple' (false positive)");
     return -1;
   }
 
   // Test basic removals
   filter->remove(&two);
-  if (filter->mightContain(&multiple)) {
+  if (filter->mayContain(&multiple)) {
     fail("Filter claims to contain 'multiple' when it should not after two was "
          "removed");
     return -1;
   }
 
   // Test multiple addition/removal
   const unsigned FILTER_SIZE = 255;
   for (unsigned i = 0; i < FILTER_SIZE - 1; ++i) {
     filter->add(&two);
   }
-  if (!filter->mightContain(&multiple)) {
+  if (!filter->mayContain(&multiple)) {
     fail("Filter should contain 'multiple' after 'two' added lots of times "
          "(false positive)");
     return -1;
   }
   for (unsigned i = 0; i < FILTER_SIZE - 1; ++i) {
     filter->remove(&two);
   }
-  if (filter->mightContain(&multiple)) {
+  if (filter->mayContain(&multiple)) {
     fail("Filter claims to contain 'multiple' when it should not after two was "
          "removed lots of times");
     return -1;
   }
 
   // Test overflowing the filter buckets
   for (unsigned i = 0; i < FILTER_SIZE + 1; ++i) {
     filter->add(&two);
   }
-  if (!filter->mightContain(&multiple)) {
+  if (!filter->mayContain(&multiple)) {
     fail("Filter should contain 'multiple' after 'two' added lots more times "
          "(false positive)");
     return -1;
   }
   for (unsigned i = 0; i < FILTER_SIZE + 1; ++i) {
     filter->remove(&two);
   }
-  if (!filter->mightContain(&multiple)) {
+  if (!filter->mayContain(&multiple)) {
     fail("Filter claims to not contain 'multiple' even though we should have "
          "run out of space in the buckets (false positive)");
     return -1;
   }
-  if (!filter->mightContain(&two)) {
+  if (!filter->mayContain(&two)) {
     fail("Filter claims to not contain 'two' even though we should have run "
          "out of space in the buckets (false positive)");
     return -1;
   }
 
   filter->remove(&one);
-  if (filter->mightContain(&one)) {
+  if (filter->mayContain(&one)) {
     fail("Filter should not contain 'one', because we didn't overflow its "
          "bucket");
     return -1;
   }
   
   filter->clear();
-  if (filter->mightContain(&multiple)) {
+  if (filter->mayContain(&multiple)) {
     fail("clear() failed to work");
     return -1;
   }
 
   return 0;
 }