22
22
#include " ClassTypeInfo.h"
23
23
#include " ExtraInhabitants.h"
24
24
#include " GenCall.h"
25
+ #include " GenClass.h"
25
26
#include " GenDecl.h"
26
27
#include " GenMeta.h"
27
28
#include " GenOpaque.h"
@@ -67,12 +68,17 @@ llvm::Value *irgen::emitDistributedActorInitializeRemote(
67
68
namespace {
68
69
69
70
struct ArgumentDecoderInfo {
70
- CanSILFunctionType Type;
71
- FunctionPointer Fn;
71
+ llvm::Value *Decoder;
72
72
73
- // / Given the decoder instance, form a callee to a
74
- // / decode method - `decodeNextArgument`.
75
- Callee getCallee (llvm::Value *decoder) const ;
73
+ struct {
74
+ CanSILFunctionType Type;
75
+ FunctionPointer Fn;
76
+ } DecodeMethod;
77
+
78
+ CanSILFunctionType getMethodType () const { return DecodeMethod.Type ; }
79
+
80
+ // / Form a callee to a decode method - `decodeNextArgument`.
81
+ Callee getCallee () const ;
76
82
};
77
83
78
84
class DistributedAccessor {
@@ -87,10 +93,6 @@ class DistributedAccessor {
87
93
// / The asynchronous context associated with this accessor.
88
94
AsyncContextLayout AsyncLayout;
89
95
90
- // / The argument decoder associated with the distributed actor
91
- // / this accessor belong to.
92
- ArgumentDecoderInfo ArgumentDecoder;
93
-
94
96
// / The list of all arguments that were allocated on the stack.
95
97
SmallVector<StackAddress, 4 > AllocatedArguments;
96
98
@@ -109,7 +111,7 @@ class DistributedAccessor {
109
111
// / the type of argument comes from runtime metadata.
110
112
// /
111
113
// / Returns a pair of aligned offset and value size.
112
- void decodeArgument (unsigned argumentIdx, llvm::Value * decoder,
114
+ void decodeArgument (unsigned argumentIdx, const ArgumentDecoderInfo & decoder,
113
115
llvm::Value *argumentType, const SILParameterInfo ¶m,
114
116
Explosion &arguments);
115
117
@@ -131,10 +133,8 @@ class DistributedAccessor {
131
133
132
134
Callee getCalleeForDistributedTarget (llvm::Value *self) const ;
133
135
134
- // / Given a distributed thunk, find argument coder that should
135
- // / could be used to decode argument values to pass to its invocation.
136
- static ArgumentDecoderInfo findArgumentDecoder (IRGenModule &IGM,
137
- SILFunction *thunk);
136
+ // / Given an instance of argument decoder, find `decodeNextArgument`.
137
+ ArgumentDecoderInfo findArgumentDecoder (llvm::Value *decoder);
138
138
139
139
// / The result type of the accessor.
140
140
SILType getResultType () const ;
@@ -247,8 +247,7 @@ DistributedAccessor::DistributedAccessor(IRGenFunction &IGF,
247
247
IGM, AccessorType, AccessorType, SubstitutionMap(),
248
248
/* suppress generics*/ true,
249
249
FunctionPointer::Kind(
250
- FunctionPointer::BasicKind::AsyncFunctionPointer))),
251
- ArgumentDecoder(findArgumentDecoder(IGM, target)) {}
250
+ FunctionPointer::BasicKind::AsyncFunctionPointer))) {}
252
251
253
252
void DistributedAccessor::decodeArguments (llvm::Value *decoder,
254
253
llvm::Value *argumentTypes,
@@ -266,6 +265,10 @@ void DistributedAccessor::decodeArguments(llvm::Value *decoder,
266
265
argumentTypes =
267
266
IGF.Builder .CreateBitCast (argumentTypes, IGM.TypeMetadataPtrPtrTy );
268
267
268
+ // / The argument decoder associated with the distributed actor
269
+ // / this accessor belong to.
270
+ ArgumentDecoderInfo decoderInfo = findArgumentDecoder (decoder);
271
+
269
272
for (unsigned i = 0 , n = parameters.size (); i != n; ++i) {
270
273
const auto ¶m = parameters[i];
271
274
auto paramTy = param.getSILStorageInterfaceType ();
@@ -293,12 +296,12 @@ void DistributedAccessor::decodeArguments(llvm::Value *decoder,
293
296
auto *argumentTy = IGF.Builder .CreateLoad (typeLoc, " arg_type" );
294
297
295
298
// Decode and load argument value using loaded type metadata.
296
- decodeArgument (i, decoder , argumentTy, param, arguments);
299
+ decodeArgument (i, decoderInfo , argumentTy, param, arguments);
297
300
}
298
301
}
299
302
300
303
void DistributedAccessor::decodeArgument (unsigned argumentIdx,
301
- llvm::Value * decoder,
304
+ const ArgumentDecoderInfo & decoder,
302
305
llvm::Value *argumentType,
303
306
const SILParameterInfo ¶m,
304
307
Explosion &arguments) {
@@ -308,7 +311,7 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
308
311
// deal with value witness tables are currently hidden in GenOpaque.cpp
309
312
llvm::Value *valueSize = emitLoadOfSize (IGF, argumentType);
310
313
311
- Callee callee = ArgumentDecoder .getCallee (decoder );
314
+ Callee callee = decoder .getCallee ();
312
315
313
316
std::unique_ptr<CallEmission> emission =
314
317
getCallEmission (IGF, callee.getSwiftContext (), std::move (callee));
@@ -340,7 +343,7 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
340
343
341
344
// Load error from the slot to emit an early return if necessary.
342
345
{
343
- SILFunctionConventions conv (ArgumentDecoder. Type , IGM.getSILModule ());
346
+ SILFunctionConventions conv (decoder. getMethodType () , IGM.getSILModule ());
344
347
SILType errorType =
345
348
conv.getSILErrorType (IGM.getMaximalTypeExpansionContext ());
346
349
@@ -631,26 +634,44 @@ DistributedAccessor::getCalleeForDistributedTarget(llvm::Value *self) const {
631
634
}
632
635
633
636
ArgumentDecoderInfo
634
- DistributedAccessor::findArgumentDecoder (IRGenModule &IGM, SILFunction *thunk) {
635
- auto *actor = getDistributedActorOf (thunk);
637
+ DistributedAccessor::findArgumentDecoder (llvm::Value *decoder) {
638
+ auto *actor = getDistributedActorOf (Target);
639
+ auto expansionContext = IGM.getMaximalTypeExpansionContext ();
636
640
637
641
auto *decodeFn = IGM.Context .getDistributedActorArgumentDecodingMethod (actor);
638
642
assert (decodeFn && " no suitable decoder?" );
639
643
644
+ auto *decoderDecl = decodeFn->getDeclContext ()->getSelfNominalTypeDecl ();
640
645
auto methodTy = IGM.getSILTypes ().getConstantFunctionType (
641
- IGM.getMaximalTypeExpansionContext (), SILDeclRef (decodeFn));
642
-
643
- auto *decodeSIL = IGM.getSILModule ().lookUpFunction (SILDeclRef (decodeFn));
644
- auto *fnPtr = IGM.getAddrOfSILFunction (decodeSIL, NotForDefinition,
645
- /* isDynamicallyReplacible=*/ false );
646
+ expansionContext, SILDeclRef (decodeFn));
646
647
647
648
auto signature = IGM.getSignature (methodTy, /* useSpecialConvention=*/ false );
648
649
650
+ // If the decoder class is `final`, let's emit a direct reference.
651
+ if (decoderDecl->isFinal ()) {
652
+ auto *decodeSIL = IGM.getSILModule ().lookUpFunction (SILDeclRef (decodeFn));
653
+ auto *fnPtr = IGM.getAddrOfSILFunction (decodeSIL, NotForDefinition,
654
+ /* isDynamicallyReplacible=*/ false );
655
+
656
+ auto methodPtr = FunctionPointer::forDirect (
657
+ classifyFunctionPointerKind (decodeSIL), fnPtr,
658
+ /* secondaryValue=*/ nullptr , signature);
659
+
660
+ return {.Decoder = decoder,
661
+ .DecodeMethod = {.Type = methodTy, .Fn = methodPtr}};
662
+ }
663
+
664
+ auto selfTy = methodTy->getSelfParameter ().getSILStorageType (
665
+ IGM.getSILModule (), methodTy, expansionContext);
666
+
667
+ auto *metadata = emitHeapMetadataRefForHeapObject (IGF, decoder, selfTy,
668
+ /* suppress cast*/ true );
669
+
649
670
auto methodPtr =
650
- FunctionPointer::forDirect (classifyFunctionPointerKind (decodeSIL), fnPtr,
651
- /* secondaryValue=*/ nullptr , signature);
671
+ emitVirtualMethodValue (IGF, metadata, SILDeclRef (decodeFn), methodTy);
652
672
653
- return {.Type = methodTy, .Fn = methodPtr};
673
+ return {.Decoder = decoder,
674
+ .DecodeMethod = {.Type = methodTy, .Fn = methodPtr}};
654
675
}
655
676
656
677
SILType DistributedAccessor::getResultType () const {
@@ -663,7 +684,7 @@ SILType DistributedAccessor::getErrorType() const {
663
684
return conv.getSILErrorType (IGM.getMaximalTypeExpansionContext ());
664
685
}
665
686
666
- Callee ArgumentDecoderInfo::getCallee (llvm::Value *decoder ) const {
667
- CalleeInfo info (Type, Type, SubstitutionMap ());
668
- return {std::move (info), Fn, decoder };
687
+ Callee ArgumentDecoderInfo::getCallee () const {
688
+ CalleeInfo info (DecodeMethod. Type , DecodeMethod. Type , SubstitutionMap ());
689
+ return {std::move (info), DecodeMethod. Fn , Decoder };
669
690
}
0 commit comments