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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 const char* IsolateMessageHandler::name() const { | 210 const char* IsolateMessageHandler::name() const { |
211 return isolate_->name(); | 211 return isolate_->name(); |
212 } | 212 } |
213 | 213 |
214 | 214 |
215 // Isolate library OOB messages are fixed sized arrays which have the | 215 // Isolate library OOB messages are fixed sized arrays which have the |
216 // following format: | 216 // following format: |
217 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] | 217 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] |
218 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { | 218 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { |
219 if (message.Length() < 2) return Error::null(); | 219 if (message.Length() < 2) return Error::null(); |
220 const Object& type = Object::Handle(I, message.At(1)); | 220 Zone* zone = I->current_zone(); |
| 221 const Object& type = Object::Handle(zone, message.At(1)); |
221 if (!type.IsSmi()) return Error::null(); | 222 if (!type.IsSmi()) return Error::null(); |
222 const intptr_t msg_type = Smi::Cast(type).Value(); | 223 const intptr_t msg_type = Smi::Cast(type).Value(); |
223 switch (msg_type) { | 224 switch (msg_type) { |
224 case Isolate::kPauseMsg: { | 225 case Isolate::kPauseMsg: { |
225 // [ OOB, kPauseMsg, pause capability, resume capability ] | 226 // [ OOB, kPauseMsg, pause capability, resume capability ] |
226 if (message.Length() != 4) return Error::null(); | 227 if (message.Length() != 4) return Error::null(); |
227 Object& obj = Object::Handle(I, message.At(2)); | 228 Object& obj = Object::Handle(zone, message.At(2)); |
228 if (!I->VerifyPauseCapability(obj)) return Error::null(); | 229 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
229 obj = message.At(3); | 230 obj = message.At(3); |
230 if (!obj.IsCapability()) return Error::null(); | 231 if (!obj.IsCapability()) return Error::null(); |
231 if (I->AddResumeCapability(Capability::Cast(obj))) { | 232 if (I->AddResumeCapability(Capability::Cast(obj))) { |
232 increment_paused(); | 233 increment_paused(); |
233 } | 234 } |
234 break; | 235 break; |
235 } | 236 } |
236 case Isolate::kResumeMsg: { | 237 case Isolate::kResumeMsg: { |
237 // [ OOB, kResumeMsg, pause capability, resume capability ] | 238 // [ OOB, kResumeMsg, pause capability, resume capability ] |
238 if (message.Length() != 4) return Error::null(); | 239 if (message.Length() != 4) return Error::null(); |
239 Object& obj = Object::Handle(I, message.At(2)); | 240 Object& obj = Object::Handle(zone, message.At(2)); |
240 if (!I->VerifyPauseCapability(obj)) return Error::null(); | 241 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
241 obj = message.At(3); | 242 obj = message.At(3); |
242 if (!obj.IsCapability()) return Error::null(); | 243 if (!obj.IsCapability()) return Error::null(); |
243 if (I->RemoveResumeCapability(Capability::Cast(obj))) { | 244 if (I->RemoveResumeCapability(Capability::Cast(obj))) { |
244 decrement_paused(); | 245 decrement_paused(); |
245 } | 246 } |
246 break; | 247 break; |
247 } | 248 } |
248 case Isolate::kPingMsg: { | 249 case Isolate::kPingMsg: { |
249 // [ OOB, kPingMsg, responsePort, priority, response ] | 250 // [ OOB, kPingMsg, responsePort, priority, response ] |
250 if (message.Length() != 5) return Error::null(); | 251 if (message.Length() != 5) return Error::null(); |
251 const Object& obj2 = Object::Handle(I, message.At(2)); | 252 const Object& obj2 = Object::Handle(zone, message.At(2)); |
252 if (!obj2.IsSendPort()) return Error::null(); | 253 if (!obj2.IsSendPort()) return Error::null(); |
253 const SendPort& send_port = SendPort::Cast(obj2); | 254 const SendPort& send_port = SendPort::Cast(obj2); |
254 const Object& obj3 = Object::Handle(I, message.At(3)); | 255 const Object& obj3 = Object::Handle(zone, message.At(3)); |
255 if (!obj3.IsSmi()) return Error::null(); | 256 if (!obj3.IsSmi()) return Error::null(); |
256 const intptr_t priority = Smi::Cast(obj3).Value(); | 257 const intptr_t priority = Smi::Cast(obj3).Value(); |
257 const Object& obj4 = Object::Handle(I, message.At(4)); | 258 const Object& obj4 = Object::Handle(zone, message.At(4)); |
258 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); | 259 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); |
259 const Instance& response = | 260 const Instance& response = |
260 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); | 261 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); |
261 if (priority == Isolate::kImmediateAction) { | 262 if (priority == Isolate::kImmediateAction) { |
262 uint8_t* data = NULL; | 263 uint8_t* data = NULL; |
263 intptr_t len = 0; | 264 intptr_t len = 0; |
264 SerializeObject(response, &data, &len, false); | 265 SerializeObject(response, &data, &len, false); |
265 PortMap::PostMessage(new Message(send_port.Id(), | 266 PortMap::PostMessage(new Message(send_port.Id(), |
266 data, len, | 267 data, len, |
267 Message::kNormalPriority)); | 268 Message::kNormalPriority)); |
268 } else { | 269 } else { |
269 ASSERT((priority == Isolate::kBeforeNextEventAction) || | 270 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
270 (priority == Isolate::kAsEventAction)); | 271 (priority == Isolate::kAsEventAction)); |
271 // Update the message so that it will be handled immediately when it | 272 // Update the message so that it will be handled immediately when it |
272 // is picked up from the message queue the next time. | 273 // is picked up from the message queue the next time. |
273 message.SetAt( | 274 message.SetAt(0, Smi::Handle(zone, |
274 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 275 Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
275 message.SetAt(3, Smi::Handle(I, Smi::New(Isolate::kImmediateAction))); | 276 message.SetAt(3, Smi::Handle(zone, |
| 277 Smi::New(Isolate::kImmediateAction))); |
276 uint8_t* data = NULL; | 278 uint8_t* data = NULL; |
277 intptr_t len = 0; | 279 intptr_t len = 0; |
278 SerializeObject(message, &data, &len, false); | 280 SerializeObject(message, &data, &len, false); |
279 this->PostMessage( | 281 this->PostMessage( |
280 new Message(Message::kIllegalPort, | 282 new Message(Message::kIllegalPort, |
281 data, len, | 283 data, len, |
282 Message::kNormalPriority), | 284 Message::kNormalPriority), |
283 priority == Isolate::kBeforeNextEventAction /* at_head */); | 285 priority == Isolate::kBeforeNextEventAction /* at_head */); |
284 } | 286 } |
285 break; | 287 break; |
286 } | 288 } |
287 case Isolate::kKillMsg: | 289 case Isolate::kKillMsg: |
288 case Isolate::kInternalKillMsg: | 290 case Isolate::kInternalKillMsg: |
289 case Isolate::kVMRestartMsg: { | 291 case Isolate::kVMRestartMsg: { |
290 // [ OOB, kKillMsg, terminate capability, priority ] | 292 // [ OOB, kKillMsg, terminate capability, priority ] |
291 if (message.Length() != 4) return Error::null(); | 293 if (message.Length() != 4) return Error::null(); |
292 Object& obj = Object::Handle(I, message.At(3)); | 294 Object& obj = Object::Handle(zone, message.At(3)); |
293 if (!obj.IsSmi()) return Error::null(); | 295 if (!obj.IsSmi()) return Error::null(); |
294 const intptr_t priority = Smi::Cast(obj).Value(); | 296 const intptr_t priority = Smi::Cast(obj).Value(); |
295 if (priority == Isolate::kImmediateAction) { | 297 if (priority == Isolate::kImmediateAction) { |
296 obj = message.At(2); | 298 obj = message.At(2); |
297 if (I->VerifyTerminateCapability(obj)) { | 299 if (I->VerifyTerminateCapability(obj)) { |
298 // We will kill the current isolate by returning an UnwindError. | 300 // We will kill the current isolate by returning an UnwindError. |
299 if (msg_type == Isolate::kKillMsg) { | 301 if (msg_type == Isolate::kKillMsg) { |
300 const String& msg = String::Handle(String::New( | 302 const String& msg = String::Handle(String::New( |
301 "isolate terminated by Isolate.kill")); | 303 "isolate terminated by Isolate.kill")); |
302 const UnwindError& error = | 304 const UnwindError& error = |
(...skipping 18 matching lines...) Expand all Loading... |
321 UNREACHABLE(); | 323 UNREACHABLE(); |
322 } | 324 } |
323 } else { | 325 } else { |
324 return Error::null(); | 326 return Error::null(); |
325 } | 327 } |
326 } else { | 328 } else { |
327 ASSERT((priority == Isolate::kBeforeNextEventAction) || | 329 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
328 (priority == Isolate::kAsEventAction)); | 330 (priority == Isolate::kAsEventAction)); |
329 // Update the message so that it will be handled immediately when it | 331 // Update the message so that it will be handled immediately when it |
330 // is picked up from the message queue the next time. | 332 // is picked up from the message queue the next time. |
331 message.SetAt( | 333 message.SetAt(0, Smi::Handle(zone, |
332 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 334 Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
333 message.SetAt(3, Smi::Handle(I, Smi::New(Isolate::kImmediateAction))); | 335 message.SetAt(3, Smi::Handle(zone, |
| 336 Smi::New(Isolate::kImmediateAction))); |
334 uint8_t* data = NULL; | 337 uint8_t* data = NULL; |
335 intptr_t len = 0; | 338 intptr_t len = 0; |
336 SerializeObject(message, &data, &len, false); | 339 SerializeObject(message, &data, &len, false); |
337 this->PostMessage( | 340 this->PostMessage( |
338 new Message(Message::kIllegalPort, | 341 new Message(Message::kIllegalPort, |
339 data, len, | 342 data, len, |
340 Message::kNormalPriority), | 343 Message::kNormalPriority), |
341 priority == Isolate::kBeforeNextEventAction /* at_head */); | 344 priority == Isolate::kBeforeNextEventAction /* at_head */); |
342 } | 345 } |
343 break; | 346 break; |
344 } | 347 } |
345 case Isolate::kInterruptMsg: { | 348 case Isolate::kInterruptMsg: { |
346 // [ OOB, kInterruptMsg, pause capability ] | 349 // [ OOB, kInterruptMsg, pause capability ] |
347 if (message.Length() != 3) return Error::null(); | 350 if (message.Length() != 3) return Error::null(); |
348 Object& obj = Object::Handle(I, message.At(2)); | 351 Object& obj = Object::Handle(zone, message.At(2)); |
349 if (!I->VerifyPauseCapability(obj)) return Error::null(); | 352 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
350 | 353 |
351 // If we are already paused, don't pause again. | 354 // If we are already paused, don't pause again. |
352 if (I->debugger()->PauseEvent() == NULL) { | 355 if (I->debugger()->PauseEvent() == NULL) { |
353 return I->debugger()->SignalIsolateInterrupted(); | 356 return I->debugger()->SignalIsolateInterrupted(); |
354 } | 357 } |
355 break; | 358 break; |
356 } | 359 } |
357 | 360 |
358 case Isolate::kAddExitMsg: | 361 case Isolate::kAddExitMsg: |
359 case Isolate::kDelExitMsg: | 362 case Isolate::kDelExitMsg: |
360 case Isolate::kAddErrorMsg: | 363 case Isolate::kAddErrorMsg: |
361 case Isolate::kDelErrorMsg: { | 364 case Isolate::kDelErrorMsg: { |
362 // [ OOB, msg, listener port ] | 365 // [ OOB, msg, listener port ] |
363 if (message.Length() < 3) return Error::null(); | 366 if (message.Length() < 3) return Error::null(); |
364 const Object& obj = Object::Handle(I, message.At(2)); | 367 const Object& obj = Object::Handle(zone, message.At(2)); |
365 if (!obj.IsSendPort()) return Error::null(); | 368 if (!obj.IsSendPort()) return Error::null(); |
366 const SendPort& listener = SendPort::Cast(obj); | 369 const SendPort& listener = SendPort::Cast(obj); |
367 switch (msg_type) { | 370 switch (msg_type) { |
368 case Isolate::kAddExitMsg: { | 371 case Isolate::kAddExitMsg: { |
369 if (message.Length() != 4) return Error::null(); | 372 if (message.Length() != 4) return Error::null(); |
370 // [ OOB, msg, listener port, response object ] | 373 // [ OOB, msg, listener port, response object ] |
371 const Object& response = Object::Handle(I, message.At(3)); | 374 const Object& response = Object::Handle(zone, message.At(3)); |
372 if (!response.IsInstance() && !response.IsNull()) { | 375 if (!response.IsInstance() && !response.IsNull()) { |
373 return Error::null(); | 376 return Error::null(); |
374 } | 377 } |
375 I->AddExitListener(listener, | 378 I->AddExitListener(listener, |
376 response.IsNull() ? Instance::null_instance() | 379 response.IsNull() ? Instance::null_instance() |
377 : Instance::Cast(response)); | 380 : Instance::Cast(response)); |
378 break; | 381 break; |
379 } | 382 } |
380 case Isolate::kDelExitMsg: | 383 case Isolate::kDelExitMsg: |
381 if (message.Length() != 3) return Error::null(); | 384 if (message.Length() != 3) return Error::null(); |
382 I->RemoveExitListener(listener); | 385 I->RemoveExitListener(listener); |
383 break; | 386 break; |
384 case Isolate::kAddErrorMsg: | 387 case Isolate::kAddErrorMsg: |
385 if (message.Length() != 3) return Error::null(); | 388 if (message.Length() != 3) return Error::null(); |
386 I->AddErrorListener(listener); | 389 I->AddErrorListener(listener); |
387 break; | 390 break; |
388 case Isolate::kDelErrorMsg: | 391 case Isolate::kDelErrorMsg: |
389 if (message.Length() != 3) return Error::null(); | 392 if (message.Length() != 3) return Error::null(); |
390 I->RemoveErrorListener(listener); | 393 I->RemoveErrorListener(listener); |
391 break; | 394 break; |
392 default: | 395 default: |
393 UNREACHABLE(); | 396 UNREACHABLE(); |
394 } | 397 } |
395 break; | 398 break; |
396 } | 399 } |
397 case Isolate::kErrorFatalMsg: { | 400 case Isolate::kErrorFatalMsg: { |
398 // [ OOB, kErrorFatalMsg, terminate capability, val ] | 401 // [ OOB, kErrorFatalMsg, terminate capability, val ] |
399 if (message.Length() != 4) return Error::null(); | 402 if (message.Length() != 4) return Error::null(); |
400 // Check that the terminate capability has been passed correctly. | 403 // Check that the terminate capability has been passed correctly. |
401 Object& obj = Object::Handle(I, message.At(2)); | 404 Object& obj = Object::Handle(zone, message.At(2)); |
402 if (!I->VerifyTerminateCapability(obj)) return Error::null(); | 405 if (!I->VerifyTerminateCapability(obj)) return Error::null(); |
403 // Get the value to be set. | 406 // Get the value to be set. |
404 obj = message.At(3); | 407 obj = message.At(3); |
405 if (!obj.IsBool()) return Error::null(); | 408 if (!obj.IsBool()) return Error::null(); |
406 I->SetErrorsFatal(Bool::Cast(obj).value()); | 409 I->SetErrorsFatal(Bool::Cast(obj).value()); |
407 break; | 410 break; |
408 } | 411 } |
409 #if defined(DEBUG) | 412 #if defined(DEBUG) |
410 // Malformed OOB messages are silently ignored in release builds. | 413 // Malformed OOB messages are silently ignored in release builds. |
411 default: | 414 default: |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 | 633 |
631 // Invoke the isolate's unhandled exception callback if there is one. | 634 // Invoke the isolate's unhandled exception callback if there is one. |
632 if (Isolate::UnhandledExceptionCallback() != NULL) { | 635 if (Isolate::UnhandledExceptionCallback() != NULL) { |
633 Dart_EnterScope(); | 636 Dart_EnterScope(); |
634 Dart_Handle error = Api::NewHandle(I, result.raw()); | 637 Dart_Handle error = Api::NewHandle(I, result.raw()); |
635 (Isolate::UnhandledExceptionCallback())(error); | 638 (Isolate::UnhandledExceptionCallback())(error); |
636 Dart_ExitScope(); | 639 Dart_ExitScope(); |
637 } | 640 } |
638 | 641 |
639 // Generate the error and stacktrace strings for the error message. | 642 // Generate the error and stacktrace strings for the error message. |
640 String& exc_str = String::Handle(I); | 643 String& exc_str = String::Handle(I->current_zone()); |
641 String& stacktrace_str = String::Handle(I); | 644 String& stacktrace_str = String::Handle(I->current_zone()); |
642 if (result.IsUnhandledException()) { | 645 if (result.IsUnhandledException()) { |
| 646 Zone* zone = I->current_zone(); |
643 const UnhandledException& uhe = UnhandledException::Cast(result); | 647 const UnhandledException& uhe = UnhandledException::Cast(result); |
644 const Instance& exception = Instance::Handle(I, uhe.exception()); | 648 const Instance& exception = Instance::Handle(zone, uhe.exception()); |
645 Object& tmp = Object::Handle(I); | 649 Object& tmp = Object::Handle(zone); |
646 tmp = DartLibraryCalls::ToString(exception); | 650 tmp = DartLibraryCalls::ToString(exception); |
647 if (!tmp.IsString()) { | 651 if (!tmp.IsString()) { |
648 tmp = String::New(exception.ToCString()); | 652 tmp = String::New(exception.ToCString()); |
649 } | 653 } |
650 exc_str ^= tmp.raw(); | 654 exc_str ^= tmp.raw(); |
651 | 655 |
652 const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace()); | 656 const Instance& stacktrace = Instance::Handle(zone, uhe.stacktrace()); |
653 tmp = DartLibraryCalls::ToString(stacktrace); | 657 tmp = DartLibraryCalls::ToString(stacktrace); |
654 if (!tmp.IsString()) { | 658 if (!tmp.IsString()) { |
655 tmp = String::New(stacktrace.ToCString()); | 659 tmp = String::New(stacktrace.ToCString()); |
656 } | 660 } |
657 stacktrace_str ^= tmp.raw();; | 661 stacktrace_str ^= tmp.raw();; |
658 } else { | 662 } else { |
659 exc_str = String::New(result.ToErrorCString()); | 663 exc_str = String::New(result.ToErrorCString()); |
660 } | 664 } |
661 if (result.IsUnwindError()) { | 665 if (result.IsUnwindError()) { |
662 // When unwinding we don't notify error listeners and we ignore | 666 // When unwinding we don't notify error listeners and we ignore |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 MutexLocker ml(mutex_); | 1059 MutexLocker ml(mutex_); |
1056 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. | 1060 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. |
1057 if (stack_limit_ == saved_stack_limit_) { | 1061 if (stack_limit_ == saved_stack_limit_) { |
1058 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; | 1062 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; |
1059 } | 1063 } |
1060 stack_limit_ |= interrupt_bits; | 1064 stack_limit_ |= interrupt_bits; |
1061 } | 1065 } |
1062 | 1066 |
1063 | 1067 |
1064 void Isolate::DoneLoading() { | 1068 void Isolate::DoneLoading() { |
1065 GrowableObjectArray& libs = | 1069 GrowableObjectArray& libs = GrowableObjectArray::Handle(current_zone(), |
1066 GrowableObjectArray::Handle(this, object_store()->libraries()); | 1070 object_store()->libraries()); |
1067 Library& lib = Library::Handle(this); | 1071 Library& lib = Library::Handle(current_zone()); |
1068 intptr_t num_libs = libs.Length(); | 1072 intptr_t num_libs = libs.Length(); |
1069 for (intptr_t i = 0; i < num_libs; i++) { | 1073 for (intptr_t i = 0; i < num_libs; i++) { |
1070 lib ^= libs.At(i); | 1074 lib ^= libs.At(i); |
1071 // If this library was loaded with Dart_LoadLibrary, it was marked | 1075 // If this library was loaded with Dart_LoadLibrary, it was marked |
1072 // as 'load in progres'. Set the status to 'loaded'. | 1076 // as 'load in progres'. Set the status to 'loaded'. |
1073 if (lib.LoadInProgress()) { | 1077 if (lib.LoadInProgress()) { |
1074 lib.SetLoaded(); | 1078 lib.SetLoaded(); |
1075 } | 1079 } |
1076 } | 1080 } |
1077 } | 1081 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 capability.IsCapability() && | 1129 capability.IsCapability() && |
1126 (terminate_capability() == Capability::Cast(capability).Id()); | 1130 (terminate_capability() == Capability::Cast(capability).Id()); |
1127 } | 1131 } |
1128 | 1132 |
1129 | 1133 |
1130 bool Isolate::AddResumeCapability(const Capability& capability) { | 1134 bool Isolate::AddResumeCapability(const Capability& capability) { |
1131 // Ensure a limit for the number of resume capabilities remembered. | 1135 // Ensure a limit for the number of resume capabilities remembered. |
1132 static const intptr_t kMaxResumeCapabilities = kSmiMax / (6 * kWordSize); | 1136 static const intptr_t kMaxResumeCapabilities = kSmiMax / (6 * kWordSize); |
1133 | 1137 |
1134 const GrowableObjectArray& caps = GrowableObjectArray::Handle( | 1138 const GrowableObjectArray& caps = GrowableObjectArray::Handle( |
1135 this, object_store()->resume_capabilities()); | 1139 current_zone(), object_store()->resume_capabilities()); |
1136 Capability& current = Capability::Handle(this); | 1140 Capability& current = Capability::Handle(current_zone()); |
1137 intptr_t insertion_index = -1; | 1141 intptr_t insertion_index = -1; |
1138 for (intptr_t i = 0; i < caps.Length(); i++) { | 1142 for (intptr_t i = 0; i < caps.Length(); i++) { |
1139 current ^= caps.At(i); | 1143 current ^= caps.At(i); |
1140 if (current.IsNull()) { | 1144 if (current.IsNull()) { |
1141 if (insertion_index < 0) { | 1145 if (insertion_index < 0) { |
1142 insertion_index = i; | 1146 insertion_index = i; |
1143 } | 1147 } |
1144 } else if (current.Id() == capability.Id()) { | 1148 } else if (current.Id() == capability.Id()) { |
1145 return false; | 1149 return false; |
1146 } | 1150 } |
1147 } | 1151 } |
1148 if (insertion_index < 0) { | 1152 if (insertion_index < 0) { |
1149 if (caps.Length() >= kMaxResumeCapabilities) { | 1153 if (caps.Length() >= kMaxResumeCapabilities) { |
1150 // Cannot grow the array of resume capabilities beyond its max. Additional | 1154 // Cannot grow the array of resume capabilities beyond its max. Additional |
1151 // pause requests are ignored. In practice will never happen as we will | 1155 // pause requests are ignored. In practice will never happen as we will |
1152 // run out of memory beforehand. | 1156 // run out of memory beforehand. |
1153 return false; | 1157 return false; |
1154 } | 1158 } |
1155 caps.Add(capability); | 1159 caps.Add(capability); |
1156 } else { | 1160 } else { |
1157 caps.SetAt(insertion_index, capability); | 1161 caps.SetAt(insertion_index, capability); |
1158 } | 1162 } |
1159 return true; | 1163 return true; |
1160 } | 1164 } |
1161 | 1165 |
1162 | 1166 |
1163 bool Isolate::RemoveResumeCapability(const Capability& capability) { | 1167 bool Isolate::RemoveResumeCapability(const Capability& capability) { |
1164 const GrowableObjectArray& caps = GrowableObjectArray::Handle( | 1168 const GrowableObjectArray& caps = GrowableObjectArray::Handle( |
1165 this, object_store()->resume_capabilities()); | 1169 current_zone(), object_store()->resume_capabilities()); |
1166 Capability& current = Capability::Handle(this); | 1170 Capability& current = Capability::Handle(current_zone()); |
1167 for (intptr_t i = 0; i < caps.Length(); i++) { | 1171 for (intptr_t i = 0; i < caps.Length(); i++) { |
1168 current ^= caps.At(i); | 1172 current ^= caps.At(i); |
1169 if (!current.IsNull() && (current.Id() == capability.Id())) { | 1173 if (!current.IsNull() && (current.Id() == capability.Id())) { |
1170 // Remove the matching capability from the list. | 1174 // Remove the matching capability from the list. |
1171 current = Capability::null(); | 1175 current = Capability::null(); |
1172 caps.SetAt(i, current); | 1176 caps.SetAt(i, current); |
1173 return true; | 1177 return true; |
1174 } | 1178 } |
1175 } | 1179 } |
1176 return false; | 1180 return false; |
1177 } | 1181 } |
1178 | 1182 |
1179 | 1183 |
1180 // TODO(iposva): Remove duplicated code and start using some hash based | 1184 // TODO(iposva): Remove duplicated code and start using some hash based |
1181 // structure instead of these linear lookups. | 1185 // structure instead of these linear lookups. |
1182 void Isolate::AddExitListener(const SendPort& listener, | 1186 void Isolate::AddExitListener(const SendPort& listener, |
1183 const Instance& response) { | 1187 const Instance& response) { |
1184 // Ensure a limit for the number of listeners remembered. | 1188 // Ensure a limit for the number of listeners remembered. |
1185 static const intptr_t kMaxListeners = kSmiMax / (12 * kWordSize); | 1189 static const intptr_t kMaxListeners = kSmiMax / (12 * kWordSize); |
1186 | 1190 |
1187 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1191 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1188 this, object_store()->exit_listeners()); | 1192 current_zone(), object_store()->exit_listeners()); |
1189 SendPort& current = SendPort::Handle(this); | 1193 SendPort& current = SendPort::Handle(current_zone()); |
1190 intptr_t insertion_index = -1; | 1194 intptr_t insertion_index = -1; |
1191 for (intptr_t i = 0; i < listeners.Length(); i += 2) { | 1195 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
1192 current ^= listeners.At(i); | 1196 current ^= listeners.At(i); |
1193 if (current.IsNull()) { | 1197 if (current.IsNull()) { |
1194 if (insertion_index < 0) { | 1198 if (insertion_index < 0) { |
1195 insertion_index = i; | 1199 insertion_index = i; |
1196 } | 1200 } |
1197 } else if (current.Id() == listener.Id()) { | 1201 } else if (current.Id() == listener.Id()) { |
1198 listeners.SetAt(i + 1, response); | 1202 listeners.SetAt(i + 1, response); |
1199 return; | 1203 return; |
(...skipping 10 matching lines...) Expand all Loading... |
1210 listeners.Add(response); | 1214 listeners.Add(response); |
1211 } else { | 1215 } else { |
1212 listeners.SetAt(insertion_index, listener); | 1216 listeners.SetAt(insertion_index, listener); |
1213 listeners.SetAt(insertion_index + 1, response); | 1217 listeners.SetAt(insertion_index + 1, response); |
1214 } | 1218 } |
1215 } | 1219 } |
1216 | 1220 |
1217 | 1221 |
1218 void Isolate::RemoveExitListener(const SendPort& listener) { | 1222 void Isolate::RemoveExitListener(const SendPort& listener) { |
1219 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1223 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1220 this, object_store()->exit_listeners()); | 1224 current_zone(), object_store()->exit_listeners()); |
1221 SendPort& current = SendPort::Handle(this); | 1225 SendPort& current = SendPort::Handle(current_zone()); |
1222 for (intptr_t i = 0; i < listeners.Length(); i += 2) { | 1226 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
1223 current ^= listeners.At(i); | 1227 current ^= listeners.At(i); |
1224 if (!current.IsNull() && (current.Id() == listener.Id())) { | 1228 if (!current.IsNull() && (current.Id() == listener.Id())) { |
1225 // Remove the matching listener from the list. | 1229 // Remove the matching listener from the list. |
1226 current = SendPort::null(); | 1230 current = SendPort::null(); |
1227 listeners.SetAt(i, current); | 1231 listeners.SetAt(i, current); |
1228 listeners.SetAt(i + 1, Object::null_instance()); | 1232 listeners.SetAt(i + 1, Object::null_instance()); |
1229 return; | 1233 return; |
1230 } | 1234 } |
1231 } | 1235 } |
1232 } | 1236 } |
1233 | 1237 |
1234 | 1238 |
1235 void Isolate::NotifyExitListeners() { | 1239 void Isolate::NotifyExitListeners() { |
1236 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1240 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1237 this, this->object_store()->exit_listeners()); | 1241 current_zone(), this->object_store()->exit_listeners()); |
1238 if (listeners.IsNull()) return; | 1242 if (listeners.IsNull()) return; |
1239 | 1243 |
1240 SendPort& listener = SendPort::Handle(this); | 1244 SendPort& listener = SendPort::Handle(current_zone()); |
1241 Instance& response = Instance::Handle(this); | 1245 Instance& response = Instance::Handle(current_zone()); |
1242 for (intptr_t i = 0; i < listeners.Length(); i += 2) { | 1246 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
1243 listener ^= listeners.At(i); | 1247 listener ^= listeners.At(i); |
1244 if (!listener.IsNull()) { | 1248 if (!listener.IsNull()) { |
1245 Dart_Port port_id = listener.Id(); | 1249 Dart_Port port_id = listener.Id(); |
1246 uint8_t* data = NULL; | 1250 uint8_t* data = NULL; |
1247 intptr_t len = 0; | 1251 intptr_t len = 0; |
1248 response ^= listeners.At(i + 1); | 1252 response ^= listeners.At(i + 1); |
1249 SerializeObject(response, &data, &len, false); | 1253 SerializeObject(response, &data, &len, false); |
1250 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); | 1254 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); |
1251 PortMap::PostMessage(msg); | 1255 PortMap::PostMessage(msg); |
1252 } | 1256 } |
1253 } | 1257 } |
1254 } | 1258 } |
1255 | 1259 |
1256 | 1260 |
1257 void Isolate::AddErrorListener(const SendPort& listener) { | 1261 void Isolate::AddErrorListener(const SendPort& listener) { |
1258 // Ensure a limit for the number of listeners remembered. | 1262 // Ensure a limit for the number of listeners remembered. |
1259 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); | 1263 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); |
1260 | 1264 |
1261 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1265 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1262 this, object_store()->error_listeners()); | 1266 current_zone(), object_store()->error_listeners()); |
1263 SendPort& current = SendPort::Handle(this); | 1267 SendPort& current = SendPort::Handle(current_zone()); |
1264 intptr_t insertion_index = -1; | 1268 intptr_t insertion_index = -1; |
1265 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1269 for (intptr_t i = 0; i < listeners.Length(); i++) { |
1266 current ^= listeners.At(i); | 1270 current ^= listeners.At(i); |
1267 if (current.IsNull()) { | 1271 if (current.IsNull()) { |
1268 if (insertion_index < 0) { | 1272 if (insertion_index < 0) { |
1269 insertion_index = i; | 1273 insertion_index = i; |
1270 } | 1274 } |
1271 } else if (current.Id() == listener.Id()) { | 1275 } else if (current.Id() == listener.Id()) { |
1272 return; | 1276 return; |
1273 } | 1277 } |
1274 } | 1278 } |
1275 if (insertion_index < 0) { | 1279 if (insertion_index < 0) { |
1276 if (listeners.Length() >= kMaxListeners) { | 1280 if (listeners.Length() >= kMaxListeners) { |
1277 // Cannot grow the array of listeners beyond its max. Additional | 1281 // Cannot grow the array of listeners beyond its max. Additional |
1278 // listeners are ignored. In practice will never happen as we will | 1282 // listeners are ignored. In practice will never happen as we will |
1279 // run out of memory beforehand. | 1283 // run out of memory beforehand. |
1280 return; | 1284 return; |
1281 } | 1285 } |
1282 listeners.Add(listener); | 1286 listeners.Add(listener); |
1283 } else { | 1287 } else { |
1284 listeners.SetAt(insertion_index, listener); | 1288 listeners.SetAt(insertion_index, listener); |
1285 } | 1289 } |
1286 } | 1290 } |
1287 | 1291 |
1288 | 1292 |
1289 void Isolate::RemoveErrorListener(const SendPort& listener) { | 1293 void Isolate::RemoveErrorListener(const SendPort& listener) { |
1290 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1294 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1291 this, object_store()->error_listeners()); | 1295 current_zone(), object_store()->error_listeners()); |
1292 SendPort& current = SendPort::Handle(this); | 1296 SendPort& current = SendPort::Handle(current_zone()); |
1293 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1297 for (intptr_t i = 0; i < listeners.Length(); i++) { |
1294 current ^= listeners.At(i); | 1298 current ^= listeners.At(i); |
1295 if (!current.IsNull() && (current.Id() == listener.Id())) { | 1299 if (!current.IsNull() && (current.Id() == listener.Id())) { |
1296 // Remove the matching listener from the list. | 1300 // Remove the matching listener from the list. |
1297 current = SendPort::null(); | 1301 current = SendPort::null(); |
1298 listeners.SetAt(i, current); | 1302 listeners.SetAt(i, current); |
1299 return; | 1303 return; |
1300 } | 1304 } |
1301 } | 1305 } |
1302 } | 1306 } |
1303 | 1307 |
1304 | 1308 |
1305 bool Isolate::NotifyErrorListeners(const String& msg, | 1309 bool Isolate::NotifyErrorListeners(const String& msg, |
1306 const String& stacktrace) { | 1310 const String& stacktrace) { |
1307 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1311 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
1308 this, this->object_store()->error_listeners()); | 1312 current_zone(), this->object_store()->error_listeners()); |
1309 if (listeners.IsNull()) return false; | 1313 if (listeners.IsNull()) return false; |
1310 | 1314 |
1311 const Array& arr = Array::Handle(this, Array::New(2)); | 1315 const Array& arr = Array::Handle(current_zone(), Array::New(2)); |
1312 arr.SetAt(0, msg); | 1316 arr.SetAt(0, msg); |
1313 arr.SetAt(1, stacktrace); | 1317 arr.SetAt(1, stacktrace); |
1314 SendPort& listener = SendPort::Handle(this); | 1318 SendPort& listener = SendPort::Handle(current_zone()); |
1315 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1319 for (intptr_t i = 0; i < listeners.Length(); i++) { |
1316 listener ^= listeners.At(i); | 1320 listener ^= listeners.At(i); |
1317 if (!listener.IsNull()) { | 1321 if (!listener.IsNull()) { |
1318 Dart_Port port_id = listener.Id(); | 1322 Dart_Port port_id = listener.Id(); |
1319 uint8_t* data = NULL; | 1323 uint8_t* data = NULL; |
1320 intptr_t len = 0; | 1324 intptr_t len = 0; |
1321 SerializeObject(arr, &data, &len, false); | 1325 SerializeObject(arr, &data, &len, false); |
1322 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); | 1326 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); |
1323 PortMap::PostMessage(msg); | 1327 PortMap::PostMessage(msg); |
1324 } | 1328 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1369 return MessageHandler::kError; | 1373 return MessageHandler::kError; |
1370 } | 1374 } |
1371 | 1375 |
1372 Object& result = Object::Handle(); | 1376 Object& result = Object::Handle(); |
1373 result = state->ResolveFunction(); | 1377 result = state->ResolveFunction(); |
1374 bool is_spawn_uri = state->is_spawn_uri(); | 1378 bool is_spawn_uri = state->is_spawn_uri(); |
1375 if (result.IsError()) { | 1379 if (result.IsError()) { |
1376 return StoreError(isolate, Error::Cast(result)); | 1380 return StoreError(isolate, Error::Cast(result)); |
1377 } | 1381 } |
1378 ASSERT(result.IsFunction()); | 1382 ASSERT(result.IsFunction()); |
1379 Function& func = Function::Handle(isolate); | 1383 Function& func = Function::Handle(thread->zone()); |
1380 func ^= result.raw(); | 1384 func ^= result.raw(); |
1381 | 1385 |
1382 // TODO(turnidge): Currently we need a way to force a one-time | 1386 // TODO(turnidge): Currently we need a way to force a one-time |
1383 // breakpoint for all spawned isolates to support isolate | 1387 // breakpoint for all spawned isolates to support isolate |
1384 // debugging. Remove this once the vmservice becomes the standard | 1388 // debugging. Remove this once the vmservice becomes the standard |
1385 // way to debug. Set the breakpoint on the static function instead | 1389 // way to debug. Set the breakpoint on the static function instead |
1386 // of its implicit closure function because that latter is merely | 1390 // of its implicit closure function because that latter is merely |
1387 // a dispatcher that is marked as undebuggable. | 1391 // a dispatcher that is marked as undebuggable. |
1388 if (FLAG_break_at_isolate_spawn) { | 1392 if (FLAG_break_at_isolate_spawn) { |
1389 isolate->debugger()->OneTimeBreakAtEntry(func); | 1393 isolate->debugger()->OneTimeBreakAtEntry(func); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 | 1665 |
1662 // First, perform higher-level cleanup that may need to allocate. | 1666 // First, perform higher-level cleanup that may need to allocate. |
1663 { | 1667 { |
1664 // Ensure we have a zone and handle scope so that we can call VM functions. | 1668 // Ensure we have a zone and handle scope so that we can call VM functions. |
1665 StackZone stack_zone(thread); | 1669 StackZone stack_zone(thread); |
1666 HandleScope handle_scope(thread); | 1670 HandleScope handle_scope(thread); |
1667 | 1671 |
1668 // Write out the coverage data if collection has been enabled. | 1672 // Write out the coverage data if collection has been enabled. |
1669 if ((this != Dart::vm_isolate()) && | 1673 if ((this != Dart::vm_isolate()) && |
1670 !ServiceIsolate::IsServiceIsolateDescendant(this)) { | 1674 !ServiceIsolate::IsServiceIsolateDescendant(this)) { |
1671 CodeCoverage::Write(this); | 1675 CodeCoverage::Write(thread); |
1672 } | 1676 } |
1673 | 1677 |
1674 // Write compiler stats data if enabled. | 1678 // Write compiler stats data if enabled. |
1675 if (FLAG_compiler_stats | 1679 if (FLAG_compiler_stats |
1676 && !ServiceIsolate::IsServiceIsolateDescendant(this) | 1680 && !ServiceIsolate::IsServiceIsolateDescendant(this) |
1677 && (this != Dart::vm_isolate())) { | 1681 && (this != Dart::vm_isolate())) { |
1678 OS::Print("%s", compiler_stats()->PrintToZone()); | 1682 OS::Print("%s", compiler_stats()->PrintToZone()); |
1679 } | 1683 } |
1680 } | 1684 } |
1681 | 1685 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1891 Library::Handle(object_store()->root_library()); | 1895 Library::Handle(object_store()->root_library()); |
1892 if (!lib.IsNull()) { | 1896 if (!lib.IsNull()) { |
1893 jsobj.AddProperty("rootLib", lib); | 1897 jsobj.AddProperty("rootLib", lib); |
1894 } | 1898 } |
1895 | 1899 |
1896 { | 1900 { |
1897 JSONObject tagCounters(&jsobj, "_tagCounters"); | 1901 JSONObject tagCounters(&jsobj, "_tagCounters"); |
1898 vm_tag_counters()->PrintToJSONObject(&tagCounters); | 1902 vm_tag_counters()->PrintToJSONObject(&tagCounters); |
1899 } | 1903 } |
1900 if (object_store()->sticky_error() != Object::null()) { | 1904 if (object_store()->sticky_error() != Object::null()) { |
1901 Error& error = Error::Handle(this, object_store()->sticky_error()); | 1905 Error& error = Error::Handle(current_zone(), |
| 1906 object_store()->sticky_error()); |
1902 ASSERT(!error.IsNull()); | 1907 ASSERT(!error.IsNull()); |
1903 jsobj.AddProperty("error", error, false); | 1908 jsobj.AddProperty("error", error, false); |
1904 } | 1909 } |
1905 | 1910 |
1906 { | 1911 { |
1907 const GrowableObjectArray& libs = | 1912 const GrowableObjectArray& libs = |
1908 GrowableObjectArray::Handle(object_store()->libraries()); | 1913 GrowableObjectArray::Handle(object_store()->libraries()); |
1909 intptr_t num_libs = libs.Length(); | 1914 intptr_t num_libs = libs.Length(); |
1910 Library& lib = Library::Handle(); | 1915 Library& lib = Library::Handle(); |
1911 | 1916 |
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2617 serialized_message_, serialized_message_len_); | 2622 serialized_message_, serialized_message_len_); |
2618 } | 2623 } |
2619 | 2624 |
2620 | 2625 |
2621 void IsolateSpawnState::Cleanup() { | 2626 void IsolateSpawnState::Cleanup() { |
2622 SwitchIsolateScope switch_scope(I); | 2627 SwitchIsolateScope switch_scope(I); |
2623 Dart::ShutdownIsolate(); | 2628 Dart::ShutdownIsolate(); |
2624 } | 2629 } |
2625 | 2630 |
2626 } // namespace dart | 2631 } // namespace dart |
OLD | NEW |