Flutter Engine
The Flutter Engine
isolate.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include <utility>
6
7#include "vm/isolate.h"
8
9#include "include/dart_api.h"
11#include "platform/assert.h"
12#include "platform/atomic.h"
14#include "vm/canonical_tables.h"
15#include "vm/class_finalizer.h"
16#include "vm/code_observers.h"
18#include "vm/dart_api_message.h"
19#include "vm/dart_api_state.h"
20#include "vm/dart_entry.h"
21#include "vm/debugger.h"
23#include "vm/dispatch_table.h"
25#include "vm/flags.h"
26#include "vm/heap/heap.h"
28#include "vm/heap/safepoint.h"
29#include "vm/heap/verifier.h"
30#include "vm/image_snapshot.h"
31#include "vm/isolate_reload.h"
32#include "vm/kernel_isolate.h"
33#include "vm/lockers.h"
34#include "vm/log.h"
35#include "vm/message_handler.h"
36#include "vm/message_snapshot.h"
37#include "vm/object.h"
38#include "vm/object_id_ring.h"
39#include "vm/object_store.h"
40#include "vm/os_thread.h"
41#include "vm/port.h"
42#include "vm/profiler.h"
43#include "vm/reusable_handles.h"
45#include "vm/service.h"
46#include "vm/service_event.h"
47#include "vm/service_isolate.h"
48#include "vm/simulator.h"
49#include "vm/stack_frame.h"
50#include "vm/stub_code.h"
51#include "vm/symbols.h"
52#include "vm/tags.h"
53#include "vm/thread.h"
55#include "vm/thread_registry.h"
56#include "vm/timeline.h"
57#include "vm/visitor.h"
58
59#if !defined(DART_PRECOMPILED_RUNTIME)
62#endif
63
64namespace dart {
65
66DECLARE_FLAG(bool, print_metrics);
67DECLARE_FLAG(bool, trace_service);
68DECLARE_FLAG(bool, trace_shutdown);
69DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
70DECLARE_FLAG(int, old_gen_growth_time_ratio);
71
72// Reload flags.
73DECLARE_FLAG(int, reload_every);
74#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
75DECLARE_FLAG(bool, check_reloaded);
76DECLARE_FLAG(bool, reload_every_back_off);
77DECLARE_FLAG(bool, trace_reload);
78#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
79
81 if (value) {
82 FLAG_background_compilation = false; // Timing dependent.
83 FLAG_concurrent_mark = false; // Timing dependent.
84 FLAG_concurrent_sweep = false; // Timing dependent.
85 FLAG_scavenger_tasks = 0; // Timing dependent.
86 FLAG_old_gen_growth_time_ratio = 0; // Timing dependent.
87 FLAG_random_seed = 0x44617274; // "Dart"
88 }
89}
90
92 deterministic,
93 "Enable deterministic mode.");
94
96 disable_thread_pool_limit,
97 false,
98 "Disables the limit of the thread pool (simulates custom embedder "
99 "with custom message handler on unlimited number of threads).");
100
101// Quick access to the locally defined thread() and isolate() methods.
102#define T (thread())
103#define I (isolate())
104#define IG (isolate_group())
105
106#if defined(DEBUG)
107// Helper class to ensure that a live origin_id is never reused
108// and assigned to an isolate.
109class VerifyOriginId : public IsolateVisitor {
110 public:
111 explicit VerifyOriginId(Dart_Port id) : id_(id) {}
112
113 void VisitIsolate(Isolate* isolate) { ASSERT(isolate->origin_id() != id_); }
114
115 private:
116 Dart_Port id_;
117 DISALLOW_COPY_AND_ASSIGN(VerifyOriginId);
118};
119#endif
120
121static std::unique_ptr<Message> SerializeMessage(Dart_Port dest_port,
122 const Instance& obj) {
123 return WriteMessage(/* same_group */ false, obj, dest_port,
125}
126
127static std::unique_ptr<Message> SerializeMessage(Zone* zone,
128 Dart_Port dest_port,
129 Dart_CObject* obj) {
130 return WriteApiMessage(zone, obj, dest_port, Message::kNormalPriority);
131}
132
134 Zone* zone,
135 const ExternalTypedData& external_typed_data) {
136 Array& loaded_blobs = Array::Handle();
137 bool saved_external_typed_data = false;
138 if (loaded_blobs_ != nullptr) {
139 loaded_blobs = loaded_blobs_;
140
141 // Walk the array, and (if stuff was removed) compact and reuse the space.
142 // Note that the space has to be compacted as the ordering is important.
143 WeakProperty& weak_property = WeakProperty::Handle();
144 WeakProperty& weak_property_tmp = WeakProperty::Handle();
145 ExternalTypedData& existing_entry = ExternalTypedData::Handle(zone);
146 intptr_t next_entry_index = 0;
147 for (intptr_t i = 0; i < loaded_blobs.Length(); i++) {
148 weak_property ^= loaded_blobs.At(i);
149 if (weak_property.key() != ExternalTypedData::null()) {
150 if (i != next_entry_index) {
151 existing_entry = ExternalTypedData::RawCast(weak_property.key());
152 weak_property_tmp ^= loaded_blobs.At(next_entry_index);
153 weak_property_tmp.set_key(existing_entry);
154 }
155 next_entry_index++;
156 }
157 }
158 if (next_entry_index < loaded_blobs.Length()) {
159 // There's now space to re-use.
160 weak_property ^= loaded_blobs.At(next_entry_index);
161 weak_property.set_key(external_typed_data);
162 next_entry_index++;
163 saved_external_typed_data = true;
164 }
165 if (next_entry_index < loaded_blobs.Length()) {
166 ExternalTypedData& nullExternalTypedData =
168 while (next_entry_index < loaded_blobs.Length()) {
169 // Null out any extra spaces.
170 weak_property ^= loaded_blobs.At(next_entry_index);
171 weak_property.set_key(nullExternalTypedData);
172 next_entry_index++;
173 }
174 }
175 }
176 if (!saved_external_typed_data) {
177 const WeakProperty& weak_property =
179 weak_property.set_key(external_typed_data);
180
181 intptr_t length = loaded_blobs.IsNull() ? 0 : loaded_blobs.Length();
182 Array& new_array =
183 Array::Handle(Array::Grow(loaded_blobs, length + 1, Heap::kOld));
184 new_array.SetAt(length, weak_property);
185 loaded_blobs_ = new_array.ptr();
186 }
188}
189
191 MutexLocker ml(&mutex_);
192 ASSERT(heap_ == nullptr && heap != nullptr);
193 heap_ = heap;
194}
195
197 MutexLocker ml(&mutex_);
198 return idle_start_time_ > 0 && FLAG_idle_timeout_micros != 0 &&
199 disabled_counter_ == 0;
200}
201
203 MutexLocker ml(&mutex_);
204 if (disabled_counter_ == 0) {
205 idle_start_time_ = OS::GetCurrentMonotonicMicros();
206 }
207}
208
210 const int64_t now = OS::GetCurrentMonotonicMicros();
211
212 MutexLocker ml(&mutex_);
213 if (idle_start_time_ > 0 && disabled_counter_ == 0) {
214 const int64_t expiry_time = idle_start_time_ + FLAG_idle_timeout_micros;
215 if (expiry_time < now) {
216 idle_start_time_ = 0;
217 return true;
218 }
219 }
220
221 *expiry = now + FLAG_idle_timeout_micros;
222 return false;
223}
224
225void IdleTimeHandler::NotifyIdle(int64_t deadline) {
226 {
227 MutexLocker ml(&mutex_);
228 disabled_counter_++;
229 }
230 if (heap_ != nullptr) {
231 heap_->NotifyIdle(deadline);
232 }
233 {
234 MutexLocker ml(&mutex_);
235 disabled_counter_--;
236 idle_start_time_ = 0;
237 }
238}
239
241 const int64_t now = OS::GetCurrentMonotonicMicros();
242 NotifyIdle(now + FLAG_idle_duration_micros);
243}
244
246 : handler_(handler) {
247 if (handler_ != nullptr) {
248 MutexLocker ml(&handler_->mutex_);
249 ++handler_->disabled_counter_;
250 handler_->idle_start_time_ = 0;
251 }
252}
253
255 if (handler_ != nullptr) {
256 MutexLocker ml(&handler_->mutex_);
257 --handler_->disabled_counter_;
258 ASSERT(handler_->disabled_counter_ >= 0);
259 }
260}
261
263 public:
265 : HandleVisitor(Thread::Current()), isolate_group_(isolate_group) {}
266
267 void VisitHandle(uword addr) override {
268 auto handle = reinterpret_cast<FinalizablePersistentHandle*>(addr);
269 handle->UpdateUnreachable(isolate_group_);
270 }
271
272 private:
273 IsolateGroup* isolate_group_;
274
275 DISALLOW_COPY_AND_ASSIGN(FinalizeWeakPersistentHandlesVisitor);
276};
277
279 if (FLAG_idle_timeout_micros == 0) return;
280
281 // If the isolate has not started running application code yet, we ignore the
282 // idle time.
283 if (!isolate_group_->initial_spawn_successful()) return;
284
285 int64_t idle_expiry = 0;
286 // Obtain the idle time we should wait.
287 if (isolate_group_->idle_time_handler()->ShouldNotifyIdle(&idle_expiry)) {
288 MonitorLeaveScope mls(ml);
289 NotifyIdle();
290 return;
291 }
292
293 // Avoid shutdown having to wait for the timeout to expire.
294 if (ShuttingDownLocked()) return;
295
296 // Wait for the recommended idle timeout.
297 // We can be woken up because of a), b) or c)
298 const auto result =
299 ml->WaitMicros(idle_expiry - OS::GetCurrentMonotonicMicros());
300
301 // a) If there are new tasks we have to run them.
302 if (TasksWaitingToRunLocked()) return;
303
304 // b) If the thread pool is shutting down we're done.
305 if (ShuttingDownLocked()) return;
306
307 // c) We timed out and should run the idle notifier.
308 if (result == Monitor::kTimedOut &&
309 isolate_group_->idle_time_handler()->ShouldNotifyIdle(&idle_expiry)) {
310 MonitorLeaveScope mls(ml);
311 NotifyIdle();
312 return;
313 }
314
315 // There must've been another thread doing active work in the meantime.
316 // If that thread becomes idle and is the last idle thread it will run this
317 // code again.
318}
319
320void MutatorThreadPool::NotifyIdle() {
321 EnterIsolateGroupScope isolate_group_scope(isolate_group_);
323}
324
325IsolateGroup::IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
326 void* embedder_data,
327 ObjectStore* object_store,
328 Dart_IsolateFlags api_flags,
329 bool is_vm_isolate)
330 : class_table_(nullptr),
331 cached_class_table_table_(nullptr),
332 object_store_(object_store),
333 class_table_allocator_(),
334 is_vm_isolate_(is_vm_isolate),
335 embedder_data_(embedder_data),
336 thread_pool_(),
337 isolates_lock_(new SafepointRwLock()),
338 isolates_(),
339 start_time_micros_(OS::GetCurrentMonotonicMicros()),
340 is_system_isolate_group_(source->flags.is_system_isolate),
341 random_(),
342#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
343 last_reload_timestamp_(OS::GetCurrentTimeMillis()),
344 reload_every_n_stack_overflow_checks_(FLAG_reload_every),
345#endif
346 source_(std::move(source)),
347 api_state_(new ApiState()),
348 thread_registry_(new ThreadRegistry()),
349 safepoint_handler_(new SafepointHandler(this)),
350 store_buffer_(new StoreBuffer()),
351 heap_(nullptr),
352 saved_unlinked_calls_(Array::null()),
353 initial_field_table_(new FieldTable(/*isolate=*/nullptr)),
354 shared_initial_field_table_(new FieldTable(/*isolate=*/nullptr,
355 /*isolate_group=*/nullptr)),
356 shared_field_table_(new FieldTable(/*isolate=*/nullptr, this)),
357#if !defined(DART_PRECOMPILED_RUNTIME)
358 background_compiler_(new BackgroundCompiler(this)),
359#endif
360 symbols_mutex_(NOT_IN_PRODUCT("IsolateGroup::symbols_mutex_")),
361 type_canonicalization_mutex_(
362 NOT_IN_PRODUCT("IsolateGroup::type_canonicalization_mutex_")),
363 type_arguments_canonicalization_mutex_(NOT_IN_PRODUCT(
364 "IsolateGroup::type_arguments_canonicalization_mutex_")),
365 subtype_test_cache_mutex_(
366 NOT_IN_PRODUCT("IsolateGroup::subtype_test_cache_mutex_")),
367 megamorphic_table_mutex_(
368 NOT_IN_PRODUCT("IsolateGroup::megamorphic_table_mutex_")),
369 type_feedback_mutex_(
370 NOT_IN_PRODUCT("IsolateGroup::type_feedback_mutex_")),
371 patchable_call_mutex_(
372 NOT_IN_PRODUCT("IsolateGroup::patchable_call_mutex_")),
373 constant_canonicalization_mutex_(
374 NOT_IN_PRODUCT("IsolateGroup::constant_canonicalization_mutex_")),
375 kernel_data_lib_cache_mutex_(
376 NOT_IN_PRODUCT("IsolateGroup::kernel_data_lib_cache_mutex_")),
377 kernel_data_class_cache_mutex_(
378 NOT_IN_PRODUCT("IsolateGroup::kernel_data_class_cache_mutex_")),
379 kernel_constants_mutex_(
380 NOT_IN_PRODUCT("IsolateGroup::kernel_constants_mutex_")),
381 field_list_mutex_(NOT_IN_PRODUCT("Isolate::field_list_mutex_")),
382 boxed_field_list_(GrowableObjectArray::null()),
383 program_lock_(new SafepointRwLock()),
384 active_mutators_monitor_(new Monitor()),
385 max_active_mutators_(Scavenger::MaxMutatorThreadCount())
386#if !defined(PRODUCT)
387 ,
388 debugger_(new GroupDebugger(this))
389#endif
390{
391 FlagsCopyFrom(api_flags);
392 if (!is_vm_isolate) {
393 thread_pool_.reset(
394 new MutatorThreadPool(this, FLAG_disable_thread_pool_limit
395 ? 0
397 }
398 {
399 WriteRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
400 // Keep isolate IDs less than 2^53 so web clients of the service
401 // protocol can process it properly.
402 //
403 // See https://github.com/dart-lang/sdk/issues/53081.
404 id_ = isolate_group_random_->NextJSInt();
405 }
406 heap_walk_class_table_ = class_table_ =
407 new ClassTable(&class_table_allocator_);
408 cached_class_table_table_.store(class_table_->table());
409 memset(&native_assets_api_, 0, sizeof(NativeAssetsApi));
410}
411
412IsolateGroup::IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
413 void* embedder_data,
414 Dart_IsolateFlags api_flags,
415 bool is_vm_isolate)
417 embedder_data,
418 new ObjectStore(),
419 api_flags,
420 is_vm_isolate) {
421 if (object_store() != nullptr) {
423 }
424}
425
427 // Ensure we destroy the heap before the other members.
428 heap_ = nullptr;
429 ASSERT(old_marking_stack_ == nullptr);
430 ASSERT(new_marking_stack_ == nullptr);
431 ASSERT(deferred_marking_stack_ == nullptr);
432
433 if (obfuscation_map_ != nullptr) {
434 for (intptr_t i = 0; obfuscation_map_[i] != nullptr; i++) {
435 delete[] obfuscation_map_[i];
436 }
437 delete[] obfuscation_map_;
438 }
439
440 class_table_allocator_.Free(class_table_);
441 if (heap_walk_class_table_ != class_table_) {
442 class_table_allocator_.Free(heap_walk_class_table_);
443 }
444
445#if !defined(PRODUCT)
446 delete debugger_;
447 debugger_ = nullptr;
448#endif
449}
450
452 SafepointWriteRwLocker ml(Thread::Current(), isolates_lock_.get());
453 ASSERT(isolates_lock_->IsCurrentThreadWriter());
454 isolates_.Append(isolate);
455 isolate_count_++;
456}
457
459 SafepointReadRwLocker ml(Thread::Current(), isolates_lock_.get());
460 // We do allow 0 here as well, because the background compiler might call
461 // this method while the mutator thread is in shutdown procedure and
462 // unregistered itself already.
463 return isolate_count_ == 0 || isolate_count_ == 1;
464}
465
467 SafepointWriteRwLocker ml(Thread::Current(), isolates_lock_.get());
468 fun();
469}
470
472 SafepointWriteRwLocker ml(Thread::Current(), isolates_lock_.get());
473 isolates_.Remove(isolate);
474}
475
477 SafepointWriteRwLocker ml(Thread::Current(), isolates_lock_.get());
478 isolate_count_--;
479 return isolate_count_ == 0;
480}
481
482void IsolateGroup::CreateHeap(bool is_vm_isolate,
483 bool is_service_or_kernel_isolate) {
486 ? 0 // New gen size 0; VM isolate should only allocate in old.
487 : FLAG_new_gen_semi_max_size * MBInWords,
488 (is_service_or_kernel_isolate ? kDefaultMaxOldGenHeapSize
489 : FLAG_old_gen_heap_size) *
490 MBInWords);
491
492#define ISOLATE_GROUP_METRIC_CONSTRUCTORS(type, variable, name, unit) \
493 metric_##variable##_.InitInstance(this, name, nullptr, Metric::unit);
495#undef ISOLATE_GROUP_METRIC_CONSTRUCTORS
496}
497
499 char* name = nullptr;
500 // We retrieve the flag value once to avoid the compiler complaining about the
501 // possibly uninitialized value of name, as the compiler is unaware that when
502 // the flag variable is non-const, it is set once during VM initialization and
503 // never changed after, and that modification never runs concurrently with
504 // this method.
505 const bool trace_shutdown = FLAG_trace_shutdown;
506
507 if (trace_shutdown) {
509 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutdown starting for group %s\n",
511 }
512 // Ensure to join all threads before waiting for pending GC tasks (the thread
513 // pool can trigger idle notification, which can start new GC tasks).
514 //
515 // (The vm-isolate doesn't have a thread pool.)
516 if (!is_vm_isolate_) {
517 ASSERT(thread_pool_ != nullptr);
518 thread_pool_->Shutdown();
519 thread_pool_.reset();
520 }
521
522 // Needs to happen before starting to destroy the heap so helper tasks like
523 // the SampleBlockProcessor don't try to enter the group during this
524 // tear-down.
526
527 // Wait for any pending GC tasks.
528 if (heap_ != nullptr) {
529 // Wait for any concurrent GC tasks to finish before shutting down.
530 // TODO(rmacnak): Interrupt tasks for faster shutdown.
531 PageSpace* old_space = heap_->old_space();
532 MonitorLocker ml(old_space->tasks_lock());
533 while (old_space->tasks() > 0) {
534 ml.Wait();
535 }
536 // Needs to happen before ~PageSpace so TLS and the thread registry are
537 // still valid.
538 old_space->AbandonMarkingForShutdown();
539 }
540
541 // If the creation of the isolate group (or the first isolate within the
542 // isolate group) failed, we do not invoke the cleanup callback (the
543 // embedder is responsible for handling the creation error).
544 if (initial_spawn_successful_ && !is_vm_isolate_) {
545 auto group_shutdown_callback = Isolate::GroupCleanupCallback();
546 if (group_shutdown_callback != nullptr) {
547 group_shutdown_callback(embedder_data());
548 }
549 }
550
551 delete this;
552
553 // After this isolate group has died we might need to notify a pending
554 // `Dart_Cleanup()` call.
555 {
556 if (trace_shutdown) {
557 OS::PrintErr("[+%" Pd64
558 "ms] SHUTDOWN: Notifying "
559 "isolate group shutdown (%s)\n",
561 }
562 MonitorLocker ml(Isolate::isolate_creation_monitor_);
563 if (!Isolate::creation_enabled_ &&
565 ml.Notify();
566 }
567 if (trace_shutdown) {
568 OS::PrintErr("[+%" Pd64
569 "ms] SHUTDOWN: Done Notifying "
570 "isolate group shutdown (%s)\n",
572 }
573 }
574 if (trace_shutdown) {
575 OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Done shutdown for group %s\n",
577 free(name);
578 }
579}
580
581void IsolateGroup::set_heap(std::unique_ptr<Heap> heap) {
582 idle_time_handler_.InitializeWithHeap(heap.get());
583 heap_ = std::move(heap);
584}
585
586void IsolateGroup::set_saved_unlinked_calls(const Array& saved_unlinked_calls) {
587 saved_unlinked_calls_ = saved_unlinked_calls.ptr();
588}
589
591 bool is_nested_reenter) {
592 ASSERT(mutator->group() == this);
593
594 // If the mutator was temporarily blocked on a worker thread, we have to
595 // unblock the worker thread again.
596 if (is_nested_reenter) {
597 ASSERT(mutator->mutator_thread() != nullptr);
599 }
600
601 // Prevent too many mutators from entering the isolate group to avoid
602 // pathological behavior where many threads are fighting for obtaining TLABs.
603 {
604 // NOTE: This is performance critical code, we should avoid monitors and use
605 // std::atomics in the fast case (where active_mutators <
606 // max_active_mutators) and only use monitors in the uncommon case.
607 MonitorLocker ml(active_mutators_monitor_.get());
608 ASSERT(active_mutators_ <= max_active_mutators_);
609 while (active_mutators_ == max_active_mutators_) {
610 waiting_mutators_++;
611 ml.Wait();
612 waiting_mutators_--;
613 }
614 active_mutators_++;
615 }
616}
617
618void IsolateGroup::DecreaseMutatorCount(Isolate* mutator, bool is_nested_exit) {
619 ASSERT(mutator->group() == this);
620
621 // If the mutator thread has an active stack and runs on our thread pool we
622 // will mark the worker as blocked, thereby possibly spawning a new worker for
623 // pending tasks (if there are any).
624 if (is_nested_exit) {
625 ASSERT(mutator->mutator_thread() != nullptr);
627 }
628
629 {
630 // NOTE: This is performance critical code, we should avoid monitors and use
631 // std::atomics in the fast case (where active_mutators <
632 // max_active_mutators) and only use monitors in the uncommon case.
633 MonitorLocker ml(active_mutators_monitor_.get());
634 ASSERT(active_mutators_ <= max_active_mutators_);
635 active_mutators_--;
636 if (waiting_mutators_ > 0) {
637 ml.Notify();
638 }
639 }
640}
641
642#ifndef PRODUCT
644 JSONObject jsobj(stream);
645 PrintToJSONObject(&jsobj, ref);
646}
647
649 jsobj->AddProperty("type", (ref ? "@IsolateGroup" : "IsolateGroup"));
651
652 jsobj->AddProperty("name", source()->script_uri);
653 jsobj->AddPropertyF("number", "%" Pu64 "", id());
654 jsobj->AddProperty("isSystemIsolateGroup", is_system_isolate_group());
655 if (ref) {
656 return;
657 }
658
659 {
660 JSONArray isolate_array(jsobj, "isolates");
661 for (auto it = isolates_.Begin(); it != isolates_.End(); ++it) {
662 Isolate* isolate = *it;
663 isolate_array.AddValue(isolate, /*ref=*/true);
664 }
665 }
666}
667
669 int64_t used = heap()->TotalUsedInWords();
670 int64_t capacity = heap()->TotalCapacityInWords();
671 int64_t external_used = heap()->TotalExternalInWords();
672
673 JSONObject jsobj(stream);
674 // This is the same "MemoryUsage" that the isolate-specific "getMemoryUsage"
675 // rpc method returns.
676 jsobj.AddProperty("type", "MemoryUsage");
677 jsobj.AddProperty64("heapUsage", used * kWordSize);
678 jsobj.AddProperty64("heapCapacity", capacity * kWordSize);
679 jsobj.AddProperty64("externalUsage", external_used * kWordSize);
680}
681#endif
682
684 ReadRwLocker wl(Thread::Current(), isolate_groups_rwlock_);
685 for (auto isolate_group : *isolate_groups_) {
686 action(isolate_group);
687 }
688}
689
691 uint64_t id,
693 std::function<void()> not_found) {
694 ReadRwLocker wl(Thread::Current(), isolate_groups_rwlock_);
695 for (auto isolate_group : *isolate_groups_) {
696 if (isolate_group->id() == id) {
697 action(isolate_group);
698 return;
699 }
700 }
701 not_found();
702}
703
705 WriteRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
706 isolate_groups_->Append(isolate_group);
707}
708
710 WriteRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
711 isolate_groups_->Remove(isolate_group);
712}
713
715 ReadRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
716 for (auto group : *isolate_groups_) {
718 return true;
719 }
720 }
721 return false;
722}
723
725 ReadRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
726 for (auto group : *isolate_groups_) {
727 if (!group->is_vm_isolate()) {
728 return false;
729 }
730 }
731 return true;
732}
733
735 ASSERT(isolate_groups_rwlock_ == nullptr);
736 isolate_groups_rwlock_ = new RwLock();
737 ASSERT(isolate_groups_ == nullptr);
738 isolate_groups_ = new IntrusiveDList<IsolateGroup>();
739 isolate_group_random_ = new Random();
740}
741
743 delete isolate_group_random_;
744 isolate_group_random_ = nullptr;
745 delete isolate_groups_rwlock_;
746 isolate_groups_rwlock_ = nullptr;
747 ASSERT(isolate_groups_->IsEmpty());
748 delete isolate_groups_;
749 isolate_groups_ = nullptr;
750}
751
753 return Isolate::IsSystemIsolate(isolate);
754}
755
757 if (handle_ == nullptr) {
758 return;
759 }
760
761 IsolateGroup* isolate_group = IsolateGroup::Current();
762 CHECK_ISOLATE_GROUP(isolate_group);
763 NoSafepointScope no_safepoint_scope;
764 ApiState* state = isolate_group->api_state();
765 ASSERT(state != nullptr);
766 state->FreePersistentHandle(handle_);
767}
768
770#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
771 if (IsReloading()) {
772 program_reload_context()->RegisterClass(cls);
773 return;
774 }
775#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
776 if (cls.IsTopLevel()) {
778 } else {
779 class_table()->Register(cls);
780 }
781}
782
783#if defined(DEBUG)
784void IsolateGroup::ValidateClassTable() {
786}
787#endif // DEBUG
788
790 const Object& initial_value) {
791 const bool need_to_grow_backing_store =
793 const intptr_t field_id = field.field_id();
794 shared_initial_field_table()->SetAt(field_id, initial_value.ptr());
795
796 if (need_to_grow_backing_store) {
797 // We have to stop other isolates from accessing shared isolate group
798 // field state, since we'll have to grow the backing store.
800 const bool need_to_grow_other_backing_store =
801 shared_field_table()->Register(field, field_id);
802 ASSERT(need_to_grow_other_backing_store);
803 } else {
804 const bool need_to_grow_other_backing_store =
805 shared_field_table()->Register(field, field_id);
806 ASSERT(!need_to_grow_other_backing_store);
807 }
808 shared_field_table()->SetAt(field_id, initial_value.ptr());
809}
810
812 const Object& initial_value) {
813 ASSERT(program_lock()->IsCurrentThreadWriter());
814
815 ASSERT(field.is_static());
816 if (field.is_shared()) {
817 RegisterSharedStaticField(field, initial_value);
818 return;
819 }
820 const bool need_to_grow_backing_store =
822 const intptr_t field_id = field.field_id();
823 initial_field_table()->SetAt(field_id, initial_value.ptr());
824
825 SafepointReadRwLocker ml(Thread::Current(), isolates_lock_.get());
826 if (need_to_grow_backing_store) {
827 // We have to stop other isolates from accessing their field state, since
828 // we'll have to grow the backing store.
830 for (auto isolate : isolates_) {
831 auto field_table = isolate->field_table();
832 if (field_table->IsReadyToUse()) {
833 field_table->Register(field, field_id);
834 field_table->SetAt(field_id, initial_value.ptr());
835 }
836 }
837 } else {
838 for (auto isolate : isolates_) {
839 auto field_table = isolate->field_table();
840 if (field_table->IsReadyToUse()) {
841 field_table->Register(field, field_id);
842 field_table->SetAt(field_id, initial_value.ptr());
843 }
844 }
845 }
846}
847
849#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
850 // This can only be called during hot-reload.
851 ASSERT(program_reload_context() != nullptr);
852#endif
853
854 const intptr_t field_id = field.field_id();
855 if (field.is_shared()) {
856 shared_field_table()->Free(field_id);
857 } else {
858 initial_field_table()->Free(field_id);
859 ForEachIsolate([&](Isolate* isolate) {
860 auto field_table = isolate->field_table();
861 // The isolate might've just been created and is now participating in
862 // the reload request inside `IsolateGroup::RegisterIsolate()`.
863 // At that point it doesn't have the field table setup yet.
864 if (field_table->IsReadyToUse()) {
865 field_table->Free(field_id);
866 }
867 });
868 }
869}
870
874 Isolate* const isolate = Isolate::InitIsolate("temp", this, flags);
875 ASSERT(isolate != nullptr);
876 ASSERT(Isolate::Current() == isolate);
877 return isolate;
878}
879
881 Thread* thread = Thread::Current();
882 ASSERT(thread != nullptr);
884 Dart::ShutdownIsolate(thread);
885}
886
888 // Even though no individual constant contains a cycle, there can be "cycles"
889 // between the canonical tables if some const instances of A have fields that
890 // are const instance of B and vice versa. So set all the old tables to the
891 // side and clear all the tables attached to the classes before rehashing
892 // instead of resetting and rehash one class at a time.
893
894 Thread* thread = Thread::Current();
895 StackZone stack_zone(thread);
896 Zone* zone = stack_zone.GetZone();
897
898 intptr_t num_cids = class_table()->NumCids();
899 Array** old_constant_tables = zone->Alloc<Array*>(num_cids);
900 for (intptr_t i = 0; i < num_cids; i++) {
901 old_constant_tables[i] = nullptr;
902 }
903
904 Class& cls = Class::Handle(zone);
905 for (intptr_t cid = kInstanceCid; cid < num_cids; cid++) {
906 if (!class_table()->IsValidIndex(cid) ||
907 !class_table()->HasValidClassAt(cid)) {
908 continue;
909 }
910 if ((cid == kTypeArgumentsCid) || IsStringClassId(cid)) {
911 // TypeArguments and Symbols have special tables for canonical objects
912 // that aren't based on address.
913 continue;
914 }
915 if ((cid == kMintCid) || (cid == kDoubleCid)) {
916 // Constants stored as a plain list or in a hashset with a stable
917 // hashcode, which only depends on the actual value of the constant.
918 continue;
919 }
920
921 cls = class_table()->At(cid);
922 if (cls.constants() == Array::null()) continue;
923 old_constant_tables[cid] = &Array::Handle(zone, cls.constants());
924 cls.set_constants(Object::null_array());
925 }
926
927 // Clear invalid hashes.
929
930 Instance& constant = Instance::Handle(zone);
931 Field& field = Field::Handle(zone);
932 String& name = String::Handle(zone);
933 Array& new_values = Array::Handle(zone);
934 Instance& old_value = Instance::Handle(zone);
935 Instance& new_value = Instance::Handle(zone);
936 Instance& deleted = Instance::Handle(zone);
937
938 if (become != nullptr) {
939 for (intptr_t cid = kInstanceCid; cid < num_cids; cid++) {
940 Array* old_constants = old_constant_tables[cid];
941 if (old_constants == nullptr) continue;
942
943 cls = class_table()->At(cid);
944 CanonicalInstancesSet set(zone, old_constants->ptr());
945 CanonicalInstancesSet::Iterator it(&set);
946 while (it.MoveNext()) {
947 constant ^= set.GetKey(it.Current());
948 ASSERT(!constant.IsNull());
949 ASSERT(!constant.InVMIsolateHeap());
950 constant.ClearCanonical();
951 }
952 set.Release();
953 }
954 }
955
956 for (intptr_t cid = kInstanceCid; cid < num_cids; cid++) {
957 Array* old_constants = old_constant_tables[cid];
958 if (old_constants == nullptr) continue;
959
960 cls = class_table()->At(cid);
961 CanonicalInstancesSet set(zone, old_constants->ptr());
962 CanonicalInstancesSet::Iterator it(&set);
963
964 if (cls.is_enum_class() && (become != nullptr)) {
965 field = cls.LookupStaticField(Symbols::_DeletedEnumSentinel());
966 deleted ^= field.StaticConstFieldValue();
967 if (deleted.IsNull()) {
968 deleted = Instance::New(cls, Heap::kOld);
969 field = object_store()->enum_name_field();
970 name = cls.ScrubbedName();
971 name = Symbols::FromConcat(thread, Symbols::_DeletedEnumPrefix(), name);
972 deleted.SetField(field, name);
973 field = object_store()->enum_index_field();
974 new_value = Smi::New(-1);
975 deleted.SetField(field, new_value);
976 field = cls.LookupStaticField(Symbols::_DeletedEnumSentinel());
977 // The static const field contains `Object::null()` instead of
978 // `Object::sentinel()` - so it's not considered an initializing store.
979 field.SetStaticConstFieldValue(deleted,
980 /*assert_initializing_store*/ false);
981 }
982
983 field = cls.LookupField(Symbols::Values());
984 new_values ^= field.StaticConstFieldValue();
985
986 field = object_store()->enum_name_field();
987 while (it.MoveNext()) {
988 old_value ^= set.GetKey(it.Current());
989 ASSERT(old_value.GetClassId() == cid);
990 bool found = false;
991 for (intptr_t j = 0; j < new_values.Length(); j++) {
992 new_value ^= new_values.At(j);
993 ASSERT(new_value.GetClassId() == cid);
994 if (old_value.GetField(field) == new_value.GetField(field)) {
995 found = true;
996 break;
997 }
998 }
999 if (!found) {
1000 new_value = deleted.ptr();
1001 }
1002
1003 if (old_value.ptr() != new_value.ptr()) {
1004 become->Add(old_value, new_value);
1005 }
1006 if (new_value.IsCanonical()) {
1007 cls.InsertCanonicalConstant(zone, new_value);
1008 }
1009 }
1010 } else {
1011 while (it.MoveNext()) {
1012 old_value ^= set.GetKey(it.Current());
1013 ASSERT(!old_value.IsNull());
1014
1015 if (become == nullptr) {
1016 ASSERT(old_value.IsCanonical());
1017 cls.InsertCanonicalConstant(zone, old_value);
1018 } else {
1019 new_value = old_value.Canonicalize(thread);
1020 if (old_value.ptr() != new_value.ptr()) {
1021 become->Add(old_value, new_value);
1022 }
1023 }
1024 }
1025 }
1026 set.Release();
1027 }
1028
1029 // Save memory.
1031}
1032
1033void Isolate::SendInternalLibMessage(LibMsgId msg_id, uint64_t capability) {
1034 const bool ok = SendInternalLibMessage(main_port(), msg_id, capability);
1035 if (!ok) UNREACHABLE();
1036}
1037
1039 LibMsgId msg_id,
1040 uint64_t capability) {
1041 Dart_CObject array_entry_msg_kind;
1042 array_entry_msg_kind.type = Dart_CObject_kInt64;
1043 array_entry_msg_kind.value.as_int64 = Message::kIsolateLibOOBMsg;
1044
1045 Dart_CObject array_entry_msg_id;
1046 array_entry_msg_id.type = Dart_CObject_kInt64;
1047 array_entry_msg_id.value.as_int64 = msg_id;
1048
1049 Dart_CObject array_entry_capability;
1050 array_entry_capability.type = Dart_CObject_kCapability;
1051 array_entry_capability.value.as_capability.id = capability;
1052
1053 Dart_CObject* array_entries[3] = {
1054 &array_entry_msg_kind,
1055 &array_entry_msg_id,
1056 &array_entry_capability,
1057 };
1058
1061 message.value.as_array.values = array_entries;
1062 message.value.as_array.length = ARRAY_SIZE(array_entries);
1063
1064 AllocOnlyStackZone zone;
1065 std::unique_ptr<Message> msg = WriteApiMessage(
1067 if (msg == nullptr) UNREACHABLE();
1068
1069 return PortMap::PostMessage(std::move(msg));
1070}
1071
1073 object_store_.reset(object_store);
1074}
1075
1077 public:
1080
1081 const char* name() const;
1082 void MessageNotify(Message::Priority priority);
1083 MessageStatus HandleMessage(std::unique_ptr<Message> message);
1084#ifndef PRODUCT
1085 void NotifyPauseOnStart();
1086 void NotifyPauseOnExit();
1087#endif // !PRODUCT
1088
1089#if defined(DEBUG)
1090 // Check that it is safe to access this handler.
1091 void CheckAccess() const;
1092#endif
1093 bool IsCurrentIsolate() const;
1094 virtual Isolate* isolate() const { return isolate_; }
1095 virtual IsolateGroup* isolate_group() const { return isolate_->group(); }
1096
1097 virtual bool KeepAliveLocked() {
1098 // If the message handler was asked to shutdown we shut down.
1099 if (!MessageHandler::KeepAliveLocked()) return false;
1100 // Otherwise we only stay alive as long as there's active receive ports, or
1101 // there are FFI callbacks keeping the isolate alive.
1102 return isolate_->HasLivePorts() || isolate_->HasOpenNativeCallables();
1103 }
1104
1105 private:
1106 // A result of false indicates that the isolate should terminate the
1107 // processing of further events.
1108 ErrorPtr HandleLibMessage(const Array& message);
1109
1110 MessageStatus ProcessUnhandledException(const Error& result);
1111 Isolate* isolate_;
1112};
1113
1115 : isolate_(isolate) {}
1116
1118
1119const char* IsolateMessageHandler::name() const {
1120 return isolate_->name();
1121}
1122
1123// Isolate library OOB messages are fixed sized arrays which have the
1124// following format:
1125// [ OOB dispatch, Isolate library dispatch, <message specific data> ]
1126ErrorPtr IsolateMessageHandler::HandleLibMessage(const Array& message) {
1127 if (message.Length() < 2) return Error::null();
1128 Zone* zone = T->zone();
1129 const Object& type = Object::Handle(zone, message.At(1));
1130 if (!type.IsSmi()) return Error::null();
1131 const intptr_t msg_type = Smi::Cast(type).Value();
1132 switch (msg_type) {
1133 case Isolate::kPauseMsg: {
1134 // [ OOB, kPauseMsg, pause capability, resume capability ]
1135 if (message.Length() != 4) return Error::null();
1136 Object& obj = Object::Handle(zone, message.At(2));
1137 if (!I->VerifyPauseCapability(obj)) return Error::null();
1138 obj = message.At(3);
1139 if (!obj.IsCapability()) return Error::null();
1140 if (I->AddResumeCapability(Capability::Cast(obj))) {
1142 }
1143 break;
1144 }
1145 case Isolate::kResumeMsg: {
1146 // [ OOB, kResumeMsg, pause capability, resume capability ]
1147 if (message.Length() != 4) return Error::null();
1148 Object& obj = Object::Handle(zone, message.At(2));
1149 if (!I->VerifyPauseCapability(obj)) return Error::null();
1150 obj = message.At(3);
1151 if (!obj.IsCapability()) return Error::null();
1152 if (I->RemoveResumeCapability(Capability::Cast(obj))) {
1154 }
1155 break;
1156 }
1157 case Isolate::kPingMsg: {
1158 // [ OOB, kPingMsg, responsePort, priority, response ]
1159 if (message.Length() != 5) return Error::null();
1160 const Object& obj2 = Object::Handle(zone, message.At(2));
1161 if (!obj2.IsSendPort()) return Error::null();
1162 const SendPort& send_port = SendPort::Cast(obj2);
1163 const Object& obj3 = Object::Handle(zone, message.At(3));
1164 if (!obj3.IsSmi()) return Error::null();
1165 const intptr_t priority = Smi::Cast(obj3).Value();
1166 const Object& obj4 = Object::Handle(zone, message.At(4));
1167 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null();
1168 const Instance& response =
1169 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4);
1170 if (priority == Isolate::kImmediateAction) {
1171 PortMap::PostMessage(SerializeMessage(send_port.Id(), response));
1172 } else {
1174 (priority == Isolate::kAsEventAction));
1175 // Update the message so that it will be handled immediately when it
1176 // is picked up from the message queue the next time.
1177 message.SetAt(
1179 message.SetAt(3,
1181 this->PostMessage(
1183 priority == Isolate::kBeforeNextEventAction /* at_head */);
1184 }
1185 break;
1186 }
1187 case Isolate::kKillMsg:
1189 // [ OOB, kKillMsg, terminate capability, priority ]
1190 if (message.Length() != 4) return Error::null();
1191 Object& obj = Object::Handle(zone, message.At(3));
1192 if (!obj.IsSmi()) return Error::null();
1193 const intptr_t priority = Smi::Cast(obj).Value();
1194 if (priority == Isolate::kImmediateAction) {
1196 obj = message.At(2);
1197 if (I->VerifyTerminateCapability(obj)) {
1198 // We will kill the current isolate by returning an UnwindError.
1199 if (msg_type == Isolate::kKillMsg) {
1200 const String& msg = String::Handle(
1201 String::New("isolate terminated by Isolate.kill"));
1202 const UnwindError& error =
1204 error.set_is_user_initiated(true);
1205 return error.ptr();
1206 } else if (msg_type == Isolate::kInternalKillMsg) {
1207 const String& msg =
1208 String::Handle(String::New("isolate terminated by vm"));
1209 return UnwindError::New(msg);
1210 } else {
1211 UNREACHABLE();
1212 }
1213 } else {
1214 return Error::null();
1215 }
1216 } else {
1218 (priority == Isolate::kAsEventAction));
1219 // Update the message so that it will be handled immediately when it
1220 // is picked up from the message queue the next time.
1221 message.SetAt(
1223 message.SetAt(3,
1225 this->PostMessage(
1227 priority == Isolate::kBeforeNextEventAction /* at_head */);
1228 }
1229 break;
1230 }
1232 // [ OOB, kInterruptMsg, pause capability ]
1233 if (message.Length() != 3) return Error::null();
1234 Object& obj = Object::Handle(zone, message.At(2));
1235 if (!I->VerifyPauseCapability(obj)) return Error::null();
1236
1237#if !defined(PRODUCT)
1238 // If we are already paused, don't pause again.
1239 if (I->debugger()->PauseEvent() == nullptr) {
1240 return I->debugger()->PauseInterrupted();
1241 }
1242#endif
1243 break;
1244 }
1246#ifndef PRODUCT
1247 Object& obj = Object::Handle(zone, message.At(2));
1248 if (!obj.IsSmi()) return Error::null();
1249 const intptr_t priority = Smi::Cast(obj).Value();
1250 if (priority == Isolate::kImmediateAction) {
1251 return I->InvokePendingServiceExtensionCalls();
1252 } else {
1254 (priority == Isolate::kAsEventAction));
1255 // Update the message so that it will be handled immediately when it
1256 // is picked up from the message queue the next time.
1257 message.SetAt(
1259 message.SetAt(2,
1261 this->PostMessage(
1263 priority == Isolate::kBeforeNextEventAction /* at_head */);
1264 }
1265#else
1266 UNREACHABLE();
1267#endif // !PRODUCT
1268 break;
1269 }
1270
1274 case Isolate::kDelErrorMsg: {
1275 // [ OOB, msg, listener port ]
1276 if (message.Length() < 3) return Error::null();
1277 const Object& obj = Object::Handle(zone, message.At(2));
1278 if (!obj.IsSendPort()) return Error::null();
1279 const SendPort& listener = SendPort::Cast(obj);
1280 switch (msg_type) {
1281 case Isolate::kAddExitMsg: {
1282 if (message.Length() != 4) return Error::null();
1283 // [ OOB, msg, listener port, response object ]
1284 const Object& response = Object::Handle(zone, message.At(3));
1285 if (!response.IsInstance() && !response.IsNull()) {
1286 return Error::null();
1287 }
1288 I->AddExitListener(listener, response.IsNull()
1289 ? Instance::null_instance()
1290 : Instance::Cast(response));
1291 break;
1292 }
1294 if (message.Length() != 3) return Error::null();
1295 I->RemoveExitListener(listener);
1296 break;
1298 if (message.Length() != 3) return Error::null();
1299 I->AddErrorListener(listener);
1300 break;
1302 if (message.Length() != 3) return Error::null();
1303 I->RemoveErrorListener(listener);
1304 break;
1305 default:
1306 UNREACHABLE();
1307 }
1308 break;
1309 }
1311 // [ OOB, kErrorFatalMsg, terminate capability, val ]
1312 if (message.Length() != 4) return Error::null();
1313 // Check that the terminate capability has been passed correctly.
1314 Object& obj = Object::Handle(zone, message.At(2));
1315 if (!I->VerifyTerminateCapability(obj)) return Error::null();
1316 // Get the value to be set.
1317 obj = message.At(3);
1318 if (!obj.IsBool()) return Error::null();
1319 I->SetErrorsFatal(Bool::Cast(obj).value());
1320 break;
1321 }
1323 // [ OOB, kCheckForReload, ignored ]
1324#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
1325 {
1326 ReloadParticipationScope allow_reload(T);
1327 T->CheckForSafepoint();
1328 }
1329#else
1330 UNREACHABLE();
1331#endif
1332 break;
1333 }
1334#if defined(DEBUG)
1335 // Malformed OOB messages are silently ignored in release builds.
1336 default:
1337 FATAL("Unknown OOB message type: %" Pd "\n", msg_type);
1338 break;
1339#endif // defined(DEBUG)
1340 }
1341 return Error::null();
1342}
1343
1345 if (priority >= Message::kOOBPriority) {
1346 // Handle out of band messages even if the mutator thread is busy.
1347 I->ScheduleInterrupts(Thread::kMessageInterrupt);
1348 }
1349 Dart_MessageNotifyCallback callback = I->message_notify_callback();
1350 if (callback != nullptr) {
1351 // Allow the embedder to handle message notification.
1352 (*callback)(Api::CastIsolate(I));
1353 }
1354}
1355
1357 return message_handler_->HasMessages() || message_handler_->HasOOBMessages();
1358}
1359
1361 std::unique_ptr<Message> message) {
1364 StackZone stack_zone(thread);
1365 Zone* zone = stack_zone.GetZone();
1366 HandleScope handle_scope(thread);
1367#if defined(SUPPORT_TIMELINE)
1368 TimelineBeginEndScope tbes(
1369 thread, Timeline::GetIsolateStream(),
1370 message->IsOOB() ? "HandleOOBMessage" : "HandleMessage");
1371 tbes.SetNumArguments(1);
1372 tbes.CopyArgument(0, "isolateName", I->name());
1373#endif
1374
1375 // Parse the message.
1376 Object& msg_obj = Object::Handle(zone, ReadMessage(thread, message.get()));
1377 if (msg_obj.IsError()) {
1378 // An error occurred while reading the message.
1379 return ProcessUnhandledException(Error::Cast(msg_obj));
1380 }
1381 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
1382 // TODO(turnidge): We need to decide what an isolate does with
1383 // malformed messages. If they (eventually) come from a remote
1384 // machine, then it might make sense to drop the message entirely.
1385 // In the case that the message originated locally, which is
1386 // always true for now, then this should never occur.
1387 UNREACHABLE();
1388 }
1389 Instance& msg = Instance::Handle(zone);
1390 msg ^= msg_obj.ptr(); // Can't use Instance::Cast because may be null.
1391
1392 MessageStatus status = kOK;
1393 if (message->IsOOB()) {
1394 // OOB messages are expected to be fixed length arrays where the first
1395 // element is a Smi describing the OOB destination. Messages that do not
1396 // confirm to this layout are silently ignored.
1397 if (msg.IsArray()) {
1398 const Array& oob_msg = Array::Cast(msg);
1399 if (oob_msg.Length() > 0) {
1400 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0));
1401 if (oob_tag.IsSmi()) {
1402 switch (Smi::Cast(oob_tag).Value()) {
1404#ifndef PRODUCT
1405 const Error& error =
1407 if (!error.IsNull()) {
1408 status = ProcessUnhandledException(error);
1409 }
1410#else
1411 UNREACHABLE();
1412#endif
1413 break;
1414 }
1416 const Error& error = Error::Handle(HandleLibMessage(oob_msg));
1417 if (!error.IsNull()) {
1418 status = ProcessUnhandledException(error);
1419 }
1420 break;
1421 }
1422#if defined(DEBUG)
1423 // Malformed OOB messages are silently ignored in release builds.
1424 default: {
1425 UNREACHABLE();
1426 break;
1427 }
1428#endif // defined(DEBUG)
1429 }
1430 }
1431 }
1432 }
1433 } else if (message->IsFinalizerInvocationRequest()) {
1434 const Object& msg_handler = Object::Handle(
1435 zone,
1436 DartLibraryCalls::HandleFinalizerMessage(FinalizerBase::Cast(msg)));
1437 if (msg_handler.IsError()) {
1438 status = ProcessUnhandledException(Error::Cast(msg_handler));
1439 } else {
1440 // The handler closure which was used to successfully handle the message.
1441 }
1442 } else if (message->dest_port() == Message::kIllegalPort) {
1443 // Check whether this is a delayed OOB message which needed handling as
1444 // part of the regular message dispatch. All other messages are dropped on
1445 // the floor.
1446 if (msg.IsArray()) {
1447 const Array& msg_arr = Array::Cast(msg);
1448 if (msg_arr.Length() > 0) {
1449 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0));
1450 if (oob_tag.IsSmi() &&
1451 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) {
1452 const Error& error = Error::Handle(HandleLibMessage(msg_arr));
1453 if (!error.IsNull()) {
1454 status = ProcessUnhandledException(error);
1455 }
1456 }
1457 }
1458 }
1459 } else {
1460 const Object& msg_handler = Object::Handle(
1461 zone, DartLibraryCalls::HandleMessage(message->dest_port(), msg));
1462 if (msg_handler.IsError()) {
1463 status = ProcessUnhandledException(Error::Cast(msg_handler));
1464 } else if (msg_handler.IsNull()) {
1465 // If the port has been closed then the message will be dropped at this
1466 // point. Make sure to post to the delivery failure port in that case.
1467 } else {
1468 // The handler closure which was used to successfully handle the message.
1469 }
1470 }
1471 return status;
1472}
1473
1474#ifndef PRODUCT
1477 return;
1478 }
1479 if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) {
1480 StartIsolateScope start_isolate(I);
1481 StackZone zone(T);
1482 HandleScope handle_scope(T);
1484 Service::HandleEvent(&pause_event);
1485 } else if (FLAG_trace_service) {
1486 OS::PrintErr("vm-service: Dropping event of type PauseStart (%s)\n",
1487 I->name());
1488 }
1489}
1490
1493 return;
1494 }
1495 if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) {
1496 StartIsolateScope start_isolate(I);
1497 StackZone zone(T);
1498 HandleScope handle_scope(T);
1500 Service::HandleEvent(&pause_event);
1501 } else if (FLAG_trace_service) {
1502 OS::PrintErr("vm-service: Dropping event of type PauseExit (%s)\n",
1503 I->name());
1504 }
1505}
1506#endif // !PRODUCT
1507
1508#if defined(DEBUG)
1509void IsolateMessageHandler::CheckAccess() const {
1511}
1512#endif
1513
1515 return (I == Isolate::Current());
1516}
1517
1519 const Error& error) {
1520 thread->set_sticky_error(error);
1521 if (error.IsUnwindError()) {
1522 const UnwindError& unwind = UnwindError::Cast(error);
1523 if (!unwind.is_user_initiated()) {
1525 }
1526 }
1528}
1529
1530MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException(
1531 const Error& result) {
1532 if (FLAG_trace_isolates) {
1534 "[!] Unhandled exception in %s:\n"
1535 " exception: %s\n",
1536 T->isolate()->name(), result.ToErrorCString());
1537 }
1538
1539 NoReloadScope no_reload(T);
1540 // Generate the error and stacktrace strings for the error message.
1541 const char* exception_cstr = nullptr;
1542 const char* stacktrace_cstr = nullptr;
1543 if (result.IsUnhandledException()) {
1544 Zone* zone = T->zone();
1545 const UnhandledException& uhe = UnhandledException::Cast(result);
1546 const Instance& exception = Instance::Handle(zone, uhe.exception());
1547 if (exception.ptr() == IG->object_store()->out_of_memory()) {
1548 exception_cstr = "Out of Memory"; // Cf. OutOfMemoryError.toString().
1549 } else if (exception.ptr() == IG->object_store()->stack_overflow()) {
1550 exception_cstr = "Stack Overflow"; // Cf. StackOverflowError.toString().
1551 } else {
1552 const Object& exception_str =
1554 if (!exception_str.IsString()) {
1555 exception_cstr = exception.ToCString();
1556 } else {
1557 exception_cstr = exception_str.ToCString();
1558 }
1559 }
1560
1561 const Instance& stacktrace = Instance::Handle(zone, uhe.stacktrace());
1562 stacktrace_cstr = stacktrace.ToCString();
1563 } else {
1564 exception_cstr = result.ToErrorCString();
1565 }
1566 if (result.IsUnwindError()) {
1567 // When unwinding we don't notify error listeners and we ignore
1568 // whether errors are fatal for the current isolate.
1569 return StoreError(T, result);
1570 } else {
1571 bool has_listener =
1572 I->NotifyErrorListeners(exception_cstr, stacktrace_cstr);
1573 if (I->ErrorsFatal()) {
1574 if (has_listener) {
1575 T->ClearStickyError();
1576 } else {
1577 T->set_sticky_error(result);
1578 }
1579#if !defined(PRODUCT)
1580 // Notify the debugger about specific unhandled exceptions which are
1581 // withheld when being thrown. Do this after setting the sticky error
1582 // so the isolate has an error set when paused with the unhandled
1583 // exception.
1584 if (result.IsUnhandledException()) {
1585 const UnhandledException& error = UnhandledException::Cast(result);
1586 InstancePtr exception = error.exception();
1587 if ((exception == IG->object_store()->out_of_memory()) ||
1588 (exception == IG->object_store()->stack_overflow())) {
1589 // We didn't notify the debugger when the stack was full. Do it now.
1590 I->debugger()->PauseException(Instance::Handle(exception));
1591 }
1592 }
1593#endif // !defined(PRODUCT)
1594 return kError;
1595 }
1596 }
1597 return kOK;
1598}
1599
1602#define INIT_FROM_FLAG(when, name, bitname, isolate_flag, flag) \
1603 api_flags->isolate_flag = flag;
1605#undef INIT_FROM_FLAG
1606 api_flags->is_service_isolate = false;
1607 api_flags->is_kernel_isolate = false;
1608 api_flags->null_safety = true;
1609}
1610
1613#define INIT_FROM_FIELD(when, name, bitname, isolate_flag, flag) \
1614 api_flags->isolate_flag = name();
1616#undef INIT_FROM_FIELD
1617 api_flags->is_service_isolate = false;
1618 api_flags->is_kernel_isolate = false;
1619 api_flags->null_safety = true;
1620}
1621
1623#if defined(DART_PRECOMPILER)
1624#define FLAG_FOR_PRECOMPILER(action) action
1625#else
1626#define FLAG_FOR_PRECOMPILER(action)
1627#endif
1628
1629#if !defined(PRODUCT)
1630#define FLAG_FOR_NONPRODUCT(action) action
1631#else
1632#define FLAG_FOR_NONPRODUCT(action)
1633#endif
1634
1635#define FLAG_FOR_PRODUCT(action) action
1636
1637#define SET_FROM_FLAG(when, name, bitname, isolate_flag, flag) \
1638 FLAG_FOR_##when(isolate_group_flags_ = bitname##Bit::update( \
1639 api_flags.isolate_flag, isolate_group_flags_));
1640
1642#undef FLAG_FOR_NONPRODUCT
1643#undef FLAG_FOR_PRECOMPILER
1644#undef FLAG_FOR_PRODUCT
1645#undef SET_FROM_FLAG
1646}
1647
1650
1652#define INIT_FROM_FLAG(when, name, bitname, isolate_flag, flag) \
1653 api_flags->isolate_flag = flag;
1655#undef INIT_FROM_FLAG
1656 api_flags->is_service_isolate = false;
1657 api_flags->is_kernel_isolate = false;
1658 api_flags->null_safety = true;
1659}
1660
1662 group()->FlagsCopyTo(api_flags);
1663
1665#define INIT_FROM_FIELD(when, name, bitname, isolate_flag, flag) \
1666 api_flags->isolate_flag = name();
1668#undef INIT_FROM_FIELD
1669 api_flags->is_service_isolate = false;
1670 api_flags->is_kernel_isolate = false;
1671 api_flags->null_safety = true;
1672}
1673
1675#if defined(DART_PRECOMPILER)
1676#define FLAG_FOR_PRECOMPILER(action) action
1677#else
1678#define FLAG_FOR_PRECOMPILER(action)
1679#endif
1680
1681#if !defined(PRODUCT)
1682#define FLAG_FOR_NONPRODUCT(action) action
1683#else
1684#define FLAG_FOR_NONPRODUCT(action)
1685#endif
1686
1687#define FLAG_FOR_PRODUCT(action) action
1688
1689#define SET_FROM_FLAG(when, name, bitname, isolate_flag, flag) \
1690 FLAG_FOR_##when(isolate_flags_ = bitname##Bit::update( \
1691 api_flags.isolate_flag, isolate_flags_));
1692
1694#undef FLAG_FOR_NONPRODUCT
1695#undef FLAG_FOR_PRECOMPILER
1696#undef FLAG_FOR_PRODUCT
1697#undef SET_FROM_FLAG
1698}
1699
1700#if defined(DEBUG)
1701// static
1702void BaseIsolate::AssertCurrent(BaseIsolate* isolate) {
1703 ASSERT(isolate == Isolate::Current());
1704}
1705#endif // defined(DEBUG)
1706
1707#if defined(DEBUG)
1708#define REUSABLE_HANDLE_SCOPE_INIT(object) \
1709 reusable_##object##_handle_scope_active_(false),
1710#else
1711#define REUSABLE_HANDLE_SCOPE_INIT(object)
1712#endif // defined(DEBUG)
1713
1714#define REUSABLE_HANDLE_INITIALIZERS(object) object##_handle_(nullptr),
1715
1717 public:
1718 static bool ReportStats() { return false; }
1719 static const char* Name() { return "LibraryPrefixMapTraits"; }
1720
1721 static bool IsMatch(const Object& a, const Object& b) {
1722 if (!a.IsLibraryPrefix() || !b.IsLibraryPrefix()) {
1723 return false;
1724 }
1725 return a.ptr() == b.ptr();
1726 }
1727
1728 static uword Hash(const Object& obj) {
1729 auto& prefix = LibraryPrefix::Cast(obj);
1730 return String::Hash(prefix.name());
1731 }
1732};
1733
1734// TODO(srdjan): Some Isolate monitors can be shared. Replace their usage with
1735// that shared monitor.
1736Isolate::Isolate(IsolateGroup* isolate_group,
1737 const Dart_IsolateFlags& api_flags)
1738 : BaseIsolate(),
1739 current_tag_(UserTag::null()),
1740 default_tag_(UserTag::null()),
1741 field_table_(new FieldTable(/*isolate=*/this)),
1742 finalizers_(GrowableObjectArray::null()),
1743 isolate_group_(isolate_group),
1744 isolate_object_store_(new IsolateObjectStore()),
1745 isolate_flags_(0),
1746#if !defined(PRODUCT)
1747 last_resume_timestamp_(OS::GetCurrentTimeMillis()),
1748 vm_tag_counters_(),
1749 pending_service_extension_calls_(GrowableObjectArray::null()),
1750 registered_service_extension_handlers_(GrowableObjectArray::null()),
1751#define ISOLATE_METRIC_CONSTRUCTORS(type, variable, name, unit) \
1752 metric_##variable##_(),
1755#endif // !defined(PRODUCT)
1756 start_time_micros_(OS::GetCurrentMonotonicMicros()),
1757 message_notify_callback_(nullptr),
1758 on_shutdown_callback_(Isolate::ShutdownCallback()),
1759 on_cleanup_callback_(Isolate::CleanupCallback()),
1760 random_(),
1761 mutex_(NOT_IN_PRODUCT("Isolate::mutex_")),
1762 tag_table_(GrowableObjectArray::null()),
1763 sticky_error_(Error::null()),
1764 spawn_count_monitor_(),
1765 handler_info_cache_(),
1766 catch_entry_moves_cache_(),
1767 wake_pause_event_handler_count_(0),
1768 loaded_prefixes_set_storage_(nullptr) {
1769 FlagsCopyFrom(api_flags);
1770 SetErrorsFatal(true);
1771 // TODO(asiva): A Thread is not available here, need to figure out
1772 // how the vm_tag (kEmbedderTagId) can be set, these tags need to
1773 // move to the OSThread structure.
1774 set_user_tag(UserTags::kDefaultUserTag);
1775}
1776
1777#undef REUSABLE_HANDLE_SCOPE_INIT
1778#undef REUSABLE_HANDLE_INITIALIZERS
1779
1781#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
1782 // TODO(32796): Re-enable assertion.
1783 // RELEASE_ASSERT(program_reload_context_ == nullptr);
1784#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
1785
1786#if !defined(PRODUCT)
1787 delete debugger_;
1788 debugger_ = nullptr;
1789 delete object_id_ring_;
1790 object_id_ring_ = nullptr;
1791 delete pause_loop_monitor_;
1792 pause_loop_monitor_ = nullptr;
1793#endif // !defined(PRODUCT)
1794
1795 free(name_);
1796 delete field_table_;
1797#if defined(USING_SIMULATOR)
1798 delete simulator_;
1799#endif
1800 delete message_handler_;
1801 message_handler_ =
1802 nullptr; // Fail fast if we send messages to a dead isolate.
1803 ASSERT(deopt_context_ ==
1804 nullptr); // No deopt in progress when isolate deleted.
1805 ASSERT(spawn_count_ == 0);
1806
1807 // The [Thread] object should've been released on the last
1808 // `Thread::ExitIsolate()` call.
1810 ASSERT(mutator_thread_ == nullptr);
1811}
1812
1813void Isolate::InitVM() {
1814 create_group_callback_ = nullptr;
1815 initialize_callback_ = nullptr;
1816 shutdown_callback_ = nullptr;
1817 cleanup_callback_ = nullptr;
1818 cleanup_group_callback_ = nullptr;
1819 register_kernel_blob_callback_ = nullptr;
1820 unregister_kernel_blob_callback_ = nullptr;
1821 if (isolate_creation_monitor_ == nullptr) {
1822 isolate_creation_monitor_ = new Monitor();
1823 }
1824 ASSERT(isolate_creation_monitor_ != nullptr);
1826}
1827
1828Isolate* Isolate::InitIsolate(const char* name_prefix,
1829 IsolateGroup* isolate_group,
1830 const Dart_IsolateFlags& api_flags,
1831 bool is_vm_isolate) {
1832 Isolate* result = new Isolate(isolate_group, api_flags);
1833 result->set_is_vm_isolate(is_vm_isolate);
1834 result->BuildName(name_prefix);
1835 if (!is_vm_isolate) {
1836 // vm isolate object store is initialized later, after null instance
1837 // is created (in Dart::Init).
1838 // Non-vm isolates need to have isolate object store initialized is that
1839 // exit_listeners have to be null-initialized as they will be used if
1840 // we fail to create isolate below, have to do low level shutdown.
1841 ASSERT(result->group()->object_store() != nullptr);
1842 result->isolate_object_store()->Init();
1843 }
1844
1845 ASSERT(result != nullptr);
1846
1847#if !defined(PRODUCT)
1848// Initialize metrics.
1849#define ISOLATE_METRIC_INIT(type, variable, name, unit) \
1850 result->metric_##variable##_.InitInstance(result, name, nullptr, \
1851 Metric::unit);
1853#undef ISOLATE_METRIC_INIT
1854#endif // !defined(PRODUCT)
1855
1856 // First we ensure we enter the isolate. This will ensure we're participating
1857 // in any safepointing requests from this point on. Other threads requesting a
1858 // safepoint operation will therefore wait until we've stopped.
1859 //
1860 // Though the [result] isolate is still in a state where no memory has been
1861 // allocated, which means it's safe to GC the isolate group until here.
1863
1864 // Setup the isolate message handler.
1865 result->message_handler_ = new IsolateMessageHandler(result);
1866
1867 result->set_main_port(PortMap::CreatePort(result->message_handler()));
1868#if defined(DEBUG)
1869 // Verify that we are never reusing a live origin id.
1870 VerifyOriginId id_verifier(result->main_port());
1871 Isolate::VisitIsolates(&id_verifier);
1872#endif
1873 result->set_origin_id(result->main_port());
1874
1875 // Keep capability IDs less than 2^53 so web clients of the service
1876 // protocol can process it properly.
1877 //
1878 // See https://github.com/dart-lang/sdk/issues/53081.
1879 result->set_pause_capability(result->random()->NextJSInt());
1880 result->set_terminate_capability(result->random()->NextJSInt());
1881
1882#if !defined(PRODUCT)
1883 result->debugger_ = new Debugger(result);
1884#endif
1885
1886 // Now we register the isolate in the group. From this point on any GC would
1887 // traverse the isolate roots (before this point, the roots are only pointing
1888 // to vm-isolate objects, e.g. null)
1889 isolate_group->RegisterIsolate(result);
1890
1891 if (api_flags.is_service_isolate) {
1894#if !defined(DART_PRECOMPILED_RUNTIME)
1895 } else if (api_flags.is_kernel_isolate) {
1898#endif // !defined(DART_PRECOMPILED_RUNTIME)
1899 }
1900
1901 if (FLAG_trace_isolates) {
1902 if (name_prefix == nullptr || strcmp(name_prefix, "vm-isolate") != 0) {
1904 "[+] Starting isolate:\n"
1905 "\tisolate: %s\n",
1906 result->name());
1907 }
1908 }
1909
1910 // Add to isolate list. Shutdown and delete the isolate on failure.
1911 if (!TryMarkIsolateReady(result)) {
1912 result->LowLevelShutdown();
1913 Isolate::LowLevelCleanup(result);
1914 return nullptr;
1915 }
1916
1917 return result;
1918}
1919
1921 ASSERT(thread_registry() != nullptr);
1922 return mutator_thread_;
1923}
1924
1926 const Object& arg1,
1927 const Object& arg2) {
1928 Thread* thread = Thread::Current();
1929 Api::Scope api_scope(thread);
1930 Dart_Handle api_arg1 = Api::NewHandle(thread, arg1.ptr());
1931 Dart_Handle api_arg2 = Api::NewHandle(thread, arg2.ptr());
1932 Dart_Handle api_result;
1933 {
1934 TransitionVMToNative transition(thread);
1936 api_result = library_tag_handler()(tag, api_arg1, api_arg2);
1937 }
1938 return Api::UnwrapHandle(api_result);
1939}
1940
1942 Thread* thread = Thread::Current();
1943 Api::Scope api_scope(thread);
1944 Dart_Handle api_result;
1945 {
1946 TransitionVMToNative transition(thread);
1948 api_result = group()->deferred_load_handler()(id);
1949 }
1950 return Api::UnwrapHandle(api_result);
1951}
1952
1953void IsolateGroup::SetupImagePage(const uint8_t* image_buffer,
1954 bool is_executable) {
1955 Image image(image_buffer);
1956 heap()->SetupImagePage(image.object_start(), image.object_size(),
1957 is_executable);
1958}
1959
1961 SafepointReadRwLocker ml(Thread::Current(), isolates_lock_.get());
1962 for (Isolate* isolate : isolates_) {
1963 isolate->ScheduleInterrupts(interrupt_bits);
1964 }
1965}
1966
1968 // We take the threads lock here to ensure that the mutator thread does not
1969 // exit the isolate while we are trying to schedule interrupts on it.
1970 MonitorLocker ml(group()->thread_registry()->threads_lock());
1971 Thread* mthread = mutator_thread();
1972 if (mthread != nullptr) {
1973 mthread->ScheduleInterrupts(interrupt_bits);
1974 }
1975}
1976
1977void Isolate::set_name(const char* name) {
1978 free(name_);
1979 name_ = Utils::StrDup(name);
1980}
1981
1983 return OS::GetCurrentMonotonicMicros() - start_time_micros_;
1984}
1985
1986int64_t Isolate::UptimeMicros() const {
1987 return OS::GetCurrentMonotonicMicros() - start_time_micros_;
1988}
1989
1991 MutexLocker ml(&origin_id_mutex_);
1992 return origin_id_;
1993}
1994
1996 MutexLocker ml(&origin_id_mutex_);
1997 ASSERT((id == main_port_ && origin_id_ == 0) || (origin_id_ == main_port_));
1998 origin_id_ = id;
1999}
2000
2002 finalizers_ = value.ptr();
2003}
2004
2005bool Isolate::IsPaused() const {
2006#if defined(PRODUCT)
2007 return false;
2008#else
2009 return (debugger_ != nullptr) && (debugger_->PauseEvent() != nullptr);
2010#endif // !defined(PRODUCT)
2011}
2012
2014#if !defined(PRODUCT)
2015 if (debugger_ == nullptr) {
2016 return Error::null();
2017 }
2018 ASSERT(!IsPaused());
2019 const Error& error = Error::Handle(debugger_->PausePostRequest());
2020 if (!error.IsNull()) {
2021 if (Thread::Current()->top_exit_frame_info() == 0) {
2022 return error.ptr();
2023 } else {
2025 UNREACHABLE();
2026 }
2027 }
2028#endif
2029 return Error::null();
2030}
2031
2032void Isolate::BuildName(const char* name_prefix) {
2033 ASSERT(name_ == nullptr);
2034 if (name_prefix == nullptr) {
2035 name_ = OS::SCreate(nullptr, "isolate-%" Pd64 "", main_port());
2036 } else {
2037 name_ = Utils::StrDup(name_prefix);
2038 }
2039}
2040
2041#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2043 // We only call this method on the mutator thread. Normally the caller is
2044 // inside of the "reloadSources" service OOB message handler. Though
2045 // we also use it in the slow path of StackOverflowCheck in the artificial
2046 // --hot-reload-test-mode like flags.
2047 //
2048 // During reload itself we don't process OOB messages and don't execute Dart
2049 // code, so the caller should implicitly have a guarantee we're not reloading
2050 // already.
2051 RELEASE_ASSERT(!Thread::Current()->OwnsReloadSafepoint());
2052
2053 // We only allow reload to take place from the point on where the first
2054 // isolate within an isolate group has setup it's root library. From that
2055 // point on it's safe to perform hot-reload.
2056 auto thread = Thread::Current();
2057 if (object_store()->root_library() == Library::null()) {
2058 return false;
2059 }
2060
2061 // We only care about the current thread's [NoReloadScope]. If we're inside
2062 // one we cannot reload right now. Though if another isolate's mutator
2063 // thread is inside such a scope, the multi-isolate reload will simply wait
2064 // until it's out of that scope again.
2065 if (thread->no_reload_scope_depth_ != 0) {
2066 return false;
2067 }
2068
2069 return !IsolateGroup::IsSystemIsolateGroup(this) &&
2071}
2072
2074 bool force_reload,
2075 const char* root_script_url,
2076 const char* packages_url,
2077 bool dont_delete_reload_context) {
2078 ASSERT(!IsReloading());
2079
2080 // Ensure all isolates inside the isolate group are paused at a place where we
2081 // can safely do a reload.
2083
2085 std::shared_ptr<IsolateGroupReloadContext> group_reload_context(
2087 group_reload_context_ = group_reload_context;
2088
2090 program_reload_context_ =
2091 new ProgramReloadContext(group_reload_context_, this);
2092 const bool success =
2093 group_reload_context_->Reload(force_reload, root_script_url, packages_url,
2094 /*kernel_buffer=*/nullptr,
2095 /*kernel_buffer_size=*/0);
2096 if (!dont_delete_reload_context) {
2098 }
2099 return success;
2100}
2101
2103 bool force_reload,
2104 const uint8_t* kernel_buffer,
2105 intptr_t kernel_buffer_size,
2106 bool dont_delete_reload_context) {
2107 ASSERT(!IsReloading());
2108
2109 // Ensure all isolates inside the isolate group are paused at a place where we
2110 // can safely do a reload.
2112
2114 std::shared_ptr<IsolateGroupReloadContext> group_reload_context(
2116 group_reload_context_ = group_reload_context;
2117
2119 program_reload_context_ =
2120 new ProgramReloadContext(group_reload_context_, this);
2121 const bool success = group_reload_context_->Reload(
2122 force_reload,
2123 /*root_script_url=*/nullptr,
2124 /*packages_url=*/nullptr, kernel_buffer, kernel_buffer_size);
2125 if (!dont_delete_reload_context) {
2127 }
2128 return success;
2129}
2130
2132 GcSafepointOperationScope safepoint_scope(Thread::Current());
2133 group_reload_context_.reset();
2134
2135 delete program_reload_context_;
2136 program_reload_context_ = nullptr;
2137}
2138#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2139
2141 MutexLocker ml(&mutex_);
2142 // Check if we are in a valid state to make the isolate runnable.
2143 if (is_runnable() == true) {
2144 return "Isolate is already runnable";
2145 }
2146 if (group()->object_store()->root_library() == Library::null()) {
2147 return "The embedder has to ensure there is a root library (e.g. by "
2148 "calling Dart_LoadScriptFromKernel ).";
2149 }
2151 return nullptr;
2152}
2153
2156 ASSERT(!is_runnable());
2157 ASSERT(group()->object_store()->root_library() != Library::null());
2158
2159 // Set the isolate as runnable and if we are being spawned schedule
2160 // isolate on thread pool for execution.
2161 set_is_runnable(true);
2162#ifndef PRODUCT
2163 if (!Isolate::IsSystemIsolate(this)) {
2164 if (FLAG_pause_isolates_on_unhandled_exceptions) {
2166 }
2167 }
2168#endif // !PRODUCT
2169#if defined(SUPPORT_TIMELINE)
2170 TimelineStream* stream = Timeline::GetIsolateStream();
2171 ASSERT(stream != nullptr);
2172 TimelineEvent* event = stream->StartEvent();
2173 if (event != nullptr) {
2174 event->Instant("Runnable");
2175 event->Complete();
2176 }
2177#endif
2178#ifndef PRODUCT
2179 if (!Isolate::IsSystemIsolate(this) && Service::isolate_stream.enabled()) {
2180 ServiceEvent runnableEvent(this, ServiceEvent::kIsolateRunnable);
2181 Service::HandleEvent(&runnableEvent, /* enter_safepoint */ false);
2182 }
2183 GetRunnableLatencyMetric()->set_value(UptimeMicros());
2184#endif // !PRODUCT
2185}
2186
2187bool Isolate::VerifyPauseCapability(const Object& capability) const {
2188 return !capability.IsNull() && capability.IsCapability() &&
2189 (pause_capability() == Capability::Cast(capability).Id());
2190}
2191
2192bool Isolate::VerifyTerminateCapability(const Object& capability) const {
2193 return !capability.IsNull() && capability.IsCapability() &&
2194 (terminate_capability() == Capability::Cast(capability).Id());
2195}
2196
2198 // Ensure a limit for the number of resume capabilities remembered.
2199 const intptr_t kMaxResumeCapabilities =
2201
2203 current_zone(), isolate_object_store()->resume_capabilities());
2204 Capability& current = Capability::Handle(current_zone());
2205 intptr_t insertion_index = -1;
2206 for (intptr_t i = 0; i < caps.Length(); i++) {
2207 current ^= caps.At(i);
2208 if (current.IsNull()) {
2209 if (insertion_index < 0) {
2210 insertion_index = i;
2211 }
2212 } else if (current.Id() == capability.Id()) {
2213 return false;
2214 }
2215 }
2216 if (insertion_index < 0) {
2217 if (caps.Length() >= kMaxResumeCapabilities) {
2218 // Cannot grow the array of resume capabilities beyond its max. Additional
2219 // pause requests are ignored. In practice will never happen as we will
2220 // run out of memory beforehand.
2221 return false;
2222 }
2223 caps.Add(capability);
2224 } else {
2225 caps.SetAt(insertion_index, capability);
2226 }
2227 return true;
2228}
2229
2232 current_zone(), isolate_object_store()->resume_capabilities());
2233 Capability& current = Capability::Handle(current_zone());
2234 for (intptr_t i = 0; i < caps.Length(); i++) {
2235 current ^= caps.At(i);
2236 if (!current.IsNull() && (current.Id() == capability.Id())) {
2237 // Remove the matching capability from the list.
2238 current = Capability::null();
2239 caps.SetAt(i, current);
2240 return true;
2241 }
2242 }
2243 return false;
2244}
2245
2246// TODO(iposva): Remove duplicated code and start using some hash based
2247// structure instead of these linear lookups.
2249 const Instance& response) {
2250 // Ensure a limit for the number of listeners remembered.
2251 const intptr_t kMaxListeners = compiler::target::kSmiMax / (12 * kWordSize);
2252
2254 current_zone(), isolate_object_store()->exit_listeners());
2255 SendPort& current = SendPort::Handle(current_zone());
2256 intptr_t insertion_index = -1;
2257 for (intptr_t i = 0; i < listeners.Length(); i += 2) {
2258 current ^= listeners.At(i);
2259 if (current.IsNull()) {
2260 if (insertion_index < 0) {
2261 insertion_index = i;
2262 }
2263 } else if (current.Id() == listener.Id()) {
2264 listeners.SetAt(i + 1, response);
2265 return;
2266 }
2267 }
2268 if (insertion_index < 0) {
2269 if (listeners.Length() >= kMaxListeners) {
2270 // Cannot grow the array of listeners beyond its max. Additional
2271 // listeners are ignored. In practice will never happen as we will
2272 // run out of memory beforehand.
2273 return;
2274 }
2275 listeners.Add(listener);
2276 listeners.Add(response);
2277 } else {
2278 listeners.SetAt(insertion_index, listener);
2279 listeners.SetAt(insertion_index + 1, response);
2280 }
2281}
2282
2285 current_zone(), isolate_object_store()->exit_listeners());
2286 SendPort& current = SendPort::Handle(current_zone());
2287 for (intptr_t i = 0; i < listeners.Length(); i += 2) {
2288 current ^= listeners.At(i);
2289 if (!current.IsNull() && (current.Id() == listener.Id())) {
2290 // Remove the matching listener from the list.
2291 current = SendPort::null();
2292 listeners.SetAt(i, current);
2293 listeners.SetAt(i + 1, Object::null_instance());
2294 return;
2295 }
2296 }
2297}
2298
2301 current_zone(), isolate_object_store()->exit_listeners());
2302 if (listeners.IsNull()) return;
2303
2304 SendPort& listener = SendPort::Handle(current_zone());
2305 Instance& response = Instance::Handle(current_zone());
2306 for (intptr_t i = 0; i < listeners.Length(); i += 2) {
2307 listener ^= listeners.At(i);
2308 if (!listener.IsNull()) {
2309 Dart_Port port_id = listener.Id();
2310 response ^= listeners.At(i + 1);
2311 PortMap::PostMessage(SerializeMessage(port_id, response));
2312 }
2313 }
2314}
2315
2317 // Ensure a limit for the number of listeners remembered.
2318 const intptr_t kMaxListeners = compiler::target::kSmiMax / (6 * kWordSize);
2319
2321 current_zone(), isolate_object_store()->error_listeners());
2322 SendPort& current = SendPort::Handle(current_zone());
2323 intptr_t insertion_index = -1;
2324 for (intptr_t i = 0; i < listeners.Length(); i++) {
2325 current ^= listeners.At(i);
2326 if (current.IsNull()) {
2327 if (insertion_index < 0) {
2328 insertion_index = i;
2329 }
2330 } else if (current.Id() == listener.Id()) {
2331 return;
2332 }
2333 }
2334 if (insertion_index < 0) {
2335 if (listeners.Length() >= kMaxListeners) {
2336 // Cannot grow the array of listeners beyond its max. Additional
2337 // listeners are ignored. In practice will never happen as we will
2338 // run out of memory beforehand.
2339 return;
2340 }
2341 listeners.Add(listener);
2342 } else {
2343 listeners.SetAt(insertion_index, listener);
2344 }
2345}
2346
2349 current_zone(), isolate_object_store()->error_listeners());
2350 SendPort& current = SendPort::Handle(current_zone());
2351 for (intptr_t i = 0; i < listeners.Length(); i++) {
2352 current ^= listeners.At(i);
2353 if (!current.IsNull() && (current.Id() == listener.Id())) {
2354 // Remove the matching listener from the list.
2355 current = SendPort::null();
2356 listeners.SetAt(i, current);
2357 return;
2358 }
2359 }
2360}
2361
2363 const char* stacktrace) {
2365 current_zone(), isolate_object_store()->error_listeners());
2366 if (listeners.IsNull()) return false;
2367
2368 Dart_CObject arr;
2369 Dart_CObject* arr_values[2];
2371 arr.value.as_array.length = 2;
2372 arr.value.as_array.values = arr_values;
2373 Dart_CObject msg;
2375 msg.value.as_string = const_cast<char*>(message);
2376 arr_values[0] = &msg;
2377 Dart_CObject stack;
2378 if (stacktrace == nullptr) {
2379 stack.type = Dart_CObject_kNull;
2380 } else {
2381 stack.type = Dart_CObject_kString;
2382 stack.value.as_string = const_cast<char*>(stacktrace);
2383 }
2384 arr_values[1] = &stack;
2385
2386 SendPort& listener = SendPort::Handle(current_zone());
2387 bool was_somebody_notified = false;
2388 for (intptr_t i = 0; i < listeners.Length(); i++) {
2389 listener ^= listeners.At(i);
2390 if (!listener.IsNull()) {
2391 Dart_Port port_id = listener.Id();
2392 PortMap::PostMessage(SerializeMessage(current_zone(), port_id, &arr));
2393 was_somebody_notified = true;
2394 }
2395 }
2396 return was_somebody_notified;
2397}
2398
2399static void ShutdownIsolate(uword parameter) {
2400 Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(parameter));
2402}
2403
2404void Isolate::SetStickyError(ErrorPtr sticky_error) {
2405 ASSERT(
2406 ((sticky_error_ == Error::null()) || (sticky_error == Error::null())) &&
2407 (sticky_error != sticky_error_));
2408 sticky_error_ = sticky_error;
2409}
2410
2412 message_handler()->Run(group()->thread_pool(), nullptr, ShutdownIsolate,
2413 reinterpret_cast<uword>(this));
2414}
2415
2417 return message_handler_;
2418}
2419
2420void Isolate::RunAndCleanupFinalizersOnShutdown() {
2421 if (finalizers_ == GrowableObjectArray::null()) return;
2422
2423 // Ensure we have a zone and handle scope so that we can call VM functions,
2424 // but we no longer allocate new heap objects.
2425 Thread* thread = Thread::Current();
2426 StackZone stack_zone(thread);
2427 HandleScope handle_scope(thread);
2428 NoSafepointScope no_safepoint_scope;
2429
2430 // Set live finalizers isolate to null, before deleting the message handler.
2431 const auto& finalizers =
2432 GrowableObjectArray::Handle(stack_zone.GetZone(), finalizers_);
2433 if (!finalizers.IsNull()) {
2434 const intptr_t num_finalizers = finalizers.Length();
2435 auto& weak_reference = WeakReference::Handle(stack_zone.GetZone());
2436 auto& finalizer = FinalizerBase::Handle(stack_zone.GetZone());
2437 auto& current_entry = FinalizerEntry::Handle(stack_zone.GetZone());
2438 auto& all_entries = Set::Handle(stack_zone.GetZone());
2439 for (int i = 0; i < num_finalizers; i++) {
2440 weak_reference ^= finalizers.At(i);
2441 finalizer ^= weak_reference.target();
2442 if (!finalizer.IsNull()) {
2443 if (finalizer.isolate() == this) {
2444 if (FLAG_trace_finalizers) {
2445 THR_Print("Isolate %p Setting finalizer %p isolate to null\n", this,
2446 finalizer.ptr()->untag());
2447 }
2448 // Finalizer was not sent to another isolate with send and exit.
2449 finalizer.set_isolate(nullptr);
2450 } else {
2451 // TODO(http://dartbug.com/47777): Send and exit support.
2452 UNREACHABLE();
2453 }
2454
2455 if (finalizer.IsNativeFinalizer()) {
2456 // Immediately call native callback.
2457 const auto& native_finalizer = NativeFinalizer::Cast(finalizer);
2458 all_entries = finalizer.all_entries();
2459 Set::Iterator iterator(all_entries);
2460 while (iterator.MoveNext()) {
2461 current_entry ^= iterator.CurrentKey();
2462 native_finalizer.RunCallback(current_entry, "Isolate shutdown");
2463 }
2464 }
2465 }
2466 }
2467 }
2468}
2469
2470void Isolate::LowLevelShutdown() {
2471 // Ensure we have a zone and handle scope so that we can call VM functions,
2472 // but we no longer allocate new heap objects.
2473 Thread* thread = Thread::Current();
2474 StackZone stack_zone(thread);
2475 HandleScope handle_scope(thread);
2476 NoSafepointScope no_safepoint_scope;
2477
2478 // Notify exit listeners that this isolate is shutting down.
2479 if (group()->object_store() != nullptr) {
2480 const Error& error = Error::Handle(thread->sticky_error());
2481 if (error.IsNull() || !error.IsUnwindError() ||
2482 UnwindError::Cast(error).is_user_initiated()) {
2484 }
2485 }
2486
2487 // Close all the ports owned by this isolate.
2489
2490 // Fail fast if anybody tries to post any more messages to this isolate.
2491 delete message_handler_;
2492 message_handler_ = nullptr;
2493
2494 // Clean up any synchronous FFI callbacks registered with this isolate. Skip
2495 // if this isolate never registered any.
2496 if (ffi_callback_list_head_ != nullptr) {
2498 &ffi_callback_list_head_);
2499 }
2500
2501#if !defined(PRODUCT)
2502 if (FLAG_dump_megamorphic_stats) {
2504 }
2505 if (FLAG_dump_symbol_stats) {
2507 }
2508 if (FLAG_trace_isolates) {
2509 group()->heap()->PrintSizes();
2511 "[-] Stopping isolate:\n"
2512 "\tisolate: %s\n",
2513 name());
2514 }
2515 if (FLAG_print_metrics) {
2516 LogBlock lb;
2517 OS::PrintErr("Printing metrics for %s\n", name());
2518#define ISOLATE_GROUP_METRIC_PRINT(type, variable, name, unit) \
2519 OS::PrintErr("%s\n", isolate_group_->Get##variable##Metric()->ToString());
2521#undef ISOLATE_GROUP_METRIC_PRINT
2522#define ISOLATE_METRIC_PRINT(type, variable, name, unit) \
2523 OS::PrintErr("%s\n", metric_##variable##_.ToString());
2525#undef ISOLATE_METRIC_PRINT
2526 OS::PrintErr("\n");
2527 }
2528#endif // !defined(PRODUCT)
2529}
2530
2531#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2533 if (FLAG_reload_every_back_off) {
2534 if (reload_every_n_stack_overflow_checks_ < 5000) {
2535 reload_every_n_stack_overflow_checks_ += 99;
2536 } else {
2537 const auto old_value = reload_every_n_stack_overflow_checks_;
2538 reload_every_n_stack_overflow_checks_ = old_value * old_value;
2539 }
2540 // Cap the value.
2541 if (reload_every_n_stack_overflow_checks_ > 1000000) {
2542 reload_every_n_stack_overflow_checks_ = 1000000;
2543 }
2544 }
2545}
2546#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2547
2549 std::unique_ptr<WeakTable> value(table);
2550 forward_table_new_ = std::move(value);
2551}
2553 std::unique_ptr<WeakTable> value(table);
2554 forward_table_old_ = std::move(value);
2555}
2556
2557void Isolate::Shutdown() {
2558 Thread* thread = Thread::Current();
2559 ASSERT(this == thread->isolate());
2560
2561 // Don't allow anymore dart code to execution on this isolate.
2562 thread->ClearStackLimit();
2563
2564 {
2565 StackZone zone(thread);
2567#if !defined(PRODUCT)
2568 HandleScope handle_scope(thread);
2569 debugger()->Shutdown();
2571#endif
2572 }
2573
2574#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2575 if (FLAG_check_reloaded && is_runnable() && !Isolate::IsSystemIsolate(this)) {
2576 if (!group()->HasAttemptedReload()) {
2577 FATAL(
2578 "Isolate did not reload before exiting and "
2579 "--check-reloaded is enabled.\n");
2580 }
2581 }
2582#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2583
2584 // Then, proceed with low-level teardown.
2585 Isolate::UnMarkIsolateReady(this);
2586
2587 // Ensure native finalizers are run before isolate has shutdown message is
2588 // sent. This way users can rely on the exit message that an isolate will not
2589 // run any Dart code anymore _and_ will not run any native finalizers anymore.
2590 RunAndCleanupFinalizersOnShutdown();
2591
2592 // Post message before LowLevelShutdown that sends onExit message.
2593 // This ensures that exit message comes last.
2594 if (bequest_ != nullptr) {
2595 auto beneficiary = bequest_->beneficiary();
2596 auto handle = bequest_->TakeHandle();
2598 Message::New(beneficiary, handle, Message::kNormalPriority));
2599 bequest_.reset();
2600 }
2601
2602 LowLevelShutdown();
2603
2604 // Now we can unregister from the thread, invoke cleanup callback, delete the
2605 // isolate (and possibly the isolate group).
2606 Isolate::LowLevelCleanup(this);
2607}
2608
2609void Isolate::LowLevelCleanup(Isolate* isolate) {
2610#if !defined(DART_PRECOMPILED_RUNTIME)
2611 if (isolate->is_kernel_isolate()) {
2613 }
2614#endif
2615 if (isolate->is_service_isolate()) {
2617 }
2618
2619 // Cache these two fields, since they are no longer available after the
2620 // `delete isolate` further down.
2621 IsolateGroup* isolate_group = isolate->isolate_group_;
2622 Dart_IsolateCleanupCallback cleanup = isolate->on_cleanup_callback();
2623 auto callback_data = isolate->init_callback_data_;
2624
2625 // From this point on the isolate is no longer visited by GC (which is ok,
2626 // since we're just going to delete it anyway).
2627 isolate_group->UnregisterIsolate(isolate);
2628
2629 // From this point on the isolate doesn't participate in safepointing
2630 // requests anymore.
2631 ASSERT(!Thread::Current()->HasActiveState());
2632 Thread::ExitIsolate(/*isolate_shutdown=*/true);
2633
2634 // Now it's safe to delete the isolate.
2635 delete isolate;
2636
2637 // Run isolate specific cleanup function for all non "vm-isolate's.
2638 const bool is_vm_isolate = Dart::vm_isolate() == isolate;
2639 if (!is_vm_isolate) {
2640 if (cleanup != nullptr) {
2641 cleanup(isolate_group->embedder_data(), callback_data);
2642 }
2643 }
2644
2645 const bool shutdown_group = isolate_group->UnregisterIsolateDecrementCount();
2646 if (shutdown_group) {
2648
2649 if (!is_vm_isolate) {
2651 /*bypass_safepoint=*/false);
2652#if !defined(DART_PRECOMPILED_RUNTIME)
2653 BackgroundCompiler::Stop(isolate_group);
2654#endif // !defined(DART_PRECOMPILED_RUNTIME)
2655
2656 // Finalize any weak persistent handles with a non-null referent with
2657 // isolate group still being available.
2658 FinalizeWeakPersistentHandlesVisitor visitor(isolate_group);
2659 isolate_group->api_state()->VisitWeakHandlesUnlocked(&visitor);
2660
2661 Thread::ExitIsolateGroupAsHelper(/*bypass_safepoint=*/false);
2662 }
2663
2664 // The "vm-isolate" does not have a thread pool.
2665 ASSERT(is_vm_isolate == (isolate_group->thread_pool() == nullptr));
2666 if (is_vm_isolate ||
2667 !isolate_group->thread_pool()->CurrentThreadIsWorker()) {
2668 isolate_group->Shutdown();
2669 } else {
2670 class ShutdownGroupTask : public ThreadPool::Task {
2671 public:
2672 explicit ShutdownGroupTask(IsolateGroup* isolate_group)
2673 : isolate_group_(isolate_group) {}
2674
2675 virtual void Run() { isolate_group_->Shutdown(); }
2676
2677 private:
2678 IsolateGroup* isolate_group_;
2679 };
2680 // The current thread is running on the isolate group's thread pool.
2681 // So we cannot safely delete the isolate group (and it's pool).
2682 // Instead we will destroy the isolate group on the VM-global pool.
2683 if (FLAG_trace_shutdown) {
2684 OS::PrintErr("[+%" Pd64 "ms] : Scheduling shutdown on VM pool %s\n",
2685 Dart::UptimeMillis(), isolate_group->source()->name);
2686 }
2687 Dart::thread_pool()->Run<ShutdownGroupTask>(isolate_group);
2688 }
2689 } else {
2690 // TODO(dartbug.com/36097): An isolate just died. A significant amount of
2691 // memory might have become unreachable. We should evaluate how to best
2692 // inform the GC about this situation.
2693 }
2694}
2695
2696Dart_InitializeIsolateCallback Isolate::initialize_callback_ = nullptr;
2697Dart_IsolateGroupCreateCallback Isolate::create_group_callback_ = nullptr;
2698Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = nullptr;
2699Dart_IsolateCleanupCallback Isolate::cleanup_callback_ = nullptr;
2700Dart_IsolateGroupCleanupCallback Isolate::cleanup_group_callback_ = nullptr;
2701Dart_RegisterKernelBlobCallback Isolate::register_kernel_blob_callback_ =
2702 nullptr;
2703Dart_UnregisterKernelBlobCallback Isolate::unregister_kernel_blob_callback_ =
2704 nullptr;
2705
2706Random* IsolateGroup::isolate_group_random_ = nullptr;
2707Monitor* Isolate::isolate_creation_monitor_ = nullptr;
2708bool Isolate::creation_enabled_ = false;
2709
2710RwLock* IsolateGroup::isolate_groups_rwlock_ = nullptr;
2711IntrusiveDList<IsolateGroup>* IsolateGroup::isolate_groups_ = nullptr;
2712
2713void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
2714 ValidationPolicy validate_frames) {
2715 ASSERT(visitor != nullptr);
2716
2717 // Visit objects in the field table.
2718 // N.B.: The heap snapshot writer requires visiting the field table first, so
2719 // that the pointer visitation order aligns with order of field name metadata.
2720 if (!visitor->trace_values_through_fields()) {
2721 field_table()->VisitObjectPointers(visitor);
2722 }
2723
2724 // Visit objects in the isolate object store.
2725 if (isolate_object_store() != nullptr) {
2727 }
2728
2729 visitor->clear_gc_root_type();
2730 // Visit the objects directly referenced from the isolate structure.
2731 visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&current_tag_));
2732 visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&default_tag_));
2733 visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&tag_table_));
2734 visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&sticky_error_));
2735 visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&finalizers_));
2736#if !defined(PRODUCT)
2737 visitor->VisitPointer(
2738 reinterpret_cast<ObjectPtr*>(&pending_service_extension_calls_));
2739 visitor->VisitPointer(
2740 reinterpret_cast<ObjectPtr*>(&registered_service_extension_handlers_));
2741#endif // !defined(PRODUCT)
2742
2743#if !defined(PRODUCT)
2744 // Visit objects in the debugger.
2745 if (debugger() != nullptr) {
2746 debugger()->VisitObjectPointers(visitor);
2747 }
2748 if (is_service_isolate()) {
2750 }
2751#endif // !defined(PRODUCT)
2752
2753#if !defined(DART_PRECOMPILED_RUNTIME)
2754 // Visit objects that are being used for deoptimization.
2755 if (deopt_context() != nullptr) {
2757 }
2758#endif // !defined(DART_PRECOMPILED_RUNTIME)
2759
2760 visitor->VisitPointer(
2761 reinterpret_cast<ObjectPtr*>(&loaded_prefixes_set_storage_));
2762
2763 if (pointers_to_verify_at_exit_.length() != 0) {
2764 visitor->VisitPointers(&pointers_to_verify_at_exit_[0],
2765 pointers_to_verify_at_exit_.length());
2766 }
2767}
2768
2769void Isolate::VisitStackPointers(ObjectPointerVisitor* visitor,
2770 ValidationPolicy validate_frames) {
2771 if (mutator_thread_ != nullptr) {
2772 mutator_thread_->VisitObjectPointers(visitor, validate_frames);
2773 }
2774}
2775
2778}
2779
2782}
2783
2785 if (mutator_thread_ != nullptr) {
2787 }
2788}
2789
2791 if (mutator_thread_ != nullptr) {
2793 }
2794}
2795
2797 ASSERT(loaded_prefixes_set_storage_ == nullptr);
2798 loaded_prefixes_set_storage_ =
2799 HashTables::New<UnorderedHashSet<LibraryPrefixMapTraits> >(4);
2800}
2801
2803 UnorderedHashSet<LibraryPrefixMapTraits> loaded_prefixes_set(
2804 loaded_prefixes_set_storage_);
2805 bool result = loaded_prefixes_set.GetOrNull(prefix) != Object::null();
2806 loaded_prefixes_set.Release();
2807 return result;
2808}
2809
2811 UnorderedHashSet<LibraryPrefixMapTraits> loaded_prefixes_set(
2812 loaded_prefixes_set_storage_);
2813 loaded_prefixes_set.InsertOrGet(prefix);
2814 loaded_prefixes_set_storage_ = loaded_prefixes_set.Release().ptr();
2815}
2816
2818 MarkingStack* old_marking_stack,
2819 MarkingStack* new_marking_stack,
2820 MarkingStack* deferred_marking_stack) {
2821 ASSERT(old_marking_stack_ == nullptr);
2822 old_marking_stack_ = old_marking_stack;
2823 ASSERT(new_marking_stack_ == nullptr);
2824 new_marking_stack_ = new_marking_stack;
2825 ASSERT(deferred_marking_stack_ == nullptr);
2826 deferred_marking_stack_ = deferred_marking_stack;
2828 ASSERT(Thread::Current()->is_marking());
2829}
2830
2833 ASSERT(old_marking_stack_ != nullptr);
2834 old_marking_stack_ = nullptr;
2835 ASSERT(new_marking_stack_ != nullptr);
2836 new_marking_stack_ = nullptr;
2837 ASSERT(deferred_marking_stack_ != nullptr);
2838 deferred_marking_stack_ = nullptr;
2839}
2840
2842 std::function<void(Isolate* isolate)> function,
2843 bool at_safepoint) {
2844 auto thread = Thread::Current();
2845 if (at_safepoint) {
2846 ASSERT(thread->OwnsSafepoint() ||
2847 (thread->task_kind() == Thread::kMutatorTask) ||
2848 (thread->task_kind() == Thread::kMarkerTask) ||
2849 (thread->task_kind() == Thread::kCompactorTask) ||
2850 (thread->task_kind() == Thread::kScavengerTask) ||
2852 for (Isolate* isolate : isolates_) {
2853 function(isolate);
2854 }
2855 return;
2856 }
2857 if (thread != nullptr && thread->OwnsSafepoint()) {
2858 for (Isolate* isolate : isolates_) {
2859 function(isolate);
2860 }
2861 return;
2862 }
2863 SafepointReadRwLocker ml(thread, isolates_lock_.get());
2864 for (Isolate* isolate : isolates_) {
2865 function(isolate);
2866 }
2867}
2868
2870 SafepointReadRwLocker ml(Thread::Current(), isolates_lock_.get());
2871 return FirstIsolateLocked();
2872}
2873
2875 return isolates_.IsEmpty() ? nullptr : isolates_.First();
2876}
2877
2879 Callable* single_current_mutator,
2880 Callable* otherwise,
2881 bool use_force_growth_in_otherwise) {
2882 auto thread = Thread::Current();
2883 StoppedMutatorsScope stopped_mutators_scope(thread);
2884
2885 if (thread->OwnsSafepoint()) {
2886 RELEASE_ASSERT(thread->OwnsSafepoint());
2887 single_current_mutator->Call();
2888 return;
2889 }
2890
2891 {
2892 SafepointReadRwLocker ml(thread, isolates_lock_.get());
2893 if (thread->IsDartMutatorThread() && ContainsOnlyOneIsolate()) {
2894 single_current_mutator->Call();
2895 return;
2896 }
2897 }
2898
2899 // We use the more strict safepoint operation scope here (which ensures that
2900 // all other threads, including auxiliary threads are at a safepoint), even
2901 // though we only need to ensure that the mutator threads are stopped.
2902 if (use_force_growth_in_otherwise) {
2903 ForceGrowthSafepointOperationScope safepoint_scope(
2905 otherwise->Call();
2906 } else {
2907 DeoptSafepointOperationScope safepoint_scope(thread);
2908 otherwise->Call();
2909 }
2910}
2911
2913 ValidationPolicy validate_frames) {
2914 VisitSharedPointers(visitor);
2915 for (Isolate* isolate : isolates_) {
2916 isolate->VisitObjectPointers(visitor, validate_frames);
2917 }
2918 VisitStackPointers(visitor, validate_frames);
2919}
2920
2922 // Visit objects in the class table.
2923 class_table()->VisitObjectPointers(visitor);
2926 }
2928 // Visit objects in the object store.
2929 if (object_store() != nullptr) {
2931 }
2932 visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&saved_unlinked_calls_));
2936
2937 // Visit the boxed_field_list_.
2938 // 'boxed_field_list_' access via mutator and background compilation threads
2939 // is guarded with a monitor. This means that we can visit it only
2940 // when at safepoint or the field_list_mutex_ lock has been taken.
2941 visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&boxed_field_list_));
2942
2943 NOT_IN_PRECOMPILED(background_compiler()->VisitPointers(visitor));
2944
2945#if !defined(PRODUCT)
2946 if (debugger() != nullptr) {
2947 debugger()->VisitObjectPointers(visitor);
2948 }
2949#endif
2950
2951#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2952 // Visit objects that are being used for isolate reload.
2953 if (program_reload_context() != nullptr) {
2954 program_reload_context()->VisitObjectPointers(visitor);
2955 program_reload_context()->group_reload_context()->VisitObjectPointers(
2956 visitor);
2957 }
2958#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2959
2960 if (source()->loaded_blobs_ != nullptr) {
2961 visitor->VisitPointer(
2962 reinterpret_cast<ObjectPtr*>(&(source()->loaded_blobs_)));
2963 }
2964
2965 if (become() != nullptr) {
2966 become()->VisitObjectPointers(visitor);
2967 }
2968}
2969
2971 ValidationPolicy validate_frames) {
2972 visitor->set_gc_root_type("stack");
2973
2974 // Visit objects in all threads (e.g. Dart stack, handles in zones), except
2975 // for the mutator threads themselves.
2976 thread_registry()->VisitObjectPointers(this, visitor, validate_frames);
2977
2978 for (Isolate* isolate : isolates_) {
2979 // Visit mutator thread, even if the isolate isn't entered/scheduled
2980 // (there might be live API handles to visit).
2981 isolate->VisitStackPointers(visitor, validate_frames);
2982 }
2983
2984 visitor->clear_gc_root_type();
2985}
2986
2988#if !defined(PRODUCT)
2989 for (Isolate* isolate : isolates_) {
2990 ObjectIdRing* ring = isolate->object_id_ring();
2991 if (ring != nullptr) {
2992 ring->VisitPointers(visitor);
2993 }
2994 }
2995#endif // !defined(PRODUCT)
2996}
2997
3000}
3001
3004 [&](Isolate* isolate) { isolate->DeferredMarkLiveTemporaries(); },
3005 /*at_safepoint=*/true);
3006}
3007
3009 ForEachIsolate([&](Isolate* isolate) { isolate->RememberLiveTemporaries(); },
3010 /*at_safepoint=*/true);
3011}
3012
3013#if !defined(PRODUCT)
3015 if (object_id_ring_ == nullptr) {
3016 object_id_ring_ = new ObjectIdRing();
3017 }
3018 return object_id_ring_;
3019}
3020#endif // !defined(PRODUCT)
3021
3022#ifndef PRODUCT
3024 switch (pi) {
3026 return "All";
3028 return "None";
3030 return "Unhandled";
3031 default:
3032 UNIMPLEMENTED();
3033 return nullptr;
3034 }
3035}
3036
3038 if (!isolate->is_runnable()) {
3039 // Isolate is not yet runnable.
3040 ASSERT((isolate->debugger() == nullptr) ||
3041 (isolate->debugger()->PauseEvent() == nullptr));
3042 return ServiceEvent(isolate, ServiceEvent::kNone);
3043 } else if (isolate->message_handler()->should_pause_on_start()) {
3044 if (isolate->message_handler()->is_paused_on_start()) {
3045 ASSERT((isolate->debugger() == nullptr) ||
3046 (isolate->debugger()->PauseEvent() == nullptr));
3047 return ServiceEvent(isolate, ServiceEvent::kPauseStart);
3048 } else {
3049 // Isolate is runnable but not paused on start.
3050 // Some service clients get confused if they see:
3051 // NotRunnable -> Runnable -> PausedAtStart
3052 // Treat Runnable+ShouldPauseOnStart as NotRunnable so they see:
3053 // NonRunnable -> PausedAtStart
3054 // The should_pause_on_start flag is set to false after resume.
3055 ASSERT((isolate->debugger() == nullptr) ||
3056 (isolate->debugger()->PauseEvent() == nullptr));
3057 return ServiceEvent(isolate, ServiceEvent::kNone);
3058 }
3059 } else if (isolate->message_handler()->is_paused_on_exit() &&
3060 ((isolate->debugger() == nullptr) ||
3061 (isolate->debugger()->PauseEvent() == nullptr))) {
3062 return ServiceEvent(isolate, ServiceEvent::kPauseExit);
3063 } else if ((isolate->debugger() != nullptr) &&
3064 (isolate->debugger()->PauseEvent() != nullptr) &&
3065 !isolate->ResumeRequest()) {
3066 return *(isolate->debugger()->PauseEvent());
3067 } else {
3068 ServiceEvent pause_event(isolate, ServiceEvent::kResume);
3069
3070#if !defined(DART_PRECOMPILED_RUNTIME)
3071 if (isolate->debugger() != nullptr) {
3072 // TODO(turnidge): Don't compute a full stack trace.
3073 DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
3074 if (stack->Length() > 0) {
3075 pause_event.set_top_frame(stack->FrameAt(0));
3076 }
3077 }
3078#endif
3079
3080 return pause_event;
3081 }
3082}
3083
3085 JSONObject jsobj(stream);
3086 jsobj.AddProperty("type", (ref ? "@Isolate" : "Isolate"));
3088 static_cast<int64_t>(main_port()));
3089
3090 jsobj.AddProperty("name", name());
3091 jsobj.AddPropertyF("number", "%" Pd64 "", static_cast<int64_t>(main_port()));
3092 jsobj.AddProperty("isSystemIsolate", is_system_isolate());
3094 group()->id());
3095 if (ref) {
3096 return;
3097 }
3098 jsobj.AddPropertyF("_originNumber", "%" Pd64 "",
3099 static_cast<int64_t>(origin_id()));
3100 int64_t uptime_millis = UptimeMicros() / kMicrosecondsPerMillisecond;
3101 int64_t start_time = OS::GetCurrentTimeMillis() - uptime_millis;
3102 jsobj.AddPropertyTimeMillis("startTime", start_time);
3103 {
3104 JSONObject jsheap(&jsobj, "_heaps");
3105 group()->heap()->PrintToJSONObject(Heap::kNew, &jsheap);
3106 group()->heap()->PrintToJSONObject(Heap::kOld, &jsheap);
3107 }
3108
3109 {
3110// Stringification macros
3111// See https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html
3112#define TO_STRING(s) STR(s)
3113#define STR(s) #s
3114
3115#define ADD_ISOLATE_FLAGS(when, name, bitname, isolate_flag_name, flag_name) \
3116 { \
3117 JSONObject jsflag(&jsflags); \
3118 jsflag.AddProperty("name", TO_STRING(name)); \
3119 jsflag.AddProperty("valueAsString", name() ? "true" : "false"); \
3120 }
3121 JSONArray jsflags(&jsobj, "isolateFlags");
3123#undef ADD_ISOLATE_FLAGS
3124#undef TO_STRING
3125#undef STR
3126 }
3127
3128 jsobj.AddProperty("runnable", is_runnable());
3129 jsobj.AddProperty("livePorts", open_ports_keepalive_);
3130 jsobj.AddProperty("pauseOnExit", message_handler()->should_pause_on_exit());
3131#if !defined(DART_PRECOMPILED_RUNTIME)
3132 jsobj.AddProperty("_isReloading", group()->IsReloading());
3133#endif // !defined(DART_PRECOMPILED_RUNTIME)
3134
3135 ServiceEvent pause_event = IsolatePauseEvent(this);
3136 jsobj.AddProperty("pauseEvent", &pause_event);
3137
3138 const Library& lib = Library::Handle(group()->object_store()->root_library());
3139 if (!lib.IsNull()) {
3140 jsobj.AddProperty("rootLib", lib);
3141 }
3142
3143 if (FLAG_profiler) {
3144 JSONObject tagCounters(&jsobj, "_tagCounters");
3145 vm_tag_counters()->PrintToJSONObject(&tagCounters);
3146 }
3149 ASSERT(!error.IsNull());
3150 jsobj.AddProperty("error", error, false);
3151 } else if (sticky_error() != Object::null()) {
3153 ASSERT(!error.IsNull());
3154 jsobj.AddProperty("error", error, false);
3155 }
3156
3157 {
3158 const GrowableObjectArray& libs =
3159 GrowableObjectArray::Handle(group()->object_store()->libraries());
3160 intptr_t num_libs = libs.Length();
3161 Library& lib = Library::Handle();
3162
3163 JSONArray lib_array(&jsobj, "libraries");
3164 for (intptr_t i = 0; i < num_libs; i++) {
3165 lib ^= libs.At(i);
3166 ASSERT(!lib.IsNull());
3167 lib_array.AddValue(lib);
3168 }
3169 }
3170
3171 {
3172 JSONArray breakpoints(&jsobj, "breakpoints");
3173 if (debugger() != nullptr) {
3174 debugger()->PrintBreakpointsToJSONArray(&breakpoints);
3175 }
3176 }
3177
3178 Dart_ExceptionPauseInfo pause_info = (debugger() != nullptr)
3181 jsobj.AddProperty("exceptionPauseMode",
3183
3184 if (debugger() != nullptr) {
3185 JSONObject settings(&jsobj, "_debuggerSettings");
3187 }
3188
3189 {
3190 GrowableObjectArray& handlers =
3191 GrowableObjectArray::Handle(registered_service_extension_handlers());
3192 if (!handlers.IsNull()) {
3193 JSONArray extensions(&jsobj, "extensionRPCs");
3194 String& handler_name = String::Handle();
3195 for (intptr_t i = 0; i < handlers.Length(); i += kRegisteredEntrySize) {
3196 handler_name ^= handlers.At(i + kRegisteredNameIndex);
3197 extensions.AddValue(handler_name.ToCString());
3198 }
3199 }
3200 }
3201
3202 {
3203 JSONObject isolate_group(&jsobj, "isolate_group");
3204 group()->PrintToJSONObject(&isolate_group, /*ref=*/true);
3205 }
3206}
3207
3210}
3211
3214}
3215
3216#endif
3217
3219 tag_table_ = value.ptr();
3220}
3221
3223 uword user_tag = tag.tag();
3225 set_user_tag(user_tag);
3226 current_tag_ = tag.ptr();
3227}
3228
3230 default_tag_ = tag.ptr();
3231}
3232
3234 NoSafepointScope no_safepoint;
3235 ErrorPtr return_value = sticky_error_;
3236 sticky_error_ = Error::null();
3237 return return_value;
3238}
3239
3240#if !defined(PRODUCT)
3241void Isolate::set_pending_service_extension_calls(
3242 const GrowableObjectArray& value) {
3243 pending_service_extension_calls_ = value.ptr();
3244}
3245
3246void Isolate::set_registered_service_extension_handlers(
3247 const GrowableObjectArray& value) {
3248 registered_service_extension_handlers_ = value.ptr();
3249}
3250#endif // !defined(PRODUCT)
3251
3252#ifndef PRODUCT
3254 GrowableObjectArray& calls =
3255 GrowableObjectArray::Handle(GetAndClearPendingServiceExtensionCalls());
3256 if (calls.IsNull()) {
3257 return Error::null();
3258 }
3259 // Grab run function.
3260 const Library& developer_lib = Library::Handle(Library::DeveloperLibrary());
3261 ASSERT(!developer_lib.IsNull());
3262 const Function& run_extension = Function::Handle(
3263 developer_lib.LookupFunctionAllowPrivate(Symbols::_runExtension()));
3264 ASSERT(!run_extension.IsNull());
3265
3266 const Array& arguments =
3267 Array::Handle(Array::New(kPendingEntrySize + 1, Heap::kNew));
3269 String& method_name = String::Handle();
3271 Array& parameter_keys = Array::Handle();
3272 Array& parameter_values = Array::Handle();
3273 Instance& reply_port = Instance::Handle();
3274 Instance& id = Instance::Handle();
3275 for (intptr_t i = 0; i < calls.Length(); i += kPendingEntrySize) {
3276 // Grab arguments for call.
3277 closure ^= calls.At(i + kPendingHandlerIndex);
3278 ASSERT(!closure.IsNull());
3279 arguments.SetAt(kPendingHandlerIndex, closure);
3280 method_name ^= calls.At(i + kPendingMethodNameIndex);
3281 ASSERT(!method_name.IsNull());
3282 arguments.SetAt(kPendingMethodNameIndex, method_name);
3283 parameter_keys ^= calls.At(i + kPendingKeysIndex);
3284 ASSERT(!parameter_keys.IsNull());
3285 arguments.SetAt(kPendingKeysIndex, parameter_keys);
3286 parameter_values ^= calls.At(i + kPendingValuesIndex);
3287 ASSERT(!parameter_values.IsNull());
3288 arguments.SetAt(kPendingValuesIndex, parameter_values);
3289 reply_port ^= calls.At(i + kPendingReplyPortIndex);
3290 ASSERT(!reply_port.IsNull());
3291 arguments.SetAt(kPendingReplyPortIndex, reply_port);
3292 id ^= calls.At(i + kPendingIdIndex);
3293 arguments.SetAt(kPendingIdIndex, id);
3294 arguments.SetAt(kPendingEntrySize, Bool::Get(FLAG_trace_service));
3295
3296 if (FLAG_trace_service) {
3297 OS::PrintErr("[+%" Pd64 "ms] Isolate %s invoking _runExtension for %s\n",
3298 Dart::UptimeMillis(), name(), method_name.ToCString());
3299 }
3300 result = DartEntry::InvokeFunction(run_extension, arguments);
3301 if (FLAG_trace_service) {
3302 OS::PrintErr("[+%" Pd64 "ms] Isolate %s _runExtension complete for %s\n",
3303 Dart::UptimeMillis(), name(), method_name.ToCString());
3304 }
3305 // Propagate the error.
3306 if (result.IsError()) {
3307 // Remaining service extension calls are dropped.
3308 if (!result.IsUnwindError()) {
3309 // Send error back over the protocol.
3310 Service::PostError(method_name, parameter_keys, parameter_values,
3311 reply_port, id, Error::Cast(result));
3312 }
3313 return Error::Cast(result).ptr();
3314 }
3315 // Drain the microtask queue.
3317 // Propagate the error.
3318 if (result.IsError()) {
3319 // Remaining service extension calls are dropped.
3320 return Error::Cast(result).ptr();
3321 }
3322 }
3323 return Error::null();
3324}
3325
3326GrowableObjectArrayPtr Isolate::GetAndClearPendingServiceExtensionCalls() {
3327 GrowableObjectArrayPtr r = pending_service_extension_calls_;
3328 pending_service_extension_calls_ = GrowableObjectArray::null();
3329 return r;
3330}
3331
3333 const String& method_name,
3334 const Array& parameter_keys,
3335 const Array& parameter_values,
3336 const Instance& reply_port,
3337 const Instance& id) {
3338 if (FLAG_trace_service) {
3339 OS::PrintErr("[+%" Pd64
3340 "ms] Isolate %s ENQUEUING request for extension %s\n",
3341 Dart::UptimeMillis(), name(), method_name.ToCString());
3342 }
3343 GrowableObjectArray& calls =
3344 GrowableObjectArray::Handle(pending_service_extension_calls());
3345 bool schedule_drain = false;
3346 if (calls.IsNull()) {
3347 calls = GrowableObjectArray::New();
3348 ASSERT(!calls.IsNull());
3349 set_pending_service_extension_calls(calls);
3350 schedule_drain = true;
3351 }
3352 ASSERT(kPendingHandlerIndex == 0);
3353 calls.Add(closure);
3354 ASSERT(kPendingMethodNameIndex == 1);
3355 calls.Add(method_name);
3356 ASSERT(kPendingKeysIndex == 2);
3357 calls.Add(parameter_keys);
3358 ASSERT(kPendingValuesIndex == 3);
3359 calls.Add(parameter_values);
3360 ASSERT(kPendingReplyPortIndex == 4);
3361 calls.Add(reply_port);
3362 ASSERT(kPendingIdIndex == 5);
3363 calls.Add(id);
3364
3365 if (schedule_drain) {
3366 const Array& msg = Array::Handle(Array::New(3));
3367 Object& element = Object::Handle();
3369 msg.SetAt(0, element);
3371 msg.SetAt(1, element);
3373 msg.SetAt(2, element);
3374 std::unique_ptr<Message> message = WriteMessage(
3375 /* same_group */ false, msg, main_port(), Message::kOOBPriority);
3376 bool posted = PortMap::PostMessage(std::move(message));
3377 ASSERT(posted);
3378 }
3379}
3380
3381// This function is written in C++ and not Dart because we must do this
3382// operation atomically in the face of random OOB messages. Do not port
3383// to Dart code unless you can ensure that the operations will can be
3384// done atomically.
3386 const Instance& closure) {
3387 // Don't allow for service extensions to be registered for internal isolates.
3388 if (Isolate::IsVMInternalIsolate(this)) {
3389 return;
3390 }
3391 GrowableObjectArray& handlers =
3392 GrowableObjectArray::Handle(registered_service_extension_handlers());
3393 if (handlers.IsNull()) {
3395 set_registered_service_extension_handlers(handlers);
3396 }
3397#if defined(DEBUG)
3398 {
3399 // Sanity check.
3400 const Instance& existing_handler =
3402 ASSERT(existing_handler.IsNull());
3403 }
3404#endif
3405 ASSERT(kRegisteredNameIndex == 0);
3406 handlers.Add(name, Heap::kOld);
3407 ASSERT(kRegisteredHandlerIndex == 1);
3408 handlers.Add(closure, Heap::kOld);
3409 {
3410 // Fire off an event.
3412 event.set_extension_rpc(&name);
3414 }
3415}
3416
3417// This function is written in C++ and not Dart because we must do this
3418// operation atomically in the face of random OOB messages. Do not port
3419// to Dart code unless you can ensure that the operations will can be
3420// done atomically.
3422 const GrowableObjectArray& handlers =
3423 GrowableObjectArray::Handle(registered_service_extension_handlers());
3424 if (handlers.IsNull()) {
3425 return Instance::null();
3426 }
3427 String& handler_name = String::Handle();
3428 for (intptr_t i = 0; i < handlers.Length(); i += kRegisteredEntrySize) {
3429 handler_name ^= handlers.At(i + kRegisteredNameIndex);
3430 ASSERT(!handler_name.IsNull());
3431 if (handler_name.Equals(name)) {
3432 return Instance::RawCast(handlers.At(i + kRegisteredHandlerIndex));
3433 }
3434 }
3435 return Instance::null();
3436}
3437
3438void Isolate::WakePauseEventHandler(Dart_Isolate isolate) {
3439 Isolate* iso = reinterpret_cast<Isolate*>(isolate);
3440 MonitorLocker ml(iso->pause_loop_monitor_);
3441 ml.Notify();
3442
3443 Dart_MessageNotifyCallback current_notify_callback =
3445 // It is possible that WakePauseEventHandler was replaced by original callback
3446 // while waiting for pause_loop_monitor_. In that case PauseEventHandler
3447 // is no longer running and the original callback needs to be invoked instead
3448 // of incrementing wake_pause_event_handler_count_.
3449 if (current_notify_callback != Isolate::WakePauseEventHandler) {
3450 if (current_notify_callback != nullptr) {
3451 current_notify_callback(isolate);
3452 }
3453 } else {
3454 ++iso->wake_pause_event_handler_count_;
3455 }
3456}
3457
3459 // We are stealing a pause event (like a breakpoint) from the
3460 // embedder. We don't know what kind of thread we are on -- it
3461 // could be from our thread pool or it could be a thread from the
3462 // embedder. Sit on the current thread handling service events
3463 // until we are told to resume.
3464 if (pause_loop_monitor_ == nullptr) {
3465 pause_loop_monitor_ = new Monitor();
3466 }
3468 MonitorLocker ml(pause_loop_monitor_, false);
3469
3470 Dart_MessageNotifyCallback saved_notify_callback = message_notify_callback();
3471 ASSERT(wake_pause_event_handler_count_ == 0);
3472 set_message_notify_callback(Isolate::WakePauseEventHandler);
3473
3474#if !defined(DART_PRECOMPILED_RUNTIME)
3475 const bool had_program_reload_context =
3476 group()->program_reload_context() != nullptr;
3477 const int64_t start_time_micros = !had_program_reload_context
3478 ? 0
3479 : group()
3483#endif // !defined(DART_PRECOMPILED_RUNTIME)
3484 bool resume = false;
3485 while (true) {
3486 // Handle all available vm service messages, up to a resume
3487 // request.
3488 while (!resume && Dart_HasServiceMessages()) {
3489 ml.Exit();
3490 resume = Dart_HandleServiceMessages();
3491 ml.Enter();
3492 }
3493 if (resume) {
3494 break;
3495 }
3496
3497#if !defined(DART_PRECOMPILED_RUNTIME)
3498 if (had_program_reload_context &&
3499 (group()->program_reload_context() == nullptr)) {
3500 if (FLAG_trace_reload) {
3501 const int64_t reload_time_micros =
3502 OS::GetCurrentMonotonicMicros() - start_time_micros;
3503 double reload_millis = MicrosecondsToMilliseconds(reload_time_micros);
3504 OS::PrintErr("Reloading has finished! (%.2f ms)\n", reload_millis);
3505 }
3506 break;
3507 }
3508#endif // !defined(DART_PRECOMPILED_RUNTIME)
3509
3510 // Wait for more service messages.
3511 Monitor::WaitResult res = ml.Wait();
3512 ASSERT(res == Monitor::kNotified);
3513 }
3514 // If any non-service messages came in, we need to notify the registered
3515 // message notify callback to check for unhandled messages. Otherwise, events
3516 // may be left unhandled until the next event comes in. See
3517 // https://github.com/dart-lang/sdk/issues/37312.
3518 if (saved_notify_callback != nullptr) {
3519 while (wake_pause_event_handler_count_ > 0) {
3520 saved_notify_callback(Api::CastIsolate(this));
3521 --wake_pause_event_handler_count_;
3522 }
3523 } else {
3524 wake_pause_event_handler_count_ = 0;
3525 }
3526 set_message_notify_callback(saved_notify_callback);
3528}
3529#endif // !PRODUCT
3530
3532 if (visitor == nullptr) {
3533 return;
3534 }
3537 [&](Isolate* isolate) { visitor->VisitIsolate(isolate); });
3538 });
3539}
3540
3542 intptr_t count = 0;
3544 group->ForEachIsolate([&](Isolate* isolate) { count++; });
3545 });
3546 return count;
3547}
3548
3550 Isolate* match = nullptr;
3552 group->ForEachIsolate([&](Isolate* isolate) {
3553 if (isolate->main_port() == port) {
3554 match = isolate;
3555 }
3556 });
3557 });
3558 return match;
3559}
3560
3562 MonitorLocker ml(isolate_creation_monitor_);
3563 std::unique_ptr<char[]> result;
3565 group->ForEachIsolate([&](Isolate* isolate) {
3566 if (isolate->main_port() == port) {
3567 const size_t len = strlen(isolate->name()) + 1;
3568 result = std::unique_ptr<char[]>(new char[len]);
3569 strncpy(result.get(), isolate->name(), len);
3570 }
3571 });
3572 });
3573 return result;
3574}
3575
3576bool Isolate::TryMarkIsolateReady(Isolate* isolate) {
3577 MonitorLocker ml(isolate_creation_monitor_);
3578 if (!creation_enabled_) {
3579 return false;
3580 }
3581 isolate->accepts_messages_ = true;
3582 return true;
3583}
3584
3585void Isolate::UnMarkIsolateReady(Isolate* isolate) {
3586 MonitorLocker ml(isolate_creation_monitor_);
3587 isolate->accepts_messages_ = false;
3588}
3589
3591 MonitorLocker ml(isolate_creation_monitor_);
3592 creation_enabled_ = false;
3593}
3594
3596 MonitorLocker ml(isolate_creation_monitor_);
3597 creation_enabled_ = true;
3598}
3599
3601 MonitorLocker ml(isolate_creation_monitor_);
3602 return creation_enabled_;
3603}
3604
3606 return group->source()->flags.is_system_isolate;
3607}
3608
3610 return isolate->is_kernel_isolate() || isolate->is_service_isolate() ||
3611 isolate->is_vm_isolate();
3612}
3613
3614void Isolate::KillLocked(LibMsgId msg_id) {
3615 Dart_CObject kill_msg;
3616 Dart_CObject* list_values[4];
3617 kill_msg.type = Dart_CObject_kArray;
3618 kill_msg.value.as_array.length = 4;
3619 kill_msg.value.as_array.values = list_values;
3620
3621 Dart_CObject oob;
3624 list_values[0] = &oob;
3625
3626 Dart_CObject msg_type;
3627 msg_type.type = Dart_CObject_kInt32;
3628 msg_type.value.as_int32 = msg_id;
3629 list_values[1] = &msg_type;
3630
3631 Dart_CObject cap;
3634 list_values[2] = &cap;
3635
3636 Dart_CObject imm;
3639 list_values[3] = &imm;
3640
3641 {
3642 AllocOnlyStackZone zone;
3643 std::unique_ptr<Message> message = WriteApiMessage(
3644 zone.GetZone(), &kill_msg, main_port(), Message::kOOBPriority);
3645 ASSERT(message != nullptr);
3646
3647 // Post the message at the given port.
3648 bool success = PortMap::PostMessage(std::move(message));
3649 ASSERT(success);
3650 }
3651}
3652
3654 public:
3656 bool kill_system_isolates = false)
3657 : target_(nullptr),
3658 msg_id_(msg_id),
3659 kill_system_isolates_(kill_system_isolates) {}
3660
3662 : target_(isolate), msg_id_(msg_id), kill_system_isolates_(false) {
3663 ASSERT(isolate != Dart::vm_isolate());
3664 }
3665
3667
3668 void VisitIsolate(Isolate* isolate) {
3669 MonitorLocker ml(Isolate::isolate_creation_monitor_);
3670 ASSERT(isolate != nullptr);
3671 if (ShouldKill(isolate)) {
3672 if (isolate->AcceptsMessagesLocked()) {
3673 isolate->KillLocked(msg_id_);
3674 }
3675 }
3676 }
3677
3678 private:
3679 bool ShouldKill(Isolate* isolate) {
3680 if (kill_system_isolates_) {
3681 ASSERT(target_ == nullptr);
3682 // Don't kill the service isolate or vm isolate.
3683 return IsSystemIsolate(isolate) && !Isolate::IsVMInternalIsolate(isolate);
3684 }
3685 // If a target_ is specified, then only kill the target_.
3686 // Otherwise, don't kill the service isolate or vm isolate.
3687 return (((target_ != nullptr) && (isolate == target_)) ||
3688 ((target_ == nullptr) && !IsSystemIsolate(isolate)));
3689 }
3690
3691 Isolate* target_;
3692 Isolate::LibMsgId msg_id_;
3693 bool kill_system_isolates_;
3694};
3695
3697 IsolateKillerVisitor visitor(msg_id);
3698 VisitIsolates(&visitor);
3699}
3700
3702 IsolateKillerVisitor visitor(msg_id, /*kill_system_isolates=*/true);
3703 VisitIsolates(&visitor);
3704}
3705
3707 IsolateKillerVisitor visitor(isolate, msg_id);
3708 VisitIsolates(&visitor);
3709}
3710
3712 MonitorLocker ml(&spawn_count_monitor_);
3713 spawn_count_++;
3714}
3715
3717 MonitorLocker ml(&spawn_count_monitor_);
3718 ASSERT(spawn_count_ > 0);
3719 spawn_count_--;
3720 ml.Notify();
3721}
3722
3724 Thread* thread = Thread::Current();
3725 ASSERT(thread != nullptr);
3726 MonitorLocker ml(&spawn_count_monitor_);
3727 while (spawn_count_ > 0) {
3728 ml.WaitWithSafepointCheck(thread);
3729 }
3730}
3731
3733 Zone* zone,
3734 const Function& send_function,
3735 Dart_Port send_port) {
3737 this, zone, send_function, send_port, &ffi_callback_list_head_);
3738}
3739
3741 Zone* zone,
3742 const Function& trampoline,
3743 const Closure& target,
3744 bool keep_isolate_alive) {
3745 if (keep_isolate_alive) {
3747 }
3749 this, zone, trampoline, target, &ffi_callback_list_head_);
3750}
3751
3753 ASSERT(0 <= open_ports_ && 0 <= open_ports_keepalive_ &&
3754 open_ports_keepalive_ <= open_ports_);
3755 return open_ports_keepalive_ > 0;
3756}
3757
3758ReceivePortPtr Isolate::CreateReceivePort(const String& debug_name) {
3760 ++open_ports_;
3761 ++open_ports_keepalive_;
3762 return ReceivePort::New(port_id, debug_name);
3763}
3764
3766 bool keep_isolate_alive) {
3767 // Changing keep-isolate-alive state of a closed port is a NOP.
3768 if (!receive_port.is_open()) return;
3769
3770 ASSERT(0 < open_ports_);
3771
3772 // If the state doesn't change it's a NOP.
3773 if (receive_port.keep_isolate_alive() == keep_isolate_alive) return;
3774
3775 if (keep_isolate_alive) {
3776 ASSERT(open_ports_keepalive_ < open_ports_);
3777 ++open_ports_keepalive_;
3778 } else {
3779 ASSERT(0 < open_ports_keepalive_);
3780 --open_ports_keepalive_;
3781 }
3782 receive_port.set_keep_isolate_alive(keep_isolate_alive);
3783}
3784
3785void Isolate::CloseReceivePort(const ReceivePort& receive_port) {
3786 // Closing an already closed port is a NOP.
3787 if (!receive_port.is_open()) return;
3788
3789 ASSERT(open_ports_ > 0);
3790 const bool ok = PortMap::ClosePort(receive_port.Id());
3792
3793 if (receive_port.keep_isolate_alive()) {
3794 --open_ports_keepalive_;
3795 receive_port.set_keep_isolate_alive(false);
3796 }
3797 --open_ports_;
3798 receive_port.set_is_open(false);
3799}
3800
3803 &ffi_callback_list_head_);
3804}
3805
3807 ffi_callback_keep_alive_counter_ += delta;
3808 ASSERT(ffi_callback_keep_alive_counter_ >= 0);
3809}
3810
3812 ASSERT(ffi_callback_keep_alive_counter_ >= 0);
3813 return ffi_callback_keep_alive_counter_ > 0;
3814}
3815
3816#if !defined(PRODUCT)
3818 RELEASE_ASSERT(class_table_ == heap_walk_class_table_);
3819 class_table_ = class_table_->Clone();
3821}
3822
3824 RELEASE_ASSERT(class_table_ != heap_walk_class_table_);
3825 class_table_allocator_.Free(class_table_);
3826 class_table_ = heap_walk_class_table_;
3827 set_cached_class_table_table(class_table_->table());
3828}
3829
3831 RELEASE_ASSERT(class_table_ != heap_walk_class_table_);
3832 class_table_allocator_.Free(heap_walk_class_table_);
3833 heap_walk_class_table_ = class_table_;
3834 set_cached_class_table_table(class_table_->table());
3835}
3836#endif
3837
3838} // namespace dart
int count
Definition: FontMgrTest.cpp:50
static bool ok(int result)
SI F table(const skcms_Curve *curve, F v)
#define UNREACHABLE()
Definition: assert.h:248
#define RELEASE_ASSERT(cond)
Definition: assert.h:327
GLenum type
void store(T arg, std::memory_order order=std::memory_order_release)
Definition: atomic.h:104
void VisitWeakHandlesUnlocked(HandleVisitor *visitor)
void VisitObjectPointersUnlocked(ObjectPointerVisitor *visitor)
static Dart_Handle NewHandle(Thread *thread, ObjectPtr raw)
static Dart_Isolate CastIsolate(Isolate *isolate)
static ObjectPtr UnwrapHandle(Dart_Handle object)
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
ObjectPtr At(intptr_t index) const
Definition: object.h:10875
intptr_t Length() const
Definition: object.h:10829
void SetAt(intptr_t index, const Object &value) const
Definition: object.h:10880
static ArrayPtr Grow(const Array &source, intptr_t new_length, Heap::Space space=Heap::kNew)
Definition: object.cc:24853
Thread * scheduled_mutator_thread_
Definition: base_isolate.h:34
Thread * mutator_thread_
Definition: base_isolate.h:38
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: become.cc:236
void Add(const Object &before, const Object &after)
Definition: become.cc:231
static const Bool & Get(bool value)
Definition: object.h:10801
virtual void Call()=0
uint64_t Id() const
Definition: object.h:12417
void Free(ClassTable *table)
Definition: class_table.cc:395
void Register(const Class &cls)
Definition: class_table.cc:65
ClassPtr At(intptr_t cid) const
Definition: class_table.h:362
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: class_table.cc:127
intptr_t NumCids() const
Definition: class_table.h:447
void RegisterTopLevel(const Class &cls)
Definition: class_table.cc:92
ClassTable * Clone() const
Definition: class_table.h:360
StringPtr ScrubbedName() const
Definition: object.cc:2981
InstancePtr InsertCanonicalConstant(Zone *zone, const Instance &constant) const
Definition: object.cc:6485
ArrayPtr constants() const
Definition: object.cc:5806
FieldPtr LookupField(const String &name) const
Definition: object.cc:6352
void set_constants(const Array &value) const
Definition: object.cc:5810
bool IsTopLevel() const
Definition: object.cc:6121
bool is_enum_class() const
Definition: object.h:1720
FieldPtr LookupStaticField(const String &name) const
Definition: object.cc:6348
static ObjectPtr InvokeFunction(const Function &function, const Array &arguments)
Definition: dart_entry.cc:31
static ObjectPtr HandleMessage(Dart_Port port_id, const Instance &message)
Definition: dart_entry.cc:701
static ObjectPtr HandleFinalizerMessage(const FinalizerBase &finalizer)
Definition: dart_entry.cc:721
static ObjectPtr ToString(const Instance &receiver)
Definition: dart_entry.cc:615
static ObjectPtr DrainMicrotaskQueue()
Definition: dart_entry.cc:750
static ThreadPool * thread_pool()
Definition: dart.h:73
static void ShutdownIsolate(Thread *T)
Definition: dart.cc:1123
static int64_t UptimeMillis()
Definition: dart.h:76
static Isolate * vm_isolate()
Definition: dart.h:68
intptr_t Length() const
Definition: debugger.h:465
ActivationFrame * FrameAt(int i) const
Definition: debugger.h:467
Dart_ExceptionPauseInfo GetExceptionPauseInfo() const
Definition: debugger.cc:1867
void PrintBreakpointsToJSONArray(JSONArray *jsarr) const
Definition: debugger.cc:451
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: debugger.cc:3037
void PrintSettingsToJSONObject(JSONObject *jsobj) const
Definition: debugger.cc:468
DebuggerStackTrace * StackTrace()
Definition: debugger.cc:1797
ErrorPtr PausePostRequest()
Definition: debugger.cc:293
const ServiceEvent * PauseEvent() const
Definition: debugger.h:733
void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info)
Definition: debugger.cc:1860
void Shutdown()
Definition: debugger.cc:1434
void VisitObjectPointers(ObjectPointerVisitor *visitor)
DisableIdleTimerScope(IdleTimeHandler *handler)
Definition: isolate.cc:245
static DART_NORETURN void PropagateError(const Error &error)
Definition: exceptions.cc:1003
Trampoline CreateIsolateLocalFfiCallback(Isolate *isolate, Zone *zone, const Function &function, const Closure &closure, Metadata **list_head)
void DeleteCallback(Trampoline trampoline, Metadata **list_head)
static FfiCallbackMetadata * Instance()
Trampoline CreateAsyncFfiCallback(Isolate *isolate, Zone *zone, const Function &function, Dart_Port send_port, Metadata **list_head)
void DeleteAllCallbacks(Metadata **list_head)
bool Register(const Field &field, intptr_t expected_field_id=-1)
Definition: field_table.cc:55
void Free(intptr_t index)
Definition: field_table.cc:86
void SetAt(intptr_t index, ObjectPtr raw_instance, bool concurrent_use=false)
Definition: field_table.h:76
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: field_table.cc:157
ObjectPtr StaticConstFieldValue() const
Definition: object.cc:12419
bool is_static() const
Definition: object.h:4440
void SetStaticConstFieldValue(const Instance &value, bool assert_initializing_store=true) const
Definition: object.cc:12448
intptr_t field_id() const
Definition: object.h:13284
bool is_shared() const
Definition: object.h:4493
void UpdateUnreachable(IsolateGroup *isolate_group)
void VisitHandle(uword addr) override
Definition: isolate.cc:267
FinalizeWeakPersistentHandlesVisitor(IsolateGroup *isolate_group)
Definition: isolate.cc:264
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: debugger.cc:3028
void Add(const Object &value, Heap::Space space=Heap::kNew) const
Definition: object.cc:24991
static GrowableObjectArrayPtr New(Heap::Space space=Heap::kNew)
Definition: object.h:11144
intptr_t Length() const
Definition: object.h:11072
ObjectPtr At(intptr_t index) const
Definition: object.h:11085
void SetAt(intptr_t index, const Object &value) const
Definition: object.h:11091
ObjectPtr GetOrNull(const Key &key, bool *present=nullptr) const
Definition: hash_table.h:840
ObjectPtr InsertOrGet(const Object &key) const
Definition: hash_table.h:813
StorageTraits::ArrayHandle & Release()
Definition: hash_table.h:195
void SetupImagePage(void *pointer, uword size, bool is_executable)
Definition: heap.h:276
@ kNew
Definition: heap.h:38
@ kOld
Definition: heap.h:39
void PrintMemoryUsageJSON(JSONStream *stream) const
Definition: heap.cc:992
void PrintSizes() const
Definition: heap.cc:793
void PrintToJSONObject(Space space, JSONObject *object) const
Definition: heap.cc:984
intptr_t TotalExternalInWords() const
Definition: heap.cc:824
void NotifyIdle(int64_t deadline)
Definition: heap.cc:375
void ResetCanonicalHashTable()
Definition: heap.cc:894
intptr_t TotalCapacityInWords() const
Definition: heap.cc:820
static void Init(IsolateGroup *isolate_group, bool is_vm_isolate, intptr_t max_new_gen_words, intptr_t max_old_gen_words)
Definition: heap.cc:704
intptr_t TotalUsedInWords() const
Definition: heap.cc:816
void InitializeWithHeap(Heap *heap)
Definition: isolate.cc:190
bool ShouldNotifyIdle(int64_t *expiry)
Definition: isolate.cc:209
bool ShouldCheckForIdle()
Definition: isolate.cc:196
void NotifyIdleUsingDefaultDeadline()
Definition: isolate.cc:240
void UpdateStartIdleTime()
Definition: isolate.cc:202
void NotifyIdle(int64_t deadline)
Definition: isolate.cc:225
ObjectPtr GetField(const Field &field) const
Definition: object.cc:20475
InstancePtr Canonicalize(Thread *thread) const
Definition: object.cc:20444
void SetField(const Field &field, const Object &value) const
Definition: object.cc:20494
static InstancePtr New(const Class &cls, Heap::Space space=Heap::kNew)
Definition: object.cc:20935
intptr_t num_blob_loads_
Definition: isolate.h:205
void add_loaded_blob(Zone *zone_, const ExternalTypedData &external_typed_data)
Definition: isolate.cc:133
void IncreaseMutatorCount(Isolate *mutator, bool is_nested_reenter)
Definition: isolate.cc:590
GroupDebugger * debugger() const
Definition: isolate.h:315
void RunWithLockedGroup(std::function< void()> fun)
Definition: isolate.cc:466
int64_t UptimeMicros() const
Definition: isolate.cc:1982
void RestoreOriginalClassTable()
Definition: isolate.cc:3823
bool ReloadKernel(JSONStream *js, bool force_reload, const uint8_t *kernel_buffer=nullptr, intptr_t kernel_buffer_size=0, bool dont_delete_reload_context=false)
Definition: isolate.cc:2102
void UnregisterIsolate(Isolate *isolate)
Definition: isolate.cc:471
void ForEachIsolate(std::function< void(Isolate *isolate)> function, bool at_safepoint=false)
Definition: isolate.cc:2841
void set_cached_class_table_table(ClassPtr *cached_class_table_table)
Definition: isolate.h:393
bool UnregisterIsolateDecrementCount()
Definition: isolate.cc:476
void DeleteReloadContext()
Definition: isolate.cc:2131
void VisitStackPointers(ObjectPointerVisitor *visitor, ValidationPolicy validate_frames)
Definition: isolate.cc:2970
MutatorThreadPool * thread_pool()
Definition: isolate.h:769
static bool IsSystemIsolateGroup(const IsolateGroup *group)
Definition: isolate.cc:3605
void ScheduleInterrupts(uword interrupt_bits)
Definition: isolate.cc:1960
void RegisterClass(const Class &cls)
Definition: isolate.cc:769
Become * become() const
Definition: isolate.h:677
void * embedder_data() const
Definition: isolate.h:291
void RehashConstants(Become *become)
Definition: isolate.cc:887
void FlagsCopyFrom(const Dart_IsolateFlags &api_flags)
Definition: isolate.cc:1622
void DropOriginalClassTable()
Definition: isolate.cc:3830
MarkingStack * deferred_marking_stack() const
Definition: isolate.h:578
Heap * heap() const
Definition: isolate.h:296
bool initial_spawn_successful()
Definition: isolate.h:293
bool ContainsOnlyOneIsolate()
Definition: isolate.cc:458
void FreeStaticField(const Field &field)
Definition: isolate.cc:848
ObjectStore * object_store() const
Definition: isolate.h:510
SafepointRwLock * program_lock()
Definition: isolate.h:537
void DisableIncrementalBarrier()
Definition: isolate.cc:2831
void CloneClassTableForReload()
Definition: isolate.cc:3817
static IsolateGroup * Current()
Definition: isolate.h:539
Dart_LibraryTagHandler library_tag_handler() const
Definition: isolate.h:555
void RegisterStaticField(const Field &field, const Object &initial_value)
Definition: isolate.cc:811
ClassTable * class_table() const
Definition: isolate.h:496
static bool HasOnlyVMIsolateGroup()
Definition: isolate.cc:724
bool is_system_isolate_group() const
Definition: isolate.h:413
void DecreaseMutatorCount(Isolate *mutator, bool is_nested_exit)
Definition: isolate.cc:618
void VisitObjectIdRingPointers(ObjectPointerVisitor *visitor)
Definition: isolate.cc:2987
void set_object_store(ObjectStore *object_store)
Definition: isolate.cc:1072
ApiState * api_state() const
Definition: isolate.h:700
void RegisterSharedStaticField(const Field &field, const Object &initial_value)
Definition: isolate.cc:789
FieldTable * initial_field_table() const
Definition: isolate.h:742
void VisitObjectPointers(ObjectPointerVisitor *visitor, ValidationPolicy validate_frames)
Definition: isolate.cc:2912
IsolateGroupSource * source() const
Definition: isolate.h:286
bool ReloadSources(JSONStream *js, bool force_reload, const char *root_script_url=nullptr, const char *packages_url=nullptr, bool dont_delete_reload_context=false)
Definition: isolate.cc:2073
void set_saved_unlinked_calls(const Array &saved_unlinked_calls)
Definition: isolate.cc:586
void SetHasAttemptedReload(bool value)
Definition: isolate.h:472
void SetupImagePage(const uint8_t *snapshot_buffer, bool is_executable)
Definition: isolate.cc:1953
ClassTable * heap_walk_class_table() const
Definition: isolate.h:503
ArrayPtr saved_unlinked_calls() const
Definition: isolate.h:739
Isolate * FirstIsolateLocked() const
Definition: isolate.cc:2874
void PrintJSON(JSONStream *stream, bool ref=true)
Definition: isolate.cc:643
void ReleaseStoreBuffers()
Definition: isolate.cc:2776
static void ExitTemporaryIsolate()
Definition: isolate.cc:880
void RememberLiveTemporaries()
Definition: isolate.cc:3008
void FlagsCopyTo(Dart_IsolateFlags *api_flags)
Definition: isolate.cc:1611
MarkingStack * old_marking_stack() const
Definition: isolate.h:576
void RunWithStoppedMutatorsCallable(Callable *single_current_mutator, Callable *otherwise, bool use_force_growth_in_otherwise=false)
Definition: isolate.cc:2878
void VisitWeakPersistentHandles(HandleVisitor *visitor)
Definition: isolate.cc:2998
static void RunWithIsolateGroup(uint64_t id, std::function< void(IsolateGroup *)> action, std::function< void()> not_found)
Definition: isolate.cc:690
void DeferredMarkLiveTemporaries()
Definition: isolate.cc:3002
bool IsReloading() const
Definition: isolate.h:669
void RegisterIsolate(Isolate *isolate)
Definition: isolate.cc:451
void MaybeIncreaseReloadEveryNStackOverflowChecks()
Definition: isolate.cc:2532
FieldTable * shared_initial_field_table() const
Definition: isolate.h:750
ISOLATE_GROUP_METRIC_LIST(ISOLATE_METRIC_ACCESSOR)
BackgroundCompiler * background_compiler() const
Definition: isolate.h:298
static void RegisterIsolateGroup(IsolateGroup *isolate_group)
Definition: isolate.cc:704
ThreadRegistry * thread_registry() const
Definition: isolate.h:333
Isolate * FirstIsolate() const
Definition: isolate.cc:2869
ObjectPtr CallTagHandler(Dart_LibraryTag tag, const Object &arg1, const Object &arg2)
Definition: isolate.cc:1925
IdleTimeHandler * idle_time_handler()
Definition: isolate.h:318
bool is_vm_isolate() const
Definition: isolate.h:290
Isolate * EnterTemporaryIsolate()
Definition: isolate.cc:871
static bool HasApplicationIsolateGroups()
Definition: isolate.cc:714
static void Init()
Definition: isolate.cc:734
Dart_DeferredLoadHandler deferred_load_handler() const
Definition: isolate.h:561
void PrintToJSONObject(JSONObject *jsobj, bool ref)
Definition: isolate.cc:648
static void ForEach(std::function< void(IsolateGroup *)> action)
Definition: isolate.cc:683
FieldTable * shared_field_table() const
Definition: isolate.h:760
void FlushMarkingStacks()
Definition: isolate.cc:2780
MarkingStack * new_marking_stack() const
Definition: isolate.h:577
void EnableIncrementalBarrier(MarkingStack *old_marking_stack, MarkingStack *new_marking_stack, MarkingStack *deferred_marking_stack)
Definition: isolate.cc:2817
ProgramReloadContext * program_reload_context()
Definition: isolate.h:659
void VisitSharedPointers(ObjectPointerVisitor *visitor)
Definition: isolate.cc:2921
static void FlagsInitialize(Dart_IsolateFlags *api_flags)
Definition: isolate.cc:1600
void CreateHeap(bool is_vm_isolate, bool is_service_or_kernel_isolate)
Definition: isolate.cc:482
IsolateGroup(std::shared_ptr< IsolateGroupSource > source, void *embedder_data, ObjectStore *object_store, Dart_IsolateFlags api_flags, bool is_vm_isolate)
Definition: isolate.cc:325
static void UnregisterIsolateGroup(IsolateGroup *isolate_group)
Definition: isolate.cc:709
static void Cleanup()
Definition: isolate.cc:742
bool HasTagHandler() const
Definition: isolate.h:551
void PrintMemoryUsageJSON(JSONStream *stream)
Definition: isolate.cc:668
virtual ~IsolateKillerVisitor()
Definition: isolate.cc:3666
void VisitIsolate(Isolate *isolate)
Definition: isolate.cc:3668
IsolateKillerVisitor(Isolate *isolate, Isolate::LibMsgId msg_id)
Definition: isolate.cc:3661
IsolateKillerVisitor(Isolate::LibMsgId msg_id, bool kill_system_isolates=false)
Definition: isolate.cc:3655
MessageStatus HandleMessage(std::unique_ptr< Message > message)
Definition: isolate.cc:1360
virtual Isolate * isolate() const
Definition: isolate.cc:1094
bool IsCurrentIsolate() const
Definition: isolate.cc:1514
virtual bool KeepAliveLocked()
Definition: isolate.cc:1097
const char * name() const
Definition: isolate.cc:1119
IsolateMessageHandler(Isolate *isolate)
Definition: isolate.cc:1114
void MessageNotify(Message::Priority priority)
Definition: isolate.cc:1344
virtual IsolateGroup * isolate_group() const
Definition: isolate.cc:1095
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: object_store.cc:19
virtual void VisitIsolate(Isolate *isolate)=0
bool IsSystemIsolate(Isolate *isolate) const
Definition: isolate.cc:752
void set_forward_table_old(WeakTable *table)
Definition: isolate.cc:2552
ReceivePortPtr CreateReceivePort(const String &debug_name)
Definition: isolate.cc:3758
bool AddResumeCapability(const Capability &capability)
Definition: isolate.cc:2197
bool HasLivePorts()
Definition: isolate.cc:3752
void AddExitListener(const SendPort &listener, const Instance &response)
Definition: isolate.cc:2248
void AddErrorListener(const SendPort &listener)
Definition: isolate.cc:2316
FfiCallbackMetadata::Trampoline CreateAsyncFfiCallback(Zone *zone, const Function &send_function, Dart_Port send_port)
Definition: isolate.cc:3732
ErrorPtr sticky_error() const
Definition: isolate.h:1357
static bool IsSystemIsolate(const Isolate *isolate)
Definition: isolate.h:1445
FieldTable * field_table() const
Definition: isolate.h:1000
static void DisableIsolateCreation()
Definition: isolate.cc:3590
void ScheduleInterrupts(uword interrupt_bits)
Definition: isolate.cc:1967
void RememberLiveTemporaries()
Definition: isolate.cc:2784
@ kErrorFatalMsg
Definition: isolate.h:969
@ kCheckForReload
Definition: isolate.h:975
@ kDrainServiceExtensionsMsg
Definition: isolate.h:974
@ kInternalKillMsg
Definition: isolate.h:973
uword user_tag() const
Definition: isolate.h:1327
static Isolate * Current()
Definition: isolate.h:986
static bool IsVMInternalIsolate(const Isolate *isolate)
Definition: isolate.cc:3609
void DeferredMarkLiveTemporaries()
Definition: isolate.cc:2790
static void KillIfExists(Isolate *isolate, LibMsgId msg_id)
Definition: isolate.cc:3706
static bool IsolateCreationEnabled()
Definition: isolate.cc:3600
IsolateObjectStore * isolate_object_store() const
Definition: isolate.h:1007
void FlagsCopyTo(Dart_IsolateFlags *api_flags) const
Definition: isolate.cc:1661
VMTagCounters * vm_tag_counters()
Definition: isolate.h:1311
static void KillAllSystemIsolates(LibMsgId msg_id)
Definition: isolate.cc:3701
static void VisitIsolates(IsolateVisitor *visitor)
Definition: isolate.cc:3531
Debugger * debugger() const
Definition: isolate.h:1108
bool VerifyPauseCapability(const Object &capability) const
Definition: isolate.cc:2187
ISOLATE_METRIC_LIST(ISOLATE_METRIC_ACCESSOR)
void DeleteFfiCallback(FfiCallbackMetadata::Trampoline callback)
Definition: isolate.cc:3801
@ kImmediateAction
Definition: isolate.h:979
@ kBeforeNextEventAction
Definition: isolate.h:980
@ kAsEventAction
Definition: isolate.h:981
void NotifyExitListeners()
Definition: isolate.cc:2299
bool IsPrefixLoaded(const LibraryPrefix &prefix) const
Definition: isolate.cc:2802
void DecrementSpawnCount()
Definition: isolate.cc:3716
bool RemoveResumeCapability(const Capability &capability)
Definition: isolate.cc:2230
void PrintJSON(JSONStream *stream, bool ref=true)
Definition: isolate.cc:3084
bool ResumeRequest() const
Definition: isolate.h:1148
MessageHandler * message_handler() const
Definition: isolate.cc:2416
ObjectPtr CallDeferredLoadHandler(intptr_t id)
Definition: isolate.cc:1941
void PrintPauseEventJSON(JSONStream *stream)
Definition: isolate.cc:3212
bool is_vm_isolate() const
Definition: isolate.h:1380
void SetReceivePortKeepAliveState(const ReceivePort &receive_port, bool keep_isolate_alive)
Definition: isolate.cc:3765
FfiCallbackMetadata::Trampoline CreateIsolateLocalFfiCallback(Zone *zone, const Function &trampoline, const Closure &target, bool keep_isolate_alive)
Definition: isolate.cc:3740
void SetPrefixIsLoaded(const LibraryPrefix &prefix)
Definition: isolate.cc:2810
void RegisterServiceExtensionHandler(const String &name, const Instance &closure)
Definition: isolate.cc:3385
static void FlagsInitialize(Dart_IsolateFlags *api_flags)
Definition: isolate.cc:1648
void PrintMemoryUsageJSON(JSONStream *stream)
Definition: isolate.cc:3208
static void KillAllIsolates(LibMsgId msg_id)
Definition: isolate.cc:3696
static std::unique_ptr< char[]> LookupIsolateNameByPort(Dart_Port port)
Definition: isolate.cc:3561
bool HasPendingMessages()
Definition: isolate.cc:1356
static intptr_t IsolateListLength()
Definition: isolate.cc:3541
uint64_t terminate_capability() const
Definition: isolate.h:1060
ThreadRegistry * thread_registry() const
Definition: isolate.h:994
void set_is_runnable(bool value)
Definition: isolate.h:1096
void CloseReceivePort(const ReceivePort &receive_port)
Definition: isolate.cc:3785
bool HasDeferredLoadHandler() const
Definition: isolate.h:1082
const char * MakeRunnable()
Definition: isolate.cc:2140
void SendInternalLibMessage(LibMsgId msg_id, uint64_t capability)
Definition: isolate.cc:1033
bool VerifyTerminateCapability(const Object &capability) const
Definition: isolate.cc:2192
void WaitForOutstandingSpawns()
Definition: isolate.cc:3723
void set_forward_table_new(WeakTable *table)
Definition: isolate.cc:2548
int64_t UptimeMicros() const
Definition: isolate.cc:1986
void UpdateNativeCallableKeepIsolateAliveCounter(intptr_t delta)
Definition: isolate.cc:3806
ObjectIdRing * EnsureObjectIdRing()
Definition: isolate.cc:3014
ErrorPtr InvokePendingServiceExtensionCalls()
Definition: isolate.cc:3253
void MakeRunnableLocked()
Definition: isolate.cc:2154
DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError()
Definition: isolate.cc:3233
ErrorPtr PausePostRequest()
Definition: isolate.cc:2013
static void EnableIsolateCreation()
Definition: isolate.cc:3595
void AppendServiceExtensionCall(const Instance &closure, const String &method_name, const Array &parameter_keys, const Array &parameter_values, const Instance &reply_port, const Instance &id)
Definition: isolate.cc:3332
IsolateGroup * group() const
Definition: isolate.h:1037
void set_current_tag(const UserTag &tag)
Definition: isolate.cc:3222
Dart_MessageNotifyCallback message_notify_callback() const
Definition: isolate.h:1011
InstancePtr LookupServiceExtensionHandler(const String &name)
Definition: isolate.cc:3421
void set_name(const char *name)
Definition: isolate.cc:1977
static Dart_IsolateGroupCleanupCallback GroupCleanupCallback()
Definition: isolate.h:1231
void FlagsCopyFrom(const Dart_IsolateFlags &api_flags)
Definition: isolate.cc:1674
void set_finalizers(const GrowableObjectArray &value)
Definition: isolate.cc:2001
void RemoveExitListener(const SendPort &listener)
Definition: isolate.cc:2283
uint64_t pause_capability() const
Definition: isolate.h:1056
static Isolate * LookupIsolateByPort(Dart_Port port)
Definition: isolate.cc:3549
bool NotifyErrorListeners(const char *msg, const char *stacktrace)
Definition: isolate.cc:2362
void init_loaded_prefixes_set_storage()
Definition: isolate.cc:2796
void Run()
Definition: isolate.cc:2411
bool IsPaused() const
Definition: isolate.cc:2005
void set_tag_table(const GrowableObjectArray &value)
Definition: isolate.cc:3218
void PauseEventHandler()
Definition: isolate.cc:3458
friend class Thread
Definition: isolate.h:1757
friend class IsolateGroup
Definition: isolate.h:1759
DeoptContext * deopt_context() const
Definition: isolate.h:1255
Thread * mutator_thread() const
Definition: isolate.cc:1920
void set_default_tag(const UserTag &tag)
Definition: isolate.cc:3229
Dart_Port origin_id()
Definition: isolate.cc:1990
void IncrementSpawnCount()
Definition: isolate.cc:3711
void set_origin_id(Dart_Port id)
Definition: isolate.cc:1995
void RemoveErrorListener(const SendPort &listener)
Definition: isolate.cc:2347
bool is_runnable() const
Definition: isolate.h:1095
void set_message_notify_callback(Dart_MessageNotifyCallback value)
Definition: isolate.h:1015
Dart_Port main_port() const
Definition: isolate.h:1048
void SetStickyError(ErrorPtr sticky_error)
Definition: isolate.cc:2404
const char * name() const
Definition: isolate.h:1043
bool HasOpenNativeCallables()
Definition: isolate.cc:3811
void AddValue(bool b) const
Definition: json_stream.h:494
void AddProperty64(const char *name, int64_t i) const
Definition: json_stream.h:401
void AddProperty(const char *name, bool b) const
Definition: json_stream.h:395
void AddServiceId(const Object &o) const
Definition: json_stream.h:380
void AddPropertyTimeMillis(const char *name, int64_t millis) const
Definition: json_stream.h:404
void AddPropertyF(const char *name, const char *format,...) const PRINTF_ATTRIBUTE(3
Definition: json_stream.cc:589
static void NotifyAboutIsolateGroupShutdown(const IsolateGroup *isolate_group)
static bool Exists()
static void SetKernelIsolate(Isolate *isolate)
static uword Hash(const Object &obj)
Definition: isolate.cc:1728
static bool IsMatch(const Object &a, const Object &b)
Definition: isolate.cc:1721
static const char * Name()
Definition: isolate.cc:1719
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition: object.cc:14084
static LibraryPtr DeveloperLibrary()
Definition: object.cc:14795
static void PrintSizes(Thread *thread)
virtual bool KeepAliveLocked()
void PostMessage(std::unique_ptr< Message > message, bool before_events=false)
Thread * thread() const
bool Run(ThreadPool *pool, StartCallback start_callback, EndCallback end_callback, CallbackData data)
bool is_paused_on_start() const
bool is_paused_on_exit() const
bool should_pause_on_start() const
static std::unique_ptr< Message > New(Args &&... args)
Definition: message.h:72
@ kServiceOOBMsg
Definition: message.h:41
@ kDelayedIsolateLibOOBMsg
Definition: message.h:43
@ kIsolateLibOOBMsg
Definition: message.h:42
static const Dart_Port kIllegalPort
Definition: message.h:47
@ kNormalPriority
Definition: message.h:28
@ kOOBPriority
Definition: message.h:29
Monitor::WaitResult WaitMicros(int64_t micros=Monitor::kNoTimeout)
Definition: lockers.h:180
Monitor::WaitResult WaitWithSafepointCheck(Thread *thread, int64_t millis=Monitor::kNoTimeout)
Definition: lockers.cc:12
Monitor::WaitResult Wait(int64_t millis=Monitor::kNoTimeout)
Definition: lockers.h:172
void Enter() const
Definition: lockers.h:155
void Exit() const
Definition: lockers.h:163
virtual void OnEnterIdleLocked(MonitorLocker *ml)
Definition: isolate.cc:278
bool IsOwnedByCurrentThread() const
Definition: os_thread.h:402
bool HasStackHeadroom()
Definition: os_thread.h:132
static OSThread * Current()
Definition: os_thread.h:179
Definition: os.h:19
static int64_t GetCurrentTimeMillis()
static int64_t GetCurrentMonotonicMicros()
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2
void VisitPointers(ObjectPointerVisitor *visitor)
void set_gc_root_type(const char *gc_root_type)
Definition: visitor.h:58
void VisitPointer(ObjectPtr *p)
Definition: visitor.h:55
void VisitObjectPointers(ObjectPointerVisitor *visitor)
void ClearCanonical() const
Definition: object.h:337
static ObjectPtr null()
Definition: object.h:433
intptr_t GetClassId() const
Definition: object.h:341
ObjectPtr ptr() const
Definition: object.h:332
bool InVMIsolateHeap() const
Definition: object.h:395
bool IsCanonical() const
Definition: object.h:335
bool IsNull() const
Definition: object.h:363
static Object & Handle()
Definition: object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition: object.h:325
intptr_t tasks() const
Definition: pages.h:315
void AbandonMarkingForShutdown()
Definition: pages.cc:587
Monitor * tasks_lock() const
Definition: pages.h:314
static bool PostMessage(std::unique_ptr< Message > message, bool before_events=false)
Definition: port.cc:152
static bool ClosePort(Dart_Port id, MessageHandler **message_handler=nullptr)
Definition: port.cc:90
static void ClosePorts(MessageHandler *handler)
Definition: port.cc:128
static Dart_Port CreatePort(MessageHandler *handler)
Definition: port.cc:55
static void IsolateShutdown(Thread *thread)
Definition: profiler.cc:1854
IsolateGroupReloadContext * group_reload_context()
uint64_t NextJSInt()
Definition: random.h:37
void set_keep_isolate_alive(bool value) const
Definition: object.h:12457
void set_is_open(bool value) const
Definition: object.h:12449
bool is_open() const
Definition: object.h:12446
Dart_Port Id() const
Definition: object.h:12436
static ReceivePortPtr New(Dart_Port id, const String &debug_name, Heap::Space space=Heap::kNew)
Definition: object.cc:25783
bool keep_isolate_alive() const
Definition: object.h:12454
static intptr_t MaxMutatorThreadCount()
Definition: scavenger.h:228
Dart_Port Id() const
Definition: object.h:12490
void set_top_frame(ActivationFrame *frame)
void PrintJSON(JSONStream *js) const
static void SetServiceIsolate(Isolate *isolate)
static void VisitObjectPointers(ObjectPointerVisitor *visitor)
static bool SendIsolateShutdownMessage()
static StreamInfo isolate_stream
Definition: service.h:180
static void HandleEvent(ServiceEvent *event, bool enter_safepoint=true)
Definition: service.cc:1206
static StreamInfo debug_stream
Definition: service.h:181
static ErrorPtr HandleIsolateMessage(Isolate *isolate, const Array &message)
Definition: service.cc:1069
static void PostError(const String &method_name, const Array &parameter_keys, const Array &parameter_values, const Instance &reply_port, const Instance &id, const Error &error)
Definition: service.cc:937
static SmiPtr New(intptr_t value)
Definition: object.h:10006
Zone * GetZone()
Definition: zone.h:213
bool Equals(const String &str) const
Definition: object.h:13337
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition: object.cc:24126
uword Hash() const
Definition: object.h:10216
static StringPtr FromConcat(Thread *thread, const String &str1, const String &str2)
Definition: symbols.cc:235
static void DumpStats(IsolateGroup *isolate_group)
Definition: symbols.cc:481
bool ShuttingDownLocked()
Definition: thread_pool.h:102
bool Run(Args &&... args)
Definition: thread_pool.h:45
void MarkCurrentWorkerAsBlocked()
Definition: thread_pool.cc:105
void MarkCurrentWorkerAsUnBlocked()
Definition: thread_pool.cc:131
bool TasksWaitingToRunLocked()
Definition: thread_pool.h:105
void VisitObjectPointers(IsolateGroup *isolate_group_of_interest, ObjectPointerVisitor *visitor, ValidationPolicy validate_frames)
static ThreadState * Current()
Definition: thread_state.h:27
void set_execution_state(ExecutionState state)
Definition: thread.h:1048
void ScheduleInterrupts(uword interrupt_bits)
Definition: thread.cc:710
void StartUnwindError()
Definition: thread.h:645
void RememberLiveTemporaries()
Definition: thread.cc:1149
bool OwnsSafepoint() const
Definition: thread.cc:1367
@ kMessageInterrupt
Definition: thread.h:489
@ kScavengerTask
Definition: thread.h:352
@ kMutatorTask
Definition: thread.h:347
@ kMarkerTask
Definition: thread.h:349
@ kIncrementalCompactorTask
Definition: thread.h:354
@ kUnknownTask
Definition: thread.h:346
@ kCompactorTask
Definition: thread.h:351
static Thread * Current()
Definition: thread.h:362
void VisitObjectPointers(ObjectPointerVisitor *visitor, ValidationPolicy validate_frames)
Definition: thread.cc:968
void set_sticky_error(const Error &value)
Definition: thread.cc:236
void ClearStackLimit()
Definition: thread.cc:701
static void ExitIsolateGroupAsHelper(bool bypass_safepoint)
Definition: thread.cc:499
bool IsDartMutatorThread() const
Definition: thread.h:551
Isolate * isolate() const
Definition: thread.h:534
TaskKind task_kind() const
Definition: thread.h:479
static void EnterIsolate(Isolate *isolate)
Definition: thread.cc:371
static void ExitIsolate(bool isolate_shutdown=false)
Definition: thread.cc:428
static bool EnterIsolateGroupAsHelper(IsolateGroup *isolate_group, TaskKind kind, bool bypass_safepoint)
Definition: thread.cc:481
void DeferredMarkLiveTemporaries()
Definition: thread.cc:1144
static UnwindErrorPtr New(const String &message, Heap::Space space=Heap::kNew)
Definition: object.cc:20005
bool is_user_initiated() const
Definition: object.h:8179
uword tag() const
Definition: object.h:13154
static constexpr uword kDefaultUserTag
Definition: tags.h:112
static char * StrDup(const char *s)
void PrintToJSONObject(JSONObject *obj)
Definition: tags.cc:123
Definition: il.h:75
static WeakPropertyPtr New(Heap::Space space=Heap::kNew)
Definition: object.cc:26756
void set_key(const Object &key) const
Definition: object.h:12921
ObjectPtr key() const
Definition: object.h:12920
ElementType * Alloc(intptr_t length)
#define THR_Print(format,...)
Definition: log.h:20
#define DART_FLAGS_CURRENT_VERSION
Definition: dart_api.h:582
void(* Dart_UnregisterKernelBlobCallback)(const char *kernel_blob_uri)
Definition: dart_api.h:894
Dart_Isolate(* Dart_IsolateGroupCreateCallback)(const char *script_uri, const char *main, const char *package_root, const char *package_config, Dart_IsolateFlags *flags, void *isolate_data, char **error)
Definition: dart_api.h:654
void(* Dart_IsolateCleanupCallback)(void *isolate_group_data, void *isolate_data)
Definition: dart_api.h:729
int64_t Dart_Port
Definition: dart_api.h:1525
void(* Dart_MessageNotifyCallback)(Dart_Isolate destination_isolate)
Definition: dart_api.h:1546
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
const char *(* Dart_RegisterKernelBlobCallback)(const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
Definition: dart_api.h:882
struct _Dart_Isolate * Dart_Isolate
Definition: dart_api.h:88
bool(* Dart_InitializeIsolateCallback)(void **child_isolate_data, char **error)
Definition: dart_api.h:693
void(* Dart_IsolateGroupCleanupCallback)(void *isolate_group_data)
Definition: dart_api.h:745
Dart_LibraryTag
Definition: dart_api.h:3419
void(* Dart_IsolateShutdownCallback)(void *isolate_group_data, void *isolate_data)
Definition: dart_api.h:711
#define CHECK_ISOLATE_GROUP(isolate_group)
Definition: dart_api_impl.h:31
@ Dart_CObject_kInt64
@ Dart_CObject_kString
@ Dart_CObject_kArray
@ Dart_CObject_kNull
@ Dart_CObject_kInt32
@ Dart_CObject_kCapability
#define UNIMPLEMENTED
#define ASSERT(E)
SkBitmap source
Definition: examples.cpp:28
static bool b
struct MyStruct a[10]
#define FATAL(error)
AtkStateType state
FlutterSemanticsFlag flags
if(end==-1)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlKeyEvent * event
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
uint32_t * target
Dart_NativeFunction function
Definition: fuchsia.cc:51
#define BOOL_ISOLATE_FLAG_LIST(V)
Definition: isolate.h:152
#define BOOL_ISOLATE_GROUP_FLAG_LIST(V)
Definition: isolate.h:136
#define RELOAD_OPERATION_SCOPE(thread_expr)
size_t length
Win32Message message
#define ISOLATE_METRIC_LIST(V)
Definition: metrics.h:49
#define ISOLATE_GROUP_METRIC_LIST(V)
Definition: metrics.h:37
sk_sp< const SkImage > image
Definition: SkRecords.h:269
def match(bench, filt)
Definition: benchmark.py:23
constexpr word kSmiMax
Definition: runtime_api.h:305
Definition: dart_vm.cc:33
DART_EXPORT bool Dart_HasServiceMessages()
static const char * ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi)
Definition: isolate.cc:3023
static void DeterministicModeHandler(bool value)
Definition: isolate.cc:80
@ kGCAndDeopt
Definition: thread.h:293
constexpr intptr_t kMicrosecondsPerMillisecond
Definition: globals.h:561
ObjectPtr ReadMessage(Thread *thread, Message *message)
DART_EXPORT void Dart_EnterScope()
const char *const name
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
static std::unique_ptr< Message > SerializeMessage(Dart_Port dest_port, const Instance &obj)
Definition: isolate.cc:121
constexpr uword kUwordMax
Definition: globals.h:519
static void ShutdownIsolate(uword parameter)
Definition: isolate.cc:2399
constexpr intptr_t KB
Definition: globals.h:528
uintptr_t uword
Definition: globals.h:501
constexpr intptr_t MBInWords
Definition: globals.h:537
AsThreadStackResource< RawReloadParticipationScope > ReloadParticipationScope
Definition: thread.h:1634
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
const intptr_t cid
const intptr_t kDefaultMaxOldGenHeapSize
Definition: globals.h:62
DEFINE_FLAG_HANDLER(PrecompilationModeHandler, precompilation, "Precompilation mode")
ValidationPolicy
Definition: thread.h:271
DART_EXPORT void Dart_ExitScope()
std::unique_ptr< Message > WriteMessage(bool same_group, const Object &obj, Dart_Port dest_port, Message::Priority priority)
static ServiceEvent IsolatePauseEvent(Isolate *isolate)
Definition: isolate.cc:3037
constexpr intptr_t kWordSize
Definition: globals.h:509
std::unique_ptr< Message > WriteApiMessage(Zone *zone, Dart_CObject *obj, Dart_Port dest_port, Message::Priority priority)
constexpr double MicrosecondsToMilliseconds(int64_t micros)
Definition: globals.h:574
static MessageHandler::MessageStatus StoreError(Thread *thread, const Error &error)
Definition: isolate.cc:1518
DART_EXPORT void Dart_ShutdownIsolate()
NOT_IN_PRODUCT(LibraryPtr ReloadTestScript(const char *script))
DART_EXPORT bool Dart_HandleServiceMessages()
Dart_ExceptionPauseInfo
Definition: debugger.h:504
@ kPauseOnUnhandledExceptions
Definition: debugger.h:506
@ kNoPauseOnExceptions
Definition: debugger.h:505
@ kPauseOnAllExceptions
Definition: debugger.h:507
bool IsStringClassId(intptr_t index)
Definition: class_id.h:350
DECLARE_FLAG(bool, show_invisible_frames)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
std::function< void()> closure
Definition: closure.h:14
Definition: ref_ptr.h:256
#define Pd64
Definition: globals.h:416
#define Pd
Definition: globals.h:408
#define Pu64
Definition: globals.h:417
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581
#define ISOLATE_GROUP_SERVICE_ID_FORMAT_STRING
Definition: service.h:50
#define ISOLATE_SERVICE_ID_FORMAT_STRING
Definition: service.h:48
bool is_service_isolate
Definition: dart_api.h:593
int32_t version
Definition: dart_api.h:585
bool is_kernel_isolate
Definition: dart_api.h:594
Definition: SkMD5.cpp:134
union _Dart_CObject::@86 value
Dart_CObject_Type type
struct _Dart_CObject::@86::@88 as_capability
const char * as_string
struct _Dart_CObject::@86::@89 as_array
struct _Dart_CObject ** values
const uintptr_t id
#define ARRAY_SIZE(array)
Definition: globals.h:72
#define T
Definition: isolate.cc:102
#define ISOLATE_METRIC_PRINT(type, variable, name, unit)
#define ISOLATE_METRIC_INIT(type, variable, name, unit)
#define IG
Definition: isolate.cc:104
#define ISOLATE_GROUP_METRIC_PRINT(type, variable, name, unit)
#define SET_FROM_FLAG(when, name, bitname, isolate_flag, flag)
#define ISOLATE_GROUP_METRIC_CONSTRUCTORS(type, variable, name, unit)
#define INIT_FROM_FLAG(when, name, bitname, isolate_flag, flag)
#define ISOLATE_METRIC_CONSTRUCTORS(type, variable, name, unit)
#define ADD_ISOLATE_FLAGS(when, name, bitname, isolate_flag_name, flag_name)
#define INIT_FROM_FIELD(when, name, bitname, isolate_flag, flag)