Skip to content

Commit 149e8e4

Browse files
authored
Merge pull request #67600 from drexin/release/5.9
[5.9][Runtime] Fix _swift_refCountBytesForMetatype for reference types
2 parents 4ac22d8 + 8c7c7fb commit 149e8e4

File tree

5 files changed

+77
-1
lines changed

5 files changed

+77
-1
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2734,7 +2734,18 @@ void swift::swift_initStructMetadataWithLayoutString(
27342734
} else if (fieldType->hasLayoutString()) {
27352735
refCountBytes += *(const size_t *)(fieldType->getLayoutString() +
27362736
sizeof(uint64_t));
2737-
} else if (fieldType->isClassObject() || fieldType->isAnyExistentialType()) {
2737+
} else if (auto *cls = fieldType->getClassObject()) {
2738+
if (cls->isTypeMetadata()) {
2739+
auto *vwt = cls->getValueWitnesses();
2740+
if (vwt != &VALUE_WITNESS_SYM(Bo) &&
2741+
vwt != &VALUE_WITNESS_SYM(BO) &&
2742+
vwt != &VALUE_WITNESS_SYM(Bb)) {
2743+
refCountBytes += sizeof(uint64_t) + sizeof(uintptr_t);
2744+
continue;
2745+
}
2746+
}
2747+
refCountBytes += sizeof(uint64_t);
2748+
} else if (fieldType->isAnyExistentialType()) {
27382749
refCountBytes += sizeof(uint64_t);
27392750
} else {
27402751
refCountBytes += sizeof(uint64_t) + sizeof(uintptr_t);

test/Interpreter/Inputs/ObjCClasses/ObjCClasses.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ __attribute__((swift_name("OuterType.InnerType")))
118118
@property NSArray<OuterType *> *things;
119119
@end
120120

121+
@interface ObjCPrintOnDealloc : NSObject
122+
@end
123+
121124
NS_ASSUME_NONNULL_END
122125

123126
#endif

test/Interpreter/Inputs/ObjCClasses/ObjCClasses.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,9 @@ - (id)init {
191191
}
192192

193193
@end
194+
195+
@implementation ObjCPrintOnDealloc
196+
- (void)dealloc {
197+
printf("ObjCPrintOnDealloc deinitialized!\n");
198+
}
199+
@end

test/Interpreter/Inputs/layout_string_witnesses_types.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,16 @@ public struct Wrapper<T> {
271271
}
272272
}
273273

274+
public struct NestedWrapper<T> {
275+
public let x: Wrapper<T>
276+
public let y: Wrapper<T>
277+
278+
public init(x: Wrapper<T>, y: Wrapper<T>) {
279+
self.x = x
280+
self.y = y
281+
}
282+
}
283+
274284
struct InternalGeneric<T> {
275285
let x: T
276286
let y: Int
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %empty-directory(%t)
2+
//
3+
// RUN: %target-clang -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o
4+
// RUN: %target-swift-frontend -prespecialize-generic-metadata -enable-experimental-feature LayoutStringValueWitnesses -enable-experimental-feature LayoutStringValueWitnessesInstantiation -enable-layout-string-value-witnesses -enable-layout-string-value-witnesses-instantiation -enable-type-layout -enable-autolinking-runtime-compatibility-bytecode-layouts -parse-stdlib -emit-module -emit-module-path=%t/layout_string_witnesses_types.swiftmodule %S/Inputs/layout_string_witnesses_types.swift
5+
// RUN: %target-build-swift-dylib(%t/%target-library-name(layout_string_witnesses_types)) -Xfrontend -enable-experimental-feature -Xfrontend LayoutStringValueWitnesses -Xfrontend -enable-experimental-feature -Xfrontend LayoutStringValueWitnessesInstantiation -Xfrontend -enable-layout-string-value-witnesses -Xfrontend -enable-layout-string-value-witnesses-instantiation -Xfrontend -enable-type-layout -Xfrontend -parse-stdlib -parse-as-library %S/Inputs/layout_string_witnesses_types.swift
6+
// RUN: %target-build-swift -g -Xfrontend -enable-experimental-feature -Xfrontend LayoutStringValueWitnesses -Xfrontend -enable-experimental-feature -Xfrontend LayoutStringValueWitnessesInstantiation -Xfrontend -enable-layout-string-value-witnesses -Xfrontend -enable-layout-string-value-witnesses-instantiation -Xfrontend -enable-type-layout -parse-stdlib -module-name layout_string_witnesses_dynamic -llayout_string_witnesses_types -L%t -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o -I %t -o %t/main %s %target-rpath(%t)
7+
// RUN: %target-codesign %t/main
8+
// RUN: %target-run %t/main %t/%target-library-name(layout_string_witnesses_types) | %FileCheck %s --check-prefix=CHECK
9+
10+
// REQUIRES: executable_test
11+
// REQUIRES: objc_interop
12+
13+
import Swift
14+
import layout_string_witnesses_types
15+
import ObjCClasses
16+
import Foundation
17+
18+
func testNestedResilientObjc() {
19+
let ptr = allocateInternalGenericPtr(of: NestedWrapper<ObjCPrintOnDealloc>.self)
20+
21+
do {
22+
let x = NestedWrapper<ObjCPrintOnDealloc>(x: .init(x: ObjCPrintOnDealloc()), y: .init(x: ObjCPrintOnDealloc()))
23+
testGenericInit(ptr, to: x)
24+
}
25+
26+
do {
27+
let y = NestedWrapper<ObjCPrintOnDealloc>(x: .init(x: ObjCPrintOnDealloc()), y: .init(x: ObjCPrintOnDealloc()))
28+
// CHECK: Before deinit
29+
print("Before deinit")
30+
31+
// CHECK-NEXT: ObjCPrintOnDealloc deinitialized!
32+
// CHECK-NEXT: ObjCPrintOnDealloc deinitialized!
33+
testGenericAssign(ptr, from: y)
34+
}
35+
36+
// CHECK-NEXT: Before deinit
37+
print("Before deinit")
38+
39+
// CHECK-NEXT: ObjCPrintOnDealloc deinitialized!
40+
// CHECK-NEXT: ObjCPrintOnDealloc deinitialized!
41+
testGenericDestroy(ptr, of: NestedWrapper<ObjCPrintOnDealloc>.self)
42+
43+
ptr.deallocate()
44+
}
45+
46+
testNestedResilientObjc()

0 commit comments

Comments
 (0)