Skip to content

Commit d1cb45f

Browse files
committed
Make byte codes with arithmetic profiles switch to using an index instead of a pointer in metadata
https://bugs.webkit.org/show_bug.cgi?id=230798 Reviewed by Yusuke Suzuki. This patch makes each bytecode that uses a BinaryArithProfile/UnaryArithProfile have an index into a table instead of storing a pointer to the profile in its metadata. Then, we can just load the profile using the index in the bytecode, which saves memory. * bytecode/BytecodeList.rb: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::finishCreation): (JSC::CodeBlock::binaryArithProfileForPC): (JSC::CodeBlock::unaryArithProfileForPC): * bytecode/UnlinkedCodeBlock.cpp: (JSC::UnlinkedCodeBlock::allocateSharedProfiles): * bytecode/UnlinkedCodeBlock.h: * bytecode/UnlinkedCodeBlockGenerator.cpp: (JSC::UnlinkedCodeBlockGenerator::finalize): * bytecode/UnlinkedCodeBlockGenerator.h: (JSC::UnlinkedCodeBlockGenerator::addBinaryArithProfile): (JSC::UnlinkedCodeBlockGenerator::addUnaryArithProfile): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitUnaryOp): (JSC::BytecodeGenerator::emitInc): (JSC::BytecodeGenerator::emitDec): * bytecompiler/BytecodeGenerator.h: * jit/JITArithmetic.cpp: (JSC::JIT::emit_op_negate): (JSC::JIT::emit_op_add): (JSC::JIT::emit_op_div): (JSC::JIT::emit_op_mul): (JSC::JIT::emit_op_sub): * llint/LowLevelInterpreter.asm: * llint/LowLevelInterpreter32_64.asm: * llint/LowLevelInterpreter64.asm: * runtime/CommonSlowPaths.cpp: (JSC::updateArithProfileForUnaryArithOp): (JSC::JSC_DEFINE_COMMON_SLOW_PATH): Canonical link: https://commits.webkit.org/242146@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283088 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent b6c7212 commit d1cb45f

15 files changed

Lines changed: 111 additions & 105 deletions

‎Source/JavaScriptCore/ChangeLog‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,45 @@
1+
2021-09-26 Saam Barati <sbarati@apple.com>
2+
3+
Make byte codes with arithmetic profiles switch to using an index instead of a pointer in metadata
4+
https://bugs.webkit.org/show_bug.cgi?id=230798
5+
6+
Reviewed by Yusuke Suzuki.
7+
8+
This patch makes each bytecode that uses a BinaryArithProfile/UnaryArithProfile
9+
have an index into a table instead of storing a pointer to the profile in its metadata.
10+
Then, we can just load the profile using the index in the bytecode, which saves memory.
11+
12+
* bytecode/BytecodeList.rb:
13+
* bytecode/CodeBlock.cpp:
14+
(JSC::CodeBlock::finishCreation):
15+
(JSC::CodeBlock::binaryArithProfileForPC):
16+
(JSC::CodeBlock::unaryArithProfileForPC):
17+
* bytecode/UnlinkedCodeBlock.cpp:
18+
(JSC::UnlinkedCodeBlock::allocateSharedProfiles):
19+
* bytecode/UnlinkedCodeBlock.h:
20+
* bytecode/UnlinkedCodeBlockGenerator.cpp:
21+
(JSC::UnlinkedCodeBlockGenerator::finalize):
22+
* bytecode/UnlinkedCodeBlockGenerator.h:
23+
(JSC::UnlinkedCodeBlockGenerator::addBinaryArithProfile):
24+
(JSC::UnlinkedCodeBlockGenerator::addUnaryArithProfile):
25+
* bytecompiler/BytecodeGenerator.cpp:
26+
(JSC::BytecodeGenerator::emitUnaryOp):
27+
(JSC::BytecodeGenerator::emitInc):
28+
(JSC::BytecodeGenerator::emitDec):
29+
* bytecompiler/BytecodeGenerator.h:
30+
* jit/JITArithmetic.cpp:
31+
(JSC::JIT::emit_op_negate):
32+
(JSC::JIT::emit_op_add):
33+
(JSC::JIT::emit_op_div):
34+
(JSC::JIT::emit_op_mul):
35+
(JSC::JIT::emit_op_sub):
36+
* llint/LowLevelInterpreter.asm:
37+
* llint/LowLevelInterpreter32_64.asm:
38+
* llint/LowLevelInterpreter64.asm:
39+
* runtime/CommonSlowPaths.cpp:
40+
(JSC::updateArithProfileForUnaryArithOp):
41+
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
42+
143
2021-09-25 Saam Barati <sbarati@apple.com>
244

345
Build an unlinked baseline JIT

‎Source/JavaScriptCore/bytecode/BytecodeList.rb‎

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@
6464

6565
:ValueProfile,
6666
:ValueProfileAndVirtualRegisterBuffer,
67-
:UnaryArithProfile,
68-
:BinaryArithProfile,
6967
:ArrayProfile,
7068
:ArrayAllocationProfile,
7169
:ObjectAllocationProfile,
@@ -289,10 +287,8 @@
289287
dst: VirtualRegister,
290288
lhs: VirtualRegister,
291289
rhs: VirtualRegister,
290+
profileIndex: unsigned,
292291
operandTypes: OperandTypes,
293-
},
294-
metadata: {
295-
arithProfile: BinaryArithProfile.*
296292
}
297293

298294
op_group :ValueProfiledBinaryOp,
@@ -351,9 +347,7 @@
351347
],
352348
args: {
353349
srcDst: VirtualRegister,
354-
},
355-
metadata: {
356-
arithProfile: UnaryArithProfile.*
350+
profileIndex: unsigned,
357351
}
358352

359353
op :to_object,
@@ -383,10 +377,8 @@
383377
args: {
384378
dst: VirtualRegister,
385379
operand: VirtualRegister,
380+
profileIndex: unsigned,
386381
resultType: ResultType,
387-
},
388-
metadata: {
389-
arithProfile: UnaryArithProfile.*
390382
}
391383

392384
op :not,

‎Source/JavaScriptCore/bytecode/CodeBlock.cpp‎

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -471,21 +471,6 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink
471471
break; \
472472
}
473473

474-
unsigned binaryProfileIndex = 0;
475-
unsigned unaryProfileIndex = 0;
476-
#define LINK_WITH_BINARY_ARITH_PROFILE(__op) \
477-
CASE(__op): { \
478-
INITIALIZE_METADATA(__op) \
479-
metadata.m_arithProfile = &m_unlinkedCode->binaryArithProfile(binaryProfileIndex++); \
480-
break; \
481-
}
482-
#define LINK_WITH_UNARY_ARITH_PROFILE(__op) \
483-
CASE(__op): { \
484-
INITIALIZE_METADATA(__op) \
485-
metadata.m_arithProfile = &m_unlinkedCode->unaryArithProfile(unaryProfileIndex++); \
486-
break; \
487-
}
488-
489474
const InstructionStream& instructionStream = instructions();
490475
for (const auto& instruction : instructionStream) {
491476
OpcodeID opcodeID = instruction->opcodeID();
@@ -548,15 +533,6 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink
548533
LINK(OpCreatePromise)
549534
LINK(OpCreateGenerator)
550535

551-
LINK_WITH_BINARY_ARITH_PROFILE(OpAdd)
552-
LINK_WITH_BINARY_ARITH_PROFILE(OpMul)
553-
LINK_WITH_BINARY_ARITH_PROFILE(OpDiv)
554-
LINK_WITH_BINARY_ARITH_PROFILE(OpSub)
555-
556-
LINK_WITH_UNARY_ARITH_PROFILE(OpNegate)
557-
LINK_WITH_UNARY_ARITH_PROFILE(OpInc)
558-
LINK_WITH_UNARY_ARITH_PROFILE(OpDec)
559-
560536
LINK(OpJneqPtr)
561537

562538
LINK(OpCatch)
@@ -3413,13 +3389,13 @@ BinaryArithProfile* CodeBlock::binaryArithProfileForPC(const Instruction* pc)
34133389
{
34143390
switch (pc->opcodeID()) {
34153391
case op_add:
3416-
return pc->as<OpAdd>().metadata(this).m_arithProfile;
3392+
return &unlinkedCodeBlock()->binaryArithProfile(pc->as<OpAdd>().m_profileIndex);
34173393
case op_mul:
3418-
return pc->as<OpMul>().metadata(this).m_arithProfile;
3394+
return &unlinkedCodeBlock()->binaryArithProfile(pc->as<OpMul>().m_profileIndex);
34193395
case op_sub:
3420-
return pc->as<OpSub>().metadata(this).m_arithProfile;
3396+
return &unlinkedCodeBlock()->binaryArithProfile(pc->as<OpSub>().m_profileIndex);
34213397
case op_div:
3422-
return pc->as<OpDiv>().metadata(this).m_arithProfile;
3398+
return &unlinkedCodeBlock()->binaryArithProfile(pc->as<OpDiv>().m_profileIndex);
34233399
default:
34243400
break;
34253401
}
@@ -3431,11 +3407,11 @@ UnaryArithProfile* CodeBlock::unaryArithProfileForPC(const Instruction* pc)
34313407
{
34323408
switch (pc->opcodeID()) {
34333409
case op_negate:
3434-
return pc->as<OpNegate>().metadata(this).m_arithProfile;
3410+
return &unlinkedCodeBlock()->unaryArithProfile(pc->as<OpNegate>().m_profileIndex);
34353411
case op_inc:
3436-
return pc->as<OpInc>().metadata(this).m_arithProfile;
3412+
return &unlinkedCodeBlock()->unaryArithProfile(pc->as<OpInc>().m_profileIndex);
34373413
case op_dec:
3438-
return pc->as<OpDec>().metadata(this).m_arithProfile;
3414+
return &unlinkedCodeBlock()->unaryArithProfile(pc->as<OpDec>().m_profileIndex);
34393415
default:
34403416
break;
34413417
}

‎Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp‎

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ int32_t UnlinkedCodeBlock::thresholdForJIT(int32_t threshold)
361361
}
362362

363363

364-
void UnlinkedCodeBlock::allocateSharedProfiles()
364+
void UnlinkedCodeBlock::allocateSharedProfiles(unsigned numBinaryArithProfiles, unsigned numUnaryArithProfiles)
365365
{
366366
RELEASE_ASSERT(!m_metadata->isFinalized());
367367

@@ -389,19 +389,10 @@ void UnlinkedCodeBlock::allocateSharedProfiles()
389389
numberOfArrayProfiles += m_metadata->numEntries<OpIteratorNext>();
390390
numberOfArrayProfiles += m_metadata->numEntries<OpGetById>();
391391
m_arrayProfiles = FixedVector<UnlinkedArrayProfile>(numberOfArrayProfiles);
392-
393-
unsigned numberOfBinaryArithProfiles = 0;
394-
#define COUNT(__op) numberOfBinaryArithProfiles += m_metadata->numEntries<__op>();
395-
FOR_EACH_OPCODE_WITH_BINARY_ARITH_PROFILE(COUNT)
396-
#undef COUNT
397-
m_binaryArithProfiles = FixedVector<BinaryArithProfile>(numberOfBinaryArithProfiles);
398-
399-
unsigned numberOfUnaryArithProfiles = 0;
400-
#define COUNT(__op) numberOfUnaryArithProfiles += m_metadata->numEntries<__op>();
401-
FOR_EACH_OPCODE_WITH_UNARY_ARITH_PROFILE(COUNT)
402-
#undef COUNT
403-
m_unaryArithProfiles = FixedVector<UnaryArithProfile>(numberOfUnaryArithProfiles);
404392
}
393+
394+
m_binaryArithProfiles = FixedVector<BinaryArithProfile>(numBinaryArithProfiles);
395+
m_unaryArithProfiles = FixedVector<UnaryArithProfile>(numUnaryArithProfiles);
405396
}
406397

407398
} // namespace JSC

‎Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ class UnlinkedCodeBlock : public JSCell {
352352
// Some builtins are required to always complete the loops they run.
353353
return !isBuiltinFunction();
354354
}
355-
void allocateSharedProfiles();
355+
void allocateSharedProfiles(unsigned numBinaryArithProfiles, unsigned numUnaryArithProfiles);
356356
UnlinkedValueProfile& unlinkedValueProfile(unsigned index) { return m_valueProfiles[index]; }
357357
UnlinkedArrayProfile& unlinkedArrayProfile(unsigned index) { return m_arrayProfiles[index]; }
358358

‎Source/JavaScriptCore/bytecode/UnlinkedCodeBlockGenerator.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void UnlinkedCodeBlockGenerator::finalize(std::unique_ptr<InstructionStream> ins
119119
{
120120
Locker locker { m_codeBlock->cellLock() };
121121
m_codeBlock->m_instructions = WTFMove(instructions);
122-
m_codeBlock->allocateSharedProfiles();
122+
m_codeBlock->allocateSharedProfiles(m_numBinaryArithProfiles, m_numUnaryArithProfiles);
123123
m_codeBlock->m_metadata->finalize();
124124

125125
m_codeBlock->m_jumpTargets = WTFMove(m_jumpTargets);

‎Source/JavaScriptCore/bytecode/UnlinkedCodeBlockGenerator.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ class UnlinkedCodeBlockGenerator {
200200

201201
void dump(PrintStream&) const;
202202

203+
unsigned addBinaryArithProfile() { return m_numBinaryArithProfiles++; }
204+
unsigned addUnaryArithProfile() { return m_numUnaryArithProfiles++; }
205+
203206
private:
204207
VM& m_vm;
205208
Strong<UnlinkedCodeBlock> m_codeBlock;
@@ -221,6 +224,8 @@ class UnlinkedCodeBlockGenerator {
221224
Vector<InstructionStream::Offset> m_opProfileControlFlowBytecodeOffsets;
222225
Vector<BitVector> m_bitVectors;
223226
Vector<IdentifierSet> m_constantIdentifierSets;
227+
unsigned m_numBinaryArithProfiles { 0 };
228+
unsigned m_numUnaryArithProfiles { 0 };
224229
};
225230

226231
} // namespace JSC

‎Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,7 +1598,7 @@ RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, R
15981598
emitUnaryOp<OpNot>(dst, src);
15991599
break;
16001600
case op_negate:
1601-
OpNegate::emit(this, dst, src, type);
1601+
OpNegate::emit(this, dst, src, m_codeBlock->addUnaryArithProfile(), type);
16021602
break;
16031603
case op_bitnot:
16041604
emitUnaryOp<OpBitnot>(dst, src);
@@ -1696,13 +1696,13 @@ RegisterID* BytecodeGenerator::emitTypeOf(RegisterID* dst, RegisterID* src)
16961696

16971697
RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
16981698
{
1699-
OpInc::emit(this, srcDst);
1699+
OpInc::emit(this, srcDst, m_codeBlock->addUnaryArithProfile());
17001700
return srcDst;
17011701
}
17021702

17031703
RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
17041704
{
1705-
OpDec::emit(this, srcDst);
1705+
OpDec::emit(this, srcDst, m_codeBlock->addUnaryArithProfile());
17061706
return srcDst;
17071707
}
17081708

‎Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ namespace JSC {
682682
RegisterID*>
683683
emitBinaryOp(RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
684684
{
685-
BinaryOp::emit(this, dst, src1, src2, types);
685+
BinaryOp::emit(this, dst, src1, src2, m_codeBlock->addBinaryArithProfile(), types);
686686
return dst;
687687
}
688688

‎Source/JavaScriptCore/jit/JITArithmetic.cpp‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ void JIT::emitBinaryDoubleOp(const Instruction *instruction, OperandTypes types,
722722

723723
void JIT::emit_op_negate(const Instruction* currentInstruction)
724724
{
725-
UnaryArithProfile* arithProfile = currentInstruction->as<OpNegate>().metadata(m_profiledCodeBlock).m_arithProfile;
725+
UnaryArithProfile* arithProfile = &m_unlinkedCodeBlock->unaryArithProfile(currentInstruction->as<OpNegate>().m_profileIndex);
726726
JITNegIC* negateIC = m_mathICs.addJITNegIC(arithProfile);
727727
m_instructionToMathIC.add(currentInstruction, negateIC);
728728
// FIXME: it would be better to call those operationValueNegate, since the operand can be a BigInt
@@ -904,7 +904,7 @@ void JIT::emit_op_urshift(const Instruction* currentInstruction)
904904

905905
void JIT::emit_op_add(const Instruction* currentInstruction)
906906
{
907-
BinaryArithProfile* arithProfile = currentInstruction->as<OpAdd>().metadata(m_profiledCodeBlock).m_arithProfile;
907+
BinaryArithProfile* arithProfile = &m_unlinkedCodeBlock->binaryArithProfile(currentInstruction->as<OpAdd>().m_profileIndex);
908908
JITAddIC* addIC = m_mathICs.addJITAddIC(arithProfile);
909909
m_instructionToMathIC.add(currentInstruction, addIC);
910910
emitMathICFast<OpAdd>(addIC, currentInstruction, operationValueAddProfiled, operationValueAdd);
@@ -1175,7 +1175,7 @@ void JIT::emit_op_div(const Instruction* currentInstruction)
11751175

11761176
BinaryArithProfile* arithProfile = nullptr;
11771177
if (shouldEmitProfiling())
1178-
arithProfile = currentInstruction->as<OpDiv>().metadata(m_profiledCodeBlock).m_arithProfile;
1178+
arithProfile = &m_unlinkedCodeBlock->binaryArithProfile(currentInstruction->as<OpDiv>().m_profileIndex);
11791179

11801180
SnippetOperand leftOperand(bytecode.m_operandTypes.first());
11811181
SnippetOperand rightOperand(bytecode.m_operandTypes.second());
@@ -1220,7 +1220,7 @@ void JIT::emit_op_div(const Instruction* currentInstruction)
12201220

12211221
void JIT::emit_op_mul(const Instruction* currentInstruction)
12221222
{
1223-
BinaryArithProfile* arithProfile = currentInstruction->as<OpMul>().metadata(m_profiledCodeBlock).m_arithProfile;
1223+
BinaryArithProfile* arithProfile = &m_unlinkedCodeBlock->binaryArithProfile(currentInstruction->as<OpMul>().m_profileIndex);
12241224
JITMulIC* mulIC = m_mathICs.addJITMulIC(arithProfile);
12251225
m_instructionToMathIC.add(currentInstruction, mulIC);
12261226
emitMathICFast<OpMul>(mulIC, currentInstruction, operationValueMulProfiled, operationValueMul);
@@ -1236,7 +1236,7 @@ void JIT::emitSlow_op_mul(const Instruction* currentInstruction, Vector<SlowCase
12361236

12371237
void JIT::emit_op_sub(const Instruction* currentInstruction)
12381238
{
1239-
BinaryArithProfile* arithProfile = currentInstruction->as<OpSub>().metadata(m_profiledCodeBlock).m_arithProfile;
1239+
BinaryArithProfile* arithProfile = &m_unlinkedCodeBlock->binaryArithProfile(currentInstruction->as<OpSub>().m_profileIndex);
12401240
JITSubIC* subIC = m_mathICs.addJITSubIC(arithProfile);
12411241
m_instructionToMathIC.add(currentInstruction, subIC);
12421242
emitMathICFast<OpSub>(subIC, currentInstruction, operationValueSubProfiled, operationValueSub);

0 commit comments

Comments
 (0)