Skip to content

[Runtime] Add ObjC support to isKnownUniquelyReferenced. #38309

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
merged 1 commit into from
Aug 2, 2021

Conversation

al45tair
Copy link
Contributor

@al45tair al45tair commented Jul 8, 2021

Add code to support detecting uniquely referenced Objective-C and Core Foundation objects.

rdar://47902425
rdar://66805490

@al45tair
Copy link
Contributor Author

al45tair commented Jul 8, 2021

@swift-ci Please smoke test

1 similar comment
@al45tair
Copy link
Contributor Author

al45tair commented Jul 9, 2021

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

al45tair commented Jul 9, 2021

@swift-ci Please clean smoke test

@al45tair al45tair force-pushed the problem/47902425 branch from cd623b6 to 6d58491 Compare July 9, 2021 17:48
@al45tair
Copy link
Contributor Author

al45tair commented Jul 9, 2021

@swift-ci Please clean smoke test

@al45tair al45tair force-pushed the problem/47902425 branch from 6d58491 to aad9abb Compare July 9, 2021 23:35
@al45tair
Copy link
Contributor Author

al45tair commented Jul 9, 2021

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test macOS platform

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test macOS platform

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

@beccadax
Copy link
Contributor

A quick glance at the "files changed" view here suggests your indentation settings aren't correct. Perhaps you've set your tabs to be two spaces wide, but you're still inserting tab characters instead of space characters.

@al45tair al45tair force-pushed the problem/47902425 branch 2 times, most recently from c0d242d to 5b65c67 Compare July 16, 2021 08:59
@al45tair
Copy link
Contributor Author

@beccadax Hmmm. I think my editor has picked up the indentation and changed the tab size to match. How annoying. I'll tinker with it. git-clang-format (which I just ran) should hopefully fix that, however.

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

2 similar comments
@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

Copy link
Contributor

@mikeash mikeash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Would be good to get a signoff from someone more familiar with IRGen for that part.

Copy link
Contributor

@aschwaighofer aschwaighofer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IRGen changes LGTM.

I have not audited the standard libraries uses of isUnique to make sure no assumptions are made about the buffer if it returns true i.e it might have checked whether the bridged object is unique and then if that is true assumed that the bridged object pointer points to a native object. We probably always track that separately through the is bridged bit in the pointer to the BridgedObject (_BridgeStorage.isNative) but I thought to point this out this might be a risk here.

@al45tair
Copy link
Contributor Author

I have not audited the standard libraries uses of isUnique to make sure no assumptions are made about the buffer if it returns true i.e it might have checked whether the bridged object is unique and then if that is true assumed that the bridged object pointer points to a native object. We probably always track that separately through the is bridged bit in the pointer to the BridgedObject (_BridgeStorage.isNative) but I thought to point this out this might be a risk here.

It's a good point. I had a look through and I don't think there's any problem with this (and all the tests pass too, which is a good sign). Do we have a standard library expert we can ask, just to confirm?

@aschwaighofer
Copy link
Contributor

I think we should audit that all uses are guarded by _BridgeStorage.isNative or the like when necessary. Which it sounds like you have done. @lorentey Do you have any concerns or know someone who might have?

@aschwaighofer
Copy link
Contributor

I wonder if there is a performance benefit now from changing the two conditions around in ArrayBuffer.swift:

  @inlinable                                                                    
  internal mutating func isUniquelyReferenced() -> Bool {                       
    if !_isClassOrObjCExistential(Element.self) {                               
      return _storage.isUniquelyReferencedUnflaggedNative()                     
    }                                                                           
    return _storage.isUniquelyReferencedNative() && _isNative  // <== swap conditions?               
   }  

_storage.isUniquelyReferencedNative calls isUnique which will go into the objc runtime to check for a unique count (right?) but we really don't care because of the second condition _isNative (which is just a bit we check on the buffer pointer).

@al45tair
Copy link
Contributor Author

@aschwaighofer Yes, those could be swapped. Also, BridgeStorage's isUniquelyReferencedNative() could maybe be renamed (since it will now return true for uniquely referenced Objective-C types). Not sure whether to do that in this PR, though?

@aschwaighofer
Copy link
Contributor

Follow-up is fine by me.

@al45tair
Copy link
Contributor Author

Hmmm. Looking at this more carefully, _isNative is true if the Element type is native, not if the buffer is native. That makes me worry about requestUniqueMutableBackingBuffer(), for instance. I need to look at this further and think about it.

@aschwaighofer
Copy link
Contributor

When the Element type is not a class (or objc existential) then we bridge eagerly (convert the element type at bridging time - no objc storage is used).
It only needs asks the buffer storage whether it is native if the element is a class like thing. On the !_isClassOrObjCExistential(Element.self) path the storage cannot be ObjC.

  @inlinable                                                                    
  internal var _isNative: Bool {                                                
    if !_isClassOrObjCExistential(Element.self) {                               
      return true  // <= We know statically this is never bridged so we can return true                                                             
    } else {                                                                    
      return _storage.isNative    <== Dynamically calls BridgeStorage.swift code to check  the storage                                            
    }                                                                           
  } 
//  - `Array<Element>` is like `ContiguousArray<Element>` when `Element` is not 
//    a reference type or an Objective-C existential.  Otherwise, it may use    
//    an `NSArray` bridged from Cocoa for storage.  

Add code to support detecting uniquely referenced Objective-C and Core
Foundation objects.

rdar://47902425
rdar://66805490
@al45tair
Copy link
Contributor Author

@swift-ci Please smoke test

@al45tair
Copy link
Contributor Author

al45tair commented Aug 2, 2021

@swift-ci Please test

@al45tair al45tair merged commit ad14730 into swiftlang:main Aug 2, 2021
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.

4 participants