Skip to content

Conversation

beccadax
Copy link
Contributor

@beccadax beccadax commented Oct 3, 2025

I’ve had trouble running SwiftParser’s tests—particularly the torture tests in the swiftlang/swift repo—locally in debug mode because some common parser functions would use many kilobytes of stack for each call, consuming the stack too quickly for even a low maximumNestingLevel to control. Break up a number of problematic functions to help with this, and also insert a missing stack overflow check in parseClosureExpression().

Each of the functions I've broken up previously used 4-11K of stack and appeared in a backtrace of a test case that crashed because of a stack overflow, either repeatedly or very close to the top of the stack.

I haven't determined if these changes regress release-mode performance; if they do, we probably shouldn't take them.

@bnbarham
Copy link
Contributor

bnbarham commented Oct 3, 2025

Ooo, thanks for looking into this @beccadax!

swift-parser-cli (Sources/swift-parser-cli) has a performance-test (outputs time + instruction count) that you can use to compare before/after your changes. @hamishknight what repo(s) do you use for the weekly performance tests?

I’ve had trouble running SwiftParser’s tests—particularly the torture tests in the swiftlang/swift repo—locally in debug mode because some common parser functions would use many kilobytes of stack for each call, consuming the stack too quickly for the `maximumNestingLevel` to control. Break up a number of problematic functions to help with this, and also insert a missing stack overflow check in `parseClosureExpression()`.
@beccadax
Copy link
Contributor Author

beccadax commented Oct 4, 2025

I'll wait for Hamish's input, but a quick run on the swift-syntax/Sources directory was actually about 1% faster than main, so that's promising.

@beccadax
Copy link
Contributor Author

beccadax commented Oct 4, 2025

@swift-ci please test

@beccadax
Copy link
Contributor Author

beccadax commented Oct 6, 2025

@swift-ci please test Windows platform

@hamishknight
Copy link
Contributor

Running the stress tester job on swiftlang/swift#58827 to get performance data

Copy link
Contributor

@hamishknight hamishknight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This is also a nice cleanup IMO. The stress tester performance data showed very little change, the percentile and mean differences were all under 0.4%, which is pretty close to the run-to-run variance of ~0.2%.

flavor: ExprFlavor,
pattern: PatternContext
) -> RawExprSyntax? {
EXPR_PREFIX: switch self.at(anyIn: ExpressionModifierKeyword.self) {
Copy link
Contributor

@hamishknight hamishknight Oct 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While here, could you get rid of this statement label? Seems like was already unnecessary, all the uses of it are directly within the switch (and now with your patch could actually be turned into return nil)

}
let element = elementKind!.makeElement(trailingComma: keepGoing, arena: self.arena)
if element.isEmpty {
break COLLECTION_LOOP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also get rid of this statement label now? (I really dislike statement labels 😄)

@beccadax beccadax enabled auto-merge October 10, 2025 21:36
@beccadax
Copy link
Contributor Author

@swift-ci smoke test

@beccadax
Copy link
Contributor Author

@swift-ci please test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants