Skip to content
Permalink
Browse files
[JSC] Use FixedVector in JumpReplacements and VariableEventStream
https://bugs.webkit.org/show_bug.cgi?id=239892

Reviewed by Mark Lam.

1. Introduce DFG::VariableEventStreamBuilder. And construct DFG::VariableEventStream from that
builder when finailizing code generation. We also make it FixedVector.
2. Use FixedVector for JumpReplacements.

* Source/JavaScriptCore/dfg/DFGCommonData.cpp:
(JSC::DFG::CommonData::shrinkToFit):
* Source/JavaScriptCore/dfg/DFGCommonData.h:
* Source/JavaScriptCore/dfg/DFGGenerationInfo.h:
(JSC::DFG::GenerationInfo::noticeOSRBirth):
(JSC::DFG::GenerationInfo::use):
(JSC::DFG::GenerationInfo::spill):
(JSC::DFG::GenerationInfo::setSpilled):
(JSC::DFG::GenerationInfo::fillGPR):
(JSC::DFG::GenerationInfo::fillJSValue):
(JSC::DFG::GenerationInfo::fillCell):
(JSC::DFG::GenerationInfo::fillInt32):
(JSC::DFG::GenerationInfo::fillInt52):
(JSC::DFG::GenerationInfo::fillStrictInt52):
(JSC::DFG::GenerationInfo::fillBoolean):
(JSC::DFG::GenerationInfo::fillDouble):
(JSC::DFG::GenerationInfo::fillStorage):
(JSC::DFG::GenerationInfo::appendBirth):
(JSC::DFG::GenerationInfo::appendFill):
(JSC::DFG::GenerationInfo::appendSpill):
* Source/JavaScriptCore/dfg/DFGJITCode.cpp:
(JSC::DFG::JITCode::shrinkToFit):
(JSC::DFG::JITCode::reconstruct):
* Source/JavaScriptCore/dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
(JSC::DFG::JITCompiler::exceptionCheck):
* Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h:
(JSC::DFG::SlowPathGenerator::SlowPathGenerator):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::speculationCheck):
(JSC::DFG::SpeculativeJIT::emitInvalidationPoint):
(JSC::DFG::SpeculativeJIT::addSlowPathGeneratorLambda):
(JSC::DFG::SpeculativeJIT::fillStorage):
(JSC::DFG::SpeculativeJIT::compileDeleteById):
(JSC::DFG::SpeculativeJIT::compileDeleteByVal):
(JSC::DFG::SpeculativeJIT::compileInById):
(JSC::DFG::SpeculativeJIT::compileInByVal):
(JSC::DFG::SpeculativeJIT::compileHasPrivate):
(JSC::DFG::SpeculativeJIT::noticeOSRBirth):
(JSC::DFG::SpeculativeJIT::compileMovHint):
(JSC::DFG::SpeculativeJIT::compileCurrentBlock):
(JSC::DFG::SpeculativeJIT::compilePutByVal):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::finalizeEventStream):
(JSC::DFG::SpeculativeJIT::use):
(JSC::DFG::SpeculativeJIT::spill):
(JSC::DFG::SpeculativeJIT::recordSetLocal):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::cachedGetById):
(JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis):
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileGetByVal):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::cachedGetById):
(JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis):
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::fillSpeculateBigInt32):
(JSC::DFG::SpeculativeJIT::compileGetByVal):
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp:
(JSC::DFG::VariableEventStreamBuilder::logEvent):
(JSC::DFG::VariableEventStream::reconstruct const):
(JSC::DFG::VariableEventStream::logEvent): Deleted.
* Source/JavaScriptCore/dfg/DFGVariableEventStream.h:
(JSC::DFG::VariableEventStream::VariableEventStream):
(JSC::DFG::VariableEventStreamBuilder::appendAndLog):
(JSC::DFG::VariableEventStreamBuilder::size const):
(JSC::DFG::VariableEventStreamBuilder::finalize):
(JSC::DFG::VariableEventStream::appendAndLog): Deleted.
* Source/JavaScriptCore/ftl/FTLLink.cpp:
(JSC::FTL::link):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/ftl/FTLState.h:

Canonical link: https://commits.webkit.org/250135@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@293629 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Constellation committed Apr 29, 2022
1 parent 77ba4e7 commit f6b5f60d1eadfe479e6c7ffe13b69e61597b39d8
Show file tree
Hide file tree
Showing 16 changed files with 251 additions and 125 deletions.
@@ -1,3 +1,103 @@
2022-04-29 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] Use FixedVector in JumpReplacements and VariableEventStream
https://bugs.webkit.org/show_bug.cgi?id=239892

Reviewed by Mark Lam.

1. Introduce DFG::VariableEventStreamBuilder. And construct DFG::VariableEventStream from that
builder when finailizing code generation. We also make it FixedVector.
2. Use FixedVector for JumpReplacements.

* dfg/DFGCommonData.cpp:
(JSC::DFG::CommonData::shrinkToFit):
* dfg/DFGCommonData.h:
* dfg/DFGGenerationInfo.h:
(JSC::DFG::GenerationInfo::noticeOSRBirth):
(JSC::DFG::GenerationInfo::use):
(JSC::DFG::GenerationInfo::spill):
(JSC::DFG::GenerationInfo::setSpilled):
(JSC::DFG::GenerationInfo::fillGPR):
(JSC::DFG::GenerationInfo::fillJSValue):
(JSC::DFG::GenerationInfo::fillCell):
(JSC::DFG::GenerationInfo::fillInt32):
(JSC::DFG::GenerationInfo::fillInt52):
(JSC::DFG::GenerationInfo::fillStrictInt52):
(JSC::DFG::GenerationInfo::fillBoolean):
(JSC::DFG::GenerationInfo::fillDouble):
(JSC::DFG::GenerationInfo::fillStorage):
(JSC::DFG::GenerationInfo::appendBirth):
(JSC::DFG::GenerationInfo::appendFill):
(JSC::DFG::GenerationInfo::appendSpill):
* dfg/DFGJITCode.cpp:
(JSC::DFG::JITCode::shrinkToFit):
(JSC::DFG::JITCode::reconstruct):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
(JSC::DFG::JITCompiler::exceptionCheck):
* dfg/DFGSlowPathGenerator.h:
(JSC::DFG::SlowPathGenerator::SlowPathGenerator):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::speculationCheck):
(JSC::DFG::SpeculativeJIT::emitInvalidationPoint):
(JSC::DFG::SpeculativeJIT::addSlowPathGeneratorLambda):
(JSC::DFG::SpeculativeJIT::fillStorage):
(JSC::DFG::SpeculativeJIT::compileDeleteById):
(JSC::DFG::SpeculativeJIT::compileDeleteByVal):
(JSC::DFG::SpeculativeJIT::compileInById):
(JSC::DFG::SpeculativeJIT::compileInByVal):
(JSC::DFG::SpeculativeJIT::compileHasPrivate):
(JSC::DFG::SpeculativeJIT::noticeOSRBirth):
(JSC::DFG::SpeculativeJIT::compileMovHint):
(JSC::DFG::SpeculativeJIT::compileCurrentBlock):
(JSC::DFG::SpeculativeJIT::compilePutByVal):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::finalizeEventStream):
(JSC::DFG::SpeculativeJIT::use):
(JSC::DFG::SpeculativeJIT::spill):
(JSC::DFG::SpeculativeJIT::recordSetLocal):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::cachedGetById):
(JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis):
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileGetByVal):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::cachedGetById):
(JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis):
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::fillSpeculateBigInt32):
(JSC::DFG::SpeculativeJIT::compileGetByVal):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGVariableEventStream.cpp:
(JSC::DFG::VariableEventStreamBuilder::logEvent):
(JSC::DFG::VariableEventStream::reconstruct const):
(JSC::DFG::VariableEventStream::logEvent): Deleted.
* dfg/DFGVariableEventStream.h:
(JSC::DFG::VariableEventStream::VariableEventStream):
(JSC::DFG::VariableEventStreamBuilder::appendAndLog):
(JSC::DFG::VariableEventStreamBuilder::size const):
(JSC::DFG::VariableEventStreamBuilder::finalize):
(JSC::DFG::VariableEventStream::appendAndLog): Deleted.
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* ftl/FTLState.h:

2022-04-29 Yury Semikhatsky <yurys@chromium.org>

Format time zone name using ICU instead of platform calls
@@ -42,7 +42,6 @@ namespace JSC { namespace DFG {
void CommonData::shrinkToFit()
{
codeOrigins->shrinkToFit();
m_jumpReplacements.shrinkToFit();
}

static Lock pcCodeBlockMapLock;
@@ -129,7 +129,7 @@ class CommonData : public MathICHolder {
FixedVector<AdaptiveInferredPropertyValueWatchpoint> m_adaptiveInferredPropertyValueWatchpoints;
std::unique_ptr<PCToCodeOriginMap> m_pcToCodeOriginMap;
RecordedStatuses recordedStatuses;
Vector<JumpReplacement> m_jumpReplacements;
FixedVector<JumpReplacement> m_jumpReplacements;
Bag<StructureStubInfo> m_stubInfos;
Bag<OptimizingCallLinkInfo> m_callLinkInfos;
Yarr::YarrBoyerMoyerData m_boyerMooreData;
@@ -148,7 +148,7 @@ class GenerationInfo {
// Get the node that produced this value.
Node* node() { return m_node; }

void noticeOSRBirth(VariableEventStream& stream, Node* node, VirtualRegister virtualRegister)
void noticeOSRBirth(VariableEventStreamBuilder& stream, Node* node, VirtualRegister virtualRegister)
{
if (m_node != node)
return;
@@ -170,7 +170,7 @@ class GenerationInfo {
// Mark the value as having been used (decrement the useCount).
// Returns true if this was the last use of the value, and any
// associated machine registers may be freed.
bool use(VariableEventStream& stream)
bool use(VariableEventStreamBuilder& stream)
{
ASSERT(m_useCount);
bool result = !--m_useCount;
@@ -268,7 +268,7 @@ class GenerationInfo {
}

// Called when a VirtualRegister is being spilled to the JSStack for the first time.
void spill(VariableEventStream& stream, VirtualRegister virtualRegister, DataFormat spillFormat)
void spill(VariableEventStreamBuilder& stream, VirtualRegister virtualRegister, DataFormat spillFormat)
{
// We shouldn't be spill values that don't need spilling.
ASSERT(!m_canFill);
@@ -286,7 +286,7 @@ class GenerationInfo {

// Called on values that don't need spilling (constants and values that have
// already been spilled), to mark them as no longer being in machine registers.
void setSpilled(VariableEventStream& stream, VirtualRegister virtualRegister)
void setSpilled(VariableEventStreamBuilder& stream, VirtualRegister virtualRegister)
{
// Should only be called on values that don't need spilling, and are currently in registers.
ASSERT(m_canFill && m_registerFormat != DataFormatNone);
@@ -302,7 +302,7 @@ class GenerationInfo {
m_canFill = false;
}

void fillGPR(VariableEventStream& stream, GPRReg gpr, DataFormat format)
void fillGPR(VariableEventStreamBuilder& stream, GPRReg gpr, DataFormat format)
{
ASSERT(gpr != InvalidGPRReg);
m_registerFormat = format;
@@ -314,13 +314,13 @@ class GenerationInfo {
// Record that this value is filled into machine registers,
// tracking which registers, and what format the value has.
#if USE(JSVALUE64)
void fillJSValue(VariableEventStream& stream, GPRReg gpr, DataFormat format = DataFormatJS)
void fillJSValue(VariableEventStreamBuilder& stream, GPRReg gpr, DataFormat format = DataFormatJS)
{
ASSERT(format & DataFormatJS);
fillGPR(stream, gpr, format);
}
#elif USE(JSVALUE32_64)
void fillJSValue(VariableEventStream& stream, GPRReg tagGPR, GPRReg payloadGPR, DataFormat format = DataFormatJS)
void fillJSValue(VariableEventStreamBuilder& stream, GPRReg tagGPR, GPRReg payloadGPR, DataFormat format = DataFormatJS)
{
ASSERT(format & DataFormatJS);
m_registerFormat = format;
@@ -330,33 +330,33 @@ class GenerationInfo {
if (m_bornForOSR)
appendFill(Fill, stream);
}
void fillCell(VariableEventStream& stream, GPRReg gpr)
void fillCell(VariableEventStreamBuilder& stream, GPRReg gpr)
{
fillGPR(stream, gpr, DataFormatCell);
}
#endif
void fillInt32(VariableEventStream& stream, GPRReg gpr)
void fillInt32(VariableEventStreamBuilder& stream, GPRReg gpr)
{
fillGPR(stream, gpr, DataFormatInt32);
}
void fillInt52(VariableEventStream& stream, GPRReg gpr, DataFormat format)
void fillInt52(VariableEventStreamBuilder& stream, GPRReg gpr, DataFormat format)
{
ASSERT(format == DataFormatInt52 || format == DataFormatStrictInt52);
fillGPR(stream, gpr, format);
}
void fillInt52(VariableEventStream& stream, GPRReg gpr)
void fillInt52(VariableEventStreamBuilder& stream, GPRReg gpr)
{
fillGPR(stream, gpr, DataFormatInt52);
}
void fillStrictInt52(VariableEventStream& stream, GPRReg gpr)
void fillStrictInt52(VariableEventStreamBuilder& stream, GPRReg gpr)
{
fillGPR(stream, gpr, DataFormatStrictInt52);
}
void fillBoolean(VariableEventStream& stream, GPRReg gpr)
void fillBoolean(VariableEventStreamBuilder& stream, GPRReg gpr)
{
fillGPR(stream, gpr, DataFormatBoolean);
}
void fillDouble(VariableEventStream& stream, FPRReg fpr)
void fillDouble(VariableEventStreamBuilder& stream, FPRReg fpr)
{
ASSERT(fpr != InvalidFPRReg);
m_registerFormat = DataFormatDouble;
@@ -365,7 +365,7 @@ class GenerationInfo {
if (m_bornForOSR)
appendFill(Fill, stream);
}
void fillStorage(VariableEventStream& stream, GPRReg gpr)
void fillStorage(VariableEventStreamBuilder& stream, GPRReg gpr)
{
fillGPR(stream, gpr, DataFormatStorage);
}
@@ -399,12 +399,12 @@ class GenerationInfo {
}

private:
void appendBirth(VariableEventStream& stream)
void appendBirth(VariableEventStreamBuilder& stream)
{
stream.appendAndLog(VariableEvent::birth(MinifiedID(m_node)));
}

void appendFill(VariableEventKind kind, VariableEventStream& stream)
void appendFill(VariableEventKind kind, VariableEventStreamBuilder& stream)
{
ASSERT(m_bornForOSR);

@@ -421,7 +421,7 @@ class GenerationInfo {
stream.appendAndLog(VariableEvent::fillGPR(kind, MinifiedID(m_node), u.gpr, m_registerFormat));
}

void appendSpill(VariableEventKind kind, VariableEventStream& stream, VirtualRegister virtualRegister)
void appendSpill(VariableEventKind kind, VariableEventStreamBuilder& stream, VirtualRegister virtualRegister)
{
stream.appendAndLog(VariableEvent::spill(kind, MinifiedID(m_node), virtualRegister, m_spillFormat));
}
@@ -59,15 +59,13 @@ void JITCode::shrinkToFit(const ConcurrentJSLocker&)
{
common.shrinkToFit();
minifiedDFG.prepareAndShrink();
variableEventStream.shrinkToFit();
}

void JITCode::reconstruct(
CodeBlock* codeBlock, CodeOrigin codeOrigin, unsigned streamIndex,
Operands<ValueRecovery>& result)
{
variableEventStream.reconstruct(
codeBlock, codeOrigin, minifiedDFG, streamIndex, result);
variableEventStream.reconstruct(codeBlock, codeOrigin, minifiedDFG, streamIndex, result);
}

void JITCode::reconstruct(CallFrame* callFrame, CodeBlock* codeBlock, CodeOrigin codeOrigin, unsigned streamIndex, Operands<std::optional<JSValue>>& result)
@@ -291,6 +291,7 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
if (!m_exceptionChecksWithCallFrameRollback.empty())
linkBuffer.link(m_exceptionChecksWithCallFrameRollback, CodeLocationLabel(vm().getCTIStub(handleExceptionWithCallFrameRollbackGenerator).retaggedCode<NoPtrTag>()));

Vector<JumpReplacement> jumpReplacements;
MacroAssemblerCodeRef<JITThunkPtrTag> osrExitThunk = vm().getCTIStub(osrExitGenerationThunkGenerator);
auto target = CodeLocationLabel<JITThunkPtrTag>(osrExitThunk.code());
for (unsigned i = 0; i < m_osrExit.size(); ++i) {
@@ -303,11 +304,12 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
}

if (info.m_replacementSource.isSet()) {
m_jitCode->common.m_jumpReplacements.append(JumpReplacement(
jumpReplacements.append(JumpReplacement(
linkBuffer.locationOf<JSInternalPtrTag>(info.m_replacementSource),
linkBuffer.locationOf<OSRExitPtrTag>(info.m_replacementDestination)));
}
}
m_jitCode->common.m_jumpReplacements = WTFMove(jumpReplacements);

if (UNLIKELY(m_graph.compilation())) {
ASSERT(m_exitSiteLabels.size() == m_osrExit.size());
@@ -415,6 +417,7 @@ void JITCompiler::compile()

auto codeRef = FINALIZE_DFG_CODE(*linkBuffer, JSEntryPtrTag, "DFG JIT code for %s", toCString(CodeBlockWithJITType(m_codeBlock, JITType::DFGJIT)).data());
m_jitCode->initializeCodeRefForDFG(codeRef, codeRef.code());
m_jitCode->variableEventStream = m_speculative->finalizeEventStream();

auto finalizer = makeUnique<JITFinalizer>(m_graph.m_plan, m_jitCode.releaseNonNull(), WTFMove(linkBuffer));
m_graph.m_plan.setFinalizer(WTFMove(finalizer));
@@ -525,6 +528,7 @@ void JITCompiler::compileFunction()
m_jitCode->initializeCodeRefForDFG(
FINALIZE_DFG_CODE(*linkBuffer, JSEntryPtrTag, "DFG JIT code for %s", toCString(CodeBlockWithJITType(m_codeBlock, JITType::DFGJIT)).data()),
withArityCheck);
m_jitCode->variableEventStream = m_speculative->finalizeEventStream();

auto finalizer = makeUnique<JITFinalizer>(m_graph.m_plan, m_jitCode.releaseNonNull(), WTFMove(linkBuffer), withArityCheck);
m_graph.m_plan.setFinalizer(WTFMove(finalizer));
@@ -653,7 +657,7 @@ void JITCompiler::exceptionCheck()
HandlerInfo* exceptionHandler;
bool willCatchException = m_graph.willCatchExceptionInMachineFrame(m_speculative->m_currentNode->origin.forExit, opCatchOrigin, exceptionHandler);
if (willCatchException) {
unsigned streamIndex = m_speculative->m_outOfLineStreamIndex ? *m_speculative->m_outOfLineStreamIndex : m_speculative->m_stream->size();
unsigned streamIndex = m_speculative->m_outOfLineStreamIndex ? *m_speculative->m_outOfLineStreamIndex : m_speculative->m_stream.size();
MacroAssembler::Jump hadException = emitNonPatchableExceptionCheck(vm());
// We assume here that this is called after callOpeartion()/appendCall() is called.
appendExceptionHandlingOSRExit(ExceptionCheck, streamIndex, opCatchOrigin, exceptionHandler, m_jitCode->common.codeOrigins->lastCallSite(), hadException);
@@ -39,7 +39,7 @@ class SlowPathGenerator {
public:
SlowPathGenerator(SpeculativeJIT* jit)
: m_currentNode(jit->m_currentNode)
, m_streamIndex(jit->m_stream->size())
, m_streamIndex(jit->m_stream.size())
, m_origin(jit->m_origin)
{
}

0 comments on commit f6b5f60

Please sign in to comment.