[vm/concurrency] Update documentation of SendPort.send to be more precise
In addition to making the documentation of [SendPort.send] more precise
by describing what objects are disallowed for sending objects between
isolates within the same isolate group, it also makes [Isolate.exit]
link to [SendPort.send].
Closes https://github.com/dart-lang/sdk/issues/46623
TEST=Updates documentation only.
Change-Id: I9bc1d88faaf2b70589af5e56168976ba89a35558
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/219080
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index d439fd4..438e967 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -563,9 +563,9 @@
/// This operation is potentially dangerous and should be used judiciously.
/// The isolate stops operating *immediately*. It throws if the optional
/// [message] does not adhere to the limitations on what can be sent from one
- /// isolate to another. It also throws if a [finalMessagePort] is associated
- /// with an isolate spawned outside of current isolate group, spawned via
- /// [spawnUri].
+ /// isolate to another (see [SendPort.send] for more details). It also throws
+ /// if a [finalMessagePort] is associated with an isolate spawned outside of
+ /// current isolate group, spawned via [spawnUri].
///
/// If successful, a call to this method does not return. Pending `finally`
/// blocks are not executed, control flow will not go back to the event loop,
@@ -575,9 +575,9 @@
/// code will run in the isolate.)
///
/// If [finalMessagePort] is provided, and the [message] can be sent through
- /// it, then the message is sent through that port as the final operation of
- /// the current isolate. The isolate terminates immediately after
- /// that [SendPort.send] call returns.
+ /// it (see [SendPort.send] for more details), then the message is sent
+ /// through that port as the final operation of the current isolate. The
+ /// isolate terminates immediately after that [SendPort.send] call returns.
///
/// If the port is a native port -- one provided by [ReceivePort.sendPort] or
/// [RawReceivePort.sendPort] -- the system may be able to send this final
@@ -599,9 +599,10 @@
/// when sent.
abstract class SendPort implements Capability {
/// Sends an asynchronous [message] through this send port, to its
- /// corresponding `ReceivePort`.
+ /// corresponding [ReceivePort].
///
- /// The content of [message] can be:
+ /// The transitive object graph of [message] can contain the following
+ /// objects:
/// - [Null]
/// - [bool]
/// - [int]
@@ -612,14 +613,34 @@
/// - [SendPort]
/// - [Capability]
///
- /// In the special circumstances when two isolates share the same code and are
- /// running in the same process (e.g. isolates created via [Isolate.spawn]),
- /// it is also possible to send object instances (which would be copied in the
- /// process).
+ /// If the sender and receiver isolate share the same code (e.g. isolates
+ /// created via [Isolate.spawn]), the transitive object graph of [message] can
+ /// contain any object, with the following exceptions:
///
- /// The send happens immediately and doesn't block. The corresponding receive
+ /// - Objects with native resources (subclasses of e.g.
+ /// `NativeFieldWrapperClass1`). A [Socket] object for example referrs
+ /// internally to objects that have native resources attached and can
+ /// therefore not be sent.
+ /// - [ReceivePort]
+ /// - [DynamicLibrary]
+ /// - [Pointer]
+ /// - [UserTag]
+ /// - `MirrorReference`
+ ///
+ /// Apart from those exceptions any object can be sent. Objects that are
+ /// identified as immutable (e.g. strings) will be shared whereas all other
+ /// objects will be copied.
+ ///
+ /// The send happens immediately and may have a linear time cost to copy the
+ /// transtive object graph. The send itself doesn't block (i.e. doesn't wait
+ /// until the receiver has received the message). The corresponding receive
/// port can receive the message as soon as its isolate's event loop is ready
/// to deliver it, independently of what the sending isolate is doing.
+ ///
+ /// Note: Due to an implementation choice the Dart VM made for how closures
+ /// represent captured state, closures can currently capture more state than
+ /// they need, which can cause the transitive closure to be larger than
+ /// needed. Open bug to address this: http://dartbug.com/36983
void send(Object? message);
/// Tests whether [other] is a [SendPort] pointing to the same