// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax // This test asserts that the cleanup function call, scheduled by GC, is a // microtask and not a normal task. // Inside a microtask, cause GC (which should schedule the cleanup as // microtask). lso schedule another microtask. Assert that the cleanup // function ran before the other microtask. let cleanedUp = false; function scheduleMicrotask(func) { Promise.resolve().then(func); } let log = []; let cleanup = (holdings) => { cleanedUp = true; } let fg = new FinalizationRegistry(cleanup); let o = null; (function() { // Use a closure here to avoid other references to o which might keep it alive // (e.g., stack frames pointing to it). o = {}; fg.register(o, {}); })(); let microtask = function() { log.push("first_microtask"); // cause GC during a microtask o = null; gc(); } assertFalse(cleanedUp); // enqueue microtask that triggers GC Promise.resolve().then(microtask); // but cleanup callback hasn't been called yet, as we're still in // synchronous execution assertFalse(cleanedUp); // flush the microtask queue to run the microtask that triggers GC %PerformMicrotaskCheckpoint(); // still no cleanup callback, because it runs after as a separate task assertFalse(cleanedUp); setTimeout(() => { assertTrue(cleanedUp); }, 0);