Runtime: Work around rdar://problem/18950072 to avoid paying for .cxx_destruct on Swift objects.

Clang overzealously infects SwiftObject with the HasCXXStructors bit because it contained a struct (with trivial constructor). Manually explode the struct to avoid this.

Swift SVN r23259
This commit is contained in:
Joe Groff
2014-11-12 02:30:31 +00:00
parent 4244c45f37
commit b50293b26a
2 changed files with 45 additions and 1 deletions

View File

@@ -83,11 +83,22 @@ struct SwiftObject_s {
long refCount __attribute__((unavailable));
};
static_assert(std::is_trivially_constructible<SwiftObject_s>::value,
"SwiftObject must be trivially constructible");
static_assert(std::is_trivially_destructible<SwiftObject_s>::value,
"SwiftObject must be trivially destructible");
#if __has_attribute(objc_root_class)
__attribute__((objc_root_class))
#endif
@interface SwiftObject<NSObject> {
SwiftObject_s magic;
// FIXME: rdar://problem/18950072 Clang emits ObjC++ classes as having
// non-trivial structors if they contain any struct fields at all, regardless of
// whether they in fact have nontrivial default constructors. Dupe the body
// of SwiftObject_s into here as a workaround because we don't want to pay
// the cost of .cxx_destruct method dispatch at deallocation time.
void *magic_isa __attribute__((unavailable));
long magic_refCount __attribute__((unavailable));
}
- (BOOL)isEqual:(id)object;

View File

@@ -216,3 +216,36 @@ println("done ValueLike hashValue")
// CHECK-NEXT: sh2 20
// CHECK-NEXT: sh3 10
// CHECK-NEXT: done ValueLike hashValue
// Native Swift objects should not have nontrivial structors from ObjC's point
// of view.
class NativeSwift {}
class GenericNativeSwift<T> {}
var native: AnyObject = NativeSwift()
if native.respondsToSelector(".cxx_construct") {
println("SwiftObject has nontrivial constructor")
} else {
println("no nontrivial constructor") // CHECK-NEXT: no nontrivial constructor
}
if native.respondsToSelector(".cxx_destruct") {
println("SwiftObject has nontrivial destructor")
} else {
println("no nontrivial destructor") // CHECK-NEXT: no nontrivial destructor
}
native = GenericNativeSwift<Int>()
if native.respondsToSelector(".cxx_construct") {
println("SwiftObject has nontrivial constructor")
} else {
println("no nontrivial constructor") // CHECK-NEXT: no nontrivial constructor
}
if native.respondsToSelector(".cxx_destruct") {
println("SwiftObject has nontrivial destructor")
} else {
println("no nontrivial destructor") // CHECK-NEXT: no nontrivial destructor
}