mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Pass an alignment mask during heap array allocation,
not an alignment value. Assert that various entrypoints get an alignment mask. Get everything uniformly passing an assertion about dealloating an object with the correct allocation size; don't actually enable the assertion yet, though. rdar://16989632 Swift SVN r18550
This commit is contained in:
@@ -229,7 +229,7 @@ HeapArrayInfo::Layout HeapArrayInfo::getLayout(IRGenFunction &IGF) const {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
IGF.IGM.getSize(headerSize),
|
IGF.IGM.getSize(headerSize),
|
||||||
IGF.IGM.getSize(headerAlign.asSize()),
|
IGF.IGM.getSize(headerAlign.asSize() - Size(1)),
|
||||||
headerAlign
|
headerAlign
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func c_malloc_size(heapMemory: UnsafePointer<Void>) -> Int
|
|||||||
deinit {
|
deinit {
|
||||||
Buffer(self)._value.destroy()
|
Buffer(self)._value.destroy()
|
||||||
}
|
}
|
||||||
@final func __getInstanceSizeAndAlignMask() -> (Int,Int) {
|
func __getInstanceSizeAndAlignMask() -> (Int,Int) {
|
||||||
return Buffer(self)._allocatedSizeAndAlignMask()
|
return Buffer(self)._allocatedSizeAndAlignMask()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1033,12 +1033,14 @@ void *swift::swift_tryAlloc(AllocIndex idx) {
|
|||||||
return _swift_tryAlloc(idx);
|
return _swift_tryAlloc(idx);
|
||||||
}
|
}
|
||||||
void *swift::swift_slowAlloc(size_t size, size_t alignMask, uintptr_t flags) {
|
void *swift::swift_slowAlloc(size_t size, size_t alignMask, uintptr_t flags) {
|
||||||
|
assert(isAlignmentMask(alignMask));
|
||||||
return _swift_slowAlloc(size, alignMask, flags);
|
return _swift_slowAlloc(size, alignMask, flags);
|
||||||
}
|
}
|
||||||
void swift::swift_dealloc(void *ptr, AllocIndex idx) {
|
void swift::swift_dealloc(void *ptr, AllocIndex idx) {
|
||||||
_swift_dealloc(ptr, idx);
|
_swift_dealloc(ptr, idx);
|
||||||
}
|
}
|
||||||
void swift::swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask) {
|
void swift::swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask) {
|
||||||
|
assert(isAlignmentMask(alignMask));
|
||||||
return _swift_slowDealloc(ptr, bytes, alignMask);
|
return _swift_slowDealloc(ptr, bytes, alignMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ swift::swift_allocObject(HeapMetadata const *metadata,
|
|||||||
static HeapObject *
|
static HeapObject *
|
||||||
_swift_allocObject_(HeapMetadata const *metadata, size_t requiredSize,
|
_swift_allocObject_(HeapMetadata const *metadata, size_t requiredSize,
|
||||||
size_t requiredAlignmentMask) {
|
size_t requiredAlignmentMask) {
|
||||||
|
assert(isAlignmentMask(requiredAlignmentMask));
|
||||||
// llvm::RoundUpToAlignment(size, mask + 1) generates terrible code
|
// llvm::RoundUpToAlignment(size, mask + 1) generates terrible code
|
||||||
auto size = (requiredSize + requiredAlignmentMask) & ~requiredAlignmentMask;
|
auto size = (requiredSize + requiredAlignmentMask) & ~requiredAlignmentMask;
|
||||||
auto object = reinterpret_cast<HeapObject *>(
|
auto object = reinterpret_cast<HeapObject *>(
|
||||||
@@ -102,6 +103,7 @@ static void destroyPOD(HeapObject *o) {
|
|||||||
|
|
||||||
BoxPair::Return
|
BoxPair::Return
|
||||||
swift::swift_allocPOD(size_t dataSize, size_t dataAlignmentMask) {
|
swift::swift_allocPOD(size_t dataSize, size_t dataAlignmentMask) {
|
||||||
|
assert(isAlignmentMask(dataAlignmentMask));
|
||||||
// Allocate the heap object.
|
// Allocate the heap object.
|
||||||
size_t valueOffset = PODBox::getValueOffset(dataSize, dataAlignmentMask);
|
size_t valueOffset = PODBox::getValueOffset(dataSize, dataAlignmentMask);
|
||||||
size_t size = valueOffset + dataSize;
|
size_t size = valueOffset + dataSize;
|
||||||
@@ -362,6 +364,7 @@ void swift::_swift_deallocClassInstance(HeapObject *self) {
|
|||||||
|
|
||||||
void swift::swift_deallocObject(HeapObject *object, size_t allocatedSize,
|
void swift::swift_deallocObject(HeapObject *object, size_t allocatedSize,
|
||||||
size_t allocatedAlignMask) {
|
size_t allocatedAlignMask) {
|
||||||
|
assert(isAlignmentMask(allocatedAlignMask));
|
||||||
assert(object->refCount == (RC_INTERVAL|RC_DEALLOCATING_BIT));
|
assert(object->refCount == (RC_INTERVAL|RC_DEALLOCATING_BIT));
|
||||||
#ifdef SWIFT_RUNTIME_CLOBBER_FREED_OBJECTS
|
#ifdef SWIFT_RUNTIME_CLOBBER_FREED_OBJECTS
|
||||||
memset_pattern8((uint8_t *)object + sizeof(HeapObject),
|
memset_pattern8((uint8_t *)object + sizeof(HeapObject),
|
||||||
|
|||||||
@@ -28,6 +28,16 @@ namespace swift {
|
|||||||
extern "C" LLVM_LIBRARY_VISIBILITY
|
extern "C" LLVM_LIBRARY_VISIBILITY
|
||||||
void _swift_deallocClassInstance(HeapObject *object);
|
void _swift_deallocClassInstance(HeapObject *object);
|
||||||
|
|
||||||
|
/// Is the given value a valid alignment mask?
|
||||||
|
static inline bool isAlignmentMask(size_t mask) {
|
||||||
|
// mask == xyz01111...
|
||||||
|
// mask+1 == xyz10000...
|
||||||
|
// mask&(mask+1) == xyz00000...
|
||||||
|
// So this is nonzero if and only if there any bits set
|
||||||
|
// other than an arbitrarily long sequence of low bits.
|
||||||
|
return (mask & (mask + 1)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
#endif /* SWIFT_RUNTIME_PRIVATE_H */
|
#endif /* SWIFT_RUNTIME_PRIVATE_H */
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ class FixedSizedRefArrayOfOptionalStorage<T> : HeapBufferStorage<Int, T?> {
|
|||||||
(buffer.elementStorage + i).destroy()
|
(buffer.elementStorage + i).destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
override func __getInstanceSizeAndAlignMask() -> (Int,Int) {
|
||||||
|
return Buffer(self)._allocatedSizeAndAlignMask()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FixedSizedRefArrayOfOptional<T>
|
struct FixedSizedRefArrayOfOptional<T>
|
||||||
|
|||||||
@@ -1422,9 +1422,12 @@ func slurpFastEnumeration(
|
|||||||
d: NSDictionary, fe: NSFastEnumeration
|
d: NSDictionary, fe: NSFastEnumeration
|
||||||
) -> Array<(Int, Int)> {
|
) -> Array<(Int, Int)> {
|
||||||
var state = NSFastEnumerationState()
|
var state = NSFastEnumerationState()
|
||||||
|
|
||||||
|
// This leaks the actual objects we store in it.
|
||||||
|
// Why are we doing this in a test again?
|
||||||
let stackBufLength = 3
|
let stackBufLength = 3
|
||||||
var stackBuf = HeapBuffer<(), AnyObject?>(
|
var stackBuf = HeapBuffer<(), AnyObject?>(
|
||||||
HeapBufferStorageBase.self, (), stackBufLength)
|
HeapBufferStorage<(), AnyObject?>.self, (), stackBufLength)
|
||||||
|
|
||||||
var pairs = Array<(Int, Int)>()
|
var pairs = Array<(Int, Int)>()
|
||||||
while true {
|
while true {
|
||||||
|
|||||||
Reference in New Issue
Block a user