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:
John McCall
2014-05-22 01:58:05 +00:00
parent 1042b5cbef
commit 329abe543d
7 changed files with 24 additions and 3 deletions

View File

@@ -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
}; };
} }

View File

@@ -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()
} }
} }

View File

@@ -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);
} }

View File

@@ -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),

View File

@@ -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 */

View File

@@ -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>

View File

@@ -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 {