108 FinalizerEntryPtr raw_entry,
110 GCVisitorType* visitor) {
111 PointerPtr callback_pointer = raw_finalizer->untag()->callback();
113 callback_pointer->untag()->data());
115 const bool is_detached = token_object == raw_entry;
116 const intptr_t external_size = raw_entry->
untag()->external_size();
119 ASSERT(token_object == raw_entry);
120 ASSERT(external_size == 0);
121 if (FLAG_trace_finalizers) {
122 TRACE_FINALIZER(
"Not running native finalizer %p callback %p, detached",
127 ASSERT(token_object.IsPointer());
128 PointerPtr token =
static_cast<PointerPtr
>(token_object);
129 void* peer =
reinterpret_cast<void*
>(token->untag()->data());
130 if (FLAG_trace_finalizers) {
131 TRACE_FINALIZER(
"Running native finalizer %p callback %p with token %p",
132 raw_finalizer->untag(),
callback, peer);
134 raw_entry.untag()->set_token(raw_entry);
136 if (external_size > 0) {
137 if (FLAG_trace_finalizers) {
139 external_size, before_gc_space == 0 ?
"new" :
"old");
141 visitor->isolate_group()->heap()->FreedExternal(external_size,
143 raw_entry->untag()->set_external_size(0);
163 FinalizerEntryPtr current_entry) {
167 const bool value_collected_this_gc =
168 GCVisitorType::ForwardOrSetNullIfCollected(
169 current_entry, ¤t_entry->untag()->value_);
170 if (!value_collected_this_gc && before_gc_space ==
Heap::kNew) {
173 const intptr_t external_size = current_entry->untag()->external_size_;
175 " bytes from new to old space",
177 visitor->isolate_group()->heap()->PromotedExternal(external_size);
180 GCVisitorType::ForwardOrSetNullIfCollected(current_entry,
181 ¤t_entry->untag()->detach_);
182 GCVisitorType::ForwardOrSetNullIfCollected(
183 current_entry, ¤t_entry->untag()->finalizer_);
187 const bool is_detached = token_object == current_entry;
189 if (!value_collected_this_gc)
return;
190 if (is_detached)
return;
192 FinalizerBasePtr finalizer = current_entry->
untag()->finalizer();
194 if (finalizer.IsRawNull()) {
196 current_entry->untag());
203 current_entry->untag(), finalizer->untag());
205 FinalizerPtr finalizer_dart =
static_cast<FinalizerPtr
>(finalizer);
220 if (finalizer.IsNativeFinalizer()) {
221 NativeFinalizerPtr native_finalizer =
222 static_cast<NativeFinalizerPtr
>(finalizer);
232 FinalizerEntryPtr previous_head =
233 finalizer_dart->untag()->exchange_entries_collected(current_entry);
234 current_entry->untag()->set_next(previous_head);
235 const bool first_entry = previous_head.IsRawNull();
241 if (!first_entry && previous_head->IsNewObject() &&
242 current_entry->IsOldObject()) {
243 TRACE_FINALIZER(
"Entry %p (old) next is %p (new)", current_entry->untag(),
244 previous_head->untag());
250 Isolate* isolate = finalizer->untag()->isolate_;
251 if (isolate ==
nullptr) {
252 TRACE_FINALIZER(
"Not scheduling finalizer %p callback on isolate null",
256 finalizer->untag(), isolate);