Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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_; }
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.
348 Heap::Space SpaceForExternal() const {
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.
396
397 // Reset the local handles block for reuse.
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:
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.
462
463 // Visit all the handles.
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_;
510};
511
512// Finalizable persistent handles repository structure.
518 : Handles<kFinalizablePersistentHandleSizeInWords,
519 kFinalizablePersistentHandlesPerChunk,
520 kOffsetOfRawPtrInFinalizablePersistentHandle> {
521 public:
527 ~FinalizablePersistentHandles() { free_list_ = nullptr; }
528
529 // Accessors.
530 FinalizablePersistentHandle* free_list() const { return free_list_; }
531 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; }
532
533 // Visit all handles stored in the various handle blocks.
539
540 // Visit all object pointers stored in the various handles.
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_;
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:
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
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
773 std::function<void(FinalizablePersistentHandles&)> fun) {
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
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_
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)
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 constexpr uword update(intptr_t value, uword original)
Definition bitfield.h:190
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
int CountScopedHandles() const
bool AllocatedExternal(intptr_t size, Space space)
Definition heap.cc:179
@ kNew
Definition heap.h:38
@ kOld
Definition heap.h:39
void PromotedExternal(intptr_t size)
Definition heap.cc:209
void FreedExternal(intptr_t size, Space space)
Definition heap.cc:200
Heap * heap() const
Definition isolate.h:295
ApiState * api_state() const
Definition isolate.h:693
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:218
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
static Thread * Current()
Definition thread.h:361
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:105
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
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
static constexpr intptr_t kObjectAlignment
const intptr_t kMaxAddrSpaceInWords
Definition globals.h:50
static constexpr int kOffsetOfRawPtrInFinalizablePersistentHandle
#define Px
Definition globals.h:410
#define DISALLOW_ALLOCATION()
Definition globals.h:604
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
#define T
#define OFFSET_OF(type, field)
Definition globals.h:138