Changeset 241037 in webkit


Ignore:
Timestamp:
Feb 6, 2019 11:49:04 AM (5 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] NativeExecutable should be smaller
https://bugs.webkit.org/show_bug.cgi?id=194331

Reviewed by Michael Saboff.

NativeExecutable takes 88 bytes now. Since our GC rounds the size with 16, it actually takes 96 bytes in IsoSubspaces.
Since a lot of NativeExecutable are allocated, we already has two MarkedBlocks even just after JSGlobalObject initialization.
This patch makes sizeof(NativeExecutable) 64 bytes, which is 32 bytes smaller than 96 bytes. Now our JSGlobalObject initialization
only takes one MarkedBlock for NativeExecutable.

To make NativeExecutable smaller,

  1. m_numParametersForCall and m_numParametersForConstruct in ExecutableBase are only meaningful in ScriptExecutable subclasses. Since they are not touched from JIT, we can remove them from ExecutableBase and move them to ScriptExecutable.
  1. DOMJIT::Signature* is rarely used. Rather than having it in NativeExecutable, we should put it in NativeJITCode. Since NativeExecutable always has JITCode, we can safely query the value from NativeExecutable. This patch creates NativeDOMJITCode, which is a subclass of NativeJITCode, and instantiated only when DOMJIT::Signature* is given.
  1. Move Intrinsic to a member of ScriptExecutable or JITCode. Since JITCode has some paddings to put things, we can leverage this to put Intrinsic for NativeExecutable.

We also move "clearCode" code from ExecutableBase to ScriptExecutable since it is only valid for ScriptExecutable subclasses.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/CallVariant.h:
  • interpreter/Interpreter.cpp:
  • jit/JITCode.cpp:

(JSC::DirectJITCode::DirectJITCode):
(JSC::NativeJITCode::NativeJITCode):
(JSC::NativeDOMJITCode::NativeDOMJITCode):

  • jit/JITCode.h:

(JSC::JITCode::signature const):
(JSC::JITCode::intrinsic):

  • jit/JITOperations.cpp:
  • jit/JITThunks.cpp:

(JSC::JITThunks::hostFunctionStub):

  • jit/Repatch.cpp:
  • llint/LLIntSlowPaths.cpp:
  • runtime/ExecutableBase.cpp:

(JSC::ExecutableBase::dump const):
(JSC::ExecutableBase::hashFor const):
(JSC::ExecutableBase::hasClearableCode const): Deleted.
(JSC::ExecutableBase::clearCode): Deleted.

  • runtime/ExecutableBase.h:

(JSC::ExecutableBase::ExecutableBase):
(JSC::ExecutableBase::isModuleProgramExecutable):
(JSC::ExecutableBase::isHostFunction const):
(JSC::ExecutableBase::generatedJITCodeForCall const):
(JSC::ExecutableBase::generatedJITCodeForConstruct const):
(JSC::ExecutableBase::generatedJITCodeFor const):
(JSC::ExecutableBase::generatedJITCodeForCall): Deleted.
(JSC::ExecutableBase::generatedJITCodeForConstruct): Deleted.
(JSC::ExecutableBase::generatedJITCodeFor): Deleted.
(JSC::ExecutableBase::offsetOfNumParametersFor): Deleted.
(JSC::ExecutableBase::hasJITCodeForCall const): Deleted.
(JSC::ExecutableBase::hasJITCodeForConstruct const): Deleted.
(JSC::ExecutableBase::intrinsic const): Deleted.

  • runtime/ExecutableBaseInlines.h: Added.

(JSC::ExecutableBase::intrinsic const):
(JSC::ExecutableBase::hasJITCodeForCall const):
(JSC::ExecutableBase::hasJITCodeForConstruct const):

  • runtime/JSBoundFunction.cpp:
  • runtime/JSType.cpp:

(WTF::printInternal):

  • runtime/JSType.h:
  • runtime/NativeExecutable.cpp:

(JSC::NativeExecutable::create):
(JSC::NativeExecutable::createStructure):
(JSC::NativeExecutable::NativeExecutable):
(JSC::NativeExecutable::signatureFor const):
(JSC::NativeExecutable::intrinsic const):

  • runtime/NativeExecutable.h:
  • runtime/ScriptExecutable.cpp:

(JSC::ScriptExecutable::ScriptExecutable):
(JSC::ScriptExecutable::clearCode):
(JSC::ScriptExecutable::installCode):
(JSC::ScriptExecutable::hasClearableCode const):

  • runtime/ScriptExecutable.h:

(JSC::ScriptExecutable::intrinsic const):
(JSC::ScriptExecutable::hasJITCodeForCall const):
(JSC::ScriptExecutable::hasJITCodeForConstruct const):

  • runtime/VM.cpp:

(JSC::VM::getHostFunction):

Location:
trunk/Source/JavaScriptCore
Files:
1 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r240965 r241037  
    783783    runtime/ExceptionScope.h
    784784    runtime/ExecutableBase.h
     785    runtime/ExecutableBaseInlines.h
    785786    runtime/Float32Array.h
    786787    runtime/Float64Array.h
  • trunk/Source/JavaScriptCore/ChangeLog

    r241014 r241037  
     12019-02-06  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] NativeExecutable should be smaller
     4        https://bugs.webkit.org/show_bug.cgi?id=194331
     5
     6        Reviewed by Michael Saboff.
     7
     8        NativeExecutable takes 88 bytes now. Since our GC rounds the size with 16, it actually takes 96 bytes in IsoSubspaces.
     9        Since a lot of NativeExecutable are allocated, we already has two MarkedBlocks even just after JSGlobalObject initialization.
     10        This patch makes sizeof(NativeExecutable) 64 bytes, which is 32 bytes smaller than 96 bytes. Now our JSGlobalObject initialization
     11        only takes one MarkedBlock for NativeExecutable.
     12
     13        To make NativeExecutable smaller,
     14
     15        1. m_numParametersForCall and m_numParametersForConstruct in ExecutableBase are only meaningful in ScriptExecutable subclasses. Since
     16           they are not touched from JIT, we can remove them from ExecutableBase and move them to ScriptExecutable.
     17
     18        2. DOMJIT::Signature* is rarely used. Rather than having it in NativeExecutable, we should put it in NativeJITCode. Since NativeExecutable
     19           always has JITCode, we can safely query the value from NativeExecutable. This patch creates NativeDOMJITCode, which is a subclass of
     20           NativeJITCode, and instantiated only when DOMJIT::Signature* is given.
     21
     22        3. Move Intrinsic to a member of ScriptExecutable or JITCode. Since JITCode has some paddings to put things, we can leverage this to put
     23           Intrinsic for NativeExecutable.
     24
     25        We also move "clearCode" code from ExecutableBase to ScriptExecutable since it is only valid for ScriptExecutable subclasses.
     26
     27        * CMakeLists.txt:
     28        * JavaScriptCore.xcodeproj/project.pbxproj:
     29        * bytecode/CallVariant.h:
     30        * interpreter/Interpreter.cpp:
     31        * jit/JITCode.cpp:
     32        (JSC::DirectJITCode::DirectJITCode):
     33        (JSC::NativeJITCode::NativeJITCode):
     34        (JSC::NativeDOMJITCode::NativeDOMJITCode):
     35        * jit/JITCode.h:
     36        (JSC::JITCode::signature const):
     37        (JSC::JITCode::intrinsic):
     38        * jit/JITOperations.cpp:
     39        * jit/JITThunks.cpp:
     40        (JSC::JITThunks::hostFunctionStub):
     41        * jit/Repatch.cpp:
     42        * llint/LLIntSlowPaths.cpp:
     43        * runtime/ExecutableBase.cpp:
     44        (JSC::ExecutableBase::dump const):
     45        (JSC::ExecutableBase::hashFor const):
     46        (JSC::ExecutableBase::hasClearableCode const): Deleted.
     47        (JSC::ExecutableBase::clearCode): Deleted.
     48        * runtime/ExecutableBase.h:
     49        (JSC::ExecutableBase::ExecutableBase):
     50        (JSC::ExecutableBase::isModuleProgramExecutable):
     51        (JSC::ExecutableBase::isHostFunction const):
     52        (JSC::ExecutableBase::generatedJITCodeForCall const):
     53        (JSC::ExecutableBase::generatedJITCodeForConstruct const):
     54        (JSC::ExecutableBase::generatedJITCodeFor const):
     55        (JSC::ExecutableBase::generatedJITCodeForCall): Deleted.
     56        (JSC::ExecutableBase::generatedJITCodeForConstruct): Deleted.
     57        (JSC::ExecutableBase::generatedJITCodeFor): Deleted.
     58        (JSC::ExecutableBase::offsetOfNumParametersFor): Deleted.
     59        (JSC::ExecutableBase::hasJITCodeForCall const): Deleted.
     60        (JSC::ExecutableBase::hasJITCodeForConstruct const): Deleted.
     61        (JSC::ExecutableBase::intrinsic const): Deleted.
     62        * runtime/ExecutableBaseInlines.h: Added.
     63        (JSC::ExecutableBase::intrinsic const):
     64        (JSC::ExecutableBase::hasJITCodeForCall const):
     65        (JSC::ExecutableBase::hasJITCodeForConstruct const):
     66        * runtime/JSBoundFunction.cpp:
     67        * runtime/JSType.cpp:
     68        (WTF::printInternal):
     69        * runtime/JSType.h:
     70        * runtime/NativeExecutable.cpp:
     71        (JSC::NativeExecutable::create):
     72        (JSC::NativeExecutable::createStructure):
     73        (JSC::NativeExecutable::NativeExecutable):
     74        (JSC::NativeExecutable::signatureFor const):
     75        (JSC::NativeExecutable::intrinsic const):
     76        * runtime/NativeExecutable.h:
     77        * runtime/ScriptExecutable.cpp:
     78        (JSC::ScriptExecutable::ScriptExecutable):
     79        (JSC::ScriptExecutable::clearCode):
     80        (JSC::ScriptExecutable::installCode):
     81        (JSC::ScriptExecutable::hasClearableCode const):
     82        * runtime/ScriptExecutable.h:
     83        (JSC::ScriptExecutable::intrinsic const):
     84        (JSC::ScriptExecutable::hasJITCodeForCall const):
     85        (JSC::ScriptExecutable::hasJITCodeForConstruct const):
     86        * runtime/VM.cpp:
     87        (JSC::VM::getHostFunction):
     88
    1892019-02-06  Pablo Saavedra  <psaavedra@igalia.com>
    290
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r240994 r241037  
    17601760                E354622B1B6065D100545386 /* ConstructAbility.h in Headers */ = {isa = PBXBuildFile; fileRef = E354622A1B6065D100545386 /* ConstructAbility.h */; settings = {ATTRIBUTES = (Private, ); }; };
    17611761                E3555B8A1DAE03A500F36921 /* DOMJITCallDOMGetterSnippet.h in Headers */ = {isa = PBXBuildFile; fileRef = E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1762                E35A0B9D220AD87A00AC4474 /* ExecutableBaseInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
    17621763                E35CA1541DBC3A5C00F83516 /* DOMJITHeapRange.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA1521DBC3A5600F83516 /* DOMJITHeapRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
    17631764                E35CA1561DBC3A5F00F83516 /* DOMJITAbstractHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA1501DBC3A5600F83516 /* DOMJITAbstractHeap.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    46934694                E354622A1B6065D100545386 /* ConstructAbility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructAbility.h; sourceTree = "<group>"; };
    46944695                E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITCallDOMGetterSnippet.h; sourceTree = "<group>"; };
     4696                E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableBaseInlines.h; sourceTree = "<group>"; };
    46954697                E35CA14F1DBC3A5600F83516 /* DOMJITAbstractHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMJITAbstractHeap.cpp; sourceTree = "<group>"; };
    46964698                E35CA1501DBC3A5600F83516 /* DOMJITAbstractHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITAbstractHeap.h; sourceTree = "<group>"; };
     
    67356737                                147341E91DC2CF2500AA29BA /* ExecutableBase.cpp */,
    67366738                                147341CB1DC02D7200AA29BA /* ExecutableBase.h */,
     6739                                E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */,
    67376740                                A7A8AF2917ADB5F3005AB174 /* Float32Array.h */,
    67386741                                A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */,
     
    89518954                                A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
    89528955                                147341CC1DC02D7200AA29BA /* ExecutableBase.h in Headers */,
     8956                                E35A0B9D220AD87A00AC4474 /* ExecutableBaseInlines.h in Headers */,
    89538957                                14142E531B796EDD00F4BF4B /* ExecutableInfo.h in Headers */,
    89548958                                0F60FE901FFC37020003320A /* ExecutableToCodeBlockEdge.h in Headers */,
  • trunk/Source/JavaScriptCore/bytecode/CallVariant.h

    r234086 r241037  
    2626#pragma once
    2727
     28#include "ExecutableBaseInlines.h"
    2829#include "FunctionExecutable.h"
    2930#include "JSCast.h"
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r240864 r241037  
    3838#include "CodeCache.h"
    3939#include "DirectArguments.h"
     40#include "ExecutableBaseInlines.h"
    4041#include "Heap.h"
    4142#include "Debugger.h"
  • trunk/Source/JavaScriptCore/jit/JITCode.cpp

    r231741 r241037  
    160160}
    161161
     162DirectJITCode::DirectJITCode(JITCode::CodeRef<JSEntryPtrTag> ref, JITCode::CodePtr<JSEntryPtrTag> withArityCheck, JITType jitType, Intrinsic intrinsic)
     163    : JITCodeWithCodeRef(ref, jitType)
     164    , m_withArityCheck(withArityCheck)
     165{
     166    m_intrinsic = intrinsic;
     167    ASSERT(m_ref);
     168    ASSERT(m_withArityCheck);
     169}
     170
    162171DirectJITCode::~DirectJITCode()
    163172{
     
    192201}
    193202
    194 NativeJITCode::NativeJITCode(CodeRef<JSEntryPtrTag> ref, JITType jitType)
     203NativeJITCode::NativeJITCode(CodeRef<JSEntryPtrTag> ref, JITType jitType, Intrinsic intrinsic)
    195204    : JITCodeWithCodeRef(ref, jitType)
    196205{
     206    m_intrinsic = intrinsic;
    197207}
    198208
     
    220230}
    221231
     232NativeDOMJITCode::NativeDOMJITCode(CodeRef<JSEntryPtrTag> ref, JITType type, Intrinsic intrinsic, const DOMJIT::Signature* signature)
     233    : NativeJITCode(ref, type, intrinsic)
     234    , m_signature(signature)
     235{
     236}
     237
    222238#if ENABLE(JIT)
    223239RegisterSet JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite(CodeBlock*, CallSiteIndex)
  • trunk/Source/JavaScriptCore/jit/JITCode.h

    r239427 r241037  
    4444class JITCode;
    4545}
     46namespace DOMJIT {
     47class Signature;
     48}
    4649
    4750struct ProtoCallFrame;
     
    153156        return jitType == InterpreterThunk || jitType == BaselineJIT;
    154157    }
     158
     159    virtual const DOMJIT::Signature* signature() const { return nullptr; }
    155160   
    156161protected:
     
    199204#endif
    200205
     206    Intrinsic intrinsic() { return m_intrinsic; }
     207
    201208private:
    202209    JITType m_jitType;
     210protected:
     211    Intrinsic m_intrinsic { NoIntrinsic }; // Effective only in NativeExecutable.
    203212};
    204213
     
    225234    DirectJITCode(JITType);
    226235    DirectJITCode(CodeRef<JSEntryPtrTag>, CodePtr<JSEntryPtrTag> withArityCheck, JITType);
     236    DirectJITCode(CodeRef<JSEntryPtrTag>, CodePtr<JSEntryPtrTag> withArityCheck, JITType, Intrinsic); // For generated thunk.
    227237    virtual ~DirectJITCode();
    228238   
     
    238248public:
    239249    NativeJITCode(JITType);
    240     NativeJITCode(CodeRef<JSEntryPtrTag>, JITType);
     250    NativeJITCode(CodeRef<JSEntryPtrTag>, JITType, Intrinsic);
    241251    virtual ~NativeJITCode();
    242252   
     
    244254
    245255    CodePtr<JSEntryPtrTag> addressForCall(ArityCheckMode) override;
     256};
     257
     258class NativeDOMJITCode final : public NativeJITCode {
     259public:
     260    NativeDOMJITCode(CodeRef<JSEntryPtrTag>, JITType, Intrinsic, const DOMJIT::Signature*);
     261    virtual ~NativeDOMJITCode() = default;
     262
     263    const DOMJIT::Signature* signature() const override { return m_signature; }
     264
     265private:
     266    const DOMJIT::Signature* m_signature;
    246267};
    247268
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r240893 r241037  
    4343#include "EvalCodeBlock.h"
    4444#include "ExceptionFuzz.h"
     45#include "ExecutableBaseInlines.h"
    4546#include "FTLOSREntry.h"
    4647#include "FrameTracers.h"
  • trunk/Source/JavaScriptCore/jit/JITThunks.cpp

    r230748 r241037  
    125125    if (generator) {
    126126        MacroAssemblerCodeRef<JSEntryPtrTag> entry = generator(vm).retagged<JSEntryPtrTag>();
    127         forCall = adoptRef(new DirectJITCode(entry, entry.code(), JITCode::HostCallThunk));
    128     } else
    129         forCall = adoptRef(new NativeJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeCall(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk));
     127        forCall = adoptRef(new DirectJITCode(entry, entry.code(), JITCode::HostCallThunk, intrinsic));
     128    } else if (signature)
     129        forCall = adoptRef(new NativeDOMJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeCall(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk, intrinsic, signature));
     130    else
     131        forCall = adoptRef(new NativeJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeCall(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk, intrinsic));
    130132   
    131     Ref<JITCode> forConstruct = adoptRef(*new NativeJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeConstruct(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk));
     133    Ref<JITCode> forConstruct = adoptRef(*new NativeJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeConstruct(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk, NoIntrinsic));
    132134   
    133     NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, forCall.releaseNonNull(), function, WTFMove(forConstruct), constructor, intrinsic, signature, name);
     135    NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, forCall.releaseNonNull(), function, WTFMove(forConstruct), constructor, name);
    134136    weakAdd(*m_hostFunctionStubMap, std::make_tuple(function, constructor, name), Weak<NativeExecutable>(nativeExecutable, this));
    135137    return nativeExecutable;
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r240023 r241037  
    3636#include "DOMJITGetterSetter.h"
    3737#include "DirectArguments.h"
     38#include "ExecutableBaseInlines.h"
    3839#include "FTLThunks.h"
    3940#include "FullCodeOrigin.h"
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r240960 r241037  
    3535#include "Exception.h"
    3636#include "ExceptionFuzz.h"
     37#include "ExecutableBaseInlines.h"
    3738#include "FrameTracers.h"
    3839#include "FunctionCodeBlock.h"
  • trunk/Source/JavaScriptCore/runtime/ExecutableBase.cpp

    r233039 r241037  
    5050}
    5151
    52 bool ExecutableBase::hasClearableCode() const
    53 {
    54     VM& vm = *this->vm();
    55 
    56 #if ENABLE(JIT)
    57     if (m_jitCodeForCall
    58         || m_jitCodeForConstruct
    59         || m_jitCodeForCallWithArityCheck
    60         || m_jitCodeForConstructWithArityCheck)
    61         return true;
    62 #endif
    63 
    64     if (structure(vm)->classInfo() == FunctionExecutable::info()) {
    65         auto* executable = static_cast<const FunctionExecutable*>(this);
    66         if (executable->m_codeBlockForCall || executable->m_codeBlockForConstruct)
    67             return true;
    68 
    69     } else if (structure(vm)->classInfo() == EvalExecutable::info()) {
    70         auto* executable = static_cast<const EvalExecutable*>(this);
    71         if (executable->m_evalCodeBlock || executable->m_unlinkedEvalCodeBlock)
    72             return true;
    73 
    74     } else if (structure(vm)->classInfo() == ProgramExecutable::info()) {
    75         auto* executable = static_cast<const ProgramExecutable*>(this);
    76         if (executable->m_programCodeBlock || executable->m_unlinkedProgramCodeBlock)
    77             return true;
    78 
    79     } else if (structure(vm)->classInfo() == ModuleProgramExecutable::info()) {
    80         auto* executable = static_cast<const ModuleProgramExecutable*>(this);
    81         if (executable->m_moduleProgramCodeBlock
    82             || executable->m_unlinkedModuleProgramCodeBlock
    83             || executable->m_moduleEnvironmentSymbolTable)
    84             return true;
    85     }
    86     return false;
    87 }
    88 
    89 void ExecutableBase::clearCode()
    90 {
    91 #if ENABLE(JIT)
    92     m_jitCodeForCall = nullptr;
    93     m_jitCodeForConstruct = nullptr;
    94     m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>();
    95     m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>();
    96 #endif
    97     m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED;
    98     m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED;
    99     VM& vm = *this->vm();
    100 
    101 
    102     if (structure(vm)->classInfo() == FunctionExecutable::info()) {
    103         FunctionExecutable* executable = static_cast<FunctionExecutable*>(this);
    104         executable->m_codeBlockForCall.clear();
    105         executable->m_codeBlockForConstruct.clear();
    106         return;
    107     }
    108 
    109     if (structure(vm)->classInfo() == EvalExecutable::info()) {
    110         EvalExecutable* executable = static_cast<EvalExecutable*>(this);
    111         executable->m_evalCodeBlock.clear();
    112         executable->m_unlinkedEvalCodeBlock.clear();
    113         return;
    114     }
    115    
    116     if (structure(vm)->classInfo() == ProgramExecutable::info()) {
    117         ProgramExecutable* executable = static_cast<ProgramExecutable*>(this);
    118         executable->m_programCodeBlock.clear();
    119         executable->m_unlinkedProgramCodeBlock.clear();
    120         return;
    121     }
    122 
    123     if (structure(vm)->classInfo() == ModuleProgramExecutable::info()) {
    124         ModuleProgramExecutable* executable = static_cast<ModuleProgramExecutable*>(this);
    125         executable->m_moduleProgramCodeBlock.clear();
    126         executable->m_unlinkedModuleProgramCodeBlock.clear();
    127         executable->m_moduleEnvironmentSymbolTable.clear();
    128         return;
    129     }
    130    
    131     ASSERT(structure(vm)->classInfo() == NativeExecutable::info());
    132 }
    133 
    13452void ExecutableBase::dump(PrintStream& out) const
    13553{
    136     VM& vm = *this->vm();
    13754    ExecutableBase* realThis = const_cast<ExecutableBase*>(this);
    13855
    139     if (classInfo(vm) == NativeExecutable::info()) {
     56    switch (type()) {
     57    case NativeExecutableType: {
    14058        NativeExecutable* native = jsCast<NativeExecutable*>(realThis);
    14159        out.print("NativeExecutable:", RawPointer(bitwise_cast<void*>(native->function())), "/", RawPointer(bitwise_cast<void*>(native->constructor())));
    14260        return;
    14361    }
    144    
    145     if (classInfo(vm) == EvalExecutable::info()) {
     62    case EvalExecutableType: {
    14663        EvalExecutable* eval = jsCast<EvalExecutable*>(realThis);
    14764        if (CodeBlock* codeBlock = eval->codeBlock())
     
    15168        return;
    15269    }
    153    
    154     if (classInfo(vm) == ProgramExecutable::info()) {
     70    case ProgramExecutableType: {
    15571        ProgramExecutable* eval = jsCast<ProgramExecutable*>(realThis);
    15672        if (CodeBlock* codeBlock = eval->codeBlock())
     
    16076        return;
    16177    }
    162 
    163     if (classInfo(vm) == ModuleProgramExecutable::info()) {
     78    case ModuleProgramExecutableType: {
    16479        ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(realThis);
    16580        if (CodeBlock* codeBlock = executable->codeBlock())
     
    16984        return;
    17085    }
    171    
    172     FunctionExecutable* function = jsCast<FunctionExecutable*>(realThis);
    173     if (!function->eitherCodeBlock())
    174         out.print("FunctionExecutable w/o CodeBlock");
    175     else {
    176         CommaPrinter comma("/");
    177         if (function->codeBlockForCall())
    178             out.print(comma, *function->codeBlockForCall());
    179         if (function->codeBlockForConstruct())
    180             out.print(comma, *function->codeBlockForConstruct());
     86    case FunctionExecutableType: {
     87        FunctionExecutable* function = jsCast<FunctionExecutable*>(realThis);
     88        if (!function->eitherCodeBlock())
     89            out.print("FunctionExecutable w/o CodeBlock");
     90        else {
     91            CommaPrinter comma("/");
     92            if (function->codeBlockForCall())
     93                out.print(comma, *function->codeBlockForCall());
     94            if (function->codeBlockForConstruct())
     95                out.print(comma, *function->codeBlockForConstruct());
     96        }
     97        return;
     98    }
     99    default:
     100        RELEASE_ASSERT_NOT_REACHED();
    181101    }
    182102}
     
    184104CodeBlockHash ExecutableBase::hashFor(CodeSpecializationKind kind) const
    185105{
    186     if (this->classInfo(*this->vm()) == NativeExecutable::info())
     106    if (type() == NativeExecutableType)
    187107        return jsCast<const NativeExecutable*>(this)->hashFor(kind);
    188108   
  • trunk/Source/JavaScriptCore/runtime/ExecutableBase.h

    r240965 r241037  
    6161
    6262protected:
    63     static const int NUM_PARAMETERS_IS_HOST = 0;
    64     static const int NUM_PARAMETERS_NOT_COMPILED = -1;
    65 
    66     ExecutableBase(VM& vm, Structure* structure, int numParameters, Intrinsic intrinsic)
     63    ExecutableBase(VM& vm, Structure* structure)
    6764        : JSCell(vm, structure)
    68         , m_numParametersForCall(numParameters)
    69         , m_numParametersForConstruct(numParameters)
    70         , m_intrinsic(intrinsic)
    7165    {
    7266    }
     
    106100        return type() == ModuleProgramExecutableType;
    107101    }
    108 
    109 
    110102    bool isHostFunction() const
    111103    {
    112         ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
    113         return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
     104        return type() == NativeExecutableType;
    114105    }
    115106
    116107    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); }
    117108
    118     bool hasClearableCode() const;
    119     void clearCode();
    120 
    121109    DECLARE_EXPORT_INFO;
    122110
    123 protected:
    124     int m_numParametersForCall;
    125     int m_numParametersForConstruct;
    126 
    127111public:
    128     Ref<JITCode> generatedJITCodeForCall()
     112    Ref<JITCode> generatedJITCodeForCall() const
    129113    {
    130114        ASSERT(m_jitCodeForCall);
     
    132116    }
    133117
    134     Ref<JITCode> generatedJITCodeForConstruct()
     118    Ref<JITCode> generatedJITCodeForConstruct() const
    135119    {
    136120        ASSERT(m_jitCodeForConstruct);
     
    138122    }
    139123       
    140     Ref<JITCode> generatedJITCodeFor(CodeSpecializationKind kind)
     124    Ref<JITCode> generatedJITCodeFor(CodeSpecializationKind kind) const
    141125    {
    142126        if (kind == CodeForCall)
     
    191175    }
    192176   
    193     static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)
    194     {
    195         if (kind == CodeForCall)
    196             return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);
    197         ASSERT(kind == CodeForConstruct);
    198         return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
    199     }
    200 
    201     bool hasJITCodeForCall() const
    202     {
    203         return m_numParametersForCall >= 0;
    204     }
    205        
    206     bool hasJITCodeForConstruct() const
    207     {
    208         return m_numParametersForConstruct >= 0;
    209     }
    210        
     177    bool hasJITCodeForCall() const;
     178    bool hasJITCodeForConstruct() const;
     179
    211180    bool hasJITCodeFor(CodeSpecializationKind kind) const
    212181    {
     
    218187
    219188    // Intrinsics are only for calls, currently.
    220     Intrinsic intrinsic() const { return m_intrinsic; }
     189    Intrinsic intrinsic() const;
    221190       
    222191    Intrinsic intrinsicFor(CodeSpecializationKind kind) const
     
    234203    MacroAssemblerCodePtr<JSEntryPtrTag> m_jitCodeForCallWithArityCheck;
    235204    MacroAssemblerCodePtr<JSEntryPtrTag> m_jitCodeForConstructWithArityCheck;
    236     Intrinsic m_intrinsic;
    237205};
    238206
  • trunk/Source/JavaScriptCore/runtime/JSBoundFunction.cpp

    r236697 r241037  
    2727#include "JSBoundFunction.h"
    2828
     29#include "ExecutableBaseInlines.h"
    2930#include "GetterSetter.h"
    3031#include "JSGlobalObject.h"
  • trunk/Source/JavaScriptCore/runtime/JSType.cpp

    r240114 r241037  
    4747    CASE(CustomGetterSetterType)
    4848    CASE(APIValueWrapperType)
     49    CASE(NativeExecutableType)
    4950    CASE(ProgramExecutableType)
    5051    CASE(ModuleProgramExecutableType)
  • trunk/Source/JavaScriptCore/runtime/JSType.h

    r240114 r241037  
    3232    CustomGetterSetterType,
    3333    APIValueWrapperType,
     34
     35    NativeExecutableType,
    3436
    3537    ProgramExecutableType,
  • trunk/Source/JavaScriptCore/runtime/NativeExecutable.cpp

    r230748 r241037  
    4141const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(NativeExecutable) };
    4242
    43 NativeExecutable* NativeExecutable::create(VM& vm, Ref<JITCode>&& callThunk, TaggedNativeFunction function, Ref<JITCode>&& constructThunk, TaggedNativeFunction constructor, Intrinsic intrinsic, const DOMJIT::Signature* signature, const String& name)
     43NativeExecutable* NativeExecutable::create(VM& vm, Ref<JITCode>&& callThunk, TaggedNativeFunction function, Ref<JITCode>&& constructThunk, TaggedNativeFunction constructor, const String& name)
    4444{
    4545    NativeExecutable* executable;
    46     executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor, intrinsic, signature);
     46    executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
    4747    executable->finishCreation(vm, WTFMove(callThunk), WTFMove(constructThunk), name);
    4848    return executable;
     
    5656Structure* NativeExecutable::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
    5757{
    58     return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info());
     58    return Structure::create(vm, globalObject, proto, TypeInfo(NativeExecutableType, StructureFlags), info());
    5959}
    6060
     
    7474}
    7575
    76 NativeExecutable::NativeExecutable(VM& vm, TaggedNativeFunction function, TaggedNativeFunction constructor, Intrinsic intrinsic, const DOMJIT::Signature* signature)
    77     : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST, intrinsic)
     76NativeExecutable::NativeExecutable(VM& vm, TaggedNativeFunction function, TaggedNativeFunction constructor)
     77    : ExecutableBase(vm, vm.nativeExecutableStructure.get())
    7878    , m_function(function)
    7979    , m_constructor(constructor)
    80     , m_signature(signature)
    8180{
     81}
     82
     83const DOMJIT::Signature* NativeExecutable::signatureFor(CodeSpecializationKind kind) const
     84{
     85    ASSERT(hasJITCodeFor(kind));
     86    return generatedJITCodeFor(kind)->signature();
     87}
     88
     89Intrinsic NativeExecutable::intrinsic() const
     90{
     91    return generatedJITCodeFor(CodeForCall)->intrinsic();
    8292}
    8393
  • trunk/Source/JavaScriptCore/runtime/NativeExecutable.h

    r240965 r241037  
    3030
    3131namespace JSC {
    32 namespace DOMJIT {
    33 class Signature;
    34 }
    3532
    3633class NativeExecutable final : public ExecutableBase {
     
    4138    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
    4239
    43     static NativeExecutable* create(VM&, Ref<JITCode>&& callThunk, TaggedNativeFunction, Ref<JITCode>&& constructThunk, TaggedNativeFunction constructor, Intrinsic, const DOMJIT::Signature*, const String& name);
     40    static NativeExecutable* create(VM&, Ref<JITCode>&& callThunk, TaggedNativeFunction, Ref<JITCode>&& constructThunk, TaggedNativeFunction constructor, const String& name);
    4441
    4542    static void destroy(JSCell*);
     
    7774
    7875    const String& name() const { return m_name; }
    79     const DOMJIT::Signature* signature() const { return m_signature; }
    8076
    81     const DOMJIT::Signature* signatureFor(CodeSpecializationKind kind) const
    82     {
    83         if (isCall(kind))
    84             return signature();
    85         return nullptr;
    86     }
     77    const DOMJIT::Signature* signatureFor(CodeSpecializationKind) const;
     78    Intrinsic intrinsic() const;
    8779
    8880protected:
     
    9385    using PoisonedTaggedNativeFunction = Poisoned<NativeCodePoison, TaggedNativeFunction>;
    9486
    95     NativeExecutable(VM&, TaggedNativeFunction, TaggedNativeFunction constructor, Intrinsic, const DOMJIT::Signature*);
     87    NativeExecutable(VM&, TaggedNativeFunction, TaggedNativeFunction constructor);
    9688
    9789    PoisonedTaggedNativeFunction m_function;
    9890    PoisonedTaggedNativeFunction m_constructor;
    99     const DOMJIT::Signature* m_signature;
    10091
    10192    String m_name;
  • trunk/Source/JavaScriptCore/runtime/ScriptExecutable.cpp

    r240965 r241037  
    4747
    4848ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext, DerivedContextType derivedContextType, bool isInArrowFunctionContext, EvalContextType evalContextType, Intrinsic intrinsic)
    49     : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED, intrinsic)
     49    : ExecutableBase(vm, structure)
     50    , m_source(source)
     51    , m_intrinsic(intrinsic)
    5052    , m_features(isInStrictContext ? StrictModeFeature : 0)
    5153    , m_hasCapturedVariables(false)
     
    5759    , m_derivedContextType(static_cast<unsigned>(derivedContextType))
    5860    , m_evalContextType(static_cast<unsigned>(evalContextType))
    59     , m_source(source)
    6061{
    6162}
     
    6869void ScriptExecutable::clearCode(IsoCellSet& clearableCodeSet)
    6970{
    70     Base::clearCode();
     71#if ENABLE(JIT)
     72    m_jitCodeForCall = nullptr;
     73    m_jitCodeForConstruct = nullptr;
     74    m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>();
     75    m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>();
     76#endif
     77    m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED;
     78    m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED;
     79
     80    switch (type()) {
     81    case FunctionExecutableType: {
     82        FunctionExecutable* executable = static_cast<FunctionExecutable*>(this);
     83        executable->m_codeBlockForCall.clear();
     84        executable->m_codeBlockForConstruct.clear();
     85        break;
     86    }
     87    case EvalExecutableType: {
     88        EvalExecutable* executable = static_cast<EvalExecutable*>(this);
     89        executable->m_evalCodeBlock.clear();
     90        executable->m_unlinkedEvalCodeBlock.clear();
     91        break;
     92    }
     93    case ProgramExecutableType: {
     94        ProgramExecutable* executable = static_cast<ProgramExecutable*>(this);
     95        executable->m_programCodeBlock.clear();
     96        executable->m_unlinkedProgramCodeBlock.clear();
     97        break;
     98    }
     99    case ModuleProgramExecutableType: {
     100        ModuleProgramExecutable* executable = static_cast<ModuleProgramExecutable*>(this);
     101        executable->m_moduleProgramCodeBlock.clear();
     102        executable->m_unlinkedModuleProgramCodeBlock.clear();
     103        executable->m_moduleEnvironmentSymbolTable.clear();
     104        break;
     105    }
     106    default:
     107        RELEASE_ASSERT_NOT_REACHED();
     108        break;
     109    }
     110
    71111    ASSERT(&VM::SpaceAndSet::setFor(*subspace()) == &clearableCodeSet);
    72112    clearableCodeSet.remove(this);
     
    151191
    152192    auto& clearableCodeSet = VM::SpaceAndSet::setFor(*subspace());
    153     if (hasClearableCode())
     193    if (hasClearableCode(vm))
    154194        clearableCodeSet.add(this);
    155195    else
     
    175215
    176216    vm.heap.writeBarrier(this);
     217}
     218
     219bool ScriptExecutable::hasClearableCode(VM& vm) const
     220{
     221#if ENABLE(JIT)
     222    if (m_jitCodeForCall
     223        || m_jitCodeForConstruct
     224        || m_jitCodeForCallWithArityCheck
     225        || m_jitCodeForConstructWithArityCheck)
     226        return true;
     227#endif
     228
     229    if (structure(vm)->classInfo() == FunctionExecutable::info()) {
     230        auto* executable = static_cast<const FunctionExecutable*>(this);
     231        if (executable->m_codeBlockForCall || executable->m_codeBlockForConstruct)
     232            return true;
     233
     234    } else if (structure(vm)->classInfo() == EvalExecutable::info()) {
     235        auto* executable = static_cast<const EvalExecutable*>(this);
     236        if (executable->m_evalCodeBlock || executable->m_unlinkedEvalCodeBlock)
     237            return true;
     238
     239    } else if (structure(vm)->classInfo() == ProgramExecutable::info()) {
     240        auto* executable = static_cast<const ProgramExecutable*>(this);
     241        if (executable->m_programCodeBlock || executable->m_unlinkedProgramCodeBlock)
     242            return true;
     243
     244    } else if (structure(vm)->classInfo() == ModuleProgramExecutable::info()) {
     245        auto* executable = static_cast<const ModuleProgramExecutable*>(this);
     246        if (executable->m_moduleProgramCodeBlock
     247            || executable->m_unlinkedModuleProgramCodeBlock
     248            || executable->m_moduleEnvironmentSymbolTable)
     249            return true;
     250    }
     251    return false;
    177252}
    178253
  • trunk/Source/JavaScriptCore/runtime/ScriptExecutable.h

    r240938 r241037  
    9898    void clearCode(IsoCellSet&);
    9999
     100    Intrinsic intrinsic() const
     101    {
     102        return m_intrinsic;
     103    }
     104
     105    static constexpr int NUM_PARAMETERS_NOT_COMPILED = -1;
     106
     107    bool hasJITCodeForCall() const
     108    {
     109        return m_numParametersForCall >= 0;
     110    }
     111    bool hasJITCodeForConstruct() const
     112    {
     113        return m_numParametersForConstruct >= 0;
     114    }
     115
    100116    // This function has an interesting GC story. Callers of this function are asking us to create a CodeBlock
    101117    // that is not jettisoned before this function returns. Callers are essentially asking for a strong reference
     
    110126    friend class ExecutableBase;
    111127    JSObject* prepareForExecutionImpl(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&);
     128
     129    bool hasClearableCode(VM&) const;
    112130
    113131protected:
     
    124142    }
    125143
     144    SourceCode m_source;
     145
     146    int m_numParametersForCall { NUM_PARAMETERS_NOT_COMPILED };
     147    int m_numParametersForConstruct { NUM_PARAMETERS_NOT_COMPILED };
     148
     149    int m_lastLine { -1 };
     150    unsigned m_endColumn { UINT_MAX };
     151
     152    Intrinsic m_intrinsic { NoIntrinsic };
    126153    bool m_didTryToEnterInLoop { false };
    127154    CodeFeatures m_features;
     
    134161    unsigned m_derivedContextType : 2; // DerivedContextType
    135162    unsigned m_evalContextType : 2; // EvalContextType
    136 
    137     int m_lastLine { -1 };
    138     unsigned m_endColumn { UINT_MAX };
    139     SourceCode m_source;
    140163};
    141164
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r240965 r241037  
    700700#endif // ENABLE(JIT)
    701701    UNUSED_PARAM(intrinsic);
     702    UNUSED_PARAM(signature);
     703
    702704    return NativeExecutable::create(*this,
    703         adoptRef(*new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_call_trampoline), JITCode::HostCallThunk)), function,
    704         adoptRef(*new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_construct_trampoline), JITCode::HostCallThunk)), constructor,
    705         NoIntrinsic, signature, name);
     705        adoptRef(*new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_call_trampoline), JITCode::HostCallThunk, NoIntrinsic)), function,
     706        adoptRef(*new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_construct_trampoline), JITCode::HostCallThunk, NoIntrinsic)), constructor,
     707        name);
    706708}
    707709
Note: See TracChangeset for help on using the changeset viewer.