| Index: runtime/vm/isolate.cc
|
| ===================================================================
|
| --- runtime/vm/isolate.cc (revision 42173)
|
| +++ runtime/vm/isolate.cc (working copy)
|
| @@ -52,6 +52,21 @@
|
| #define I (isolate())
|
|
|
|
|
| +static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
|
| + void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
|
| + return reinterpret_cast<uint8_t*>(new_ptr);
|
| +}
|
| +
|
| +
|
| +static void SerializeObject(const Instance& obj,
|
| + uint8_t** obj_data,
|
| + intptr_t* obj_len) {
|
| + MessageWriter writer(obj_data, &allocator);
|
| + writer.WriteMessage(obj);
|
| + *obj_len = writer.BytesWritten();
|
| +}
|
| +
|
| +
|
| void Isolate::RegisterClass(const Class& cls) {
|
| class_table()->Register(cls);
|
| }
|
| @@ -89,7 +104,12 @@
|
| // Keep in sync with isolate_patch.dart.
|
| enum {
|
| kPauseMsg = 1,
|
| - kResumeMsg
|
| + kResumeMsg = 2,
|
| + kPingMsg = 3,
|
| +
|
| + kImmediateAction = 0,
|
| + kBeforeNextEventAction = 1,
|
| + kAsEventAction = 2
|
| };
|
|
|
| void HandleLibMessage(const Array& message);
|
| @@ -147,6 +167,50 @@
|
| }
|
| break;
|
| }
|
| + case kPingMsg: {
|
| + // [ OOB, kPingMsg, responsePort, pingType ]
|
| + if (message.Length() != 4) return;
|
| + const Object& obj2 = Object::Handle(I, message.At(2));
|
| + if (!obj2.IsSendPort()) return;
|
| + const SendPort& send_port = SendPort::Cast(obj2);
|
| + const Object& obj3 = Object::Handle(I, message.At(3));
|
| + if (!obj3.IsSmi()) return;
|
| + const intptr_t ping_type = Smi::Cast(obj3).Value();
|
| + if (ping_type == kImmediateAction) {
|
| + uint8_t* data = NULL;
|
| + intptr_t len = 0;
|
| + SerializeObject(Object::null_instance(), &data, &len);
|
| + PortMap::PostMessage(new Message(send_port.Id(),
|
| + data, len,
|
| + Message::kNormalPriority));
|
| + } else if (ping_type == kBeforeNextEventAction) {
|
| + // Update the message so that it will be handled immediately when it
|
| + // is picked up from the message queue the next time.
|
| + message.SetAt(
|
| + 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg)));
|
| + message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction)));
|
| + uint8_t* data = NULL;
|
| + intptr_t len = 0;
|
| + SerializeObject(message, &data, &len);
|
| + this->PostMessage(new Message(Message::kIllegalPort,
|
| + data, len,
|
| + Message::kNormalPriority),
|
| + true /* at_head */);
|
| + } else if (ping_type == kAsEventAction) {
|
| + // Update the message so that it will be handled immediately when it
|
| + // is picked up from the message queue the next time.
|
| + message.SetAt(
|
| + 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg)));
|
| + message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction)));
|
| + uint8_t* data = NULL;
|
| + intptr_t len = 0;
|
| + SerializeObject(message, &data, &len);
|
| + this->PostMessage(new Message(Message::kIllegalPort,
|
| + data, len,
|
| + Message::kNormalPriority));
|
| + }
|
| + break;
|
| + }
|
| #if defined(DEBUG)
|
| // Malformed OOB messages are silently ignored in release builds.
|
| default:
|
| @@ -180,8 +244,10 @@
|
|
|
| // If the message is in band we lookup the handler to dispatch to. If the
|
| // receive port was closed, we drop the message without deserializing it.
|
| + // Illegal port is a special case for artificially enqueued isolate library
|
| + // messages which are handled in C++ code below.
|
| Object& msg_handler = Object::Handle(I);
|
| - if (!message->IsOOB()) {
|
| + if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) {
|
| msg_handler = DartLibraryCalls::LookupHandler(message->dest_port());
|
| if (msg_handler.IsError()) {
|
| delete message;
|
| @@ -251,6 +317,20 @@
|
| }
|
| }
|
| }
|
| + } else if (message->dest_port() == Message::kIllegalPort) {
|
| + // Check whether this is a delayed OOB message which needed handling as
|
| + // part of the regular message dispatch. All other messages are dropped on
|
| + // the floor.
|
| + if (msg.IsArray()) {
|
| + const Array& msg_arr = Array::Cast(msg);
|
| + if (msg_arr.Length() > 0) {
|
| + const Object& oob_tag = Object::Handle(I, msg_arr.At(0));
|
| + if (oob_tag.IsSmi() &&
|
| + (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) {
|
| + HandleLibMessage(Array::Cast(msg_arr));
|
| + }
|
| + }
|
| + }
|
| } else {
|
| const Object& result = Object::Handle(I,
|
| DartLibraryCalls::HandleMessage(msg_handler, msg));
|
| @@ -1409,21 +1489,6 @@
|
| }
|
|
|
|
|
| -static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
|
| - void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
|
| - return reinterpret_cast<uint8_t*>(new_ptr);
|
| -}
|
| -
|
| -
|
| -static void SerializeObject(const Instance& obj,
|
| - uint8_t** obj_data,
|
| - intptr_t* obj_len) {
|
| - MessageWriter writer(obj_data, &allocator);
|
| - writer.WriteMessage(obj);
|
| - *obj_len = writer.BytesWritten();
|
| -}
|
| -
|
| -
|
| static RawInstance* DeserializeObject(Isolate* isolate,
|
| uint8_t* obj_data,
|
| intptr_t obj_len) {
|
|
|