WebKit Bugzilla
Attachment 371189 Details for
Bug 198482
: JSScript should not keep bytecode cache in memory
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-198482-20190603160602.patch (text/plain), 31.11 KB, created by
Tadeu Zagallo
on 2019-06-03 07:06:04 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Tadeu Zagallo
Created:
2019-06-03 07:06:04 PDT
Size:
31.11 KB
patch
obsolete
>Subversion Revision: 246030 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 25a5e395b767924300436dbec9e1fea6732c4a28..4b4a4eb392624aaeb5a96c2b2ecb73120f8e87c7 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,52 @@ >+2019-06-03 Tadeu Zagallo <tzagallo@apple.com> >+ >+ JSScript should not keep bytecode cache in memory >+ https://bugs.webkit.org/show_bug.cgi?id=198482 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ When JSScript writes to the cache, we keep the in-memory serialized bytecode alive. >+ Instead, we should only ever hold the memory mapped bytecode cache to avoid using >+ too much memory. >+ >+ * API/JSScript.mm: >+ (-[JSScript writeCache:]): >+ * API/tests/testapi.mm: >+ (testBytecodeCacheWithSyntaxError): >+ * CMakeLists.txt: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Sources.txt: >+ * jsc.cpp: >+ * runtime/BytecodeCacheError.cpp: Added. >+ (JSC::BytecodeCacheError::isValid const): >+ (JSC::BytecodeCacheError::message const): >+ (JSC::BytecodeCacheError::parserError): >+ (JSC::BytecodeCacheError::standardError): >+ (JSC::BytecodeCacheError::writeError): >+ (JSC::BytecodeCacheError::StandardError::isValid const): >+ (JSC::BytecodeCacheError::StandardError::message const): >+ (JSC::BytecodeCacheError::WriteError::isValid const): >+ (JSC::BytecodeCacheError::WriteError::message const): >+ * runtime/BytecodeCacheError.h: Added. >+ (JSC::BytecodeCacheError::StandardError::StandardError): >+ (JSC::BytecodeCacheError::WriteError::WriteError): >+ * runtime/CachedBytecode.h: >+ (JSC::CachedBytecode::create): >+ * runtime/CachedTypes.cpp: >+ (JSC::Encoder::Encoder): >+ (JSC::Encoder::release): >+ (JSC::Encoder::releaseMapped): >+ (JSC::encodeCodeBlock): >+ (JSC::encodeFunctionCodeBlock): >+ * runtime/CachedTypes.h: >+ * runtime/CodeCache.cpp: >+ (JSC::serializeBytecode): >+ * runtime/CodeCache.h: >+ * runtime/Completion.cpp: >+ (JSC::generateProgramBytecode): >+ (JSC::generateModuleBytecode): >+ * runtime/Completion.h: >+ > 2019-06-02 Yusuke Suzuki <ysuzuki@apple.com> > > [JSC] Crash explicitly if StructureIDs are exhausted >diff --git a/Source/JavaScriptCore/API/JSScript.mm b/Source/JavaScriptCore/API/JSScript.mm >index 411ddcd467d2be5eddbc32d4a656fff85af2ca6d..3a5180dd3e78a3d5ea548b9a44a590bf25e6a043 100644 >--- a/Source/JavaScriptCore/API/JSScript.mm >+++ b/Source/JavaScriptCore/API/JSScript.mm >@@ -27,6 +27,7 @@ > #import "JSScriptInternal.h" > > #import "APICast.h" >+#import "BytecodeCacheError.h" > #import "CachedTypes.h" > #import "CodeCache.h" > #import "Identifier.h" >@@ -35,7 +36,6 @@ > #import "JSSourceCode.h" > #import "JSValuePrivate.h" > #import "JSVirtualMachineInternal.h" >-#import "ParserError.h" > #import "Symbol.h" > #include <sys/stat.h> > #include <wtf/FileMetadata.h> >@@ -277,32 +277,21 @@ - (BOOL)writeCache:(String&)error > close(fd); > }); > >- JSC::ParserError parserError; >+ JSC::BytecodeCacheError cacheError; > 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, cacheError); > break; > case kJSScriptTypeProgram: >- m_cachedBytecode = JSC::generateProgramBytecode(m_virtualMachine.vm, sourceCode, parserError); >+ m_cachedBytecode = JSC::generateProgramBytecode(m_virtualMachine.vm, sourceCode, fd, cacheError); > break; > } > >- if (parserError.isValid()) { >+ if (cacheError.isValid()) { > m_cachedBytecode = JSC::CachedBytecode::create(); >- error = makeString("Unable to generate bytecode for this JSScript because of a parser error: ", parserError.message()); >- 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."); >+ error = makeString("Unable to generate bytecode for this JSScript because: ", cacheError.message()); > return NO; > } > >diff --git a/Source/JavaScriptCore/API/tests/testapi.mm b/Source/JavaScriptCore/API/tests/testapi.mm >index 5253b02f722a862f7c031717a2535ec3c0e6c267..6ce80f0e012a8c2ab763cd760e4d671e08b11248 100644 >--- a/Source/JavaScriptCore/API/tests/testapi.mm >+++ b/Source/JavaScriptCore/API/tests/testapi.mm >@@ -2197,7 +2197,7 @@ static void testBytecodeCacheWithSyntaxError(JSScriptType type) > if ([script cacheBytecodeWithError:&error]) > CRASH(); > RELEASE_ASSERT(error); >- checkResult(@"Got error when trying to cache bytecode for a script with a syntax error.", [[error description] containsString:@"Unable to generate bytecode for this JSScript because of a parser error"]); >+ checkResult(@"Got error when trying to cache bytecode for a script with a syntax error.", [[error description] containsString:@"Unable to generate bytecode for this JSScript because"]); > } > } > >diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt >index 9415ea0715400d698805a6e39d757fd51649e024..fa971cfe38c9ad12499fbab39552e165d3ec97b3 100644 >--- a/Source/JavaScriptCore/CMakeLists.txt >+++ b/Source/JavaScriptCore/CMakeLists.txt >@@ -751,6 +751,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS > runtime/BooleanPrototype.h > runtime/Butterfly.h > runtime/ButterflyInlines.h >+ runtime/BytecodeCacheError.h > runtime/CachePayload.h > runtime/CacheUpdate.h > runtime/CachedBytecode.h >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index bda0c56cba220d6dbf3e462ef86d803576f78644..7dc5545f67633a3c7a84d31446249c924f40fb18 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -772,6 +772,7 @@ > 142E313B134FF0A600AFADB5 /* Strong.h in Headers */ = {isa = PBXBuildFile; fileRef = 142E3132134FF0A600AFADB5 /* Strong.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 142E313C134FF0A600AFADB5 /* Weak.h in Headers */ = {isa = PBXBuildFile; fileRef = 142E3133134FF0A600AFADB5 /* Weak.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 142F16E021558802003D49C9 /* MetadataTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 142F16DF215585C8003D49C9 /* MetadataTable.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 1435952122A521CD00E8086D /* BytecodeCacheError.h in Headers */ = {isa = PBXBuildFile; fileRef = 1435951F22A521CA00E8086D /* BytecodeCacheError.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 14386A751DD69895008652C4 /* DirectEvalExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 14386A731DD69895008652C4 /* DirectEvalExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 14386A791DD6989C008652C4 /* IndirectEvalExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 14386A771DD6989C008652C4 /* IndirectEvalExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 1440057F0A5335640005F061 /* JSNode.c in Sources */ = {isa = PBXBuildFile; fileRef = 1440F6420A4F8B6A0005F061 /* JSNode.c */; }; >@@ -3190,6 +3191,8 @@ > 142E3133134FF0A600AFADB5 /* Weak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Weak.h; sourceTree = "<group>"; }; > 142F16DF215585C8003D49C9 /* MetadataTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetadataTable.h; sourceTree = "<group>"; }; > 142F16E921583B5E003D49C9 /* CodeBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockInlines.h; sourceTree = "<group>"; }; >+ 1435951F22A521CA00E8086D /* BytecodeCacheError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BytecodeCacheError.h; sourceTree = "<group>"; }; >+ 1435952022A521CA00E8086D /* BytecodeCacheError.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeCacheError.cpp; sourceTree = "<group>"; }; > 14386A721DD69895008652C4 /* DirectEvalExecutable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectEvalExecutable.cpp; sourceTree = "<group>"; }; > 14386A731DD69895008652C4 /* DirectEvalExecutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectEvalExecutable.h; sourceTree = "<group>"; }; > 14386A761DD6989C008652C4 /* IndirectEvalExecutable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndirectEvalExecutable.cpp; sourceTree = "<group>"; }; >@@ -6755,6 +6758,8 @@ > 9E729409190F0306001A91B5 /* BundlePath.mm */, > 0FB7F38B15ED8E3800F167B2 /* Butterfly.h */, > 0FB7F38C15ED8E3800F167B2 /* ButterflyInlines.h */, >+ 1435952022A521CA00E8086D /* BytecodeCacheError.cpp */, >+ 1435951F22A521CA00E8086D /* BytecodeCacheError.h */, > 148B1419225DD1E900D6E998 /* CachedBytecode.cpp */, > 144CA34F221F037900817789 /* CachedBytecode.h */, > 14DAFA4521E3B871004B68F7 /* CachedTypes.cpp */, >@@ -8776,6 +8781,7 @@ > 0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */, > 0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */, > C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */, >+ 1435952122A521CD00E8086D /* BytecodeCacheError.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 43d7ef475822a83afaf9a12e8cf9e11a9d7db87b..3c7dd9846ccd24f2b02a1d7c62ef2f65e5f58063 100644 >--- a/Source/JavaScriptCore/Sources.txt >+++ b/Source/JavaScriptCore/Sources.txt >@@ -718,6 +718,7 @@ runtime/BigIntPrototype.cpp > runtime/BooleanConstructor.cpp > runtime/BooleanObject.cpp > runtime/BooleanPrototype.cpp >+runtime/BytecodeCacheError.cpp > runtime/CallData.cpp > runtime/CachePayload.cpp > runtime/CacheUpdate.cpp >diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp >index c110dc43f1763866489ca44882a56c19c29531ce..84684501bca56b8cf47860aa8e5b0ebdf89e1fd8 100644 >--- a/Source/JavaScriptCore/jsc.cpp >+++ b/Source/JavaScriptCore/jsc.cpp >@@ -26,6 +26,7 @@ > #include "ArrayPrototype.h" > #include "BuiltinNames.h" > #include "ButterflyInlines.h" >+#include "BytecodeCacheError.h" > #include "CatchScope.h" > #include "CodeBlock.h" > #include "CodeCache.h" >@@ -981,8 +982,10 @@ public: > { > if (!cacheEnabled() || !m_cachedBytecode) > return; >- Ref<CachedBytecode> cachedBytecode = encodeFunctionCodeBlock(*executable->vm(), codeBlock); >- m_cachedBytecode->addFunctionUpdate(executable, kind, WTFMove(cachedBytecode)); >+ BytecodeCacheError error; >+ Ref<CachedBytecode> cachedBytecode = encodeFunctionCodeBlock(*executable->vm(), codeBlock, error); >+ if (!error.isValid()) >+ m_cachedBytecode->addFunctionUpdate(executable, kind, WTFMove(cachedBytecode)); > } > > void cacheBytecode(const BytecodeCacheGenerator& generator) const override >diff --git a/Source/JavaScriptCore/runtime/BytecodeCacheError.cpp b/Source/JavaScriptCore/runtime/BytecodeCacheError.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..17a365ad9f11cf403873f89ab29a993f9acaee20 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/BytecodeCacheError.cpp >@@ -0,0 +1,81 @@ >+/* >+ * 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 "BytecodeCacheError.h" >+ >+namespace JSC { >+ >+bool BytecodeCacheError::isValid() const >+{ >+ return WTF::switchOn(m_error, [](const auto& error) { >+ return error.isValid(); >+ }); >+} >+ >+String BytecodeCacheError::message() const >+{ >+ return WTF::switchOn(m_error, [](const auto& error) { >+ return error.message(); >+ }); >+} >+ >+ParserError& BytecodeCacheError::parserError() >+{ >+ m_error = ParserError(); >+ return WTF::get<ParserError>(m_error); >+} >+ >+void BytecodeCacheError::standardError(int error) >+{ >+ m_error = StandardError(error); >+} >+ >+void BytecodeCacheError::writeError(size_t written, size_t expected) >+{ >+ m_error = WriteError(written, expected); >+} >+ >+bool BytecodeCacheError::StandardError::isValid() const >+{ >+ return true; >+} >+ >+String BytecodeCacheError::StandardError::message() const >+{ >+ return strerror(m_errno); >+} >+ >+bool BytecodeCacheError::WriteError::isValid() const >+{ >+ return true; >+} >+ >+String BytecodeCacheError::WriteError::message() const >+{ >+ return makeString("Could not write the full cache file to disk. Only wrote ", String::number(m_written), " of the expected ", String::number(m_expected), " bytes."); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/BytecodeCacheError.h b/Source/JavaScriptCore/runtime/BytecodeCacheError.h >new file mode 100644 >index 0000000000000000000000000000000000000000..433095f504c009fb458a46308f9e0479da665697 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/BytecodeCacheError.h >@@ -0,0 +1,79 @@ >+/* >+ * 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 "JSGlobalObject.h" >+#include "JSSourceCode.h" >+#include "ParserError.h" >+#include <wtf/Variant.h> >+#include <wtf/text/WTFString.h> >+ >+namespace JSC { >+ >+class BytecodeCacheError { >+public: >+ JS_EXPORT_PRIVATE bool isValid() const; >+ JS_EXPORT_PRIVATE String message() const; >+ >+ ParserError& parserError(); >+ void standardError(int); >+ void writeError(size_t written, size_t expected); >+ >+private: >+ class StandardError { >+ public: >+ StandardError(int error) >+ : m_errno(error) >+ { >+ } >+ >+ bool isValid() const; >+ String message() const; >+ >+ private: >+ int m_errno; >+ }; >+ >+ class WriteError { >+ public: >+ WriteError(size_t written, size_t expected) >+ : m_written(written) >+ , m_expected(expected) >+ { >+ } >+ >+ bool isValid() const; >+ String message() const; >+ >+ private: >+ size_t m_written; >+ size_t m_expected; >+ }; >+ >+ Variant<ParserError, StandardError, WriteError> m_error; >+}; >+ >+} // namespace JSC >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 e0b4cbfb9a503fe72ff91719c77745d16079282e..7cc79f2d9b5b0021c3cab2411f513c0b5ee45819 100644 >--- a/Source/JavaScriptCore/runtime/CachedTypes.cpp >+++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp >@@ -26,6 +26,7 @@ > #include "config.h" > #include "CachedTypes.h" > >+#include "BytecodeCacheError.h" > #include "BytecodeCacheVersion.h" > #include "BytecodeLivenessAnalysis.h" > #include "JSCInlines.h" >@@ -87,8 +88,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) > { >@@ -144,12 +146,20 @@ public: > m_leafExecutables.add(executable, offset); > } > >- Ref<CachedBytecode> release() >+ Ref<CachedBytecode> release(BytecodeCacheError& error) > { > if (!m_currentPage) > return CachedBytecode::create(); >- > m_currentPage->alignEnd(); >+ >+ if (m_fd != -1) { >+#if !OS(WINDOWS) >+ return releaseMapped(error); >+#else >+ RELEASE_ASSERT_NOT_REACHED(); >+#endif >+ } >+ > size_t size = m_baseOffset + m_currentPage->size(); > MallocPtr<uint8_t> buffer = MallocPtr<uint8_t>::malloc(size); > unsigned offset = 0; >@@ -162,6 +172,38 @@ public: > } > > private: >+#if !OS(WINDOWS) >+ Ref<CachedBytecode> releaseMapped(BytecodeCacheError& error) >+ { >+ size_t size = m_baseOffset + m_currentPage->size(); >+ if (ftruncate(m_fd, size)) { >+ error.standardError(errno); >+ return CachedBytecode::create(); >+ } >+ >+ for (const auto& page : m_pages) { >+ ssize_t bytesWritten = write(m_fd, page.buffer(), page.size()); >+ if (bytesWritten == -1) { >+ error.standardError(errno); >+ return CachedBytecode::create(); >+ } >+ >+ if (static_cast<size_t>(bytesWritten) != page.size()) { >+ error.writeError(bytesWritten, page.size()); >+ return CachedBytecode::create(); >+ } >+ } >+ >+ void* buffer = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, m_fd, 0); >+ if (buffer == MAP_FAILED) { >+ error.standardError(errno); >+ return CachedBytecode::create(); >+ } >+ >+ return CachedBytecode::create(buffer, size, WTFMove(m_leafExecutables)); >+ } >+#endif >+ > class Page { > public: > Page(size_t size) >@@ -228,6 +270,7 @@ private: > } > > VM& m_vm; >+ int m_fd; > ptrdiff_t m_baseOffset; > Page* m_currentPage; > Vector<Page> m_pages; >@@ -2342,11 +2385,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, BytecodeCacheError& error) > { > 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()) >@@ -2354,14 +2397,20 @@ Ref<CachedBytecode> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const Unli > else > ASSERT(classInfo == UnlinkedEvalCodeBlock::info()); > >- return encoder.release(); >+ return encoder.release(error); >+} >+ >+Ref<CachedBytecode> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const UnlinkedCodeBlock* codeBlock) >+{ >+ BytecodeCacheError error; >+ return encodeCodeBlock(vm, key, codeBlock, -1, error); > } > >-Ref<CachedBytecode> encodeFunctionCodeBlock(VM& vm, const UnlinkedFunctionCodeBlock* codeBlock) >+Ref<CachedBytecode> encodeFunctionCodeBlock(VM& vm, const UnlinkedFunctionCodeBlock* codeBlock, BytecodeCacheError& error) > { >- Encoder encoder(vm); >+ Encoder encoder(vm, -1); > encoder.malloc<CachedFunctionCodeBlock>()->encode(encoder, *codeBlock); >- return encoder.release(); >+ return encoder.release(error); > } > > UnlinkedCodeBlock* decodeCodeBlockImpl(VM& vm, const SourceCodeKey& key, Ref<CachedBytecode> cachedBytecode) >diff --git a/Source/JavaScriptCore/runtime/CachedTypes.h b/Source/JavaScriptCore/runtime/CachedTypes.h >index 9d00e1733b4bcd89fcc9183e678ab2f01ce49ef0..8a913f0d48bc7aee219c199692442411a7b05993 100644 >--- a/Source/JavaScriptCore/runtime/CachedTypes.h >+++ b/Source/JavaScriptCore/runtime/CachedTypes.h >@@ -33,6 +33,7 @@ > > namespace JSC { > >+class BytecodeCacheError; > class CachedBytecode; > class SourceCodeKey; > class UnlinkedCodeBlock; >@@ -108,6 +109,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, BytecodeCacheError&); > > UnlinkedCodeBlock* decodeCodeBlockImpl(VM&, const SourceCodeKey&, Ref<CachedBytecode>); > >@@ -117,7 +119,7 @@ UnlinkedCodeBlockType* decodeCodeBlock(VM& vm, const SourceCodeKey& key, Ref<Cac > return jsCast<UnlinkedCodeBlockType*>(decodeCodeBlockImpl(vm, key, WTFMove(cachedBytecode))); > } > >-JS_EXPORT_PRIVATE Ref<CachedBytecode> encodeFunctionCodeBlock(VM&, const UnlinkedFunctionCodeBlock*); >+JS_EXPORT_PRIVATE Ref<CachedBytecode> encodeFunctionCodeBlock(VM&, const UnlinkedFunctionCodeBlock*, BytecodeCacheError&); > > JS_EXPORT_PRIVATE void decodeFunctionCodeBlock(Decoder&, int32_t cachedFunctionCodeBlockOffset, WriteBarrier<UnlinkedFunctionCodeBlock>&, const JSCell*); > >diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp >index 03a92ee64a37d22cf23dd487f5979938ec9b3632..4aadde6a4eb369c6e7fc7c8621d18704ab2deae2 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 >@@ -225,10 +225,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, BytecodeCacheError& error, OptionSet<CodeGenerationMode> codeGenerationMode) > { > return encodeCodeBlock(vm, >- sourceCodeKeyForSerializedBytecode(vm, source, codeType, strictMode, scriptMode, codeGenerationMode), codeBlock); >+ sourceCodeKeyForSerializedBytecode(vm, source, codeType, strictMode, scriptMode, codeGenerationMode), codeBlock, fd, error); > } > > } >diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h >index b067f847dae301ceee70658be7659f8e7d3ab36c..f02b9c38edc25721358463266a3ca0333e66ea30 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 >@@ -318,7 +318,7 @@ recursivelyGenerateUnlinkedCodeBlock(VM& vm, const SourceCode& source, JSParserS > } > > 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, BytecodeCacheError&, 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..8bff70d7b358310fbe87a356dbb25a7c3441bac9 100644 >--- a/Source/JavaScriptCore/runtime/Completion.cpp >+++ b/Source/JavaScriptCore/runtime/Completion.cpp >@@ -23,6 +23,7 @@ > #include "config.h" > #include "Completion.h" > >+#include "BytecodeCacheError.h" > #include "CallFrame.h" > #include "CatchScope.h" > #include "CodeCache.h" >@@ -91,7 +92,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, BytecodeCacheError& error) > { > JSLockHolder lock(vm); > RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable()); >@@ -101,13 +102,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.parserError(), evalContextType, &variablesUnderTDZ); > if (!unlinkedCodeBlock) > return CachedBytecode::create(); >- return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, { }); >+ >+ return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, fd, error, { }); > } > >-Ref<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, ParserError& error) >+Ref<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, int fd, BytecodeCacheError& error) > { > JSLockHolder lock(vm); > RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable()); >@@ -117,10 +119,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.parserError(), evalContextType, &variablesUnderTDZ); > if (!unlinkedCodeBlock) > return CachedBytecode::create(); >- return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, { }); >+ return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, fd, error, { }); > } > > JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException) >diff --git a/Source/JavaScriptCore/runtime/Completion.h b/Source/JavaScriptCore/runtime/Completion.h >index d5a0231b780175b88420d6aff4b3c0a524ed1851..8cc3845b1aea3b3bf22a437aab4355e43a58231b 100644 >--- a/Source/JavaScriptCore/runtime/Completion.h >+++ b/Source/JavaScriptCore/runtime/Completion.h >@@ -28,6 +28,7 @@ > > namespace JSC { > >+class BytecodeCacheError; > 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, BytecodeCacheError&); >+JS_EXPORT_PRIVATE Ref<CachedBytecode> generateModuleBytecode(VM&, const SourceCode&, int fd, BytecodeCacheError&); > > JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue, NakedPtr<Exception>& returnedException); > inline JSValue evaluate(ExecState* exec, const SourceCode& sourceCode, JSValue thisValue = JSValue())
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
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198482
:
371185
|
371189
|
371264