Skip to content

Commit 2e72cf3

Browse files
authored
Merge pull request #3063 from drexin/wip-immortal-constants
Make constants immortal
2 parents b344e37 + 1a3b9a3 commit 2e72cf3

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

CoreFoundation/Base.subproj/CFBase.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,11 @@ CFTypeRef CFMakeCollectable(CFTypeRef cf) CF_AUTOMATED_REFCOUNT_UNAVAILABLE;
686686

687687
#if DEPLOYMENT_RUNTIME_SWIFT
688688

689-
#define _CF_SWIFT_RC_PINNED_FLAG (0x1)
689+
#if TARGET_RT_64_BIT
690+
#define _CF_SWIFT_RC_PINNED_FLAG (0x80000004ffffffff)
691+
#else
692+
#define _CF_SWIFT_RC_PINNED_FLAG (0x800004FF)
693+
#endif
690694
#define _CF_CONSTANT_OBJECT_STRONG_RC ((uintptr_t)_CF_SWIFT_RC_PINNED_FLAG)
691695
#endif
692696

Tests/Foundation/Tests/TestBridging.swift

+29
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class TestBridging : XCTestCase {
2727
return [
2828
("testBridgedDescription", testBridgedDescription),
2929
("testDynamicCast", testDynamicCast),
30+
("testConstantsImmortal", testConstantsImmortal),
3031
]
3132
}
3233

@@ -70,4 +71,32 @@ class TestBridging : XCTestCase {
7071
let anyArray: Any = [TestClass()]
7172
XCTAssertNotNil(anyArray as? NSObject)
7273
}
74+
75+
func testConstantsImmortal() throws {
76+
func release(_ ptr: UnsafeRawPointer, count: Int) {
77+
let object: Unmanaged<NSNumber> = Unmanaged.fromOpaque(ptr)
78+
for _ in 0..<count {
79+
object.release()
80+
}
81+
}
82+
83+
let trueConstant = NSNumber(value: true)
84+
let falseConstant = NSNumber(value: false)
85+
86+
// To accurately read the whole refcount, we need to read the second
87+
// word of the pointer.
88+
let truePtr = unsafeBitCast(trueConstant, to: UnsafePointer<Int>.self)
89+
let falsePtr = unsafeBitCast(falseConstant, to: UnsafePointer<Int>.self)
90+
91+
let trueRefCount = truePtr.advanced(by: 1).pointee
92+
let falseRefCount = falsePtr.advanced(by: 1).pointee
93+
94+
XCTAssertEqual(trueRefCount, falseRefCount)
95+
96+
release(truePtr, count: 5)
97+
release(falsePtr, count: 5)
98+
99+
XCTAssertEqual(trueRefCount, truePtr.advanced(by: 1).pointee)
100+
XCTAssertEqual(falseRefCount, falsePtr.advanced(by: 1).pointee)
101+
}
73102
}

0 commit comments

Comments
 (0)