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 "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/json.h" | 10 #include "platform/json.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { | 142 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { |
143 class_table()->RegisterAt(index, cls); | 143 class_table()->RegisterAt(index, cls); |
144 } | 144 } |
145 | 145 |
146 | 146 |
147 void Isolate::ValidateClassTable() { | 147 void Isolate::ValidateClassTable() { |
148 class_table()->Validate(); | 148 class_table()->Validate(); |
149 } | 149 } |
150 | 150 |
151 | 151 |
| 152 void Isolate::SendInternalLibMessage(LibMsgId msg_id, uint64_t capability) { |
| 153 const Array& msg = Array::Handle(Array::New(3)); |
| 154 Object& element = Object::Handle(); |
| 155 |
| 156 element = Smi::New(Message::kIsolateLibOOBMsg); |
| 157 msg.SetAt(0, element); |
| 158 element = Smi::New(msg_id); |
| 159 msg.SetAt(1, element); |
| 160 element = Capability::New(capability); |
| 161 msg.SetAt(2, element); |
| 162 |
| 163 uint8_t* data = NULL; |
| 164 MessageWriter writer(&data, &allocator, false); |
| 165 writer.WriteMessage(msg); |
| 166 |
| 167 PortMap::PostMessage(new Message(main_port(), |
| 168 data, writer.BytesWritten(), |
| 169 Message::kOOBPriority)); |
| 170 } |
| 171 |
| 172 |
152 class IsolateMessageHandler : public MessageHandler { | 173 class IsolateMessageHandler : public MessageHandler { |
153 public: | 174 public: |
154 explicit IsolateMessageHandler(Isolate* isolate); | 175 explicit IsolateMessageHandler(Isolate* isolate); |
155 ~IsolateMessageHandler(); | 176 ~IsolateMessageHandler(); |
156 | 177 |
157 const char* name() const; | 178 const char* name() const; |
158 void MessageNotify(Message::Priority priority); | 179 void MessageNotify(Message::Priority priority); |
159 bool HandleMessage(Message* message); | 180 bool HandleMessage(Message* message); |
160 void NotifyPauseOnStart(); | 181 void NotifyPauseOnStart(); |
161 void NotifyPauseOnExit(); | 182 void NotifyPauseOnExit(); |
162 | 183 |
163 #if defined(DEBUG) | 184 #if defined(DEBUG) |
164 // Check that it is safe to access this handler. | 185 // Check that it is safe to access this handler. |
165 void CheckAccess(); | 186 void CheckAccess(); |
166 #endif | 187 #endif |
167 bool IsCurrentIsolate() const; | 188 bool IsCurrentIsolate() const; |
168 virtual Isolate* isolate() const { return isolate_; } | 189 virtual Isolate* isolate() const { return isolate_; } |
169 | 190 |
170 // Keep both these enums in sync with isolate_patch.dart. | |
171 // The different Isolate API message types. | |
172 enum { | |
173 kPauseMsg = 1, | |
174 kResumeMsg = 2, | |
175 kPingMsg = 3, | |
176 kKillMsg = 4, | |
177 kAddExitMsg = 5, | |
178 kDelExitMsg = 6, | |
179 kAddErrorMsg = 7, | |
180 kDelErrorMsg = 8, | |
181 kErrorFatalMsg = 9, | |
182 }; | |
183 // The different Isolate API message priorities for ping and kill messages. | |
184 enum { | |
185 kImmediateAction = 0, | |
186 kBeforeNextEventAction = 1, | |
187 kAsEventAction = 2 | |
188 }; | |
189 | |
190 private: | 191 private: |
191 // A result of false indicates that the isolate should terminate the | 192 // A result of false indicates that the isolate should terminate the |
192 // processing of further events. | 193 // processing of further events. |
193 bool HandleLibMessage(const Array& message); | 194 RawError* HandleLibMessage(const Array& message); |
194 | 195 |
195 bool ProcessUnhandledException(const Error& result); | 196 bool ProcessUnhandledException(const Error& result); |
196 Isolate* isolate_; | 197 Isolate* isolate_; |
197 }; | 198 }; |
198 | 199 |
199 | 200 |
200 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) | 201 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
201 : isolate_(isolate) { | 202 : isolate_(isolate) { |
202 } | 203 } |
203 | 204 |
204 | 205 |
205 IsolateMessageHandler::~IsolateMessageHandler() { | 206 IsolateMessageHandler::~IsolateMessageHandler() { |
206 } | 207 } |
207 | 208 |
208 const char* IsolateMessageHandler::name() const { | 209 const char* IsolateMessageHandler::name() const { |
209 return isolate_->name(); | 210 return isolate_->name(); |
210 } | 211 } |
211 | 212 |
212 | 213 |
213 // Isolate library OOB messages are fixed sized arrays which have the | 214 // Isolate library OOB messages are fixed sized arrays which have the |
214 // following format: | 215 // following format: |
215 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] | 216 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] |
216 bool IsolateMessageHandler::HandleLibMessage(const Array& message) { | 217 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { |
217 if (message.Length() < 2) return true; | 218 if (message.Length() < 2) return Error::null(); |
218 const Object& type = Object::Handle(I, message.At(1)); | 219 const Object& type = Object::Handle(I, message.At(1)); |
219 if (!type.IsSmi()) return true; | 220 if (!type.IsSmi()) return Error::null(); |
220 const intptr_t msg_type = Smi::Cast(type).Value(); | 221 const intptr_t msg_type = Smi::Cast(type).Value(); |
221 switch (msg_type) { | 222 switch (msg_type) { |
222 case kPauseMsg: { | 223 case Isolate::kPauseMsg: { |
223 // [ OOB, kPauseMsg, pause capability, resume capability ] | 224 // [ OOB, kPauseMsg, pause capability, resume capability ] |
224 if (message.Length() != 4) return true; | 225 if (message.Length() != 4) return Error::null(); |
225 Object& obj = Object::Handle(I, message.At(2)); | 226 Object& obj = Object::Handle(I, message.At(2)); |
226 if (!I->VerifyPauseCapability(obj)) return true; | 227 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
227 obj = message.At(3); | 228 obj = message.At(3); |
228 if (!obj.IsCapability()) return true; | 229 if (!obj.IsCapability()) return Error::null(); |
229 if (I->AddResumeCapability(Capability::Cast(obj))) { | 230 if (I->AddResumeCapability(Capability::Cast(obj))) { |
230 increment_paused(); | 231 increment_paused(); |
231 } | 232 } |
232 break; | 233 break; |
233 } | 234 } |
234 case kResumeMsg: { | 235 case Isolate::kResumeMsg: { |
235 // [ OOB, kResumeMsg, pause capability, resume capability ] | 236 // [ OOB, kResumeMsg, pause capability, resume capability ] |
236 if (message.Length() != 4) return true; | 237 if (message.Length() != 4) return Error::null(); |
237 Object& obj = Object::Handle(I, message.At(2)); | 238 Object& obj = Object::Handle(I, message.At(2)); |
238 if (!I->VerifyPauseCapability(obj)) return true; | 239 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
239 obj = message.At(3); | 240 obj = message.At(3); |
240 if (!obj.IsCapability()) return true; | 241 if (!obj.IsCapability()) return Error::null(); |
241 if (I->RemoveResumeCapability(Capability::Cast(obj))) { | 242 if (I->RemoveResumeCapability(Capability::Cast(obj))) { |
242 decrement_paused(); | 243 decrement_paused(); |
243 } | 244 } |
244 break; | 245 break; |
245 } | 246 } |
246 case kPingMsg: { | 247 case Isolate::kPingMsg: { |
247 // [ OOB, kPingMsg, responsePort, priority, response ] | 248 // [ OOB, kPingMsg, responsePort, priority, response ] |
248 if (message.Length() != 5) return true; | 249 if (message.Length() != 5) return Error::null(); |
249 const Object& obj2 = Object::Handle(I, message.At(2)); | 250 const Object& obj2 = Object::Handle(I, message.At(2)); |
250 if (!obj2.IsSendPort()) return true; | 251 if (!obj2.IsSendPort()) return Error::null(); |
251 const SendPort& send_port = SendPort::Cast(obj2); | 252 const SendPort& send_port = SendPort::Cast(obj2); |
252 const Object& obj3 = Object::Handle(I, message.At(3)); | 253 const Object& obj3 = Object::Handle(I, message.At(3)); |
253 if (!obj3.IsSmi()) return true; | 254 if (!obj3.IsSmi()) return Error::null(); |
254 const intptr_t priority = Smi::Cast(obj3).Value(); | 255 const intptr_t priority = Smi::Cast(obj3).Value(); |
255 const Object& obj4 = Object::Handle(I, message.At(4)); | 256 const Object& obj4 = Object::Handle(I, message.At(4)); |
256 if (!obj4.IsInstance() && !obj4.IsNull()) return true; | 257 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); |
257 const Instance& response = | 258 const Instance& response = |
258 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); | 259 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); |
259 if (priority == kImmediateAction) { | 260 if (priority == Isolate::kImmediateAction) { |
260 uint8_t* data = NULL; | 261 uint8_t* data = NULL; |
261 intptr_t len = 0; | 262 intptr_t len = 0; |
262 SerializeObject(response, &data, &len, false); | 263 SerializeObject(response, &data, &len, false); |
263 PortMap::PostMessage(new Message(send_port.Id(), | 264 PortMap::PostMessage(new Message(send_port.Id(), |
264 data, len, | 265 data, len, |
265 Message::kNormalPriority)); | 266 Message::kNormalPriority)); |
266 } else { | 267 } else { |
267 ASSERT((priority == kBeforeNextEventAction) || | 268 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
268 (priority == kAsEventAction)); | 269 (priority == Isolate::kAsEventAction)); |
269 // Update the message so that it will be handled immediately when it | 270 // Update the message so that it will be handled immediately when it |
270 // is picked up from the message queue the next time. | 271 // is picked up from the message queue the next time. |
271 message.SetAt( | 272 message.SetAt( |
272 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 273 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
273 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | 274 message.SetAt(3, Smi::Handle(I, Smi::New(Isolate::kImmediateAction))); |
274 uint8_t* data = NULL; | 275 uint8_t* data = NULL; |
275 intptr_t len = 0; | 276 intptr_t len = 0; |
276 SerializeObject(message, &data, &len, false); | 277 SerializeObject(message, &data, &len, false); |
277 this->PostMessage(new Message(Message::kIllegalPort, | 278 this->PostMessage( |
278 data, len, | 279 new Message(Message::kIllegalPort, |
279 Message::kNormalPriority), | 280 data, len, |
280 priority == kBeforeNextEventAction /* at_head */); | 281 Message::kNormalPriority), |
| 282 priority == Isolate::kBeforeNextEventAction /* at_head */); |
281 } | 283 } |
282 break; | 284 break; |
283 } | 285 } |
284 case kKillMsg: { | 286 case Isolate::kKillMsg: { |
285 // [ OOB, kKillMsg, terminate capability, priority ] | 287 // [ OOB, kKillMsg, terminate capability, priority ] |
286 if (message.Length() != 4) return true; | 288 if (message.Length() != 4) return Error::null(); |
287 Object& obj = Object::Handle(I, message.At(3)); | 289 Object& obj = Object::Handle(I, message.At(3)); |
288 if (!obj.IsSmi()) return true; | 290 if (!obj.IsSmi()) return Error::null(); |
289 const intptr_t priority = Smi::Cast(obj).Value(); | 291 const intptr_t priority = Smi::Cast(obj).Value(); |
290 if (priority == kImmediateAction) { | 292 if (priority == Isolate::kImmediateAction) { |
291 obj = message.At(2); | 293 obj = message.At(2); |
292 // Signal that the isolate should stop execution. | 294 // Signal that the isolate should stop execution. |
293 return !I->VerifyTerminateCapability(obj); | 295 if (I->VerifyTerminateCapability(obj)) { |
| 296 const String& msg = String::Handle(String::New( |
| 297 "isolate terminated by Isolate.kill")); |
| 298 return UnwindError::New(msg); |
| 299 } else { |
| 300 return Error::null(); |
| 301 } |
294 } else { | 302 } else { |
295 ASSERT((priority == kBeforeNextEventAction) || | 303 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
296 (priority == kAsEventAction)); | 304 (priority == Isolate::kAsEventAction)); |
297 // Update the message so that it will be handled immediately when it | 305 // Update the message so that it will be handled immediately when it |
298 // is picked up from the message queue the next time. | 306 // is picked up from the message queue the next time. |
299 message.SetAt( | 307 message.SetAt( |
300 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 308 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
301 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | 309 message.SetAt(3, Smi::Handle(I, Smi::New(Isolate::kImmediateAction))); |
302 uint8_t* data = NULL; | 310 uint8_t* data = NULL; |
303 intptr_t len = 0; | 311 intptr_t len = 0; |
304 SerializeObject(message, &data, &len, false); | 312 SerializeObject(message, &data, &len, false); |
305 this->PostMessage(new Message(Message::kIllegalPort, | 313 this->PostMessage( |
306 data, len, | 314 new Message(Message::kIllegalPort, |
307 Message::kNormalPriority), | 315 data, len, |
308 priority == kBeforeNextEventAction /* at_head */); | 316 Message::kNormalPriority), |
| 317 priority == Isolate::kBeforeNextEventAction /* at_head */); |
309 } | 318 } |
310 break; | 319 break; |
311 } | 320 } |
312 case kAddExitMsg: | 321 case Isolate::kInterruptMsg: { |
313 case kDelExitMsg: | 322 // [ OOB, kInterruptMsg, pause capability ] |
314 case kAddErrorMsg: | 323 if (message.Length() != 3) return Error::null(); |
315 case kDelErrorMsg: { | 324 Object& obj = Object::Handle(I, message.At(2)); |
| 325 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
| 326 |
| 327 // If we are already paused, don't pause again. |
| 328 if (I->debugger()->PauseEvent() == NULL) { |
| 329 return I->debugger()->SignalIsolateInterrupted(); |
| 330 } |
| 331 break; |
| 332 } |
| 333 |
| 334 case Isolate::kAddExitMsg: |
| 335 case Isolate::kDelExitMsg: |
| 336 case Isolate::kAddErrorMsg: |
| 337 case Isolate::kDelErrorMsg: { |
316 // [ OOB, msg, listener port ] | 338 // [ OOB, msg, listener port ] |
317 if (message.Length() < 3) return true; | 339 if (message.Length() < 3) return Error::null(); |
318 const Object& obj = Object::Handle(I, message.At(2)); | 340 const Object& obj = Object::Handle(I, message.At(2)); |
319 if (!obj.IsSendPort()) return true; | 341 if (!obj.IsSendPort()) return Error::null(); |
320 const SendPort& listener = SendPort::Cast(obj); | 342 const SendPort& listener = SendPort::Cast(obj); |
321 switch (msg_type) { | 343 switch (msg_type) { |
322 case kAddExitMsg: { | 344 case Isolate::kAddExitMsg: { |
323 if (message.Length() != 4) return true; | 345 if (message.Length() != 4) return Error::null(); |
324 // [ OOB, msg, listener port, response object ] | 346 // [ OOB, msg, listener port, response object ] |
325 const Object& response = Object::Handle(I, message.At(3)); | 347 const Object& response = Object::Handle(I, message.At(3)); |
326 if (!response.IsInstance() && !response.IsNull()) return true; | 348 if (!response.IsInstance() && !response.IsNull()) { |
| 349 return Error::null(); |
| 350 } |
327 I->AddExitListener(listener, | 351 I->AddExitListener(listener, |
328 response.IsNull() ? Instance::null_instance() | 352 response.IsNull() ? Instance::null_instance() |
329 : Instance::Cast(response)); | 353 : Instance::Cast(response)); |
330 break; | 354 break; |
331 } | 355 } |
332 case kDelExitMsg: | 356 case Isolate::kDelExitMsg: |
333 if (message.Length() != 3) return true; | 357 if (message.Length() != 3) return Error::null(); |
334 I->RemoveExitListener(listener); | 358 I->RemoveExitListener(listener); |
335 break; | 359 break; |
336 case kAddErrorMsg: | 360 case Isolate::kAddErrorMsg: |
337 if (message.Length() != 3) return true; | 361 if (message.Length() != 3) return Error::null(); |
338 I->AddErrorListener(listener); | 362 I->AddErrorListener(listener); |
339 break; | 363 break; |
340 case kDelErrorMsg: | 364 case Isolate::kDelErrorMsg: |
341 if (message.Length() != 3) return true; | 365 if (message.Length() != 3) return Error::null(); |
342 I->RemoveErrorListener(listener); | 366 I->RemoveErrorListener(listener); |
343 break; | 367 break; |
344 default: | 368 default: |
345 UNREACHABLE(); | 369 UNREACHABLE(); |
346 } | 370 } |
347 break; | 371 break; |
348 } | 372 } |
349 case kErrorFatalMsg: { | 373 case Isolate::kErrorFatalMsg: { |
350 // [ OOB, kErrorFatalMsg, terminate capability, val ] | 374 // [ OOB, kErrorFatalMsg, terminate capability, val ] |
351 if (message.Length() != 4) return true; | 375 if (message.Length() != 4) return Error::null(); |
352 // Check that the terminate capability has been passed correctly. | 376 // Check that the terminate capability has been passed correctly. |
353 Object& obj = Object::Handle(I, message.At(2)); | 377 Object& obj = Object::Handle(I, message.At(2)); |
354 if (!I->VerifyTerminateCapability(obj)) return true; | 378 if (!I->VerifyTerminateCapability(obj)) return Error::null(); |
355 // Get the value to be set. | 379 // Get the value to be set. |
356 obj = message.At(3); | 380 obj = message.At(3); |
357 if (!obj.IsBool()) return true; | 381 if (!obj.IsBool()) return Error::null(); |
358 I->SetErrorsFatal(Bool::Cast(obj).value()); | 382 I->SetErrorsFatal(Bool::Cast(obj).value()); |
359 break; | 383 break; |
360 } | 384 } |
361 #if defined(DEBUG) | 385 #if defined(DEBUG) |
362 // Malformed OOB messages are silently ignored in release builds. | 386 // Malformed OOB messages are silently ignored in release builds. |
363 default: | 387 default: |
364 UNREACHABLE(); | 388 UNREACHABLE(); |
365 break; | 389 break; |
366 #endif // defined(DEBUG) | 390 #endif // defined(DEBUG) |
367 } | 391 } |
368 return true; | 392 return Error::null(); |
369 } | 393 } |
370 | 394 |
371 | 395 |
372 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { | 396 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { |
373 if (priority >= Message::kOOBPriority) { | 397 if (priority >= Message::kOOBPriority) { |
374 // Handle out of band messages even if the isolate is busy. | 398 // Handle out of band messages even if the isolate is busy. |
375 I->ScheduleInterrupts(Isolate::kMessageInterrupt); | 399 I->ScheduleInterrupts(Isolate::kMessageInterrupt); |
376 } | 400 } |
377 Dart_MessageNotifyCallback callback = I->message_notify_callback(); | 401 Dart_MessageNotifyCallback callback = I->message_notify_callback(); |
378 if (callback) { | 402 if (callback) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 const Array& oob_msg = Array::Cast(msg); | 472 const Array& oob_msg = Array::Cast(msg); |
449 if (oob_msg.Length() > 0) { | 473 if (oob_msg.Length() > 0) { |
450 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); | 474 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); |
451 if (oob_tag.IsSmi()) { | 475 if (oob_tag.IsSmi()) { |
452 switch (Smi::Cast(oob_tag).Value()) { | 476 switch (Smi::Cast(oob_tag).Value()) { |
453 case Message::kServiceOOBMsg: { | 477 case Message::kServiceOOBMsg: { |
454 Service::HandleIsolateMessage(I, oob_msg); | 478 Service::HandleIsolateMessage(I, oob_msg); |
455 break; | 479 break; |
456 } | 480 } |
457 case Message::kIsolateLibOOBMsg: { | 481 case Message::kIsolateLibOOBMsg: { |
458 success = HandleLibMessage(oob_msg); | 482 const Error& error = Error::Handle(HandleLibMessage(oob_msg)); |
| 483 if (!error.IsNull()) { |
| 484 success = ProcessUnhandledException(error); |
| 485 } |
459 break; | 486 break; |
460 } | 487 } |
461 #if defined(DEBUG) | 488 #if defined(DEBUG) |
462 // Malformed OOB messages are silently ignored in release builds. | 489 // Malformed OOB messages are silently ignored in release builds. |
463 default: { | 490 default: { |
464 UNREACHABLE(); | 491 UNREACHABLE(); |
465 break; | 492 break; |
466 } | 493 } |
467 #endif // defined(DEBUG) | 494 #endif // defined(DEBUG) |
468 } | 495 } |
469 } | 496 } |
470 } | 497 } |
471 } | 498 } |
472 } else if (message->dest_port() == Message::kIllegalPort) { | 499 } else if (message->dest_port() == Message::kIllegalPort) { |
473 // Check whether this is a delayed OOB message which needed handling as | 500 // Check whether this is a delayed OOB message which needed handling as |
474 // part of the regular message dispatch. All other messages are dropped on | 501 // part of the regular message dispatch. All other messages are dropped on |
475 // the floor. | 502 // the floor. |
476 if (msg.IsArray()) { | 503 if (msg.IsArray()) { |
477 const Array& msg_arr = Array::Cast(msg); | 504 const Array& msg_arr = Array::Cast(msg); |
478 if (msg_arr.Length() > 0) { | 505 if (msg_arr.Length() > 0) { |
479 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); | 506 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); |
480 if (oob_tag.IsSmi() && | 507 if (oob_tag.IsSmi() && |
481 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { | 508 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { |
482 success = HandleLibMessage(Array::Cast(msg_arr)); | 509 const Error& error = Error::Handle(HandleLibMessage(msg_arr)); |
| 510 if (!error.IsNull()) { |
| 511 success = ProcessUnhandledException(error); |
| 512 } |
483 } | 513 } |
484 } | 514 } |
485 } | 515 } |
486 } else { | 516 } else { |
487 const Object& result = Object::Handle(zone, | 517 const Object& result = Object::Handle(zone, |
488 DartLibraryCalls::HandleMessage(msg_handler, msg)); | 518 DartLibraryCalls::HandleMessage(msg_handler, msg)); |
489 if (result.IsError()) { | 519 if (result.IsError()) { |
490 success = ProcessUnhandledException(Error::Cast(result)); | 520 success = ProcessUnhandledException(Error::Cast(result)); |
491 } else { | 521 } else { |
492 ASSERT(result.IsNull()); | 522 ASSERT(result.IsNull()); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 | 612 |
583 const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace()); | 613 const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace()); |
584 tmp = DartLibraryCalls::ToString(stacktrace); | 614 tmp = DartLibraryCalls::ToString(stacktrace); |
585 if (!tmp.IsString()) { | 615 if (!tmp.IsString()) { |
586 tmp = String::New(stacktrace.ToCString()); | 616 tmp = String::New(stacktrace.ToCString()); |
587 } | 617 } |
588 stacktrace_str ^= tmp.raw();; | 618 stacktrace_str ^= tmp.raw();; |
589 } else { | 619 } else { |
590 exc_str = String::New(result.ToErrorCString()); | 620 exc_str = String::New(result.ToErrorCString()); |
591 } | 621 } |
592 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); | 622 if (result.IsUnwindError()) { |
593 | 623 // Unwind errors are always fatal and don't notify listeners. |
594 if (I->ErrorsFatal()) { | 624 I->object_store()->set_sticky_error(result); |
595 if (has_listener) { | 625 return false; |
596 I->object_store()->clear_sticky_error(); | 626 } else { |
597 } else { | 627 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); |
598 I->object_store()->set_sticky_error(result); | 628 if (I->ErrorsFatal()) { |
| 629 if (has_listener) { |
| 630 I->object_store()->clear_sticky_error(); |
| 631 } else { |
| 632 I->object_store()->set_sticky_error(result); |
| 633 } |
| 634 return false; |
599 } | 635 } |
600 return false; | |
601 } | 636 } |
602 return true; | 637 return true; |
603 } | 638 } |
604 | 639 |
605 | 640 |
606 Isolate::Flags::Flags() | 641 Isolate::Flags::Flags() |
607 : type_checks_(FLAG_enable_type_checks), | 642 : type_checks_(FLAG_enable_type_checks), |
608 asserts_(FLAG_enable_asserts), | 643 asserts_(FLAG_enable_asserts), |
609 error_on_bad_type_(FLAG_error_on_bad_type), | 644 error_on_bad_type_(FLAG_error_on_bad_type), |
610 error_on_bad_override_(FLAG_error_on_bad_override) {} | 645 error_on_bad_override_(FLAG_error_on_bad_override) {} |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 MutexLocker ml(mutex_); | 1441 MutexLocker ml(mutex_); |
1407 if (stack_limit_ == saved_stack_limit_) { | 1442 if (stack_limit_ == saved_stack_limit_) { |
1408 return 0; // No interrupt was requested. | 1443 return 0; // No interrupt was requested. |
1409 } | 1444 } |
1410 uword interrupt_bits = stack_limit_ & kInterruptsMask; | 1445 uword interrupt_bits = stack_limit_ & kInterruptsMask; |
1411 stack_limit_ = saved_stack_limit_; | 1446 stack_limit_ = saved_stack_limit_; |
1412 return interrupt_bits; | 1447 return interrupt_bits; |
1413 } | 1448 } |
1414 | 1449 |
1415 | 1450 |
| 1451 RawError* Isolate::HandleInterrupts() { |
| 1452 uword interrupt_bits = GetAndClearInterrupts(); |
| 1453 if ((interrupt_bits & kVMInterrupt) != 0) { |
| 1454 thread_registry()->CheckSafepoint(); |
| 1455 if (store_buffer()->Overflowed()) { |
| 1456 if (FLAG_verbose_gc) { |
| 1457 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); |
| 1458 } |
| 1459 heap()->CollectGarbage(Heap::kNew); |
| 1460 } |
| 1461 } |
| 1462 if ((interrupt_bits & kMessageInterrupt) != 0) { |
| 1463 bool ok = message_handler()->HandleOOBMessages(); |
| 1464 if (!ok) { |
| 1465 // False result from HandleOOBMessages signals that the isolate should |
| 1466 // be terminating. |
| 1467 if (FLAG_trace_isolates) { |
| 1468 OS::Print("[!] Terminating isolate due to OOB message:\n" |
| 1469 "\tisolate: %s\n", name()); |
| 1470 } |
| 1471 // TODO(turnidge): If the isolate is being killed by |
| 1472 // Isolate.kill, then we probably want to respect pause_on_exit. |
| 1473 // If the isolate is being killed due to vm restart we don't. |
| 1474 message_handler()->set_pause_on_start(false); |
| 1475 message_handler()->set_pause_on_exit(false); |
| 1476 const String& msg = String::Handle(String::New("isolate terminated")); |
| 1477 return UnwindError::New(msg); |
| 1478 } |
| 1479 } |
| 1480 return Error::null(); |
| 1481 } |
| 1482 |
| 1483 |
1416 uword Isolate::GetAndClearStackOverflowFlags() { | 1484 uword Isolate::GetAndClearStackOverflowFlags() { |
1417 uword stack_overflow_flags = stack_overflow_flags_; | 1485 uword stack_overflow_flags = stack_overflow_flags_; |
1418 stack_overflow_flags_ = 0; | 1486 stack_overflow_flags_ = 0; |
1419 return stack_overflow_flags; | 1487 return stack_overflow_flags; |
1420 } | 1488 } |
1421 | 1489 |
1422 | 1490 |
1423 static int MostUsedFunctionFirst(const Function* const* a, | 1491 static int MostUsedFunctionFirst(const Function* const* a, |
1424 const Function* const* b) { | 1492 const Function* const* b) { |
1425 if ((*a)->usage_counter() > (*b)->usage_counter()) { | 1493 if ((*a)->usage_counter() > (*b)->usage_counter()) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 void Isolate::LowLevelShutdown() { | 1560 void Isolate::LowLevelShutdown() { |
1493 // Ensure we have a zone and handle scope so that we can call VM functions, | 1561 // Ensure we have a zone and handle scope so that we can call VM functions, |
1494 // but we no longer allocate new heap objects. | 1562 // but we no longer allocate new heap objects. |
1495 Thread* thread = Thread::Current(); | 1563 Thread* thread = Thread::Current(); |
1496 StackZone stack_zone(thread); | 1564 StackZone stack_zone(thread); |
1497 HandleScope handle_scope(thread); | 1565 HandleScope handle_scope(thread); |
1498 NoSafepointScope no_safepoint_scope; | 1566 NoSafepointScope no_safepoint_scope; |
1499 | 1567 |
1500 // Notify exit listeners that this isolate is shutting down. | 1568 // Notify exit listeners that this isolate is shutting down. |
1501 if (object_store() != NULL) { | 1569 if (object_store() != NULL) { |
| 1570 // TODO(turnidge): If the isolate is being killed by Isolate.kill, |
| 1571 // then we want to notify event listeners. If the isolate is |
| 1572 // being killed due to vm restart we probably don't. |
1502 NotifyExitListeners(); | 1573 NotifyExitListeners(); |
1503 } | 1574 } |
1504 | 1575 |
1505 // Clean up debugger resources. | 1576 // Clean up debugger resources. |
1506 debugger()->Shutdown(); | 1577 debugger()->Shutdown(); |
1507 | 1578 |
1508 // Close all the ports owned by this isolate. | 1579 // Close all the ports owned by this isolate. |
1509 PortMap::ClosePorts(message_handler()); | 1580 PortMap::ClosePorts(message_handler()); |
1510 | 1581 |
1511 // Fail fast if anybody tries to post any more messsages to this isolate. | 1582 // Fail fast if anybody tries to post any more messsages to this isolate. |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 kill_msg.value.as_array.length = 4; | 2290 kill_msg.value.as_array.length = 4; |
2220 kill_msg.value.as_array.values = list_values; | 2291 kill_msg.value.as_array.values = list_values; |
2221 | 2292 |
2222 Dart_CObject oob; | 2293 Dart_CObject oob; |
2223 oob.type = Dart_CObject_kInt32; | 2294 oob.type = Dart_CObject_kInt32; |
2224 oob.value.as_int32 = Message::kIsolateLibOOBMsg; | 2295 oob.value.as_int32 = Message::kIsolateLibOOBMsg; |
2225 list_values[0] = &oob; | 2296 list_values[0] = &oob; |
2226 | 2297 |
2227 Dart_CObject kill; | 2298 Dart_CObject kill; |
2228 kill.type = Dart_CObject_kInt32; | 2299 kill.type = Dart_CObject_kInt32; |
2229 kill.value.as_int32 = IsolateMessageHandler::kKillMsg; | 2300 kill.value.as_int32 = Isolate::kKillMsg; |
2230 list_values[1] = &kill; | 2301 list_values[1] = &kill; |
2231 | 2302 |
2232 Dart_CObject cap; | 2303 Dart_CObject cap; |
2233 cap.type = Dart_CObject_kCapability; | 2304 cap.type = Dart_CObject_kCapability; |
2234 cap.value.as_capability.id = terminate_capability(); | 2305 cap.value.as_capability.id = terminate_capability(); |
2235 list_values[2] = ∩ | 2306 list_values[2] = ∩ |
2236 | 2307 |
2237 Dart_CObject imm; | 2308 Dart_CObject imm; |
2238 imm.type = Dart_CObject_kInt32; | 2309 imm.type = Dart_CObject_kInt32; |
2239 imm.value.as_int32 = IsolateMessageHandler::kImmediateAction; | 2310 imm.value.as_int32 = Isolate::kImmediateAction; |
2240 list_values[3] = &imm; | 2311 list_values[3] = &imm; |
2241 | 2312 |
2242 { | 2313 { |
2243 uint8_t* buffer = NULL; | 2314 uint8_t* buffer = NULL; |
2244 ApiMessageWriter writer(&buffer, allocator); | 2315 ApiMessageWriter writer(&buffer, allocator); |
2245 bool success = writer.WriteCMessage(&kill_msg); | 2316 bool success = writer.WriteCMessage(&kill_msg); |
2246 ASSERT(success); | 2317 ASSERT(success); |
2247 | 2318 |
2248 // Post the message at the given port. | 2319 // Post the message at the given port. |
2249 success = PortMap::PostMessage(new Message(main_port(), | 2320 success = PortMap::PostMessage(new Message(main_port(), |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2494 serialized_message_, serialized_message_len_); | 2565 serialized_message_, serialized_message_len_); |
2495 } | 2566 } |
2496 | 2567 |
2497 | 2568 |
2498 void IsolateSpawnState::Cleanup() { | 2569 void IsolateSpawnState::Cleanup() { |
2499 SwitchIsolateScope switch_scope(I); | 2570 SwitchIsolateScope switch_scope(I); |
2500 Dart::ShutdownIsolate(); | 2571 Dart::ShutdownIsolate(); |
2501 } | 2572 } |
2502 | 2573 |
2503 } // namespace dart | 2574 } // namespace dart |
OLD | NEW |