| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org> | 2 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org> |
| 3 * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. | 3 * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. |
| 4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * | 9 * |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 | 58 |
| 59 void Step::optimize() { | 59 void Step::optimize() { |
| 60 // Evaluate predicates as part of node test if possible to avoid building | 60 // Evaluate predicates as part of node test if possible to avoid building |
| 61 // unnecessary NodeSets. | 61 // unnecessary NodeSets. |
| 62 // E.g., there is no need to build a set of all "foo" nodes to evaluate | 62 // E.g., there is no need to build a set of all "foo" nodes to evaluate |
| 63 // "foo[@bar]", we can check the predicate while enumerating. | 63 // "foo[@bar]", we can check the predicate while enumerating. |
| 64 // This optimization can be applied to predicates that are not context node | 64 // This optimization can be applied to predicates that are not context node |
| 65 // list sensitive, or to first predicate that is only context position | 65 // list sensitive, or to first predicate that is only context position |
| 66 // sensitive, e.g. foo[position() mod 2 = 0]. | 66 // sensitive, e.g. foo[position() mod 2 = 0]. |
| 67 HeapVector<Member<Predicate>> remainingPredicates; | 67 HeapVector<Member<Predicate>> remainingPredicates; |
| 68 for (size_t i = 0; i < m_predicates.size(); ++i) { | 68 for (const auto& predicate : m_predicates) { |
| 69 Predicate* predicate = m_predicates[i]; | |
| 70 if ((!predicate->isContextPositionSensitive() || | 69 if ((!predicate->isContextPositionSensitive() || |
| 71 nodeTest().mergedPredicates().isEmpty()) && | 70 nodeTest().mergedPredicates().isEmpty()) && |
| 72 !predicate->isContextSizeSensitive() && remainingPredicates.isEmpty()) { | 71 !predicate->isContextSizeSensitive() && remainingPredicates.isEmpty()) { |
| 73 nodeTest().mergedPredicates().append(predicate); | 72 nodeTest().mergedPredicates().append(predicate); |
| 74 } else { | 73 } else { |
| 75 remainingPredicates.append(predicate); | 74 remainingPredicates.append(predicate); |
| 76 } | 75 } |
| 77 } | 76 } |
| 78 swap(remainingPredicates, m_predicates); | 77 swap(remainingPredicates, m_predicates); |
| 79 } | 78 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 98 first->nodeTest().mergedPredicates()); | 97 first->nodeTest().mergedPredicates()); |
| 99 swap(second->m_predicates, first->m_predicates); | 98 swap(second->m_predicates, first->m_predicates); |
| 100 first->optimize(); | 99 first->optimize(); |
| 101 return true; | 100 return true; |
| 102 } | 101 } |
| 103 } | 102 } |
| 104 return false; | 103 return false; |
| 105 } | 104 } |
| 106 | 105 |
| 107 bool Step::predicatesAreContextListInsensitive() const { | 106 bool Step::predicatesAreContextListInsensitive() const { |
| 108 for (size_t i = 0; i < m_predicates.size(); ++i) { | 107 for (const auto& predicate : m_predicates) { |
| 109 Predicate* predicate = m_predicates[i].get(); | |
| 110 if (predicate->isContextPositionSensitive() || | 108 if (predicate->isContextPositionSensitive() || |
| 111 predicate->isContextSizeSensitive()) | 109 predicate->isContextSizeSensitive()) |
| 112 return false; | 110 return false; |
| 113 } | 111 } |
| 114 | 112 |
| 115 for (size_t i = 0; i < nodeTest().mergedPredicates().size(); ++i) { | 113 for (const auto& predicate : nodeTest().mergedPredicates()) { |
| 116 Predicate* predicate = nodeTest().mergedPredicates()[i].get(); | |
| 117 if (predicate->isContextPositionSensitive() || | 114 if (predicate->isContextPositionSensitive() || |
| 118 predicate->isContextSizeSensitive()) | 115 predicate->isContextSizeSensitive()) |
| 119 return false; | 116 return false; |
| 120 } | 117 } |
| 121 | 118 |
| 122 return true; | 119 return true; |
| 123 } | 120 } |
| 124 | 121 |
| 125 void Step::evaluate(EvaluationContext& evaluationContext, | 122 void Step::evaluate(EvaluationContext& evaluationContext, |
| 126 Node* context, | 123 Node* context, |
| 127 NodeSet& nodes) const { | 124 NodeSet& nodes) const { |
| 128 evaluationContext.position = 0; | 125 evaluationContext.position = 0; |
| 129 | 126 |
| 130 nodesInAxis(evaluationContext, context, nodes); | 127 nodesInAxis(evaluationContext, context, nodes); |
| 131 | 128 |
| 132 // Check predicates that couldn't be merged into node test. | 129 // Check predicates that couldn't be merged into node test. |
| 133 for (unsigned i = 0; i < m_predicates.size(); i++) { | 130 for (const auto& predicate : m_predicates) { |
| 134 Predicate* predicate = m_predicates[i].get(); | |
| 135 | |
| 136 NodeSet* newNodes = NodeSet::create(); | 131 NodeSet* newNodes = NodeSet::create(); |
| 137 if (!nodes.isSorted()) | 132 if (!nodes.isSorted()) |
| 138 newNodes->markSorted(false); | 133 newNodes->markSorted(false); |
| 139 | 134 |
| 140 for (unsigned j = 0; j < nodes.size(); j++) { | 135 for (unsigned j = 0; j < nodes.size(); j++) { |
| 141 Node* node = nodes[j]; | 136 Node* node = nodes[j]; |
| 142 | 137 |
| 143 evaluationContext.node = node; | 138 evaluationContext.node = node; |
| 144 evaluationContext.size = nodes.size(); | 139 evaluationContext.size = nodes.size(); |
| 145 evaluationContext.position = j + 1; | 140 evaluationContext.position = j + 1; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 static inline bool nodeMatches(EvaluationContext& evaluationContext, | 234 static inline bool nodeMatches(EvaluationContext& evaluationContext, |
| 240 Node* node, | 235 Node* node, |
| 241 Step::Axis axis, | 236 Step::Axis axis, |
| 242 const Step::NodeTest& nodeTest) { | 237 const Step::NodeTest& nodeTest) { |
| 243 if (!nodeMatchesBasicTest(node, axis, nodeTest)) | 238 if (!nodeMatchesBasicTest(node, axis, nodeTest)) |
| 244 return false; | 239 return false; |
| 245 | 240 |
| 246 // Only the first merged predicate may depend on position. | 241 // Only the first merged predicate may depend on position. |
| 247 ++evaluationContext.position; | 242 ++evaluationContext.position; |
| 248 | 243 |
| 249 const HeapVector<Member<Predicate>>& mergedPredicates = | 244 for (const auto& predicate : nodeTest.mergedPredicates()) { |
| 250 nodeTest.mergedPredicates(); | |
| 251 for (unsigned i = 0; i < mergedPredicates.size(); i++) { | |
| 252 Predicate* predicate = mergedPredicates[i].get(); | |
| 253 | |
| 254 evaluationContext.node = node; | 245 evaluationContext.node = node; |
| 255 // No need to set context size - we only get here when evaluating | 246 // No need to set context size - we only get here when evaluating |
| 256 // predicates that do not depend on it. | 247 // predicates that do not depend on it. |
| 257 if (!predicate->evaluate(evaluationContext)) | 248 if (!predicate->evaluate(evaluationContext)) |
| 258 return false; | 249 return false; |
| 259 } | 250 } |
| 260 | 251 |
| 261 return true; | 252 return true; |
| 262 } | 253 } |
| 263 | 254 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 nodes.markSorted(false); | 438 nodes.markSorted(false); |
| 448 return; | 439 return; |
| 449 } | 440 } |
| 450 } | 441 } |
| 451 NOTREACHED(); | 442 NOTREACHED(); |
| 452 } | 443 } |
| 453 | 444 |
| 454 } // namespace XPath | 445 } // namespace XPath |
| 455 | 446 |
| 456 } // namespace blink | 447 } // namespace blink |
| OLD | NEW |