Changeset 243136 in webkit


Ignore:
Timestamp:
Mar 19, 2019 6:36:05 AM (5 years ago)
Author:
Caio Lima
Message:

[JSC] LLIntEntryPoint creates same DirectJITCode for all functions
https://bugs.webkit.org/show_bug.cgi?id=194648

Reviewed by Keith Miller.

JSTests:

  • microbenchmarks/generate-multiple-llint-entrypoints.js: Added.

Source/JavaScriptCore:

  1. Making LLIntThunks singleton.

Motivation: Former implementation has one LLIntThunk per type per VM.
However, the generated code for every kind of thunk is essentially the
same and we end up wasting memory (right now jitAllocationGranule = 32 bytes)
when we have 2 or more VM instantiated. Turn these thunks into
singleton will avoid such wasting.

Tradeoff: This change comes with a price, because we will keep thunks
allocated even when there is no VM instantiated. Considering WebCore use case,
the situation of having no VM instantiated is uncommon, since once a
VM is created through commomVM(), it will never be destroyed. Given
that, this change does not impact the overall memory comsumption of
WebCore/JSC. It also doesn't impact memory footprint, since thunks are
generated lazily (see results below).

Since we are keeping a static MacroAssemblerCodeRef<JITThunkPtrTag>,
we have the assurance that JITed code will never be deallocated,
given it is being pointed by RefPtr<ExecutableMemoryHandle> m_executableMemory.
To understand why we decided to make LLIntThunks singleton instead of
removing them, please see the comment on llint/LLIntThunks.cpp.

  1. Making all LLIntEntrypoints singleton

Motivation: With singleton LLIntThunks, we also can have singleton
DirectJITCodes and NativeJITCodes for each LLIntEntrypoint type and
avoid multiple allocations of objects with the same content.

Tradeoff: As explained before, once we allocate an entrypoint, it
will be alive until the program exits. However, the gains we can
achieve in some use cases justifies such allocations.

As DirectJITCode and NativeJITCode are ThreadSafeRefCounted and we are using
codeBlock->setJITCode(makeRef(*jitCode)), their reference counter
will never be less than 1.

  1. Memory usage analysis

This change reduces memory usage on stress/generate-multiple-llint-entrypoints.js
by 2% and is neutral on JetStream 2. Following results were generated
running each benchmark 6 times and using 95% Student's t distribution
confidence interval.

microbenchmarks/generate-multiple-llint-entrypoints.js (Changes uses less memory):

Mean of memory peak on ToT: 122576896 bytes (confidence interval: 67747.2316)
Mean of memory peak on Changes: 119248213.33 bytes (confidence interval: 50251.2718)

JetStream2 (Neutral):

Mean of memory peak on ToT: 5442742272 bytes (confidence interval: 134381565.9117)
Mean of memory peak on Changes: 5384949760 bytes (confidence interval: 158413904.8352)

  1. Performance Analysis

This change is performance neutral on JetStream 2 and Speedometer 2.
See results below.:

JetStream 2 (Neutral):

Mean of score on ToT: 139.58 (confidence interval: 2.44)
Mean of score on Changes: 141.46 (confidence interval: 4.24)

Speedometer run #1

ToT: 110 +- 2.9
Changes: 110 +- 1.8

Speedometer run #2

ToT: 110 +- 1.6
Changes: 108 +- 2.3

Speedometer run #3

ToT: 110 +- 3.0
Changes: 110 +- 1.4

  • jit/JSInterfaceJIT.h:

(JSC::JSInterfaceJIT::JSInterfaceJIT):

  • llint/LLIntEntrypoint.cpp:

Here we are changing the usage or DirectJITCode by NativeJITCode on cases
where there is no difference from address of calls with and without
ArithCheck.

(JSC::LLInt::setFunctionEntrypoint):
(JSC::LLInt::setEvalEntrypoint):
(JSC::LLInt::setProgramEntrypoint):
(JSC::LLInt::setModuleProgramEntrypoint):
(JSC::LLInt::setEntrypoint):

  • llint/LLIntEntrypoint.h:
  • llint/LLIntThunks.cpp:

(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::functionForCallEntryThunk):
(JSC::LLInt::functionForConstructEntryThunk):
(JSC::LLInt::functionForCallArityCheckThunk):
(JSC::LLInt::functionForConstructArityCheckThunk):
(JSC::LLInt::evalEntryThunk):
(JSC::LLInt::programEntryThunk):
(JSC::LLInt::moduleProgramEntryThunk):
(JSC::LLInt::functionForCallEntryThunkGenerator): Deleted.
(JSC::LLInt::functionForConstructEntryThunkGenerator): Deleted.
(JSC::LLInt::functionForCallArityCheckThunkGenerator): Deleted.
(JSC::LLInt::functionForConstructArityCheckThunkGenerator): Deleted.
(JSC::LLInt::evalEntryThunkGenerator): Deleted.
(JSC::LLInt::programEntryThunkGenerator): Deleted.
(JSC::LLInt::moduleProgramEntryThunkGenerator): Deleted.

  • llint/LLIntThunks.h:
  • runtime/ScriptExecutable.cpp:

(JSC::setupLLInt):
(JSC::ScriptExecutable::prepareForExecutionImpl):

Location:
trunk
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r243079 r243136  
     12019-03-19  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [JSC] LLIntEntryPoint creates same DirectJITCode for all functions
     4        https://bugs.webkit.org/show_bug.cgi?id=194648
     5
     6        Reviewed by Keith Miller.
     7
     8        * microbenchmarks/generate-multiple-llint-entrypoints.js: Added.
     9
    1102019-03-18  Mark Lam  <mark.lam@apple.com>
    211
  • trunk/Source/JavaScriptCore/ChangeLog

    r243128 r243136  
     12019-03-19  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [JSC] LLIntEntryPoint creates same DirectJITCode for all functions
     4        https://bugs.webkit.org/show_bug.cgi?id=194648
     5
     6        Reviewed by Keith Miller.
     7
     8        1. Making LLIntThunks singleton.
     9
     10        Motivation: Former implementation has one LLIntThunk per type per VM.
     11        However, the generated code for every kind of thunk is essentially the
     12        same and we end up wasting memory (right now jitAllocationGranule = 32 bytes)
     13        when we have 2 or more VM instantiated. Turn these thunks into
     14        singleton will avoid such wasting.
     15
     16        Tradeoff: This change comes with a price, because we will keep thunks
     17        allocated even when there is no VM instantiated. Considering WebCore use case,
     18        the situation of having no VM instantiated is uncommon, since once a
     19        VM is created through `commomVM()`, it will never be destroyed. Given
     20        that, this change does not impact the overall memory comsumption of
     21        WebCore/JSC. It also doesn't impact memory footprint, since thunks are
     22        generated lazily (see results below).
     23
     24        Since we are keeping a static `MacroAssemblerCodeRef<JITThunkPtrTag>`,
     25        we have the assurance that JITed code will never be deallocated,
     26        given it is being pointed by `RefPtr<ExecutableMemoryHandle> m_executableMemory`.
     27        To understand why we decided to make LLIntThunks singleton instead of
     28        removing them, please see the comment on `llint/LLIntThunks.cpp`.
     29
     30        2. Making all LLIntEntrypoints singleton
     31
     32        Motivation: With singleton LLIntThunks, we also can have singleton
     33        DirectJITCodes and NativeJITCodes for each LLIntEntrypoint type and
     34        avoid multiple allocations of objects with the same content.
     35
     36        Tradeoff: As explained before, once we allocate an entrypoint, it
     37        will be alive until the program exits. However, the gains we can
     38        achieve in some use cases justifies such allocations.
     39
     40        As DirectJITCode and NativeJITCode are ThreadSafeRefCounted and we are using
     41        `codeBlock->setJITCode(makeRef(*jitCode))`, their reference counter
     42        will never be less than 1.
     43
     44        3. Memory usage analysis
     45
     46        This change reduces memory usage on stress/generate-multiple-llint-entrypoints.js
     47        by 2% and is neutral on JetStream 2. Following results were generated
     48        running each benchmark 6 times and using 95% Student's t distribution
     49        confidence interval.
     50
     51        microbenchmarks/generate-multiple-llint-entrypoints.js (Changes uses less memory):
     52            Mean of memory peak on ToT: 122576896 bytes (confidence interval: 67747.2316)
     53            Mean of memory peak on Changes: 119248213.33 bytes (confidence interval: 50251.2718)
     54
     55        JetStream2 (Neutral):
     56            Mean of memory peak on ToT: 5442742272 bytes (confidence interval: 134381565.9117)
     57            Mean of memory peak on Changes: 5384949760 bytes (confidence interval: 158413904.8352)
     58
     59        4. Performance Analysis
     60
     61        This change is performance neutral on JetStream 2 and Speedometer 2.
     62        See results below.:
     63
     64        JetStream 2 (Neutral):
     65            Mean of score on ToT: 139.58 (confidence interval: 2.44)
     66            Mean of score on Changes: 141.46 (confidence interval: 4.24)
     67
     68        Speedometer run #1
     69           ToT: 110 +- 2.9
     70           Changes: 110 +- 1.8
     71
     72        Speedometer run #2
     73           ToT: 110 +- 1.6
     74           Changes: 108 +- 2.3
     75
     76        Speedometer run #3
     77           ToT: 110 +- 3.0
     78           Changes: 110 +- 1.4
     79
     80        * jit/JSInterfaceJIT.h:
     81        (JSC::JSInterfaceJIT::JSInterfaceJIT):
     82        * llint/LLIntEntrypoint.cpp:
     83
     84        Here we are changing the usage or DirectJITCode by NativeJITCode on cases
     85        where there is no difference from address of calls with and without
     86        ArithCheck.
     87
     88        (JSC::LLInt::setFunctionEntrypoint):
     89        (JSC::LLInt::setEvalEntrypoint):
     90        (JSC::LLInt::setProgramEntrypoint):
     91        (JSC::LLInt::setModuleProgramEntrypoint):
     92        (JSC::LLInt::setEntrypoint):
     93        * llint/LLIntEntrypoint.h:
     94        * llint/LLIntThunks.cpp:
     95        (JSC::LLInt::generateThunkWithJumpTo):
     96        (JSC::LLInt::functionForCallEntryThunk):
     97        (JSC::LLInt::functionForConstructEntryThunk):
     98        (JSC::LLInt::functionForCallArityCheckThunk):
     99        (JSC::LLInt::functionForConstructArityCheckThunk):
     100        (JSC::LLInt::evalEntryThunk):
     101        (JSC::LLInt::programEntryThunk):
     102        (JSC::LLInt::moduleProgramEntryThunk):
     103        (JSC::LLInt::functionForCallEntryThunkGenerator): Deleted.
     104        (JSC::LLInt::functionForConstructEntryThunkGenerator): Deleted.
     105        (JSC::LLInt::functionForCallArityCheckThunkGenerator): Deleted.
     106        (JSC::LLInt::functionForConstructArityCheckThunkGenerator): Deleted.
     107        (JSC::LLInt::evalEntryThunkGenerator): Deleted.
     108        (JSC::LLInt::programEntryThunkGenerator): Deleted.
     109        (JSC::LLInt::moduleProgramEntryThunkGenerator): Deleted.
     110        * llint/LLIntThunks.h:
     111        * runtime/ScriptExecutable.cpp:
     112        (JSC::setupLLInt):
     113        (JSC::ScriptExecutable::prepareForExecutionImpl):
     114
    11152019-03-18  Yusuke Suzuki  <ysuzuki@apple.com>
    2116
  • trunk/Source/JavaScriptCore/jit/JSInterfaceJIT.h

    r232105 r243136  
    3939    class JSInterfaceJIT : public CCallHelpers, public GPRInfo, public FPRInfo {
    4040    public:
    41         JSInterfaceJIT(VM* vm, CodeBlock* codeBlock = 0)
     41
     42        JSInterfaceJIT(VM* vm = nullptr, CodeBlock* codeBlock = nullptr)
    4243            : CCallHelpers(codeBlock)
    4344            , m_vm(vm)
  • trunk/Source/JavaScriptCore/llint/LLIntEntrypoint.cpp

    r242928 r243136  
    3939namespace JSC { namespace LLInt {
    4040
    41 static void setFunctionEntrypoint(VM& vm, CodeBlock* codeBlock)
     41static void setFunctionEntrypoint(CodeBlock* codeBlock)
    4242{
    4343    CodeSpecializationKind kind = codeBlock->specializationKind();
     
    4646    if (VM::canUseJIT()) {
    4747        if (kind == CodeForCall) {
    48             codeBlock->setJITCode(
    49                 adoptRef(*new DirectJITCode(vm.getCTIStub(functionForCallEntryThunkGenerator).retagged<JSEntryPtrTag>(), vm.getCTIStub(functionForCallArityCheckThunkGenerator).retaggedCode<JSEntryPtrTag>(), JITCode::InterpreterThunk)));
     48            static DirectJITCode* jitCode;
     49            static std::once_flag onceKey;
     50            std::call_once(onceKey, [&] {
     51                auto callRef = functionForCallEntryThunk().retagged<JSEntryPtrTag>();
     52                auto callArityCheckRef = functionForCallArityCheckThunk().retaggedCode<JSEntryPtrTag>();
     53                jitCode = new DirectJITCode(callRef, callArityCheckRef, JITCode::InterpreterThunk, JITCode::ShareAttribute::Shared);
     54            });
     55
     56            codeBlock->setJITCode(makeRef(*jitCode));
    5057            return;
    5158        }
    5259        ASSERT(kind == CodeForConstruct);
    53         codeBlock->setJITCode(
    54             adoptRef(*new DirectJITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator).retagged<JSEntryPtrTag>(), vm.getCTIStub(functionForConstructArityCheckThunkGenerator).retaggedCode<JSEntryPtrTag>(), JITCode::InterpreterThunk)));
     60
     61        static DirectJITCode* jitCode;
     62        static std::once_flag onceKey;
     63        std::call_once(onceKey, [&] {
     64            auto constructRef = functionForConstructEntryThunk().retagged<JSEntryPtrTag>();
     65            auto constructArityCheckRef = functionForConstructArityCheckThunk().retaggedCode<JSEntryPtrTag>();
     66            jitCode = new DirectJITCode(constructRef, constructArityCheckRef, JITCode::InterpreterThunk, JITCode::ShareAttribute::Shared);
     67        });
     68
     69        codeBlock->setJITCode(makeRef(*jitCode));
    5570        return;
    5671    }
    5772#endif // ENABLE(JIT)
    5873
    59     UNUSED_PARAM(vm);
    6074    if (kind == CodeForCall) {
    6175        static DirectJITCode* jitCode;
     
    7589}
    7690
    77 static void setEvalEntrypoint(VM& vm, CodeBlock* codeBlock)
     91static void setEvalEntrypoint(CodeBlock* codeBlock)
    7892{
    7993#if ENABLE(JIT)
    8094    if (VM::canUseJIT()) {
    81         MacroAssemblerCodeRef<JSEntryPtrTag> codeRef = vm.getCTIStub(evalEntryThunkGenerator).retagged<JSEntryPtrTag>();
    82         codeBlock->setJITCode(
    83             adoptRef(*new DirectJITCode(codeRef, codeRef.code(), JITCode::InterpreterThunk)));
     95        static NativeJITCode* jitCode;
     96        static std::once_flag onceKey;
     97        std::call_once(onceKey, [&] {
     98            MacroAssemblerCodeRef<JSEntryPtrTag> codeRef = evalEntryThunk().retagged<JSEntryPtrTag>();
     99            jitCode = new NativeJITCode(codeRef, JITCode::InterpreterThunk, Intrinsic::NoIntrinsic, JITCode::ShareAttribute::Shared);
     100        });
     101        codeBlock->setJITCode(makeRef(*jitCode));
    84102        return;
    85103    }
    86104#endif // ENABLE(JIT)
    87105
    88     UNUSED_PARAM(vm);
    89106    static NativeJITCode* jitCode;
    90107    static std::once_flag onceKey;
     
    95112}
    96113
    97 static void setProgramEntrypoint(VM& vm, CodeBlock* codeBlock)
     114static void setProgramEntrypoint(CodeBlock* codeBlock)
    98115{
    99116#if ENABLE(JIT)
    100117    if (VM::canUseJIT()) {
    101         MacroAssemblerCodeRef<JSEntryPtrTag> codeRef = vm.getCTIStub(programEntryThunkGenerator).retagged<JSEntryPtrTag>();
    102         codeBlock->setJITCode(
    103             adoptRef(*new DirectJITCode(codeRef, codeRef.code(), JITCode::InterpreterThunk)));
     118        static NativeJITCode* jitCode;
     119        static std::once_flag onceKey;
     120        std::call_once(onceKey, [&] {
     121            MacroAssemblerCodeRef<JSEntryPtrTag> codeRef = programEntryThunk().retagged<JSEntryPtrTag>();
     122            jitCode = new NativeJITCode(codeRef, JITCode::InterpreterThunk, Intrinsic::NoIntrinsic, JITCode::ShareAttribute::Shared);
     123        });
     124        codeBlock->setJITCode(makeRef(*jitCode));
    104125        return;
    105126    }
    106127#endif // ENABLE(JIT)
    107128
    108     UNUSED_PARAM(vm);
    109129    static NativeJITCode* jitCode;
    110130    static std::once_flag onceKey;
     
    115135}
    116136
    117 static void setModuleProgramEntrypoint(VM& vm, CodeBlock* codeBlock)
     137static void setModuleProgramEntrypoint(CodeBlock* codeBlock)
    118138{
    119139#if ENABLE(JIT)
    120140    if (VM::canUseJIT()) {
    121         MacroAssemblerCodeRef<JSEntryPtrTag> codeRef = vm.getCTIStub(moduleProgramEntryThunkGenerator).retagged<JSEntryPtrTag>();
    122         codeBlock->setJITCode(
    123             adoptRef(*new DirectJITCode(codeRef, codeRef.code(), JITCode::InterpreterThunk)));
     141        static NativeJITCode* jitCode;
     142        static std::once_flag onceKey;
     143        std::call_once(onceKey, [&] {
     144            MacroAssemblerCodeRef<JSEntryPtrTag> codeRef = moduleProgramEntryThunk().retagged<JSEntryPtrTag>();
     145            jitCode = new NativeJITCode(codeRef, JITCode::InterpreterThunk, Intrinsic::NoIntrinsic, JITCode::ShareAttribute::Shared);
     146        });
     147        codeBlock->setJITCode(makeRef(*jitCode));
    124148        return;
    125149    }
    126150#endif // ENABLE(JIT)
    127151
    128     UNUSED_PARAM(vm);
    129152    static NativeJITCode* jitCode;
    130153    static std::once_flag onceKey;
     
    135158}
    136159
    137 void setEntrypoint(VM& vm, CodeBlock* codeBlock)
     160void setEntrypoint(CodeBlock* codeBlock)
    138161{
    139162    switch (codeBlock->codeType()) {
    140163    case GlobalCode:
    141         setProgramEntrypoint(vm, codeBlock);
     164        setProgramEntrypoint(codeBlock);
    142165        return;
    143166    case ModuleCode:
    144         setModuleProgramEntrypoint(vm, codeBlock);
     167        setModuleProgramEntrypoint(codeBlock);
    145168        return;
    146169    case EvalCode:
    147         setEvalEntrypoint(vm, codeBlock);
     170        setEvalEntrypoint(codeBlock);
    148171        return;
    149172    case FunctionCode:
    150         setFunctionEntrypoint(vm, codeBlock);
     173        setFunctionEntrypoint(codeBlock);
    151174        return;
    152175    }
  • trunk/Source/JavaScriptCore/llint/LLIntEntrypoint.h

    r218794 r243136  
    3434namespace LLInt {
    3535
    36 void setEntrypoint(VM&, CodeBlock*);
     36void setEntrypoint(CodeBlock*);
    3737
    3838unsigned frameRegisterCountFor(CodeBlock*);
  • trunk/Source/JavaScriptCore/llint/LLIntThunks.cpp

    r236381 r243136  
    4040#include "StackAlignment.h"
    4141#include "VM.h"
     42#include <wtf/NeverDestroyed.h>
    4243
    4344namespace JSC {
     
    4748namespace LLInt {
    4849
    49 static MacroAssemblerCodeRef<JITThunkPtrTag> generateThunkWithJumpTo(VM* vm, OpcodeID opcodeID, const char *thunkKind)
     50// These thunks are necessary because of nearCall used on JITed code.
     51// It requires that the distance from nearCall address to the destination address
     52// fits on 32-bits, and that's not the case of getCodeRef(llint_function_for_call_prologue)
     53// and others LLIntEntrypoints.
     54
     55static MacroAssemblerCodeRef<JITThunkPtrTag> generateThunkWithJumpTo(OpcodeID opcodeID, const char *thunkKind)
    5056{
    51     JSInterfaceJIT jit(vm);
     57    JSInterfaceJIT jit;
    5258
    5359    // FIXME: there's probably a better way to do it on X86, but I'm not sure I care.
     
    6268}
    6369
    64 MacroAssemblerCodeRef<JITThunkPtrTag> functionForCallEntryThunkGenerator(VM* vm)
     70MacroAssemblerCodeRef<JITThunkPtrTag> functionForCallEntryThunk()
    6571{
    66     return generateThunkWithJumpTo(vm, llint_function_for_call_prologue, "function for call");
     72    static LazyNeverDestroyed<MacroAssemblerCodeRef<JITThunkPtrTag>> codeRef;
     73    static std::once_flag onceKey;
     74    std::call_once(onceKey, [&] {
     75        codeRef.construct(generateThunkWithJumpTo(llint_function_for_call_prologue, "function for call"));
     76    });
     77    return codeRef;
    6778}
    6879
    69 MacroAssemblerCodeRef<JITThunkPtrTag> functionForConstructEntryThunkGenerator(VM* vm)
     80MacroAssemblerCodeRef<JITThunkPtrTag> functionForConstructEntryThunk()
    7081{
    71     return generateThunkWithJumpTo(vm, llint_function_for_construct_prologue, "function for construct");
     82    static LazyNeverDestroyed<MacroAssemblerCodeRef<JITThunkPtrTag>> codeRef;
     83    static std::once_flag onceKey;
     84    std::call_once(onceKey, [&] {
     85        codeRef.construct(generateThunkWithJumpTo(llint_function_for_construct_prologue, "function for construct"));
     86    });
     87    return codeRef;
    7288}
    7389
    74 MacroAssemblerCodeRef<JITThunkPtrTag> functionForCallArityCheckThunkGenerator(VM* vm)
     90MacroAssemblerCodeRef<JITThunkPtrTag> functionForCallArityCheckThunk()
    7591{
    76     return generateThunkWithJumpTo(vm, llint_function_for_call_arity_check, "function for call with arity check");
     92    static LazyNeverDestroyed<MacroAssemblerCodeRef<JITThunkPtrTag>> codeRef;
     93    static std::once_flag onceKey;
     94    std::call_once(onceKey, [&] {
     95        codeRef.construct(generateThunkWithJumpTo(llint_function_for_call_arity_check, "function for call with arity check"));
     96    });
     97    return codeRef;
    7798}
    7899
    79 MacroAssemblerCodeRef<JITThunkPtrTag> functionForConstructArityCheckThunkGenerator(VM* vm)
     100MacroAssemblerCodeRef<JITThunkPtrTag> functionForConstructArityCheckThunk()
    80101{
    81     return generateThunkWithJumpTo(vm, llint_function_for_construct_arity_check, "function for construct with arity check");
     102    static LazyNeverDestroyed<MacroAssemblerCodeRef<JITThunkPtrTag>> codeRef;
     103    static std::once_flag onceKey;
     104    std::call_once(onceKey, [&] {
     105        codeRef.construct(generateThunkWithJumpTo(llint_function_for_construct_arity_check, "function for construct with arity check"));
     106    });
     107    return codeRef;
    82108}
    83109
    84 MacroAssemblerCodeRef<JITThunkPtrTag> evalEntryThunkGenerator(VM* vm)
     110MacroAssemblerCodeRef<JITThunkPtrTag> evalEntryThunk()
    85111{
    86     return generateThunkWithJumpTo(vm, llint_eval_prologue, "eval");
     112    static LazyNeverDestroyed<MacroAssemblerCodeRef<JITThunkPtrTag>> codeRef;
     113    static std::once_flag onceKey;
     114    std::call_once(onceKey, [&] {
     115        codeRef.construct(generateThunkWithJumpTo(llint_eval_prologue, "eval"));
     116    });
     117    return codeRef;
    87118}
    88119
    89 MacroAssemblerCodeRef<JITThunkPtrTag> programEntryThunkGenerator(VM* vm)
     120MacroAssemblerCodeRef<JITThunkPtrTag> programEntryThunk()
    90121{
    91     return generateThunkWithJumpTo(vm, llint_program_prologue, "program");
     122    static LazyNeverDestroyed<MacroAssemblerCodeRef<JITThunkPtrTag>> codeRef;
     123    static std::once_flag onceKey;
     124    std::call_once(onceKey, [&] {
     125        codeRef.construct(generateThunkWithJumpTo(llint_program_prologue, "program"));
     126    });
     127    return codeRef;
    92128}
    93129
    94 MacroAssemblerCodeRef<JITThunkPtrTag> moduleProgramEntryThunkGenerator(VM* vm)
     130MacroAssemblerCodeRef<JITThunkPtrTag> moduleProgramEntryThunk()
    95131{
    96     return generateThunkWithJumpTo(vm, llint_module_program_prologue, "module_program");
     132    static LazyNeverDestroyed<MacroAssemblerCodeRef<JITThunkPtrTag>> codeRef;
     133    static std::once_flag onceKey;
     134    std::call_once(onceKey, [&] {
     135        codeRef.construct(generateThunkWithJumpTo(llint_module_program_prologue, "module_program"));
     136    });
     137    return codeRef;
    97138}
    98139
  • trunk/Source/JavaScriptCore/llint/LLIntThunks.h

    r235785 r243136  
    4747namespace LLInt {
    4848
    49 MacroAssemblerCodeRef<JITThunkPtrTag> functionForCallEntryThunkGenerator(VM*);
    50 MacroAssemblerCodeRef<JITThunkPtrTag> functionForConstructEntryThunkGenerator(VM*);
    51 MacroAssemblerCodeRef<JITThunkPtrTag> functionForCallArityCheckThunkGenerator(VM*);
    52 MacroAssemblerCodeRef<JITThunkPtrTag> functionForConstructArityCheckThunkGenerator(VM*);
    53 MacroAssemblerCodeRef<JITThunkPtrTag> evalEntryThunkGenerator(VM*);
    54 MacroAssemblerCodeRef<JITThunkPtrTag> programEntryThunkGenerator(VM*);
    55 MacroAssemblerCodeRef<JITThunkPtrTag> moduleProgramEntryThunkGenerator(VM*);
     49MacroAssemblerCodeRef<JITThunkPtrTag> functionForCallEntryThunk();
     50MacroAssemblerCodeRef<JITThunkPtrTag> functionForConstructEntryThunk();
     51MacroAssemblerCodeRef<JITThunkPtrTag> functionForCallArityCheckThunk();
     52MacroAssemblerCodeRef<JITThunkPtrTag> functionForConstructArityCheckThunk();
     53MacroAssemblerCodeRef<JITThunkPtrTag> evalEntryThunk();
     54MacroAssemblerCodeRef<JITThunkPtrTag> programEntryThunk();
     55MacroAssemblerCodeRef<JITThunkPtrTag> moduleProgramEntryThunk();
    5656
    5757} } // namespace JSC::LLInt
  • trunk/Source/JavaScriptCore/runtime/ScriptExecutable.cpp

    r242596 r243136  
    386386}
    387387
    388 static void setupLLInt(VM& vm, CodeBlock* codeBlock)
    389 {
    390     LLInt::setEntrypoint(vm, codeBlock);
     388static void setupLLInt(CodeBlock* codeBlock)
     389{
     390    LLInt::setEntrypoint(codeBlock);
    391391}
    392392
     
    425425   
    426426    if (Options::useLLInt())
    427         setupLLInt(vm, codeBlock);
     427        setupLLInt(codeBlock);
    428428    else
    429429        setupJIT(vm, codeBlock);
Note: See TracChangeset for help on using the changeset viewer.