Skip to content

Commit d32b342

Browse files
rintaronkcsgexi
authored andcommitted
[Syntax] Use single storage across all SyntaxParsingContexts
1 parent 6dac640 commit d32b342

File tree

2 files changed

+63
-38
lines changed

2 files changed

+63
-38
lines changed

include/swift/Syntax/SyntaxParsingContext.h

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ struct alignas(1 << SyntaxAlignInBits) RootContextData {
7373
// Where to issue diagnostics.
7474
DiagnosticEngine &Diags;
7575

76+
// Storage for Collected parts.
77+
std::vector<RC<RawSyntax>> Storage;
78+
7679
RootContextData(SourceFile &SF, DiagnosticEngine &Diags): SF(SF), Diags(Diags) {}
7780
};
7881

@@ -94,13 +97,16 @@ struct alignas(1 << SyntaxAlignInBits) RootContextData {
9497
class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
9598
// When this context is a root, this points to an instance of RootContextData;
9699
// When this context isn't a root, this points to the parent context.
97-
llvm::PointerUnion<RootContextData*, SyntaxParsingContext*> RootDataOrParent;
100+
const llvm::PointerUnion<RootContextData *, SyntaxParsingContext *>
101+
RootDataOrParent;
98102

99103
// Reference to the
100104
SyntaxParsingContext *&CtxtHolder;
101105

102-
// Collected parts.
103-
std::vector<RC<RawSyntax>> Parts;
106+
std::vector<RC<RawSyntax>> &Storage;
107+
108+
// Offet for 'Storage' this context owns from.
109+
const size_t Offset;
104110

105111
// Operation on destruction.
106112
AccumulationMode Mode = AccumulationMode::NotSet;
@@ -120,6 +126,10 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
120126
/// replace those parts with the single result.
121127
void createNodeInPlace(SyntaxKind Kind, size_t N);
122128

129+
ArrayRef<RC<RawSyntax>> getParts() const {
130+
return makeArrayRef(Storage).drop_front(Offset);
131+
}
132+
123133
public:
124134
/// Construct root context.
125135
SyntaxParsingContext(SyntaxParsingContext *&CtxtHolder, SourceFile &SF,
@@ -128,7 +138,8 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
128138
/// Designated constructor for child context.
129139
SyntaxParsingContext(SyntaxParsingContext *&CtxtHolder)
130140
: RootDataOrParent(CtxtHolder), CtxtHolder(CtxtHolder),
131-
Enabled(getParent()->isEnabled()) {
141+
Storage(CtxtHolder->Storage), Offset(Storage.size()),
142+
Enabled(CtxtHolder->isEnabled()) {
132143
assert(CtxtHolder->isTopOfContextStack() &&
133144
"SyntaxParsingContext cannot have multiple children");
134145
CtxtHolder = this;
@@ -170,24 +181,22 @@ class alignas(1 << SyntaxAlignInBits) SyntaxParsingContext {
170181
/// Add Syntax to the parts.
171182
void addSyntax(Syntax Node);
172183

173-
RC<RawSyntax> popBack() {
174-
auto Raw = std::move(Parts.back());
175-
Parts.pop_back();
176-
return Raw;
177-
}
178-
179184
template<typename SyntaxNode>
180185
llvm::Optional<SyntaxNode> popIf() {
181-
if (auto Node = make<Syntax>(Parts.back()).getAs<SyntaxNode>()) {
182-
Parts.pop_back();
186+
assert(Storage.size() > Offset);
187+
if (auto Node = make<Syntax>(Storage.back()).getAs<SyntaxNode>()) {
188+
Storage.pop_back();
183189
return Node;
184190
}
185191
return None;
186192
}
187193

188194
TokenSyntax popToken() {
189-
assert(Parts.back()->Kind == SyntaxKind::Token);
190-
return make<TokenSyntax>(popBack());
195+
assert(Storage.size() > Offset);
196+
assert(Storage.back()->Kind == SyntaxKind::Token);
197+
auto Node = make<TokenSyntax>(std::move(Storage.back()));
198+
Storage.pop_back();
199+
return Node;
191200
}
192201

193202
/// Create a node using the tail of the collected parts. The number of parts

lib/Syntax/SyntaxParsingContext.cpp

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ RC<RawSyntax> createSyntaxAs(SyntaxKind Kind, ArrayRef<RC<RawSyntax>> Parts) {
5353
SyntaxParsingContext::SyntaxParsingContext(SyntaxParsingContext *&CtxtHolder,
5454
SourceFile &SF,
5555
DiagnosticEngine &Diags)
56-
: RootDataOrParent(new RootContextData(SF, Diags)),
57-
CtxtHolder(CtxtHolder), Mode(AccumulationMode::Root),
56+
: RootDataOrParent(new RootContextData(SF, Diags)), CtxtHolder(CtxtHolder),
57+
Storage(getRootData().Storage), Offset(0), Mode(AccumulationMode::Root),
5858
Enabled(SF.shouldKeepSyntaxInfo()) {
5959
CtxtHolder = this;
6060
}
6161

6262
/// Add RawSyntax to the parts.
6363
void SyntaxParsingContext::addRawSyntax(RC<RawSyntax> Raw) {
64-
Parts.emplace_back(Raw);
64+
Storage.emplace_back(Raw);
6565
}
6666

6767
SyntaxParsingContext *SyntaxParsingContext::getRoot() {
@@ -90,14 +90,17 @@ void SyntaxParsingContext::addSyntax(Syntax Node) {
9090
}
9191

9292
void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind, size_t N) {
93-
assert(N >= 1);
93+
if (N == 0) {
94+
Storage.push_back(createSyntaxAs(Kind, {}));
95+
return;
96+
}
9497

95-
auto I = Parts.end() - N;
96-
*I = createSyntaxAs(Kind, llvm::makeArrayRef(Parts).take_back(N));
98+
auto I = Storage.end() - N;
99+
*I = createSyntaxAs(Kind, getParts().take_back(N));
97100

98-
// Remove used parts.
101+
// Remove consumed parts.
99102
if (N != 1)
100-
Parts.erase(I + 1, Parts.end());
103+
Storage.erase(I + 1, Storage.end());
101104
}
102105

103106
void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind) {
@@ -123,7 +126,7 @@ void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind) {
123126
case SyntaxKind::FunctionCallExpr:
124127
case SyntaxKind::SubscriptExpr:
125128
case SyntaxKind::ExprList: {
126-
createNodeInPlace(Kind, Parts.size());
129+
createNodeInPlace(Kind, getParts().size());
127130
break;
128131
}
129132
default:
@@ -136,14 +139,16 @@ void SyntaxParsingContext::collectNodesInPlace(SyntaxKind ColletionKind) {
136139
assert(isTopOfContextStack());
137140
if (!Enabled)
138141
return;
139-
auto Count = std::count_if(Parts.rbegin(), Parts.rend(),
140-
[&](const RC<RawSyntax> &Raw) {
141-
return SyntaxFactory::canServeAsCollectionMember(ColletionKind,
142-
make<Syntax>(Raw));
143-
});
144-
if (Count) {
145-
createNodeInPlace(ColletionKind, Count);
142+
auto Parts = getParts();
143+
auto Count = 0;
144+
for (auto I = Parts.rbegin(), End = Parts.rend(); I != End; ++I) {
145+
if (!SyntaxFactory::canServeAsCollectionMember(ColletionKind,
146+
make<Syntax>(*I)))
147+
break;
148+
++Count;
146149
}
150+
if (Count)
151+
createNodeInPlace(ColletionKind, Count);
147152
}
148153

149154
namespace {
@@ -257,28 +262,39 @@ SyntaxParsingContext::~SyntaxParsingContext() {
257262
switch (Mode) {
258263
// Create specified Syntax node from the parts and add it to the parent.
259264
case AccumulationMode::CreateSyntax:
260-
getParent()->addRawSyntax(createSyntaxAs(SynKind, Parts));
265+
assert(!isRoot());
266+
createNodeInPlace(SynKind, Storage.size() - Offset);
261267
break;
262268

263269
// Ensure the result is specified Syntax category and add it to the parent.
264-
case AccumulationMode::CoerceKind:
265-
getParent()->addRawSyntax(bridgeAs(CtxtKind, Parts));
270+
case AccumulationMode::CoerceKind: {
271+
assert(!isRoot());
272+
if (Storage.size() == Offset) {
273+
Storage.push_back(bridgeAs(CtxtKind, {}));
274+
} else {
275+
auto I = Storage.begin() + Offset;
276+
*I = bridgeAs(CtxtKind, getParts());
277+
// Remove used parts.
278+
if (Storage.size() > Offset + 1)
279+
Storage.erase(Storage.begin() + (Offset + 1), Storage.end());
280+
}
266281
break;
282+
}
267283

268-
// Just move the parts to the tail of the parent.
284+
// Do nothing.
269285
case AccumulationMode::Transparent:
270-
std::move(Parts.begin(), Parts.end(), std::back_inserter(getParent()->Parts));
286+
assert(!isRoot());
271287
break;
272288

273-
// Do nothing. Just let it discarded.
289+
// Remove all parts in this context.
274290
case AccumulationMode::Discard:
275-
assert(!isRoot());
291+
Storage.resize(Offset);
276292
break;
277293

278294
// Accumulate parsed toplevel syntax onto the SourceFile.
279295
case AccumulationMode::Root:
280296
assert(isRoot() && "AccumulationMode::Root is only for root context");
281-
finalizeSourceFile(getRootData().SF, Parts);
297+
finalizeSourceFile(getRootData().SF, getParts());
282298
break;
283299

284300
// Never.

0 commit comments

Comments
 (0)