blob: 1d2bf6473d710e7b276bad00072548b2a8e467f0 [file] [log] [blame]
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Logic shared between the Scavenger and Marker.
#ifndef RUNTIME_VM_HEAP_GC_SHARED_H_
#define RUNTIME_VM_HEAP_GC_SHARED_H_
#include "vm/compiler/runtime_api.h"
#if defined(SHOULD_NOT_INCLUDE_RUNTIME)
#error "Should not include runtime"
#endif
#include "vm/dart_api_state.h"
#include "vm/heap/scavenger.h"
#include "vm/log.h"
#include "vm/message_handler.h"
#include "vm/object.h"
namespace dart {
// These object types have a linked list chaining all pending objects when
// processing these in the GC.
// The field should not be visited by pointer visitors.
// The field should only be set during a GC.
//
// Macro params:
// - type
// - variable name
#define GC_LINKED_LIST(V) \
V(WeakProperty, weak_properties) \
V(WeakReference, weak_references)
template <typename Type, typename PtrType>
class GCLinkedList {
public:
void Enqueue(PtrType ptr) {
ptr->untag()->next_seen_by_gc_ = head_;
if (head_ == Type::null()) {
tail_ = ptr;
}
head_ = ptr;
}
void FlushInto(GCLinkedList<Type, PtrType>* to) {
if (to->head_ == Type::null()) {
ASSERT(to->tail_ == Type::null());
to->head_ = head_;
to->tail_ = tail_;
} else {
ASSERT(to->tail_ != Type::null());
ASSERT(to->tail_->untag()->next_seen_by_gc() == Type::null());
to->tail_->untag()->next_seen_by_gc_ = head_;
to->tail_ = tail_;
}
Release();
}
PtrType Release() {
PtrType return_value = head_;
head_ = Type::null();
tail_ = Type::null();
return return_value;
}
bool IsEmpty() { return head_ == Type::null() && tail_ == Type::null(); }
private:
PtrType head_ = Type::null();
PtrType tail_ = Type::null();
};
struct GCLinkedLists {
void Release();
bool IsEmpty();
void FlushInto(GCLinkedLists* to);
#define FOREACH(type, var) GCLinkedList<type, type##Ptr> var;
GC_LINKED_LIST(FOREACH)
#undef FOREACH
};
} // namespace dart
#endif // RUNTIME_VM_HEAP_GC_SHARED_H_