blob: 92dc3c7fe6df3d3ff2baa7bfc50d781ec68509b9 [file] [log] [blame]
// 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<NativeUnaryOp, UnaryOpVoid>("CollectOnNthAllocation");
extension PointerOffsetBy<T extends NativeType> on Pointer<T> {
Pointer<T> 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<IntPtr> token) {
final myFinalizable = MyFinalizable();
setTokenFinalizer.attach(myFinalizable, token.cast());
}
final setTokenTo42Ptr =
ffiTestFunctions.lookup<NativeFinalizerFunction>("SetArgumentTo42");
final setTokenFinalizer = NativeFinalizer(setTokenTo42Ptr);
class MyFinalizable implements Finalizable {}