 Chromium Code Reviews
 Chromium Code Reviews Issue 1317533002:
  Sibling invalidation sets  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master
    
  
    Issue 1317533002:
  Sibling invalidation sets  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master| OLD | NEW | 
|---|---|
| 1 | 1 | 
| 2 // Copyright 2014 The Chromium Authors. All rights reserved. | 2 // Copyright 2014 The Chromium Authors. All rights reserved. | 
| 3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be | 
| 4 // found in the LICENSE file. | 4 // found in the LICENSE file. | 
| 5 | 5 | 
| 6 #include "config.h" | 6 #include "config.h" | 
| 7 | 7 | 
| 8 #include "core/css/invalidation/StyleInvalidator.h" | 8 #include "core/css/invalidation/StyleInvalidator.h" | 
| 9 | 9 | 
| 10 #include "core/css/invalidation/DescendantInvalidationSet.h" | 10 #include "core/css/invalidation/InvalidationSet.h" | 
| 11 #include "core/dom/Document.h" | 11 #include "core/dom/Document.h" | 
| 12 #include "core/dom/Element.h" | 12 #include "core/dom/Element.h" | 
| 13 #include "core/dom/ElementTraversal.h" | 13 #include "core/dom/ElementTraversal.h" | 
| 14 #include "core/dom/shadow/ElementShadow.h" | 14 #include "core/dom/shadow/ElementShadow.h" | 
| 15 #include "core/dom/shadow/ShadowRoot.h" | 15 #include "core/dom/shadow/ShadowRoot.h" | 
| 16 #include "core/inspector/InspectorTraceEvents.h" | 16 #include "core/inspector/InspectorTraceEvents.h" | 
| 17 #include "core/layout/LayoutObject.h" | 17 #include "core/layout/LayoutObject.h" | 
| 18 | 18 | 
| 19 namespace blink { | 19 namespace blink { | 
| 20 | 20 | 
| 21 // StyleInvalidator methods are super sensitive to performance benchmarks. | 21 // StyleInvalidator methods are super sensitive to performance benchmarks. | 
| 22 // We easily get 1% regression per additional if statement on recursive | 22 // We easily get 1% regression per additional if statement on recursive | 
| 23 // invalidate methods. | 23 // invalidate methods. | 
| 24 // To minimize performance impact, we wrap trace events with a lookup of | 24 // To minimize performance impact, we wrap trace events with a lookup of | 
| 25 // cached flag. The cached flag is made "static const" and is not shared | 25 // cached flag. The cached flag is made "static const" and is not shared | 
| 26 // with DescendantInvalidationSet to avoid additional GOT lookup cost. | 26 // with InvalidationSet to avoid additional GOT lookup cost. | 
| 27 static const unsigned char* s_tracingEnabled = nullptr; | 27 static const unsigned char* s_tracingEnabled = nullptr; | 
| 28 | 28 | 
| 29 #define TRACE_STYLE_INVALIDATOR_INVALIDATION_IF_ENABLED(element, reason) \ | 29 #define TRACE_STYLE_INVALIDATOR_INVALIDATION_IF_ENABLED(element, reason) \ | 
| 30 if (UNLIKELY(*s_tracingEnabled)) \ | 30 if (UNLIKELY(*s_tracingEnabled)) \ | 
| 31 TRACE_STYLE_INVALIDATOR_INVALIDATION(element, reason); | 31 TRACE_STYLE_INVALIDATOR_INVALIDATION(element, reason); | 
| 32 | 32 | 
| 33 void StyleInvalidator::invalidate(Document& document) | 33 void StyleInvalidator::invalidate(Document& document) | 
| 34 { | 34 { | 
| 35 RecursionData recursionData; | 35 RecursionData recursionData; | 
| 36 SiblingData siblingData; | |
| 36 if (Element* documentElement = document.documentElement()) | 37 if (Element* documentElement = document.documentElement()) | 
| 37 invalidate(*documentElement, recursionData); | 38 invalidate(*documentElement, recursionData, siblingData); | 
| 38 document.clearChildNeedsStyleInvalidation(); | 39 document.clearChildNeedsStyleInvalidation(); | 
| 39 document.clearNeedsStyleInvalidation(); | 40 document.clearNeedsStyleInvalidation(); | 
| 40 clearPendingInvalidations(); | 41 clearPendingInvalidations(); | 
| 41 } | 42 } | 
| 42 | 43 | 
| 43 void StyleInvalidator::scheduleInvalidation(PassRefPtrWillBeRawPtr<DescendantInv alidationSet> invalidationSet, Element& element) | 44 void StyleInvalidator::scheduleInvalidationSetsForElement(const InvalidationSetV ector& descendant, const InvalidationSetVector& sibling, Element& element) | 
| 44 { | 45 { | 
| 45 ASSERT(element.inActiveDocument()); | 46 ASSERT(element.inActiveDocument()); | 
| 46 if (element.styleChangeType() >= SubtreeStyleChange) | 47 | 
| 47 return; | 48 bool requiresDescendantInvalidation = false; | 
| 48 if (invalidationSet->wholeSubtreeInvalid()) { | 49 if (element.styleChangeType() < SubtreeStyleChange) { | 
| 49 element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTrac ing::create(StyleChangeReason::StyleInvalidator)); | 50 for (auto& invalidationSet : descendant) { | 
| 50 clearInvalidation(element); | 51 if (invalidationSet->wholeSubtreeInvalid()) { | 
| 51 return; | 52 element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReaso nForTracing::create(StyleChangeReason::StyleInvalidator)); | 
| 52 } | 53 requiresDescendantInvalidation = false; | 
| 53 if (invalidationSet->isEmpty()) { | 54 break; | 
| 
Timothy Loh
2015/09/10 06:09:40
this could possibly still be an early return, as w
 
Eric Willigers
2015/09/14 07:20:24
Done.
 | |
| 54 element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracin g::create(StyleChangeReason::StyleInvalidator)); | 55 } | 
| 55 return; | 56 | 
| 57 ASSERT(invalidationSet->appliesDirectly() || !invalidationSet->isEmp ty()); | |
| 58 if (invalidationSet->appliesDirectly()) | |
| 59 element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonF orTracing::create(StyleChangeReason::StyleInvalidator)); | |
| 60 if (!invalidationSet->isEmpty()) | |
| 61 requiresDescendantInvalidation = true; | |
| 62 } | |
| 56 } | 63 } | 
| 57 | 64 | 
| 58 InvalidationList& list = ensurePendingInvalidationList(element); | 65 if (sibling.isEmpty() && !requiresDescendantInvalidation) | 
| 59 list.append(invalidationSet); | 66 return; | 
| 67 | |
| 60 element.setNeedsStyleInvalidation(); | 68 element.setNeedsStyleInvalidation(); | 
| 61 } | 69 InvalidationListData& listData = ensurePendingInvalidationListData(element); | 
| 62 | 70 | 
| 63 StyleInvalidator::InvalidationList& StyleInvalidator::ensurePendingInvalidationL ist(Element& element) | 71 for (auto& invalidationSet : sibling) | 
| 64 { | 72 listData.siblings().append(invalidationSet); | 
| 65 PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(& element, nullptr); | 73 | 
| 66 if (addResult.isNewEntry) | 74 if (!requiresDescendantInvalidation) | 
| 67 addResult.storedValue->value = adoptPtrWillBeNoop(new InvalidationList); | 75 return; | 
| 68 return *addResult.storedValue->value; | 76 | 
| 77 for (auto& invalidationSet : descendant) { | |
| 78 ASSERT(!invalidationSet->wholeSubtreeInvalid()); | |
| 79 if (!invalidationSet->isEmpty()) | |
| 80 listData.descendants().append(invalidationSet); | |
| 81 } | |
| 69 } | 82 } | 
| 70 | 83 | 
| 71 void StyleInvalidator::clearInvalidation(Element& element) | 84 void StyleInvalidator::clearInvalidation(Element& element) | 
| 72 { | 85 { | 
| 73 if (!element.needsStyleInvalidation()) | 86 if (!element.needsStyleInvalidation()) | 
| 74 return; | 87 return; | 
| 75 m_pendingInvalidationMap.remove(&element); | 88 m_pendingInvalidationMap.remove(&element); | 
| 76 element.clearNeedsStyleInvalidation(); | 89 element.clearNeedsStyleInvalidation(); | 
| 77 } | 90 } | 
| 78 | 91 | 
| 92 InvalidationListData& StyleInvalidator::ensurePendingInvalidationListData(Elemen t& element) | |
| 93 { | |
| 94 PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(& element, nullptr); | |
| 95 if (addResult.isNewEntry) | |
| 96 addResult.storedValue->value = InvalidationListData::create(); | |
| 97 return *addResult.storedValue->value; | |
| 98 } | |
| 99 | |
| 79 void StyleInvalidator::clearPendingInvalidations() | 100 void StyleInvalidator::clearPendingInvalidations() | 
| 80 { | 101 { | 
| 81 m_pendingInvalidationMap.clear(); | 102 m_pendingInvalidationMap.clear(); | 
| 82 } | 103 } | 
| 83 | 104 | 
| 84 StyleInvalidator::StyleInvalidator() | 105 StyleInvalidator::StyleInvalidator() | 
| 85 { | 106 { | 
| 86 s_tracingEnabled = TRACE_EVENT_API_GET_CATEGORY_ENABLED(TRACE_DISABLED_BY_DE FAULT("devtools.timeline.invalidationTracking")); | 107 s_tracingEnabled = TRACE_EVENT_API_GET_CATEGORY_ENABLED(TRACE_DISABLED_BY_DE FAULT("devtools.timeline.invalidationTracking")); | 
| 87 DescendantInvalidationSet::cacheTracingFlag(); | 108 InvalidationSet::cacheTracingFlag(); | 
| 88 } | 109 } | 
| 89 | 110 | 
| 90 StyleInvalidator::~StyleInvalidator() | 111 StyleInvalidator::~StyleInvalidator() | 
| 91 { | 112 { | 
| 92 } | 113 } | 
| 93 | 114 | 
| 94 void StyleInvalidator::RecursionData::pushInvalidationSet(const DescendantInvali dationSet& invalidationSet) | 115 void StyleInvalidator::RecursionData::pushInvalidationSet(const InvalidationSet& invalidationSet) | 
| 95 { | 116 { | 
| 96 ASSERT(!m_wholeSubtreeInvalid); | 117 ASSERT(!m_wholeSubtreeInvalid); | 
| 97 ASSERT(!invalidationSet.wholeSubtreeInvalid()); | 118 ASSERT(!invalidationSet.wholeSubtreeInvalid()); | 
| 98 ASSERT(!invalidationSet.isEmpty()); | 119 ASSERT(!invalidationSet.isEmpty()); | 
| 99 if (invalidationSet.treeBoundaryCrossing()) | 120 if (invalidationSet.treeBoundaryCrossing()) | 
| 100 m_treeBoundaryCrossing = true; | 121 m_treeBoundaryCrossing = true; | 
| 101 if (invalidationSet.insertionPointCrossing()) | 122 if (invalidationSet.insertionPointCrossing()) | 
| 102 m_insertionPointCrossing = true; | 123 m_insertionPointCrossing = true; | 
| 103 m_invalidationSets.append(&invalidationSet); | 124 m_invalidationSets.append(&invalidationSet); | 
| 104 m_invalidateCustomPseudo = invalidationSet.customPseudoInvalid(); | 125 m_invalidateCustomPseudo = invalidationSet.customPseudoInvalid(); | 
| 105 } | 126 } | 
| 106 | 127 | 
| 107 ALWAYS_INLINE bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSe ts(Element& element) | 128 ALWAYS_INLINE bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSe ts(Element& element) const | 
| 108 { | 129 { | 
| 109 if (m_invalidateCustomPseudo && element.shadowPseudoId() != nullAtom) { | 130 if (m_invalidateCustomPseudo && element.shadowPseudoId() != nullAtom) { | 
| 110 TRACE_STYLE_INVALIDATOR_INVALIDATION_IF_ENABLED(element, InvalidateCusto mPseudo); | 131 TRACE_STYLE_INVALIDATOR_INVALIDATION_IF_ENABLED(element, InvalidateCusto mPseudo); | 
| 111 return true; | 132 return true; | 
| 112 } | 133 } | 
| 113 | 134 | 
| 114 if (m_insertionPointCrossing && element.isInsertionPoint()) | 135 if (m_insertionPointCrossing && element.isInsertionPoint()) | 
| 115 return true; | 136 return true; | 
| 116 | 137 | 
| 117 for (const auto& invalidationSet : m_invalidationSets) { | 138 for (const auto& invalidationSet : m_invalidationSets) { | 
| 118 if (invalidationSet->invalidatesElement(element)) | 139 if (invalidationSet->invalidatesElement(element)) | 
| 119 return true; | 140 return true; | 
| 120 } | 141 } | 
| 121 | 142 | 
| 122 return false; | 143 return false; | 
| 123 } | 144 } | 
| 124 | 145 | 
| 125 ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element & element, StyleInvalidator::RecursionData& recursionData) | 146 void StyleInvalidator::SiblingData::pushInvalidationSet(const InvalidationSet& i nvalidationSet) | 
| 147 { | |
| 148 unsigned invalidationLimit; | |
| 149 if (invalidationSet.maxDirectAdjacentSelectors() == std::numeric_limits<unsi gned>::max()) | |
| 150 invalidationLimit = std::numeric_limits<unsigned>::max(); | |
| 151 else | |
| 152 invalidationLimit = m_elementIndex + invalidationSet.maxDirectAdjacentSe lectors(); | |
| 153 m_invalidationEntries.append(Entry { &invalidationSet, invalidationLimit }); | |
| 
Timothy Loh
2015/09/10 06:09:40
this is banned https://chromium-cpp.appspot.com/ :
 
Eric Willigers
2015/09/14 07:20:24
Fixed.
 | |
| 154 } | |
| 155 | |
| 156 ALWAYS_INLINE bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(E lement& element, RecursionData& recursionData) | |
| 157 { | |
| 158 bool thisElementNeedsStyleRecalc = false; | |
| 159 ASSERT(!recursionData.wholeSubtreeInvalid()); | |
| 160 | |
| 161 unsigned index = 0; | |
| 162 while (index < m_invalidationEntries.size()) { | |
| 163 if (m_elementIndex > m_invalidationEntries[index].invalidationLimit) { | |
| 164 m_invalidationEntries[index] = m_invalidationEntries[m_invalidationE ntries.size() - 1]; | |
| 
Timothy Loh
2015/09/10 06:09:40
.last() I think?
 
Eric Willigers
2015/09/14 07:20:24
Done.
 | |
| 165 m_invalidationEntries.removeLast(); | |
| 166 continue; | |
| 167 } | |
| 168 | |
| 169 const InvalidationSet* invalidationSet = m_invalidationEntries[index].in validationSet.get(); | |
| 170 | |
| 171 if (invalidationSet->invalidatesElement(element)) { | |
| 172 ASSERT(invalidationSet->appliesDirectly() || invalidationSet->descen dants()); | |
| 173 if (invalidationSet->appliesDirectly()) | |
| 174 thisElementNeedsStyleRecalc = true; | |
| 175 if (const InvalidationSet* descendants = invalidationSet->descendant s()) { | |
| 176 if (descendants->wholeSubtreeInvalid()) { | |
| 177 // Avoid directly setting SubtreeStyleChange on element, or ContainerNode::checkForChildrenAdjacentRuleChanges() | |
| 178 // may propagate the SubtreeStyleChange to our own siblings' subtrees. | |
| 179 | |
| 180 for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) { | |
| 181 child->setNeedsStyleRecalc(SubtreeStyleChange, StyleChan geReasonForTracing::create(StyleChangeReason::SiblingSelector)); | |
| 182 } | |
| 183 return true; | |
| 184 } | |
| 185 | |
| 186 recursionData.pushInvalidationSet(*descendants); | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 ++index; | |
| 191 } | |
| 192 return thisElementNeedsStyleRecalc; | |
| 193 } | |
| 194 | |
| 195 ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element & element, RecursionData& recursionData, SiblingData& siblingData) | |
| 126 { | 196 { | 
| 127 if (element.styleChangeType() >= SubtreeStyleChange || recursionData.wholeSu btreeInvalid()) { | 197 if (element.styleChangeType() >= SubtreeStyleChange || recursionData.wholeSu btreeInvalid()) { | 
| 128 recursionData.setWholeSubtreeInvalid(); | 198 recursionData.setWholeSubtreeInvalid(); | 
| 129 return false; | 199 return false; | 
| 130 } | 200 } | 
| 131 if (element.needsStyleInvalidation()) { | 201 | 
| 132 if (InvalidationList* invalidationList = m_pendingInvalidationMap.get(&e lement)) { | 202 bool thisElementNeedsStyleRecalc = recursionData.matchesCurrentInvalidationS ets(element); | 
| 133 for (const auto& invalidationSet : *invalidationList) | 203 thisElementNeedsStyleRecalc |= siblingData.matchCurrentInvalidationSets(elem ent, recursionData); | 
| 204 | |
| 205 if (UNLIKELY(element.needsStyleInvalidation())) { | |
| 206 InvalidationListData* listData = m_pendingInvalidationMap.get(&element); | |
| 207 ASSERT(listData); | |
| 208 | |
| 209 if (!listData->descendants().isEmpty()) { | |
| 210 for (const auto& invalidationSet : listData->descendants()) | |
| 134 recursionData.pushInvalidationSet(*invalidationSet); | 211 recursionData.pushInvalidationSet(*invalidationSet); | 
| 135 if (UNLIKELY(*s_tracingEnabled)) { | 212 if (UNLIKELY(*s_tracingEnabled)) { | 
| 136 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timelin e.invalidationTracking"), | 213 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timelin e.invalidationTracking"), | 
| 137 "StyleInvalidatorInvalidationTracking", | 214 "StyleInvalidatorInvalidationTracking", | 
| 138 TRACE_EVENT_SCOPE_THREAD, | 215 TRACE_EVENT_SCOPE_THREAD, | 
| 139 "data", InspectorStyleInvalidatorInvalidateEvent::invalidati onList(element, *invalidationList)); | 216 "data", InspectorStyleInvalidatorInvalidateEvent::invalidati onList(element, listData->descendants())); | 
| 140 } | 217 } | 
| 141 return true; | |
| 142 } | 218 } | 
| 219 | |
| 220 for (const auto& invalidationSet : listData->siblings()) | |
| 221 siblingData.pushInvalidationSet(*invalidationSet); | |
| 143 } | 222 } | 
| 144 | 223 | 
| 145 return recursionData.matchesCurrentInvalidationSets(element); | 224 return thisElementNeedsStyleRecalc; | 
| 146 } | 225 } | 
| 147 | 226 | 
| 148 bool StyleInvalidator::invalidateChildren(Element& element, StyleInvalidator::Re cursionData& recursionData) | 227 bool StyleInvalidator::invalidateChildren(Element& element, RecursionData& recur sionData) | 
| 149 { | 228 { | 
| 229 SiblingData siblingData; | |
| 230 | |
| 150 bool someChildrenNeedStyleRecalc = false; | 231 bool someChildrenNeedStyleRecalc = false; | 
| 151 for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->old erShadowRoot()) { | 232 for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->old erShadowRoot()) { | 
| 152 if (!recursionData.treeBoundaryCrossing() && !root->childNeedsStyleInval idation() && !root->needsStyleInvalidation()) | 233 if (!recursionData.treeBoundaryCrossing() && !root->childNeedsStyleInval idation() && !root->needsStyleInvalidation()) | 
| 153 continue; | 234 continue; | 
| 154 for (Element* child = ElementTraversal::firstChild(*root); child; child = ElementTraversal::nextSibling(*child)) { | 235 for (Element* child = ElementTraversal::firstChild(*root); child; child = ElementTraversal::nextSibling(*child)) { | 
| 155 bool childRecalced = invalidate(*child, recursionData); | 236 bool childRecalced = invalidate(*child, recursionData, siblingData); | 
| 156 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRe calced; | 237 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRe calced; | 
| 157 } | 238 } | 
| 158 root->clearChildNeedsStyleInvalidation(); | 239 root->clearChildNeedsStyleInvalidation(); | 
| 159 root->clearNeedsStyleInvalidation(); | 240 root->clearNeedsStyleInvalidation(); | 
| 160 } | 241 } | 
| 161 for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) { | 242 for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) { | 
| 162 bool childRecalced = invalidate(*child, recursionData); | 243 bool childRecalced = invalidate(*child, recursionData, siblingData); | 
| 163 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalc ed; | 244 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalc ed; | 
| 164 } | 245 } | 
| 165 return someChildrenNeedStyleRecalc; | 246 return someChildrenNeedStyleRecalc; | 
| 166 } | 247 } | 
| 167 | 248 | 
| 168 bool StyleInvalidator::invalidate(Element& element, StyleInvalidator::RecursionD ata& recursionData) | 249 bool StyleInvalidator::invalidate(Element& element, RecursionData& recursionData , SiblingData& siblingData) | 
| 169 { | 250 { | 
| 170 RecursionCheckpoint checkpoint(&recursionData); | 251 RecursionCheckpoint checkpoint(&recursionData); | 
| 252 siblingData.advance(); | |
| 171 | 253 | 
| 172 bool thisElementNeedsStyleRecalc = checkInvalidationSetsAgainstElement(eleme nt, recursionData); | 254 bool thisElementNeedsStyleRecalc = checkInvalidationSetsAgainstElement(eleme nt, recursionData, siblingData); | 
| 173 | 255 | 
| 174 bool someChildrenNeedStyleRecalc = false; | 256 bool someChildrenNeedStyleRecalc = false; | 
| 175 if (recursionData.hasInvalidationSets() || element.childNeedsStyleInvalidati on()) | 257 if (recursionData.hasInvalidationSets() || element.childNeedsStyleInvalidati on()) | 
| 176 someChildrenNeedStyleRecalc = invalidateChildren(element, recursionData) ; | 258 someChildrenNeedStyleRecalc = invalidateChildren(element, recursionData) ; | 
| 177 | 259 | 
| 178 if (thisElementNeedsStyleRecalc) { | 260 if (thisElementNeedsStyleRecalc) { | 
| 179 ASSERT(!recursionData.wholeSubtreeInvalid()); | 261 ASSERT(!recursionData.wholeSubtreeInvalid()); | 
| 180 element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracin g::create(StyleChangeReason::StyleInvalidator)); | 262 element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracin g::create(StyleChangeReason::StyleInvalidator)); | 
| 181 } else if (recursionData.hasInvalidationSets() && someChildrenNeedStyleRecal c) { | 263 } else if (recursionData.hasInvalidationSets() && someChildrenNeedStyleRecal c) { | 
| 182 // Clone the ComputedStyle in order to preserve correct style sharing, i f possible. Otherwise recalc style. | 264 // Clone the ComputedStyle in order to preserve correct style sharing, i f possible. Otherwise recalc style. | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 198 } | 280 } | 
| 199 | 281 | 
| 200 DEFINE_TRACE(StyleInvalidator) | 282 DEFINE_TRACE(StyleInvalidator) | 
| 201 { | 283 { | 
| 202 #if ENABLE(OILPAN) | 284 #if ENABLE(OILPAN) | 
| 203 visitor->trace(m_pendingInvalidationMap); | 285 visitor->trace(m_pendingInvalidationMap); | 
| 204 #endif | 286 #endif | 
| 205 } | 287 } | 
| 206 | 288 | 
| 207 } // namespace blink | 289 } // namespace blink | 
| OLD | NEW |