Skip to content

Commit

Permalink
Better comments, fix a calculation.
Browse files Browse the repository at this point in the history
  • Loading branch information
rjmccall committed Oct 20, 2021
1 parent 68b9ccc commit d7cae26
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions include/swift/ABI/Task.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,25 +480,42 @@ class AsyncTask : public Job {
return resultType;
}

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

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

/// Determine the size of the future fragment given a particular future
/// result type.
static size_t fragmentSize(size_t initialOffset, const Metadata *resultType) {
/// Determine the size of the future fragment given the result type
/// of the future.
static size_t fragmentSize(size_t fragmentOffset,
const Metadata *resultType) {
assert((fragmentOffset & (alignof(FutureFragment) - 1)) == 0);
size_t alignment = resultType->vw_alignment();
size_t padding = alignment - ((sizeof(FutureFragment) + initialOffset) % alignment);
return sizeof(FutureFragment) + padding + resultType->vw_size();
size_t resultOffset = fragmentOffset + sizeof(FutureFragment);
resultOffset = (resultOffset + alignment - 1) & ~(alignment - 1);
size_t endOffset = resultOffset + resultType->vw_size();
return (endOffset - fragmentOffset);
}
};

Expand Down

0 comments on commit d7cae26

Please sign in to comment.