|
| 1 | +2019-05-03 Yusuke Suzuki <ysuzuki@apple.com> |
| 2 | + |
| 3 | + [JSC] Generator CodeBlock generation should be idempotent |
| 4 | + https://bugs.webkit.org/show_bug.cgi?id=197552 |
| 5 | + |
| 6 | + Reviewed by Keith Miller. |
| 7 | + |
| 8 | + ES6 Generator saves and resumes the current execution state. Since ES6 generator can save the execution state at expression |
| 9 | + granularity (not statement granularity), the saved state involves locals. But if the underlying CodeBlock is jettisoned and |
| 10 | + recompiled with different code generation option (like, debugger, type profiler etc.), the generated instructions can be largely |
| 11 | + different and it does not have the same state previously used. If we resume the previously created generator with the newly |
| 12 | + generator function, resuming is messed up. |
| 13 | + |
| 14 | + function* gen () { ... } |
| 15 | + var g = gen(); |
| 16 | + g.next(); |
| 17 | + |
| 18 | + // CodeBlock is destroyed & Debugger is enabled. |
| 19 | + |
| 20 | + g.next(); |
| 21 | + |
| 22 | + In this patch, |
| 23 | + |
| 24 | + 1. In generatorification, we use index Identifier (localN => Identifier("N")) instead of private symbols to generate the same |
| 25 | + instructions every time we regenerate the CodeBlock. |
| 26 | + |
| 27 | + 2. We decouple the options which can affect on the generated code (Debugger, TypeProfiler, ControlFlowProfiler) from the BytecodeGenerator, |
| 28 | + and pass them as a parameter, OptionSet<CodeGeneratorMode>. |
| 29 | + |
| 30 | + 3. Generator ScriptExecutable remembers the previous CodeGeneratorMode and reuses this parameter to regenerate CodeBlock. It means that, |
| 31 | + even if the debugger is enabled, previously created generators are not debuggable. But newly created generators are debuggable. |
| 32 | + |
| 33 | + * bytecode/BytecodeGeneratorification.cpp: |
| 34 | + (JSC::BytecodeGeneratorification::storageForGeneratorLocal): |
| 35 | + (JSC::BytecodeGeneratorification::run): |
| 36 | + * bytecode/CodeBlock.cpp: |
| 37 | + (JSC::CodeBlock::finishCreation): |
| 38 | + (JSC::CodeBlock::setConstantRegisters): |
| 39 | + * bytecode/UnlinkedCodeBlock.cpp: |
| 40 | + (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): |
| 41 | + * bytecode/UnlinkedCodeBlock.h: |
| 42 | + (JSC::UnlinkedCodeBlock::wasCompiledWithDebuggingOpcodes const): |
| 43 | + (JSC::UnlinkedCodeBlock::wasCompiledWithTypeProfilerOpcodes const): |
| 44 | + (JSC::UnlinkedCodeBlock::wasCompiledWithControlFlowProfilerOpcodes const): |
| 45 | + (JSC::UnlinkedCodeBlock::codeGenerationMode const): |
| 46 | + * bytecode/UnlinkedEvalCodeBlock.h: |
| 47 | + * bytecode/UnlinkedFunctionCodeBlock.h: |
| 48 | + * bytecode/UnlinkedFunctionExecutable.cpp: |
| 49 | + (JSC::generateUnlinkedFunctionCodeBlock): |
| 50 | + (JSC::UnlinkedFunctionExecutable::fromGlobalCode): |
| 51 | + (JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor): |
| 52 | + * bytecode/UnlinkedFunctionExecutable.h: |
| 53 | + * bytecode/UnlinkedGlobalCodeBlock.h: |
| 54 | + (JSC::UnlinkedGlobalCodeBlock::UnlinkedGlobalCodeBlock): |
| 55 | + * bytecode/UnlinkedModuleProgramCodeBlock.h: |
| 56 | + * bytecode/UnlinkedProgramCodeBlock.h: |
| 57 | + * bytecompiler/BytecodeGenerator.cpp: |
| 58 | + (JSC::BytecodeGenerator::BytecodeGenerator): |
| 59 | + (JSC::BytecodeGenerator::emitTypeProfilerExpressionInfo): |
| 60 | + (JSC::BytecodeGenerator::emitProfileType): |
| 61 | + (JSC::BytecodeGenerator::emitProfileControlFlow): |
| 62 | + (JSC::BytecodeGenerator::pushLexicalScopeInternal): |
| 63 | + (JSC::BytecodeGenerator::popLexicalScopeInternal): |
| 64 | + (JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration): |
| 65 | + (JSC::BytecodeGenerator::emitCall): |
| 66 | + (JSC::BytecodeGenerator::emitCallVarargs): |
| 67 | + (JSC::BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary): |
| 68 | + (JSC::BytecodeGenerator::emitLogShadowChickenTailIfNecessary): |
| 69 | + (JSC::BytecodeGenerator::emitDebugHook): |
| 70 | + * bytecompiler/BytecodeGenerator.h: |
| 71 | + (JSC::BytecodeGenerator::generate): |
| 72 | + (JSC::BytecodeGenerator::shouldEmitDebugHooks const): |
| 73 | + (JSC::BytecodeGenerator::shouldEmitTypeProfilerHooks const): |
| 74 | + (JSC::BytecodeGenerator::shouldEmitControlFlowProfilerHooks const): |
| 75 | + * bytecompiler/NodesCodegen.cpp: |
| 76 | + (JSC::PrefixNode::emitResolve): |
| 77 | + (JSC::EmptyVarExpression::emitBytecode): |
| 78 | + (JSC::ReturnNode::emitBytecode): |
| 79 | + (JSC::FunctionNode::emitBytecode): |
| 80 | + * parser/ParserModes.h: |
| 81 | + (): Deleted. |
| 82 | + * parser/SourceCodeKey.h: |
| 83 | + (JSC::SourceCodeFlags::SourceCodeFlags): |
| 84 | + (JSC::SourceCodeKey::SourceCodeKey): |
| 85 | + * runtime/CachedTypes.cpp: |
| 86 | + (JSC::CachedCodeBlock::isClassContext const): |
| 87 | + (JSC::CachedCodeBlock::codeGenerationMode const): |
| 88 | + (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): |
| 89 | + (JSC::CachedCodeBlock<CodeBlockType>::encode): |
| 90 | + (JSC::CachedCodeBlock::wasCompiledWithDebuggingOpcodes const): Deleted. |
| 91 | + * runtime/CodeCache.cpp: |
| 92 | + (JSC::CodeCache::getUnlinkedGlobalCodeBlock): |
| 93 | + (JSC::CodeCache::getUnlinkedProgramCodeBlock): |
| 94 | + (JSC::CodeCache::getUnlinkedEvalCodeBlock): |
| 95 | + (JSC::CodeCache::getUnlinkedModuleProgramCodeBlock): |
| 96 | + (JSC::CodeCache::getUnlinkedGlobalFunctionExecutable): |
| 97 | + (JSC::generateUnlinkedCodeBlockForFunctions): |
| 98 | + (JSC::sourceCodeKeyForSerializedBytecode): |
| 99 | + (JSC::sourceCodeKeyForSerializedProgram): |
| 100 | + (JSC::sourceCodeKeyForSerializedModule): |
| 101 | + (JSC::serializeBytecode): |
| 102 | + * runtime/CodeCache.h: |
| 103 | + (JSC::generateUnlinkedCodeBlockImpl): |
| 104 | + (JSC::generateUnlinkedCodeBlock): |
| 105 | + * runtime/Completion.cpp: |
| 106 | + (JSC::generateProgramBytecode): |
| 107 | + (JSC::generateModuleBytecode): |
| 108 | + * runtime/DirectEvalExecutable.cpp: |
| 109 | + (JSC::DirectEvalExecutable::create): |
| 110 | + * runtime/IndirectEvalExecutable.cpp: |
| 111 | + (JSC::IndirectEvalExecutable::create): |
| 112 | + * runtime/JSGlobalObject.h: |
| 113 | + (JSC::JSGlobalObject::defaultCodeGenerationMode const): |
| 114 | + * runtime/ModuleProgramExecutable.cpp: |
| 115 | + (JSC::ModuleProgramExecutable::create): |
| 116 | + * runtime/ProgramExecutable.cpp: |
| 117 | + (JSC::ProgramExecutable::initializeGlobalProperties): |
| 118 | + * runtime/ScriptExecutable.cpp: |
| 119 | + (JSC::ScriptExecutable::ScriptExecutable): |
| 120 | + (JSC::ScriptExecutable::newCodeBlockFor): |
| 121 | + * runtime/ScriptExecutable.h: |
| 122 | + * tools/JSDollarVM.cpp: |
| 123 | + (JSC::changeDebuggerModeWhenIdle): |
| 124 | + (JSC::functionEnableDebuggerModeWhenIdle): |
| 125 | + (JSC::functionDisableDebuggerModeWhenIdle): |
| 126 | + |
1 | 127 | 2019-05-03 Devin Rousso <drousso@apple.com> |
2 | 128 |
|
3 | 129 | Web Inspector: Record actions performed on WebGL2RenderingContext |
|
0 commit comments