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-426] Memory leak with enum containing class, downcast to Any.Type #43043

Closed
swift-ci opened this issue Dec 31, 2015 · 11 comments
Closed

[SR-426] Memory leak with enum containing class, downcast to Any.Type #43043

swift-ci opened this issue Dec 31, 2015 · 11 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. non-optimized only Flag: An issue whose reproduction requires non-optimized compilation runtime The Swift Runtime standard library Area: Standard library umbrella

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-426
Radar None
Original Reporter austin (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Building on OS X 10.11.2, revision 73872e5.

Additional Detail from JIRA
Votes 0
Component/s Standard Library
Labels Bug, NotOptimizedOnly, Runtime
Assignee jder (JIRA)
Priority Medium

md5: 66dcf74255f01d0bc1c3c7eded17fdfe

blocks:

  • SR-88 Remove old mirrors

Issue Description:

The following code appears to produce a memory leak. When it is run, the relevant class's `deinit` is never called:

class BasicClass {
    let a : Int
    init(_ a: Int) {
        print("BasicClass being init'ed with value \(a)")
        self.a = a
    }

    deinit {
        print("BasicClass being deinit'ed with value \(a)")
    }
}

enum Bar<T> {
    case First(T)
}

enum Baz<T, U> {
    case First(T), Second(U), Third, Fourth
}

func doSomething() {
    let myThing : Any = Bar.First(BasicClass(10))
    // bad behavior also happens with multi-payload generic enums
    // bad behavior also happens with a tuple, like "(1, 2, BasicClass(10))"
    // bad behavior does not happen with just a bare "BasicClass(10)"

    // A: 
    if let foo = myThing as? Any.Type {
        print("myThing is a metatype")
    }
}

doSomething()

In particular, the thing that causes trouble is the conditional downcast to Any.Type (marked by the comment 'A'). If the if-let statement is removed, the init and deinit run properly. If the if-let statement is present, only the init runs properly.

A downcast to a non-metatype seems to work fine. I have not tried downcasting to other metatypes.

@gottesmm
Copy link
Member

Is this with optimization or not?

@swift-ci
Copy link
Collaborator Author

Comment by Austin Zheng (JIRA)

This appears to happen with or without optimization; I tried -Onone, -O, and -Ounchecked.

@gottesmm
Copy link
Member

Thanks!

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jan 2, 2016

Comment by Jesse Rusak (JIRA)

Looks to me like the problem is that _dynamicCastToExistentialMetatype doesn't respect the DestroyOnFailure flag in the failure case for Tuples, Structs, Enums, etc. It does handle it for classes, which is why just the bare BaseClass works.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jan 2, 2016

Comment by Jesse Rusak (JIRA)

I've put up a PR for this: #857

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jan 9, 2016

Comment by Jesse Rusak (JIRA)

Fix merged in f91dd6f

@swift-ci
Copy link
Collaborator Author

Comment by Austin Zheng (JIRA)

I'm running Swift off revision 19b4be7, and still seeing the 'deinit not called' behavior with my code example. I'm re-opening this ticket; would someone be willing to attempt to reproduce on their build? (The code snippet can be run from 'swift' verbatim.)

Interestingly enough, the new unit test doesn't seem to trigger a test failure when the test suite is run. However, when I run the code in the test case manually, the test class also does not run its deinit properly.

Let me know if you have any questions.

@swift-ci
Copy link
Collaborator Author

Comment by Jesse Rusak (JIRA)

I just tried with the latest master (0d96017) and the revision you mentioned and the code snippet above produces for me:

BasicClass being init'ed with value 10
BasicClass being deinit'ed with value 10

The exact steps I took (for the latest master) were:

cd swift
./utils/update-checkout -a
./utils/build-script
../build/Ninja-DebugAssert/swift-macosx-x86_64/bin/swift test.swift

Where test.swift has your example content above. Not sure what the reason for the discrepancy is; how exactly are you reproducing the issue?

@swift-ci
Copy link
Collaborator Author

Comment by Austin Zheng (JIRA)

Hi Jesse,

Apologies for the delayed response. I updated my dependencies manually and built Swift from source. I'm going to use the update script, which is probably doing something my manual update procedure is missing, and see if I can reproduce the bad behavior tonight.

@swift-ci
Copy link
Collaborator Author

Comment by Jesse Rusak (JIRA)

Yes, do let me know if that resolves your issue. I also could have something stale I need to clean out locally. Are you testing on OS X and in debug?

@swift-ci
Copy link
Collaborator Author

Comment by Austin Zheng (JIRA)

I just rebuilt Swift using update-checkout, it works fine now. I was indeed on OS X/debug.

I'm closing this ticket now.

@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. non-optimized only Flag: An issue whose reproduction requires non-optimized compilation runtime The Swift Runtime standard library Area: Standard library umbrella
Projects
None yet
Development

No branches or pull requests

2 participants