Changeset 240511 in webkit


Ignore:
Timestamp:
Jan 25, 2019 2:31:12 PM (5 years ago)
Author:
Tadeu Zagallo
Message:

Add API to generate and consume cached bytecode
https://bugs.webkit.org/show_bug.cgi?id=193401
<rdar://problem/47514099>

Reviewed by Keith Miller.

Add the generateBytecode and generateModuleBytecode functions to
generate serialized bytecode for a given SourceCode. These functions
will eagerly generate code for all the nested functions.

Additionally, update the API methods in JSScript to generate and use the
bytecode when the bytecodeCache path is provided.

  • API/JSAPIGlobalObject.mm:

(JSC::JSAPIGlobalObject::moduleLoaderFetch):

  • API/JSContext.mm:

(-[JSContext wrapperMap]):

  • API/JSContextInternal.h:
  • API/JSScript.mm:

(+[JSScript scriptWithSource:inVirtualMachine:]):
(+[JSScript scriptFromASCIIFile:inVirtualMachine:withCodeSigning:andBytecodeCache:]):
(-[JSScript dealloc]):
(-[JSScript readCache]):
(-[JSScript writeCache]):
(-[JSScript hash]):
(-[JSScript source]):
(-[JSScript cachedBytecode]):
(-[JSScript jsSourceCode:]):

  • API/JSScriptInternal.h:
  • API/JSScriptSourceProvider.h: Copied from Source/JavaScriptCore/API/JSScriptInternal.h.

(JSScriptSourceProvider::create):
(JSScriptSourceProvider::JSScriptSourceProvider):

  • API/JSScriptSourceProvider.mm: Copied from Source/JavaScriptCore/API/JSScriptInternal.h.

(JSScriptSourceProvider::hash const):
(JSScriptSourceProvider::source const):
(JSScriptSourceProvider::cachedBytecode const):

  • API/JSVirtualMachine.mm:

(-[JSVirtualMachine vm]):

  • API/JSVirtualMachineInternal.h:
  • API/tests/testapi.mm:

(testBytecodeCache):
(-[JSContextFileLoaderDelegate context:fetchModuleForIdentifier:withResolveHandler:andRejectHandler:]):
(testObjectiveCAPI):

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • SourcesCocoa.txt:
  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor):

  • bytecode/UnlinkedFunctionExecutable.h:
  • parser/SourceCodeKey.h:

(JSC::SourceCodeKey::source const):

  • parser/SourceProvider.h:

(JSC::CachedBytecode::CachedBytecode):
(JSC::CachedBytecode::operator=):
(JSC::CachedBytecode::data const):
(JSC::CachedBytecode::size const):
(JSC::CachedBytecode::owned const):
(JSC::CachedBytecode::~CachedBytecode):
(JSC::CachedBytecode::freeDataIfOwned):
(JSC::SourceProvider::cachedBytecode const):

  • parser/UnlinkedSourceCode.h:

(JSC::UnlinkedSourceCode::provider const):

  • runtime/CodeCache.cpp:

(JSC::generateUnlinkedCodeBlockForFunctions):
(JSC::writeCodeBlock):
(JSC::serializeBytecode):

  • runtime/CodeCache.h:

(JSC::CodeCacheMap::fetchFromDiskImpl):
(JSC::CodeCacheMap::findCacheAndUpdateAge):
(JSC::generateUnlinkedCodeBlockImpl):
(JSC::generateUnlinkedCodeBlock):

  • runtime/Completion.cpp:

(JSC::generateBytecode):
(JSC::generateModuleBytecode):

  • runtime/Completion.h:
  • runtime/Options.cpp:

(JSC::recomputeDependentOptions):

Location:
trunk/Source/JavaScriptCore
Files:
21 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSAPIGlobalObject.mm

    r239933 r240511  
    165165    auto strongKey = Strong<JSString>(vm, jsSecureCast<JSString*>(vm, key));
    166166    auto* resolve = JSNativeStdFunction::create(vm, globalObject, 1, "resolve", [=] (ExecState* exec) {
    167         VM& vm = exec->vm();
    168167        // This captures the globalObject but that's ok because our structure keeps it alive anyway.
    169168        JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject->globalExec())];
     
    177176        }
    178177
    179         const String& source = getJSScriptSourceCode(static_cast<JSScript *>(script));
    180         args.append(JSSourceCode::create(vm, makeSource(source, SourceOrigin(moduleKey.string()), URL({ }, moduleKey.string()), TextPosition(), JSC::SourceProviderSourceType::Module)));
     178        args.append([static_cast<JSScript *>(script) jsSourceCode:moduleKey]);
    181179        call(exec, deferredPromise->JSPromiseDeferred::resolve(), args, "This should never be seen...");
    182180        return encodedJSUndefined();
  • trunk/Source/JavaScriptCore/API/JSContext.mm

    r239933 r240511  
    3535#import "JSInternalPromise.h"
    3636#import "JSModuleLoader.h"
    37 #import "JSScriptInternal.h"
    3837#import "JSValueInternal.h"
    3938#import "JSVirtualMachineInternal.h"
     
    134133        return nil;
    135134    return [JSValue valueWithJSValueRef:toRef(m_exception.get()) inContext:self];
    136 }
    137 
    138 - (JSWrapperMap *)wrapperMap
    139 {
    140     return toJS(m_context)->lexicalGlobalObject()->wrapperMap();
    141135}
    142136
     
    333327}
    334328
     329- (JSWrapperMap *)wrapperMap
     330{
     331    return toJS(m_context)->lexicalGlobalObject()->wrapperMap();
     332}
     333
    335334- (JSValue *)wrapperForJSObject:(JSValueRef)value
    336335{
  • trunk/Source/JavaScriptCore/API/JSContextInternal.h

    r239933 r240511  
    5252- (void)endCallbackWithData:(CallbackData *)callbackData;
    5353
     54- (JSWrapperMap *)wrapperMap;
    5455- (JSValue *)wrapperForObjCObject:(id)object;
    5556- (JSValue *)wrapperForJSObject:(JSValueRef)value;
  • trunk/Source/JavaScriptCore/API/JSScript.mm

    r240194 r240511  
    2828
    2929#import "APICast.h"
     30#import "Identifier.h"
    3031#import "JSContextInternal.h"
     32#import "JSScriptSourceProvider.h"
     33#import "JSSourceCode.h"
    3134#import "JSValuePrivate.h"
     35#import "JSVirtualMachineInternal.h"
     36#import "ParserError.h"
    3237#import "Symbol.h"
     38#include <sys/stat.h>
    3339
    3440#if JSC_OBJC_API_ENABLED
    3541
    3642@implementation JSScript {
     43    __weak JSVirtualMachine* m_virtualMachine;
    3744    String m_source;
     45    NSURL* m_cachePath;
     46    JSC::CachedBytecode m_cachedBytecode;
     47    JSC::Strong<JSC::JSSourceCode> m_jsSourceCode;
     48    UniquedStringImpl* m_moduleKey;
    3849}
    3950
    4051+ (instancetype)scriptWithSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm
    4152{
    42     UNUSED_PARAM(vm);
    43     JSScript *result = [[JSScript alloc] init];
     53    JSScript *result = [[[JSScript alloc] init] autorelease];
    4454    result->m_source = source;
     55    result->m_virtualMachine = vm;
    4556    return result;
    4657}
     
    8293    // FIXME: This should check codeSigning.
    8394    UNUSED_PARAM(codeSigningPath);
    84     // FIXME: This should actually cache bytecode.
    85     UNUSED_PARAM(cachePath);
    86     UNUSED_PARAM(vm);
    8795    URL filePathURL([filePath absoluteURL]);
    8896    if (!filePathURL.isLocalFile())
     
    96104        return nil;
    97105
    98     JSScript *result = [[JSScript alloc] init];
     106    JSScript *result = [[[JSScript alloc] init] autorelease];
     107    result->m_virtualMachine = vm;
    99108    result->m_source = String::fromUTF8WithLatin1Fallback(buffer.data(), buffer.size());
     109    result->m_cachePath = cachePath;
     110    [result readCache];
    100111    return result;
    101112}
     
    106117}
    107118
    108 const String& getJSScriptSourceCode(JSScript *module) { return module->m_source; }
     119- (void)dealloc
     120{
     121    if (m_cachedBytecode.size() && !m_cachedBytecode.owned())
     122        munmap(const_cast<void*>(m_cachedBytecode.data()), m_cachedBytecode.size());
     123    [super dealloc];
     124}
     125
     126- (void)readCache
     127{
     128    if (!m_cachePath)
     129        return;
     130
     131    int fd = open(m_cachePath.path.UTF8String, O_RDONLY);
     132    if (fd == -1)
     133        return;
     134
     135    int rc = flock(fd, LOCK_SH | LOCK_NB);
     136    if (rc) {
     137        close(fd);
     138        return;
     139    }
     140
     141    struct stat sb;
     142    int res = fstat(fd, &sb);
     143    size_t size = static_cast<size_t>(sb.st_size);
     144    if (res || !size) {
     145        close(fd);
     146        return;
     147    }
     148
     149    void* buffer = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
     150    close(fd);
     151
     152    m_cachedBytecode = JSC::CachedBytecode { buffer, size };
     153}
     154
     155- (void)writeCache
     156{
     157    if (m_cachedBytecode.size() || !m_cachePath)
     158        return;
     159
     160    JSC::ParserError error;
     161    m_cachedBytecode = JSC::generateModuleBytecode(m_virtualMachine.vm, m_jsSourceCode->sourceCode(), error);
     162    if (error.isValid())
     163        return;
     164    int fd = open(m_cachePath.path.UTF8String, O_CREAT | O_WRONLY, 0666);
     165    if (fd == -1)
     166        return;
     167    int rc = flock(fd, LOCK_EX | LOCK_NB);
     168    if (!rc)
     169        write(fd, m_cachedBytecode.data(), m_cachedBytecode.size());
     170    close(fd);
     171}
    109172
    110173@end
    111174
     175@implementation JSScript(Internal)
     176
     177- (unsigned)hash
     178{
     179    return m_source.hash();
     180}
     181
     182- (const String&)source
     183{
     184    return m_source;
     185}
     186
     187- (const JSC::CachedBytecode*)cachedBytecode
     188{
     189    return &m_cachedBytecode;
     190}
     191
     192- (JSC::JSSourceCode*)jsSourceCode:(const JSC::Identifier&)moduleKey
     193{
     194    if (m_jsSourceCode) {
     195        ASSERT(moduleKey.impl() == m_moduleKey);
     196        return m_jsSourceCode.get();
     197    }
     198
     199    JSC::VM& vm = m_virtualMachine.vm;
     200    TextPosition startPosition { };
     201    Ref<JSScriptSourceProvider> sourceProvider = JSScriptSourceProvider::create(self, JSC::SourceOrigin(moduleKey.string()), URL({ }, moduleKey.string()), TextPosition(), JSC::SourceProviderSourceType::Module);
     202    JSC::SourceCode sourceCode(WTFMove(sourceProvider), startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt());
     203    JSC::JSSourceCode* jsSourceCode = JSC::JSSourceCode::create(vm, WTFMove(sourceCode));
     204    m_jsSourceCode.set(vm, jsSourceCode);
     205    [self writeCache];
     206    return jsSourceCode;
     207}
     208
     209@end
     210
    112211
    113212#endif
  • trunk/Source/JavaScriptCore/API/JSScriptInternal.h

    r239933 r240511  
    2929#import "SourceCode.h"
    3030
    31 OBJC_CLASS JSScript;
     31#if JSC_OBJC_API_ENABLED
    3232
    33 const String& getJSScriptSourceCode(JSScript *);
     33NS_ASSUME_NONNULL_BEGIN
     34
     35namespace JSC {
     36class CachedBytecode;
     37class Identifier;
     38class JSSourceCode;
     39};
     40
     41namespace WTF {
     42class String;
     43};
     44
     45@interface JSScript(Internal)
     46
     47- (unsigned)hash;
     48- (const WTF::String&)source;
     49- (const JSC::CachedBytecode*)cachedBytecode;
     50- (JSC::JSSourceCode*)jsSourceCode:(const JSC::Identifier&)moduleKey;
     51
     52@end
     53
     54NS_ASSUME_NONNULL_END
     55
     56#endif // JSC_OBJC_API_ENABLED
  • trunk/Source/JavaScriptCore/API/JSScriptSourceProvider.h

    r240510 r240511  
    2424 */
    2525
    26 #pragma once
     26#if JSC_OBJC_API_ENABLED
    2727
    28 #import "JSScript.h"
    29 #import "SourceCode.h"
     28#import "SourceProvider.h"
    3029
    31 OBJC_CLASS JSScript;
     30@class JSScript;
    3231
    33 const String& getJSScriptSourceCode(JSScript *);
     32class JSScriptSourceProvider : public JSC::SourceProvider {
     33public:
     34    template<typename... Args>
     35    static Ref<JSScriptSourceProvider> create(JSScript *script, Args&&... args)
     36    {
     37        return adoptRef(*new JSScriptSourceProvider(script, std::forward<Args>(args)...));
     38    }
     39
     40    unsigned hash() const override;
     41    StringView source() const override;
     42    const JSC::CachedBytecode* cachedBytecode() const override;
     43
     44private:
     45    template<typename... Args>
     46    JSScriptSourceProvider(JSScript *script, Args&&... args)
     47        : SourceProvider(std::forward<Args>(args)...)
     48        , m_script(script)
     49    { }
     50
     51    RetainPtr<JSScript> m_script;
     52};
     53
     54#endif // JSC_OBJC_API_ENABLED
  • trunk/Source/JavaScriptCore/API/JSScriptSourceProvider.mm

    r240510 r240511  
    2424 */
    2525
    26 #pragma once
     26#import "config.h"
     27#import "JSScriptSourceProvider.h"
    2728
    28 #import "JSScript.h"
    29 #import "SourceCode.h"
     29#if JSC_OBJC_API_ENABLED
    3030
    31 OBJC_CLASS JSScript;
     31#import "JSScriptInternal.h"
    3232
    33 const String& getJSScriptSourceCode(JSScript *);
     33unsigned JSScriptSourceProvider::hash() const
     34{
     35    return [m_script.get() hash];
     36}
     37
     38StringView JSScriptSourceProvider::source() const
     39{
     40    return [m_script.get() source];
     41}
     42
     43const JSC::CachedBytecode* JSScriptSourceProvider::cachedBytecode() const
     44{
     45    return [m_script.get() cachedBytecode];
     46}
     47
     48#endif // JSC_OBJC_API_ENABLED
  • trunk/Source/JavaScriptCore/API/JSVirtualMachine.mm

    r237607 r240511  
    298298#endif // ENABLE(DFG_JIT)
    299299
     300- (JSC::VM&)vm
     301{
     302    return *toJS(m_group);
     303}
     304
    300305@end
    301306
  • trunk/Source/JavaScriptCore/API/JSVirtualMachineInternal.h

    r239933 r240511  
    4747- (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext;
    4848- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext;
     49- (JSC::VM&)vm;
     50
    4951@end
    5052
  • trunk/Source/JavaScriptCore/API/tests/testapi.mm

    r240194 r240511  
    19811981}
    19821982
     1983static void testBytecodeCache()
     1984{
     1985    @autoreleasepool {
     1986        NSURL* tempDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
     1987
     1988        NSString* fooSource = @"import { n } from \"../foo.js\"; export let foo = n;";
     1989        NSString* barSource = @"import \"otherDirectory/baz.js\"; export let n = null;";
     1990        NSString* bazSource = @"import { foo } from \"../directory/bar.js\"; globalThis.ran = null; export let exp = foo;";
     1991
     1992        NSURL* fooPath = [tempDirectory URLByAppendingPathComponent:@"foo.js"];
     1993        NSURL* barPath = [tempDirectory URLByAppendingPathComponent:@"bar.js"];
     1994        NSURL* bazPath = [tempDirectory URLByAppendingPathComponent:@"baz.js"];
     1995
     1996        NSURL* fooCachePath = [tempDirectory URLByAppendingPathComponent:@"foo.js.cache"];
     1997        NSURL* barCachePath = [tempDirectory URLByAppendingPathComponent:@"bar.js.cache"];
     1998        NSURL* bazCachePath = [tempDirectory URLByAppendingPathComponent:@"baz.js.cache"];
     1999
     2000        [fooSource writeToURL:fooPath atomically:NO encoding:NSASCIIStringEncoding error:nil];
     2001        [barSource writeToURL:barPath atomically:NO encoding:NSASCIIStringEncoding error:nil];
     2002        [bazSource writeToURL:bazPath atomically:NO encoding:NSASCIIStringEncoding error:nil];
     2003
     2004        __block bool forceDiskCache = false;
     2005        auto block = ^(JSContext *context, JSValue *identifier, JSValue *resolve, JSValue *reject) {
     2006            JSC::Options::forceDiskCache() = forceDiskCache;
     2007            if ([identifier isEqualToObject:@"file:///directory/bar.js"])
     2008                [resolve callWithArguments:@[[JSScript scriptFromASCIIFile:fooPath inVirtualMachine:context.virtualMachine withCodeSigning:nil andBytecodeCache:fooCachePath]]];
     2009            else if ([identifier isEqualToObject:@"file:///foo.js"])
     2010                [resolve callWithArguments:@[[JSScript scriptFromASCIIFile:barPath inVirtualMachine:context.virtualMachine withCodeSigning:nil andBytecodeCache:barCachePath]]];
     2011            else if ([identifier isEqualToObject:@"file:///otherDirectory/baz.js"])
     2012                [resolve callWithArguments:@[[JSScript scriptFromASCIIFile:bazPath inVirtualMachine:context.virtualMachine withCodeSigning:nil andBytecodeCache:bazCachePath]]];
     2013            else
     2014                [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Weird path" inContext:context]]];
     2015        };
     2016
     2017        @autoreleasepool {
     2018            auto *context = [JSContextFetchDelegate contextWithBlockForFetch:block];
     2019            context.moduleLoaderDelegate = context;
     2020            JSValue *promise = [context evaluateScript:@"import('../otherDirectory/baz.js');" withSourceURL:[NSURL fileURLWithPath:@"/directory" isDirectory:YES]];
     2021            JSValue *null = [JSValue valueWithNullInContext:context];
     2022            checkModuleCodeRan(context, promise, null);
     2023        }
     2024
     2025        @autoreleasepool {
     2026            forceDiskCache = true;
     2027            auto *context = [JSContextFetchDelegate contextWithBlockForFetch:block];
     2028            context.moduleLoaderDelegate = context;
     2029            JSValue *promise = [context evaluateScript:@"import('../otherDirectory/baz.js');" withSourceURL:[NSURL fileURLWithPath:@"/directory" isDirectory:YES]];
     2030            JSValue *null = [JSValue valueWithNullInContext:context];
     2031            checkModuleCodeRan(context, promise, null);
     2032            JSC::Options::forceDiskCache() = false;
     2033        }
     2034
     2035        NSFileManager* fileManager = [NSFileManager defaultManager];
     2036        [fileManager removeItemAtURL:fooPath error:nil];
     2037        [fileManager removeItemAtURL:barPath error:nil];
     2038        [fileManager removeItemAtURL:bazPath error:nil];
     2039        [fileManager removeItemAtURL:fooCachePath error:nil];
     2040        [fileManager removeItemAtURL:barCachePath error:nil];
     2041        [fileManager removeItemAtURL:bazCachePath error:nil];
     2042    }
     2043}
     2044
    19832045@interface JSContextFileLoaderDelegate : JSContext <JSModuleLoaderDelegate>
    19842046
     
    20182080{
    20192081    NSURL *filePath = [NSURL URLWithString:[identifier toString]];
    2020     auto *script = [JSScript scriptFromASCIIFile:filePath inVirtualMachine:[context virtualMachine] withCodeSigning:nil andBytecodeCache:nil];
     2082    auto *script = [JSScript scriptFromASCIIFile:filePath inVirtualMachine:context.virtualMachine withCodeSigning:nil andBytecodeCache:nil];
    20212083    if (script)
    20222084        [resolve callWithArguments:@[script]];
     
    20502112    testFetchWithThreeCycle();
    20512113    testImportModuleTwice();
     2114    testBytecodeCache();
    20522115
    20532116    testLoaderRejectsNilScriptURL();
  • trunk/Source/JavaScriptCore/ChangeLog

    r240508 r240511  
     12019-01-25  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        Add API to generate and consume cached bytecode
     4        https://bugs.webkit.org/show_bug.cgi?id=193401
     5        <rdar://problem/47514099>
     6
     7        Reviewed by Keith Miller.
     8
     9        Add the `generateBytecode` and `generateModuleBytecode` functions to
     10        generate serialized bytecode for a given `SourceCode`. These functions
     11        will eagerly generate code for all the nested functions.
     12
     13        Additionally, update the API methods in JSScript to generate and use the
     14        bytecode when the bytecodeCache path is provided.
     15
     16        * API/JSAPIGlobalObject.mm:
     17        (JSC::JSAPIGlobalObject::moduleLoaderFetch):
     18        * API/JSContext.mm:
     19        (-[JSContext wrapperMap]):
     20        * API/JSContextInternal.h:
     21        * API/JSScript.mm:
     22        (+[JSScript scriptWithSource:inVirtualMachine:]):
     23        (+[JSScript scriptFromASCIIFile:inVirtualMachine:withCodeSigning:andBytecodeCache:]):
     24        (-[JSScript dealloc]):
     25        (-[JSScript readCache]):
     26        (-[JSScript writeCache]):
     27        (-[JSScript hash]):
     28        (-[JSScript source]):
     29        (-[JSScript cachedBytecode]):
     30        (-[JSScript jsSourceCode:]):
     31        * API/JSScriptInternal.h:
     32        * API/JSScriptSourceProvider.h: Copied from Source/JavaScriptCore/API/JSScriptInternal.h.
     33        (JSScriptSourceProvider::create):
     34        (JSScriptSourceProvider::JSScriptSourceProvider):
     35        * API/JSScriptSourceProvider.mm: Copied from Source/JavaScriptCore/API/JSScriptInternal.h.
     36        (JSScriptSourceProvider::hash const):
     37        (JSScriptSourceProvider::source const):
     38        (JSScriptSourceProvider::cachedBytecode const):
     39        * API/JSVirtualMachine.mm:
     40        (-[JSVirtualMachine vm]):
     41        * API/JSVirtualMachineInternal.h:
     42        * API/tests/testapi.mm:
     43        (testBytecodeCache):
     44        (-[JSContextFileLoaderDelegate context:fetchModuleForIdentifier:withResolveHandler:andRejectHandler:]):
     45        (testObjectiveCAPI):
     46        * JavaScriptCore.xcodeproj/project.pbxproj:
     47        * SourcesCocoa.txt:
     48        * bytecode/UnlinkedFunctionExecutable.cpp:
     49        (JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor):
     50        * bytecode/UnlinkedFunctionExecutable.h:
     51        * parser/SourceCodeKey.h:
     52        (JSC::SourceCodeKey::source const):
     53        * parser/SourceProvider.h:
     54        (JSC::CachedBytecode::CachedBytecode):
     55        (JSC::CachedBytecode::operator=):
     56        (JSC::CachedBytecode::data const):
     57        (JSC::CachedBytecode::size const):
     58        (JSC::CachedBytecode::owned const):
     59        (JSC::CachedBytecode::~CachedBytecode):
     60        (JSC::CachedBytecode::freeDataIfOwned):
     61        (JSC::SourceProvider::cachedBytecode const):
     62        * parser/UnlinkedSourceCode.h:
     63        (JSC::UnlinkedSourceCode::provider const):
     64        * runtime/CodeCache.cpp:
     65        (JSC::generateUnlinkedCodeBlockForFunctions):
     66        (JSC::writeCodeBlock):
     67        (JSC::serializeBytecode):
     68        * runtime/CodeCache.h:
     69        (JSC::CodeCacheMap::fetchFromDiskImpl):
     70        (JSC::CodeCacheMap::findCacheAndUpdateAge):
     71        (JSC::generateUnlinkedCodeBlockImpl):
     72        (JSC::generateUnlinkedCodeBlock):
     73        * runtime/Completion.cpp:
     74        (JSC::generateBytecode):
     75        (JSC::generateModuleBytecode):
     76        * runtime/Completion.h:
     77        * runtime/Options.cpp:
     78        (JSC::recomputeDependentOptions):
     79
    1802019-01-25  Keith Rollin  <krollin@apple.com>
    281
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r240468 r240511  
    815815                14CA958B16AB50DE00938A06 /* StaticPropertyAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 14CA958A16AB50DE00938A06 /* StaticPropertyAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
    816816                14CA958D16AB50FA00938A06 /* ObjectAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 14CA958C16AB50FA00938A06 /* ObjectAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
     817                14D01A7721FB351F00BC54E9 /* JSScriptSourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01A7621FB350300BC54E9 /* JSScriptSourceProvider.h */; };
    817818                14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D2F3D9139F4BE200491031 /* MarkedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
    818819                14DF04DA16B3996D0016A513 /* StaticPropertyAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DF04D916B3996D0016A513 /* StaticPropertyAnalysis.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    32393240                14CC3BA12138A238002D58B6 /* InstructionStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InstructionStream.cpp; sourceTree = "<group>"; };
    32403241                14CC3BA22138A238002D58B6 /* InstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InstructionStream.h; sourceTree = "<group>"; };
     3242                14D01A7521FB350300BC54E9 /* JSScriptSourceProvider.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = JSScriptSourceProvider.mm; sourceTree = "<group>"; };
     3243                14D01A7621FB350300BC54E9 /* JSScriptSourceProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSScriptSourceProvider.h; sourceTree = "<group>"; };
    32413244                14D2F3D9139F4BE200491031 /* MarkedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpace.h; sourceTree = "<group>"; };
    32423245                14D792640DAA03FB001A9F05 /* CLoopStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLoopStack.h; sourceTree = "<group>"; };
     
    59945997                                A7C0C4AA167C08CD0017011D /* JSScriptRef.cpp */,
    59955998                                A7C0C4AB167C08CD0017011D /* JSScriptRefPrivate.h */,
     5999                                14D01A7621FB350300BC54E9 /* JSScriptSourceProvider.h */,
     6000                                14D01A7521FB350300BC54E9 /* JSScriptSourceProvider.mm */,
    59966001                                1482B74C0A43032800517CFC /* JSStringRef.cpp */,
    59976002                                1482B74B0A43032800517CFC /* JSStringRef.h */,
     
    97769781                                14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
    97779782                                14BE7D3317135CF400D1807A /* WeakInlines.h in Headers */,
     9783                                14D01A7721FB351F00BC54E9 /* JSScriptSourceProvider.h in Headers */,
    97789784                                A7CA3AE417DA41AE006538AF /* WeakMapConstructor.h in Headers */,
    97799785                                E3A32BC71FC83147007D7E76 /* WeakMapImpl.h in Headers */,
  • trunk/Source/JavaScriptCore/SourcesCocoa.txt

    r239933 r240511  
    2525API/JSAPIWrapperObject.mm
    2626API/JSScript.mm
     27API/JSScriptSourceProvider.mm
    2728API/JSContext.mm
    2829API/JSManagedValue.mm
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp

    r239427 r240511  
    195195}
    196196
     197UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::unlinkedCodeBlockFor(CodeSpecializationKind specializationKind)
     198{
     199    switch (specializationKind) {
     200    case CodeForCall:
     201        return m_unlinkedCodeBlockForCall.get();
     202    case CodeForConstruct:
     203        return m_unlinkedCodeBlockForConstruct.get();
     204    }
     205}
     206
    197207UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::unlinkedCodeBlockFor(
    198208    VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind,
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h

    r240255 r240511  
    105105    void setInvalidTypeProfilingOffsets();
    106106
     107    UnlinkedFunctionCodeBlock* unlinkedCodeBlockFor(CodeSpecializationKind);
     108
    107109    UnlinkedFunctionCodeBlock* unlinkedCodeBlockFor(
    108110        VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode,
  • trunk/Source/JavaScriptCore/parser/SourceCodeKey.h

    r240255 r240511  
    101101    unsigned hash() const { return m_hash; }
    102102
     103    const UnlinkedSourceCode& source() const { return m_sourceCode; }
     104
    103105    size_t length() const { return m_sourceCode.length(); }
    104106
  • trunk/Source/JavaScriptCore/parser/SourceProvider.h

    r240228 r240511  
    11/*
    2  * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343    };
    4444
     45    class CachedBytecode {
     46        WTF_MAKE_NONCOPYABLE(CachedBytecode);
     47
     48    public:
     49        CachedBytecode()
     50            : CachedBytecode(nullptr, 0)
     51        {
     52        }
     53
     54        CachedBytecode(const void* data, size_t size)
     55            : m_owned(false)
     56            , m_size(size)
     57            , m_data(data)
     58        {
     59        }
     60
     61        CachedBytecode(MallocPtr<uint8_t>&& data, size_t size)
     62            : m_owned(true)
     63            , m_size(size)
     64            , m_data(data.leakPtr())
     65        {
     66        }
     67
     68        CachedBytecode(CachedBytecode&& other)
     69        {
     70            *this = WTFMove(other);
     71        }
     72
     73        CachedBytecode& operator=(CachedBytecode&& other)
     74        {
     75            freeDataIfOwned();
     76            m_owned = other.m_owned;
     77            m_size = other.m_size;
     78            m_data = other.m_data;
     79            other.m_owned = false;
     80            return *this;
     81        }
     82
     83        const void* data() const { return m_data; }
     84        size_t size() const { return m_size; }
     85        bool owned() const { return m_owned; }
     86
     87        ~CachedBytecode()
     88        {
     89            freeDataIfOwned();
     90        }
     91
     92    private:
     93        void freeDataIfOwned()
     94        {
     95            if (m_data && m_owned)
     96                fastFree(const_cast<void*>(m_data));
     97        }
     98
     99        bool m_owned;
     100        size_t m_size;
     101        const void* m_data;
     102    };
     103
     104
    45105    class SourceProvider : public RefCounted<SourceProvider> {
    46106    public:
     
    53113        virtual unsigned hash() const = 0;
    54114        virtual StringView source() const = 0;
     115        virtual const CachedBytecode* cachedBytecode() const { return nullptr; }
     116
    55117        StringView getRange(int start, int end) const
    56118        {
     
    105167        }
    106168
    107     private:
     169    protected:
    108170        StringSourceProvider(const String& source, const SourceOrigin& sourceOrigin, URL&& url, const TextPosition& startPosition, SourceProviderSourceType sourceType)
    109171            : SourceProvider(sourceOrigin, WTFMove(url), startPosition, sourceType)
     
    112174        }
    113175
     176    private:
    114177        Ref<StringImpl> m_source;
    115178    };
    116    
     179
    117180#if ENABLE(WEBASSEMBLY)
    118181    class WebAssemblySourceProvider : public SourceProvider {
  • trunk/Source/JavaScriptCore/parser/UnlinkedSourceCode.h

    r240255 r240511  
    8282        bool isHashTableDeletedValue() const { return m_provider.isHashTableDeletedValue(); }
    8383
     84        const SourceProvider& provider() const
     85        {
     86            return *m_provider;
     87        }
     88
    8489        unsigned hash() const
    8590        {
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r240255 r240511  
    163163}
    164164
    165 }
     165void generateUnlinkedCodeBlockForFunctions(VM& vm, UnlinkedCodeBlock* unlinkedCodeBlock, const SourceCode& parentSource, DebuggerMode debuggerMode, ParserError& error)
     166{
     167    auto generate = [&](UnlinkedFunctionExecutable* unlinkedExecutable, CodeSpecializationKind constructorKind) {
     168        if (constructorKind == CodeForConstruct && SourceParseModeSet(SourceParseMode::AsyncArrowFunctionMode, SourceParseMode::AsyncMethodMode, SourceParseMode::AsyncFunctionMode).contains(unlinkedExecutable->parseMode()))
     169            return;
     170
     171        FunctionExecutable* executable = unlinkedExecutable->link(vm, parentSource);
     172        const SourceCode& source = executable->source();
     173        UnlinkedFunctionCodeBlock* unlinkedFunctionCodeBlock = unlinkedExecutable->unlinkedCodeBlockFor(vm, source, constructorKind, debuggerMode, error, unlinkedExecutable->parseMode());
     174        if (unlinkedFunctionCodeBlock)
     175            generateUnlinkedCodeBlockForFunctions(vm, unlinkedFunctionCodeBlock, source, debuggerMode, error);
     176    };
     177
     178    // FIXME: We should also generate CodeBlocks for CodeForConstruct
     179    // https://bugs.webkit.org/show_bug.cgi?id=193823
     180    for (unsigned i = 0; i < unlinkedCodeBlock->numberOfFunctionDecls(); i++)
     181        generate(unlinkedCodeBlock->functionDecl(i), CodeForCall);
     182    for (unsigned i = 0; i < unlinkedCodeBlock->numberOfFunctionExprs(); i++)
     183        generate(unlinkedCodeBlock->functionExpr(i), CodeForCall);
     184}
     185
     186void writeCodeBlock(VM& vm, const SourceCodeKey& key, const SourceCodeValue& value)
     187{
     188#if OS(DARWIN)
     189    const char* cachePath = Options::diskCachePath();
     190    if (LIKELY(!cachePath))
     191        return;
     192
     193    UnlinkedCodeBlock* codeBlock = jsDynamicCast<UnlinkedCodeBlock*>(vm, value.cell.get());
     194    if (!codeBlock)
     195        return;
     196
     197    std::pair<MallocPtr<uint8_t>, size_t> result = encodeCodeBlock(vm, key, codeBlock);
     198
     199    String filename = makeString(cachePath, '/', String::number(key.hash()), ".cache");
     200    int fd = open(filename.utf8().data(), O_CREAT | O_WRONLY, 0666);
     201    if (fd == -1)
     202        return;
     203    int rc = flock(fd, LOCK_EX | LOCK_NB);
     204    if (!rc)
     205        ::write(fd, result.first.get(), result.second);
     206    close(fd);
     207#else
     208    UNUSED_PARAM(vm);
     209    UNUSED_PARAM(key);
     210    UNUSED_PARAM(value);
     211#endif
     212}
     213
     214CachedBytecode serializeBytecode(VM& vm, UnlinkedCodeBlock* codeBlock, const SourceCode& source, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode)
     215{
     216    SourceCodeKey key(
     217        source, String(), codeType, strictMode, scriptMode,
     218        DerivedContextType::None, EvalContextType::None, false, debuggerMode,
     219        vm.typeProfiler() ? TypeProfilerEnabled::Yes : TypeProfilerEnabled::No,
     220        vm.controlFlowProfiler() ? ControlFlowProfilerEnabled::Yes : ControlFlowProfilerEnabled::No,
     221        WTF::nullopt);
     222    std::pair<MallocPtr<uint8_t>, size_t> result = encodeCodeBlock(vm, key, codeBlock);
     223    return CachedBytecode { WTFMove(result.first), result.second };
     224}
     225
     226}
  • trunk/Source/JavaScriptCore/runtime/CodeCache.h

    r240255 r240511  
    3737#include "UnlinkedCodeBlock.h"
    3838#include "UnlinkedEvalCodeBlock.h"
     39#include "UnlinkedFunctionCodeBlock.h"
    3940#include "UnlinkedModuleProgramCodeBlock.h"
    4041#include "UnlinkedProgramCodeBlock.h"
     
    6162class VariableEnvironment;
    6263
     64namespace CodeCacheInternal {
     65static const bool verbose = false;
     66} // namespace CodeCacheInternal
     67
     68#define VERBOSE_LOG(...) do { \
     69    if (CodeCacheInternal::verbose) \
     70        dataLogLn("(JSC::CodeCache) ", __VA_ARGS__); \
     71} while (false)
     72
    6373struct SourceCodeValue {
    6474    SourceCodeValue()
     
    98108    UnlinkedCodeBlockType* fetchFromDiskImpl(VM& vm, const SourceCodeKey& key)
    99109    {
     110        {
     111            const auto* cachedBytecode = key.source().provider().cachedBytecode();
     112            if (cachedBytecode && cachedBytecode->size()) {
     113                VERBOSE_LOG("Found cached CodeBlock in the SourceProvider");
     114                UnlinkedCodeBlockType* unlinkedCodeBlock = decodeCodeBlock<UnlinkedCodeBlockType>(vm, key, cachedBytecode->data(), cachedBytecode->size());
     115                if (unlinkedCodeBlock)
     116                    return unlinkedCodeBlock;
     117            }
     118        }
     119
    100120#if OS(DARWIN)
    101121        const char* cachePath = Options::diskCachePath();
     
    122142        int res = fstat(fd, &sb);
    123143        size_t size = static_cast<size_t>(sb.st_size);
    124         if (res || !size)
    125             return nullptr;
    126 
    127         const void* buffer = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
     144        if (res || !size) {
     145            close(fd);
     146            return nullptr;
     147        }
     148
     149        void* buffer = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
    128150        UnlinkedCodeBlockType* unlinkedCodeBlock = decodeCodeBlock<UnlinkedCodeBlockType>(vm, key, buffer, size);
     151        munmap(buffer, size);
    129152
    130153        if (!unlinkedCodeBlock)
    131154            return nullptr;
    132155
     156        VERBOSE_LOG("Found cached CodeBlock on disk");
    133157        addCache(key, SourceCodeValue(vm, unlinkedCodeBlock, m_age));
    134158        return unlinkedCodeBlock;
     
    159183        prune();
    160184
     185        VERBOSE_LOG("Trying to find cached CodeBlock for ", key.source().provider().url().string());
    161186        iterator findResult = m_map.find(key);
    162187        if (findResult == m_map.end())
     
    181206        m_age += key.length();
    182207
     208        VERBOSE_LOG("Found cached CodeBlock in memory");
    183209        return jsCast<UnlinkedCodeBlockType*>(findResult->value.cell.get());
    184210    }
     
    292318};
    293319
    294 template <class UnlinkedCodeBlockType, class ExecutableType>
    295 UnlinkedCodeBlockType* generateUnlinkedCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
     320template <class UnlinkedCodeBlockType, class ExecutableType = ScriptExecutable>
     321UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, DerivedContextType derivedContextType, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ, ExecutableType* executable = nullptr)
    296322{
    297323    typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
    298     DerivedContextType derivedContextType = executable->derivedContextType();
    299324    std::unique_ptr<RootNode> rootNode = parse<RootNode>(
    300325        &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, strictMode, scriptMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType);
     
    307332    unsigned unlinkedEndColumn = rootNode->endColumn();
    308333    unsigned endColumn = unlinkedEndColumn + (endColumnIsOnStartLine ? startColumn : 1);
    309     unsigned arrowContextFeature = executable->isArrowFunctionContext() ? ArrowFunctionContextFeature : 0;
    310     executable->recordParse(rootNode->features() | arrowContextFeature, rootNode->hasCapturedVariables(), rootNode->lastLine(), endColumn);
    311 
    312     UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo(), debuggerMode);
     334    unsigned arrowContextFeature = isArrowFunctionContext ? ArrowFunctionContextFeature : 0;
     335    if (executable)
     336        executable->recordParse(rootNode->features() | arrowContextFeature, rootNode->hasCapturedVariables(), rootNode->lastLine(), endColumn);
     337
     338    bool usesEval = rootNode->features() & EvalFeature;
     339    bool isStrictMode = rootNode->features() & StrictModeFeature;
     340    ExecutableInfo executableInfo(usesEval, isStrictMode, false, false, ConstructorKind::None, scriptMode, SuperBinding::NotNeeded, CacheTypes<UnlinkedCodeBlockType>::parseMode, derivedContextType, isArrowFunctionContext, false, evalContextType);
     341
     342    UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executableInfo, debuggerMode);
    313343    unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), lineCount, unlinkedEndColumn);
    314344    unlinkedCodeBlock->setSourceURLDirective(source.provider()->sourceURL());
     
    323353}
    324354
    325 ALWAYS_INLINE static void writeCodeBlock(VM& vm, const SourceCodeKey& key, const SourceCodeValue& value)
     355template <class UnlinkedCodeBlockType, class ExecutableType>
     356UnlinkedCodeBlockType* generateUnlinkedCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
    326357{
    327 #if OS(DARWIN)
    328     const char* cachePath = Options::diskCachePath();
    329     if (LIKELY(!cachePath))
    330         return;
    331 
    332     UnlinkedCodeBlock* codeBlock = jsDynamicCast<UnlinkedCodeBlock*>(vm, value.cell.get());
    333     if (!codeBlock)
    334         return;
    335 
    336     unsigned hash = key.hash();
    337     char filename[512];
    338     int count = snprintf(filename, 512, "%s/%u.cache", cachePath, hash);
    339     if (count < 0 || count > 512)
    340         return;
    341 
    342     std::pair<MallocPtr<uint8_t>, size_t> result = encodeCodeBlock(vm, key, codeBlock);
    343 
    344     int fd = open(filename, O_CREAT | O_WRONLY, 0666);
    345     int rc = flock(fd, LOCK_EX | LOCK_NB);
    346     if (!rc)
    347         ::write(fd, result.first.get(), result.second);
    348     close(fd);
    349 #else
    350     UNUSED_PARAM(vm);
    351     UNUSED_PARAM(key);
    352     UNUSED_PARAM(value);
    353 #endif
     358    return generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType, ExecutableType>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, executable->derivedContextType(), executable->isArrowFunctionContext(), variablesUnderTDZ, executable);
    354359}
    355360
     361void generateUnlinkedCodeBlockForFunctions(VM&, UnlinkedCodeBlock*, const SourceCode&, DebuggerMode, ParserError&);
     362
     363template <class UnlinkedCodeBlockType>
     364std::enable_if_t<!std::is_same<UnlinkedCodeBlockType, UnlinkedEvalCodeBlock>::value, UnlinkedCodeBlockType*>
     365recursivelyGenerateUnlinkedCodeBlock(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
     366{
     367    bool isArrowFunctionContext = false;
     368    UnlinkedCodeBlockType* unlinkedCodeBlock = generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, DerivedContextType::None, isArrowFunctionContext, variablesUnderTDZ);
     369    if (!unlinkedCodeBlock)
     370        return nullptr;
     371
     372    generateUnlinkedCodeBlockForFunctions(vm, unlinkedCodeBlock, source, debuggerMode, error);
     373    return unlinkedCodeBlock;
     374}
     375
     376void writeCodeBlock(VM&, const SourceCodeKey&, const SourceCodeValue&);
     377CachedBytecode serializeBytecode(VM&, UnlinkedCodeBlock*, const SourceCode&, SourceCodeType, JSParserStrictMode, JSParserScriptMode, DebuggerMode);
    356378
    357379} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/Completion.cpp

    r239933 r240511  
    2626#include "CallFrame.h"
    2727#include "CatchScope.h"
     28#include "CodeCache.h"
    2829#include "CodeProfiling.h"
    2930#include "Exception.h"
     
    9192}
    9293
     94CachedBytecode generateBytecode(VM& vm, const SourceCode& source, ParserError& error)
     95{
     96    JSLockHolder lock(vm);
     97    RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
     98
     99    VariableEnvironment variablesUnderTDZ;
     100    JSParserStrictMode strictMode = JSParserStrictMode::NotStrict;
     101    JSParserScriptMode scriptMode = JSParserScriptMode::Classic;
     102    DebuggerMode debuggerMode = DebuggerOff;
     103    EvalContextType evalContextType = EvalContextType::None;
     104
     105    UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedProgramCodeBlock>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, &variablesUnderTDZ);
     106    return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, debuggerMode);
     107}
     108
     109CachedBytecode generateModuleBytecode(VM& vm, const SourceCode& source, ParserError& error)
     110{
     111    JSLockHolder lock(vm);
     112    RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
     113
     114    VariableEnvironment variablesUnderTDZ;
     115    JSParserStrictMode strictMode = JSParserStrictMode::Strict;
     116    JSParserScriptMode scriptMode = JSParserScriptMode::Module;
     117    DebuggerMode debuggerMode = DebuggerOff;
     118    EvalContextType evalContextType = EvalContextType::None;
     119
     120    UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, &variablesUnderTDZ);
     121    return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, debuggerMode);
     122}
     123
    93124JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException)
    94125{
  • trunk/Source/JavaScriptCore/runtime/Completion.h

    r239933 r240511  
    2929namespace JSC {
    3030
     31class CachedBytecode;
    3132class Exception;
    3233class ExecState;
     
    4142JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
    4243JS_EXPORT_PRIVATE bool checkModuleSyntax(ExecState*, const SourceCode&, ParserError&);
     44
     45JS_EXPORT_PRIVATE CachedBytecode generateBytecode(VM&, const SourceCode&, ParserError&);
     46JS_EXPORT_PRIVATE CachedBytecode generateModuleBytecode(VM&, const SourceCode&, ParserError&);
    4347
    4448JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue, NakedPtr<Exception>& returnedException);
  • trunk/Source/JavaScriptCore/runtime/Options.cpp

    r240255 r240511  
    528528    if (!Options::useCodeCache())
    529529        Options::diskCachePath() = nullptr;
    530 
    531     if (!Options::diskCachePath())
    532         Options::forceDiskCache() = false;
    533530}
    534531
Note: See TracChangeset for help on using the changeset viewer.