| 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/text_buffer.h" | 10 #include "platform/text_buffer.h" |
| 11 #include "vm/atomic.h" | 11 #include "vm/atomic.h" |
| 12 #include "vm/class_finalizer.h" | 12 #include "vm/class_finalizer.h" |
| 13 #include "vm/code_observers.h" | 13 #include "vm/code_observers.h" |
| 14 #include "vm/compiler.h" | 14 #include "vm/compiler.h" |
| 15 #include "vm/compiler_stats.h" | 15 #include "vm/compiler_stats.h" |
| 16 #include "vm/dart_api_message.h" | 16 #include "vm/dart_api_message.h" |
| 17 #include "vm/dart_api_state.h" | 17 #include "vm/dart_api_state.h" |
| 18 #include "vm/dart_entry.h" | 18 #include "vm/dart_entry.h" |
| 19 #include "vm/debugger.h" | 19 #include "vm/debugger.h" |
| 20 #include "vm/deopt_instructions.h" | 20 #include "vm/deopt_instructions.h" |
| 21 #include "vm/flags.h" | 21 #include "vm/flags.h" |
| 22 #include "vm/heap.h" | 22 #include "vm/heap.h" |
| 23 #include "vm/isolate_reload.h" | 23 #include "vm/isolate_reload.h" |
| 24 #include "vm/lockers.h" | 24 #include "vm/lockers.h" |
| 25 #include "vm/log.h" | 25 #include "vm/log.h" |
| 26 #include "vm/message_handler.h" | 26 #include "vm/message_handler.h" |
| 27 #include "vm/object.h" |
| 27 #include "vm/object_id_ring.h" | 28 #include "vm/object_id_ring.h" |
| 28 #include "vm/object_store.h" | 29 #include "vm/object_store.h" |
| 29 #include "vm/object.h" | |
| 30 #include "vm/os_thread.h" | 30 #include "vm/os_thread.h" |
| 31 #include "vm/port.h" | 31 #include "vm/port.h" |
| 32 #include "vm/profiler.h" | 32 #include "vm/profiler.h" |
| 33 #include "vm/reusable_handles.h" | 33 #include "vm/reusable_handles.h" |
| 34 #include "vm/safepoint.h" | 34 #include "vm/safepoint.h" |
| 35 #include "vm/service.h" | 35 #include "vm/service.h" |
| 36 #include "vm/service_event.h" | 36 #include "vm/service_event.h" |
| 37 #include "vm/service_isolate.h" | 37 #include "vm/service_isolate.h" |
| 38 #include "vm/simulator.h" | 38 #include "vm/simulator.h" |
| 39 #include "vm/stack_frame.h" | 39 #include "vm/stack_frame.h" |
| 40 #include "vm/store_buffer.h" | 40 #include "vm/store_buffer.h" |
| 41 #include "vm/stub_code.h" | 41 #include "vm/stub_code.h" |
| 42 #include "vm/symbols.h" | 42 #include "vm/symbols.h" |
| 43 #include "vm/tags.h" | 43 #include "vm/tags.h" |
| 44 #include "vm/thread_interrupter.h" | 44 #include "vm/thread_interrupter.h" |
| 45 #include "vm/thread_registry.h" | 45 #include "vm/thread_registry.h" |
| 46 #include "vm/timeline.h" | 46 #include "vm/timeline.h" |
| 47 #include "vm/timeline_analysis.h" | 47 #include "vm/timeline_analysis.h" |
| 48 #include "vm/timer.h" | 48 #include "vm/timer.h" |
| 49 #include "vm/verifier.h" | 49 #include "vm/verifier.h" |
| 50 #include "vm/visitor.h" | 50 #include "vm/visitor.h" |
| 51 | 51 |
| 52 | |
| 53 namespace dart { | 52 namespace dart { |
| 54 | 53 |
| 55 DECLARE_FLAG(bool, print_metrics); | 54 DECLARE_FLAG(bool, print_metrics); |
| 56 DECLARE_FLAG(bool, timing); | 55 DECLARE_FLAG(bool, timing); |
| 57 DECLARE_FLAG(bool, trace_service); | 56 DECLARE_FLAG(bool, trace_service); |
| 58 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger); | 57 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger); |
| 59 | 58 |
| 60 // Reload flags. | 59 // Reload flags. |
| 61 DECLARE_FLAG(bool, check_reloaded); | 60 DECLARE_FLAG(bool, check_reloaded); |
| 62 DECLARE_FLAG(int, reload_every); | 61 DECLARE_FLAG(int, reload_every); |
| 63 DECLARE_FLAG(bool, reload_every_back_off); | 62 DECLARE_FLAG(bool, reload_every_back_off); |
| 64 DECLARE_FLAG(bool, trace_reload); | 63 DECLARE_FLAG(bool, trace_reload); |
| 65 | 64 |
| 66 | |
| 67 #if !defined(PRODUCT) | 65 #if !defined(PRODUCT) |
| 68 static void CheckedModeHandler(bool value) { | 66 static void CheckedModeHandler(bool value) { |
| 69 FLAG_enable_asserts = value; | 67 FLAG_enable_asserts = value; |
| 70 FLAG_enable_type_checks = value; | 68 FLAG_enable_type_checks = value; |
| 71 } | 69 } |
| 72 | 70 |
| 73 // --enable-checked-mode and --checked both enable checked mode which is | 71 // --enable-checked-mode and --checked both enable checked mode which is |
| 74 // equivalent to setting --enable-asserts and --enable-type-checks. | 72 // equivalent to setting --enable-asserts and --enable-type-checks. |
| 75 DEFINE_FLAG_HANDLER(CheckedModeHandler, | 73 DEFINE_FLAG_HANDLER(CheckedModeHandler, |
| 76 enable_checked_mode, | 74 enable_checked_mode, |
| 77 "Enable checked mode."); | 75 "Enable checked mode."); |
| 78 | 76 |
| 79 DEFINE_FLAG_HANDLER(CheckedModeHandler, checked, "Enable checked mode."); | 77 DEFINE_FLAG_HANDLER(CheckedModeHandler, checked, "Enable checked mode."); |
| 80 #endif // !defined(PRODUCT) | 78 #endif // !defined(PRODUCT) |
| 81 | 79 |
| 82 | |
| 83 // Quick access to the locally defined thread() and isolate() methods. | 80 // Quick access to the locally defined thread() and isolate() methods. |
| 84 #define T (thread()) | 81 #define T (thread()) |
| 85 #define I (isolate()) | 82 #define I (isolate()) |
| 86 | 83 |
| 87 #if defined(DEBUG) | 84 #if defined(DEBUG) |
| 88 // Helper class to ensure that a live origin_id is never reused | 85 // Helper class to ensure that a live origin_id is never reused |
| 89 // and assigned to an isolate. | 86 // and assigned to an isolate. |
| 90 class VerifyOriginId : public IsolateVisitor { | 87 class VerifyOriginId : public IsolateVisitor { |
| 91 public: | 88 public: |
| 92 explicit VerifyOriginId(Dart_Port id) : id_(id) {} | 89 explicit VerifyOriginId(Dart_Port id) : id_(id) {} |
| 93 | 90 |
| 94 void VisitIsolate(Isolate* isolate) { ASSERT(isolate->origin_id() != id_); } | 91 void VisitIsolate(Isolate* isolate) { ASSERT(isolate->origin_id() != id_); } |
| 95 | 92 |
| 96 private: | 93 private: |
| 97 Dart_Port id_; | 94 Dart_Port id_; |
| 98 DISALLOW_COPY_AND_ASSIGN(VerifyOriginId); | 95 DISALLOW_COPY_AND_ASSIGN(VerifyOriginId); |
| 99 }; | 96 }; |
| 100 #endif | 97 #endif |
| 101 | 98 |
| 102 | |
| 103 static uint8_t* malloc_allocator(uint8_t* ptr, | 99 static uint8_t* malloc_allocator(uint8_t* ptr, |
| 104 intptr_t old_size, | 100 intptr_t old_size, |
| 105 intptr_t new_size) { | 101 intptr_t new_size) { |
| 106 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 102 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 107 return reinterpret_cast<uint8_t*>(new_ptr); | 103 return reinterpret_cast<uint8_t*>(new_ptr); |
| 108 } | 104 } |
| 109 | 105 |
| 110 static void malloc_deallocator(uint8_t* ptr) { | 106 static void malloc_deallocator(uint8_t* ptr) { |
| 111 free(reinterpret_cast<void*>(ptr)); | 107 free(reinterpret_cast<void*>(ptr)); |
| 112 } | 108 } |
| 113 | 109 |
| 114 | |
| 115 static void SerializeObject(const Instance& obj, | 110 static void SerializeObject(const Instance& obj, |
| 116 uint8_t** obj_data, | 111 uint8_t** obj_data, |
| 117 intptr_t* obj_len, | 112 intptr_t* obj_len, |
| 118 bool allow_any_object) { | 113 bool allow_any_object) { |
| 119 MessageWriter writer(obj_data, &malloc_allocator, &malloc_deallocator, | 114 MessageWriter writer(obj_data, &malloc_allocator, &malloc_deallocator, |
| 120 allow_any_object); | 115 allow_any_object); |
| 121 writer.WriteMessage(obj); | 116 writer.WriteMessage(obj); |
| 122 *obj_len = writer.BytesWritten(); | 117 *obj_len = writer.BytesWritten(); |
| 123 } | 118 } |
| 124 | 119 |
| 125 // TODO(zra): Allocation of Message objects should be centralized. | 120 // TODO(zra): Allocation of Message objects should be centralized. |
| 126 static Message* SerializeMessage(Dart_Port dest_port, const Instance& obj) { | 121 static Message* SerializeMessage(Dart_Port dest_port, const Instance& obj) { |
| 127 if (ApiObjectConverter::CanConvert(obj.raw())) { | 122 if (ApiObjectConverter::CanConvert(obj.raw())) { |
| 128 return new Message(dest_port, obj.raw(), Message::kNormalPriority); | 123 return new Message(dest_port, obj.raw(), Message::kNormalPriority); |
| 129 } else { | 124 } else { |
| 130 uint8_t* obj_data; | 125 uint8_t* obj_data; |
| 131 intptr_t obj_len; | 126 intptr_t obj_len; |
| 132 SerializeObject(obj, &obj_data, &obj_len, false); | 127 SerializeObject(obj, &obj_data, &obj_len, false); |
| 133 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority); | 128 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority); |
| 134 } | 129 } |
| 135 } | 130 } |
| 136 | 131 |
| 137 | |
| 138 bool IsolateVisitor::IsVMInternalIsolate(Isolate* isolate) const { | 132 bool IsolateVisitor::IsVMInternalIsolate(Isolate* isolate) const { |
| 139 return ((isolate == Dart::vm_isolate()) || | 133 return ((isolate == Dart::vm_isolate()) || |
| 140 ServiceIsolate::IsServiceIsolateDescendant(isolate)); | 134 ServiceIsolate::IsServiceIsolateDescendant(isolate)); |
| 141 } | 135 } |
| 142 | 136 |
| 143 | |
| 144 NoOOBMessageScope::NoOOBMessageScope(Thread* thread) : StackResource(thread) { | 137 NoOOBMessageScope::NoOOBMessageScope(Thread* thread) : StackResource(thread) { |
| 145 thread->DeferOOBMessageInterrupts(); | 138 thread->DeferOOBMessageInterrupts(); |
| 146 } | 139 } |
| 147 | 140 |
| 148 | |
| 149 NoOOBMessageScope::~NoOOBMessageScope() { | 141 NoOOBMessageScope::~NoOOBMessageScope() { |
| 150 thread()->RestoreOOBMessageInterrupts(); | 142 thread()->RestoreOOBMessageInterrupts(); |
| 151 } | 143 } |
| 152 | 144 |
| 153 | |
| 154 NoReloadScope::NoReloadScope(Isolate* isolate, Thread* thread) | 145 NoReloadScope::NoReloadScope(Isolate* isolate, Thread* thread) |
| 155 : StackResource(thread), isolate_(isolate) { | 146 : StackResource(thread), isolate_(isolate) { |
| 156 ASSERT(isolate_ != NULL); | 147 ASSERT(isolate_ != NULL); |
| 157 AtomicOperations::FetchAndIncrement(&(isolate_->no_reload_scope_depth_)); | 148 AtomicOperations::FetchAndIncrement(&(isolate_->no_reload_scope_depth_)); |
| 158 ASSERT(AtomicOperations::LoadRelaxed(&(isolate_->no_reload_scope_depth_)) >= | 149 ASSERT(AtomicOperations::LoadRelaxed(&(isolate_->no_reload_scope_depth_)) >= |
| 159 0); | 150 0); |
| 160 } | 151 } |
| 161 | 152 |
| 162 | |
| 163 NoReloadScope::~NoReloadScope() { | 153 NoReloadScope::~NoReloadScope() { |
| 164 AtomicOperations::FetchAndDecrement(&(isolate_->no_reload_scope_depth_)); | 154 AtomicOperations::FetchAndDecrement(&(isolate_->no_reload_scope_depth_)); |
| 165 ASSERT(AtomicOperations::LoadRelaxed(&(isolate_->no_reload_scope_depth_)) >= | 155 ASSERT(AtomicOperations::LoadRelaxed(&(isolate_->no_reload_scope_depth_)) >= |
| 166 0); | 156 0); |
| 167 } | 157 } |
| 168 | 158 |
| 169 | |
| 170 void Isolate::RegisterClass(const Class& cls) { | 159 void Isolate::RegisterClass(const Class& cls) { |
| 171 #if !defined(PRODUCT) | 160 #if !defined(PRODUCT) |
| 172 if (IsReloading()) { | 161 if (IsReloading()) { |
| 173 reload_context()->RegisterClass(cls); | 162 reload_context()->RegisterClass(cls); |
| 174 return; | 163 return; |
| 175 } | 164 } |
| 176 #endif // !defined(PRODUCT) | 165 #endif // !defined(PRODUCT) |
| 177 class_table()->Register(cls); | 166 class_table()->Register(cls); |
| 178 } | 167 } |
| 179 | 168 |
| 180 | |
| 181 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { | 169 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { |
| 182 class_table()->RegisterAt(index, cls); | 170 class_table()->RegisterAt(index, cls); |
| 183 } | 171 } |
| 184 | 172 |
| 185 | |
| 186 void Isolate::ValidateClassTable() { | 173 void Isolate::ValidateClassTable() { |
| 187 class_table()->Validate(); | 174 class_table()->Validate(); |
| 188 } | 175 } |
| 189 | 176 |
| 190 | |
| 191 void Isolate::SendInternalLibMessage(LibMsgId msg_id, uint64_t capability) { | 177 void Isolate::SendInternalLibMessage(LibMsgId msg_id, uint64_t capability) { |
| 192 const Array& msg = Array::Handle(Array::New(3)); | 178 const Array& msg = Array::Handle(Array::New(3)); |
| 193 Object& element = Object::Handle(); | 179 Object& element = Object::Handle(); |
| 194 | 180 |
| 195 element = Smi::New(Message::kIsolateLibOOBMsg); | 181 element = Smi::New(Message::kIsolateLibOOBMsg); |
| 196 msg.SetAt(0, element); | 182 msg.SetAt(0, element); |
| 197 element = Smi::New(msg_id); | 183 element = Smi::New(msg_id); |
| 198 msg.SetAt(1, element); | 184 msg.SetAt(1, element); |
| 199 element = Capability::New(capability); | 185 element = Capability::New(capability); |
| 200 msg.SetAt(2, element); | 186 msg.SetAt(2, element); |
| 201 | 187 |
| 202 uint8_t* data = NULL; | 188 uint8_t* data = NULL; |
| 203 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 189 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
| 204 writer.WriteMessage(msg); | 190 writer.WriteMessage(msg); |
| 205 | 191 |
| 206 PortMap::PostMessage(new Message(main_port(), data, writer.BytesWritten(), | 192 PortMap::PostMessage(new Message(main_port(), data, writer.BytesWritten(), |
| 207 Message::kOOBPriority)); | 193 Message::kOOBPriority)); |
| 208 } | 194 } |
| 209 | 195 |
| 210 | |
| 211 class IsolateMessageHandler : public MessageHandler { | 196 class IsolateMessageHandler : public MessageHandler { |
| 212 public: | 197 public: |
| 213 explicit IsolateMessageHandler(Isolate* isolate); | 198 explicit IsolateMessageHandler(Isolate* isolate); |
| 214 ~IsolateMessageHandler(); | 199 ~IsolateMessageHandler(); |
| 215 | 200 |
| 216 const char* name() const; | 201 const char* name() const; |
| 217 void MessageNotify(Message::Priority priority); | 202 void MessageNotify(Message::Priority priority); |
| 218 MessageStatus HandleMessage(Message* message); | 203 MessageStatus HandleMessage(Message* message); |
| 219 #ifndef PRODUCT | 204 #ifndef PRODUCT |
| 220 void NotifyPauseOnStart(); | 205 void NotifyPauseOnStart(); |
| 221 void NotifyPauseOnExit(); | 206 void NotifyPauseOnExit(); |
| 222 #endif // !PRODUCT | 207 #endif // !PRODUCT |
| 223 | 208 |
| 224 #if defined(DEBUG) | 209 #if defined(DEBUG) |
| 225 // Check that it is safe to access this handler. | 210 // Check that it is safe to access this handler. |
| 226 void CheckAccess(); | 211 void CheckAccess(); |
| 227 #endif | 212 #endif |
| 228 bool IsCurrentIsolate() const; | 213 bool IsCurrentIsolate() const; |
| 229 virtual Isolate* isolate() const { return isolate_; } | 214 virtual Isolate* isolate() const { return isolate_; } |
| 230 | 215 |
| 231 private: | 216 private: |
| 232 // A result of false indicates that the isolate should terminate the | 217 // A result of false indicates that the isolate should terminate the |
| 233 // processing of further events. | 218 // processing of further events. |
| 234 RawError* HandleLibMessage(const Array& message); | 219 RawError* HandleLibMessage(const Array& message); |
| 235 | 220 |
| 236 MessageStatus ProcessUnhandledException(const Error& result); | 221 MessageStatus ProcessUnhandledException(const Error& result); |
| 237 Isolate* isolate_; | 222 Isolate* isolate_; |
| 238 }; | 223 }; |
| 239 | 224 |
| 240 | |
| 241 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) | 225 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
| 242 : isolate_(isolate) {} | 226 : isolate_(isolate) {} |
| 243 | 227 |
| 244 | |
| 245 IsolateMessageHandler::~IsolateMessageHandler() {} | 228 IsolateMessageHandler::~IsolateMessageHandler() {} |
| 246 | 229 |
| 247 const char* IsolateMessageHandler::name() const { | 230 const char* IsolateMessageHandler::name() const { |
| 248 return isolate_->name(); | 231 return isolate_->name(); |
| 249 } | 232 } |
| 250 | 233 |
| 251 | |
| 252 // Isolate library OOB messages are fixed sized arrays which have the | 234 // Isolate library OOB messages are fixed sized arrays which have the |
| 253 // following format: | 235 // following format: |
| 254 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] | 236 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] |
| 255 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { | 237 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { |
| 256 if (message.Length() < 2) return Error::null(); | 238 if (message.Length() < 2) return Error::null(); |
| 257 Zone* zone = T->zone(); | 239 Zone* zone = T->zone(); |
| 258 const Object& type = Object::Handle(zone, message.At(1)); | 240 const Object& type = Object::Handle(zone, message.At(1)); |
| 259 if (!type.IsSmi()) return Error::null(); | 241 if (!type.IsSmi()) return Error::null(); |
| 260 const intptr_t msg_type = Smi::Cast(type).Value(); | 242 const intptr_t msg_type = Smi::Cast(type).Value(); |
| 261 switch (msg_type) { | 243 switch (msg_type) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 #if defined(DEBUG) | 405 #if defined(DEBUG) |
| 424 // Malformed OOB messages are silently ignored in release builds. | 406 // Malformed OOB messages are silently ignored in release builds. |
| 425 default: | 407 default: |
| 426 UNREACHABLE(); | 408 UNREACHABLE(); |
| 427 break; | 409 break; |
| 428 #endif // defined(DEBUG) | 410 #endif // defined(DEBUG) |
| 429 } | 411 } |
| 430 return Error::null(); | 412 return Error::null(); |
| 431 } | 413 } |
| 432 | 414 |
| 433 | |
| 434 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { | 415 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { |
| 435 if (priority >= Message::kOOBPriority) { | 416 if (priority >= Message::kOOBPriority) { |
| 436 // Handle out of band messages even if the mutator thread is busy. | 417 // Handle out of band messages even if the mutator thread is busy. |
| 437 I->ScheduleMessageInterrupts(); | 418 I->ScheduleMessageInterrupts(); |
| 438 } | 419 } |
| 439 Dart_MessageNotifyCallback callback = I->message_notify_callback(); | 420 Dart_MessageNotifyCallback callback = I->message_notify_callback(); |
| 440 if (callback) { | 421 if (callback) { |
| 441 // Allow the embedder to handle message notification. | 422 // Allow the embedder to handle message notification. |
| 442 (*callback)(Api::CastIsolate(I)); | 423 (*callback)(Api::CastIsolate(I)); |
| 443 } | 424 } |
| 444 } | 425 } |
| 445 | 426 |
| 446 | |
| 447 MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage( | 427 MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage( |
| 448 Message* message) { | 428 Message* message) { |
| 449 ASSERT(IsCurrentIsolate()); | 429 ASSERT(IsCurrentIsolate()); |
| 450 Thread* thread = Thread::Current(); | 430 Thread* thread = Thread::Current(); |
| 451 StackZone stack_zone(thread); | 431 StackZone stack_zone(thread); |
| 452 Zone* zone = stack_zone.GetZone(); | 432 Zone* zone = stack_zone.GetZone(); |
| 453 HandleScope handle_scope(thread); | 433 HandleScope handle_scope(thread); |
| 454 #ifndef PRODUCT | 434 #ifndef PRODUCT |
| 455 TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), | 435 TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), |
| 456 "HandleMessage"); | 436 "HandleMessage"); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 if (result.IsError()) { | 562 if (result.IsError()) { |
| 583 status = ProcessUnhandledException(Error::Cast(result)); | 563 status = ProcessUnhandledException(Error::Cast(result)); |
| 584 } else { | 564 } else { |
| 585 ASSERT(result.IsNull()); | 565 ASSERT(result.IsNull()); |
| 586 } | 566 } |
| 587 } | 567 } |
| 588 #endif // !PRODUCT | 568 #endif // !PRODUCT |
| 589 return status; | 569 return status; |
| 590 } | 570 } |
| 591 | 571 |
| 592 | |
| 593 #ifndef PRODUCT | 572 #ifndef PRODUCT |
| 594 void IsolateMessageHandler::NotifyPauseOnStart() { | 573 void IsolateMessageHandler::NotifyPauseOnStart() { |
| 595 if (!FLAG_support_service) { | 574 if (!FLAG_support_service) { |
| 596 return; | 575 return; |
| 597 } | 576 } |
| 598 if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) { | 577 if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) { |
| 599 StartIsolateScope start_isolate(I); | 578 StartIsolateScope start_isolate(I); |
| 600 StackZone zone(T); | 579 StackZone zone(T); |
| 601 HandleScope handle_scope(T); | 580 HandleScope handle_scope(T); |
| 602 ServiceEvent pause_event(I, ServiceEvent::kPauseStart); | 581 ServiceEvent pause_event(I, ServiceEvent::kPauseStart); |
| 603 Service::HandleEvent(&pause_event); | 582 Service::HandleEvent(&pause_event); |
| 604 } else if (FLAG_trace_service) { | 583 } else if (FLAG_trace_service) { |
| 605 OS::Print("vm-service: Dropping event of type PauseStart (%s)\n", | 584 OS::Print("vm-service: Dropping event of type PauseStart (%s)\n", |
| 606 I->name()); | 585 I->name()); |
| 607 } | 586 } |
| 608 } | 587 } |
| 609 | 588 |
| 610 | |
| 611 void IsolateMessageHandler::NotifyPauseOnExit() { | 589 void IsolateMessageHandler::NotifyPauseOnExit() { |
| 612 if (!FLAG_support_service) { | 590 if (!FLAG_support_service) { |
| 613 return; | 591 return; |
| 614 } | 592 } |
| 615 if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) { | 593 if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) { |
| 616 StartIsolateScope start_isolate(I); | 594 StartIsolateScope start_isolate(I); |
| 617 StackZone zone(T); | 595 StackZone zone(T); |
| 618 HandleScope handle_scope(T); | 596 HandleScope handle_scope(T); |
| 619 ServiceEvent pause_event(I, ServiceEvent::kPauseExit); | 597 ServiceEvent pause_event(I, ServiceEvent::kPauseExit); |
| 620 Service::HandleEvent(&pause_event); | 598 Service::HandleEvent(&pause_event); |
| 621 } else if (FLAG_trace_service) { | 599 } else if (FLAG_trace_service) { |
| 622 OS::Print("vm-service: Dropping event of type PauseExit (%s)\n", I->name()); | 600 OS::Print("vm-service: Dropping event of type PauseExit (%s)\n", I->name()); |
| 623 } | 601 } |
| 624 } | 602 } |
| 625 #endif // !PRODUCT | 603 #endif // !PRODUCT |
| 626 | 604 |
| 627 | |
| 628 #if defined(DEBUG) | 605 #if defined(DEBUG) |
| 629 void IsolateMessageHandler::CheckAccess() { | 606 void IsolateMessageHandler::CheckAccess() { |
| 630 ASSERT(IsCurrentIsolate()); | 607 ASSERT(IsCurrentIsolate()); |
| 631 } | 608 } |
| 632 #endif | 609 #endif |
| 633 | 610 |
| 634 | |
| 635 bool IsolateMessageHandler::IsCurrentIsolate() const { | 611 bool IsolateMessageHandler::IsCurrentIsolate() const { |
| 636 return (I == Isolate::Current()); | 612 return (I == Isolate::Current()); |
| 637 } | 613 } |
| 638 | 614 |
| 639 | |
| 640 static MessageHandler::MessageStatus StoreError(Thread* thread, | 615 static MessageHandler::MessageStatus StoreError(Thread* thread, |
| 641 const Error& error) { | 616 const Error& error) { |
| 642 thread->set_sticky_error(error); | 617 thread->set_sticky_error(error); |
| 643 if (error.IsUnwindError()) { | 618 if (error.IsUnwindError()) { |
| 644 const UnwindError& unwind = UnwindError::Cast(error); | 619 const UnwindError& unwind = UnwindError::Cast(error); |
| 645 if (!unwind.is_user_initiated()) { | 620 if (!unwind.is_user_initiated()) { |
| 646 return MessageHandler::kShutdown; | 621 return MessageHandler::kShutdown; |
| 647 } | 622 } |
| 648 } | 623 } |
| 649 return MessageHandler::kError; | 624 return MessageHandler::kError; |
| 650 } | 625 } |
| 651 | 626 |
| 652 | |
| 653 MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException( | 627 MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException( |
| 654 const Error& result) { | 628 const Error& result) { |
| 655 NoReloadScope no_reload_scope(T->isolate(), T); | 629 NoReloadScope no_reload_scope(T->isolate(), T); |
| 656 // Generate the error and stacktrace strings for the error message. | 630 // Generate the error and stacktrace strings for the error message. |
| 657 String& exc_str = String::Handle(T->zone()); | 631 String& exc_str = String::Handle(T->zone()); |
| 658 String& stacktrace_str = String::Handle(T->zone()); | 632 String& stacktrace_str = String::Handle(T->zone()); |
| 659 if (result.IsUnhandledException()) { | 633 if (result.IsUnhandledException()) { |
| 660 Zone* zone = T->zone(); | 634 Zone* zone = T->zone(); |
| 661 const UnhandledException& uhe = UnhandledException::Cast(result); | 635 const UnhandledException& uhe = UnhandledException::Cast(result); |
| 662 const Instance& exception = Instance::Handle(zone, uhe.exception()); | 636 const Instance& exception = Instance::Handle(zone, uhe.exception()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 I->debugger()->PauseException(Instance::Handle(exception)); | 676 I->debugger()->PauseException(Instance::Handle(exception)); |
| 703 } | 677 } |
| 704 } | 678 } |
| 705 } | 679 } |
| 706 return kError; | 680 return kError; |
| 707 } | 681 } |
| 708 } | 682 } |
| 709 return kOK; | 683 return kOK; |
| 710 } | 684 } |
| 711 | 685 |
| 712 | |
| 713 void Isolate::FlagsInitialize(Dart_IsolateFlags* api_flags) { | 686 void Isolate::FlagsInitialize(Dart_IsolateFlags* api_flags) { |
| 714 api_flags->version = DART_FLAGS_CURRENT_VERSION; | 687 api_flags->version = DART_FLAGS_CURRENT_VERSION; |
| 715 #define INIT_FROM_FLAG(name, isolate_flag, flag) api_flags->isolate_flag = flag; | 688 #define INIT_FROM_FLAG(name, isolate_flag, flag) api_flags->isolate_flag = flag; |
| 716 ISOLATE_FLAG_LIST(INIT_FROM_FLAG) | 689 ISOLATE_FLAG_LIST(INIT_FROM_FLAG) |
| 717 #undef INIT_FROM_FLAG | 690 #undef INIT_FROM_FLAG |
| 718 } | 691 } |
| 719 | 692 |
| 720 | |
| 721 void Isolate::FlagsCopyTo(Dart_IsolateFlags* api_flags) const { | 693 void Isolate::FlagsCopyTo(Dart_IsolateFlags* api_flags) const { |
| 722 api_flags->version = DART_FLAGS_CURRENT_VERSION; | 694 api_flags->version = DART_FLAGS_CURRENT_VERSION; |
| 723 #define INIT_FROM_FIELD(name, isolate_flag, flag) \ | 695 #define INIT_FROM_FIELD(name, isolate_flag, flag) \ |
| 724 api_flags->isolate_flag = name(); | 696 api_flags->isolate_flag = name(); |
| 725 ISOLATE_FLAG_LIST(INIT_FROM_FIELD) | 697 ISOLATE_FLAG_LIST(INIT_FROM_FIELD) |
| 726 #undef INIT_FROM_FIELD | 698 #undef INIT_FROM_FIELD |
| 727 } | 699 } |
| 728 | 700 |
| 729 | |
| 730 #if !defined(PRODUCT) | 701 #if !defined(PRODUCT) |
| 731 void Isolate::FlagsCopyFrom(const Dart_IsolateFlags& api_flags) { | 702 void Isolate::FlagsCopyFrom(const Dart_IsolateFlags& api_flags) { |
| 732 #define SET_FROM_FLAG(name, isolate_flag, flag) \ | 703 #define SET_FROM_FLAG(name, isolate_flag, flag) \ |
| 733 name##_ = api_flags.isolate_flag; | 704 name##_ = api_flags.isolate_flag; |
| 734 ISOLATE_FLAG_LIST(SET_FROM_FLAG) | 705 ISOLATE_FLAG_LIST(SET_FROM_FLAG) |
| 735 #undef SET_FROM_FLAG | 706 #undef SET_FROM_FLAG |
| 736 // Leave others at defaults. | 707 // Leave others at defaults. |
| 737 } | 708 } |
| 738 #endif // !defined(PRODUCT) | 709 #endif // !defined(PRODUCT) |
| 739 | 710 |
| 740 | |
| 741 #if defined(DEBUG) | 711 #if defined(DEBUG) |
| 742 // static | 712 // static |
| 743 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) { | 713 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) { |
| 744 ASSERT(isolate == Isolate::Current()); | 714 ASSERT(isolate == Isolate::Current()); |
| 745 } | 715 } |
| 746 | 716 |
| 747 void BaseIsolate::AssertCurrentThreadIsMutator() const { | 717 void BaseIsolate::AssertCurrentThreadIsMutator() const { |
| 748 ASSERT(Isolate::Current() == this); | 718 ASSERT(Isolate::Current() == this); |
| 749 ASSERT(Thread::Current()->IsMutatorThread()); | 719 ASSERT(Thread::Current()->IsMutatorThread()); |
| 750 } | 720 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 delete pause_loop_monitor_; | 857 delete pause_loop_monitor_; |
| 888 pause_loop_monitor_ = NULL; | 858 pause_loop_monitor_ = NULL; |
| 889 delete field_list_mutex_; | 859 delete field_list_mutex_; |
| 890 field_list_mutex_ = NULL; | 860 field_list_mutex_ = NULL; |
| 891 ASSERT(spawn_count_ == 0); | 861 ASSERT(spawn_count_ == 0); |
| 892 delete spawn_count_monitor_; | 862 delete spawn_count_monitor_; |
| 893 delete safepoint_handler_; | 863 delete safepoint_handler_; |
| 894 delete thread_registry_; | 864 delete thread_registry_; |
| 895 } | 865 } |
| 896 | 866 |
| 897 | |
| 898 void Isolate::InitOnce() { | 867 void Isolate::InitOnce() { |
| 899 create_callback_ = NULL; | 868 create_callback_ = NULL; |
| 900 isolates_list_monitor_ = new Monitor(); | 869 isolates_list_monitor_ = new Monitor(); |
| 901 ASSERT(isolates_list_monitor_ != NULL); | 870 ASSERT(isolates_list_monitor_ != NULL); |
| 902 EnableIsolateCreation(); | 871 EnableIsolateCreation(); |
| 903 } | 872 } |
| 904 | 873 |
| 905 | |
| 906 Isolate* Isolate::Init(const char* name_prefix, | 874 Isolate* Isolate::Init(const char* name_prefix, |
| 907 const Dart_IsolateFlags& api_flags, | 875 const Dart_IsolateFlags& api_flags, |
| 908 bool is_vm_isolate) { | 876 bool is_vm_isolate) { |
| 909 Isolate* result = new Isolate(api_flags); | 877 Isolate* result = new Isolate(api_flags); |
| 910 ASSERT(result != NULL); | 878 ASSERT(result != NULL); |
| 911 | 879 |
| 912 // Initialize metrics. | 880 // Initialize metrics. |
| 913 #define ISOLATE_METRIC_INIT(type, variable, name, unit) \ | 881 #define ISOLATE_METRIC_INIT(type, variable, name, unit) \ |
| 914 result->metric_##variable##_.Init(result, name, NULL, Metric::unit); | 882 result->metric_##variable##_.Init(result, name, NULL, Metric::unit); |
| 915 ISOLATE_METRIC_LIST(ISOLATE_METRIC_INIT); | 883 ISOLATE_METRIC_LIST(ISOLATE_METRIC_INIT); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 if (!AddIsolateToList(result)) { | 943 if (!AddIsolateToList(result)) { |
| 976 result->LowLevelShutdown(); | 944 result->LowLevelShutdown(); |
| 977 Thread::ExitIsolate(); | 945 Thread::ExitIsolate(); |
| 978 delete result; | 946 delete result; |
| 979 return NULL; | 947 return NULL; |
| 980 } | 948 } |
| 981 | 949 |
| 982 return result; | 950 return result; |
| 983 } | 951 } |
| 984 | 952 |
| 985 | |
| 986 Thread* Isolate::mutator_thread() const { | 953 Thread* Isolate::mutator_thread() const { |
| 987 ASSERT(thread_registry() != NULL); | 954 ASSERT(thread_registry() != NULL); |
| 988 return thread_registry()->mutator_thread(); | 955 return thread_registry()->mutator_thread(); |
| 989 } | 956 } |
| 990 | 957 |
| 991 | |
| 992 void Isolate::SetupImagePage(const uint8_t* image_buffer, bool is_executable) { | 958 void Isolate::SetupImagePage(const uint8_t* image_buffer, bool is_executable) { |
| 993 Image image(image_buffer); | 959 Image image(image_buffer); |
| 994 heap_->SetupImagePage(image.object_start(), image.object_size(), | 960 heap_->SetupImagePage(image.object_start(), image.object_size(), |
| 995 is_executable); | 961 is_executable); |
| 996 } | 962 } |
| 997 | 963 |
| 998 | |
| 999 void Isolate::ScheduleMessageInterrupts() { | 964 void Isolate::ScheduleMessageInterrupts() { |
| 1000 // We take the threads lock here to ensure that the mutator thread does not | 965 // We take the threads lock here to ensure that the mutator thread does not |
| 1001 // exit the isolate while we are trying to schedule interrupts on it. | 966 // exit the isolate while we are trying to schedule interrupts on it. |
| 1002 MonitorLocker ml(threads_lock()); | 967 MonitorLocker ml(threads_lock()); |
| 1003 Thread* mthread = mutator_thread(); | 968 Thread* mthread = mutator_thread(); |
| 1004 if (mthread != NULL) { | 969 if (mthread != NULL) { |
| 1005 mthread->ScheduleInterrupts(Thread::kMessageInterrupt); | 970 mthread->ScheduleInterrupts(Thread::kMessageInterrupt); |
| 1006 } | 971 } |
| 1007 } | 972 } |
| 1008 | 973 |
| 1009 | |
| 1010 void Isolate::set_debugger_name(const char* name) { | 974 void Isolate::set_debugger_name(const char* name) { |
| 1011 free(debugger_name_); | 975 free(debugger_name_); |
| 1012 debugger_name_ = strdup(name); | 976 debugger_name_ = strdup(name); |
| 1013 } | 977 } |
| 1014 | 978 |
| 1015 | |
| 1016 int64_t Isolate::UptimeMicros() const { | 979 int64_t Isolate::UptimeMicros() const { |
| 1017 return OS::GetCurrentMonotonicMicros() - start_time_micros_; | 980 return OS::GetCurrentMonotonicMicros() - start_time_micros_; |
| 1018 } | 981 } |
| 1019 | 982 |
| 1020 | |
| 1021 bool Isolate::IsPaused() const { | 983 bool Isolate::IsPaused() const { |
| 1022 return (debugger_ != NULL) && (debugger_->PauseEvent() != NULL); | 984 return (debugger_ != NULL) && (debugger_->PauseEvent() != NULL); |
| 1023 } | 985 } |
| 1024 | 986 |
| 1025 | |
| 1026 RawError* Isolate::PausePostRequest() { | 987 RawError* Isolate::PausePostRequest() { |
| 1027 if (!FLAG_support_debugger) { | 988 if (!FLAG_support_debugger) { |
| 1028 return Error::null(); | 989 return Error::null(); |
| 1029 } | 990 } |
| 1030 if (debugger_ == NULL) { | 991 if (debugger_ == NULL) { |
| 1031 return Error::null(); | 992 return Error::null(); |
| 1032 } | 993 } |
| 1033 ASSERT(!IsPaused()); | 994 ASSERT(!IsPaused()); |
| 1034 const Error& error = Error::Handle(debugger_->PausePostRequest()); | 995 const Error& error = Error::Handle(debugger_->PausePostRequest()); |
| 1035 if (!error.IsNull()) { | 996 if (!error.IsNull()) { |
| 1036 if (Thread::Current()->top_exit_frame_info() == 0) { | 997 if (Thread::Current()->top_exit_frame_info() == 0) { |
| 1037 return error.raw(); | 998 return error.raw(); |
| 1038 } else { | 999 } else { |
| 1039 Exceptions::PropagateError(error); | 1000 Exceptions::PropagateError(error); |
| 1040 UNREACHABLE(); | 1001 UNREACHABLE(); |
| 1041 } | 1002 } |
| 1042 } | 1003 } |
| 1043 return Error::null(); | 1004 return Error::null(); |
| 1044 } | 1005 } |
| 1045 | 1006 |
| 1046 | |
| 1047 void Isolate::BuildName(const char* name_prefix) { | 1007 void Isolate::BuildName(const char* name_prefix) { |
| 1048 ASSERT(name_ == NULL); | 1008 ASSERT(name_ == NULL); |
| 1049 if (name_prefix == NULL) { | 1009 if (name_prefix == NULL) { |
| 1050 name_prefix = "isolate"; | 1010 name_prefix = "isolate"; |
| 1051 } | 1011 } |
| 1052 set_debugger_name(name_prefix); | 1012 set_debugger_name(name_prefix); |
| 1053 if (ServiceIsolate::NameEquals(name_prefix)) { | 1013 if (ServiceIsolate::NameEquals(name_prefix)) { |
| 1054 name_ = strdup(name_prefix); | 1014 name_ = strdup(name_prefix); |
| 1055 return; | 1015 return; |
| 1056 } | 1016 } |
| 1057 name_ = OS::SCreate(NULL, "%s-%" Pd64 "", name_prefix, main_port()); | 1017 name_ = OS::SCreate(NULL, "%s-%" Pd64 "", name_prefix, main_port()); |
| 1058 } | 1018 } |
| 1059 | 1019 |
| 1060 | |
| 1061 void Isolate::DoneLoading() { | 1020 void Isolate::DoneLoading() { |
| 1062 GrowableObjectArray& libs = | 1021 GrowableObjectArray& libs = |
| 1063 GrowableObjectArray::Handle(current_zone(), object_store()->libraries()); | 1022 GrowableObjectArray::Handle(current_zone(), object_store()->libraries()); |
| 1064 Library& lib = Library::Handle(current_zone()); | 1023 Library& lib = Library::Handle(current_zone()); |
| 1065 intptr_t num_libs = libs.Length(); | 1024 intptr_t num_libs = libs.Length(); |
| 1066 for (intptr_t i = 0; i < num_libs; i++) { | 1025 for (intptr_t i = 0; i < num_libs; i++) { |
| 1067 lib ^= libs.At(i); | 1026 lib ^= libs.At(i); |
| 1068 // If this library was loaded with Dart_LoadLibrary, it was marked | 1027 // If this library was loaded with Dart_LoadLibrary, it was marked |
| 1069 // as 'load in progres'. Set the status to 'loaded'. | 1028 // as 'load in progres'. Set the status to 'loaded'. |
| 1070 if (lib.LoadInProgress()) { | 1029 if (lib.LoadInProgress()) { |
| 1071 lib.SetLoaded(); | 1030 lib.SetLoaded(); |
| 1072 } | 1031 } |
| 1073 } | 1032 } |
| 1074 TokenStream::CloseSharedTokenList(this); | 1033 TokenStream::CloseSharedTokenList(this); |
| 1075 } | 1034 } |
| 1076 | 1035 |
| 1077 | |
| 1078 bool Isolate::CanReload() const { | 1036 bool Isolate::CanReload() const { |
| 1079 #ifndef PRODUCT | 1037 #ifndef PRODUCT |
| 1080 return !ServiceIsolate::IsServiceIsolateDescendant(this) && is_runnable() && | 1038 return !ServiceIsolate::IsServiceIsolateDescendant(this) && is_runnable() && |
| 1081 !IsReloading() && | 1039 !IsReloading() && |
| 1082 (AtomicOperations::LoadRelaxed(&no_reload_scope_depth_) == 0) && | 1040 (AtomicOperations::LoadRelaxed(&no_reload_scope_depth_) == 0) && |
| 1083 IsolateCreationEnabled(); | 1041 IsolateCreationEnabled(); |
| 1084 #else | 1042 #else |
| 1085 return false; | 1043 return false; |
| 1086 #endif | 1044 #endif |
| 1087 } | 1045 } |
| 1088 | 1046 |
| 1089 | |
| 1090 #ifndef PRODUCT | 1047 #ifndef PRODUCT |
| 1091 bool Isolate::ReloadSources(JSONStream* js, | 1048 bool Isolate::ReloadSources(JSONStream* js, |
| 1092 bool force_reload, | 1049 bool force_reload, |
| 1093 const char* root_script_url, | 1050 const char* root_script_url, |
| 1094 const char* packages_url, | 1051 const char* packages_url, |
| 1095 bool dont_delete_reload_context) { | 1052 bool dont_delete_reload_context) { |
| 1096 ASSERT(!IsReloading()); | 1053 ASSERT(!IsReloading()); |
| 1097 has_attempted_reload_ = true; | 1054 has_attempted_reload_ = true; |
| 1098 reload_context_ = new IsolateReloadContext(this, js); | 1055 reload_context_ = new IsolateReloadContext(this, js); |
| 1099 reload_context_->Reload(force_reload, root_script_url, packages_url); | 1056 reload_context_->Reload(force_reload, root_script_url, packages_url); |
| 1100 bool success = !reload_context_->reload_aborted(); | 1057 bool success = !reload_context_->reload_aborted(); |
| 1101 if (!dont_delete_reload_context) { | 1058 if (!dont_delete_reload_context) { |
| 1102 DeleteReloadContext(); | 1059 DeleteReloadContext(); |
| 1103 } | 1060 } |
| 1104 return success; | 1061 return success; |
| 1105 } | 1062 } |
| 1106 | 1063 |
| 1107 | |
| 1108 void Isolate::DeleteReloadContext() { | 1064 void Isolate::DeleteReloadContext() { |
| 1109 // Another thread may be in the middle of GetClassForHeapWalkAt. | 1065 // Another thread may be in the middle of GetClassForHeapWalkAt. |
| 1110 Thread* thread = Thread::Current(); | 1066 Thread* thread = Thread::Current(); |
| 1111 SafepointOperationScope safepoint_scope(thread); | 1067 SafepointOperationScope safepoint_scope(thread); |
| 1112 | 1068 |
| 1113 delete reload_context_; | 1069 delete reload_context_; |
| 1114 reload_context_ = NULL; | 1070 reload_context_ = NULL; |
| 1115 } | 1071 } |
| 1116 #endif // !PRODUCT | 1072 #endif // !PRODUCT |
| 1117 | 1073 |
| 1118 | |
| 1119 void Isolate::DoneFinalizing() { | 1074 void Isolate::DoneFinalizing() { |
| 1120 #if !defined(PRODUCT) | 1075 #if !defined(PRODUCT) |
| 1121 if (IsReloading()) { | 1076 if (IsReloading()) { |
| 1122 reload_context_->FinalizeLoading(); | 1077 reload_context_->FinalizeLoading(); |
| 1123 } | 1078 } |
| 1124 #endif // !defined(PRODUCT) | 1079 #endif // !defined(PRODUCT) |
| 1125 } | 1080 } |
| 1126 | 1081 |
| 1127 | |
| 1128 bool Isolate::MakeRunnable() { | 1082 bool Isolate::MakeRunnable() { |
| 1129 ASSERT(Isolate::Current() == NULL); | 1083 ASSERT(Isolate::Current() == NULL); |
| 1130 | 1084 |
| 1131 MutexLocker ml(mutex_); | 1085 MutexLocker ml(mutex_); |
| 1132 // Check if we are in a valid state to make the isolate runnable. | 1086 // Check if we are in a valid state to make the isolate runnable. |
| 1133 if (is_runnable() == true) { | 1087 if (is_runnable() == true) { |
| 1134 return false; // Already runnable. | 1088 return false; // Already runnable. |
| 1135 } | 1089 } |
| 1136 // Set the isolate as runnable and if we are being spawned schedule | 1090 // Set the isolate as runnable and if we are being spawned schedule |
| 1137 // isolate on thread pool for execution. | 1091 // isolate on thread pool for execution. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 StartIsolateScope scope(this); | 1127 StartIsolateScope scope(this); |
| 1174 heap()->CollectAllGarbage(); | 1128 heap()->CollectAllGarbage(); |
| 1175 } | 1129 } |
| 1176 int64_t heap_size = (heap()->UsedInWords(Heap::kNew) * kWordSize) + | 1130 int64_t heap_size = (heap()->UsedInWords(Heap::kNew) * kWordSize) + |
| 1177 (heap()->UsedInWords(Heap::kOld) * kWordSize); | 1131 (heap()->UsedInWords(Heap::kOld) * kWordSize); |
| 1178 GetRunnableHeapSizeMetric()->set_value(heap_size); | 1132 GetRunnableHeapSizeMetric()->set_value(heap_size); |
| 1179 } | 1133 } |
| 1180 return true; | 1134 return true; |
| 1181 } | 1135 } |
| 1182 | 1136 |
| 1183 | |
| 1184 bool Isolate::VerifyPauseCapability(const Object& capability) const { | 1137 bool Isolate::VerifyPauseCapability(const Object& capability) const { |
| 1185 return !capability.IsNull() && capability.IsCapability() && | 1138 return !capability.IsNull() && capability.IsCapability() && |
| 1186 (pause_capability() == Capability::Cast(capability).Id()); | 1139 (pause_capability() == Capability::Cast(capability).Id()); |
| 1187 } | 1140 } |
| 1188 | 1141 |
| 1189 | |
| 1190 bool Isolate::VerifyTerminateCapability(const Object& capability) const { | 1142 bool Isolate::VerifyTerminateCapability(const Object& capability) const { |
| 1191 return !capability.IsNull() && capability.IsCapability() && | 1143 return !capability.IsNull() && capability.IsCapability() && |
| 1192 (terminate_capability() == Capability::Cast(capability).Id()); | 1144 (terminate_capability() == Capability::Cast(capability).Id()); |
| 1193 } | 1145 } |
| 1194 | 1146 |
| 1195 | |
| 1196 bool Isolate::AddResumeCapability(const Capability& capability) { | 1147 bool Isolate::AddResumeCapability(const Capability& capability) { |
| 1197 // Ensure a limit for the number of resume capabilities remembered. | 1148 // Ensure a limit for the number of resume capabilities remembered. |
| 1198 static const intptr_t kMaxResumeCapabilities = kSmiMax / (6 * kWordSize); | 1149 static const intptr_t kMaxResumeCapabilities = kSmiMax / (6 * kWordSize); |
| 1199 | 1150 |
| 1200 const GrowableObjectArray& caps = GrowableObjectArray::Handle( | 1151 const GrowableObjectArray& caps = GrowableObjectArray::Handle( |
| 1201 current_zone(), object_store()->resume_capabilities()); | 1152 current_zone(), object_store()->resume_capabilities()); |
| 1202 Capability& current = Capability::Handle(current_zone()); | 1153 Capability& current = Capability::Handle(current_zone()); |
| 1203 intptr_t insertion_index = -1; | 1154 intptr_t insertion_index = -1; |
| 1204 for (intptr_t i = 0; i < caps.Length(); i++) { | 1155 for (intptr_t i = 0; i < caps.Length(); i++) { |
| 1205 current ^= caps.At(i); | 1156 current ^= caps.At(i); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1218 // run out of memory beforehand. | 1169 // run out of memory beforehand. |
| 1219 return false; | 1170 return false; |
| 1220 } | 1171 } |
| 1221 caps.Add(capability); | 1172 caps.Add(capability); |
| 1222 } else { | 1173 } else { |
| 1223 caps.SetAt(insertion_index, capability); | 1174 caps.SetAt(insertion_index, capability); |
| 1224 } | 1175 } |
| 1225 return true; | 1176 return true; |
| 1226 } | 1177 } |
| 1227 | 1178 |
| 1228 | |
| 1229 bool Isolate::RemoveResumeCapability(const Capability& capability) { | 1179 bool Isolate::RemoveResumeCapability(const Capability& capability) { |
| 1230 const GrowableObjectArray& caps = GrowableObjectArray::Handle( | 1180 const GrowableObjectArray& caps = GrowableObjectArray::Handle( |
| 1231 current_zone(), object_store()->resume_capabilities()); | 1181 current_zone(), object_store()->resume_capabilities()); |
| 1232 Capability& current = Capability::Handle(current_zone()); | 1182 Capability& current = Capability::Handle(current_zone()); |
| 1233 for (intptr_t i = 0; i < caps.Length(); i++) { | 1183 for (intptr_t i = 0; i < caps.Length(); i++) { |
| 1234 current ^= caps.At(i); | 1184 current ^= caps.At(i); |
| 1235 if (!current.IsNull() && (current.Id() == capability.Id())) { | 1185 if (!current.IsNull() && (current.Id() == capability.Id())) { |
| 1236 // Remove the matching capability from the list. | 1186 // Remove the matching capability from the list. |
| 1237 current = Capability::null(); | 1187 current = Capability::null(); |
| 1238 caps.SetAt(i, current); | 1188 caps.SetAt(i, current); |
| 1239 return true; | 1189 return true; |
| 1240 } | 1190 } |
| 1241 } | 1191 } |
| 1242 return false; | 1192 return false; |
| 1243 } | 1193 } |
| 1244 | 1194 |
| 1245 | |
| 1246 // TODO(iposva): Remove duplicated code and start using some hash based | 1195 // TODO(iposva): Remove duplicated code and start using some hash based |
| 1247 // structure instead of these linear lookups. | 1196 // structure instead of these linear lookups. |
| 1248 void Isolate::AddExitListener(const SendPort& listener, | 1197 void Isolate::AddExitListener(const SendPort& listener, |
| 1249 const Instance& response) { | 1198 const Instance& response) { |
| 1250 // Ensure a limit for the number of listeners remembered. | 1199 // Ensure a limit for the number of listeners remembered. |
| 1251 static const intptr_t kMaxListeners = kSmiMax / (12 * kWordSize); | 1200 static const intptr_t kMaxListeners = kSmiMax / (12 * kWordSize); |
| 1252 | 1201 |
| 1253 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1202 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
| 1254 current_zone(), object_store()->exit_listeners()); | 1203 current_zone(), object_store()->exit_listeners()); |
| 1255 SendPort& current = SendPort::Handle(current_zone()); | 1204 SendPort& current = SendPort::Handle(current_zone()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1273 return; | 1222 return; |
| 1274 } | 1223 } |
| 1275 listeners.Add(listener); | 1224 listeners.Add(listener); |
| 1276 listeners.Add(response); | 1225 listeners.Add(response); |
| 1277 } else { | 1226 } else { |
| 1278 listeners.SetAt(insertion_index, listener); | 1227 listeners.SetAt(insertion_index, listener); |
| 1279 listeners.SetAt(insertion_index + 1, response); | 1228 listeners.SetAt(insertion_index + 1, response); |
| 1280 } | 1229 } |
| 1281 } | 1230 } |
| 1282 | 1231 |
| 1283 | |
| 1284 void Isolate::RemoveExitListener(const SendPort& listener) { | 1232 void Isolate::RemoveExitListener(const SendPort& listener) { |
| 1285 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1233 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
| 1286 current_zone(), object_store()->exit_listeners()); | 1234 current_zone(), object_store()->exit_listeners()); |
| 1287 SendPort& current = SendPort::Handle(current_zone()); | 1235 SendPort& current = SendPort::Handle(current_zone()); |
| 1288 for (intptr_t i = 0; i < listeners.Length(); i += 2) { | 1236 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
| 1289 current ^= listeners.At(i); | 1237 current ^= listeners.At(i); |
| 1290 if (!current.IsNull() && (current.Id() == listener.Id())) { | 1238 if (!current.IsNull() && (current.Id() == listener.Id())) { |
| 1291 // Remove the matching listener from the list. | 1239 // Remove the matching listener from the list. |
| 1292 current = SendPort::null(); | 1240 current = SendPort::null(); |
| 1293 listeners.SetAt(i, current); | 1241 listeners.SetAt(i, current); |
| 1294 listeners.SetAt(i + 1, Object::null_instance()); | 1242 listeners.SetAt(i + 1, Object::null_instance()); |
| 1295 return; | 1243 return; |
| 1296 } | 1244 } |
| 1297 } | 1245 } |
| 1298 } | 1246 } |
| 1299 | 1247 |
| 1300 | |
| 1301 void Isolate::NotifyExitListeners() { | 1248 void Isolate::NotifyExitListeners() { |
| 1302 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1249 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
| 1303 current_zone(), this->object_store()->exit_listeners()); | 1250 current_zone(), this->object_store()->exit_listeners()); |
| 1304 if (listeners.IsNull()) return; | 1251 if (listeners.IsNull()) return; |
| 1305 | 1252 |
| 1306 SendPort& listener = SendPort::Handle(current_zone()); | 1253 SendPort& listener = SendPort::Handle(current_zone()); |
| 1307 Instance& response = Instance::Handle(current_zone()); | 1254 Instance& response = Instance::Handle(current_zone()); |
| 1308 for (intptr_t i = 0; i < listeners.Length(); i += 2) { | 1255 for (intptr_t i = 0; i < listeners.Length(); i += 2) { |
| 1309 listener ^= listeners.At(i); | 1256 listener ^= listeners.At(i); |
| 1310 if (!listener.IsNull()) { | 1257 if (!listener.IsNull()) { |
| 1311 Dart_Port port_id = listener.Id(); | 1258 Dart_Port port_id = listener.Id(); |
| 1312 response ^= listeners.At(i + 1); | 1259 response ^= listeners.At(i + 1); |
| 1313 PortMap::PostMessage(SerializeMessage(port_id, response)); | 1260 PortMap::PostMessage(SerializeMessage(port_id, response)); |
| 1314 } | 1261 } |
| 1315 } | 1262 } |
| 1316 } | 1263 } |
| 1317 | 1264 |
| 1318 | |
| 1319 void Isolate::AddErrorListener(const SendPort& listener) { | 1265 void Isolate::AddErrorListener(const SendPort& listener) { |
| 1320 // Ensure a limit for the number of listeners remembered. | 1266 // Ensure a limit for the number of listeners remembered. |
| 1321 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); | 1267 static const intptr_t kMaxListeners = kSmiMax / (6 * kWordSize); |
| 1322 | 1268 |
| 1323 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1269 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
| 1324 current_zone(), object_store()->error_listeners()); | 1270 current_zone(), object_store()->error_listeners()); |
| 1325 SendPort& current = SendPort::Handle(current_zone()); | 1271 SendPort& current = SendPort::Handle(current_zone()); |
| 1326 intptr_t insertion_index = -1; | 1272 intptr_t insertion_index = -1; |
| 1327 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1273 for (intptr_t i = 0; i < listeners.Length(); i++) { |
| 1328 current ^= listeners.At(i); | 1274 current ^= listeners.At(i); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1340 // listeners are ignored. In practice will never happen as we will | 1286 // listeners are ignored. In practice will never happen as we will |
| 1341 // run out of memory beforehand. | 1287 // run out of memory beforehand. |
| 1342 return; | 1288 return; |
| 1343 } | 1289 } |
| 1344 listeners.Add(listener); | 1290 listeners.Add(listener); |
| 1345 } else { | 1291 } else { |
| 1346 listeners.SetAt(insertion_index, listener); | 1292 listeners.SetAt(insertion_index, listener); |
| 1347 } | 1293 } |
| 1348 } | 1294 } |
| 1349 | 1295 |
| 1350 | |
| 1351 void Isolate::RemoveErrorListener(const SendPort& listener) { | 1296 void Isolate::RemoveErrorListener(const SendPort& listener) { |
| 1352 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1297 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
| 1353 current_zone(), object_store()->error_listeners()); | 1298 current_zone(), object_store()->error_listeners()); |
| 1354 SendPort& current = SendPort::Handle(current_zone()); | 1299 SendPort& current = SendPort::Handle(current_zone()); |
| 1355 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1300 for (intptr_t i = 0; i < listeners.Length(); i++) { |
| 1356 current ^= listeners.At(i); | 1301 current ^= listeners.At(i); |
| 1357 if (!current.IsNull() && (current.Id() == listener.Id())) { | 1302 if (!current.IsNull() && (current.Id() == listener.Id())) { |
| 1358 // Remove the matching listener from the list. | 1303 // Remove the matching listener from the list. |
| 1359 current = SendPort::null(); | 1304 current = SendPort::null(); |
| 1360 listeners.SetAt(i, current); | 1305 listeners.SetAt(i, current); |
| 1361 return; | 1306 return; |
| 1362 } | 1307 } |
| 1363 } | 1308 } |
| 1364 } | 1309 } |
| 1365 | 1310 |
| 1366 | |
| 1367 bool Isolate::NotifyErrorListeners(const String& msg, | 1311 bool Isolate::NotifyErrorListeners(const String& msg, |
| 1368 const String& stacktrace) { | 1312 const String& stacktrace) { |
| 1369 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( | 1313 const GrowableObjectArray& listeners = GrowableObjectArray::Handle( |
| 1370 current_zone(), this->object_store()->error_listeners()); | 1314 current_zone(), this->object_store()->error_listeners()); |
| 1371 if (listeners.IsNull()) return false; | 1315 if (listeners.IsNull()) return false; |
| 1372 | 1316 |
| 1373 const Array& arr = Array::Handle(current_zone(), Array::New(2)); | 1317 const Array& arr = Array::Handle(current_zone(), Array::New(2)); |
| 1374 arr.SetAt(0, msg); | 1318 arr.SetAt(0, msg); |
| 1375 arr.SetAt(1, stacktrace); | 1319 arr.SetAt(1, stacktrace); |
| 1376 SendPort& listener = SendPort::Handle(current_zone()); | 1320 SendPort& listener = SendPort::Handle(current_zone()); |
| 1377 for (intptr_t i = 0; i < listeners.Length(); i++) { | 1321 for (intptr_t i = 0; i < listeners.Length(); i++) { |
| 1378 listener ^= listeners.At(i); | 1322 listener ^= listeners.At(i); |
| 1379 if (!listener.IsNull()) { | 1323 if (!listener.IsNull()) { |
| 1380 Dart_Port port_id = listener.Id(); | 1324 Dart_Port port_id = listener.Id(); |
| 1381 PortMap::PostMessage(SerializeMessage(port_id, arr)); | 1325 PortMap::PostMessage(SerializeMessage(port_id, arr)); |
| 1382 } | 1326 } |
| 1383 } | 1327 } |
| 1384 return listeners.Length() > 0; | 1328 return listeners.Length() > 0; |
| 1385 } | 1329 } |
| 1386 | 1330 |
| 1387 | |
| 1388 static MessageHandler::MessageStatus RunIsolate(uword parameter) { | 1331 static MessageHandler::MessageStatus RunIsolate(uword parameter) { |
| 1389 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1332 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 1390 IsolateSpawnState* state = NULL; | 1333 IsolateSpawnState* state = NULL; |
| 1391 { | 1334 { |
| 1392 // TODO(turnidge): Is this locking required here at all anymore? | 1335 // TODO(turnidge): Is this locking required here at all anymore? |
| 1393 MutexLocker ml(isolate->mutex()); | 1336 MutexLocker ml(isolate->mutex()); |
| 1394 state = isolate->spawn_state(); | 1337 state = isolate->spawn_state(); |
| 1395 } | 1338 } |
| 1396 { | 1339 { |
| 1397 StartIsolateScope start_scope(isolate); | 1340 StartIsolateScope start_scope(isolate); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1409 isolate->AddExitListener(listener, Instance::null_instance()); | 1352 isolate->AddExitListener(listener, Instance::null_instance()); |
| 1410 } | 1353 } |
| 1411 if (state->on_error_port() != ILLEGAL_PORT) { | 1354 if (state->on_error_port() != ILLEGAL_PORT) { |
| 1412 const SendPort& listener = | 1355 const SendPort& listener = |
| 1413 SendPort::Handle(SendPort::New(state->on_error_port())); | 1356 SendPort::Handle(SendPort::New(state->on_error_port())); |
| 1414 isolate->AddErrorListener(listener); | 1357 isolate->AddErrorListener(listener); |
| 1415 } | 1358 } |
| 1416 | 1359 |
| 1417 // Switch back to spawning isolate. | 1360 // Switch back to spawning isolate. |
| 1418 | 1361 |
| 1419 | |
| 1420 if (!ClassFinalizer::ProcessPendingClasses()) { | 1362 if (!ClassFinalizer::ProcessPendingClasses()) { |
| 1421 // Error is in sticky error already. | 1363 // Error is in sticky error already. |
| 1422 #if defined(DEBUG) | 1364 #if defined(DEBUG) |
| 1423 const Error& error = Error::Handle(thread->sticky_error()); | 1365 const Error& error = Error::Handle(thread->sticky_error()); |
| 1424 ASSERT(!error.IsUnwindError()); | 1366 ASSERT(!error.IsUnwindError()); |
| 1425 #endif | 1367 #endif |
| 1426 return MessageHandler::kError; | 1368 return MessageHandler::kError; |
| 1427 } | 1369 } |
| 1428 | 1370 |
| 1429 Object& result = Object::Handle(); | 1371 Object& result = Object::Handle(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1484 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); | 1426 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); |
| 1485 | 1427 |
| 1486 result = DartEntry::InvokeFunction(entry_point, args); | 1428 result = DartEntry::InvokeFunction(entry_point, args); |
| 1487 if (result.IsError()) { | 1429 if (result.IsError()) { |
| 1488 return StoreError(thread, Error::Cast(result)); | 1430 return StoreError(thread, Error::Cast(result)); |
| 1489 } | 1431 } |
| 1490 } | 1432 } |
| 1491 return MessageHandler::kOK; | 1433 return MessageHandler::kOK; |
| 1492 } | 1434 } |
| 1493 | 1435 |
| 1494 | |
| 1495 static void ShutdownIsolate(uword parameter) { | 1436 static void ShutdownIsolate(uword parameter) { |
| 1496 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1437 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 1497 // We must wait for any outstanding spawn calls to complete before | 1438 // We must wait for any outstanding spawn calls to complete before |
| 1498 // running the shutdown callback. | 1439 // running the shutdown callback. |
| 1499 isolate->WaitForOutstandingSpawns(); | 1440 isolate->WaitForOutstandingSpawns(); |
| 1500 { | 1441 { |
| 1501 // Print the error if there is one. This may execute dart code to | 1442 // Print the error if there is one. This may execute dart code to |
| 1502 // print the exception object, so we need to use a StartIsolateScope. | 1443 // print the exception object, so we need to use a StartIsolateScope. |
| 1503 StartIsolateScope start_scope(isolate); | 1444 StartIsolateScope start_scope(isolate); |
| 1504 Thread* thread = Thread::Current(); | 1445 Thread* thread = Thread::Current(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1519 const Error& error = Error::Handle(thread->sticky_error()); | 1460 const Error& error = Error::Handle(thread->sticky_error()); |
| 1520 if (!error.IsNull() && !error.IsUnwindError()) { | 1461 if (!error.IsNull() && !error.IsUnwindError()) { |
| 1521 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); | 1462 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
| 1522 } | 1463 } |
| 1523 Dart::RunShutdownCallback(); | 1464 Dart::RunShutdownCallback(); |
| 1524 } | 1465 } |
| 1525 // Shut the isolate down. | 1466 // Shut the isolate down. |
| 1526 Dart::ShutdownIsolate(isolate); | 1467 Dart::ShutdownIsolate(isolate); |
| 1527 } | 1468 } |
| 1528 | 1469 |
| 1529 | |
| 1530 void Isolate::SetStickyError(RawError* sticky_error) { | 1470 void Isolate::SetStickyError(RawError* sticky_error) { |
| 1531 ASSERT( | 1471 ASSERT( |
| 1532 ((sticky_error_ == Error::null()) || (sticky_error == Error::null())) && | 1472 ((sticky_error_ == Error::null()) || (sticky_error == Error::null())) && |
| 1533 (sticky_error != sticky_error_)); | 1473 (sticky_error != sticky_error_)); |
| 1534 sticky_error_ = sticky_error; | 1474 sticky_error_ = sticky_error; |
| 1535 } | 1475 } |
| 1536 | 1476 |
| 1537 | |
| 1538 void Isolate::Run() { | 1477 void Isolate::Run() { |
| 1539 message_handler()->Run(Dart::thread_pool(), RunIsolate, ShutdownIsolate, | 1478 message_handler()->Run(Dart::thread_pool(), RunIsolate, ShutdownIsolate, |
| 1540 reinterpret_cast<uword>(this)); | 1479 reinterpret_cast<uword>(this)); |
| 1541 } | 1480 } |
| 1542 | 1481 |
| 1543 | |
| 1544 void Isolate::AddClosureFunction(const Function& function) const { | 1482 void Isolate::AddClosureFunction(const Function& function) const { |
| 1545 ASSERT(!Compiler::IsBackgroundCompilation()); | 1483 ASSERT(!Compiler::IsBackgroundCompilation()); |
| 1546 GrowableObjectArray& closures = | 1484 GrowableObjectArray& closures = |
| 1547 GrowableObjectArray::Handle(object_store()->closure_functions()); | 1485 GrowableObjectArray::Handle(object_store()->closure_functions()); |
| 1548 ASSERT(!closures.IsNull()); | 1486 ASSERT(!closures.IsNull()); |
| 1549 ASSERT(function.IsNonImplicitClosureFunction()); | 1487 ASSERT(function.IsNonImplicitClosureFunction()); |
| 1550 closures.Add(function, Heap::kOld); | 1488 closures.Add(function, Heap::kOld); |
| 1551 } | 1489 } |
| 1552 | 1490 |
| 1553 | |
| 1554 // If the linear lookup turns out to be too expensive, the list | 1491 // If the linear lookup turns out to be too expensive, the list |
| 1555 // of closures could be maintained in a hash map, with the key | 1492 // of closures could be maintained in a hash map, with the key |
| 1556 // being the token position of the closure. There are almost no | 1493 // being the token position of the closure. There are almost no |
| 1557 // collisions with this simple hash value. However, iterating over | 1494 // collisions with this simple hash value. However, iterating over |
| 1558 // all closure functions becomes more difficult, especially when | 1495 // all closure functions becomes more difficult, especially when |
| 1559 // the list/map changes while iterating over it. | 1496 // the list/map changes while iterating over it. |
| 1560 RawFunction* Isolate::LookupClosureFunction(const Function& parent, | 1497 RawFunction* Isolate::LookupClosureFunction(const Function& parent, |
| 1561 TokenPosition token_pos) const { | 1498 TokenPosition token_pos) const { |
| 1562 const GrowableObjectArray& closures = | 1499 const GrowableObjectArray& closures = |
| 1563 GrowableObjectArray::Handle(object_store()->closure_functions()); | 1500 GrowableObjectArray::Handle(object_store()->closure_functions()); |
| 1564 ASSERT(!closures.IsNull()); | 1501 ASSERT(!closures.IsNull()); |
| 1565 Function& closure = Function::Handle(); | 1502 Function& closure = Function::Handle(); |
| 1566 intptr_t num_closures = closures.Length(); | 1503 intptr_t num_closures = closures.Length(); |
| 1567 for (intptr_t i = 0; i < num_closures; i++) { | 1504 for (intptr_t i = 0; i < num_closures; i++) { |
| 1568 closure ^= closures.At(i); | 1505 closure ^= closures.At(i); |
| 1569 if ((closure.token_pos() == token_pos) && | 1506 if ((closure.token_pos() == token_pos) && |
| 1570 (closure.parent_function() == parent.raw())) { | 1507 (closure.parent_function() == parent.raw())) { |
| 1571 return closure.raw(); | 1508 return closure.raw(); |
| 1572 } | 1509 } |
| 1573 } | 1510 } |
| 1574 return Function::null(); | 1511 return Function::null(); |
| 1575 } | 1512 } |
| 1576 | 1513 |
| 1577 | |
| 1578 intptr_t Isolate::FindClosureIndex(const Function& needle) const { | 1514 intptr_t Isolate::FindClosureIndex(const Function& needle) const { |
| 1579 const GrowableObjectArray& closures_array = | 1515 const GrowableObjectArray& closures_array = |
| 1580 GrowableObjectArray::Handle(object_store()->closure_functions()); | 1516 GrowableObjectArray::Handle(object_store()->closure_functions()); |
| 1581 intptr_t num_closures = closures_array.Length(); | 1517 intptr_t num_closures = closures_array.Length(); |
| 1582 for (intptr_t i = 0; i < num_closures; i++) { | 1518 for (intptr_t i = 0; i < num_closures; i++) { |
| 1583 if (closures_array.At(i) == needle.raw()) { | 1519 if (closures_array.At(i) == needle.raw()) { |
| 1584 return i; | 1520 return i; |
| 1585 } | 1521 } |
| 1586 } | 1522 } |
| 1587 return -1; | 1523 return -1; |
| 1588 } | 1524 } |
| 1589 | 1525 |
| 1590 | |
| 1591 RawFunction* Isolate::ClosureFunctionFromIndex(intptr_t idx) const { | 1526 RawFunction* Isolate::ClosureFunctionFromIndex(intptr_t idx) const { |
| 1592 const GrowableObjectArray& closures_array = | 1527 const GrowableObjectArray& closures_array = |
| 1593 GrowableObjectArray::Handle(object_store()->closure_functions()); | 1528 GrowableObjectArray::Handle(object_store()->closure_functions()); |
| 1594 if ((idx < 0) || (idx >= closures_array.Length())) { | 1529 if ((idx < 0) || (idx >= closures_array.Length())) { |
| 1595 return Function::null(); | 1530 return Function::null(); |
| 1596 } | 1531 } |
| 1597 return Function::RawCast(closures_array.At(idx)); | 1532 return Function::RawCast(closures_array.At(idx)); |
| 1598 } | 1533 } |
| 1599 | 1534 |
| 1600 | |
| 1601 class FinalizeWeakPersistentHandlesVisitor : public HandleVisitor { | 1535 class FinalizeWeakPersistentHandlesVisitor : public HandleVisitor { |
| 1602 public: | 1536 public: |
| 1603 FinalizeWeakPersistentHandlesVisitor() : HandleVisitor(Thread::Current()) {} | 1537 FinalizeWeakPersistentHandlesVisitor() : HandleVisitor(Thread::Current()) {} |
| 1604 | 1538 |
| 1605 void VisitHandle(uword addr) { | 1539 void VisitHandle(uword addr) { |
| 1606 FinalizablePersistentHandle* handle = | 1540 FinalizablePersistentHandle* handle = |
| 1607 reinterpret_cast<FinalizablePersistentHandle*>(addr); | 1541 reinterpret_cast<FinalizablePersistentHandle*>(addr); |
| 1608 handle->UpdateUnreachable(thread()->isolate()); | 1542 handle->UpdateUnreachable(thread()->isolate()); |
| 1609 } | 1543 } |
| 1610 | 1544 |
| 1611 private: | 1545 private: |
| 1612 DISALLOW_COPY_AND_ASSIGN(FinalizeWeakPersistentHandlesVisitor); | 1546 DISALLOW_COPY_AND_ASSIGN(FinalizeWeakPersistentHandlesVisitor); |
| 1613 }; | 1547 }; |
| 1614 | 1548 |
| 1615 | |
| 1616 void Isolate::LowLevelShutdown() { | 1549 void Isolate::LowLevelShutdown() { |
| 1617 // Ensure we have a zone and handle scope so that we can call VM functions, | 1550 // Ensure we have a zone and handle scope so that we can call VM functions, |
| 1618 // but we no longer allocate new heap objects. | 1551 // but we no longer allocate new heap objects. |
| 1619 Thread* thread = Thread::Current(); | 1552 Thread* thread = Thread::Current(); |
| 1620 StackZone stack_zone(thread); | 1553 StackZone stack_zone(thread); |
| 1621 HandleScope handle_scope(thread); | 1554 HandleScope handle_scope(thread); |
| 1622 NoSafepointScope no_safepoint_scope; | 1555 NoSafepointScope no_safepoint_scope; |
| 1623 | 1556 |
| 1624 // Notify exit listeners that this isolate is shutting down. | 1557 // Notify exit listeners that this isolate is shutting down. |
| 1625 if (object_store() != NULL) { | 1558 if (object_store() != NULL) { |
| 1626 const Error& error = Error::Handle(thread->sticky_error()); | 1559 const Error& error = Error::Handle(thread->sticky_error()); |
| 1627 if (error.IsNull() || !error.IsUnwindError() || | 1560 if (error.IsNull() || !error.IsUnwindError() || |
| 1628 UnwindError::Cast(error).is_user_initiated()) { | 1561 UnwindError::Cast(error).is_user_initiated()) { |
| 1629 NotifyExitListeners(); | 1562 NotifyExitListeners(); |
| 1630 } | 1563 } |
| 1631 } | 1564 } |
| 1632 | 1565 |
| 1633 // Clean up debugger resources. | 1566 // Clean up debugger resources. |
| 1634 if (FLAG_support_debugger) { | 1567 if (FLAG_support_debugger) { |
| 1635 debugger()->Shutdown(); | 1568 debugger()->Shutdown(); |
| 1636 } | 1569 } |
| 1637 | 1570 |
| 1638 | |
| 1639 // Close all the ports owned by this isolate. | 1571 // Close all the ports owned by this isolate. |
| 1640 PortMap::ClosePorts(message_handler()); | 1572 PortMap::ClosePorts(message_handler()); |
| 1641 | 1573 |
| 1642 // Fail fast if anybody tries to post any more messages to this isolate. | 1574 // Fail fast if anybody tries to post any more messages to this isolate. |
| 1643 delete message_handler(); | 1575 delete message_handler(); |
| 1644 set_message_handler(NULL); | 1576 set_message_handler(NULL); |
| 1645 if (FLAG_support_timeline) { | 1577 if (FLAG_support_timeline) { |
| 1646 // Before analyzing the isolate's timeline blocks- reclaim all cached | 1578 // Before analyzing the isolate's timeline blocks- reclaim all cached |
| 1647 // blocks. | 1579 // blocks. |
| 1648 Timeline::ReclaimCachedBlocksFromThreads(); | 1580 Timeline::ReclaimCachedBlocksFromThreads(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1677 LogBlock lb; | 1609 LogBlock lb; |
| 1678 OS::PrintErr("Printing metrics for %s\n", name()); | 1610 OS::PrintErr("Printing metrics for %s\n", name()); |
| 1679 #define ISOLATE_METRIC_PRINT(type, variable, name, unit) \ | 1611 #define ISOLATE_METRIC_PRINT(type, variable, name, unit) \ |
| 1680 OS::PrintErr("%s\n", metric_##variable##_.ToString()); | 1612 OS::PrintErr("%s\n", metric_##variable##_.ToString()); |
| 1681 ISOLATE_METRIC_LIST(ISOLATE_METRIC_PRINT) | 1613 ISOLATE_METRIC_LIST(ISOLATE_METRIC_PRINT) |
| 1682 #undef ISOLATE_METRIC_PRINT | 1614 #undef ISOLATE_METRIC_PRINT |
| 1683 OS::PrintErr("\n"); | 1615 OS::PrintErr("\n"); |
| 1684 } | 1616 } |
| 1685 } | 1617 } |
| 1686 | 1618 |
| 1687 | |
| 1688 void Isolate::StopBackgroundCompiler() { | 1619 void Isolate::StopBackgroundCompiler() { |
| 1689 // Wait until all background compilation has finished. | 1620 // Wait until all background compilation has finished. |
| 1690 if (background_compiler_ != NULL) { | 1621 if (background_compiler_ != NULL) { |
| 1691 BackgroundCompiler::Stop(this); | 1622 BackgroundCompiler::Stop(this); |
| 1692 } | 1623 } |
| 1693 } | 1624 } |
| 1694 | 1625 |
| 1695 | |
| 1696 void Isolate::MaybeIncreaseReloadEveryNStackOverflowChecks() { | 1626 void Isolate::MaybeIncreaseReloadEveryNStackOverflowChecks() { |
| 1697 if (FLAG_reload_every_back_off) { | 1627 if (FLAG_reload_every_back_off) { |
| 1698 if (reload_every_n_stack_overflow_checks_ < 5000) { | 1628 if (reload_every_n_stack_overflow_checks_ < 5000) { |
| 1699 reload_every_n_stack_overflow_checks_ += 99; | 1629 reload_every_n_stack_overflow_checks_ += 99; |
| 1700 } else { | 1630 } else { |
| 1701 reload_every_n_stack_overflow_checks_ *= 2; | 1631 reload_every_n_stack_overflow_checks_ *= 2; |
| 1702 } | 1632 } |
| 1703 // Cap the value. | 1633 // Cap the value. |
| 1704 if (reload_every_n_stack_overflow_checks_ > 1000000) { | 1634 if (reload_every_n_stack_overflow_checks_ > 1000000) { |
| 1705 reload_every_n_stack_overflow_checks_ = 1000000; | 1635 reload_every_n_stack_overflow_checks_ = 1000000; |
| 1706 } | 1636 } |
| 1707 } | 1637 } |
| 1708 } | 1638 } |
| 1709 | 1639 |
| 1710 | |
| 1711 void Isolate::Shutdown() { | 1640 void Isolate::Shutdown() { |
| 1712 ASSERT(this == Isolate::Current()); | 1641 ASSERT(this == Isolate::Current()); |
| 1713 StopBackgroundCompiler(); | 1642 StopBackgroundCompiler(); |
| 1714 | 1643 |
| 1715 #if defined(DEBUG) | 1644 #if defined(DEBUG) |
| 1716 if (heap_ != NULL && FLAG_verify_on_transition) { | 1645 if (heap_ != NULL && FLAG_verify_on_transition) { |
| 1717 // The VM isolate keeps all objects marked. | 1646 // The VM isolate keeps all objects marked. |
| 1718 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); | 1647 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); |
| 1719 } | 1648 } |
| 1720 #endif // DEBUG | 1649 #endif // DEBUG |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1776 // TODO(5411455): For now just make sure there are no current isolates | 1705 // TODO(5411455): For now just make sure there are no current isolates |
| 1777 // as we are shutting down the isolate. | 1706 // as we are shutting down the isolate. |
| 1778 Thread::ExitIsolate(); | 1707 Thread::ExitIsolate(); |
| 1779 | 1708 |
| 1780 Dart_IsolateCleanupCallback cleanup = Isolate::CleanupCallback(); | 1709 Dart_IsolateCleanupCallback cleanup = Isolate::CleanupCallback(); |
| 1781 if (cleanup != NULL) { | 1710 if (cleanup != NULL) { |
| 1782 cleanup(init_callback_data()); | 1711 cleanup(init_callback_data()); |
| 1783 } | 1712 } |
| 1784 } | 1713 } |
| 1785 | 1714 |
| 1786 | |
| 1787 Dart_IsolateCreateCallback Isolate::create_callback_ = NULL; | 1715 Dart_IsolateCreateCallback Isolate::create_callback_ = NULL; |
| 1788 Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL; | 1716 Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL; |
| 1789 Dart_IsolateCleanupCallback Isolate::cleanup_callback_ = NULL; | 1717 Dart_IsolateCleanupCallback Isolate::cleanup_callback_ = NULL; |
| 1790 | 1718 |
| 1791 Monitor* Isolate::isolates_list_monitor_ = NULL; | 1719 Monitor* Isolate::isolates_list_monitor_ = NULL; |
| 1792 Isolate* Isolate::isolates_list_head_ = NULL; | 1720 Isolate* Isolate::isolates_list_head_ = NULL; |
| 1793 bool Isolate::creation_enabled_ = false; | 1721 bool Isolate::creation_enabled_ = false; |
| 1794 | 1722 |
| 1795 void Isolate::IterateObjectPointers(ObjectPointerVisitor* visitor, | 1723 void Isolate::IterateObjectPointers(ObjectPointerVisitor* visitor, |
| 1796 bool validate_frames) { | 1724 bool validate_frames) { |
| 1797 HeapIterationScope heap_iteration_scope; | 1725 HeapIterationScope heap_iteration_scope; |
| 1798 VisitObjectPointers(visitor, validate_frames); | 1726 VisitObjectPointers(visitor, validate_frames); |
| 1799 } | 1727 } |
| 1800 | 1728 |
| 1801 | |
| 1802 void Isolate::IterateStackPointers(ObjectPointerVisitor* visitor, | 1729 void Isolate::IterateStackPointers(ObjectPointerVisitor* visitor, |
| 1803 bool validate_frames) { | 1730 bool validate_frames) { |
| 1804 HeapIterationScope heap_iteration_scope; | 1731 HeapIterationScope heap_iteration_scope; |
| 1805 VisitStackPointers(visitor, validate_frames); | 1732 VisitStackPointers(visitor, validate_frames); |
| 1806 } | 1733 } |
| 1807 | 1734 |
| 1808 | |
| 1809 void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, | 1735 void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, |
| 1810 bool validate_frames) { | 1736 bool validate_frames) { |
| 1811 ASSERT(visitor != NULL); | 1737 ASSERT(visitor != NULL); |
| 1812 | 1738 |
| 1813 // Visit objects in the object store. | 1739 // Visit objects in the object store. |
| 1814 object_store()->VisitObjectPointers(visitor); | 1740 object_store()->VisitObjectPointers(visitor); |
| 1815 | 1741 |
| 1816 // Visit objects in the class table. | 1742 // Visit objects in the class table. |
| 1817 class_table()->VisitObjectPointers(visitor); | 1743 class_table()->VisitObjectPointers(visitor); |
| 1818 | 1744 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1875 #if !defined(DART_PRECOMPILED_RUNTIME) | 1801 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 1876 // Visit objects that are being used for deoptimization. | 1802 // Visit objects that are being used for deoptimization. |
| 1877 if (deopt_context() != NULL) { | 1803 if (deopt_context() != NULL) { |
| 1878 deopt_context()->VisitObjectPointers(visitor); | 1804 deopt_context()->VisitObjectPointers(visitor); |
| 1879 } | 1805 } |
| 1880 #endif | 1806 #endif |
| 1881 | 1807 |
| 1882 VisitStackPointers(visitor, validate_frames); | 1808 VisitStackPointers(visitor, validate_frames); |
| 1883 } | 1809 } |
| 1884 | 1810 |
| 1885 | |
| 1886 void Isolate::VisitStackPointers(ObjectPointerVisitor* visitor, | 1811 void Isolate::VisitStackPointers(ObjectPointerVisitor* visitor, |
| 1887 bool validate_frames) { | 1812 bool validate_frames) { |
| 1888 // Visit objects in all threads (e.g., Dart stack, handles in zones). | 1813 // Visit objects in all threads (e.g., Dart stack, handles in zones). |
| 1889 thread_registry()->VisitObjectPointers(visitor, validate_frames); | 1814 thread_registry()->VisitObjectPointers(visitor, validate_frames); |
| 1890 } | 1815 } |
| 1891 | 1816 |
| 1892 | |
| 1893 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) { | 1817 void Isolate::VisitWeakPersistentHandles(HandleVisitor* visitor) { |
| 1894 if (api_state() != NULL) { | 1818 if (api_state() != NULL) { |
| 1895 api_state()->VisitWeakHandles(visitor); | 1819 api_state()->VisitWeakHandles(visitor); |
| 1896 } | 1820 } |
| 1897 } | 1821 } |
| 1898 | 1822 |
| 1899 | |
| 1900 void Isolate::PrepareForGC() { | 1823 void Isolate::PrepareForGC() { |
| 1901 thread_registry()->PrepareForGC(); | 1824 thread_registry()->PrepareForGC(); |
| 1902 } | 1825 } |
| 1903 | 1826 |
| 1904 | |
| 1905 RawClass* Isolate::GetClassForHeapWalkAt(intptr_t cid) { | 1827 RawClass* Isolate::GetClassForHeapWalkAt(intptr_t cid) { |
| 1906 RawClass* raw_class = NULL; | 1828 RawClass* raw_class = NULL; |
| 1907 #ifndef PRODUCT | 1829 #ifndef PRODUCT |
| 1908 if (IsReloading()) { | 1830 if (IsReloading()) { |
| 1909 raw_class = reload_context()->GetClassForHeapWalkAt(cid); | 1831 raw_class = reload_context()->GetClassForHeapWalkAt(cid); |
| 1910 } else { | 1832 } else { |
| 1911 raw_class = class_table()->At(cid); | 1833 raw_class = class_table()->At(cid); |
| 1912 } | 1834 } |
| 1913 #else | 1835 #else |
| 1914 raw_class = class_table()->At(cid); | 1836 raw_class = class_table()->At(cid); |
| 1915 #endif // !PRODUCT | 1837 #endif // !PRODUCT |
| 1916 ASSERT(raw_class != NULL); | 1838 ASSERT(raw_class != NULL); |
| 1917 ASSERT(remapping_cids_ || raw_class->ptr()->id_ == cid); | 1839 ASSERT(remapping_cids_ || raw_class->ptr()->id_ == cid); |
| 1918 return raw_class; | 1840 return raw_class; |
| 1919 } | 1841 } |
| 1920 | 1842 |
| 1921 | |
| 1922 void Isolate::AddPendingDeopt(uword fp, uword pc) { | 1843 void Isolate::AddPendingDeopt(uword fp, uword pc) { |
| 1923 // GrowableArray::Add is not atomic and may be interrupt by a profiler | 1844 // GrowableArray::Add is not atomic and may be interrupt by a profiler |
| 1924 // stack walk. | 1845 // stack walk. |
| 1925 MallocGrowableArray<PendingLazyDeopt>* old_pending_deopts = pending_deopts_; | 1846 MallocGrowableArray<PendingLazyDeopt>* old_pending_deopts = pending_deopts_; |
| 1926 MallocGrowableArray<PendingLazyDeopt>* new_pending_deopts = | 1847 MallocGrowableArray<PendingLazyDeopt>* new_pending_deopts = |
| 1927 new MallocGrowableArray<PendingLazyDeopt>(old_pending_deopts->length() + | 1848 new MallocGrowableArray<PendingLazyDeopt>(old_pending_deopts->length() + |
| 1928 1); | 1849 1); |
| 1929 for (intptr_t i = 0; i < old_pending_deopts->length(); i++) { | 1850 for (intptr_t i = 0; i < old_pending_deopts->length(); i++) { |
| 1930 ASSERT((*old_pending_deopts)[i].fp() != fp); | 1851 ASSERT((*old_pending_deopts)[i].fp() != fp); |
| 1931 new_pending_deopts->Add((*old_pending_deopts)[i]); | 1852 new_pending_deopts->Add((*old_pending_deopts)[i]); |
| 1932 } | 1853 } |
| 1933 PendingLazyDeopt deopt(fp, pc); | 1854 PendingLazyDeopt deopt(fp, pc); |
| 1934 new_pending_deopts->Add(deopt); | 1855 new_pending_deopts->Add(deopt); |
| 1935 | 1856 |
| 1936 pending_deopts_ = new_pending_deopts; | 1857 pending_deopts_ = new_pending_deopts; |
| 1937 delete old_pending_deopts; | 1858 delete old_pending_deopts; |
| 1938 } | 1859 } |
| 1939 | 1860 |
| 1940 | |
| 1941 uword Isolate::FindPendingDeopt(uword fp) const { | 1861 uword Isolate::FindPendingDeopt(uword fp) const { |
| 1942 for (intptr_t i = 0; i < pending_deopts_->length(); i++) { | 1862 for (intptr_t i = 0; i < pending_deopts_->length(); i++) { |
| 1943 if ((*pending_deopts_)[i].fp() == fp) { | 1863 if ((*pending_deopts_)[i].fp() == fp) { |
| 1944 return (*pending_deopts_)[i].pc(); | 1864 return (*pending_deopts_)[i].pc(); |
| 1945 } | 1865 } |
| 1946 } | 1866 } |
| 1947 FATAL("Missing pending deopt entry"); | 1867 FATAL("Missing pending deopt entry"); |
| 1948 return 0; | 1868 return 0; |
| 1949 } | 1869 } |
| 1950 | 1870 |
| 1951 | |
| 1952 void Isolate::ClearPendingDeoptsAtOrBelow(uword fp) const { | 1871 void Isolate::ClearPendingDeoptsAtOrBelow(uword fp) const { |
| 1953 for (intptr_t i = pending_deopts_->length() - 1; i >= 0; i--) { | 1872 for (intptr_t i = pending_deopts_->length() - 1; i >= 0; i--) { |
| 1954 if ((*pending_deopts_)[i].fp() <= fp) { | 1873 if ((*pending_deopts_)[i].fp() <= fp) { |
| 1955 pending_deopts_->RemoveAt(i); | 1874 pending_deopts_->RemoveAt(i); |
| 1956 } | 1875 } |
| 1957 } | 1876 } |
| 1958 } | 1877 } |
| 1959 | 1878 |
| 1960 | |
| 1961 #ifndef PRODUCT | 1879 #ifndef PRODUCT |
| 1962 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) { | 1880 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) { |
| 1963 switch (pi) { | 1881 switch (pi) { |
| 1964 case kPauseOnAllExceptions: | 1882 case kPauseOnAllExceptions: |
| 1965 return "All"; | 1883 return "All"; |
| 1966 case kNoPauseOnExceptions: | 1884 case kNoPauseOnExceptions: |
| 1967 return "None"; | 1885 return "None"; |
| 1968 case kPauseOnUnhandledExceptions: | 1886 case kPauseOnUnhandledExceptions: |
| 1969 return "Unhandled"; | 1887 return "Unhandled"; |
| 1970 default: | 1888 default: |
| 1971 UNIMPLEMENTED(); | 1889 UNIMPLEMENTED(); |
| 1972 return NULL; | 1890 return NULL; |
| 1973 } | 1891 } |
| 1974 } | 1892 } |
| 1975 | 1893 |
| 1976 | |
| 1977 void Isolate::PrintJSON(JSONStream* stream, bool ref) { | 1894 void Isolate::PrintJSON(JSONStream* stream, bool ref) { |
| 1978 if (!FLAG_support_service) { | 1895 if (!FLAG_support_service) { |
| 1979 return; | 1896 return; |
| 1980 } | 1897 } |
| 1981 JSONObject jsobj(stream); | 1898 JSONObject jsobj(stream); |
| 1982 jsobj.AddProperty("type", (ref ? "@Isolate" : "Isolate")); | 1899 jsobj.AddProperty("type", (ref ? "@Isolate" : "Isolate")); |
| 1983 jsobj.AddFixedServiceId(ISOLATE_SERVICE_ID_FORMAT_STRING, | 1900 jsobj.AddFixedServiceId(ISOLATE_SERVICE_ID_FORMAT_STRING, |
| 1984 static_cast<int64_t>(main_port())); | 1901 static_cast<int64_t>(main_port())); |
| 1985 | 1902 |
| 1986 jsobj.AddProperty("name", debugger_name()); | 1903 jsobj.AddProperty("name", debugger_name()); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2101 handler_name ^= handlers.At(i + kRegisteredNameIndex); | 2018 handler_name ^= handlers.At(i + kRegisteredNameIndex); |
| 2102 extensions.AddValue(handler_name.ToCString()); | 2019 extensions.AddValue(handler_name.ToCString()); |
| 2103 } | 2020 } |
| 2104 } | 2021 } |
| 2105 } | 2022 } |
| 2106 | 2023 |
| 2107 jsobj.AddProperty("_threads", thread_registry_); | 2024 jsobj.AddProperty("_threads", thread_registry_); |
| 2108 } | 2025 } |
| 2109 #endif | 2026 #endif |
| 2110 | 2027 |
| 2111 | |
| 2112 void Isolate::set_tag_table(const GrowableObjectArray& value) { | 2028 void Isolate::set_tag_table(const GrowableObjectArray& value) { |
| 2113 tag_table_ = value.raw(); | 2029 tag_table_ = value.raw(); |
| 2114 } | 2030 } |
| 2115 | 2031 |
| 2116 | |
| 2117 void Isolate::set_current_tag(const UserTag& tag) { | 2032 void Isolate::set_current_tag(const UserTag& tag) { |
| 2118 uword user_tag = tag.tag(); | 2033 uword user_tag = tag.tag(); |
| 2119 ASSERT(user_tag < kUwordMax); | 2034 ASSERT(user_tag < kUwordMax); |
| 2120 set_user_tag(user_tag); | 2035 set_user_tag(user_tag); |
| 2121 current_tag_ = tag.raw(); | 2036 current_tag_ = tag.raw(); |
| 2122 } | 2037 } |
| 2123 | 2038 |
| 2124 | |
| 2125 void Isolate::set_default_tag(const UserTag& tag) { | 2039 void Isolate::set_default_tag(const UserTag& tag) { |
| 2126 default_tag_ = tag.raw(); | 2040 default_tag_ = tag.raw(); |
| 2127 } | 2041 } |
| 2128 | 2042 |
| 2129 void Isolate::set_ic_miss_code(const Code& code) { | 2043 void Isolate::set_ic_miss_code(const Code& code) { |
| 2130 ic_miss_code_ = code.raw(); | 2044 ic_miss_code_ = code.raw(); |
| 2131 } | 2045 } |
| 2132 | 2046 |
| 2133 | |
| 2134 void Isolate::set_deoptimized_code_array(const GrowableObjectArray& value) { | 2047 void Isolate::set_deoptimized_code_array(const GrowableObjectArray& value) { |
| 2135 ASSERT(Thread::Current()->IsMutatorThread()); | 2048 ASSERT(Thread::Current()->IsMutatorThread()); |
| 2136 deoptimized_code_array_ = value.raw(); | 2049 deoptimized_code_array_ = value.raw(); |
| 2137 } | 2050 } |
| 2138 | 2051 |
| 2139 | |
| 2140 void Isolate::TrackDeoptimizedCode(const Code& code) { | 2052 void Isolate::TrackDeoptimizedCode(const Code& code) { |
| 2141 ASSERT(!code.IsNull()); | 2053 ASSERT(!code.IsNull()); |
| 2142 const GrowableObjectArray& deoptimized_code = | 2054 const GrowableObjectArray& deoptimized_code = |
| 2143 GrowableObjectArray::Handle(deoptimized_code_array()); | 2055 GrowableObjectArray::Handle(deoptimized_code_array()); |
| 2144 if (deoptimized_code.IsNull()) { | 2056 if (deoptimized_code.IsNull()) { |
| 2145 // Not tracking deoptimized code. | 2057 // Not tracking deoptimized code. |
| 2146 return; | 2058 return; |
| 2147 } | 2059 } |
| 2148 // TODO(johnmccutchan): Scan this array and the isolate's profile before | 2060 // TODO(johnmccutchan): Scan this array and the isolate's profile before |
| 2149 // old space GC and remove the keep_code flag. | 2061 // old space GC and remove the keep_code flag. |
| 2150 deoptimized_code.Add(code); | 2062 deoptimized_code.Add(code); |
| 2151 } | 2063 } |
| 2152 | 2064 |
| 2153 | |
| 2154 void Isolate::clear_sticky_error() { | 2065 void Isolate::clear_sticky_error() { |
| 2155 sticky_error_ = Error::null(); | 2066 sticky_error_ = Error::null(); |
| 2156 } | 2067 } |
| 2157 | 2068 |
| 2158 | |
| 2159 void Isolate::set_pending_service_extension_calls( | 2069 void Isolate::set_pending_service_extension_calls( |
| 2160 const GrowableObjectArray& value) { | 2070 const GrowableObjectArray& value) { |
| 2161 pending_service_extension_calls_ = value.raw(); | 2071 pending_service_extension_calls_ = value.raw(); |
| 2162 } | 2072 } |
| 2163 | 2073 |
| 2164 | |
| 2165 void Isolate::set_registered_service_extension_handlers( | 2074 void Isolate::set_registered_service_extension_handlers( |
| 2166 const GrowableObjectArray& value) { | 2075 const GrowableObjectArray& value) { |
| 2167 registered_service_extension_handlers_ = value.raw(); | 2076 registered_service_extension_handlers_ = value.raw(); |
| 2168 } | 2077 } |
| 2169 | 2078 |
| 2170 | |
| 2171 void Isolate::AddDeoptimizingBoxedField(const Field& field) { | 2079 void Isolate::AddDeoptimizingBoxedField(const Field& field) { |
| 2172 ASSERT(Compiler::IsBackgroundCompilation()); | 2080 ASSERT(Compiler::IsBackgroundCompilation()); |
| 2173 ASSERT(!field.IsOriginal()); | 2081 ASSERT(!field.IsOriginal()); |
| 2174 // The enclosed code allocates objects and can potentially trigger a GC, | 2082 // The enclosed code allocates objects and can potentially trigger a GC, |
| 2175 // ensure that we account for safepoints when grabbing the lock. | 2083 // ensure that we account for safepoints when grabbing the lock. |
| 2176 SafepointMutexLocker ml(field_list_mutex_); | 2084 SafepointMutexLocker ml(field_list_mutex_); |
| 2177 if (boxed_field_list_ == GrowableObjectArray::null()) { | 2085 if (boxed_field_list_ == GrowableObjectArray::null()) { |
| 2178 boxed_field_list_ = GrowableObjectArray::New(Heap::kOld); | 2086 boxed_field_list_ = GrowableObjectArray::New(Heap::kOld); |
| 2179 } | 2087 } |
| 2180 const GrowableObjectArray& array = | 2088 const GrowableObjectArray& array = |
| 2181 GrowableObjectArray::Handle(boxed_field_list_); | 2089 GrowableObjectArray::Handle(boxed_field_list_); |
| 2182 array.Add(Field::Handle(field.Original()), Heap::kOld); | 2090 array.Add(Field::Handle(field.Original()), Heap::kOld); |
| 2183 } | 2091 } |
| 2184 | 2092 |
| 2185 | |
| 2186 RawField* Isolate::GetDeoptimizingBoxedField() { | 2093 RawField* Isolate::GetDeoptimizingBoxedField() { |
| 2187 ASSERT(Thread::Current()->IsMutatorThread()); | 2094 ASSERT(Thread::Current()->IsMutatorThread()); |
| 2188 SafepointMutexLocker ml(field_list_mutex_); | 2095 SafepointMutexLocker ml(field_list_mutex_); |
| 2189 if (boxed_field_list_ == GrowableObjectArray::null()) { | 2096 if (boxed_field_list_ == GrowableObjectArray::null()) { |
| 2190 return Field::null(); | 2097 return Field::null(); |
| 2191 } | 2098 } |
| 2192 const GrowableObjectArray& array = | 2099 const GrowableObjectArray& array = |
| 2193 GrowableObjectArray::Handle(boxed_field_list_); | 2100 GrowableObjectArray::Handle(boxed_field_list_); |
| 2194 if (array.Length() == 0) { | 2101 if (array.Length() == 0) { |
| 2195 return Field::null(); | 2102 return Field::null(); |
| 2196 } | 2103 } |
| 2197 return Field::RawCast(array.RemoveLast()); | 2104 return Field::RawCast(array.RemoveLast()); |
| 2198 } | 2105 } |
| 2199 | 2106 |
| 2200 | |
| 2201 #ifndef PRODUCT | 2107 #ifndef PRODUCT |
| 2202 RawObject* Isolate::InvokePendingServiceExtensionCalls() { | 2108 RawObject* Isolate::InvokePendingServiceExtensionCalls() { |
| 2203 if (!FLAG_support_service) { | 2109 if (!FLAG_support_service) { |
| 2204 return Object::null(); | 2110 return Object::null(); |
| 2205 } | 2111 } |
| 2206 GrowableObjectArray& calls = | 2112 GrowableObjectArray& calls = |
| 2207 GrowableObjectArray::Handle(GetAndClearPendingServiceExtensionCalls()); | 2113 GrowableObjectArray::Handle(GetAndClearPendingServiceExtensionCalls()); |
| 2208 if (calls.IsNull()) { | 2114 if (calls.IsNull()) { |
| 2209 return Object::null(); | 2115 return Object::null(); |
| 2210 } | 2116 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2268 result = DartLibraryCalls::DrainMicrotaskQueue(); | 2174 result = DartLibraryCalls::DrainMicrotaskQueue(); |
| 2269 // Propagate the error. | 2175 // Propagate the error. |
| 2270 if (result.IsError()) { | 2176 if (result.IsError()) { |
| 2271 // Remaining service extension calls are dropped. | 2177 // Remaining service extension calls are dropped. |
| 2272 return result.raw(); | 2178 return result.raw(); |
| 2273 } | 2179 } |
| 2274 } | 2180 } |
| 2275 return Object::null(); | 2181 return Object::null(); |
| 2276 } | 2182 } |
| 2277 | 2183 |
| 2278 | |
| 2279 RawGrowableObjectArray* Isolate::GetAndClearPendingServiceExtensionCalls() { | 2184 RawGrowableObjectArray* Isolate::GetAndClearPendingServiceExtensionCalls() { |
| 2280 RawGrowableObjectArray* r = pending_service_extension_calls_; | 2185 RawGrowableObjectArray* r = pending_service_extension_calls_; |
| 2281 pending_service_extension_calls_ = GrowableObjectArray::null(); | 2186 pending_service_extension_calls_ = GrowableObjectArray::null(); |
| 2282 return r; | 2187 return r; |
| 2283 } | 2188 } |
| 2284 | 2189 |
| 2285 | |
| 2286 void Isolate::AppendServiceExtensionCall(const Instance& closure, | 2190 void Isolate::AppendServiceExtensionCall(const Instance& closure, |
| 2287 const String& method_name, | 2191 const String& method_name, |
| 2288 const Array& parameter_keys, | 2192 const Array& parameter_keys, |
| 2289 const Array& parameter_values, | 2193 const Array& parameter_values, |
| 2290 const Instance& reply_port, | 2194 const Instance& reply_port, |
| 2291 const Instance& id) { | 2195 const Instance& id) { |
| 2292 if (FLAG_trace_service) { | 2196 if (FLAG_trace_service) { |
| 2293 OS::Print("[+%" Pd64 "ms] Isolate %s ENQUEUING request for extension %s\n", | 2197 OS::Print("[+%" Pd64 "ms] Isolate %s ENQUEUING request for extension %s\n", |
| 2294 Dart::UptimeMillis(), name(), method_name.ToCString()); | 2198 Dart::UptimeMillis(), name(), method_name.ToCString()); |
| 2295 } | 2199 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2307 ASSERT(kPendingKeysIndex == 2); | 2211 ASSERT(kPendingKeysIndex == 2); |
| 2308 calls.Add(parameter_keys); | 2212 calls.Add(parameter_keys); |
| 2309 ASSERT(kPendingValuesIndex == 3); | 2213 ASSERT(kPendingValuesIndex == 3); |
| 2310 calls.Add(parameter_values); | 2214 calls.Add(parameter_values); |
| 2311 ASSERT(kPendingReplyPortIndex == 4); | 2215 ASSERT(kPendingReplyPortIndex == 4); |
| 2312 calls.Add(reply_port); | 2216 calls.Add(reply_port); |
| 2313 ASSERT(kPendingIdIndex == 5); | 2217 ASSERT(kPendingIdIndex == 5); |
| 2314 calls.Add(id); | 2218 calls.Add(id); |
| 2315 } | 2219 } |
| 2316 | 2220 |
| 2317 | |
| 2318 // This function is written in C++ and not Dart because we must do this | 2221 // This function is written in C++ and not Dart because we must do this |
| 2319 // operation atomically in the face of random OOB messages. Do not port | 2222 // operation atomically in the face of random OOB messages. Do not port |
| 2320 // to Dart code unless you can ensure that the operations will can be | 2223 // to Dart code unless you can ensure that the operations will can be |
| 2321 // done atomically. | 2224 // done atomically. |
| 2322 void Isolate::RegisterServiceExtensionHandler(const String& name, | 2225 void Isolate::RegisterServiceExtensionHandler(const String& name, |
| 2323 const Instance& closure) { | 2226 const Instance& closure) { |
| 2324 if (!FLAG_support_service) { | 2227 if (!FLAG_support_service) { |
| 2325 return; | 2228 return; |
| 2326 } | 2229 } |
| 2327 GrowableObjectArray& handlers = | 2230 GrowableObjectArray& handlers = |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2343 ASSERT(kRegisteredHandlerIndex == 1); | 2246 ASSERT(kRegisteredHandlerIndex == 1); |
| 2344 handlers.Add(closure, Heap::kOld); | 2247 handlers.Add(closure, Heap::kOld); |
| 2345 { | 2248 { |
| 2346 // Fire off an event. | 2249 // Fire off an event. |
| 2347 ServiceEvent event(this, ServiceEvent::kServiceExtensionAdded); | 2250 ServiceEvent event(this, ServiceEvent::kServiceExtensionAdded); |
| 2348 event.set_extension_rpc(&name); | 2251 event.set_extension_rpc(&name); |
| 2349 Service::HandleEvent(&event); | 2252 Service::HandleEvent(&event); |
| 2350 } | 2253 } |
| 2351 } | 2254 } |
| 2352 | 2255 |
| 2353 | |
| 2354 // This function is written in C++ and not Dart because we must do this | 2256 // This function is written in C++ and not Dart because we must do this |
| 2355 // operation atomically in the face of random OOB messages. Do not port | 2257 // operation atomically in the face of random OOB messages. Do not port |
| 2356 // to Dart code unless you can ensure that the operations will can be | 2258 // to Dart code unless you can ensure that the operations will can be |
| 2357 // done atomically. | 2259 // done atomically. |
| 2358 RawInstance* Isolate::LookupServiceExtensionHandler(const String& name) { | 2260 RawInstance* Isolate::LookupServiceExtensionHandler(const String& name) { |
| 2359 if (!FLAG_support_service) { | 2261 if (!FLAG_support_service) { |
| 2360 return Instance::null(); | 2262 return Instance::null(); |
| 2361 } | 2263 } |
| 2362 const GrowableObjectArray& handlers = | 2264 const GrowableObjectArray& handlers = |
| 2363 GrowableObjectArray::Handle(registered_service_extension_handlers()); | 2265 GrowableObjectArray::Handle(registered_service_extension_handlers()); |
| 2364 if (handlers.IsNull()) { | 2266 if (handlers.IsNull()) { |
| 2365 return Instance::null(); | 2267 return Instance::null(); |
| 2366 } | 2268 } |
| 2367 String& handler_name = String::Handle(); | 2269 String& handler_name = String::Handle(); |
| 2368 for (intptr_t i = 0; i < handlers.Length(); i += kRegisteredEntrySize) { | 2270 for (intptr_t i = 0; i < handlers.Length(); i += kRegisteredEntrySize) { |
| 2369 handler_name ^= handlers.At(i + kRegisteredNameIndex); | 2271 handler_name ^= handlers.At(i + kRegisteredNameIndex); |
| 2370 ASSERT(!handler_name.IsNull()); | 2272 ASSERT(!handler_name.IsNull()); |
| 2371 if (handler_name.Equals(name)) { | 2273 if (handler_name.Equals(name)) { |
| 2372 return Instance::RawCast(handlers.At(i + kRegisteredHandlerIndex)); | 2274 return Instance::RawCast(handlers.At(i + kRegisteredHandlerIndex)); |
| 2373 } | 2275 } |
| 2374 } | 2276 } |
| 2375 return Instance::null(); | 2277 return Instance::null(); |
| 2376 } | 2278 } |
| 2377 #endif // !PRODUCT | 2279 #endif // !PRODUCT |
| 2378 | 2280 |
| 2379 | |
| 2380 void Isolate::WakePauseEventHandler(Dart_Isolate isolate) { | 2281 void Isolate::WakePauseEventHandler(Dart_Isolate isolate) { |
| 2381 Isolate* iso = reinterpret_cast<Isolate*>(isolate); | 2282 Isolate* iso = reinterpret_cast<Isolate*>(isolate); |
| 2382 MonitorLocker ml(iso->pause_loop_monitor_); | 2283 MonitorLocker ml(iso->pause_loop_monitor_); |
| 2383 ml.Notify(); | 2284 ml.Notify(); |
| 2384 } | 2285 } |
| 2385 | 2286 |
| 2386 | |
| 2387 void Isolate::PauseEventHandler() { | 2287 void Isolate::PauseEventHandler() { |
| 2388 // We are stealing a pause event (like a breakpoint) from the | 2288 // We are stealing a pause event (like a breakpoint) from the |
| 2389 // embedder. We don't know what kind of thread we are on -- it | 2289 // embedder. We don't know what kind of thread we are on -- it |
| 2390 // could be from our thread pool or it could be a thread from the | 2290 // could be from our thread pool or it could be a thread from the |
| 2391 // embedder. Sit on the current thread handling service events | 2291 // embedder. Sit on the current thread handling service events |
| 2392 // until we are told to resume. | 2292 // until we are told to resume. |
| 2393 if (pause_loop_monitor_ == NULL) { | 2293 if (pause_loop_monitor_ == NULL) { |
| 2394 pause_loop_monitor_ = new Monitor(); | 2294 pause_loop_monitor_ = new Monitor(); |
| 2395 } | 2295 } |
| 2396 Dart_EnterScope(); | 2296 Dart_EnterScope(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2426 } | 2326 } |
| 2427 | 2327 |
| 2428 // Wait for more service messages. | 2328 // Wait for more service messages. |
| 2429 Monitor::WaitResult res = ml.Wait(); | 2329 Monitor::WaitResult res = ml.Wait(); |
| 2430 ASSERT(res == Monitor::kNotified); | 2330 ASSERT(res == Monitor::kNotified); |
| 2431 } | 2331 } |
| 2432 set_message_notify_callback(saved_notify_callback); | 2332 set_message_notify_callback(saved_notify_callback); |
| 2433 Dart_ExitScope(); | 2333 Dart_ExitScope(); |
| 2434 } | 2334 } |
| 2435 | 2335 |
| 2436 | |
| 2437 void Isolate::VisitIsolates(IsolateVisitor* visitor) { | 2336 void Isolate::VisitIsolates(IsolateVisitor* visitor) { |
| 2438 if (visitor == NULL) { | 2337 if (visitor == NULL) { |
| 2439 return; | 2338 return; |
| 2440 } | 2339 } |
| 2441 // The visitor could potentially run code that could safepoint so use | 2340 // The visitor could potentially run code that could safepoint so use |
| 2442 // SafepointMonitorLocker to ensure the lock has safepoint checks. | 2341 // SafepointMonitorLocker to ensure the lock has safepoint checks. |
| 2443 SafepointMonitorLocker ml(isolates_list_monitor_); | 2342 SafepointMonitorLocker ml(isolates_list_monitor_); |
| 2444 Isolate* current = isolates_list_head_; | 2343 Isolate* current = isolates_list_head_; |
| 2445 while (current) { | 2344 while (current) { |
| 2446 visitor->VisitIsolate(current); | 2345 visitor->VisitIsolate(current); |
| 2447 current = current->next_; | 2346 current = current->next_; |
| 2448 } | 2347 } |
| 2449 } | 2348 } |
| 2450 | 2349 |
| 2451 | |
| 2452 intptr_t Isolate::IsolateListLength() { | 2350 intptr_t Isolate::IsolateListLength() { |
| 2453 MonitorLocker ml(isolates_list_monitor_); | 2351 MonitorLocker ml(isolates_list_monitor_); |
| 2454 intptr_t count = 0; | 2352 intptr_t count = 0; |
| 2455 Isolate* current = isolates_list_head_; | 2353 Isolate* current = isolates_list_head_; |
| 2456 while (current != NULL) { | 2354 while (current != NULL) { |
| 2457 count++; | 2355 count++; |
| 2458 current = current->next_; | 2356 current = current->next_; |
| 2459 } | 2357 } |
| 2460 return count; | 2358 return count; |
| 2461 } | 2359 } |
| 2462 | 2360 |
| 2463 | |
| 2464 bool Isolate::AddIsolateToList(Isolate* isolate) { | 2361 bool Isolate::AddIsolateToList(Isolate* isolate) { |
| 2465 MonitorLocker ml(isolates_list_monitor_); | 2362 MonitorLocker ml(isolates_list_monitor_); |
| 2466 if (!creation_enabled_) { | 2363 if (!creation_enabled_) { |
| 2467 return false; | 2364 return false; |
| 2468 } | 2365 } |
| 2469 ASSERT(isolate != NULL); | 2366 ASSERT(isolate != NULL); |
| 2470 ASSERT(isolate->next_ == NULL); | 2367 ASSERT(isolate->next_ == NULL); |
| 2471 isolate->next_ = isolates_list_head_; | 2368 isolate->next_ = isolates_list_head_; |
| 2472 isolates_list_head_ = isolate; | 2369 isolates_list_head_ = isolate; |
| 2473 return true; | 2370 return true; |
| 2474 } | 2371 } |
| 2475 | 2372 |
| 2476 | |
| 2477 void Isolate::RemoveIsolateFromList(Isolate* isolate) { | 2373 void Isolate::RemoveIsolateFromList(Isolate* isolate) { |
| 2478 MonitorLocker ml(isolates_list_monitor_); | 2374 MonitorLocker ml(isolates_list_monitor_); |
| 2479 ASSERT(isolate != NULL); | 2375 ASSERT(isolate != NULL); |
| 2480 if (isolate == isolates_list_head_) { | 2376 if (isolate == isolates_list_head_) { |
| 2481 isolates_list_head_ = isolate->next_; | 2377 isolates_list_head_ = isolate->next_; |
| 2482 if (!creation_enabled_) { | 2378 if (!creation_enabled_) { |
| 2483 ml.Notify(); | 2379 ml.Notify(); |
| 2484 } | 2380 } |
| 2485 return; | 2381 return; |
| 2486 } | 2382 } |
| 2487 Isolate* previous = NULL; | 2383 Isolate* previous = NULL; |
| 2488 Isolate* current = isolates_list_head_; | 2384 Isolate* current = isolates_list_head_; |
| 2489 while (current) { | 2385 while (current) { |
| 2490 if (current == isolate) { | 2386 if (current == isolate) { |
| 2491 ASSERT(previous != NULL); | 2387 ASSERT(previous != NULL); |
| 2492 previous->next_ = current->next_; | 2388 previous->next_ = current->next_; |
| 2493 if (!creation_enabled_) { | 2389 if (!creation_enabled_) { |
| 2494 ml.Notify(); | 2390 ml.Notify(); |
| 2495 } | 2391 } |
| 2496 return; | 2392 return; |
| 2497 } | 2393 } |
| 2498 previous = current; | 2394 previous = current; |
| 2499 current = current->next_; | 2395 current = current->next_; |
| 2500 } | 2396 } |
| 2501 // If we are shutting down the VM, the isolate may not be in the list. | 2397 // If we are shutting down the VM, the isolate may not be in the list. |
| 2502 ASSERT(!creation_enabled_); | 2398 ASSERT(!creation_enabled_); |
| 2503 } | 2399 } |
| 2504 | 2400 |
| 2505 | |
| 2506 void Isolate::DisableIsolateCreation() { | 2401 void Isolate::DisableIsolateCreation() { |
| 2507 MonitorLocker ml(isolates_list_monitor_); | 2402 MonitorLocker ml(isolates_list_monitor_); |
| 2508 creation_enabled_ = false; | 2403 creation_enabled_ = false; |
| 2509 } | 2404 } |
| 2510 | 2405 |
| 2511 | |
| 2512 void Isolate::EnableIsolateCreation() { | 2406 void Isolate::EnableIsolateCreation() { |
| 2513 MonitorLocker ml(isolates_list_monitor_); | 2407 MonitorLocker ml(isolates_list_monitor_); |
| 2514 creation_enabled_ = true; | 2408 creation_enabled_ = true; |
| 2515 } | 2409 } |
| 2516 | 2410 |
| 2517 | |
| 2518 bool Isolate::IsolateCreationEnabled() { | 2411 bool Isolate::IsolateCreationEnabled() { |
| 2519 MonitorLocker ml(isolates_list_monitor_); | 2412 MonitorLocker ml(isolates_list_monitor_); |
| 2520 return creation_enabled_; | 2413 return creation_enabled_; |
| 2521 } | 2414 } |
| 2522 | 2415 |
| 2523 | |
| 2524 void Isolate::KillLocked(LibMsgId msg_id) { | 2416 void Isolate::KillLocked(LibMsgId msg_id) { |
| 2525 Dart_CObject kill_msg; | 2417 Dart_CObject kill_msg; |
| 2526 Dart_CObject* list_values[4]; | 2418 Dart_CObject* list_values[4]; |
| 2527 kill_msg.type = Dart_CObject_kArray; | 2419 kill_msg.type = Dart_CObject_kArray; |
| 2528 kill_msg.value.as_array.length = 4; | 2420 kill_msg.value.as_array.length = 4; |
| 2529 kill_msg.value.as_array.values = list_values; | 2421 kill_msg.value.as_array.values = list_values; |
| 2530 | 2422 |
| 2531 Dart_CObject oob; | 2423 Dart_CObject oob; |
| 2532 oob.type = Dart_CObject_kInt32; | 2424 oob.type = Dart_CObject_kInt32; |
| 2533 oob.value.as_int32 = Message::kIsolateLibOOBMsg; | 2425 oob.value.as_int32 = Message::kIsolateLibOOBMsg; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2554 bool success = writer.WriteCMessage(&kill_msg); | 2446 bool success = writer.WriteCMessage(&kill_msg); |
| 2555 ASSERT(success); | 2447 ASSERT(success); |
| 2556 | 2448 |
| 2557 // Post the message at the given port. | 2449 // Post the message at the given port. |
| 2558 success = PortMap::PostMessage(new Message( | 2450 success = PortMap::PostMessage(new Message( |
| 2559 main_port(), buffer, writer.BytesWritten(), Message::kOOBPriority)); | 2451 main_port(), buffer, writer.BytesWritten(), Message::kOOBPriority)); |
| 2560 ASSERT(success); | 2452 ASSERT(success); |
| 2561 } | 2453 } |
| 2562 } | 2454 } |
| 2563 | 2455 |
| 2564 | |
| 2565 class IsolateKillerVisitor : public IsolateVisitor { | 2456 class IsolateKillerVisitor : public IsolateVisitor { |
| 2566 public: | 2457 public: |
| 2567 explicit IsolateKillerVisitor(Isolate::LibMsgId msg_id) | 2458 explicit IsolateKillerVisitor(Isolate::LibMsgId msg_id) |
| 2568 : target_(NULL), msg_id_(msg_id) {} | 2459 : target_(NULL), msg_id_(msg_id) {} |
| 2569 | 2460 |
| 2570 IsolateKillerVisitor(Isolate* isolate, Isolate::LibMsgId msg_id) | 2461 IsolateKillerVisitor(Isolate* isolate, Isolate::LibMsgId msg_id) |
| 2571 : target_(isolate), msg_id_(msg_id) { | 2462 : target_(isolate), msg_id_(msg_id) { |
| 2572 ASSERT(isolate != Dart::vm_isolate()); | 2463 ASSERT(isolate != Dart::vm_isolate()); |
| 2573 } | 2464 } |
| 2574 | 2465 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2586 // If a target_ is specified, then only kill the target_. | 2477 // If a target_ is specified, then only kill the target_. |
| 2587 // Otherwise, don't kill the service isolate or vm isolate. | 2478 // Otherwise, don't kill the service isolate or vm isolate. |
| 2588 return (((target_ != NULL) && (isolate == target_)) || | 2479 return (((target_ != NULL) && (isolate == target_)) || |
| 2589 ((target_ == NULL) && !IsVMInternalIsolate(isolate))); | 2480 ((target_ == NULL) && !IsVMInternalIsolate(isolate))); |
| 2590 } | 2481 } |
| 2591 | 2482 |
| 2592 Isolate* target_; | 2483 Isolate* target_; |
| 2593 Isolate::LibMsgId msg_id_; | 2484 Isolate::LibMsgId msg_id_; |
| 2594 }; | 2485 }; |
| 2595 | 2486 |
| 2596 | |
| 2597 void Isolate::KillAllIsolates(LibMsgId msg_id) { | 2487 void Isolate::KillAllIsolates(LibMsgId msg_id) { |
| 2598 IsolateKillerVisitor visitor(msg_id); | 2488 IsolateKillerVisitor visitor(msg_id); |
| 2599 VisitIsolates(&visitor); | 2489 VisitIsolates(&visitor); |
| 2600 } | 2490 } |
| 2601 | 2491 |
| 2602 | |
| 2603 void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) { | 2492 void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) { |
| 2604 IsolateKillerVisitor visitor(isolate, msg_id); | 2493 IsolateKillerVisitor visitor(isolate, msg_id); |
| 2605 VisitIsolates(&visitor); | 2494 VisitIsolates(&visitor); |
| 2606 } | 2495 } |
| 2607 | 2496 |
| 2608 | |
| 2609 void Isolate::IncrementSpawnCount() { | 2497 void Isolate::IncrementSpawnCount() { |
| 2610 MonitorLocker ml(spawn_count_monitor_); | 2498 MonitorLocker ml(spawn_count_monitor_); |
| 2611 spawn_count_++; | 2499 spawn_count_++; |
| 2612 } | 2500 } |
| 2613 | 2501 |
| 2614 | |
| 2615 void Isolate::WaitForOutstandingSpawns() { | 2502 void Isolate::WaitForOutstandingSpawns() { |
| 2616 MonitorLocker ml(spawn_count_monitor_); | 2503 MonitorLocker ml(spawn_count_monitor_); |
| 2617 while (spawn_count_ > 0) { | 2504 while (spawn_count_ > 0) { |
| 2618 ml.Wait(); | 2505 ml.Wait(); |
| 2619 } | 2506 } |
| 2620 } | 2507 } |
| 2621 | 2508 |
| 2622 | |
| 2623 Monitor* Isolate::threads_lock() const { | 2509 Monitor* Isolate::threads_lock() const { |
| 2624 return thread_registry_->threads_lock(); | 2510 return thread_registry_->threads_lock(); |
| 2625 } | 2511 } |
| 2626 | 2512 |
| 2627 | |
| 2628 Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) { | 2513 Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) { |
| 2629 // Schedule the thread into the isolate by associating | 2514 // Schedule the thread into the isolate by associating |
| 2630 // a 'Thread' structure with it (this is done while we are holding | 2515 // a 'Thread' structure with it (this is done while we are holding |
| 2631 // the thread registry lock). | 2516 // the thread registry lock). |
| 2632 Thread* thread = NULL; | 2517 Thread* thread = NULL; |
| 2633 OSThread* os_thread = OSThread::Current(); | 2518 OSThread* os_thread = OSThread::Current(); |
| 2634 if (os_thread != NULL) { | 2519 if (os_thread != NULL) { |
| 2635 // We are about to associate the thread with an isolate and it would | 2520 // We are about to associate the thread with an isolate and it would |
| 2636 // not be possible to correctly track no_safepoint_scope_depth for the | 2521 // not be possible to correctly track no_safepoint_scope_depth for the |
| 2637 // thread in the constructor/destructor of MonitorLocker, | 2522 // thread in the constructor/destructor of MonitorLocker, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2669 os_thread->set_thread(thread); | 2554 os_thread->set_thread(thread); |
| 2670 if (is_mutator) { | 2555 if (is_mutator) { |
| 2671 mutator_thread_ = thread; | 2556 mutator_thread_ = thread; |
| 2672 } | 2557 } |
| 2673 Thread::SetCurrent(thread); | 2558 Thread::SetCurrent(thread); |
| 2674 os_thread->EnableThreadInterrupts(); | 2559 os_thread->EnableThreadInterrupts(); |
| 2675 } | 2560 } |
| 2676 return thread; | 2561 return thread; |
| 2677 } | 2562 } |
| 2678 | 2563 |
| 2679 | |
| 2680 void Isolate::UnscheduleThread(Thread* thread, | 2564 void Isolate::UnscheduleThread(Thread* thread, |
| 2681 bool is_mutator, | 2565 bool is_mutator, |
| 2682 bool bypass_safepoint) { | 2566 bool bypass_safepoint) { |
| 2683 // Disassociate the 'Thread' structure and unschedule the thread | 2567 // Disassociate the 'Thread' structure and unschedule the thread |
| 2684 // from this isolate. | 2568 // from this isolate. |
| 2685 // We are disassociating the thread from an isolate and it would | 2569 // We are disassociating the thread from an isolate and it would |
| 2686 // not be possible to correctly track no_safepoint_scope_depth for the | 2570 // not be possible to correctly track no_safepoint_scope_depth for the |
| 2687 // thread in the constructor/destructor of MonitorLocker, | 2571 // thread in the constructor/destructor of MonitorLocker, |
| 2688 // so we create a MonitorLocker object which does not do any | 2572 // so we create a MonitorLocker object which does not do any |
| 2689 // no_safepoint_scope_depth increments/decrements. | 2573 // no_safepoint_scope_depth increments/decrements. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2714 thread->heap_ = NULL; | 2598 thread->heap_ = NULL; |
| 2715 thread->set_os_thread(NULL); | 2599 thread->set_os_thread(NULL); |
| 2716 thread->set_execution_state(Thread::kThreadInNative); | 2600 thread->set_execution_state(Thread::kThreadInNative); |
| 2717 thread->set_safepoint_state(Thread::SetAtSafepoint(true, 0)); | 2601 thread->set_safepoint_state(Thread::SetAtSafepoint(true, 0)); |
| 2718 thread->clear_pending_functions(); | 2602 thread->clear_pending_functions(); |
| 2719 ASSERT(thread->no_safepoint_scope_depth() == 0); | 2603 ASSERT(thread->no_safepoint_scope_depth() == 0); |
| 2720 // Return thread structure. | 2604 // Return thread structure. |
| 2721 thread_registry()->ReturnThreadLocked(is_mutator, thread); | 2605 thread_registry()->ReturnThreadLocked(is_mutator, thread); |
| 2722 } | 2606 } |
| 2723 | 2607 |
| 2724 | |
| 2725 static RawInstance* DeserializeObject(Thread* thread, | 2608 static RawInstance* DeserializeObject(Thread* thread, |
| 2726 uint8_t* obj_data, | 2609 uint8_t* obj_data, |
| 2727 intptr_t obj_len) { | 2610 intptr_t obj_len) { |
| 2728 if (obj_data == NULL) { | 2611 if (obj_data == NULL) { |
| 2729 return Instance::null(); | 2612 return Instance::null(); |
| 2730 } | 2613 } |
| 2731 MessageSnapshotReader reader(obj_data, obj_len, thread); | 2614 MessageSnapshotReader reader(obj_data, obj_len, thread); |
| 2732 Zone* zone = thread->zone(); | 2615 Zone* zone = thread->zone(); |
| 2733 const Object& obj = Object::Handle(zone, reader.ReadObject()); | 2616 const Object& obj = Object::Handle(zone, reader.ReadObject()); |
| 2734 ASSERT(!obj.IsError()); | 2617 ASSERT(!obj.IsError()); |
| 2735 Instance& instance = Instance::Handle(zone); | 2618 Instance& instance = Instance::Handle(zone); |
| 2736 instance ^= obj.raw(); // Can't use Instance::Cast because may be null. | 2619 instance ^= obj.raw(); // Can't use Instance::Cast because may be null. |
| 2737 return instance.raw(); | 2620 return instance.raw(); |
| 2738 } | 2621 } |
| 2739 | 2622 |
| 2740 | |
| 2741 static const char* NewConstChar(const char* chars) { | 2623 static const char* NewConstChar(const char* chars) { |
| 2742 size_t len = strlen(chars); | 2624 size_t len = strlen(chars); |
| 2743 char* mem = new char[len + 1]; | 2625 char* mem = new char[len + 1]; |
| 2744 memmove(mem, chars, len + 1); | 2626 memmove(mem, chars, len + 1); |
| 2745 return mem; | 2627 return mem; |
| 2746 } | 2628 } |
| 2747 | 2629 |
| 2748 | |
| 2749 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, | 2630 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
| 2750 Dart_Port origin_id, | 2631 Dart_Port origin_id, |
| 2751 void* init_data, | 2632 void* init_data, |
| 2752 const char* script_url, | 2633 const char* script_url, |
| 2753 const Function& func, | 2634 const Function& func, |
| 2754 SerializedObjectBuffer* message_buffer, | 2635 SerializedObjectBuffer* message_buffer, |
| 2755 Monitor* spawn_count_monitor, | 2636 Monitor* spawn_count_monitor, |
| 2756 intptr_t* spawn_count, | 2637 intptr_t* spawn_count, |
| 2757 const char* package_root, | 2638 const char* package_root, |
| 2758 const char* package_config, | 2639 const char* package_config, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2792 if (!cls.IsTopLevel()) { | 2673 if (!cls.IsTopLevel()) { |
| 2793 const String& class_name = String::Handle(cls.Name()); | 2674 const String& class_name = String::Handle(cls.Name()); |
| 2794 class_name_ = NewConstChar(class_name.ToCString()); | 2675 class_name_ = NewConstChar(class_name.ToCString()); |
| 2795 } | 2676 } |
| 2796 message_buffer->StealBuffer(&serialized_message_, &serialized_message_len_); | 2677 message_buffer->StealBuffer(&serialized_message_, &serialized_message_len_); |
| 2797 | 2678 |
| 2798 // Inherit flags from spawning isolate. | 2679 // Inherit flags from spawning isolate. |
| 2799 Isolate::Current()->FlagsCopyTo(isolate_flags()); | 2680 Isolate::Current()->FlagsCopyTo(isolate_flags()); |
| 2800 } | 2681 } |
| 2801 | 2682 |
| 2802 | |
| 2803 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, | 2683 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
| 2804 void* init_data, | 2684 void* init_data, |
| 2805 const char* script_url, | 2685 const char* script_url, |
| 2806 const char* package_root, | 2686 const char* package_root, |
| 2807 const char* package_config, | 2687 const char* package_config, |
| 2808 SerializedObjectBuffer* args_buffer, | 2688 SerializedObjectBuffer* args_buffer, |
| 2809 SerializedObjectBuffer* message_buffer, | 2689 SerializedObjectBuffer* message_buffer, |
| 2810 Monitor* spawn_count_monitor, | 2690 Monitor* spawn_count_monitor, |
| 2811 intptr_t* spawn_count, | 2691 intptr_t* spawn_count, |
| 2812 bool paused, | 2692 bool paused, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2836 errors_are_fatal_(errors_are_fatal) { | 2716 errors_are_fatal_(errors_are_fatal) { |
| 2837 function_name_ = NewConstChar("main"); | 2717 function_name_ = NewConstChar("main"); |
| 2838 args_buffer->StealBuffer(&serialized_args_, &serialized_args_len_); | 2718 args_buffer->StealBuffer(&serialized_args_, &serialized_args_len_); |
| 2839 message_buffer->StealBuffer(&serialized_message_, &serialized_message_len_); | 2719 message_buffer->StealBuffer(&serialized_message_, &serialized_message_len_); |
| 2840 | 2720 |
| 2841 // By default inherit flags from spawning isolate. These can be overridden | 2721 // By default inherit flags from spawning isolate. These can be overridden |
| 2842 // from the calling code. | 2722 // from the calling code. |
| 2843 Isolate::Current()->FlagsCopyTo(isolate_flags()); | 2723 Isolate::Current()->FlagsCopyTo(isolate_flags()); |
| 2844 } | 2724 } |
| 2845 | 2725 |
| 2846 | |
| 2847 IsolateSpawnState::~IsolateSpawnState() { | 2726 IsolateSpawnState::~IsolateSpawnState() { |
| 2848 delete[] script_url_; | 2727 delete[] script_url_; |
| 2849 delete[] package_root_; | 2728 delete[] package_root_; |
| 2850 delete[] package_config_; | 2729 delete[] package_config_; |
| 2851 delete[] library_url_; | 2730 delete[] library_url_; |
| 2852 delete[] class_name_; | 2731 delete[] class_name_; |
| 2853 delete[] function_name_; | 2732 delete[] function_name_; |
| 2854 free(serialized_args_); | 2733 free(serialized_args_); |
| 2855 free(serialized_message_); | 2734 free(serialized_message_); |
| 2856 } | 2735 } |
| 2857 | 2736 |
| 2858 | |
| 2859 RawObject* IsolateSpawnState::ResolveFunction() { | 2737 RawObject* IsolateSpawnState::ResolveFunction() { |
| 2860 Thread* thread = Thread::Current(); | 2738 Thread* thread = Thread::Current(); |
| 2861 Zone* zone = thread->zone(); | 2739 Zone* zone = thread->zone(); |
| 2862 | 2740 |
| 2863 const String& func_name = String::Handle(zone, String::New(function_name())); | 2741 const String& func_name = String::Handle(zone, String::New(function_name())); |
| 2864 | 2742 |
| 2865 if (library_url() == NULL) { | 2743 if (library_url() == NULL) { |
| 2866 // Handle spawnUri lookup rules. | 2744 // Handle spawnUri lookup rules. |
| 2867 // Check whether the root library defines a main function. | 2745 // Check whether the root library defines a main function. |
| 2868 const Library& lib = | 2746 const Library& lib = |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2926 const String& msg = String::Handle( | 2804 const String& msg = String::Handle( |
| 2927 zone, String::NewFormatted( | 2805 zone, String::NewFormatted( |
| 2928 "Unable to resolve static method '%s.%s' in library '%s'.", | 2806 "Unable to resolve static method '%s.%s' in library '%s'.", |
| 2929 class_name(), function_name(), | 2807 class_name(), function_name(), |
| 2930 (library_url() != NULL ? library_url() : script_url()))); | 2808 (library_url() != NULL ? library_url() : script_url()))); |
| 2931 return LanguageError::New(msg); | 2809 return LanguageError::New(msg); |
| 2932 } | 2810 } |
| 2933 return func.raw(); | 2811 return func.raw(); |
| 2934 } | 2812 } |
| 2935 | 2813 |
| 2936 | |
| 2937 RawInstance* IsolateSpawnState::BuildArgs(Thread* thread) { | 2814 RawInstance* IsolateSpawnState::BuildArgs(Thread* thread) { |
| 2938 return DeserializeObject(thread, serialized_args_, serialized_args_len_); | 2815 return DeserializeObject(thread, serialized_args_, serialized_args_len_); |
| 2939 } | 2816 } |
| 2940 | 2817 |
| 2941 | |
| 2942 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { | 2818 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { |
| 2943 return DeserializeObject(thread, serialized_message_, | 2819 return DeserializeObject(thread, serialized_message_, |
| 2944 serialized_message_len_); | 2820 serialized_message_len_); |
| 2945 } | 2821 } |
| 2946 | 2822 |
| 2947 | |
| 2948 void IsolateSpawnState::DecrementSpawnCount() { | 2823 void IsolateSpawnState::DecrementSpawnCount() { |
| 2949 ASSERT(spawn_count_monitor_ != NULL); | 2824 ASSERT(spawn_count_monitor_ != NULL); |
| 2950 ASSERT(spawn_count_ != NULL); | 2825 ASSERT(spawn_count_ != NULL); |
| 2951 MonitorLocker ml(spawn_count_monitor_); | 2826 MonitorLocker ml(spawn_count_monitor_); |
| 2952 ASSERT(*spawn_count_ > 0); | 2827 ASSERT(*spawn_count_ > 0); |
| 2953 *spawn_count_ = *spawn_count_ - 1; | 2828 *spawn_count_ = *spawn_count_ - 1; |
| 2954 ml.Notify(); | 2829 ml.Notify(); |
| 2955 } | 2830 } |
| 2956 | 2831 |
| 2957 } // namespace dart | 2832 } // namespace dart |
| OLD | NEW |