Changeset 269115 in webkit for trunk/Source/JavaScriptCore/bytecompiler
- Timestamp:
- Oct 28, 2020, 12:25:14 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore/bytecompiler
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r268593 r269115 49 49 #include "PrivateFieldPutKind.h" 50 50 #include "StrongInlines.h" 51 #include "SuperSampler.h" 51 52 #include "UnlinkedCodeBlock.h" 52 53 #include "UnlinkedEvalCodeBlock.h" … … 289 290 } 290 291 291 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment*parentScopeTDZVariables, ECMAMode ecmaMode)292 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const CachedTDZStack& parentScopeTDZVariables, ECMAMode ecmaMode) 292 293 : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()) 293 294 , m_codeGenerationMode(codeGenerationMode) … … 301 302 , m_usesNonStrictEval(false) 302 303 , m_inTailPosition(false) 303 , m_hasCachedVariablesUnderTDZ(false)304 304 , m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval()) 305 305 , m_ecmaMode(ecmaMode) 306 306 { 307 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables ->size());307 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables.size()); 308 308 309 309 m_codeBlock->setNumParameters(1); // Allocate space for "this" … … 337 337 } 338 338 339 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment*parentScopeTDZVariables, ECMAMode ecmaMode)339 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const CachedTDZStack& parentScopeTDZVariables, ECMAMode ecmaMode) 340 340 : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()) 341 341 , m_codeGenerationMode(codeGenerationMode) … … 356 356 // Note that we intentionally enable tail call for naked constructors since it does not have special code for "return". 357 357 , m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && ecmaMode.isStrict()) 358 , m_hasCachedVariablesUnderTDZ(false)359 358 , m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval()) 360 359 , m_ecmaMode(ecmaMode) … … 364 363 functionSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval); 365 364 int symbolTableConstantIndex = 0; 365 366 m_parentScopeTDZStackSize = parentScopeTDZVariables.size(); 367 m_cachedVariablesUnderTDZ = parentScopeTDZVariables; 366 368 367 369 FunctionParameters& parameters = *functionNode->parameters(); … … 771 773 } 772 774 773 // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called774 // because a function's default parameter ExpressionNodes will use temporary registers.775 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ);776 777 775 Ref<Label> catchLabel = newLabel(); 778 776 TryData* tryFormalParametersData = nullptr; … … 783 781 } 784 782 783 // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called 784 // because a function's default parameter ExpressionNodes will use temporary registers. 785 785 initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, isSimpleParameterList, functionNode, functionSymbolTable, symbolTableConstantIndex, captures, shouldCreateArgumentsVariableInParameterScope); 786 786 … … 841 841 } 842 842 843 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment*parentScopeTDZVariables, ECMAMode ecmaMode)843 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const CachedTDZStack& parentScopeTDZVariables, ECMAMode ecmaMode) 844 844 : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()) 845 845 , m_codeGenerationMode(codeGenerationMode) … … 853 853 , m_usesNonStrictEval(codeBlock->usesEval() && !ecmaMode.isStrict()) 854 854 , m_inTailPosition(false) 855 , m_hasCachedVariablesUnderTDZ(false)856 855 , m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval()) 857 856 , m_ecmaMode(ecmaMode) … … 860 859 m_codeBlock->setNumParameters(1); 861 860 862 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ); 861 m_parentScopeTDZStackSize = parentScopeTDZVariables.size(); 862 m_cachedVariablesUnderTDZ = parentScopeTDZVariables; 863 863 864 864 emitEnter(); … … 905 905 } 906 906 907 BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment*parentScopeTDZVariables, ECMAMode ecmaMode)907 BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const CachedTDZStack& parentScopeTDZVariables, ECMAMode ecmaMode) 908 908 : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()) 909 909 , m_codeGenerationMode(codeGenerationMode) … … 917 917 , m_usesNonStrictEval(false) 918 918 , m_inTailPosition(false) 919 , m_hasCachedVariablesUnderTDZ(false)920 919 , m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval()) 921 920 , m_ecmaMode(ecmaMode) 922 921 { 923 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables ->size());922 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables.size()); 924 923 925 924 SymbolTable* moduleEnvironmentSymbolTable = SymbolTable::create(m_vm); … … 2171 2170 2172 2171 m_TDZStack.removeLast(); 2173 m_cachedVariablesUnderTDZ = { };2172 m_cachedVariablesUnderTDZ.removeLast(); 2174 2173 } 2175 2174 … … 2859 2858 } 2860 2859 2860 for (unsigned i = m_parentScopeTDZStackSize; i--;) { 2861 if (m_cachedVariablesUnderTDZ[i].environment().toTDZEnvironment().contains(variable.ident().impl())) 2862 return true; 2863 } 2864 2861 2865 return false; 2862 2866 } … … 2881 2885 auto iter = m_TDZStack[i].find(identifier); 2882 2886 if (iter != m_TDZStack[i].end()) { 2883 if (iter->value == TDZNecessityLevel::Optimize) { 2884 m_cachedVariablesUnderTDZ = { }; 2887 if (iter->value == TDZNecessityLevel::Optimize) 2885 2888 iter->value = TDZNecessityLevel::NotNeeded; 2886 }2887 2889 break; 2888 2890 } … … 2909 2911 2910 2912 m_TDZStack.append(WTFMove(map)); 2911 m_cachedVariablesUnderTDZ = { }; 2912 } 2913 2914 Optional<CompactVariableMap::Handle> BytecodeGenerator::getVariablesUnderTDZ() 2915 { 2916 if (m_cachedVariablesUnderTDZ) { 2917 if (!m_hasCachedVariablesUnderTDZ) { 2918 ASSERT(m_cachedVariablesUnderTDZ.environment().toVariableEnvironment().isEmpty()); 2919 return WTF::nullopt; 2920 } 2913 m_cachedVariablesUnderTDZ.append({ }); 2914 } 2915 2916 Optional<BytecodeGenerator::CachedTDZStack> BytecodeGenerator::getVariablesUnderTDZ() 2917 { 2918 auto assertCacheIsCoherent = [&] { 2919 #if ASSERT_ENABLED 2920 for (size_t i = 0; i < m_cachedVariablesUnderTDZ.size(); ++i) 2921 ASSERT(!!m_cachedVariablesUnderTDZ[i]); 2922 #endif 2923 }; 2924 2925 RELEASE_ASSERT(m_TDZStack.size() + m_parentScopeTDZStackSize == m_cachedVariablesUnderTDZ.size()); 2926 2927 if (m_cachedVariablesUnderTDZ.isEmpty()) 2928 return WTF::nullopt; 2929 2930 if (m_cachedVariablesUnderTDZ.last()) { 2931 assertCacheIsCoherent(); 2921 2932 return m_cachedVariablesUnderTDZ; 2922 2933 } 2923 2934 2924 // We keep track of variablesThatDontNeedTDZ in this algorithm to prevent 2925 // reporting that "x" is under TDZ if this function is called at "...". 2926 // 2927 // { 2928 // { 2929 // let x; 2930 // ... 2931 // } 2932 // let x; 2933 // } 2934 SmallPtrSet<UniquedStringImpl*, 16> variablesThatDontNeedTDZ; 2935 VariableEnvironment environment; 2936 for (unsigned i = m_TDZStack.size(); i--; ) { 2935 for (size_t i = m_TDZStack.size(); i--;) { 2936 if (m_cachedVariablesUnderTDZ[i + m_parentScopeTDZStackSize]) 2937 break; 2938 2937 2939 auto& map = m_TDZStack[i]; 2938 for (auto& entry : map) { 2939 if (entry.value != TDZNecessityLevel::NotNeeded) { 2940 if (!variablesThatDontNeedTDZ.contains(entry.key.get())) 2941 environment.add(entry.key.get()); 2942 } else 2943 variablesThatDontNeedTDZ.add(entry.key.get()); 2944 } 2945 } 2946 2947 m_cachedVariablesUnderTDZ = m_vm.m_compactVariableMap->get(environment); 2948 m_hasCachedVariablesUnderTDZ = !environment.isEmpty(); 2949 if (!m_hasCachedVariablesUnderTDZ) 2950 return WTF::nullopt; 2951 2940 TDZEnvironment environment; 2941 for (auto& entry : map) { 2942 if (entry.value != TDZNecessityLevel::NotNeeded) 2943 environment.add(entry.key.get()); 2944 } 2945 m_cachedVariablesUnderTDZ[i + m_parentScopeTDZStackSize] = m_vm.m_compactVariableMap->get(environment); 2946 } 2947 2948 assertCacheIsCoherent(); 2952 2949 return m_cachedVariablesUnderTDZ; 2953 2950 } … … 2956 2953 { 2957 2954 preservedStack.m_preservedTDZStack = m_TDZStack; 2955 preservedStack.m_cachedTDZStack = m_cachedVariablesUnderTDZ; 2958 2956 } 2959 2957 … … 2961 2959 { 2962 2960 m_TDZStack = preservedStack.m_preservedTDZStack; 2963 m_cachedVariablesUnderTDZ = { };2961 m_cachedVariablesUnderTDZ = preservedStack.m_cachedTDZStack; 2964 2962 } 2965 2963 … … 3148 3146 } 3149 3147 3150 Optional<CompactVariableMap::Handle>variablesUnderTDZ = getVariablesUnderTDZ();3148 auto variablesUnderTDZ = getVariablesUnderTDZ(); 3151 3149 SourceParseMode parseMode = SourceParseMode::InstanceFieldInitializerMode; 3152 3150 ConstructAbility constructAbility = ConstructAbility::CannotConstruct; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r266264 r269115 408 408 public: 409 409 typedef DeclarationStacks::FunctionStack FunctionStack; 410 411 BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, OptionSet<CodeGenerationMode>, const VariableEnvironment*, ECMAMode); 412 BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, OptionSet<CodeGenerationMode>, const VariableEnvironment*, ECMAMode); 413 BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, OptionSet<CodeGenerationMode>, const VariableEnvironment*, ECMAMode); 414 BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, OptionSet<CodeGenerationMode>, const VariableEnvironment*, ECMAMode); 410 using CachedTDZStack = Vector<CompactTDZEnvironmentMap::Handle>; 411 412 BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, OptionSet<CodeGenerationMode>, const CachedTDZStack&, ECMAMode); 413 BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, OptionSet<CodeGenerationMode>, const CachedTDZStack&, ECMAMode); 414 BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, OptionSet<CodeGenerationMode>, const CachedTDZStack&, ECMAMode); 415 BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, OptionSet<CodeGenerationMode>, const CachedTDZStack&, ECMAMode); 415 416 416 417 ~BytecodeGenerator(); … … 432 433 433 434 template<typename Node, typename UnlinkedCodeBlock> 434 static ParserError generate(VM& vm, Node* node, const SourceCode& sourceCode, UnlinkedCodeBlock* unlinkedCodeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* environment, ECMAMode ecmaMode)435 static ParserError generate(VM& vm, Node* node, const SourceCode& sourceCode, UnlinkedCodeBlock* unlinkedCodeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const CachedTDZStack& parentScopeTDZVariables, ECMAMode ecmaMode) 435 436 { 436 437 MonotonicTime before; … … 439 440 440 441 DeferGC deferGC(vm.heap); 441 auto bytecodeGenerator = makeUnique<BytecodeGenerator>(vm, node, unlinkedCodeBlock, codeGenerationMode, environment, ecmaMode);442 auto bytecodeGenerator = makeUnique<BytecodeGenerator>(vm, node, unlinkedCodeBlock, codeGenerationMode, parentScopeTDZVariables, ecmaMode); 442 443 auto result = bytecodeGenerator->generate(); 443 444 … … 1186 1187 } 1187 1188 1188 Optional<CompactVariableMap::Handle>optionalVariablesUnderTDZ = getVariablesUnderTDZ();1189 auto optionalVariablesUnderTDZ = getVariablesUnderTDZ(); 1189 1190 1190 1191 // FIXME: These flags, ParserModes and propagation to XXXCodeBlocks should be reorganized. … … 1198 1199 } 1199 1200 1200 Optional<C ompactVariableMap::Handle> getVariablesUnderTDZ();1201 Optional<CachedTDZStack> getVariablesUnderTDZ(); 1201 1202 1202 1203 RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall); … … 1232 1233 private: 1233 1234 Vector<TDZMap> m_preservedTDZStack; 1235 CachedTDZStack m_cachedTDZStack; 1234 1236 friend class BytecodeGenerator; 1235 1237 }; … … 1263 1265 Vector<LexicalScopeStackEntry> m_lexicalScopeStack; 1264 1266 1267 size_t m_parentScopeTDZStackSize { 0 }; 1265 1268 Vector<TDZMap> m_TDZStack; 1269 CachedTDZStack m_cachedVariablesUnderTDZ; 1266 1270 Optional<size_t> m_varScopeLexicalScopeStackIndex; 1267 1271 void pushTDZVariables(const VariableEnvironment&, TDZCheckOptimization, TDZRequirement); … … 1345 1349 bool m_usesNonStrictEval { false }; 1346 1350 bool m_inTailPosition { false }; 1347 bool m_hasCachedVariablesUnderTDZ { false };1348 1351 bool m_needsToUpdateArrowFunctionContext : 1; 1349 1352 ECMAMode m_ecmaMode; 1350 1353 DerivedContextType m_derivedContextType { DerivedContextType::None }; 1351 1352 CompactVariableMap::Handle m_cachedVariablesUnderTDZ;1353 1354 1354 1355 struct CatchEntry {
Note:
See TracChangeset
for help on using the changeset viewer.