Changeset 208063 in webkit for trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h
- Timestamp:
- Oct 28, 2016, 1:04:56 PM (9 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h
r207790 r208063 26 26 #pragma once 27 27 28 #include "ArityCheckMode.h" 29 #include "CallData.h" 30 #include "CodeBlockHash.h" 31 #include "CodeSpecializationKind.h" 32 #include "CompilationResult.h" 33 #include "ExecutableInfo.h" 34 #include "HandlerInfo.h" 35 #include "InferredValue.h" 36 #include "JITCode.h" 37 #include "JSGlobalObject.h" 38 #include "SourceCode.h" 39 #include "TypeSet.h" 40 #include "UnlinkedCodeBlock.h" 41 #include "UnlinkedFunctionExecutable.h" 28 #include "ScriptExecutable.h" 42 29 43 30 namespace JSC { 44 45 class CodeBlock;46 class EvalCodeBlock;47 class FunctionCodeBlock;48 class JSScope;49 class JSWasmModule;50 class LLIntOffsetsExtractor;51 class ModuleProgramCodeBlock;52 class ProgramCodeBlock;53 class WebAssemblyCodeBlock;54 55 enum CompilationKind { FirstCompilation, OptimizingCompilation };56 57 inline bool isCall(CodeSpecializationKind kind)58 {59 if (kind == CodeForCall)60 return true;61 ASSERT(kind == CodeForConstruct);62 return false;63 }64 65 class ExecutableBase : public JSCell {66 friend class JIT;67 68 protected:69 static const int NUM_PARAMETERS_IS_HOST = 0;70 static const int NUM_PARAMETERS_NOT_COMPILED = -1;71 72 ExecutableBase(VM& vm, Structure* structure, int numParameters, Intrinsic intrinsic)73 : JSCell(vm, structure)74 , m_numParametersForCall(numParameters)75 , m_numParametersForConstruct(numParameters)76 , m_intrinsic(intrinsic)77 {78 }79 80 void finishCreation(VM& vm)81 {82 Base::finishCreation(vm);83 }84 85 public:86 typedef JSCell Base;87 static const unsigned StructureFlags = Base::StructureFlags;88 89 static const bool needsDestruction = true;90 static void destroy(JSCell*);91 92 CodeBlockHash hashFor(CodeSpecializationKind) const;93 94 bool isEvalExecutable() const95 {96 return type() == EvalExecutableType;97 }98 bool isFunctionExecutable() const99 {100 return type() == FunctionExecutableType;101 }102 bool isProgramExecutable() const103 {104 return type() == ProgramExecutableType;105 }106 bool isModuleProgramExecutable()107 {108 return type() == ModuleProgramExecutableType;109 }110 111 112 bool isHostFunction() const113 {114 ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));115 return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;116 }117 118 #if ENABLE(WEBASSEMBLY)119 bool isWebAssemblyExecutable() const120 {121 return type() == WebAssemblyExecutableType;122 }123 #endif124 125 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); }126 127 void clearCode();128 129 DECLARE_EXPORT_INFO;130 131 protected:132 int m_numParametersForCall;133 int m_numParametersForConstruct;134 135 public:136 PassRefPtr<JITCode> generatedJITCodeForCall()137 {138 ASSERT(m_jitCodeForCall);139 return m_jitCodeForCall;140 }141 142 PassRefPtr<JITCode> generatedJITCodeForConstruct()143 {144 ASSERT(m_jitCodeForConstruct);145 return m_jitCodeForConstruct;146 }147 148 PassRefPtr<JITCode> generatedJITCodeFor(CodeSpecializationKind kind)149 {150 if (kind == CodeForCall)151 return generatedJITCodeForCall();152 ASSERT(kind == CodeForConstruct);153 return generatedJITCodeForConstruct();154 }155 156 MacroAssemblerCodePtr entrypointFor(CodeSpecializationKind kind, ArityCheckMode arity)157 {158 // Check if we have a cached result. We only have it for arity check because we use the159 // no-arity entrypoint in non-virtual calls, which will "cache" this value directly in160 // machine code.161 if (arity == MustCheckArity) {162 switch (kind) {163 case CodeForCall:164 if (MacroAssemblerCodePtr result = m_jitCodeForCallWithArityCheck)165 return result;166 break;167 case CodeForConstruct:168 if (MacroAssemblerCodePtr result = m_jitCodeForConstructWithArityCheck)169 return result;170 break;171 }172 }173 MacroAssemblerCodePtr result =174 generatedJITCodeFor(kind)->addressForCall(arity);175 if (arity == MustCheckArity) {176 // Cache the result; this is necessary for the JIT's virtual call optimizations.177 switch (kind) {178 case CodeForCall:179 m_jitCodeForCallWithArityCheck = result;180 break;181 case CodeForConstruct:182 m_jitCodeForConstructWithArityCheck = result;183 break;184 }185 }186 return result;187 }188 189 static ptrdiff_t offsetOfJITCodeWithArityCheckFor(190 CodeSpecializationKind kind)191 {192 switch (kind) {193 case CodeForCall:194 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);195 case CodeForConstruct:196 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);197 }198 RELEASE_ASSERT_NOT_REACHED();199 return 0;200 }201 202 static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)203 {204 if (kind == CodeForCall)205 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);206 ASSERT(kind == CodeForConstruct);207 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);208 }209 210 bool hasJITCodeForCall() const211 {212 return m_numParametersForCall >= 0;213 }214 215 bool hasJITCodeForConstruct() const216 {217 return m_numParametersForConstruct >= 0;218 }219 220 bool hasJITCodeFor(CodeSpecializationKind kind) const221 {222 if (kind == CodeForCall)223 return hasJITCodeForCall();224 ASSERT(kind == CodeForConstruct);225 return hasJITCodeForConstruct();226 }227 228 // Intrinsics are only for calls, currently.229 Intrinsic intrinsic() const { return m_intrinsic; }230 231 Intrinsic intrinsicFor(CodeSpecializationKind kind) const232 {233 if (isCall(kind))234 return intrinsic();235 return NoIntrinsic;236 }237 238 void dump(PrintStream&) const;239 240 protected:241 Intrinsic m_intrinsic;242 RefPtr<JITCode> m_jitCodeForCall;243 RefPtr<JITCode> m_jitCodeForConstruct;244 MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;245 MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck;246 };247 248 class NativeExecutable final : public ExecutableBase {249 friend class JIT;250 friend class LLIntOffsetsExtractor;251 public:252 typedef ExecutableBase Base;253 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;254 255 static NativeExecutable* create(VM& vm, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic intrinsic, const String& name);256 257 static void destroy(JSCell*);258 259 CodeBlockHash hashFor(CodeSpecializationKind) const;260 261 NativeFunction function() { return m_function; }262 NativeFunction constructor() { return m_constructor; }263 264 NativeFunction nativeFunctionFor(CodeSpecializationKind kind)265 {266 if (kind == CodeForCall)267 return function();268 ASSERT(kind == CodeForConstruct);269 return constructor();270 }271 272 static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind)273 {274 if (kind == CodeForCall)275 return OBJECT_OFFSETOF(NativeExecutable, m_function);276 ASSERT(kind == CodeForConstruct);277 return OBJECT_OFFSETOF(NativeExecutable, m_constructor);278 }279 280 static Structure* createStructure(VM&, JSGlobalObject*, JSValue proto);281 282 DECLARE_INFO;283 284 const String& name() const { return m_name; }285 286 protected:287 void finishCreation(VM&, PassRefPtr<JITCode> callThunk, PassRefPtr<JITCode> constructThunk, const String& name);288 289 private:290 friend class ExecutableBase;291 292 NativeExecutable(VM&, NativeFunction function, NativeFunction constructor, Intrinsic);293 294 NativeFunction m_function;295 NativeFunction m_constructor;296 297 String m_name;298 };299 300 class ScriptExecutable : public ExecutableBase {301 public:302 typedef ExecutableBase Base;303 static const unsigned StructureFlags = Base::StructureFlags;304 305 static void destroy(JSCell*);306 307 CodeBlockHash hashFor(CodeSpecializationKind) const;308 309 const SourceCode& source() const { return m_source; }310 intptr_t sourceID() const { return m_source.providerID(); }311 const String& sourceURL() const { return m_source.provider()->url(); }312 int firstLine() const { return m_firstLine; }313 void setOverrideLineNumber(int overrideLineNumber) { m_overrideLineNumber = overrideLineNumber; }314 bool hasOverrideLineNumber() const { return m_overrideLineNumber != -1; }315 int overrideLineNumber() const { return m_overrideLineNumber; }316 int lastLine() const { return m_lastLine; }317 unsigned startColumn() const { return m_startColumn; }318 unsigned endColumn() const { return m_endColumn; }319 unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }320 unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }321 322 bool usesEval() const { return m_features & EvalFeature; }323 bool usesArguments() const { return m_features & ArgumentsFeature; }324 bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }325 bool isStrictMode() const { return m_features & StrictModeFeature; }326 DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); }327 EvalContextType evalContextType() const { return static_cast<EvalContextType>(m_evalContextType); }328 329 ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }330 331 void setNeverInline(bool value) { m_neverInline = value; }332 void setNeverOptimize(bool value) { m_neverOptimize = value; }333 void setNeverFTLOptimize(bool value) { m_neverFTLOptimize = value; }334 void setDidTryToEnterInLoop(bool value) { m_didTryToEnterInLoop = value; }335 void setCanUseOSRExitFuzzing(bool value) { m_canUseOSRExitFuzzing = value; }336 bool neverInline() const { return m_neverInline; }337 bool neverOptimize() const { return m_neverOptimize; }338 bool neverFTLOptimize() const { return m_neverFTLOptimize; }339 bool didTryToEnterInLoop() const { return m_didTryToEnterInLoop; }340 bool isInliningCandidate() const { return !neverInline(); }341 bool isOkToOptimize() const { return !neverOptimize(); }342 bool canUseOSRExitFuzzing() const { return m_canUseOSRExitFuzzing; }343 344 bool* addressOfDidTryToEnterInLoop() { return &m_didTryToEnterInLoop; }345 346 CodeFeatures features() const { return m_features; }347 348 DECLARE_EXPORT_INFO;349 350 void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn, unsigned endColumn)351 {352 m_features = features;353 m_hasCapturedVariables = hasCapturedVariables;354 m_firstLine = firstLine;355 m_lastLine = lastLine;356 ASSERT(startColumn != UINT_MAX);357 m_startColumn = startColumn;358 ASSERT(endColumn != UINT_MAX);359 m_endColumn = endColumn;360 }361 362 void installCode(CodeBlock*);363 void installCode(VM&, CodeBlock*, CodeType, CodeSpecializationKind);364 CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception);365 CodeBlock* newReplacementCodeBlockFor(CodeSpecializationKind);366 367 // This function has an interesting GC story. Callers of this function are asking us to create a CodeBlock368 // that is not jettisoned before this function returns. Callers are essentially asking for a strong reference369 // to the CodeBlock. Because the Executable may be allocating the CodeBlock, we require callers to pass in370 // their CodeBlock*& reference because it's safe for CodeBlock to be jettisoned if Executable is the only thing371 // to point to it. This forces callers to have a CodeBlock* in a register or on the stack that will be marked372 // by conservative GC if a GC happens after we create the CodeBlock.373 template <typename ExecutableType>374 JSObject* prepareForExecution(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*& resultCodeBlock);375 376 template <typename Functor> void forEachCodeBlock(Functor&&);377 378 private:379 friend class ExecutableBase;380 JSObject* prepareForExecutionImpl(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*&);381 382 protected:383 ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, DerivedContextType, bool isInArrowFunctionContext, EvalContextType, Intrinsic);384 385 void finishCreation(VM& vm)386 {387 Base::finishCreation(vm);388 vm.heap.addExecutable(this); // Balanced by Heap::deleteUnmarkedCompiledCode().389 390 #if ENABLE(CODEBLOCK_SAMPLING)391 if (SamplingTool* sampler = vm.interpreter->sampler())392 sampler->notifyOfScope(vm, this);393 #endif394 }395 396 CodeFeatures m_features;397 bool m_didTryToEnterInLoop;398 bool m_hasCapturedVariables : 1;399 bool m_neverInline : 1;400 bool m_neverOptimize : 1;401 bool m_neverFTLOptimize : 1;402 bool m_isArrowFunctionContext : 1;403 bool m_canUseOSRExitFuzzing : 1;404 unsigned m_derivedContextType : 2; // DerivedContextType405 unsigned m_evalContextType : 2; // EvalContextType406 407 int m_overrideLineNumber;408 int m_firstLine;409 int m_lastLine;410 unsigned m_startColumn;411 unsigned m_endColumn;412 unsigned m_typeProfilingStartOffset;413 unsigned m_typeProfilingEndOffset;414 SourceCode m_source;415 };416 417 class EvalExecutable final : public ScriptExecutable {418 friend class LLIntOffsetsExtractor;419 public:420 typedef ScriptExecutable Base;421 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;422 423 static void destroy(JSCell*);424 425 EvalCodeBlock* codeBlock()426 {427 return m_evalCodeBlock.get();428 }429 430 static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, DerivedContextType, bool isArrowFunctionContext, EvalContextType, const VariableEnvironment*);431 432 PassRefPtr<JITCode> generatedJITCode()433 {434 return generatedJITCodeForCall();435 }436 437 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)438 {439 return Structure::create(vm, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), info());440 }441 442 DECLARE_INFO;443 444 ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, evalContextType()); }445 446 unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }447 unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }448 449 private:450 friend class ExecutableBase;451 friend class ScriptExecutable;452 453 EvalExecutable(ExecState*, const SourceCode&, bool inStrictContext, DerivedContextType, bool isArrowFunctionContext, EvalContextType);454 455 static void visitChildren(JSCell*, SlotVisitor&);456 457 WriteBarrier<EvalCodeBlock> m_evalCodeBlock;458 WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;459 };460 461 class ProgramExecutable final : public ScriptExecutable {462 friend class LLIntOffsetsExtractor;463 public:464 typedef ScriptExecutable Base;465 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;466 467 static ProgramExecutable* create(ExecState* exec, const SourceCode& source)468 {469 ProgramExecutable* executable = new (NotNull, allocateCell<ProgramExecutable>(*exec->heap())) ProgramExecutable(exec, source);470 executable->finishCreation(exec->vm());471 return executable;472 }473 474 475 JSObject* initializeGlobalProperties(VM&, CallFrame*, JSScope*);476 477 static void destroy(JSCell*);478 479 ProgramCodeBlock* codeBlock()480 {481 return m_programCodeBlock.get();482 }483 484 JSObject* checkSyntax(ExecState*);485 486 PassRefPtr<JITCode> generatedJITCode()487 {488 return generatedJITCodeForCall();489 }490 491 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)492 {493 return Structure::create(vm, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), info());494 }495 496 DECLARE_INFO;497 498 ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, EvalContextType::None); }499 500 private:501 friend class ExecutableBase;502 friend class ScriptExecutable;503 504 ProgramExecutable(ExecState*, const SourceCode&);505 506 static void visitChildren(JSCell*, SlotVisitor&);507 508 WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;509 WriteBarrier<ProgramCodeBlock> m_programCodeBlock;510 };511 31 512 32 class ModuleProgramExecutable final : public ScriptExecutable { … … 556 76 }; 557 77 558 class FunctionExecutable final : public ScriptExecutable {559 friend class JIT;560 friend class LLIntOffsetsExtractor;561 public:562 typedef ScriptExecutable Base;563 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;564 565 static FunctionExecutable* create(566 VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable,567 unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn, Intrinsic intrinsic)568 {569 FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn, endColumn, intrinsic);570 executable->finishCreation(vm);571 return executable;572 }573 static FunctionExecutable* fromGlobalCode(574 const Identifier& name, ExecState&, const SourceCode&,575 JSObject*& exception, int overrideLineNumber);576 577 static void destroy(JSCell*);578 579 UnlinkedFunctionExecutable* unlinkedExecutable() const580 {581 return m_unlinkedExecutable.get();582 }583 584 // Returns either call or construct bytecode. This can be appropriate585 // for answering questions that that don't vary between call and construct --586 // for example, argumentsRegister().587 FunctionCodeBlock* eitherCodeBlock()588 {589 if (m_codeBlockForCall)590 return m_codeBlockForCall.get();591 return m_codeBlockForConstruct.get();592 }593 594 bool isGeneratedForCall() const595 {596 return !!m_codeBlockForCall;597 }598 599 FunctionCodeBlock* codeBlockForCall()600 {601 return m_codeBlockForCall.get();602 }603 604 bool isGeneratedForConstruct() const605 {606 return m_codeBlockForConstruct.get();607 }608 609 FunctionCodeBlock* codeBlockForConstruct()610 {611 return m_codeBlockForConstruct.get();612 }613 614 bool isGeneratedFor(CodeSpecializationKind kind)615 {616 if (kind == CodeForCall)617 return isGeneratedForCall();618 ASSERT(kind == CodeForConstruct);619 return isGeneratedForConstruct();620 }621 622 FunctionCodeBlock* codeBlockFor(CodeSpecializationKind kind)623 {624 if (kind == CodeForCall)625 return codeBlockForCall();626 ASSERT(kind == CodeForConstruct);627 return codeBlockForConstruct();628 }629 630 FunctionCodeBlock* baselineCodeBlockFor(CodeSpecializationKind);631 632 FunctionCodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)633 {634 return baselineCodeBlockFor(kind);635 }636 637 RefPtr<TypeSet> returnStatementTypeSet()638 {639 if (!m_returnStatementTypeSet)640 m_returnStatementTypeSet = TypeSet::create();641 642 return m_returnStatementTypeSet;643 }644 645 FunctionMode functionMode() { return m_unlinkedExecutable->functionMode(); }646 bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }647 ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); }648 bool isClass() const { return !classSource().isNull(); }649 bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }650 bool isGetter() const { return parseMode() == SourceParseMode::GetterMode; }651 bool isSetter() const { return parseMode() == SourceParseMode::SetterMode; }652 bool isGenerator() const { return SourceParseModeSet(SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(parseMode()); }653 bool isMethod() const { return parseMode() == SourceParseMode::MethodMode; }654 bool hasCallerAndArgumentsProperties() const655 {656 // Per https://tc39.github.io/ecma262/#sec-forbidden-extensions, only sloppy-mode non-builtin functions in old-style (pre-ES6) syntactic forms can contain657 // "caller" and "arguments".658 return !isStrictMode() && parseMode() == SourceParseMode::NormalFunctionMode && !isClassConstructorFunction();659 }660 bool hasPrototypeProperty() const661 {662 return SourceParseModeSet(663 SourceParseMode::NormalFunctionMode,664 SourceParseMode::GeneratorBodyMode,665 SourceParseMode::GeneratorWrapperFunctionMode666 ).contains(parseMode()) || isClass();667 }668 DerivedContextType derivedContextType() const { return m_unlinkedExecutable->derivedContextType(); }669 bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }670 const Identifier& name() { return m_unlinkedExecutable->name(); }671 const Identifier& ecmaName() { return m_unlinkedExecutable->ecmaName(); }672 const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }673 unsigned parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!674 unsigned functionLength() const { return m_unlinkedExecutable->functionLength(); }675 SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); }676 JSParserScriptMode scriptMode() const { return m_unlinkedExecutable->scriptMode(); }677 const SourceCode& classSource() const { return m_unlinkedExecutable->classSource(); }678 679 static void visitChildren(JSCell*, SlotVisitor&);680 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)681 {682 return Structure::create(vm, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), info());683 }684 685 unsigned parametersStartOffset() const { return m_parametersStartOffset; }686 687 void overrideParameterAndTypeProfilingStartEndOffsets(unsigned parametersStartOffset, unsigned typeProfilingStartOffset, unsigned typeProfilingEndOffset)688 {689 m_parametersStartOffset = parametersStartOffset;690 m_typeProfilingStartOffset = typeProfilingStartOffset;691 m_typeProfilingEndOffset = typeProfilingEndOffset;692 }693 694 DECLARE_INFO;695 696 InferredValue* singletonFunction() { return m_singletonFunction.get(); }697 698 private:699 friend class ExecutableBase;700 FunctionExecutable(701 VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine,702 unsigned lastLine, unsigned startColumn, unsigned endColumn, Intrinsic);703 704 void finishCreation(VM&);705 706 friend class ScriptExecutable;707 708 unsigned m_parametersStartOffset;709 WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;710 WriteBarrier<FunctionCodeBlock> m_codeBlockForCall;711 WriteBarrier<FunctionCodeBlock> m_codeBlockForConstruct;712 RefPtr<TypeSet> m_returnStatementTypeSet;713 WriteBarrier<InferredValue> m_singletonFunction;714 };715 716 #if ENABLE(WEBASSEMBLY)717 class WebAssemblyExecutable final : public ExecutableBase {718 public:719 typedef ExecutableBase Base;720 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;721 722 static WebAssemblyExecutable* create(VM& vm, const SourceCode& source, JSWasmModule* module, unsigned functionIndex)723 {724 WebAssemblyExecutable* executable = new (NotNull, allocateCell<WebAssemblyExecutable>(vm.heap)) WebAssemblyExecutable(vm, source, module, functionIndex);725 executable->finishCreation(vm);726 return executable;727 }728 729 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)730 {731 return Structure::create(vm, globalObject, proto, TypeInfo(WebAssemblyExecutableType, StructureFlags), info());732 }733 734 static void destroy(JSCell*);735 736 DECLARE_INFO;737 738 void prepareForExecution(VM&);739 740 WebAssemblyCodeBlock* codeBlockForCall()741 {742 return m_codeBlockForCall.get();743 }744 745 private:746 friend class ExecutableBase;747 WebAssemblyExecutable(VM&, const SourceCode&, JSWasmModule*, unsigned functionIndex);748 749 static void visitChildren(JSCell*, SlotVisitor&);750 751 SourceCode m_source;752 WriteBarrier<JSWasmModule> m_module;753 unsigned m_functionIndex;754 755 WriteBarrier<WebAssemblyCodeBlock> m_codeBlockForCall;756 };757 #endif758 759 template <typename ExecutableType>760 JSObject* ScriptExecutable::prepareForExecution(VM& vm, JSFunction* function, JSScope* scope, CodeSpecializationKind kind, CodeBlock*& resultCodeBlock)761 {762 if (hasJITCodeFor(kind)) {763 if (std::is_same<ExecutableType, EvalExecutable>::value)764 resultCodeBlock = jsCast<CodeBlock*>(jsCast<EvalExecutable*>(this)->codeBlock());765 else if (std::is_same<ExecutableType, ProgramExecutable>::value)766 resultCodeBlock = jsCast<CodeBlock*>(jsCast<ProgramExecutable*>(this)->codeBlock());767 else if (std::is_same<ExecutableType, ModuleProgramExecutable>::value)768 resultCodeBlock = jsCast<CodeBlock*>(jsCast<ModuleProgramExecutable*>(this)->codeBlock());769 else if (std::is_same<ExecutableType, FunctionExecutable>::value)770 resultCodeBlock = jsCast<CodeBlock*>(jsCast<FunctionExecutable*>(this)->codeBlockFor(kind));771 else772 RELEASE_ASSERT_NOT_REACHED();773 return nullptr;774 }775 return prepareForExecutionImpl(vm, function, scope, kind, resultCodeBlock);776 }777 778 78 } // namespace JSC
Note:
See TracChangeset
for help on using the changeset viewer.