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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 Object& obj = Object::Handle(I, message.At(2)); | 195 Object& obj = Object::Handle(I, message.At(2)); |
196 if (!I->VerifyPauseCapability(obj)) return true; | 196 if (!I->VerifyPauseCapability(obj)) return true; |
197 obj = message.At(3); | 197 obj = message.At(3); |
198 if (!obj.IsCapability()) return true; | 198 if (!obj.IsCapability()) return true; |
199 if (I->RemoveResumeCapability(Capability::Cast(obj))) { | 199 if (I->RemoveResumeCapability(Capability::Cast(obj))) { |
200 decrement_paused(); | 200 decrement_paused(); |
201 } | 201 } |
202 break; | 202 break; |
203 } | 203 } |
204 case kPingMsg: { | 204 case kPingMsg: { |
205 // [ OOB, kPingMsg, responsePort, priority ] | 205 // [ OOB, kPingMsg, responsePort, priority, response ] |
206 if (message.Length() != 4) return true; | 206 if (message.Length() != 5) return true; |
207 const Object& obj2 = Object::Handle(I, message.At(2)); | 207 const Object& obj2 = Object::Handle(I, message.At(2)); |
208 if (!obj2.IsSendPort()) return true; | 208 if (!obj2.IsSendPort()) return true; |
209 const SendPort& send_port = SendPort::Cast(obj2); | 209 const SendPort& send_port = SendPort::Cast(obj2); |
210 const Object& obj3 = Object::Handle(I, message.At(3)); | 210 const Object& obj3 = Object::Handle(I, message.At(3)); |
211 if (!obj3.IsSmi()) return true; | 211 if (!obj3.IsSmi()) return true; |
212 const intptr_t priority = Smi::Cast(obj3).Value(); | 212 const intptr_t priority = Smi::Cast(obj3).Value(); |
| 213 const Object& obj4 = Object::Handle(I, message.At(4)); |
| 214 if (!obj4.IsInstance() && !obj4.IsNull()) return true; |
| 215 const Instance& response = |
| 216 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); |
213 if (priority == kImmediateAction) { | 217 if (priority == kImmediateAction) { |
214 uint8_t* data = NULL; | 218 uint8_t* data = NULL; |
215 intptr_t len = 0; | 219 intptr_t len = 0; |
216 SerializeObject(Object::null_instance(), &data, &len, false); | 220 SerializeObject(response, &data, &len, false); |
217 PortMap::PostMessage(new Message(send_port.Id(), | 221 PortMap::PostMessage(new Message(send_port.Id(), |
218 data, len, | 222 data, len, |
219 Message::kNormalPriority)); | 223 Message::kNormalPriority)); |
220 } else { | 224 } else { |
221 ASSERT((priority == kBeforeNextEventAction) || | 225 ASSERT((priority == kBeforeNextEventAction) || |
222 (priority == kAsEventAction)); | 226 (priority == kAsEventAction)); |
223 // Update the message so that it will be handled immediately when it | 227 // Update the message so that it will be handled immediately when it |
224 // is picked up from the message queue the next time. | 228 // is picked up from the message queue the next time. |
225 message.SetAt( | 229 message.SetAt( |
226 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 230 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 Message::kNormalPriority), | 265 Message::kNormalPriority), |
262 priority == kBeforeNextEventAction /* at_head */); | 266 priority == kBeforeNextEventAction /* at_head */); |
263 } | 267 } |
264 break; | 268 break; |
265 } | 269 } |
266 case kAddExitMsg: | 270 case kAddExitMsg: |
267 case kDelExitMsg: | 271 case kDelExitMsg: |
268 case kAddErrorMsg: | 272 case kAddErrorMsg: |
269 case kDelErrorMsg: { | 273 case kDelErrorMsg: { |
270 // [ OOB, msg, listener port ] | 274 // [ OOB, msg, listener port ] |
271 if (message.Length() != 3) return true; | 275 if (message.Length() < 3) return true; |
272 const Object& obj = Object::Handle(I, message.At(2)); | 276 const Object& obj = Object::Handle(I, message.At(2)); |
273 if (!obj.IsSendPort()) return true; | 277 if (!obj.IsSendPort()) return true; |
274 const SendPort& listener = SendPort::Cast(obj); | 278 const SendPort& listener = SendPort::Cast(obj); |
275 switch (msg_type) { | 279 switch (msg_type) { |
276 case kAddExitMsg: | 280 case kAddExitMsg: { |
277 I->AddExitListener(listener); | 281 if (message.Length() != 4) return true; |
| 282 // [ OOB, msg, listener port, response object ] |
| 283 const Object& response = Object::Handle(I, message.At(3)); |
| 284 if (!response.IsInstance() && !response.IsNull()) return true; |
| 285 I->AddExitListener(listener, |
| 286 response.IsNull() ? Instance::null_instance() |
| 287 : Instance::Cast(response)); |
278 break; | 288 break; |
| 289 } |
279 case kDelExitMsg: | 290 case kDelExitMsg: |
| 291 if (message.Length() != 3) return true; |
280 I->RemoveExitListener(listener); | 292 I->RemoveExitListener(listener); |
281 break; | 293 break; |
282 case kAddErrorMsg: | 294 case kAddErrorMsg: |
| 295 if (message.Length() != 3) return true; |
283 I->AddErrorListener(listener); | 296 I->AddErrorListener(listener); |
284 break; | 297 break; |
285 case kDelErrorMsg: | 298 case kDelErrorMsg: |
| 299 if (message.Length() != 3) return true; |
286 I->RemoveErrorListener(listener); | 300 I->RemoveErrorListener(listener); |
287 break; | 301 break; |
288 default: | 302 default: |
289 UNREACHABLE(); | 303 UNREACHABLE(); |
290 } | 304 } |
291 break; | 305 break; |
292 } | 306 } |
293 case kErrorFatalMsg: { | 307 case kErrorFatalMsg: { |
294 // [ OOB, kErrorFatalMsg, terminate capability, val ] | 308 // [ OOB, kErrorFatalMsg, terminate capability, val ] |
295 if (message.Length() != 4) return true; | 309 if (message.Length() != 4) return true; |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 caps.SetAt(i, current); | 1009 caps.SetAt(i, current); |
996 return true; | 1010 return true; |
997 } | 1011 } |
998 } | 1012 } |
999 return false; | 1013 return false; |
1000 } | 1014 } |
1001 | 1015 |
1002 | 1016 |
1003 // TODO(iposva): Remove duplicated code and start using some hash based | 1017 // TODO(iposva): Remove duplicated code and start using some hash based |
1004 // structure instead of these linear lookups. | 1018 // structure instead of these linear lookups. |
1005 void Isolate::AddExitListener(const SendPort& listener) { | 1019 void Isolate::AddExitListener(const SendPort& listener, |
| 1020 const Instance& response) { |
1006 // Ensure a limit for the number of listeners remembered. | 1021 // Ensure a limit for the number of listeners remembered. |
1007 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); | 1022 static const intptr_t kMaxListeners = kSmiMax / (12 * kWordSize); |
1008 | 1023 |
1009 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1024 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1010 this, object_store()->exit_listeners()); | 1025 this, object_store()->exit_listeners()); |
1011 SendPort& current = SendPort::Handle(this); | 1026 SendPort& current = SendPort::Handle(this); |
1012 intptr_t insertion_index = -1; | 1027 intptr_t insertion_index = -1; |
1013 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1028 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
1014 current ^= listeners.At(i); | 1029 current ^= listeners.At(i); |
1015 if (current.IsNull()) { | 1030 if (current.IsNull()) { |
1016 if (insertion_index < 0) { | 1031 if (insertion_index < 0) { |
1017 insertion_index = i; | 1032 insertion_index = i; |
1018 } | 1033 } |
1019 } else if (current.Id() == listener.Id()) { | 1034 } else if (current.Id() == listener.Id()) { |
| 1035 listeners.SetAt(i + 1, response); |
1020 return; | 1036 return; |
1021 } | 1037 } |
1022 } | 1038 } |
1023 if (insertion_index < 0) { | 1039 if (insertion_index < 0) { |
1024 if (listeners.Length() >= kMaxListeners) { | 1040 if (listeners.Length() >= kMaxListeners) { |
1025 // Cannot grow the array of listeners beyond its max. Additional | 1041 // Cannot grow the array of listeners beyond its max. Additional |
1026 // listeners are ignored. In practice will never happen as we will | 1042 // listeners are ignored. In practice will never happen as we will |
1027 // run out of memory beforehand. | 1043 // run out of memory beforehand. |
1028 return; | 1044 return; |
1029 } | 1045 } |
1030 listeners.Add(listener); | 1046 listeners.Add(listener); |
| 1047 listeners.Add(response); |
1031 } else { | 1048 } else { |
1032 listeners.SetAt(insertion_index, listener); | 1049 listeners.SetAt(insertion_index, listener); |
| 1050 listeners.SetAt(insertion_index + 1, response); |
1033 } | 1051 } |
1034 } | 1052 } |
1035 | 1053 |
1036 | 1054 |
1037 void Isolate::RemoveExitListener(const SendPort& listener) { | 1055 void Isolate::RemoveExitListener(const SendPort& listener) { |
1038 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1056 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1039 this, object_store()->exit_listeners()); | 1057 this, object_store()->exit_listeners()); |
1040 SendPort& current = SendPort::Handle(this); | 1058 SendPort& current = SendPort::Handle(this); |
1041 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1059 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
1042 current ^= listeners.At(i); | 1060 current ^= listeners.At(i); |
1043 if (!current.IsNull() && (current.Id() == listener.Id())) { | 1061 if (!current.IsNull() && (current.Id() == listener.Id())) { |
1044 // Remove the matching listener from the list. | 1062 // Remove the matching listener from the list. |
1045 current = SendPort::null(); | 1063 current = SendPort::null(); |
1046 listeners.SetAt(i, current); | 1064 listeners.SetAt(i, current); |
| 1065 listeners.SetAt(i + 1, Object::null_instance()); |
1047 return; | 1066 return; |
1048 } | 1067 } |
1049 } | 1068 } |
1050 } | 1069 } |
1051 | 1070 |
1052 | 1071 |
1053 void Isolate::NotifyExitListeners() { | 1072 void Isolate::NotifyExitListeners() { |
1054 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1073 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1055 this, this->object_store()->exit_listeners()); | 1074 this, this->object_store()->exit_listeners()); |
1056 if (listeners.IsNull()) return; | 1075 if (listeners.IsNull()) return; |
1057 | 1076 |
1058 SendPort& listener = SendPort::Handle(this); | 1077 SendPort& listener = SendPort::Handle(this); |
1059 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1078 Instance& response = Instance::Handle(this); |
| 1079 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
1060 listener ^= listeners.At(i); | 1080 listener ^= listeners.At(i); |
1061 if (!listener.IsNull()) { | 1081 if (!listener.IsNull()) { |
1062 Dart_Port port_id = listener.Id(); | 1082 Dart_Port port_id = listener.Id(); |
1063 uint8_t* data = NULL; | 1083 uint8_t* data = NULL; |
1064 intptr_t len = 0; | 1084 intptr_t len = 0; |
1065 SerializeObject(Object::null_instance(), &data, &len, false); | 1085 response ^= listeners.At(i + 1); |
| 1086 SerializeObject(response, &data, &len, false); |
1066 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); | 1087 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); |
1067 PortMap::PostMessage(msg); | 1088 PortMap::PostMessage(msg); |
1068 } | 1089 } |
1069 } | 1090 } |
1070 } | 1091 } |
1071 | 1092 |
1072 | 1093 |
1073 void Isolate::AddErrorListener(const SendPort& listener) { | 1094 void Isolate::AddErrorListener(const SendPort& listener) { |
1074 // Ensure a limit for the number of listeners remembered. | 1095 // Ensure a limit for the number of listeners remembered. |
1075 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); | 1096 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); |
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1947 serialized_message_, serialized_message_len_); | 1968 serialized_message_, serialized_message_len_); |
1948 } | 1969 } |
1949 | 1970 |
1950 | 1971 |
1951 void IsolateSpawnState::Cleanup() { | 1972 void IsolateSpawnState::Cleanup() { |
1952 SwitchIsolateScope switch_scope(I); | 1973 SwitchIsolateScope switch_scope(I); |
1953 Dart::ShutdownIsolate(); | 1974 Dart::ShutdownIsolate(); |
1954 } | 1975 } |
1955 | 1976 |
1956 } // namespace dart | 1977 } // namespace dart |
OLD | NEW |