Commit 1eda90a1 by Andrew Scull

Order jump tables for deterministic or randomized emission.

BUG= R=stichnot@chromium.org, jvoung, stichnot Review URL: https://codereview.chromium.org/1260183008.
parent c5c8957b
...@@ -878,11 +878,32 @@ ConstantList GlobalContext::getConstantExternSyms() { ...@@ -878,11 +878,32 @@ ConstantList GlobalContext::getConstantExternSyms() {
return getConstPool()->ExternRelocatables.getConstantPool(); return getConstPool()->ExternRelocatables.getConstantPool();
} }
JumpTableDataList GlobalContext::getJumpTables() {
JumpTableDataList JumpTables(*getJumpTableList());
if (getFlags().shouldReorderPooledConstants()) {
// If reorder-pooled-constants option is set to true, we need to shuffle the
// constant pool before emitting it.
RandomShuffle(JumpTables.begin(), JumpTables.end(), [this](uint64_t N) {
return (uint32_t)getRNG().next(N);
});
} else {
// Make order deterministic by sorting into functions and then ID of the
// jump table within that function.
std::sort(JumpTables.begin(), JumpTables.end(), [](const JumpTableData &A,
const JumpTableData &B) {
if (A.getFunctionName() != B.getFunctionName())
return A.getFunctionName() < B.getFunctionName();
return A.getId() < B.getId();
});
}
return JumpTables;
}
JumpTableData &GlobalContext::addJumpTable(IceString FuncName, SizeT Id, JumpTableData &GlobalContext::addJumpTable(IceString FuncName, SizeT Id,
SizeT NumTargets) { SizeT NumTargets) {
auto JumpTables = getJumpTables(); auto JumpTableList = getJumpTableList();
JumpTables->emplace_back(FuncName, Id, NumTargets); JumpTableList->emplace_back(FuncName, Id, NumTargets);
return JumpTables->back(); return JumpTableList->back();
} }
TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) { TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) {
......
...@@ -212,9 +212,7 @@ public: ...@@ -212,9 +212,7 @@ public:
ConstantList getConstantExternSyms(); ConstantList getConstantExternSyms();
/// Return a locked pointer to the registered jump tables. /// Return a locked pointer to the registered jump tables.
LockedPtr<JumpTableDataList> getJumpTables() { JumpTableDataList getJumpTables();
return LockedPtr<JumpTableDataList>(&JumpTables, &JumpTablesLock);
}
/// Create a new jump table entry and return a reference to it. /// Create a new jump table entry and return a reference to it.
JumpTableData &addJumpTable(IceString FuncName, SizeT Id, SizeT NumTargets); JumpTableData &addJumpTable(IceString FuncName, SizeT Id, SizeT NumTargets);
...@@ -467,9 +465,9 @@ private: ...@@ -467,9 +465,9 @@ private:
std::unique_ptr<ConstantPool> ConstPool; std::unique_ptr<ConstantPool> ConstPool;
ICE_CACHELINE_BOUNDARY; ICE_CACHELINE_BOUNDARY;
// Managed by getJumpTables() // Managed by getJumpTableList()
GlobalLockType JumpTablesLock; GlobalLockType JumpTablesLock;
JumpTableDataList JumpTables; JumpTableDataList JumpTableList;
ICE_CACHELINE_BOUNDARY; ICE_CACHELINE_BOUNDARY;
// Managed by getErrorStatus() // Managed by getErrorStatus()
...@@ -522,6 +520,9 @@ private: ...@@ -522,6 +520,9 @@ private:
LockedPtr<ConstantPool> getConstPool() { LockedPtr<ConstantPool> getConstPool() {
return LockedPtr<ConstantPool>(ConstPool.get(), &ConstPoolLock); return LockedPtr<ConstantPool>(ConstPool.get(), &ConstPoolLock);
} }
LockedPtr<JumpTableDataList> getJumpTableList() {
return LockedPtr<JumpTableDataList>(&JumpTableList, &JumpTablesLock);
}
LockedPtr<CodeStats> getStatsCumulative() { LockedPtr<CodeStats> getStatsCumulative() {
return LockedPtr<CodeStats>(&StatsCumulative, &StatsLock); return LockedPtr<CodeStats>(&StatsCumulative, &StatsLock);
} }
......
...@@ -79,7 +79,6 @@ private: ...@@ -79,7 +79,6 @@ private:
/// ELF section once the offsets from the start of the function are known. /// ELF section once the offsets from the start of the function are known.
class JumpTableData { class JumpTableData {
JumpTableData() = delete; JumpTableData() = delete;
JumpTableData(const JumpTableData &) = delete;
JumpTableData &operator=(const JumpTableData &) = delete; JumpTableData &operator=(const JumpTableData &) = delete;
public: public:
...@@ -87,7 +86,9 @@ public: ...@@ -87,7 +86,9 @@ public:
: FuncName(FuncName), Id(Id) { : FuncName(FuncName), Id(Id) {
TargetOffsets.reserve(NumTargets); TargetOffsets.reserve(NumTargets);
} }
JumpTableData(const JumpTableData &) = default;
JumpTableData(JumpTableData &&) = default; JumpTableData(JumpTableData &&) = default;
JumpTableData &operator=(JumpTableData &&) = default;
void pushTarget(intptr_t Offset) { TargetOffsets.emplace_back(Offset); } void pushTarget(intptr_t Offset) { TargetOffsets.emplace_back(Offset); }
...@@ -98,8 +99,8 @@ public: ...@@ -98,8 +99,8 @@ public:
} }
private: private:
const IceString FuncName; IceString FuncName;
const SizeT Id; SizeT Id;
std::vector<intptr_t> TargetOffsets; std::vector<intptr_t> TargetOffsets;
}; };
......
...@@ -243,8 +243,8 @@ void TargetDataX8632::lowerJumpTables() { ...@@ -243,8 +243,8 @@ void TargetDataX8632::lowerJumpTables() {
switch (Ctx->getFlags().getOutFileType()) { switch (Ctx->getFlags().getOutFileType()) {
case FT_Elf: { case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter(); ELFObjectWriter *Writer = Ctx->getObjectWriter();
for (const JumpTableData &JumpTable : *Ctx->getJumpTables()) for (const JumpTableData &JT : Ctx->getJumpTables())
Writer->writeJumpTable(JumpTable, llvm::ELF::R_386_32); Writer->writeJumpTable(JT, llvm::ELF::R_386_32);
} break; } break;
case FT_Asm: case FT_Asm:
// Already emitted from Cfg // Already emitted from Cfg
...@@ -253,7 +253,7 @@ void TargetDataX8632::lowerJumpTables() { ...@@ -253,7 +253,7 @@ void TargetDataX8632::lowerJumpTables() {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
for (const JumpTableData &JT : *Ctx->getJumpTables()) { for (const JumpTableData &JT : Ctx->getJumpTables()) {
Str << "\t.section\t.rodata." << JT.getFunctionName() Str << "\t.section\t.rodata." << JT.getFunctionName()
<< "$jumptable,\"a\",@progbits\n"; << "$jumptable,\"a\",@progbits\n";
Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
......
...@@ -240,9 +240,9 @@ void TargetDataX8664::lowerJumpTables() { ...@@ -240,9 +240,9 @@ void TargetDataX8664::lowerJumpTables() {
switch (Ctx->getFlags().getOutFileType()) { switch (Ctx->getFlags().getOutFileType()) {
case FT_Elf: { case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter(); ELFObjectWriter *Writer = Ctx->getObjectWriter();
for (const JumpTableData &JumpTable : *Ctx->getJumpTables()) for (const JumpTableData &JT : Ctx->getJumpTables())
// TODO(jpp): not 386. // TODO(jpp): not 386.
Writer->writeJumpTable(JumpTable, llvm::ELF::R_386_32); Writer->writeJumpTable(JT, llvm::ELF::R_386_32);
} break; } break;
case FT_Asm: case FT_Asm:
// Already emitted from Cfg // Already emitted from Cfg
...@@ -251,7 +251,7 @@ void TargetDataX8664::lowerJumpTables() { ...@@ -251,7 +251,7 @@ void TargetDataX8664::lowerJumpTables() {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
for (const JumpTableData &JT : *Ctx->getJumpTables()) { for (const JumpTableData &JT : Ctx->getJumpTables()) {
Str << "\t.section\t.rodata." << JT.getFunctionName() Str << "\t.section\t.rodata." << JT.getFunctionName()
<< "$jumptable,\"a\",@progbits\n"; << "$jumptable,\"a\",@progbits\n";
Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment