WebKit Bugzilla
Attachment 369724 Details for
Bug 194047
: Integrate JSC bytecode cache with WebKit
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194047-20190513144343.patch (text/plain), 171.53 KB, created by
Tadeu Zagallo
on 2019-05-13 05:43:46 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Tadeu Zagallo
Created:
2019-05-13 05:43:46 PDT
Size:
171.53 KB
patch
obsolete
>Subversion Revision: 245212 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index b3ecb66cabd844cd19a132cc938e16ed48a62234..08f4223be492b501ea488ea37ae101f0a4e851d8 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,105 @@ >+2019-05-11 Tadeu Zagallo <tzagallo@apple.com> >+ >+ Integrate JSC bytecode cache with WebKit >+ https://bugs.webkit.org/show_bug.cgi?id=194047 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch adds BytecodeCacheMetadata, a data structure for recording which CodeBlocks >+ have been executed that can later be fed back into generate(Program|Module)Bytecode >+ to determine what to generate bytecode for. It also makes 2 changes to the cache to >+ improve encoding and decoding performance: >+ - Add a custom encoding/decoding method to CachedInstructionStream. For encoding, make >+ CacheInstructionStream a VariableLengthObject, so that it can allocate its own buffer and >+ copy the whole stream with a single memcpy. When decoding, change InstructionStream so that >+ it can use the mmaped memory instead of copying the stream. >+ - Allow providing a file descriptor when encoding, so that instead of allocating a big >+ buffer and returning the bytecode cache in memory at the end of encoding, we write the >+ cache straight to the file. >+ >+ * API/JSScript.mm: >+ (-[JSScript writeCache:]): >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Sources.txt: >+ * bytecode/BytecodeCacheMetadata.cpp: Added. >+ (JSC::BytecodeCacheMetadata::recordCachedFunctionCodeBlock): >+ (JSC::BytecodeCacheMetadata::shouldCache const): >+ (JSC::BytecodeCacheMetadata::decode): >+ (JSC::BytecodeCacheMetadata::encode const): >+ * bytecode/BytecodeCacheMetadata.h: Added. >+ (JSC::BytecodeCacheMetadata::isEmpty const): >+ (JSC::BytecodeCacheMetadata::Entry::Entry): >+ (JSC::BytecodeCacheMetadata::encode const): >+ (JSC::BytecodeCacheMetadata::decode): >+ * bytecode/BytecodeRewriter.cpp: >+ (JSC::BytecodeRewriter::applyModification): >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::CodeBlock): >+ * bytecode/InstructionStream.cpp: >+ (JSC::InstructionStream::InstructionStream): >+ (JSC::InstructionStream::sizeInBytes const): >+ (JSC::InstructionStream::contains const): >+ (JSC::InstructionStreamReader::InstructionStreamReader): >+ * bytecode/InstructionStream.h: >+ (JSC::InstructionStream::~InstructionStream): >+ (JSC::InstructionStream::BaseRef::BaseRef): >+ (JSC::InstructionStream::BaseRef::operator=): >+ (JSC::InstructionStream::BaseRef::operator!= const): >+ (JSC::InstructionStream::BaseRef::next const): >+ (JSC::InstructionStream::BaseRef::isValid const): >+ (JSC::InstructionStream::BaseRef::unwrap const): >+ (JSC::InstructionStream::begin const): >+ (JSC::InstructionStream::end const): >+ (JSC::InstructionStream::at const): >+ (JSC::InstructionStreamReader::~InstructionStreamReader): >+ (JSC::InstructionStreamReader::InstructionStreamReader): >+ (JSC::InstructionStreamWriter::InstructionStreamWriter): >+ (JSC::InstructionStreamWriter::mutableInstructions): >+ (JSC::InstructionStreamWriter::MutableRef::freeze const): >+ (JSC::InstructionStreamWriter::MutableRef::operator->): >+ (JSC::InstructionStreamWriter::MutableRef::ptr): >+ (JSC::InstructionStreamWriter::MutableRef::operator Ref): >+ (JSC::InstructionStreamWriter::MutableRef::unwrap): >+ (JSC::InstructionStreamWriter::ref): >+ (JSC::InstructionStreamWriter::seek): >+ (JSC::InstructionStreamWriter::write): >+ (JSC::InstructionStreamWriter::rewind): >+ (JSC::InstructionStreamWriter::finalize): >+ (JSC::InstructionStreamWriter::swap): >+ (JSC::InstructionStreamWriter::begin): >+ (JSC::InstructionStreamWriter::end): >+ * bytecode/PreciseJumpTargetsInlines.h: >+ (JSC::updateStoredJumpTargetsForInstruction): >+ * bytecompiler/BytecodeGenerator.cpp: >+ (JSC::StructureForInContext::finalize): >+ * bytecompiler/BytecodeGenerator.h: >+ * bytecompiler/StaticPropertyAnalysis.h: >+ (JSC::StaticPropertyAnalysis::create): >+ (JSC::StaticPropertyAnalysis::StaticPropertyAnalysis): >+ * bytecompiler/StaticPropertyAnalyzer.h: >+ (JSC::StaticPropertyAnalyzer::createThis): >+ (JSC::StaticPropertyAnalyzer::newObject): >+ * runtime/CachedBytecode.h: >+ (JSC::CachedBytecode::create): >+ * runtime/CachedTypes.cpp: >+ (JSC::Encoder::Encoder): >+ (JSC::Encoder::release): >+ (JSC::Encoder::releaseMapped): >+ (JSC::CachedInstructionStream::encode): >+ (JSC::CachedInstructionStream::decode const): >+ (JSC::encodeCodeBlock): >+ (JSC::encodeFunctionCodeBlock): >+ * runtime/CachedTypes.h: >+ * runtime/CodeCache.cpp: >+ (JSC::generateUnlinkedCodeBlockForFunctions): >+ (JSC::serializeBytecode): >+ * runtime/CodeCache.h: >+ * runtime/Completion.cpp: >+ (JSC::generateProgramBytecode): >+ (JSC::generateModuleBytecode): >+ (JSC::evaluate): >+ * runtime/Completion.h: >+ > 2019-05-10 Saam barati <sbarati@apple.com> > > Call to JSToWasmICCallee::createStructure passes in wrong prototype value >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index a5f9d9680c22ef14505b2dee8f5dbf15d6cc49a6..b01295efb512bb360a977ece5261ba07fbea2544 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,16 @@ >+2019-05-11 Tadeu Zagallo <tzagallo@apple.com> >+ >+ Integrate JSC bytecode cache with WebKit >+ https://bugs.webkit.org/show_bug.cgi?id=194047 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ RELEASE_ASSERT when reading kern.bootsessionuuid. Otherwise, we crash when >+ returning the uninitialized LazyNeverDestroyed value. >+ >+ * wtf/UUID.cpp: >+ (WTF::bootSessionUUIDString): >+ > 2019-05-10 Saam barati <sbarati@apple.com> > > Bag's move operator= leaks memory >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 626c55f197498d417bd040ea9af0359c4dab5a38..cf144c2739f223ef3a01520f9b34b0532c54a30d 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,51 @@ >+2019-05-11 Tadeu Zagallo <tzagallo@apple.com> >+ >+ Integrate JSC bytecode cache with WebKit >+ https://bugs.webkit.org/show_bug.cgi?id=194047 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add CachedBytecode to CachedScript. >+ Add the type of the script being loaded into the request (classic or module). >+ Notify the loader when bytecode should be cached for the next request. >+ >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * bindings/js/CachedScriptFetcher.cpp: >+ (WebCore::CachedScriptFetcher::requestModuleScript const): >+ (WebCore::CachedScriptFetcher::requestScriptWithCache const): >+ * bindings/js/CachedScriptFetcher.h: >+ * bindings/js/CachedScriptSourceProvider.cpp: Copied from Source/WebCore/dom/ScriptElementCachedScriptFetcher.cpp. >+ (WebCore::CachedScriptSourceProvider::cacheBytecode const): >+ (WebCore::CachedScriptSourceProvider::updateCache const): >+ (WebCore::CachedScriptSourceProvider::commitCachedBytecode const): >+ * bindings/js/CachedScriptSourceProvider.h: >+ (WebCore::CachedScriptSourceProvider::~CachedScriptSourceProvider): >+ * dom/LoadableClassicScript.cpp: >+ (WebCore::LoadableClassicScript::load): >+ * dom/ScriptElementCachedScriptFetcher.cpp: >+ (WebCore::ScriptElementCachedScriptFetcher::requestModuleScript const): >+ * html/parser/HTMLResourcePreloader.cpp: >+ (WebCore::PreloadRequest::resourceRequest): >+ * loader/LinkLoader.cpp: >+ (WebCore::LinkLoader::preloadIfNeeded): >+ * loader/LoaderStrategy.h: >+ * loader/ResourceLoader.cpp: >+ (WebCore::ResourceLoader::didRetrieveDerivedDataFromCache): >+ * loader/ResourceLoader.h: >+ * loader/ResourceLoaderOptions.h: >+ * loader/SubresourceLoader.cpp: >+ (WebCore::SubresourceLoader::didRetrieveDerivedDataFromCache): >+ * loader/SubresourceLoader.h: >+ * loader/ThreadableLoader.cpp: >+ (WebCore::ThreadableLoaderOptions::isolatedCopy const): >+ * loader/cache/CachedResource.h: >+ (WebCore::CachedResource::didRetrieveDerivedDataFromCache): >+ * loader/cache/CachedScript.cpp: >+ (WebCore::CachedScript::cachedBytecode): >+ (WebCore::CachedScript::didRetrieveDerivedDataFromCache): >+ * loader/cache/CachedScript.h: >+ > 2019-05-11 Simon Fraser <simon.fraser@apple.com> > > Overflow scroll that becomes non-scrollable should stop being composited >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index cdb9040ba4e255fe4ce04e260cc6422cd4468b5a..2f9befa04eedc49d0ecdcdbc9f994aefdf995315 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,120 @@ >+2019-05-11 Tadeu Zagallo <tzagallo@apple.com> >+ >+ Integrate JSC bytecode cache with WebKit >+ https://bugs.webkit.org/show_bug.cgi?id=194047 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add BytecodeCache to the NetworkProcess to generate and store >+ bytecode for requests. >+ >+ * NetworkProcess/NetworkConnectionToWebProcess.cpp: >+ (WebKit::NetworkConnectionToWebProcess::cacheBytecodeForRequest): >+ * NetworkProcess/NetworkConnectionToWebProcess.h: >+ * NetworkProcess/NetworkConnectionToWebProcess.messages.in: >+ * NetworkProcess/NetworkProcess.h: >+ (WebKit::NetworkProcess::bytecodeCache): >+ * NetworkProcess/NetworkProcessCreationParameters.cpp: >+ (WebKit::NetworkProcessCreationParameters::encode const): >+ (WebKit::NetworkProcessCreationParameters::decode): >+ * NetworkProcess/NetworkProcessCreationParameters.h: >+ * NetworkProcess/NetworkResourceLoadParameters.cpp: >+ (WebKit::NetworkResourceLoadParameters::encode const): >+ (WebKit::NetworkResourceLoadParameters::decode): >+ * NetworkProcess/NetworkResourceLoadParameters.h: >+ * NetworkProcess/NetworkResourceLoader.cpp: >+ (WebKit::NetworkResourceLoader::canUseBytecodeCache const): >+ (WebKit::NetworkResourceLoader::didReceiveResponse): >+ (WebKit::NetworkResourceLoader::didRetrieveCacheEntry): >+ (WebKit::NetworkResourceLoader::loadBytecodeCache): >+ (WebKit::NetworkResourceLoader::processCachedEntryAfterDidReceiveResponse): >+ * NetworkProcess/NetworkResourceLoader.h: >+ * NetworkProcess/cache/BytecodeCache.cpp: Added. >+ (WebKit::CacheFile::CacheFile): >+ (WebKit::CacheFile::operator=): >+ (WebKit::CacheFile::~CacheFile): >+ (WebKit::CacheFile::name const): >+ (WebKit::CacheFile::fd const): >+ (WebKit::CacheFile::operator! const): >+ (WebKit::BytecodeCache::Plan::create): >+ (WebKit::BytecodeCache::Plan::compile): >+ (WebKit::BytecodeCache::Plan::Plan): >+ (WebKit::BytecodeCache::Thread::create): >+ (WebKit::BytecodeCache::Thread::Thread): >+ (WebKit::BytecodeCache::create): >+ (WebKit::BytecodeCache::BytecodeCache): >+ (WebKit::BytecodeCache::~BytecodeCache): >+ (WebKit::BytecodeCache::storeMetadataForRequest): >+ (WebKit::BytecodeCache::createCacheFile const): >+ (WebKit::BytecodeCache::bytecodeForRequest): >+ * NetworkProcess/cache/BytecodeCache.h: Added. >+ * NetworkProcess/cache/NetworkCache.cpp: >+ (WebKit::NetworkCache::Cache::retrieveFile): >+ (WebKit::NetworkCache::Cache::storeFile): >+ (WebKit::NetworkCache::Cache::removeFile): >+ * NetworkProcess/cache/NetworkCache.h: >+ * NetworkProcess/cache/NetworkCacheKey.cpp: >+ (WebKit::NetworkCache::Key::Key): >+ * NetworkProcess/cache/NetworkCacheKey.h: >+ * NetworkProcess/cache/NetworkCacheStorage.cpp: >+ (WebKit::NetworkCache::Storage::storeFile): >+ (WebKit::NetworkCache::Storage::retrieveFile): >+ (WebKit::NetworkCache::Storage::removeFile): >+ * NetworkProcess/cache/NetworkCacheStorage.h: >+ * NetworkProcess/cocoa/NetworkProcessCocoa.mm: >+ (WebKit::NetworkProcess::platformInitializeNetworkProcessCocoa): >+ * NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in: >+ * NetworkProcess/soup/NetworkProcessSoup.cpp: >+ (WebKit::NetworkProcess::platformInitializeNetworkProcess): >+ * Platform/IPC/DerivedData.cpp: Copied from Source/WebCore/bindings/js/CachedScriptFetcher.h. >+ (IPC::DerivedData::encode const): >+ (IPC::DerivedData::decode): >+ * Platform/IPC/DerivedData.h: Copied from Source/WebCore/bindings/js/CachedScriptFetcher.h. >+ (IPC::DerivedData::DerivedData): >+ (IPC::DerivedData::isEmpty const): >+ (IPC::DerivedData::type const): >+ (IPC::DerivedData::data const): >+ * Platform/Logging.h: >+ * Scripts/webkit/messages.py: >+ * Shared/WebProcessCreationParameters.cpp: >+ (WebKit::WebProcessCreationParameters::encode const): >+ (WebKit::WebProcessCreationParameters::decode): >+ * Shared/WebProcessCreationParameters.h: >+ * Sources.txt: >+ * UIProcess/API/APIProcessPoolConfiguration.cpp: >+ (API::ProcessPoolConfiguration::createWithWebsiteDataStoreConfiguration): >+ (API::ProcessPoolConfiguration::ProcessPoolConfiguration): >+ (API::ProcessPoolConfiguration::copy): >+ * UIProcess/API/APIProcessPoolConfiguration.h: >+ * UIProcess/API/APIWebsiteDataStore.cpp: >+ (API::WebsiteDataStore::defaultDataStoreConfiguration): >+ (API::WebsiteDataStore::legacyDefaultDataStoreConfiguration): >+ * UIProcess/API/APIWebsiteDataStore.h: >+ * UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm: >+ (API::WebsiteDataStore::defaultBytecodeCacheDirectory): >+ (API::WebsiteDataStore::legacyDefaultBytecodeCacheDirectory): >+ * UIProcess/WebProcessPool.cpp: >+ (WebKit::legacyWebsiteDataStoreConfiguration): >+ (WebKit::WebProcessPool::ensureNetworkProcess): >+ (WebKit::WebProcessPool::initializeNewWebProcess): >+ * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp: >+ (WebKit::WebsiteDataStoreConfiguration::copy): >+ * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h: >+ (WebKit::WebsiteDataStoreConfiguration::bytecodeCacheDirectory const): >+ (WebKit::WebsiteDataStoreConfiguration::setBytecodeCacheDirectory): >+ * WebKit.xcodeproj/project.pbxproj: >+ * WebProcess/Network/WebLoaderStrategy.cpp: >+ (WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess): >+ (WebKit::WebLoaderStrategy::cacheBytecodeForScript): >+ * WebProcess/Network/WebLoaderStrategy.h: >+ * WebProcess/Network/WebResourceLoader.cpp: >+ (WebKit::WebResourceLoader::didReceiveResponse): >+ * WebProcess/Network/WebResourceLoader.h: >+ * WebProcess/Network/WebResourceLoader.messages.in: >+ * WebProcess/cocoa/WebProcessCocoa.mm: >+ (WebKit::WebProcess::platformInitializeWebProcess): >+ * WebProcess/com.apple.WebProcess.sb.in: >+ > 2019-05-10 Chris Dumez <cdumez@apple.com> > > [PSON] Prevent flashing when the process-swap is forced by the client >diff --git a/Source/WebKitLegacy/ChangeLog b/Source/WebKitLegacy/ChangeLog >index 69790e8e45fad0fcd8970f84368648069eeadd34..ff296e07dbd84713bbb8d688559ea21e271b4ad2 100644 >--- a/Source/WebKitLegacy/ChangeLog >+++ b/Source/WebKitLegacy/ChangeLog >@@ -1,3 +1,14 @@ >+2019-05-11 Tadeu Zagallo <tzagallo@apple.com> >+ >+ Integrate JSC bytecode cache with WebKit >+ https://bugs.webkit.org/show_bug.cgi?id=194047 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Implement LoaderStrategy's `cacheBytecodeForScript` as no-op. >+ >+ * WebCoreSupport/WebResourceLoadScheduler.h: >+ > 2019-05-03 Commit Queue <commit-queue@webkit.org> > > Unreviewed, rolling out r244881. >diff --git a/Source/JavaScriptCore/API/JSScript.mm b/Source/JavaScriptCore/API/JSScript.mm >index bdbd682283f36c6514cf2736ffdaa012c85120cf..49b69f97accf58cc1f7ffb363323c77273b3a0ae 100644 >--- a/Source/JavaScriptCore/API/JSScript.mm >+++ b/Source/JavaScriptCore/API/JSScript.mm >@@ -234,10 +234,10 @@ - (BOOL)writeCache:(String&)error > JSC::SourceCode sourceCode = [self sourceCode]; > switch (m_type) { > case kJSScriptTypeModule: >- m_cachedBytecode = JSC::generateModuleBytecode(m_virtualMachine.vm, sourceCode, parserError); >+ m_cachedBytecode = JSC::generateModuleBytecode(m_virtualMachine.vm, sourceCode, fd, parserError); > break; > case kJSScriptTypeProgram: >- m_cachedBytecode = JSC::generateProgramBytecode(m_virtualMachine.vm, sourceCode, parserError); >+ m_cachedBytecode = JSC::generateProgramBytecode(m_virtualMachine.vm, sourceCode, fd, parserError); > break; > } > >@@ -247,18 +247,6 @@ - (BOOL)writeCache:(String&)error > return NO; > } > >- ssize_t bytesWritten = write(fd, m_cachedBytecode->data(), m_cachedBytecode->size()); >- if (bytesWritten == -1) { >- error = makeString("Could not write cache file to disk: ", strerror(errno)); >- return NO; >- } >- >- if (static_cast<size_t>(bytesWritten) != m_cachedBytecode->size()) { >- ftruncate(fd, 0); >- error = makeString("Could not write the full cache file to disk. Only wrote ", String::number(bytesWritten), " of the expected ", String::number(m_cachedBytecode->size()), " bytes."); >- return NO; >- } >- > return YES; > } > >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index e7dc887b9aaf815bb3b80a7d42e8a07f894fdd03..fa5f17f76c0d523b9b2dc29a9bb109bea5d2bc3c 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -761,6 +761,7 @@ > 141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 14150132154BB13F005D8C98 /* WeakSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 14201D591DECF26A00904BD3 /* SourceCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 14201D581DECF26A00904BD3 /* SourceCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 14243CC321F277DC004B264E /* BytecodeCacheMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 14243CC221F277D2004B264E /* BytecodeCacheMetadata.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D77B0ED20D7300B89619 /* Interpreter.h */; }; > 1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D8DC0ED2205B00B89619 /* CallFrame.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 1429D9300ED22D7000B89619 /* JIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D92E0ED22D7000B89619 /* JIT.h */; }; >@@ -3164,6 +3165,7 @@ > 14150132154BB13F005D8C98 /* WeakSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakSetInlines.h; sourceTree = "<group>"; }; > 14201D581DECF26A00904BD3 /* SourceCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceCode.h; sourceTree = "<group>"; }; > 1421359A0A677F4F00A8195E /* JSBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBase.cpp; sourceTree = "<group>"; }; >+ 14243CC221F277D2004B264E /* BytecodeCacheMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeCacheMetadata.h; sourceTree = "<group>"; }; > 142711380A460BBB0080EEEA /* JSBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBase.h; sourceTree = "<group>"; }; > 1429D77B0ED20D7300B89619 /* Interpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Interpreter.h; sourceTree = "<group>"; }; > 1429D7D30ED2128200B89619 /* Interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Interpreter.cpp; sourceTree = "<group>"; }; >@@ -7872,6 +7874,7 @@ > 0F63945215D07051006A597C /* ArrayProfile.h */, > C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */, > C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */, >+ 14243CC221F277D2004B264E /* BytecodeCacheMetadata.h */, > 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */, > E3D877711E65C08900BE945A /* BytecodeDumper.cpp */, > E3D877721E65C08900BE945A /* BytecodeDumper.h */, >@@ -8761,6 +8764,7 @@ > 0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */, > 0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */, > C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */, >+ 14243CC321F277DC004B264E /* BytecodeCacheMetadata.h in Headers */, > 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */, > E3D877741E65C0A000BE945A /* BytecodeDumper.h in Headers */, > 969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */, >diff --git a/Source/JavaScriptCore/Sources.txt b/Source/JavaScriptCore/Sources.txt >index f5534441390d1a608aae0dc28ffbef31868329b4..256c766724fc565791a151ea5f23bc5b57373e2c 100644 >--- a/Source/JavaScriptCore/Sources.txt >+++ b/Source/JavaScriptCore/Sources.txt >@@ -193,6 +193,7 @@ bytecode/ArithProfile.cpp > bytecode/ArrayAllocationProfile.cpp > bytecode/ArrayProfile.cpp > bytecode/BytecodeBasicBlock.cpp >+bytecode/BytecodeCacheMetadata.cpp > bytecode/BytecodeDumper.cpp > bytecode/BytecodeGeneratorification.cpp > bytecode/BytecodeIntrinsicRegistry.cpp >diff --git a/Source/JavaScriptCore/bytecode/BytecodeCacheMetadata.cpp b/Source/JavaScriptCore/bytecode/BytecodeCacheMetadata.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..ce04584d89c892598e8f40380f6e152fd2bc81c7 >--- /dev/null >+++ b/Source/JavaScriptCore/bytecode/BytecodeCacheMetadata.cpp >@@ -0,0 +1,86 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "BytecodeCacheMetadata.h" >+ >+#include "SourceCode.h" >+ >+namespace JSC { >+ >+void BytecodeCacheMetadata::recordCachedFunctionCodeBlock(const SourceCode& sourceCode, CodeSpecializationKind kind) >+{ >+ auto result = m_map.add(sourceCode.startOffset(), Entry { }); >+ switch (kind) { >+ case CodeForCall: >+ result.iterator->value.m_codeForCall = true; >+ break; >+ case CodeForConstruct: >+ result.iterator->value.m_codeForConstrut = true; >+ break; >+ } >+} >+ >+bool BytecodeCacheMetadata::shouldCache(const SourceCode& sourceCode, CodeSpecializationKind kind) const >+{ >+ auto iterator = m_map.find(sourceCode.startOffset()); >+ if (iterator == m_map.end()) >+ return false; >+ >+ switch (kind) { >+ case CodeForCall: >+ return iterator->value.m_codeForCall; >+ break; >+ case CodeForConstruct: >+ return iterator->value.m_codeForConstrut; >+ break; >+ } >+} >+ >+BytecodeCacheMetadata BytecodeCacheMetadata::decode(const uint8_t* data, size_t size) >+{ >+ ASSERT(!(size % sizeof(EncodedEntry))); >+ size_t length = size / sizeof(EncodedEntry); >+ EncodedEntry* entries = bitwise_cast<EncodedEntry*>(data); >+ BytecodeCacheMetadata metadata; >+ for (unsigned i = 0; i < length; i++) >+ metadata.m_map.add(entries[i].key, entries[i].value); >+ return metadata; >+} >+ >+std::pair<MallocPtr<uint8_t>, size_t> BytecodeCacheMetadata::encode() const >+{ >+ size_t size = m_map.size() * sizeof(EncodedEntry); >+ MallocPtr<uint8_t> data = MallocPtr<uint8_t>::malloc(size); >+ unsigned offset = 0; >+ for (const EncodedEntry& entry : m_map) { >+ uint8_t* ptr = data.get() + (offset * sizeof(EncodedEntry)); >+ memcpy(ptr, &entry, sizeof(entry)); >+ ++offset; >+ } >+ return std::make_pair(WTFMove(data), size); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/bytecode/BytecodeCacheMetadata.h b/Source/JavaScriptCore/bytecode/BytecodeCacheMetadata.h >new file mode 100644 >index 0000000000000000000000000000000000000000..7041899361386185cd2535fd2cf9282ee01d38ca >--- /dev/null >+++ b/Source/JavaScriptCore/bytecode/BytecodeCacheMetadata.h >@@ -0,0 +1,97 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "CodeSpecializationKind.h" >+#include <wtf/HashMap.h> >+#include <wtf/MallocPtr.h> >+#include <wtf/Optional.h> >+ >+namespace JSC { >+ >+class SourceCode; >+ >+class BytecodeCacheMetadata { >+ class Entry; >+ >+ using EncodedEntry = KeyValuePair<int, Entry>; >+ >+public: >+ >+ bool isEmpty() const { return m_map.isEmpty(); } >+ >+ JS_EXPORT_PRIVATE void recordCachedFunctionCodeBlock(const SourceCode&, CodeSpecializationKind); >+ JS_EXPORT_PRIVATE bool shouldCache(const SourceCode&, CodeSpecializationKind) const; >+ >+ JS_EXPORT_PRIVATE static BytecodeCacheMetadata decode(const uint8_t*, size_t); >+ JS_EXPORT_PRIVATE std::pair<MallocPtr<uint8_t>, size_t> encode() const; >+ >+ template<typename Encoder> >+ void encode(Encoder&) const; >+ >+ template<typename Decoder> >+ static Optional<BytecodeCacheMetadata> decode(Decoder&); >+ >+private: >+ class Entry { >+ friend class BytecodeCacheMetadata; >+ >+ public: >+ Entry() >+ : m_codeForCall(false) >+ , m_codeForConstrut(false) >+ { >+ } >+ >+ private: >+ bool m_codeForCall : 1; >+ bool m_codeForConstrut : 1; >+ }; >+ >+ HashMap<int, Entry> m_map; >+}; >+ >+template<typename Encoder> >+void BytecodeCacheMetadata::encode(Encoder& encoder) const >+{ >+ std::pair<MallocPtr<uint8_t>, size_t> data = encode(); >+ encoder << static_cast<uint64_t>(data.second); >+ encoder.encodeFixedLengthData(data.first.get(), data.second, alignof(EncodedEntry)); >+} >+ >+template<typename Decoder> >+Optional<BytecodeCacheMetadata> BytecodeCacheMetadata::decode(Decoder& decoder) >+{ >+ uint64_t size; >+ if (!decoder.decode(size)) >+ return WTF::nullopt; >+ MallocPtr<uint8_t> data = MallocPtr<uint8_t>::malloc(size); >+ if (!decoder.decodeFixedLengthData(data.get(), size, alignof(EncodedEntry))) >+ return WTF::nullopt; >+ return BytecodeCacheMetadata::decode(data.get(), size); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/bytecode/BytecodeRewriter.cpp b/Source/JavaScriptCore/bytecode/BytecodeRewriter.cpp >index 4bbd1132e9f75a6411d7a736d836cf93fb10ff7b..2acc85c721aef9ed864cda599622d12decabe3dc 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeRewriter.cpp >+++ b/Source/JavaScriptCore/bytecode/BytecodeRewriter.cpp >@@ -38,13 +38,13 @@ void BytecodeRewriter::applyModification() > for (size_t insertionIndex = m_insertions.size(); insertionIndex--;) { > Insertion& insertion = m_insertions[insertionIndex]; > if (insertion.type == Insertion::Type::Remove) >- m_writer.m_instructions.remove(insertion.index.bytecodeOffset, insertion.length()); >+ m_writer.m_stream.remove(insertion.index.bytecodeOffset, insertion.length()); > else { > if (insertion.includeBranch == IncludeBranch::Yes) { > int finalOffset = insertion.index.bytecodeOffset + calculateDifference(m_insertions.begin(), m_insertions.begin() + insertionIndex); > adjustJumpTargetsInFragment(finalOffset, insertion); > } >- m_writer.m_instructions.insertVector(insertion.index.bytecodeOffset, insertion.instructions.m_instructions); >+ m_writer.m_stream.insertVector(insertion.index.bytecodeOffset, insertion.instructions.m_stream); > } > } > m_insertions.clear(); >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index db28f67e2d17b30395500484e86945a7ce1e9d8a..69fd419e8667a0480784a3e6d27ecfaf167d00eb 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -360,7 +360,7 @@ CodeBlock::CodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecut > , m_unlinkedCode(*vm, this, unlinkedCodeBlock) > , m_ownerExecutable(*vm, this, ownerExecutable) > , m_vm(vm) >- , m_instructionsRawPointer(unlinkedCodeBlock->instructions().rawPointer()) >+ , m_instructionsRawPointer(unlinkedCodeBlock->instructions().instructions()) > , m_osrExitCounter(0) > , m_optimizationDelayCounter(0) > , m_reoptimizationRetryCounter(0) >diff --git a/Source/JavaScriptCore/bytecode/InstructionStream.cpp b/Source/JavaScriptCore/bytecode/InstructionStream.cpp >index 514cf11253eb4a28694c80fe8e522a6233fd9773..1ffb2121dae2ba09544be85ea057fb159896c45e 100644 >--- a/Source/JavaScriptCore/bytecode/InstructionStream.cpp >+++ b/Source/JavaScriptCore/bytecode/InstructionStream.cpp >@@ -31,20 +31,26 @@ > > namespace JSC { > >-InstructionStream::InstructionStream(InstructionBuffer&& instructions) >- : m_instructions(WTFMove(instructions)) >+InstructionStream::InstructionStream() > { } > > size_t InstructionStream::sizeInBytes() const > { >- return m_instructions.size(); >+ return size(); > } > > bool InstructionStream::contains(Instruction* instruction) const > { > > const uint8_t* pointer = bitwise_cast<const uint8_t*>(instruction); >- return pointer >= m_instructions.data() && pointer < (m_instructions.data() + m_instructions.size()); >+ return pointer >= instructions() && pointer < (instructions() + size()); > } > >+InstructionStreamReader::InstructionStreamReader(InstructionVector&& vector) >+ : m_owned(true) >+ , m_size(vector.size()) >+ , m_instructions(vector.releaseBuffer().leakPtr()) >+{ > } >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/bytecode/InstructionStream.h b/Source/JavaScriptCore/bytecode/InstructionStream.h >index ce9607b372f3bda529a9b5e1fbc74ab60f5c2584..5f823967d335653b45788890e471630d45a3b7b7 100644 >--- a/Source/JavaScriptCore/bytecode/InstructionStream.h >+++ b/Source/JavaScriptCore/bytecode/InstructionStream.h >@@ -31,50 +31,53 @@ > > namespace JSC { > >+class InstructionStreamWriter; > struct Instruction; > >+using InstructionVector = Vector<uint8_t, 0, UnsafeVectorOverflow>; >+ > class InstructionStream { > WTF_MAKE_FAST_ALLOCATED; > >- using InstructionBuffer = Vector<uint8_t, 0, UnsafeVectorOverflow>; >- > friend class InstructionStreamWriter; > friend class CachedInstructionStream; > public: >+ virtual ~InstructionStream() { } >+ > size_t sizeInBytes() const; > > using Offset = unsigned; > > private: >- template<class InstructionBuffer> >+ template<class InstructionStream> > class BaseRef { > WTF_MAKE_FAST_ALLOCATED; > >- friend class InstructionStream; >+ friend InstructionStream; > > public: >- BaseRef(const BaseRef<InstructionBuffer>& other) >- : m_instructions(other.m_instructions) >- , m_index(other.m_index) >+ BaseRef(const BaseRef<InstructionStream>& other) >+ : m_stream(other.m_stream) >+ , m_index(other.m_index) > { } > >- void operator=(const BaseRef<InstructionBuffer>& other) >+ void operator=(const BaseRef<InstructionStream>& other) > { >- m_instructions = other.m_instructions; >+ m_stream = other.m_stream; > m_index = other.m_index; > } > > inline const Instruction* operator->() const { return unwrap(); } > inline const Instruction* ptr() const { return unwrap(); } > >- bool operator!=(const BaseRef<InstructionBuffer>& other) const >+ bool operator!=(const BaseRef<InstructionStream>& other) const > { >- return &m_instructions != &other.m_instructions || m_index != other.m_index; >+ return &m_stream != &other.m_stream || m_index != other.m_index; > } > > BaseRef next() const > { >- return BaseRef { m_instructions, m_index + ptr()->size() }; >+ return BaseRef { m_stream, m_index + ptr()->size() }; > } > > inline Offset offset() const >@@ -84,43 +87,23 @@ private: > > bool isValid() const > { >- return m_index < m_instructions.size(); >+ return m_index < m_stream.size(); > } > >- private: >- inline const Instruction* unwrap() const { return reinterpret_cast<const Instruction*>(&m_instructions[m_index]); } >- >- protected: >- BaseRef(InstructionBuffer& instructions, size_t index) >- : m_instructions(instructions) >+ BaseRef(InstructionStream& stream, size_t index) >+ : m_stream(stream) > , m_index(index) > { } > >- InstructionBuffer& m_instructions; >+ private: >+ inline const Instruction* unwrap() const { return reinterpret_cast<const Instruction*>(&m_stream.instructions()[m_index]); } >+ >+ InstructionStream& m_stream; > Offset m_index; > }; > > public: >- using Ref = BaseRef<const InstructionBuffer>; >- >- class MutableRef : public BaseRef<InstructionBuffer> { >- friend class InstructionStreamWriter; >- >- protected: >- using BaseRef<InstructionBuffer>::BaseRef; >- >- public: >- Ref freeze() const { return Ref { m_instructions, m_index }; } >- inline Instruction* operator->() { return unwrap(); } >- inline Instruction* ptr() { return unwrap(); } >- inline operator Ref() >- { >- return Ref { m_instructions, m_index }; >- } >- >- private: >- inline Instruction* unwrap() { return reinterpret_cast<Instruction*>(&m_instructions[m_index]); } >- }; >+ using Ref = BaseRef<const InstructionStream>; > > private: > class iterator : public Ref { >@@ -144,54 +127,111 @@ private: > public: > inline iterator begin() const > { >- return iterator { m_instructions, 0 }; >+ return iterator { *this, 0 }; > } > > inline iterator end() const > { >- return iterator { m_instructions, m_instructions.size() }; >+ return iterator { *this, size() }; > } > > inline const Ref at(Offset offset) const > { >- ASSERT(offset < m_instructions.size()); >- return Ref { m_instructions, offset }; >+ ASSERT(offset < size()); >+ return Ref { *this, offset }; > } > >- inline size_t size() const >+ virtual size_t size() const = 0; >+ virtual const uint8_t* instructions() const = 0; >+ >+ bool contains(Instruction *) const; >+ >+protected: >+ InstructionStream(); >+}; >+ >+class InstructionStreamReader : public InstructionStream { >+ friend class CachedInstructionStream; >+ >+public: >+ InstructionStreamReader(InstructionVector&&); >+ >+ const uint8_t* instructions() const override > { >- return m_instructions.size(); >+ return m_instructions; > } > >- const void* rawPointer() const >+ size_t size() const override > { >- return m_instructions.data(); >+ return m_size; > } > >- bool contains(Instruction *) const; >+ ~InstructionStreamReader() >+ { >+ if (m_owned) >+ fastFree(const_cast<uint8_t*>(m_instructions)); >+ } > >-protected: >- explicit InstructionStream(InstructionBuffer&&); >+private: >+ InstructionStreamReader() >+ { >+ } > >- InstructionBuffer m_instructions; >+ bool m_owned { false }; >+ size_t m_size; >+ const uint8_t* m_instructions; > }; > > class InstructionStreamWriter : public InstructionStream { > friend class BytecodeRewriter; > public: >- InstructionStreamWriter() >- : InstructionStream({ }) >- { } >+ InstructionStreamWriter() { } >+ >+ const uint8_t* instructions() const override >+ { >+ return m_stream.data(); >+ } >+ >+ size_t size() const override >+ { >+ return m_stream.size(); >+ } >+ >+ uint8_t* mutableInstructions() >+ { >+ return m_stream.data(); >+ } >+ >+ >+ class MutableRef : public BaseRef<InstructionStreamWriter> { >+ friend class InstructionStreamWriter; >+ >+ protected: >+ using BaseRef<InstructionStreamWriter>::BaseRef; >+ >+ public: >+ Ref freeze() const { return Ref { m_stream, m_index }; } >+ inline Instruction* operator->() { return unwrap(); } >+ inline Instruction* ptr() { return unwrap(); } >+ inline operator Ref() >+ { >+ return Ref { m_stream, m_index }; >+ } >+ >+ private: >+ inline Instruction* unwrap() { return reinterpret_cast<Instruction*>(&m_stream.mutableInstructions()[m_index]); } >+ }; >+ > > inline MutableRef ref(Offset offset) > { >- ASSERT(offset < m_instructions.size()); >- return MutableRef { m_instructions, offset }; >+ ASSERT(offset < m_stream.size()); >+ return MutableRef { *this, offset }; > } > > void seek(unsigned position) > { >- ASSERT(position <= m_instructions.size()); >+ ASSERT(position <= m_stream.size()); > m_position = position; > } > >@@ -203,10 +243,10 @@ public: > void write(uint8_t byte) > { > ASSERT(!m_finalized); >- if (m_position < m_instructions.size()) >- m_instructions[m_position++] = byte; >+ if (m_position < m_stream.size()) >+ m_stream[m_position++] = byte; > else { >- m_instructions.append(byte); >+ m_stream.append(byte); > m_position++; > } > } >@@ -227,28 +267,28 @@ public: > > void rewind(MutableRef& ref) > { >- ASSERT(ref.offset() < m_instructions.size()); >- m_instructions.shrink(ref.offset()); >+ ASSERT(ref.offset() < m_stream.size()); >+ m_stream.shrink(ref.offset()); > m_position = ref.offset(); > } > > std::unique_ptr<InstructionStream> finalize() > { > m_finalized = true; >- m_instructions.shrinkToFit(); >- return std::unique_ptr<InstructionStream> { new InstructionStream(WTFMove(m_instructions)) }; >+ m_stream.shrinkToFit(); >+ return std::unique_ptr<InstructionStreamReader> { new InstructionStreamReader(WTFMove(m_stream)) }; > } > > MutableRef ref() > { >- return MutableRef { m_instructions, m_position }; >+ return MutableRef { *this, m_position }; > } > > void swap(InstructionStreamWriter& other) > { > std::swap(m_finalized, other.m_finalized); > std::swap(m_position, other.m_position); >- m_instructions.swap(other.m_instructions); >+ m_stream.swap(other.m_stream); > } > > private: >@@ -274,17 +314,18 @@ private: > public: > iterator begin() > { >- return iterator { m_instructions, 0 }; >+ return iterator { *this, 0 }; > } > > iterator end() > { >- return iterator { m_instructions, m_instructions.size() }; >+ return iterator { *this, m_stream.size() }; > } > > private: > unsigned m_position { 0 }; > bool m_finalized { false }; >+ InstructionVector m_stream; > }; > > >diff --git a/Source/JavaScriptCore/bytecode/PreciseJumpTargetsInlines.h b/Source/JavaScriptCore/bytecode/PreciseJumpTargetsInlines.h >index 4dd189d657d92ac80b4353abd1960e4e70beb0c2..2bf5a519bb3ed85cd33980d4e4ad140e477f5eab 100644 >--- a/Source/JavaScriptCore/bytecode/PreciseJumpTargetsInlines.h >+++ b/Source/JavaScriptCore/bytecode/PreciseJumpTargetsInlines.h >@@ -133,7 +133,7 @@ SWITCH_JMP(CASE_OP, SWITCH_CASE, SWITCH_DEFAULT_OFFSET) > } > > template<typename Block, typename Function, typename CodeBlockOrHashMap> >-inline void updateStoredJumpTargetsForInstruction(Block&& codeBlock, unsigned finalOffset, InstructionStream::MutableRef instruction, const Function& function, CodeBlockOrHashMap& codeBlockOrHashMap) >+inline void updateStoredJumpTargetsForInstruction(Block&& codeBlock, unsigned finalOffset, InstructionStreamWriter::MutableRef instruction, const Function& function, CodeBlockOrHashMap& codeBlockOrHashMap) > { > #define CASE_OP(__op) \ > case __op::opcodeID: { \ >@@ -169,7 +169,7 @@ SWITCH_JMP(CASE_OP, SWITCH_CASE, SWITCH_DEFAULT_OFFSET) > } > > template<typename Block, typename Function> >-inline void updateStoredJumpTargetsForInstruction(Block* codeBlock, unsigned finalOffset, InstructionStream::MutableRef instruction, Function function) >+inline void updateStoredJumpTargetsForInstruction(Block* codeBlock, unsigned finalOffset, InstructionStreamWriter::MutableRef instruction, Function function) > { > updateStoredJumpTargetsForInstruction(codeBlock, finalOffset, instruction, function, codeBlock); > } >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >index 661cb49d3f3d34da4d48db203da617ab22a08556..cd3346996aed7d3b6750c8542e4f86b27cda1f18 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >@@ -4977,7 +4977,7 @@ void StructureForInContext::finalize(BytecodeGenerator& generator, UnlinkedCodeB > return; > > OpcodeID lastOpcodeID = generator.m_lastOpcodeID; >- InstructionStream::MutableRef lastInstruction = generator.m_lastInstruction; >+ InstructionStreamWriter::MutableRef lastInstruction = generator.m_lastInstruction; > for (const auto& instTuple : m_getInsts) { > unsigned instIndex = std::get<0>(instTuple); > int propertyRegIndex = std::get<1>(instTuple); >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >index 95341a9483f5ef5ff0a70d4fea9aa3795a93f515..a0a0c56cfeb3d964f815a570a66a1a14da290dc3 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >@@ -1055,7 +1055,7 @@ namespace JSC { > void allocateAndEmitScope(); > > template<typename JumpOp> >- void setTargetForJumpInstruction(InstructionStream::MutableRef&, int target); >+ void setTargetForJumpInstruction(InstructionStreamWriter::MutableRef&, int target); > > using BigIntMapEntry = std::tuple<UniquedStringImpl*, uint8_t, bool>; > >@@ -1281,7 +1281,7 @@ namespace JSC { > VM* m_vm; > > OpcodeID m_lastOpcodeID = op_end; >- InstructionStream::MutableRef m_lastInstruction { m_writer.ref() }; >+ InstructionStreamWriter::MutableRef m_lastInstruction { m_writer.ref() }; > > bool m_usesExceptions { false }; > bool m_expressionTooDeep { false }; >diff --git a/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h b/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h >index 8757d3a0d54fc89fb0d97ac8b99e86a341eb6d74..530688f29b3111b638a148d84658735b3a0d4fa6 100644 >--- a/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h >+++ b/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h >@@ -33,7 +33,7 @@ namespace JSC { > // Reference count indicates number of live registers that alias this object. > class StaticPropertyAnalysis : public RefCounted<StaticPropertyAnalysis> { > public: >- static Ref<StaticPropertyAnalysis> create(InstructionStream::MutableRef&& instructionRef) >+ static Ref<StaticPropertyAnalysis> create(InstructionStreamWriter::MutableRef&& instructionRef) > { > return adoptRef(*new StaticPropertyAnalysis(WTFMove(instructionRef))); > } >@@ -45,12 +45,12 @@ public: > int propertyIndexCount() { return m_propertyIndexes.size(); } > > private: >- StaticPropertyAnalysis(InstructionStream::MutableRef&& instructionRef) >+ StaticPropertyAnalysis(InstructionStreamWriter::MutableRef&& instructionRef) > : m_instructionRef(WTFMove(instructionRef)) > { > } > >- InstructionStream::MutableRef m_instructionRef; >+ InstructionStreamWriter::MutableRef m_instructionRef; > typedef HashSet<unsigned, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> PropertyIndexSet; > PropertyIndexSet m_propertyIndexes; > }; >diff --git a/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h b/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h >index 5f9e73862a4acd307b101bd1cd6f23fc51752d3b..872857ed78c2f65ed1ab7f57928c0a58dbaa06c0 100644 >--- a/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h >+++ b/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h >@@ -35,8 +35,8 @@ namespace JSC { > // is understood to be lossy, and it's OK if it turns out to be wrong sometimes. > class StaticPropertyAnalyzer { > public: >- void createThis(RegisterID* dst, InstructionStream::MutableRef instructionRef); >- void newObject(RegisterID* dst, InstructionStream::MutableRef instructionRef); >+ void createThis(RegisterID* dst, InstructionStreamWriter::MutableRef instructionRef); >+ void newObject(RegisterID* dst, InstructionStreamWriter::MutableRef instructionRef); > void putById(RegisterID* dst, unsigned propertyIndex); // propertyIndex is an index into a uniqued set of strings. > void mov(RegisterID* dst, RegisterID* src); > >@@ -50,14 +50,14 @@ private: > AnalysisMap m_analyses; > }; > >-inline void StaticPropertyAnalyzer::createThis(RegisterID* dst, InstructionStream::MutableRef instructionRef) >+inline void StaticPropertyAnalyzer::createThis(RegisterID* dst, InstructionStreamWriter::MutableRef instructionRef) > { > AnalysisMap::AddResult addResult = m_analyses.add( > dst->index(), StaticPropertyAnalysis::create(WTFMove(instructionRef))); > ASSERT_UNUSED(addResult, addResult.isNewEntry); // Can't have two 'this' in the same constructor. > } > >-inline void StaticPropertyAnalyzer::newObject(RegisterID* dst, InstructionStream::MutableRef instructionRef) >+inline void StaticPropertyAnalyzer::newObject(RegisterID* dst, InstructionStreamWriter::MutableRef instructionRef) > { > auto analysis = StaticPropertyAnalysis::create(WTFMove(instructionRef)); > AnalysisMap::AddResult addResult = m_analyses.add(dst->index(), analysis.copyRef()); >diff --git a/Source/JavaScriptCore/runtime/CachedBytecode.h b/Source/JavaScriptCore/runtime/CachedBytecode.h >index 579366824bc8a53d3023c9e291077e29ac129f9f..15cab3c0470ba0ca062d555e47c3ffddc8fed792 100644 >--- a/Source/JavaScriptCore/runtime/CachedBytecode.h >+++ b/Source/JavaScriptCore/runtime/CachedBytecode.h >@@ -47,9 +47,9 @@ public: > } > > #if !OS(WINDOWS) >- static Ref<CachedBytecode> create(void* data, size_t size) >+ static Ref<CachedBytecode> create(void* data, size_t size, LeafExecutableMap&& leafExecutables = { }) > { >- return adoptRef(*new CachedBytecode(CachePayload::makeMappedPayload(data, size))); >+ return adoptRef(*new CachedBytecode(CachePayload::makeMappedPayload(data, size), WTFMove(leafExecutables))); > } > #endif > >diff --git a/Source/JavaScriptCore/runtime/CachedTypes.cpp b/Source/JavaScriptCore/runtime/CachedTypes.cpp >index 22f3c2ed21f15480392879f436ea5bafb7e7446b..b58a1a3a5001a246b804ada5eb7c31b7c7ae4e23 100644 >--- a/Source/JavaScriptCore/runtime/CachedTypes.cpp >+++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp >@@ -87,8 +87,9 @@ public: > ptrdiff_t m_offset; > }; > >- Encoder(VM& vm) >+ Encoder(VM& vm, int fd) > : m_vm(vm) >+ , m_fd(fd) > , m_baseOffset(0) > , m_currentPage(nullptr) > { >@@ -146,6 +147,9 @@ public: > > Ref<CachedBytecode> release() > { >+ if (m_fd != -1) >+ return releaseMapped(); >+ > size_t size = m_baseOffset + m_currentPage->size(); > MallocPtr<uint8_t> buffer = MallocPtr<uint8_t>::malloc(size); > unsigned offset = 0; >@@ -158,6 +162,19 @@ public: > } > > private: >+ Ref<CachedBytecode> releaseMapped() >+ { >+ size_t size = m_baseOffset + m_currentPage->size(); >+ if (ftruncate(m_fd, size)) >+ return CachedBytecode::create(); >+ >+ for (const auto& page : m_pages) >+ write(m_fd, page.buffer(), page.size()); >+ >+ void* buffer = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, m_fd, 0); >+ return CachedBytecode::create(buffer, size, WTFMove(m_leafExecutables)); >+ } >+ > class Page { > public: > Page(size_t size) >@@ -213,6 +230,7 @@ private: > } > > VM& m_vm; >+ int m_fd; > ptrdiff_t m_baseOffset; > Page* m_currentPage; > Vector<Page> m_pages; >@@ -1305,22 +1323,25 @@ private: > EncodedType m_type; > }; > >-class CachedInstructionStream : public CachedObject<InstructionStream> { >+class CachedInstructionStream : public VariableLengthObject<InstructionStream> { > public: > void encode(Encoder& encoder, const InstructionStream& stream) > { >- m_instructions.encode(encoder, stream.m_instructions); >+ m_size = stream.size(); >+ uint8_t* buffer = this->allocate<uint8_t>(encoder, m_size); >+ memcpy(buffer, stream.instructions(), m_size); > } > >- InstructionStream* decode(Decoder& decoder) const >+ InstructionStream* decode(Decoder&) const > { >- Vector<uint8_t, 0, UnsafeVectorOverflow> instructionsVector; >- m_instructions.decode(decoder, instructionsVector); >- return new InstructionStream(WTFMove(instructionsVector)); >+ InstructionStreamReader* stream = new InstructionStreamReader(); >+ stream->m_size = m_size; >+ stream->m_instructions = this->buffer(); >+ return stream; > } > > private: >- CachedVector<uint8_t, 0, UnsafeVectorOverflow> m_instructions; >+ size_t m_size; > }; > > class CachedMetadataTable : public CachedObject<UnlinkedMetadataTable> { >@@ -2309,11 +2330,11 @@ void encodeCodeBlock(Encoder& encoder, const SourceCodeKey& key, const UnlinkedC > entry->encode(encoder, { key, jsCast<const UnlinkedCodeBlockType*>(codeBlock) }); > } > >-Ref<CachedBytecode> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const UnlinkedCodeBlock* codeBlock) >+Ref<CachedBytecode> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const UnlinkedCodeBlock* codeBlock, int fd) > { > const ClassInfo* classInfo = codeBlock->classInfo(vm); > >- Encoder encoder(vm); >+ Encoder encoder(vm, fd); > if (classInfo == UnlinkedProgramCodeBlock::info()) > encodeCodeBlock<UnlinkedProgramCodeBlock>(encoder, key, codeBlock); > else if (classInfo == UnlinkedModuleProgramCodeBlock::info()) >@@ -2324,9 +2345,14 @@ Ref<CachedBytecode> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const Unli > return encoder.release(); > } > >+Ref<CachedBytecode> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const UnlinkedCodeBlock* codeBlock) >+{ >+ return encodeCodeBlock(vm, key, codeBlock, -1); >+} >+ > Ref<CachedBytecode> encodeFunctionCodeBlock(VM& vm, const UnlinkedFunctionCodeBlock* codeBlock) > { >- Encoder encoder(vm); >+ Encoder encoder(vm, -1); > encoder.malloc<CachedFunctionCodeBlock>()->encode(encoder, *codeBlock); > return encoder.release(); > } >diff --git a/Source/JavaScriptCore/runtime/CachedTypes.h b/Source/JavaScriptCore/runtime/CachedTypes.h >index 9d00e1733b4bcd89fcc9183e678ab2f01ce49ef0..dc4016e8fbd39433902759e18300dfaac897f4a2 100644 >--- a/Source/JavaScriptCore/runtime/CachedTypes.h >+++ b/Source/JavaScriptCore/runtime/CachedTypes.h >@@ -108,6 +108,7 @@ private: > }; > > JS_EXPORT_PRIVATE Ref<CachedBytecode> encodeCodeBlock(VM&, const SourceCodeKey&, const UnlinkedCodeBlock*); >+JS_EXPORT_PRIVATE Ref<CachedBytecode> encodeCodeBlock(VM&, const SourceCodeKey&, const UnlinkedCodeBlock*, int fd); > > UnlinkedCodeBlock* decodeCodeBlockImpl(VM&, const SourceCodeKey&, Ref<CachedBytecode>); > >diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp >index 03a92ee64a37d22cf23dd487f5979938ec9b3632..f0b64df7a4091c5c8750d9efdec53b7f0672a7e8 100644 >--- a/Source/JavaScriptCore/runtime/CodeCache.cpp >+++ b/Source/JavaScriptCore/runtime/CodeCache.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012, 2016 Apple Inc. All Rights Reserved. >+ * Copyright (C) 2012-2019 Apple Inc. All Rights Reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -26,6 +26,7 @@ > #include "config.h" > #include "CodeCache.h" > >+#include "BytecodeCacheMetadata.h" > #include "IndirectEvalExecutable.h" > #include <wtf/text/StringConcatenateNumbers.h> > >@@ -174,16 +175,19 @@ void CodeCache::write(VM& vm) > writeCodeBlock(vm, it.key, it.value); > } > >-void generateUnlinkedCodeBlockForFunctions(VM& vm, UnlinkedCodeBlock* unlinkedCodeBlock, const SourceCode& parentSource, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error) >+void generateUnlinkedCodeBlockForFunctions(VM& vm, UnlinkedCodeBlock* unlinkedCodeBlock, const SourceCode& parentSource, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, const BytecodeCacheMetadata* metadata) > { > auto generate = [&](UnlinkedFunctionExecutable* unlinkedExecutable, CodeSpecializationKind constructorKind) { > if (constructorKind == CodeForConstruct && SourceParseModeSet(SourceParseMode::AsyncArrowFunctionMode, SourceParseMode::AsyncMethodMode, SourceParseMode::AsyncFunctionMode).contains(unlinkedExecutable->parseMode())) > return; > > SourceCode source = unlinkedExecutable->linkedSourceCode(parentSource); >+ if (metadata && !metadata->shouldCache(source, constructorKind)) >+ return; >+ > UnlinkedFunctionCodeBlock* unlinkedFunctionCodeBlock = unlinkedExecutable->unlinkedCodeBlockFor(vm, source, constructorKind, codeGenerationMode, error, unlinkedExecutable->parseMode()); > if (unlinkedFunctionCodeBlock) >- generateUnlinkedCodeBlockForFunctions(vm, unlinkedFunctionCodeBlock, source, codeGenerationMode, error); >+ generateUnlinkedCodeBlockForFunctions(vm, unlinkedFunctionCodeBlock, source, codeGenerationMode, error, metadata); > }; > > // FIXME: We should also generate CodeBlocks for CodeForConstruct >@@ -225,10 +229,10 @@ SourceCodeKey sourceCodeKeyForSerializedModule(VM& vm, const SourceCode& sourceC > return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ModuleType, strictMode, scriptMode, { }); > } > >-Ref<CachedBytecode> serializeBytecode(VM& vm, UnlinkedCodeBlock* codeBlock, const SourceCode& source, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode) >+Ref<CachedBytecode> serializeBytecode(VM& vm, UnlinkedCodeBlock* codeBlock, const SourceCode& source, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, int fd, OptionSet<CodeGenerationMode> codeGenerationMode) > { > return encodeCodeBlock(vm, >- sourceCodeKeyForSerializedBytecode(vm, source, codeType, strictMode, scriptMode, codeGenerationMode), codeBlock); >+ sourceCodeKeyForSerializedBytecode(vm, source, codeType, strictMode, scriptMode, codeGenerationMode), codeBlock, fd); > } > > } >diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h >index b067f847dae301ceee70658be7659f8e7d3ab36c..bafc8e2dec13747fbb9c163ae0594a4bf03a3fd6 100644 >--- a/Source/JavaScriptCore/runtime/CodeCache.h >+++ b/Source/JavaScriptCore/runtime/CodeCache.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved. >+ * Copyright (C) 2012-2019 Apple Inc. All Rights Reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -42,6 +42,7 @@ > > namespace JSC { > >+class BytecodeCacheMetadata; > class EvalExecutable; > class IndirectEvalExecutable; > class Identifier; >@@ -302,23 +303,23 @@ UnlinkedCodeBlockType* generateUnlinkedCodeBlock(VM& vm, ExecutableType* executa > return generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType, ExecutableType>(vm, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, executable->derivedContextType(), executable->isArrowFunctionContext(), variablesUnderTDZ, executable); > } > >-void generateUnlinkedCodeBlockForFunctions(VM&, UnlinkedCodeBlock*, const SourceCode&, OptionSet<CodeGenerationMode>, ParserError&); >+void generateUnlinkedCodeBlockForFunctions(VM&, UnlinkedCodeBlock*, const SourceCode&, OptionSet<CodeGenerationMode>, ParserError&, const BytecodeCacheMetadata*); > > template <class UnlinkedCodeBlockType> > std::enable_if_t<!std::is_same<UnlinkedCodeBlockType, UnlinkedEvalCodeBlock>::value, UnlinkedCodeBlockType*> >-recursivelyGenerateUnlinkedCodeBlock(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ) >+recursivelyGenerateUnlinkedCodeBlock(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ, const BytecodeCacheMetadata* metadata) > { > bool isArrowFunctionContext = false; > UnlinkedCodeBlockType* unlinkedCodeBlock = generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType>(vm, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, DerivedContextType::None, isArrowFunctionContext, variablesUnderTDZ); > if (!unlinkedCodeBlock) > return nullptr; > >- generateUnlinkedCodeBlockForFunctions(vm, unlinkedCodeBlock, source, codeGenerationMode, error); >+ generateUnlinkedCodeBlockForFunctions(vm, unlinkedCodeBlock, source, codeGenerationMode, error, metadata); > return unlinkedCodeBlock; > } > > void writeCodeBlock(VM&, const SourceCodeKey&, const SourceCodeValue&); >-Ref<CachedBytecode> serializeBytecode(VM&, UnlinkedCodeBlock*, const SourceCode&, SourceCodeType, JSParserStrictMode, JSParserScriptMode, OptionSet<CodeGenerationMode>); >+Ref<CachedBytecode> serializeBytecode(VM&, UnlinkedCodeBlock*, const SourceCode&, SourceCodeType, JSParserStrictMode, JSParserScriptMode, int fd, OptionSet<CodeGenerationMode>); > SourceCodeKey sourceCodeKeyForSerializedProgram(VM&, const SourceCode&); > SourceCodeKey sourceCodeKeyForSerializedModule(VM&, const SourceCode&); > >diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp >index 19796af4f89d2e881fb7d579602c094f7e5fea61..8ae9d519ee690a95c21e823b50dc0156b6383cfa 100644 >--- a/Source/JavaScriptCore/runtime/Completion.cpp >+++ b/Source/JavaScriptCore/runtime/Completion.cpp >@@ -91,7 +91,7 @@ bool checkModuleSyntax(ExecState* exec, const SourceCode& source, ParserError& e > return true; > } > >-Ref<CachedBytecode> generateProgramBytecode(VM& vm, const SourceCode& source, ParserError& error) >+Ref<CachedBytecode> generateProgramBytecode(VM& vm, const SourceCode& source, int fd, ParserError& error, const BytecodeCacheMetadata* metadata) > { > JSLockHolder lock(vm); > RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable()); >@@ -101,13 +101,14 @@ Ref<CachedBytecode> generateProgramBytecode(VM& vm, const SourceCode& source, Pa > JSParserScriptMode scriptMode = JSParserScriptMode::Classic; > EvalContextType evalContextType = EvalContextType::None; > >- UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, error, evalContextType, &variablesUnderTDZ); >+ UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, error, evalContextType, &variablesUnderTDZ, metadata); > if (!unlinkedCodeBlock) > return CachedBytecode::create(); >- return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, { }); >+ >+ return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, fd, { }); > } > >-Ref<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, ParserError& error) >+Ref<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, int fd, ParserError& error, const BytecodeCacheMetadata* metadata) > { > JSLockHolder lock(vm); > RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable()); >@@ -117,10 +118,10 @@ Ref<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, Par > JSParserScriptMode scriptMode = JSParserScriptMode::Module; > EvalContextType evalContextType = EvalContextType::None; > >- UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, error, evalContextType, &variablesUnderTDZ); >+ UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, error, evalContextType, &variablesUnderTDZ, metadata); > if (!unlinkedCodeBlock) > return CachedBytecode::create(); >- return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, { }); >+ return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, fd, { }); > } > > JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException) >@@ -144,6 +145,8 @@ JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, N > return jsUndefined(); > } > >+ vm.codeCache()->write(vm); >+ > RELEASE_ASSERT(result); > return result; > } >diff --git a/Source/JavaScriptCore/runtime/Completion.h b/Source/JavaScriptCore/runtime/Completion.h >index d5a0231b780175b88420d6aff4b3c0a524ed1851..86f42910b0aad9c533e2d60e4f34a8ef17dd535c 100644 >--- a/Source/JavaScriptCore/runtime/Completion.h >+++ b/Source/JavaScriptCore/runtime/Completion.h >@@ -28,6 +28,7 @@ > > namespace JSC { > >+class BytecodeCacheMetadata; > class CachedBytecode; > class Exception; > class ExecState; >@@ -42,8 +43,8 @@ JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&); > JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0); > JS_EXPORT_PRIVATE bool checkModuleSyntax(ExecState*, const SourceCode&, ParserError&); > >-JS_EXPORT_PRIVATE Ref<CachedBytecode> generateProgramBytecode(VM&, const SourceCode&, ParserError&); >-JS_EXPORT_PRIVATE Ref<CachedBytecode> generateModuleBytecode(VM&, const SourceCode&, ParserError&); >+JS_EXPORT_PRIVATE Ref<CachedBytecode> generateProgramBytecode(VM&, const SourceCode&, int fd, ParserError&, const BytecodeCacheMetadata* = nullptr); >+JS_EXPORT_PRIVATE Ref<CachedBytecode> generateModuleBytecode(VM&, const SourceCode&, int fd, ParserError&, const BytecodeCacheMetadata* = nullptr); > > JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue, NakedPtr<Exception>& returnedException); > inline JSValue evaluate(ExecState* exec, const SourceCode& sourceCode, JSValue thisValue = JSValue()) >diff --git a/Source/WTF/wtf/UUID.cpp b/Source/WTF/wtf/UUID.cpp >index 85968bf59116d13cad92396f339f204fe1dc2151..06f1426e373672d6b8f9b8f4a33c9051a7b5f4e2 100644 >--- a/Source/WTF/wtf/UUID.cpp >+++ b/Source/WTF/wtf/UUID.cpp >@@ -72,10 +72,12 @@ String bootSessionUUIDString() > std::call_once(onceKey, [] { > size_t uuidLength = 37; > char uuid[uuidLength]; >- if (sysctlbyname("kern.bootsessionuuid", uuid, &uuidLength, nullptr, 0)) >- return; >+ int result = sysctlbyname("kern.bootsessionuuid", uuid, &uuidLength, nullptr, 0); >+ RELEASE_ASSERT(!result); > bootSessionUUID.construct(static_cast<const char*>(uuid), uuidLength - 1); > }); >+#else >+ RELEASE_ASSERT_NOT_REACHED(); > #endif > return bootSessionUUID; > } >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index bcecba9089766f90f950c21783af62e118ffb6cc..f5a9e7fbaaddba838637f60292c59ba8f4c4bb7f 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -434,6 +434,7 @@ animation/WebAnimation.cpp > bindings/js/JSAudioNodeCustom.cpp > bindings/js/CachedModuleScriptLoader.cpp > bindings/js/CachedScriptFetcher.cpp >+bindings/js/CachedScriptSourceProvider.cpp > bindings/js/CallTracer.cpp > bindings/js/CommonVM.cpp > bindings/js/DOMGCOutputConstraint.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 680d6446f594c5f5bce02500f0ac5151ff7759a6..62a249b1648a475b73484ce3b5705dae830672e1 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -3824,7 +3824,7 @@ > BCB16C1C0979C3BD00467741 /* CachedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C030979C3BD00467741 /* CachedImage.h */; settings = {ATTRIBUTES = (Private, ); }; }; > BCB16C200979C3BD00467741 /* CachedResource.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C070979C3BD00467741 /* CachedResource.h */; settings = {ATTRIBUTES = (Private, ); }; }; > BCB16C220979C3BD00467741 /* CachedResourceClientWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C090979C3BD00467741 /* CachedResourceClientWalker.h */; }; >- BCB16C240979C3BD00467741 /* CachedScript.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C0B0979C3BD00467741 /* CachedScript.h */; }; >+ BCB16C240979C3BD00467741 /* CachedScript.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C0B0979C3BD00467741 /* CachedScript.h */; settings = {ATTRIBUTES = (Private, ); }; }; > BCB16C280979C3BD00467741 /* CachedXSLStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */; }; > BCB16C2A0979C3BD00467741 /* CachedResourceLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C110979C3BD00467741 /* CachedResourceLoader.h */; settings = {ATTRIBUTES = (Private, ); }; }; > BCB92D4F1293550B00C8387F /* FontBaseline.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB92D4E1293550B00C8387F /* FontBaseline.h */; settings = {ATTRIBUTES = (Private, ); }; }; >diff --git a/Source/WebCore/bindings/js/CachedScriptFetcher.cpp b/Source/WebCore/bindings/js/CachedScriptFetcher.cpp >index 7c87b23938e433e508c0fb80be9c9e6fde382103..1b36bc3977b9d8d77f17b39a55e7324d30f73a6f 100644 >--- a/Source/WebCore/bindings/js/CachedScriptFetcher.cpp >+++ b/Source/WebCore/bindings/js/CachedScriptFetcher.cpp >@@ -42,10 +42,10 @@ Ref<CachedScriptFetcher> CachedScriptFetcher::create(const String& charset) > > CachedResourceHandle<CachedScript> CachedScriptFetcher::requestModuleScript(Document& document, const URL& sourceURL, String&& integrity) const > { >- return requestScriptWithCache(document, sourceURL, String { }, WTFMove(integrity)); >+ return requestScriptWithCache(document, sourceURL, WebCore::ScriptMode::Module, String { }, WTFMove(integrity)); > } > >-CachedResourceHandle<CachedScript> CachedScriptFetcher::requestScriptWithCache(Document& document, const URL& sourceURL, const String& crossOriginMode, String&& integrity) const >+CachedResourceHandle<CachedScript> CachedScriptFetcher::requestScriptWithCache(Document& document, const URL& sourceURL, WebCore::ScriptMode scriptMode, const String& crossOriginMode, String&& integrity) const > { > if (!document.settings().isScriptEnabled()) > return nullptr; >@@ -56,6 +56,7 @@ CachedResourceHandle<CachedScript> CachedScriptFetcher::requestScriptWithCache(D > options.contentSecurityPolicyImposition = hasKnownNonce ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck; > options.sameOriginDataURLFlag = SameOriginDataURLFlag::Set; > options.integrity = WTFMove(integrity); >+ options.scriptMode = scriptMode; > > auto request = createPotentialAccessControlRequest(sourceURL, document, crossOriginMode, WTFMove(options)); > request.upgradeInsecureRequestIfNeeded(document); >diff --git a/Source/WebCore/bindings/js/CachedScriptFetcher.h b/Source/WebCore/bindings/js/CachedScriptFetcher.h >index d5391c697d7cf4f6f5d4079ca272ef77ea9caba7..969e643b2d8428b10005eba682be5e38dd76f5fa 100644 >--- a/Source/WebCore/bindings/js/CachedScriptFetcher.h >+++ b/Source/WebCore/bindings/js/CachedScriptFetcher.h >@@ -33,6 +33,7 @@ namespace WebCore { > > class CachedScript; > class Document; >+enum class ScriptMode : uint8_t; > > class CachedScriptFetcher : public JSC::ScriptFetcher { > public: >@@ -54,7 +55,7 @@ protected: > { > } > >- CachedResourceHandle<CachedScript> requestScriptWithCache(Document&, const URL& sourceURL, const String& crossOriginMode, String&& integrity) const; >+ CachedResourceHandle<CachedScript> requestScriptWithCache(Document&, const URL& sourceURL, ScriptMode, const String& crossOriginMode, String&& integrity) const; > > private: > String m_nonce; >diff --git a/Source/WebCore/bindings/js/CachedScriptSourceProvider.cpp b/Source/WebCore/bindings/js/CachedScriptSourceProvider.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..064f018f543e9f7139d48cc857755d8bfdca2115 >--- /dev/null >+++ b/Source/WebCore/bindings/js/CachedScriptSourceProvider.cpp >@@ -0,0 +1,53 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "CachedScriptSourceProvider.h" >+ >+namespace WebCore { >+ >+void CachedScriptSourceProvider::cacheBytecode(const JSC::BytecodeCacheGenerator&) const >+{ >+ m_shouldCache = true; >+ m_hasUpdates = true; >+} >+ >+void CachedScriptSourceProvider::updateCache(const JSC::UnlinkedFunctionExecutable*, const JSC::SourceCode& source, JSC::CodeSpecializationKind kind, const JSC::UnlinkedFunctionCodeBlock*) const >+{ >+ if (!m_shouldCache) >+ return; >+ m_hasUpdates = true; >+ m_bytecodeCacheMetadata.recordCachedFunctionCodeBlock(source, kind); >+} >+ >+void CachedScriptSourceProvider::commitCachedBytecode() const >+{ >+ if (!m_hasUpdates) >+ return; >+ m_hasUpdates = false; >+ platformStrategies()->loaderStrategy()->cacheBytecodeForScript(*m_cachedScript, m_bytecodeCacheMetadata); >+} >+ >+} // namespace WebCore >diff --git a/Source/WebCore/bindings/js/CachedScriptSourceProvider.h b/Source/WebCore/bindings/js/CachedScriptSourceProvider.h >index ae444c64536b235ca165746d940a170bc91caeab..bbb3881b9dfeae1b523bd56b3425220572f0a0aa 100644 >--- a/Source/WebCore/bindings/js/CachedScriptSourceProvider.h >+++ b/Source/WebCore/bindings/js/CachedScriptSourceProvider.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2008-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2008-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -29,6 +29,9 @@ > #include "CachedResourceHandle.h" > #include "CachedScript.h" > #include "CachedScriptFetcher.h" >+#include "LoaderStrategy.h" >+#include "PlatformStrategies.h" >+#include <JavaScriptCore/BytecodeCacheMetadata.h> > #include <JavaScriptCore/SourceProvider.h> > > namespace WebCore { >@@ -40,13 +43,21 @@ public: > > virtual ~CachedScriptSourceProvider() > { >+ commitCachedBytecode(); > m_cachedScript->removeClient(*this); > } > > unsigned hash() const override { return m_cachedScript->scriptHash(); } > StringView source() const override { return m_cachedScript->script(); } >+ RefPtr<JSC::CachedBytecode> cachedBytecode() const override { return m_cachedScript->cachedBytecode(); } >+ void commitCachedBytecode() const override; >+ >+ void cacheBytecode(const JSC::BytecodeCacheGenerator&) const override; >+ void updateCache(const JSC::UnlinkedFunctionExecutable*, const JSC::SourceCode&, JSC::CodeSpecializationKind, const JSC::UnlinkedFunctionCodeBlock*) const override; > > private: >+ void commitBytecodeCache(); >+ > CachedScriptSourceProvider(CachedScript* cachedScript, JSC::SourceProviderSourceType sourceType, Ref<CachedScriptFetcher>&& scriptFetcher) > : SourceProvider(JSC::SourceOrigin { cachedScript->response().url(), WTFMove(scriptFetcher) }, URL(cachedScript->response().url()), TextPosition(), sourceType) > , m_cachedScript(cachedScript) >@@ -54,6 +65,9 @@ private: > m_cachedScript->addClient(*this); > } > >+ mutable bool m_shouldCache { false }; >+ mutable bool m_hasUpdates { false }; >+ mutable JSC::BytecodeCacheMetadata m_bytecodeCacheMetadata; > CachedResourceHandle<CachedScript> m_cachedScript; > }; > >diff --git a/Source/WebCore/dom/LoadableClassicScript.cpp b/Source/WebCore/dom/LoadableClassicScript.cpp >index d927e95be269a25ae4336a74b00027c1758fe48a..3a2577140325e14e3443267c431fc3d1b4094e18 100644 >--- a/Source/WebCore/dom/LoadableClassicScript.cpp >+++ b/Source/WebCore/dom/LoadableClassicScript.cpp >@@ -126,7 +126,7 @@ void LoadableClassicScript::execute(ScriptElement& scriptElement) > bool LoadableClassicScript::load(Document& document, const URL& sourceURL) > { > ASSERT(!m_cachedScript); >- m_cachedScript = requestScriptWithCache(document, sourceURL, crossOriginMode(), String { m_integrity }); >+ m_cachedScript = requestScriptWithCache(document, sourceURL, WebCore::ScriptMode::Classic, crossOriginMode(), String { m_integrity }); > if (!m_cachedScript) > return false; > m_cachedScript->addClient(*this); >diff --git a/Source/WebCore/dom/ScriptElementCachedScriptFetcher.cpp b/Source/WebCore/dom/ScriptElementCachedScriptFetcher.cpp >index 843da203123c1283c089b396bb62b9ae4bd36c6b..2dd4166d7aa2f8c2d0f49b8714240d443158e388 100644 >--- a/Source/WebCore/dom/ScriptElementCachedScriptFetcher.cpp >+++ b/Source/WebCore/dom/ScriptElementCachedScriptFetcher.cpp >@@ -27,6 +27,7 @@ > #include "ScriptElementCachedScriptFetcher.h" > > #include "Element.h" >+#include "ResourceLoaderOptions.h" > #include "ScriptElement.h" > > namespace WebCore { >@@ -36,7 +37,7 @@ CachedResourceHandle<CachedScript> ScriptElementCachedScriptFetcher::requestModu > // https://github.com/tc39/proposal-dynamic-import/blob/master/HTML Integration.md > // If the fetcher is not module script, credential mode is always "omit". > >- return requestScriptWithCache(document, sourceURL, isClassicScript() ? "omit"_s : m_crossOriginMode, WTFMove(integrity)); >+ return requestScriptWithCache(document, sourceURL, isClassicScript() ? WebCore::ScriptMode::Classic : WebCore::ScriptMode::Module, isClassicScript() ? "omit"_s : m_crossOriginMode, WTFMove(integrity)); > } > > } >diff --git a/Source/WebCore/html/parser/HTMLResourcePreloader.cpp b/Source/WebCore/html/parser/HTMLResourcePreloader.cpp >index 3d006ab04bf528764f9f0c844abf46e0d63631ff..748a31fe27ed2b3ec617ee9c4c4fd235936b5c6a 100644 >--- a/Source/WebCore/html/parser/HTMLResourcePreloader.cpp >+++ b/Source/WebCore/html/parser/HTMLResourcePreloader.cpp >@@ -53,6 +53,12 @@ CachedResourceRequest PreloadRequest::resourceRequest(Document& document) > ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions(); > if (skipContentSecurityPolicyCheck) > options.contentSecurityPolicyImposition = ContentSecurityPolicyImposition::SkipPolicyCheck; >+ if (m_resourceType == CachedResource::Type::Script) { >+ if (m_moduleScript == ModuleScript::Yes) >+ options.scriptMode = ScriptMode::Module; >+ else >+ options.scriptMode = ScriptMode::Classic; >+ } > > String crossOriginMode = m_crossOriginMode; > if (m_moduleScript == ModuleScript::Yes) { >diff --git a/Source/WebCore/loader/LinkLoader.cpp b/Source/WebCore/loader/LinkLoader.cpp >index 2cd76f9301a4ffc1f26a8e00be41571c0a881ad9..cb6e1c85178ac5dc8a3d69e34a52cc43ea679837 100644 >--- a/Source/WebCore/loader/LinkLoader.cpp >+++ b/Source/WebCore/loader/LinkLoader.cpp >@@ -248,6 +248,9 @@ std::unique_ptr<LinkPreloadResourceClient> LinkLoader::preloadIfNeeded(const Lin > return nullptr; > > auto options = CachedResourceLoader::defaultCachedResourceOptions(); >+ if (type.value() == CachedResource::Type::Script) >+ options.scriptMode = ScriptMode::Classic; >+ > auto linkRequest = createPotentialAccessControlRequest(document.completeURL(href), document, crossOriginMode, WTFMove(options)); > linkRequest.setPriority(CachedResource::defaultPriorityForResourceType(type.value())); > linkRequest.setInitiator("link"); >diff --git a/Source/WebCore/loader/LoaderStrategy.h b/Source/WebCore/loader/LoaderStrategy.h >index 8a82381f018165e653e3c4b254e5697b63c09f70..4ee763ae23cdb47796259a66cc285b1d75083a5a 100644 >--- a/Source/WebCore/loader/LoaderStrategy.h >+++ b/Source/WebCore/loader/LoaderStrategy.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. >+ * Copyright (C) 2012-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -32,9 +32,14 @@ > #include <pal/SessionID.h> > #include <wtf/Forward.h> > >+namespace JSC { >+class BytecodeCacheMetadata; >+}; >+ > namespace WebCore { > > class CachedResource; >+class CachedScript; > class ContentSecurityPolicy; > class Frame; > class FrameLoader; >@@ -74,6 +79,8 @@ public: > using PreconnectCompletionHandler = WTF::Function<void(const ResourceError&)>; > virtual void preconnectTo(FrameLoader&, const URL&, StoredCredentialsPolicy, PreconnectCompletionHandler&&) = 0; > >+ virtual void cacheBytecodeForScript(const CachedScript&, const JSC::BytecodeCacheMetadata&) = 0; >+ > virtual void setCaptureExtraNetworkLoadMetricsEnabled(bool) = 0; > > virtual bool isOnLine() const = 0; >diff --git a/Source/WebCore/loader/ResourceLoader.cpp b/Source/WebCore/loader/ResourceLoader.cpp >index 8b66628f61cddb47d6e64108a2cb4d72ea032ab4..bd2ad03dcebd002a4a353f8f1be70f4e5afdc9fc 100644 >--- a/Source/WebCore/loader/ResourceLoader.cpp >+++ b/Source/WebCore/loader/ResourceLoader.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2006-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2006-2019 Apple Inc. All rights reserved. > * (C) 2007 Graham Dennis (graham.dennis@gmail.com) > * > * Redistribution and use in source and binary forms, with or without >@@ -818,4 +818,8 @@ bool ResourceLoader::isAlwaysOnLoggingAllowed() const > return frameLoader() && frameLoader()->isAlwaysOnLoggingAllowed(); > } > >+void ResourceLoader::didRetrieveDerivedDataFromCache(const String&, SharedBuffer&) >+{ >+} >+ > } >diff --git a/Source/WebCore/loader/ResourceLoader.h b/Source/WebCore/loader/ResourceLoader.h >index d17e58d6bd0449225c13b1a338fd1010f572eec6..1b5dfc09066742dd54c54d21f63ffa18dd42908a 100644 >--- a/Source/WebCore/loader/ResourceLoader.h >+++ b/Source/WebCore/loader/ResourceLoader.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2005-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2005-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -106,6 +106,7 @@ public: > virtual void didReceiveBuffer(Ref<SharedBuffer>&&, long long encodedDataLength, DataPayloadType); > virtual void didFinishLoading(const NetworkLoadMetrics&); > virtual void didFail(const ResourceError&); >+ virtual void didRetrieveDerivedDataFromCache(const String& type, SharedBuffer&); > > WEBCORE_EXPORT void didBlockAuthenticationChallenge(); > >diff --git a/Source/WebCore/loader/ResourceLoaderOptions.h b/Source/WebCore/loader/ResourceLoaderOptions.h >index 9e3074da3211d0ee97b8eb2edf49169ec5df2a4a..4e01064544a36fcd071074458a9ecae0366736e4 100644 >--- a/Source/WebCore/loader/ResourceLoaderOptions.h >+++ b/Source/WebCore/loader/ResourceLoaderOptions.h >@@ -127,6 +127,12 @@ enum class LoadedFromOpaqueSource : uint8_t { > No > }; > >+enum class ScriptMode : uint8_t { >+ None, >+ Classic, >+ Module, >+}; >+ > struct ResourceLoaderOptions : public FetchOptions { > ResourceLoaderOptions() { } > >@@ -172,6 +178,7 @@ struct ResourceLoaderOptions : public FetchOptions { > ClientCredentialPolicy clientCredentialPolicy { ClientCredentialPolicy::CannotAskClientForCredentials }; > PreflightPolicy preflightPolicy { PreflightPolicy::Consider }; > LoadedFromOpaqueSource loadedFromOpaqueSource { LoadedFromOpaqueSource::No }; >+ ScriptMode scriptMode { ScriptMode::None }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/loader/SubresourceLoader.cpp b/Source/WebCore/loader/SubresourceLoader.cpp >index 36b06bb891804b78aff257752353fc5ec8d0d2a9..9abde8eb9f6f744ef7219047c9e68aed763f32de 100644 >--- a/Source/WebCore/loader/SubresourceLoader.cpp >+++ b/Source/WebCore/loader/SubresourceLoader.cpp >@@ -751,6 +751,13 @@ void SubresourceLoader::didCancel(const ResourceError&) > notifyDone(LoadCompletionType::Cancel); > } > >+void SubresourceLoader::didRetrieveDerivedDataFromCache(const String& type, SharedBuffer& buffer) >+{ >+ if (m_state != Initialized) >+ return; >+ m_resource->didRetrieveDerivedDataFromCache(type, buffer); >+} >+ > void SubresourceLoader::notifyDone(LoadCompletionType type) > { > if (reachedTerminalState()) >diff --git a/Source/WebCore/loader/SubresourceLoader.h b/Source/WebCore/loader/SubresourceLoader.h >index dec8d0bacccf7b585e8b7d08f7c5bd92d621270c..af440da732611901e5857b32204201a4c63ec0ac 100644 >--- a/Source/WebCore/loader/SubresourceLoader.h >+++ b/Source/WebCore/loader/SubresourceLoader.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2005-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2005-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -79,6 +79,7 @@ private: > void didFail(const ResourceError&) override; > void willCancel(const ResourceError&) override; > void didCancel(const ResourceError&) override; >+ void didRetrieveDerivedDataFromCache(const String& type, SharedBuffer&) override; > > void updateReferrerPolicy(const String&); > >diff --git a/Source/WebCore/loader/ThreadableLoader.cpp b/Source/WebCore/loader/ThreadableLoader.cpp >index 2b7bf429dd622fc727e101302effeedd5e4c3847..6574606c006ec7561c16aef5a1ff2087d26be9f6 100644 >--- a/Source/WebCore/loader/ThreadableLoader.cpp >+++ b/Source/WebCore/loader/ThreadableLoader.cpp >@@ -90,6 +90,7 @@ ThreadableLoaderOptions ThreadableLoaderOptions::isolatedCopy() const > copy.clientCredentialPolicy = this->clientCredentialPolicy; > copy.maxRedirectCount = this->maxRedirectCount; > copy.preflightPolicy = this->preflightPolicy; >+ copy.scriptMode = this->scriptMode; > > // ThreadableLoaderOptions > copy.contentSecurityPolicyEnforcement = this->contentSecurityPolicyEnforcement; >diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h >index 9bf51e0b22744aa62e775d9ee75537f31ba88204..c7a48fa794d1775257eac94459d4f301019cd152 100644 >--- a/Source/WebCore/loader/cache/CachedResource.h >+++ b/Source/WebCore/loader/cache/CachedResource.h >@@ -270,6 +270,8 @@ public: > > virtual void didSendData(unsigned long long /* bytesSent */, unsigned long long /* totalBytesToBeSent */) { } > >+ virtual void didRetrieveDerivedDataFromCache(const String& /* type */, SharedBuffer&) { } >+ > #if USE(FOUNDATION) || USE(SOUP) > WEBCORE_EXPORT void tryReplaceEncodedData(SharedBuffer&); > #endif >diff --git a/Source/WebCore/loader/cache/CachedScript.cpp b/Source/WebCore/loader/cache/CachedScript.cpp >index 1bbd44469207c2466222dd235fa23f9b22fdda67..598326eda1e124d88a39a1629f1bc2eccd93cb1c 100644 >--- a/Source/WebCore/loader/cache/CachedScript.cpp >+++ b/Source/WebCore/loader/cache/CachedScript.cpp >@@ -3,7 +3,7 @@ > Copyright (C) 2001 Dirk Mueller (mueller@kde.org) > Copyright (C) 2002 Waldo Bastian (bastian@kde.org) > Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) >- Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. >+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2019 Apple Inc. All rights reserved. > > This library is free software; you can redistribute it and/or > modify it under the terms of the GNU Library General Public >@@ -33,6 +33,7 @@ > #include "RuntimeApplicationChecks.h" > #include "SharedBuffer.h" > #include "TextResourceDecoder.h" >+#include <wtf/Scope.h> > > namespace WebCore { > >@@ -89,6 +90,11 @@ StringView CachedScript::script() > return m_script; > } > >+RefPtr<JSC::CachedBytecode> CachedScript::cachedBytecode() >+{ >+ return m_cachedBytecode; >+} >+ > unsigned CachedScript::scriptHash() > { > if (m_decodingState == NeverDecoded) >@@ -103,6 +109,41 @@ void CachedScript::finishLoading(SharedBuffer* data) > CachedResource::finishLoading(data); > } > >+void CachedScript::didRetrieveDerivedDataFromCache(const String& type, SharedBuffer& sharedBuffer) >+{ >+#if OS(DARWIN) >+ ASSERT_UNUSED(type, type == "bytecode-cache"); >+ >+ String filename = String(sharedBuffer.data(), sharedBuffer.size()); >+ >+ dataLogLn("Reading cache from: ", filename); >+ >+ int fd = open(filename.ascii().data(), O_RDONLY | O_SHLOCK | O_NONBLOCK); >+ if (fd == -1) >+ return; >+ >+ auto closeFD = makeScopeExit([&] { >+ close(fd); >+ unlink(filename.ascii().data()); >+ }); >+ >+ struct stat sb; >+ int res = fstat(fd, &sb); >+ size_t size = static_cast<size_t>(sb.st_size); >+ if (res || !size) >+ return; >+ >+ void* buffer = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0); >+ if (buffer == MAP_FAILED) >+ return; >+ >+ m_cachedBytecode = JSC::CachedBytecode::create(buffer, size); >+#else >+ UNUSED_PARAM(type); >+ UNUSED_PARAM(sharedBuffer); >+#endif >+} >+ > void CachedScript::destroyDecodedData() > { > m_script = String(); >diff --git a/Source/WebCore/loader/cache/CachedScript.h b/Source/WebCore/loader/cache/CachedScript.h >index dd6fbcc3687811df06ec1ce28431f388a3d6003c..58bb2034b42367289371976b9992656dd600dfc7 100644 >--- a/Source/WebCore/loader/cache/CachedScript.h >+++ b/Source/WebCore/loader/cache/CachedScript.h >@@ -2,7 +2,7 @@ > Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) > Copyright (C) 2001 Dirk Mueller <mueller@kde.org> > Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) >- Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. >+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2019 Apple Inc. All rights reserved. > > This library is free software; you can redistribute it and/or > modify it under the terms of the GNU Library General Public >@@ -26,6 +26,7 @@ > #pragma once > > #include "CachedResource.h" >+#include <JavaScriptCore/SourceProvider.h> > > namespace WebCore { > >@@ -37,6 +38,7 @@ public: > virtual ~CachedScript(); > > StringView script(); >+ RefPtr<JSC::CachedBytecode> cachedBytecode(); > unsigned scriptHash(); > > private: >@@ -48,12 +50,14 @@ private: > String encoding() const final; > const TextResourceDecoder* textResourceDecoder() const final { return m_decoder.get(); } > void finishLoading(SharedBuffer*) final; >+ void didRetrieveDerivedDataFromCache(const String&, SharedBuffer&) final; > > void destroyDecodedData() final; > > void setBodyDataFrom(const CachedResource&) final; > > String m_script; >+ RefPtr<JSC::CachedBytecode> m_cachedBytecode; > unsigned m_scriptHash { 0 }; > > enum DecodingState { NeverDecoded, DataAndDecodedStringHaveSameBytes, DataAndDecodedStringHaveDifferentBytes }; >diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp >index e9c98f2e2227fe1c5251770d060d2ed2e3ccde5b..0aeb1741649a29cabe3061bedfde82bf8376cea3 100644 >--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp >@@ -603,6 +603,12 @@ WebCore::BlobRegistryImpl& NetworkConnectionToWebProcess::blobRegistry() > return m_networkProcess->networkBlobRegistry().blobRegistry(); > } > >+void NetworkConnectionToWebProcess::cacheBytecodeForRequest(const WebCore::ResourceRequest& request, const JSC::BytecodeCacheMetadata& metadata) >+{ >+ if (auto* bytecodeCache = m_networkProcess->bytecodeCache()) >+ bytecodeCache->storeMetadataForRequest(request, metadata); >+} >+ > void NetworkConnectionToWebProcess::setCaptureExtraNetworkLoadMetricsEnabled(bool enabled) > { > m_captureExtraNetworkLoadMetricsEnabled = enabled; >diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h >index 0903a164589da1954ce63fc31bed20beb21aed87..8ea363fca497839d5967e23decd6e0a2f9c78b05 100644 >--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h >+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h >@@ -187,6 +187,8 @@ private: > void unregisterBlobURL(const URL&); > void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&&)>&&); > >+ void cacheBytecodeForRequest(const WebCore::ResourceRequest&, const JSC::BytecodeCacheMetadata&); >+ > void setCaptureExtraNetworkLoadMetricsEnabled(bool); > > void createSocketStream(URL&&, PAL::SessionID, String cachePartition, uint64_t); >diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in >index fd848e3ad046c80c3ae3f46d39015a02f003c951..65d8bacef59d2f504f2da33edb75b1c9a01df860 100644 >--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in >+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in >@@ -49,6 +49,8 @@ messages -> NetworkConnectionToWebProcess LegacyReceiver { > BlobSize(URL url) -> (uint64_t resultSize) Synchronous > WriteBlobsToTemporaryFiles(Vector<String> blobURLs) -> (Vector<String> fileNames) Async > >+ CacheBytecodeForRequest(WebCore::ResourceRequest request, JSC::BytecodeCacheMetadata metadata) >+ > SetCaptureExtraNetworkLoadMetricsEnabled(bool enabled) > > CreateSocketStream(URL url, PAL::SessionID sessionID, String cachePartition, uint64_t identifier) >diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h >index d8563d22ab4f9c31ed5cf1943c53d15bd42abbeb..663b05bbb64833a6d6b8fc9be859a6263f2331d2 100644 >--- a/Source/WebKit/NetworkProcess/NetworkProcess.h >+++ b/Source/WebKit/NetworkProcess/NetworkProcess.h >@@ -26,6 +26,7 @@ > #pragma once > > #include "AuxiliaryProcess.h" >+#include "BytecodeCache.h" > #include "CacheModel.h" > #include "DownloadManager.h" > #include "NetworkBlobRegistry.h" >@@ -161,6 +162,7 @@ public: > DownloadManager& downloadManager(); > > NetworkCache::Cache* cache() { return m_cache.get(); } >+ BytecodeCache* bytecodeCache() { return m_bytecodeCache.get(); } > > void setSession(const PAL::SessionID&, Ref<NetworkSession>&&); > NetworkSession* networkSession(const PAL::SessionID&) const override; >@@ -473,6 +475,7 @@ private: > Vector<Ref<NetworkConnectionToWebProcess>> m_webProcessConnections; > > String m_diskCacheDirectory; >+ String m_bytecodeCacheDirectory; > bool m_hasSetCacheModel { false }; > CacheModel m_cacheModel { CacheModel::DocumentViewer }; > bool m_suppressMemoryPressureHandler { false }; >@@ -484,6 +487,7 @@ private: > HashMap<PAL::SessionID, Ref<CacheStorage::Engine>> m_cacheEngines; > > RefPtr<NetworkCache::Cache> m_cache; >+ RefPtr<BytecodeCache> m_bytecodeCache; > > typedef HashMap<const char*, std::unique_ptr<NetworkProcessSupplement>, PtrHash<const char*>> NetworkProcessSupplementMap; > NetworkProcessSupplementMap m_supplements; >diff --git a/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp b/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp >index dc34806a9b2a0442ce33113728ac35e55ee12e92..39221d6745c87fd2576cc59c741ea65c568fbe3d 100644 >--- a/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp >@@ -45,6 +45,8 @@ void NetworkProcessCreationParameters::encode(IPC::Encoder& encoder) const > encoder << canHandleHTTPSServerTrustEvaluation; > encoder << diskCacheDirectory; > encoder << diskCacheDirectoryExtensionHandle; >+ encoder << bytecodeCacheDirectory; >+ encoder << bytecodeCacheDirectoryExtensionHandle; > #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION) > encoder << shouldEnableNetworkCacheSpeculativeRevalidation; > #endif >@@ -112,6 +114,15 @@ bool NetworkProcessCreationParameters::decode(IPC::Decoder& decoder, NetworkProc > return false; > result.diskCacheDirectoryExtensionHandle = WTFMove(*diskCacheDirectoryExtensionHandle); > >+ if (!decoder.decode(result.bytecodeCacheDirectory)) >+ return false; >+ >+ Optional<SandboxExtension::Handle> bytecodeCacheDirectoryExtensionHandle; >+ decoder >> bytecodeCacheDirectoryExtensionHandle; >+ if (!bytecodeCacheDirectoryExtensionHandle) >+ return false; >+ result.bytecodeCacheDirectoryExtensionHandle = WTFMove(*bytecodeCacheDirectoryExtensionHandle); >+ > #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION) > if (!decoder.decode(result.shouldEnableNetworkCacheSpeculativeRevalidation)) > return false; >diff --git a/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h b/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h >index 9cdc45a1b2953000de7d9a06b7315fb65b2791fd..f1fcc3a92fd94aedf1607d3ed6fe834f6ce6bace 100644 >--- a/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h >+++ b/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h >@@ -56,6 +56,8 @@ struct NetworkProcessCreationParameters { > > String diskCacheDirectory; > SandboxExtension::Handle diskCacheDirectoryExtensionHandle; >+ String bytecodeCacheDirectory; >+ SandboxExtension::Handle bytecodeCacheDirectoryExtensionHandle; > #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION) > bool shouldEnableNetworkCacheSpeculativeRevalidation { false }; > #endif >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp >index 58aacb993db98accda6522d9564c9eaa894bda81..e1f5f704593389f5d19a46b8e609ecf489e1ad8b 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp >@@ -96,6 +96,8 @@ void NetworkResourceLoadParameters::encode(IPC::Encoder& encoder) const > encoder << frameAncestorOrigins; > encoder << isHTTPSUpgradeEnabled; > >+ encoder.encodeEnum(scriptMode); >+ > #if ENABLE(CONTENT_EXTENSIONS) > encoder << mainDocumentURL; > encoder << userContentControllerIdentifier; >@@ -212,6 +214,9 @@ bool NetworkResourceLoadParameters::decode(IPC::Decoder& decoder, NetworkResourc > if (!isHTTPSUpgradeEnabled) > return false; > result.isHTTPSUpgradeEnabled = *isHTTPSUpgradeEnabled; >+ >+ if (!decoder.decodeEnum(result.scriptMode)) >+ return false; > > #if ENABLE(CONTENT_EXTENSIONS) > if (!decoder.decode(result.mainDocumentURL)) >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h >index b05ff803f17190ade319cda063da031406e4f376..1dbcc853b17af241bf2f27b9668941676fe654d1 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h >@@ -30,6 +30,7 @@ > #include "UserContentControllerIdentifier.h" > #include <WebCore/ContentSecurityPolicyResponseHeaders.h> > #include <WebCore/FetchOptions.h> >+#include <WebCore/ResourceLoaderOptions.h> > #include <WebCore/SecurityOrigin.h> > #include <wtf/Seconds.h> > >@@ -60,6 +61,7 @@ public: > bool shouldEnableCrossOriginResourcePolicy { false }; > Vector<RefPtr<WebCore::SecurityOrigin>> frameAncestorOrigins; > bool isHTTPSUpgradeEnabled { false }; >+ WebCore::ScriptMode scriptMode { WebCore::ScriptMode::None }; > > #if ENABLE(CONTENT_EXTENSIONS) > URL mainDocumentURL; >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >index 4510e9268a22c205c8c6b035a7b0fcfe478e06e2..ede36c3f9abcaf3d040e8288648604dec2d7fb77 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >@@ -27,6 +27,7 @@ > #include "NetworkResourceLoader.h" > > #include "DataReference.h" >+#include "DerivedData.h" > #include "FormDataReference.h" > #include "Logging.h" > #include "NetworkCache.h" >@@ -99,6 +100,7 @@ NetworkResourceLoader::NetworkResourceLoader(NetworkResourceLoadParameters&& par > , m_isAllowedToAskUserForCredentials { m_parameters.clientCredentialPolicy == ClientCredentialPolicy::MayAskClientForCredentials } > , m_bufferingTimer { *this, &NetworkResourceLoader::bufferingTimerFired } > , m_cache { sessionID().isEphemeral() ? nullptr : connection.networkProcess().cache() } >+ , m_bytecodeCache { sessionID().isEphemeral() ? nullptr : connection.networkProcess().bytecodeCache() } > , m_shouldCaptureExtraNetworkLoadMetrics(m_connection->captureExtraNetworkLoadMetricsEnabled()) > { > ASSERT(RunLoop::isMain()); >@@ -143,6 +145,18 @@ bool NetworkResourceLoader::canUseCache(const ResourceRequest& request) const > return true; > } > >+bool NetworkResourceLoader::canUseBytecodeCache(const ResourceRequest& request) const >+{ >+ if (!m_bytecodeCache) >+ return false; >+ ASSERT(!sessionID().isEphemeral()); >+ >+ if (!canUseCache(request)) >+ return false; >+ >+ return true; >+} >+ > bool NetworkResourceLoader::canUseCachedRedirect(const ResourceRequest& request) const > { > if (!canUseCache(request) || m_cacheEntryForMaxAgeCapValidation) >@@ -482,14 +496,15 @@ void NetworkResourceLoader::didReceiveResponse(ResourceResponse&& receivedRespon > // We wait to receive message NetworkResourceLoader::ContinueDidReceiveResponse before continuing a load for > // a main resource because the embedding client must decide whether to allow the load. > bool willWaitForContinueDidReceiveResponse = isMainResource(); >- send(Messages::WebResourceLoader::DidReceiveResponse { response, willWaitForContinueDidReceiveResponse }); > > if (willWaitForContinueDidReceiveResponse) { >+ send(Messages::WebResourceLoader::DidReceiveResponse { response, willWaitForContinueDidReceiveResponse, { } }); > m_responseCompletionHandler = WTFMove(completionHandler); > return; > } > > if (m_isKeptAlive) { >+ send(Messages::WebResourceLoader::DidReceiveResponse { response, willWaitForContinueDidReceiveResponse, { } }); > m_responseCompletionHandler = WTFMove(completionHandler); > RunLoop::main().dispatch([protectedThis = makeRef(*this)] { > protectedThis->didFinishLoading(NetworkLoadMetrics { }); >@@ -497,7 +512,12 @@ void NetworkResourceLoader::didReceiveResponse(ResourceResponse&& receivedRespon > return; > } > >- completionHandler(PolicyAction::Use); >+ loadBytecodeCache(response, m_bufferedDataForCache, [loader = makeRef(*this), completionHandler = WTFMove(completionHandler), response = WTFMove(response)](Vector<IPC::DerivedData>&& derivedData) mutable { >+ if (loader->hasOneRef()) >+ return; >+ loader->send(Messages::WebResourceLoader::DidReceiveResponse { response, false, WTFMove(derivedData) }); >+ completionHandler(PolicyAction::Use); >+ }); > } > > void NetworkResourceLoader::didReceiveBuffer(Ref<SharedBuffer>&& buffer, int reportedEncodedDataLength) >@@ -850,16 +870,41 @@ void NetworkResourceLoader::didRetrieveCacheEntry(std::unique_ptr<NetworkCache:: > } > > bool needsContinueDidReceiveResponseMessage = isMainResource(); >- send(Messages::WebResourceLoader::DidReceiveResponse { response, needsContinueDidReceiveResponseMessage }); > >- if (needsContinueDidReceiveResponseMessage) >- m_cacheEntryWaitingForContinueDidReceiveResponse = WTFMove(entry); >+ if (!needsContinueDidReceiveResponseMessage) >+ processCachedEntryAfterDidReceiveResponse(WTFMove(entry)); > else { >- sendResultForCacheEntry(WTFMove(entry)); >- cleanup(LoadResult::Success); >+ send(Messages::WebResourceLoader::DidReceiveResponse { response, needsContinueDidReceiveResponseMessage, { } }); >+ m_cacheEntryWaitingForContinueDidReceiveResponse = WTFMove(entry); > } > } > >+void NetworkResourceLoader::loadBytecodeCache(const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer> buffer, CompletionHandler<void(Vector<IPC::DerivedData>&&)>&& completionHandler) >+{ >+ if (!buffer || m_parameters.scriptMode == WebCore::ScriptMode::None || !canUseBytecodeCache(originalRequest())) { >+ completionHandler({ }); >+ return; >+ } >+ >+ m_bytecodeCache->bytecodeForRequest(originalRequest(), m_parameters.scriptMode, buffer, [completionHandler = WTFMove(completionHandler)](const uint8_t* data, size_t size) mutable { >+ Vector<IPC::DerivedData> derivedData; >+ if (data) >+ derivedData.append(IPC::DerivedData { "bytecode-cache", IPC::DataReference { data, size } }); >+ completionHandler(WTFMove(derivedData)); >+ }); >+} >+ >+void NetworkResourceLoader::processCachedEntryAfterDidReceiveResponse(std::unique_ptr<NetworkCache::Entry> entry) >+{ >+ loadBytecodeCache(entry->response(), entry->buffer(), [loader = makeRef(*this), entry = WTFMove(entry)](Vector<IPC::DerivedData>&& derivedData) mutable { >+ if (loader->hasOneRef()) >+ return; >+ loader->send(Messages::WebResourceLoader::DidReceiveResponse { entry->response(), false, WTFMove(derivedData) }); >+ loader->sendResultForCacheEntry(WTFMove(entry)); >+ loader->cleanup(LoadResult::Success); >+ }); >+} >+ > void NetworkResourceLoader::sendResultForCacheEntry(std::unique_ptr<NetworkCache::Entry> entry) > { > #if ENABLE(SHAREABLE_RESOURCE) >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.h b/Source/WebKit/NetworkProcess/NetworkResourceLoader.h >index a8a3005c142306138876821a43a057a0b6f3d7fc..1ec125e1a0fd253abde1561a9c446f60da8ef9f3 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.h >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012-2015 Apple Inc. All rights reserved. >+ * Copyright (C) 2012-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -25,6 +25,7 @@ > > #pragma once > >+#include "BytecodeCache.h" > #include "DownloadID.h" > #include "MessageSender.h" > #include "NetworkCache.h" >@@ -44,6 +45,10 @@ class NetworkStorageSession; > class ResourceRequest; > } > >+namespace IPC { >+class DerivedData; >+} >+ > namespace WebKit { > > class NetworkConnectionToWebProcess; >@@ -125,6 +130,7 @@ private: > uint64_t messageSenderDestinationID() const override { return m_parameters.identifier; } > > bool canUseCache(const WebCore::ResourceRequest&) const; >+ bool canUseBytecodeCache(const WebCore::ResourceRequest&) const; > bool canUseCachedRedirect(const WebCore::ResourceRequest&) const; > > void tryStoreAsCacheEntry(); >@@ -133,6 +139,8 @@ private: > void sendResultForCacheEntry(std::unique_ptr<NetworkCache::Entry>); > void validateCacheEntry(std::unique_ptr<NetworkCache::Entry>); > void dispatchWillSendRequestForCacheEntry(WebCore::ResourceRequest&&, std::unique_ptr<NetworkCache::Entry>&&); >+ void loadBytecodeCache(const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>, CompletionHandler<void(Vector<IPC::DerivedData>&&)>&&); >+ void processCachedEntryAfterDidReceiveResponse(std::unique_ptr<NetworkCache::Entry>); > > bool shouldInterruptLoadForXFrameOptions(const String&, const URL&); > bool shouldInterruptLoadForCSPFrameAncestorsOrXFrameOptions(const WebCore::ResourceResponse&); >@@ -198,10 +206,9 @@ private: > bool m_isAllowedToAskUserForCredentials { false }; > size_t m_numBytesReceived { 0 }; > >- unsigned m_retrievedDerivedDataCount { 0 }; >- > WebCore::Timer m_bufferingTimer; > RefPtr<NetworkCache::Cache> m_cache; >+ RefPtr<BytecodeCache> m_bytecodeCache; > RefPtr<WebCore::SharedBuffer> m_bufferedDataForCache; > std::unique_ptr<NetworkCache::Entry> m_cacheEntryForValidation; > std::unique_ptr<NetworkCache::Entry> m_cacheEntryForMaxAgeCapValidation; >diff --git a/Source/WebKit/NetworkProcess/cache/BytecodeCache.cpp b/Source/WebKit/NetworkProcess/cache/BytecodeCache.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..e940d4cd55e95842f281abd15aa25d242d205b00 >--- /dev/null >+++ b/Source/WebKit/NetworkProcess/cache/BytecodeCache.cpp >@@ -0,0 +1,338 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "BytecodeCache.h" >+ >+#include "Logging.h" >+#include "NetworkCache.h" >+#include "NetworkProcess.h" >+#include <JavaScriptCore/BytecodeCacheMetadata.h> >+#include <JavaScriptCore/Completion.h> >+#include <JavaScriptCore/JSGlobalObject.h> >+#include <JavaScriptCore/JSSourceCode.h> >+#include <JavaScriptCore/ParserError.h> >+#include <JavaScriptCore/VM.h> >+#include <WebCore/ResourceLoaderOptions.h> >+#include <WebCore/ResourceRequest.h> >+#include <wtf/Threading.h> >+ >+namespace WebKit { >+ >+class CacheFile { >+ WTF_MAKE_NONCOPYABLE(CacheFile); >+ >+public: >+ CacheFile() >+ : m_fd(-1) >+ { >+ } >+ >+ CacheFile(const CString& name, int fd) >+ : m_name(name) >+ , m_fd(fd) >+ { >+ } >+ >+ CacheFile(CacheFile&& other) >+ : m_name(WTFMove(other.m_name)) >+ , m_fd(other.m_fd) >+ { >+ other.m_fd = -1; >+ } >+ >+ CacheFile& operator=(CacheFile&& other) >+ { >+ m_name = WTFMove(other.m_name); >+ m_fd = other.m_fd; >+ other.m_fd = -1; >+ return *this; >+ } >+ >+ ~CacheFile() >+ { >+ if (m_fd != -1) >+ close(m_fd); >+ } >+ >+ const CString& name() const { return m_name; } >+ int fd() const { return m_fd; } >+ >+ bool operator!() const { return m_fd < 0; } >+ >+private: >+ CString m_name; >+ int m_fd; >+}; >+ >+static constexpr const char* bytecodeCacheKey = "bytecode-cache"; >+static constexpr const char* bytecodeMetadataKey = "bytecode-metadata"; >+ >+class BytecodeCache::Plan : public RefCounted<BytecodeCache::Plan> { >+ WTF_MAKE_NONCOPYABLE(Plan); >+ WTF_MAKE_FAST_ALLOCATED; >+ >+public: >+ static Ref<Plan> create(const URL& url, const String& cachePartition, ScriptMode scriptMode, JSC::BytecodeCacheMetadata&& metadata, RefPtr<WebCore::SharedBuffer> body, Callback&& callback) >+ { >+ return adoptRef(*new Plan { url, cachePartition, scriptMode, WTFMove(metadata), WTFMove(body), WTFMove(callback) }); >+ } >+ >+ void compile(NetworkCache::Cache* cache, JSC::VM& vm, CacheFile&& cacheFile) >+ { >+ LOG(BytecodeCache, "[BytecodeCache][Plan] Processing: %s", m_url.string().ascii().data()); >+ >+ { >+ auto start = MonotonicTime::now(); >+ JSC::JSLockHolder locker(vm); >+ JSC::SourceCode sourceCode = JSC::makeSource(String(m_body->data(), m_body->size()), JSC::SourceOrigin { m_url.string() }, URL(m_url)); >+ JSC::ParserError error; >+ switch (m_scriptMode) { >+ case WebCore::ScriptMode::Classic: >+ JSC::generateProgramBytecode(vm, sourceCode, cacheFile.fd(), error, &m_metadata); >+ break; >+ case WebCore::ScriptMode::Module: >+ JSC::generateModuleBytecode(vm, sourceCode, cacheFile.fd(), error, &m_metadata); >+ break; >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ } >+ auto end = MonotonicTime::now(); >+ dataLogLn("generateBytecode: ", end - start, " - ", m_url.string()); >+ >+ if (error.isValid()) { >+ LOG(BytecodeCache, "[BytecodeCache] Unable to generate bytecode cache because script had a parse error"); >+ m_callback(nullptr, 0); >+ return; >+ } >+ } >+ >+ RunLoop::main().dispatch([protectedThis = makeRef(*this), cache, cacheFile = WTFMove(cacheFile)]() mutable { >+ NetworkCache::DataKey cacheKey { protectedThis->m_cachePartition, bytecodeCacheKey, protectedThis->m_url.string() }; >+ cache->storeFile(cacheKey, cacheFile.name().data()); >+ protectedThis->m_callback(reinterpret_cast<const uint8_t*>(cacheFile.name().data()), cacheFile.name().length()); >+ }); >+ } >+ >+private: >+ Plan(const URL& url, const String& cachePartition, ScriptMode scriptMode, JSC::BytecodeCacheMetadata&& metadata, RefPtr<WebCore::SharedBuffer> body, Callback&& callback) >+ : m_url(url) >+ , m_cachePartition(cachePartition) >+ , m_scriptMode(scriptMode) >+ , m_metadata(WTFMove(metadata)) >+ , m_body(WTFMove(body)) >+ , m_callback(WTFMove(callback)) >+ { >+ } >+ >+ URL m_url; >+ String m_cachePartition; >+ ScriptMode m_scriptMode; >+ JSC::BytecodeCacheMetadata m_metadata; >+ RefPtr<WebCore::SharedBuffer> m_body; >+ Callback m_callback; >+}; >+ >+class BytecodeCache::Thread : public AutomaticThread { >+public: >+ static Ref<Thread> create(const AbstractLocker& locker, BytecodeCache& cache) >+ { >+ return adoptRef(*new Thread(locker, cache)); >+ } >+ >+ const char* name() const override >+ { >+ return "BytecodeCache Helper Thread"; >+ } >+ >+protected: >+ PollResult poll(const AbstractLocker&) override >+ { >+ if (m_cache.m_queue.isEmpty()) >+ return PollResult::Wait; >+ >+ m_plans = WTFMove(m_cache.m_queue); >+ return PollResult::Work; >+ } >+ >+ WorkResult work() override >+ { >+ RELEASE_ASSERT(!m_plans.isEmpty()); >+ NetworkCache::Cache* cache = m_cache.m_networkProcess.cache(); >+ if (!cache) >+ return WorkResult::Stop; >+ >+ for (const auto& plan : m_plans) >+ plan->compile(cache, *m_vm, m_cache.createCacheFile()); >+ >+ m_plans.clear(); >+ return WorkResult::Continue; >+ } >+ >+ void threadDidStart() override >+ { >+ LOG(BytecodeCache, "[BytecodeCache][Thread] Started"); >+ m_vm = JSC::VM::create(); >+ } >+ >+ void threadIsStopping(const AbstractLocker&) override >+ { >+ JSC::JSLockHolder locker(*m_vm); >+ m_vm = nullptr; >+ LOG(BytecodeCache, "[BytecodeCache][Thread] Stopped"); >+ } >+ >+private: >+ Thread(const AbstractLocker& locker, BytecodeCache& cache) >+ : AutomaticThread(locker, cache.m_lock, cache.m_condition.copyRef()) >+ , m_cache(cache) >+ { >+ } >+ >+ BytecodeCache& m_cache; >+ Plans m_plans; >+ RefPtr<JSC::VM> m_vm; >+}; >+ >+RefPtr<BytecodeCache> BytecodeCache::create(NetworkProcess& networkProcess, const String& bytecodeCacheDirectory) >+{ >+ if (!FileSystem::makeAllDirectories(bytecodeCacheDirectory)) >+ return nullptr; >+ return adoptRef(*new BytecodeCache(networkProcess, bytecodeCacheDirectory)); >+} >+ >+BytecodeCache::BytecodeCache(NetworkProcess& networkProcess, const String& bytecodeCacheDirectory) >+ : m_networkProcess(networkProcess) >+ , m_bytecodeCacheDirectory(bytecodeCacheDirectory) >+ , m_lock(Box<Lock>::create()) >+ , m_condition(AutomaticThreadCondition::create()) >+{ >+ LockHolder locker(*m_lock); >+ m_thread = Thread::create(locker, *this); >+} >+ >+BytecodeCache::~BytecodeCache() >+{ >+} >+ >+void BytecodeCache::storeMetadataForRequest(const WebCore::ResourceRequest& request, const JSC::BytecodeCacheMetadata& metadata) >+{ >+ LOG(BytecodeCache, "[BytecodeCache] storeMetadataForRequest - Checking: %s", request.url().string().ascii().data()); >+ >+ NetworkCache::Cache* cache = m_networkProcess.cache(); >+ if (!cache) { >+ LOG(BytecodeCache, "[BytecodeCache] Cannot store metadata: cache is not available"); >+ return; >+ } >+ >+ NetworkCache::DataKey metadataKey { request.cachePartition(), bytecodeMetadataKey, request.url().string() }; >+ std::pair<MallocPtr<uint8_t>, size_t> encodedMetadata = metadata.encode(); >+ cache->storeData(metadataKey, encodedMetadata.first.get(), encodedMetadata.second); >+ >+ NetworkCache::DataKey cacheKey { request.cachePartition(), bytecodeCacheKey, request.url().string() }; >+ cache->removeFile(cacheKey); >+} >+ >+CacheFile BytecodeCache::createCacheFile() const >+{ >+ String fileTemplate = FileSystem::pathByAppendingComponent(m_bytecodeCacheDirectory, "XXXXXXXX"); >+ CString filename = FileSystem::fileSystemRepresentation(fileTemplate); >+ int fd = mkstemp(filename.mutableData()); >+ if (fd < 0) >+ return { }; >+ return { WTFMove(filename), fd }; >+} >+ >+void BytecodeCache::bytecodeForRequest(const WebCore::ResourceRequest& request, WebCore::ScriptMode scriptMode, RefPtr<WebCore::SharedBuffer> body, Callback&& callback) >+{ >+ LOG(BytecodeCache, "[BytecodeCache] bytecodeForRequest - Checking: %s", request.url().string().ascii().data()); >+ >+ NetworkCache::Cache* cache = m_networkProcess.cache(); >+ if (!cache) { >+ LOG(BytecodeCache, "[BytecodeCache] Cannot generate bytecode for request: cache is not available"); >+ callback(nullptr, 0); >+ return; >+ } >+ >+ // tryLoadBytecodeCache() => tryLoadMetadata() => generateBytecode() >+ NetworkCache::DataKey cacheKey { request.cachePartition(), bytecodeCacheKey, request.url().string() }; >+ cache->retrieveFile(cacheKey, [protectedThis = makeRef(*this), callback = WTFMove(callback), request = WebCore::ResourceRequest { request }, body = WTFMove(body), scriptMode](const char* file) mutable { >+ if (file) { >+ CacheFile cacheFile = protectedThis->createCacheFile(); >+ if (!cacheFile) { >+ LOG(BytecodeCache, "[BytecodeCache] Failed to create cache file"); >+ callback(nullptr, 0); >+ return; >+ } >+ >+ unlink(cacheFile.name().data()); >+ if (link(file, cacheFile.name().data())) { >+ LOG(BytecodeCache, "[BytecodeCache] Failed to link cache file"); >+ callback(nullptr, 0); >+ return; >+ } >+ >+ LOG(BytecodeCache, "[BytecodeCache] Returning bytecode from disk cache"); >+ callback(reinterpret_cast<const uint8_t*>(cacheFile.name().data()), cacheFile.name().length()); >+ return; >+ } >+ >+ NetworkCache::Cache* cache = protectedThis->m_networkProcess.cache(); >+ if (!cache) { >+ LOG(BytecodeCache, "[BytecodeCache] Cannot generate bytecode for request: cache is not available"); >+ callback(nullptr, 0); >+ return; >+ } >+ >+ NetworkCache::DataKey metadataKey { request.cachePartition(), bytecodeMetadataKey, request.url().string() }; >+ cache->retrieveData(metadataKey, [protectedThis = WTFMove(protectedThis), callback = WTFMove(callback), request = WebCore::ResourceRequest { request }, body = WTFMove(body), scriptMode](const uint8_t* data, size_t size) mutable { >+ if (!data) { >+ LOG(BytecodeCache, "[BytecodeCache] Did not find bytecode or metadata for %s", request.url().string().ascii().data()); >+ callback(nullptr, 0); >+ return; >+ } >+ >+ NetworkCache::Cache* cache = protectedThis->m_networkProcess.cache(); >+ if (!cache) { >+ LOG(BytecodeCache, "[BytecodeCache] Cannot generate bytecode for request: cache is not available"); >+ callback(nullptr, 0); >+ return; >+ } >+ >+ LOG(BytecodeCache, "[BytecodeCache] Found metadata, generating bytecode"); >+ LockHolder locker(*protectedThis->m_lock); >+ protectedThis->m_queue.append(Plan::create( >+ request.url(), >+ request.cachePartition(), >+ scriptMode, >+ JSC::BytecodeCacheMetadata::decode(data, size), >+ WTFMove(body), >+ WTFMove(callback))); >+ protectedThis->m_condition->notifyAll(locker); >+ }); >+ }); >+} >+ >+} // namespace WebKit >diff --git a/Source/WebKit/NetworkProcess/cache/BytecodeCache.h b/Source/WebKit/NetworkProcess/cache/BytecodeCache.h >new file mode 100644 >index 0000000000000000000000000000000000000000..236be150f6e65156f90525b9636481bde6705e62 >--- /dev/null >+++ b/Source/WebKit/NetworkProcess/cache/BytecodeCache.h >@@ -0,0 +1,86 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include <wtf/AutomaticThread.h> >+#include <wtf/CompletionHandler.h> >+#include <wtf/Noncopyable.h> >+#include <wtf/RefCounted.h> >+#include <wtf/RefPtr.h> >+#include <wtf/text/WTFString.h> >+ >+namespace JSC { >+class BytecodeCacheMetadata; >+class VM; >+}; >+ >+namespace WebCore { >+class ResourceRequest; >+class SharedBuffer; >+enum class ScriptMode : uint8_t; >+}; >+ >+namespace WebKit { >+ >+class NetworkProcess; >+ >+class CacheFile; >+ >+class BytecodeCache : public RefCounted<BytecodeCache> { >+ WTF_MAKE_NONCOPYABLE(BytecodeCache); >+ WTF_MAKE_FAST_ALLOCATED; >+ >+ class Plan; >+ class Thread; >+ using Plans = Vector<Ref<Plan>, 2>; >+ >+ friend class Thread; >+ >+public: >+ static RefPtr<BytecodeCache> create(NetworkProcess&, const String& bytecodeCacheDirectory); >+ >+ ~BytecodeCache(); >+ >+ void storeMetadataForRequest(const WebCore::ResourceRequest&, const JSC::BytecodeCacheMetadata&); >+ >+ using Callback = CompletionHandler<void(const uint8_t*, size_t)>; >+ void bytecodeForRequest(const WebCore::ResourceRequest&, WebCore::ScriptMode, RefPtr<WebCore::SharedBuffer>, Callback&&); >+ >+private: >+ BytecodeCache(NetworkProcess&, const String& bytecodeCacheDirectory); >+ >+ CacheFile createCacheFile() const; >+ void generateBytecode(const WebCore::ResourceRequest&, WebCore::ScriptMode, RefPtr<WebCore::SharedBuffer>, JSC::BytecodeCacheMetadata&&, Callback&&); >+ >+ NetworkProcess& m_networkProcess; >+ String m_bytecodeCacheDirectory; >+ Plans m_queue; >+ Box<Lock> m_lock; >+ Ref<AutomaticThreadCondition> m_condition; >+ RefPtr<AutomaticThread> m_thread; >+}; >+ >+} // namespace WebKit >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp b/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp >index e5e68138ff55efd12743b5fbd66a046ff34ba20b..126f4daf52ce06194b7ccb210d8506cdb3b5282e 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp >@@ -592,5 +592,23 @@ void Cache::storeData(const DataKey& dataKey, const uint8_t* data, size_t size) > m_storage->store(record, { }); > } > >+void Cache::retrieveFile(const DataKey& dataKey, Function<void(const char*)> completionHandler) >+{ >+ Key key { dataKey, m_storage->salt() }; >+ m_storage->retrieveFile(key, WTFMove(completionHandler)); >+} >+ >+void Cache::storeFile(const DataKey& dataKey, const char* filename) >+{ >+ Key key { dataKey, m_storage->salt() }; >+ m_storage->storeFile(key, filename); >+} >+ >+void Cache::removeFile(const DataKey& dataKey) >+{ >+ Key key { dataKey, m_storage->salt() }; >+ m_storage->removeFile(key); >+} >+ > } > } >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCache.h b/Source/WebKit/NetworkProcess/cache/NetworkCache.h >index c7f386b3d7c3145580f2ac0e0e352ea6b87155c1..3365419ad1ec577f1c279312f77d96e4fc543690 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCache.h >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCache.h >@@ -130,7 +130,11 @@ public: > > void retrieveData(const DataKey&, Function<void(const uint8_t*, size_t)>); > void storeData(const DataKey&, const uint8_t* data, size_t); >- >+ >+ void retrieveFile(const DataKey&, Function<void(const char*)>); >+ void storeFile(const DataKey&, const char*); >+ void removeFile(const DataKey&); >+ > std::unique_ptr<Entry> makeEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&); > std::unique_ptr<Entry> makeRedirectEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest); > >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheKey.cpp b/Source/WebKit/NetworkProcess/cache/NetworkCacheKey.cpp >index 8fa81d109a4c73cd0b3195b88ff5e3db157c38e6..d804bae12897d43ab8545a81bc968871e426a139 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCacheKey.cpp >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheKey.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2014-2015 Apple Inc. All rights reserved. >+ * Copyright (C) 2014-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -64,7 +64,7 @@ Key::Key(WTF::HashTableDeletedValueType) > Key::Key(const DataKey& dataKey, const Salt& salt) > : m_partition(dataKey.partition) > , m_type(dataKey.type) >- , m_identifier(hashAsString(dataKey.identifier)) >+ , m_identifier(dataKey.identifier) > , m_hash(computeHash(salt)) > , m_partitionHash(computePartitionHash(salt)) > { >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheKey.h b/Source/WebKit/NetworkProcess/cache/NetworkCacheKey.h >index 2915b214b32eca479513849f12b7c4dbc7f3d549..714f998ebbcdab2e5afc7fb44aa8ed28204233cb 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCacheKey.h >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheKey.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2014-2015 Apple Inc. All rights reserved. >+ * Copyright (C) 2014-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -37,7 +37,7 @@ namespace NetworkCache { > struct DataKey { > String partition; > String type; >- SHA1::Digest identifier; >+ String identifier; > > template <class Encoder> void encode(Encoder& encoder) const > { >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp b/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp >index bbfc649890f95cc7e04ce82a4fe32944dc1ab1f0..147ca8548a63f5f3c7e0d58cfd6c9c0bbfe98167 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp >@@ -1135,5 +1135,42 @@ void Storage::deleteOldVersions() > }); > } > >+void Storage::storeFile(const Key& key, const char* filename) >+{ >+ ASSERT(RunLoop::isMain()); >+ ASSERT(!key.isNull()); >+ >+ auto blobDirectoryPath = recordDirectoryPathForKey(key); >+ FileSystem::makeAllDirectories(blobDirectoryPath); >+ >+ auto blobPath = FileSystem::fileSystemRepresentation(blobPathForKey(key)); >+ unlink(blobPath.data()); >+ if (link(filename, blobPath.data()) == -1) >+ LOG(NetworkCacheStorage, "Failed to store file: %s", filename); >+} >+ >+void Storage::retrieveFile(const Key& key, RetrieveFileCompletionHandler&& completionHandler) >+{ >+ ASSERT(RunLoop::isMain()); >+ ASSERT(!key.isNull()); >+ >+ auto blobPath = blobPathForKey(key); >+ if (!FileSystem::fileExists(blobPath)) { >+ completionHandler(nullptr); >+ return; >+ } >+ >+ completionHandler(FileSystem::fileSystemRepresentation(blobPath).data()); >+} >+ >+void Storage::removeFile(const Key& key) >+{ >+ ASSERT(RunLoop::isMain()); >+ ASSERT(!key.isNull()); >+ >+ auto blobPath = blobPathForKey(key); >+ FileSystem::deleteFile(blobPath); >+} >+ > } > } >diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h b/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h >index 617b2b3a5fde2a575b18fc7cb57cef1e18272ea9..7737b2b085e78b9f50354f155068f9706b9b570d 100644 >--- a/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h >+++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.h >@@ -84,6 +84,11 @@ public: > using MappedBodyHandler = Function<void (const Data& mappedBody)>; > void store(const Record&, MappedBodyHandler&&, CompletionHandler<void(int)>&& = { }); > >+ using RetrieveFileCompletionHandler = CompletionHandler<void(const char*)>; >+ void retrieveFile(const Key&, RetrieveFileCompletionHandler&&); >+ void storeFile(const Key&, const char*); >+ void removeFile(const Key&); >+ > void remove(const Key&); > void remove(const Vector<Key>&, CompletionHandler<void()>&&); > void clear(const String& type, WallTime modifiedSinceTime, CompletionHandler<void()>&&); >diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm >index ead5e62eab8454b3ddf2f9cb6cebaf40c80f7ba2..1e681dda07f33039d31ae338500cb616507e563c 100644 >--- a/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm >+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2014-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2014-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -88,6 +88,7 @@ void NetworkProcess::platformInitializeNetworkProcessCocoa(const NetworkProcessC > #endif > #endif > m_diskCacheDirectory = parameters.diskCacheDirectory; >+ m_bytecodeCacheDirectory = parameters.bytecodeCacheDirectory; > > _CFNetworkSetATSContext(parameters.networkATSContext.get()); > >@@ -132,6 +133,14 @@ void NetworkProcess::platformInitializeNetworkProcessCocoa(const NetworkProcessC > // Disable NSURLCache. > auto urlCache(adoptNS([[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil])); > [NSURLCache setSharedURLCache:urlCache.get()]; >+ >+ if (m_bytecodeCacheDirectory.isNull()) >+ return; >+ >+ SandboxExtension::consumePermanently(parameters.bytecodeCacheDirectoryExtensionHandle); >+ m_bytecodeCache = BytecodeCache::create(*this, m_bytecodeCacheDirectory); >+ if (!m_bytecodeCache) >+ RELEASE_LOG_ERROR(BytecodeCache, "Failed to initialize the WebKit bytecode cache"); > } > > std::unique_ptr<WebCore::NetworkStorageSession> NetworkProcess::platformCreateDefaultStorageSession() const >diff --git a/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in b/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in >index 06a13d4a3f2b58a55f5f272efb4d8f34d886dc50..f5ab88169458e480d4b7b37e03c5fafbc4e3bb5d 100644 >--- a/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in >+++ b/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in >@@ -1,4 +1,4 @@ >-; Copyright (C) 2013-2017 Apple Inc. All rights reserved. >+; Copyright (C) 2013-2019 Apple Inc. All rights reserved. > ; > ; Redistribution and use in source and binary forms, with or without > ; modification, are permitted provided that the following conditions >@@ -38,6 +38,7 @@ > "hw.availcpu" > "hw.ncpu" > "hw.model" >+ "kern.bootsessionuuid" > "kern.memorystatus_level" > "vm.footprint_suspend")) > >diff --git a/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp >index 3cab50698c0e280c9e09c15be0fdcdba38e2b9bc..b3283fee7c150103477a1be4a28da64f7f5b1caf 100644 >--- a/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp >+++ b/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp >@@ -108,6 +108,7 @@ void NetworkProcess::platformInitializeNetworkProcess(const NetworkProcessCreati > > ASSERT(!parameters.diskCacheDirectory.isEmpty()); > m_diskCacheDirectory = parameters.diskCacheDirectory; >+ m_bytecodeCacheDirectory = parameters.bytecodeCacheDirectory; > > SoupNetworkSession::clearOldSoupCache(FileSystem::directoryName(m_diskCacheDirectory)); > >@@ -119,6 +120,9 @@ void NetworkProcess::platformInitializeNetworkProcess(const NetworkProcessCreati > > m_cache = NetworkCache::Cache::open(*this, m_diskCacheDirectory, cacheOptions); > >+ if (!m_bytecodeCacheDirectory.isEmpty()) >+ m_bytecodeCache = BytecodeCache::create(*this, m_bytecodeCacheDirectory); >+ > supplement<WebCookieManager>()->setHTTPCookieAcceptPolicy(parameters.cookieAcceptPolicy, OptionalCallbackID()); > > if (!parameters.languages.isEmpty()) >diff --git a/Source/WebKit/Platform/IPC/DerivedData.cpp b/Source/WebKit/Platform/IPC/DerivedData.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..108f746c47de03a31b22b7752fef8016bce4610a >--- /dev/null >+++ b/Source/WebKit/Platform/IPC/DerivedData.cpp >@@ -0,0 +1,56 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "DerivedData.h" >+ >+#include "ArgumentCoders.h" >+#include "Decoder.h" >+#include "Encoder.h" >+ >+namespace IPC { >+ >+void DerivedData::encode(Encoder& encoder) const >+{ >+ ArgumentCoder<String>::encode(encoder, m_type); >+ encoder.encode(m_data); >+} >+ >+bool DerivedData::decode(Decoder& decoder, DerivedData& derivedData) >+{ >+ if (!ArgumentCoder<String>::decode(decoder, derivedData.m_type)) >+ return false; >+ return decoder.decode(derivedData.m_data); >+} >+ >+Optional<DerivedData> DerivedData::decode(Decoder& decoder) >+{ >+ DerivedData derivedData; >+ if (!decode(decoder, derivedData)) >+ return WTF::nullopt; >+ return { derivedData }; >+} >+ >+} // namespace IPC >diff --git a/Source/WebKit/Platform/IPC/DerivedData.h b/Source/WebKit/Platform/IPC/DerivedData.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f8141ad0caaf8e17ee1678f79679a3464422b48a >--- /dev/null >+++ b/Source/WebKit/Platform/IPC/DerivedData.h >@@ -0,0 +1,62 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "DataReference.h" >+#include <wtf/CompletionHandler.h> >+#include <wtf/Optional.h> >+#include <wtf/text/WTFString.h> >+ >+namespace IPC { >+ >+class Decoder; >+class Encoder; >+ >+class DerivedData { >+public: >+ DerivedData() = default; >+ >+ DerivedData(const String& type, const IPC::DataReference& data) >+ : m_type(type) >+ , m_data(data) >+ { >+ } >+ >+ bool isEmpty() const { return !m_data.size(); } >+ >+ const String& type() const { return m_type; } >+ const DataReference& data() const { return m_data; } >+ >+ void encode(Encoder&) const; >+ static bool decode(Decoder&, DerivedData&); >+ static Optional<DerivedData> decode(Decoder&); >+ >+private: >+ String m_type; >+ DataReference m_data; >+}; >+ >+} // namespace IPC >diff --git a/Source/WebKit/Platform/Logging.h b/Source/WebKit/Platform/Logging.h >index 1f773a711e616c885d131bf38a13d971601c12de..330502618ca0916c4482002bd89408fe14a22f1d 100644 >--- a/Source/WebKit/Platform/Logging.h >+++ b/Source/WebKit/Platform/Logging.h >@@ -44,6 +44,7 @@ extern "C" { > M(Automation) \ > M(ActivityState) \ > M(BackForward) \ >+ M(BytecodeCache) \ > M(CacheStorage) \ > M(ContentObservation) \ > M(ContextMenu) \ >diff --git a/Source/WebKit/Scripts/webkit/messages.py b/Source/WebKit/Scripts/webkit/messages.py >index a3773b1412fe365a4a127e86aca9ca66ce6f207c..8e415e2134fa9c638591026246478acc2e00df5a 100644 >--- a/Source/WebKit/Scripts/webkit/messages.py >+++ b/Source/WebKit/Scripts/webkit/messages.py >@@ -1,4 +1,4 @@ >-# Copyright (C) 2010-2018 Apple Inc. All rights reserved. >+# Copyright (C) 2010-2019 Apple Inc. All rights reserved. > # > # Redistribution and use in source and binary forms, with or without > # modification, are permitted provided that the following conditions >@@ -405,6 +405,7 @@ def headers_for_type(type): > special_cases = { > 'IPC::SharedBufferDataReference': ['"SharedBufferDataReference.h"', '"DataReference.h"'], > 'MachSendRight': ['<wtf/MachSendRight.h>'], >+ 'JSC::BytecodeCacheMetadata': ['<JavaScriptCore/BytecodeCacheMetadata.h>'], > 'JSC::MessageLevel': ['<JavaScriptCore/ConsoleTypes.h>'], > 'JSC::MessageSource': ['<JavaScriptCore/ConsoleTypes.h>'], > 'Inspector::InspectorTargetType': ['<JavaScriptCore/InspectorTarget.h>'], >diff --git a/Source/WebKit/Shared/WebProcessCreationParameters.cpp b/Source/WebKit/Shared/WebProcessCreationParameters.cpp >index 9582e6b6bb88143a3238cd9966db6d695e4c4ef2..6ff9b9a9bc5319a90bbe2f6ca66a36e5c67e1a4e 100644 >--- a/Source/WebKit/Shared/WebProcessCreationParameters.cpp >+++ b/Source/WebKit/Shared/WebProcessCreationParameters.cpp >@@ -97,6 +97,8 @@ void WebProcessCreationParameters::encode(IPC::Encoder& encoder) const > encoder << presentingApplicationPID; > #if PLATFORM(COCOA) > encoder << accessibilityEnhancedUserInterfaceEnabled; >+ encoder << bytecodeCacheDirectory; >+ encoder << bytecodeCacheDirectoryExtensionHandle; > encoder << acceleratedCompositingPort; > encoder << uiProcessBundleResourcePath; > encoder << uiProcessBundleResourcePathExtensionHandle; >@@ -279,6 +281,15 @@ bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreat > #if PLATFORM(COCOA) > if (!decoder.decode(parameters.accessibilityEnhancedUserInterfaceEnabled)) > return false; >+ if (!decoder.decode(parameters.bytecodeCacheDirectory)) >+ return false; >+ >+ Optional<SandboxExtension::Handle> bytecodeCacheDirectoryExtensionHandle; >+ decoder >> bytecodeCacheDirectoryExtensionHandle; >+ if (!bytecodeCacheDirectoryExtensionHandle) >+ return false; >+ parameters.bytecodeCacheDirectoryExtensionHandle = WTFMove(*bytecodeCacheDirectoryExtensionHandle); >+ > if (!decoder.decode(parameters.acceleratedCompositingPort)) > return false; > if (!decoder.decode(parameters.uiProcessBundleResourcePath)) >diff --git a/Source/WebKit/Shared/WebProcessCreationParameters.h b/Source/WebKit/Shared/WebProcessCreationParameters.h >index 8450dcec6fa589b69f527c94b3553c6d690ae875..6763b0d26b1d4008663cc2a58833c1db922bea8f 100644 >--- a/Source/WebKit/Shared/WebProcessCreationParameters.h >+++ b/Source/WebKit/Shared/WebProcessCreationParameters.h >@@ -149,6 +149,9 @@ struct WebProcessCreationParameters { > bool shouldEnableJIT { false }; > bool shouldEnableFTLJIT { false }; > bool accessibilityEnhancedUserInterfaceEnabled { false }; >+ >+ String bytecodeCacheDirectory; >+ SandboxExtension::Handle bytecodeCacheDirectoryExtensionHandle; > > RefPtr<API::Data> bundleParameterData; > #endif // PLATFORM(COCOA) >diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt >index 48f58e3c243b87ad36ff2d84e0d9660cdd4289d9..7d44579f6a9d259e4031ba686a4701dbd9f49e71 100644 >--- a/Source/WebKit/Sources.txt >+++ b/Source/WebKit/Sources.txt >@@ -65,6 +65,7 @@ NetworkProcess/ServiceWorker/WebSWOriginStore.cpp @no-unify > NetworkProcess/ServiceWorker/WebSWServerConnection.cpp @no-unify > NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp @no-unify > >+NetworkProcess/cache/BytecodeCache.cpp > NetworkProcess/cache/CacheStorageEngine.cpp > NetworkProcess/cache/CacheStorageEngineCache.cpp > NetworkProcess/cache/CacheStorageEngineCaches.cpp >diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp >index 54a4ab560381bcec7d5cd3665cc0d7582560b6b8..93ad3f2b0242ceb1771ece4230ea4f6ab7ae1c3e 100644 >--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp >+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp >@@ -53,6 +53,7 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::createWithWebsiteDataSto > configuration->m_applicationCacheDirectory = legacyConfiguration.applicationCacheDirectory(); > configuration->m_applicationCacheFlatFileSubdirectoryName = legacyConfiguration.applicationCacheFlatFileSubdirectoryName(); > configuration->m_diskCacheDirectory = legacyConfiguration.networkCacheDirectory(); >+ configuration->m_bytecodeCacheDirectory = legacyConfiguration.bytecodeCacheDirectory(); > configuration->m_mediaCacheDirectory = legacyConfiguration.mediaCacheDirectory(); > configuration->m_indexedDBDatabaseDirectory = legacyConfiguration.indexedDBDatabaseDirectory(); > configuration->m_localStorageDirectory = legacyConfiguration.localStorageDirectory(); >@@ -69,6 +70,7 @@ ProcessPoolConfiguration::ProcessPoolConfiguration() > : m_applicationCacheDirectory(WebsiteDataStore::defaultApplicationCacheDirectory()) > , m_applicationCacheFlatFileSubdirectoryName("Files") > , m_diskCacheDirectory(WebsiteDataStore::defaultNetworkCacheDirectory()) >+ , m_bytecodeCacheDirectory(WebsiteDataStore::defaultBytecodeCacheDirectory()) > , m_mediaCacheDirectory(WebsiteDataStore::defaultMediaCacheDirectory()) > , m_indexedDBDatabaseDirectory(WebsiteDataStore::defaultIndexedDBDatabaseDirectory()) > , m_localStorageDirectory(WebsiteDataStore::defaultLocalStorageDirectory()) >@@ -91,6 +93,7 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy() > copy->m_shouldHaveLegacyDataStore = this->m_shouldHaveLegacyDataStore; > copy->m_cacheModel = this->m_cacheModel; > copy->m_diskCacheDirectory = this->m_diskCacheDirectory; >+ copy->m_bytecodeCacheDirectory = this->m_bytecodeCacheDirectory; > copy->m_diskCacheSpeculativeValidationEnabled = this->m_diskCacheSpeculativeValidationEnabled; > copy->m_applicationCacheDirectory = this->m_applicationCacheDirectory; > copy->m_applicationCacheFlatFileSubdirectoryName = this->m_applicationCacheFlatFileSubdirectoryName; >diff --git a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h >index 872ceff9e08e009a50351fd0c074902df5b3d1ba..e841740b1178f93b6d1dd713aff2c56d8d12d208 100644 >--- a/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h >+++ b/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h >@@ -90,6 +90,9 @@ public: > const WTF::String& diskCacheDirectory() const { return m_diskCacheDirectory; } > void setDiskCacheDirectory(const WTF::String& diskCacheDirectory) { m_diskCacheDirectory = diskCacheDirectory; } > >+ const WTF::String& bytecodeCacheDirectory() const { return m_bytecodeCacheDirectory; } >+ void setBytecodeCacheDirectory(const WTF::String& bytecodeCacheDirectory) { m_bytecodeCacheDirectory = bytecodeCacheDirectory; } >+ > const WTF::String& mediaCacheDirectory() const { return m_mediaCacheDirectory; } > void setMediaCacheDirectory(const WTF::String& mediaCacheDirectory) { m_mediaCacheDirectory = mediaCacheDirectory; } > >@@ -197,6 +200,7 @@ private: > WTF::String m_applicationCacheDirectory; > WTF::String m_applicationCacheFlatFileSubdirectoryName; > WTF::String m_diskCacheDirectory; >+ WTF::String m_bytecodeCacheDirectory; > WTF::String m_mediaCacheDirectory; > WTF::String m_indexedDBDatabaseDirectory; > WTF::String m_injectedBundlePath; >diff --git a/Source/WebKit/UIProcess/API/APIWebsiteDataStore.cpp b/Source/WebKit/UIProcess/API/APIWebsiteDataStore.cpp >index f74b2c5db97f12d82506206e7896ecbb2960df5f..c8e89c78ce00147de620aeedd255a499908ad8cc 100644 >--- a/Source/WebKit/UIProcess/API/APIWebsiteDataStore.cpp >+++ b/Source/WebKit/UIProcess/API/APIWebsiteDataStore.cpp >@@ -149,6 +149,7 @@ Ref<WebKit::WebsiteDataStoreConfiguration> WebsiteDataStore::defaultDataStoreCon > configuration->setApplicationCacheFlatFileSubdirectoryName("Files"); > configuration->setCacheStorageDirectory(defaultCacheStorageDirectory()); > configuration->setNetworkCacheDirectory(defaultNetworkCacheDirectory()); >+ configuration->setBytecodeCacheDirectory(defaultBytecodeCacheDirectory()); > configuration->setMediaCacheDirectory(defaultMediaCacheDirectory()); > > configuration->setIndexedDBDatabaseDirectory(defaultIndexedDBDatabaseDirectory()); >@@ -171,6 +172,7 @@ Ref<WebKit::WebsiteDataStoreConfiguration> WebsiteDataStore::legacyDefaultDataSt > configuration->setApplicationCacheDirectory(legacyDefaultApplicationCacheDirectory()); > configuration->setApplicationCacheFlatFileSubdirectoryName("ApplicationCache"); > configuration->setNetworkCacheDirectory(legacyDefaultNetworkCacheDirectory()); >+ configuration->setBytecodeCacheDirectory(legacyDefaultBytecodeCacheDirectory()); > configuration->setMediaCacheDirectory(legacyDefaultMediaCacheDirectory()); > configuration->setMediaKeysStorageDirectory(legacyDefaultMediaKeysStorageDirectory()); > configuration->setDeviceIdHashSaltsStorageDirectory(legacyDefaultDeviceIdHashSaltsStorageDirectory()); >diff --git a/Source/WebKit/UIProcess/API/APIWebsiteDataStore.h b/Source/WebKit/UIProcess/API/APIWebsiteDataStore.h >index 9c9a43b73c43dd6d2b32b7e860d85e61ba810bf2..49f42e5f120d6113c20f31f5d0d3827091e5b0df 100644 >--- a/Source/WebKit/UIProcess/API/APIWebsiteDataStore.h >+++ b/Source/WebKit/UIProcess/API/APIWebsiteDataStore.h >@@ -59,6 +59,7 @@ public: > static WTF::String defaultApplicationCacheDirectory(); > static WTF::String defaultCacheStorageDirectory(); > static WTF::String defaultNetworkCacheDirectory(); >+ static WTF::String defaultBytecodeCacheDirectory(); > static WTF::String defaultMediaCacheDirectory(); > static WTF::String defaultIndexedDBDatabaseDirectory(); > static WTF::String defaultServiceWorkerRegistrationDirectory(); >@@ -73,6 +74,7 @@ public: > > static WTF::String legacyDefaultApplicationCacheDirectory(); > static WTF::String legacyDefaultNetworkCacheDirectory(); >+ static WTF::String legacyDefaultBytecodeCacheDirectory(); > static WTF::String legacyDefaultLocalStorageDirectory(); > static WTF::String legacyDefaultIndexedDBDatabaseDirectory(); > static WTF::String legacyDefaultWebSQLDatabaseDirectory(); >diff --git a/Source/WebKit/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm b/Source/WebKit/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm >index 3ae884511972ea75a6d37e85c4def3e6a8e86757..6f91ddb52b05fe8a0a26677c8584db963074bc4d 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm >+++ b/Source/WebKit/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm >@@ -69,6 +69,11 @@ WTF::String WebsiteDataStore::defaultNetworkCacheDirectory() > return cacheDirectoryFileSystemRepresentation("NetworkCache"); > } > >+WTF::String WebsiteDataStore::defaultBytecodeCacheDirectory() >+{ >+ return cacheDirectoryFileSystemRepresentation("BytecodeCache"); >+} >+ > WTF::String WebsiteDataStore::defaultMediaCacheDirectory() > { > return tempDirectoryFileSystemRepresentation("MediaCache"); >@@ -148,6 +153,17 @@ WTF::String WebsiteDataStore::legacyDefaultNetworkCacheDirectory() > return WebKit::stringByResolvingSymlinksInPath([cachePath stringByStandardizingPath]); > } > >+WTF::String WebsiteDataStore::legacyDefaultBytecodeCacheDirectory() >+{ >+ NSString *cachePath = CFBridgingRelease(_CFURLCacheCopyCacheDirectory([[NSURLCache sharedURLCache] _CFURLCache])); >+ if (!cachePath) >+ cachePath = @"~/Library/Caches/com.apple.WebKit.WebProcess"; >+ >+ cachePath = [cachePath stringByAppendingPathComponent:@"BytecodeCache"]; >+ >+ return WebKit::stringByResolvingSymlinksInPath([cachePath stringByStandardizingPath]); >+} >+ > WTF::String WebsiteDataStore::legacyDefaultWebSQLDatabaseDirectory() > { > NSString *databasesDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:WebDatabaseDirectoryDefaultsKey]; >diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp >index 9376da5dab5bd033c2fdee8b20db794bda2bc3f2..7c8b057128925a38bd93bd3e22f6b4da2f6ec286 100644 >--- a/Source/WebKit/UIProcess/WebProcessPool.cpp >+++ b/Source/WebKit/UIProcess/WebProcessPool.cpp >@@ -225,6 +225,7 @@ static Ref<WebsiteDataStoreConfiguration> legacyWebsiteDataStoreConfiguration(AP > configuration->setIndexedDBDatabaseDirectory(String(processPoolConfiguration.indexedDBDatabaseDirectory())); > configuration->setResourceLoadStatisticsDirectory(String(processPoolConfiguration.resourceLoadStatisticsDirectory())); > configuration->setNetworkCacheDirectory(String(processPoolConfiguration.diskCacheDirectory())); >+ configuration->setBytecodeCacheDirectory(String(processPoolConfiguration.bytecodeCacheDirectory())); > configuration->setJavaScriptConfigurationDirectory(String(processPoolConfiguration.javaScriptConfigurationDirectory())); > > return configuration; >@@ -513,6 +514,11 @@ NetworkProcessProxy& WebProcessPool::ensureNetworkProcess(WebsiteDataStore* with > parameters.diskCacheDirectory = m_configuration->diskCacheDirectory(); > if (!parameters.diskCacheDirectory.isEmpty()) > SandboxExtension::createHandleForReadWriteDirectory(parameters.diskCacheDirectory, parameters.diskCacheDirectoryExtensionHandle); >+ >+ parameters.bytecodeCacheDirectory = m_configuration->bytecodeCacheDirectory(); >+ if (!parameters.bytecodeCacheDirectory.isEmpty()) >+ SandboxExtension::createHandleForReadWriteDirectory(parameters.bytecodeCacheDirectory, parameters.bytecodeCacheDirectoryExtensionHandle); >+ > #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION) > parameters.shouldEnableNetworkCacheSpeculativeRevalidation = m_configuration->diskCacheSpeculativeValidationEnabled(); > #endif >@@ -911,6 +917,10 @@ void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDa > if (!parameters.injectedBundlePath.isEmpty()) > SandboxExtension::createHandleWithoutResolvingPath(parameters.injectedBundlePath, SandboxExtension::Type::ReadOnly, parameters.injectedBundlePathExtensionHandle); > >+ parameters.bytecodeCacheDirectory = m_configuration->bytecodeCacheDirectory(); >+ if (!parameters.bytecodeCacheDirectory.isEmpty()) >+ SandboxExtension::createHandleForReadWriteDirectory(parameters.bytecodeCacheDirectory, parameters.bytecodeCacheDirectoryExtensionHandle); >+ > parameters.additionalSandboxExtensionHandles.allocate(m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.size()); > for (size_t i = 0, size = m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.size(); i < size; ++i) > SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.additionalWebProcessSandboxExtensionPaths[i], SandboxExtension::Type::ReadOnly, parameters.additionalSandboxExtensionHandles[i]); >diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp >index 99f57e4ae3a4e1437b54b25250f7217a3120a2ee..4615d9143e559369444b1d13e4f185a67afe55e6 100644 >--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp >+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp >@@ -42,6 +42,7 @@ Ref<WebsiteDataStoreConfiguration> WebsiteDataStoreConfiguration::copy() > copy->m_cacheStorageDirectory = this->m_cacheStorageDirectory; > copy->m_perOriginStorageQuota = this->m_perOriginStorageQuota; > copy->m_networkCacheDirectory = this->m_networkCacheDirectory; >+ copy->m_bytecodeCacheDirectory = this->m_bytecodeCacheDirectory; > copy->m_applicationCacheDirectory = this->m_applicationCacheDirectory; > copy->m_applicationCacheFlatFileSubdirectoryName = this->m_applicationCacheFlatFileSubdirectoryName; > copy->m_webStorageDirectory = this->m_webStorageDirectory; >diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h >index 9cc8a5079bc0afea42919706b062128b57fcb20b..fd7e65a36f56f8f3a7f74448aaf3e58eb2317f06 100644 >--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h >+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h >@@ -76,6 +76,9 @@ public: > const String& networkCacheDirectory() const { return m_networkCacheDirectory; } > void setNetworkCacheDirectory(String&& directory) { m_networkCacheDirectory = WTFMove(directory); } > >+ const String& bytecodeCacheDirectory() const { return m_bytecodeCacheDirectory; } >+ void setBytecodeCacheDirectory(String&& directory) { m_bytecodeCacheDirectory = WTFMove(directory); } >+ > const String& cacheStorageDirectory() const { return m_cacheStorageDirectory; } > void setCacheStorageDirectory(String&& directory) { m_cacheStorageDirectory = WTFMove(directory); } > >@@ -105,6 +108,7 @@ private: > String m_cacheStorageDirectory; > uint64_t m_perOriginStorageQuota { defaultPerOriginStorageQuota }; > String m_networkCacheDirectory; >+ String m_bytecodeCacheDirectory; > String m_applicationCacheDirectory; > String m_applicationCacheFlatFileSubdirectoryName; > String m_webStorageDirectory; >diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >index 26c05c7469e68f7fb24c47086cab523fb42536e0..3b520bbc94f9e1e52663eb4f8a0ed27d7b250205 100644 >--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj >+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >@@ -122,6 +122,9 @@ > 0FF24A2D1879E4BC003ABF0C /* RemoteLayerTreeDrawingAreaProxyMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF24A2B1879E4BC003ABF0C /* RemoteLayerTreeDrawingAreaProxyMessageReceiver.cpp */; }; > 0FF24A2E1879E4BC003ABF0C /* RemoteLayerTreeDrawingAreaProxyMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF24A2C1879E4BC003ABF0C /* RemoteLayerTreeDrawingAreaProxyMessages.h */; }; > 0FF264A01A1FF9CC001FE759 /* RemoteLayerTreeScrollingPerformanceData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F707C791A1FEEA300DA7A45 /* RemoteLayerTreeScrollingPerformanceData.h */; }; >+ 14D01A7321FA180600BC54E9 /* BytecodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01A7121FA180500BC54E9 /* BytecodeCache.h */; }; >+ 14E2809422000A0F003BC57B /* DerivedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E28092220009F9003BC57B /* DerivedData.h */; }; >+ 14E2809522000A22003BC57B /* DerivedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14E28093220009F9003BC57B /* DerivedData.cpp */; }; > 15739BBD1B42042D00D258C1 /* WebUserMediaClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A410F4919AF7B80002EBAB5 /* WebUserMediaClient.h */; }; > 1A002D43196B337000B9AD44 /* _WKSessionStateInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A002D42196B337000B9AD44 /* _WKSessionStateInternal.h */; }; > 1A002D44196B338900B9AD44 /* _WKSessionState.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A002D3F196B329400B9AD44 /* _WKSessionState.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -1970,6 +1973,10 @@ > 0FF24A2C1879E4BC003ABF0C /* RemoteLayerTreeDrawingAreaProxyMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RemoteLayerTreeDrawingAreaProxyMessages.h; path = DerivedSources/WebKit2/RemoteLayerTreeDrawingAreaProxyMessages.h; sourceTree = BUILT_PRODUCTS_DIR; }; > 0FF24A2F1879E4FE003ABF0C /* RemoteLayerTreeDrawingAreaProxy.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = RemoteLayerTreeDrawingAreaProxy.messages.in; sourceTree = "<group>"; }; > 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; >+ 14D01A7021FA180500BC54E9 /* BytecodeCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeCache.cpp; sourceTree = "<group>"; }; >+ 14D01A7121FA180500BC54E9 /* BytecodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeCache.h; sourceTree = "<group>"; }; >+ 14E28092220009F9003BC57B /* DerivedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DerivedData.h; sourceTree = "<group>"; }; >+ 14E28093220009F9003BC57B /* DerivedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DerivedData.cpp; sourceTree = "<group>"; }; > 1A002D3E196B329400B9AD44 /* _WKSessionState.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKSessionState.mm; sourceTree = "<group>"; }; > 1A002D3F196B329400B9AD44 /* _WKSessionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKSessionState.h; sourceTree = "<group>"; }; > 1A002D42196B337000B9AD44 /* _WKSessionStateInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKSessionStateInternal.h; sourceTree = "<group>"; }; >@@ -5510,6 +5517,8 @@ > 1AC7537E183BE50F0072CB15 /* DataReference.h */, > BC032D9D10F437D10058C15A /* Decoder.cpp */, > BC032D9E10F437D10058C15A /* Decoder.h */, >+ 14E28093220009F9003BC57B /* DerivedData.cpp */, >+ 14E28092220009F9003BC57B /* DerivedData.h */, > BC032D9F10F437D10058C15A /* Encoder.cpp */, > BC032DA010F437D10058C15A /* Encoder.h */, > 4151E5C31FBB90A900E47E2D /* FormDataReference.h */, >@@ -8934,6 +8943,8 @@ > E489D2821A0A2BE80078C06A /* cache */ = { > isa = PBXGroup; > children = ( >+ 14D01A7021FA180500BC54E9 /* BytecodeCache.cpp */, >+ 14D01A7121FA180500BC54E9 /* BytecodeCache.h */, > 41897ED61F415D860016FA42 /* CacheStorageEngine.cpp */, > 41897ED21F415D850016FA42 /* CacheStorageEngine.h */, > 41C858191F510DEE0065E085 /* CacheStorageEngineCache.cpp */, >@@ -9196,6 +9207,7 @@ > E170876C16D6CA6900F99226 /* BlobRegistryProxy.h in Headers */, > 4F601432155C5AA2001FBDE0 /* BlockingResponseMap.h in Headers */, > 1A5705111BE410E600874AF1 /* BlockSPI.h in Headers */, >+ 14D01A7321FA180600BC54E9 /* BytecodeCache.h in Headers */, > BC3065FA1259344E00E71278 /* CacheModel.h in Headers */, > 41897ED81F415D8A0016FA42 /* CacheStorageEngine.h in Headers */, > 41FABD2A1F4DE001006A6C97 /* CacheStorageEngineCache.h in Headers */, >@@ -9215,6 +9227,7 @@ > C55F91711C59676E0029E92D /* DataDetectionResult.h in Headers */, > 1AC75380183BE50F0072CB15 /* DataReference.h in Headers */, > BC032DA610F437D10058C15A /* Decoder.h in Headers */, >+ 14E2809422000A0F003BC57B /* DerivedData.h in Headers */, > 57DCEDAB214C60090016B847 /* DeviceIdentitySPI.h in Headers */, > 07297F9F1C17BBEA015F0735 /* DeviceIdHashSaltStorage.h in Headers */, > 83891B6C1A68C30B0030F386 /* DiagnosticLoggingClient.h in Headers */, >@@ -10973,6 +10986,7 @@ > 2D92A77D212B6A7100F493FD /* Connection.cpp in Sources */, > 2D92A77E212B6A7100F493FD /* DataReference.cpp in Sources */, > 2D92A77F212B6A7100F493FD /* Decoder.cpp in Sources */, >+ 14E2809522000A22003BC57B /* DerivedData.cpp in Sources */, > 1AB7D6191288B9D900CFD08C /* DownloadProxyMessageReceiver.cpp in Sources */, > 1A64229912DD029200CAAE2C /* DrawingAreaMessageReceiver.cpp in Sources */, > 1A64230812DD09EB00CAAE2C /* DrawingAreaProxyMessageReceiver.cpp in Sources */, >diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >index 04ae0e45d5e9d29ca0f270a06418a6ab2d501fcb..37021f132335fa073e18212b0ecbda52d241db39 100644 >--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012, 2015, 2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2012, 2015, 2018, 2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -45,8 +45,10 @@ > #include "WebServiceWorkerProvider.h" > #include "WebURLSchemeHandlerProxy.h" > #include "WebURLSchemeTaskProxy.h" >+#include <JavaScriptCore/BytecodeCacheMetadata.h> > #include <WebCore/ApplicationCacheHost.h> > #include <WebCore/CachedResource.h> >+#include <WebCore/CachedScript.h> > #include <WebCore/ContentSecurityPolicy.h> > #include <WebCore/DiagnosticLoggingClient.h> > #include <WebCore/DiagnosticLoggingKeys.h> >@@ -281,6 +283,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL > loadParameters.needsCertificateInfo = resourceLoader.shouldIncludeCertificateInfo(); > loadParameters.maximumBufferingTime = maximumBufferingTime; > loadParameters.options = resourceLoader.options(); >+ loadParameters.scriptMode = resourceLoader.options().scriptMode; > loadParameters.preflightPolicy = resourceLoader.options().preflightPolicy; > loadParameters.isHTTPSUpgradeEnabled = resourceLoader.frame() ? resourceLoader.frame()->settings().HTTPSUpgradeEnabled() : false; > >@@ -667,6 +670,11 @@ void WebLoaderStrategy::didFinishPreconnection(uint64_t preconnectionIdentifier, > completionHandler(WTFMove(error)); > } > >+void WebLoaderStrategy::cacheBytecodeForScript(const WebCore::CachedScript& script, const JSC::BytecodeCacheMetadata& metadata) >+{ >+ WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::CacheBytecodeForRequest(script.resourceRequest(), metadata), 0); >+} >+ > bool WebLoaderStrategy::isOnLine() const > { > return m_isOnLine; >diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >index 4af59941e34f72ad26e81efb560606751811f8c6..dbe242a0d0634ecd69be30f5fdd250bd2aab09dc 100644 >--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. >+ * Copyright (C) 2012, 2015, 2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -33,6 +33,10 @@ > #include <wtf/HashSet.h> > #include <wtf/RunLoop.h> > >+namespace JSC { >+class BytecodeCacheMetadata; >+} >+ > namespace WebCore { > struct FetchOptions; > } >@@ -69,6 +73,8 @@ public: > void preconnectTo(WebCore::FrameLoader&, const URL&, WebCore::StoredCredentialsPolicy, PreconnectCompletionHandler&&) final; > void didFinishPreconnection(uint64_t preconnectionIdentifier, WebCore::ResourceError&&); > >+ void cacheBytecodeForScript(const WebCore::CachedScript&, const JSC::BytecodeCacheMetadata&) override; >+ > void setCaptureExtraNetworkLoadMetricsEnabled(bool) final; > > WebResourceLoader* webResourceLoaderForIdentifier(ResourceLoadIdentifier identifier) const { return m_webResourceLoaders.get(identifier); } >diff --git a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp >index bf88fda3007e164ff38a9522abb81fefd7e9f852..c1d9c62d53d675775c00cecd04ff9594fbab6497 100644 >--- a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp >+++ b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2012-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -27,6 +27,7 @@ > #include "WebResourceLoader.h" > > #include "DataReference.h" >+#include "DerivedData.h" > #include "Logging.h" > #include "NetworkProcessConnection.h" > #include "NetworkResourceLoaderMessages.h" >@@ -110,7 +111,7 @@ void WebResourceLoader::didSendData(uint64_t bytesSent, uint64_t totalBytesToBeS > m_coreLoader->didSendData(bytesSent, totalBytesToBeSent); > } > >-void WebResourceLoader::didReceiveResponse(const ResourceResponse& response, bool needsContinueDidReceiveResponseMessage) >+void WebResourceLoader::didReceiveResponse(const ResourceResponse& response, bool needsContinueDidReceiveResponseMessage, const Vector<IPC::DerivedData>& derivedData) > { > LOG(Network, "(WebProcess) WebResourceLoader::didReceiveResponse for '%s'. Status %d.", m_coreLoader->url().string().latin1().data(), response.httpStatusCode()); > RELEASE_LOG_IF_ALLOWED("didReceiveResponse: (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ", status = %d)", m_trackingParameters.pageID, m_trackingParameters.frameID, m_trackingParameters.resourceID, response.httpStatusCode()); >@@ -140,6 +141,10 @@ void WebResourceLoader::didReceiveResponse(const ResourceResponse& response, boo > } > > m_coreLoader->didReceiveResponse(response, WTFMove(policyDecisionCompletionHandler)); >+ for (const auto& entry : derivedData) { >+ auto buffer = SharedBuffer::create(entry.data().data(), entry.data().size()); >+ m_coreLoader->didRetrieveDerivedDataFromCache(entry.type(), buffer.get()); >+ } > } > > void WebResourceLoader::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength) >diff --git a/Source/WebKit/WebProcess/Network/WebResourceLoader.h b/Source/WebKit/WebProcess/Network/WebResourceLoader.h >index 7fd7832233a362c23a904fc15ef34ca64a967eae..14f52542815f9a155937fb5177e0cd2ab90c7fe1 100644 >--- a/Source/WebKit/WebProcess/Network/WebResourceLoader.h >+++ b/Source/WebKit/WebProcess/Network/WebResourceLoader.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2012 Apple Inc. All rights reserved. >+ * Copyright (C) 2012-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -33,6 +33,7 @@ > > namespace IPC { > class DataReference; >+class DerivedData; > } > > namespace WebCore { >@@ -76,9 +77,8 @@ private: > > void willSendRequest(WebCore::ResourceRequest&&, WebCore::ResourceResponse&&); > void didSendData(uint64_t bytesSent, uint64_t totalBytesToBeSent); >- void didReceiveResponse(const WebCore::ResourceResponse&, bool needsContinueDidReceiveResponseMessage); >+ void didReceiveResponse(const WebCore::ResourceResponse&, bool needsContinueDidReceiveResponseMessage, const Vector<IPC::DerivedData>&); > void didReceiveData(const IPC::DataReference&, int64_t encodedDataLength); >- void didRetrieveDerivedData(const String& type, const IPC::DataReference&); > void didFinishResourceLoad(const WebCore::NetworkLoadMetrics&); > void didFailResourceLoad(const WebCore::ResourceError&); > void didBlockAuthenticationChallenge(); >diff --git a/Source/WebKit/WebProcess/Network/WebResourceLoader.messages.in b/Source/WebKit/WebProcess/Network/WebResourceLoader.messages.in >index 7b93256f036dd042f44ba83a318bb7b6636d41aa..30b03d06d2820c8b76e645c7d2e37fe3f648ebcd 100644 >--- a/Source/WebKit/WebProcess/Network/WebResourceLoader.messages.in >+++ b/Source/WebKit/WebProcess/Network/WebResourceLoader.messages.in >@@ -23,7 +23,7 @@ > messages -> WebResourceLoader LegacyReceiver { > WillSendRequest(WebCore::ResourceRequest request, WebCore::ResourceResponse redirectResponse) > DidSendData(uint64_t bytesSent, uint64_t totalBytesToBeSent) >- DidReceiveResponse(WebCore::ResourceResponse response, bool needsContinueDidReceiveResponseMessage) >+ DidReceiveResponse(WebCore::ResourceResponse response, bool needsContinueDidReceiveResponseMessage, Vector<IPC::DerivedData> data) > DidReceiveData(IPC::SharedBufferDataReference data, int64_t encodedDataLength) > DidFinishResourceLoad(WebCore::NetworkLoadMetrics networkLoadMetrics) > DidFailResourceLoad(WebCore::ResourceError error) >diff --git a/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm b/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm >index 2e190b035f7280b1fbedb3af001e6958c4202116..60fe61f6152b9df46f513c0bf78779f0554fe04c 100644 >--- a/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm >+++ b/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm >@@ -154,6 +154,7 @@ void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters& para > > #if ENABLE(SANDBOX_EXTENSIONS) > SandboxExtension::consumePermanently(parameters.uiProcessBundleResourcePathExtensionHandle); >+ SandboxExtension::consumePermanently(parameters.bytecodeCacheDirectoryExtensionHandle); > #if ENABLE(MEDIA_STREAM) > SandboxExtension::consumePermanently(parameters.audioCaptureExtensionHandle); > #endif >diff --git a/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in b/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in >index 09b8eee344d5f65942199510adbd9b71e4491a9a..c1dfc054759f55cd95c87ae2544e591a1955aae9 100644 >--- a/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in >+++ b/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in >@@ -1,4 +1,4 @@ >-; Copyright (C) 2010-2018 Apple Inc. All rights reserved. >+; Copyright (C) 2010-2019 Apple Inc. All rights reserved. > ; > ; Redistribution and use in source and binary forms, with or without > ; modification, are permitted provided that the following conditions >@@ -165,6 +165,7 @@ > "hw.ncpu" > "hw.vectorunit" > "kern.bootargs" ;; <rdar://problem/47738015> >+ "kern.bootsessionuuid" > "kern.hostname" > "kern.maxfilesperproc" > "kern.memorystatus_level" >diff --git a/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h b/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h >index 55b3697530658214bc979a8792b660726d8296dd..2980ea5153163676dc7dd80b9d2ae17589725194 100644 >--- a/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h >+++ b/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h >@@ -1,7 +1,7 @@ > /* > Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) > Copyright (C) 2001 Dirk Mueller <mueller@kde.org> >- Copyright (C) 2004, 2006-2008, 2015 Apple Inc. All rights reserved. >+ Copyright (C) 2004, 2006-2008, 2015, 2019 Apple Inc. All rights reserved. > Copyright (C) 2010 Google Inc. All rights reserved. > > This library is free software; you can redistribute it and/or >@@ -39,6 +39,10 @@ class WebResourceLoadScheduler; > > WebResourceLoadScheduler& webResourceLoadScheduler(); > >+namespace JSC { >+class BytecodeCacheMetadata; >+} >+ > class WebResourceLoadScheduler final : public WebCore::LoaderStrategy { > WTF_MAKE_NONCOPYABLE(WebResourceLoadScheduler); WTF_MAKE_FAST_ALLOCATED; > public: >@@ -60,6 +64,8 @@ public: > > void preconnectTo(WebCore::FrameLoader&, const URL&, WebCore::StoredCredentialsPolicy, PreconnectCompletionHandler&&) final; > >+ void cacheBytecodeForScript(const WebCore::CachedScript&, const JSC::BytecodeCacheMetadata&) final { } >+ > void setCaptureExtraNetworkLoadMetricsEnabled(bool) final { } > > bool isSerialLoadingEnabled() const { return m_isSerialLoadingEnabled; }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
tzagallo
:
review?
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194047
:
360620
|
361237
|
361242
|
361724
|
367681
|
369651
| 369724