// Copyright (c) 2019, 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. // // Helpers for tests which trigger GC in delicate places. // ignore: import_internal_library, unused_import import 'dart:_internal'; import 'dart:ffi'; import 'dylib_utils.dart'; typedef NativeNullaryOp = Void Function(); typedef NullaryOpVoid = void Function(); typedef NativeUnaryOp = Void Function(IntPtr); typedef UnaryOpVoid = void Function(int); final DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific( "ffi_test_functions", ); final collectOnNthAllocation = ffiTestFunctions .lookupFunction("CollectOnNthAllocation"); extension PointerOffsetBy on Pointer { Pointer offsetBy(int bytes) => Pointer.fromAddress(address + bytes); } /// Triggers garbage collection. // Defined in `dart:_internal`. // ignore: undefined_identifier void triggerGc() => VMInternalsForTesting.collectAllGarbage(); void Function(String) _namedPrint(String? name) { if (name != null) { return (String value) => print('$name: $value'); } return (String value) => print(value); } /// Does a GC and if [doAwait] awaits a future to enable running finalizers. /// /// Also prints for debug purposes. /// /// If provided, [name] prefixes the debug prints. void doGC({String? name}) { final _print = _namedPrint(name); _print('Do GC.'); triggerGc(); _print('GC done'); } void createAndLoseFinalizable(Pointer token) { final myFinalizable = MyFinalizable(); setTokenFinalizer.attach(myFinalizable, token.cast()); } final setTokenTo42Ptr = ffiTestFunctions.lookup( "SetArgumentTo42", ); final setTokenFinalizer = NativeFinalizer(setTokenTo42Ptr); class MyFinalizable implements Finalizable {}