forked from OSchip/llvm-project
[BOLT] Fix data race while running split functions pass
Summary: In BinaryContext::calculateEmittedSize(), after the temporary code emission, we have to perform a cleanup and mark all symbols used during the emission as undefined and unregistered (so that we can emit them again later). The cleanup is happening even for symbols that were referenced and not defined by emitted code. If all emitted symbols are local, there is no risk that one thread will define a symbol while some other thread will undefine it in its cleanup code. Such behavior is expected as local symbols can only be referenced within the containing function and each function is processed in one thread. However, secondary entry points have associated global symbols and if we emit them, then it is possible for a thread to undefine a symbol while the other thread had defined it and was in the process of emitting the fragment with it. In such case, a data race may happen and the thread that contains the definition of the symbol may define it twice causing a redefinition error. To avoid the data race, we skip the emission of secondary entry global symbols when emitting code used only for the size estimation. (cherry picked from FBD24986007)
This commit is contained in:
parent
1e9b733008
commit
7eaf63a118
|
@ -1948,10 +1948,11 @@ BinaryContext::calculateEmittedSize(BinaryFunction &BF, bool FixBranches) {
|
||||||
auto *Section = MCEInstance.LocalMOFI->getTextSection();
|
auto *Section = MCEInstance.LocalMOFI->getTextSection();
|
||||||
Section->setHasInstructions(true);
|
Section->setHasInstructions(true);
|
||||||
|
|
||||||
auto *StartLabel = LocalCtx->getOrCreateSymbol("__hstart");
|
// Create symbols in the LocalCtx so that they get destroyed with it.
|
||||||
auto *EndLabel = LocalCtx->getOrCreateSymbol("__hend");
|
MCSymbol *StartLabel = LocalCtx->createTempSymbol();
|
||||||
auto *ColdStartLabel = LocalCtx->getOrCreateSymbol("__cstart");
|
MCSymbol *EndLabel = LocalCtx->createTempSymbol();
|
||||||
auto *ColdEndLabel = LocalCtx->getOrCreateSymbol("__cend");
|
MCSymbol *ColdStartLabel = LocalCtx->createTempSymbol();
|
||||||
|
MCSymbol *ColdEndLabel = LocalCtx->createTempSymbol();
|
||||||
|
|
||||||
Streamer->SwitchSection(Section);
|
Streamer->SwitchSection(Section);
|
||||||
Streamer->EmitLabel(StartLabel);
|
Streamer->EmitLabel(StartLabel);
|
||||||
|
|
|
@ -1190,7 +1190,8 @@ public:
|
||||||
MCEInstance.LocalMOFI = llvm::make_unique<MCObjectFileInfo>();
|
MCEInstance.LocalMOFI = llvm::make_unique<MCObjectFileInfo>();
|
||||||
MCEInstance.LocalCtx = llvm::make_unique<MCContext>(
|
MCEInstance.LocalCtx = llvm::make_unique<MCContext>(
|
||||||
AsmInfo.get(), MRI.get(), MCEInstance.LocalMOFI.get());
|
AsmInfo.get(), MRI.get(), MCEInstance.LocalMOFI.get());
|
||||||
MCEInstance.LocalMOFI->InitMCObjectFileInfo(*TheTriple, /*PIC=*/false,
|
MCEInstance.LocalMOFI->InitMCObjectFileInfo(*TheTriple,
|
||||||
|
/*PIC=*/!HasFixedLoadAddress,
|
||||||
*MCEInstance.LocalCtx);
|
*MCEInstance.LocalCtx);
|
||||||
MCEInstance.MCE.reset(
|
MCEInstance.MCE.reset(
|
||||||
TheTarget->createMCCodeEmitter(*MII, *MRI, *MCEInstance.LocalCtx));
|
TheTarget->createMCCodeEmitter(*MII, *MRI, *MCEInstance.LocalCtx));
|
||||||
|
|
|
@ -398,9 +398,11 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, bool EmitColdPart,
|
||||||
BB->getAlignmentMaxBytes());
|
BB->getAlignmentMaxBytes());
|
||||||
}
|
}
|
||||||
Streamer.EmitLabel(BB->getLabel());
|
Streamer.EmitLabel(BB->getLabel());
|
||||||
|
if (!EmitCodeOnly) {
|
||||||
if (auto *EntrySymbol = BF.getSecondaryEntryPointSymbol(*BB)) {
|
if (auto *EntrySymbol = BF.getSecondaryEntryPointSymbol(*BB)) {
|
||||||
Streamer.EmitLabel(EntrySymbol);
|
Streamer.EmitLabel(EntrySymbol);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if special alignment for macro-fusion is needed.
|
// Check if special alignment for macro-fusion is needed.
|
||||||
bool MayNeedMacroFusionAlignment =
|
bool MayNeedMacroFusionAlignment =
|
||||||
|
|
Loading…
Reference in New Issue