Skip to content

DI: New way of modeling factory initializers #4225

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

Merged

Conversation

slavapestov
Copy link
Contributor

@slavapestov slavapestov commented Aug 11, 2016

No description provided.

@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test os x

@slavapestov slavapestov force-pushed the fix-protocol-extension-factory-init branch from 0b66783 to 729ae20 Compare August 12, 2016 02:29
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test os x

@slavapestov
Copy link
Contributor Author

slavapestov commented Aug 12, 2016

It appears that the dispatch overlay failure is related to rdar://27226313. I'll try to fix both bugs.

Previously, we were only able to detect factory initializers
dispatched through class_method. This didn't work for
factory initializers defined in protocol extensions.

The end result would be that we would strong_release an
uninitialized class instance, which could cause crashes.

Fix DI to correctly release the old instance using
dealloc_partial_ref instead.

Fixes <rdar://problem/27713221>.
I apologize in advance to @jrose-apple, who is not a fan
of this fix ;-)

In unoptimized builds, the convenience initializers on
DispatchQueue allocate and immediately deallocate an
instance of OS_dispatch_queue prior to calling the
C function that returns the "real" instance.

This is because we don't have a way to write user-defined
factory initializers yet; convenience initializers still
have an 'initializing' entry point that takes an existing
instance, which we have no choice but to throw away.

Unfortunately, when we perform the fake allocation, we
look up class metadata by calling the wrong Swift runtime
function, causing a crash when we send +allocWithZone:.

Fix this so that the metadata is accessed via a lookup
from the Objective-C runtime, instead of making a totally
fake 'foreign metadata' object -- it looks like there was
code for this already, it just wasn't used in all cases.

While getting metadata for a runtime-only class should be
rare, this feels like a real bug fix, to me.

Second, we would ultimately free the fake object by sending
-release, however OS_dispatch_queue has an override of
-dealloc which doesn't like to be called with a completely
uninitialized instance.

Here, I'm going to drop all pretense of sanity. The patch
just changes IRGen to lower the dealloc_partial_ref instruction
as a call to the object_dispose() Objective-C runtime function
when the class in question is a runtime-only class. This
frees the object without running -dealloc, which *happens*
to work for OS_dispatch_queue.

Fixes <rdar://problem/27226313>.
@slavapestov slavapestov force-pushed the fix-protocol-extension-factory-init branch from 729ae20 to c98ce0c Compare August 13, 2016 08:55
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test OS X

@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test os x

@slavapestov
Copy link
Contributor Author

@swift-ci Please test os x

1 similar comment
@slavapestov
Copy link
Contributor Author

@swift-ci Please test os x

@slavapestov slavapestov merged commit ccc2ff9 into swiftlang:master Aug 13, 2016
@slavapestov slavapestov deleted the fix-protocol-extension-factory-init branch August 19, 2016 05:21
kateinoigakukun pushed a commit that referenced this pull request Aug 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants