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

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

Powered by Google App Engine
This is Rietveld 408576698