Skip to content

Commit 4201149

Browse files
authored
[NFC] Refactor a generic function for binary writing of a code annotations section (#7592)
This will allow 95% of the code to be shared for binary writing, between branch hints and inline hints for example. They have almost identical formats in structure, differing only in the hint itself and section name. Also prepare for multiple code annotations sections.
1 parent fe6f97b commit 4201149

File tree

2 files changed

+56
-14
lines changed

2 files changed

+56
-14
lines changed

src/wasm-binary.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,8 @@ class WasmBinaryWriter {
14101410
// must then insert before the code (as the spec requires that).
14111411
std::optional<BufferWithRandomAccess> writeCodeAnnotations();
14121412

1413+
std::optional<BufferWithRandomAccess> getBranchHintsBuffer();
1414+
14131415
// helpers
14141416
void writeInlineString(std::string_view name);
14151417
void writeEscapedName(std::string_view name);
@@ -1492,6 +1494,15 @@ class WasmBinaryWriter {
14921494
std::unordered_map<Name, Index> stringIndexes;
14931495

14941496
void prepare();
1497+
1498+
// Internal helper for emitting a code annotation section for a hint that is
1499+
// expression offset based. Receives the name of the section and two
1500+
// functions, one to check if the annotation we care about exists (receiving
1501+
// the annotation), and another to emit it (receiving the annotation and the
1502+
// buffer to write in).
1503+
template<typename HasFunc, typename EmitFunc>
1504+
std::optional<BufferWithRandomAccess>
1505+
writeExpressionHints(Name sectionName, HasFunc has, EmitFunc emit);
14951506
};
14961507

14971508
extern std::vector<char> defaultEmptySourceMap;
@@ -1679,7 +1690,6 @@ class WasmBinaryReader {
16791690
// hint position and size in the first pass, and handle it later.
16801691
size_t branchHintsPos = 0;
16811692
size_t branchHintsLen = 0;
1682-
16831693
void readBranchHints(size_t payloadLen);
16841694

16851695
Index readMemoryAccess(Address& alignment, Address& offset);

src/wasm/wasm-binary.cpp

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,8 +1549,28 @@ void WasmBinaryWriter::trackExpressionDelimiter(Expression* curr,
15491549
}
15501550

15511551
std::optional<BufferWithRandomAccess> WasmBinaryWriter::writeCodeAnnotations() {
1552-
// Assemble the info for Branch Hinting: for each function, a vector of the
1553-
// hints.
1552+
std::optional<BufferWithRandomAccess> ret;
1553+
1554+
auto append = [&](std::optional<BufferWithRandomAccess>&& temp) {
1555+
if (temp) {
1556+
if (!ret) {
1557+
// This is the first section.
1558+
ret = std::move(temp);
1559+
} else {
1560+
// This is a later section, append.
1561+
ret->insert(ret->end(), temp->begin(), temp->end());
1562+
}
1563+
}
1564+
};
1565+
1566+
append(getBranchHintsBuffer());
1567+
return ret;
1568+
}
1569+
1570+
template<typename HasFunc, typename EmitFunc>
1571+
std::optional<BufferWithRandomAccess> WasmBinaryWriter::writeExpressionHints(
1572+
Name sectionName, HasFunc has, EmitFunc emit) {
1573+
// Assemble the info: for each function, a vector of the hints.
15541574
struct ExprHint {
15551575
Expression* expr;
15561576
// The offset we will write in the custom section.
@@ -1566,15 +1586,15 @@ std::optional<BufferWithRandomAccess> WasmBinaryWriter::writeCodeAnnotations() {
15661586
std::vector<FuncHints> funcHintsVec;
15671587

15681588
for (auto& func : wasm->functions) {
1569-
// Collect the Branch Hints for this function.
1589+
// Collect the hints for this function.
15701590
FuncHints funcHints;
15711591

15721592
// We compute the location of the function declaration area (where the
15731593
// locals are declared) the first time we need it.
15741594
BinaryLocation funcDeclarationsOffset = 0;
15751595

15761596
for (auto& [expr, annotation] : func->codeAnnotations) {
1577-
if (annotation.branchLikely) {
1597+
if (has(annotation)) {
15781598
auto exprIter = binaryLocations.expressions.find(expr);
15791599
if (exprIter == binaryLocations.expressions.end()) {
15801600
// No expression exists for this annotation - perhaps optimizations
@@ -1622,7 +1642,7 @@ std::optional<BufferWithRandomAccess> WasmBinaryWriter::writeCodeAnnotations() {
16221642
// We found data: emit the section.
16231643
buffer << uint8_t(BinaryConsts::Custom);
16241644
auto lebPos = buffer.writeU32LEBPlaceholder();
1625-
buffer.writeInlineString(Annotations::BranchHint.str);
1645+
buffer.writeInlineString(sectionName.str);
16261646

16271647
buffer << U32LEB(funcHintsVec.size());
16281648
for (auto& funcHints : funcHintsVec) {
@@ -1632,14 +1652,7 @@ std::optional<BufferWithRandomAccess> WasmBinaryWriter::writeCodeAnnotations() {
16321652
for (auto& exprHint : funcHints.exprHints) {
16331653
buffer << U32LEB(exprHint.offset);
16341654

1635-
// Hint size, always 1 for now.
1636-
buffer << U32LEB(1);
1637-
1638-
// We must only emit hints that are present.
1639-
assert(exprHint.hint->branchLikely);
1640-
1641-
// Hint contents: likely or not.
1642-
buffer << U32LEB(int(*exprHint.hint->branchLikely));
1655+
emit(*exprHint.hint, buffer);
16431656
}
16441657
}
16451658

@@ -1651,6 +1664,25 @@ std::optional<BufferWithRandomAccess> WasmBinaryWriter::writeCodeAnnotations() {
16511664
return buffer;
16521665
}
16531666

1667+
std::optional<BufferWithRandomAccess> WasmBinaryWriter::getBranchHintsBuffer() {
1668+
return writeExpressionHints(
1669+
Annotations::BranchHint,
1670+
[](const Function::CodeAnnotation& annotation) {
1671+
return annotation.branchLikely;
1672+
},
1673+
[](const Function::CodeAnnotation& annotation,
1674+
BufferWithRandomAccess& buffer) {
1675+
// Hint size, always 1 for now.
1676+
buffer << U32LEB(1);
1677+
1678+
// We must only emit hints that are present.
1679+
assert(annotation.branchLikely);
1680+
1681+
// Hint contents: likely or not.
1682+
buffer << U32LEB(int(*annotation.branchLikely));
1683+
});
1684+
}
1685+
16541686
void WasmBinaryWriter::writeData(const char* data, size_t size) {
16551687
for (size_t i = 0; i < size; i++) {
16561688
o << int8_t(data[i]);

0 commit comments

Comments
 (0)