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 "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "platform/json.h" | 9 #include "platform/json.h" |
10 #include "vm/code_observers.h" | 10 #include "vm/code_observers.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 "Pause isolates exiting."); | 45 "Pause isolates exiting."); |
46 DEFINE_FLAG(bool, break_at_isolate_spawn, false, | 46 DEFINE_FLAG(bool, break_at_isolate_spawn, false, |
47 "Insert a one-time breakpoint at the entrypoint for all spawned " | 47 "Insert a one-time breakpoint at the entrypoint for all spawned " |
48 "isolates"); | 48 "isolates"); |
49 | 49 |
50 | 50 |
51 // Quick access to the locally defined isolate() method. | 51 // Quick access to the locally defined isolate() method. |
52 #define I (isolate()) | 52 #define I (isolate()) |
53 | 53 |
54 | 54 |
| 55 #if defined(DEBUG) |
| 56 // Helper class to ensure that a live origin_id is never reused |
| 57 // and assigned to an isolate. |
| 58 class VerifyOriginId : public IsolateVisitor { |
| 59 public: |
| 60 explicit VerifyOriginId(Dart_Port id) : id_(id) {} |
| 61 |
| 62 void VisitIsolate(Isolate* isolate) { |
| 63 ASSERT(isolate->origin_id() != id_); |
| 64 } |
| 65 |
| 66 private: |
| 67 Dart_Port id_; |
| 68 DISALLOW_COPY_AND_ASSIGN(VerifyOriginId); |
| 69 }; |
| 70 #endif |
| 71 |
| 72 |
55 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 73 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
56 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 74 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
57 return reinterpret_cast<uint8_t*>(new_ptr); | 75 return reinterpret_cast<uint8_t*>(new_ptr); |
58 } | 76 } |
59 | 77 |
60 | 78 |
61 static void SerializeObject(const Instance& obj, | 79 static void SerializeObject(const Instance& obj, |
62 uint8_t** obj_data, | 80 uint8_t** obj_data, |
63 intptr_t* obj_len) { | 81 intptr_t* obj_len, |
64 MessageWriter writer(obj_data, &allocator); | 82 bool allow_any_object) { |
| 83 MessageWriter writer(obj_data, &allocator, allow_any_object); |
65 writer.WriteMessage(obj); | 84 writer.WriteMessage(obj); |
66 *obj_len = writer.BytesWritten(); | 85 *obj_len = writer.BytesWritten(); |
67 } | 86 } |
68 | 87 |
69 | 88 |
70 void Isolate::RegisterClass(const Class& cls) { | 89 void Isolate::RegisterClass(const Class& cls) { |
71 class_table()->Register(cls); | 90 class_table()->Register(cls); |
72 } | 91 } |
73 | 92 |
74 | 93 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 if (message.Length() != 4) return true; | 193 if (message.Length() != 4) return true; |
175 const Object& obj2 = Object::Handle(I, message.At(2)); | 194 const Object& obj2 = Object::Handle(I, message.At(2)); |
176 if (!obj2.IsSendPort()) return true; | 195 if (!obj2.IsSendPort()) return true; |
177 const SendPort& send_port = SendPort::Cast(obj2); | 196 const SendPort& send_port = SendPort::Cast(obj2); |
178 const Object& obj3 = Object::Handle(I, message.At(3)); | 197 const Object& obj3 = Object::Handle(I, message.At(3)); |
179 if (!obj3.IsSmi()) return true; | 198 if (!obj3.IsSmi()) return true; |
180 const intptr_t priority = Smi::Cast(obj3).Value(); | 199 const intptr_t priority = Smi::Cast(obj3).Value(); |
181 if (priority == kImmediateAction) { | 200 if (priority == kImmediateAction) { |
182 uint8_t* data = NULL; | 201 uint8_t* data = NULL; |
183 intptr_t len = 0; | 202 intptr_t len = 0; |
184 SerializeObject(Object::null_instance(), &data, &len); | 203 SerializeObject(Object::null_instance(), &data, &len, false); |
185 PortMap::PostMessage(new Message(send_port.Id(), | 204 PortMap::PostMessage(new Message(send_port.Id(), |
186 data, len, | 205 data, len, |
187 Message::kNormalPriority)); | 206 Message::kNormalPriority)); |
188 } else { | 207 } else { |
189 ASSERT((priority == kBeforeNextEventAction) || | 208 ASSERT((priority == kBeforeNextEventAction) || |
190 (priority == kAsEventAction)); | 209 (priority == kAsEventAction)); |
191 // Update the message so that it will be handled immediately when it | 210 // Update the message so that it will be handled immediately when it |
192 // is picked up from the message queue the next time. | 211 // is picked up from the message queue the next time. |
193 message.SetAt( | 212 message.SetAt( |
194 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 213 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
195 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | 214 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); |
196 uint8_t* data = NULL; | 215 uint8_t* data = NULL; |
197 intptr_t len = 0; | 216 intptr_t len = 0; |
198 SerializeObject(message, &data, &len); | 217 SerializeObject(message, &data, &len, false); |
199 this->PostMessage(new Message(Message::kIllegalPort, | 218 this->PostMessage(new Message(Message::kIllegalPort, |
200 data, len, | 219 data, len, |
201 Message::kNormalPriority), | 220 Message::kNormalPriority), |
202 priority == kBeforeNextEventAction /* at_head */); | 221 priority == kBeforeNextEventAction /* at_head */); |
203 } | 222 } |
204 break; | 223 break; |
205 } | 224 } |
206 case kKillMsg: { | 225 case kKillMsg: { |
207 // [ OOB, kKillMsg, terminate capability, priority ] | 226 // [ OOB, kKillMsg, terminate capability, priority ] |
208 if (message.Length() != 4) return true; | 227 if (message.Length() != 4) return true; |
209 Object& obj = Object::Handle(I, message.At(3)); | 228 Object& obj = Object::Handle(I, message.At(3)); |
210 if (!obj.IsSmi()) return true; | 229 if (!obj.IsSmi()) return true; |
211 const intptr_t priority = Smi::Cast(obj).Value(); | 230 const intptr_t priority = Smi::Cast(obj).Value(); |
212 if (priority == kImmediateAction) { | 231 if (priority == kImmediateAction) { |
213 obj = message.At(2); | 232 obj = message.At(2); |
214 // Signal that the isolate should stop execution. | 233 // Signal that the isolate should stop execution. |
215 return !I->VerifyTerminateCapability(obj); | 234 return !I->VerifyTerminateCapability(obj); |
216 } else { | 235 } else { |
217 ASSERT((priority == kBeforeNextEventAction) || | 236 ASSERT((priority == kBeforeNextEventAction) || |
218 (priority == kAsEventAction)); | 237 (priority == kAsEventAction)); |
219 // Update the message so that it will be handled immediately when it | 238 // Update the message so that it will be handled immediately when it |
220 // is picked up from the message queue the next time. | 239 // is picked up from the message queue the next time. |
221 message.SetAt( | 240 message.SetAt( |
222 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 241 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
223 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | 242 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); |
224 uint8_t* data = NULL; | 243 uint8_t* data = NULL; |
225 intptr_t len = 0; | 244 intptr_t len = 0; |
226 SerializeObject(message, &data, &len); | 245 SerializeObject(message, &data, &len, false); |
227 this->PostMessage(new Message(Message::kIllegalPort, | 246 this->PostMessage(new Message(Message::kIllegalPort, |
228 data, len, | 247 data, len, |
229 Message::kNormalPriority), | 248 Message::kNormalPriority), |
230 priority == kBeforeNextEventAction /* at_head */); | 249 priority == kBeforeNextEventAction /* at_head */); |
231 } | 250 } |
232 break; | 251 break; |
233 } | 252 } |
234 #if defined(DEBUG) | 253 #if defined(DEBUG) |
235 // Malformed OOB messages are silently ignored in release builds. | 254 // Malformed OOB messages are silently ignored in release builds. |
236 default: | 255 default: |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 | 510 |
492 #define REUSABLE_HANDLE_INITIALIZERS(object) \ | 511 #define REUSABLE_HANDLE_INITIALIZERS(object) \ |
493 object##_handle_(NULL), | 512 object##_handle_(NULL), |
494 | 513 |
495 Isolate::Isolate() | 514 Isolate::Isolate() |
496 : store_buffer_(), | 515 : store_buffer_(), |
497 message_notify_callback_(NULL), | 516 message_notify_callback_(NULL), |
498 name_(NULL), | 517 name_(NULL), |
499 start_time_(OS::GetCurrentTimeMicros()), | 518 start_time_(OS::GetCurrentTimeMicros()), |
500 main_port_(0), | 519 main_port_(0), |
| 520 origin_id_(0), |
501 pause_capability_(0), | 521 pause_capability_(0), |
502 terminate_capability_(0), | 522 terminate_capability_(0), |
503 heap_(NULL), | 523 heap_(NULL), |
504 object_store_(NULL), | 524 object_store_(NULL), |
505 top_exit_frame_info_(0), | 525 top_exit_frame_info_(0), |
506 init_callback_data_(NULL), | 526 init_callback_data_(NULL), |
507 environment_callback_(NULL), | 527 environment_callback_(NULL), |
508 library_tag_handler_(NULL), | 528 library_tag_handler_(NULL), |
509 api_state_(NULL), | 529 api_state_(NULL), |
510 stub_code_(NULL), | 530 stub_code_(NULL), |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 ApiState* state = new ApiState(); | 721 ApiState* state = new ApiState(); |
702 ASSERT(state != NULL); | 722 ASSERT(state != NULL); |
703 result->set_api_state(state); | 723 result->set_api_state(state); |
704 | 724 |
705 // Initialize stack top and limit in case we are running the isolate in the | 725 // Initialize stack top and limit in case we are running the isolate in the |
706 // main thread. | 726 // main thread. |
707 // TODO(5411455): Need to figure out how to set the stack limit for the | 727 // TODO(5411455): Need to figure out how to set the stack limit for the |
708 // main thread. | 728 // main thread. |
709 result->SetStackLimitFromStackBase(reinterpret_cast<uword>(&result)); | 729 result->SetStackLimitFromStackBase(reinterpret_cast<uword>(&result)); |
710 result->set_main_port(PortMap::CreatePort(result->message_handler())); | 730 result->set_main_port(PortMap::CreatePort(result->message_handler())); |
| 731 #if defined(DEBUG) |
| 732 // Verify that we are never reusing a live origin id. |
| 733 VerifyOriginId id_verifier(result->main_port()); |
| 734 Isolate::VisitIsolates(&id_verifier); |
| 735 #endif |
| 736 result->set_origin_id(result->main_port()); |
711 result->set_pause_capability(result->random()->NextUInt64()); | 737 result->set_pause_capability(result->random()->NextUInt64()); |
712 result->set_terminate_capability(result->random()->NextUInt64()); | 738 result->set_terminate_capability(result->random()->NextUInt64()); |
713 | 739 |
714 result->BuildName(name_prefix); | 740 result->BuildName(name_prefix); |
715 | 741 |
716 result->debugger_ = new Debugger(); | 742 result->debugger_ = new Debugger(); |
717 result->debugger_->Initialize(result); | 743 result->debugger_->Initialize(result); |
718 if (FLAG_trace_isolates) { | 744 if (FLAG_trace_isolates) { |
719 if (name_prefix == NULL || strcmp(name_prefix, "vm-isolate") != 0) { | 745 if (name_prefix == NULL || strcmp(name_prefix, "vm-isolate") != 0) { |
720 OS::Print("[+] Starting isolate:\n" | 746 OS::Print("[+] Starting isolate:\n" |
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 const String& lib_url = String::Handle(lib.url()); | 1589 const String& lib_url = String::Handle(lib.url()); |
1564 library_url_ = strdup(lib_url.ToCString()); | 1590 library_url_ = strdup(lib_url.ToCString()); |
1565 | 1591 |
1566 const String& func_name = String::Handle(func.name()); | 1592 const String& func_name = String::Handle(func.name()); |
1567 function_name_ = strdup(func_name.ToCString()); | 1593 function_name_ = strdup(func_name.ToCString()); |
1568 if (!cls.IsTopLevel()) { | 1594 if (!cls.IsTopLevel()) { |
1569 const String& class_name = String::Handle(cls.Name()); | 1595 const String& class_name = String::Handle(cls.Name()); |
1570 class_name_ = strdup(class_name.ToCString()); | 1596 class_name_ = strdup(class_name.ToCString()); |
1571 } | 1597 } |
1572 exception_callback_name_ = strdup("_unhandledExceptionCallback"); | 1598 exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
1573 SerializeObject(message, &serialized_message_, &serialized_message_len_); | 1599 bool can_send_any_object = true; |
| 1600 SerializeObject(message, |
| 1601 &serialized_message_, |
| 1602 &serialized_message_len_, |
| 1603 can_send_any_object); |
1574 } | 1604 } |
1575 | 1605 |
1576 | 1606 |
1577 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, | 1607 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
1578 const char* script_url, | 1608 const char* script_url, |
1579 const char* package_root, | 1609 const char* package_root, |
1580 const Instance& args, | 1610 const Instance& args, |
1581 const Instance& message, | 1611 const Instance& message, |
1582 bool paused) | 1612 bool paused) |
1583 : isolate_(NULL), | 1613 : isolate_(NULL), |
1584 parent_port_(parent_port), | 1614 parent_port_(parent_port), |
1585 package_root_(NULL), | 1615 package_root_(NULL), |
1586 library_url_(NULL), | 1616 library_url_(NULL), |
1587 class_name_(NULL), | 1617 class_name_(NULL), |
1588 function_name_(NULL), | 1618 function_name_(NULL), |
1589 exception_callback_name_(NULL), | 1619 exception_callback_name_(NULL), |
1590 serialized_args_(NULL), | 1620 serialized_args_(NULL), |
1591 serialized_args_len_(0), | 1621 serialized_args_len_(0), |
1592 serialized_message_(NULL), | 1622 serialized_message_(NULL), |
1593 serialized_message_len_(0), | 1623 serialized_message_len_(0), |
1594 paused_(paused) { | 1624 paused_(paused) { |
1595 script_url_ = strdup(script_url); | 1625 script_url_ = strdup(script_url); |
1596 if (package_root != NULL) { | 1626 if (package_root != NULL) { |
1597 package_root_ = strdup(package_root); | 1627 package_root_ = strdup(package_root); |
1598 } | 1628 } |
1599 library_url_ = NULL; | 1629 library_url_ = NULL; |
1600 function_name_ = strdup("main"); | 1630 function_name_ = strdup("main"); |
1601 exception_callback_name_ = strdup("_unhandledExceptionCallback"); | 1631 exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
1602 SerializeObject(args, &serialized_args_, &serialized_args_len_); | 1632 bool can_send_any_object = false; |
1603 SerializeObject(message, &serialized_message_, &serialized_message_len_); | 1633 SerializeObject(args, |
| 1634 &serialized_args_, |
| 1635 &serialized_args_len_, |
| 1636 can_send_any_object); |
| 1637 SerializeObject(message, |
| 1638 &serialized_message_, |
| 1639 &serialized_message_len_, |
| 1640 can_send_any_object); |
1604 } | 1641 } |
1605 | 1642 |
1606 | 1643 |
1607 IsolateSpawnState::~IsolateSpawnState() { | 1644 IsolateSpawnState::~IsolateSpawnState() { |
1608 free(script_url_); | 1645 free(script_url_); |
1609 free(package_root_); | 1646 free(package_root_); |
1610 free(library_url_); | 1647 free(library_url_); |
1611 free(function_name_); | 1648 free(function_name_); |
1612 free(class_name_); | 1649 free(class_name_); |
1613 free(exception_callback_name_); | 1650 free(exception_callback_name_); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1679 serialized_message_, serialized_message_len_); | 1716 serialized_message_, serialized_message_len_); |
1680 } | 1717 } |
1681 | 1718 |
1682 | 1719 |
1683 void IsolateSpawnState::Cleanup() { | 1720 void IsolateSpawnState::Cleanup() { |
1684 SwitchIsolateScope switch_scope(I); | 1721 SwitchIsolateScope switch_scope(I); |
1685 Dart::ShutdownIsolate(); | 1722 Dart::ShutdownIsolate(); |
1686 } | 1723 } |
1687 | 1724 |
1688 } // namespace dart | 1725 } // namespace dart |
OLD | NEW |