| 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 |