Skip to content
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-459] Weakened optionals don't zero in 2.2 snapshot builds #43076

Closed
swift-ci opened this issue Jan 4, 2016 · 13 comments
Closed

[SR-459] Weakened optionals don't zero in 2.2 snapshot builds #43076

swift-ci opened this issue Jan 4, 2016 · 13 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 2.2

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jan 4, 2016

Previous ID SR-459
Radar rdar://problem/24057977
Original Reporter inscrutablemike (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

Apple Swift version 2.2-dev (LLVM 3ebdbb2c7e, Clang f66c5bb67b, Swift 1f2908b)
Target: x86_64-apple-macosx10.9

Swift version 2.2-dev (LLVM 3ebdbb2c7e, Clang f66c5bb67b, Swift 1f2908b)
Target: x86_64-unknown-linux-gnu

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 2.2Regression
Assignee @atrick
Priority Medium

md5: 8e13adeca5cfa5d36defbd71b51e4b1e

Issue Description:

Weakened optionals referring to an object are supposed to zero themselves when all strong references to that object are released. In the production 2.1.1 toolchain, this happens properly. In the 2.2 snapshots it doesn't seem to work on any platform.

== release version Swift results ==
macbook-pro:devel$ swift -version
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Target: x86_64-apple-darwin15.2.0

macbook-pro:devel$ swift weakrefs.swift
willSet(value=Optional(weakrefs.Held))
didSet(value=Optional(weakrefs.Held))
t1: has value
t2: no value
willSet(value=Optional(weakrefs.Held))
didSet(value=Optional(weakrefs.Held))
t3: has value
t4: no value

== Snapshot 2015-12-31 on Linux ==
user@host:~$ swift -version
Swift version 2.2-dev (LLVM 3ebdbb2c7e, Clang f66c5bb67b, Swift 1f2908b)
Target: x86_64-unknown-linux-gnu

user@host:~$ swift weakrefs.swift
willSet(value=Optional(weakrefs.Held))
didSet(value=Optional(weakrefs.Held))
t1: has value
t2: has value!
willSet(value=Optional(weakrefs.Held))
didSet(value=Optional(weakrefs.Held))
t3: has value
t4: has value!

== Snapshot 2015-12-31 on Mac ==
macbook-pro:devel$ swift -version
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Target: x86_64-apple-darwin15.2.0

macbook-pro:devel$ swift weakrefs.swift
willSet(value=Optional(weakrefs.Held))
didSet(value=Optional(weakrefs.Held))
t1: has value
t2: no value
willSet(value=Optional(weakrefs.Held))
didSet(value=Optional(weakrefs.Held))
t3: has value
t4: no value

@belkadan
Copy link
Contributor

belkadan commented Jan 4, 2016

Yikes. @jckarter, is this intentional?

@jckarter
Copy link
Member

jckarter commented Jan 6, 2016

I don't think we intentionally changed anything here, at least, not in the runtime that I know of. There's a possibility that our code gen broke and introduced a leak.

@jckarter
Copy link
Member

jckarter commented Jan 7, 2016

The problem seems to specifically be with willSet/didSet codegen. Remove the willSet/didSet accessors, and the property appears to zero out correctly.

@jckarter
Copy link
Member

jckarter commented Jan 7, 2016

The problem appears to be a memory leak; the original value never gets deallocated if there are observers on a weak var.

@jckarter
Copy link
Member

jckarter commented Jan 7, 2016

Making the property strong with observers also appears to work around the problem.

@jckarter
Copy link
Member

jckarter commented Jan 7, 2016

Reduced it further. Referencing newValue in a string interpolation during willSet seems to cause the leak:

  weak var value: HeldBase? {
    willSet {
      _ = "\(newValue)"
    }
  }

Making the willSet empty, or referring to newValue outside of an interpolation, doesn't seem to cause a leak. @gribozavr, are you aware of any recent changes to printing that might have introduced leaks? Interestingly print(newValue) seems to be OK.

@jckarter
Copy link
Member

jckarter commented Jan 7, 2016

Found it—printing an Optional leaks in 2.2. @atrick, can you take a look? Here's a reduced test case:

class Wut {
  deinit { print("x") }
}

do {
  _ = "\(Optional(Wut()))"
}
// should print x, but prints nothing

@atrick
Copy link
Member

atrick commented Jan 7, 2016

This is either directly due to or exposed by my extending swift_dynamicCast to handle Optional casts. This is the case that leaks:

// .Some
// Single payload enums are guaranteed layout compatible with their
// payload. Only the source's payload needs to be taken or destroyed.
srcType = payloadType;

It's not clear to me how the runtime cast itself could leak, although I'll try to debug that tomorrow. It's possible that by allowing the cast to succeed (as it must by language rules), I've exposed a leak somewhere in the stdlib.

@gribozavr
Copy link
Collaborator

@jckarter No, I'm not.

@atrick
Copy link
Member

atrick commented Jan 7, 2016

When casting an optional that itself conforms to an existential, I'm double copying into that existential container, resulting in an extra retain of the Optional payload. At least that's my theory. I'm trying out a fix.

@atrick
Copy link
Member

atrick commented Jan 8, 2016

Fix in apple/swift.git 9cf84c2.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jan 8, 2016

Comment by Michael Henson (JIRA)

What's the standard practice for bug report titles that turn out to be inaccurate? Should I update it or leave it as-is?

@atrick
Copy link
Member

atrick commented Jan 8, 2016

Good question. I probably should have changed the title before committing and cross referencing the bug. I left it as-is because that was the symptom you observed.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 2.2
Projects
None yet
Development

No branches or pull requests

6 participants