Skip to content

Commit 65b2269

Browse files
authored
Merge pull request #15770 from dcci/refcount-obj
2 parents e74f2a6 + c850bfd commit 65b2269

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

include/swift/Runtime/HeapObject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ SWIFT_RUNTIME_EXPORT
231231
size_t swift_retainCount(HeapObject *object);
232232
SWIFT_RUNTIME_EXPORT
233233
size_t swift_unownedRetainCount(HeapObject *object);
234+
SWIFT_RUNTIME_EXPORT
235+
size_t swift_weakRetainCount(HeapObject *object);
234236

235237
/// Is this pointer a non-null unique reference to an object
236238
/// that uses Swift reference counting?

stdlib/public/SwiftShims/HeapObject.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define SWIFT_STDLIB_SHIMS_HEAPOBJECT_H
1414

1515
#include "RefCount.h"
16+
#include "SwiftStddef.h"
1617
#include "System.h"
1718

1819
#define SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_64 16
@@ -30,6 +31,7 @@ template <typename Target> struct TargetHeapMetadata;
3031
using HeapMetadata = TargetHeapMetadata<InProcess>;
3132
#else
3233
typedef struct HeapMetadata HeapMetadata;
34+
typedef struct HeapObject HeapObject;
3335
#endif
3436

3537
// The members of the HeapObject header that are not shared by a
@@ -69,6 +71,15 @@ SWIFT_RUNTIME_STDLIB_INTERFACE
6971
void _swift_instantiateInertHeapObject(void *address,
7072
const HeapMetadata *metadata);
7173

74+
SWIFT_RUNTIME_STDLIB_INTERFACE
75+
__swift_size_t swift_retainCount(HeapObject *obj);
76+
77+
SWIFT_RUNTIME_STDLIB_INTERFACE
78+
__swift_size_t swift_unownedRetainCount(HeapObject *obj);
79+
80+
SWIFT_RUNTIME_STDLIB_INTERFACE
81+
__swift_size_t swift_weakRetainCount(HeapObject *obj);
82+
7283
#ifdef __cplusplus
7384
} // extern "C"
7485
#endif

stdlib/public/core/DebuggerSupport.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import SwiftShims
14+
1315
@_frozen // FIXME(sil-serialize-all)
1416
public enum _DebuggerSupport {
1517
@_frozen // FIXME(sil-serialize-all)
@@ -335,3 +337,11 @@ func _stringForPrintObject(_ value: Any) -> String {
335337
public
336338
func _debuggerTestingCheckExpect(_ checked_value: String,
337339
_ expected_value: String) {}
340+
341+
// Utilities to get refcount(s) of class objects.
342+
@_silgen_name("swift_retainCount")
343+
public func _getRetainCount(_ Value: AnyObject) -> UInt
344+
@_silgen_name("swift_unownedRetainCount")
345+
public func _getUnownedRetainCount(_ Value : AnyObject) -> UInt
346+
@_silgen_name("swift_weakRetainCount")
347+
public func _getWeakRetainCount(_ Value : AnyObject) -> UInt

stdlib/public/runtime/HeapObject.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ size_t swift::swift_unownedRetainCount(HeapObject *object) {
372372
return object->refCounts.getUnownedCount();
373373
}
374374

375+
size_t swift::swift_weakRetainCount(HeapObject *object) {
376+
return object->refCounts.getWeakCount();
377+
}
378+
375379
HeapObject *swift::swift_unownedRetain(HeapObject *object) {
376380
SWIFT_RT_TRACK_INVOCATION(object, swift_unownedRetain);
377381
if (!isValidPointerForNativeRetain(object))

test/stdlib/DebuggerSupport.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-run-simple-swift
22
// REQUIRES: executable_test
3+
// REQUIRES: optimized_stdlib
34

45
import StdlibUnittest
56

@@ -99,4 +100,31 @@ StringForPrintObjectTests.test("DontBridgeThisStruct") {
99100
}
100101
#endif
101102

103+
class RefCountedObj {
104+
var patatino : Int
105+
init(_ p : Int) {
106+
self.patatino = p
107+
}
108+
public func f() -> Int {
109+
return self.patatino
110+
}
111+
}
112+
113+
let RefcountTests = TestSuite("RefCount")
114+
RefcountTests.test("Basic") {
115+
var Obj = RefCountedObj(47);
116+
117+
// Counters for live objects should be always positive.
118+
// We try to be a little bit more lax here because optimizations
119+
// or different stdlib versions might impact the exact value of
120+
// refcounting, and we're just interested in testing whether the
121+
// stub works properly.
122+
expectGT(_getRetainCount(Obj), 0);
123+
expectGT(_getWeakRetainCount(Obj), 0);
124+
expectGT(_getUnownedRetainCount(Obj), 0);
125+
126+
// Try to keep the object live here.
127+
let _ = Obj.f()
128+
}
129+
102130
runAllTests()

0 commit comments

Comments
 (0)