Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |