| 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 |