Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1149)

Side by Side Diff: runtime/vm/isolate.cc

Issue 1344993002: Refactor isolate interrupts to use OOB messages instead of interrupt bits. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code review 2 Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/service.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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] = &cap; 2306 list_values[2] = &cap;
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
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
OLDNEW
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698