| // 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. | 
 |  | 
 | // Issue https://github.com/dart-lang/sdk/issues/50537 | 
 |  | 
 | import "dart:async"; | 
 | import "dart:ffi"; | 
 | import "dart:io"; | 
 |  | 
 | final libc = DynamicLibrary.process(); | 
 | typedef MallocForeign = Pointer<Void> Function(IntPtr size); | 
 | typedef MallocNative = Pointer<Void> Function(int size); | 
 | final malloc = libc.lookupFunction<MallocForeign, MallocNative>('malloc'); | 
 | typedef FreeForeign = Void Function(Pointer<Void>); | 
 | final free = libc.lookup<NativeFunction<FreeForeign>>('free'); | 
 | final freeFinalizer = NativeFinalizer(free); | 
 |  | 
 | class Resource implements Finalizable { | 
 |   Pointer<Void> _target; | 
 |   Resource() : _target = malloc(8) { | 
 |     if (_target == nullptr) { | 
 |       throw OutOfMemoryError(); | 
 |     } | 
 |     freeFinalizer.attach(this, _target, detach: this, externalSize: 8); | 
 |   } | 
 | } | 
 |  | 
 | void main() { | 
 |   if (Platform.isWindows) { | 
 |     print("No malloc via self process lookup on Windows"); | 
 |     return; | 
 |   } | 
 |  | 
 |   // Split across turns so the internal finalizer cleanup can run. | 
 |   // Cf. https://github.com/dart-lang/sdk/issues/50570 | 
 |   final sw = Stopwatch()..start(); | 
 |   step() { | 
 |     if (sw.elapsedMilliseconds < 2000) { | 
 |       // VM assertion: external size of each generation should always be | 
 |       // non-negative. | 
 |       List.generate(1000, (_) => new Resource()); | 
 |       Timer.run(step); | 
 |     } | 
 |   } | 
 |  | 
 |   Timer.run(step); | 
 | } |