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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); |
593 | 623 |
594 if (I->ErrorsFatal()) { | 624 if (result.IsUnwindError() || I->ErrorsFatal()) { |
turnidge
2015/09/15 22:14:10
This isn't quite right, probably, but I wanted to
| |
595 if (has_listener) { | 625 if (has_listener) { |
596 I->object_store()->clear_sticky_error(); | 626 I->object_store()->clear_sticky_error(); |
597 } else { | 627 } else { |
598 I->object_store()->set_sticky_error(result); | 628 I->object_store()->set_sticky_error(result); |
599 } | 629 } |
600 return false; | 630 return false; |
601 } | 631 } |
602 return true; | 632 return true; |
603 } | 633 } |
604 | 634 |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1388 MutexLocker ml(mutex_); | 1418 MutexLocker ml(mutex_); |
1389 if (stack_limit_ == saved_stack_limit_) { | 1419 if (stack_limit_ == saved_stack_limit_) { |
1390 return 0; // No interrupt was requested. | 1420 return 0; // No interrupt was requested. |
1391 } | 1421 } |
1392 uword interrupt_bits = stack_limit_ & kInterruptsMask; | 1422 uword interrupt_bits = stack_limit_ & kInterruptsMask; |
1393 stack_limit_ = saved_stack_limit_; | 1423 stack_limit_ = saved_stack_limit_; |
1394 return interrupt_bits; | 1424 return interrupt_bits; |
1395 } | 1425 } |
1396 | 1426 |
1397 | 1427 |
1428 RawError* Isolate::HandleInterrupts() { | |
1429 uword interrupt_bits = GetAndClearInterrupts(); | |
1430 if ((interrupt_bits & kVMInterrupt) != 0) { | |
1431 thread_registry()->CheckSafepoint(); | |
1432 if (store_buffer()->Overflowed()) { | |
1433 if (FLAG_verbose_gc) { | |
1434 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); | |
1435 } | |
1436 heap()->CollectGarbage(Heap::kNew); | |
1437 } | |
1438 } | |
1439 if ((interrupt_bits & kMessageInterrupt) != 0) { | |
1440 bool ok = message_handler()->HandleOOBMessages(); | |
1441 if (!ok) { | |
1442 // False result from HandleOOBMessages signals that the isolate should | |
1443 // be terminating. | |
1444 if (FLAG_trace_isolates) { | |
1445 OS::Print("[!] Terminating isolate due to OOB message:\n" | |
1446 "\tisolate: %s\n", name()); | |
1447 } | |
1448 message_handler()->set_pause_on_start(false); | |
1449 message_handler()->set_pause_on_exit(false); | |
1450 const String& msg = String::Handle(String::New("isolate terminated")); | |
1451 return UnwindError::New(msg); | |
1452 } | |
1453 } | |
1454 return Error::null(); | |
1455 } | |
1456 | |
1457 | |
1398 uword Isolate::GetAndClearStackOverflowFlags() { | 1458 uword Isolate::GetAndClearStackOverflowFlags() { |
1399 uword stack_overflow_flags = stack_overflow_flags_; | 1459 uword stack_overflow_flags = stack_overflow_flags_; |
1400 stack_overflow_flags_ = 0; | 1460 stack_overflow_flags_ = 0; |
1401 return stack_overflow_flags; | 1461 return stack_overflow_flags; |
1402 } | 1462 } |
1403 | 1463 |
1404 | 1464 |
1405 static int MostUsedFunctionFirst(const Function* const* a, | 1465 static int MostUsedFunctionFirst(const Function* const* a, |
1406 const Function* const* b) { | 1466 const Function* const* b) { |
1407 if ((*a)->usage_counter() > (*b)->usage_counter()) { | 1467 if ((*a)->usage_counter() > (*b)->usage_counter()) { |
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2198 kill_msg.value.as_array.length = 4; | 2258 kill_msg.value.as_array.length = 4; |
2199 kill_msg.value.as_array.values = list_values; | 2259 kill_msg.value.as_array.values = list_values; |
2200 | 2260 |
2201 Dart_CObject oob; | 2261 Dart_CObject oob; |
2202 oob.type = Dart_CObject_kInt32; | 2262 oob.type = Dart_CObject_kInt32; |
2203 oob.value.as_int32 = Message::kIsolateLibOOBMsg; | 2263 oob.value.as_int32 = Message::kIsolateLibOOBMsg; |
2204 list_values[0] = &oob; | 2264 list_values[0] = &oob; |
2205 | 2265 |
2206 Dart_CObject kill; | 2266 Dart_CObject kill; |
2207 kill.type = Dart_CObject_kInt32; | 2267 kill.type = Dart_CObject_kInt32; |
2208 kill.value.as_int32 = IsolateMessageHandler::kKillMsg; | 2268 kill.value.as_int32 = Isolate::kKillMsg; |
2209 list_values[1] = &kill; | 2269 list_values[1] = &kill; |
2210 | 2270 |
2211 Dart_CObject cap; | 2271 Dart_CObject cap; |
2212 cap.type = Dart_CObject_kCapability; | 2272 cap.type = Dart_CObject_kCapability; |
2213 cap.value.as_capability.id = terminate_capability(); | 2273 cap.value.as_capability.id = terminate_capability(); |
2214 list_values[2] = ∩ | 2274 list_values[2] = ∩ |
2215 | 2275 |
2216 Dart_CObject imm; | 2276 Dart_CObject imm; |
2217 imm.type = Dart_CObject_kInt32; | 2277 imm.type = Dart_CObject_kInt32; |
2218 imm.value.as_int32 = IsolateMessageHandler::kImmediateAction; | 2278 imm.value.as_int32 = Isolate::kImmediateAction; |
2219 list_values[3] = &imm; | 2279 list_values[3] = &imm; |
2220 | 2280 |
2221 { | 2281 { |
2222 uint8_t* buffer = NULL; | 2282 uint8_t* buffer = NULL; |
2223 ApiMessageWriter writer(&buffer, allocator); | 2283 ApiMessageWriter writer(&buffer, allocator); |
2224 bool success = writer.WriteCMessage(&kill_msg); | 2284 bool success = writer.WriteCMessage(&kill_msg); |
2225 ASSERT(success); | 2285 ASSERT(success); |
2226 | 2286 |
2227 // Post the message at the given port. | 2287 // Post the message at the given port. |
2228 success = PortMap::PostMessage(new Message(main_port(), | 2288 success = PortMap::PostMessage(new Message(main_port(), |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2473 serialized_message_, serialized_message_len_); | 2533 serialized_message_, serialized_message_len_); |
2474 } | 2534 } |
2475 | 2535 |
2476 | 2536 |
2477 void IsolateSpawnState::Cleanup() { | 2537 void IsolateSpawnState::Cleanup() { |
2478 SwitchIsolateScope switch_scope(I); | 2538 SwitchIsolateScope switch_scope(I); |
2479 Dart::ShutdownIsolate(); | 2539 Dart::ShutdownIsolate(); |
2480 } | 2540 } |
2481 | 2541 |
2482 } // namespace dart | 2542 } // namespace dart |
OLD | NEW |