Skip to content

Commit fd1bb03

Browse files
committed
Better comments, fix a calculation.
1 parent d3d34ae commit fd1bb03

File tree

1 file changed

+28
-11
lines changed

1 file changed

+28
-11
lines changed

include/swift/ABI/Task.h

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -480,25 +480,42 @@ class AsyncTask : public Job {
480480
return resultType;
481481
}
482482

483-
/// Retrieve a pointer to the storage of result.
483+
/// Retrieve a pointer to the storage of the result.
484484
OpaqueValue *getStoragePtr() {
485-
auto *startAddr = reinterpret_cast<char *>(this) + sizeof(FutureFragment);
486-
uintptr_t startAddrVal = (uintptr_t)startAddr;
485+
// The result storage starts at the first aligned offset following
486+
// the fragment header. This offset will agree with the abstract
487+
// calculation for `resultOffset` in the fragmentSize function below
488+
// because the entire task is aligned to at least the target
489+
// alignment (because it's aligned to MaxAlignment), which means
490+
// `this` must have the same value modulo that alignment as
491+
// `fragmentOffset` has in that function.
492+
char *fragmentAddr = reinterpret_cast<char *>(this);
487493
uintptr_t alignment = resultType->vw_alignment();
488-
startAddrVal = (startAddrVal + alignment -1) & ~(alignment -1);
489-
return reinterpret_cast<OpaqueValue *>(
490-
reinterpret_cast<char *>(startAddrVal));
494+
char *resultAddr = fragmentAddr + sizeof(FutureFragment);
495+
uintptr_t unalignedResultAddrInt =
496+
reinterpret_cast<uintptr_t>(resultAddr);
497+
uintptr_t alignedResultAddrInt =
498+
(unalignedResultAddrInt + alignment - 1) & ~(alignment - 1);
499+
// We could just cast alignedResultAddrInt back to a pointer, but
500+
// doing pointer arithmetic is more strictly conformant and less
501+
// likely to annoy the optimizer.
502+
resultAddr += (alignedResultAddrInt - unalignedResultAddrInt);
503+
return reinterpret_cast<OpaqueValue *>(resultAddr);
491504
}
492505

493506
/// Retrieve the error.
494507
SwiftError *&getError() { return error; }
495508

496-
/// Determine the size of the future fragment given a particular future
497-
/// result type.
498-
static size_t fragmentSize(size_t initialOffset, const Metadata *resultType) {
509+
/// Determine the size of the future fragment given the result type
510+
/// of the future.
511+
static size_t fragmentSize(size_t fragmentOffset,
512+
const Metadata *resultType) {
513+
assert((fragmentOffset & (alignof(FutureFragment) - 1)) == 0);
499514
size_t alignment = resultType->vw_alignment();
500-
size_t padding = alignment - ((sizeof(FutureFragment) + initialOffset) % alignment);
501-
return sizeof(FutureFragment) + padding + resultType->vw_size();
515+
size_t resultOffset = fragmentOffset + sizeof(FutureFragment);
516+
resultOffset = (resultOffset + alignment - 1) & ~(alignment - 1);
517+
size_t endOffset = resultOffset + resultType->vw_size();
518+
return (endOffset - fragmentOffset);
502519
}
503520
};
504521

0 commit comments

Comments
 (0)