| Index: runtime/vm/message.cc
|
| diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
|
| index ea9b9861425510f59e1b38ca9e79ab209aad79b7..e5bc7ed9973eb084287f2abc75e2d4c8ea49614c 100644
|
| --- a/runtime/vm/message.cc
|
| +++ b/runtime/vm/message.cc
|
| @@ -4,6 +4,9 @@
|
|
|
| #include "vm/message.h"
|
|
|
| +#include "vm/dart_entry.h"
|
| +#include "vm/json_stream.h"
|
| +#include "vm/object.h"
|
| #include "vm/port.h"
|
|
|
| namespace dart {
|
| @@ -18,6 +21,26 @@ bool Message::RedirectToDeliveryFailurePort() {
|
| }
|
|
|
|
|
| +intptr_t Message::Id() const {
|
| + // Messages are allocated on the C heap. Use the raw address as the id.
|
| + return reinterpret_cast<intptr_t>(this);
|
| +}
|
| +
|
| +const char* Message::PriorityAsString(Priority priority) {
|
| + switch (priority) {
|
| + case kNormalPriority:
|
| + return "Normal";
|
| + break;
|
| + case kOOBPriority:
|
| + return "OOB";
|
| + break;
|
| + default:
|
| + UNIMPLEMENTED();
|
| + return NULL;
|
| + }
|
| +}
|
| +
|
| +
|
| MessageQueue::MessageQueue() {
|
| head_ = NULL;
|
| tail_ = NULL;
|
| @@ -106,4 +129,95 @@ void MessageQueue::Clear() {
|
| }
|
|
|
|
|
| +MessageQueue::Iterator::Iterator(const MessageQueue* queue)
|
| + : next_(NULL) {
|
| + Reset(queue);
|
| +}
|
| +
|
| +
|
| +MessageQueue::Iterator::~Iterator() {
|
| +}
|
| +
|
| +void MessageQueue::Iterator::Reset(const MessageQueue* queue) {
|
| + ASSERT(queue != NULL);
|
| + next_ = queue->head_;
|
| +}
|
| +
|
| +// returns false when there are no more messages left.
|
| +bool MessageQueue::Iterator::HasNext() {
|
| + return next_ != NULL;
|
| +}
|
| +
|
| +// Returns the current message and moves forward.
|
| +Message* MessageQueue::Iterator::Next() {
|
| + Message* current = next_;
|
| + next_ = next_->next_;
|
| + return current;
|
| +}
|
| +
|
| +
|
| +intptr_t MessageQueue::Length() const {
|
| + MessageQueue::Iterator it(this);
|
| + intptr_t length = 0;
|
| + while (it.HasNext()) {
|
| + it.Next();
|
| + length++;
|
| + }
|
| + return length;
|
| +}
|
| +
|
| +
|
| +Message* MessageQueue::FindMessageById(intptr_t id) {
|
| + MessageQueue::Iterator it(this);
|
| + while (it.HasNext()) {
|
| + Message* current = it.Next();
|
| + ASSERT(current != NULL);
|
| + if (current->Id() == id) {
|
| + return current;
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +void MessageQueue::PrintJSON(JSONStream* stream) {
|
| + Isolate* isolate = Isolate::Current();
|
| + JSONArray messages(stream);
|
| +
|
| + Object& msg_handler = Object::Handle(isolate);
|
| +
|
| + MessageQueue::Iterator it(this);
|
| + intptr_t depth = 0;
|
| + while (it.HasNext()) {
|
| + Message* current = it.Next();
|
| + JSONObject message(&messages);
|
| + message.AddProperty("type", "Message");
|
| + message.AddPropertyF("name", "Isolate Message (%" Px ")", current->Id());
|
| + message.AddPropertyF("messageObjectId", "messages/%" Px "",
|
| + current->Id());
|
| + message.AddProperty("size", current->len());
|
| + message.AddProperty("depth", depth++);
|
| + message.AddProperty("_destinationPort",
|
| + static_cast<intptr_t>(current->dest_port()));
|
| + message.AddProperty("priority",
|
| + Message::PriorityAsString(current->priority()));
|
| + // TODO(johnmccutchan): Move port -> handler map out of Dart and into the
|
| + // VM, that way we can lookup the handler without invoking Dart code.
|
| + msg_handler = DartLibraryCalls::LookupHandler(current->dest_port());
|
| + if (msg_handler.IsInstance() && Instance::Cast(msg_handler).IsClosure()) {
|
| + // Grab function from closure.
|
| + msg_handler = Closure::function(Instance::Cast(msg_handler));
|
| + }
|
| + if (!msg_handler.IsFunction()) {
|
| + // No handler function.
|
| + continue;
|
| + }
|
| + const Function& function = Function::Cast(msg_handler);
|
| + const Script& script = Script::Handle(function.script());
|
| + message.AddProperty("handlerFunction", function);
|
| + message.AddProperty("handlerScript", script);
|
| + message.AddProperty("handlerTokenPos", function.token_pos());
|
| + }
|
| +}
|
| +
|
| } // namespace dart
|
|
|