Skip to content

Commit 386338e

Browse files
aamcommit-bot@chromium.org
authored andcommitted
[vm/sendport] Do port handler lookup and message dispatch in one dart call.
This improves performance of SendPort.Receive.Nop benchmark with isolate groups enabled on Intel Xeon by ~17%. This benchmark emphasizes performance of handle message flow. Issue #46752 TEST=ci Change-Id: I3b9be3283047631e8989bb56f90af2b3b007afe8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/209642 Commit-Queue: Alexander Aprelev <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 4c47fdb commit 386338e

File tree

4 files changed

+26
-35
lines changed

4 files changed

+26
-35
lines changed

runtime/vm/dart_entry.cc

+4-5
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ ObjectPtr DartLibraryCalls::LookupOpenPorts() {
727727
return result.ptr();
728728
}
729729

730-
ObjectPtr DartLibraryCalls::HandleMessage(const Object& handler,
730+
ObjectPtr DartLibraryCalls::HandleMessage(Dart_Port port_id,
731731
const Instance& message) {
732732
auto thread = Thread::Current();
733733
auto zone = thread->zone();
@@ -743,7 +743,7 @@ ObjectPtr DartLibraryCalls::HandleMessage(const Object& handler,
743743
args = Array::New(kNumArguments);
744744
isolate->isolate_object_store()->set_dart_args_2(args);
745745
}
746-
args.SetAt(0, handler);
746+
args.SetAt(0, Integer::Handle(zone, Integer::New(port_id)));
747747
args.SetAt(1, message);
748748
#if !defined(PRODUCT)
749749
if (isolate->debugger()->IsStepping()) {
@@ -753,10 +753,9 @@ ObjectPtr DartLibraryCalls::HandleMessage(const Object& handler,
753753
isolate->debugger()->SetResumeAction(Debugger::kStepInto);
754754
}
755755
#endif
756-
const Object& result =
756+
const Object& handler =
757757
Object::Handle(zone, DartEntry::InvokeFunction(function, args));
758-
ASSERT(result.IsNull() || result.IsError());
759-
return result.ptr();
758+
return handler.ptr();
760759
}
761760

762761
ObjectPtr DartLibraryCalls::DrainMicrotaskQueue() {

runtime/vm/dart_entry.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,13 @@ class DartLibraryCalls : public AllStatic {
291291
// Returns the handler if one has been registered for this port id.
292292
static ObjectPtr LookupHandler(Dart_Port port_id);
293293

294+
// Returns handler on success, an ErrorPtr on failure, null if can't find
295+
// handler for this port id.
296+
static ObjectPtr HandleMessage(Dart_Port port_id, const Instance& message);
297+
294298
// Returns a list of open ReceivePorts.
295299
static ObjectPtr LookupOpenPorts();
296300

297-
// Returns null on success, an ErrorPtr on failure.
298-
static ObjectPtr HandleMessage(const Object& handler,
299-
const Instance& dart_message);
300301

301302
// Returns null on success, an ErrorPtr on failure.
302303
static ObjectPtr DrainMicrotaskQueue();

runtime/vm/isolate.cc

+11-25
Original file line numberDiff line numberDiff line change
@@ -1307,26 +1307,6 @@ MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage(
13071307
tbes.CopyArgument(0, "isolateName", I->name());
13081308
#endif
13091309

1310-
// If the message is in band we lookup the handler to dispatch to. If the
1311-
// receive port was closed, we drop the message without deserializing it.
1312-
// Illegal port is a special case for artificially enqueued isolate library
1313-
// messages which are handled in C++ code below.
1314-
Object& msg_handler = Object::Handle(zone);
1315-
if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) {
1316-
msg_handler = DartLibraryCalls::LookupHandler(message->dest_port());
1317-
if (msg_handler.IsError()) {
1318-
return ProcessUnhandledException(Error::Cast(msg_handler));
1319-
}
1320-
if (msg_handler.IsNull()) {
1321-
// If the port has been closed then the message will be dropped at this
1322-
// point. Make sure to post to the delivery failure port in that case.
1323-
if (message->RedirectToDeliveryFailurePort()) {
1324-
PortMap::PostMessage(std::move(message));
1325-
}
1326-
return kOK;
1327-
}
1328-
}
1329-
13301310
// Parse the message.
13311311
Object& msg_obj = Object::Handle(zone, ReadMessage(thread, message.get()));
13321312
if (msg_obj.IsError()) {
@@ -1414,12 +1394,18 @@ MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage(
14141394
tbes.CopyArgument(1, "mode", "basic");
14151395
}
14161396
#endif
1417-
const Object& result =
1418-
Object::Handle(zone, DartLibraryCalls::HandleMessage(msg_handler, msg));
1419-
if (result.IsError()) {
1420-
status = ProcessUnhandledException(Error::Cast(result));
1397+
const Object& msg_handler = Object::Handle(
1398+
zone, DartLibraryCalls::HandleMessage(message->dest_port(), msg));
1399+
if (msg_handler.IsError()) {
1400+
status = ProcessUnhandledException(Error::Cast(msg_handler));
1401+
} else if (msg_handler.IsNull()) {
1402+
// If the port has been closed then the message will be dropped at this
1403+
// point. Make sure to post to the delivery failure port in that case.
1404+
if (message->RedirectToDeliveryFailurePort()) {
1405+
PortMap::PostMessage(std::move(message));
1406+
}
14211407
} else {
1422-
ASSERT(result.IsNull());
1408+
// The handler closure which was used to successfully handle the message.
14231409
}
14241410
}
14251411
return status;

sdk/lib/_internal/vm/lib/isolate_patch.dart

+7-2
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,19 @@ class _RawReceivePortImpl implements RawReceivePort {
175175
return _portMap.values.map((e) => e['port']).toList();
176176
}
177177

178-
// Called from the VM to dispatch to the handler.
178+
// Called from the VM to retrieve the handler and handle a message.
179179
@pragma("vm:entry-point", "call")
180-
static void _handleMessage(Function handler, var message) {
180+
static _handleMessage(int id, var message) {
181+
final handler = _portMap[id]?['handler'];
182+
if (handler == null) {
183+
return null;
184+
}
181185
// TODO(floitsch): this relies on the fact that any exception aborts the
182186
// VM. Once we have non-fatal global exceptions we need to catch errors
183187
// so that we can run the immediate callbacks.
184188
handler(message);
185189
_runPendingImmediateCallback();
190+
return handler;
186191
}
187192

188193
// Call into the VM to close the VM maintained mappings.

0 commit comments

Comments
 (0)