Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: runtime/vm/isolate.cc

Issue 1499853004: Adds a special case for sending an int over a port with the native API. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/isolate.h" 5 #include "vm/isolate.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "include/dart_native_api.h" 8 #include "include/dart_native_api.h"
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "platform/text_buffer.h" 10 #include "platform/text_buffer.h"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 static void SerializeObject(const Instance& obj, 128 static void SerializeObject(const Instance& obj,
129 uint8_t** obj_data, 129 uint8_t** obj_data,
130 intptr_t* obj_len, 130 intptr_t* obj_len,
131 bool allow_any_object) { 131 bool allow_any_object) {
132 MessageWriter writer(obj_data, &allocator, allow_any_object); 132 MessageWriter writer(obj_data, &allocator, allow_any_object);
133 writer.WriteMessage(obj); 133 writer.WriteMessage(obj);
134 *obj_len = writer.BytesWritten(); 134 *obj_len = writer.BytesWritten();
135 } 135 }
136 136
137 137
138 static Message* SerializeMessage(
turnidge 2015/12/11 22:30:48 Instead of having this helper function, how about
Ivan Posva 2015/12/11 22:53:39 Todd, I tend to agree with your concern about the
zra 2015/12/11 23:44:32 Added TODO here.
139 Dart_Port dest_port, const Instance& obj) {
140 if (ApiObjectConverter::CanConvert(obj.raw())) {
141 return new Message(dest_port,
142 reinterpret_cast<uint8_t*>(obj.raw()), 0,
143 Message::kNormalPriority);
144 } else {
145 uint8_t* obj_data;
146 intptr_t obj_len;
147 SerializeObject(obj, &obj_data, &obj_len, false);
148 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority);
149 }
150 }
151
152
138 void Isolate::RegisterClass(const Class& cls) { 153 void Isolate::RegisterClass(const Class& cls) {
139 class_table()->Register(cls); 154 class_table()->Register(cls);
140 } 155 }
141 156
142 157
143 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { 158 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) {
144 class_table()->RegisterAt(index, cls); 159 class_table()->RegisterAt(index, cls);
145 } 160 }
146 161
147 162
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 if (!obj2.IsSendPort()) return Error::null(); 268 if (!obj2.IsSendPort()) return Error::null();
254 const SendPort& send_port = SendPort::Cast(obj2); 269 const SendPort& send_port = SendPort::Cast(obj2);
255 const Object& obj3 = Object::Handle(zone, message.At(3)); 270 const Object& obj3 = Object::Handle(zone, message.At(3));
256 if (!obj3.IsSmi()) return Error::null(); 271 if (!obj3.IsSmi()) return Error::null();
257 const intptr_t priority = Smi::Cast(obj3).Value(); 272 const intptr_t priority = Smi::Cast(obj3).Value();
258 const Object& obj4 = Object::Handle(zone, message.At(4)); 273 const Object& obj4 = Object::Handle(zone, message.At(4));
259 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); 274 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null();
260 const Instance& response = 275 const Instance& response =
261 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); 276 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4);
262 if (priority == Isolate::kImmediateAction) { 277 if (priority == Isolate::kImmediateAction) {
263 uint8_t* data = NULL; 278 PortMap::PostMessage(SerializeMessage(
264 intptr_t len = 0; 279 send_port.Id(), response));
265 SerializeObject(response, &data, &len, false);
266 PortMap::PostMessage(new Message(send_port.Id(),
267 data, len,
268 Message::kNormalPriority));
269 } else { 280 } else {
270 ASSERT((priority == Isolate::kBeforeNextEventAction) || 281 ASSERT((priority == Isolate::kBeforeNextEventAction) ||
271 (priority == Isolate::kAsEventAction)); 282 (priority == Isolate::kAsEventAction));
272 // Update the message so that it will be handled immediately when it 283 // Update the message so that it will be handled immediately when it
273 // is picked up from the message queue the next time. 284 // is picked up from the message queue the next time.
274 message.SetAt(0, Smi::Handle(zone, 285 message.SetAt(0, Smi::Handle(zone,
275 Smi::New(Message::kDelayedIsolateLibOOBMsg))); 286 Smi::New(Message::kDelayedIsolateLibOOBMsg)));
276 message.SetAt(3, Smi::Handle(zone, 287 message.SetAt(3, Smi::Handle(zone,
277 Smi::New(Isolate::kImmediateAction))); 288 Smi::New(Isolate::kImmediateAction)));
278 uint8_t* data = NULL; 289 this->PostMessage(SerializeMessage(
279 intptr_t len = 0; 290 Message::kIllegalPort, message),
280 SerializeObject(message, &data, &len, false);
281 this->PostMessage(
282 new Message(Message::kIllegalPort,
283 data, len,
284 Message::kNormalPriority),
285 priority == Isolate::kBeforeNextEventAction /* at_head */); 291 priority == Isolate::kBeforeNextEventAction /* at_head */);
286 } 292 }
287 break; 293 break;
288 } 294 }
289 case Isolate::kKillMsg: 295 case Isolate::kKillMsg:
290 case Isolate::kInternalKillMsg: 296 case Isolate::kInternalKillMsg:
291 case Isolate::kVMRestartMsg: { 297 case Isolate::kVMRestartMsg: {
292 // [ OOB, kKillMsg, terminate capability, priority ] 298 // [ OOB, kKillMsg, terminate capability, priority ]
293 if (message.Length() != 4) return Error::null(); 299 if (message.Length() != 4) return Error::null();
294 Object& obj = Object::Handle(zone, message.At(3)); 300 Object& obj = Object::Handle(zone, message.At(3));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 } 333 }
328 } else { 334 } else {
329 ASSERT((priority == Isolate::kBeforeNextEventAction) || 335 ASSERT((priority == Isolate::kBeforeNextEventAction) ||
330 (priority == Isolate::kAsEventAction)); 336 (priority == Isolate::kAsEventAction));
331 // Update the message so that it will be handled immediately when it 337 // Update the message so that it will be handled immediately when it
332 // is picked up from the message queue the next time. 338 // is picked up from the message queue the next time.
333 message.SetAt(0, Smi::Handle(zone, 339 message.SetAt(0, Smi::Handle(zone,
334 Smi::New(Message::kDelayedIsolateLibOOBMsg))); 340 Smi::New(Message::kDelayedIsolateLibOOBMsg)));
335 message.SetAt(3, Smi::Handle(zone, 341 message.SetAt(3, Smi::Handle(zone,
336 Smi::New(Isolate::kImmediateAction))); 342 Smi::New(Isolate::kImmediateAction)));
337 uint8_t* data = NULL; 343 this->PostMessage(SerializeMessage(
338 intptr_t len = 0; 344 Message::kIllegalPort, message),
339 SerializeObject(message, &data, &len, false);
340 this->PostMessage(
341 new Message(Message::kIllegalPort,
342 data, len,
343 Message::kNormalPriority),
344 priority == Isolate::kBeforeNextEventAction /* at_head */); 345 priority == Isolate::kBeforeNextEventAction /* at_head */);
345 } 346 }
346 break; 347 break;
347 } 348 }
348 case Isolate::kInterruptMsg: { 349 case Isolate::kInterruptMsg: {
349 // [ OOB, kInterruptMsg, pause capability ] 350 // [ OOB, kInterruptMsg, pause capability ]
350 if (message.Length() != 3) return Error::null(); 351 if (message.Length() != 3) return Error::null();
351 Object& obj = Object::Handle(zone, message.At(2)); 352 Object& obj = Object::Handle(zone, message.At(2));
352 if (!I->VerifyPauseCapability(obj)) return Error::null(); 353 if (!I->VerifyPauseCapability(obj)) return Error::null();
353 354
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 if (message->RedirectToDeliveryFailurePort()) { 462 if (message->RedirectToDeliveryFailurePort()) {
462 PortMap::PostMessage(message); 463 PortMap::PostMessage(message);
463 } else { 464 } else {
464 delete message; 465 delete message;
465 } 466 }
466 return kOK; 467 return kOK;
467 } 468 }
468 } 469 }
469 470
470 // Parse the message. 471 // Parse the message.
471 MessageSnapshotReader reader(message->data(), message->len(), thread); 472 Object& msg_obj = Object::Handle(zone);
472 const Object& msg_obj = Object::Handle(zone, reader.ReadObject()); 473 if (message->IsRaw()) {
474 msg_obj = message->raw_obj();
475 // We should only be sending RawObjects that can be converted to CObjects.
476 ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw()));
477 } else {
478 MessageSnapshotReader reader(message->data(), message->len(), thread);
479 msg_obj = reader.ReadObject();
480 }
473 if (msg_obj.IsError()) { 481 if (msg_obj.IsError()) {
474 // An error occurred while reading the message. 482 // An error occurred while reading the message.
475 delete message; 483 delete message;
476 return ProcessUnhandledException(Error::Cast(msg_obj)); 484 return ProcessUnhandledException(Error::Cast(msg_obj));
477 } 485 }
478 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { 486 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
479 // TODO(turnidge): We need to decide what an isolate does with 487 // TODO(turnidge): We need to decide what an isolate does with
480 // malformed messages. If they (eventually) come from a remote 488 // malformed messages. If they (eventually) come from a remote
481 // machine, then it might make sense to drop the message entirely. 489 // machine, then it might make sense to drop the message entirely.
482 // In the case that the message originated locally, which is 490 // In the case that the message originated locally, which is
483 // always true for now, then this should never occur. 491 // always true for now, then this should never occur.
484 UNREACHABLE(); 492 UNREACHABLE();
485 } 493 }
486
487 Instance& msg = Instance::Handle(zone); 494 Instance& msg = Instance::Handle(zone);
488 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. 495 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null.
489 496
490 MessageStatus status = kOK; 497 MessageStatus status = kOK;
491 if (message->IsOOB()) { 498 if (message->IsOOB()) {
492 // OOB messages are expected to be fixed length arrays where the first 499 // OOB messages are expected to be fixed length arrays where the first
493 // element is a Smi describing the OOB destination. Messages that do not 500 // element is a Smi describing the OOB destination. Messages that do not
494 // confirm to this layout are silently ignored. 501 // confirm to this layout are silently ignored.
495 if (msg.IsArray()) { 502 if (msg.IsArray()) {
496 const Array& oob_msg = Array::Cast(msg); 503 const Array& oob_msg = Array::Cast(msg);
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( 1203 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
1197 current_zone(), this->object_store()->exit_listeners()); 1204 current_zone(), this->object_store()->exit_listeners());
1198 if (listeners.IsNull()) return; 1205 if (listeners.IsNull()) return;
1199 1206
1200 SendPort& listener = SendPort::Handle(current_zone()); 1207 SendPort& listener = SendPort::Handle(current_zone());
1201 Instance& response = Instance::Handle(current_zone()); 1208 Instance& response = Instance::Handle(current_zone());
1202 for (intptr_t i = 0; i < listeners.Length(); i += 2) { 1209 for (intptr_t i = 0; i < listeners.Length(); i += 2) {
1203 listener ^= listeners.At(i); 1210 listener ^= listeners.At(i);
1204 if (!listener.IsNull()) { 1211 if (!listener.IsNull()) {
1205 Dart_Port port_id = listener.Id(); 1212 Dart_Port port_id = listener.Id();
1206 uint8_t* data = NULL;
1207 intptr_t len = 0;
1208 response ^= listeners.At(i + 1); 1213 response ^= listeners.At(i + 1);
1209 SerializeObject(response, &data, &len, false); 1214 PortMap::PostMessage(SerializeMessage(port_id, response));
1210 Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
1211 PortMap::PostMessage(msg);
1212 } 1215 }
1213 } 1216 }
1214 } 1217 }
1215 1218
1216 1219
1217 void Isolate::AddErrorListener(const SendPort& listener) { 1220 void Isolate::AddErrorListener(const SendPort& listener) {
1218 // Ensure a limit for the number of listeners remembered. 1221 // Ensure a limit for the number of listeners remembered.
1219 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); 1222 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize);
1220 1223
1221 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( 1224 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 if (listeners.IsNull()) return false; 1272 if (listeners.IsNull()) return false;
1270 1273
1271 const Array& arr = Array::Handle(current_zone(), Array::New(2)); 1274 const Array& arr = Array::Handle(current_zone(), Array::New(2));
1272 arr.SetAt(0, msg); 1275 arr.SetAt(0, msg);
1273 arr.SetAt(1, stacktrace); 1276 arr.SetAt(1, stacktrace);
1274 SendPort& listener = SendPort::Handle(current_zone()); 1277 SendPort& listener = SendPort::Handle(current_zone());
1275 for (intptr_t i = 0; i < listeners.Length(); i++) { 1278 for (intptr_t i = 0; i < listeners.Length(); i++) {
1276 listener ^= listeners.At(i); 1279 listener ^= listeners.At(i);
1277 if (!listener.IsNull()) { 1280 if (!listener.IsNull()) {
1278 Dart_Port port_id = listener.Id(); 1281 Dart_Port port_id = listener.Id();
1279 uint8_t* data = NULL; 1282 PortMap::PostMessage(SerializeMessage(port_id, arr));
1280 intptr_t len = 0;
1281 SerializeObject(arr, &data, &len, false);
1282 Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
1283 PortMap::PostMessage(msg);
1284 } 1283 }
1285 } 1284 }
1286 return listeners.Length() > 0; 1285 return listeners.Length() > 0;
1287 } 1286 }
1288 1287
1289 1288
1290 static MessageHandler::MessageStatus RunIsolate(uword parameter) { 1289 static MessageHandler::MessageStatus RunIsolate(uword parameter) {
1291 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); 1290 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
1292 IsolateSpawnState* state = NULL; 1291 IsolateSpawnState* state = NULL;
1293 { 1292 {
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after
2494 } 2493 }
2495 2494
2496 2495
2497 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { 2496 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
2498 return DeserializeObject(thread, 2497 return DeserializeObject(thread,
2499 serialized_message_, serialized_message_len_); 2498 serialized_message_, serialized_message_len_);
2500 } 2499 }
2501 2500
2502 2501
2503 } // namespace dart 2502 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698