Skip to content

Commit ded0c11

Browse files
committed
Reduce traffic through macroConfigPaths lock
Internally to `MacroValueAssignmentTable` we were looking up interned location references to paths and back, even though we really only need to pass the reference to new `MacroValueAssignment` instances. rdar://146340881
1 parent db117d2 commit ded0c11

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

Sources/SWBMacro/MacroValueAssignmentTable.swift

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ public struct MacroValueAssignmentTable: Serializable, Sendable {
8585
valueAssignments[macro] = MacroValueAssignment(expression: value, conditions: conditions, next: valueAssignments[macro], location: location)
8686
}
8787

88+
mutating func push(_ macro: MacroDeclaration, _ value: MacroExpression, conditions: MacroConditionSet? = nil, locationRef: InternedMacroValueAssignmentLocation?) {
89+
assert(namespace.lookupMacroDeclaration(macro.name) === macro)
90+
// Validate the type.
91+
assert(macro.type.matchesExpressionType(value))
92+
valueAssignments[macro] = MacroValueAssignment(expression: value, conditions: conditions, next: valueAssignments[macro], locationRef: locationRef)
93+
}
94+
8895
/// Adds a mapping from each of the macro-to-value mappings in `otherTable`, inserting them ahead of any already existing assignments in the receiving table. The other table isn’t affected in any way (in particular, no reference is kept from the receiver to the other table).
8996
public mutating func pushContentsOf(_ otherTable: MacroValueAssignmentTable) {
9097
for (macro, firstAssignment) in otherTable.valueAssignments {
@@ -183,15 +190,15 @@ public struct MacroValueAssignmentTable: Serializable, Sendable {
183190
if effectiveConditionValue.evaluate(condition) == true {
184191
// Condition evaluates to true, so we push an assignment with a condition set that excludes the condition.
185192
let filteredConditions = conditions.conditions.filter{ $0.parameter != parameter }
186-
table.push(macro, assignment.expression, conditions: filteredConditions.isEmpty ? nil : MacroConditionSet(conditions: filteredConditions), location: assignment.location)
193+
table.push(macro, assignment.expression, conditions: filteredConditions.isEmpty ? nil : MacroConditionSet(conditions: filteredConditions), locationRef: assignment._location)
187194
}
188195
else {
189196
// Condition evaluates to false, so we elide the assignment.
190197
}
191198
}
192199
else {
193200
// Assignment isn't conditioned on the specified parameter, so we just push it as-is.
194-
table.push(macro, assignment.expression, conditions: assignment.conditions, location: assignment.location)
201+
table.push(macro, assignment.expression, conditions: assignment.conditions, locationRef: assignment._location)
195202
}
196203
}
197204
bindAndPushAssignment(firstAssignment)
@@ -330,7 +337,7 @@ public final class MacroValueAssignment: Serializable, CustomStringConvertible,
330337
/// Reference to the next (lower precedence) assignment in the linked list, or nil if this is the last one.
331338
public let next: MacroValueAssignment?
332339

333-
private let _location: InternedMacroValueAssignmentLocation?
340+
let _location: InternedMacroValueAssignmentLocation?
334341
private static let macroConfigPaths = SWBMutex<OrderedSet<Path>>(OrderedSet())
335342

336343
public var location: MacroValueAssignmentLocation? {
@@ -348,22 +355,33 @@ public final class MacroValueAssignment: Serializable, CustomStringConvertible,
348355
}
349356

350357
/// Initializes the macro value assignment to represent `expression`, with the next existing macro value assignment (if any).
351-
init(expression: MacroExpression, conditions: MacroConditionSet? = nil, next: MacroValueAssignment?, location: MacroValueAssignmentLocation?) {
352-
self.expression = expression
353-
self.conditions = conditions
354-
self.next = next
355-
358+
convenience init(expression: MacroExpression, conditions: MacroConditionSet? = nil, next: MacroValueAssignment?, location: MacroValueAssignmentLocation?) {
359+
let locationRef: InternedMacroValueAssignmentLocation?
356360
if let location {
357-
self._location = InternedMacroValueAssignmentLocation(
361+
locationRef = InternedMacroValueAssignmentLocation(
358362
pathRef: Self.macroConfigPaths.withLock({ $0.append(location.path).index }),
359363
startLine: location.startLine,
360364
endLine: location.endLine,
361365
startColumn: location.startColumn,
362366
endColumn: location.endColumn
363367
)
364368
} else {
365-
self._location = nil
369+
locationRef = nil
366370
}
371+
372+
self.init(
373+
expression: expression,
374+
conditions: conditions,
375+
next: next,
376+
locationRef: locationRef
377+
)
378+
}
379+
380+
init(expression: MacroExpression, conditions: MacroConditionSet? = nil, next: MacroValueAssignment?, locationRef: InternedMacroValueAssignmentLocation?) {
381+
self.expression = expression
382+
self.conditions = conditions
383+
self.next = next
384+
self._location = locationRef
367385
}
368386

369387
/// Returns the first macro value assignment that is reachable from the receiver and whose conditions match the given set of parameter values, or nil if there is no such assignment value. The returned assignment may be the receiver itself, or it may be any assignment that’s downstream in the linked list of macro value assignments, or it may be nil if there is none. Unconditional macro value assignments are considered to match any conditions. Conditions that reference parameters that don’t have a value in `paramValues` are only considered to match if the match pattern is `*`, i.e. the “match-anything” pattern (which is effectively a no-op).
@@ -448,7 +466,7 @@ public struct MacroValueAssignmentLocation: Sendable, Equatable {
448466
}
449467
}
450468

451-
private struct InternedMacroValueAssignmentLocation: Serializable, Sendable {
469+
struct InternedMacroValueAssignmentLocation: Serializable, Sendable {
452470
let pathRef: OrderedSet<Path>.Index
453471
public let startLine: Int
454472
public let endLine: Int

0 commit comments

Comments
 (0)