mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
runtime lib: a mechanism to set an "immutable" flag on an object for COW buffer runtime checking.
In an assert built of the library, store an extra boolean flag (isImmutable) in the object side-buffer table. This flag can be set and get by the Array implementation to sanity check the immutability status of the buffer object.
This commit is contained in:
@@ -1271,6 +1271,11 @@ class RefCounts {
|
||||
// Note that this is not equal to the number of outstanding weak pointers.
|
||||
uint32_t getWeakCount() const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool isImmutableCOWBuffer();
|
||||
bool setIsImmutableCOWBuffer(bool immutable);
|
||||
#endif
|
||||
|
||||
// DO NOT TOUCH.
|
||||
// This exists for the benefits of the Refcounting.cpp tests. Do not use it
|
||||
// elsewhere.
|
||||
@@ -1301,6 +1306,11 @@ class HeapObjectSideTableEntry {
|
||||
std::atomic<HeapObject*> object;
|
||||
SideTableRefCounts refCounts;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Used for runtime consistency checking of COW buffers.
|
||||
bool immutableCOWBuffer = false;
|
||||
#endif
|
||||
|
||||
public:
|
||||
HeapObjectSideTableEntry(HeapObject *newObject)
|
||||
: object(newObject), refCounts()
|
||||
@@ -1455,6 +1465,16 @@ class HeapObjectSideTableEntry {
|
||||
void *getSideTable() {
|
||||
return refCounts.getSideTable();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool isImmutableCOWBuffer() const {
|
||||
return immutableCOWBuffer;
|
||||
}
|
||||
|
||||
void setIsImmutableCOWBuffer(bool immutable) {
|
||||
immutableCOWBuffer = immutable;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -345,6 +345,16 @@ internal func _class_getInstancePositiveExtentSize(_ theClass: AnyClass) -> Int
|
||||
#endif
|
||||
}
|
||||
|
||||
#if INTERNAL_CHECKS_ENABLED
|
||||
@usableFromInline
|
||||
@_silgen_name("_swift_isImmutableCOWBuffer")
|
||||
internal func _swift_isImmutableCOWBuffer(_ object: AnyObject) -> Bool
|
||||
|
||||
@usableFromInline
|
||||
@_silgen_name("_swift_setImmutableCOWBuffer")
|
||||
internal func _swift_setImmutableCOWBuffer(_ object: AnyObject, _ immutable: Bool) -> Bool
|
||||
#endif
|
||||
|
||||
@inlinable
|
||||
internal func _isValidAddress(_ address: UInt) -> Bool {
|
||||
// TODO: define (and use) ABI max valid pointer value
|
||||
|
||||
@@ -887,6 +887,23 @@ WeakReference *swift::swift_weakTakeAssign(WeakReference *dest,
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
/// Returns true if the "immutable" flag is set on \p object.
|
||||
///
|
||||
/// Used for runtime consistency checking of COW buffers.
|
||||
SWIFT_RUNTIME_EXPORT
|
||||
bool _swift_isImmutableCOWBuffer(HeapObject *object) {
|
||||
return object->refCounts.isImmutableCOWBuffer();
|
||||
}
|
||||
|
||||
/// Sets the "immutable" flag on \p object to \p immutable and returns the old
|
||||
/// value of the flag.
|
||||
///
|
||||
/// Used for runtime consistency checking of COW buffers.
|
||||
SWIFT_RUNTIME_EXPORT
|
||||
bool _swift_setImmutableCOWBuffer(HeapObject *object, bool immutable) {
|
||||
return object->refCounts.setIsImmutableCOWBuffer(immutable);
|
||||
}
|
||||
|
||||
void HeapObject::dump() const {
|
||||
auto *Self = const_cast<HeapObject *>(this);
|
||||
printf("HeapObject: %p\n", Self);
|
||||
|
||||
@@ -156,6 +156,28 @@ void _swift_stdlib_immortalize(void *obj) {
|
||||
heapObj->refCounts.setIsImmortal(true);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
// SideTableRefCountBits specialization intentionally does not exist.
|
||||
template <>
|
||||
bool RefCounts<InlineRefCountBits>::isImmutableCOWBuffer() {
|
||||
if (!hasSideTable())
|
||||
return false;
|
||||
HeapObjectSideTableEntry *sideTable = allocateSideTable(false);
|
||||
assert(sideTable);
|
||||
return sideTable->isImmutableCOWBuffer();
|
||||
}
|
||||
|
||||
template <>
|
||||
bool RefCounts<InlineRefCountBits>::setIsImmutableCOWBuffer(bool immutable) {
|
||||
HeapObjectSideTableEntry *sideTable = allocateSideTable(false);
|
||||
assert(sideTable);
|
||||
bool oldValue = sideTable->isImmutableCOWBuffer();
|
||||
sideTable->setIsImmutableCOWBuffer(immutable);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// namespace swift
|
||||
} // namespace swift
|
||||
|
||||
|
||||
Reference in New Issue
Block a user