Skip to content

Commit 95a15a6

Browse files
authored
Merge pull request #2071 from swiftwasm/main
[pull] swiftwasm from main
2 parents 2f9184d + 33771cf commit 95a15a6

File tree

124 files changed

+3445
-616
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+3445
-616
lines changed

include/swift/ABI/MetadataKind.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ METADATAKIND(HeapGenericLocalVariable,
8585
METADATAKIND(ErrorObject,
8686
1 | MetadataKindIsNonType | MetadataKindIsRuntimePrivate)
8787

88+
/// A heap-allocated simple task.
89+
METADATAKIND(SimpleTask,
90+
2 | MetadataKindIsNonType | MetadataKindIsRuntimePrivate)
91+
8892
// getEnumeratedMetadataKind assumes that all the enumerated values here
8993
// will be <= LastEnumeratedMetadataKind.
9094

include/swift/ABI/MetadataValues.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,9 +1914,8 @@ class JobFlags : public FlagSet<size_t> {
19141914

19151915
// Kind-specific flags.
19161916

1917-
Task_IsHeapObject = 24,
1918-
Task_IsChildTask = 25,
1919-
Task_IsFuture = 26
1917+
Task_IsChildTask = 24,
1918+
Task_IsFuture = 25
19201919
};
19211920

19221921
explicit JobFlags(size_t bits) : FlagSet(bits) {}
@@ -1933,9 +1932,6 @@ class JobFlags : public FlagSet<size_t> {
19331932
return getKind() == JobKind::Task;
19341933
}
19351934

1936-
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsHeapObject,
1937-
task_isHeapObject,
1938-
task_setIsHeapObject)
19391935
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsChildTask,
19401936
task_isChildTask,
19411937
task_setIsChildTask)
@@ -2034,8 +2030,8 @@ class AsyncContextFlags : public FlagSet<uint32_t> {
20342030
/// allocated as part of the caller's context, or if the callee will
20352031
/// be called multiple times.
20362032
FLAGSET_DEFINE_FLAG_ACCESSORS(ShouldNotDeallocate,
2037-
shouldNotDeallocateInCaller,
2038-
setShouldNotDeallocateInCaller)
2033+
shouldNotDeallocateInCallee,
2034+
setShouldNotDeallocateInCallee)
20392035
};
20402036

20412037
} // end namespace swift

include/swift/ABI/Task.h

Lines changed: 86 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef SWIFT_ABI_TASK_H
1818
#define SWIFT_ABI_TASK_H
1919

20+
#include "swift/Basic/RelativePointer.h"
2021
#include "swift/ABI/HeapObject.h"
2122
#include "swift/ABI/MetadataValues.h"
2223
#include "swift/Runtime/Config.h"
@@ -32,7 +33,21 @@ class TaskStatusRecord;
3233

3334
/// An ExecutorRef isn't necessarily just a pointer to an executor
3435
/// object; it may have other bits set.
35-
using ExecutorRef = Executor *;
36+
struct ExecutorRef {
37+
Executor *Pointer;
38+
39+
/// Get an executor ref that represents a lack of preference about
40+
/// where execution resumes. This is only valid in continuations,
41+
/// return contexts, and so on; it is not generally passed to
42+
/// executing functions.
43+
static ExecutorRef noPreference() {
44+
return { nullptr };
45+
}
46+
47+
bool operator==(ExecutorRef other) const {
48+
return Pointer == other.Pointer;
49+
}
50+
};
3651

3752
using JobInvokeFunction =
3853
SWIFT_CC(swift)
@@ -42,6 +57,33 @@ using TaskContinuationFunction =
4257
SWIFT_CC(swift)
4358
void (AsyncTask *, ExecutorRef, AsyncContext *);
4459

60+
template <class Fn>
61+
struct AsyncFunctionTypeImpl;
62+
template <class Result, class... Params>
63+
struct AsyncFunctionTypeImpl<Result(Params...)> {
64+
// TODO: expand and include the arguments in the parameters.
65+
using type = TaskContinuationFunction;
66+
};
67+
68+
template <class Fn>
69+
using AsyncFunctionType = typename AsyncFunctionTypeImpl<Fn>::type;
70+
71+
/// A "function pointer" for an async function.
72+
///
73+
/// Eventually, this will always be signed with the data key
74+
/// using a type-specific discriminator.
75+
template <class FnType>
76+
class AsyncFunctionPointer {
77+
public:
78+
/// The function to run.
79+
RelativeDirectPointer<AsyncFunctionType<FnType>,
80+
/*nullable*/ false,
81+
int32_t> Function;
82+
83+
/// The expected size of the context.
84+
uint32_t ExpectedContextSize;
85+
};
86+
4587
/// A schedulable job.
4688
class alignas(2 * alignof(void*)) Job {
4789
public:
@@ -76,7 +118,7 @@ class alignas(2 * alignof(void*)) Job {
76118
}
77119

78120
/// Run this job.
79-
void run(Executor *currentExecutor);
121+
void run(ExecutorRef currentExecutor);
80122
};
81123

82124
// The compiler will eventually assume these.
@@ -128,7 +170,7 @@ class ActiveTaskStatus {
128170
/// An asynchronous task. Tasks are the analogue of threads for
129171
/// asynchronous functions: that is, they are a persistent identity
130172
/// for the overall async computation.
131-
class AsyncTask : public Job {
173+
class AsyncTask : public HeapObject, public Job {
132174
public:
133175
/// The context for resuming the job. When a task is scheduled
134176
/// as a job, the next continuation should be installed as the
@@ -146,9 +188,10 @@ class AsyncTask : public Job {
146188
/// Reserved for the use of the task-local stack allocator.
147189
void *AllocatorPrivate[4];
148190

149-
AsyncTask(JobFlags flags, TaskContinuationFunction *run,
191+
AsyncTask(const HeapMetadata *metadata, JobFlags flags,
192+
TaskContinuationFunction *run,
150193
AsyncContext *initialContext)
151-
: Job(flags, run),
194+
: HeapObject(metadata), Job(flags, run),
152195
ResumeContext(initialContext),
153196
Status(ActiveTaskStatus()) {
154197
assert(flags.isAsyncTask());
@@ -164,12 +207,6 @@ class AsyncTask : public Job {
164207
return Status.load(std::memory_order_relaxed).isCancelled();
165208
}
166209

167-
bool isHeapObject() const { return Flags.task_isHeapObject(); }
168-
HeapObject *heapObjectHeader() {
169-
assert(isHeapObject());
170-
return reinterpret_cast<HeapObject*>(this) - 1;
171-
}
172-
173210
/// A fragment of an async task structure that happens to be a child task.
174211
class ChildFragment {
175212
/// The parent task of this task.
@@ -182,6 +219,8 @@ class AsyncTask : public Job {
182219
AsyncTask *NextChild = nullptr;
183220

184221
public:
222+
ChildFragment(AsyncTask *parent) : Parent(parent) {}
223+
185224
AsyncTask *getParent() const {
186225
return Parent;
187226
}
@@ -191,6 +230,8 @@ class AsyncTask : public Job {
191230
}
192231
};
193232

233+
bool isFuture() const { return Flags.task_isFuture(); }
234+
194235
bool hasChildFragment() const { return Flags.task_isChildTask(); }
195236
ChildFragment *childFragment() {
196237
assert(hasChildFragment());
@@ -205,7 +246,7 @@ class AsyncTask : public Job {
205246
};
206247

207248
// The compiler will eventually assume these.
208-
static_assert(sizeof(AsyncTask) == 10 * sizeof(void*),
249+
static_assert(sizeof(AsyncTask) == 12 * sizeof(void*),
209250
"AsyncTask size is wrong");
210251
static_assert(alignof(AsyncTask) == 2 * alignof(void*),
211252
"AsyncTask alignment is wrong");
@@ -237,6 +278,9 @@ class alignas(MaximumAlignment) AsyncContext {
237278
TaskContinuationFunction * __ptrauth_swift_async_context_resume
238279
ResumeParent;
239280

281+
/// The executor that the parent needs to be resumed on.
282+
ExecutorRef ResumeParentExecutor;
283+
240284
/// Flags describing this context.
241285
///
242286
/// Note that this field is only 32 bits; any alignment padding
@@ -245,31 +289,44 @@ class alignas(MaximumAlignment) AsyncContext {
245289
/// is of course interrupted by the YieldToParent field.
246290
AsyncContextFlags Flags;
247291

248-
// Fields following this point may not be valid in all instances
249-
// of AsyncContext.
250-
251-
/// The function to call to temporarily resume running in the
252-
/// parent context temporarily. Generally this means a semantic
253-
/// yield. Requires Flags.hasYieldFunction().
254-
TaskContinuationFunction * __ptrauth_swift_async_context_yield
255-
YieldToParent;
256-
257-
AsyncContext(AsyncContextFlags flags,
258-
TaskContinuationFunction *resumeParent,
259-
AsyncContext *parent)
260-
: Parent(parent), ResumeParent(resumeParent), Flags(flags) {}
261-
262292
AsyncContext(AsyncContextFlags flags,
263293
TaskContinuationFunction *resumeParent,
264-
TaskContinuationFunction *yieldToParent,
294+
ExecutorRef resumeParentExecutor,
265295
AsyncContext *parent)
266-
: Parent(parent), ResumeParent(resumeParent), Flags(flags),
267-
YieldToParent(yieldToParent) {}
296+
: Parent(parent), ResumeParent(resumeParent),
297+
ResumeParentExecutor(resumeParentExecutor),
298+
Flags(flags) {}
268299

269300
AsyncContext(const AsyncContext &) = delete;
270301
AsyncContext &operator=(const AsyncContext &) = delete;
271302
};
272303

304+
/// An async context that supports yielding.
305+
class YieldingAsyncContext : public AsyncContext {
306+
public:
307+
/// The function to call to temporarily resume running in the
308+
/// parent context. Generally this means a semantic yield.
309+
TaskContinuationFunction * __ptrauth_swift_async_context_yield
310+
YieldToParent;
311+
312+
/// The executor that the parent context needs to be yielded to on.
313+
ExecutorRef YieldToParentExecutor;
314+
315+
YieldingAsyncContext(AsyncContextFlags flags,
316+
TaskContinuationFunction *resumeParent,
317+
ExecutorRef resumeParentExecutor,
318+
TaskContinuationFunction *yieldToParent,
319+
ExecutorRef yieldToParentExecutor,
320+
AsyncContext *parent)
321+
: AsyncContext(flags, resumeParent, resumeParentExecutor, parent),
322+
YieldToParent(yieldToParent),
323+
YieldToParentExecutor(yieldToParentExecutor) {}
324+
325+
static bool classof(const AsyncContext *context) {
326+
return context->Flags.getKind() == AsyncContextKind::Yielding;
327+
}
328+
};
329+
273330
} // end namespace swift
274331

275332
#endif

include/swift/ABI/TaskStatus.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class TaskStatusRecord {
8282
}
8383
};
8484

85-
TaskStatusRecord *
85+
inline TaskStatusRecord *
8686
ActiveTaskStatus::getStatusRecordParent(TaskStatusRecord *ptr) {
8787
return ptr->getParent();
8888
}

include/swift/AST/AbstractSourceFileDepGraphFactory.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_AST_SOURCE_FILE_DEP_GRAPH_CONSTRUCTOR_H
1414
#define SWIFT_AST_SOURCE_FILE_DEP_GRAPH_CONSTRUCTOR_H
1515

16+
#include "swift/AST/Decl.h"
1617
#include "swift/AST/DeclContext.h"
1718
#include "swift/AST/FineGrainedDependencies.h"
1819

@@ -72,6 +73,21 @@ class AbstractSourceFileDepGraphFactory {
7273
Optional<StringRef> fingerprint);
7374

7475
void addAUsedDecl(const DependencyKey &def, const DependencyKey &use);
76+
77+
static Optional<std::string> getFingerprintIfAny(
78+
std::pair<const NominalTypeDecl *, const ValueDecl *>) {
79+
return None;
80+
}
81+
82+
static Optional<std::string> getFingerprintIfAny(const Decl *d) {
83+
if (const auto *idc = dyn_cast<IterableDeclContext>(d)) {
84+
auto result = idc->getBodyFingerprint();
85+
assert((!result || !result->empty()) &&
86+
"Fingerprint should never be empty");
87+
return result;
88+
}
89+
return None;
90+
}
7591
};
7692

7793
} // namespace fine_grained_dependencies

include/swift/AST/Decl.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -950,9 +950,6 @@ class alignas(1 << DeclAlignInBits) Decl {
950950
/// If this returns true, the decl can be safely casted to ValueDecl.
951951
bool isPotentiallyOverridable() const;
952952

953-
/// Returns true if this Decl cannot be seen by any other source file
954-
bool isPrivateToEnclosingFile() const;
955-
956953
/// Retrieve the global actor attribute that applies to this declaration,
957954
/// if any.
958955
///
@@ -4763,11 +4760,19 @@ class VarDecl : public AbstractStorageDecl {
47634760

47644761
/// Determines if this var has an initializer expression that should be
47654762
/// exposed to clients.
4763+
///
47664764
/// There's a very narrow case when we would: if the decl is an instance
47674765
/// member with an initializer expression and the parent type is
47684766
/// @frozen and resides in a resilient module.
47694767
bool isInitExposedToClients() const;
4770-
4768+
4769+
/// Determines if this var is exposed as part of the layout of a
4770+
/// @frozen struct.
4771+
///
4772+
/// From the standpoint of access control and exportability checking, this
4773+
/// var will behave as if it was public, even if it is internal or private.
4774+
bool isLayoutExposedToClients() const;
4775+
47714776
/// Is this a special debugger variable?
47724777
bool isDebuggerVar() const { return Bits.VarDecl.IsDebuggerVar; }
47734778
void setDebuggerVar(bool IsDebuggerVar) {

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5061,12 +5061,12 @@ ERROR(local_type_in_inlinable_function,
50615061
(Identifier, unsigned))
50625062

50635063
ERROR(resilience_decl_unavailable,
5064-
none, DECL_OR_ACCESSOR "4 %1 is %select{private|fileprivate|internal|'@_spi'|'@_spi'}2 and "
5064+
none, DECL_OR_ACCESSOR "4 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
50655065
"cannot be referenced from " FRAGILE_FUNC_KIND "3",
50665066
(DescriptiveDeclKind, DeclName, AccessLevel, unsigned, bool))
50675067

50685068
WARNING(resilience_decl_unavailable_warn,
5069-
none, DECL_OR_ACCESSOR "4 %1 is %select{private|fileprivate|internal|'@_spi'|'@_spi'}2 and "
5069+
none, DECL_OR_ACCESSOR "4 %1 is %select{private|fileprivate|internal|%error|%error}2 and "
50705070
"should not be referenced from " FRAGILE_FUNC_KIND "3",
50715071
(DescriptiveDeclKind, DeclName, AccessLevel, unsigned, bool))
50725072

include/swift/Basic/StringExtras.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ class InheritedNameSet {
442442
///
443443
/// \param allPropertyNames The set of property names in the enclosing context.
444444
///
445+
/// \param isAsync Whether this is a function imported as 'async'.
446+
///
445447
/// \param scratch Scratch space that will be used for modifications beyond
446448
/// just chopping names.
447449
///
@@ -455,6 +457,7 @@ bool omitNeedlessWords(StringRef &baseName,
455457
bool returnsSelf,
456458
bool isProperty,
457459
const InheritedNameSet *allPropertyNames,
460+
bool isAsync,
458461
StringScratchSpace &scratch);
459462

460463
} // end namespace swift

include/swift/Driver/Job.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,23 @@ class Job {
308308
/// The modification time of the main input file, if any.
309309
llvm::sys::TimePoint<> InputModTime = llvm::sys::TimePoint<>::max();
310310

311+
#ifndef NDEBUG
312+
/// The "wave" of incremental jobs that this \c Job was scheduled into.
313+
///
314+
/// The first "wave" of jobs is computed by the driver from the set of inputs
315+
/// and external files that have been mutated by the user. From there, as
316+
/// jobs from the first wave finish executing, we reload their \c swiftdeps
317+
/// files and re-integrate them into the dependency graph to discover
318+
/// the jobs for the second "wave".
319+
///
320+
/// In +asserts builds, we ensure that no more than two "waves" occur for
321+
/// any given incremental compilation session. This is a consequence of
322+
/// 1) transitivity in dependency arcs
323+
/// 2) dependency tracing from uses that affect a def's interfaces to that
324+
/// def's uses.
325+
mutable unsigned Wave = 1;
326+
#endif
327+
311328
public:
312329
Job(const JobAction &Source, SmallVectorImpl<const Job *> &&Inputs,
313330
std::unique_ptr<CommandOutput> Output, const char *Executable,
@@ -399,6 +416,11 @@ class Job {
399416
/// Assumes that, if a compile job, has one primary swift input
400417
/// May return empty if none.
401418
StringRef getFirstSwiftPrimaryInput() const;
419+
420+
#ifndef NDEBUG
421+
unsigned getWave() const { return Wave; }
422+
void setWave(unsigned WaveNum) const { Wave = WaveNum; }
423+
#endif
402424
};
403425

404426
/// A BatchJob comprises a _set_ of jobs, each of which is sufficiently similar

0 commit comments

Comments
 (0)