Skip to content

Commit 107add7

Browse files
authored
Merge pull request #36278 from ahoppen/pr/inline-rawsyntax-methods
[libSyntax] Inline commonly called methods in RawSyntax and AbsoluteRawSyntax
2 parents 26dc01b + 3fa3e6c commit 107add7

File tree

6 files changed

+133
-163
lines changed

6 files changed

+133
-163
lines changed

include/swift/Syntax/AbsoluteRawSyntax.h

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,29 @@ class SyntaxIndexInTree {
3232

3333
/// Assuming that this index points to the start of \p Raw, advance it so that
3434
/// it points to the next sibling of \p Raw.
35-
SyntaxIndexInTree advancedBy(const RawSyntax *Raw) const;
35+
SyntaxIndexInTree advancedBy(const RawSyntax *Raw) const {
36+
auto NewIndexInTree = IndexInTree;
37+
if (Raw) {
38+
NewIndexInTree += Raw->getTotalNodes();
39+
}
40+
return SyntaxIndexInTree(NewIndexInTree);
41+
}
3642

3743
/// Assuming that this index points to the next sibling of \p Raw, reverse it
3844
/// so that it points to the start of \p Raw.
39-
SyntaxIndexInTree reversedBy(const RawSyntax *Raw) const;
45+
SyntaxIndexInTree reversedBy(const RawSyntax *Raw) const {
46+
auto NewIndexInTree = IndexInTree;
47+
if (Raw) {
48+
NewIndexInTree -= Raw->getTotalNodes();
49+
}
50+
return SyntaxIndexInTree(NewIndexInTree);
51+
}
4052

4153
/// Advance this index to point to its first immediate child.
42-
SyntaxIndexInTree advancedToFirstChild() const;
54+
SyntaxIndexInTree advancedToFirstChild() const {
55+
auto NewIndexInTree = IndexInTree + 1;
56+
return SyntaxIndexInTree(NewIndexInTree);
57+
}
4358

4459
bool operator==(SyntaxIndexInTree Other) const {
4560
return IndexInTree == Other.IndexInTree;
@@ -138,11 +153,25 @@ class AbsoluteSyntaxPosition {
138153

139154
/// Assuming that this position points to the start of \p Raw, advance it so
140155
/// that it points to the next sibling of \p Raw.
141-
AbsoluteSyntaxPosition advancedBy(const RawSyntax *Raw) const;
156+
AbsoluteSyntaxPosition advancedBy(const RawSyntax *Raw) const {
157+
OffsetType NewOffset = Offset;
158+
if (Raw) {
159+
NewOffset += Raw->getTextLength();
160+
}
161+
IndexInParentType NewIndexInParent = IndexInParent + 1;
162+
return AbsoluteSyntaxPosition(NewOffset, NewIndexInParent);
163+
}
142164

143165
/// Assuming that this position points to the next sibling of \p Raw, reverse
144166
/// it so that it points to the start of \p Raw.
145-
AbsoluteSyntaxPosition reversedBy(const RawSyntax *Raw) const;
167+
AbsoluteSyntaxPosition reversedBy(const RawSyntax *Raw) const {
168+
OffsetType NewOffset = Offset;
169+
if (Raw) {
170+
NewOffset -= Raw->getTextLength();
171+
}
172+
IndexInParentType NewIndexInParent = IndexInParent - 1;
173+
return AbsoluteSyntaxPosition(NewOffset, NewIndexInParent);
174+
}
146175

147176
/// Get the position of the node's first immediate child.
148177
AbsoluteSyntaxPosition advancedToFirstChild() const {

include/swift/Syntax/RawSyntax.h

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,39 @@ class RawSyntax final
223223
/// the caller needs to assure that the node ID has not been used yet.
224224
RawSyntax(SyntaxKind Kind, ArrayRef<const RawSyntax *> Layout,
225225
size_t TextLength, SourcePresence Presence,
226-
const RC<SyntaxArena> &Arena, llvm::Optional<SyntaxNodeId> NodeId);
226+
const RC<SyntaxArena> &Arena, llvm::Optional<SyntaxNodeId> NodeId)
227+
: Arena(Arena.get()),
228+
Bits({{unsigned(TextLength), unsigned(Presence), false}}) {
229+
assert(Arena && "RawSyntax nodes must always be allocated in an arena");
230+
assert(
231+
Kind != SyntaxKind::Token &&
232+
"'token' syntax node must be constructed with dedicated constructor");
233+
234+
size_t TotalSubNodeCount = 0;
235+
for (auto Child : Layout) {
236+
if (Child) {
237+
TotalSubNodeCount += Child->getTotalSubNodeCount() + 1;
238+
// If the child is stored in a different arena, it needs to stay alive
239+
// as long as this node's arena is alive.
240+
Arena->addChildArena(Child->Arena);
241+
}
242+
}
243+
244+
if (NodeId.hasValue()) {
245+
this->NodeId = NodeId.getValue();
246+
NextFreeNodeId = std::max(this->NodeId + 1, NextFreeNodeId);
247+
} else {
248+
this->NodeId = NextFreeNodeId++;
249+
}
250+
Bits.Layout.NumChildren = Layout.size();
251+
Bits.Layout.TotalSubNodeCount = TotalSubNodeCount;
252+
Bits.Layout.Kind = unsigned(Kind);
253+
254+
// Initialize layout data.
255+
std::uninitialized_copy(Layout.begin(), Layout.end(),
256+
getTrailingObjects<const RawSyntax *>());
257+
}
258+
227259
/// Constructor for creating token nodes
228260
/// \c SyntaxArena, that arena must be passed as \p Arena to retain the node's
229261
/// underlying storage.
@@ -232,7 +264,39 @@ class RawSyntax final
232264
RawSyntax(tok TokKind, StringRef Text, size_t TextLength,
233265
StringRef LeadingTrivia, StringRef TrailingTrivia,
234266
SourcePresence Presence, const RC<SyntaxArena> &Arena,
235-
llvm::Optional<SyntaxNodeId> NodeId);
267+
llvm::Optional<SyntaxNodeId> NodeId)
268+
: Arena(Arena.get()),
269+
Bits({{unsigned(TextLength), unsigned(Presence), true}}) {
270+
assert(Arena && "RawSyntax nodes must always be allocated in an arena");
271+
272+
if (Presence == SourcePresence::Missing) {
273+
assert(TextLength == 0);
274+
} else {
275+
assert(TextLength ==
276+
LeadingTrivia.size() + Text.size() + TrailingTrivia.size());
277+
}
278+
279+
if (NodeId.hasValue()) {
280+
this->NodeId = NodeId.getValue();
281+
NextFreeNodeId = std::max(this->NodeId + 1, NextFreeNodeId);
282+
} else {
283+
this->NodeId = NextFreeNodeId++;
284+
}
285+
Bits.Token.LeadingTrivia = LeadingTrivia.data();
286+
Bits.Token.TokenText = Text.data();
287+
Bits.Token.TrailingTrivia = TrailingTrivia.data();
288+
Bits.Token.LeadingTriviaLength = LeadingTrivia.size();
289+
Bits.Token.TokenLength = Text.size();
290+
Bits.Token.TrailingTriviaLength = TrailingTrivia.size();
291+
Bits.Token.TokenKind = unsigned(TokKind);
292+
293+
Arena->copyStringToArenaIfNecessary(Bits.Token.LeadingTrivia,
294+
Bits.Token.LeadingTriviaLength);
295+
Arena->copyStringToArenaIfNecessary(Bits.Token.TokenText,
296+
Bits.Token.TokenLength);
297+
Arena->copyStringToArenaIfNecessary(Bits.Token.TrailingTrivia,
298+
Bits.Token.TrailingTriviaLength);
299+
}
236300

237301
/// Compute the node's text length by summing up the length of its childern
238302
size_t computeTextLength() {
@@ -254,7 +318,13 @@ class RawSyntax final
254318
static const RawSyntax *
255319
make(SyntaxKind Kind, ArrayRef<const RawSyntax *> Layout, size_t TextLength,
256320
SourcePresence Presence, const RC<SyntaxArena> &Arena,
257-
llvm::Optional<SyntaxNodeId> NodeId = llvm::None);
321+
llvm::Optional<SyntaxNodeId> NodeId = llvm::None) {
322+
assert(Arena && "RawSyntax nodes must always be allocated in an arena");
323+
auto size = totalSizeToAlloc<const RawSyntax *>(Layout.size());
324+
void *data = Arena->Allocate(size, alignof(RawSyntax));
325+
return new (data)
326+
RawSyntax(Kind, Layout, TextLength, Presence, Arena, NodeId);
327+
}
258328

259329
static const RawSyntax *
260330
makeAndCalcLength(SyntaxKind Kind, ArrayRef<const RawSyntax *> Layout,
@@ -274,7 +344,13 @@ class RawSyntax final
274344
make(tok TokKind, StringRef Text, size_t TextLength, StringRef LeadingTrivia,
275345
StringRef TrailingTrivia, SourcePresence Presence,
276346
const RC<SyntaxArena> &Arena,
277-
llvm::Optional<SyntaxNodeId> NodeId = llvm::None);
347+
llvm::Optional<SyntaxNodeId> NodeId = llvm::None) {
348+
assert(Arena && "RawSyntax nodes must always be allocated in an arena");
349+
auto size = totalSizeToAlloc<const RawSyntax *>(0);
350+
void *data = Arena->Allocate(size, alignof(RawSyntax));
351+
return new (data) RawSyntax(TokKind, Text, TextLength, LeadingTrivia,
352+
TrailingTrivia, Presence, Arena, NodeId);
353+
}
278354

279355
/// Make a raw "token" syntax node that was allocated in \p Arena.
280356
static const RawSyntax *

include/swift/Syntax/SyntaxArena.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,23 @@ class SyntaxArena : public llvm::ThreadSafeRefCountedBase<SyntaxArena> {
108108
}
109109
return getAllocator().identifyObject(Ptr) != llvm::None;
110110
}
111+
112+
/// If the \p Data is not allocated in this arena, copy it to this and adjust
113+
/// \p Data to point to the string's copy in this arena.
114+
void copyStringToArenaIfNecessary(const char *&Data, size_t Length) {
115+
if (Length == 0) {
116+
// Empty strings can live wherever they want. Nothing to do.
117+
return;
118+
}
119+
if (containsPointer(Data)) {
120+
// String already in arena. Nothing to do.
121+
return;
122+
}
123+
// Copy string to arena
124+
char *ArenaData = (char *)getAllocator().Allocate<char>(Length);
125+
std::memcpy(ArenaData, Data, Length);
126+
Data = ArenaData;
127+
}
111128
};
112129

113130
} // namespace syntax

lib/Syntax/AbsoluteRawSyntax.cpp

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,47 +17,6 @@ using namespace swift::syntax;
1717

1818
std::atomic<SyntaxIdentifier::RootIdType> SyntaxIdentifier::NextUnusedRootId(0);
1919

20-
SyntaxIndexInTree SyntaxIndexInTree::advancedBy(const RawSyntax *Raw) const {
21-
auto NewIndexInTree = IndexInTree;
22-
if (Raw) {
23-
NewIndexInTree += Raw->getTotalNodes();
24-
}
25-
return SyntaxIndexInTree(NewIndexInTree);
26-
}
27-
28-
SyntaxIndexInTree SyntaxIndexInTree::reversedBy(const RawSyntax *Raw) const {
29-
auto NewIndexInTree = IndexInTree;
30-
if (Raw) {
31-
NewIndexInTree -= Raw->getTotalNodes();
32-
}
33-
return SyntaxIndexInTree(NewIndexInTree);
34-
}
35-
36-
SyntaxIndexInTree SyntaxIndexInTree::advancedToFirstChild() const {
37-
auto NewIndexInTree = IndexInTree + 1;
38-
return SyntaxIndexInTree(NewIndexInTree);
39-
}
40-
41-
AbsoluteSyntaxPosition
42-
AbsoluteSyntaxPosition::advancedBy(const RawSyntax *Raw) const {
43-
OffsetType NewOffset = Offset;
44-
if (Raw) {
45-
NewOffset += Raw->getTextLength();
46-
}
47-
IndexInParentType NewIndexInParent = IndexInParent + 1;
48-
return AbsoluteSyntaxPosition(NewOffset, NewIndexInParent);
49-
}
50-
51-
AbsoluteSyntaxPosition
52-
AbsoluteSyntaxPosition::reversedBy(const RawSyntax *Raw) const {
53-
OffsetType NewOffset = Offset;
54-
if (Raw) {
55-
NewOffset -= Raw->getTextLength();
56-
}
57-
IndexInParentType NewIndexInParent = IndexInParent - 1;
58-
return AbsoluteSyntaxPosition(NewOffset, NewIndexInParent);
59-
}
60-
6120
raw_ostream &llvm::operator<<(raw_ostream &OS,
6221
swift::syntax::AbsoluteOffsetPosition Pos) {
6322
OS << "Offset " << Pos.getOffset();

lib/Syntax/RawSyntax.cpp

Lines changed: 0 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -87,119 +87,9 @@ Trivia lexTrivia(StringRef TriviaStr) {
8787
return SyntaxTrivia;
8888
}
8989

90-
/// If the \p Str is not allocated in \p Arena, copy it to \p Arena and adjust
91-
/// \p Str to point to the string's copy in \p Arena.
92-
void copyToArenaIfNecessary(StringRef &Str, const RC<SyntaxArena> &Arena) {
93-
if (Str.empty()) {
94-
// Empty strings can live wherever they want. Nothing to do.
95-
return;
96-
}
97-
if (Arena->containsPointer(Str.data())) {
98-
// String already in arena. Nothing to do.
99-
return;
100-
}
101-
// Copy string to arena
102-
char *Data = (char *)Arena->Allocate(Str.size(), alignof(char *));
103-
std::uninitialized_copy(Str.begin(), Str.end(), Data);
104-
Str = StringRef(Data, Str.size());
105-
}
106-
10790
// FIXME: If we want thread-safety for tree creation, this needs to be atomic.
10891
unsigned RawSyntax::NextFreeNodeId = 1;
10992

110-
RawSyntax::RawSyntax(SyntaxKind Kind, ArrayRef<const RawSyntax *> Layout,
111-
size_t TextLength, SourcePresence Presence,
112-
const RC<SyntaxArena> &Arena,
113-
llvm::Optional<unsigned> NodeId)
114-
: Arena(Arena.get()),
115-
Bits({{unsigned(TextLength), unsigned(Presence), false}}) {
116-
assert(Arena && "RawSyntax nodes must always be allocated in an arena");
117-
assert(Kind != SyntaxKind::Token &&
118-
"'token' syntax node must be constructed with dedicated constructor");
119-
120-
size_t TotalSubNodeCount = 0;
121-
for (auto Child : Layout) {
122-
if (Child) {
123-
TotalSubNodeCount += Child->getTotalSubNodeCount() + 1;
124-
// If the child is stored in a different arena, it needs to stay alive
125-
// as long as this node's arena is alive.
126-
Arena->addChildArena(Child->Arena);
127-
}
128-
}
129-
130-
if (NodeId.hasValue()) {
131-
this->NodeId = NodeId.getValue();
132-
NextFreeNodeId = std::max(this->NodeId + 1, NextFreeNodeId);
133-
} else {
134-
this->NodeId = NextFreeNodeId++;
135-
}
136-
Bits.Layout.NumChildren = Layout.size();
137-
Bits.Layout.TotalSubNodeCount = TotalSubNodeCount;
138-
Bits.Layout.Kind = unsigned(Kind);
139-
140-
// Initialize layout data.
141-
std::uninitialized_copy(Layout.begin(), Layout.end(),
142-
getTrailingObjects<const RawSyntax *>());
143-
}
144-
145-
RawSyntax::RawSyntax(tok TokKind, StringRef Text, size_t TextLength,
146-
StringRef LeadingTrivia, StringRef TrailingTrivia,
147-
SourcePresence Presence, const RC<SyntaxArena> &Arena,
148-
llvm::Optional<unsigned> NodeId)
149-
: Arena(Arena.get()),
150-
Bits({{unsigned(TextLength), unsigned(Presence), true}}) {
151-
assert(Arena && "RawSyntax nodes must always be allocated in an arena");
152-
copyToArenaIfNecessary(LeadingTrivia, Arena);
153-
copyToArenaIfNecessary(Text, Arena);
154-
copyToArenaIfNecessary(TrailingTrivia, Arena);
155-
156-
if (Presence == SourcePresence::Missing) {
157-
assert(TextLength == 0);
158-
} else {
159-
assert(TextLength ==
160-
LeadingTrivia.size() + Text.size() + TrailingTrivia.size());
161-
}
162-
163-
if (NodeId.hasValue()) {
164-
this->NodeId = NodeId.getValue();
165-
NextFreeNodeId = std::max(this->NodeId + 1, NextFreeNodeId);
166-
} else {
167-
this->NodeId = NextFreeNodeId++;
168-
}
169-
Bits.Token.LeadingTrivia = LeadingTrivia.data();
170-
Bits.Token.TokenText = Text.data();
171-
Bits.Token.TrailingTrivia = TrailingTrivia.data();
172-
Bits.Token.LeadingTriviaLength = LeadingTrivia.size();
173-
Bits.Token.TokenLength = Text.size();
174-
Bits.Token.TrailingTriviaLength = TrailingTrivia.size();
175-
Bits.Token.TokenKind = unsigned(TokKind);
176-
}
177-
178-
const RawSyntax *RawSyntax::make(SyntaxKind Kind,
179-
ArrayRef<const RawSyntax *> Layout,
180-
size_t TextLength, SourcePresence Presence,
181-
const RC<SyntaxArena> &Arena,
182-
llvm::Optional<unsigned> NodeId) {
183-
assert(Arena && "RawSyntax nodes must always be allocated in an arena");
184-
auto size = totalSizeToAlloc<const RawSyntax *>(Layout.size());
185-
void *data = Arena->Allocate(size, alignof(RawSyntax));
186-
return new (data)
187-
RawSyntax(Kind, Layout, TextLength, Presence, Arena, NodeId);
188-
}
189-
190-
const RawSyntax *RawSyntax::make(tok TokKind, StringRef Text, size_t TextLength,
191-
StringRef LeadingTrivia,
192-
StringRef TrailingTrivia,
193-
SourcePresence Presence,
194-
const RC<SyntaxArena> &Arena,
195-
llvm::Optional<unsigned> NodeId) {
196-
assert(Arena && "RawSyntax nodes must always be allocated in an arena");
197-
auto size = totalSizeToAlloc<const RawSyntax *>(0);
198-
void *data = Arena->Allocate(size, alignof(RawSyntax));
199-
return new (data) RawSyntax(TokKind, Text, TextLength, LeadingTrivia,
200-
TrailingTrivia, Presence, Arena, NodeId);
201-
}
202-
20393
Trivia RawSyntax::getLeadingTriviaPieces() const {
20494
return lexTrivia(getLeadingTrivia());
20595
}

lib/SyntaxParse/SyntaxTreeCreator.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ SyntaxTreeCreator::SyntaxTreeCreator(SourceManager &SM, unsigned bufferID,
3535
SyntaxCache(syntaxCache),
3636
TokenCache(new RawSyntaxTokenCache()) {
3737
StringRef BufferContent = SM.getEntireTextForBuffer(BufferID);
38-
char *Data = (char *)Arena->Allocate(BufferContent.size(), alignof(char *));
39-
std::uninitialized_copy(BufferContent.begin(), BufferContent.end(), Data);
38+
const char *Data = BufferContent.data();
39+
Arena->copyStringToArenaIfNecessary(Data, BufferContent.size());
4040
ArenaSourceBuffer = StringRef(Data, BufferContent.size());
41-
assert(ArenaSourceBuffer == BufferContent);
4241
Arena->setHotUseMemoryRegion(ArenaSourceBuffer.begin(),
4342
ArenaSourceBuffer.end());
4443
}

0 commit comments

Comments
 (0)