Skip to content

Commit

Permalink
Make sure that the future fragment's storage pointer is properly aligned
Browse files Browse the repository at this point in the history
  • Loading branch information
aschwaighofer authored and rjmccall committed Oct 20, 2021
1 parent 367734a commit 68b9ccc
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 12 deletions.
20 changes: 9 additions & 11 deletions include/swift/ABI/Task.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,25 +482,23 @@ class AsyncTask : public Job {

/// Retrieve a pointer to the storage of result.
OpaqueValue *getStoragePtr() {
auto *startAddr = reinterpret_cast<char *>(this) + sizeof(FutureFragment);
uintptr_t startAddrVal = (uintptr_t)startAddr;
uintptr_t alignment = resultType->vw_alignment();
startAddrVal = (startAddrVal + alignment -1) & ~(alignment -1);
return reinterpret_cast<OpaqueValue *>(
reinterpret_cast<char *>(this) + storageOffset(resultType));
reinterpret_cast<char *>(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();
}
};

Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/Concurrency/Task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 68b9ccc

Please sign in to comment.