5#ifndef RUNTIME_VM_HEAP_POINTER_BLOCK_H_
6#define RUNTIME_VM_HEAP_POINTER_BLOCK_H_
17class ObjectPointerVisitor;
33 intptr_t
Count()
const {
return top_; }
39 pointers_[top_++] = obj;
44 return pointers_[--top_];
51 for (intptr_t i = 0; i <
Count(); i++) {
52 if (pointers_[i] == obj) {
73 PointerBlock<Size>* next_;
75 ObjectPtr pointers_[
kSize];
79 template <
int,
typename T>
88template <
int BlockSize>
121 List() : head_(nullptr), length_(0) {}
125 intptr_t
length()
const {
return length_; }
126 bool IsEmpty()
const {
return head_ ==
nullptr; }
157template <
typename Stack>
160 typedef typename Stack::Block
Block;
163 local_output_ = stack_->PopEmptyBlock();
164 local_input_ = stack_->PopEmptyBlock();
168 ASSERT(local_output_ ==
nullptr);
169 ASSERT(local_input_ ==
nullptr);
170 ASSERT(stack_ ==
nullptr);
175 ASSERT(local_input_ !=
nullptr);
176 if (
UNLIKELY(local_input_->IsEmpty())) {
177 if (!local_output_->IsEmpty()) {
178 auto temp = local_output_;
179 local_output_ = local_input_;
182 Block* new_work = stack_->PopNonEmptyBlock();
183 if (new_work ==
nullptr) {
186 stack_->PushBlock(local_input_);
187 local_input_ = new_work;
192 *
object = local_input_->Pop();
197 if (
UNLIKELY(local_output_->IsFull())) {
198 stack_->PushBlock(local_output_);
199 local_output_ = stack_->PopEmptyBlock();
201 local_output_->Push(raw_obj);
205 if (!local_output_->IsEmpty()) {
206 stack_->PushBlock(local_output_);
207 local_output_ = stack_->PopEmptyBlock();
209 if (!local_input_->IsEmpty()) {
210 stack_->PushBlock(local_input_);
211 local_input_ = stack_->PopEmptyBlock();
216 ASSERT(local_input_->IsEmpty() || abort);
217 Block* new_work = stack_->WaitForWork(num_busy, abort);
218 if (new_work ==
nullptr) {
221 stack_->PushBlock(local_input_);
222 local_input_ = new_work;
227 ASSERT(local_output_->IsEmpty());
228 stack_->PushBlock(local_output_);
229 local_output_ =
nullptr;
230 ASSERT(local_input_->IsEmpty());
231 stack_->PushBlock(local_input_);
232 local_input_ =
nullptr;
238 stack_->PushBlock(local_output_);
239 local_output_ =
nullptr;
240 stack_->PushBlock(local_input_);
241 local_input_ =
nullptr;
246 if (!local_input_->IsEmpty()) {
249 if (!local_output_->IsEmpty()) {
258 Block* local_output_;
308template <
int Size,
typename T>
314 template <
typename Lambda>
318 while (block !=
nullptr) {
319 while (!block->IsEmpty()) {
320 action(
static_cast<T>(block->Pop()));
322 auto*
next = block->next();
348 while (block !=
nullptr) {
349 auto*
next = block->next_;
static float next(float f)
static void TrimGlobalEmpty()
Block * PopNonFullBlock()
static Mutex * global_mutex_
PointerBlock< BlockSize > Block
Block * WaitForWork(RelaxedAtomic< uintptr_t > *num_busy, bool abort)
static List * global_empty_
void PushAll(Block *blocks)
void VisitObjectPointers(ObjectPointerVisitor *visitor)
static constexpr intptr_t kMaxGlobalEmpty
void PushBlockImpl(Block *block)
Block * PopNonEmptyBlock()
void Push(ObjectPtr raw_obj)
BlockWorkList(Stack *stack)
bool Pop(ObjectPtr *object)
bool WaitForWork(RelaxedAtomic< uintptr_t > *num_busy, bool abort=false)
DART_FORCE_INLINE void Process(Lambda action)
void PushBlock(Block *block)
static intptr_t pointers_offset()
static intptr_t top_offset()
PointerBlock< Size > * next() const
void set_next(PointerBlock< Size > *next)
void VisitObjectPointers(ObjectPointerVisitor *visitor)
void PushBlock(Block *block, ThresholdPolicy policy)
static constexpr intptr_t kMaxNonEmpty
#define MSAN_UNPOISON(ptr, len)
StoreBuffer::Block StoreBufferBlock
static constexpr int kMarkingStackBlockSize
MarkingStack::Block MarkingStackBlock
static constexpr int kPromotionStackBlockSize
PromotionStack::Block PromotionStackBlock
BlockWorkList< PromotionStack > PromotionWorkList
static constexpr int kStoreBufferBlockSize
BlockWorkList< MarkingStack > MarkerWorkList
#define OFFSET_OF(type, field)