5#ifndef RUNTIME_VM_HANDLES_H_
6#define RUNTIME_VM_HANDLES_H_
50class ObjectPointerVisitor;
53template <
int kHandleSizeInWords,
int kHandlesPerChunk,
int kOffsetOfRawPtr>
57 : zone_blocks_(nullptr),
58 first_scoped_block_(nullptr),
59 scoped_blocks_(&first_scoped_block_) {}
92 static bool IsZoneHandle(
uword handle);
97 if (scoped_blocks_->IsFull()) {
98 SetupNextScopeBlock();
100 return scoped_blocks_->AllocateHandle();
104 if (zone_blocks_ !=
nullptr)
return false;
105 if (first_scoped_block_.HandleCount() != 0)
return false;
106 if (scoped_blocks_ != &first_scoped_block_)
return false;
111 intptr_t capacity = 0;
112 for (HandlesBlock* block = zone_blocks_; block !=
nullptr;
113 block = block->next_block()) {
114 capacity +=
sizeof(*block);
120 intptr_t capacity = 0;
121 for (HandlesBlock* block = scoped_blocks_; block !=
nullptr;
122 block = block->next_block()) {
123 capacity +=
sizeof(*block);
146 explicit HandlesBlock(HandlesBlock*
next)
147 : next_block_(
next), next_handle_slot_(0) {}
154 bool IsFull()
const {
155 return next_handle_slot_ >= (kHandleSizeInWords * kHandlesPerChunk);
159 bool IsValidHandle(
uword handle)
const {
162 return (start <= handle && handle < end);
168 uword handle_address =
reinterpret_cast<uword>(data_ + next_handle_slot_);
169 next_handle_slot_ += kHandleSizeInWords;
170 return handle_address;
177 void Visit(HandleVisitor* visitor);
181 void ZapFreeHandles();
185 int HandleCount()
const;
188 intptr_t next_handle_slot()
const {
return next_handle_slot_; }
189 void set_next_handle_slot(intptr_t next_handle_slot) {
190 next_handle_slot_ = next_handle_slot;
192 HandlesBlock* next_block()
const {
return next_block_; }
193 void set_next_block(HandlesBlock*
next) { next_block_ =
next; }
196 HandlesBlock* next_block_;
197 intptr_t next_handle_slot_;
198 uword data_[kHandleSizeInWords * kHandlesPerChunk];
205 void DeleteHandleBlocks(HandlesBlock* blocks);
208 void SetupNextScopeBlock();
211 uword AllocateHandleInZone() {
212 if (zone_blocks_ ==
nullptr || zone_blocks_->IsFull()) {
213 SetupNextZoneBlock();
215 return zone_blocks_->AllocateHandle();
219 void SetupNextZoneBlock();
221 HandlesBlock* zone_blocks_;
222 HandlesBlock first_scoped_block_;
223 HandlesBlock* scoped_blocks_;
236static constexpr int kOffsetOfIsZoneHandle = 2;
251 if (FLAG_trace_handles) {
253 reinterpret_cast<intptr_t
>(
this));
259 if (FLAG_trace_handles) {
261 "):Zone = %d,Scoped = %d\n",
265 reinterpret_cast<intptr_t
>(
this));
284 static bool IsZoneHandle(
uword handle);
312 VMHandles::HandlesBlock* saved_handle_block_;
313 uword saved_handle_slot_;
321#define HANDLESCOPE(thread) \
322 dart::HandleScope vm_internal_handles_scope_(thread);
static float next(float f)
HandleScope(ThreadState *thread)
int CountZoneHandles() const
static uword AllocateZoneHandle(Zone *zone)
void VisitUnvisitedScopedHandles(ObjectPointerVisitor *visitor)
bool IsValidZoneHandle(uword handle) const
intptr_t ZoneHandlesCapacityInBytes() const
intptr_t ScopedHandlesCapacityInBytes() const
void Visit(HandleVisitor *visitor)
void VisitObjectPointers(ObjectPointerVisitor *visitor)
uword AllocateScopedHandle()
int CountScopedHandles() const
void VisitScopedHandles(ObjectPointerVisitor *visitor)
static uword AllocateHandle(Zone *zone)
bool IsValidScopedHandle(uword handle) const
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
ThreadState * thread() const
static int ZoneHandleCount()
static constexpr int kOffsetOfRawPtrInHandle
static uword AllocateZoneHandle(Zone *zone)
static uword AllocateHandle(Zone *zone)
void VisitObjectPointers(ObjectPointerVisitor *visitor)
static int ScopedHandleCount()
static constexpr int kVMHandleSizeInWords
static constexpr int kVMHandlesPerChunk
static constexpr int kOffsetOfRawPtr
constexpr intptr_t kWordSize