Log Message
[Content Extensions] Cache domain actions https://bugs.webkit.org/show_bug.cgi?id=146817
Reviewed by Benjamin Poulain. Source/WebCore: Right now we run regular expressions on the domain every time we have any rules that match with if-domain or unless-domain. This caches the results of running regular expressions on the domain of the main document's url so we only need to run those regular expressions when the main document changes domain. We also spend less time adding unused actions into HashSets. All behavior is covered by existing api tests, but I added some to explicitly test if-domain and unless-domain with multiple load types. * contentextensions/ContentExtension.cpp: (WebCore::ContentExtensions::ContentExtension::globalDisplayNoneStyleSheet): (WebCore::ContentExtensions::ContentExtension::cachedDomainActions): * contentextensions/ContentExtension.h: (WebCore::ContentExtensions::ContentExtension::identifier): (WebCore::ContentExtensions::ContentExtension::compiledExtension): * contentextensions/ContentExtensionsBackend.cpp: (WebCore::ContentExtensions::ContentExtensionsBackend::actionsForResourceLoad): * contentextensions/DFABytecodeInterpreter.cpp: (WebCore::ContentExtensions::getJumpDistance): (WebCore::ContentExtensions::matchesDomain): (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretAppendAction): (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretTestFlagsAndAppendAction): (WebCore::ContentExtensions::DFABytecodeInterpreter::actionsForDefaultStylesheetFromDFARoot): (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretWithDomains): (WebCore::ContentExtensions::DFABytecodeInterpreter::interpret): * contentextensions/DFABytecodeInterpreter.h: Tools: * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp: (TestWebKitAPI::TEST_F): Test if-domain and unless-domain with multiple load types.
Modified Paths
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/contentextensions/ContentExtension.cpp
- trunk/Source/WebCore/contentextensions/ContentExtension.h
- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp
- trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp
- trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.h
- trunk/Tools/ChangeLog
- trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp
Diff
Modified: trunk/Source/WebCore/ChangeLog (186911 => 186912)
--- trunk/Source/WebCore/ChangeLog 2015-07-16 21:54:06 UTC (rev 186911)
+++ trunk/Source/WebCore/ChangeLog 2015-07-16 22:08:19 UTC (rev 186912)
@@ -1,3 +1,34 @@
+2015-07-16 Alex Christensen <[email protected]>
+
+ [Content Extensions] Cache domain actions
+ https://bugs.webkit.org/show_bug.cgi?id=146817
+
+ Reviewed by Benjamin Poulain.
+
+ Right now we run regular expressions on the domain every time we have any rules that match with if-domain or unless-domain.
+ This caches the results of running regular expressions on the domain of the main document's url so we only need to
+ run those regular expressions when the main document changes domain. We also spend less time adding unused actions into HashSets.
+
+ All behavior is covered by existing api tests, but I added some to explicitly test if-domain and unless-domain with multiple load types.
+
+ * contentextensions/ContentExtension.cpp:
+ (WebCore::ContentExtensions::ContentExtension::globalDisplayNoneStyleSheet):
+ (WebCore::ContentExtensions::ContentExtension::cachedDomainActions):
+ * contentextensions/ContentExtension.h:
+ (WebCore::ContentExtensions::ContentExtension::identifier):
+ (WebCore::ContentExtensions::ContentExtension::compiledExtension):
+ * contentextensions/ContentExtensionsBackend.cpp:
+ (WebCore::ContentExtensions::ContentExtensionsBackend::actionsForResourceLoad):
+ * contentextensions/DFABytecodeInterpreter.cpp:
+ (WebCore::ContentExtensions::getJumpDistance):
+ (WebCore::ContentExtensions::matchesDomain):
+ (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretAppendAction):
+ (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretTestFlagsAndAppendAction):
+ (WebCore::ContentExtensions::DFABytecodeInterpreter::actionsForDefaultStylesheetFromDFARoot):
+ (WebCore::ContentExtensions::DFABytecodeInterpreter::interpretWithDomains):
+ (WebCore::ContentExtensions::DFABytecodeInterpreter::interpret):
+ * contentextensions/DFABytecodeInterpreter.h:
+
2015-07-16 Simon Fraser <[email protected]>
Fix disappearing position:fixed elements in fixed layout mode
Modified: trunk/Source/WebCore/contentextensions/ContentExtension.cpp (186911 => 186912)
--- trunk/Source/WebCore/contentextensions/ContentExtension.cpp 2015-07-16 21:54:06 UTC (rev 186911)
+++ trunk/Source/WebCore/contentextensions/ContentExtension.cpp 2015-07-16 22:08:19 UTC (rev 186912)
@@ -75,6 +75,21 @@
return m_globalDisplayNoneStyleSheet.get();
}
+const DFABytecodeInterpreter::Actions& ContentExtension::cachedDomainActions(const String& domain)
+{
+ if (m_cachedDomain != domain) {
+ DFABytecodeInterpreter interpreter(m_compiledExtension->domainFiltersBytecode(), m_compiledExtension->domainFiltersBytecodeLength());
+ const uint16_t allLoadTypesAndResourceTypes = LoadTypeMask | ResourceTypeMask;
+ auto domainActions = interpreter.interpret(domain.utf8(), allLoadTypesAndResourceTypes);
+
+ m_cachedDomainActions.clear();
+ for (uint64_t action : domainActions)
+ m_cachedDomainActions.add(action);
+ m_cachedDomain = domain;
+ }
+ return m_cachedDomainActions;
+}
+
} // namespace ContentExtensions
} // namespace WebCore
Modified: trunk/Source/WebCore/contentextensions/ContentExtension.h (186911 => 186912)
--- trunk/Source/WebCore/contentextensions/ContentExtension.h 2015-07-16 21:54:06 UTC (rev 186911)
+++ trunk/Source/WebCore/contentextensions/ContentExtension.h 2015-07-16 22:08:19 UTC (rev 186912)
@@ -32,6 +32,7 @@
#if ENABLE(CONTENT_EXTENSIONS)
+#include "DFABytecodeInterpreter.h"
#include "StyleSheetContents.h"
namespace WebCore {
@@ -47,6 +48,7 @@
const String& identifier() const { return m_identifier; }
const CompiledContentExtension& compiledExtension() const { return m_compiledExtension.get(); }
StyleSheetContents* globalDisplayNoneStyleSheet();
+ const DFABytecodeInterpreter::Actions& cachedDomainActions(const String& domain);
private:
ContentExtension(const String& identifier, Ref<CompiledContentExtension>&&);
@@ -55,6 +57,9 @@
Ref<CompiledContentExtension> m_compiledExtension;
RefPtr<StyleSheetContents> m_globalDisplayNoneStyleSheet;
bool m_parsedGlobalDisplayNoneStyleSheet;
+
+ String m_cachedDomain;
+ DFABytecodeInterpreter::Actions m_cachedDomainActions;
};
} // namespace ContentExtensions
Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp (186911 => 186912)
--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp 2015-07-16 21:54:06 UTC (rev 186911)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp 2015-07-16 22:08:19 UTC (rev 186912)
@@ -90,47 +90,22 @@
const CompiledContentExtension& compiledExtension = contentExtension->compiledExtension();
DFABytecodeInterpreter withoutDomainsInterpreter(compiledExtension.filtersWithoutDomainsBytecode(), compiledExtension.filtersWithoutDomainsBytecodeLength());
- DFABytecodeInterpreter::Actions triggeredActions = withoutDomainsInterpreter.interpret(urlCString, flags);
+ DFABytecodeInterpreter::Actions withoutDomainsActions = withoutDomainsInterpreter.interpret(urlCString, flags);
- // Check to see if there are any actions triggered with if- or unless-domain and check the domain if there are.
DFABytecodeInterpreter withDomainsInterpreter(compiledExtension.filtersWithDomainsBytecode(), compiledExtension.filtersWithDomainsBytecodeLength());
+ DFABytecodeInterpreter::Actions withDomainsActions = withDomainsInterpreter.interpretWithDomains(urlCString, flags, contentExtension->cachedDomainActions(resourceLoadInfo.mainDocumentURL.host()));
- DFABytecodeInterpreter::Actions withDomainsPossibleActions = withDomainsInterpreter.interpret(urlCString, flags);
- if (!withDomainsPossibleActions.isEmpty()) {
- DFABytecodeInterpreter domainsInterpreter(compiledExtension.domainFiltersBytecode(), compiledExtension.domainFiltersBytecodeLength());
- DFABytecodeInterpreter::Actions domainsActions = domainsInterpreter.interpret(resourceLoadInfo.mainDocumentURL.host().utf8(), flags);
-
- DFABytecodeInterpreter::Actions ifDomainActions;
- DFABytecodeInterpreter::Actions unlessDomainActions;
- for (uint64_t action : domainsActions) {
- if (action & IfDomainFlag)
- ifDomainActions.add(action);
- else
- unlessDomainActions.add(action);
- }
-
- for (uint64_t action : withDomainsPossibleActions) {
- if (ifDomainActions.contains(action)) {
- // If an if-domain trigger matches, add the action.
- ASSERT(action & IfDomainFlag);
- triggeredActions.add(action & ~IfDomainFlag);
- } else if (!(action & IfDomainFlag) && !unlessDomainActions.contains(action)) {
- // If this action did not need an if-domain, it must have been an unless-domain rule.
- // Add the action unless it matched an unless-domain trigger.
- triggeredActions.add(action);
- }
- }
- }
-
const SerializedActionByte* actions = compiledExtension.actions();
const unsigned actionsLength = compiledExtension.actionsLength();
bool sawIgnorePreviousRules = false;
- if (!triggeredActions.isEmpty()) {
- Vector<unsigned> actionLocations;
- actionLocations.reserveInitialCapacity(triggeredActions.size());
- for (auto actionLocation : triggeredActions)
- actionLocations.append(static_cast<unsigned>(actionLocation));
+ if (!withoutDomainsActions.isEmpty() || !withDomainsActions.isEmpty()) {
+ Vector<uint32_t> actionLocations;
+ actionLocations.reserveInitialCapacity(withoutDomainsActions.size() + withDomainsActions.size());
+ for (uint64_t actionLocation : withoutDomainsActions)
+ actionLocations.uncheckedAppend(static_cast<uint32_t>(actionLocation));
+ for (uint64_t actionLocation : withDomainsActions)
+ actionLocations.uncheckedAppend(static_cast<uint32_t>(actionLocation));
std::sort(actionLocations.begin(), actionLocations.end());
// Add actions in reverse order to properly deal with IgnorePreviousRules.
Modified: trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp (186911 => 186912)
--- trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp 2015-07-16 21:54:06 UTC (rev 186911)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp 2015-07-16 22:08:19 UTC (rev 186912)
@@ -86,12 +86,22 @@
}
}
+static inline bool matchesDomain(uint64_t actionAndFlags, const DFABytecodeInterpreter::Actions& domainActions)
+{
+ bool ifDomain = actionAndFlags & IfDomainFlag;
+ bool domain = domainActions.contains(actionAndFlags);
+ return ifDomain == domain;
+}
+
void DFABytecodeInterpreter::interpretAppendAction(uint32_t& programCounter, Actions& actions, bool ifDomain)
{
ASSERT(getInstruction(m_bytecode, m_bytecodeLength, programCounter) == DFABytecodeInstruction::AppendAction
|| getInstruction(m_bytecode, m_bytecodeLength, programCounter) == DFABytecodeInstruction::AppendActionWithIfDomain
|| getInstruction(m_bytecode, m_bytecodeLength, programCounter) == DFABytecodeInstruction::AppendActionDefaultStylesheet);
- actions.add((ifDomain ? IfDomainFlag : 0) | static_cast<uint64_t>(getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction))));
+ uint64_t action = "" ? IfDomainFlag : 0) | static_cast<uint64_t>(getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction)));
+ if (!m_domainActions || matchesDomain(action, *m_domainActions))
+ actions.add(action);
+
programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction);
ASSERT(instructionSizeWithArguments(DFABytecodeInstruction::AppendAction) == instructionSizeWithArguments(DFABytecodeInstruction::AppendActionWithIfDomain));
ASSERT(instructionSizeWithArguments(DFABytecodeInstruction::AppendAction) == instructionSizeWithArguments(DFABytecodeInstruction::AppendActionDefaultStylesheet));
@@ -104,13 +114,16 @@
uint16_t flagsToCheck = getBits<uint16_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction));
uint16_t loadTypeFlags = flagsToCheck & LoadTypeMask;
- uint16_t ressourceTypeFlags = flagsToCheck & ResourceTypeMask;
+ uint16_t resourceTypeFlags = flagsToCheck & ResourceTypeMask;
bool loadTypeMatches = loadTypeFlags ? (loadTypeFlags & flags) : true;
- bool ressourceTypeMatches = ressourceTypeFlags ? (ressourceTypeFlags & flags) : true;
+ bool resourceTypeMatches = resourceTypeFlags ? (resourceTypeFlags & flags) : true;
- if (loadTypeMatches && ressourceTypeMatches)
- actions.add((ifDomain ? IfDomainFlag : 0) | static_cast<uint64_t>(getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint16_t))));
+ if (loadTypeMatches && resourceTypeMatches) {
+ uint64_t actionAndFlags = (ifDomain ? IfDomainFlag : 0) | (static_cast<uint64_t>(flagsToCheck) << 32) | static_cast<uint64_t>(getBits<uint32_t>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint16_t)));
+ if (!m_domainActions || matchesDomain(actionAndFlags, *m_domainActions))
+ actions.add(actionAndFlags);
+ }
programCounter += instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction);
ASSERT(instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendAction) == instructionSizeWithArguments(DFABytecodeInstruction::TestFlagsAndAppendActionWithIfDomain));
}
@@ -142,6 +155,15 @@
return actions;
}
+DFABytecodeInterpreter::Actions DFABytecodeInterpreter::interpretWithDomains(const CString& urlCString, uint16_t flags, const DFABytecodeInterpreter::Actions& domainActions)
+{
+ ASSERT(!m_domainActions);
+ m_domainActions = &domainActions;
+ DFABytecodeInterpreter::Actions actions = interpret(urlCString, flags);
+ m_domainActions = nullptr;
+ return actions;
+}
+
DFABytecodeInterpreter::Actions DFABytecodeInterpreter::interpret(const CString& urlCString, uint16_t flags)
{
const char* url = ""
Modified: trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.h (186911 => 186912)
--- trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.h 2015-07-16 21:54:06 UTC (rev 186911)
+++ trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.h 2015-07-16 22:08:19 UTC (rev 186912)
@@ -50,6 +50,7 @@
typedef HashSet<uint64_t, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> Actions;
Actions interpret(const CString&, uint16_t flags);
+ Actions interpretWithDomains(const CString&, uint16_t flags, const DFABytecodeInterpreter::Actions& domainActions);
Actions actionsForDefaultStylesheetFromDFARoot();
private:
@@ -57,6 +58,7 @@
void interpretTestFlagsAndAppendAction(unsigned& programCounter, uint16_t flags, Actions&, bool ifDomain);
const DFABytecode* m_bytecode;
const unsigned m_bytecodeLength;
+ const DFABytecodeInterpreter::Actions* m_domainActions { nullptr };
};
} // namespace ContentExtensions
Modified: trunk/Tools/ChangeLog (186911 => 186912)
--- trunk/Tools/ChangeLog 2015-07-16 21:54:06 UTC (rev 186911)
+++ trunk/Tools/ChangeLog 2015-07-16 22:08:19 UTC (rev 186912)
@@ -1,3 +1,14 @@
+2015-07-16 Alex Christensen <[email protected]>
+
+ [Content Extensions] Cache domain actions
+ https://bugs.webkit.org/show_bug.cgi?id=146817
+
+ Reviewed by Benjamin Poulain.
+
+ * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp:
+ (TestWebKitAPI::TEST_F):
+ Test if-domain and unless-domain with multiple load types.
+
2015-07-16 Benjamin Poulain <[email protected]>
[Content extensions] Combine suffixes when generating NFAs
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp (186911 => 186912)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp 2015-07-16 21:54:06 UTC (rev 186911)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp 2015-07-16 22:08:19 UTC (rev 186912)
@@ -1204,6 +1204,38 @@
"{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\".*\"}}]");
EXPECT_EQ(nullptr, backend5.globalDisplayNoneStyleSheet(ASCIILiteral("testFilter")));
testRequest(backend5, mainDocumentRequest("http://webkit.org"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }, true);
+
+ auto backend6 = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*\",\"if-domain\":[\"webkit.org\",\"*w3c.org\"],\"resource-type\":[\"document\",\"script\"]}},"
+ "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"ignore\",\"if-domain\":[\"*webkit.org\",\"w3c.org\"]}},"
+ "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\".*\",\"unless-domain\":[\"webkit.org\",\"whatwg.org\"],\"resource-type\":[\"script\",\"image\"],\"load-type\":[\"third-party\"]}}]");
+ EXPECT_EQ(nullptr, backend6.globalDisplayNoneStyleSheet(ASCIILiteral("testFilter")));
+ testRequest(backend6, mainDocumentRequest("http://webkit.org"), { ContentExtensions::ActionType::BlockLoad });
+ testRequest(backend6, mainDocumentRequest("http://w3c.org"), { ContentExtensions::ActionType::BlockLoad });
+ testRequest(backend6, mainDocumentRequest("http://whatwg.org"), { });
+ testRequest(backend6, mainDocumentRequest("http://sub.webkit.org"), { });
+ testRequest(backend6, mainDocumentRequest("http://sub.w3c.org"), { ContentExtensions::ActionType::BlockLoad });
+ testRequest(backend6, mainDocumentRequest("http://sub.whatwg.org"), { });
+ testRequest(backend6, mainDocumentRequest("http://webkit.org/ignore"), { }, true);
+ testRequest(backend6, mainDocumentRequest("http://w3c.org/ignore"), { }, true);
+ testRequest(backend6, mainDocumentRequest("http://whatwg.org/ignore"), { });
+ testRequest(backend6, mainDocumentRequest("http://sub.webkit.org/ignore"), { }, true);
+ testRequest(backend6, mainDocumentRequest("http://sub.w3c.org/ignore"), { ContentExtensions::ActionType::BlockLoad });
+ testRequest(backend6, mainDocumentRequest("http://sub.whatwg.org/ignore"), { });
+ testRequest(backend6, subResourceRequest("http://example.com/image.png", "http://webkit.org/", ResourceType::Image), { });
+ testRequest(backend6, subResourceRequest("http://example.com/image.png", "http://w3c.org/", ResourceType::Image), { ContentExtensions::ActionType::BlockCookies });
+ testRequest(backend6, subResourceRequest("http://example.com/doc.html", "http://webkit.org/", ResourceType::Document), { ContentExtensions::ActionType::BlockLoad });
+ testRequest(backend6, subResourceRequest("http://example.com/script.js", "http://webkit.org/", ResourceType::Script), { ContentExtensions::ActionType::BlockLoad });
+ testRequest(backend6, subResourceRequest("http://example.com/script.js", "http://w3c.org/", ResourceType::Script), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockLoad });
+ testRequest(backend6, subResourceRequest("http://example.com/script.js", "http://example.com/", ResourceType::Script), { });
+ testRequest(backend6, subResourceRequest("http://example.com/ignore/image.png", "http://webkit.org/", ResourceType::Image), { }, true);
+ testRequest(backend6, subResourceRequest("http://example.com/ignore/image.png", "http://example.com/", ResourceType::Image), { });
+ testRequest(backend6, subResourceRequest("http://example.com/ignore/image.png", "http://example.org/", ResourceType::Image), { ContentExtensions::ActionType::BlockCookies });
+ testRequest(backend6, subResourceRequest("http://example.com/doc.html", "http://example.org/", ResourceType::Document), { });
+ testRequest(backend6, subResourceRequest("http://example.com/", "http://example.com/", ResourceType::Font), { });
+ testRequest(backend6, subResourceRequest("http://example.com/ignore", "http://webkit.org/", ResourceType::Image), { }, true);
+ testRequest(backend6, subResourceRequest("http://example.com/ignore", "http://webkit.org/", ResourceType::Font), { }, true);
+ testRequest(backend6, subResourceRequest("http://example.com/", "http://example.com/", ResourceType::Script), { });
+ testRequest(backend6, subResourceRequest("http://example.com/ignore", "http://example.com/", ResourceType::Script), { });
}
TEST_F(ContentExtensionTest, InvalidJSON)
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
