Title: [242239] trunk/Source/_javascript_Core
Revision
242239
Author
sbar...@apple.com
Date
2019-02-28 15:58:12 -0800 (Thu, 28 Feb 2019)

Log Message

Make JSScript:cacheBytecodeWithError update the cache when the script changes
https://bugs.webkit.org/show_bug.cgi?id=194912

Reviewed by Mark Lam.

Prior to this patch, the JSScript SPI would never check if its cached
bytecode were still valid. This would lead the cacheBytecodeWithError
succeeding even if the underlying cache were stale. This patch fixes
that by making JSScript check if the cache is still valid. If it's not,
we will cache bytecode when cacheBytecodeWithError is invoked.

* API/JSScript.mm:
(-[JSScript readCache]):
(-[JSScript writeCache:]):
* API/tests/testapi.mm:
(testBytecodeCacheWithSameCacheFileAndDifferentScript):
(testObjectiveCAPI):
* runtime/CachedTypes.cpp:
(JSC::Decoder::Decoder):
(JSC::VariableLengthObject::buffer const):
(JSC::CachedPtr::decode const):
(JSC::tagFromSourceCodeType):
(JSC::GenericCacheEntry::isUpToDate const):
(JSC::CacheEntry::isStillValid const):
(JSC::GenericCacheEntry::decode const):
(JSC::GenericCacheEntry::isStillValid const):
(JSC::encodeCodeBlock):
(JSC::decodeCodeBlockImpl):
(JSC::isCachedBytecodeStillValid):
* runtime/CachedTypes.h:
* runtime/CodeCache.cpp:
(JSC::sourceCodeKeyForSerializedBytecode):
(JSC::sourceCodeKeyForSerializedProgram):
(JSC::sourceCodeKeyForSerializedModule):
(JSC::serializeBytecode):
* runtime/CodeCache.h:
(JSC::CodeCacheMap::fetchFromDiskImpl):
* runtime/Completion.cpp:
(JSC::generateProgramBytecode):
(JSC::generateBytecode): Deleted.
* runtime/Completion.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSScript.mm (242238 => 242239)


--- trunk/Source/_javascript_Core/API/JSScript.mm	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/API/JSScript.mm	2019-02-28 23:58:12 UTC (rev 242239)
@@ -27,6 +27,8 @@
 #import "JSScriptInternal.h"
 
 #import "APICast.h"
+#import "CachedTypes.h"
+#import "CodeCache.h"
 #import "Identifier.h"
 #import "JSContextInternal.h"
 #import "JSScriptSourceProvider.h"
@@ -201,7 +203,13 @@
     void* buffer = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
     close(fd);
 
-    m_cachedBytecode = JSC::CachedBytecode { buffer, size };
+    JSC::CachedBytecode cachedBytecode { buffer, size };
+
+    JSC::VM& vm = m_virtualMachine.vm;
+    const JSC::SourceCode& sourceCode = [self jsSourceCode]->sourceCode();
+    JSC::SourceCodeKey key = m_type == kJSScriptTypeProgram ? sourceCodeKeyForSerializedProgram(vm, sourceCode) : sourceCodeKeyForSerializedModule(vm, sourceCode);
+    if (isCachedBytecodeStillValid(vm, cachedBytecode, key, m_type == kJSScriptTypeProgram ? JSC::SourceCodeType::ProgramType : JSC::SourceCodeType::ModuleType))
+        m_cachedBytecode = WTFMove(cachedBytecode);
 }
 
 - (BOOL)cacheBytecodeWithError:(NSError **)error
@@ -269,7 +277,7 @@
         m_cachedBytecode = JSC::generateModuleBytecode(m_virtualMachine.vm, [self jsSourceCode]->sourceCode(), parserError);
         break;
     case kJSScriptTypeProgram:
-        m_cachedBytecode = JSC::generateBytecode(m_virtualMachine.vm, [self jsSourceCode]->sourceCode(), parserError);
+        m_cachedBytecode = JSC::generateProgramBytecode(m_virtualMachine.vm, [self jsSourceCode]->sourceCode(), parserError);
         break;
     }
 

Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (242238 => 242239)


--- trunk/Source/_javascript_Core/API/tests/testapi.mm	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm	2019-02-28 23:58:12 UTC (rev 242239)
@@ -2094,6 +2094,50 @@
     }
 }
 
+static void testBytecodeCacheWithSameCacheFileAndDifferentScript(bool forceDiskCache)
+{
+    NSURL *cachePath = tempFile(@"cachePath.cache");
+    NSURL *sourceURL = [NSURL URLWithString:@"my-path"];
+
+    @autoreleasepool {
+        JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];
+        NSString *source = @"function foo() { return 42; }; function bar() { return 40; }; foo() + bar();";
+        JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
+        JSScript *script = [JSScript scriptOfType:kJSScriptTypeProgram withSource:source andSourceURL:sourceURL andBytecodeCache:cachePath inVirtualMachine:vm error:nil];
+        RELEASE_ASSERT(script);
+        if (![script cacheBytecodeWithError:nil])
+            CRASH();
+
+        JSC::Options::forceDiskCache() = forceDiskCache;
+        JSValue *result = [context evaluateJSScript:script];
+        RELEASE_ASSERT(result);
+        RELEASE_ASSERT([result isNumber]);
+        checkResult(@"Expected 82 as result", [[result toNumber] intValue] == 82);
+    }
+
+    @autoreleasepool {
+        JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];
+        NSString *source = @"function foo() { return 10; }; function bar() { return 20; }; foo() + bar();";
+        JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
+        JSScript *script = [JSScript scriptOfType:kJSScriptTypeProgram withSource:source andSourceURL:sourceURL andBytecodeCache:cachePath inVirtualMachine:vm error:nil];
+        RELEASE_ASSERT(script);
+        if (![script cacheBytecodeWithError:nil])
+            CRASH();
+
+        JSC::Options::forceDiskCache() = forceDiskCache;
+        JSValue *result = [context evaluateJSScript:script];
+        RELEASE_ASSERT(result);
+        RELEASE_ASSERT([result isNumber]);
+        checkResult(@"Expected 30 as result", [[result toNumber] intValue] == 30);
+    }
+
+    JSC::Options::forceDiskCache() = false;
+
+    NSFileManager* fileManager = [NSFileManager defaultManager];
+    BOOL removedAll = [fileManager removeItemAtURL:cachePath error:nil];
+    checkResult(@"Removed all temp files created", removedAll);
+}
+
 static void testProgramJSScriptException()
 {
     @autoreleasepool {
@@ -2319,6 +2363,8 @@
     RUN(testProgramBytecodeCache());
     RUN(testBytecodeCacheWithSyntaxError(kJSScriptTypeProgram));
     RUN(testBytecodeCacheWithSyntaxError(kJSScriptTypeModule));
+    RUN(testBytecodeCacheWithSameCacheFileAndDifferentScript(false));
+    RUN(testBytecodeCacheWithSameCacheFileAndDifferentScript(true));
     RUN(testProgramJSScriptException());
 
     RUN(testLoaderRejectsNilScriptURL());

Modified: trunk/Source/_javascript_Core/ChangeLog (242238 => 242239)


--- trunk/Source/_javascript_Core/ChangeLog	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-02-28 23:58:12 UTC (rev 242239)
@@ -1,3 +1,47 @@
+2019-02-28  Saam barati  <sbar...@apple.com>
+
+        Make JSScript:cacheBytecodeWithError update the cache when the script changes
+        https://bugs.webkit.org/show_bug.cgi?id=194912
+
+        Reviewed by Mark Lam.
+
+        Prior to this patch, the JSScript SPI would never check if its cached
+        bytecode were still valid. This would lead the cacheBytecodeWithError
+        succeeding even if the underlying cache were stale. This patch fixes
+        that by making JSScript check if the cache is still valid. If it's not,
+        we will cache bytecode when cacheBytecodeWithError is invoked.
+
+        * API/JSScript.mm:
+        (-[JSScript readCache]):
+        (-[JSScript writeCache:]):
+        * API/tests/testapi.mm:
+        (testBytecodeCacheWithSameCacheFileAndDifferentScript):
+        (testObjectiveCAPI):
+        * runtime/CachedTypes.cpp:
+        (JSC::Decoder::Decoder):
+        (JSC::VariableLengthObject::buffer const):
+        (JSC::CachedPtr::decode const):
+        (JSC::tagFromSourceCodeType):
+        (JSC::GenericCacheEntry::isUpToDate const):
+        (JSC::CacheEntry::isStillValid const):
+        (JSC::GenericCacheEntry::decode const):
+        (JSC::GenericCacheEntry::isStillValid const):
+        (JSC::encodeCodeBlock):
+        (JSC::decodeCodeBlockImpl):
+        (JSC::isCachedBytecodeStillValid):
+        * runtime/CachedTypes.h:
+        * runtime/CodeCache.cpp:
+        (JSC::sourceCodeKeyForSerializedBytecode):
+        (JSC::sourceCodeKeyForSerializedProgram):
+        (JSC::sourceCodeKeyForSerializedModule):
+        (JSC::serializeBytecode):
+        * runtime/CodeCache.h:
+        (JSC::CodeCacheMap::fetchFromDiskImpl):
+        * runtime/Completion.cpp:
+        (JSC::generateProgramBytecode):
+        (JSC::generateBytecode): Deleted.
+        * runtime/Completion.h:
+
 2019-02-28  Mark Lam  <mark....@apple.com>
 
         cloop.rb shift mask should depend on the word size being shifted.

Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (242238 => 242239)


--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp	2019-02-28 23:58:12 UTC (rev 242239)
@@ -33,6 +33,7 @@
 #include "JSTemplateObjectDescriptor.h"
 #include "ScopedArgumentsTable.h"
 #include "SourceCodeKey.h"
+#include "SourceProvider.h"
 #include "UnlinkedEvalCodeBlock.h"
 #include "UnlinkedFunctionCodeBlock.h"
 #include "UnlinkedMetadataTableInlines.h"
@@ -217,7 +218,7 @@
 public:
     Decoder(VM& vm, const void* baseAddress, size_t size)
         : m_vm(vm)
-        , m_baseAddress(reinterpret_cast<const uint8_t*>(baseAddress))
+        , m_baseAddress(static_cast<const uint8_t*>(baseAddress))
 #ifndef NDEBUG
         , m_size(size)
 #endif
@@ -348,7 +349,7 @@
     const uint8_t* buffer() const
     {
         ASSERT(m_offset != s_invalidOffset);
-        return reinterpret_cast<const uint8_t*>(this) + m_offset;
+        return bitwise_cast<const uint8_t*>(this) + m_offset;
     }
 
     template<typename T>
@@ -412,7 +413,7 @@
         ptrdiff_t bufferOffset = decoder.offsetOf(this->buffer());
         if (Optional<void*> ptr = decoder.cachedPtrForOffset(bufferOffset)) {
             isNewAllocation = false;
-            return reinterpret_cast<Source*>(*ptr);
+            return static_cast<Source*>(*ptr);
         }
 
         isNewAllocation = true;
@@ -1815,6 +1816,21 @@
     CachedEvalCodeBlockTag,
 };
 
+static constexpr CachedCodeBlockTag tagFromSourceCodeType(SourceCodeType type)
+{
+    switch (type) {
+    case SourceCodeType::ProgramType:
+        return CachedProgramCodeBlockTag;
+    case SourceCodeType::EvalType:
+        return CachedEvalCodeBlockTag;
+    case SourceCodeType::ModuleType:
+        return CachedModuleCodeBlockTag;
+    case SourceCodeType::FunctionType:
+        ASSERT_NOT_REACHED();
+        return static_cast<CachedCodeBlockTag>(-1);
+    }
+}
+
 template<>
 struct CachedCodeBlockTypeImpl<UnlinkedProgramCodeBlock> {
     using type = CachedProgramCodeBlock;
@@ -2078,6 +2094,7 @@
 class GenericCacheEntry {
 public:
     bool decode(Decoder&, std::pair<SourceCodeKey, UnlinkedCodeBlock*>&) const;
+    bool isStillValid(Decoder&, const SourceCodeKey&, CachedCodeBlockTag) const;
 
 protected:
     GenericCacheEntry(Encoder& encoder, CachedCodeBlockTag tag)
@@ -2088,6 +2105,15 @@
 
     CachedCodeBlockTag tag() const { return m_tag; }
 
+    bool isUpToDate(Decoder& decoder) const
+    {
+        if (m_cacheVersion != JSC_BYTECODE_CACHE_VERSION)
+            return false;
+        if (m_bootSessionUUID.decode(decoder) != bootSessionUUIDString())
+            return false;
+        return true;
+    }
+
 private:
     uint32_t m_cacheVersion { JSC_BYTECODE_CACHE_VERSION };
     CachedString m_bootSessionUUID;
@@ -2111,6 +2137,13 @@
 private:
     friend GenericCacheEntry;
 
+    bool isStillValid(Decoder& decoder, const SourceCodeKey& key) const
+    {
+        SourceCodeKey decodedKey;
+        m_key.decode(decoder, decodedKey);
+        return decodedKey == key;
+    }
+
     bool decode(Decoder& decoder, std::pair<SourceCodeKey, UnlinkedCodeBlockType*>& result) const
     {
         ASSERT(tag() == CachedCodeBlockTypeImpl<UnlinkedCodeBlockType>::tag);
@@ -2126,16 +2159,14 @@
 
 bool GenericCacheEntry::decode(Decoder& decoder, std::pair<SourceCodeKey, UnlinkedCodeBlock*>& result) const
 {
-    if (m_cacheVersion != JSC_BYTECODE_CACHE_VERSION)
+    if (!isUpToDate(decoder))
         return false;
-    if (m_bootSessionUUID.decode(decoder) != bootSessionUUIDString())
-        return false;
 
     switch (m_tag) {
     case CachedProgramCodeBlockTag:
-        return reinterpret_cast<const CacheEntry<UnlinkedProgramCodeBlock>*>(this)->decode(decoder, reinterpret_cast<std::pair<SourceCodeKey, UnlinkedProgramCodeBlock*>&>(result));
+        return bitwise_cast<const CacheEntry<UnlinkedProgramCodeBlock>*>(this)->decode(decoder, reinterpret_cast<std::pair<SourceCodeKey, UnlinkedProgramCodeBlock*>&>(result));
     case CachedModuleCodeBlockTag:
-        return reinterpret_cast<const CacheEntry<UnlinkedModuleProgramCodeBlock>*>(this)->decode(decoder, reinterpret_cast<std::pair<SourceCodeKey, UnlinkedModuleProgramCodeBlock*>&>(result));
+        return bitwise_cast<const CacheEntry<UnlinkedModuleProgramCodeBlock>*>(this)->decode(decoder, reinterpret_cast<std::pair<SourceCodeKey, UnlinkedModuleProgramCodeBlock*>&>(result));
     case CachedEvalCodeBlockTag:
         // We do not cache eval code blocks
         RELEASE_ASSERT_NOT_REACHED();
@@ -2147,11 +2178,29 @@
 #endif
 }
 
+bool GenericCacheEntry::isStillValid(Decoder& decoder, const SourceCodeKey& key, CachedCodeBlockTag tag) const
+{
+    if (!isUpToDate(decoder))
+        return false;
+
+    switch (tag) {
+    case CachedProgramCodeBlockTag:
+        return bitwise_cast<const CacheEntry<UnlinkedProgramCodeBlock>*>(this)->isStillValid(decoder, key);
+    case CachedModuleCodeBlockTag:
+        return bitwise_cast<const CacheEntry<UnlinkedModuleProgramCodeBlock>*>(this)->isStillValid(decoder, key);
+    case CachedEvalCodeBlockTag:
+        // We do not cache eval code blocks
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return false;
+}
+
 template<typename UnlinkedCodeBlockType>
 void encodeCodeBlock(Encoder& encoder, const SourceCodeKey& key, const UnlinkedCodeBlock* codeBlock)
 {
     auto* entry = encoder.template malloc<CacheEntry<UnlinkedCodeBlockType>>(encoder);
-    entry->encode(encoder,  { key, jsCast<const UnlinkedCodeBlockType*>(codeBlock) });
+    entry->encode(encoder, { key, jsCast<const UnlinkedCodeBlockType*>(codeBlock) });
 }
 
 std::pair<MallocPtr<uint8_t>, size_t> encodeCodeBlock(VM& vm, const SourceCodeKey& key, const UnlinkedCodeBlock* codeBlock)
@@ -2171,7 +2220,7 @@
 
 UnlinkedCodeBlock* decodeCodeBlockImpl(VM& vm, const SourceCodeKey& key, const void* buffer, size_t size)
 {
-    const auto* cachedEntry = reinterpret_cast<const GenericCacheEntry*>(buffer);
+    const auto* cachedEntry = bitwise_cast<const GenericCacheEntry*>(buffer);
     Decoder decoder(vm, buffer, size);
     std::pair<SourceCodeKey, UnlinkedCodeBlock*> entry;
     {
@@ -2185,4 +2234,15 @@
     return entry.second;
 }
 
+bool isCachedBytecodeStillValid(VM& vm, const CachedBytecode& cachedBytecode, const SourceCodeKey& key, SourceCodeType type)
+{
+    const void* buffer = cachedBytecode.data();
+    size_t size = cachedBytecode.size();
+    if (!size)
+        return false;
+    const auto* cachedEntry = bitwise_cast<const GenericCacheEntry*>(buffer);
+    Decoder decoder(vm, buffer, size);
+    return cachedEntry->isStillValid(decoder, key, tagFromSourceCodeType(type));
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.h (242238 => 242239)


--- trunk/Source/_javascript_Core/runtime/CachedTypes.h	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.h	2019-02-28 23:58:12 UTC (rev 242239)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 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
@@ -30,9 +30,12 @@
 
 namespace JSC {
 
+class CachedBytecode;
 class SourceCodeKey;
 class UnlinkedCodeBlock;
 
+enum class SourceCodeType;
+
 std::pair<MallocPtr<uint8_t>, size_t> encodeCodeBlock(VM&, const SourceCodeKey&, const UnlinkedCodeBlock*);
 UnlinkedCodeBlock* decodeCodeBlockImpl(VM&, const SourceCodeKey&, const void*, size_t);
 
@@ -43,4 +46,6 @@
     return jsCast<UnlinkedCodeBlockType*>(decodeCodeBlockImpl(vm, key, buffer, size));
 }
 
+bool isCachedBytecodeStillValid(VM&, const CachedBytecode&, const SourceCodeKey&, SourceCodeType);
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/CodeCache.cpp (242238 => 242239)


--- trunk/Source/_javascript_Core/runtime/CodeCache.cpp	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.cpp	2019-02-28 23:58:12 UTC (rev 242239)
@@ -205,15 +205,36 @@
     });
 }
 
-CachedBytecode serializeBytecode(VM& vm, UnlinkedCodeBlock* codeBlock, const SourceCode& source, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode)
+static SourceCodeKey sourceCodeKeyForSerializedBytecode(VM& vm, const SourceCode& sourceCode, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode)
 {
-    SourceCodeKey key(
-        source, String(), codeType, strictMode, scriptMode,
+    return SourceCodeKey(
+        sourceCode, String(), codeType, strictMode, scriptMode,
         DerivedContextType::None, EvalContextType::None, false, debuggerMode,
         vm.typeProfiler() ? TypeProfilerEnabled::Yes : TypeProfilerEnabled::No,
         vm.controlFlowProfiler() ? ControlFlowProfilerEnabled::Yes : ControlFlowProfilerEnabled::No,
         WTF::nullopt);
-    std::pair<MallocPtr<uint8_t>, size_t> result = encodeCodeBlock(vm, key, codeBlock);
+}
+
+SourceCodeKey sourceCodeKeyForSerializedProgram(VM& vm, const SourceCode& sourceCode)
+{
+    JSParserStrictMode strictMode = JSParserStrictMode::NotStrict;
+    JSParserScriptMode scriptMode = JSParserScriptMode::Classic;
+    DebuggerMode debuggerMode = DebuggerOff;
+    return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ProgramType, strictMode, scriptMode, debuggerMode);
+}
+
+SourceCodeKey sourceCodeKeyForSerializedModule(VM& vm, const SourceCode& sourceCode)
+{
+    JSParserStrictMode strictMode = JSParserStrictMode::Strict;
+    JSParserScriptMode scriptMode = JSParserScriptMode::Module;
+    DebuggerMode debuggerMode = DebuggerOff;
+    return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ModuleType, strictMode, scriptMode, debuggerMode);
+}
+
+CachedBytecode serializeBytecode(VM& vm, UnlinkedCodeBlock* codeBlock, const SourceCode& source, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode)
+{
+    std::pair<MallocPtr<uint8_t>, size_t> result = encodeCodeBlock(vm,
+        sourceCodeKeyForSerializedBytecode(vm, source, codeType, strictMode, scriptMode, debuggerMode), codeBlock);
     return CachedBytecode { WTFMove(result.first), result.second };
 }
 

Modified: trunk/Source/_javascript_Core/runtime/CodeCache.h (242238 => 242239)


--- trunk/Source/_javascript_Core/runtime/CodeCache.h	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.h	2019-02-28 23:58:12 UTC (rev 242239)
@@ -104,33 +104,6 @@
     iterator end() { return m_map.end(); }
 
     template<typename UnlinkedCodeBlockType>
-    UnlinkedCodeBlockType* fetchFromDiskImpl(VM& vm, const SourceCodeKey& key)
-    {
-        const CachedBytecode* cachedBytecode = key.source().provider().cachedBytecode();
-        if (cachedBytecode && cachedBytecode->size()) {
-            VERBOSE_LOG("Found cached CodeBlock in the SourceProvider");
-            UnlinkedCodeBlockType* unlinkedCodeBlock = decodeCodeBlock<UnlinkedCodeBlockType>(vm, key, cachedBytecode->data(), cachedBytecode->size());
-            if (unlinkedCodeBlock)
-                return unlinkedCodeBlock;
-        }
-        return nullptr;
-    }
-
-    template<typename UnlinkedCodeBlockType>
-    std::enable_if_t<std::is_base_of<UnlinkedCodeBlock, UnlinkedCodeBlockType>::value && !std::is_same<UnlinkedCodeBlockType, UnlinkedEvalCodeBlock>::value, UnlinkedCodeBlockType*>
-    fetchFromDisk(VM& vm, const SourceCodeKey& key)
-    {
-        UnlinkedCodeBlockType* codeBlock = fetchFromDiskImpl<UnlinkedCodeBlockType>(vm, key);
-        if (UNLIKELY(Options::forceDiskCache()))
-            RELEASE_ASSERT(codeBlock);
-        return codeBlock;
-    }
-
-    template<typename T>
-    std::enable_if_t<!std::is_base_of<UnlinkedCodeBlock, T>::value || std::is_same<T, UnlinkedEvalCodeBlock>::value, T*>
-    fetchFromDisk(VM&, const SourceCodeKey&) { return nullptr; }
-
-    template<typename UnlinkedCodeBlockType>
     UnlinkedCodeBlockType* findCacheAndUpdateAge(VM& vm, const SourceCodeKey& key)
     {
         prune();
@@ -190,6 +163,33 @@
     int64_t age() { return m_age; }
 
 private:
+    template<typename UnlinkedCodeBlockType>
+    UnlinkedCodeBlockType* fetchFromDiskImpl(VM& vm, const SourceCodeKey& key)
+    {
+        const CachedBytecode* cachedBytecode = key.source().provider().cachedBytecode();
+        if (cachedBytecode && cachedBytecode->size()) {
+            VERBOSE_LOG("Found cached CodeBlock in the SourceProvider");
+            UnlinkedCodeBlockType* unlinkedCodeBlock = decodeCodeBlock<UnlinkedCodeBlockType>(vm, key, cachedBytecode->data(), cachedBytecode->size());
+            if (unlinkedCodeBlock)
+                return unlinkedCodeBlock;
+        }
+        return nullptr;
+    }
+
+    template<typename UnlinkedCodeBlockType>
+    std::enable_if_t<std::is_base_of<UnlinkedCodeBlock, UnlinkedCodeBlockType>::value && !std::is_same<UnlinkedCodeBlockType, UnlinkedEvalCodeBlock>::value, UnlinkedCodeBlockType*>
+    fetchFromDisk(VM& vm, const SourceCodeKey& key)
+    {
+        UnlinkedCodeBlockType* codeBlock = fetchFromDiskImpl<UnlinkedCodeBlockType>(vm, key);
+        if (UNLIKELY(Options::forceDiskCache()))
+            RELEASE_ASSERT(codeBlock);
+        return codeBlock;
+    }
+
+    template<typename T>
+    std::enable_if_t<!std::is_base_of<UnlinkedCodeBlock, T>::value || std::is_same<T, UnlinkedEvalCodeBlock>::value, T*>
+    fetchFromDisk(VM&, const SourceCodeKey&) { return nullptr; }
+
     // This constant factor biases cache capacity toward allowing a minimum
     // working set to enter the cache before it starts evicting.
     static const Seconds workingSetTime;
@@ -330,5 +330,7 @@
 
 void writeCodeBlock(VM&, const SourceCodeKey&, const SourceCodeValue&);
 CachedBytecode serializeBytecode(VM&, UnlinkedCodeBlock*, const SourceCode&, SourceCodeType, JSParserStrictMode, JSParserScriptMode, DebuggerMode);
+SourceCodeKey sourceCodeKeyForSerializedProgram(VM&, const SourceCode&);
+SourceCodeKey sourceCodeKeyForSerializedModule(VM&, const SourceCode&);
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/Completion.cpp (242238 => 242239)


--- trunk/Source/_javascript_Core/runtime/Completion.cpp	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/runtime/Completion.cpp	2019-02-28 23:58:12 UTC (rev 242239)
@@ -91,7 +91,7 @@
     return true;
 }
 
-CachedBytecode generateBytecode(VM& vm, const SourceCode& source, ParserError& error)
+CachedBytecode generateProgramBytecode(VM& vm, const SourceCode& source, ParserError& error)
 {
     JSLockHolder lock(vm);
     RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());

Modified: trunk/Source/_javascript_Core/runtime/Completion.h (242238 => 242239)


--- trunk/Source/_javascript_Core/runtime/Completion.h	2019-02-28 23:57:54 UTC (rev 242238)
+++ trunk/Source/_javascript_Core/runtime/Completion.h	2019-02-28 23:58:12 UTC (rev 242239)
@@ -42,7 +42,7 @@
 JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
 JS_EXPORT_PRIVATE bool checkModuleSyntax(ExecState*, const SourceCode&, ParserError&);
 
-JS_EXPORT_PRIVATE CachedBytecode generateBytecode(VM&, const SourceCode&, ParserError&);
+JS_EXPORT_PRIVATE CachedBytecode generateProgramBytecode(VM&, const SourceCode&, ParserError&);
 JS_EXPORT_PRIVATE CachedBytecode generateModuleBytecode(VM&, const SourceCode&, ParserError&);
 
 JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue, NakedPtr<Exception>& returnedException);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to