WebKit Bugzilla
Attachment 361283 Details for
Bug 194331
: [JSC] NativeExecutable should be smaller
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194331-20190206014725.patch (text/plain), 46.16 KB, created by
Yusuke Suzuki
on 2019-02-06 01:47:26 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2019-02-06 01:47:26 PST
Size:
46.16 KB
patch
obsolete
>Subversion Revision: 241010 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index fb8389d38d980e86d6792f3b8103ca902ad6f5e2..dbafa3d114e9180c274e3dd4df723964c970d564 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,91 @@ >+2019-02-06 Yusuke Suzuki <ysuzuki@apple.com> >+ >+ [JSC] NativeExecutable should be smaller >+ https://bugs.webkit.org/show_bug.cgi?id=194331 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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. >+ >+ 2. 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. >+ >+ 3. 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): >+ > 2019-02-05 Mark Lam <mark.lam@apple.com> > > Fix DFG's doesGC() for a few more nodes. >diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt >index be0c2140e9b73671f312b9e83568161543050db5..2cef93668bac8dff97e705100f86aa735ad5673e 100644 >--- a/Source/JavaScriptCore/CMakeLists.txt >+++ b/Source/JavaScriptCore/CMakeLists.txt >@@ -782,6 +782,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS > runtime/ExceptionHelpers.h > runtime/ExceptionScope.h > runtime/ExecutableBase.h >+ runtime/ExecutableBaseInlines.h > runtime/Float32Array.h > runtime/Float64Array.h > runtime/FunctionConstructor.h >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index 15563fe3c082e83a503c0bf9e6596c073785d37b..ecc17d352e8059da72a66ef9622ce3ac6766469c 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -1759,6 +1759,7 @@ > E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = E35070891DC49BB60089BCD6 /* DOMJITSignature.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E354622B1B6065D100545386 /* ConstructAbility.h in Headers */ = {isa = PBXBuildFile; fileRef = E354622A1B6065D100545386 /* ConstructAbility.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E3555B8A1DAE03A500F36921 /* DOMJITCallDOMGetterSnippet.h in Headers */ = {isa = PBXBuildFile; fileRef = E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ E35A0B9D220AD87A00AC4474 /* ExecutableBaseInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E35CA1541DBC3A5C00F83516 /* DOMJITHeapRange.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA1521DBC3A5600F83516 /* DOMJITHeapRange.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E35CA1561DBC3A5F00F83516 /* DOMJITAbstractHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA1501DBC3A5600F83516 /* DOMJITAbstractHeap.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E35E03601B7AB43E0073AD2A /* InspectorInstrumentationObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E35E035E1B7AB43E0073AD2A /* InspectorInstrumentationObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -4692,6 +4693,7 @@ > E35070891DC49BB60089BCD6 /* DOMJITSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITSignature.h; sourceTree = "<group>"; }; > E354622A1B6065D100545386 /* ConstructAbility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructAbility.h; sourceTree = "<group>"; }; > E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITCallDOMGetterSnippet.h; sourceTree = "<group>"; }; >+ E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableBaseInlines.h; sourceTree = "<group>"; }; > E35CA14F1DBC3A5600F83516 /* DOMJITAbstractHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMJITAbstractHeap.cpp; sourceTree = "<group>"; }; > E35CA1501DBC3A5600F83516 /* DOMJITAbstractHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITAbstractHeap.h; sourceTree = "<group>"; }; > E35CA1511DBC3A5600F83516 /* DOMJITHeapRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMJITHeapRange.cpp; sourceTree = "<group>"; }; >@@ -6734,6 +6736,7 @@ > FE6491361D78F01300A694D4 /* ExceptionScope.h */, > 147341E91DC2CF2500AA29BA /* ExecutableBase.cpp */, > 147341CB1DC02D7200AA29BA /* ExecutableBase.h */, >+ E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */, > A7A8AF2917ADB5F3005AB174 /* Float32Array.h */, > A7A8AF2A17ADB5F3005AB174 /* Float64Array.h */, > BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */, >@@ -8950,6 +8953,7 @@ > 0FF054FA1AC35B4400E5BE57 /* ExecutableAllocationFuzz.h in Headers */, > A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */, > 147341CC1DC02D7200AA29BA /* ExecutableBase.h in Headers */, >+ E35A0B9D220AD87A00AC4474 /* ExecutableBaseInlines.h in Headers */, > 14142E531B796EDD00F4BF4B /* ExecutableInfo.h in Headers */, > 0F60FE901FFC37020003320A /* ExecutableToCodeBlockEdge.h in Headers */, > 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */, >diff --git a/Source/JavaScriptCore/bytecode/CallVariant.h b/Source/JavaScriptCore/bytecode/CallVariant.h >index c0d06a58e50766d4aa581028b9f7046d11543e95..8cedae61202ad823d47a53481dbb691f5adbe9d7 100644 >--- a/Source/JavaScriptCore/bytecode/CallVariant.h >+++ b/Source/JavaScriptCore/bytecode/CallVariant.h >@@ -25,6 +25,7 @@ > > #pragma once > >+#include "ExecutableBaseInlines.h" > #include "FunctionExecutable.h" > #include "JSCast.h" > #include "JSFunction.h" >diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp >index 17f4a7fcc9eae1f0303bb5bf7110e672721160fe..06221fd69dbd6b60d43b9b80c1426e7694d73c4d 100644 >--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp >+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp >@@ -37,6 +37,7 @@ > #include "CodeBlock.h" > #include "CodeCache.h" > #include "DirectArguments.h" >+#include "ExecutableBaseInlines.h" > #include "Heap.h" > #include "Debugger.h" > #include "DebuggerCallFrame.h" >diff --git a/Source/JavaScriptCore/jit/JITCode.cpp b/Source/JavaScriptCore/jit/JITCode.cpp >index bc281802dc22d287f0a4d73370ee08236ccf327a..714ab23a4355adb12415e6bd7fa55eeec3855feb 100644 >--- a/Source/JavaScriptCore/jit/JITCode.cpp >+++ b/Source/JavaScriptCore/jit/JITCode.cpp >@@ -159,6 +159,15 @@ DirectJITCode::DirectJITCode(JITCode::CodeRef<JSEntryPtrTag> ref, JITCode::CodeP > ASSERT(m_withArityCheck); > } > >+DirectJITCode::DirectJITCode(JITCode::CodeRef<JSEntryPtrTag> ref, JITCode::CodePtr<JSEntryPtrTag> withArityCheck, JITType jitType, Intrinsic intrinsic) >+ : JITCodeWithCodeRef(ref, jitType) >+ , m_withArityCheck(withArityCheck) >+{ >+ m_intrinsic = intrinsic; >+ ASSERT(m_ref); >+ ASSERT(m_withArityCheck); >+} >+ > DirectJITCode::~DirectJITCode() > { > } >@@ -191,9 +200,10 @@ NativeJITCode::NativeJITCode(JITType jitType) > { > } > >-NativeJITCode::NativeJITCode(CodeRef<JSEntryPtrTag> ref, JITType jitType) >+NativeJITCode::NativeJITCode(CodeRef<JSEntryPtrTag> ref, JITType jitType, Intrinsic intrinsic) > : JITCodeWithCodeRef(ref, jitType) > { >+ m_intrinsic = intrinsic; > } > > NativeJITCode::~NativeJITCode() >@@ -219,6 +229,12 @@ JITCode::CodePtr<JSEntryPtrTag> NativeJITCode::addressForCall(ArityCheckMode ari > return CodePtr<JSEntryPtrTag>(); > } > >+NativeDOMJITCode::NativeDOMJITCode(CodeRef<JSEntryPtrTag> ref, JITType type, Intrinsic intrinsic, const DOMJIT::Signature* signature) >+ : NativeJITCode(ref, type, intrinsic) >+ , m_signature(signature) >+{ >+} >+ > #if ENABLE(JIT) > RegisterSet JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite(CodeBlock*, CallSiteIndex) > { >diff --git a/Source/JavaScriptCore/jit/JITCode.h b/Source/JavaScriptCore/jit/JITCode.h >index e70647ffb57d2fbcacd0813afc0d1a8ddbcf2878..8474b9a07624c6f00fdaec75fdcd5b43762b9ad5 100644 >--- a/Source/JavaScriptCore/jit/JITCode.h >+++ b/Source/JavaScriptCore/jit/JITCode.h >@@ -43,6 +43,9 @@ namespace FTL { > class ForOSREntryJITCode; > class JITCode; > } >+namespace DOMJIT { >+class Signature; >+} > > struct ProtoCallFrame; > class TrackedReferences; >@@ -152,6 +155,8 @@ class JITCode : public ThreadSafeRefCounted<JITCode> { > { > return jitType == InterpreterThunk || jitType == BaselineJIT; > } >+ >+ virtual const DOMJIT::Signature* signature() const { return nullptr; } > > protected: > JITCode(JITType); >@@ -198,8 +203,12 @@ class JITCode : public ThreadSafeRefCounted<JITCode> { > virtual Optional<CodeOrigin> findPC(CodeBlock*, void* pc) { UNUSED_PARAM(pc); return WTF::nullopt; } > #endif > >+ Intrinsic intrinsic() { return m_intrinsic; } >+ > private: > JITType m_jitType; >+protected: >+ Intrinsic m_intrinsic { NoIntrinsic }; // Effective only in NativeExecutable. > }; > > class JITCodeWithCodeRef : public JITCode { >@@ -224,6 +233,7 @@ class DirectJITCode : public JITCodeWithCodeRef { > public: > DirectJITCode(JITType); > DirectJITCode(CodeRef<JSEntryPtrTag>, CodePtr<JSEntryPtrTag> withArityCheck, JITType); >+ DirectJITCode(CodeRef<JSEntryPtrTag>, CodePtr<JSEntryPtrTag> withArityCheck, JITType, Intrinsic); // For generated thunk. > virtual ~DirectJITCode(); > > void initializeCodeRef(CodeRef<JSEntryPtrTag>, CodePtr<JSEntryPtrTag> withArityCheck); >@@ -237,7 +247,7 @@ class DirectJITCode : public JITCodeWithCodeRef { > class NativeJITCode : public JITCodeWithCodeRef { > public: > NativeJITCode(JITType); >- NativeJITCode(CodeRef<JSEntryPtrTag>, JITType); >+ NativeJITCode(CodeRef<JSEntryPtrTag>, JITType, Intrinsic); > virtual ~NativeJITCode(); > > void initializeCodeRef(CodeRef<JSEntryPtrTag>); >@@ -245,6 +255,17 @@ class NativeJITCode : public JITCodeWithCodeRef { > CodePtr<JSEntryPtrTag> addressForCall(ArityCheckMode) override; > }; > >+class NativeDOMJITCode final : public NativeJITCode { >+public: >+ NativeDOMJITCode(CodeRef<JSEntryPtrTag>, JITType, Intrinsic, const DOMJIT::Signature*); >+ virtual ~NativeDOMJITCode() = default; >+ >+ const DOMJIT::Signature* signature() const override { return m_signature; } >+ >+private: >+ const DOMJIT::Signature* m_signature; >+}; >+ > } // namespace JSC > > namespace WTF { >diff --git a/Source/JavaScriptCore/jit/JITOperations.cpp b/Source/JavaScriptCore/jit/JITOperations.cpp >index e8babd284e4cf83e7fc78a56e66e5334dd0338f6..a58e5d744eddfb1778f1d2277fadcfdfb1b89946 100644 >--- a/Source/JavaScriptCore/jit/JITOperations.cpp >+++ b/Source/JavaScriptCore/jit/JITOperations.cpp >@@ -42,6 +42,7 @@ > #include "ErrorHandlingScope.h" > #include "EvalCodeBlock.h" > #include "ExceptionFuzz.h" >+#include "ExecutableBaseInlines.h" > #include "FTLOSREntry.h" > #include "FrameTracers.h" > #include "FunctionCodeBlock.h" >diff --git a/Source/JavaScriptCore/jit/JITThunks.cpp b/Source/JavaScriptCore/jit/JITThunks.cpp >index 5f8c02b9f02400ed9e05a6a40f4ef685e46c776e..e1607c60a20f2741d31c0264a334dfe3db2c1158 100644 >--- a/Source/JavaScriptCore/jit/JITThunks.cpp >+++ b/Source/JavaScriptCore/jit/JITThunks.cpp >@@ -124,13 +124,15 @@ NativeExecutable* JITThunks::hostFunctionStub(VM* vm, TaggedNativeFunction funct > RefPtr<JITCode> forCall; > if (generator) { > MacroAssemblerCodeRef<JSEntryPtrTag> entry = generator(vm).retagged<JSEntryPtrTag>(); >- forCall = adoptRef(new DirectJITCode(entry, entry.code(), JITCode::HostCallThunk)); >- } else >- forCall = adoptRef(new NativeJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeCall(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk)); >+ forCall = adoptRef(new DirectJITCode(entry, entry.code(), JITCode::HostCallThunk, intrinsic)); >+ } else if (signature) >+ forCall = adoptRef(new NativeDOMJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeCall(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk, intrinsic, signature)); >+ else >+ forCall = adoptRef(new NativeJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeCall(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk, intrinsic)); > >- Ref<JITCode> forConstruct = adoptRef(*new NativeJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeConstruct(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk)); >+ Ref<JITCode> forConstruct = adoptRef(*new NativeJITCode(MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(ctiNativeConstruct(vm).retagged<JSEntryPtrTag>()), JITCode::HostCallThunk, NoIntrinsic)); > >- NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, forCall.releaseNonNull(), function, WTFMove(forConstruct), constructor, intrinsic, signature, name); >+ NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, forCall.releaseNonNull(), function, WTFMove(forConstruct), constructor, name); > weakAdd(*m_hostFunctionStubMap, std::make_tuple(function, constructor, name), Weak<NativeExecutable>(nativeExecutable, this)); > return nativeExecutable; > } >diff --git a/Source/JavaScriptCore/jit/Repatch.cpp b/Source/JavaScriptCore/jit/Repatch.cpp >index ad572c46b872c903900afcd8873d13d7221b8771..fba76da490395e1ba596782ceceff1d5cd9f5959 100644 >--- a/Source/JavaScriptCore/jit/Repatch.cpp >+++ b/Source/JavaScriptCore/jit/Repatch.cpp >@@ -35,6 +35,7 @@ > #include "DFGSpeculativeJIT.h" > #include "DOMJITGetterSetter.h" > #include "DirectArguments.h" >+#include "ExecutableBaseInlines.h" > #include "FTLThunks.h" > #include "FullCodeOrigin.h" > #include "FunctionCodeBlock.h" >diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >index 2b3c7cb1e314bf84b5ef88f9ae6d45b5acc49d88..a9a85507d21f37d23ff82c56016564a910e2fc35 100644 >--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp >@@ -34,6 +34,7 @@ > #include "EvalCodeBlock.h" > #include "Exception.h" > #include "ExceptionFuzz.h" >+#include "ExecutableBaseInlines.h" > #include "FrameTracers.h" > #include "FunctionCodeBlock.h" > #include "FunctionWhitelist.h" >diff --git a/Source/JavaScriptCore/runtime/ExecutableBase.cpp b/Source/JavaScriptCore/runtime/ExecutableBase.cpp >index df4313012dd8b7ff629cf06adca8b7968ad26f03..2989b1d0392152711158bf0a1e3058743f29eb49 100644 >--- a/Source/JavaScriptCore/runtime/ExecutableBase.cpp >+++ b/Source/JavaScriptCore/runtime/ExecutableBase.cpp >@@ -49,100 +49,17 @@ void ExecutableBase::destroy(JSCell* cell) > static_cast<ExecutableBase*>(cell)->ExecutableBase::~ExecutableBase(); > } > >-bool ExecutableBase::hasClearableCode() const >-{ >- VM& vm = *this->vm(); >- >-#if ENABLE(JIT) >- if (m_jitCodeForCall >- || m_jitCodeForConstruct >- || m_jitCodeForCallWithArityCheck >- || m_jitCodeForConstructWithArityCheck) >- return true; >-#endif >- >- if (structure(vm)->classInfo() == FunctionExecutable::info()) { >- auto* executable = static_cast<const FunctionExecutable*>(this); >- if (executable->m_codeBlockForCall || executable->m_codeBlockForConstruct) >- return true; >- >- } else if (structure(vm)->classInfo() == EvalExecutable::info()) { >- auto* executable = static_cast<const EvalExecutable*>(this); >- if (executable->m_evalCodeBlock || executable->m_unlinkedEvalCodeBlock) >- return true; >- >- } else if (structure(vm)->classInfo() == ProgramExecutable::info()) { >- auto* executable = static_cast<const ProgramExecutable*>(this); >- if (executable->m_programCodeBlock || executable->m_unlinkedProgramCodeBlock) >- return true; >- >- } else if (structure(vm)->classInfo() == ModuleProgramExecutable::info()) { >- auto* executable = static_cast<const ModuleProgramExecutable*>(this); >- if (executable->m_moduleProgramCodeBlock >- || executable->m_unlinkedModuleProgramCodeBlock >- || executable->m_moduleEnvironmentSymbolTable) >- return true; >- } >- return false; >-} >- >-void ExecutableBase::clearCode() >-{ >-#if ENABLE(JIT) >- m_jitCodeForCall = nullptr; >- m_jitCodeForConstruct = nullptr; >- m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>(); >- m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>(); >-#endif >- m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED; >- m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED; >- VM& vm = *this->vm(); >- >- >- if (structure(vm)->classInfo() == FunctionExecutable::info()) { >- FunctionExecutable* executable = static_cast<FunctionExecutable*>(this); >- executable->m_codeBlockForCall.clear(); >- executable->m_codeBlockForConstruct.clear(); >- return; >- } >- >- if (structure(vm)->classInfo() == EvalExecutable::info()) { >- EvalExecutable* executable = static_cast<EvalExecutable*>(this); >- executable->m_evalCodeBlock.clear(); >- executable->m_unlinkedEvalCodeBlock.clear(); >- return; >- } >- >- if (structure(vm)->classInfo() == ProgramExecutable::info()) { >- ProgramExecutable* executable = static_cast<ProgramExecutable*>(this); >- executable->m_programCodeBlock.clear(); >- executable->m_unlinkedProgramCodeBlock.clear(); >- return; >- } >- >- if (structure(vm)->classInfo() == ModuleProgramExecutable::info()) { >- ModuleProgramExecutable* executable = static_cast<ModuleProgramExecutable*>(this); >- executable->m_moduleProgramCodeBlock.clear(); >- executable->m_unlinkedModuleProgramCodeBlock.clear(); >- executable->m_moduleEnvironmentSymbolTable.clear(); >- return; >- } >- >- ASSERT(structure(vm)->classInfo() == NativeExecutable::info()); >-} >- > void ExecutableBase::dump(PrintStream& out) const > { >- VM& vm = *this->vm(); > ExecutableBase* realThis = const_cast<ExecutableBase*>(this); > >- if (classInfo(vm) == NativeExecutable::info()) { >+ switch (type()) { >+ case NativeExecutableType: { > NativeExecutable* native = jsCast<NativeExecutable*>(realThis); > out.print("NativeExecutable:", RawPointer(bitwise_cast<void*>(native->function())), "/", RawPointer(bitwise_cast<void*>(native->constructor()))); > return; > } >- >- if (classInfo(vm) == EvalExecutable::info()) { >+ case EvalExecutableType: { > EvalExecutable* eval = jsCast<EvalExecutable*>(realThis); > if (CodeBlock* codeBlock = eval->codeBlock()) > out.print(*codeBlock); >@@ -150,8 +67,7 @@ void ExecutableBase::dump(PrintStream& out) const > out.print("EvalExecutable w/o CodeBlock"); > return; > } >- >- if (classInfo(vm) == ProgramExecutable::info()) { >+ case ProgramExecutableType: { > ProgramExecutable* eval = jsCast<ProgramExecutable*>(realThis); > if (CodeBlock* codeBlock = eval->codeBlock()) > out.print(*codeBlock); >@@ -159,8 +75,7 @@ void ExecutableBase::dump(PrintStream& out) const > out.print("ProgramExecutable w/o CodeBlock"); > return; > } >- >- if (classInfo(vm) == ModuleProgramExecutable::info()) { >+ case ModuleProgramExecutableType: { > ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(realThis); > if (CodeBlock* codeBlock = executable->codeBlock()) > out.print(*codeBlock); >@@ -168,22 +83,27 @@ void ExecutableBase::dump(PrintStream& out) const > out.print("ModuleProgramExecutable w/o CodeBlock"); > return; > } >- >- FunctionExecutable* function = jsCast<FunctionExecutable*>(realThis); >- if (!function->eitherCodeBlock()) >- out.print("FunctionExecutable w/o CodeBlock"); >- else { >- CommaPrinter comma("/"); >- if (function->codeBlockForCall()) >- out.print(comma, *function->codeBlockForCall()); >- if (function->codeBlockForConstruct()) >- out.print(comma, *function->codeBlockForConstruct()); >+ case FunctionExecutableType: { >+ FunctionExecutable* function = jsCast<FunctionExecutable*>(realThis); >+ if (!function->eitherCodeBlock()) >+ out.print("FunctionExecutable w/o CodeBlock"); >+ else { >+ CommaPrinter comma("/"); >+ if (function->codeBlockForCall()) >+ out.print(comma, *function->codeBlockForCall()); >+ if (function->codeBlockForConstruct()) >+ out.print(comma, *function->codeBlockForConstruct()); >+ } >+ return; >+ } >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); > } > } > > CodeBlockHash ExecutableBase::hashFor(CodeSpecializationKind kind) const > { >- if (this->classInfo(*this->vm()) == NativeExecutable::info()) >+ if (type() == NativeExecutableType) > return jsCast<const NativeExecutable*>(this)->hashFor(kind); > > return jsCast<const ScriptExecutable*>(this)->hashFor(kind); >diff --git a/Source/JavaScriptCore/runtime/ExecutableBase.h b/Source/JavaScriptCore/runtime/ExecutableBase.h >index 4ba9896070935cd4e4378b5ff336eafad0582da7..339e2d48ef60651610298e7ede9553799457dea6 100644 >--- a/Source/JavaScriptCore/runtime/ExecutableBase.h >+++ b/Source/JavaScriptCore/runtime/ExecutableBase.h >@@ -60,14 +60,8 @@ class ExecutableBase : public JSCell { > friend MacroAssemblerCodeRef<JITThunkPtrTag> boundThisNoArgsFunctionCallGenerator(VM*); > > protected: >- static const int NUM_PARAMETERS_IS_HOST = 0; >- static const int NUM_PARAMETERS_NOT_COMPILED = -1; >- >- ExecutableBase(VM& vm, Structure* structure, int numParameters, Intrinsic intrinsic) >+ ExecutableBase(VM& vm, Structure* structure) > : JSCell(vm, structure) >- , m_numParametersForCall(numParameters) >- , m_numParametersForConstruct(numParameters) >- , m_intrinsic(intrinsic) > { > } > >@@ -105,39 +99,29 @@ class ExecutableBase : public JSCell { > { > return type() == ModuleProgramExecutableType; > } >- >- > bool isHostFunction() const > { >- ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST)); >- return m_numParametersForCall == NUM_PARAMETERS_IS_HOST; >+ return type() == NativeExecutableType; > } > > static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); } > >- bool hasClearableCode() const; >- void clearCode(); >- > DECLARE_EXPORT_INFO; > >-protected: >- int m_numParametersForCall; >- int m_numParametersForConstruct; >- > public: >- Ref<JITCode> generatedJITCodeForCall() >+ Ref<JITCode> generatedJITCodeForCall() const > { > ASSERT(m_jitCodeForCall); > return *m_jitCodeForCall; > } > >- Ref<JITCode> generatedJITCodeForConstruct() >+ Ref<JITCode> generatedJITCodeForConstruct() const > { > ASSERT(m_jitCodeForConstruct); > return *m_jitCodeForConstruct; > } > >- Ref<JITCode> generatedJITCodeFor(CodeSpecializationKind kind) >+ Ref<JITCode> generatedJITCodeFor(CodeSpecializationKind kind) const > { > if (kind == CodeForCall) > return generatedJITCodeForCall(); >@@ -190,24 +174,9 @@ class ExecutableBase : public JSCell { > return 0; > } > >- static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind) >- { >- if (kind == CodeForCall) >- return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall); >- ASSERT(kind == CodeForConstruct); >- return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct); >- } >+ bool hasJITCodeForCall() const; >+ bool hasJITCodeForConstruct() const; > >- bool hasJITCodeForCall() const >- { >- return m_numParametersForCall >= 0; >- } >- >- bool hasJITCodeForConstruct() const >- { >- return m_numParametersForConstruct >= 0; >- } >- > bool hasJITCodeFor(CodeSpecializationKind kind) const > { > if (kind == CodeForCall) >@@ -217,7 +186,7 @@ class ExecutableBase : public JSCell { > } > > // Intrinsics are only for calls, currently. >- Intrinsic intrinsic() const { return m_intrinsic; } >+ Intrinsic intrinsic() const; > > Intrinsic intrinsicFor(CodeSpecializationKind kind) const > { >@@ -233,7 +202,6 @@ class ExecutableBase : public JSCell { > RefPtr<JITCode> m_jitCodeForConstruct; > MacroAssemblerCodePtr<JSEntryPtrTag> m_jitCodeForCallWithArityCheck; > MacroAssemblerCodePtr<JSEntryPtrTag> m_jitCodeForConstructWithArityCheck; >- Intrinsic m_intrinsic; > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/ExecutableBaseInlines.h b/Source/JavaScriptCore/runtime/ExecutableBaseInlines.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e9de48a8c8193c34885cde95ec870d902329c52c >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/ExecutableBaseInlines.h >@@ -0,0 +1,55 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "ExecutableBase.h" >+#include "NativeExecutable.h" >+#include "ScriptExecutable.h" >+ >+namespace JSC { >+ >+inline Intrinsic ExecutableBase::intrinsic() const >+{ >+ if (isHostFunction()) >+ return jsCast<const NativeExecutable*>(this)->intrinsic(); >+ return jsCast<const ScriptExecutable*>(this)->intrinsic(); >+} >+ >+inline bool ExecutableBase::hasJITCodeForCall() const >+{ >+ if (isHostFunction()) >+ return true; >+ return jsCast<const ScriptExecutable*>(this)->hasJITCodeForCall(); >+} >+ >+inline bool ExecutableBase::hasJITCodeForConstruct() const >+{ >+ if (isHostFunction()) >+ return true; >+ return jsCast<const ScriptExecutable*>(this)->hasJITCodeForConstruct(); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp >index ff49eafb90f7053ea471726edc476ee6fe511032..29d727e9527646a9127e2bb5ac573e5be39d4c0e 100644 >--- a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp >+++ b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp >@@ -26,6 +26,7 @@ > #include "config.h" > #include "JSBoundFunction.h" > >+#include "ExecutableBaseInlines.h" > #include "GetterSetter.h" > #include "JSGlobalObject.h" > #include "JSCInlines.h" >diff --git a/Source/JavaScriptCore/runtime/JSType.cpp b/Source/JavaScriptCore/runtime/JSType.cpp >index 054df78d8f2b20efccce0eca77dffeb8627cf5ce..780dabd4ae35b30083873229641c02d27fc58950 100644 >--- a/Source/JavaScriptCore/runtime/JSType.cpp >+++ b/Source/JavaScriptCore/runtime/JSType.cpp >@@ -46,6 +46,7 @@ void printInternal(PrintStream& out, JSC::JSType type) > CASE(BigIntType) > CASE(CustomGetterSetterType) > CASE(APIValueWrapperType) >+ CASE(NativeExecutableType) > CASE(ProgramExecutableType) > CASE(ModuleProgramExecutableType) > CASE(EvalExecutableType) >diff --git a/Source/JavaScriptCore/runtime/JSType.h b/Source/JavaScriptCore/runtime/JSType.h >index 38aaf51a07abdcaa0eb527a6ad46f8b56996a210..c62ec6de486bda420b4a7ec364b331793a65fadd 100644 >--- a/Source/JavaScriptCore/runtime/JSType.h >+++ b/Source/JavaScriptCore/runtime/JSType.h >@@ -32,6 +32,8 @@ enum JSType : uint8_t { > CustomGetterSetterType, > APIValueWrapperType, > >+ NativeExecutableType, >+ > ProgramExecutableType, > ModuleProgramExecutableType, > EvalExecutableType, >diff --git a/Source/JavaScriptCore/runtime/NativeExecutable.cpp b/Source/JavaScriptCore/runtime/NativeExecutable.cpp >index 51cfcc8f3799945339f187bae80f8a3e05520378..63dd2ec380fcf913999e857184061bc6c073890a 100644 >--- a/Source/JavaScriptCore/runtime/NativeExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/NativeExecutable.cpp >@@ -40,10 +40,10 @@ namespace JSC { > > const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(NativeExecutable) }; > >-NativeExecutable* NativeExecutable::create(VM& vm, Ref<JITCode>&& callThunk, TaggedNativeFunction function, Ref<JITCode>&& constructThunk, TaggedNativeFunction constructor, Intrinsic intrinsic, const DOMJIT::Signature* signature, const String& name) >+NativeExecutable* NativeExecutable::create(VM& vm, Ref<JITCode>&& callThunk, TaggedNativeFunction function, Ref<JITCode>&& constructThunk, TaggedNativeFunction constructor, const String& name) > { > NativeExecutable* executable; >- executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor, intrinsic, signature); >+ executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor); > executable->finishCreation(vm, WTFMove(callThunk), WTFMove(constructThunk), name); > return executable; > } >@@ -55,7 +55,7 @@ void NativeExecutable::destroy(JSCell* cell) > > Structure* NativeExecutable::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) > { >- return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); >+ return Structure::create(vm, globalObject, proto, TypeInfo(NativeExecutableType, StructureFlags), info()); > } > > void NativeExecutable::finishCreation(VM& vm, Ref<JITCode>&& callThunk, Ref<JITCode>&& constructThunk, const String& name) >@@ -73,14 +73,24 @@ void NativeExecutable::finishCreation(VM& vm, Ref<JITCode>&& callThunk, Ref<JITC > assertIsTaggedWith(m_jitCodeForConstructWithArityCheck.executableAddress(), JSEntryPtrTag); > } > >-NativeExecutable::NativeExecutable(VM& vm, TaggedNativeFunction function, TaggedNativeFunction constructor, Intrinsic intrinsic, const DOMJIT::Signature* signature) >- : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST, intrinsic) >+NativeExecutable::NativeExecutable(VM& vm, TaggedNativeFunction function, TaggedNativeFunction constructor) >+ : ExecutableBase(vm, vm.nativeExecutableStructure.get()) > , m_function(function) > , m_constructor(constructor) >- , m_signature(signature) > { > } > >+const DOMJIT::Signature* NativeExecutable::signatureFor(CodeSpecializationKind kind) const >+{ >+ ASSERT(hasJITCodeFor(kind)); >+ return generatedJITCodeFor(kind)->signature(); >+} >+ >+Intrinsic NativeExecutable::intrinsic() const >+{ >+ return generatedJITCodeFor(CodeForCall)->intrinsic(); >+} >+ > CodeBlockHash NativeExecutable::hashFor(CodeSpecializationKind kind) const > { > if (kind == CodeForCall) >diff --git a/Source/JavaScriptCore/runtime/NativeExecutable.h b/Source/JavaScriptCore/runtime/NativeExecutable.h >index 91fb35ba0ea3c438a2400c24a458e9bbfb99cb44..b9ab65af0fe28f20b6f6d44f4113cac3ab6c5363 100644 >--- a/Source/JavaScriptCore/runtime/NativeExecutable.h >+++ b/Source/JavaScriptCore/runtime/NativeExecutable.h >@@ -29,9 +29,6 @@ > #include "JSCPoison.h" > > namespace JSC { >-namespace DOMJIT { >-class Signature; >-} > > class NativeExecutable final : public ExecutableBase { > friend class JIT; >@@ -40,7 +37,7 @@ class NativeExecutable final : public ExecutableBase { > typedef ExecutableBase Base; > static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; > >- static NativeExecutable* create(VM&, Ref<JITCode>&& callThunk, TaggedNativeFunction, Ref<JITCode>&& constructThunk, TaggedNativeFunction constructor, Intrinsic, const DOMJIT::Signature*, const String& name); >+ static NativeExecutable* create(VM&, Ref<JITCode>&& callThunk, TaggedNativeFunction, Ref<JITCode>&& constructThunk, TaggedNativeFunction constructor, const String& name); > > static void destroy(JSCell*); > >@@ -76,14 +73,9 @@ class NativeExecutable final : public ExecutableBase { > DECLARE_INFO; > > const String& name() const { return m_name; } >- const DOMJIT::Signature* signature() const { return m_signature; } > >- const DOMJIT::Signature* signatureFor(CodeSpecializationKind kind) const >- { >- if (isCall(kind)) >- return signature(); >- return nullptr; >- } >+ const DOMJIT::Signature* signatureFor(CodeSpecializationKind) const; >+ Intrinsic intrinsic() const; > > protected: > void finishCreation(VM&, Ref<JITCode>&& callThunk, Ref<JITCode>&& constructThunk, const String& name); >@@ -92,11 +84,10 @@ class NativeExecutable final : public ExecutableBase { > friend class ExecutableBase; > using PoisonedTaggedNativeFunction = Poisoned<NativeCodePoison, TaggedNativeFunction>; > >- NativeExecutable(VM&, TaggedNativeFunction, TaggedNativeFunction constructor, Intrinsic, const DOMJIT::Signature*); >+ NativeExecutable(VM&, TaggedNativeFunction, TaggedNativeFunction constructor); > > PoisonedTaggedNativeFunction m_function; > PoisonedTaggedNativeFunction m_constructor; >- const DOMJIT::Signature* m_signature; > > String m_name; > }; >diff --git a/Source/JavaScriptCore/runtime/ScriptExecutable.cpp b/Source/JavaScriptCore/runtime/ScriptExecutable.cpp >index 3251a7908f681ef1d2aadef3ef8d9e7255d9b339..b882b98afb0548d7bc29e4beb5964fa01a8084ea 100644 >--- a/Source/JavaScriptCore/runtime/ScriptExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/ScriptExecutable.cpp >@@ -46,7 +46,9 @@ namespace JSC { > const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ScriptExecutable) }; > > ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext, DerivedContextType derivedContextType, bool isInArrowFunctionContext, EvalContextType evalContextType, Intrinsic intrinsic) >- : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED, intrinsic) >+ : ExecutableBase(vm, structure) >+ , m_source(source) >+ , m_intrinsic(intrinsic) > , m_features(isInStrictContext ? StrictModeFeature : 0) > , m_hasCapturedVariables(false) > , m_neverInline(false) >@@ -56,7 +58,6 @@ ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCod > , m_canUseOSRExitFuzzing(true) > , m_derivedContextType(static_cast<unsigned>(derivedContextType)) > , m_evalContextType(static_cast<unsigned>(evalContextType)) >- , m_source(source) > { > } > >@@ -67,7 +68,46 @@ void ScriptExecutable::destroy(JSCell* cell) > > void ScriptExecutable::clearCode(IsoCellSet& clearableCodeSet) > { >- Base::clearCode(); >+#if ENABLE(JIT) >+ m_jitCodeForCall = nullptr; >+ m_jitCodeForConstruct = nullptr; >+ m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>(); >+ m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>(); >+#endif >+ m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED; >+ m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED; >+ >+ switch (type()) { >+ case FunctionExecutableType: { >+ FunctionExecutable* executable = static_cast<FunctionExecutable*>(this); >+ executable->m_codeBlockForCall.clear(); >+ executable->m_codeBlockForConstruct.clear(); >+ break; >+ } >+ case EvalExecutableType: { >+ EvalExecutable* executable = static_cast<EvalExecutable*>(this); >+ executable->m_evalCodeBlock.clear(); >+ executable->m_unlinkedEvalCodeBlock.clear(); >+ break; >+ } >+ case ProgramExecutableType: { >+ ProgramExecutable* executable = static_cast<ProgramExecutable*>(this); >+ executable->m_programCodeBlock.clear(); >+ executable->m_unlinkedProgramCodeBlock.clear(); >+ break; >+ } >+ case ModuleProgramExecutableType: { >+ ModuleProgramExecutable* executable = static_cast<ModuleProgramExecutable*>(this); >+ executable->m_moduleProgramCodeBlock.clear(); >+ executable->m_unlinkedModuleProgramCodeBlock.clear(); >+ executable->m_moduleEnvironmentSymbolTable.clear(); >+ break; >+ } >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ } >+ > ASSERT(&VM::SpaceAndSet::setFor(*subspace()) == &clearableCodeSet); > clearableCodeSet.remove(this); > } >@@ -150,7 +190,7 @@ void ScriptExecutable::installCode(VM& vm, CodeBlock* genericCodeBlock, CodeType > } > > auto& clearableCodeSet = VM::SpaceAndSet::setFor(*subspace()); >- if (hasClearableCode()) >+ if (hasClearableCode(vm)) > clearableCodeSet.add(this); > else > clearableCodeSet.remove(this); >@@ -176,6 +216,41 @@ void ScriptExecutable::installCode(VM& vm, CodeBlock* genericCodeBlock, CodeType > vm.heap.writeBarrier(this); > } > >+bool ScriptExecutable::hasClearableCode(VM& vm) const >+{ >+#if ENABLE(JIT) >+ if (m_jitCodeForCall >+ || m_jitCodeForConstruct >+ || m_jitCodeForCallWithArityCheck >+ || m_jitCodeForConstructWithArityCheck) >+ return true; >+#endif >+ >+ if (structure(vm)->classInfo() == FunctionExecutable::info()) { >+ auto* executable = static_cast<const FunctionExecutable*>(this); >+ if (executable->m_codeBlockForCall || executable->m_codeBlockForConstruct) >+ return true; >+ >+ } else if (structure(vm)->classInfo() == EvalExecutable::info()) { >+ auto* executable = static_cast<const EvalExecutable*>(this); >+ if (executable->m_evalCodeBlock || executable->m_unlinkedEvalCodeBlock) >+ return true; >+ >+ } else if (structure(vm)->classInfo() == ProgramExecutable::info()) { >+ auto* executable = static_cast<const ProgramExecutable*>(this); >+ if (executable->m_programCodeBlock || executable->m_unlinkedProgramCodeBlock) >+ return true; >+ >+ } else if (structure(vm)->classInfo() == ModuleProgramExecutable::info()) { >+ auto* executable = static_cast<const ModuleProgramExecutable*>(this); >+ if (executable->m_moduleProgramCodeBlock >+ || executable->m_unlinkedModuleProgramCodeBlock >+ || executable->m_moduleEnvironmentSymbolTable) >+ return true; >+ } >+ return false; >+} >+ > CodeBlock* ScriptExecutable::newCodeBlockFor( > CodeSpecializationKind kind, JSFunction* function, JSScope* scope, JSObject*& exception) > { >diff --git a/Source/JavaScriptCore/runtime/ScriptExecutable.h b/Source/JavaScriptCore/runtime/ScriptExecutable.h >index 5b85393912a53688ad20751d50fe5037b9d70238..115f88397b7ce64534985edf8746c3f611f36285 100644 >--- a/Source/JavaScriptCore/runtime/ScriptExecutable.h >+++ b/Source/JavaScriptCore/runtime/ScriptExecutable.h >@@ -97,6 +97,22 @@ class ScriptExecutable : public ExecutableBase { > > void clearCode(IsoCellSet&); > >+ Intrinsic intrinsic() const >+ { >+ return m_intrinsic; >+ } >+ >+ static constexpr int NUM_PARAMETERS_NOT_COMPILED = -1; >+ >+ bool hasJITCodeForCall() const >+ { >+ return m_numParametersForCall >= 0; >+ } >+ bool hasJITCodeForConstruct() const >+ { >+ return m_numParametersForConstruct >= 0; >+ } >+ > // This function has an interesting GC story. Callers of this function are asking us to create a CodeBlock > // that is not jettisoned before this function returns. Callers are essentially asking for a strong reference > // to the CodeBlock. Because the Executable may be allocating the CodeBlock, we require callers to pass in >@@ -110,6 +126,8 @@ class ScriptExecutable : public ExecutableBase { > friend class ExecutableBase; > JSObject* prepareForExecutionImpl(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&); > >+ bool hasClearableCode(VM&) const; >+ > protected: > ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, DerivedContextType, bool isInArrowFunctionContext, EvalContextType, Intrinsic); > >@@ -123,6 +141,15 @@ class ScriptExecutable : public ExecutableBase { > #endif > } > >+ SourceCode m_source; >+ >+ int m_numParametersForCall { NUM_PARAMETERS_NOT_COMPILED }; >+ int m_numParametersForConstruct { NUM_PARAMETERS_NOT_COMPILED }; >+ >+ int m_lastLine { -1 }; >+ unsigned m_endColumn { UINT_MAX }; >+ >+ Intrinsic m_intrinsic { NoIntrinsic }; > bool m_didTryToEnterInLoop { false }; > CodeFeatures m_features; > bool m_hasCapturedVariables : 1; >@@ -133,10 +160,6 @@ class ScriptExecutable : public ExecutableBase { > bool m_canUseOSRExitFuzzing : 1; > unsigned m_derivedContextType : 2; // DerivedContextType > unsigned m_evalContextType : 2; // EvalContextType >- >- int m_lastLine { -1 }; >- unsigned m_endColumn { UINT_MAX }; >- SourceCode m_source; > }; > > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/VM.cpp b/Source/JavaScriptCore/runtime/VM.cpp >index 4ef7baab5c51c8854ba95a08627ddbf964bbf25c..763b0d62850f8fe2fe75e18843aa0bedd3dfc149 100644 >--- a/Source/JavaScriptCore/runtime/VM.cpp >+++ b/Source/JavaScriptCore/runtime/VM.cpp >@@ -699,10 +699,12 @@ NativeExecutable* VM::getHostFunction(NativeFunction function, Intrinsic intrins > } > #endif // ENABLE(JIT) > UNUSED_PARAM(intrinsic); >+ UNUSED_PARAM(signature); >+ > return NativeExecutable::create(*this, >- adoptRef(*new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_call_trampoline), JITCode::HostCallThunk)), function, >- adoptRef(*new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_construct_trampoline), JITCode::HostCallThunk)), constructor, >- NoIntrinsic, signature, name); >+ adoptRef(*new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_call_trampoline), JITCode::HostCallThunk, NoIntrinsic)), function, >+ adoptRef(*new NativeJITCode(LLInt::getCodeRef<JSEntryPtrTag>(llint_native_construct_trampoline), JITCode::HostCallThunk, NoIntrinsic)), constructor, >+ name); > } > > MacroAssemblerCodePtr<JSEntryPtrTag> VM::getCTIInternalFunctionTrampolineFor(CodeSpecializationKind kind)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194331
: 361283