From 68b9ccc4ad0b9d7f104c5033caa3c9127e9eba41 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 19 Oct 2021 16:48:38 -0700 Subject: [PATCH] Make sure that the future fragment's storage pointer is properly aligned --- include/swift/ABI/Task.h | 20 +++++++++----------- stdlib/public/Concurrency/Task.cpp | 2 +- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/swift/ABI/Task.h b/include/swift/ABI/Task.h index cbbb88b714a7b..9f959a82108b0 100644 --- a/include/swift/ABI/Task.h +++ b/include/swift/ABI/Task.h @@ -482,25 +482,23 @@ class AsyncTask : public Job { /// Retrieve a pointer to the storage of result. OpaqueValue *getStoragePtr() { + auto *startAddr = reinterpret_cast(this) + sizeof(FutureFragment); + uintptr_t startAddrVal = (uintptr_t)startAddr; + uintptr_t alignment = resultType->vw_alignment(); + startAddrVal = (startAddrVal + alignment -1) & ~(alignment -1); return reinterpret_cast( - reinterpret_cast(this) + storageOffset(resultType)); + reinterpret_cast(startAddrVal)); } /// Retrieve the error. SwiftError *&getError() { return error; } - /// Compute the offset of the storage from the base of the future - /// fragment. - static size_t storageOffset(const Metadata *resultType) { - size_t offset = sizeof(FutureFragment); - size_t alignment = resultType->vw_alignment(); - return (offset + alignment - 1) & ~(alignment - 1); - } - /// Determine the size of the future fragment given a particular future /// result type. - static size_t fragmentSize(const Metadata *resultType) { - return storageOffset(resultType) + resultType->vw_size(); + static size_t fragmentSize(size_t initialOffset, const Metadata *resultType) { + size_t alignment = resultType->vw_alignment(); + size_t padding = alignment - ((sizeof(FutureFragment) + initialOffset) % alignment); + return sizeof(FutureFragment) + padding + resultType->vw_size(); } }; diff --git a/stdlib/public/Concurrency/Task.cpp b/stdlib/public/Concurrency/Task.cpp index b7861059c0f4e..8c8d0d3a7eadc 100644 --- a/stdlib/public/Concurrency/Task.cpp +++ b/stdlib/public/Concurrency/Task.cpp @@ -513,7 +513,7 @@ static AsyncTaskAndContext swift_task_create_commonImpl( headerSize += sizeof(AsyncTask::GroupChildFragment); } if (futureResultType) { - headerSize += FutureFragment::fragmentSize(futureResultType); + headerSize += FutureFragment::fragmentSize(headerSize, futureResultType); // Add the future async context prefix. headerSize += sizeof(FutureAsyncContextPrefix); } else {