Diff
Modified: trunk/Source/_javascript_Core/API/JSScript.mm (246059 => 246060)
--- trunk/Source/_javascript_Core/API/JSScript.mm 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/API/JSScript.mm 2019-06-04 11:14:10 UTC (rev 246060)
@@ -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 @@
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;
}
Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (246059 => 246060)
--- trunk/Source/_javascript_Core/API/tests/testapi.mm 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm 2019-06-04 11:14:10 UTC (rev 246060)
@@ -2197,7 +2197,7 @@
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"]);
}
}
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (246059 => 246060)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2019-06-04 11:14:10 UTC (rev 246060)
@@ -751,6 +751,7 @@
runtime/BooleanPrototype.h
runtime/Butterfly.h
runtime/ButterflyInlines.h
+ runtime/BytecodeCacheError.h
runtime/CachePayload.h
runtime/CacheUpdate.h
runtime/CachedBytecode.h
Modified: trunk/Source/_javascript_Core/ChangeLog (246059 => 246060)
--- trunk/Source/_javascript_Core/ChangeLog 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-06-04 11:14:10 UTC (rev 246060)
@@ -1,3 +1,51 @@
+2019-06-04 Tadeu Zagallo <[email protected]>
+
+ JSScript should not keep bytecode cache in memory
+ https://bugs.webkit.org/show_bug.cgi?id=198482
+
+ Reviewed by Saam Barati.
+
+ 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:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Sources.txt:
+ * jsc.cpp:
+ * parser/SourceProvider.h:
+ * runtime/BytecodeCacheError.cpp: Added.
+ (JSC::BytecodeCacheError::StandardError::isValid const):
+ (JSC::BytecodeCacheError::StandardError::message const):
+ (JSC::BytecodeCacheError::WriteError::isValid const):
+ (JSC::BytecodeCacheError::WriteError::message const):
+ (JSC::BytecodeCacheError::operator=):
+ (JSC::BytecodeCacheError::isValid const):
+ (JSC::BytecodeCacheError::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-03 Caio Lima <[email protected]>
[ESNext][BigInt] Implement support for "**"
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (246059 => 246060)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-06-04 11:14:10 UTC (rev 246060)
@@ -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 */,
Modified: trunk/Source/_javascript_Core/Sources.txt (246059 => 246060)
--- trunk/Source/_javascript_Core/Sources.txt 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/Sources.txt 2019-06-04 11:14:10 UTC (rev 246060)
@@ -718,6 +718,7 @@
runtime/BooleanConstructor.cpp
runtime/BooleanObject.cpp
runtime/BooleanPrototype.cpp
+runtime/BytecodeCacheError.cpp
runtime/CallData.cpp
runtime/CachePayload.cpp
runtime/CacheUpdate.cpp
Modified: trunk/Source/_javascript_Core/jsc.cpp (246059 => 246060)
--- trunk/Source/_javascript_Core/jsc.cpp 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/jsc.cpp 2019-06-04 11:14:10 UTC (rev 246060)
@@ -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 @@
{
if (!cacheEnabled() || !m_cachedBytecode)
return;
- Ref<CachedBytecode> cachedBytecode = encodeFunctionCodeBlock(*executable->vm(), codeBlock);
- m_cachedBytecode->addFunctionUpdate(executable, kind, WTFMove(cachedBytecode));
+ BytecodeCacheError error;
+ RefPtr<CachedBytecode> cachedBytecode = encodeFunctionCodeBlock(*executable->vm(), codeBlock, error);
+ if (cachedBytecode && !error.isValid())
+ m_cachedBytecode->addFunctionUpdate(executable, kind, *cachedBytecode);
}
void cacheBytecode(const BytecodeCacheGenerator& generator) const override
@@ -991,7 +994,9 @@
return;
if (!m_cachedBytecode)
m_cachedBytecode = CachedBytecode::create();
- m_cachedBytecode->addGlobalUpdate(generator());
+ auto update = generator();
+ if (update)
+ m_cachedBytecode->addGlobalUpdate(*update);
}
void commitCachedBytecode() const override
Modified: trunk/Source/_javascript_Core/parser/SourceProvider.h (246059 => 246060)
--- trunk/Source/_javascript_Core/parser/SourceProvider.h 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/parser/SourceProvider.h 2019-06-04 11:14:10 UTC (rev 246060)
@@ -48,7 +48,7 @@
WebAssembly,
};
- using BytecodeCacheGenerator = Function<Ref<CachedBytecode>()>;
+ using BytecodeCacheGenerator = Function<RefPtr<CachedBytecode>()>;
class SourceProvider : public RefCounted<SourceProvider> {
public:
Added: trunk/Source/_javascript_Core/runtime/BytecodeCacheError.cpp (0 => 246060)
--- trunk/Source/_javascript_Core/runtime/BytecodeCacheError.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/BytecodeCacheError.cpp 2019-06-04 11:14:10 UTC (rev 246060)
@@ -0,0 +1,83 @@
+/*
+ * 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::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.");
+}
+
+BytecodeCacheError& BytecodeCacheError::operator=(const ParserError& error)
+{
+ m_error = error;
+ return *this;
+}
+
+BytecodeCacheError& BytecodeCacheError::operator=(const StandardError& error)
+{
+ m_error = error;
+ return *this;
+}
+
+BytecodeCacheError& BytecodeCacheError::operator=(const WriteError& error)
+{
+ m_error = error;
+ return *this;
+}
+
+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();
+ });
+}
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/runtime/BytecodeCacheError.h (0 => 246060)
--- trunk/Source/_javascript_Core/runtime/BytecodeCacheError.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/BytecodeCacheError.h 2019-06-04 11:14:10 UTC (rev 246060)
@@ -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:
+ 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;
+ };
+
+ JS_EXPORT_PRIVATE BytecodeCacheError& operator=(const ParserError&);
+ JS_EXPORT_PRIVATE BytecodeCacheError& operator=(const StandardError&);
+ JS_EXPORT_PRIVATE BytecodeCacheError& operator=(const WriteError&);
+
+ JS_EXPORT_PRIVATE bool isValid() const;
+ JS_EXPORT_PRIVATE String message() const;
+
+private:
+ Variant<ParserError, StandardError, WriteError> m_error;
+};
+
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/CachedBytecode.h (246059 => 246060)
--- trunk/Source/_javascript_Core/runtime/CachedBytecode.h 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/runtime/CachedBytecode.h 2019-06-04 11:14:10 UTC (rev 246060)
@@ -47,9 +47,9 @@
}
#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
Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (246059 => 246060)
--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2019-06-04 11:14:10 UTC (rev 246060)
@@ -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 @@
ptrdiff_t m_offset;
};
- Encoder(VM& vm)
+ Encoder(VM& vm, int fd = -1)
: m_vm(vm)
+ , m_fd(fd)
, m_baseOffset(0)
, m_currentPage(nullptr)
{
@@ -144,12 +146,20 @@
m_leafExecutables.add(executable, offset);
}
- Ref<CachedBytecode> release()
+ RefPtr<CachedBytecode> release(BytecodeCacheError& error)
{
if (!m_currentPage)
- return CachedBytecode::create();
+ return nullptr;
+ m_currentPage->alignEnd();
- 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 @@
}
private:
+#if !OS(WINDOWS)
+ RefPtr<CachedBytecode> releaseMapped(BytecodeCacheError& error)
+ {
+ size_t size = m_baseOffset + m_currentPage->size();
+ if (ftruncate(m_fd, size)) {
+ error = BytecodeCacheError::StandardError(errno);
+ return nullptr;
+ }
+
+ for (const auto& page : m_pages) {
+ ssize_t bytesWritten = write(m_fd, page.buffer(), page.size());
+ if (bytesWritten == -1) {
+ error = BytecodeCacheError::StandardError(errno);
+ return nullptr;
+ }
+
+ if (static_cast<size_t>(bytesWritten) != page.size()) {
+ error = BytecodeCacheError::WriteError(bytesWritten, page.size());
+ return nullptr;
+ }
+ }
+
+ void* buffer = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, m_fd, 0);
+ if (buffer == MAP_FAILED) {
+ error = BytecodeCacheError::StandardError(errno);
+ return nullptr;
+ }
+
+ return CachedBytecode::create(buffer, size, WTFMove(m_leafExecutables));
+ }
+#endif
+
class Page {
public:
Page(size_t size)
@@ -228,6 +270,7 @@
}
VM& m_vm;
+ int m_fd;
ptrdiff_t m_baseOffset;
Page* m_currentPage;
Vector<Page> m_pages;
@@ -2342,11 +2385,11 @@
entry->encode(encoder, { key, jsCast<const UnlinkedCodeBlockType*>(codeBlock) });
}
-Ref<CachedBytecode> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const UnlinkedCodeBlock* codeBlock)
+RefPtr<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 @@
else
ASSERT(classInfo == UnlinkedEvalCodeBlock::info());
- return encoder.release();
+ return encoder.release(error);
}
-Ref<CachedBytecode> encodeFunctionCodeBlock(VM& vm, const UnlinkedFunctionCodeBlock* codeBlock)
+RefPtr<CachedBytecode> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const UnlinkedCodeBlock* codeBlock)
{
+ BytecodeCacheError error;
+ return encodeCodeBlock(vm, key, codeBlock, -1, error);
+}
+
+RefPtr<CachedBytecode> encodeFunctionCodeBlock(VM& vm, const UnlinkedFunctionCodeBlock* codeBlock, BytecodeCacheError& error)
+{
Encoder encoder(vm);
encoder.malloc<CachedFunctionCodeBlock>()->encode(encoder, *codeBlock);
- return encoder.release();
+ return encoder.release(error);
}
UnlinkedCodeBlock* decodeCodeBlockImpl(VM& vm, const SourceCodeKey& key, Ref<CachedBytecode> cachedBytecode)
Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.h (246059 => 246060)
--- trunk/Source/_javascript_Core/runtime/CachedTypes.h 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.h 2019-06-04 11:14:10 UTC (rev 246060)
@@ -33,6 +33,7 @@
namespace JSC {
+class BytecodeCacheError;
class CachedBytecode;
class SourceCodeKey;
class UnlinkedCodeBlock;
@@ -107,7 +108,8 @@
RefPtr<SourceProvider> m_provider;
};
-JS_EXPORT_PRIVATE Ref<CachedBytecode> encodeCodeBlock(VM&, const SourceCodeKey&, const UnlinkedCodeBlock*);
+JS_EXPORT_PRIVATE RefPtr<CachedBytecode> encodeCodeBlock(VM&, const SourceCodeKey&, const UnlinkedCodeBlock*);
+JS_EXPORT_PRIVATE RefPtr<CachedBytecode> encodeCodeBlock(VM&, const SourceCodeKey&, const UnlinkedCodeBlock*, int fd, BytecodeCacheError&);
UnlinkedCodeBlock* decodeCodeBlockImpl(VM&, const SourceCodeKey&, Ref<CachedBytecode>);
@@ -117,7 +119,7 @@
return jsCast<UnlinkedCodeBlockType*>(decodeCodeBlockImpl(vm, key, WTFMove(cachedBytecode)));
}
-JS_EXPORT_PRIVATE Ref<CachedBytecode> encodeFunctionCodeBlock(VM&, const UnlinkedFunctionCodeBlock*);
+JS_EXPORT_PRIVATE RefPtr<CachedBytecode> encodeFunctionCodeBlock(VM&, const UnlinkedFunctionCodeBlock*, BytecodeCacheError&);
JS_EXPORT_PRIVATE void decodeFunctionCodeBlock(Decoder&, int32_t cachedFunctionCodeBlockOffset, WriteBarrier<UnlinkedFunctionCodeBlock>&, const JSCell*);
Modified: trunk/Source/_javascript_Core/runtime/CodeCache.cpp (246059 => 246060)
--- trunk/Source/_javascript_Core/runtime/CodeCache.cpp 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.cpp 2019-06-04 11:14:10 UTC (rev 246060)
@@ -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 @@
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)
+RefPtr<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);
}
}
Modified: trunk/Source/_javascript_Core/runtime/CodeCache.h (246059 => 246060)
--- trunk/Source/_javascript_Core/runtime/CodeCache.h 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.h 2019-06-04 11:14:10 UTC (rev 246060)
@@ -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 @@
}
void writeCodeBlock(VM&, const SourceCodeKey&, const SourceCodeValue&);
-Ref<CachedBytecode> serializeBytecode(VM&, UnlinkedCodeBlock*, const SourceCode&, SourceCodeType, JSParserStrictMode, JSParserScriptMode, OptionSet<CodeGenerationMode>);
+RefPtr<CachedBytecode> serializeBytecode(VM&, UnlinkedCodeBlock*, const SourceCode&, SourceCodeType, JSParserStrictMode, JSParserScriptMode, int fd, BytecodeCacheError&, OptionSet<CodeGenerationMode>);
SourceCodeKey sourceCodeKeyForSerializedProgram(VM&, const SourceCode&);
SourceCodeKey sourceCodeKeyForSerializedModule(VM&, const SourceCode&);
Modified: trunk/Source/_javascript_Core/runtime/Completion.cpp (246059 => 246060)
--- trunk/Source/_javascript_Core/runtime/Completion.cpp 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/runtime/Completion.cpp 2019-06-04 11:14:10 UTC (rev 246060)
@@ -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 @@
return true;
}
-Ref<CachedBytecode> generateProgramBytecode(VM& vm, const SourceCode& source, ParserError& error)
+RefPtr<CachedBytecode> generateProgramBytecode(VM& vm, const SourceCode& source, int fd, BytecodeCacheError& error)
{
JSLockHolder lock(vm);
RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
@@ -101,13 +102,17 @@
JSParserScriptMode scriptMode = JSParserScriptMode::Classic;
EvalContextType evalContextType = EvalContextType::None;
- UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, error, evalContextType, &variablesUnderTDZ);
+ ParserError parserError;
+ UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, parserError, evalContextType, &variablesUnderTDZ);
+ if (parserError.isValid())
+ error = parserError;
if (!unlinkedCodeBlock)
- return CachedBytecode::create();
- return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, { });
+ return nullptr;
+
+ return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, fd, error, { });
}
-Ref<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, ParserError& error)
+RefPtr<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, int fd, BytecodeCacheError& error)
{
JSLockHolder lock(vm);
RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
@@ -117,10 +122,13 @@
JSParserScriptMode scriptMode = JSParserScriptMode::Module;
EvalContextType evalContextType = EvalContextType::None;
- UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, error, evalContextType, &variablesUnderTDZ);
+ ParserError parserError;
+ UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, parserError, evalContextType, &variablesUnderTDZ);
+ if (parserError.isValid())
+ error = parserError;
if (!unlinkedCodeBlock)
- return CachedBytecode::create();
- return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, { });
+ return nullptr;
+ return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, fd, error, { });
}
JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException)
Modified: trunk/Source/_javascript_Core/runtime/Completion.h (246059 => 246060)
--- trunk/Source/_javascript_Core/runtime/Completion.h 2019-06-04 10:37:58 UTC (rev 246059)
+++ trunk/Source/_javascript_Core/runtime/Completion.h 2019-06-04 11:14:10 UTC (rev 246060)
@@ -28,6 +28,7 @@
namespace JSC {
+class BytecodeCacheError;
class CachedBytecode;
class Exception;
class ExecState;
@@ -42,8 +43,8 @@
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 RefPtr<CachedBytecode> generateProgramBytecode(VM&, const SourceCode&, int fd, BytecodeCacheError&);
+JS_EXPORT_PRIVATE RefPtr<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())