Skip to content

Commit d3d34ae

Browse files
aschwaighoferrjmccall
authored andcommitted
Make sure that the future fragment's storage pointer is properly aligned
1 parent 80e9fe1 commit d3d34ae

File tree

2 files changed

+10
-12
lines changed

2 files changed

+10
-12
lines changed

include/swift/ABI/Task.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -482,25 +482,23 @@ class AsyncTask : public Job {
482482

483483
/// Retrieve a pointer to the storage of result.
484484
OpaqueValue *getStoragePtr() {
485+
auto *startAddr = reinterpret_cast<char *>(this) + sizeof(FutureFragment);
486+
uintptr_t startAddrVal = (uintptr_t)startAddr;
487+
uintptr_t alignment = resultType->vw_alignment();
488+
startAddrVal = (startAddrVal + alignment -1) & ~(alignment -1);
485489
return reinterpret_cast<OpaqueValue *>(
486-
reinterpret_cast<char *>(this) + storageOffset(resultType));
490+
reinterpret_cast<char *>(startAddrVal));
487491
}
488492

489493
/// Retrieve the error.
490494
SwiftError *&getError() { return error; }
491495

492-
/// Compute the offset of the storage from the base of the future
493-
/// fragment.
494-
static size_t storageOffset(const Metadata *resultType) {
495-
size_t offset = sizeof(FutureFragment);
496-
size_t alignment = resultType->vw_alignment();
497-
return (offset + alignment - 1) & ~(alignment - 1);
498-
}
499-
500496
/// Determine the size of the future fragment given a particular future
501497
/// result type.
502-
static size_t fragmentSize(const Metadata *resultType) {
503-
return storageOffset(resultType) + resultType->vw_size();
498+
static size_t fragmentSize(size_t initialOffset, const Metadata *resultType) {
499+
size_t alignment = resultType->vw_alignment();
500+
size_t padding = alignment - ((sizeof(FutureFragment) + initialOffset) % alignment);
501+
return sizeof(FutureFragment) + padding + resultType->vw_size();
504502
}
505503
};
506504

stdlib/public/Concurrency/Task.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
507507
headerSize += sizeof(AsyncTask::GroupChildFragment);
508508
}
509509
if (futureResultType) {
510-
headerSize += FutureFragment::fragmentSize(futureResultType);
510+
headerSize += FutureFragment::fragmentSize(headerSize, futureResultType);
511511
// Add the future async context prefix.
512512
headerSize += sizeof(FutureAsyncContextPrefix);
513513
} else {

0 commit comments

Comments
 (0)