Flutter Engine
The Flutter Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
dart_api_state.h
Go to the documentation of this file.
1// Copyright (c) 2012, 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#ifndef RUNTIME_VM_DART_API_STATE_H_
6#define RUNTIME_VM_DART_API_STATE_H_
7
8#include "include/dart_api.h"
9#include "platform/utils.h"
10#include "vm/bitfield.h"
11#include "vm/dart_api_impl.h"
12#include "vm/flags.h"
13#include "vm/growable_array.h"
14#include "vm/handles.h"
15#include "vm/handles_impl.h"
16#include "vm/heap/weak_table.h"
17#include "vm/object.h"
18#include "vm/os.h"
19#include "vm/os_thread.h"
20#include "vm/raw_object.h"
21#include "vm/thread_pool.h"
22#include "vm/visitor.h"
23
24namespace dart {
25
26// Implementation of Zone support for very fast allocation of small chunks
27// of memory. The chunks cannot be deallocated individually, but instead
28// zones support deallocating all chunks in one fast operation when the
29// scope is exited.
30class ApiZone {
31 public:
32 // Create an empty zone.
33 ApiZone() : zone_() {
34 Thread* thread = Thread::Current();
35 Zone* zone = thread != nullptr ? thread->zone() : nullptr;
36 zone_.Link(zone);
37 if (thread != nullptr) {
38 thread->set_zone(&zone_);
39 }
40 if (FLAG_trace_zones) {
41 OS::PrintErr("*** Starting a new Api zone 0x%" Px "(0x%" Px ")\n",
42 reinterpret_cast<intptr_t>(this),
43 reinterpret_cast<intptr_t>(&zone_));
44 }
45 }
46
47 // Delete all memory associated with the zone.
49 Thread* thread = Thread::Current();
50#if defined(DEBUG)
51 if (thread == nullptr) {
52 ASSERT(zone_.handles()->CountScopedHandles() == 0);
53 ASSERT(zone_.handles()->CountZoneHandles() == 0);
54 }
55#endif
56 if ((thread != nullptr) && (thread->zone() == &zone_)) {
57 thread->set_zone(zone_.previous_);
58 }
59 if (FLAG_trace_zones) {
60 OS::PrintErr("*** Deleting Api zone 0x%" Px "(0x%" Px ")\n",
61 reinterpret_cast<intptr_t>(this),
62 reinterpret_cast<intptr_t>(&zone_));
63 }
64 }
65
66 // Allocates an array sized to hold 'len' elements of type
67 // 'ElementType'. Checks for integer overflow when performing the
68 // size computation.
69 template <class ElementType>
70 ElementType* Alloc(intptr_t len) {
71 return zone_.Alloc<ElementType>(len);
72 }
73
74 // Allocates an array sized to hold 'len' elements of type
75 // 'ElementType'. The new array is initialized from the memory of
76 // 'old_array' up to 'old_len'.
77 template <class ElementType>
78 ElementType* Realloc(ElementType* old_array,
79 intptr_t old_len,
80 intptr_t new_len) {
81 return zone_.Realloc<ElementType>(old_array, old_len, new_len);
82 }
83
84 // Allocates 'size' bytes of memory in the zone; expands the zone by
85 // allocating new segments of memory on demand using 'new'.
86 //
87 // It is preferred to use Alloc<T>() instead, as that function can
88 // check for integer overflow. If you use AllocUnsafe, you are
89 // responsible for avoiding integer overflow yourself.
90 uword AllocUnsafe(intptr_t size) { return zone_.AllocUnsafe(size); }
91
92 // Compute the total size of this zone. This includes wasted space that is
93 // due to internal fragmentation in the segments.
94 intptr_t SizeInBytes() const { return zone_.SizeInBytes(); }
95
96 Zone* GetZone() { return &zone_; }
97
98 void Reinit(Thread* thread) {
99 if (thread == nullptr) {
100 zone_.Link(nullptr);
101 } else {
102 zone_.Link(thread->zone());
103 thread->set_zone(&zone_);
104 }
105 }
106
107 void Reset(Thread* thread) {
108 if ((thread != nullptr) && (thread->zone() == &zone_)) {
109 thread->set_zone(zone_.previous_);
110 }
111 zone_.Reset();
112 }
113
114 private:
115 Zone zone_;
116
117 template <typename T>
118 friend class ApiGrowableArray;
120};
121
122// Implementation of local handles which are handed out from every
123// dart API call, these handles are valid only in the present scope
124// and are destroyed when a Dart_ExitScope() is called.
126 public:
127 // Accessors.
128 ObjectPtr ptr() const { return ptr_; }
129 void set_ptr(ObjectPtr ptr) { ptr_ = ptr; }
130 static intptr_t ptr_offset() { return OFFSET_OF(LocalHandle, ptr_); }
131
132 Dart_Handle apiHandle() { return reinterpret_cast<Dart_Handle>(this); }
133
134 private:
135 LocalHandle() {}
136 ~LocalHandle() {}
137
138 ObjectPtr ptr_;
139 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
140 DISALLOW_COPY_AND_ASSIGN(LocalHandle);
141};
142
143// A distinguished callback which indicates that a persistent handle
144// should not be deleted from the dart api.
145void ProtectedHandleCallback(void* peer);
146
147// Implementation of persistent handles which are handed out through the
148// dart API.
150 public:
151 // Accessors.
152 ObjectPtr ptr() const { return ptr_; }
153 void set_ptr(ObjectPtr ref) { ptr_ = ref; }
154 void set_ptr(const LocalHandle& ref) { ptr_ = ref.ptr(); }
155 void set_ptr(const Object& object) { ptr_ = object.ptr(); }
156 ObjectPtr* raw_addr() { return &ptr_; }
157
159 return reinterpret_cast<Dart_PersistentHandle>(this);
160 }
161
162 static intptr_t ptr_offset() { return OFFSET_OF(PersistentHandle, ptr_); }
163
165
166 private:
167 friend class PersistentHandles;
168
171
172 // Overload the ptr_ field as a next pointer when adding freed
173 // handles to the free list.
174 PersistentHandle* Next() {
175 return reinterpret_cast<PersistentHandle*>(static_cast<uword>(ptr_));
176 }
177 void SetNext(PersistentHandle* free_list) {
178 ptr_ = static_cast<ObjectPtr>(reinterpret_cast<uword>(free_list));
179 ASSERT(!ptr_->IsHeapObject());
180 }
181 void FreeHandle(PersistentHandle* free_list) { SetNext(free_list); }
182
183 ObjectPtr ptr_;
184 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
185 DISALLOW_COPY_AND_ASSIGN(PersistentHandle);
186};
187
188// Implementation of persistent handles which are handed out through the
189// dart API.
191 public:
192 static FinalizablePersistentHandle* New(IsolateGroup* isolate_group,
193 const Object& object,
194 void* peer,
196 intptr_t external_size,
197 bool auto_delete);
198
199 // Accessors.
200 ObjectPtr ptr() const { return ptr_; }
201 ObjectPtr* ptr_addr() { return &ptr_; }
202 static intptr_t ptr_offset() {
204 }
205 void* peer() const { return peer_; }
206 Dart_HandleFinalizer callback() const { return callback_; }
208 return reinterpret_cast<Dart_WeakPersistentHandle>(this);
209 }
211 return reinterpret_cast<Dart_FinalizableHandle>(this);
212 }
213
214 bool auto_delete() const { return auto_delete_; }
215
216 bool IsFinalizedNotFreed() const {
217 return ptr_ == static_cast<ObjectPtr>(reinterpret_cast<uword>(this));
218 }
219
220 intptr_t external_size() const {
221 return ExternalSizeInWordsBits::decode(external_data_) * kWordSize;
222 }
223
224 bool SetExternalSize(intptr_t size, IsolateGroup* isolate_group) {
225 // This method only behaves correctly when external_size() has not been
226 // previously modified.
227 ASSERT(external_size() == 0);
228 if (size < 0 || (size >> kWordSizeLog2) > kMaxAddrSpaceInWords) {
229 return false;
230 }
231 set_external_size(size);
232 if (SpaceForExternal() == Heap::kNew) {
233 SetExternalNewSpaceBit();
234 }
235 return isolate_group->heap()->AllocatedExternal(external_size(),
236 SpaceForExternal());
237 }
238
239 // Called when the referent becomes unreachable.
240 void UpdateUnreachable(IsolateGroup* isolate_group) {
241 EnsureFreedExternal(isolate_group);
242 Finalize(isolate_group, this);
243 }
244
245 // Called when the referent has moved, potentially between generations.
246 void UpdateRelocated(IsolateGroup* isolate_group) {
247 if (IsSetNewSpaceBit() && (SpaceForExternal() == Heap::kOld)) {
248 isolate_group->heap()->PromotedExternal(external_size());
249 ClearExternalNewSpaceBit();
250 }
251 }
252
253 // Idempotent. Called when the handle is explicitly deleted or the
254 // referent becomes unreachable.
255 void EnsureFreedExternal(IsolateGroup* isolate_group) {
256 isolate_group->heap()->FreedExternal(external_size(), SpaceForExternal());
257 set_external_size(0);
258 }
259
262
263 private:
264 enum {
265 kExternalNewSpaceBit = 0,
266 kExternalSizeBits = 1,
267 kExternalSizeBitsSize = (kBitsPerWord - 1),
268 };
269
270 // This part of external_data_ is the number of externally allocated bytes.
271 class ExternalSizeInWordsBits : public BitField<uword,
272 intptr_t,
273 kExternalSizeBits,
274 kExternalSizeBitsSize> {};
275 // This bit of external_data_ is true if the referent was created in new
276 // space and UpdateRelocated has not yet detected any promotion.
277 class ExternalNewSpaceBit
278 : public BitField<uword, bool, kExternalNewSpaceBit, 1> {};
279
281
283 : ptr_(nullptr), peer_(nullptr), external_data_(0), callback_(nullptr) {}
285
286 static void Finalize(IsolateGroup* isolate_group,
287 FinalizablePersistentHandle* handle);
288
289 // Overload the ptr_ field as a next pointer when adding freed
290 // handles to the free list.
291 FinalizablePersistentHandle* Next() {
292 return reinterpret_cast<FinalizablePersistentHandle*>(
293 static_cast<uword>(ptr_));
294 }
295 void SetNext(FinalizablePersistentHandle* free_list) {
296 ptr_ = static_cast<ObjectPtr>(reinterpret_cast<uword>(free_list));
297 ASSERT(!ptr_->IsHeapObject());
298 }
299
300 void SetFinalizedNotFreed() {
301 // `handle->raw_ != Object::null()` or the GC will finalize again.
302 SetNext(this);
303 }
304
305 void FreeHandle(FinalizablePersistentHandle* free_list) {
306 Clear();
307 SetNext(free_list);
308 }
309
310 void Clear() {
311 ptr_ = Object::null();
312 peer_ = nullptr;
313 external_data_ = 0;
314 callback_ = nullptr;
315 auto_delete_ = false;
316 }
317
318 void set_ptr(ObjectPtr raw) { ptr_ = raw; }
319 void set_ptr(const LocalHandle& ref) { ptr_ = ref.ptr(); }
320 void set_ptr(const Object& object) { ptr_ = object.ptr(); }
321
322 void set_peer(void* peer) { peer_ = peer; }
323
324 void set_callback(Dart_HandleFinalizer callback) { callback_ = callback; }
325
326 void set_auto_delete(bool auto_delete) { auto_delete_ = auto_delete; }
327
328 void set_external_size(intptr_t size) {
329 intptr_t size_in_words = Utils::RoundUp(size, kObjectAlignment) / kWordSize;
331 external_data_ =
332 ExternalSizeInWordsBits::update(size_in_words, external_data_);
333 }
334
335 bool IsSetNewSpaceBit() const {
336 return ExternalNewSpaceBit::decode(external_data_);
337 }
338
339 void SetExternalNewSpaceBit() {
340 external_data_ = ExternalNewSpaceBit::update(true, external_data_);
341 }
342
343 void ClearExternalNewSpaceBit() {
344 external_data_ = ExternalNewSpaceBit::update(false, external_data_);
345 }
346
347 // Returns the space to charge for the external size.
349 // Non-heap and VM-heap objects count as old space here.
350 return ptr_->IsImmediateOrOldObject() ? Heap::kOld : Heap::kNew;
351 }
352
353 ObjectPtr ptr_;
354 void* peer_;
355 uword external_data_;
356 Dart_HandleFinalizer callback_;
357 bool auto_delete_;
358
359 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
360 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle);
361};
362
363// Local handles repository structure.
364static constexpr int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize;
365static constexpr int kLocalHandlesPerChunk = 64;
366static constexpr int kOffsetOfRawPtrInLocalHandle = 0;
367class LocalHandles : Handles<kLocalHandleSizeInWords,
368 kLocalHandlesPerChunk,
369 kOffsetOfRawPtrInLocalHandle> {
370 public:
375 if (FLAG_trace_handles) {
376 OS::PrintErr("*** Starting a new Local handle block 0x%" Px "\n",
377 reinterpret_cast<intptr_t>(this));
378 }
379 }
381 if (FLAG_trace_handles) {
382 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n",
383 reinterpret_cast<intptr_t>(this), CountHandles());
384 OS::PrintErr("*** Deleting Local handle block 0x%" Px "\n",
385 reinterpret_cast<intptr_t>(this));
386 }
387 }
388
389 // Visit all object pointers stored in the various handles.
391 visitor->set_gc_root_type("local handle");
394 visitor->clear_gc_root_type();
395 }
396
397 // Reset the local handles block for reuse.
398 void Reset() {
401 }
402
403 // Allocates a handle in the current handle scope. This handle is valid only
404 // in the current handle scope and is destroyed when the current handle
405 // scope ends.
407 return reinterpret_cast<LocalHandle*>(AllocateScopedHandle());
408 }
409
410 // Validate if passed in handle is a Local Handle.
411 bool IsValidHandle(Dart_Handle object) const {
412 return IsValidScopedHandle(reinterpret_cast<uword>(object));
413 }
414
415 // Returns a count of active handles (used for testing purposes).
416 int CountHandles() const { return CountScopedHandles(); }
417
418 private:
419 DISALLOW_COPY_AND_ASSIGN(LocalHandles);
420};
421
422// Persistent handles repository structure.
423static constexpr int kPersistentHandleSizeInWords =
424 sizeof(PersistentHandle) / kWordSize;
425static constexpr int kPersistentHandlesPerChunk = 64;
426static constexpr int kOffsetOfRawPtrInPersistentHandle = 0;
427class PersistentHandles : Handles<kPersistentHandleSizeInWords,
428 kPersistentHandlesPerChunk,
429 kOffsetOfRawPtrInPersistentHandle> {
430 public:
435 free_list_(nullptr) {
436 if (FLAG_trace_handles) {
437 OS::PrintErr("*** Starting a new Persistent handle block 0x%" Px "\n",
438 reinterpret_cast<intptr_t>(this));
439 }
440 }
442 free_list_ = nullptr;
443 if (FLAG_trace_handles) {
444 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n",
445 reinterpret_cast<intptr_t>(this), CountHandles());
446 OS::PrintErr("*** Deleting Persistent handle block 0x%" Px "\n",
447 reinterpret_cast<intptr_t>(this));
448 }
449 }
450
451 // Accessors.
452 PersistentHandle* free_list() const { return free_list_; }
453 void set_free_list(PersistentHandle* value) { free_list_ = value; }
454
455 // Visit all object pointers stored in the various handles.
457 visitor->set_gc_root_type("persistent handle");
460 visitor->clear_gc_root_type();
461 }
462
463 // Visit all the handles.
464 void Visit(HandleVisitor* visitor) {
467 }
468
469 // Allocates a persistent handle, these have to be destroyed explicitly
470 // by calling FreeHandle.
472 PersistentHandle* handle;
473 if (free_list_ != nullptr) {
474 handle = free_list_;
475 free_list_ = handle->Next();
476 } else {
477 handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle());
478 }
479 handle->set_ptr(Object::null());
480 return handle;
481 }
482
484 handle->FreeHandle(free_list());
485 set_free_list(handle);
486 }
487
488 // Validate if passed in handle is a Persistent Handle.
490 return IsValidScopedHandle(reinterpret_cast<uword>(object));
491 }
492
494 PersistentHandle* handle = free_list_;
495 while (handle != nullptr) {
496 if (handle == reinterpret_cast<PersistentHandle*>(object)) {
497 return true;
498 }
499 handle = handle->Next();
500 }
501 return false;
502 }
503
504 // Returns a count of active handles (used for testing purposes).
505 int CountHandles() const { return CountScopedHandles(); }
506
507 private:
508 PersistentHandle* free_list_;
509 DISALLOW_COPY_AND_ASSIGN(PersistentHandles);
510};
511
512// Finalizable persistent handles repository structure.
518 : Handles<kFinalizablePersistentHandleSizeInWords,
519 kFinalizablePersistentHandlesPerChunk,
520 kOffsetOfRawPtrInFinalizablePersistentHandle> {
521 public:
526 free_list_(nullptr) {}
527 ~FinalizablePersistentHandles() { free_list_ = nullptr; }
528
529 // Accessors.
530 FinalizablePersistentHandle* free_list() const { return free_list_; }
532
533 // Visit all handles stored in the various handle blocks.
538 }
539
540 // Visit all object pointers stored in the various handles.
542 visitor->set_gc_root_type("weak persistent handle");
546 VisitObjectPointers(visitor);
547 visitor->clear_gc_root_type();
548 }
549
550 // Allocates a persistent handle, these have to be destroyed explicitly
551 // by calling FreeHandle.
554 if (free_list_ != nullptr) {
555 handle = free_list_;
556 free_list_ = handle->Next();
557 handle->set_ptr(Object::null());
558 return handle;
559 }
560
561 handle =
563 handle->Clear();
564 return handle;
565 }
566
568 handle->Clear();
569 handle->SetFinalizedNotFreed();
570 }
571
573 handle->FreeHandle(free_list());
574 set_free_list(handle);
575 }
576
577 // Validate if passed in handle is a Persistent Handle.
579 return IsValidScopedHandle(reinterpret_cast<uword>(object));
580 }
581
583 return IsValidScopedHandle(reinterpret_cast<uword>(object));
584 }
585
587 FinalizablePersistentHandle* handle = free_list_;
588 while (handle != nullptr) {
589 if (handle == reinterpret_cast<FinalizablePersistentHandle*>(object)) {
590 return true;
591 }
592 handle = handle->Next();
593 }
594 return false;
595 }
596
597 // Returns a count of active handles (used for testing purposes).
598 int CountHandles() const { return CountScopedHandles(); }
599
600 private:
601 FinalizablePersistentHandle* free_list_;
602 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles);
603};
604
605// Structure used for the implementation of local scopes used in dart_api.
606// These local scopes manage handles and memory allocated in the scope.
608 public:
610 : previous_(previous), stack_marker_(stack_marker) {}
611 ~ApiLocalScope() { previous_ = nullptr; }
612
613 // Reinit the ApiLocalScope to new values.
615 previous_ = previous;
616 stack_marker_ = stack_marker;
617 zone_.Reinit(thread);
618 }
619
620 // Reset the ApiLocalScope so that it can be reused again.
621 void Reset(Thread* thread) {
622 local_handles_.Reset();
623 zone_.Reset(thread);
624 previous_ = nullptr;
625 stack_marker_ = 0;
626 }
627
628 // Accessors.
629 ApiLocalScope* previous() const { return previous_; }
630 uword stack_marker() const { return stack_marker_; }
631 void set_previous(ApiLocalScope* value) { previous_ = value; }
632 LocalHandles* local_handles() { return &local_handles_; }
633 Zone* zone() { return zone_.GetZone(); }
634
635 private:
636 ApiLocalScope* previous_;
637 uword stack_marker_;
638 LocalHandles local_handles_;
639 ApiZone zone_;
640
641 DISALLOW_COPY_AND_ASSIGN(ApiLocalScope);
642};
643
645 public:
647 // Currently no support for nesting native scopes.
648 ASSERT(Current() == nullptr);
649 OSThread::SetThreadLocal(Api::api_native_key_,
650 reinterpret_cast<uword>(this));
651 }
652
654 ASSERT(Current() == this);
655 OSThread::SetThreadLocal(Api::api_native_key_, 0);
656 }
657
658 static inline ApiNativeScope* Current() {
659 return reinterpret_cast<ApiNativeScope*>(
660 OSThread::GetThreadLocal(Api::api_native_key_));
661 }
662
664 Zone* result = zone_.GetZone();
665 ASSERT(result->handles()->CountScopedHandles() == 0);
666 ASSERT(result->handles()->CountZoneHandles() == 0);
667 return result;
668 }
669
670 private:
671 ApiZone zone_;
672};
673
674// Api growable arrays use a zone for allocation. The constructor
675// picks the zone from the current isolate if in an isolate
676// environment. When outside an isolate environment it picks the zone
677// from the current native scope.
678template <typename T>
679class ApiGrowableArray : public BaseGrowableArray<T, ValueObject, Zone> {
680 public:
681 explicit ApiGrowableArray(int initial_capacity)
683 initial_capacity,
684 ApiNativeScope::Current()->zone()) {}
687 ApiNativeScope::Current()->zone()) {}
688 ApiGrowableArray(intptr_t initial_capacity, Zone* zone)
689 : BaseGrowableArray<T, ValueObject, Zone>(initial_capacity, zone) {}
690};
691
692// Implementation of the API State used in dart api for maintaining
693// local scopes, persistent handles etc. These are setup on a per isolate
694// group basis and destroyed when the isolate group is shutdown.
695class ApiState {
696 public:
697 ApiState() : persistent_handles_(), weak_persistent_handles_() {}
698
699 void MergeOtherApiState(ApiState* api_state);
700
702 persistent_handles_.VisitObjectPointers(visitor);
703 if (visitor->visit_weak_persistent_handles()) {
704 weak_persistent_handles_.VisitObjectPointers(visitor);
705 }
706 }
707
709 weak_persistent_handles_.VisitHandles(visitor);
710 }
711
713 MutexLocker ml(&mutex_);
714 return persistent_handles_.AllocateHandle();
715 }
717 MutexLocker ml(&mutex_);
718 persistent_handles_.FreeHandle(ref);
719 }
720
722 MutexLocker ml(&mutex_);
723 return weak_persistent_handles_.AllocateHandle();
724 }
726 MutexLocker ml(&mutex_);
727 weak_persistent_handles_.ClearHandle(weak_ref);
728 }
730 MutexLocker ml(&mutex_);
731 weak_persistent_handles_.FreeHandle(weak_ref);
732 }
733
735 MutexLocker ml(&mutex_);
736 return persistent_handles_.IsValidHandle(object);
737 }
738
740 MutexLocker ml(&mutex_);
741 return persistent_handles_.IsValidHandle(object) &&
742 !persistent_handles_.IsFreeHandle(object);
743 }
744
746 MutexLocker ml(&mutex_);
747 return weak_persistent_handles_.IsValidHandle(object);
748 }
749
751 MutexLocker ml(&mutex_);
752 return weak_persistent_handles_.IsValidHandle(object);
753 }
754
756 MutexLocker ml(&mutex_);
757 return weak_persistent_handles_.IsValidHandle(object) &&
758 !weak_persistent_handles_.IsFreeHandle(object);
759 }
760
762 MutexLocker ml(&mutex_);
763 return persistent_handles_.CountHandles();
764 }
765
767 std::function<void(PersistentHandles&)> fun) {
768 MutexLocker ml(&mutex_);
769 fun(persistent_handles_);
770 }
771
774 MutexLocker ml(&mutex_);
775 fun(weak_persistent_handles_);
776 }
777
778 WeakTable* acquired_table() { return &acquired_table_; }
779
780 private:
781 Mutex mutex_;
782
783 PersistentHandles persistent_handles_;
784 FinalizablePersistentHandles weak_persistent_handles_;
785 WeakTable acquired_table_;
786
787 DISALLOW_COPY_AND_ASSIGN(ApiState);
788};
789
791 IsolateGroup* isolate_group,
792 const Object& object,
793 void* peer,
795 intptr_t external_size,
796 bool auto_delete) {
797 ApiState* state = isolate_group->api_state();
798 ASSERT(state != nullptr);
799 FinalizablePersistentHandle* ref = state->AllocateWeakPersistentHandle();
800 ref->set_ptr(object);
801 ref->set_peer(peer);
802 ref->set_callback(callback);
803 ref->set_auto_delete(auto_delete);
804 // This may trigger GC, so it must be called last.
805 if (!(ref->SetExternalSize(external_size, isolate_group))) {
806 state->FreeWeakPersistentHandle(ref);
807 return nullptr;
808 }
809 return ref;
810}
811
812} // namespace dart
813
814#endif // RUNTIME_VM_DART_API_STATE_H_
static bool is_valid(SkISize dim)
ApiGrowableArray(int initial_capacity)
ApiGrowableArray(intptr_t initial_capacity, Zone *zone)
uword stack_marker() const
void Reinit(Thread *thread, ApiLocalScope *previous, uword stack_marker)
void set_previous(ApiLocalScope *value)
LocalHandles * local_handles()
ApiLocalScope(ApiLocalScope *previous, uword stack_marker)
ApiLocalScope * previous() const
void Reset(Thread *thread)
static ApiNativeScope * Current()
void VisitWeakHandlesUnlocked(HandleVisitor *visitor)
bool IsActivePersistentHandle(Dart_PersistentHandle object)
WeakTable * acquired_table()
void ClearWeakPersistentHandle(FinalizablePersistentHandle *weak_ref)
bool IsValidPersistentHandle(Dart_PersistentHandle object)
PersistentHandle * AllocatePersistentHandle()
FinalizablePersistentHandle * AllocateWeakPersistentHandle()
void RunWithLockedWeakPersistentHandles(std::function< void(FinalizablePersistentHandles &)> fun)
void VisitObjectPointersUnlocked(ObjectPointerVisitor *visitor)
void MergeOtherApiState(ApiState *api_state)
bool IsValidWeakPersistentHandle(Dart_WeakPersistentHandle object)
void FreePersistentHandle(PersistentHandle *ref)
void FreeWeakPersistentHandle(FinalizablePersistentHandle *weak_ref)
bool IsValidFinalizableHandle(Dart_FinalizableHandle object)
int CountPersistentHandles()
bool IsActiveWeakPersistentHandle(Dart_WeakPersistentHandle object)
void RunWithLockedPersistentHandles(std::function< void(PersistentHandles &)> fun)
intptr_t SizeInBytes() const
void Reinit(Thread *thread)
Zone * GetZone()
uword AllocUnsafe(intptr_t size)
void Reset(Thread *thread)
ElementType * Alloc(intptr_t len)
ElementType * Realloc(ElementType *old_array, intptr_t old_len, intptr_t new_len)
static FinalizablePersistentHandle * New(IsolateGroup *isolate_group, const Object &object, void *peer, Dart_HandleFinalizer callback, intptr_t external_size, bool auto_delete)
Dart_HandleFinalizer callback() const
Dart_FinalizableHandle ApiFinalizableHandle()
void UpdateUnreachable(IsolateGroup *isolate_group)
void EnsureFreedExternal(IsolateGroup *isolate_group)
bool SetExternalSize(intptr_t size, IsolateGroup *isolate_group)
void UpdateRelocated(IsolateGroup *isolate_group)
Dart_WeakPersistentHandle ApiWeakPersistentHandle()
static FinalizablePersistentHandle * Cast(Dart_WeakPersistentHandle handle)
void ClearHandle(FinalizablePersistentHandle *handle)
void FreeHandle(FinalizablePersistentHandle *handle)
FinalizablePersistentHandle * AllocateHandle()
void set_free_list(FinalizablePersistentHandle *value)
bool IsFreeHandle(Dart_WeakPersistentHandle object) const
void VisitHandles(HandleVisitor *visitor)
bool IsValidHandle(Dart_WeakPersistentHandle object) const
FinalizablePersistentHandle * free_list() const
bool IsValidHandle(Dart_FinalizableHandle object) const
void VisitObjectPointers(ObjectPointerVisitor *visitor)
int CountZoneHandles() const
Definition: handles_impl.h:228
int CountScopedHandles() const
Definition: handles_impl.h:212
bool AllocatedExternal(intptr_t size, Space space)
Definition: heap.cc:180
@ kNew
Definition: heap.h:38
@ kOld
Definition: heap.h:39
void PromotedExternal(intptr_t size)
Definition: heap.cc:210
void FreedExternal(intptr_t size, Space space)
Definition: heap.cc:201
Heap * heap() const
Definition: isolate.h:296
ApiState * api_state() const
Definition: isolate.h:700
void set_ptr(ObjectPtr ptr)
ObjectPtr ptr() const
static intptr_t ptr_offset()
Dart_Handle apiHandle()
int CountHandles() const
LocalHandle * AllocateHandle()
void VisitObjectPointers(ObjectPointerVisitor *visitor)
bool IsValidHandle(Dart_Handle object) const
static uword GetThreadLocal(ThreadLocalKey key)
Definition: os_thread.h:222
static void SetThreadLocal(ThreadLocalKey key, uword value)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
void set_gc_root_type(const char *gc_root_type)
Definition: visitor.h:58
virtual bool visit_weak_persistent_handles() const
Definition: visitor.h:64
static ObjectPtr null()
Definition: object.h:433
Dart_PersistentHandle apiHandle()
void set_ptr(const Object &object)
static intptr_t ptr_offset()
void set_ptr(const LocalHandle &ref)
void set_ptr(ObjectPtr ref)
static PersistentHandle * Cast(Dart_PersistentHandle handle)
ObjectPtr ptr() const
PersistentHandle * AllocateHandle()
bool IsValidHandle(Dart_PersistentHandle object) const
PersistentHandle * free_list() const
void VisitObjectPointers(ObjectPointerVisitor *visitor)
void FreeHandle(PersistentHandle *handle)
void Visit(HandleVisitor *visitor)
bool IsFreeHandle(Dart_PersistentHandle object) const
void set_free_list(PersistentHandle *value)
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
Definition: utils.h:120
void * AllocUnsafe(intptr_t size)
uintptr_t SizeInBytes() const
Definition: zone.cc:182
ElementType * Realloc(ElementType *old_array, intptr_t old_length, intptr_t new_length)
VMHandles * handles()
Definition: zone.h:73
ElementType * Alloc(intptr_t length)
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
void(* Dart_HandleFinalizer)(void *isolate_callback_data, void *peer)
Definition: dart_api.h:265
Dart_Handle Dart_PersistentHandle
Definition: dart_api.h:259
struct _Dart_FinalizableHandle * Dart_FinalizableHandle
Definition: dart_api.h:261
struct _Dart_WeakPersistentHandle * Dart_WeakPersistentHandle
Definition: dart_api.h:260
#define ASSERT(E)
AtkStateType state
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
uint8_t value
GAsyncResult * result
Dart_NativeFunction function
Definition: fuchsia.cc:51
Definition: dart_vm.cc:33
static constexpr int kPersistentHandlesPerChunk
static constexpr int kLocalHandlesPerChunk
constexpr intptr_t kBitsPerWord
Definition: globals.h:514
static constexpr int kPersistentHandleSizeInWords
static constexpr int kOffsetOfRawPtrInPersistentHandle
void ProtectedHandleCallback(void *peer)
static constexpr int kOffsetOfRawPtrInLocalHandle
constexpr intptr_t kWordSizeLog2
Definition: globals.h:507
uintptr_t uword
Definition: globals.h:501
static constexpr int kFinalizablePersistentHandleSizeInWords
static constexpr int kFinalizablePersistentHandlesPerChunk
static constexpr int kLocalHandleSizeInWords
constexpr intptr_t kWordSize
Definition: globals.h:509
Heap::Space SpaceForExternal(FinalizerEntryPtr raw_entry)
Definition: gc_shared.cc:42
static constexpr intptr_t kObjectAlignment
const intptr_t kMaxAddrSpaceInWords
Definition: globals.h:50
static constexpr int kOffsetOfRawPtrInFinalizablePersistentHandle
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
#define Px
Definition: globals.h:410
#define DISALLOW_ALLOCATION()
Definition: globals.h:604
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581
static DecodeResult decode(std::string path)
Definition: png_codec.cpp:124
#define T
Definition: precompiler.cc:65
#define OFFSET_OF(type, field)
Definition: globals.h:138