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