Title: [255687] trunk/Source
Revision
255687
Author
[email protected]
Date
2020-02-04 11:05:17 -0800 (Tue, 04 Feb 2020)

Log Message

[JSC] Introduce UnlinkedCodeBlockGenerator and reduce sizeof(UnlinkedCodeBlock)
https://bugs.webkit.org/show_bug.cgi?id=207087

Reviewed by Tadeu Zagallo.

Source/_javascript_Core:

While UnlinkedCodeBlock is immutable once it is created from BytecodeGenerator, it has many mutable Vectors.
This is because we are using UnlinkedCodeBlock as a builder of UnlinkedCodeBlock itself too in BytecodeGenerator.
Since Vector takes 16 bytes to allow efficient expansions, it is nice if we can use RefCountedArray instead when
we know this Vector is immutable.

In this patch, we introduce UnlinkedCodeBlockGenerator wrapper. BytecodeGenerator, BytecodeRewriter, BytecodeDumper,
and BytecodeGeneratorification interact with UnlinkedCodeBlockGenerator instead of UnlinkedCodeBlock. And UnlinkedCodeBlockGenerator
will generate the finalized UnlinkedCodeBlock. This design allows us to use RefCountedArray for data in UnlinkedCodeBlock,
which is (1) smaller and (2) doing shrinkToFit operation when creating it from Vector.

This patch reduces sizeof(UnlinkedCodeBlock) from 256 to 168, 88 bytes reduction.

* _javascript_Core.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/BytecodeBasicBlock.cpp:
(JSC::BytecodeBasicBlock::compute):
* bytecode/BytecodeBasicBlock.h:
* bytecode/BytecodeDumper.cpp:
* bytecode/BytecodeGeneratorification.cpp:
(JSC::BytecodeGeneratorification::BytecodeGeneratorification):
(JSC::GeneratorLivenessAnalysis::run):
(JSC::BytecodeGeneratorification::run):
(JSC::performGeneratorification):
* bytecode/BytecodeGeneratorification.h:
* bytecode/BytecodeRewriter.h:
(JSC::BytecodeRewriter::BytecodeRewriter):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::setConstantIdentifierSetRegisters):
(JSC::CodeBlock::setConstantRegisters):
(JSC::CodeBlock::handlerForIndex):
(JSC::CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::numberOfSwitchJumpTables const):
(JSC::CodeBlock::numberOfStringSwitchJumpTables const):
(JSC::CodeBlock::addSwitchJumpTable): Deleted.
(JSC::CodeBlock::addStringSwitchJumpTable): Deleted.
* bytecode/HandlerInfo.h:
(JSC::HandlerInfoBase::handlerForIndex):
* bytecode/JumpTable.h:
(JSC::SimpleJumpTable::add): Deleted.
* bytecode/PreciseJumpTargets.cpp:
(JSC::computePreciseJumpTargets):
(JSC::recomputePreciseJumpTargets):
(JSC::findJumpTargetsForInstruction):
* bytecode/PreciseJumpTargets.h:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
(JSC::UnlinkedCodeBlock::visitChildren):
(JSC::UnlinkedCodeBlock::dumpExpressionRangeInfo):
(JSC::UnlinkedCodeBlock::expressionRangeForBytecodeIndex const):
(JSC::UnlinkedCodeBlock::handlerForIndex):
(JSC::UnlinkedCodeBlock::addExpressionInfo): Deleted.
(JSC::UnlinkedCodeBlock::addTypeProfilerExpressionInfo): Deleted.
(JSC::UnlinkedCodeBlock::setInstructions): Deleted.
(JSC::UnlinkedCodeBlock::applyModification): Deleted.
(JSC::UnlinkedCodeBlock::shrinkToFit): Deleted.
(JSC::UnlinkedCodeBlock::addOutOfLineJumpTarget): Deleted.
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::expressionInfo):
(JSC::UnlinkedCodeBlock::setNumParameters):
(JSC::UnlinkedCodeBlock::numberOfIdentifiers const):
(JSC::UnlinkedCodeBlock::identifiers const):
(JSC::UnlinkedCodeBlock::bitVector):
(JSC::UnlinkedCodeBlock::constantRegisters):
(JSC::UnlinkedCodeBlock::constantsSourceCodeRepresentation):
(JSC::UnlinkedCodeBlock::constantIdentifierSets):
(JSC::UnlinkedCodeBlock::numberOfJumpTargets const):
(JSC::UnlinkedCodeBlock::numberOfSwitchJumpTables const):
(JSC::UnlinkedCodeBlock::numberOfStringSwitchJumpTables const):
(JSC::UnlinkedCodeBlock::numberOfFunctionDecls):
(JSC::UnlinkedCodeBlock::numberOfExceptionHandlers const):
(JSC::UnlinkedCodeBlock::opProfileControlFlowBytecodeOffsets const):
(JSC::UnlinkedCodeBlock::createRareDataIfNecessary):
(JSC::UnlinkedCodeBlock::addParameter): Deleted.
(JSC::UnlinkedCodeBlock::addIdentifier): Deleted.
(JSC::UnlinkedCodeBlock::addBitVector): Deleted.
(JSC::UnlinkedCodeBlock::addSetConstant): Deleted.
(JSC::UnlinkedCodeBlock::addConstant): Deleted.
(JSC::UnlinkedCodeBlock::addJumpTarget): Deleted.
(JSC::UnlinkedCodeBlock::addSwitchJumpTable): Deleted.
(JSC::UnlinkedCodeBlock::addStringSwitchJumpTable): Deleted.
(JSC::UnlinkedCodeBlock::addFunctionDecl): Deleted.
(JSC::UnlinkedCodeBlock::addFunctionExpr): Deleted.
(JSC::UnlinkedCodeBlock::addExceptionHandler): Deleted.
(JSC::UnlinkedCodeBlock::addOpProfileControlFlowBytecodeOffset): Deleted.
(JSC::UnlinkedCodeBlock::replaceOutOfLineJumpTargets): Deleted.
* bytecode/UnlinkedCodeBlockGenerator.cpp: Added.
(JSC::UnlinkedCodeBlockGenerator::getLineAndColumn const):
(JSC::UnlinkedCodeBlockGenerator::addExpressionInfo):
(JSC::UnlinkedCodeBlockGenerator::addTypeProfilerExpressionInfo):
(JSC::UnlinkedCodeBlockGenerator::finalize):
(JSC::UnlinkedCodeBlockGenerator::handlerForBytecodeIndex):
(JSC::UnlinkedCodeBlockGenerator::handlerForIndex):
(JSC::UnlinkedCodeBlockGenerator::applyModification):
(JSC::UnlinkedCodeBlockGenerator::addOutOfLineJumpTarget):
(JSC::UnlinkedCodeBlockGenerator::outOfLineJumpOffset):
(JSC::UnlinkedCodeBlockGenerator::dump const):
* bytecode/UnlinkedCodeBlockGenerator.h: Added.
(JSC::UnlinkedCodeBlockGenerator::UnlinkedCodeBlockGenerator):
(JSC::UnlinkedCodeBlockGenerator::vm):
(JSC::UnlinkedCodeBlockGenerator::isConstructor const):
(JSC::UnlinkedCodeBlockGenerator::constructorKind const):
(JSC::UnlinkedCodeBlockGenerator::superBinding const):
(JSC::UnlinkedCodeBlockGenerator::scriptMode const):
(JSC::UnlinkedCodeBlockGenerator::needsClassFieldInitializer const):
(JSC::UnlinkedCodeBlockGenerator::isStrictMode const):
(JSC::UnlinkedCodeBlockGenerator::usesEval const):
(JSC::UnlinkedCodeBlockGenerator::parseMode const):
(JSC::UnlinkedCodeBlockGenerator::isArrowFunction):
(JSC::UnlinkedCodeBlockGenerator::derivedContextType const):
(JSC::UnlinkedCodeBlockGenerator::evalContextType const):
(JSC::UnlinkedCodeBlockGenerator::isArrowFunctionContext const):
(JSC::UnlinkedCodeBlockGenerator::isClassContext const):
(JSC::UnlinkedCodeBlockGenerator::numCalleeLocals const):
(JSC::UnlinkedCodeBlockGenerator::numVars const):
(JSC::UnlinkedCodeBlockGenerator::numParameters const):
(JSC::UnlinkedCodeBlockGenerator::thisRegister const):
(JSC::UnlinkedCodeBlockGenerator::scopeRegister const):
(JSC::UnlinkedCodeBlockGenerator::wasCompiledWithDebuggingOpcodes const):
(JSC::UnlinkedCodeBlockGenerator::hasCheckpoints const):
(JSC::UnlinkedCodeBlockGenerator::hasTailCalls const):
(JSC::UnlinkedCodeBlockGenerator::setHasCheckpoints):
(JSC::UnlinkedCodeBlockGenerator::setHasTailCalls):
(JSC::UnlinkedCodeBlockGenerator::setNumCalleeLocals):
(JSC::UnlinkedCodeBlockGenerator::setNumVars):
(JSC::UnlinkedCodeBlockGenerator::setThisRegister):
(JSC::UnlinkedCodeBlockGenerator::setScopeRegister):
(JSC::UnlinkedCodeBlockGenerator::setNumParameters):
(JSC::UnlinkedCodeBlockGenerator::metadata):
(JSC::UnlinkedCodeBlockGenerator::addOpProfileControlFlowBytecodeOffset):
(JSC::UnlinkedCodeBlockGenerator::numberOfJumpTargets const):
(JSC::UnlinkedCodeBlockGenerator::addJumpTarget):
(JSC::UnlinkedCodeBlockGenerator::jumpTarget const):
(JSC::UnlinkedCodeBlockGenerator::lastJumpTarget const):
(JSC::UnlinkedCodeBlockGenerator::numberOfSwitchJumpTables const):
(JSC::UnlinkedCodeBlockGenerator::addSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::switchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::numberOfStringSwitchJumpTables const):
(JSC::UnlinkedCodeBlockGenerator::addStringSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::stringSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::numberOfExceptionHandlers const):
(JSC::UnlinkedCodeBlockGenerator::exceptionHandler):
(JSC::UnlinkedCodeBlockGenerator::addExceptionHandler):
(JSC::UnlinkedCodeBlockGenerator::bitVector):
(JSC::UnlinkedCodeBlockGenerator::addBitVector):
(JSC::UnlinkedCodeBlockGenerator::numberOfConstantIdentifierSets const):
(JSC::UnlinkedCodeBlockGenerator::constantIdentifierSets):
(JSC::UnlinkedCodeBlockGenerator::addSetConstant):
(JSC::UnlinkedCodeBlockGenerator::constantRegister const):
(JSC::UnlinkedCodeBlockGenerator::constantRegisters):
(JSC::UnlinkedCodeBlockGenerator::getConstant const):
(JSC::UnlinkedCodeBlockGenerator::constantsSourceCodeRepresentation):
(JSC::UnlinkedCodeBlockGenerator::addConstant):
(JSC::UnlinkedCodeBlockGenerator::addFunctionDecl):
(JSC::UnlinkedCodeBlockGenerator::addFunctionExpr):
(JSC::UnlinkedCodeBlockGenerator::numberOfIdentifiers const):
(JSC::UnlinkedCodeBlockGenerator::identifier const):
(JSC::UnlinkedCodeBlockGenerator::addIdentifier):
(JSC::UnlinkedCodeBlockGenerator::outOfLineJumpOffset):
(JSC::UnlinkedCodeBlockGenerator::replaceOutOfLineJumpTargets):
(JSC::UnlinkedCodeBlockGenerator::metadataSizeInBytes):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeNextParameter):
(JSC::BytecodeGenerator::emitPushFunctionNameScope):
(JSC::prepareJumpTableForSwitch):
(JSC::ForInContext::finalize):
(JSC::StructureForInContext::finalize):
(JSC::IndexedForInContext::finalize):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/BytecodeGeneratorBaseInlines.h:
(JSC::BytecodeGeneratorBase<Traits>::newRegister):
(JSC::BytecodeGeneratorBase<Traits>::addVar):
* runtime/CachedTypes.cpp:
(JSC::CachedVector::encode):
(JSC::CachedVector::decode const):
* wasm/WasmFunctionCodeBlock.h:
(JSC::Wasm::FunctionCodeBlock::setNumVars):
(JSC::Wasm::FunctionCodeBlock::setNumCalleeLocals):

Source/WTF:

Add more useful methods for RefCountedArray.

* wtf/RefCountedArray.h:
(WTF::RefCountedArray::operator=):
(WTF::RefCountedArray::isEmpty const):
(WTF::RefCountedArray::front):
(WTF::RefCountedArray::front const):
(WTF::RefCountedArray::last):
(WTF::RefCountedArray::last const):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (255686 => 255687)


--- trunk/Source/_javascript_Core/ChangeLog	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-02-04 19:05:17 UTC (rev 255687)
@@ -1,3 +1,192 @@
+2020-02-04  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Introduce UnlinkedCodeBlockGenerator and reduce sizeof(UnlinkedCodeBlock)
+        https://bugs.webkit.org/show_bug.cgi?id=207087
+
+        Reviewed by Tadeu Zagallo.
+
+        While UnlinkedCodeBlock is immutable once it is created from BytecodeGenerator, it has many mutable Vectors.
+        This is because we are using UnlinkedCodeBlock as a builder of UnlinkedCodeBlock itself too in BytecodeGenerator.
+        Since Vector takes 16 bytes to allow efficient expansions, it is nice if we can use RefCountedArray instead when
+        we know this Vector is immutable.
+
+        In this patch, we introduce UnlinkedCodeBlockGenerator wrapper. BytecodeGenerator, BytecodeRewriter, BytecodeDumper,
+        and BytecodeGeneratorification interact with UnlinkedCodeBlockGenerator instead of UnlinkedCodeBlock. And UnlinkedCodeBlockGenerator
+        will generate the finalized UnlinkedCodeBlock. This design allows us to use RefCountedArray for data in UnlinkedCodeBlock,
+        which is (1) smaller and (2) doing shrinkToFit operation when creating it from Vector.
+
+        This patch reduces sizeof(UnlinkedCodeBlock) from 256 to 168, 88 bytes reduction.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * bytecode/BytecodeBasicBlock.cpp:
+        (JSC::BytecodeBasicBlock::compute):
+        * bytecode/BytecodeBasicBlock.h:
+        * bytecode/BytecodeDumper.cpp:
+        * bytecode/BytecodeGeneratorification.cpp:
+        (JSC::BytecodeGeneratorification::BytecodeGeneratorification):
+        (JSC::GeneratorLivenessAnalysis::run):
+        (JSC::BytecodeGeneratorification::run):
+        (JSC::performGeneratorification):
+        * bytecode/BytecodeGeneratorification.h:
+        * bytecode/BytecodeRewriter.h:
+        (JSC::BytecodeRewriter::BytecodeRewriter):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finishCreation):
+        (JSC::CodeBlock::setConstantIdentifierSetRegisters):
+        (JSC::CodeBlock::setConstantRegisters):
+        (JSC::CodeBlock::handlerForIndex):
+        (JSC::CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::numberOfSwitchJumpTables const):
+        (JSC::CodeBlock::numberOfStringSwitchJumpTables const):
+        (JSC::CodeBlock::addSwitchJumpTable): Deleted.
+        (JSC::CodeBlock::addStringSwitchJumpTable): Deleted.
+        * bytecode/HandlerInfo.h:
+        (JSC::HandlerInfoBase::handlerForIndex):
+        * bytecode/JumpTable.h:
+        (JSC::SimpleJumpTable::add): Deleted.
+        * bytecode/PreciseJumpTargets.cpp:
+        (JSC::computePreciseJumpTargets):
+        (JSC::recomputePreciseJumpTargets):
+        (JSC::findJumpTargetsForInstruction):
+        * bytecode/PreciseJumpTargets.h:
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        (JSC::UnlinkedCodeBlock::visitChildren):
+        (JSC::UnlinkedCodeBlock::dumpExpressionRangeInfo):
+        (JSC::UnlinkedCodeBlock::expressionRangeForBytecodeIndex const):
+        (JSC::UnlinkedCodeBlock::handlerForIndex):
+        (JSC::UnlinkedCodeBlock::addExpressionInfo): Deleted.
+        (JSC::UnlinkedCodeBlock::addTypeProfilerExpressionInfo): Deleted.
+        (JSC::UnlinkedCodeBlock::setInstructions): Deleted.
+        (JSC::UnlinkedCodeBlock::applyModification): Deleted.
+        (JSC::UnlinkedCodeBlock::shrinkToFit): Deleted.
+        (JSC::UnlinkedCodeBlock::addOutOfLineJumpTarget): Deleted.
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::expressionInfo):
+        (JSC::UnlinkedCodeBlock::setNumParameters):
+        (JSC::UnlinkedCodeBlock::numberOfIdentifiers const):
+        (JSC::UnlinkedCodeBlock::identifiers const):
+        (JSC::UnlinkedCodeBlock::bitVector):
+        (JSC::UnlinkedCodeBlock::constantRegisters):
+        (JSC::UnlinkedCodeBlock::constantsSourceCodeRepresentation):
+        (JSC::UnlinkedCodeBlock::constantIdentifierSets):
+        (JSC::UnlinkedCodeBlock::numberOfJumpTargets const):
+        (JSC::UnlinkedCodeBlock::numberOfSwitchJumpTables const):
+        (JSC::UnlinkedCodeBlock::numberOfStringSwitchJumpTables const):
+        (JSC::UnlinkedCodeBlock::numberOfFunctionDecls):
+        (JSC::UnlinkedCodeBlock::numberOfExceptionHandlers const):
+        (JSC::UnlinkedCodeBlock::opProfileControlFlowBytecodeOffsets const):
+        (JSC::UnlinkedCodeBlock::createRareDataIfNecessary):
+        (JSC::UnlinkedCodeBlock::addParameter): Deleted.
+        (JSC::UnlinkedCodeBlock::addIdentifier): Deleted.
+        (JSC::UnlinkedCodeBlock::addBitVector): Deleted.
+        (JSC::UnlinkedCodeBlock::addSetConstant): Deleted.
+        (JSC::UnlinkedCodeBlock::addConstant): Deleted.
+        (JSC::UnlinkedCodeBlock::addJumpTarget): Deleted.
+        (JSC::UnlinkedCodeBlock::addSwitchJumpTable): Deleted.
+        (JSC::UnlinkedCodeBlock::addStringSwitchJumpTable): Deleted.
+        (JSC::UnlinkedCodeBlock::addFunctionDecl): Deleted.
+        (JSC::UnlinkedCodeBlock::addFunctionExpr): Deleted.
+        (JSC::UnlinkedCodeBlock::addExceptionHandler): Deleted.
+        (JSC::UnlinkedCodeBlock::addOpProfileControlFlowBytecodeOffset): Deleted.
+        (JSC::UnlinkedCodeBlock::replaceOutOfLineJumpTargets): Deleted.
+        * bytecode/UnlinkedCodeBlockGenerator.cpp: Added.
+        (JSC::UnlinkedCodeBlockGenerator::getLineAndColumn const):
+        (JSC::UnlinkedCodeBlockGenerator::addExpressionInfo):
+        (JSC::UnlinkedCodeBlockGenerator::addTypeProfilerExpressionInfo):
+        (JSC::UnlinkedCodeBlockGenerator::finalize):
+        (JSC::UnlinkedCodeBlockGenerator::handlerForBytecodeIndex):
+        (JSC::UnlinkedCodeBlockGenerator::handlerForIndex):
+        (JSC::UnlinkedCodeBlockGenerator::applyModification):
+        (JSC::UnlinkedCodeBlockGenerator::addOutOfLineJumpTarget):
+        (JSC::UnlinkedCodeBlockGenerator::outOfLineJumpOffset):
+        (JSC::UnlinkedCodeBlockGenerator::dump const):
+        * bytecode/UnlinkedCodeBlockGenerator.h: Added.
+        (JSC::UnlinkedCodeBlockGenerator::UnlinkedCodeBlockGenerator):
+        (JSC::UnlinkedCodeBlockGenerator::vm):
+        (JSC::UnlinkedCodeBlockGenerator::isConstructor const):
+        (JSC::UnlinkedCodeBlockGenerator::constructorKind const):
+        (JSC::UnlinkedCodeBlockGenerator::superBinding const):
+        (JSC::UnlinkedCodeBlockGenerator::scriptMode const):
+        (JSC::UnlinkedCodeBlockGenerator::needsClassFieldInitializer const):
+        (JSC::UnlinkedCodeBlockGenerator::isStrictMode const):
+        (JSC::UnlinkedCodeBlockGenerator::usesEval const):
+        (JSC::UnlinkedCodeBlockGenerator::parseMode const):
+        (JSC::UnlinkedCodeBlockGenerator::isArrowFunction):
+        (JSC::UnlinkedCodeBlockGenerator::derivedContextType const):
+        (JSC::UnlinkedCodeBlockGenerator::evalContextType const):
+        (JSC::UnlinkedCodeBlockGenerator::isArrowFunctionContext const):
+        (JSC::UnlinkedCodeBlockGenerator::isClassContext const):
+        (JSC::UnlinkedCodeBlockGenerator::numCalleeLocals const):
+        (JSC::UnlinkedCodeBlockGenerator::numVars const):
+        (JSC::UnlinkedCodeBlockGenerator::numParameters const):
+        (JSC::UnlinkedCodeBlockGenerator::thisRegister const):
+        (JSC::UnlinkedCodeBlockGenerator::scopeRegister const):
+        (JSC::UnlinkedCodeBlockGenerator::wasCompiledWithDebuggingOpcodes const):
+        (JSC::UnlinkedCodeBlockGenerator::hasCheckpoints const):
+        (JSC::UnlinkedCodeBlockGenerator::hasTailCalls const):
+        (JSC::UnlinkedCodeBlockGenerator::setHasCheckpoints):
+        (JSC::UnlinkedCodeBlockGenerator::setHasTailCalls):
+        (JSC::UnlinkedCodeBlockGenerator::setNumCalleeLocals):
+        (JSC::UnlinkedCodeBlockGenerator::setNumVars):
+        (JSC::UnlinkedCodeBlockGenerator::setThisRegister):
+        (JSC::UnlinkedCodeBlockGenerator::setScopeRegister):
+        (JSC::UnlinkedCodeBlockGenerator::setNumParameters):
+        (JSC::UnlinkedCodeBlockGenerator::metadata):
+        (JSC::UnlinkedCodeBlockGenerator::addOpProfileControlFlowBytecodeOffset):
+        (JSC::UnlinkedCodeBlockGenerator::numberOfJumpTargets const):
+        (JSC::UnlinkedCodeBlockGenerator::addJumpTarget):
+        (JSC::UnlinkedCodeBlockGenerator::jumpTarget const):
+        (JSC::UnlinkedCodeBlockGenerator::lastJumpTarget const):
+        (JSC::UnlinkedCodeBlockGenerator::numberOfSwitchJumpTables const):
+        (JSC::UnlinkedCodeBlockGenerator::addSwitchJumpTable):
+        (JSC::UnlinkedCodeBlockGenerator::switchJumpTable):
+        (JSC::UnlinkedCodeBlockGenerator::numberOfStringSwitchJumpTables const):
+        (JSC::UnlinkedCodeBlockGenerator::addStringSwitchJumpTable):
+        (JSC::UnlinkedCodeBlockGenerator::stringSwitchJumpTable):
+        (JSC::UnlinkedCodeBlockGenerator::numberOfExceptionHandlers const):
+        (JSC::UnlinkedCodeBlockGenerator::exceptionHandler):
+        (JSC::UnlinkedCodeBlockGenerator::addExceptionHandler):
+        (JSC::UnlinkedCodeBlockGenerator::bitVector):
+        (JSC::UnlinkedCodeBlockGenerator::addBitVector):
+        (JSC::UnlinkedCodeBlockGenerator::numberOfConstantIdentifierSets const):
+        (JSC::UnlinkedCodeBlockGenerator::constantIdentifierSets):
+        (JSC::UnlinkedCodeBlockGenerator::addSetConstant):
+        (JSC::UnlinkedCodeBlockGenerator::constantRegister const):
+        (JSC::UnlinkedCodeBlockGenerator::constantRegisters):
+        (JSC::UnlinkedCodeBlockGenerator::getConstant const):
+        (JSC::UnlinkedCodeBlockGenerator::constantsSourceCodeRepresentation):
+        (JSC::UnlinkedCodeBlockGenerator::addConstant):
+        (JSC::UnlinkedCodeBlockGenerator::addFunctionDecl):
+        (JSC::UnlinkedCodeBlockGenerator::addFunctionExpr):
+        (JSC::UnlinkedCodeBlockGenerator::numberOfIdentifiers const):
+        (JSC::UnlinkedCodeBlockGenerator::identifier const):
+        (JSC::UnlinkedCodeBlockGenerator::addIdentifier):
+        (JSC::UnlinkedCodeBlockGenerator::outOfLineJumpOffset):
+        (JSC::UnlinkedCodeBlockGenerator::replaceOutOfLineJumpTargets):
+        (JSC::UnlinkedCodeBlockGenerator::metadataSizeInBytes):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeNextParameter):
+        (JSC::BytecodeGenerator::emitPushFunctionNameScope):
+        (JSC::prepareJumpTableForSwitch):
+        (JSC::ForInContext::finalize):
+        (JSC::StructureForInContext::finalize):
+        (JSC::IndexedForInContext::finalize):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/BytecodeGeneratorBaseInlines.h:
+        (JSC::BytecodeGeneratorBase<Traits>::newRegister):
+        (JSC::BytecodeGeneratorBase<Traits>::addVar):
+        * runtime/CachedTypes.cpp:
+        (JSC::CachedVector::encode):
+        (JSC::CachedVector::decode const):
+        * wasm/WasmFunctionCodeBlock.h:
+        (JSC::Wasm::FunctionCodeBlock::setNumVars):
+        (JSC::Wasm::FunctionCodeBlock::setNumCalleeLocals):
+
 2020-02-04  Devin Rousso  <[email protected]>
 
         Web Inspector: REGRESSION(r248287): Console: function objects saved to a $n will be invoked instead of just referenced when evaluating in the Console

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (255686 => 255687)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2020-02-04 19:05:17 UTC (rev 255687)
@@ -1788,6 +1788,7 @@
 		E328DAE91D38D005001A2529 /* BytecodeGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D264281D38C042000BE174 /* BytecodeGraph.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E328DAEB1D38D005001A2529 /* BytecodeRewriter.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D2642A1D38C042000BE174 /* BytecodeRewriter.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E32AB2441DCD75F400D7533A /* MacroAssemblerHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E380A76B1DCD7195000F89E6 /* MacroAssemblerHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		E32C3C6923E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */; };
 		E33095DD23210A1B00EB7856 /* JSInternalFieldObjectImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E33095DC23210A1400EB7856 /* JSInternalFieldObjectImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E334CBB521FD96A9000EB178 /* RegExpGlobalData.h in Headers */ = {isa = PBXBuildFile; fileRef = E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E33637A61B63220200EE0840 /* ReflectObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E33637A41B63220200EE0840 /* ReflectObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4908,6 +4909,7 @@
 		E326C4961ECBEF5700A9A905 /* ClassInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassInfo.cpp; sourceTree = "<group>"; };
 		E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; };
 		E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; };
+		E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedCodeBlockGenerator.h; sourceTree = "<group>"; };
 		E3305FAF20B0F78700CEB82B /* InByIdStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdStatus.h; sourceTree = "<group>"; };
 		E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdVariant.cpp; sourceTree = "<group>"; };
 		E3305FB120B0F78800CEB82B /* InByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdVariant.h; sourceTree = "<group>"; };
@@ -4956,6 +4958,7 @@
 		E35E03611B7AB4850073AD2A /* InspectorInstrumentationObject.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = InspectorInstrumentationObject.js; sourceTree = "<group>"; };
 		E3637EE7236E56B00096BD0A /* LinkTimeConstant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkTimeConstant.h; sourceTree = "<group>"; };
 		E3637EE8236E56B00096BD0A /* LinkTimeConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkTimeConstant.cpp; sourceTree = "<group>"; };
+		E36B480123E9573800E4A66E /* UnlinkedCodeBlockGenerator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedCodeBlockGenerator.cpp; sourceTree = "<group>"; };
 		E36B766E22F8D61100D09818 /* WasmOMGForOSREntryPlan.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOMGForOSREntryPlan.cpp; sourceTree = "<group>"; };
 		E36B766F22F8D61100D09818 /* WasmOMGForOSREntryPlan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmOMGForOSREntryPlan.h; sourceTree = "<group>"; };
 		E36CC9462086314F0051FFD6 /* WasmCreationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmCreationMode.h; sourceTree = "<group>"; };
@@ -8360,6 +8363,8 @@
 				0F2D4DE719832DAC007D4B19 /* TypeLocation.h */,
 				A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */,
 				A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */,
+				E36B480123E9573800E4A66E /* UnlinkedCodeBlockGenerator.cpp */,
+				E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */,
 				14AD91281DCAAAB00014F9FE /* UnlinkedEvalCodeBlock.cpp */,
 				14AD911E1DCA9FA40014F9FE /* UnlinkedEvalCodeBlock.h */,
 				14AD912B1DCAAAB00014F9FE /* UnlinkedFunctionCodeBlock.cpp */,
@@ -9150,6 +9155,7 @@
 				A53243981856A489002ED692 /* CombinedDomains.json in Headers */,
 				BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */,
 				0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
+				33A920BD23DA2C6D000EBAF0 /* CommonSlowPathsInlines.h in Headers */,
 				A7E5A3A81797432D00E893C0 /* CompilationResult.h in Headers */,
 				0F4F11E8209BCDAB00709654 /* CompilerTimingScope.h in Headers */,
 				0FDCE12A1FAFA85F006F3901 /* CompleteSubspace.h in Headers */,
@@ -9386,7 +9392,6 @@
 				0F1FB3971E1AF7E300A9BE50 /* DFGWorklistInlines.h in Headers */,
 				0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */,
 				0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */,
-				33A920BD23DA2C6D000EBAF0 /* CommonSlowPathsInlines.h in Headers */,
 				969A07980ED1D3AE00F1F681 /* DirectEvalCodeCache.h in Headers */,
 				14386A751DD69895008652C4 /* DirectEvalExecutable.h in Headers */,
 				0F37308F1C0CD68500052BFA /* DisallowMacroScratchRegisterUsage.h in Headers */,
@@ -10249,6 +10254,7 @@
 				A7A8AF3F17ADB5F3005AB174 /* Uint8Array.h in Headers */,
 				A7A8AF4017ADB5F3005AB174 /* Uint8ClampedArray.h in Headers */,
 				A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */,
+				E32C3C6923E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h in Headers */,
 				14AD91241DCA9FA40014F9FE /* UnlinkedEvalCodeBlock.h in Headers */,
 				14AD91231DCA9FA40014F9FE /* UnlinkedFunctionCodeBlock.h in Headers */,
 				14142E511B796ECE00F4BF4B /* UnlinkedFunctionExecutable.h in Headers */,

Modified: trunk/Source/_javascript_Core/Sources.txt (255686 => 255687)


--- trunk/Source/_javascript_Core/Sources.txt	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/Sources.txt	2020-02-04 19:05:17 UTC (rev 255687)
@@ -275,6 +275,7 @@
 bytecode/ToThisStatus.cpp
 bytecode/TrackedReferences.cpp
 bytecode/UnlinkedCodeBlock.cpp
+bytecode/UnlinkedCodeBlockGenerator.cpp
 bytecode/UnlinkedEvalCodeBlock.cpp
 bytecode/UnlinkedFunctionCodeBlock.cpp
 bytecode/UnlinkedFunctionExecutable.cpp

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeBasicBlock.cpp (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/BytecodeBasicBlock.cpp	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeBasicBlock.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -30,6 +30,7 @@
 #include "InterpreterInlines.h"
 #include "JSCInlines.h"
 #include "PreciseJumpTargets.h"
+#include "UnlinkedCodeBlockGenerator.h"
 
 namespace JSC {
 
@@ -220,7 +221,7 @@
     return computeImpl(codeBlock, instructions);
 }
 
-auto BytecodeBasicBlock::compute(UnlinkedCodeBlock* codeBlock, const InstructionStream& instructions) -> BasicBlockVector
+auto BytecodeBasicBlock::compute(UnlinkedCodeBlockGenerator* codeBlock, const InstructionStream& instructions) -> BasicBlockVector
 {
     return computeImpl(codeBlock, instructions);
 }

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeBasicBlock.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/BytecodeBasicBlock.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeBasicBlock.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -36,6 +36,7 @@
 class BytecodeGraph;
 class CodeBlock;
 class UnlinkedCodeBlock;
+class UnlinkedCodeBlockGenerator;
 struct Instruction;
 
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(BytecodeBasicBlock);
@@ -72,7 +73,7 @@
 private:
     // Only called from BytecodeGraph.
     static BasicBlockVector compute(CodeBlock*, const InstructionStream& instructions);
-    static BasicBlockVector compute(UnlinkedCodeBlock*, const InstructionStream& instructions);
+    static BasicBlockVector compute(UnlinkedCodeBlockGenerator*, const InstructionStream& instructions);
     template<typename Block> static BasicBlockVector computeImpl(Block* codeBlock, const InstructionStream& instructions);
     void shrinkToFit();
 

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -40,7 +40,7 @@
 #include "PutByIdFlags.h"
 #include "StructureInlines.h"
 #include "ToThisStatus.h"
-#include "UnlinkedCodeBlock.h"
+#include "UnlinkedCodeBlockGenerator.h"
 #include "UnlinkedMetadataTableInlines.h"
 #include "WasmFunctionCodeBlock.h"
 #include "WasmGeneratorTraits.h"
@@ -270,7 +270,7 @@
 }
 
 template class BytecodeDumper<CodeBlock>;
-template class CodeBlockBytecodeDumper<UnlinkedCodeBlock>;
+template class CodeBlockBytecodeDumper<UnlinkedCodeBlockGenerator>;
 template class CodeBlockBytecodeDumper<CodeBlock>;
 
 #if ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -40,7 +40,7 @@
 #include "JSGenerator.h"
 #include "Label.h"
 #include "StrongInlines.h"
-#include "UnlinkedCodeBlock.h"
+#include "UnlinkedCodeBlockGenerator.h"
 #include "UnlinkedMetadataTableInlines.h"
 #include <wtf/Optional.h>
 
@@ -64,7 +64,7 @@
         VirtualRegister m_initialValue;
     };
 
-    BytecodeGeneratorification(BytecodeGenerator& bytecodeGenerator, UnlinkedCodeBlock* codeBlock, InstructionStreamWriter& instructions, SymbolTable* generatorFrameSymbolTable, int generatorFrameSymbolTableIndex)
+    BytecodeGeneratorification(BytecodeGenerator& bytecodeGenerator, UnlinkedCodeBlockGenerator* codeBlock, InstructionStreamWriter& instructions, SymbolTable* generatorFrameSymbolTable, int generatorFrameSymbolTableIndex)
         : m_bytecodeGenerator(bytecodeGenerator)
         , m_codeBlock(codeBlock)
         , m_instructions(instructions)
@@ -174,7 +174,7 @@
     BytecodeGenerator& m_bytecodeGenerator;
     InstructionStream::Offset m_enterPoint;
     Optional<GeneratorFrameData> m_generatorFrameData;
-    UnlinkedCodeBlock* m_codeBlock;
+    UnlinkedCodeBlockGenerator* m_codeBlock;
     InstructionStreamWriter& m_instructions;
     BytecodeGraph m_graph;
     Vector<Optional<Storage>> m_storages;
@@ -190,7 +190,7 @@
     {
     }
 
-    void run(UnlinkedCodeBlock* codeBlock, InstructionStreamWriter& instructions)
+    void run(UnlinkedCodeBlockGenerator* codeBlock, InstructionStreamWriter& instructions)
     {
         // Perform modified liveness analysis to determine which locals are live at the merge points.
         // This produces the conservative results for the question, "which variables should be saved and resumed?".
@@ -224,8 +224,8 @@
         VirtualRegister state = virtualRegisterForArgumentIncludingThis(static_cast<int32_t>(JSGenerator::GeneratorArgument::State));
         auto& jumpTable = m_codeBlock->addSwitchJumpTable();
         jumpTable.min = 0;
-        jumpTable.branchOffsets.resize(m_yields.size() + 1);
-        jumpTable.branchOffsets.fill(0);
+        jumpTable.branchOffsets = RefCountedArray<int32_t>(m_yields.size() + 1);
+        std::fill(jumpTable.branchOffsets.begin(), jumpTable.branchOffsets.end(), 0);
         jumpTable.add(0, nextToEnterPoint.offset());
         for (unsigned i = 0; i < m_yields.size(); ++i)
             jumpTable.add(i + 1, m_yields[i].point);
@@ -295,10 +295,10 @@
     rewriter.execute();
 }
 
-void performGeneratorification(BytecodeGenerator& bytecodeGenerator, UnlinkedCodeBlock* codeBlock, InstructionStreamWriter& instructions, SymbolTable* generatorFrameSymbolTable, int generatorFrameSymbolTableIndex)
+void performGeneratorification(BytecodeGenerator& bytecodeGenerator, UnlinkedCodeBlockGenerator* codeBlock, InstructionStreamWriter& instructions, SymbolTable* generatorFrameSymbolTable, int generatorFrameSymbolTableIndex)
 {
     if (UNLIKELY(Options::dumpBytecodesBeforeGeneratorification()))
-        CodeBlockBytecodeDumper<UnlinkedCodeBlock>::dumpBlock(codeBlock, instructions, WTF::dataFile());
+        CodeBlockBytecodeDumper<UnlinkedCodeBlockGenerator>::dumpBlock(codeBlock, instructions, WTF::dataFile());
 
     BytecodeGeneratorification pass(bytecodeGenerator, codeBlock, instructions, generatorFrameSymbolTable, generatorFrameSymbolTableIndex);
     pass.run();

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -31,9 +31,9 @@
 class BytecodeGenerator;
 class InstructionStreamWriter;
 class SymbolTable;
-class UnlinkedCodeBlock;
+class UnlinkedCodeBlockGenerator;
 class SymbolTable;
 
-void performGeneratorification(BytecodeGenerator&, UnlinkedCodeBlock*, InstructionStreamWriter&, SymbolTable* generatorFrameSymbolTable, int generatorFrameSymbolTableIndex);
+void performGeneratorification(BytecodeGenerator&, UnlinkedCodeBlockGenerator*, InstructionStreamWriter&, SymbolTable* generatorFrameSymbolTable, int generatorFrameSymbolTableIndex);
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeRewriter.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -173,7 +173,7 @@
         IncludeBranch& m_includeBranch;
     };
 
-    BytecodeRewriter(BytecodeGenerator& bytecodeGenerator, BytecodeGraph& graph, UnlinkedCodeBlock* codeBlock, InstructionStreamWriter& writer)
+    BytecodeRewriter(BytecodeGenerator& bytecodeGenerator, BytecodeGraph& graph, UnlinkedCodeBlockGenerator* codeBlock, InstructionStreamWriter& writer)
         : m_bytecodeGenerator(bytecodeGenerator)
         , m_graph(graph)
         , m_codeBlock(codeBlock)
@@ -227,7 +227,7 @@
 private:
     void insertImpl(InsertionPoint, IncludeBranch, InstructionStreamWriter&& fragment);
 
-    friend class UnlinkedCodeBlock;
+    friend class UnlinkedCodeBlockGenerator;
     void applyModification();
     void adjustJumpTargetsInFragment(unsigned finalOffset, Insertion&);
 
@@ -236,7 +236,7 @@
 
     BytecodeGenerator& m_bytecodeGenerator;
     BytecodeGraph& m_graph;
-    UnlinkedCodeBlock* m_codeBlock;
+    UnlinkedCodeBlockGenerator* m_codeBlock;
     InstructionStreamWriter& m_writer;
     Vector<Insertion, 8> m_insertions;
 };

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -473,7 +473,8 @@
             for (size_t i = 0; i < count; i++) {
                 UnlinkedSimpleJumpTable& sourceTable = unlinkedCodeBlock->switchJumpTable(i);
                 SimpleJumpTable& destTable = m_rareData->m_switchJumpTables[i];
-                destTable.branchOffsets = sourceTable.branchOffsets;
+                destTable.branchOffsets.resizeToFit(sourceTable.branchOffsets.size());
+                std::copy(sourceTable.branchOffsets.begin(), sourceTable.branchOffsets.end(), destTable.branchOffsets.begin());
                 destTable.min = sourceTable.min;
             }
         }
@@ -866,7 +867,7 @@
 #endif // ENABLE(JIT)
 }
 
-void CodeBlock::setConstantIdentifierSetRegisters(VM& vm, const Vector<ConstantIdentifierSetEntry>& constants)
+void CodeBlock::setConstantIdentifierSetRegisters(VM& vm, const RefCountedArray<ConstantIdentifierSetEntry>& constants)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSGlobalObject* globalObject = m_globalObject.get();
@@ -888,7 +889,7 @@
     }
 }
 
-void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable)
+void CodeBlock::setConstantRegisters(const RefCountedArray<WriteBarrier<Unknown>>& constants, const RefCountedArray<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable)
 {
     VM& vm = *m_vm;
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -899,10 +900,13 @@
     {
         ConcurrentJSLocker locker(m_lock);
         m_constantRegisters.resizeToFit(count);
+        m_constantsSourceCodeRepresentation.resizeToFit(count);
     }
     for (size_t i = 0; i < count; i++) {
         JSValue constant = constants[i].get();
-        switch (constantsSourceCodeRepresentation[i]) {
+        SourceCodeRepresentation representation = constantsSourceCodeRepresentation[i];
+        m_constantsSourceCodeRepresentation[i] = representation;
+        switch (representation) {
         case SourceCodeRepresentation::LinkTimeConstant:
             constant = globalObject->linkTimeConstant(static_cast<LinkTimeConstant>(constant.asInt32AsAnyInt()));
             break;
@@ -934,8 +938,6 @@
         }
         m_constantRegisters[i].set(vm, this, constant);
     }
-
-    m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
 }
 
 void CodeBlock::setAlternative(VM& vm, CodeBlock* alternative)
@@ -1808,7 +1810,7 @@
 {
     if (!m_rareData)
         return 0;
-    return HandlerInfo::handlerForIndex(m_rareData->m_exceptionHandlers, index, requiredHandler);
+    return HandlerInfo::handlerForIndex<HandlerInfo>(m_rareData->m_exceptionHandlers, index, requiredHandler);
 }
 
 DisposableCallSiteIndex CodeBlock::newExceptionHandlingCallSiteIndex(CallSiteIndex originalCallSite)
@@ -3195,7 +3197,7 @@
 {
     if (!unlinkedCodeBlock()->hasOpProfileControlFlowBytecodeOffsets())
         return;
-    const Vector<InstructionStream::Offset>& bytecodeOffsets = unlinkedCodeBlock()->opProfileControlFlowBytecodeOffsets();
+    const RefCountedArray<InstructionStream::Offset>& bytecodeOffsets = unlinkedCodeBlock()->opProfileControlFlowBytecodeOffsets();
     for (size_t i = 0, offsetsLength = bytecodeOffsets.size(); i < offsetsLength; i++) {
         // Because op_profile_control_flow is emitted at the beginning of every basic block, finding 
         // the next op_profile_control_flow will give us the text range of a single basic block.

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -615,7 +615,6 @@
     // Jump Tables
 
     size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
-    SimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(SimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); }
     SimpleJumpTable& switchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
     void clearSwitchJumpTables()
     {
@@ -632,7 +631,6 @@
 #endif
 
     size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
-    StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
     StringJumpTable& stringSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
 
     DirectEvalCodeCache& directEvalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_directEvalCodeCache; }
@@ -949,9 +947,9 @@
 
     void updateAllValueProfilePredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
 
-    void setConstantIdentifierSetRegisters(VM&, const Vector<ConstantIdentifierSetEntry>& constants);
+    void setConstantIdentifierSetRegisters(VM&, const RefCountedArray<ConstantIdentifierSetEntry>& constants);
 
-    void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable);
+    void setConstantRegisters(const RefCountedArray<WriteBarrier<Unknown>>& constants, const RefCountedArray<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable);
 
     void replaceConstant(VirtualRegister reg, JSValue value)
     {

Modified: trunk/Source/_javascript_Core/bytecode/HandlerInfo.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/HandlerInfo.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/HandlerInfo.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -65,10 +65,10 @@
 
     bool isCatchHandler() const { return type() == HandlerType::Catch; }
 
-    template<typename Handler>
-    static Handler* handlerForIndex(Vector<Handler>& exeptionHandlers, unsigned index, RequiredHandler requiredHandler)
+    template<typename Handler, typename Container>
+    static Handler* handlerForIndex(Container& exeptionHandlers, unsigned index, RequiredHandler requiredHandler)
     {
-        for (Handler& handler : exeptionHandlers) {
+        for (auto& handler : exeptionHandlers) {
             if ((requiredHandler == RequiredHandler::CatchHandler) && !handler.isCatchHandler())
                 continue;
 

Modified: trunk/Source/_javascript_Core/bytecode/JumpTable.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/JumpTable.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/JumpTable.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -97,12 +97,6 @@
 #endif
 
         int32_t offsetForValue(int32_t value, int32_t defaultOffset);
-        void add(int32_t key, int32_t offset)
-        {
-            if (!branchOffsets[key])
-                branchOffsets[key] = offset;
-        }
-
 #if ENABLE(JIT)
         void ensureCTITable()
         {

Modified: trunk/Source/_javascript_Core/bytecode/PreciseJumpTargets.cpp (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/PreciseJumpTargets.cpp	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/PreciseJumpTargets.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -99,12 +99,12 @@
     computePreciseJumpTargetsInternal<ComputePreciseJumpTargetsMode::FollowCodeBlockClaim>(codeBlock, instructions, out);
 }
 
-void computePreciseJumpTargets(UnlinkedCodeBlock* codeBlock, const InstructionStream& instructions, Vector<InstructionStream::Offset, 32>& out)
+void computePreciseJumpTargets(UnlinkedCodeBlockGenerator* codeBlock, const InstructionStream& instructions, Vector<InstructionStream::Offset, 32>& out)
 {
     computePreciseJumpTargetsInternal<ComputePreciseJumpTargetsMode::FollowCodeBlockClaim>(codeBlock, instructions, out);
 }
 
-void recomputePreciseJumpTargets(UnlinkedCodeBlock* codeBlock, const InstructionStream& instructions, Vector<InstructionStream::Offset>& out)
+void recomputePreciseJumpTargets(UnlinkedCodeBlockGenerator* codeBlock, const InstructionStream& instructions, Vector<InstructionStream::Offset>& out)
 {
     computePreciseJumpTargetsInternal<ComputePreciseJumpTargetsMode::ForceCompute>(codeBlock, instructions, out);
 }
@@ -114,7 +114,7 @@
     getJumpTargetsForInstruction(codeBlock, instruction, out);
 }
 
-void findJumpTargetsForInstruction(UnlinkedCodeBlock* codeBlock, const InstructionStream::Ref& instruction, Vector<InstructionStream::Offset, 1>& out)
+void findJumpTargetsForInstruction(UnlinkedCodeBlockGenerator* codeBlock, const InstructionStream::Ref& instruction, Vector<InstructionStream::Offset, 1>& out)
 {
     getJumpTargetsForInstruction(codeBlock, instruction, out);
 }

Modified: trunk/Source/_javascript_Core/bytecode/PreciseJumpTargets.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/PreciseJumpTargets.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/PreciseJumpTargets.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -34,11 +34,11 @@
 // Return a sorted list of bytecode index that are the destination of a jump.
 void computePreciseJumpTargets(CodeBlock*, Vector<InstructionStream::Offset, 32>& out);
 void computePreciseJumpTargets(CodeBlock*, const InstructionStream& instructions, Vector<InstructionStream::Offset, 32>& out);
-void computePreciseJumpTargets(UnlinkedCodeBlock*, const InstructionStream&, Vector<InstructionStream::Offset, 32>& out);
+void computePreciseJumpTargets(UnlinkedCodeBlockGenerator*, const InstructionStream&, Vector<InstructionStream::Offset, 32>& out);
 
-void recomputePreciseJumpTargets(UnlinkedCodeBlock*, const InstructionStream&, Vector<InstructionStream::Offset>& out);
+void recomputePreciseJumpTargets(UnlinkedCodeBlockGenerator*, const InstructionStream&, Vector<InstructionStream::Offset>& out);
 
 void findJumpTargetsForInstruction(CodeBlock*, const InstructionStream::Ref&, Vector<InstructionStream::Offset, 1>& out);
-void findJumpTargetsForInstruction(UnlinkedCodeBlock*, const InstructionStream::Ref&, Vector<InstructionStream::Offset, 1>& out);
+void findJumpTargetsForInstruction(UnlinkedCodeBlockGenerator*, const InstructionStream::Ref&, Vector<InstructionStream::Offset, 1>& out);
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -81,7 +81,7 @@
     ASSERT(m_codeType == static_cast<unsigned>(codeType));
     ASSERT(m_didOptimize == static_cast<unsigned>(MixedTriState));
     if (info.needsClassFieldInitializer() == NeedsClassFieldInitializer::Yes) {
-        createRareDataIfNecessary();
+        createRareDataIfNecessary(holdLock(cellLock()));
         m_rareData->m_needsClassFieldInitializer = static_cast<unsigned>(NeedsClassFieldInitializer::Yes);
     }
 }
@@ -94,10 +94,10 @@
     auto locker = holdLock(thisObject->cellLock());
     if (visitor.isFirstVisit())
         thisObject->m_age = std::min<unsigned>(static_cast<unsigned>(thisObject->m_age) + 1, maxAge);
-    for (FunctionExpressionVector::iterator ptr = thisObject->m_functionDecls.begin(), end = thisObject->m_functionDecls.end(); ptr != end; ++ptr)
-        visitor.append(*ptr);
-    for (FunctionExpressionVector::iterator ptr = thisObject->m_functionExprs.begin(), end = thisObject->m_functionExprs.end(); ptr != end; ++ptr)
-        visitor.append(*ptr);
+    for (auto& barrier : thisObject->m_functionDecls)
+        visitor.append(barrier);
+    for (auto& barrier : thisObject->m_functionExprs)
+        visitor.append(barrier);
     visitor.appendValues(thisObject->m_constantRegisters.data(), thisObject->m_constantRegisters.size());
     size_t extraMemory = thisObject->m_metadata->sizeInBytes();
     if (thisObject->m_instructions)
@@ -167,7 +167,7 @@
 
 void UnlinkedCodeBlock::dumpExpressionRangeInfo()
 {
-    Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
+    RefCountedArray<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
 
     size_t size = m_expressionInfo.size();
     dataLogF("UnlinkedCodeBlock %p expressionRangeInfo[%zu] {\n", this, size);
@@ -196,7 +196,7 @@
         return;
     }
 
-    const Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
+    const RefCountedArray<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
 
     int low = 0;
     int high = expressionInfo.size();
@@ -218,60 +218,6 @@
     getLineAndColumn(info, line, column);
 }
 
-void UnlinkedCodeBlock::addExpressionInfo(unsigned instructionOffset,
-    int divot, int startOffset, int endOffset, unsigned line, unsigned column)
-{
-    if (divot > ExpressionRangeInfo::MaxDivot) {
-        // Overflow has occurred, we can only give line number info for errors for this region
-        divot = 0;
-        startOffset = 0;
-        endOffset = 0;
-    } else if (startOffset > ExpressionRangeInfo::MaxOffset) {
-        // If the start offset is out of bounds we clear both offsets
-        // so we only get the divot marker. Error message will have to be reduced
-        // to line and charPosition number.
-        startOffset = 0;
-        endOffset = 0;
-    } else if (endOffset > ExpressionRangeInfo::MaxOffset) {
-        // The end offset is only used for additional context, and is much more likely
-        // to overflow (eg. function call arguments) so we are willing to drop it without
-        // dropping the rest of the range.
-        endOffset = 0;
-    }
-
-    unsigned positionMode =
-        (line <= ExpressionRangeInfo::MaxFatLineModeLine && column <= ExpressionRangeInfo::MaxFatLineModeColumn) 
-        ? ExpressionRangeInfo::FatLineMode
-        : (line <= ExpressionRangeInfo::MaxFatColumnModeLine && column <= ExpressionRangeInfo::MaxFatColumnModeColumn)
-        ? ExpressionRangeInfo::FatColumnMode
-        : ExpressionRangeInfo::FatLineAndColumnMode;
-
-    ExpressionRangeInfo info;
-    info.instructionOffset = instructionOffset;
-    info.divotPoint = divot;
-    info.startOffset = startOffset;
-    info.endOffset = endOffset;
-
-    info.mode = positionMode;
-    switch (positionMode) {
-    case ExpressionRangeInfo::FatLineMode:
-        info.encodeFatLineMode(line, column);
-        break;
-    case ExpressionRangeInfo::FatColumnMode:
-        info.encodeFatColumnMode(line, column);
-        break;
-    case ExpressionRangeInfo::FatLineAndColumnMode: {
-        createRareDataIfNecessary();
-        unsigned fatIndex = m_rareData->m_expressionInfoFatPositions.size();
-        ExpressionRangeInfo::FatPosition fatPos = { line, column };
-        m_rareData->m_expressionInfoFatPositions.append(fatPos);
-        info.position = fatIndex;
-    }
-    } // switch
-
-    m_expressionInfo.append(info);
-}
-
 bool UnlinkedCodeBlock::typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot)
 {
     static constexpr bool verbose = false;
@@ -298,30 +244,10 @@
     return true;
 }
 
-void UnlinkedCodeBlock::addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot)
-{
-    createRareDataIfNecessary();
-    RareData::TypeProfilerExpressionRange range;
-    range.m_startDivot = startDivot;
-    range.m_endDivot = endDivot;
-    m_rareData->m_typeProfilerInfoMap.set(instructionOffset, range);
-}
-
 UnlinkedCodeBlock::~UnlinkedCodeBlock()
 {
 }
 
-void UnlinkedCodeBlock::setInstructions(std::unique_ptr<InstructionStream> instructions)
-{
-    ASSERT(instructions);
-    {
-        auto locker = holdLock(cellLock());
-        m_instructions = WTFMove(instructions);
-        m_metadata->finalize();
-    }
-    Heap::heap(this)->reportExtraMemoryAllocated(m_instructions->sizeInBytes() + m_metadata->sizeInBytes());
-}
-
 const InstructionStream& UnlinkedCodeBlock::instructions() const
 {
     ASSERT(m_instructions.get());
@@ -337,69 +263,9 @@
 {
     if (!m_rareData)
         return nullptr;
-    return UnlinkedHandlerInfo::handlerForIndex(m_rareData->m_exceptionHandlers, index, requiredHandler);
+    return UnlinkedHandlerInfo::handlerForIndex<UnlinkedHandlerInfo>(m_rareData->m_exceptionHandlers, index, requiredHandler);
 }
 
-void UnlinkedCodeBlock::applyModification(BytecodeRewriter& rewriter, InstructionStreamWriter& instructions)
-{
-    // Before applying the changes, we adjust the jumps based on the original bytecode offset, the offset to the jump target, and
-    // the insertion information.
-
-    rewriter.adjustJumpTargets();
-
-    // Then, exception handlers should be adjusted.
-    if (m_rareData) {
-        for (UnlinkedHandlerInfo& handler : m_rareData->m_exceptionHandlers) {
-            handler.target = rewriter.adjustAbsoluteOffset(handler.target);
-            handler.start = rewriter.adjustAbsoluteOffset(handler.start);
-            handler.end = rewriter.adjustAbsoluteOffset(handler.end);
-        }
-
-        for (size_t i = 0; i < m_rareData->m_opProfileControlFlowBytecodeOffsets.size(); ++i)
-            m_rareData->m_opProfileControlFlowBytecodeOffsets[i] = rewriter.adjustAbsoluteOffset(m_rareData->m_opProfileControlFlowBytecodeOffsets[i]);
-
-        if (!m_rareData->m_typeProfilerInfoMap.isEmpty()) {
-            HashMap<unsigned, RareData::TypeProfilerExpressionRange> adjustedTypeProfilerInfoMap;
-            for (auto& entry : m_rareData->m_typeProfilerInfoMap)
-                adjustedTypeProfilerInfoMap.set(rewriter.adjustAbsoluteOffset(entry.key), entry.value);
-            m_rareData->m_typeProfilerInfoMap.swap(adjustedTypeProfilerInfoMap);
-        }
-    }
-
-    for (size_t i = 0; i < m_expressionInfo.size(); ++i)
-        m_expressionInfo[i].instructionOffset = rewriter.adjustAbsoluteOffset(m_expressionInfo[i].instructionOffset);
-
-    // Then, modify the unlinked instructions.
-    rewriter.applyModification();
-
-    // And recompute the jump target based on the modified unlinked instructions.
-    m_jumpTargets.clear();
-    recomputePreciseJumpTargets(this, instructions, m_jumpTargets);
-}
-
-void UnlinkedCodeBlock::shrinkToFit()
-{
-    auto locker = holdLock(cellLock());
-    
-    m_jumpTargets.shrinkToFit();
-    m_identifiers.shrinkToFit();
-    m_constantRegisters.shrinkToFit();
-    m_constantsSourceCodeRepresentation.shrinkToFit();
-    m_functionDecls.shrinkToFit();
-    m_functionExprs.shrinkToFit();
-    m_expressionInfo.shrinkToFit();
-
-    if (m_rareData) {
-        m_rareData->m_exceptionHandlers.shrinkToFit();
-        m_rareData->m_switchJumpTables.shrinkToFit();
-        m_rareData->m_stringSwitchJumpTables.shrinkToFit();
-        m_rareData->m_expressionInfoFatPositions.shrinkToFit();
-        m_rareData->m_opProfileControlFlowBytecodeOffsets.shrinkToFit();
-        m_rareData->m_bitVectors.shrinkToFit();
-        m_rareData->m_constantIdentifierSets.shrinkToFit();
-    }
-}
-
 void UnlinkedCodeBlock::dump(PrintStream&) const
 {
 }
@@ -420,12 +286,6 @@
     return *m_liveness;
 }
 
-void UnlinkedCodeBlock::addOutOfLineJumpTarget(InstructionStream::Offset bytecodeOffset, int target)
-{
-    RELEASE_ASSERT(target);
-    m_outOfLineJumpTargets.set(bytecodeOffset, target);
-}
-
 int UnlinkedCodeBlock::outOfLineJumpOffset(InstructionStream::Offset bytecodeOffset)
 {
     ASSERT(m_outOfLineJumpTargets.contains(bytecodeOffset));

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -43,6 +43,7 @@
 #include <algorithm>
 #include <wtf/BitVector.h>
 #include <wtf/HashSet.h>
+#include <wtf/RefCountedArray.h>
 #include <wtf/TriState.h>
 #include <wtf/Vector.h>
 #include <wtf/text/UniquedStringImpl.h>
@@ -59,6 +60,7 @@
 class SourceCode;
 class SourceProvider;
 class UnlinkedCodeBlock;
+class UnlinkedCodeBlockGenerator;
 class UnlinkedFunctionCodeBlock;
 class UnlinkedFunctionExecutable;
 struct ExecutableInfo;
@@ -94,7 +96,7 @@
 };
 
 struct UnlinkedSimpleJumpTable {
-    Vector<int32_t> branchOffsets;
+    RefCountedArray<int32_t> branchOffsets;
     int32_t min;
 
     int32_t offsetForValue(int32_t value, int32_t defaultOffset);
@@ -133,13 +135,8 @@
     void setHasTailCalls() { m_hasTailCalls = true; }
     bool allowDirectEvalCache() const { return !(m_features & NoEvalCacheFeature); }
 
-    void addExpressionInfo(unsigned instructionOffset, int divot,
-        int startOffset, int endOffset, unsigned line, unsigned column);
-
-    void addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot);
-
     bool hasExpressionInfo() { return m_expressionInfo.size(); }
-    const Vector<ExpressionRangeInfo>& expressionInfo() { return m_expressionInfo; }
+    const RefCountedArray<ExpressionRangeInfo>& expressionInfo() { return m_expressionInfo; }
 
     bool hasCheckpoints() const { return m_hasCheckpoints; }
     void setHasCheckpoints() { m_hasCheckpoints = true; }
@@ -150,67 +147,26 @@
 
     // Parameter information
     void setNumParameters(int newValue) { m_numParameters = newValue; }
-    void addParameter() { m_numParameters++; }
     unsigned numParameters() const { return m_numParameters; }
 
     // Constant Pools
 
     size_t numberOfIdentifiers() const { return m_identifiers.size(); }
-    void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
     const Identifier& identifier(int index) const { return m_identifiers[index]; }
-    const Vector<Identifier>& identifiers() const { return m_identifiers; }
+    const RefCountedArray<Identifier>& identifiers() const { return m_identifiers; }
 
     BitVector& bitVector(size_t i) { ASSERT(m_rareData); return m_rareData->m_bitVectors[i]; }
-    unsigned addBitVector(BitVector&& bitVector)
-    {
-        createRareDataIfNecessary();
-        m_rareData->m_bitVectors.append(WTFMove(bitVector));
-        return m_rareData->m_bitVectors.size() - 1;
-    }
 
-    void addSetConstant(IdentifierSet& set)
-    {
-        createRareDataIfNecessary();
-        VM& vm = this->vm();
-        auto locker = lockDuringMarking(vm.heap, cellLock());
-        unsigned result = m_constantRegisters.size();
-        m_constantRegisters.append(WriteBarrier<Unknown>());
-        m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
-        m_rareData->m_constantIdentifierSets.append(ConstantIdentifierSetEntry(set, result));
-    }
-
-    unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other)
-    {
-        VM& vm = this->vm();
-        auto locker = lockDuringMarking(vm.heap, cellLock());
-        unsigned result = m_constantRegisters.size();
-        m_constantRegisters.append(WriteBarrier<Unknown>());
-        m_constantRegisters.last().set(vm, this, v);
-        m_constantsSourceCodeRepresentation.append(sourceCodeRepresentation);
-        return result;
-    }
-    unsigned addConstant(LinkTimeConstant linkTimeConstant)
-    {
-        VM& vm = this->vm();
-        auto locker = lockDuringMarking(vm.heap, cellLock());
-        unsigned result = m_constantRegisters.size();
-        m_constantRegisters.append(WriteBarrier<Unknown>());
-        m_constantRegisters.last().set(vm, this, jsNumber(static_cast<int32_t>(linkTimeConstant)));
-        m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::LinkTimeConstant);
-        return result;
-    }
-
-    const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; }
+    const RefCountedArray<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; }
     const WriteBarrier<Unknown>& constantRegister(VirtualRegister reg) const { return m_constantRegisters[reg.toConstantIndex()]; }
     ALWAYS_INLINE JSValue getConstant(VirtualRegister reg) const { return m_constantRegisters[reg.toConstantIndex()].get(); }
-    const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; }
+    const RefCountedArray<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; }
 
     unsigned numberOfConstantIdentifierSets() const { return m_rareData ? m_rareData->m_constantIdentifierSets.size() : 0; }
-    const Vector<ConstantIdentifierSetEntry>& constantIdentifierSets() { ASSERT(m_rareData); return m_rareData->m_constantIdentifierSets; }
+    const RefCountedArray<ConstantIdentifierSetEntry>& constantIdentifierSets() { ASSERT(m_rareData); return m_rareData->m_constantIdentifierSets; }
 
     // Jumps
     size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
-    void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
     unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
     unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
 
@@ -223,9 +179,6 @@
     SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); }
     JSParserScriptMode scriptMode() const { return static_cast<JSParserScriptMode>(m_scriptMode); }
 
-    void shrinkToFit();
-
-    void setInstructions(std::unique_ptr<InstructionStream>);
     const InstructionStream& instructions() const;
 
     int numCalleeLocals() const { return m_numCalleeLocals; }
@@ -234,39 +187,18 @@
     // Jump Tables
 
     size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
-    UnlinkedSimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); }
     UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
 
     size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
-    UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
     UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
 
-    unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
-    {
-        VM& vm = this->vm();
-        auto locker = lockDuringMarking(vm.heap, cellLock());
-        unsigned size = m_functionDecls.size();
-        m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
-        m_functionDecls.last().set(vm, this, n);
-        return size;
-    }
     UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
     size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
-    unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
-    {
-        VM& vm = this->vm();
-        auto locker = lockDuringMarking(vm.heap, cellLock());
-        unsigned size = m_functionExprs.size();
-        m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
-        m_functionExprs.last().set(vm, this, n);
-        return size;
-    }
     UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
     size_t numberOfFunctionExprs() { return m_functionExprs.size(); }
 
     // Exception handling support
     size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
-    void addExceptionHandler(const UnlinkedHandlerInfo& handler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(handler); }
     UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
 
     CodeType codeType() const { return static_cast<CodeType>(m_codeType); }
@@ -303,13 +235,8 @@
     ALWAYS_INLINE unsigned startColumn() const { return 0; }
     unsigned endColumn() const { return m_endColumn; }
 
-    void addOpProfileControlFlowBytecodeOffset(InstructionStream::Offset offset)
+    const RefCountedArray<InstructionStream::Offset>& opProfileControlFlowBytecodeOffsets() const
     {
-        createRareDataIfNecessary();
-        m_rareData->m_opProfileControlFlowBytecodeOffsets.append(offset);
-    }
-    const Vector<InstructionStream::Offset>& opProfileControlFlowBytecodeOffsets() const
-    {
         ASSERT(m_rareData);
         return m_rareData->m_opProfileControlFlowBytecodeOffsets;
     }
@@ -387,7 +314,7 @@
 
 private:
     friend class BytecodeRewriter;
-    friend class BytecodeGenerator;
+    friend class UnlinkedCodeBlockGenerator;
     template<typename Traits>
     friend class BytecodeGeneratorBase;
 
@@ -394,14 +321,10 @@
     template<typename CodeBlockType>
     friend class CachedCodeBlock;
 
-    void applyModification(BytecodeRewriter&, InstructionStreamWriter&);
-
-    void createRareDataIfNecessary()
+    void createRareDataIfNecessary(const AbstractLocker&)
     {
-        if (!m_rareData) {
-            auto locker = lockDuringMarking(*heap(), cellLock());
+        if (!m_rareData)
             m_rareData = makeUnique<RareData>();
-        }
     }
 
     void getLineAndColumn(const ExpressionRangeInfo&, unsigned& line, unsigned& column) const;
@@ -446,7 +369,7 @@
     String m_sourceURLDirective;
     String m_sourceMappingURLDirective;
 
-    Vector<InstructionStream::Offset> m_jumpTargets;
+    RefCountedArray<InstructionStream::Offset> m_jumpTargets;
     Ref<UnlinkedMetadataTable> m_metadata;
     std::unique_ptr<InstructionStream> m_instructions;
     std::unique_ptr<BytecodeLivenessAnalysis> m_liveness;
@@ -457,10 +380,10 @@
 #endif
 
     // Constant Pools
-    Vector<Identifier> m_identifiers;
-    Vector<WriteBarrier<Unknown>> m_constantRegisters;
-    Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
-    typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector;
+    RefCountedArray<Identifier> m_identifiers;
+    RefCountedArray<WriteBarrier<Unknown>> m_constantRegisters;
+    RefCountedArray<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
+    using FunctionExpressionVector = RefCountedArray<WriteBarrier<UnlinkedFunctionExecutable>>;
     FunctionExpressionVector m_functionDecls;
     FunctionExpressionVector m_functionExprs;
 
@@ -468,13 +391,13 @@
     struct RareData {
         WTF_MAKE_STRUCT_FAST_ALLOCATED;
 
-        Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
+        RefCountedArray<UnlinkedHandlerInfo> m_exceptionHandlers;
 
         // Jump Tables
-        Vector<UnlinkedSimpleJumpTable> m_switchJumpTables;
-        Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
+        RefCountedArray<UnlinkedSimpleJumpTable> m_switchJumpTables;
+        RefCountedArray<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
 
-        Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
+        RefCountedArray<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
 
         struct TypeProfilerExpressionRange {
             unsigned m_startDivot;
@@ -481,14 +404,13 @@
             unsigned m_endDivot;
         };
         HashMap<unsigned, TypeProfilerExpressionRange> m_typeProfilerInfoMap;
-        Vector<InstructionStream::Offset> m_opProfileControlFlowBytecodeOffsets;
-        Vector<BitVector> m_bitVectors;
-        Vector<ConstantIdentifierSetEntry> m_constantIdentifierSets;
+        RefCountedArray<InstructionStream::Offset> m_opProfileControlFlowBytecodeOffsets;
+        RefCountedArray<BitVector> m_bitVectors;
+        RefCountedArray<ConstantIdentifierSetEntry> m_constantIdentifierSets;
 
         unsigned m_needsClassFieldInitializer : 1;
     };
 
-    void addOutOfLineJumpTarget(InstructionStream::Offset, int target);
     int outOfLineJumpOffset(InstructionStream::Offset);
     int outOfLineJumpOffset(const InstructionStream::Ref& instruction)
     {
@@ -498,16 +420,9 @@
 private:
     using OutOfLineJumpTargets = HashMap<InstructionStream::Offset, int>;
 
-    OutOfLineJumpTargets replaceOutOfLineJumpTargets()
-    {
-        OutOfLineJumpTargets newJumpTargets;
-        std::swap(m_outOfLineJumpTargets, newJumpTargets);
-        return newJumpTargets;
-    }
-
     OutOfLineJumpTargets m_outOfLineJumpTargets;
     std::unique_ptr<RareData> m_rareData;
-    Vector<ExpressionRangeInfo> m_expressionInfo;
+    RefCountedArray<ExpressionRangeInfo> m_expressionInfo;
 
 protected:
     static void visitChildren(JSCell*, SlotVisitor&);

Added: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp (0 => 255687)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -0,0 +1,237 @@
+/*
+ * 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 INC. ``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 INC. OR
+ * 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.
+ */
+
+#include "config.h"
+#include "UnlinkedCodeBlockGenerator.h"
+
+#include "BytecodeGenerator.h"
+#include "BytecodeLivenessAnalysis.h"
+#include "BytecodeRewriter.h"
+#include "ClassInfo.h"
+#include "CodeCache.h"
+#include "ExecutableInfo.h"
+#include "FunctionOverrides.h"
+#include "InstructionStream.h"
+#include "JSCInlines.h"
+#include "JSString.h"
+#include "Opcode.h"
+#include "Parser.h"
+#include "PreciseJumpTargetsInlines.h"
+#include "SourceProvider.h"
+#include "Structure.h"
+#include "SymbolTable.h"
+#include "UnlinkedEvalCodeBlock.h"
+#include "UnlinkedFunctionCodeBlock.h"
+#include "UnlinkedMetadataTableInlines.h"
+#include "UnlinkedModuleProgramCodeBlock.h"
+#include "UnlinkedProgramCodeBlock.h"
+#include <wtf/DataLog.h>
+
+namespace JSC {
+
+inline void UnlinkedCodeBlockGenerator::getLineAndColumn(const ExpressionRangeInfo& info, unsigned& line, unsigned& column) const
+{
+    switch (info.mode) {
+    case ExpressionRangeInfo::FatLineMode:
+        info.decodeFatLineMode(line, column);
+        break;
+    case ExpressionRangeInfo::FatColumnMode:
+        info.decodeFatColumnMode(line, column);
+        break;
+    case ExpressionRangeInfo::FatLineAndColumnMode: {
+        unsigned fatIndex = info.position;
+        const ExpressionRangeInfo::FatPosition& fatPos = m_expressionInfoFatPositions[fatIndex];
+        line = fatPos.line;
+        column = fatPos.column;
+        break;
+    }
+    } // switch
+}
+
+void UnlinkedCodeBlockGenerator::addExpressionInfo(unsigned instructionOffset, int divot, int startOffset, int endOffset, unsigned line, unsigned column)
+{
+    if (divot > ExpressionRangeInfo::MaxDivot) {
+        // Overflow has occurred, we can only give line number info for errors for this region
+        divot = 0;
+        startOffset = 0;
+        endOffset = 0;
+    } else if (startOffset > ExpressionRangeInfo::MaxOffset) {
+        // If the start offset is out of bounds we clear both offsets
+        // so we only get the divot marker. Error message will have to be reduced
+        // to line and charPosition number.
+        startOffset = 0;
+        endOffset = 0;
+    } else if (endOffset > ExpressionRangeInfo::MaxOffset) {
+        // The end offset is only used for additional context, and is much more likely
+        // to overflow (eg. function call arguments) so we are willing to drop it without
+        // dropping the rest of the range.
+        endOffset = 0;
+    }
+
+    unsigned positionMode =
+        (line <= ExpressionRangeInfo::MaxFatLineModeLine && column <= ExpressionRangeInfo::MaxFatLineModeColumn)
+        ? ExpressionRangeInfo::FatLineMode
+        : (line <= ExpressionRangeInfo::MaxFatColumnModeLine && column <= ExpressionRangeInfo::MaxFatColumnModeColumn)
+        ? ExpressionRangeInfo::FatColumnMode
+        : ExpressionRangeInfo::FatLineAndColumnMode;
+
+    ExpressionRangeInfo info;
+    info.instructionOffset = instructionOffset;
+    info.divotPoint = divot;
+    info.startOffset = startOffset;
+    info.endOffset = endOffset;
+
+    info.mode = positionMode;
+    switch (positionMode) {
+    case ExpressionRangeInfo::FatLineMode:
+        info.encodeFatLineMode(line, column);
+        break;
+    case ExpressionRangeInfo::FatColumnMode:
+        info.encodeFatColumnMode(line, column);
+        break;
+    case ExpressionRangeInfo::FatLineAndColumnMode: {
+        unsigned fatIndex = m_expressionInfoFatPositions.size();
+        ExpressionRangeInfo::FatPosition fatPos = { line, column };
+        m_expressionInfoFatPositions.append(fatPos);
+        info.position = fatIndex;
+    }
+    } // switch
+
+    m_expressionInfo.append(info);
+}
+
+void UnlinkedCodeBlockGenerator::addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot)
+{
+    UnlinkedCodeBlock::RareData::TypeProfilerExpressionRange range;
+    range.m_startDivot = startDivot;
+    range.m_endDivot = endDivot;
+    m_typeProfilerInfoMap.set(instructionOffset, range);
+}
+
+void UnlinkedCodeBlockGenerator::finalize(std::unique_ptr<InstructionStream> instructions)
+{
+    ASSERT(instructions);
+    {
+        auto locker = holdLock(m_codeBlock->cellLock());
+        m_codeBlock->m_instructions = WTFMove(instructions);
+        m_codeBlock->m_metadata->finalize();
+
+        m_codeBlock->m_jumpTargets = WTFMove(m_jumpTargets);
+        m_codeBlock->m_identifiers = WTFMove(m_identifiers);
+        m_codeBlock->m_constantRegisters = WTFMove(m_constantRegisters);
+        m_codeBlock->m_constantsSourceCodeRepresentation = WTFMove(m_constantsSourceCodeRepresentation);
+        m_codeBlock->m_functionDecls = WTFMove(m_functionDecls);
+        m_codeBlock->m_functionExprs = WTFMove(m_functionExprs);
+        m_codeBlock->m_expressionInfo = WTFMove(m_expressionInfo);
+        m_codeBlock->m_outOfLineJumpTargets = WTFMove(m_outOfLineJumpTargets);
+
+        if (!m_codeBlock->m_rareData) {
+            if (!m_exceptionHandlers.isEmpty()
+                || !m_switchJumpTables.isEmpty()
+                || !m_stringSwitchJumpTables.isEmpty()
+                || !m_expressionInfoFatPositions.isEmpty()
+                || !m_typeProfilerInfoMap.isEmpty()
+                || !m_opProfileControlFlowBytecodeOffsets.isEmpty()
+                || !m_bitVectors.isEmpty()
+                || !m_constantIdentifierSets.isEmpty())
+                m_codeBlock->createRareDataIfNecessary(locker);
+        }
+        if (m_codeBlock->m_rareData) {
+            m_codeBlock->m_rareData->m_exceptionHandlers = WTFMove(m_exceptionHandlers);
+            m_codeBlock->m_rareData->m_switchJumpTables = WTFMove(m_switchJumpTables);
+            m_codeBlock->m_rareData->m_stringSwitchJumpTables = WTFMove(m_stringSwitchJumpTables);
+            m_codeBlock->m_rareData->m_expressionInfoFatPositions = WTFMove(m_expressionInfoFatPositions);
+            m_codeBlock->m_rareData->m_typeProfilerInfoMap = WTFMove(m_typeProfilerInfoMap);
+            m_codeBlock->m_rareData->m_opProfileControlFlowBytecodeOffsets = WTFMove(m_opProfileControlFlowBytecodeOffsets);
+            m_codeBlock->m_rareData->m_bitVectors = WTFMove(m_bitVectors);
+            m_codeBlock->m_rareData->m_constantIdentifierSets = WTFMove(m_constantIdentifierSets);
+        }
+    }
+    m_vm.heap.writeBarrier(m_codeBlock.get());
+    m_vm.heap.reportExtraMemoryAllocated(m_codeBlock->m_instructions->sizeInBytes() + m_codeBlock->m_metadata->sizeInBytes());
+}
+
+UnlinkedHandlerInfo* UnlinkedCodeBlockGenerator::handlerForBytecodeIndex(BytecodeIndex bytecodeIndex, RequiredHandler requiredHandler)
+{
+    return handlerForIndex(bytecodeIndex.offset(), requiredHandler);
+}
+
+UnlinkedHandlerInfo* UnlinkedCodeBlockGenerator::handlerForIndex(unsigned index, RequiredHandler requiredHandler)
+{
+    return UnlinkedHandlerInfo::handlerForIndex<UnlinkedHandlerInfo>(m_exceptionHandlers, index, requiredHandler);
+}
+
+void UnlinkedCodeBlockGenerator::applyModification(BytecodeRewriter& rewriter, InstructionStreamWriter& instructions)
+{
+    // Before applying the changes, we adjust the jumps based on the original bytecode offset, the offset to the jump target, and
+    // the insertion information.
+
+    rewriter.adjustJumpTargets();
+
+    // Then, exception handlers should be adjusted.
+    for (UnlinkedHandlerInfo& handler : m_exceptionHandlers) {
+        handler.target = rewriter.adjustAbsoluteOffset(handler.target);
+        handler.start = rewriter.adjustAbsoluteOffset(handler.start);
+        handler.end = rewriter.adjustAbsoluteOffset(handler.end);
+    }
+
+    for (size_t i = 0; i < m_opProfileControlFlowBytecodeOffsets.size(); ++i)
+        m_opProfileControlFlowBytecodeOffsets[i] = rewriter.adjustAbsoluteOffset(m_opProfileControlFlowBytecodeOffsets[i]);
+
+    if (!m_typeProfilerInfoMap.isEmpty()) {
+        HashMap<unsigned, UnlinkedCodeBlock::RareData::TypeProfilerExpressionRange> adjustedTypeProfilerInfoMap;
+        for (auto& entry : m_typeProfilerInfoMap)
+            adjustedTypeProfilerInfoMap.set(rewriter.adjustAbsoluteOffset(entry.key), entry.value);
+        m_typeProfilerInfoMap.swap(adjustedTypeProfilerInfoMap);
+    }
+
+    for (size_t i = 0; i < m_expressionInfo.size(); ++i)
+        m_expressionInfo[i].instructionOffset = rewriter.adjustAbsoluteOffset(m_expressionInfo[i].instructionOffset);
+
+    // Then, modify the unlinked instructions.
+    rewriter.applyModification();
+
+    // And recompute the jump target based on the modified unlinked instructions.
+    m_jumpTargets.clear();
+    recomputePreciseJumpTargets(this, instructions, m_jumpTargets);
+}
+
+void UnlinkedCodeBlockGenerator::addOutOfLineJumpTarget(InstructionStream::Offset bytecodeOffset, int target)
+{
+    RELEASE_ASSERT(target);
+    m_outOfLineJumpTargets.set(bytecodeOffset, target);
+}
+
+int UnlinkedCodeBlockGenerator::outOfLineJumpOffset(InstructionStream::Offset bytecodeOffset)
+{
+    ASSERT(m_outOfLineJumpTargets.contains(bytecodeOffset));
+    return m_outOfLineJumpTargets.get(bytecodeOffset);
+}
+
+void UnlinkedCodeBlockGenerator::dump(PrintStream&) const
+{
+}
+
+} // namespace JSC

Added: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.h (0 => 255687)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -0,0 +1,216 @@
+/*
+ * 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 INC. ``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 INC. OR
+ * 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.
+ */
+
+
+#pragma once
+
+#include "UnlinkedCodeBlock.h"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+// FIXME: Create UnlinkedCodeBlock inside UnlinkedCodeBlockGenerator.
+// https://bugs.webkit.org/show_bug.cgi?id=207212
+class UnlinkedCodeBlockGenerator {
+    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(UnlinkedCodeBlockGenerator)
+public:
+    UnlinkedCodeBlockGenerator(VM& vm, UnlinkedCodeBlock* codeBlock)
+        : m_vm(vm)
+        , m_codeBlock(vm, codeBlock)
+    {
+    }
+
+    VM& vm() { return m_vm; }
+
+    bool isConstructor() const { return m_codeBlock->isConstructor(); }
+    ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); }
+    SuperBinding superBinding() const { return m_codeBlock->superBinding(); }
+    JSParserScriptMode scriptMode() const { return m_codeBlock->scriptMode(); }
+    NeedsClassFieldInitializer needsClassFieldInitializer() const { return m_codeBlock->needsClassFieldInitializer(); }
+    bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
+    bool usesEval() const { return m_codeBlock->usesEval(); }
+    SourceParseMode parseMode() const { return m_codeBlock->parseMode(); }
+    bool isArrowFunction() { return m_codeBlock->isArrowFunction(); }
+    DerivedContextType derivedContextType() const { return m_codeBlock->derivedContextType(); }
+    EvalContextType evalContextType() const { return m_codeBlock->evalContextType(); }
+    bool isArrowFunctionContext() const { return m_codeBlock->isArrowFunctionContext(); }
+    bool isClassContext() const { return m_codeBlock->isClassContext(); }
+    int numCalleeLocals() const { return m_codeBlock->m_numCalleeLocals; }
+    int numVars() const { return m_codeBlock->m_numVars; }
+    unsigned numParameters() const { return m_codeBlock->numParameters(); }
+    VirtualRegister thisRegister() const { return m_codeBlock->thisRegister(); }
+    VirtualRegister scopeRegister() const { return m_codeBlock->scopeRegister(); }
+    bool wasCompiledWithDebuggingOpcodes() const { return m_codeBlock->wasCompiledWithDebuggingOpcodes(); }
+    bool hasCheckpoints() const { return m_codeBlock->hasCheckpoints(); }
+    bool hasTailCalls() const { return m_codeBlock->hasTailCalls(); }
+
+    // Updating UnlinkedCodeBlock.
+    void setHasCheckpoints() { m_codeBlock->setHasCheckpoints(); }
+    void setHasTailCalls() { m_codeBlock->setHasTailCalls(); }
+    void setNumCalleeLocals(int numCalleeLocals) { m_codeBlock->m_numCalleeLocals = numCalleeLocals; }
+    void setNumVars(int numVars) { m_codeBlock->m_numVars = numVars; }
+    void setThisRegister(VirtualRegister thisRegister) { m_codeBlock->setThisRegister(thisRegister); }
+    void setScopeRegister(VirtualRegister thisRegister) { m_codeBlock->setScopeRegister(thisRegister); }
+    void setNumParameters(int newValue) { m_codeBlock->setNumParameters(newValue); }
+
+    UnlinkedMetadataTable& metadata() { return m_codeBlock->metadata(); }
+    void addExpressionInfo(unsigned instructionOffset, int divot, int startOffset, int endOffset, unsigned line, unsigned column);
+    void addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot);
+    void addOpProfileControlFlowBytecodeOffset(InstructionStream::Offset offset)
+    {
+        m_opProfileControlFlowBytecodeOffsets.append(offset);
+    }
+
+    size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
+    void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
+    unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
+    unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
+
+    size_t numberOfSwitchJumpTables() const { return m_switchJumpTables.size(); }
+    UnlinkedSimpleJumpTable& addSwitchJumpTable() { m_switchJumpTables.append(UnlinkedSimpleJumpTable()); return m_switchJumpTables.last(); }
+    UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { return m_switchJumpTables[tableIndex]; }
+
+    size_t numberOfStringSwitchJumpTables() const { return m_stringSwitchJumpTables.size(); }
+    UnlinkedStringJumpTable& addStringSwitchJumpTable() { m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_stringSwitchJumpTables.last(); }
+    UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { return m_stringSwitchJumpTables[tableIndex]; }
+
+    size_t numberOfExceptionHandlers() const { return m_exceptionHandlers.size(); }
+    UnlinkedHandlerInfo& exceptionHandler(int index) { return m_exceptionHandlers[index]; }
+    void addExceptionHandler(const UnlinkedHandlerInfo& handler) { m_exceptionHandlers.append(handler); }
+    UnlinkedHandlerInfo* handlerForBytecodeIndex(BytecodeIndex, RequiredHandler = RequiredHandler::AnyHandler);
+    UnlinkedHandlerInfo* handlerForIndex(unsigned, RequiredHandler = RequiredHandler::AnyHandler);
+
+    BitVector& bitVector(size_t i) { return m_bitVectors[i]; }
+    unsigned addBitVector(BitVector&& bitVector)
+    {
+        m_bitVectors.append(WTFMove(bitVector));
+        return m_bitVectors.size() - 1;
+    }
+
+    unsigned numberOfConstantIdentifierSets() const { return m_constantIdentifierSets.size(); }
+    const Vector<ConstantIdentifierSetEntry>& constantIdentifierSets() { return m_constantIdentifierSets; }
+    void addSetConstant(IdentifierSet& set)
+    {
+        ASSERT(m_vm.heap.isDeferred());
+        unsigned result = m_constantRegisters.size();
+        m_constantRegisters.append(WriteBarrier<Unknown>());
+        m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
+        m_constantIdentifierSets.append(ConstantIdentifierSetEntry(set, result));
+    }
+
+    const WriteBarrier<Unknown>& constantRegister(VirtualRegister reg) const { return m_constantRegisters[reg.toConstantIndex()]; }
+    const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; }
+    ALWAYS_INLINE JSValue getConstant(VirtualRegister reg) const { return m_constantRegisters[reg.toConstantIndex()].get(); }
+    const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; }
+
+    unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other)
+    {
+        ASSERT(m_vm.heap.isDeferred());
+        unsigned result = m_constantRegisters.size();
+        m_constantRegisters.append(WriteBarrier<Unknown>());
+        m_constantRegisters.last().setWithoutWriteBarrier(v);
+        m_constantsSourceCodeRepresentation.append(sourceCodeRepresentation);
+        return result;
+    }
+    unsigned addConstant(LinkTimeConstant linkTimeConstant)
+    {
+        ASSERT(m_vm.heap.isDeferred());
+        unsigned result = m_constantRegisters.size();
+        m_constantRegisters.append(WriteBarrier<Unknown>());
+        m_constantRegisters.last().setWithoutWriteBarrier(jsNumber(static_cast<int32_t>(linkTimeConstant)));
+        m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::LinkTimeConstant);
+        return result;
+    }
+
+    unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
+    {
+        ASSERT(m_vm.heap.isDeferred());
+        unsigned size = m_functionDecls.size();
+        m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
+        m_functionDecls.last().setWithoutWriteBarrier(n);
+        return size;
+    }
+
+    unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
+    {
+        unsigned size = m_functionExprs.size();
+        m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
+        m_functionExprs.last().setWithoutWriteBarrier(n);
+        return size;
+    }
+
+    size_t numberOfIdentifiers() const { return m_identifiers.size(); }
+    const Identifier& identifier(int index) const { return m_identifiers[index]; }
+    void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
+
+    using OutOfLineJumpTargets = HashMap<InstructionStream::Offset, int>;
+    void addOutOfLineJumpTarget(InstructionStream::Offset, int target);
+    int outOfLineJumpOffset(InstructionStream::Offset);
+    int outOfLineJumpOffset(const InstructionStream::Ref& instruction)
+    {
+        return outOfLineJumpOffset(instruction.offset());
+    }
+    OutOfLineJumpTargets replaceOutOfLineJumpTargets()
+    {
+        OutOfLineJumpTargets newJumpTargets;
+        std::swap(m_outOfLineJumpTargets, newJumpTargets);
+        return newJumpTargets;
+    }
+
+    size_t metadataSizeInBytes() { return m_codeBlock->metadataSizeInBytes(); }
+
+    void getLineAndColumn(const ExpressionRangeInfo&, unsigned& line, unsigned& column) const;
+
+    void applyModification(BytecodeRewriter&, InstructionStreamWriter&);
+
+    void finalize(std::unique_ptr<InstructionStream>);
+
+    void dump(PrintStream&) const;
+
+private:
+    VM& m_vm;
+    Strong<UnlinkedCodeBlock> m_codeBlock;
+    // In non-RareData.
+    Vector<InstructionStream::Offset> m_jumpTargets;
+    Vector<Identifier> m_identifiers;
+    Vector<WriteBarrier<Unknown>> m_constantRegisters;
+    Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
+    Vector<WriteBarrier<UnlinkedFunctionExecutable>> m_functionDecls;
+    Vector<WriteBarrier<UnlinkedFunctionExecutable>> m_functionExprs;
+    Vector<ExpressionRangeInfo> m_expressionInfo;
+    OutOfLineJumpTargets m_outOfLineJumpTargets;
+    // In RareData.
+    Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
+    Vector<UnlinkedSimpleJumpTable> m_switchJumpTables;
+    Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
+    Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
+    HashMap<unsigned, UnlinkedCodeBlock::RareData::TypeProfilerExpressionRange> m_typeProfilerInfoMap;
+    Vector<InstructionStream::Offset> m_opProfileControlFlowBytecodeOffsets;
+    Vector<BitVector> m_bitVectors;
+    Vector<ConstantIdentifierSetEntry> m_constantIdentifierSets;
+};
+
+} // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -288,10 +288,7 @@
         performGeneratorification(*this, m_codeBlock.get(), m_writer, m_generatorFrameSymbolTable.get(), m_generatorFrameSymbolTableIndex);
 
     RELEASE_ASSERT(static_cast<unsigned>(m_codeBlock->numCalleeLocals()) < static_cast<unsigned>(FirstConstantRegisterIndex));
-    m_codeBlock->setInstructions(m_writer.finalize());
-
-    m_codeBlock->shrinkToFit();
-
+    m_codeBlock->finalize(m_writer.finalize());
     if (m_expressionTooDeep)
         return ParserError(ParserError::OutOfMemory);
     return ParserError(ParserError::ErrorNone);
@@ -298,7 +295,7 @@
 }
 
 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables)
-    : BytecodeGeneratorBase(Strong<UnlinkedCodeBlock>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
+    : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
     , m_codeGenerationMode(codeGenerationMode)
     , m_scopeNode(programNode)
     , m_thisRegister(CallFrame::thisArgumentOffset())
@@ -339,7 +336,7 @@
 }
 
 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables)
-    : BytecodeGeneratorBase(Strong<UnlinkedCodeBlock>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
+    : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
     , m_codeGenerationMode(codeGenerationMode)
     , m_scopeNode(functionNode)
     , m_codeType(FunctionCode)
@@ -830,7 +827,7 @@
 }
 
 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables)
-    : BytecodeGeneratorBase(Strong<UnlinkedCodeBlock>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
+    : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
     , m_codeGenerationMode(codeGenerationMode)
     , m_scopeNode(evalNode)
     , m_thisRegister(CallFrame::thisArgumentOffset())
@@ -888,7 +885,7 @@
 }
 
 BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, OptionSet<CodeGenerationMode> codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables)
-    : BytecodeGeneratorBase(Strong<UnlinkedCodeBlock>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
+    : BytecodeGeneratorBase(makeUnique<UnlinkedCodeBlockGenerator>(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters())
     , m_codeGenerationMode(codeGenerationMode)
     , m_scopeNode(moduleProgramNode)
     , m_thisRegister(CallFrame::thisArgumentOffset())
@@ -1190,7 +1187,7 @@
     m_parameters.grow(m_parameters.size() + 1);
     auto& parameter = registerFor(reg);
     parameter.setIndex(reg);
-    m_codeBlock->addParameter();
+    m_codeBlock->setNumParameters(m_codeBlock->numParameters() + 1);
     return &parameter;
 }
 
@@ -3781,9 +3778,9 @@
     if (isCaptured)
         addResult.iterator->value.setIsCaptured();
     addResult.iterator->value.setIsConst(); // The function name scope name acts like a const variable.
-    unsigned numVars = m_codeBlock->m_numVars;
+    unsigned numVars = m_codeBlock->numVars();
     pushLexicalScopeInternal(nameScopeEnvironment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::NotUnderTDZ, ScopeType::FunctionNameScope, ScopeRegisterType::Var);
-    ASSERT_UNUSED(numVars, m_codeBlock->m_numVars == static_cast<int>(numVars + 1)); // Should have only created one new "var" for the function name scope.
+    ASSERT_UNUSED(numVars, m_codeBlock->numVars() == static_cast<int>(numVars + 1)); // Should have only created one new "var" for the function name scope.
     bool shouldTreatAsLexicalVariable = isStrictMode();
     Variable functionVar = variableForLocalEntry(property, m_lexicalScopeStack.last().m_symbolTable->get(NoLockingNecessary, property.impl()), m_lexicalScopeStack.last().m_symbolTableConstantIndex, shouldTreatAsLexicalVariable);
     emitPutToScope(m_lexicalScopeStack.last().m_scope, functionVar, callee, ThrowIfNotFound, InitializationMode::NotInitialization);
@@ -3874,8 +3871,8 @@
     int32_t (*keyGetter)(ExpressionNode*, int32_t min, int32_t max))
 {
     jumpTable.min = min;
-    jumpTable.branchOffsets.resize(max - min + 1);
-    jumpTable.branchOffsets.fill(0);
+    jumpTable.branchOffsets = RefCountedArray<int32_t>(max - min + 1);
+    std::fill(jumpTable.branchOffsets.begin(), jumpTable.branchOffsets.end(), 0);
     for (uint32_t i = 0; i < clauseCount; ++i) {
         // We're emitting this after the clause labels should have been fixed, so 
         // the labels should not be "forward" references
@@ -4948,7 +4945,7 @@
     emitJumpIfTrue(emitIsUndefinedOrNull(newTemporary(), src), m_optionalChainTargetStack.last().get());
 }
 
-void ForInContext::finalize(BytecodeGenerator& generator, UnlinkedCodeBlock* codeBlock, unsigned bodyBytecodeEndOffset)
+void ForInContext::finalize(BytecodeGenerator& generator, UnlinkedCodeBlockGenerator* codeBlock, unsigned bodyBytecodeEndOffset)
 {
     // Lexically invalidating ForInContexts is kind of weak sauce, but it only occurs if
     // either of the following conditions is true:
@@ -4973,7 +4970,7 @@
     }
 }
 
-void StructureForInContext::finalize(BytecodeGenerator& generator, UnlinkedCodeBlock* codeBlock, unsigned bodyBytecodeEndOffset)
+void StructureForInContext::finalize(BytecodeGenerator& generator, UnlinkedCodeBlockGenerator* codeBlock, unsigned bodyBytecodeEndOffset)
 {
     Base::finalize(generator, codeBlock, bodyBytecodeEndOffset);
     if (isValid())
@@ -5012,7 +5009,7 @@
     }
 }
 
-void IndexedForInContext::finalize(BytecodeGenerator& generator, UnlinkedCodeBlock* codeBlock, unsigned bodyBytecodeEndOffset)
+void IndexedForInContext::finalize(BytecodeGenerator& generator, UnlinkedCodeBlockGenerator* codeBlock, unsigned bodyBytecodeEndOffset)
 {
     Base::finalize(generator, codeBlock, bodyBytecodeEndOffset);
     if (isValid())

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -48,6 +48,7 @@
 #include "StaticPropertyAnalyzer.h"
 #include "SymbolTable.h"
 #include "UnlinkedCodeBlock.h"
+#include "UnlinkedCodeBlockGenerator.h"
 #include <functional>
 #include <wtf/CheckedArithmetic.h>
 #include <wtf/HashFunctions.h>
@@ -224,7 +225,7 @@
 
         unsigned bodyBytecodeStartOffset() const { return m_bodyBytecodeStartOffset; }
 
-        void finalize(BytecodeGenerator&, UnlinkedCodeBlock*, unsigned bodyBytecodeEndOffset);
+        void finalize(BytecodeGenerator&, UnlinkedCodeBlockGenerator*, unsigned bodyBytecodeEndOffset);
 
     private:
         RefPtr<RegisterID> m_localRegister;
@@ -255,7 +256,7 @@
             m_getInsts.append(GetInst { instIndex, propertyRegIndex });
         }
 
-        void finalize(BytecodeGenerator&, UnlinkedCodeBlock*, unsigned bodyBytecodeEndOffset);
+        void finalize(BytecodeGenerator&, UnlinkedCodeBlockGenerator*, unsigned bodyBytecodeEndOffset);
 
     private:
         RefPtr<RegisterID> m_indexRegister;
@@ -275,7 +276,7 @@
 
         RegisterID* index() const { return m_indexRegister.get(); }
 
-        void finalize(BytecodeGenerator&, UnlinkedCodeBlock*, unsigned bodyBytecodeEndOffset);
+        void finalize(BytecodeGenerator&, UnlinkedCodeBlockGenerator*, unsigned bodyBytecodeEndOffset);
         void addGetInst(unsigned instIndex, int propertyIndex) { m_getInsts.append({ instIndex, propertyIndex }); }
 
     private:
@@ -368,7 +369,7 @@
         using OpcodeTraits = JSOpcodeTraits;
         using OpcodeID = ::JSC::OpcodeID;
         using OpNop = ::JSC::OpNop;
-        using CodeBlock = Strong<UnlinkedCodeBlock>;
+        using CodeBlock = std::unique_ptr<UnlinkedCodeBlockGenerator>;
         static constexpr OpcodeID opcodeForDisablingOptimizations = op_end;
     };
 

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGeneratorBaseInlines.h (255686 => 255687)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGeneratorBaseInlines.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGeneratorBaseInlines.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -161,9 +161,9 @@
 RegisterID* BytecodeGeneratorBase<Traits>::newRegister()
 {
     m_calleeLocals.append(virtualRegisterForLocal(m_calleeLocals.size()));
-    int numCalleeLocals = std::max<int>(m_codeBlock->m_numCalleeLocals, m_calleeLocals.size());
+    int numCalleeLocals = std::max<int>(m_codeBlock->numCalleeLocals(), m_calleeLocals.size());
     numCalleeLocals = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numCalleeLocals);
-    m_codeBlock->m_numCalleeLocals = numCalleeLocals;
+    m_codeBlock->setNumCalleeLocals(numCalleeLocals);
     return &m_calleeLocals.last();
 }
 
@@ -181,9 +181,10 @@
 template<typename Traits>
 RegisterID* BytecodeGeneratorBase<Traits>::addVar()
 {
-    ++m_codeBlock->m_numVars;
+    int numVars = m_codeBlock->numVars();
+    m_codeBlock->setNumVars(numVars + 1);
     RegisterID* result = newRegister();
-    ASSERT(VirtualRegister(result->index()).toLocal() == m_codeBlock->m_numVars - 1);
+    ASSERT(VirtualRegister(result->index()).toLocal() == numVars);
     result->ref(); // We should never free this slot.
     return result;
 }

Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (255686 => 255687)


--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp	2020-02-04 19:05:17 UTC (rev 255687)
@@ -611,6 +611,16 @@
             ::JSC::encode(encoder, buffer[i], vector[i]);
     }
 
+    void encode(Encoder& encoder, const RefCountedArray<SourceType<T>>& vector)
+    {
+        m_size = vector.size();
+        if (!m_size)
+            return;
+        T* buffer = this->template allocate<T>(encoder, m_size);
+        for (unsigned i = 0; i < m_size; ++i)
+            ::JSC::encode(encoder, buffer[i], vector[i]);
+    }
+
     template<typename... Args>
     void decode(Decoder& decoder, Vector<SourceType<T>, InlineCapacity, OverflowHandler, 16, Malloc>& vector, Args... args) const
     {
@@ -622,6 +632,18 @@
             ::JSC::decode(decoder, buffer[i], vector[i], args...);
     }
 
+    template<typename... Args>
+    void decode(Decoder& decoder, RefCountedArray<SourceType<T>>& vector, Args... args) const
+    {
+        if (!m_size)
+            return;
+        vector = RefCountedArray<SourceType<T>>(m_size);
+        const T* buffer = this->template buffer<T>();
+        for (unsigned i = 0; i < m_size; ++i)
+            ::JSC::decode(decoder, buffer[i], vector[i], args...);
+    }
+
+
 private:
     unsigned m_size;
 };

Modified: trunk/Source/_javascript_Core/wasm/WasmFunctionCodeBlock.h (255686 => 255687)


--- trunk/Source/_javascript_Core/wasm/WasmFunctionCodeBlock.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/_javascript_Core/wasm/WasmFunctionCodeBlock.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -72,6 +72,9 @@
     const Vector<uint64_t>& constants() const { return m_constants; }
     const InstructionStream& instructions() const { return *m_instructions; }
 
+    void setNumVars(int numVars) { m_numVars = numVars; }
+    void setNumCalleeLocals(int numCalleeLocals) { m_numCalleeLocals = numCalleeLocals; }
+
     ALWAYS_INLINE uint64_t getConstant(VirtualRegister reg) const { return m_constants[reg.toConstantIndex()]; }
     ALWAYS_INLINE Type getConstantType(VirtualRegister reg) const
     {

Modified: trunk/Source/WTF/ChangeLog (255686 => 255687)


--- trunk/Source/WTF/ChangeLog	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/WTF/ChangeLog	2020-02-04 19:05:17 UTC (rev 255687)
@@ -1,3 +1,20 @@
+2020-02-04  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Introduce UnlinkedCodeBlockGenerator and reduce sizeof(UnlinkedCodeBlock)
+        https://bugs.webkit.org/show_bug.cgi?id=207087
+
+        Reviewed by Tadeu Zagallo.
+
+        Add more useful methods for RefCountedArray.
+
+        * wtf/RefCountedArray.h:
+        (WTF::RefCountedArray::operator=):
+        (WTF::RefCountedArray::isEmpty const):
+        (WTF::RefCountedArray::front):
+        (WTF::RefCountedArray::front const):
+        (WTF::RefCountedArray::last):
+        (WTF::RefCountedArray::last const):
+
 2020-02-03  Alex Christensen  <[email protected]>
 
         Reduce size of HashMap and HashSet

Modified: trunk/Source/WTF/wtf/RefCountedArray.h (255686 => 255687)


--- trunk/Source/WTF/wtf/RefCountedArray.h	2020-02-04 19:01:40 UTC (rev 255686)
+++ trunk/Source/WTF/wtf/RefCountedArray.h	2020-02-04 19:05:17 UTC (rev 255687)
@@ -115,6 +115,30 @@
         return assign<PtrTraits>(other);
     }
 
+    template<size_t inlineCapacity, typename OverflowHandler>
+    RefCountedArray& operator=(const Vector<T, inlineCapacity, OverflowHandler>& other)
+    {
+        T* oldData = data();
+        if (other.isEmpty())
+            PtrTraits::exchange(m_data, nullptr);
+        else {
+            T* data = "" + sizeof(T) * other.size())))->payload();
+            m_data = data;
+            Header::fromPayload(data)->refCount = 1;
+            Header::fromPayload(data)->length = other.size();
+            ASSERT(Header::fromPayload(data)->length == other.size());
+            VectorTypeOperations<T>::uninitializedCopy(other.begin(), other.end(), data);
+        }
+        if (!oldData)
+            return *this;
+        if (--Header::fromPayload(oldData)->refCount)
+            return *this;
+        VectorTypeOperations<T>::destruct(oldData, oldData + Header::fromPayload(oldData)->length);
+
+        RefCountedArrayMalloc::free(Header::fromPayload(oldData));
+        return *this;
+    }
+
     ~RefCountedArray()
     {
         if (!m_data)
@@ -139,6 +163,8 @@
             return 0;
         return Header::fromPayload(data())->length;
     }
+
+    bool isEmpty() const { return size() == 0; }
     
     size_t byteSize() const { return size() * sizeof(T); }
     
@@ -171,6 +197,11 @@
     T& operator[](size_t i) { return at(i); }
     const T& operator[](size_t i) const { return at(i); }
 
+    T& first() { return (*this)[0]; }
+    const T& first() const { return (*this)[0]; }
+    T& last() { return (*this)[size() - 1]; }
+    const T& last() const { return (*this)[size() - 1]; }
+
     template<typename OtherTraits = PtrTraits>
     bool operator==(const RefCountedArray<T, OtherTraits>& other) const
     {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to