Skip to content

Commit 54f10c1

Browse files
Merge pull request #13121 from aschwaighofer/fix_closure_capture_leak
IRGen: Indirect_In_Constant inside of partial apply forwarders is now…
2 parents 0ba59a3 + 7100a09 commit 54f10c1

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

lib/IRGen/LoadableByAddress.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,12 @@ getNewParameter(GenericEnvironment *env, SILParameterInfo param,
283283
return param;
284284
}
285285
} else if (isLargeLoadableType(env, storageType, IGM)) {
286-
return SILParameterInfo(storageType.getSwiftRValueType(),
287-
ParameterConvention::Indirect_In_Constant);
286+
if (param.getConvention() == ParameterConvention::Direct_Guaranteed)
287+
return SILParameterInfo(storageType.getSwiftRValueType(),
288+
ParameterConvention::Indirect_In_Guaranteed);
289+
else
290+
return SILParameterInfo(storageType.getSwiftRValueType(),
291+
ParameterConvention::Indirect_In_Constant);
288292
} else {
289293
return param;
290294
}

test/Interpreter/ClosureLeak.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %target-run-simple-swift | %FileCheck %s
2+
3+
// REQUIRES: executable_test
4+
// REQUIRES: objc_interop
5+
6+
import Foundation
7+
8+
enum E {
9+
case a(String, Character, String)
10+
}
11+
12+
func doit( action: () -> ()) {
13+
action()
14+
}
15+
16+
func foo(_ s: [String]) {
17+
let bar = E.a(s[0], "a", "b")
18+
doit {
19+
let _ = bar
20+
}
21+
}
22+
23+
func getStrings() -> [String] {
24+
let c = "f.f".components(separatedBy: ".")
25+
return c
26+
}
27+
28+
for _ in 0 ..< 2_000_000 {
29+
autoreleasepool {
30+
let c = getStrings()
31+
foo(c)
32+
}
33+
}
34+
35+
var usage = rusage()
36+
getrusage(RUSAGE_SELF, &usage)
37+
38+
// CHECK: success
39+
// CHECK-NOT: failure
40+
41+
// We should not need 50MB for this.
42+
print(usage.ru_maxrss/(1024*1024))
43+
if usage.ru_maxrss > 50 * 1024 * 1024 {
44+
print("failure - should not need 50MB!")
45+
} else {
46+
print("success")
47+
}

0 commit comments

Comments
 (0)