Skip to content

[5.5][Reflection] Fix iterateAsyncTaskAllocations. #38205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions include/swift/Reflection/ReflectionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1310,9 +1310,7 @@ class ReflectionContext
if (!AsyncTaskObj)
return std::string("failure reading async task");

auto *Allocator = reinterpret_cast<const StackAllocator *>(
&AsyncTaskObj->AllocatorPrivate);
StoredPointer SlabPtr = Allocator->FirstSlab;
StoredPointer SlabPtr = AsyncTaskObj->PrivateStorage.Allocator.FirstSlab;
while (SlabPtr) {
auto SlabBytes = getReader().readBytes(
RemoteAddress(SlabPtr), sizeof(typename StackAllocator::Slab));
Expand Down
24 changes: 18 additions & 6 deletions include/swift/Reflection/RuntimeInternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ struct HeapObject {

template <typename Runtime>
struct Job {
typename Runtime::StoredPointer Opaque[4];
HeapObject<Runtime> HeapObject;
typename Runtime::StoredPointer SchedulerPrivate[2];
uint32_t Flags;
uint32_t Id;
typename Runtime::StoredPointer Reserved[2];
typename Runtime::StoredPointer RunJob;
};

template <typename Runtime>
Expand All @@ -86,12 +91,19 @@ struct StackAllocator {
};

template <typename Runtime>
struct AsyncTask {
HeapObject<Runtime> HeapObject;
Job<Runtime> Job;
typename Runtime::StoredPointer ResumeContext;
struct AsyncTaskPrivateStorage {
typename Runtime::StoredSize Status;
typename Runtime::StoredPointer AllocatorPrivate[4];
StackAllocator<Runtime> Allocator;
typename Runtime::StoredPointer Local;
};

template <typename Runtime>
struct AsyncTask: Job<Runtime> {
// On 64-bit, there's a Reserved64 after ResumeContext.
typename Runtime::StoredPointer ResumeContextAndReserved[
sizeof(typename Runtime::StoredPointer) == 8 ? 2 : 1];

AsyncTaskPrivateStorage<Runtime> PrivateStorage;
};

} // end namespace reflection
Expand Down
15 changes: 8 additions & 7 deletions include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,6 @@

#include <stdlib.h>

/// Major version changes when there are ABI or source incompatible changes.
#define SWIFT_REFLECTION_VERSION_MAJOR 3

/// Minor version changes when new APIs are added in ABI- and source-compatible
/// way.
#define SWIFT_REFLECTION_VERSION_MINOR 0

#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -43,6 +36,14 @@ __attribute__((__weak_import__))
#endif
extern unsigned long long swift_reflection_classIsSwiftMask;

/// An arbitrary version number for this library. Incremented to indicate the
/// presence of a bug fix or feature that can't be detected from the outside
/// otherwise. The currently used version numbers are:
///
/// 0 - Indicates that swift_reflection_iterateAsyncTaskAllocations has been
/// fixed to use the right AsyncTask layout.
SWIFT_REMOTE_MIRROR_LINKAGE extern uint32_t swift_reflection_libraryVersion;

/// Get the metadata version supported by the Remote Mirror library.
SWIFT_REMOTE_MIRROR_LINKAGE
uint16_t swift_reflection_getSupportedMetadataVersion(void);
Expand Down
2 changes: 2 additions & 0 deletions stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
extern "C" {
SWIFT_REMOTE_MIRROR_LINKAGE
unsigned long long swift_reflection_classIsSwiftMask = 2;

SWIFT_REMOTE_MIRROR_LINKAGE uint32_t swift_reflection_libraryVersion = 0;
}

#include "swift/Demangling/Demangler.h"
Expand Down
48 changes: 48 additions & 0 deletions test/Concurrency/Reflection/reflect_task.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency -parse-stdlib -parse-as-library -lswiftSwiftReflectionTest %s -o %t/reflect_task
// RUN: %target-codesign %t/reflect_task

// RUN: %target-run %target-swift-reflection-test %t/reflect_task | %FileCheck %s --dump-input=fail

// REQUIRES: reflection_test_support
// REQUIRES: executable_test
// REQUIRES: concurrency
// UNSUPPORTED: use_os_stdlib

import Swift
import _Concurrency

import SwiftReflectionTest

@_silgen_name("swift_task_getCurrent")
func _getCurrentAsyncTask() -> UInt

func add(_ a: UInt, _ b: UInt) async -> UInt {
if b == 0 {
reflect(asyncTask: _getCurrentAsyncTask())
// CHECK: Reflecting an async task.
// CHECK: Async task {{0x[0-9a-fA-F]*}}

// The actual number of chunks we'll get depends on internal implementation
// details that we don't want this test to depend on. We'll just make sure
// we get at least two, and ignore the details.
// CHECK: Allocation block {{0x[0-9a-fA-F]*}}
// CHECK: Chunk at {{0x[0-9a-fA-F]*}} length {{[0-9]*}} kind {{[0-9]*}}
// CHECK: Allocation block {{0x[0-9a-fA-F]*}}
// CHECK: Chunk at {{0x[0-9a-fA-F]*}} length {{[0-9]*}} kind {{[0-9]*}}
return a
} else {
return await add(a, b - 1) + 1
}
}

@main struct Main {
static func main() async {
let n = await add(100, 100)
reflect(any: n)

doneReflecting()
}
}

// CHECK: Done.