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 88915 f925f2f8d1fd474de2463ce949d03403714a23ac
parent 88914 83a33626d9658fd26deef1f8141a525033bd9223
child 88916 6799a5e6912f834ebbd8e94c74c34c34f20a92f5
push id603
push usertim.taubert@gmx.de
push dateTue, 13 Mar 2012 10:29:11 +0000
treeherderfx-team@ee4e0c98cb02 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs732667, 705877
milestone13.0a1
backs out83a33626d9658fd26deef1f8141a525033bd9223
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;
 }