New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-6464] Leak of enums > 32 bytes when passed to dispatch queue #666
Labels
Comments
Comment by Oliver Chick (JIRA) @swift-ci create |
Comment by Oliver Chick (JIRA) SIL for foo is: Should %10 be released? // foo(_:)
sil hidden @_T04main3fooySaySSGF : $@convention(thin) (@owned Array<String>) -> () {
// %0 // users: %8, %35, %2
bb0(%0 : $Array<String>):
%1 = global_addr @_T04main9syncQueue8Dispatch0dC0Cvp : $*DispatchQueue // user: %27
debug_value %0 : $Array<String>, let, name "s", argno 1 // id: %2
%3 = metatype $@thin E.Type
%4 = integer_literal $Builtin.Int64, 0 // user: %5
%5 = struct $Int (%4 : $Builtin.Int64) // user: %8
%6 = alloc_stack $String // users: %9, %10, %26
// function_ref specialized Array.subscript.getter
%7 = function_ref @_T0SaxSicigSS_Tg5 : $@convention(method) (Int, @guaranteed Array<String>) -> @owned String // user: %8
%8 = apply %7(%5, %0) : $@convention(method) (Int, @guaranteed Array<String>) -> @owned String // user: %9
store %8 to %6 : $*String // id: %9
%10 = load %6 : $*String // user: %23
%11 = string_literal utf16 "a" // user: %16
%12 = integer_literal $Builtin.Word, 1 // user: %16
%13 = integer_literal $Builtin.Int1, -1
%14 = metatype $@thin Character.Type // user: %16
// function_ref Character.init(_builtinExtendedGraphemeClusterLiteral:utf16CodeUnitCount:)
%15 = function_ref @_T0s9CharacterVABBp38_builtinExtendedGraphemeClusterLiteral_Bw18utf16CodeUnitCounttcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, @thin Character.Type) -> @owned Character // user: %16
%16 = apply %15(%11, %12, %14) : $@convention(method) (Builtin.RawPointer, Builtin.Word, @thin Character.Type) -> @owned Character // user: %23
%17 = string_literal utf8 "b" // user: %22
%18 = integer_literal $Builtin.Word, 1 // user: %22
%19 = integer_literal $Builtin.Int1, -1 // user: %22
%20 = metatype $@thin String.Type // user: %22
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
%21 = function_ref @_T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %22
%22 = apply %21(%17, %18, %19, %20) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %23
%23 = tuple (%10 : $String, %16 : $Character, %22 : $String) // user: %24
%24 = enum $E, #E.a!enumelt.1, %23 : $(String, Character, String) // users: %34, %30, %29, %25
debug_value %24 : $E, let, name "bar" // id: %25
dealloc_stack %6 : $*String // id: %26
%27 = load %1 : $*DispatchQueue // users: %32, %33
// function_ref closure #​1 in foo(_:)
%28 = function_ref @_T04main3fooySaySSGFyycfU_ : $@convention(thin) (@guaranteed E) -> () // user: %30
retain_value %24 : $E // id: %29
%30 = partial_apply [callee_guaranteed] %28(%24) : $@convention(thin) (@guaranteed E) -> () // user: %31
%31 = convert_function %30 : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> () // user: %33
%32 = class_method %27 : $DispatchQueue, #DispatchQueue.sync!1 : (DispatchQueue) -> (() -> ()) -> (), $@convention(method) (@owned @noescape @callee_guaranteed () -> (), @guaranteed DispatchQueue) -> () // user: %33
%33 = apply %32(%31, %27) : $@convention(method) (@owned @noescape @callee_guaranteed () -> (), @guaranteed DispatchQueue) -> ()
release_value %24 : $E // id: %34
release_value %0 : $Array<String> // id: %35
%36 = tuple () // user: %37
return %36 : $() // id: %37
} // end sil function '_T04main3fooySaySSGF' |
Comment by Oliver Chick (JIRA) This also leaks when E is a struct > 32 bytes |
What happens with the following code: import Dispatch
import Foundation
let syncQueue = DispatchQueue(label: "q")
enum E {
case a(String, Character, String)
}
func foo(_ s: [String]) {
let bar = E.a(s[0], "a", "b")
return syncQueue.sync {
let _ = bar
}
}
print(MemoryLayout<E>.size)
while true {
autoreleasepool {
foo("f.f".components(separatedBy: "."))
}
} |
Okay, with the autorelease pool I see that DEVELOPMENT-SNAPSHOT-2017-11-16-a does not leak but later versions leak. |
Should be fixed by: apple/swift#13121 |
This issue was closed.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Additional Detail from JIRA
md5: ded90b305923cb75a9e4cfd2bcf7f7e3
Issue Description:
There seems to have been a change go into swift betweenDEVELOPMENT-SNAPSHOT-2017-11-16-a and DEVELOPMENT-SNAPSHOT-2017-11-21-a such that the following code now leaks memory on Darwin and Linux:
It seems that memory is only leaked when the size of E is > 32 bytes.
Valgrind claims:
The text was updated successfully, but these errors were encountered: