Skip to content

Commit 5f15479

Browse files
committed
[JITLink] Add convenience methods for creating block readers / writers.
This saves clients some boilerplate compared to setting up the readers and writers manually. To obtain a BinaryStreamWriter / BinaryStreamReader for a given block, B, clients can now write: auto Reader = G.getBlockContentReader(B); and auto Writer = G.getBlockContentWriter(B); The latter will trigger a copy to mutable memory allocated on the graph's allocator if the block is currently marked as backed by read-only memory. This commit also introduces a new createMutableContentBlock overload that creates a block with a given size and zero-filled content (by default -- passing false for the ZeroInitialize bypasses initialization entirely). This overload is intended to be used with getBlockContentWriter above when creating new content for the graph.
1 parent b96cbbd commit 5f15479

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "llvm/ExecutionEngine/JITSymbol.h"
2323
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
2424
#include "llvm/Support/Allocator.h"
25+
#include "llvm/Support/BinaryStreamReader.h"
26+
#include "llvm/Support/BinaryStreamWriter.h"
2527
#include "llvm/Support/Endian.h"
2628
#include "llvm/Support/Error.h"
2729
#include "llvm/Support/FormatVariadic.h"
@@ -1031,13 +1033,43 @@ class LinkGraph {
10311033
AlignmentOffset);
10321034
}
10331035

1036+
/// Create a content block with initially mutable data of the given size.
1037+
/// Content will be allocated via the LinkGraph's allocateBuffer method.
1038+
/// By default the memory will be zero-initialized. Passing false for
1039+
/// ZeroInitialize will prevent this.
1040+
Block &createMutableContentBlock(Section &Parent, size_t ContentSize,
1041+
orc::ExecutorAddr Address,
1042+
uint64_t Alignment, uint64_t AlignmentOffset,
1043+
bool ZeroInitialize = true) {
1044+
auto Content = allocateContent(ContentSize);
1045+
if (ZeroInitialize)
1046+
memset(Content.data(), 0, Content.size());
1047+
return createBlock(Parent, Content, Address, Alignment, AlignmentOffset);
1048+
}
1049+
10341050
/// Create a zero-fill block.
10351051
Block &createZeroFillBlock(Section &Parent, orc::ExecutorAddrDiff Size,
10361052
orc::ExecutorAddr Address, uint64_t Alignment,
10371053
uint64_t AlignmentOffset) {
10381054
return createBlock(Parent, Size, Address, Alignment, AlignmentOffset);
10391055
}
10401056

1057+
/// Returns a BinaryStreamReader for the given block.
1058+
BinaryStreamReader getBlockContentReader(Block &B) {
1059+
ArrayRef<uint8_t> C(
1060+
reinterpret_cast<const uint8_t *>(B.getContent().data()), B.getSize());
1061+
return BinaryStreamReader(C, getEndianness());
1062+
}
1063+
1064+
/// Returns a BinaryStreamWriter for the given block.
1065+
/// This will call getMutableContent to obtain mutable content for the block.
1066+
BinaryStreamWriter getBlockContentWriter(Block &B) {
1067+
MutableArrayRef<uint8_t> C(
1068+
reinterpret_cast<uint8_t *>(B.getMutableContent(*this).data()),
1069+
B.getSize());
1070+
return BinaryStreamWriter(C, getEndianness());
1071+
}
1072+
10411073
/// Cache type for the splitBlock function.
10421074
using SplitBlockCache = Optional<SmallVector<Symbol *, 8>>;
10431075

llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
1111
#include "llvm/Support/Endian.h"
1212
#include "llvm/Support/Memory.h"
13+
14+
#include "llvm/Testing/Support/Error.h"
1315
#include "gtest/gtest.h"
1416

1517
using namespace llvm;
@@ -196,6 +198,16 @@ TEST(LinkGraphTest, ContentAccessAndUpdate) {
196198
EXPECT_EQ(MutableContent3.size(), MutableContent.size())
197199
<< "Unexpected mutable content 2 size";
198200

201+
// Check that we can obtain a writer and reader over the content.
202+
// Check that we can get a BinaryStreamReader for B.
203+
auto Writer = G.getBlockContentWriter(B);
204+
EXPECT_THAT_ERROR(Writer.writeInteger((uint32_t)0xcafef00d), Succeeded());
205+
206+
auto Reader = G.getBlockContentReader(B);
207+
uint32_t Initial32Bits = 0;
208+
EXPECT_THAT_ERROR(Reader.readInteger(Initial32Bits), Succeeded());
209+
EXPECT_EQ(Initial32Bits, (uint32_t)0xcafef00d);
210+
199211
// Set content back to immutable and check that everything behaves as
200212
// expected again.
201213
B.setContent(BlockContent);

0 commit comments

Comments
 (0)