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-8526] Memory leak after switch in release configuration #51046

Closed
swift-ci opened this issue Aug 13, 2018 · 3 comments
Closed

[SR-8526] Memory leak after switch in release configuration #51046

swift-ci opened this issue Aug 13, 2018 · 3 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself memory leak bug: Memory leak optimized only Flag: An issue whose reproduction requires optimized compilation

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-8526
Radar rdar://problem/43888666
Original Reporter rermolov (JIRA User)
Type Bug
Status Closed
Resolution Done
Environment

Xcode 9.4.1 (9F2000), Xcode 10.0 beta 5 (10L221o)

Swift 4.1/Swift 4.2, Release configuration

iPhone X iOS 11.4 / iPhone X Simulator 12.0

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

md5: 78345c898f38d78fa1941b37f88392e2

Issue Description:

What I do:

build code below in Release configuration:

final class Subject {
  init() {
    print("subject init")
  }
  deinit {
    print("!!! subject deinit")
  }
}

final class Holder {
  private let objects: [Subject]
  init(objects: [Subject]) {
    self.objects = objects
  }
}

enum Content {
  case empty
  case withSubject(Subject)
}

final class Graph {
  private let holder: Holder

  init(content: Content) {
    let s: Subject
    switch content {
    case .empty:
      s = Subject()
    case let .withSubject(subject):
      s = subject
    }
    holder = Holder(objects: [s])
    if true {
      print(content)
    }
  }
}

func test() {
  print(Graph(content: .empty))
}

What I expect:

Subject is deallocated eventually

What I receive:

Subject is not deallocated. It seems that the problem is in switch + array + if statement: changing any part of this fixes the problem.

Possible workarounds:

1) Extracting switch to extension of Content

2) Making additional init in Holder, that receives only one Subject

3) Extracting if statement to function with content as argument

@belkadan
Copy link
Contributor

@swift-ci create

@atrick
Copy link
Member

atrick commented Sep 1, 2018

As a build-level workaround, you can add this to your swiftc options (Other Swift Flags):

-Xllvm -enable-destroyhoisting=false

@atrick
Copy link
Member

atrick commented Sep 1, 2018

PR: [Fix a bug in CopyForwarding. Bailout during destoy hoisting. #19103](#19103

Once the algorithm has begun hoisting destroys globally, there's no
way to cleanly bailout. The previous attempt to bailout could result
in an assert or lost destroy in release mode.

This is continued fall-out from changes in the previous release to
upstream SILGen or mandatory passes, such as PredictableMemOps, that
no longer preserve natural variable lifetimes.

In this case, we end up with SIL like this before CopyForwarding:

bb(%arg)
%local_addr = alloc_stack
store %arg to %local_addr
%payload = switch_enum(%arg)
retain %arg
store %arg to %some_addr
destroy_addr %local_addr
release_value %arg

We're attempting to hoist the destroy_addr to its last use, but can't
because the lifetimes of the alloc_stack (%local_addr) and the value
being stored on the stack (%arg) have become mixed up by an upstream
pass. We actually detect this situation now in order to bail-out of
destroy hoisting. Sadly, the bailout might only partially recover in
the case of interesting control flow, as happens in the test case's
Graph.init function. This triggers an assert, but in release mode it
simply drops the destroy.

@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 memory leak bug: Memory leak optimized only Flag: An issue whose reproduction requires optimized compilation
Projects
None yet
Development

No branches or pull requests

3 participants