Chromium Code Reviews| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 "Pause isolates exiting."); | 45 "Pause isolates exiting."); |
| 46 DEFINE_FLAG(bool, break_at_isolate_spawn, false, | 46 DEFINE_FLAG(bool, break_at_isolate_spawn, false, |
| 47 "Insert a one-time breakpoint at the entrypoint for all spawned " | 47 "Insert a one-time breakpoint at the entrypoint for all spawned " |
| 48 "isolates"); | 48 "isolates"); |
| 49 | 49 |
| 50 | 50 |
| 51 // Quick access to the locally defined isolate() method. | 51 // Quick access to the locally defined isolate() method. |
| 52 #define I (isolate()) | 52 #define I (isolate()) |
| 53 | 53 |
| 54 | 54 |
| 55 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | |
| 56 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | |
| 57 return reinterpret_cast<uint8_t*>(new_ptr); | |
| 58 } | |
| 59 | |
| 60 | |
| 61 static void SerializeObject(const Instance& obj, | |
| 62 uint8_t** obj_data, | |
| 63 intptr_t* obj_len) { | |
| 64 MessageWriter writer(obj_data, &allocator); | |
| 65 writer.WriteMessage(obj); | |
| 66 *obj_len = writer.BytesWritten(); | |
| 67 } | |
| 68 | |
| 69 | |
| 55 void Isolate::RegisterClass(const Class& cls) { | 70 void Isolate::RegisterClass(const Class& cls) { |
| 56 class_table()->Register(cls); | 71 class_table()->Register(cls); |
| 57 } | 72 } |
| 58 | 73 |
| 59 | 74 |
| 60 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { | 75 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { |
| 61 class_table()->RegisterAt(index, cls); | 76 class_table()->RegisterAt(index, cls); |
| 62 } | 77 } |
| 63 | 78 |
| 64 | 79 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 82 #endif | 97 #endif |
| 83 bool IsCurrentIsolate() const; | 98 bool IsCurrentIsolate() const; |
| 84 virtual Isolate* isolate() const { return isolate_; } | 99 virtual Isolate* isolate() const { return isolate_; } |
| 85 bool UnhandledExceptionCallbackHandler(const Object& message, | 100 bool UnhandledExceptionCallbackHandler(const Object& message, |
| 86 const UnhandledException& error); | 101 const UnhandledException& error); |
| 87 | 102 |
| 88 private: | 103 private: |
| 89 // Keep in sync with isolate_patch.dart. | 104 // Keep in sync with isolate_patch.dart. |
| 90 enum { | 105 enum { |
| 91 kPauseMsg = 1, | 106 kPauseMsg = 1, |
| 92 kResumeMsg | 107 kResumeMsg = 2, |
| 108 kPingMsg = 3, | |
| 109 | |
| 110 kImmediateAction = 0, | |
| 111 kBeforeNextEventAction = 1, | |
| 112 kAsEventAction = 2 | |
| 93 }; | 113 }; |
| 94 | 114 |
| 95 void HandleLibMessage(const Array& message); | 115 void HandleLibMessage(const Array& message); |
| 96 bool ProcessUnhandledException(const Object& message, const Error& result); | 116 bool ProcessUnhandledException(const Object& message, const Error& result); |
| 97 RawFunction* ResolveCallbackFunction(); | 117 RawFunction* ResolveCallbackFunction(); |
| 98 Isolate* isolate_; | 118 Isolate* isolate_; |
| 99 }; | 119 }; |
| 100 | 120 |
| 101 | 121 |
| 102 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) | 122 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 Object& obj = Object::Handle(I, message.At(2)); | 160 Object& obj = Object::Handle(I, message.At(2)); |
| 141 if (!obj.IsCapability()) return; | 161 if (!obj.IsCapability()) return; |
| 142 if (!I->VerifyPauseCapability(Capability::Cast(obj))) return; | 162 if (!I->VerifyPauseCapability(Capability::Cast(obj))) return; |
| 143 obj = message.At(3); | 163 obj = message.At(3); |
| 144 if (!obj.IsCapability()) return; | 164 if (!obj.IsCapability()) return; |
| 145 if (I->RemoveResumeCapability(Capability::Cast(obj))) { | 165 if (I->RemoveResumeCapability(Capability::Cast(obj))) { |
| 146 decrement_paused(); | 166 decrement_paused(); |
| 147 } | 167 } |
| 148 break; | 168 break; |
| 149 } | 169 } |
| 170 case kPingMsg: { | |
| 171 // [ OOB, kPingMsg, responsePort, pingType ] | |
| 172 if (message.Length() != 4) return; | |
| 173 const Object& obj2 = Object::Handle(I, message.At(2)); | |
| 174 if (!obj2.IsSendPort()) return; | |
| 175 const SendPort& send_port = SendPort::Cast(obj2); | |
| 176 const Object& obj3 = Object::Handle(I, message.At(3)); | |
| 177 if (!obj3.IsSmi()) return; | |
| 178 const Smi& ping_type = Smi::Cast(obj3); | |
|
siva
2014/12/01 19:48:05
why not
intptr_t ping_value = Smi::Cast(obj3).Valu
Ivan Posva
2014/12/12 20:21:46
Done.
| |
| 179 if (ping_type.Value() == kImmediateAction) { | |
| 180 uint8_t* data = NULL; | |
| 181 intptr_t len = 0; | |
| 182 SerializeObject(Object::null_instance(), &data, &len); | |
| 183 PortMap::PostMessage(new Message(send_port.Id(), | |
| 184 data, len, | |
| 185 Message::kNormalPriority)); | |
|
siva
2014/12/01 19:48:05
How does the spec resolve a potential Denial of Se
Ivan Posva
2014/12/12 20:21:46
If you control the isolate, then you can do other
| |
| 186 } else if (ping_type.Value() == kBeforeNextEventAction) { | |
| 187 // Update the message so that it will be handled immediately when it | |
| 188 // is picked up from the message queue the next time. | |
| 189 message.SetAt( | |
| 190 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | |
| 191 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | |
| 192 uint8_t* data = NULL; | |
| 193 intptr_t len = 0; | |
| 194 SerializeObject(message, &data, &len); | |
| 195 this->PostMessage(new Message(Message::kIllegalPort, | |
| 196 data, len, | |
| 197 Message::kNormalPriority), | |
| 198 true /* at_head */); | |
| 199 } else if (ping_type.Value() == kAsEventAction) { | |
| 200 // Update the message so that it will be handled immediately when it | |
| 201 // is picked up from the message queue the next time. | |
| 202 message.SetAt( | |
| 203 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | |
| 204 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | |
| 205 uint8_t* data = NULL; | |
| 206 intptr_t len = 0; | |
| 207 SerializeObject(message, &data, &len); | |
| 208 this->PostMessage(new Message(Message::kIllegalPort, | |
| 209 data, len, | |
| 210 Message::kNormalPriority)); | |
| 211 } | |
| 212 break; | |
| 213 } | |
| 150 #if defined(DEBUG) | 214 #if defined(DEBUG) |
| 151 // Malformed OOB messages are silently ignored in release builds. | 215 // Malformed OOB messages are silently ignored in release builds. |
| 152 default: | 216 default: |
| 153 UNREACHABLE(); | 217 UNREACHABLE(); |
| 154 break; | 218 break; |
| 155 #endif // defined(DEBUG) | 219 #endif // defined(DEBUG) |
| 156 } | 220 } |
| 157 } | 221 } |
| 158 | 222 |
| 159 | 223 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 173 bool IsolateMessageHandler::HandleMessage(Message* message) { | 237 bool IsolateMessageHandler::HandleMessage(Message* message) { |
| 174 StartIsolateScope start_scope(I); | 238 StartIsolateScope start_scope(I); |
| 175 StackZone zone(I); | 239 StackZone zone(I); |
| 176 HandleScope handle_scope(I); | 240 HandleScope handle_scope(I); |
| 177 // TODO(turnidge): Rework collection total dart execution. This can | 241 // TODO(turnidge): Rework collection total dart execution. This can |
| 178 // overcount when other things (gc, compilation) are active. | 242 // overcount when other things (gc, compilation) are active. |
| 179 TIMERSCOPE(isolate_, time_dart_execution); | 243 TIMERSCOPE(isolate_, time_dart_execution); |
| 180 | 244 |
| 181 // If the message is in band we lookup the handler to dispatch to. If the | 245 // If the message is in band we lookup the handler to dispatch to. If the |
| 182 // receive port was closed, we drop the message without deserializing it. | 246 // receive port was closed, we drop the message without deserializing it. |
| 247 // Illegal port is a special case for artificially enqueued isolate library | |
| 248 // messages which are handled in C++ code below. | |
| 183 Object& msg_handler = Object::Handle(I); | 249 Object& msg_handler = Object::Handle(I); |
| 184 if (!message->IsOOB()) { | 250 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { |
| 185 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); | 251 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); |
| 186 if (msg_handler.IsError()) { | 252 if (msg_handler.IsError()) { |
| 187 delete message; | 253 delete message; |
| 188 return ProcessUnhandledException(Object::null_instance(), | 254 return ProcessUnhandledException(Object::null_instance(), |
| 189 Error::Cast(msg_handler)); | 255 Error::Cast(msg_handler)); |
| 190 } | 256 } |
| 191 if (msg_handler.IsNull()) { | 257 if (msg_handler.IsNull()) { |
| 192 // If the port has been closed then the message will be dropped at this | 258 // If the port has been closed then the message will be dropped at this |
| 193 // point. Make sure to post to the delivery failure port in that case. | 259 // point. Make sure to post to the delivery failure port in that case. |
| 194 if (message->RedirectToDeliveryFailurePort()) { | 260 if (message->RedirectToDeliveryFailurePort()) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 // Malformed OOB messages are silently ignored in release builds. | 310 // Malformed OOB messages are silently ignored in release builds. |
| 245 default: { | 311 default: { |
| 246 UNREACHABLE(); | 312 UNREACHABLE(); |
| 247 break; | 313 break; |
| 248 } | 314 } |
| 249 #endif // defined(DEBUG) | 315 #endif // defined(DEBUG) |
| 250 } | 316 } |
| 251 } | 317 } |
| 252 } | 318 } |
| 253 } | 319 } |
| 320 } else if (message->dest_port() == Message::kIllegalPort) { | |
| 321 // Check whether this is a delayed OOB message which needed handling as | |
| 322 // part of the regular message dispatch. All other messages are dropped on | |
| 323 // the floor. | |
| 324 if (msg.IsArray()) { | |
| 325 const Array& msg_arr = Array::Cast(msg); | |
| 326 if (msg_arr.Length() > 0) { | |
| 327 const Object& oob_tag = Object::Handle(I, msg_arr.At(0)); | |
| 328 if (oob_tag.IsSmi() && | |
| 329 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { | |
| 330 HandleLibMessage(Array::Cast(msg_arr)); | |
| 331 } | |
| 332 } | |
| 333 } | |
| 254 } else { | 334 } else { |
| 255 const Object& result = Object::Handle(I, | 335 const Object& result = Object::Handle(I, |
| 256 DartLibraryCalls::HandleMessage(msg_handler, msg)); | 336 DartLibraryCalls::HandleMessage(msg_handler, msg)); |
| 257 if (result.IsError()) { | 337 if (result.IsError()) { |
| 258 success = ProcessUnhandledException(msg, Error::Cast(result)); | 338 success = ProcessUnhandledException(msg, Error::Cast(result)); |
| 259 } else { | 339 } else { |
| 260 ASSERT(result.IsNull()); | 340 ASSERT(result.IsNull()); |
| 261 } | 341 } |
| 262 } | 342 } |
| 263 delete message; | 343 delete message; |
| (...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1402 | 1482 |
| 1403 | 1483 |
| 1404 template<class T> | 1484 template<class T> |
| 1405 T* Isolate::AllocateReusableHandle() { | 1485 T* Isolate::AllocateReusableHandle() { |
| 1406 T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); | 1486 T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); |
| 1407 T::initializeHandle(handle, T::null()); | 1487 T::initializeHandle(handle, T::null()); |
| 1408 return handle; | 1488 return handle; |
| 1409 } | 1489 } |
| 1410 | 1490 |
| 1411 | 1491 |
| 1412 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | |
| 1413 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | |
| 1414 return reinterpret_cast<uint8_t*>(new_ptr); | |
| 1415 } | |
| 1416 | |
| 1417 | |
| 1418 static void SerializeObject(const Instance& obj, | |
| 1419 uint8_t** obj_data, | |
| 1420 intptr_t* obj_len) { | |
| 1421 MessageWriter writer(obj_data, &allocator); | |
| 1422 writer.WriteMessage(obj); | |
| 1423 *obj_len = writer.BytesWritten(); | |
| 1424 } | |
| 1425 | |
| 1426 | |
| 1427 static RawInstance* DeserializeObject(Isolate* isolate, | 1492 static RawInstance* DeserializeObject(Isolate* isolate, |
| 1428 uint8_t* obj_data, | 1493 uint8_t* obj_data, |
| 1429 intptr_t obj_len) { | 1494 intptr_t obj_len) { |
| 1430 if (obj_data == NULL) { | 1495 if (obj_data == NULL) { |
| 1431 return Instance::null(); | 1496 return Instance::null(); |
| 1432 } | 1497 } |
| 1433 SnapshotReader reader(obj_data, obj_len, Snapshot::kMessage, isolate); | 1498 SnapshotReader reader(obj_data, obj_len, Snapshot::kMessage, isolate); |
| 1434 const Object& obj = Object::Handle(isolate, reader.ReadObject()); | 1499 const Object& obj = Object::Handle(isolate, reader.ReadObject()); |
| 1435 ASSERT(!obj.IsError()); | 1500 ASSERT(!obj.IsError()); |
| 1436 Instance& instance = Instance::Handle(isolate); | 1501 Instance& instance = Instance::Handle(isolate); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1574 serialized_message_, serialized_message_len_); | 1639 serialized_message_, serialized_message_len_); |
| 1575 } | 1640 } |
| 1576 | 1641 |
| 1577 | 1642 |
| 1578 void IsolateSpawnState::Cleanup() { | 1643 void IsolateSpawnState::Cleanup() { |
| 1579 SwitchIsolateScope switch_scope(I); | 1644 SwitchIsolateScope switch_scope(I); |
| 1580 Dart::ShutdownIsolate(); | 1645 Dart::ShutdownIsolate(); |
| 1581 } | 1646 } |
| 1582 | 1647 |
| 1583 } // namespace dart | 1648 } // namespace dart |
| OLD | NEW |