diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/runtime/Executable.h | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/runtime/Executable.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/Executable.h | 485 |
1 files changed, 201 insertions, 284 deletions
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h index 3a3fd8f42..6ff27aee9 100644 --- a/Source/JavaScriptCore/runtime/Executable.h +++ b/Source/JavaScriptCore/runtime/Executable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010, 2013-2015 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,21 +26,20 @@ #ifndef Executable_h #define Executable_h -#include "ArityCheckMode.h" #include "CallData.h" #include "CodeBlockHash.h" #include "CodeSpecializationKind.h" #include "CompilationResult.h" -#include "ExecutableInfo.h" +#include "DFGPlan.h" #include "HandlerInfo.h" -#include "InferredValue.h" +#include "JSFunction.h" +#include "Interpreter.h" #include "JITCode.h" #include "JSGlobalObject.h" #include "SamplingTool.h" #include "SourceCode.h" -#include "TypeSet.h" #include "UnlinkedCodeBlock.h" -#include "UnlinkedFunctionExecutable.h" +#include <wtf/PassOwnPtr.h> namespace JSC { @@ -48,17 +47,10 @@ class CodeBlock; class Debugger; class EvalCodeBlock; class FunctionCodeBlock; -class JSScope; -class JSWASMModule; class LLIntOffsetsExtractor; class ProgramCodeBlock; -class ModuleProgramCodeBlock; -class JSScope; -class WebAssemblyCodeBlock; -class ModuleProgramCodeBlock; -class JSModuleRecord; class JSScope; - + enum CompilationKind { FirstCompilation, OptimizingCompilation }; inline bool isCall(CodeSpecializationKind kind) @@ -69,7 +61,8 @@ inline bool isCall(CodeSpecializationKind kind) return false; } -class ExecutableBase : public JSCell { +class ExecutableBase : public JSCell, public DoublyLinkedListNode<ExecutableBase> { + friend class WTF::DoublyLinkedListNode<ExecutableBase>; friend class JIT; protected: @@ -90,30 +83,27 @@ protected: public: typedef JSCell Base; - static const unsigned StructureFlags = Base::StructureFlags; +#if ENABLE(JIT) static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); +#endif CodeBlockHash hashFor(CodeSpecializationKind) const; - bool isEvalExecutable() const + bool isEvalExecutable() { - return type() == EvalExecutableType; + return structure()->typeInfo().type() == EvalExecutableType; } - bool isFunctionExecutable() const + bool isFunctionExecutable() { - return type() == FunctionExecutableType; + return structure()->typeInfo().type() == FunctionExecutableType; } - bool isProgramExecutable() const + bool isProgramExecutable() { - return type() == ProgramExecutableType; + return structure()->typeInfo().type() == ProgramExecutableType; } - bool isModuleProgramExecutable() - { - return type() == ModuleProgramExecutableType; - } - bool isHostFunction() const { @@ -121,24 +111,20 @@ public: return m_numParametersForCall == NUM_PARAMETERS_IS_HOST; } -#if ENABLE(WEBASSEMBLY) - bool isWebAssemblyExecutable() const - { - return type() == WebAssemblyExecutableType; - } -#endif - - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); } + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CompoundType, StructureFlags), info()); } void clearCode(); DECLARE_EXPORT_INFO; protected: + static const unsigned StructureFlags = 0; int m_numParametersForCall; int m_numParametersForConstruct; public: + static void clearCodeVirtual(ExecutableBase*); + PassRefPtr<JITCode> generatedJITCodeForCall() { ASSERT(m_jitCodeForCall); @@ -158,53 +144,37 @@ public: ASSERT(kind == CodeForConstruct); return generatedJITCodeForConstruct(); } - - MacroAssemblerCodePtr entrypointFor(CodeSpecializationKind kind, ArityCheckMode arity) - { - // Check if we have a cached result. We only have it for arity check because we use the - // no-arity entrypoint in non-virtual calls, which will "cache" this value directly in - // machine code. - if (arity == MustCheckArity) { - switch (kind) { - case CodeForCall: - if (MacroAssemblerCodePtr result = m_jitCodeForCallWithArityCheck) - return result; - break; - case CodeForConstruct: - if (MacroAssemblerCodePtr result = m_jitCodeForConstructWithArityCheck) - return result; - break; - } - } - MacroAssemblerCodePtr result = - generatedJITCodeFor(kind)->addressForCall(arity); - if (arity == MustCheckArity) { - // Cache the result; this is necessary for the JIT's virtual call optimizations. - switch (kind) { - case CodeForCall: - m_jitCodeForCallWithArityCheck = result; - break; - case CodeForConstruct: - m_jitCodeForConstructWithArityCheck = result; - break; - } - } - return result; - } - - static ptrdiff_t offsetOfJITCodeWithArityCheckFor( - CodeSpecializationKind kind) - { - switch (kind) { - case CodeForCall: + + MacroAssemblerCodePtr generatedJITCodeForCallWithArityCheck() + { + ASSERT(m_jitCodeForCall); + ASSERT(m_jitCodeForCallWithArityCheck); + return m_jitCodeForCallWithArityCheck; + } + + MacroAssemblerCodePtr generatedJITCodeForConstructWithArityCheck() + { + ASSERT(m_jitCodeForConstruct); + ASSERT(m_jitCodeForConstructWithArityCheck); + return m_jitCodeForConstructWithArityCheck; + } + + MacroAssemblerCodePtr generatedJITCodeWithArityCheckFor(CodeSpecializationKind kind) + { + if (kind == CodeForCall) + return generatedJITCodeForCallWithArityCheck(); + ASSERT(kind == CodeForConstruct); + return generatedJITCodeForConstructWithArityCheck(); + } + + static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind) + { + if (kind == CodeForCall) return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck); - case CodeForConstruct: - return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck); - } - RELEASE_ASSERT_NOT_REACHED(); - return 0; + ASSERT(kind == CodeForConstruct); + return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck); } - + static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind) { if (kind == CodeForCall) @@ -240,32 +210,52 @@ public: return intrinsic(); return NoIntrinsic; } - - void dump(PrintStream&) const; + MacroAssemblerCodePtr hostCodeEntryFor(CodeSpecializationKind kind) + { + return generatedJITCodeFor(kind)->addressForCall(); + } + + MacroAssemblerCodePtr jsCodeEntryFor(CodeSpecializationKind kind) + { + return generatedJITCodeFor(kind)->addressForCall(); + } + + MacroAssemblerCodePtr jsCodeWithArityCheckEntryFor(CodeSpecializationKind kind) + { + return generatedJITCodeWithArityCheckFor(kind); + } + protected: + ExecutableBase* m_prev; + ExecutableBase* m_next; + RefPtr<JITCode> m_jitCodeForCall; RefPtr<JITCode> m_jitCodeForConstruct; MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck; MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck; }; -class NativeExecutable final : public ExecutableBase { +class NativeExecutable : public ExecutableBase { friend class JIT; friend class LLIntOffsetsExtractor; public: typedef ExecutableBase Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; - static NativeExecutable* create(VM& vm, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic intrinsic, const String& name) + static NativeExecutable* create(VM& vm, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic) { NativeExecutable* executable; executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor); - executable->finishCreation(vm, callThunk, constructThunk, intrinsic, name); + if (!callThunk) + executable->finishCreation(vm, 0, 0, intrinsic); + else + executable->finishCreation(vm, JITCode::hostFunction(callThunk), JITCode::hostFunction(constructThunk), intrinsic); return executable; } +#if ENABLE(JIT) static void destroy(JSCell*); +#endif CodeBlockHash hashFor(CodeSpecializationKind) const; @@ -288,27 +278,24 @@ public: return OBJECT_OFFSETOF(NativeExecutable, m_constructor); } - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); } + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(LeafType, StructureFlags), info()); } DECLARE_INFO; Intrinsic intrinsic() const; - const String& name() const { return m_name; } - protected: - void finishCreation(VM& vm, PassRefPtr<JITCode> callThunk, PassRefPtr<JITCode> constructThunk, Intrinsic intrinsic, const String& name) + void finishCreation(VM& vm, PassRefPtr<JITCode> callThunk, PassRefPtr<JITCode> constructThunk, Intrinsic intrinsic) { Base::finishCreation(vm); + m_jitCodeForCallWithArityCheck = callThunk ? callThunk->addressForCall() : MacroAssemblerCodePtr(); + m_jitCodeForConstructWithArityCheck = constructThunk ? constructThunk->addressForCall() : MacroAssemblerCodePtr(); m_jitCodeForCall = callThunk; m_jitCodeForConstruct = constructThunk; m_intrinsic = intrinsic; - m_name = name; } private: - friend class ExecutableBase; - NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor) : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST) , m_function(function) @@ -320,54 +307,61 @@ private: NativeFunction m_constructor; Intrinsic m_intrinsic; - - String m_name; }; class ScriptExecutable : public ExecutableBase { public: typedef ExecutableBase Base; - static const unsigned StructureFlags = Base::StructureFlags; + ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext) + : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED) + , m_source(source) + , m_features(isInStrictContext ? StrictModeFeature : 0) + , m_neverInline(false) + , m_startColumn(UINT_MAX) + , m_endColumn(UINT_MAX) + { + } + + ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext) + : ExecutableBase(exec->vm(), structure, NUM_PARAMETERS_NOT_COMPILED) + , m_source(source) + , m_features(isInStrictContext ? StrictModeFeature : 0) + , m_neverInline(false) + , m_startColumn(UINT_MAX) + , m_endColumn(UINT_MAX) + { + } + +#if ENABLE(JIT) static void destroy(JSCell*); +#endif CodeBlockHash hashFor(CodeSpecializationKind) const; const SourceCode& source() const { return m_source; } intptr_t sourceID() const { return m_source.providerID(); } const String& sourceURL() const { return m_source.provider()->url(); } - int firstLine() const { return m_firstLine; } - void setOverrideLineNumber(int overrideLineNumber) { m_overrideLineNumber = overrideLineNumber; } - bool hasOverrideLineNumber() const { return m_overrideLineNumber != -1; } - int overrideLineNumber() const { return m_overrideLineNumber; } + int lineNo() const { return m_firstLine; } int lastLine() const { return m_lastLine; } unsigned startColumn() const { return m_startColumn; } unsigned endColumn() const { return m_endColumn; } - unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; } - unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; } bool usesEval() const { return m_features & EvalFeature; } bool usesArguments() const { return m_features & ArgumentsFeature; } - bool isArrowFunctionContext() const { return m_isArrowFunctionContext; } + bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); } bool isStrictMode() const { return m_features & StrictModeFeature; } - DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); } - ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; } void setNeverInline(bool value) { m_neverInline = value; } - void setNeverOptimize(bool value) { m_neverOptimize = value; } - void setDidTryToEnterInLoop(bool value) { m_didTryToEnterInLoop = value; } bool neverInline() const { return m_neverInline; } - bool neverOptimize() const { return m_neverOptimize; } - bool didTryToEnterInLoop() const { return m_didTryToEnterInLoop; } bool isInliningCandidate() const { return !neverInline(); } - bool isOkToOptimize() const { return !neverOptimize(); } - - bool* addressOfDidTryToEnterInLoop() { return &m_didTryToEnterInLoop; } + void unlinkCalls(); + CodeFeatures features() const { return m_features; } - DECLARE_EXPORT_INFO; + DECLARE_INFO; void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn, unsigned endColumn) { @@ -382,30 +376,24 @@ public: } void installCode(CodeBlock*); - void installCode(VM&, CodeBlock*, CodeType, CodeSpecializationKind); - CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception); - CodeBlock* newReplacementCodeBlockFor(CodeSpecializationKind); + PassRefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSScope*, JSObject*& exception); + PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind); - JSObject* prepareForExecution(ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind) + JSObject* prepareForExecution(ExecState* exec, JSScope* scope, CodeSpecializationKind kind) { if (hasJITCodeFor(kind)) return 0; - return prepareForExecutionImpl(exec, function, scope, kind); + return prepareForExecutionImpl(exec, scope, kind); } - template <typename Functor> void forEachCodeBlock(Functor&&); - private: - friend class ExecutableBase; - JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope*, CodeSpecializationKind); + JSObject* prepareForExecutionImpl(ExecState*, JSScope*, CodeSpecializationKind); protected: - ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, DerivedContextType, bool isInArrowFunctionContext); - void finishCreation(VM& vm) { Base::finishCreation(vm); - vm.heap.addExecutable(this); // Balanced by Heap::deleteUnmarkedCompiledCode(). + vm.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode(). #if ENABLE(CODEBLOCK_SAMPLING) if (SamplingTool* sampler = vm.interpreter->sampler()) @@ -413,29 +401,20 @@ protected: #endif } + SourceCode m_source; CodeFeatures m_features; - bool m_didTryToEnterInLoop; - bool m_hasCapturedVariables : 1; - bool m_neverInline : 1; - bool m_neverOptimize : 1; - bool m_isArrowFunctionContext : 1; - unsigned m_derivedContextType : 2; // DerivedContextType - - int m_overrideLineNumber; + bool m_hasCapturedVariables; + bool m_neverInline; int m_firstLine; int m_lastLine; unsigned m_startColumn; unsigned m_endColumn; - unsigned m_typeProfilingStartOffset; - unsigned m_typeProfilingEndOffset; - SourceCode m_source; }; -class EvalExecutable final : public ScriptExecutable { +class EvalExecutable : public ScriptExecutable { friend class LLIntOffsetsExtractor; public: typedef ScriptExecutable Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; static void destroy(JSCell*); @@ -444,7 +423,7 @@ public: return m_evalCodeBlock.get(); } - static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, ThisTDZMode, DerivedContextType, bool isArrowFunctionContext, const VariableEnvironment*); + static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext); PassRefPtr<JITCode> generatedJITCode() { @@ -458,28 +437,30 @@ public: DECLARE_INFO; - ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext() , false); } + void unlinkCalls(); + + void clearCode(); + + ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); } unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); } unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); } private: - friend class ExecutableBase; friend class ScriptExecutable; - - EvalExecutable(ExecState*, const SourceCode&, bool inStrictContext, DerivedContextType, bool isArrowFunctionContext); + static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; + EvalExecutable(ExecState*, const SourceCode&, bool); static void visitChildren(JSCell*, SlotVisitor&); - WriteBarrier<EvalCodeBlock> m_evalCodeBlock; + RefPtr<EvalCodeBlock> m_evalCodeBlock; WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock; }; -class ProgramExecutable final : public ScriptExecutable { +class ProgramExecutable : public ScriptExecutable { friend class LLIntOffsetsExtractor; public: typedef ScriptExecutable Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; static ProgramExecutable* create(ExecState* exec, const SourceCode& source) { @@ -511,89 +492,43 @@ public: } DECLARE_INFO; + + void unlinkCalls(); - ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false); } + void clearCode(); + + ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); } private: - friend class ExecutableBase; friend class ScriptExecutable; + + static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; ProgramExecutable(ExecState*, const SourceCode&); static void visitChildren(JSCell*, SlotVisitor&); WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock; - WriteBarrier<ProgramCodeBlock> m_programCodeBlock; -}; - -class ModuleProgramExecutable final : public ScriptExecutable { - friend class LLIntOffsetsExtractor; -public: - typedef ScriptExecutable Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; - - static ModuleProgramExecutable* create(ExecState*, const SourceCode&); - - static void destroy(JSCell*); - - ModuleProgramCodeBlock* codeBlock() - { - return m_moduleProgramCodeBlock.get(); - } - - PassRefPtr<JITCode> generatedJITCode() - { - return generatedJITCodeForCall(); - } - - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) - { - return Structure::create(vm, globalObject, proto, TypeInfo(ModuleProgramExecutableType, StructureFlags), info()); - } - - DECLARE_INFO; - - ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, derivedContextType(), isArrowFunctionContext(), false); } - - UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); } - - SymbolTable* moduleEnvironmentSymbolTable() { return m_moduleEnvironmentSymbolTable.get(); } - -private: - friend class ExecutableBase; - friend class ScriptExecutable; - - ModuleProgramExecutable(ExecState*, const SourceCode&); - - static void visitChildren(JSCell*, SlotVisitor&); - - WriteBarrier<UnlinkedModuleProgramCodeBlock> m_unlinkedModuleProgramCodeBlock; - WriteBarrier<SymbolTable> m_moduleEnvironmentSymbolTable; - WriteBarrier<ModuleProgramCodeBlock> m_moduleProgramCodeBlock; + RefPtr<ProgramCodeBlock> m_programCodeBlock; }; -class FunctionExecutable final : public ScriptExecutable { +class FunctionExecutable : public ScriptExecutable { friend class JIT; friend class LLIntOffsetsExtractor; public: typedef ScriptExecutable Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; - static FunctionExecutable* create( - VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, - unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn) + static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces = true) { - FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn, endColumn); + FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn, endColumn, bodyIncludesBraces); executable->finishCreation(vm); return executable; } - static FunctionExecutable* fromGlobalCode( - const Identifier& name, ExecState&, const SourceCode&, - JSObject*& exception, int overrideLineNumber); + static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception); static void destroy(JSCell*); - UnlinkedFunctionExecutable* unlinkedExecutable() const + UnlinkedFunctionExecutable* unlinkedExecutable() { return m_unlinkedExecutable.get(); } @@ -610,7 +545,7 @@ public: bool isGeneratedForCall() const { - return !!m_codeBlockForCall; + return m_codeBlockForCall; } FunctionCodeBlock* codeBlockForCall() @@ -620,7 +555,7 @@ public: bool isGeneratedForConstruct() const { - return m_codeBlockForConstruct.get(); + return m_codeBlockForConstruct; } FunctionCodeBlock* codeBlockForConstruct() @@ -650,107 +585,89 @@ public: { return baselineCodeBlockFor(kind); } - - RefPtr<TypeSet> returnStatementTypeSet() - { - if (!m_returnStatementTypeSet) - m_returnStatementTypeSet = TypeSet::create(); - - return m_returnStatementTypeSet; - } - FunctionMode functionMode() { return m_unlinkedExecutable->functionMode(); } - bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); } - ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); } - bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; } - DerivedContextType derivedContextType() const { return m_unlinkedExecutable->derivedContextType(); } - bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); } const Identifier& name() { return m_unlinkedExecutable->name(); } const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); } JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); } size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'! - SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); } + String paramString() const; + SymbolTable* symbolTable(CodeSpecializationKind); + void clearCodeIfNotCompiling(); + void clearUnlinkedCodeForRecompilationIfNotCompiling(); static void visitChildren(JSCell*, SlotVisitor&); static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), info()); } - - unsigned parametersStartOffset() const { return m_parametersStartOffset; } - - void overrideParameterAndTypeProfilingStartEndOffsets(unsigned parametersStartOffset, unsigned typeProfilingStartOffset, unsigned typeProfilingEndOffset) - { - m_parametersStartOffset = parametersStartOffset; - m_typeProfilingStartOffset = typeProfilingStartOffset; - m_typeProfilingEndOffset = typeProfilingEndOffset; - } - + DECLARE_INFO; + + void unlinkCalls(); - InferredValue* singletonFunction() { return m_singletonFunction.get(); } - -private: - friend class ExecutableBase; - FunctionExecutable( - VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, - unsigned lastLine, unsigned startColumn, unsigned endColumn); - - void finishCreation(VM&); - - friend class ScriptExecutable; - - unsigned m_parametersStartOffset; - WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable; - WriteBarrier<FunctionCodeBlock> m_codeBlockForCall; - WriteBarrier<FunctionCodeBlock> m_codeBlockForConstruct; - RefPtr<TypeSet> m_returnStatementTypeSet; - WriteBarrier<InferredValue> m_singletonFunction; -}; + void clearCode(); -#if ENABLE(WEBASSEMBLY) -class WebAssemblyExecutable final : public ExecutableBase { -public: - typedef ExecutableBase Base; - static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; + bool bodyIncludesBraces() const { return m_bodyIncludesBraces; } - static WebAssemblyExecutable* create(VM& vm, const SourceCode& source, JSWASMModule* module, unsigned functionIndex) - { - WebAssemblyExecutable* executable = new (NotNull, allocateCell<WebAssemblyExecutable>(vm.heap)) WebAssemblyExecutable(vm, source, module, functionIndex); - executable->finishCreation(vm); - return executable; - } +private: + FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, bool bodyIncludesBraces); - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) + bool isCompiling() { - return Structure::create(vm, globalObject, proto, TypeInfo(WebAssemblyExecutableType, StructureFlags), info()); +#if ENABLE(JIT) + if (!m_jitCodeForCall && m_codeBlockForCall) + return true; + if (!m_jitCodeForConstruct && m_codeBlockForConstruct) + return true; +#endif + return false; } - static void destroy(JSCell*); + friend class ScriptExecutable; - DECLARE_INFO; + static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; + WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable; + RefPtr<FunctionCodeBlock> m_codeBlockForCall; + RefPtr<FunctionCodeBlock> m_codeBlockForConstruct; + bool m_bodyIncludesBraces; +}; - void prepareForExecution(ExecState*); +inline bool isHostFunction(JSValue value, NativeFunction nativeFunction) +{ + JSFunction* function = jsCast<JSFunction*>(getJSFunction(value)); + if (!function || !function->isHostFunction()) + return false; + return function->nativeFunction() == nativeFunction; +} - WebAssemblyCodeBlock* codeBlockForCall() - { - return m_codeBlockForCall.get(); +inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable) +{ + switch (executable->structure()->typeInfo().type()) { + case EvalExecutableType: + return jsCast<EvalExecutable*>(executable)->clearCode(); + case ProgramExecutableType: + return jsCast<ProgramExecutable*>(executable)->clearCode(); + case FunctionExecutableType: + return jsCast<FunctionExecutable*>(executable)->clearCode(); + default: + return jsCast<NativeExecutable*>(executable)->clearCode(); } +} -private: - friend class ExecutableBase; - WebAssemblyExecutable(VM&, const SourceCode&, JSWASMModule*, unsigned functionIndex); - - static void visitChildren(JSCell*, SlotVisitor&); +inline void ScriptExecutable::unlinkCalls() +{ + switch (structure()->typeInfo().type()) { + case EvalExecutableType: + return jsCast<EvalExecutable*>(this)->unlinkCalls(); + case ProgramExecutableType: + return jsCast<ProgramExecutable*>(this)->unlinkCalls(); + case FunctionExecutableType: + return jsCast<FunctionExecutable*>(this)->unlinkCalls(); + default: + RELEASE_ASSERT_NOT_REACHED(); + } +} - SourceCode m_source; - WriteBarrier<JSWASMModule> m_module; - unsigned m_functionIndex; +} - WriteBarrier<WebAssemblyCodeBlock> m_codeBlockForCall; -}; #endif - -} // namespace JSC - -#endif // Executable_h |