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 "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "platform/json.h" | 9 #include "platform/json.h" |
10 #include "vm/code_observers.h" | 10 #include "vm/code_observers.h" |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 } | 373 } |
374 Dart_MessageNotifyCallback callback = I->message_notify_callback(); | 374 Dart_MessageNotifyCallback callback = I->message_notify_callback(); |
375 if (callback) { | 375 if (callback) { |
376 // Allow the embedder to handle message notification. | 376 // Allow the embedder to handle message notification. |
377 (*callback)(Api::CastIsolate(I)); | 377 (*callback)(Api::CastIsolate(I)); |
378 } | 378 } |
379 } | 379 } |
380 | 380 |
381 | 381 |
382 bool IsolateMessageHandler::HandleMessage(Message* message) { | 382 bool IsolateMessageHandler::HandleMessage(Message* message) { |
383 StackZone zone(I); | 383 ASSERT(IsCurrentIsolate()); |
384 HandleScope handle_scope(I); | 384 Thread* thread = Thread::Current(); |
385 TimelineDurationScope tds(I, I->GetIsolateStream(), "HandleMessage"); | 385 StackZone stack_zone(thread); |
| 386 Zone* zone = stack_zone.GetZone(); |
| 387 HandleScope handle_scope(thread); |
| 388 TimelineDurationScope tds(thread, I->GetIsolateStream(), "HandleMessage"); |
386 tds.SetNumArguments(1); | 389 tds.SetNumArguments(1); |
387 tds.CopyArgument(0, "isolateName", I->name()); | 390 tds.CopyArgument(0, "isolateName", I->name()); |
388 | 391 |
389 // TODO(turnidge): Rework collection total dart execution. This can | 392 // TODO(turnidge): Rework collection total dart execution. This can |
390 // overcount when other things (gc, compilation) are active. | 393 // overcount when other things (gc, compilation) are active. |
391 TIMERSCOPE(isolate_, time_dart_execution); | 394 TIMERSCOPE(thread, time_dart_execution); |
392 | 395 |
393 // If the message is in band we lookup the handler to dispatch to. If the | 396 // If the message is in band we lookup the handler to dispatch to. If the |
394 // receive port was closed, we drop the message without deserializing it. | 397 // receive port was closed, we drop the message without deserializing it. |
395 // Illegal port is a special case for artificially enqueued isolate library | 398 // Illegal port is a special case for artificially enqueued isolate library |
396 // messages which are handled in C++ code below. | 399 // messages which are handled in C++ code below. |
397 Object& msg_handler = Object::Handle(I); | 400 Object& msg_handler = Object::Handle(zone); |
398 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { | 401 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { |
399 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); | 402 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); |
400 if (msg_handler.IsError()) { | 403 if (msg_handler.IsError()) { |
401 delete message; | 404 delete message; |
402 return ProcessUnhandledException(Error::Cast(msg_handler)); | 405 return ProcessUnhandledException(Error::Cast(msg_handler)); |
403 } | 406 } |
404 if (msg_handler.IsNull()) { | 407 if (msg_handler.IsNull()) { |
405 // If the port has been closed then the message will be dropped at this | 408 // If the port has been closed then the message will be dropped at this |
406 // point. Make sure to post to the delivery failure port in that case. | 409 // point. Make sure to post to the delivery failure port in that case. |
407 if (message->RedirectToDeliveryFailurePort()) { | 410 if (message->RedirectToDeliveryFailurePort()) { |
408 PortMap::PostMessage(message); | 411 PortMap::PostMessage(message); |
409 } else { | 412 } else { |
410 delete message; | 413 delete message; |
411 } | 414 } |
412 return true; | 415 return true; |
413 } | 416 } |
414 } | 417 } |
415 | 418 |
416 // Parse the message. | 419 // Parse the message. |
417 MessageSnapshotReader reader(message->data(), | 420 MessageSnapshotReader reader(message->data(), |
418 message->len(), | 421 message->len(), |
419 I, zone.GetZone()); | 422 I, zone); |
420 const Object& msg_obj = Object::Handle(I, reader.ReadObject()); | 423 const Object& msg_obj = Object::Handle(zone, reader.ReadObject()); |
421 if (msg_obj.IsError()) { | 424 if (msg_obj.IsError()) { |
422 // An error occurred while reading the message. | 425 // An error occurred while reading the message. |
423 delete message; | 426 delete message; |
424 return ProcessUnhandledException(Error::Cast(msg_obj)); | 427 return ProcessUnhandledException(Error::Cast(msg_obj)); |
425 } | 428 } |
426 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { | 429 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { |
427 // TODO(turnidge): We need to decide what an isolate does with | 430 // TODO(turnidge): We need to decide what an isolate does with |
428 // malformed messages. If they (eventually) come from a remote | 431 // malformed messages. If they (eventually) come from a remote |
429 // machine, then it might make sense to drop the message entirely. | 432 // machine, then it might make sense to drop the message entirely. |
430 // In the case that the message originated locally, which is | 433 // In the case that the message originated locally, which is |
431 // always true for now, then this should never occur. | 434 // always true for now, then this should never occur. |
432 UNREACHABLE(); | 435 UNREACHABLE(); |
433 } | 436 } |
434 | 437 |
435 Instance& msg = Instance::Handle(I); | 438 Instance& msg = Instance::Handle(zone); |
436 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. | 439 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. |
437 | 440 |
438 bool success = true; | 441 bool success = true; |
439 if (message->IsOOB()) { | 442 if (message->IsOOB()) { |
440 // OOB messages are expected to be fixed length arrays where the first | 443 // OOB messages are expected to be fixed length arrays where the first |
441 // element is a Smi describing the OOB destination. Messages that do not | 444 // element is a Smi describing the OOB destination. Messages that do not |
442 // confirm to this layout are silently ignored. | 445 // confirm to this layout are silently ignored. |
443 if (msg.IsArray()) { | 446 if (msg.IsArray()) { |
444 const Array& oob_msg = Array::Cast(msg); | 447 const Array& oob_msg = Array::Cast(msg); |
445 if (oob_msg.Length() > 0) { | 448 if (oob_msg.Length() > 0) { |
446 const Object& oob_tag = Object::Handle(I, oob_msg.At(0)); | 449 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); |
447 if (oob_tag.IsSmi()) { | 450 if (oob_tag.IsSmi()) { |
448 switch (Smi::Cast(oob_tag).Value()) { | 451 switch (Smi::Cast(oob_tag).Value()) { |
449 case Message::kServiceOOBMsg: { | 452 case Message::kServiceOOBMsg: { |
450 Service::HandleIsolateMessage(I, oob_msg); | 453 Service::HandleIsolateMessage(I, oob_msg); |
451 break; | 454 break; |
452 } | 455 } |
453 case Message::kIsolateLibOOBMsg: { | 456 case Message::kIsolateLibOOBMsg: { |
454 success = HandleLibMessage(oob_msg); | 457 success = HandleLibMessage(oob_msg); |
455 break; | 458 break; |
456 } | 459 } |
457 #if defined(DEBUG) | 460 #if defined(DEBUG) |
458 // Malformed OOB messages are silently ignored in release builds. | 461 // Malformed OOB messages are silently ignored in release builds. |
459 default: { | 462 default: { |
460 UNREACHABLE(); | 463 UNREACHABLE(); |
461 break; | 464 break; |
462 } | 465 } |
463 #endif // defined(DEBUG) | 466 #endif // defined(DEBUG) |
464 } | 467 } |
465 } | 468 } |
466 } | 469 } |
467 } | 470 } |
468 } else if (message->dest_port() == Message::kIllegalPort) { | 471 } else if (message->dest_port() == Message::kIllegalPort) { |
469 // Check whether this is a delayed OOB message which needed handling as | 472 // Check whether this is a delayed OOB message which needed handling as |
470 // part of the regular message dispatch. All other messages are dropped on | 473 // part of the regular message dispatch. All other messages are dropped on |
471 // the floor. | 474 // the floor. |
472 if (msg.IsArray()) { | 475 if (msg.IsArray()) { |
473 const Array& msg_arr = Array::Cast(msg); | 476 const Array& msg_arr = Array::Cast(msg); |
474 if (msg_arr.Length() > 0) { | 477 if (msg_arr.Length() > 0) { |
475 const Object& oob_tag = Object::Handle(I, msg_arr.At(0)); | 478 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); |
476 if (oob_tag.IsSmi() && | 479 if (oob_tag.IsSmi() && |
477 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { | 480 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { |
478 success = HandleLibMessage(Array::Cast(msg_arr)); | 481 success = HandleLibMessage(Array::Cast(msg_arr)); |
479 } | 482 } |
480 } | 483 } |
481 } | 484 } |
482 } else { | 485 } else { |
483 const Object& result = Object::Handle(I, | 486 const Object& result = Object::Handle(zone, |
484 DartLibraryCalls::HandleMessage(msg_handler, msg)); | 487 DartLibraryCalls::HandleMessage(msg_handler, msg)); |
485 if (result.IsError()) { | 488 if (result.IsError()) { |
486 success = ProcessUnhandledException(Error::Cast(result)); | 489 success = ProcessUnhandledException(Error::Cast(result)); |
487 } else { | 490 } else { |
488 ASSERT(result.IsNull()); | 491 ASSERT(result.IsNull()); |
489 } | 492 } |
490 } | 493 } |
491 delete message; | 494 delete message; |
492 return success; | 495 return success; |
493 } | 496 } |
(...skipping 1649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2143 serialized_message_, serialized_message_len_); | 2146 serialized_message_, serialized_message_len_); |
2144 } | 2147 } |
2145 | 2148 |
2146 | 2149 |
2147 void IsolateSpawnState::Cleanup() { | 2150 void IsolateSpawnState::Cleanup() { |
2148 SwitchIsolateScope switch_scope(I); | 2151 SwitchIsolateScope switch_scope(I); |
2149 Dart::ShutdownIsolate(); | 2152 Dart::ShutdownIsolate(); |
2150 } | 2153 } |
2151 | 2154 |
2152 } // namespace dart | 2155 } // namespace dart |
OLD | NEW |