Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/isolate.h" | 5 #include "vm/isolate.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "platform/json.h" | 10 #include "platform/json.h" |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { | 142 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { |
| 143 class_table()->RegisterAt(index, cls); | 143 class_table()->RegisterAt(index, cls); |
| 144 } | 144 } |
| 145 | 145 |
| 146 | 146 |
| 147 void Isolate::ValidateClassTable() { | 147 void Isolate::ValidateClassTable() { |
| 148 class_table()->Validate(); | 148 class_table()->Validate(); |
| 149 } | 149 } |
| 150 | 150 |
| 151 | 151 |
| 152 void Isolate::SendInternalLibMessage(LibMsgId msg_id, uint64_t capability) { | |
| 153 const Array& msg = Array::Handle(Array::New(3)); | |
| 154 Object& element = Object::Handle(); | |
| 155 | |
| 156 element = Smi::New(Message::kIsolateLibOOBMsg); | |
| 157 msg.SetAt(0, element); | |
| 158 element = Smi::New(msg_id); | |
| 159 msg.SetAt(1, element); | |
| 160 element = Capability::New(capability); | |
| 161 msg.SetAt(2, element); | |
| 162 | |
| 163 uint8_t* data = NULL; | |
| 164 MessageWriter writer(&data, &allocator, false); | |
| 165 writer.WriteMessage(msg); | |
| 166 | |
| 167 PortMap::PostMessage(new Message(main_port(), | |
| 168 data, writer.BytesWritten(), | |
| 169 Message::kOOBPriority)); | |
| 170 } | |
| 171 | |
| 172 | |
| 152 class IsolateMessageHandler : public MessageHandler { | 173 class IsolateMessageHandler : public MessageHandler { |
| 153 public: | 174 public: |
| 154 explicit IsolateMessageHandler(Isolate* isolate); | 175 explicit IsolateMessageHandler(Isolate* isolate); |
| 155 ~IsolateMessageHandler(); | 176 ~IsolateMessageHandler(); |
| 156 | 177 |
| 157 const char* name() const; | 178 const char* name() const; |
| 158 void MessageNotify(Message::Priority priority); | 179 void MessageNotify(Message::Priority priority); |
| 159 bool HandleMessage(Message* message); | 180 bool HandleMessage(Message* message); |
| 160 void NotifyPauseOnStart(); | 181 void NotifyPauseOnStart(); |
| 161 void NotifyPauseOnExit(); | 182 void NotifyPauseOnExit(); |
| 162 | 183 |
| 163 #if defined(DEBUG) | 184 #if defined(DEBUG) |
| 164 // Check that it is safe to access this handler. | 185 // Check that it is safe to access this handler. |
| 165 void CheckAccess(); | 186 void CheckAccess(); |
| 166 #endif | 187 #endif |
| 167 bool IsCurrentIsolate() const; | 188 bool IsCurrentIsolate() const; |
| 168 virtual Isolate* isolate() const { return isolate_; } | 189 virtual Isolate* isolate() const { return isolate_; } |
| 169 | 190 |
| 170 // Keep both these enums in sync with isolate_patch.dart. | |
| 171 // The different Isolate API message types. | |
| 172 enum { | |
| 173 kPauseMsg = 1, | |
| 174 kResumeMsg = 2, | |
| 175 kPingMsg = 3, | |
| 176 kKillMsg = 4, | |
| 177 kAddExitMsg = 5, | |
| 178 kDelExitMsg = 6, | |
| 179 kAddErrorMsg = 7, | |
| 180 kDelErrorMsg = 8, | |
| 181 kErrorFatalMsg = 9, | |
| 182 }; | |
| 183 // The different Isolate API message priorities for ping and kill messages. | |
| 184 enum { | |
| 185 kImmediateAction = 0, | |
| 186 kBeforeNextEventAction = 1, | |
| 187 kAsEventAction = 2 | |
| 188 }; | |
| 189 | |
| 190 private: | 191 private: |
| 191 // A result of false indicates that the isolate should terminate the | 192 // A result of false indicates that the isolate should terminate the |
| 192 // processing of further events. | 193 // processing of further events. |
| 193 bool HandleLibMessage(const Array& message); | 194 RawError* HandleLibMessage(const Array& message); |
| 194 | 195 |
| 195 bool ProcessUnhandledException(const Error& result); | 196 bool ProcessUnhandledException(const Error& result); |
| 196 Isolate* isolate_; | 197 Isolate* isolate_; |
| 197 }; | 198 }; |
| 198 | 199 |
| 199 | 200 |
| 200 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) | 201 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
| 201 : isolate_(isolate) { | 202 : isolate_(isolate) { |
| 202 } | 203 } |
| 203 | 204 |
| 204 | 205 |
| 205 IsolateMessageHandler::~IsolateMessageHandler() { | 206 IsolateMessageHandler::~IsolateMessageHandler() { |
| 206 } | 207 } |
| 207 | 208 |
| 208 const char* IsolateMessageHandler::name() const { | 209 const char* IsolateMessageHandler::name() const { |
| 209 return isolate_->name(); | 210 return isolate_->name(); |
| 210 } | 211 } |
| 211 | 212 |
| 212 | 213 |
| 213 // Isolate library OOB messages are fixed sized arrays which have the | 214 // Isolate library OOB messages are fixed sized arrays which have the |
| 214 // following format: | 215 // following format: |
| 215 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] | 216 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] |
| 216 bool IsolateMessageHandler::HandleLibMessage(const Array& message) { | 217 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { |
| 217 if (message.Length() < 2) return true; | 218 if (message.Length() < 2) return Error::null(); |
| 218 const Object& type = Object::Handle(I, message.At(1)); | 219 const Object& type = Object::Handle(I, message.At(1)); |
| 219 if (!type.IsSmi()) return true; | 220 if (!type.IsSmi()) return Error::null(); |
| 220 const intptr_t msg_type = Smi::Cast(type).Value(); | 221 const intptr_t msg_type = Smi::Cast(type).Value(); |
| 221 switch (msg_type) { | 222 switch (msg_type) { |
| 222 case kPauseMsg: { | 223 case Isolate::kPauseMsg: { |
| 223 // [ OOB, kPauseMsg, pause capability, resume capability ] | 224 // [ OOB, kPauseMsg, pause capability, resume capability ] |
| 224 if (message.Length() != 4) return true; | 225 if (message.Length() != 4) return Error::null(); |
| 225 Object& obj = Object::Handle(I, message.At(2)); | 226 Object& obj = Object::Handle(I, message.At(2)); |
| 226 if (!I->VerifyPauseCapability(obj)) return true; | 227 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
| 227 obj = message.At(3); | 228 obj = message.At(3); |
| 228 if (!obj.IsCapability()) return true; | 229 if (!obj.IsCapability()) return Error::null(); |
| 229 if (I->AddResumeCapability(Capability::Cast(obj))) { | 230 if (I->AddResumeCapability(Capability::Cast(obj))) { |
| 230 increment_paused(); | 231 increment_paused(); |
| 231 } | 232 } |
| 232 break; | 233 break; |
| 233 } | 234 } |
| 234 case kResumeMsg: { | 235 case Isolate::kResumeMsg: { |
| 235 // [ OOB, kResumeMsg, pause capability, resume capability ] | 236 // [ OOB, kResumeMsg, pause capability, resume capability ] |
| 236 if (message.Length() != 4) return true; | 237 if (message.Length() != 4) return Error::null(); |
| 237 Object& obj = Object::Handle(I, message.At(2)); | 238 Object& obj = Object::Handle(I, message.At(2)); |
| 238 if (!I->VerifyPauseCapability(obj)) return true; | 239 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
| 239 obj = message.At(3); | 240 obj = message.At(3); |
| 240 if (!obj.IsCapability()) return true; | 241 if (!obj.IsCapability()) return Error::null(); |
| 241 if (I->RemoveResumeCapability(Capability::Cast(obj))) { | 242 if (I->RemoveResumeCapability(Capability::Cast(obj))) { |
| 242 decrement_paused(); | 243 decrement_paused(); |
| 243 } | 244 } |
| 244 break; | 245 break; |
| 245 } | 246 } |
| 246 case kPingMsg: { | 247 case Isolate::kPingMsg: { |
| 247 // [ OOB, kPingMsg, responsePort, priority, response ] | 248 // [ OOB, kPingMsg, responsePort, priority, response ] |
| 248 if (message.Length() != 5) return true; | 249 if (message.Length() != 5) return Error::null(); |
| 249 const Object& obj2 = Object::Handle(I, message.At(2)); | 250 const Object& obj2 = Object::Handle(I, message.At(2)); |
| 250 if (!obj2.IsSendPort()) return true; | 251 if (!obj2.IsSendPort()) return Error::null(); |
| 251 const SendPort& send_port = SendPort::Cast(obj2); | 252 const SendPort& send_port = SendPort::Cast(obj2); |
| 252 const Object& obj3 = Object::Handle(I, message.At(3)); | 253 const Object& obj3 = Object::Handle(I, message.At(3)); |
| 253 if (!obj3.IsSmi()) return true; | 254 if (!obj3.IsSmi()) return Error::null(); |
| 254 const intptr_t priority = Smi::Cast(obj3).Value(); | 255 const intptr_t priority = Smi::Cast(obj3).Value(); |
| 255 const Object& obj4 = Object::Handle(I, message.At(4)); | 256 const Object& obj4 = Object::Handle(I, message.At(4)); |
| 256 if (!obj4.IsInstance() && !obj4.IsNull()) return true; | 257 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); |
| 257 const Instance& response = | 258 const Instance& response = |
| 258 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); | 259 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); |
| 259 if (priority == kImmediateAction) { | 260 if (priority == Isolate::kImmediateAction) { |
| 260 uint8_t* data = NULL; | 261 uint8_t* data = NULL; |
| 261 intptr_t len = 0; | 262 intptr_t len = 0; |
| 262 SerializeObject(response, &data, &len, false); | 263 SerializeObject(response, &data, &len, false); |
| 263 PortMap::PostMessage(new Message(send_port.Id(), | 264 PortMap::PostMessage(new Message(send_port.Id(), |
| 264 data, len, | 265 data, len, |
| 265 Message::kNormalPriority)); | 266 Message::kNormalPriority)); |
| 266 } else { | 267 } else { |
| 267 ASSERT((priority == kBeforeNextEventAction) || | 268 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
| 268 (priority == kAsEventAction)); | 269 (priority == Isolate::kAsEventAction)); |
| 269 // Update the message so that it will be handled immediately when it | 270 // Update the message so that it will be handled immediately when it |
| 270 // is picked up from the message queue the next time. | 271 // is picked up from the message queue the next time. |
| 271 message.SetAt( | 272 message.SetAt( |
| 272 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 273 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
| 273 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | 274 message.SetAt(3, Smi::Handle(I, Smi::New(Isolate::kImmediateAction))); |
| 274 uint8_t* data = NULL; | 275 uint8_t* data = NULL; |
| 275 intptr_t len = 0; | 276 intptr_t len = 0; |
| 276 SerializeObject(message, &data, &len, false); | 277 SerializeObject(message, &data, &len, false); |
| 277 this->PostMessage(new Message(Message::kIllegalPort, | 278 this->PostMessage( |
| 278 data, len, | 279 new Message(Message::kIllegalPort, |
| 279 Message::kNormalPriority), | 280 data, len, |
| 280 priority == kBeforeNextEventAction /* at_head */); | 281 Message::kNormalPriority), |
| 282 priority == Isolate::kBeforeNextEventAction /* at_head */); | |
| 281 } | 283 } |
| 282 break; | 284 break; |
| 283 } | 285 } |
| 284 case kKillMsg: { | 286 case Isolate::kKillMsg: { |
| 285 // [ OOB, kKillMsg, terminate capability, priority ] | 287 // [ OOB, kKillMsg, terminate capability, priority ] |
| 286 if (message.Length() != 4) return true; | 288 if (message.Length() != 4) return Error::null(); |
| 287 Object& obj = Object::Handle(I, message.At(3)); | 289 Object& obj = Object::Handle(I, message.At(3)); |
| 288 if (!obj.IsSmi()) return true; | 290 if (!obj.IsSmi()) return Error::null(); |
| 289 const intptr_t priority = Smi::Cast(obj).Value(); | 291 const intptr_t priority = Smi::Cast(obj).Value(); |
| 290 if (priority == kImmediateAction) { | 292 if (priority == Isolate::kImmediateAction) { |
| 291 obj = message.At(2); | 293 obj = message.At(2); |
| 292 // Signal that the isolate should stop execution. | 294 // Signal that the isolate should stop execution. |
| 293 return !I->VerifyTerminateCapability(obj); | 295 if (I->VerifyTerminateCapability(obj)) { |
| 296 const String& msg = String::Handle(String::New( | |
| 297 "isolate terminated by Isolate.kill")); | |
| 298 return UnwindError::New(msg); | |
| 299 } else { | |
| 300 return Error::null(); | |
| 301 } | |
| 294 } else { | 302 } else { |
| 295 ASSERT((priority == kBeforeNextEventAction) || | 303 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
| 296 (priority == kAsEventAction)); | 304 (priority == Isolate::kAsEventAction)); |
| 297 // Update the message so that it will be handled immediately when it | 305 // Update the message so that it will be handled immediately when it |
| 298 // is picked up from the message queue the next time. | 306 // is picked up from the message queue the next time. |
| 299 message.SetAt( | 307 message.SetAt( |
| 300 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 308 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
| 301 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | 309 message.SetAt(3, Smi::Handle(I, Smi::New(Isolate::kImmediateAction))); |
| 302 uint8_t* data = NULL; | 310 uint8_t* data = NULL; |
| 303 intptr_t len = 0; | 311 intptr_t len = 0; |
| 304 SerializeObject(message, &data, &len, false); | 312 SerializeObject(message, &data, &len, false); |
| 305 this->PostMessage(new Message(Message::kIllegalPort, | 313 this->PostMessage( |
| 306 data, len, | 314 new Message(Message::kIllegalPort, |
| 307 Message::kNormalPriority), | 315 data, len, |
| 308 priority == kBeforeNextEventAction /* at_head */); | 316 Message::kNormalPriority), |
| 317 priority == Isolate::kBeforeNextEventAction /* at_head */); | |
| 309 } | 318 } |
| 310 break; | 319 break; |
| 311 } | 320 } |
| 312 case kAddExitMsg: | 321 case Isolate::kInterruptMsg: { |
| 313 case kDelExitMsg: | 322 // [ OOB, kInterruptMsg, pause capability ] |
| 314 case kAddErrorMsg: | 323 if (message.Length() != 3) return Error::null(); |
| 315 case kDelErrorMsg: { | 324 Object& obj = Object::Handle(I, message.At(2)); |
| 325 if (!I->VerifyPauseCapability(obj)) return Error::null(); | |
| 326 | |
| 327 // If we are already paused, don't pause again. | |
| 328 if (I->debugger()->PauseEvent() == NULL) { | |
| 329 return I->debugger()->SignalIsolateInterrupted(); | |
| 330 } | |
| 331 break; | |
| 332 } | |
| 333 | |
| 334 case Isolate::kAddExitMsg: | |
| 335 case Isolate::kDelExitMsg: | |
| 336 case Isolate::kAddErrorMsg: | |
| 337 case Isolate::kDelErrorMsg: { | |
| 316 // [ OOB, msg, listener port ] | 338 // [ OOB, msg, listener port ] |
| 317 if (message.Length() < 3) return true; | 339 if (message.Length() < 3) return Error::null(); |
| 318 const Object& obj = Object::Handle(I, message.At(2)); | 340 const Object& obj = Object::Handle(I, message.At(2)); |
| 319 if (!obj.IsSendPort()) return true; | 341 if (!obj.IsSendPort()) return Error::null(); |
| 320 const SendPort& listener = SendPort::Cast(obj); | 342 const SendPort& listener = SendPort::Cast(obj); |
| 321 switch (msg_type) { | 343 switch (msg_type) { |
| 322 case kAddExitMsg: { | 344 case Isolate::kAddExitMsg: { |
| 323 if (message.Length() != 4) return true; | 345 if (message.Length() != 4) return Error::null(); |
| 324 // [ OOB, msg, listener port, response object ] | 346 // [ OOB, msg, listener port, response object ] |
| 325 const Object& response = Object::Handle(I, message.At(3)); | 347 const Object& response = Object::Handle(I, message.At(3)); |
| 326 if (!response.IsInstance() && !response.IsNull()) return true; | 348 if (!response.IsInstance() && !response.IsNull()) { |
| 349 return Error::null(); | |
| 350 } | |
| 327 I->AddExitListener(listener, | 351 I->AddExitListener(listener, |
| 328 response.IsNull() ? Instance::null_instance() | 352 response.IsNull() ? Instance::null_instance() |
| 329 : Instance::Cast(response)); | 353 : Instance::Cast(response)); |
| 330 break; | 354 break; |
| 331 } | 355 } |
| 332 case kDelExitMsg: | 356 case Isolate::kDelExitMsg: |
| 333 if (message.Length() != 3) return true; | 357 if (message.Length() != 3) return Error::null(); |
| 334 I->RemoveExitListener(listener); | 358 I->RemoveExitListener(listener); |
| 335 break; | 359 break; |
| 336 case kAddErrorMsg: | 360 case Isolate::kAddErrorMsg: |
| 337 if (message.Length() != 3) return true; | 361 if (message.Length() != 3) return Error::null(); |
| 338 I->AddErrorListener(listener); | 362 I->AddErrorListener(listener); |
| 339 break; | 363 break; |
| 340 case kDelErrorMsg: | 364 case Isolate::kDelErrorMsg: |
| 341 if (message.Length() != 3) return true; | 365 if (message.Length() != 3) return Error::null(); |
| 342 I->RemoveErrorListener(listener); | 366 I->RemoveErrorListener(listener); |
| 343 break; | 367 break; |
| 344 default: | 368 default: |
| 345 UNREACHABLE(); | 369 UNREACHABLE(); |
| 346 } | 370 } |
| 347 break; | 371 break; |
| 348 } | 372 } |
| 349 case kErrorFatalMsg: { | 373 case Isolate::kErrorFatalMsg: { |
| 350 // [ OOB, kErrorFatalMsg, terminate capability, val ] | 374 // [ OOB, kErrorFatalMsg, terminate capability, val ] |
| 351 if (message.Length() != 4) return true; | 375 if (message.Length() != 4) return Error::null(); |
| 352 // Check that the terminate capability has been passed correctly. | 376 // Check that the terminate capability has been passed correctly. |
| 353 Object& obj = Object::Handle(I, message.At(2)); | 377 Object& obj = Object::Handle(I, message.At(2)); |
| 354 if (!I->VerifyTerminateCapability(obj)) return true; | 378 if (!I->VerifyTerminateCapability(obj)) return Error::null(); |
| 355 // Get the value to be set. | 379 // Get the value to be set. |
| 356 obj = message.At(3); | 380 obj = message.At(3); |
| 357 if (!obj.IsBool()) return true; | 381 if (!obj.IsBool()) return Error::null(); |
| 358 I->SetErrorsFatal(Bool::Cast(obj).value()); | 382 I->SetErrorsFatal(Bool::Cast(obj).value()); |
| 359 break; | 383 break; |
| 360 } | 384 } |
| 361 #if defined(DEBUG) | 385 #if defined(DEBUG) |
| 362 // Malformed OOB messages are silently ignored in release builds. | 386 // Malformed OOB messages are silently ignored in release builds. |
| 363 default: | 387 default: |
| 364 UNREACHABLE(); | 388 UNREACHABLE(); |
| 365 break; | 389 break; |
| 366 #endif // defined(DEBUG) | 390 #endif // defined(DEBUG) |
| 367 } | 391 } |
| 368 return true; | 392 return Error::null(); |
| 369 } | 393 } |
| 370 | 394 |
| 371 | 395 |
| 372 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { | 396 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { |
| 373 if (priority >= Message::kOOBPriority) { | 397 if (priority >= Message::kOOBPriority) { |
| 374 // Handle out of band messages even if the isolate is busy. | 398 // Handle out of band messages even if the isolate is busy. |
| 375 I->ScheduleInterrupts(Isolate::kMessageInterrupt); | 399 I->ScheduleInterrupts(Isolate::kMessageInterrupt); |
| 376 } | 400 } |
| 377 Dart_MessageNotifyCallback callback = I->message_notify_callback(); | 401 Dart_MessageNotifyCallback callback = I->message_notify_callback(); |
| 378 if (callback) { | 402 if (callback) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 const Array& oob_msg = Array::Cast(msg); | 472 const Array& oob_msg = Array::Cast(msg); |
| 449 if (oob_msg.Length() > 0) { | 473 if (oob_msg.Length() > 0) { |
| 450 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); | 474 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); |
| 451 if (oob_tag.IsSmi()) { | 475 if (oob_tag.IsSmi()) { |
| 452 switch (Smi::Cast(oob_tag).Value()) { | 476 switch (Smi::Cast(oob_tag).Value()) { |
| 453 case Message::kServiceOOBMsg: { | 477 case Message::kServiceOOBMsg: { |
| 454 Service::HandleIsolateMessage(I, oob_msg); | 478 Service::HandleIsolateMessage(I, oob_msg); |
| 455 break; | 479 break; |
| 456 } | 480 } |
| 457 case Message::kIsolateLibOOBMsg: { | 481 case Message::kIsolateLibOOBMsg: { |
| 458 success = HandleLibMessage(oob_msg); | 482 const Error& error = Error::Handle(HandleLibMessage(oob_msg)); |
| 483 if (!error.IsNull()) { | |
| 484 success = ProcessUnhandledException(error); | |
| 485 } | |
| 459 break; | 486 break; |
| 460 } | 487 } |
| 461 #if defined(DEBUG) | 488 #if defined(DEBUG) |
| 462 // Malformed OOB messages are silently ignored in release builds. | 489 // Malformed OOB messages are silently ignored in release builds. |
| 463 default: { | 490 default: { |
| 464 UNREACHABLE(); | 491 UNREACHABLE(); |
| 465 break; | 492 break; |
| 466 } | 493 } |
| 467 #endif // defined(DEBUG) | 494 #endif // defined(DEBUG) |
| 468 } | 495 } |
| 469 } | 496 } |
| 470 } | 497 } |
| 471 } | 498 } |
| 472 } else if (message->dest_port() == Message::kIllegalPort) { | 499 } else if (message->dest_port() == Message::kIllegalPort) { |
| 473 // Check whether this is a delayed OOB message which needed handling as | 500 // Check whether this is a delayed OOB message which needed handling as |
| 474 // part of the regular message dispatch. All other messages are dropped on | 501 // part of the regular message dispatch. All other messages are dropped on |
| 475 // the floor. | 502 // the floor. |
| 476 if (msg.IsArray()) { | 503 if (msg.IsArray()) { |
| 477 const Array& msg_arr = Array::Cast(msg); | 504 const Array& msg_arr = Array::Cast(msg); |
| 478 if (msg_arr.Length() > 0) { | 505 if (msg_arr.Length() > 0) { |
| 479 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); | 506 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); |
| 480 if (oob_tag.IsSmi() && | 507 if (oob_tag.IsSmi() && |
| 481 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { | 508 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { |
| 482 success = HandleLibMessage(Array::Cast(msg_arr)); | 509 const Error& error = Error::Handle(HandleLibMessage(msg_arr)); |
| 510 if (!error.IsNull()) { | |
| 511 success = ProcessUnhandledException(error); | |
| 512 } | |
| 483 } | 513 } |
| 484 } | 514 } |
| 485 } | 515 } |
| 486 } else { | 516 } else { |
| 487 const Object& result = Object::Handle(zone, | 517 const Object& result = Object::Handle(zone, |
| 488 DartLibraryCalls::HandleMessage(msg_handler, msg)); | 518 DartLibraryCalls::HandleMessage(msg_handler, msg)); |
| 489 if (result.IsError()) { | 519 if (result.IsError()) { |
| 490 success = ProcessUnhandledException(Error::Cast(result)); | 520 success = ProcessUnhandledException(Error::Cast(result)); |
| 491 } else { | 521 } else { |
| 492 ASSERT(result.IsNull()); | 522 ASSERT(result.IsNull()); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 584 tmp = DartLibraryCalls::ToString(stacktrace); | 614 tmp = DartLibraryCalls::ToString(stacktrace); |
| 585 if (!tmp.IsString()) { | 615 if (!tmp.IsString()) { |
| 586 tmp = String::New(stacktrace.ToCString()); | 616 tmp = String::New(stacktrace.ToCString()); |
| 587 } | 617 } |
| 588 stacktrace_str ^= tmp.raw();; | 618 stacktrace_str ^= tmp.raw();; |
| 589 } else { | 619 } else { |
| 590 exc_str = String::New(result.ToErrorCString()); | 620 exc_str = String::New(result.ToErrorCString()); |
| 591 } | 621 } |
| 592 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); | 622 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); |
| 593 | 623 |
| 594 if (I->ErrorsFatal()) { | 624 if (result.IsUnwindError() || I->ErrorsFatal()) { |
|
turnidge
2015/09/15 22:14:10
This isn't quite right, probably, but I wanted to
| |
| 595 if (has_listener) { | 625 if (has_listener) { |
| 596 I->object_store()->clear_sticky_error(); | 626 I->object_store()->clear_sticky_error(); |
| 597 } else { | 627 } else { |
| 598 I->object_store()->set_sticky_error(result); | 628 I->object_store()->set_sticky_error(result); |
| 599 } | 629 } |
| 600 return false; | 630 return false; |
| 601 } | 631 } |
| 602 return true; | 632 return true; |
| 603 } | 633 } |
| 604 | 634 |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1388 MutexLocker ml(mutex_); | 1418 MutexLocker ml(mutex_); |
| 1389 if (stack_limit_ == saved_stack_limit_) { | 1419 if (stack_limit_ == saved_stack_limit_) { |
| 1390 return 0; // No interrupt was requested. | 1420 return 0; // No interrupt was requested. |
| 1391 } | 1421 } |
| 1392 uword interrupt_bits = stack_limit_ & kInterruptsMask; | 1422 uword interrupt_bits = stack_limit_ & kInterruptsMask; |
| 1393 stack_limit_ = saved_stack_limit_; | 1423 stack_limit_ = saved_stack_limit_; |
| 1394 return interrupt_bits; | 1424 return interrupt_bits; |
| 1395 } | 1425 } |
| 1396 | 1426 |
| 1397 | 1427 |
| 1428 RawError* Isolate::HandleInterrupts() { | |
| 1429 uword interrupt_bits = GetAndClearInterrupts(); | |
| 1430 if ((interrupt_bits & kVMInterrupt) != 0) { | |
| 1431 thread_registry()->CheckSafepoint(); | |
| 1432 if (store_buffer()->Overflowed()) { | |
| 1433 if (FLAG_verbose_gc) { | |
| 1434 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); | |
| 1435 } | |
| 1436 heap()->CollectGarbage(Heap::kNew); | |
| 1437 } | |
| 1438 } | |
| 1439 if ((interrupt_bits & kMessageInterrupt) != 0) { | |
| 1440 bool ok = message_handler()->HandleOOBMessages(); | |
| 1441 if (!ok) { | |
| 1442 // False result from HandleOOBMessages signals that the isolate should | |
| 1443 // be terminating. | |
| 1444 if (FLAG_trace_isolates) { | |
| 1445 OS::Print("[!] Terminating isolate due to OOB message:\n" | |
| 1446 "\tisolate: %s\n", name()); | |
| 1447 } | |
| 1448 message_handler()->set_pause_on_start(false); | |
| 1449 message_handler()->set_pause_on_exit(false); | |
| 1450 const String& msg = String::Handle(String::New("isolate terminated")); | |
| 1451 return UnwindError::New(msg); | |
| 1452 } | |
| 1453 } | |
| 1454 return Error::null(); | |
| 1455 } | |
| 1456 | |
| 1457 | |
| 1398 uword Isolate::GetAndClearStackOverflowFlags() { | 1458 uword Isolate::GetAndClearStackOverflowFlags() { |
| 1399 uword stack_overflow_flags = stack_overflow_flags_; | 1459 uword stack_overflow_flags = stack_overflow_flags_; |
| 1400 stack_overflow_flags_ = 0; | 1460 stack_overflow_flags_ = 0; |
| 1401 return stack_overflow_flags; | 1461 return stack_overflow_flags; |
| 1402 } | 1462 } |
| 1403 | 1463 |
| 1404 | 1464 |
| 1405 static int MostUsedFunctionFirst(const Function* const* a, | 1465 static int MostUsedFunctionFirst(const Function* const* a, |
| 1406 const Function* const* b) { | 1466 const Function* const* b) { |
| 1407 if ((*a)->usage_counter() > (*b)->usage_counter()) { | 1467 if ((*a)->usage_counter() > (*b)->usage_counter()) { |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2198 kill_msg.value.as_array.length = 4; | 2258 kill_msg.value.as_array.length = 4; |
| 2199 kill_msg.value.as_array.values = list_values; | 2259 kill_msg.value.as_array.values = list_values; |
| 2200 | 2260 |
| 2201 Dart_CObject oob; | 2261 Dart_CObject oob; |
| 2202 oob.type = Dart_CObject_kInt32; | 2262 oob.type = Dart_CObject_kInt32; |
| 2203 oob.value.as_int32 = Message::kIsolateLibOOBMsg; | 2263 oob.value.as_int32 = Message::kIsolateLibOOBMsg; |
| 2204 list_values[0] = &oob; | 2264 list_values[0] = &oob; |
| 2205 | 2265 |
| 2206 Dart_CObject kill; | 2266 Dart_CObject kill; |
| 2207 kill.type = Dart_CObject_kInt32; | 2267 kill.type = Dart_CObject_kInt32; |
| 2208 kill.value.as_int32 = IsolateMessageHandler::kKillMsg; | 2268 kill.value.as_int32 = Isolate::kKillMsg; |
| 2209 list_values[1] = &kill; | 2269 list_values[1] = &kill; |
| 2210 | 2270 |
| 2211 Dart_CObject cap; | 2271 Dart_CObject cap; |
| 2212 cap.type = Dart_CObject_kCapability; | 2272 cap.type = Dart_CObject_kCapability; |
| 2213 cap.value.as_capability.id = terminate_capability(); | 2273 cap.value.as_capability.id = terminate_capability(); |
| 2214 list_values[2] = ∩ | 2274 list_values[2] = ∩ |
| 2215 | 2275 |
| 2216 Dart_CObject imm; | 2276 Dart_CObject imm; |
| 2217 imm.type = Dart_CObject_kInt32; | 2277 imm.type = Dart_CObject_kInt32; |
| 2218 imm.value.as_int32 = IsolateMessageHandler::kImmediateAction; | 2278 imm.value.as_int32 = Isolate::kImmediateAction; |
| 2219 list_values[3] = &imm; | 2279 list_values[3] = &imm; |
| 2220 | 2280 |
| 2221 { | 2281 { |
| 2222 uint8_t* buffer = NULL; | 2282 uint8_t* buffer = NULL; |
| 2223 ApiMessageWriter writer(&buffer, allocator); | 2283 ApiMessageWriter writer(&buffer, allocator); |
| 2224 bool success = writer.WriteCMessage(&kill_msg); | 2284 bool success = writer.WriteCMessage(&kill_msg); |
| 2225 ASSERT(success); | 2285 ASSERT(success); |
| 2226 | 2286 |
| 2227 // Post the message at the given port. | 2287 // Post the message at the given port. |
| 2228 success = PortMap::PostMessage(new Message(main_port(), | 2288 success = PortMap::PostMessage(new Message(main_port(), |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2473 serialized_message_, serialized_message_len_); | 2533 serialized_message_, serialized_message_len_); |
| 2474 } | 2534 } |
| 2475 | 2535 |
| 2476 | 2536 |
| 2477 void IsolateSpawnState::Cleanup() { | 2537 void IsolateSpawnState::Cleanup() { |
| 2478 SwitchIsolateScope switch_scope(I); | 2538 SwitchIsolateScope switch_scope(I); |
| 2479 Dart::ShutdownIsolate(); | 2539 Dart::ShutdownIsolate(); |
| 2480 } | 2540 } |
| 2481 | 2541 |
| 2482 } // namespace dart | 2542 } // namespace dart |
| OLD | NEW |