OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/message.h" | 5 #include "vm/message.h" |
6 | 6 |
| 7 #include "vm/dart_entry.h" |
| 8 #include "vm/json_stream.h" |
| 9 #include "vm/object.h" |
7 #include "vm/port.h" | 10 #include "vm/port.h" |
8 | 11 |
9 namespace dart { | 12 namespace dart { |
10 | 13 |
11 bool Message::RedirectToDeliveryFailurePort() { | 14 bool Message::RedirectToDeliveryFailurePort() { |
12 if (delivery_failure_port_ == kIllegalPort) { | 15 if (delivery_failure_port_ == kIllegalPort) { |
13 return false; | 16 return false; |
14 } | 17 } |
15 dest_port_ = delivery_failure_port_; | 18 dest_port_ = delivery_failure_port_; |
16 delivery_failure_port_ = kIllegalPort; | 19 delivery_failure_port_ = kIllegalPort; |
17 return true; | 20 return true; |
18 } | 21 } |
19 | 22 |
20 | 23 |
| 24 intptr_t Message::Id() const { |
| 25 // Messages are allocated on the C heap. Use the raw address as the id. |
| 26 return reinterpret_cast<intptr_t>(this); |
| 27 } |
| 28 |
| 29 const char* Message::PriorityAsString(Priority priority) { |
| 30 switch (priority) { |
| 31 case kNormalPriority: |
| 32 return "Normal"; |
| 33 break; |
| 34 case kOOBPriority: |
| 35 return "OOB"; |
| 36 break; |
| 37 default: |
| 38 UNIMPLEMENTED(); |
| 39 return NULL; |
| 40 } |
| 41 } |
| 42 |
| 43 |
21 MessageQueue::MessageQueue() { | 44 MessageQueue::MessageQueue() { |
22 head_ = NULL; | 45 head_ = NULL; |
23 tail_ = NULL; | 46 tail_ = NULL; |
24 } | 47 } |
25 | 48 |
26 | 49 |
27 MessageQueue::~MessageQueue() { | 50 MessageQueue::~MessageQueue() { |
28 // Ensure that all pending messages have been released. | 51 // Ensure that all pending messages have been released. |
29 Clear(); | 52 Clear(); |
30 ASSERT(head_ == NULL); | 53 ASSERT(head_ == NULL); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 if (cur->RedirectToDeliveryFailurePort()) { | 122 if (cur->RedirectToDeliveryFailurePort()) { |
100 PortMap::PostMessage(cur); | 123 PortMap::PostMessage(cur); |
101 } else { | 124 } else { |
102 delete cur; | 125 delete cur; |
103 } | 126 } |
104 cur = next; | 127 cur = next; |
105 } | 128 } |
106 } | 129 } |
107 | 130 |
108 | 131 |
| 132 MessageQueue::Iterator::Iterator(const MessageQueue* queue) |
| 133 : next_(NULL) { |
| 134 Reset(queue); |
| 135 } |
| 136 |
| 137 |
| 138 MessageQueue::Iterator::~Iterator() { |
| 139 } |
| 140 |
| 141 void MessageQueue::Iterator::Reset(const MessageQueue* queue) { |
| 142 ASSERT(queue != NULL); |
| 143 next_ = queue->head_; |
| 144 } |
| 145 |
| 146 // returns false when there are no more messages left. |
| 147 bool MessageQueue::Iterator::HasNext() { |
| 148 return next_ != NULL; |
| 149 } |
| 150 |
| 151 // Returns the current message and moves forward. |
| 152 Message* MessageQueue::Iterator::Next() { |
| 153 Message* current = next_; |
| 154 next_ = next_->next_; |
| 155 return current; |
| 156 } |
| 157 |
| 158 |
| 159 intptr_t MessageQueue::Length() const { |
| 160 MessageQueue::Iterator it(this); |
| 161 intptr_t length = 0; |
| 162 while (it.HasNext()) { |
| 163 it.Next(); |
| 164 length++; |
| 165 } |
| 166 return length; |
| 167 } |
| 168 |
| 169 |
| 170 Message* MessageQueue::FindMessageById(intptr_t id) { |
| 171 MessageQueue::Iterator it(this); |
| 172 while (it.HasNext()) { |
| 173 Message* current = it.Next(); |
| 174 ASSERT(current != NULL); |
| 175 if (current->Id() == id) { |
| 176 return current; |
| 177 } |
| 178 } |
| 179 return NULL; |
| 180 } |
| 181 |
| 182 |
| 183 void MessageQueue::PrintJSON(JSONStream* stream) { |
| 184 Isolate* isolate = Isolate::Current(); |
| 185 JSONArray messages(stream); |
| 186 |
| 187 Object& msg_handler = Object::Handle(isolate); |
| 188 |
| 189 MessageQueue::Iterator it(this); |
| 190 intptr_t depth = 0; |
| 191 while (it.HasNext()) { |
| 192 Message* current = it.Next(); |
| 193 JSONObject message(&messages); |
| 194 message.AddProperty("type", "Message"); |
| 195 message.AddPropertyF("name", "Isolate Message (%" Px ")", current->Id()); |
| 196 message.AddPropertyF("messageObjectId", "messages/%" Px "", |
| 197 current->Id()); |
| 198 message.AddProperty("size", current->len()); |
| 199 message.AddProperty("depth", depth++); |
| 200 message.AddProperty("_destinationPort", |
| 201 static_cast<intptr_t>(current->dest_port())); |
| 202 message.AddProperty("priority", |
| 203 Message::PriorityAsString(current->priority())); |
| 204 // TODO(johnmccutchan): Move port -> handler map out of Dart and into the |
| 205 // VM, that way we can lookup the handler without invoking Dart code. |
| 206 msg_handler = DartLibraryCalls::LookupHandler(current->dest_port()); |
| 207 if (msg_handler.IsInstance() && Instance::Cast(msg_handler).IsClosure()) { |
| 208 // Grab function from closure. |
| 209 msg_handler = Closure::function(Instance::Cast(msg_handler)); |
| 210 } |
| 211 if (!msg_handler.IsFunction()) { |
| 212 // No handler function. |
| 213 continue; |
| 214 } |
| 215 const Function& function = Function::Cast(msg_handler); |
| 216 const Script& script = Script::Handle(function.script()); |
| 217 message.AddProperty("handlerFunction", function); |
| 218 message.AddProperty("handlerScript", script); |
| 219 message.AddProperty("handlerTokenPos", function.token_pos()); |
| 220 } |
| 221 } |
| 222 |
109 } // namespace dart | 223 } // namespace dart |
OLD | NEW |