Skip to content

Commit b82ac6b

Browse files
authored
Merge pull request #67599 from drexin/wip-112474091
[Runtime] Fix _swift_refCountBytesForMetatype for reference types
2 parents 1d8cce5 + f257b3b commit b82ac6b

File tree

5 files changed

+78
-2
lines changed

5 files changed

+78
-2
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2785,15 +2785,26 @@ size_t swift::_swift_refCountBytesForMetatype(const Metadata *type) {
27852785
size_t offset = sizeof(uint64_t);
27862786
return LayoutStringReader{type->getLayoutString(), offset}
27872787
.readBytes<size_t>();
2788-
} else if (type->isClassObject() || type->isAnyExistentialType()) {
2789-
return sizeof(uint64_t);
27902788
} else if (auto *tuple = dyn_cast<TupleTypeMetadata>(type)) {
27912789
size_t res = 0;
27922790
for (InProcess::StoredSize i = 0; i < tuple->NumElements; i++) {
27932791
res += _swift_refCountBytesForMetatype(tuple->getElement(i).Type);
27942792
}
27952793
return res;
2794+
} else if (auto *cls = type->getClassObject()) {
2795+
if (cls->isTypeMetadata()) {
2796+
auto *vwt = cls->getValueWitnesses();
2797+
if (vwt != &VALUE_WITNESS_SYM(Bo) &&
2798+
vwt != &VALUE_WITNESS_SYM(BO) &&
2799+
vwt != &VALUE_WITNESS_SYM(Bb)) {
2800+
goto metadata;
2801+
}
2802+
}
2803+
return sizeof(uint64_t);
2804+
} else if (type->isAnyExistentialType()) {
2805+
return sizeof(uint64_t);
27962806
} else {
2807+
metadata:
27972808
return sizeof(uint64_t) + sizeof(uintptr_t);
27982809
}
27992810
}

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
@@ -276,6 +276,16 @@ public struct Wrapper<T> {
276276
}
277277
}
278278

279+
public struct NestedWrapper<T> {
280+
public let x: Wrapper<T>
281+
public let y: Wrapper<T>
282+
283+
public init(x: Wrapper<T>, y: Wrapper<T>) {
284+
self.x = x
285+
self.y = y
286+
}
287+
}
288+
279289
struct InternalGeneric<T> {
280290
let x: T
281291
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 -check-prefix=CHECK-%target-os
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-macosx: Before deinit
29+
print("Before deinit")
30+
31+
// CHECK-macosx-NEXT: ObjCPrintOnDealloc deinitialized!
32+
// CHECK-macosx-NEXT: ObjCPrintOnDealloc deinitialized!
33+
testGenericAssign(ptr, from: y)
34+
}
35+
36+
// CHECK-macosx-NEXT: Before deinit
37+
print("Before deinit")
38+
39+
// CHECK-macosx-NEXT: ObjCPrintOnDealloc deinitialized!
40+
// CHECK-macosx-NEXT: ObjCPrintOnDealloc deinitialized!
41+
testGenericDestroy(ptr, of: NestedWrapper<ObjCPrintOnDealloc>.self)
42+
43+
ptr.deallocate()
44+
}
45+
46+
testNestedResilientObjc()

0 commit comments

Comments
 (0)