Skip to content

Commit

Permalink
IRGen: Always use Swift reference counting when Obj-C interop is not …
Browse files Browse the repository at this point in the history
…available

The swift_unknown* entry points are not available on the Linux port.
Previously we would still attempt to use them in a couple of cases:

1) Foreign classes
2) Existentials and archetypes
3) Optionals of boxed existentials

Note that this patch changes IRGen to never emit the
swift_errorRelease/Retain entry points on Linux. We would like to
use them in the future if we ever adopt a tagged-pointer representation
for small errors. In this case, they can be brought back, and the
TypeInfo for optionals will need to be generalized to propagate the
reference counting of the payload type, instead of defaulting to
unknown if the payload type is not natively reference counted.
A similar change will need to be made to support blocks, if we ever
want to use the blocks runtime on Linux.

Fixes <rdar://problem/23335318>, <rdar://problem/23335537>,
<rdar://problem/23335453>.
  • Loading branch information
slavapestov committed Nov 3, 2015
1 parent 6402411 commit 3d19691
Show file tree
Hide file tree
Showing 18 changed files with 480 additions and 246 deletions.
18 changes: 12 additions & 6 deletions lib/IRGen/GenArchetype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ class OpaqueArchetypeTypeInfo
/// A type implementation for a class archetype, that is, an archetype
/// bounded by a class protocol constraint. These archetypes can be
/// represented by a refcounted pointer instead of an opaque value buffer.
/// We use an unknown-refcounted pointer in order to allow ObjC or Swift
/// classes to conform to the type variable.
/// If ObjC interop is disabled, we can use Swift refcounting entry
/// points, otherwise we have to use the unknown ones.
class ClassArchetypeTypeInfo
: public HeapTypeInfo<ClassArchetypeTypeInfo>,
public ArchetypeTypeInfoBase
Expand Down Expand Up @@ -314,10 +314,16 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
// If the archetype is class-constrained, use a class pointer
// representation.
if (archetype->requiresClass()) {
// Fully general archetypes can't be assumed to have any particular
// refcounting scheme.
ReferenceCounting refcount = ReferenceCounting::Unknown;
llvm::PointerType *reprTy = IGM.UnknownRefCountedPtrTy;
ReferenceCounting refcount;
llvm::PointerType *reprTy;

if (!IGM.ObjCInterop) {
refcount = ReferenceCounting::Native;
reprTy = IGM.RefCountedPtrTy;
} else {
refcount = ReferenceCounting::Unknown;
reprTy = IGM.UnknownRefCountedPtrTy;
}

// If the archetype has a superclass constraint, it has at least the
// retain semantics of its superclass, and it can be represented with
Expand Down
5 changes: 5 additions & 0 deletions lib/IRGen/GenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,15 @@ static ClassDecl *getRootClass(ClassDecl *theClass) {
/// What reference counting mechanism does a class have?
ReferenceCounting irgen::getReferenceCountingForClass(IRGenModule &IGM,
ClassDecl *theClass) {
// If ObjC interop is disabled, we have a Swift refcount.
if (!IGM.ObjCInterop)
return ReferenceCounting::Native;

// If the root class is implemented in swift, then we have a swift
// refcount; otherwise, we have an ObjC refcount.
if (hasKnownSwiftImplementation(IGM, getRootClass(theClass)))
return ReferenceCounting::Native;

return ReferenceCounting::ObjC;
}

Expand Down
Loading

0 comments on commit 3d19691

Please sign in to comment.