|
| 1 | +let _swift_MinAllocationAlignment: UInt = 16 |
| 2 | + |
| 3 | +@_silgen_name("posix_memalign") |
| 4 | +func posix_memalign(_: UnsafeMutablePointer<UnsafeMutableRawPointer?>, _: UInt, _: UInt) -> CInt |
| 5 | + |
| 6 | +@_silgen_name("free") |
| 7 | +func free(_: UnsafeMutableRawPointer?) |
| 8 | + |
| 9 | +func alignedAlloc(size: UInt, alignment: UInt) -> UnsafeMutableRawPointer? { |
| 10 | + let alignment = max(alignment, UInt(MemoryLayout<UnsafeRawPointer>.size)) |
| 11 | + var r: UnsafeMutableRawPointer? = nil |
| 12 | + _ = posix_memalign(&r, alignment, size) |
| 13 | + return r |
| 14 | +} |
| 15 | + |
| 16 | +/// Public APIs |
| 17 | +// void *swift_slowAlloc(size_t size, size_t alignMask); |
| 18 | +@_cdecl("swift_slowAlloc") |
| 19 | +public func swift_slowAlloc(_ size: UInt, _ alignMask: UInt) -> UnsafeMutableRawPointer? { |
| 20 | + let alignment: UInt |
| 21 | + if alignMask == UInt.max { |
| 22 | + alignment = _swift_MinAllocationAlignment |
| 23 | + } else { |
| 24 | + alignment = alignMask + 1 |
| 25 | + } |
| 26 | + return alignedAlloc(size: size, alignment: alignment) |
| 27 | +} |
| 28 | + |
| 29 | +// void swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask); |
| 30 | +@_cdecl("swift_slowDealloc") |
| 31 | +public func swift_slowDealloc(_ ptr: UnsafeMutableRawPointer?, _ size: UInt, _ alignMask: UInt) { |
| 32 | + free(ptr) |
| 33 | +} |
| 34 | + |
| 35 | +@_silgen_name("swift_allocObject") |
| 36 | +public func swift_allocObject(metadata: UnsafeMutableRawPointer, requiredSize: UInt, requiredAlignmentMask: UInt) -> UnsafeMutablePointer<HeapObject> { |
| 37 | + let p = swift_slowAlloc(requiredSize, requiredAlignmentMask)! |
| 38 | + let object = p.assumingMemoryBound(to: HeapObject.self) |
| 39 | + object.pointee.metadata = metadata |
| 40 | + object.pointee.refcount = 1 |
| 41 | + return object |
| 42 | +} |
| 43 | + |
| 44 | +@_silgen_name("swift_deallocClassInstance") |
| 45 | +public func swift_deallocClassInstance(object: UnsafeMutablePointer<HeapObject>, allocatedSize: UInt, allocatedAlignMask: UInt) { |
| 46 | + free(object) |
| 47 | +} |
| 48 | + |
| 49 | +@_silgen_name("swift_initStackObject") |
| 50 | +public func swift_initStackObject(metadata: UnsafeMutableRawPointer, object: UnsafeMutablePointer<HeapObject>) -> UnsafeMutablePointer<HeapObject> { |
| 51 | + object.pointee.metadata = metadata |
| 52 | + object.pointee.refcount = -1 |
| 53 | + return object |
| 54 | +} |
| 55 | + |
| 56 | +@_silgen_name("swift_isUniquelyReferenced_nonNull_native") |
| 57 | +public func swift_isUniquelyReferenced_nonNull_native(object: UnsafeMutablePointer<HeapObject>) -> Bool { |
| 58 | + return object.pointee.refcount == 1 |
| 59 | +} |
| 60 | + |
| 61 | +public struct HeapObject { |
| 62 | + var metadata: UnsafeMutableRawPointer |
| 63 | + var refcount: Int |
| 64 | +} |
| 65 | + |
| 66 | +@_silgen_name("swift_retain") |
| 67 | +public func swift_retain(object: UnsafeMutablePointer<HeapObject>) -> UnsafeMutablePointer<HeapObject> { |
| 68 | + if object.pointee.refcount == -1 { return object } |
| 69 | + object.pointee.refcount += 1 |
| 70 | + return object |
| 71 | +} |
| 72 | + |
| 73 | +@_silgen_name("swift_release") |
| 74 | +public func swift_release(object: UnsafeMutablePointer<HeapObject>) { |
| 75 | + if object.pointee.refcount == -1 { return } |
| 76 | + object.pointee.refcount -= 1 |
| 77 | + if object.pointee.refcount == 0 { |
| 78 | + free(object) |
| 79 | + } |
| 80 | +} |
0 commit comments