WebKit Bugzilla
Attachment 368915 Details for
Bug 197552
: [JSC] Generator CodeBlock generation should be idempotent
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-197552-20190503012853.patch (text/plain), 97.39 KB, created by
Yusuke Suzuki
on 2019-05-03 01:28:54 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2019-05-03 01:28:54 PDT
Size:
97.39 KB
patch
obsolete
>Subversion Revision: 244868 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 84b44232a66053607fdb670f49f399796d89a55c..d0eb5d256372bd91adf4961e083723ca6612a99b 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,133 @@ >+2019-05-03 Yusuke Suzuki <ysuzuki@apple.com> >+ >+ [JSC] Generator CodeBlock generation should be idempotent >+ https://bugs.webkit.org/show_bug.cgi?id=197552 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ ES6 Generator saves and resumes the current execution state. Since ES6 generator can save the execution state at expression >+ granularity (not statement granularity), the saved state involves locals. But if the underlying CodeBlock is jettisoned and >+ recompiled with different code generation option (like, debugger, type profiler etc.), the generated instructions can be largely >+ different and it does not have the same state previously used. If we resume the previously created generator with the newly >+ generator function, resuming is messed up. >+ >+ function* gen () { ... } >+ var g = gen(); >+ g.next(); >+ >+ // CodeBlock is destroyed & Debugger is enabled. >+ >+ g.next(); >+ >+ In this patch, >+ >+ 1. In generatorification, we use index Identifier (localN => Identifier("N")) instead of private symbols to generate the same >+ instructions every time we regenerate the CodeBlock. >+ >+ 2. We decouple the options which can affect on the generated code (Debugger, TypeProfiler, ControlFlowProfiler) from the BytecodeGenerator, >+ and pass them as a parameter, OptionSet<CodeGeneratorMode>. >+ >+ 3. Generator ScriptExecutable remembers the previous CodeGeneratorMode and reuses this parameter to regenerate CodeBlock. It means that, >+ even if the debugger is enabled, previously created generators are not debuggable. But newly created generators are debuggable. >+ >+ * bytecode/BytecodeGeneratorification.cpp: >+ (JSC::BytecodeGeneratorification::storageForGeneratorLocal): >+ (JSC::BytecodeGeneratorification::run): >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::finishCreation): >+ (JSC::CodeBlock::setConstantRegisters): >+ * bytecode/UnlinkedCodeBlock.cpp: >+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): >+ * bytecode/UnlinkedCodeBlock.h: >+ (JSC::UnlinkedCodeBlock::wasCompiledWithDebuggingOpcodes const): >+ (JSC::UnlinkedCodeBlock::wasCompiledWithTypeProfilerOpcodes const): >+ (JSC::UnlinkedCodeBlock::wasCompiledWithControlFlowProfilerOpcodes const): >+ (JSC::UnlinkedCodeBlock::codeGenerationMode const): >+ * bytecode/UnlinkedEvalCodeBlock.h: >+ * bytecode/UnlinkedFunctionCodeBlock.h: >+ * bytecode/UnlinkedFunctionExecutable.cpp: >+ (JSC::generateUnlinkedFunctionCodeBlock): >+ (JSC::UnlinkedFunctionExecutable::fromGlobalCode): >+ (JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor): >+ * bytecode/UnlinkedFunctionExecutable.h: >+ * bytecode/UnlinkedGlobalCodeBlock.h: >+ (JSC::UnlinkedGlobalCodeBlock::UnlinkedGlobalCodeBlock): >+ * bytecode/UnlinkedModuleProgramCodeBlock.h: >+ * bytecode/UnlinkedProgramCodeBlock.h: >+ * bytecompiler/BytecodeGenerator.cpp: >+ (JSC::BytecodeGenerator::BytecodeGenerator): >+ (JSC::BytecodeGenerator::emitTypeProfilerExpressionInfo): >+ (JSC::BytecodeGenerator::emitProfileType): >+ (JSC::BytecodeGenerator::emitProfileControlFlow): >+ (JSC::BytecodeGenerator::pushLexicalScopeInternal): >+ (JSC::BytecodeGenerator::popLexicalScopeInternal): >+ (JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration): >+ (JSC::BytecodeGenerator::emitCall): >+ (JSC::BytecodeGenerator::emitCallVarargs): >+ (JSC::BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary): >+ (JSC::BytecodeGenerator::emitLogShadowChickenTailIfNecessary): >+ (JSC::BytecodeGenerator::emitDebugHook): >+ * bytecompiler/BytecodeGenerator.h: >+ (JSC::BytecodeGenerator::generate): >+ (JSC::BytecodeGenerator::shouldEmitDebugHooks const): >+ (JSC::BytecodeGenerator::shouldEmitTypeProfilerHooks const): >+ (JSC::BytecodeGenerator::shouldEmitControlFlowProfilerHooks const): >+ * bytecompiler/NodesCodegen.cpp: >+ (JSC::PrefixNode::emitResolve): >+ (JSC::EmptyVarExpression::emitBytecode): >+ (JSC::ReturnNode::emitBytecode): >+ (JSC::FunctionNode::emitBytecode): >+ * interpreter/Interpreter.cpp: >+ (JSC::Interpreter::executeCall): >+ * parser/ParserModes.h: >+ (): Deleted. >+ * parser/SourceCodeKey.h: >+ (JSC::SourceCodeFlags::SourceCodeFlags): >+ (JSC::SourceCodeKey::SourceCodeKey): >+ * runtime/CachedTypes.cpp: >+ (JSC::CachedCodeBlock::isClassContext const): >+ (JSC::CachedCodeBlock::codeGenerationMode const): >+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): >+ (JSC::CachedCodeBlock<CodeBlockType>::encode): >+ (JSC::CachedCodeBlock::wasCompiledWithDebuggingOpcodes const): Deleted. >+ * runtime/CodeCache.cpp: >+ (JSC::CodeCache::getUnlinkedGlobalCodeBlock): >+ (JSC::CodeCache::getUnlinkedProgramCodeBlock): >+ (JSC::CodeCache::getUnlinkedEvalCodeBlock): >+ (JSC::CodeCache::getUnlinkedModuleProgramCodeBlock): >+ (JSC::CodeCache::getUnlinkedGlobalFunctionExecutable): >+ (JSC::generateUnlinkedCodeBlockForFunctions): >+ (JSC::sourceCodeKeyForSerializedBytecode): >+ (JSC::sourceCodeKeyForSerializedProgram): >+ (JSC::sourceCodeKeyForSerializedModule): >+ (JSC::serializeBytecode): >+ * runtime/CodeCache.h: >+ (JSC::generateUnlinkedCodeBlockImpl): >+ (JSC::generateUnlinkedCodeBlock): >+ * runtime/CommonSlowPaths.cpp: >+ (JSC::SLOW_PATH_DECL): >+ * runtime/Completion.cpp: >+ (JSC::generateProgramBytecode): >+ (JSC::generateModuleBytecode): >+ * runtime/DirectEvalExecutable.cpp: >+ (JSC::DirectEvalExecutable::create): >+ * runtime/IndirectEvalExecutable.cpp: >+ (JSC::IndirectEvalExecutable::create): >+ * runtime/JSGlobalObject.h: >+ (JSC::JSGlobalObject::defaultCodeGenerationMode const): >+ * runtime/ModuleProgramExecutable.cpp: >+ (JSC::ModuleProgramExecutable::create): >+ * runtime/ProgramExecutable.cpp: >+ (JSC::ProgramExecutable::initializeGlobalProperties): >+ * runtime/ScriptExecutable.cpp: >+ (JSC::ScriptExecutable::ScriptExecutable): >+ (JSC::ScriptExecutable::newCodeBlockFor): >+ * runtime/ScriptExecutable.h: >+ * tools/JSDollarVM.cpp: >+ (JSC::changeDebuggerModeWhenIdle): >+ (JSC::functionEnableDebuggerModeWhenIdle): >+ (JSC::functionDisableDebuggerModeWhenIdle): >+ > 2019-05-01 Saam barati <sbarati@apple.com> > > Baseline JIT should do argument value profiling after checking for stack overflow >diff --git a/Source/JavaScriptCore/bytecode/BytecodeGeneratorification.cpp b/Source/JavaScriptCore/bytecode/BytecodeGeneratorification.cpp >index eebeb4dfba58b59c79b470c5727f7b017a114616..2e6dcc828cc84382b653e9f0f49d8d9ca39cfbfe 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeGeneratorification.cpp >+++ b/Source/JavaScriptCore/bytecode/BytecodeGeneratorification.cpp >@@ -146,7 +146,7 @@ class BytecodeGeneratorification { > } > > private: >- Storage storageForGeneratorLocal(unsigned index) >+ Storage storageForGeneratorLocal(VM& vm, unsigned index) > { > // We assign a symbol to a register. There is one-on-one corresponding between a register and a symbol. > // By doing so, we allocate the specific storage to save the given register. >@@ -158,7 +158,7 @@ class BytecodeGeneratorification { > if (Optional<Storage> storage = m_storages[index]) > return *storage; > >- Identifier identifier = Identifier::fromUid(PrivateName()); >+ Identifier identifier = Identifier::from(&vm, index); > unsigned identifierIndex = m_codeBlock->numberOfIdentifiers(); > m_codeBlock->addIdentifier(identifier); > ScopeOffset scopeOffset = m_generatorFrameSymbolTable->takeNextScopeOffset(NoLockingNecessary); >@@ -211,6 +211,7 @@ void BytecodeGeneratorification::run() > { > // We calculate the liveness at each merge point. This gives us the information which registers should be saved and resumed conservatively. > >+ VM& vm = *m_bytecodeGenerator.vm(); > { > GeneratorLivenessAnalysis pass(*this); > pass.run(m_codeBlock, m_instructions); >@@ -244,7 +245,7 @@ void BytecodeGeneratorification::run() > rewriter.insertFragmentBefore(instruction, [&] (BytecodeRewriter::Fragment& fragment) { > data.liveness.forEachSetBit([&](size_t index) { > VirtualRegister operand = virtualRegisterForLocal(index); >- Storage storage = storageForGeneratorLocal(index); >+ Storage storage = storageForGeneratorLocal(vm, index); > > fragment.appendInstruction<OpPutToScope>( > scope, // scope >@@ -264,7 +265,7 @@ void BytecodeGeneratorification::run() > rewriter.insertFragmentAfter(instruction, [&] (BytecodeRewriter::Fragment& fragment) { > data.liveness.forEachSetBit([&](size_t index) { > VirtualRegister operand = virtualRegisterForLocal(index); >- Storage storage = storageForGeneratorLocal(index); >+ Storage storage = storageForGeneratorLocal(vm, index); > > fragment.appendInstruction<OpGetFromScope>( > operand, // dst >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index 09e8c228a4c491bc9f3e86528ca6b58070dcde81..7b191cd2bec07ce930305cddc27376d8c67f9e5b 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -392,7 +392,7 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink > > auto throwScope = DECLARE_THROW_SCOPE(vm); > >- if (vm.typeProfiler() || vm.controlFlowProfiler()) >+ if (m_unlinkedCode->wasCompiledWithTypeProfilerOpcodes() || m_unlinkedCode->wasCompiledWithControlFlowProfilerOpcodes()) > vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(vm), ownerExecutable->typeProfilingEndOffset(vm)); > > setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation()); >@@ -408,14 +408,14 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink > // the module environments before linking the code block. We replace the stored symbol table with the already cloned one. > if (UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock = jsDynamicCast<UnlinkedModuleProgramCodeBlock*>(vm, unlinkedCodeBlock)) { > SymbolTable* clonedSymbolTable = jsCast<ModuleProgramExecutable*>(ownerExecutable)->moduleEnvironmentSymbolTable(); >- if (vm.typeProfiler()) { >+ if (m_unlinkedCode->wasCompiledWithTypeProfilerOpcodes()) { > ConcurrentJSLocker locker(clonedSymbolTable->m_lock); > clonedSymbolTable->prepareForTypeProfiling(locker); > } > replaceConstant(unlinkedModuleProgramCodeBlock->moduleEnvironmentSymbolTableConstantRegisterOffset(), clonedSymbolTable); > } > >- bool shouldUpdateFunctionHasExecutedCache = vm.typeProfiler() || vm.controlFlowProfiler(); >+ bool shouldUpdateFunctionHasExecutedCache = m_unlinkedCode->wasCompiledWithTypeProfilerOpcodes() || m_unlinkedCode->wasCompiledWithControlFlowProfilerOpcodes(); > m_functionDecls = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionDecls()); > for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) { > UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i); >@@ -672,7 +672,7 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink > } > > case op_profile_type: { >- RELEASE_ASSERT(vm.typeProfiler()); >+ RELEASE_ASSERT(m_unlinkedCode->wasCompiledWithTypeProfilerOpcodes()); > > INITIALIZE_METADATA(OpProfileType) > >@@ -781,7 +781,7 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink > #undef LINK_FIELD > #undef LINK > >- if (vm.controlFlowProfiler()) >+ if (m_unlinkedCode->wasCompiledWithControlFlowProfilerOpcodes()) > insertBasicBlockBoundariesForControlFlowProfiler(); > > // Set optimization thresholds only after instructions is initialized, since these >@@ -880,7 +880,6 @@ void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& consta > ASSERT(constants.size() == constantsSourceCodeRepresentation.size()); > size_t count = constants.size(); > m_constantRegisters.resizeToFit(count); >- bool hasTypeProfiler = !!vm.typeProfiler(); > for (size_t i = 0; i < count; i++) { > JSValue constant = constants[i].get(); > >@@ -888,7 +887,7 @@ void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& consta > if (constant.isCell()) { > JSCell* cell = constant.asCell(); > if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(vm, cell)) { >- if (hasTypeProfiler) { >+ if (m_unlinkedCode->wasCompiledWithTypeProfilerOpcodes()) { > ConcurrentJSLocker locker(symbolTable->m_lock); > symbolTable->prepareForTypeProfiling(locker); > } >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >index 7fba73d7341ef6247d9619e8e2c9cf224985b675..f9c3ba9d71647d423db18a14419804d34f30f441 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >@@ -54,7 +54,7 @@ namespace JSC { > > const ClassInfo UnlinkedCodeBlock::s_info = { "UnlinkedCodeBlock", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(UnlinkedCodeBlock) }; > >-UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info, DebuggerMode debuggerMode) >+UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) > : Base(*vm, structure) > , m_usesEval(info.usesEval()) > , m_isStrictMode(info.isStrictMode()) >@@ -65,14 +65,14 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType code > , m_scriptMode(static_cast<unsigned>(info.scriptMode())) > , m_isArrowFunctionContext(info.isArrowFunctionContext()) > , m_isClassContext(info.isClassContext()) >- , m_wasCompiledWithDebuggingOpcodes(debuggerMode == DebuggerMode::DebuggerOn || Options::forceDebuggerBytecodeGeneration()) >+ , m_hasTailCalls(false) > , m_constructorKind(static_cast<unsigned>(info.constructorKind())) > , m_derivedContextType(static_cast<unsigned>(info.derivedContextType())) > , m_evalContextType(static_cast<unsigned>(info.evalContextType())) >- , m_hasTailCalls(false) > , m_codeType(static_cast<unsigned>(codeType)) > , m_didOptimize(static_cast<unsigned>(MixedTriState)) > , m_parseMode(info.parseMode()) >+ , m_codeGenerationMode(codeGenerationMode) > , m_metadata(UnlinkedMetadataTable::create()) > { > for (auto& constantRegisterIndex : m_linkTimeConstants) >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >index 8dc676978c6206ee6913d2894823b9f47227a39e..2a350a1f11cf2131f72c2b4bd809018fe712eff2 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >@@ -331,7 +331,10 @@ class UnlinkedCodeBlock : public JSCell { > > void dumpExpressionRangeInfo(); // For debugging purpose only. > >- bool wasCompiledWithDebuggingOpcodes() const { return m_wasCompiledWithDebuggingOpcodes; } >+ bool wasCompiledWithDebuggingOpcodes() const { return m_codeGenerationMode.contains(CodeGenerationMode::Debugger); } >+ bool wasCompiledWithTypeProfilerOpcodes() const { return m_codeGenerationMode.contains(CodeGenerationMode::TypeProfiler); } >+ bool wasCompiledWithControlFlowProfilerOpcodes() const { return m_codeGenerationMode.contains(CodeGenerationMode::ControlFlowProfiler); } >+ OptionSet<CodeGenerationMode> codeGenerationMode() const { return m_codeGenerationMode; } > > TriState didOptimize() const { return static_cast<TriState>(m_didOptimize); } > void setDidOptimize(TriState didOptimize) { m_didOptimize = static_cast<unsigned>(didOptimize); } >@@ -369,7 +372,7 @@ class UnlinkedCodeBlock : public JSCell { > > > protected: >- UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&, DebuggerMode); >+ UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&, OptionSet<CodeGenerationMode>); > > template<typename CodeBlockType> > UnlinkedCodeBlock(Decoder&, Structure*, const CachedCodeBlock<CodeBlockType>&); >@@ -415,11 +418,10 @@ class UnlinkedCodeBlock : public JSCell { > unsigned m_scriptMode: 1; > unsigned m_isArrowFunctionContext : 1; > unsigned m_isClassContext : 1; >- unsigned m_wasCompiledWithDebuggingOpcodes : 1; >+ unsigned m_hasTailCalls : 1; > unsigned m_constructorKind : 2; > unsigned m_derivedContextType : 2; > unsigned m_evalContextType : 2; >- unsigned m_hasTailCalls : 1; > unsigned m_codeType : 2; > unsigned m_didOptimize : 2; > public: >@@ -427,6 +429,7 @@ class UnlinkedCodeBlock : public JSCell { > private: > CodeFeatures m_features { 0 }; > SourceParseMode m_parseMode; >+ OptionSet<CodeGenerationMode> m_codeGenerationMode; > > unsigned m_lineCount { 0 }; > unsigned m_endColumn { UINT_MAX }; >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedEvalCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedEvalCodeBlock.h >index 2f32379a01f435c3d018df651935a2e2b03cd01e..9aa1d9696a358f8a5ac783b204028f02916326ba 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedEvalCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedEvalCodeBlock.h >@@ -36,9 +36,9 @@ class UnlinkedEvalCodeBlock final : public UnlinkedGlobalCodeBlock { > typedef UnlinkedGlobalCodeBlock Base; > static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; > >- static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info, DebuggerMode debuggerMode) >+ static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) > { >- UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info, debuggerMode); >+ UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info, codeGenerationMode); > instance->finishCreation(*vm); > return instance; > } >@@ -63,8 +63,8 @@ class UnlinkedEvalCodeBlock final : public UnlinkedGlobalCodeBlock { > private: > friend CachedEvalCodeBlock; > >- UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info, DebuggerMode debuggerMode) >- : Base(vm, structure, EvalCode, info, debuggerMode) >+ UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) >+ : Base(vm, structure, EvalCode, info, codeGenerationMode) > { > } > >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedFunctionCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedFunctionCodeBlock.h >index 65aafc88e597cb20f49fd3272bde15a10dcbdd58..a910e7790bc2810b85e3cea4cda28d35442fecd8 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedFunctionCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedFunctionCodeBlock.h >@@ -36,9 +36,9 @@ class UnlinkedFunctionCodeBlock final : public UnlinkedCodeBlock { > typedef UnlinkedCodeBlock Base; > static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; > >- static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info, DebuggerMode debuggerMode) >+ static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) > { >- UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info, debuggerMode); >+ UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info, codeGenerationMode); > instance->finishCreation(*vm); > return instance; > } >@@ -48,8 +48,8 @@ class UnlinkedFunctionCodeBlock final : public UnlinkedCodeBlock { > private: > friend CachedFunctionCodeBlock; > >- UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info, DebuggerMode debuggerMode) >- : Base(vm, structure, codeType, info, debuggerMode) >+ UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) >+ : Base(vm, structure, codeType, info, codeGenerationMode) > { > } > >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp >index 44d5e5317eb14dc4644edd05f5efe89fcd4d0437..61449db642025ff78b119fdb666c2af59d117fad 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp >+++ b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp >@@ -50,7 +50,7 @@ const ClassInfo UnlinkedFunctionExecutable::s_info = { "UnlinkedFunctionExecutab > > static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock( > VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source, >- CodeSpecializationKind kind, DebuggerMode debuggerMode, >+ CodeSpecializationKind kind, OptionSet<CodeGenerationMode> codeGenerationMode, > UnlinkedFunctionKind functionKind, ParserError& error, SourceParseMode parseMode) > { > JSParserBuiltinMode builtinMode = executable->isBuiltinFunction() ? JSParserBuiltinMode::Builtin : JSParserBuiltinMode::NotBuiltin; >@@ -70,10 +70,10 @@ static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock( > > bool isClassContext = executable->superBinding() == SuperBinding::Needed; > >- UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), scriptMode, executable->superBinding(), parseMode, executable->derivedContextType(), false, isClassContext, EvalContextType::FunctionEvalContext), debuggerMode); >+ UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), scriptMode, executable->superBinding(), parseMode, executable->derivedContextType(), false, isClassContext, EvalContextType::FunctionEvalContext), codeGenerationMode); > > VariableEnvironment parentScopeTDZVariables = executable->parentScopeTDZVariables(); >- error = BytecodeGenerator::generate(vm, function.get(), source, result, debuggerMode, &parentScopeTDZVariables); >+ error = BytecodeGenerator::generate(vm, function.get(), source, result, codeGenerationMode, &parentScopeTDZVariables); > > if (error.isValid()) > return nullptr; >@@ -184,8 +184,8 @@ UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode( > VM& vm = exec.vm(); > auto& globalObject = *exec.lexicalGlobalObject(); > CodeCache* codeCache = vm.codeCache(); >- DebuggerMode debuggerMode = globalObject.hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; >- UnlinkedFunctionExecutable* executable = codeCache->getUnlinkedGlobalFunctionExecutable(vm, name, source, debuggerMode, functionConstructorParametersEndPosition, error); >+ OptionSet<CodeGenerationMode> codeGenerationMode = globalObject.defaultCodeGenerationMode(); >+ UnlinkedFunctionExecutable* executable = codeCache->getUnlinkedGlobalFunctionExecutable(vm, name, source, codeGenerationMode, functionConstructorParametersEndPosition, error); > > if (globalObject.hasDebugger()) > globalObject.debugger()->sourceParsed(&exec, source.provider(), error.line(), error.message()); >@@ -212,7 +212,7 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::unlinkedCodeBlockFor(Code > > UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::unlinkedCodeBlockFor( > VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind, >- DebuggerMode debuggerMode, ParserError& error, SourceParseMode parseMode) >+ OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, SourceParseMode parseMode) > { > if (m_isCached) > decodeCachedCodeBlocks(); >@@ -228,7 +228,7 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::unlinkedCodeBlockFor( > } > > UnlinkedFunctionCodeBlock* result = generateUnlinkedFunctionCodeBlock( >- vm, this, source, specializationKind, debuggerMode, >+ vm, this, source, specializationKind, codeGenerationMode, > isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, > error, parseMode); > >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h >index 3d3956cb5da841583d261f586ff576dd614e15de..1b035977a2bad2ca2b35ca298ca572edc5506071 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h >@@ -118,7 +118,7 @@ class UnlinkedFunctionExecutable final : public JSCell { > UnlinkedFunctionCodeBlock* unlinkedCodeBlockFor(CodeSpecializationKind); > > UnlinkedFunctionCodeBlock* unlinkedCodeBlockFor( >- VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, >+ VM&, const SourceCode&, CodeSpecializationKind, OptionSet<CodeGenerationMode>, > ParserError&, SourceParseMode); > > static UnlinkedFunctionExecutable* fromGlobalCode( >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedGlobalCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedGlobalCodeBlock.h >index 3d042ef486c7d12caf0d32d602e16fb212f6e075..4866c6a3a2bcc02ae960486994c96fb1c8a5c66a 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedGlobalCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedGlobalCodeBlock.h >@@ -34,8 +34,8 @@ class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock { > typedef UnlinkedCodeBlock Base; > > protected: >- UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info, DebuggerMode debuggerMode) >- : Base(vm, structure, codeType, info, debuggerMode) >+ UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) >+ : Base(vm, structure, codeType, info, codeGenerationMode) > { > } > >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedModuleProgramCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedModuleProgramCodeBlock.h >index 3933bfd3e3ae24e6f64f5e0a9d9d1190213006d1..a53d192c7f8051256098f3f69a05be4c4c598fe0 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedModuleProgramCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedModuleProgramCodeBlock.h >@@ -37,9 +37,9 @@ class UnlinkedModuleProgramCodeBlock final : public UnlinkedGlobalCodeBlock { > typedef UnlinkedGlobalCodeBlock Base; > static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; > >- static UnlinkedModuleProgramCodeBlock* create(VM* vm, const ExecutableInfo& info, DebuggerMode debuggerMode) >+ static UnlinkedModuleProgramCodeBlock* create(VM* vm, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) > { >- UnlinkedModuleProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedModuleProgramCodeBlock>(vm->heap)) UnlinkedModuleProgramCodeBlock(vm, vm->unlinkedModuleProgramCodeBlockStructure.get(), info, debuggerMode); >+ UnlinkedModuleProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedModuleProgramCodeBlock>(vm->heap)) UnlinkedModuleProgramCodeBlock(vm, vm->unlinkedModuleProgramCodeBlockStructure.get(), info, codeGenerationMode); > instance->finishCreation(*vm); > return instance; > } >@@ -79,8 +79,8 @@ class UnlinkedModuleProgramCodeBlock final : public UnlinkedGlobalCodeBlock { > private: > friend CachedModuleCodeBlock; > >- UnlinkedModuleProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info, DebuggerMode debuggerMode) >- : Base(vm, structure, ModuleCode, info, debuggerMode) >+ UnlinkedModuleProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) >+ : Base(vm, structure, ModuleCode, info, codeGenerationMode) > { > } > >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedProgramCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedProgramCodeBlock.h >index 76844a37a411952eedaba45c782ddf5553b0cdfe..3184c76ff151adfff3a51c54ae587c11db8cf551 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedProgramCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedProgramCodeBlock.h >@@ -36,9 +36,9 @@ class UnlinkedProgramCodeBlock final : public UnlinkedGlobalCodeBlock { > typedef UnlinkedGlobalCodeBlock Base; > static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; > >- static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info, DebuggerMode debuggerMode) >+ static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) > { >- UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info, debuggerMode); >+ UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info, codeGenerationMode); > instance->finishCreation(*vm); > return instance; > } >@@ -54,8 +54,8 @@ class UnlinkedProgramCodeBlock final : public UnlinkedGlobalCodeBlock { > private: > friend CachedProgramCodeBlock; > >- UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info, DebuggerMode debuggerMode) >- : Base(vm, structure, GlobalCode, info, debuggerMode) >+ UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info, OptionSet<CodeGenerationMode> codeGenerationMode) >+ : Base(vm, structure, GlobalCode, info, codeGenerationMode) > { > } > >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >index 872ba0313bebf088bec764832caef814b808b449..35409a6904b04e8675083c0a25b9d34c076cc98d 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >@@ -328,8 +328,8 @@ ParserError BytecodeGenerator::generate() > return ParserError(ParserError::ErrorNone); > } > >-BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables) >- : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn) >+BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables) >+ : m_codeGenerationMode(codeGenerationMode) > , m_scopeNode(programNode) > , m_codeBlock(vm, codeBlock) > , m_thisRegister(CallFrame::thisArgumentOffset()) >@@ -374,8 +374,8 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedP > } > } > >-BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables) >- : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn) >+BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables) >+ : m_codeGenerationMode(codeGenerationMode) > , m_scopeNode(functionNode) > , m_codeBlock(vm, codeBlock) > , m_codeType(FunctionCode) >@@ -394,9 +394,6 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke > for (auto& constantRegister : m_linkTimeConstantRegisters) > constantRegister = nullptr; > >- if (m_isBuiltinFunction) >- m_shouldEmitDebugHooks = false; >- > allocateCalleeSaveSpace(); > > SymbolTable* functionSymbolTable = SymbolTable::create(*m_vm); >@@ -415,9 +412,9 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke > SourceParseMode parseMode = codeBlock->parseMode(); > > bool containsArrowOrEvalButNotInArrowBlock = ((functionNode->usesArrowFunction() && functionNode->doAnyInnerArrowFunctionsUseAnyFeature()) || functionNode->usesEval()) && !m_codeBlock->isArrowFunction(); >- bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || functionNode->needsActivation() || containsArrowOrEvalButNotInArrowBlock; >+ bool shouldCaptureSomeOfTheThings = shouldEmitDebugHooks() || functionNode->needsActivation() || containsArrowOrEvalButNotInArrowBlock; > >- bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval(); >+ bool shouldCaptureAllOfTheThings = shouldEmitDebugHooks() || codeBlock->usesEval(); > bool needsArguments = ((functionNode->usesArguments() && !codeBlock->isArrowFunction()) || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction())); > > if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode)) { >@@ -488,7 +485,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke > if (shouldCaptureSomeOfTheThings) > m_lexicalEnvironmentRegister = addVar(); > >- if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode) || shouldCaptureSomeOfTheThings || vm.typeProfiler()) >+ if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode) || shouldCaptureSomeOfTheThings || shouldEmitTypeProfilerHooks()) > symbolTableConstantIndex = addConstantValue(functionSymbolTable)->index(); > > // We can allocate the "var" environment if we don't have default parameter expressions. If we have >@@ -855,8 +852,8 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke > pushLexicalScope(m_scopeNode, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions); > } > >-BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables) >- : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn) >+BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables) >+ : m_codeGenerationMode(codeGenerationMode) > , m_scopeNode(evalNode) > , m_codeBlock(vm, codeBlock) > , m_thisRegister(CallFrame::thisArgumentOffset()) >@@ -918,8 +915,8 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod > pushLexicalScope(m_scopeNode, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, shouldInitializeBlockScopedFunctions); > } > >-BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, const VariableEnvironment* parentScopeTDZVariables) >- : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn) >+BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables) >+ : m_codeGenerationMode(codeGenerationMode) > , m_scopeNode(moduleProgramNode) > , m_codeBlock(vm, codeBlock) > , m_thisRegister(CallFrame::thisArgumentOffset()) >@@ -933,16 +930,13 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNod > for (auto& constantRegister : m_linkTimeConstantRegisters) > constantRegister = nullptr; > >- if (m_isBuiltinFunction) >- m_shouldEmitDebugHooks = false; >- > allocateCalleeSaveSpace(); > > SymbolTable* moduleEnvironmentSymbolTable = SymbolTable::create(*m_vm); > moduleEnvironmentSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval); > moduleEnvironmentSymbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope); > >- bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval(); >+ bool shouldCaptureAllOfTheThings = shouldEmitDebugHooks() || codeBlock->usesEval(); > if (shouldCaptureAllOfTheThings) > moduleProgramNode->varDeclarations().markAllVariablesAsCaptured(); > >@@ -995,7 +989,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNod > > // We keep the symbol table in the constant pool. > RegisterID* constantSymbolTable = nullptr; >- if (vm.typeProfiler()) >+ if (shouldEmitTypeProfilerHooks()) > constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable); > else > constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable->cloneScopePart(*m_vm)); >@@ -1785,7 +1779,7 @@ bool BytecodeGenerator::emitEqualityOpImpl(RegisterID* dst, RegisterID* src1, Re > > void BytecodeGenerator::emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot) > { >- ASSERT(vm()->typeProfiler()); >+ ASSERT(shouldEmitTypeProfilerHooks()); > > unsigned start = startDivot.offset; // Ranges are inclusive of their endpoints, AND 0 indexed. > unsigned end = endDivot.offset - 1; // End Ranges already go one past the inclusive range, so subtract 1. >@@ -1795,7 +1789,7 @@ void BytecodeGenerator::emitTypeProfilerExpressionInfo(const JSTextPosition& sta > > void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag) > { >- if (!vm()->typeProfiler()) >+ if (!shouldEmitTypeProfilerHooks()) > return; > > if (!registerToProfile) >@@ -1815,7 +1809,7 @@ void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const JST > > void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag flag, const JSTextPosition& startDivot, const JSTextPosition& endDivot) > { >- if (!vm()->typeProfiler()) >+ if (!shouldEmitTypeProfilerHooks()) > return; > > if (!registerToProfile) >@@ -1827,7 +1821,7 @@ void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, ProfileTy > > void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const Variable& var, const JSTextPosition& startDivot, const JSTextPosition& endDivot) > { >- if (!vm()->typeProfiler()) >+ if (!shouldEmitTypeProfilerHooks()) > return; > > if (!registerToProfile) >@@ -1850,7 +1844,7 @@ void BytecodeGenerator::emitProfileType(RegisterID* registerToProfile, const Var > > void BytecodeGenerator::emitProfileControlFlow(int textOffset) > { >- if (vm()->controlFlowProfiler()) { >+ if (shouldEmitControlFlowProfilerHooks()) { > RELEASE_ASSERT(textOffset >= 0); > > OpProfileControlFlow::emit(this, textOffset); >@@ -1996,7 +1990,7 @@ void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environmen > if (!environment.size()) > return; > >- if (m_shouldEmitDebugHooks) >+ if (shouldEmitDebugHooks()) > environment.markAllVariablesAsCaptured(); > > SymbolTable* symbolTable = SymbolTable::create(*m_vm); >@@ -2024,7 +2018,7 @@ void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environmen > RegisterID* newScope = nullptr; > RegisterID* constantSymbolTable = nullptr; > int symbolTableConstantIndex = 0; >- if (vm()->typeProfiler()) { >+ if (shouldEmitTypeProfilerHooks()) { > constantSymbolTable = addConstantValue(symbolTable); > symbolTableConstantIndex = constantSymbolTable->index(); > } >@@ -2035,7 +2029,7 @@ void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environmen > } else > newScope = addVar(); > if (!constantSymbolTable) { >- ASSERT(!vm()->typeProfiler()); >+ ASSERT(!shouldEmitTypeProfilerHooks()); > constantSymbolTable = addConstantValue(symbolTable->cloneScopePart(*m_vm)); > symbolTableConstantIndex = constantSymbolTable->index(); > } >@@ -2190,7 +2184,7 @@ void BytecodeGenerator::popLexicalScopeInternal(VariableEnvironment& environment > if (!environment.size()) > return; > >- if (m_shouldEmitDebugHooks) >+ if (shouldEmitDebugHooks()) > environment.markAllVariablesAsCaptured(); > > auto stackEntry = m_lexicalScopeStack.takeLast(); >@@ -2225,7 +2219,7 @@ void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvir > VariableEnvironment& environment = node->lexicalVariables(); > if (!environment.size()) > return; >- if (m_shouldEmitDebugHooks) >+ if (shouldEmitDebugHooks()) > environment.markAllVariablesAsCaptured(); > if (!environment.hasCapturedVariables()) > return; >@@ -3244,7 +3238,7 @@ RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, Expec > for (int i = 0; i < CallFrame::headerSizeInRegisters; ++i) > callFrame.append(newTemporary()); > >- if (m_shouldEmitDebugHooks && debuggableCall == DebuggableCall::Yes) >+ if (shouldEmitDebugHooks() && debuggableCall == DebuggableCall::Yes) > emitDebugHook(WillExecuteExpression, divotStart); > > emitExpressionInfo(divot, divotStart, divotEnd); >@@ -3293,7 +3287,7 @@ RegisterID* BytecodeGenerator::emitCallForwardArgumentsInTailPosition(RegisterID > template<typename VarargsOp> > RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall debuggableCall) > { >- if (m_shouldEmitDebugHooks && debuggableCall == DebuggableCall::Yes) >+ if (shouldEmitDebugHooks() && debuggableCall == DebuggableCall::Yes) > emitDebugHook(WillExecuteExpression, divotStart); > > emitExpressionInfo(divot, divotStart, divotEnd); >@@ -3309,14 +3303,14 @@ RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func > > void BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary() > { >- if (!m_shouldEmitDebugHooks && !Options::alwaysUseShadowChicken()) >+ if (!shouldEmitDebugHooks() && !Options::alwaysUseShadowChicken()) > return; > OpLogShadowChickenPrologue::emit(this, scopeRegister()); > } > > void BytecodeGenerator::emitLogShadowChickenTailIfNecessary() > { >- if (!m_shouldEmitDebugHooks && !Options::alwaysUseShadowChicken()) >+ if (!shouldEmitDebugHooks() && !Options::alwaysUseShadowChicken()) > return; > OpLogShadowChickenTail::emit(this, thisRegister(), scopeRegister()); > } >@@ -3513,7 +3507,7 @@ void BytecodeGenerator::emitPopWithScope() > > void BytecodeGenerator::emitDebugHook(DebugHookType debugHookType, const JSTextPosition& divot) > { >- if (!m_shouldEmitDebugHooks) >+ if (!shouldEmitDebugHooks()) > return; > > emitExpressionInfo(divot, divot, divot); >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >index f5305b0877e611b830144465b45c656f4394847c..4426b515c432e18f65e884e8be8cb3c8d4b483b1 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >@@ -372,10 +372,10 @@ namespace JSC { > public: > typedef DeclarationStacks::FunctionStack FunctionStack; > >- BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, DebuggerMode, const VariableEnvironment*); >- BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, const VariableEnvironment*); >- BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, DebuggerMode, const VariableEnvironment*); >- BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, DebuggerMode, const VariableEnvironment*); >+ BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, OptionSet<CodeGenerationMode>, const VariableEnvironment*); >+ BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, OptionSet<CodeGenerationMode>, const VariableEnvironment*); >+ BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, OptionSet<CodeGenerationMode>, const VariableEnvironment*); >+ BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, OptionSet<CodeGenerationMode>, const VariableEnvironment*); > > ~BytecodeGenerator(); > >@@ -394,14 +394,14 @@ namespace JSC { > JSParserScriptMode scriptMode() const { return m_codeBlock->scriptMode(); } > > template<typename Node, typename UnlinkedCodeBlock> >- static ParserError generate(VM& vm, Node* node, const SourceCode& sourceCode, UnlinkedCodeBlock* unlinkedCodeBlock, DebuggerMode debuggerMode, const VariableEnvironment* environment) >+ static ParserError generate(VM& vm, Node* node, const SourceCode& sourceCode, UnlinkedCodeBlock* unlinkedCodeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* environment) > { > MonotonicTime before; > if (UNLIKELY(Options::reportBytecodeCompileTimes())) > before = MonotonicTime::now(); > > DeferGC deferGC(vm.heap); >- auto bytecodeGenerator = std::make_unique<BytecodeGenerator>(vm, node, unlinkedCodeBlock, debuggerMode, environment); >+ auto bytecodeGenerator = std::make_unique<BytecodeGenerator>(vm, node, unlinkedCodeBlock, codeGenerationMode, environment); > auto result = bytecodeGenerator->generate(); > > if (UNLIKELY(Options::reportBytecodeCompileTimes())) { >@@ -985,7 +985,9 @@ namespace JSC { > > bool shouldBeConcernedWithCompletionValue() const { return m_codeType != FunctionCode; } > >- bool shouldEmitDebugHooks() const { return m_shouldEmitDebugHooks; } >+ bool shouldEmitDebugHooks() const { return m_codeGenerationMode.contains(CodeGenerationMode::Debugger) && !m_isBuiltinFunction; } >+ bool shouldEmitTypeProfilerHooks() const { return m_codeGenerationMode.contains(CodeGenerationMode::TypeProfiler); } >+ bool shouldEmitControlFlowProfilerHooks() const { return m_codeGenerationMode.contains(CodeGenerationMode::ControlFlowProfiler); } > > bool isStrictMode() const { return m_codeBlock->isStrictMode(); } > >@@ -1186,7 +1188,7 @@ namespace JSC { > private: > InstructionStreamWriter m_writer; > >- bool m_shouldEmitDebugHooks; >+ OptionSet<CodeGenerationMode> m_codeGenerationMode; > > struct LexicalScopeStackEntry { > SymbolTable* m_symbolTable; >diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp >index 33027e4c69bd257f93c2ccf972ba0a78f86f6405..21301da24ea2559d516d27703086bc4facef4a20 100644 >--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp >+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp >@@ -1781,7 +1781,7 @@ RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* ds > if (var.isReadOnly()) { > generator.emitReadOnlyExceptionIfNeeded(var); > localReg = generator.move(generator.tempDestination(dst), localReg.get()); >- } else if (generator.vm()->typeProfiler()) { >+ } else if (generator.shouldEmitTypeProfilerHooks()) { > RefPtr<RegisterID> tempDst = generator.tempDestination(dst); > generator.move(tempDst.get(), localReg.get()); > emitIncOrDec(generator, tempDst.get(), m_operator); >@@ -2726,7 +2726,7 @@ void DeclarationStatement::emitBytecode(BytecodeGenerator& generator, RegisterID > RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*) > { > // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value. >- if (!generator.vm()->typeProfiler()) >+ if (!generator.shouldEmitTypeProfilerHooks()) > return nullptr; > > Variable var = generator.variable(m_ident); >@@ -3356,7 +3356,7 @@ void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) > generator.emitProfileControlFlow(endOffset()); > // Emitting an unreachable return here is needed in case this op_profile_control_flow is the > // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode. >- if (generator.vm()->controlFlowProfiler()) >+ if (generator.shouldEmitControlFlowProfilerHooks()) > generator.emitReturn(generator.emitLoad(nullptr, jsUndefined())); > } > >@@ -3738,7 +3738,7 @@ void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) > > void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) > { >- if (generator.vm()->typeProfiler()) { >+ if (generator.shouldEmitTypeProfilerHooks()) { > // If the parameter list is non simple one, it is handled in bindValue's code. > if (m_parameters->isSimpleParameterList()) { > for (size_t i = 0; i < m_parameters->size(); i++) { >diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp >index c1f2f1f445e6a10639cd82f9befd10ef608f21a4..ceddcb73d2baefb260330b974589ed62384d984c 100644 >--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp >+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp >@@ -883,6 +883,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT > return checkedReturn(compileError); > > ASSERT(!!newCodeBlock); >+ RELEASE_ASSERT(newCodeBlock->isLive()); > newCodeBlock->m_shouldAlwaysBeInlined = false; > } else > newCodeBlock = 0; >diff --git a/Source/JavaScriptCore/parser/ParserModes.h b/Source/JavaScriptCore/parser/ParserModes.h >index e2a08b16501a4a81f521576e19615e7ace9a938e..e26d9f7bccb68981c2c15540a10400b9c3389c6c 100644 >--- a/Source/JavaScriptCore/parser/ParserModes.h >+++ b/Source/JavaScriptCore/parser/ParserModes.h >@@ -37,7 +37,11 @@ enum class JSParserScriptMode { Classic, Module }; > enum class ConstructorKind { None, Base, Extends }; > enum class SuperBinding { Needed, NotNeeded }; > >-enum DebuggerMode { DebuggerOff, DebuggerOn }; >+enum class CodeGenerationMode : uint8_t { >+ Debugger = 1 << 0, >+ TypeProfiler = 1 << 1, >+ ControlFlowProfiler = 1 << 2, >+}; > > enum class FunctionMode { FunctionExpression, FunctionDeclaration, MethodDefinition }; > >diff --git a/Source/JavaScriptCore/parser/SourceCodeKey.h b/Source/JavaScriptCore/parser/SourceCodeKey.h >index 274ac8b4921bea17c006c5ab48bc2e7bf3175872..7062195ced9041f2b80533ec600fc0104a94874e 100644 >--- a/Source/JavaScriptCore/parser/SourceCodeKey.h >+++ b/Source/JavaScriptCore/parser/SourceCodeKey.h >@@ -33,8 +33,6 @@ > namespace JSC { > > enum class SourceCodeType { EvalType, ProgramType, FunctionType, ModuleType }; >-enum class TypeProfilerEnabled { No, Yes }; >-enum class ControlFlowProfilerEnabled { No, Yes }; > > class SourceCodeFlags { > friend class CachedSourceCodeKey; >@@ -45,11 +43,9 @@ class SourceCodeFlags { > SourceCodeFlags( > SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, > DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext, >- DebuggerMode debuggerMode, TypeProfilerEnabled typeProfilerEnabled, ControlFlowProfilerEnabled controlFlowProfilerEnabled) >+ OptionSet<CodeGenerationMode> codeGenerationMode) > : m_flags( >- (static_cast<unsigned>(debuggerMode) << 8) | >- (static_cast<unsigned>(typeProfilerEnabled) << 7) | >- (static_cast<unsigned>(controlFlowProfilerEnabled) << 6) | >+ (static_cast<unsigned>(codeGenerationMode.toRaw()) << 6) | > (static_cast<unsigned>(scriptMode) << 5) | > (static_cast<unsigned>(isArrowFunctionContext) << 4) | > (static_cast<unsigned>(evalContextType) << 3) | >@@ -82,10 +78,10 @@ class SourceCodeKey { > SourceCodeKey( > const UnlinkedSourceCode& sourceCode, const String& name, SourceCodeType codeType, JSParserStrictMode strictMode, > JSParserScriptMode scriptMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext, >- DebuggerMode debuggerMode, TypeProfilerEnabled typeProfilerEnabled, ControlFlowProfilerEnabled controlFlowProfilerEnabled, Optional<int> functionConstructorParametersEndPosition) >+ OptionSet<CodeGenerationMode> codeGenerationMode, Optional<int> functionConstructorParametersEndPosition) > : m_sourceCode(sourceCode) > , m_name(name) >- , m_flags(codeType, strictMode, scriptMode, derivedContextType, evalContextType, isArrowFunctionContext, debuggerMode, typeProfilerEnabled, controlFlowProfilerEnabled) >+ , m_flags(codeType, strictMode, scriptMode, derivedContextType, evalContextType, isArrowFunctionContext, codeGenerationMode) > , m_functionConstructorParametersEndPosition(functionConstructorParametersEndPosition.valueOr(-1)) > , m_hash(sourceCode.hash() ^ m_flags.bits()) > { >diff --git a/Source/JavaScriptCore/runtime/CachedTypes.cpp b/Source/JavaScriptCore/runtime/CachedTypes.cpp >index 579ad3ddd51e846e82353689f13c5a607f03fd1c..93f2224efb0c0c1e802cbfcbaa3744f3b8eaf600 100644 >--- a/Source/JavaScriptCore/runtime/CachedTypes.cpp >+++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp >@@ -1721,7 +1721,6 @@ class CachedCodeBlock : public CachedObject<CodeBlockType> { > unsigned scriptMode() const { return m_scriptMode; } > unsigned isArrowFunctionContext() const { return m_isArrowFunctionContext; } > unsigned isClassContext() const { return m_isClassContext; } >- unsigned wasCompiledWithDebuggingOpcodes() const { return m_wasCompiledWithDebuggingOpcodes; } > unsigned constructorKind() const { return m_constructorKind; } > unsigned derivedContextType() const { return m_derivedContextType; } > unsigned evalContextType() const { return m_evalContextType; } >@@ -1735,6 +1734,7 @@ class CachedCodeBlock : public CachedObject<CodeBlockType> { > > CodeFeatures features() const { return m_features; } > SourceParseMode parseMode() const { return m_parseMode; } >+ OptionSet<CodeGenerationMode> codeGenerationMode() const { return m_codeGenerationMode; } > unsigned codeType() const { return m_codeType; } > > UnlinkedCodeBlock::RareData* rareData(Decoder& decoder) const { return m_rareData.decode(decoder); } >@@ -1753,7 +1753,6 @@ class CachedCodeBlock : public CachedObject<CodeBlockType> { > unsigned m_scriptMode: 1; > unsigned m_isArrowFunctionContext : 1; > unsigned m_isClassContext : 1; >- unsigned m_wasCompiledWithDebuggingOpcodes : 1; > unsigned m_constructorKind : 2; > unsigned m_derivedContextType : 2; > unsigned m_evalContextType : 2; >@@ -1762,6 +1761,7 @@ class CachedCodeBlock : public CachedObject<CodeBlockType> { > > CodeFeatures m_features; > SourceParseMode m_parseMode; >+ OptionSet<CodeGenerationMode> m_codeGenerationMode; > > unsigned m_lineCount; > unsigned m_endColumn; >@@ -1949,17 +1949,17 @@ ALWAYS_INLINE UnlinkedCodeBlock::UnlinkedCodeBlock(Decoder& decoder, Structure* > , m_scriptMode(cachedCodeBlock.scriptMode()) > , m_isArrowFunctionContext(cachedCodeBlock.isArrowFunctionContext()) > , m_isClassContext(cachedCodeBlock.isClassContext()) >- , m_wasCompiledWithDebuggingOpcodes(cachedCodeBlock.wasCompiledWithDebuggingOpcodes()) >+ , m_hasTailCalls(cachedCodeBlock.hasTailCalls()) > , m_constructorKind(cachedCodeBlock.constructorKind()) > , m_derivedContextType(cachedCodeBlock.derivedContextType()) > , m_evalContextType(cachedCodeBlock.evalContextType()) >- , m_hasTailCalls(cachedCodeBlock.hasTailCalls()) > , m_codeType(cachedCodeBlock.codeType()) > > , m_didOptimize(static_cast<unsigned>(MixedTriState)) > > , m_features(cachedCodeBlock.features()) > , m_parseMode(cachedCodeBlock.parseMode()) >+ , m_codeGenerationMode(cachedCodeBlock.codeGenerationMode()) > > , m_lineCount(cachedCodeBlock.lineCount()) > , m_endColumn(cachedCodeBlock.endColumn()) >@@ -2131,11 +2131,10 @@ ALWAYS_INLINE void CachedCodeBlock<CodeBlockType>::encode(Encoder& encoder, cons > m_scriptMode = codeBlock.m_scriptMode; > m_isArrowFunctionContext = codeBlock.m_isArrowFunctionContext; > m_isClassContext = codeBlock.m_isClassContext; >- m_wasCompiledWithDebuggingOpcodes = codeBlock.m_wasCompiledWithDebuggingOpcodes; >+ m_hasTailCalls = codeBlock.m_hasTailCalls; > m_constructorKind = codeBlock.m_constructorKind; > m_derivedContextType = codeBlock.m_derivedContextType; > m_evalContextType = codeBlock.m_evalContextType; >- m_hasTailCalls = codeBlock.m_hasTailCalls; > m_lineCount = codeBlock.m_lineCount; > m_endColumn = codeBlock.m_endColumn; > m_numVars = codeBlock.m_numVars; >@@ -2143,6 +2142,7 @@ ALWAYS_INLINE void CachedCodeBlock<CodeBlockType>::encode(Encoder& encoder, cons > m_numParameters = codeBlock.m_numParameters; > m_features = codeBlock.m_features; > m_parseMode = codeBlock.m_parseMode; >+ m_codeGenerationMode = codeBlock.m_codeGenerationMode; > m_codeType = codeBlock.m_codeType; > > for (unsigned i = LinkTimeConstantCount; i--;) >diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp >index 6ee965ca451a446e3f5906eeb7270f7664d49dc1..03a92ee64a37d22cf23dd487f5979938ec9b3632 100644 >--- a/Source/JavaScriptCore/runtime/CodeCache.cpp >+++ b/Source/JavaScriptCore/runtime/CodeCache.cpp >@@ -53,15 +53,13 @@ void CodeCacheMap::pruneSlowCase() > } > > template <class UnlinkedCodeBlockType, class ExecutableType> >-UnlinkedCodeBlockType* CodeCache::getUnlinkedGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType) >+UnlinkedCodeBlockType* CodeCache::getUnlinkedGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType) > { > DerivedContextType derivedContextType = executable->derivedContextType(); > bool isArrowFunctionContext = executable->isArrowFunctionContext(); > SourceCodeKey key( > source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, strictMode, scriptMode, >- derivedContextType, evalContextType, isArrowFunctionContext, debuggerMode, >- vm.typeProfiler() ? TypeProfilerEnabled::Yes : TypeProfilerEnabled::No, >- vm.controlFlowProfiler() ? ControlFlowProfilerEnabled::Yes : ControlFlowProfilerEnabled::No, >+ derivedContextType, evalContextType, isArrowFunctionContext, codeGenerationMode, > WTF::nullopt); > UnlinkedCodeBlockType* unlinkedCodeBlock = m_sourceCode.findCacheAndUpdateAge<UnlinkedCodeBlockType>(vm, key); > if (unlinkedCodeBlock && Options::useCodeCache()) { >@@ -78,7 +76,7 @@ UnlinkedCodeBlockType* CodeCache::getUnlinkedGlobalCodeBlock(VM& vm, ExecutableT > } > > VariableEnvironment variablesUnderTDZ; >- unlinkedCodeBlock = generateUnlinkedCodeBlock<UnlinkedCodeBlockType, ExecutableType>(vm, executable, source, strictMode, scriptMode, debuggerMode, error, evalContextType, &variablesUnderTDZ); >+ unlinkedCodeBlock = generateUnlinkedCodeBlock<UnlinkedCodeBlockType, ExecutableType>(vm, executable, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, &variablesUnderTDZ); > > if (unlinkedCodeBlock && Options::useCodeCache()) { > m_sourceCode.addCache(key, SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age())); >@@ -91,22 +89,22 @@ UnlinkedCodeBlockType* CodeCache::getUnlinkedGlobalCodeBlock(VM& vm, ExecutableT > return unlinkedCodeBlock; > } > >-UnlinkedProgramCodeBlock* CodeCache::getUnlinkedProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error) >+UnlinkedProgramCodeBlock* CodeCache::getUnlinkedProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserStrictMode strictMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error) > { >- return getUnlinkedGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, strictMode, JSParserScriptMode::Classic, debuggerMode, error, EvalContextType::None); >+ return getUnlinkedGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, strictMode, JSParserScriptMode::Classic, codeGenerationMode, error, EvalContextType::None); > } > >-UnlinkedEvalCodeBlock* CodeCache::getUnlinkedEvalCodeBlock(VM& vm, IndirectEvalExecutable* executable, const SourceCode& source, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType) >+UnlinkedEvalCodeBlock* CodeCache::getUnlinkedEvalCodeBlock(VM& vm, IndirectEvalExecutable* executable, const SourceCode& source, JSParserStrictMode strictMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType) > { >- return getUnlinkedGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, strictMode, JSParserScriptMode::Classic, debuggerMode, error, evalContextType); >+ return getUnlinkedGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, strictMode, JSParserScriptMode::Classic, codeGenerationMode, error, evalContextType); > } > >-UnlinkedModuleProgramCodeBlock* CodeCache::getUnlinkedModuleProgramCodeBlock(VM& vm, ModuleProgramExecutable* executable, const SourceCode& source, DebuggerMode debuggerMode, ParserError& error) >+UnlinkedModuleProgramCodeBlock* CodeCache::getUnlinkedModuleProgramCodeBlock(VM& vm, ModuleProgramExecutable* executable, const SourceCode& source, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error) > { >- return getUnlinkedGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, JSParserStrictMode::Strict, JSParserScriptMode::Module, debuggerMode, error, EvalContextType::None); >+ return getUnlinkedGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, JSParserStrictMode::Strict, JSParserScriptMode::Module, codeGenerationMode, error, EvalContextType::None); > } > >-UnlinkedFunctionExecutable* CodeCache::getUnlinkedGlobalFunctionExecutable(VM& vm, const Identifier& name, const SourceCode& source, DebuggerMode debuggerMode, Optional<int> functionConstructorParametersEndPosition, ParserError& error) >+UnlinkedFunctionExecutable* CodeCache::getUnlinkedGlobalFunctionExecutable(VM& vm, const Identifier& name, const SourceCode& source, OptionSet<CodeGenerationMode> codeGenerationMode, Optional<int> functionConstructorParametersEndPosition, ParserError& error) > { > bool isArrowFunctionContext = false; > SourceCodeKey key( >@@ -116,9 +114,7 @@ UnlinkedFunctionExecutable* CodeCache::getUnlinkedGlobalFunctionExecutable(VM& v > DerivedContextType::None, > EvalContextType::None, > isArrowFunctionContext, >- debuggerMode, >- vm.typeProfiler() ? TypeProfilerEnabled::Yes : TypeProfilerEnabled::No, >- vm.controlFlowProfiler() ? ControlFlowProfilerEnabled::Yes : ControlFlowProfilerEnabled::No, >+ codeGenerationMode, > functionConstructorParametersEndPosition); > UnlinkedFunctionExecutable* executable = m_sourceCode.findCacheAndUpdateAge<UnlinkedFunctionExecutable>(vm, key); > if (executable && Options::useCodeCache()) { >@@ -178,16 +174,16 @@ void CodeCache::write(VM& vm) > writeCodeBlock(vm, it.key, it.value); > } > >-void generateUnlinkedCodeBlockForFunctions(VM& vm, UnlinkedCodeBlock* unlinkedCodeBlock, const SourceCode& parentSource, DebuggerMode debuggerMode, ParserError& error) >+void generateUnlinkedCodeBlockForFunctions(VM& vm, UnlinkedCodeBlock* unlinkedCodeBlock, const SourceCode& parentSource, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error) > { > auto generate = [&](UnlinkedFunctionExecutable* unlinkedExecutable, CodeSpecializationKind constructorKind) { > if (constructorKind == CodeForConstruct && SourceParseModeSet(SourceParseMode::AsyncArrowFunctionMode, SourceParseMode::AsyncMethodMode, SourceParseMode::AsyncFunctionMode).contains(unlinkedExecutable->parseMode())) > return; > > SourceCode source = unlinkedExecutable->linkedSourceCode(parentSource); >- UnlinkedFunctionCodeBlock* unlinkedFunctionCodeBlock = unlinkedExecutable->unlinkedCodeBlockFor(vm, source, constructorKind, debuggerMode, error, unlinkedExecutable->parseMode()); >+ UnlinkedFunctionCodeBlock* unlinkedFunctionCodeBlock = unlinkedExecutable->unlinkedCodeBlockFor(vm, source, constructorKind, codeGenerationMode, error, unlinkedExecutable->parseMode()); > if (unlinkedFunctionCodeBlock) >- generateUnlinkedCodeBlockForFunctions(vm, unlinkedFunctionCodeBlock, source, debuggerMode, error); >+ generateUnlinkedCodeBlockForFunctions(vm, unlinkedFunctionCodeBlock, source, codeGenerationMode, error); > }; > > // FIXME: We should also generate CodeBlocks for CodeForConstruct >@@ -207,13 +203,11 @@ void writeCodeBlock(VM& vm, const SourceCodeKey& key, const SourceCodeValue& val > key.source().provider().commitCachedBytecode(); > } > >-static SourceCodeKey sourceCodeKeyForSerializedBytecode(VM& vm, const SourceCode& sourceCode, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode) >+static SourceCodeKey sourceCodeKeyForSerializedBytecode(VM&, const SourceCode& sourceCode, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode) > { > return SourceCodeKey( > sourceCode, String(), codeType, strictMode, scriptMode, >- DerivedContextType::None, EvalContextType::None, false, debuggerMode, >- vm.typeProfiler() ? TypeProfilerEnabled::Yes : TypeProfilerEnabled::No, >- vm.controlFlowProfiler() ? ControlFlowProfilerEnabled::Yes : ControlFlowProfilerEnabled::No, >+ DerivedContextType::None, EvalContextType::None, false, codeGenerationMode, > WTF::nullopt); > } > >@@ -221,22 +215,20 @@ SourceCodeKey sourceCodeKeyForSerializedProgram(VM& vm, const SourceCode& source > { > JSParserStrictMode strictMode = JSParserStrictMode::NotStrict; > JSParserScriptMode scriptMode = JSParserScriptMode::Classic; >- DebuggerMode debuggerMode = DebuggerOff; >- return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ProgramType, strictMode, scriptMode, debuggerMode); >+ return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ProgramType, strictMode, scriptMode, { }); > } > > SourceCodeKey sourceCodeKeyForSerializedModule(VM& vm, const SourceCode& sourceCode) > { > JSParserStrictMode strictMode = JSParserStrictMode::Strict; > JSParserScriptMode scriptMode = JSParserScriptMode::Module; >- DebuggerMode debuggerMode = DebuggerOff; >- return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ModuleType, strictMode, scriptMode, debuggerMode); >+ return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ModuleType, strictMode, scriptMode, { }); > } > >-Ref<CachedBytecode> serializeBytecode(VM& vm, UnlinkedCodeBlock* codeBlock, const SourceCode& source, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode) >+Ref<CachedBytecode> serializeBytecode(VM& vm, UnlinkedCodeBlock* codeBlock, const SourceCode& source, SourceCodeType codeType, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode) > { > return encodeCodeBlock(vm, >- sourceCodeKeyForSerializedBytecode(vm, source, codeType, strictMode, scriptMode, debuggerMode), codeBlock); >+ sourceCodeKeyForSerializedBytecode(vm, source, codeType, strictMode, scriptMode, codeGenerationMode), codeBlock); > } > > } >diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h >index 16abd1d078369af664839fa9e2d05ef80d41d7ab..b067f847dae301ceee70658be7659f8e7d3ab36c 100644 >--- a/Source/JavaScriptCore/runtime/CodeCache.h >+++ b/Source/JavaScriptCore/runtime/CodeCache.h >@@ -222,10 +222,10 @@ class CodeCacheMap { > class CodeCache { > WTF_MAKE_FAST_ALLOCATED; > public: >- UnlinkedProgramCodeBlock* getUnlinkedProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserStrictMode, DebuggerMode, ParserError&); >- UnlinkedEvalCodeBlock* getUnlinkedEvalCodeBlock(VM&, IndirectEvalExecutable*, const SourceCode&, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType); >- UnlinkedModuleProgramCodeBlock* getUnlinkedModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, DebuggerMode, ParserError&); >- UnlinkedFunctionExecutable* getUnlinkedGlobalFunctionExecutable(VM&, const Identifier&, const SourceCode&, DebuggerMode, Optional<int> functionConstructorParametersEndPosition, ParserError&); >+ UnlinkedProgramCodeBlock* getUnlinkedProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserStrictMode, OptionSet<CodeGenerationMode>, ParserError&); >+ UnlinkedEvalCodeBlock* getUnlinkedEvalCodeBlock(VM&, IndirectEvalExecutable*, const SourceCode&, JSParserStrictMode, OptionSet<CodeGenerationMode>, ParserError&, EvalContextType); >+ UnlinkedModuleProgramCodeBlock* getUnlinkedModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, OptionSet<CodeGenerationMode>, ParserError&); >+ UnlinkedFunctionExecutable* getUnlinkedGlobalFunctionExecutable(VM&, const Identifier&, const SourceCode&, OptionSet<CodeGenerationMode>, Optional<int> functionConstructorParametersEndPosition, ParserError&); > > void updateCache(const UnlinkedFunctionExecutable*, const SourceCode&, CodeSpecializationKind, const UnlinkedFunctionCodeBlock*); > >@@ -234,7 +234,7 @@ class CodeCache { > > private: > template <class UnlinkedCodeBlockType, class ExecutableType> >- UnlinkedCodeBlockType* getUnlinkedGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserStrictMode, JSParserScriptMode, DebuggerMode, ParserError&, EvalContextType); >+ UnlinkedCodeBlockType* getUnlinkedGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserStrictMode, JSParserScriptMode, OptionSet<CodeGenerationMode>, ParserError&, EvalContextType); > > CodeCacheMap m_sourceCode; > }; >@@ -260,7 +260,7 @@ template <> struct CacheTypes<UnlinkedModuleProgramCodeBlock> { > }; > > template <class UnlinkedCodeBlockType, class ExecutableType = ScriptExecutable> >-UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, DerivedContextType derivedContextType, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ, ExecutableType* executable = nullptr) >+UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, DerivedContextType derivedContextType, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ, ExecutableType* executable = nullptr) > { > typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode; > std::unique_ptr<RootNode> rootNode = parse<RootNode>( >@@ -281,14 +281,14 @@ UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& s > bool isStrictMode = rootNode->features() & StrictModeFeature; > ExecutableInfo executableInfo(usesEval, isStrictMode, false, false, ConstructorKind::None, scriptMode, SuperBinding::NotNeeded, CacheTypes<UnlinkedCodeBlockType>::parseMode, derivedContextType, isArrowFunctionContext, false, evalContextType); > >- UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executableInfo, debuggerMode); >+ UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executableInfo, codeGenerationMode); > unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), lineCount, unlinkedEndColumn); > if (!source.provider()->sourceURLDirective().isNull()) > unlinkedCodeBlock->setSourceURLDirective(source.provider()->sourceURLDirective()); > if (!source.provider()->sourceMappingURLDirective().isNull()) > unlinkedCodeBlock->setSourceMappingURLDirective(source.provider()->sourceMappingURLDirective()); > >- error = BytecodeGenerator::generate(vm, rootNode.get(), source, unlinkedCodeBlock, debuggerMode, variablesUnderTDZ); >+ error = BytecodeGenerator::generate(vm, rootNode.get(), source, unlinkedCodeBlock, codeGenerationMode, variablesUnderTDZ); > > if (error.isValid()) > return nullptr; >@@ -297,28 +297,28 @@ UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& s > } > > template <class UnlinkedCodeBlockType, class ExecutableType> >-UnlinkedCodeBlockType* generateUnlinkedCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ) >+UnlinkedCodeBlockType* generateUnlinkedCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ) > { >- return generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType, ExecutableType>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, executable->derivedContextType(), executable->isArrowFunctionContext(), variablesUnderTDZ, executable); >+ return generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType, ExecutableType>(vm, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, executable->derivedContextType(), executable->isArrowFunctionContext(), variablesUnderTDZ, executable); > } > >-void generateUnlinkedCodeBlockForFunctions(VM&, UnlinkedCodeBlock*, const SourceCode&, DebuggerMode, ParserError&); >+void generateUnlinkedCodeBlockForFunctions(VM&, UnlinkedCodeBlock*, const SourceCode&, OptionSet<CodeGenerationMode>, ParserError&); > > template <class UnlinkedCodeBlockType> > std::enable_if_t<!std::is_same<UnlinkedCodeBlockType, UnlinkedEvalCodeBlock>::value, UnlinkedCodeBlockType*> >-recursivelyGenerateUnlinkedCodeBlock(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ) >+recursivelyGenerateUnlinkedCodeBlock(VM& vm, const SourceCode& source, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, OptionSet<CodeGenerationMode> codeGenerationMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ) > { > bool isArrowFunctionContext = false; >- UnlinkedCodeBlockType* unlinkedCodeBlock = generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, DerivedContextType::None, isArrowFunctionContext, variablesUnderTDZ); >+ UnlinkedCodeBlockType* unlinkedCodeBlock = generateUnlinkedCodeBlockImpl<UnlinkedCodeBlockType>(vm, source, strictMode, scriptMode, codeGenerationMode, error, evalContextType, DerivedContextType::None, isArrowFunctionContext, variablesUnderTDZ); > if (!unlinkedCodeBlock) > return nullptr; > >- generateUnlinkedCodeBlockForFunctions(vm, unlinkedCodeBlock, source, debuggerMode, error); >+ generateUnlinkedCodeBlockForFunctions(vm, unlinkedCodeBlock, source, codeGenerationMode, error); > return unlinkedCodeBlock; > } > > void writeCodeBlock(VM&, const SourceCodeKey&, const SourceCodeValue&); >-Ref<CachedBytecode> serializeBytecode(VM&, UnlinkedCodeBlock*, const SourceCode&, SourceCodeType, JSParserStrictMode, JSParserScriptMode, DebuggerMode); >+Ref<CachedBytecode> serializeBytecode(VM&, UnlinkedCodeBlock*, const SourceCode&, SourceCodeType, JSParserStrictMode, JSParserScriptMode, OptionSet<CodeGenerationMode>); > SourceCodeKey sourceCodeKeyForSerializedProgram(VM&, const SourceCode&); > SourceCodeKey sourceCodeKeyForSerializedModule(VM&, const SourceCode&); > >diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >index 8544188836fe689cd8a67d2bff437252173cf5be..c7bcd6d5b93026cbbf7dac2bf330db4173a6dba6 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -1063,6 +1063,8 @@ SLOW_PATH_DECL(slow_path_resolve_scope) > // Proxy can throw an error here, e.g. Proxy in with statement's @unscopables. > CHECK_EXCEPTION(); > >+ RELEASE_ASSERT(resolvedScope->inherits<JSScope>(vm)); >+ > ResolveType resolveType = metadata.m_resolveType; > > // ModuleVar does not keep the scope register value alive in DFG. >diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp >index 27237b1bb09e3c6b57469316666545ebdcc4d2a4..19796af4f89d2e881fb7d579602c094f7e5fea61 100644 >--- a/Source/JavaScriptCore/runtime/Completion.cpp >+++ b/Source/JavaScriptCore/runtime/Completion.cpp >@@ -99,13 +99,12 @@ Ref<CachedBytecode> generateProgramBytecode(VM& vm, const SourceCode& source, Pa > VariableEnvironment variablesUnderTDZ; > JSParserStrictMode strictMode = JSParserStrictMode::NotStrict; > JSParserScriptMode scriptMode = JSParserScriptMode::Classic; >- DebuggerMode debuggerMode = DebuggerOff; > EvalContextType evalContextType = EvalContextType::None; > >- UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedProgramCodeBlock>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, &variablesUnderTDZ); >+ UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, error, evalContextType, &variablesUnderTDZ); > if (!unlinkedCodeBlock) > return CachedBytecode::create(); >- return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, debuggerMode); >+ return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, { }); > } > > Ref<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, ParserError& error) >@@ -116,13 +115,12 @@ Ref<CachedBytecode> generateModuleBytecode(VM& vm, const SourceCode& source, Par > VariableEnvironment variablesUnderTDZ; > JSParserStrictMode strictMode = JSParserStrictMode::Strict; > JSParserScriptMode scriptMode = JSParserScriptMode::Module; >- DebuggerMode debuggerMode = DebuggerOff; > EvalContextType evalContextType = EvalContextType::None; > >- UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, &variablesUnderTDZ); >+ UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, source, strictMode, scriptMode, { }, error, evalContextType, &variablesUnderTDZ); > if (!unlinkedCodeBlock) > return CachedBytecode::create(); >- return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, debuggerMode); >+ return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, { }); > } > > JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException) >diff --git a/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp b/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp >index 96016c07c58292d4c1a458a0b41e0445fc92d5ff..73309ae1b163959f029572cc47f64f9dd03017ef 100644 >--- a/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/DirectEvalExecutable.cpp >@@ -51,11 +51,11 @@ DirectEvalExecutable* DirectEvalExecutable::create(ExecState* exec, const Source > > ParserError error; > JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict; >- DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; >+ OptionSet<CodeGenerationMode> codeGenerationMode = globalObject->defaultCodeGenerationMode(); > > // We don't bother with CodeCache here because direct eval uses a specialized DirectEvalCodeCache. > UnlinkedEvalCodeBlock* unlinkedEvalCode = generateUnlinkedCodeBlock<UnlinkedEvalCodeBlock>( >- vm, executable, executable->source(), strictMode, JSParserScriptMode::Classic, debuggerMode, error, evalContextType, variablesUnderTDZ); >+ vm, executable, executable->source(), strictMode, JSParserScriptMode::Classic, codeGenerationMode, error, evalContextType, variablesUnderTDZ); > > if (globalObject->hasDebugger()) > globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message()); >diff --git a/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp b/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp >index 50ab3739a9a4f844758a916110e52eb90edcf201..dad902c83de5469f6e251548758f6631eb2ae0a6 100644 >--- a/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/IndirectEvalExecutable.cpp >@@ -51,10 +51,10 @@ IndirectEvalExecutable* IndirectEvalExecutable::create(ExecState* exec, const So > > ParserError error; > JSParserStrictMode strictMode = executable->isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict; >- DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; >+ OptionSet<CodeGenerationMode> codeGenerationMode = globalObject->defaultCodeGenerationMode(); > > UnlinkedEvalCodeBlock* unlinkedEvalCode = vm.codeCache()->getUnlinkedEvalCodeBlock( >- vm, executable, executable->source(), strictMode, debuggerMode, error, evalContextType); >+ vm, executable, executable->source(), strictMode, codeGenerationMode, error, evalContextType); > > if (globalObject->hasDebugger()) > globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message()); >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h >index 8f60764951902a260286bd4a67d84d28ad2a6d59..451719568002f6baf69650b146afc125f180b1bf 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h >@@ -38,6 +38,7 @@ > #include "LazyProperty.h" > #include "LazyClassStructure.h" > #include "NumberPrototype.h" >+#include "ParserModes.h" > #include "RegExpGlobalData.h" > #include "RuntimeFlags.h" > #include "SpecialPointer.h" >@@ -970,6 +971,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > VM& vm() const { return m_vm; } > JSObject* globalThis() const; > WriteBarrier<JSObject>* addressOfGlobalThis() { return &m_globalThis; } >+ OptionSet<CodeGenerationMode> defaultCodeGenerationMode() const; > > static Structure* createStructure(VM& vm, JSValue prototype) > { >@@ -1139,4 +1141,16 @@ inline JSObject* JSGlobalObject::globalThis() const > return m_globalThis.get(); > } > >+inline OptionSet<CodeGenerationMode> JSGlobalObject::defaultCodeGenerationMode() const >+{ >+ OptionSet<CodeGenerationMode> codeGenerationMode; >+ if (hasInteractiveDebugger() || Options::forceDebuggerBytecodeGeneration()) >+ codeGenerationMode.add(CodeGenerationMode::Debugger); >+ if (m_vm.typeProfiler()) >+ codeGenerationMode.add(CodeGenerationMode::TypeProfiler); >+ if (m_vm.controlFlowProfiler()) >+ codeGenerationMode.add(CodeGenerationMode::ControlFlowProfiler); >+ return codeGenerationMode; >+} >+ > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp b/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp >index 232b418872b87c8279a951519a677bf2fc5e2638..4373b6478c42bbd20f0ebd12ee6c3584586e8d93 100644 >--- a/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp >@@ -61,9 +61,9 @@ ModuleProgramExecutable* ModuleProgramExecutable::create(ExecState* exec, const > executable->finishCreation(exec->vm()); > > ParserError error; >- DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; >+ OptionSet<CodeGenerationMode> codeGenerationMode = globalObject->defaultCodeGenerationMode(); > UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCode = vm.codeCache()->getUnlinkedModuleProgramCodeBlock( >- vm, executable, executable->source(), debuggerMode, error); >+ vm, executable, executable->source(), codeGenerationMode, error); > > if (globalObject->hasDebugger()) > globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message()); >diff --git a/Source/JavaScriptCore/runtime/ProgramExecutable.cpp b/Source/JavaScriptCore/runtime/ProgramExecutable.cpp >index 21623bb41c5dd4c02e5059f6d34fd0f8c2c493fa..91054164caa86175bcac2a308869c3f8892ebff5 100644 >--- a/Source/JavaScriptCore/runtime/ProgramExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/ProgramExecutable.cpp >@@ -83,10 +83,9 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF > > ParserError error; > JSParserStrictMode strictMode = isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict; >- DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; >- >+ OptionSet<CodeGenerationMode> codeGenerationMode = globalObject->defaultCodeGenerationMode(); > UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm.codeCache()->getUnlinkedProgramCodeBlock( >- vm, this, source(), strictMode, debuggerMode, error); >+ vm, this, source(), strictMode, codeGenerationMode, error); > > if (globalObject->hasDebugger()) > globalObject->debugger()->sourceParsed(callFrame, source().provider(), error.line(), error.message()); >diff --git a/Source/JavaScriptCore/runtime/ScriptExecutable.cpp b/Source/JavaScriptCore/runtime/ScriptExecutable.cpp >index 0aae2eec51461f355e6b777a39aba72eee4d5722..56a5d4876c90831d299b8de13e61d195f85316e5 100644 >--- a/Source/JavaScriptCore/runtime/ScriptExecutable.cpp >+++ b/Source/JavaScriptCore/runtime/ScriptExecutable.cpp >@@ -57,6 +57,7 @@ ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCod > , m_neverFTLOptimize(false) > , m_isArrowFunctionContext(isInArrowFunctionContext) > , m_canUseOSRExitFuzzing(true) >+ , m_codeForGeneratorBodyWasGenerated(false) > , m_derivedContextType(static_cast<unsigned>(derivedContextType)) > , m_evalContextType(static_cast<unsigned>(evalContextType)) > { >@@ -312,10 +313,19 @@ CodeBlock* ScriptExecutable::newCodeBlockFor( > FunctionExecutable* executable = jsCast<FunctionExecutable*>(this); > RELEASE_ASSERT(!executable->codeBlockFor(kind)); > ParserError error; >- DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; >+ OptionSet<CodeGenerationMode> codeGenerationMode = globalObject->defaultCodeGenerationMode(); >+ // We continue using the same CodeGenerationMode for Generators because live generator objects can >+ // keep the state which is only valid with the CodeBlock compiled with the same CodeGenerationMode. >+ if (isGeneratorOrAsyncFunctionBodyParseMode(executable->parseMode())) { >+ if (!m_codeForGeneratorBodyWasGenerated) { >+ m_codeGenerationModeForGeneratorBody = codeGenerationMode; >+ m_codeForGeneratorBodyWasGenerated = true; >+ } else >+ codeGenerationMode = m_codeGenerationModeForGeneratorBody; >+ } > UnlinkedFunctionCodeBlock* unlinkedCodeBlock = > executable->m_unlinkedExecutable->unlinkedCodeBlockFor( >- *vm, executable->source(), kind, debuggerMode, error, >+ *vm, executable->source(), kind, codeGenerationMode, error, > executable->parseMode()); > recordParse( > executable->m_unlinkedExecutable->features(), >diff --git a/Source/JavaScriptCore/runtime/ScriptExecutable.h b/Source/JavaScriptCore/runtime/ScriptExecutable.h >index 462db80b7570b9306044b7cfafb622d7ea0b32ed..6c3eecc850237cc7f67ee30b47909efc8b9dd2ac 100644 >--- a/Source/JavaScriptCore/runtime/ScriptExecutable.h >+++ b/Source/JavaScriptCore/runtime/ScriptExecutable.h >@@ -141,12 +141,14 @@ class ScriptExecutable : public ExecutableBase { > Intrinsic m_intrinsic { NoIntrinsic }; > bool m_didTryToEnterInLoop { false }; > CodeFeatures m_features; >+ OptionSet<CodeGenerationMode> m_codeGenerationModeForGeneratorBody; > bool m_hasCapturedVariables : 1; > bool m_neverInline : 1; > bool m_neverOptimize : 1; > bool m_neverFTLOptimize : 1; > bool m_isArrowFunctionContext : 1; > bool m_canUseOSRExitFuzzing : 1; >+ bool m_codeForGeneratorBodyWasGenerated : 1; > unsigned m_derivedContextType : 2; // DerivedContextType > unsigned m_evalContextType : 2; // EvalContextType > }; >diff --git a/Source/JavaScriptCore/tools/JSDollarVM.cpp b/Source/JavaScriptCore/tools/JSDollarVM.cpp >index 36321b98bab5b56f6b5e63711b331fdb23012459..d624a70316cb9a2f8163f73f773e227533b11a31 100644 >--- a/Source/JavaScriptCore/tools/JSDollarVM.cpp >+++ b/Source/JavaScriptCore/tools/JSDollarVM.cpp >@@ -2061,9 +2061,9 @@ static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*) > return JSValue::encode(jsUndefined()); > } > >-static EncodedJSValue changeDebuggerModeWhenIdle(ExecState* exec, DebuggerMode mode) >+static EncodedJSValue changeDebuggerModeWhenIdle(ExecState* exec, OptionSet<CodeGenerationMode> codeGenerationMode) > { >- bool newDebuggerMode = (mode == DebuggerOn); >+ bool newDebuggerMode = codeGenerationMode.contains(CodeGenerationMode::Debugger); > if (Options::forceDebuggerBytecodeGeneration() == newDebuggerMode) > return JSValue::encode(jsUndefined()); > >@@ -2071,7 +2071,7 @@ static EncodedJSValue changeDebuggerModeWhenIdle(ExecState* exec, DebuggerMode m > vm->whenIdle([=] () { > Options::forceDebuggerBytecodeGeneration() = newDebuggerMode; > vm->deleteAllCode(PreventCollectionAndDeleteAllCode); >- if (mode == DebuggerMode::DebuggerOn) >+ if (newDebuggerMode) > vm->ensureShadowChicken(); > }); > return JSValue::encode(jsUndefined()); >@@ -2079,12 +2079,12 @@ static EncodedJSValue changeDebuggerModeWhenIdle(ExecState* exec, DebuggerMode m > > static EncodedJSValue JSC_HOST_CALL functionEnableDebuggerModeWhenIdle(ExecState* exec) > { >- return changeDebuggerModeWhenIdle(exec, DebuggerOn); >+ return changeDebuggerModeWhenIdle(exec, { CodeGenerationMode::Debugger }); > } > > static EncodedJSValue JSC_HOST_CALL functionDisableDebuggerModeWhenIdle(ExecState* exec) > { >- return changeDebuggerModeWhenIdle(exec, DebuggerOff); >+ return changeDebuggerModeWhenIdle(exec, { }); > } > > static EncodedJSValue JSC_HOST_CALL functionGlobalObjectCount(ExecState* exec) >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 68cf46b40c9432d5048210d438c4c86bdb286fd2..54e98c7ba541bfc18d32ade14076fd4946bc8130 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,14 @@ >+2019-05-03 Yusuke Suzuki <ysuzuki@apple.com> >+ >+ [JSC] Generator CodeBlock generation should be idempotent >+ https://bugs.webkit.org/show_bug.cgi?id=197552 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * Scripts/run-javascriptcore-tests: >+ (runJSCStressTests): >+ * Scripts/run-jsc-stress-tests: >+ > 2019-05-01 Don Olmstead <don.olmstead@sony.com> > > TestWebKitAPI config.h should be aware of what suite is being built >diff --git a/Tools/Scripts/run-javascriptcore-tests b/Tools/Scripts/run-javascriptcore-tests >index c7b23e6427dce629078f059b8c75bc058e30b7d6..cfe61a277418d19b07640f05deec57af548c980f 100755 >--- a/Tools/Scripts/run-javascriptcore-tests >+++ b/Tools/Scripts/run-javascriptcore-tests >@@ -447,6 +447,7 @@ sub runJSCStressTests > "JSTests/controlFlowProfiler.yaml", > "JSTests/es6.yaml", > "JSTests/modules.yaml", >+ "JSTests/complex.yaml", > "JSTests/ChakraCore.yaml", > "JSTests/wasm.yaml"); > $hasTestsToRun = 1; >diff --git a/Tools/Scripts/run-jsc-stress-tests b/Tools/Scripts/run-jsc-stress-tests >index cfae9c95895fde534c01b4921e9c70195102f48e..a7be368588a5df26ddefe2a555412659e9fbeeec 100755 >--- a/Tools/Scripts/run-jsc-stress-tests >+++ b/Tools/Scripts/run-jsc-stress-tests >@@ -1333,6 +1333,13 @@ def prepareExtraAbsoluteFiles(absoluteBase, extraFiles) > } > end > >+def runComplexTest(before, after, *options) >+ prepareExtraRelativeFiles(before.map{|v| (Pathname("..") + v).to_s}, $collection) >+ prepareExtraRelativeFiles(after.map{|v| (Pathname("..") + v).to_s}, $collection) >+ args = [pathToVM.to_s] + BASE_OPTIONS + $testSpecificRequiredOptions + options + before.map{|v| v.to_s} + [$benchmark.to_s] + after.map{|v| v.to_s} >+ addRunCommand("complex", args, silentOutputHandler, simpleErrorHandler) >+end >+ > def runMozillaTest(kind, mode, extraFiles, *options) > if kind > kind = "mozilla-" + kind >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index e5487fe7a4b0287f3a6bbf282bf589947e2c005e..e857cdbeea5170f14a05bd993369c73287010884 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,18 @@ >+2019-05-03 Yusuke Suzuki <ysuzuki@apple.com> >+ >+ [JSC] Generator CodeBlock generation should be idempotent >+ https://bugs.webkit.org/show_bug.cgi?id=197552 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add complex.yaml, which controls how to run JSC shell more. >+ We split test files into two to run macro task between them which allows debugger to be attached to VM. >+ >+ * complex.yaml: Added. >+ * complex/generator-regeneration-after.js: Added. >+ * complex/generator-regeneration.js: Added. >+ (gen): >+ > 2019-05-01 Saam barati <sbarati@apple.com> > > Baseline JIT should do argument value profiling after checking for stack overflow >diff --git a/JSTests/complex.yaml b/JSTests/complex.yaml >new file mode 100644 >index 0000000000000000000000000000000000000000..ce038f4d6242cde75752e5ac22390fa0198831d2 >--- /dev/null >+++ b/JSTests/complex.yaml >@@ -0,0 +1,27 @@ >+# 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 AND ITS CONTRIBUTORS "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 OR ITS 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. >+# >+# This is for writing a bit complex tests to drive in JSC shell (e.g. including multiple files with some special options). >+ >+- path: complex/generator-regeneration.js >+ cmd: runComplexTest [], ["generator-regeneration-after.js"], "--useDollarVM=1" >diff --git a/JSTests/complex/generator-regeneration-after.js b/JSTests/complex/generator-regeneration-after.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b6ae6cd1d253d31b9f4f8fa398f44971d5f952b1 >--- /dev/null >+++ b/JSTests/complex/generator-regeneration-after.js >@@ -0,0 +1 @@ >+g.next(); >diff --git a/JSTests/complex/generator-regeneration.js b/JSTests/complex/generator-regeneration.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0a2e40e0d20c093e2d9b32cffc70bcd607fac040 >--- /dev/null >+++ b/JSTests/complex/generator-regeneration.js >@@ -0,0 +1,14 @@ >+function* gen() >+{ >+ var ok = 2; >+ ok = ok + (yield 42); >+ yield ok; >+ yield ok; >+ yield ok; >+} >+ >+var g = gen(); >+g.next(); >+$vm.enableDebuggerModeWhenIdle(); >+fullGC(); >+g.next();
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 197552
:
368915
|
368917
|
368918
|
368919