Skip to content

🍒[5.10][Distributed] Destroy decoded parameters after executeDistributedTarget #70808

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
merged 1 commit into from
Jan 11, 2024
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
1 change: 1 addition & 0 deletions lib/IRGen/GenDistributed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
// The argument is +0, so we can use the address of the param in
// the context directly.
arguments.add(resultAddr);
LoadedArguments.push_back(std::make_pair(resultValue.getAddress(), argumentType));
break;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeCodableForDistributedTests.swiftmodule -module-name FakeCodableForDistributedTests -disable-availability-checking %S/../Inputs/FakeCodableForDistributedTests.swift
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift
// XXX: %target-build-swift -emit-silgen -module-name main -Xfrontend -enable-experimental-distributed -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeCodableForDistributedTests.swift %S/../Inputs/FakeDistributedActorSystems.swift
// RUN: %target-build-swift -module-name main -Xfrontend -enable-experimental-distributed -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeCodableForDistributedTests.swift %S/../Inputs/FakeDistributedActorSystems.swift -o %t/a.out
// RUN: %target-codesign %t/a.out
// RUN: %target-run %t/a.out | %FileCheck %s --color
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeCodableForDistributedTests.swiftmodule -module-name FakeCodableForDistributedTests -disable-availability-checking %S/../Inputs/FakeCodableForDistributedTests.swift
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift
// XXX: %target-build-swift -emit-silgen -module-name main -Xfrontend -enable-experimental-distributed -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeCodableForDistributedTests.swift %S/../Inputs/FakeDistributedActorSystems.swift
// RUN: %target-build-swift -module-name main -Xfrontend -enable-experimental-distributed -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeCodableForDistributedTests.swift %S/../Inputs/FakeDistributedActorSystems.swift -o %t/a.out
// RUN: %target-codesign %t/a.out
// RUN: %target-run %t/a.out | %FileCheck %s

// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: distributed

// rdar://76038845
// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime

import Distributed
import FakeDistributedActorSystems
import FakeCodableForDistributedTests

typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem

class Sentinel {
let str: String

init(_ str: String) {
self.str = str
print("\(str).init: \(Unmanaged.passUnretained(self).toOpaque())")
}

deinit {
print("\(str).deinit: \(Unmanaged.passUnretained(self).toOpaque())")
}
}

struct InnerStruct1 {
let sentinel: Sentinel
let innerStruct2: InnerStruct2

init() {
self.sentinel = Sentinel("\(Self.self)")
self.innerStruct2 = InnerStruct2()
}
}

struct InnerStruct2 {
let sentinel: Sentinel

init() {
self.sentinel = Sentinel("\(Self.self)")
}
}

enum InnerEnum {
case v1(String)
case v2(InnerStruct1)
}

struct ArgumentType: Codable {
let sentinel: Sentinel
let value: Int
let innerEnum: InnerEnum

init(_ value: Int) {
self.sentinel = Sentinel("ArgumentType")
self.value = value
self.innerEnum = .v2(InnerStruct1())
}

init(from decoder: Decoder) throws {
self.sentinel = Sentinel("ArgumentType")
self.value = 100
self.innerEnum = .v2(InnerStruct1())
}

func encode(to encoder: Encoder) throws {
print("ArgumentType.encode")
}
}

distributed actor TestActor {
public distributed func testFunc(arg: ArgumentType) {
print("value=\(arg.value)")
}
}

@main
struct Main {

static func main() async throws {
let system = DefaultDistributedActorSystem()

let instance = TestActor(actorSystem: system)
let resolved = try TestActor.resolve(id: instance.id, using: system)

// CHECK: ArgumentType.init: [[P1:0x[0-9]+]]
// CHECK: InnerStruct1.init: [[P2:0x[0-9]+]]
// CHECK: InnerStruct2.init: [[P3:0x[0-9]+]]

// CHECK: ArgumentType.deinit: [[P1]]
// CHECK: InnerStruct1.deinit: [[P2]]
// CHECK: InnerStruct2.deinit: [[P3]]

let arg = ArgumentType(100)
try await resolved.testFunc(arg: arg)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,52 @@ struct S<T> : Codable {
var data: SomeClass<T>
}


class Sentinel {
let str: String = ""
}

struct InnerStruct1 {
let sentinel: Sentinel
let innerStruct2: InnerStruct2

init() {
self.sentinel = Sentinel()
self.innerStruct2 = InnerStruct2()
}
}

struct InnerStruct2 {
let sentinel: Sentinel

init() {
self.sentinel = Sentinel()
}
}

enum InnerEnum {
case v1(String)
case v2(InnerStruct1)
}

struct ArgumentType: Codable {
let sentinel: Sentinel
let value: Int
let innerEnum: InnerEnum

init() {
self.sentinel = Sentinel()
self.value = 100
self.innerEnum = .v2(InnerStruct1())
}

init(from decoder: Decoder) throws {
fatalError("Not implemented")
}

func encode(to encoder: Encoder) throws {}
}

distributed actor Greeter {
// CHECK-LABEL: define linkonce_odr hidden swifttailcc void @"$s15no_to_arg_leaks7GreeterC5test1yyAA9SomeClassCyxGYaKlFTETF"
// CHECK: call void {{.*}}(ptr noalias [[PARAM:%.*]], ptr %arg_type)
Expand All @@ -35,6 +81,11 @@ distributed actor Greeter {
// CHECK: call void {{.*}}(ptr noalias [[PARAM:%.*]], ptr %arg_type)
// CHECK-NEXT: call swiftcc void @swift_task_dealloc(ptr [[PARAM]])
distributed func test2<T>(_: S<T>) {}

// CHECK-LABEL: define linkonce_odr hidden swifttailcc void @"$s15no_to_arg_leaks7GreeterC5test3yyAA12ArgumentTypeVYaKFTETF"
// CHECK: call void {{.*}}(ptr noalias [[PARAM:%.*]], ptr %arg_type)
// CHECK-NEXT: call swiftcc void @swift_task_dealloc(ptr [[PARAM]])
distributed func test3(_: ArgumentType) {}
}

func test() async throws {
Expand All @@ -45,4 +96,5 @@ func test() async throws {

try await ref.test1(SomeClass<Int>())
try await ref.test2(S(data: SomeClass<Int>()))
try await ref.test3(.init())
}