> On Aug 27, 2017, at 10:57 AM, Edward Connell via swift-users 
> <swift-users@swift.org> wrote:
> 
> import Foundation
> 
> class A {
>       var counter = 0 {
> //            didSet { onSet("counter") }  // no leak
>               didSet { onSet() }  // huge leak
>       }
> 
>       var properties = ["counter" : 0]
>       func onSet(_ name: String = #function) {
>               properties[name]! += 1
>       }
> }
> 
> var myclass = A()
> 
> for i in 0..<10000000 {
>       myclass.counter = i
> }
> 
> print(myclass.properties["counter"]!)

The only code generation difference I see, if I modify your didSet to make both 
calls is that the compiler treats #function as a UTF-16 literal, whereas 
"counter" is recognized as an ASCII literal:

// A.counter.didset
sil hidden @_T03foo1AC7counterSifW : $@convention(method) (Int, @guaranteed A) 
-> () {
// %0                                             // user: %2
// %1                                             // users: %19, %12, %11, %4, 
%3
bb0(%0 : $Int, %1 : $A):
  debug_value %0 : $Int, let, name "oldValue", argno 1 // id: %2
  debug_value %1 : $A, let, name "self", argno 2  // id: %3
  %4 = class_method %1 : $A, #A.onSet!1 : (A) -> (String) -> (), 
$@convention(method) (@owned String, @guaranteed A) -> () // user: %11
  %5 = string_literal utf8 "counter"              // user: %10
  %6 = integer_literal $Builtin.Word, 7           // user: %10
  %7 = integer_literal $Builtin.Int1, -1          // user: %10
  %8 = metatype $@thin String.Type                // user: %10
  // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
  %9 = function_ref 
@_T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC : 
$@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin 
String.Type) -> @owned String // user: %10
  %10 = apply %9(%5, %6, %7, %8) : $@convention(method) (Builtin.RawPointer, 
Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %11
  %11 = apply %4(%10, %1) : $@convention(method) (@owned String, @guaranteed A) 
-> ()
  %12 = class_method %1 : $A, #A.onSet!1 : (A) -> (String) -> (), 
$@convention(method) (@owned String, @guaranteed A) -> () // user: %19
  %13 = string_literal utf16 "counter"            // user: %18
  %14 = integer_literal $Builtin.Word, 7          // user: %18
  %15 = integer_literal $Builtin.Int1, -1
  %16 = metatype $@thin String.Type               // user: %18
  // function_ref String.init(_builtinUTF16StringLiteral:utf16CodeUnitCount:)
  %17 = function_ref 
@_T0S2SBp26_builtinUTF16StringLiteral_Bw18utf16CodeUnitCounttcfC : 
$@convention(method) (Builtin.RawPointer, Builtin.Word, @thin String.Type) -> 
@owned String // user: %18
  %18 = apply %17(%13, %14, %16) : $@convention(method) (Builtin.RawPointer, 
Builtin.Word, @thin String.Type) -> @owned String // user: %19
  %19 = apply %12(%18, %1) : $@convention(method) (@owned String, @guaranteed 
A) -> ()
  %20 = tuple ()                                  // user: %21
  return %20 : $()                                // id: %21
} // end sil function '_T03foo1AC7counterSifW'

Michael, could there be a leak in the implementation of 
String(_builtinUTF16StringLiteral:utf16CodeUnitCount:)? The SIL at first glance 
looks balanced here.

-Joe

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to