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 ¶meter;
}
@@ -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
{