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 |