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

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: 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* SerializeObjectToMessage(
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 MessageWriter writer(&obj_data, &allocator, false);
148 writer.WriteMessage(obj);
149 obj_len = writer.BytesWritten();
Ivan Posva 2015/12/11 21:02:39 Why not call SerializeObject() here?
zra 2015/12/11 22:01:31 Done.
150 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority);
151 }
152 }
153
154
138 void Isolate::RegisterClass(const Class& cls) { 155 void Isolate::RegisterClass(const Class& cls) {
139 class_table()->Register(cls); 156 class_table()->Register(cls);
140 } 157 }
141 158
142 159
143 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { 160 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) {
144 class_table()->RegisterAt(index, cls); 161 class_table()->RegisterAt(index, cls);
145 } 162 }
146 163
147 164
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 if (!obj2.IsSendPort()) return Error::null(); 270 if (!obj2.IsSendPort()) return Error::null();
254 const SendPort& send_port = SendPort::Cast(obj2); 271 const SendPort& send_port = SendPort::Cast(obj2);
255 const Object& obj3 = Object::Handle(zone, message.At(3)); 272 const Object& obj3 = Object::Handle(zone, message.At(3));
256 if (!obj3.IsSmi()) return Error::null(); 273 if (!obj3.IsSmi()) return Error::null();
257 const intptr_t priority = Smi::Cast(obj3).Value(); 274 const intptr_t priority = Smi::Cast(obj3).Value();
258 const Object& obj4 = Object::Handle(zone, message.At(4)); 275 const Object& obj4 = Object::Handle(zone, message.At(4));
259 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); 276 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null();
260 const Instance& response = 277 const Instance& response =
261 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); 278 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4);
262 if (priority == Isolate::kImmediateAction) { 279 if (priority == Isolate::kImmediateAction) {
263 uint8_t* data = NULL; 280 PortMap::PostMessage(SerializeObjectToMessage(
264 intptr_t len = 0; 281 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 { 282 } else {
270 ASSERT((priority == Isolate::kBeforeNextEventAction) || 283 ASSERT((priority == Isolate::kBeforeNextEventAction) ||
271 (priority == Isolate::kAsEventAction)); 284 (priority == Isolate::kAsEventAction));
272 // Update the message so that it will be handled immediately when it 285 // Update the message so that it will be handled immediately when it
273 // is picked up from the message queue the next time. 286 // is picked up from the message queue the next time.
274 message.SetAt(0, Smi::Handle(zone, 287 message.SetAt(0, Smi::Handle(zone,
275 Smi::New(Message::kDelayedIsolateLibOOBMsg))); 288 Smi::New(Message::kDelayedIsolateLibOOBMsg)));
276 message.SetAt(3, Smi::Handle(zone, 289 message.SetAt(3, Smi::Handle(zone,
277 Smi::New(Isolate::kImmediateAction))); 290 Smi::New(Isolate::kImmediateAction)));
278 uint8_t* data = NULL; 291 this->PostMessage(SerializeObjectToMessage(
279 intptr_t len = 0; 292 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 */); 293 priority == Isolate::kBeforeNextEventAction /* at_head */);
286 } 294 }
287 break; 295 break;
288 } 296 }
289 case Isolate::kKillMsg: 297 case Isolate::kKillMsg:
290 case Isolate::kInternalKillMsg: 298 case Isolate::kInternalKillMsg:
291 case Isolate::kVMRestartMsg: { 299 case Isolate::kVMRestartMsg: {
292 // [ OOB, kKillMsg, terminate capability, priority ] 300 // [ OOB, kKillMsg, terminate capability, priority ]
293 if (message.Length() != 4) return Error::null(); 301 if (message.Length() != 4) return Error::null();
294 Object& obj = Object::Handle(zone, message.At(3)); 302 Object& obj = Object::Handle(zone, message.At(3));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 } 335 }
328 } else { 336 } else {
329 ASSERT((priority == Isolate::kBeforeNextEventAction) || 337 ASSERT((priority == Isolate::kBeforeNextEventAction) ||
330 (priority == Isolate::kAsEventAction)); 338 (priority == Isolate::kAsEventAction));
331 // Update the message so that it will be handled immediately when it 339 // Update the message so that it will be handled immediately when it
332 // is picked up from the message queue the next time. 340 // is picked up from the message queue the next time.
333 message.SetAt(0, Smi::Handle(zone, 341 message.SetAt(0, Smi::Handle(zone,
334 Smi::New(Message::kDelayedIsolateLibOOBMsg))); 342 Smi::New(Message::kDelayedIsolateLibOOBMsg)));
335 message.SetAt(3, Smi::Handle(zone, 343 message.SetAt(3, Smi::Handle(zone,
336 Smi::New(Isolate::kImmediateAction))); 344 Smi::New(Isolate::kImmediateAction)));
337 uint8_t* data = NULL; 345 this->PostMessage(SerializeObjectToMessage(
338 intptr_t len = 0; 346 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 */); 347 priority == Isolate::kBeforeNextEventAction /* at_head */);
345 } 348 }
346 break; 349 break;
347 } 350 }
348 case Isolate::kInterruptMsg: { 351 case Isolate::kInterruptMsg: {
349 // [ OOB, kInterruptMsg, pause capability ] 352 // [ OOB, kInterruptMsg, pause capability ]
350 if (message.Length() != 3) return Error::null(); 353 if (message.Length() != 3) return Error::null();
351 Object& obj = Object::Handle(zone, message.At(2)); 354 Object& obj = Object::Handle(zone, message.At(2));
352 if (!I->VerifyPauseCapability(obj)) return Error::null(); 355 if (!I->VerifyPauseCapability(obj)) return Error::null();
353 356
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 if (message->RedirectToDeliveryFailurePort()) { 464 if (message->RedirectToDeliveryFailurePort()) {
462 PortMap::PostMessage(message); 465 PortMap::PostMessage(message);
463 } else { 466 } else {
464 delete message; 467 delete message;
465 } 468 }
466 return kOK; 469 return kOK;
467 } 470 }
468 } 471 }
469 472
470 // Parse the message. 473 // Parse the message.
471 MessageSnapshotReader reader(message->data(), message->len(), thread); 474 Object& msg_obj = Object::Handle(zone);
472 const Object& msg_obj = Object::Handle(zone, reader.ReadObject()); 475 if (message->IsRaw()) {
476 msg_obj = message->raw_obj();
477 // We should only be sending RawObjects that can be converted to CObjects.
478 ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw()));
479 } else {
480 MessageSnapshotReader reader(message->data(), message->len(), thread);
481 msg_obj = reader.ReadObject();
482 }
473 if (msg_obj.IsError()) { 483 if (msg_obj.IsError()) {
474 // An error occurred while reading the message. 484 // An error occurred while reading the message.
475 delete message; 485 delete message;
476 return ProcessUnhandledException(Error::Cast(msg_obj)); 486 return ProcessUnhandledException(Error::Cast(msg_obj));
477 } 487 }
478 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { 488 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
479 // TODO(turnidge): We need to decide what an isolate does with 489 // TODO(turnidge): We need to decide what an isolate does with
480 // malformed messages. If they (eventually) come from a remote 490 // malformed messages. If they (eventually) come from a remote
481 // machine, then it might make sense to drop the message entirely. 491 // machine, then it might make sense to drop the message entirely.
482 // In the case that the message originated locally, which is 492 // In the case that the message originated locally, which is
483 // always true for now, then this should never occur. 493 // always true for now, then this should never occur.
484 UNREACHABLE(); 494 UNREACHABLE();
485 } 495 }
486
487 Instance& msg = Instance::Handle(zone); 496 Instance& msg = Instance::Handle(zone);
488 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. 497 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null.
489 498
490 MessageStatus status = kOK; 499 MessageStatus status = kOK;
491 if (message->IsOOB()) { 500 if (message->IsOOB()) {
492 // OOB messages are expected to be fixed length arrays where the first 501 // 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 502 // element is a Smi describing the OOB destination. Messages that do not
494 // confirm to this layout are silently ignored. 503 // confirm to this layout are silently ignored.
495 if (msg.IsArray()) { 504 if (msg.IsArray()) {
496 const Array& oob_msg = Array::Cast(msg); 505 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( 1205 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
1197 current_zone(), this->object_store()->exit_listeners()); 1206 current_zone(), this->object_store()->exit_listeners());
1198 if (listeners.IsNull()) return; 1207 if (listeners.IsNull()) return;
1199 1208
1200 SendPort& listener = SendPort::Handle(current_zone()); 1209 SendPort& listener = SendPort::Handle(current_zone());
1201 Instance& response = Instance::Handle(current_zone()); 1210 Instance& response = Instance::Handle(current_zone());
1202 for (intptr_t i = 0; i < listeners.Length(); i += 2) { 1211 for (intptr_t i = 0; i < listeners.Length(); i += 2) {
1203 listener ^= listeners.At(i); 1212 listener ^= listeners.At(i);
1204 if (!listener.IsNull()) { 1213 if (!listener.IsNull()) {
1205 Dart_Port port_id = listener.Id(); 1214 Dart_Port port_id = listener.Id();
1206 uint8_t* data = NULL;
1207 intptr_t len = 0;
1208 response ^= listeners.At(i + 1); 1215 response ^= listeners.At(i + 1);
1209 SerializeObject(response, &data, &len, false); 1216 PortMap::PostMessage(SerializeObjectToMessage(port_id, response));
Ivan Posva 2015/12/11 21:02:39 How about shortening the name SerializeMessage?
zra 2015/12/11 22:01:31 Done.
1210 Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
1211 PortMap::PostMessage(msg);
1212 } 1217 }
1213 } 1218 }
1214 } 1219 }
1215 1220
1216 1221
1217 void Isolate::AddErrorListener(const SendPort& listener) { 1222 void Isolate::AddErrorListener(const SendPort& listener) {
1218 // Ensure a limit for the number of listeners remembered. 1223 // Ensure a limit for the number of listeners remembered.
1219 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); 1224 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize);
1220 1225
1221 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( 1226 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 if (listeners.IsNull()) return false; 1274 if (listeners.IsNull()) return false;
1270 1275
1271 const Array& arr = Array::Handle(current_zone(), Array::New(2)); 1276 const Array& arr = Array::Handle(current_zone(), Array::New(2));
1272 arr.SetAt(0, msg); 1277 arr.SetAt(0, msg);
1273 arr.SetAt(1, stacktrace); 1278 arr.SetAt(1, stacktrace);
1274 SendPort& listener = SendPort::Handle(current_zone()); 1279 SendPort& listener = SendPort::Handle(current_zone());
1275 for (intptr_t i = 0; i < listeners.Length(); i++) { 1280 for (intptr_t i = 0; i < listeners.Length(); i++) {
1276 listener ^= listeners.At(i); 1281 listener ^= listeners.At(i);
1277 if (!listener.IsNull()) { 1282 if (!listener.IsNull()) {
1278 Dart_Port port_id = listener.Id(); 1283 Dart_Port port_id = listener.Id();
1279 uint8_t* data = NULL; 1284 PortMap::PostMessage(SerializeObjectToMessage(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 } 1285 }
1285 } 1286 }
1286 return listeners.Length() > 0; 1287 return listeners.Length() > 0;
1287 } 1288 }
1288 1289
1289 1290
1290 static MessageHandler::MessageStatus RunIsolate(uword parameter) { 1291 static MessageHandler::MessageStatus RunIsolate(uword parameter) {
1291 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); 1292 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
1292 IsolateSpawnState* state = NULL; 1293 IsolateSpawnState* state = NULL;
1293 { 1294 {
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after
2494 } 2495 }
2495 2496
2496 2497
2497 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { 2498 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
2498 return DeserializeObject(thread, 2499 return DeserializeObject(thread,
2499 serialized_message_, serialized_message_len_); 2500 serialized_message_, serialized_message_len_);
2500 } 2501 }
2501 2502
2502 2503
2503 } // namespace dart 2504 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698