mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-04 02:18:46 +00:00
[ORC] Strip weak flags from a symbol once it is selected for materialization.
Once a symbol has been selected for materialization it can no longer be overridden. Stripping the weak flag guarantees this (override attempts will then be treated as duplicate definitions and result in a DuplicateDefinition error). llvm-svn: 334771
This commit is contained in:
parent
e567892d10
commit
a86b02ba7f
@ -468,6 +468,8 @@ void VSO::resolve(const SymbolMap &Resolved) {
|
|||||||
for (const auto &KV : Resolved) {
|
for (const auto &KV : Resolved) {
|
||||||
auto &Name = KV.first;
|
auto &Name = KV.first;
|
||||||
auto Sym = KV.second;
|
auto Sym = KV.second;
|
||||||
|
JITSymbolFlags ResolvedFlags = Sym.getFlags();
|
||||||
|
ResolvedFlags &= ~JITSymbolFlags::Weak;
|
||||||
|
|
||||||
assert(!Sym.getFlags().isLazy() && !Sym.getFlags().isMaterializing() &&
|
assert(!Sym.getFlags().isLazy() && !Sym.getFlags().isMaterializing() &&
|
||||||
"Materializing flags should be managed internally");
|
"Materializing flags should be managed internally");
|
||||||
@ -480,13 +482,11 @@ void VSO::resolve(const SymbolMap &Resolved) {
|
|||||||
"Symbol should be materializing");
|
"Symbol should be materializing");
|
||||||
assert(I->second.getAddress() == 0 && "Symbol has already been resolved");
|
assert(I->second.getAddress() == 0 && "Symbol has already been resolved");
|
||||||
|
|
||||||
assert(Sym.getFlags() ==
|
assert(ResolvedFlags ==
|
||||||
JITSymbolFlags::stripTransientFlags(I->second.getFlags()) &&
|
JITSymbolFlags::stripTransientFlags(I->second.getFlags()) &&
|
||||||
"Resolved flags should match the declared flags");
|
"Resolved flags should match the declared flags");
|
||||||
|
|
||||||
// Once resolved, symbols can never be weak.
|
// Once resolved, symbols can never be weak.
|
||||||
JITSymbolFlags ResolvedFlags = Sym.getFlags();
|
|
||||||
ResolvedFlags &= ~JITSymbolFlags::Weak;
|
|
||||||
ResolvedFlags |= JITSymbolFlags::Materializing;
|
ResolvedFlags |= JITSymbolFlags::Materializing;
|
||||||
I->second = JITEvaluatedSymbol(Sym.getAddress(), ResolvedFlags);
|
I->second = JITEvaluatedSymbol(Sym.getAddress(), ResolvedFlags);
|
||||||
|
|
||||||
@ -748,6 +748,7 @@ void VSO::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
|
|||||||
for (auto &KV : MU->getSymbols()) {
|
for (auto &KV : MU->getSymbols()) {
|
||||||
auto SymK = Symbols.find(KV.first);
|
auto SymK = Symbols.find(KV.first);
|
||||||
auto Flags = SymK->second.getFlags();
|
auto Flags = SymK->second.getFlags();
|
||||||
|
Flags &= ~JITSymbolFlags::Weak;
|
||||||
Flags &= ~JITSymbolFlags::Lazy;
|
Flags &= ~JITSymbolFlags::Lazy;
|
||||||
Flags |= JITSymbolFlags::Materializing;
|
Flags |= JITSymbolFlags::Materializing;
|
||||||
SymK->second.setFlags(Flags);
|
SymK->second.setFlags(Flags);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "OrcTestCommon.h"
|
#include "OrcTestCommon.h"
|
||||||
#include "llvm/Config/llvm-config.h"
|
#include "llvm/Config/llvm-config.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||||
|
#include "llvm/ExecutionEngine/Orc/OrcError.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -768,4 +769,50 @@ TEST(CoreAPIsTest, TestGetRequestedSymbolsAndDelegate) {
|
|||||||
EXPECT_TRUE(BarMaterialized) << "Bar should be materialized now";
|
EXPECT_TRUE(BarMaterialized) << "Bar should be materialized now";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CoreAPIsTest, TestMaterializeWeakSymbol) {
|
||||||
|
// Confirm that once a weak definition is selected for materialization it is
|
||||||
|
// treated as strong.
|
||||||
|
|
||||||
|
constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef;
|
||||||
|
JITSymbolFlags FooFlags = JITSymbolFlags::Exported;
|
||||||
|
FooFlags &= JITSymbolFlags::Weak;
|
||||||
|
auto FooSym = JITEvaluatedSymbol(FakeFooAddr, FooFlags);
|
||||||
|
|
||||||
|
ExecutionSession ES;
|
||||||
|
auto Foo = ES.getSymbolStringPool().intern("foo");
|
||||||
|
|
||||||
|
auto &V = ES.createVSO("V");
|
||||||
|
|
||||||
|
std::unique_ptr<MaterializationResponsibility> FooResponsibility;
|
||||||
|
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
|
||||||
|
SymbolFlagsMap({{Foo, FooFlags}}), [&](MaterializationResponsibility R) {
|
||||||
|
FooResponsibility =
|
||||||
|
llvm::make_unique<MaterializationResponsibility>(std::move(R));
|
||||||
|
});
|
||||||
|
|
||||||
|
cantFail(V.define(MU));
|
||||||
|
auto Q = std::make_shared<AsynchronousSymbolQuery>(
|
||||||
|
SymbolNameSet({Foo}),
|
||||||
|
[](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
|
||||||
|
cantFail(std::move(R));
|
||||||
|
},
|
||||||
|
[](Error Err) { cantFail(std::move(Err)); });
|
||||||
|
V.lookup(std::move(Q), SymbolNameSet({Foo}));
|
||||||
|
|
||||||
|
auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
|
||||||
|
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
|
||||||
|
[](MaterializationResponsibility R) {
|
||||||
|
llvm_unreachable("This unit should never be materialized");
|
||||||
|
});
|
||||||
|
|
||||||
|
auto Err = V.define(MU2);
|
||||||
|
EXPECT_TRUE(!!Err) << "Expected failure value";
|
||||||
|
EXPECT_TRUE(Err.isA<DuplicateDefinition>())
|
||||||
|
<< "Expected a duplicate definition error";
|
||||||
|
consumeError(std::move(Err));
|
||||||
|
|
||||||
|
FooResponsibility->resolve(SymbolMap({{Foo, FooSym}}));
|
||||||
|
FooResponsibility->finalize();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user