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 |