Skip to content

Commit cb51359

Browse files
authored
Merge pull request #65874 from xedin/rdar-109207043
[IRGen] Distributed: Destroy loaded arguments after the call
2 parents 7816138 + 89ba257 commit cb51359

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

lib/IRGen/GenDistributed.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ class DistributedAccessor {
134134
/// The list of all arguments that were allocated on the stack.
135135
SmallVector<StackAddress, 4> AllocatedArguments;
136136

137+
/// The list of all the arguments that were loaded.
138+
SmallVector<std::pair<Address, /*type=*/llvm::Value *>, 4> LoadedArguments;
139+
137140
public:
138141
DistributedAccessor(IRGenFunction &IGF, SILFunction *target,
139142
CanSILFunctionType accessorTy);
@@ -498,13 +501,16 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
498501
resultValue.getAddress(), IGM.getStorageType(paramTy));
499502

500503
cast<LoadableTypeInfo>(paramInfo).loadAsTake(IGF, eltPtr, arguments);
504+
LoadedArguments.push_back(std::make_pair(eltPtr, argumentType));
501505
break;
502506
}
503507

504508
case ParameterConvention::Direct_Owned: {
505509
// Copy the value out at +1.
506510
cast<LoadableTypeInfo>(paramInfo).loadAsCopy(IGF, resultValue.getAddress(),
507511
arguments);
512+
LoadedArguments.push_back(
513+
std::make_pair(resultValue.getAddress(), argumentType));
508514
break;
509515
}
510516
}
@@ -584,6 +590,11 @@ void DistributedAccessor::emitReturn(llvm::Value *errorValue) {
584590
}
585591
}
586592

593+
// Destroy loaded arguments.
594+
llvm::for_each(LoadedArguments, [&](const auto &argInfo) {
595+
emitDestroyCall(IGF, argInfo.second, argInfo.first);
596+
});
597+
587598
Explosion voidResult;
588599

589600
Explosion error;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/Inputs/FakeDistributedActorSystems.swift
2+
// RUN: %target-swift-frontend -module-name no_to_arg_leaks -emit-irgen -disable-availability-checking -I %t 2>&1 %s | %IRGenFileCheck %s -check-prefix CHECK-%target-import-type
3+
4+
// UNSUPPORTED: back_deploy_concurrency
5+
// REQUIRES: concurrency
6+
// REQUIRES: distributed
7+
8+
// REQUIRES: CPU=x86_64 || CPU=arm64
9+
10+
// UNSUPPORTED: OS=windows-msvc
11+
12+
import Distributed
13+
import FakeDistributedActorSystems
14+
15+
@available(SwiftStdlib 5.5, *)
16+
typealias DefaultDistributedActorSystem = FakeActorSystem
17+
18+
final class SomeClass<T>: Sendable, Codable {
19+
init() {}
20+
}
21+
22+
struct S<T> : Codable {
23+
var data: SomeClass<T>
24+
}
25+
26+
distributed actor Greeter {
27+
// CHECK-LABEL: define linkonce_odr hidden swifttailcc void @"$s15no_to_arg_leaks7GreeterC5test1yyAA9SomeClassCyxGYaKlFTETF"
28+
// CHECK: [[ARG_ADDR:%.*]] = bitcast i8* {{.*}} to %T15no_to_arg_leaks9SomeClassC**
29+
// CHECK: %destroy = bitcast i8* {{.*}} to void (%swift.opaque*, %swift.type*)*
30+
// CHECK-NEXT: [[OPAQUE_ARG_ADDR:%.*]] = bitcast %T15no_to_arg_leaks9SomeClassC** [[ARG_ADDR]] to %swift.opaque*
31+
// CHECK-NEXT: call void %destroy(%swift.opaque* noalias [[OPAQUE_ARG_ADDR]], %swift.type* %arg_type)
32+
distributed func test1<T>(_: SomeClass<T>) {
33+
}
34+
35+
// CHECK-LABEL: define linkonce_odr hidden swifttailcc void @"$s15no_to_arg_leaks7GreeterC5test2yyAA1SVyxGYaKlFTETF"
36+
// CHECK: [[ARG_ADDR:%.*]] = bitcast i8* {{.*}} to %T15no_to_arg_leaks1SV*
37+
// CHECK: %destroy = bitcast i8* {{.*}} to void (%swift.opaque*, %swift.type*)*
38+
// CHECK-NEXT: [[OPAQUE_ARG_ADDR:%.*]] = bitcast %T15no_to_arg_leaks1SV* [[ARG_ADDR]] to %swift.opaque*
39+
// CHECK-NEXT: call void %destroy(%swift.opaque* noalias [[OPAQUE_ARG_ADDR]], %swift.type* %arg_type)
40+
distributed func test2<T>(_: S<T>) {}
41+
}
42+
43+
func test() async throws {
44+
let system = DefaultDistributedActorSystem()
45+
46+
let local = Greeter(actorSystem: system)
47+
let ref = try Greeter.resolve(id: local.id, using: system)
48+
49+
try await ref.test1(SomeClass<Int>())
50+
try await ref.test2(S(data: SomeClass<Int>()))
51+
}

0 commit comments

Comments
 (0)