Version 2.18.0-78.0.dev
Merge commit '8566dbeb5790663792f331269996c39f087d713b' into 'dev'
diff --git a/DEPS b/DEPS
index 51d7633..fe525a4 100644
--- a/DEPS
+++ b/DEPS
@@ -49,7 +49,7 @@
"co19_2_rev": "b2034a17609472e374623f3dbe0efd9f5cb258af",
# The internal benchmarks to use. See go/dart-benchmarks-internal
- "benchmarks_internal_rev": "076df10d9b77af337f2d8029725787155eb1cd52",
+ "benchmarks_internal_rev": "599aa474a03c37be146f82dfbad85f34f25ffa47",
"checkout_benchmarks_internal": False,
# Checkout Android dependencies only on Mac and Linux.
diff --git a/benchmarks/Isolate/dart2/Isolate.dart b/benchmarks/Isolate/dart2/Isolate.dart
index 7014df6..c8bfaab 100644
--- a/benchmarks/Isolate/dart2/Isolate.dart
+++ b/benchmarks/Isolate/dart2/Isolate.dart
@@ -8,8 +8,7 @@
import 'dart:isolate';
import 'dart:typed_data';
-import 'package:benchmark_harness/benchmark_harness.dart'
- show PrintEmitter, ScoreEmitter;
+import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:meta/meta.dart';
class SendReceiveBytes extends AsyncBenchmarkBase {
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py
index d1d4fb5..10b878a 100644
--- a/build/toolchain/win/setup_toolchain.py
+++ b/build/toolchain/win/setup_toolchain.py
@@ -118,8 +118,15 @@
args.extend(('&&', 'set'))
popen = subprocess.Popen(
args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- variables, _ = popen.communicate()
- env = _ExtractImportantEnvironment(variables)
+ stdout_data, stderr_data = popen.communicate()
+ if popen.returncode != 0:
+ print('Error, got returncode:', popen.returncode)
+ print('## stdout:')
+ print(stdout_data)
+ print('## stderr:')
+ print(stderr_data)
+ sys.exit(2)
+ env = _ExtractImportantEnvironment(stdout_data)
env['PATH'] = runtime_dirs + ';' + env['PATH']
if cpu == target_cpu:
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 9a145c4..1049101 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -1394,6 +1394,20 @@
__ Bind(&init_done);
__ Comment("Copy frame to SuspendState");
+#ifdef DEBUG
+ {
+ // Verify that SuspendState.frame_size == kFrameSize.
+ Label okay;
+ __ LoadFromOffset(
+ kTemp,
+ FieldAddress(kSuspendState, target::SuspendState::frame_size_offset()));
+ __ CompareRegisters(kTemp, kFrameSize);
+ __ BranchIf(EQUAL, &okay);
+ __ Breakpoint();
+ __ Bind(&okay);
+ }
+#endif
+
__ LoadFromOffset(
kTemp, Address(FPREG, kSavedCallerPcSlotFromFp * target::kWordSize));
__ StoreToOffset(
@@ -1412,6 +1426,8 @@
#ifdef DEBUG
{
+ // Verify that kSuspendState matches :suspend_state in the copied stack
+ // frame.
Label okay;
__ LoadFromOffset(
kTemp,
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index ed63079..da1ffb1 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -222,8 +222,8 @@
Timeline::stream_##name##_.set_enabled(false);
TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE)
#undef TIMELINE_STREAM_DISABLE
- Timeline::Clear();
RecorderLock::WaitForShutdown();
+ Timeline::Clear();
delete recorder_;
recorder_ = NULL;
if (enabled_streams_ != NULL) {
diff --git a/sdk/lib/core/weak.dart b/sdk/lib/core/weak.dart
index 0da4c16..e7832d8 100644
--- a/sdk/lib/core/weak.dart
+++ b/sdk/lib/core/weak.dart
@@ -93,8 +93,8 @@
/// /// ```
/// /// final cached = CachedComputation(
/// /// () => jsonDecode(someJsonSource) as Object);
-/// /// print(cached.result);
-/// /// print(cached.result);
+/// /// print(cached.result); // Executes computation.
+/// /// print(cached.result); // Most likely uses cache.
/// /// ```
/// class CachedComputation<R extends Object> {
/// final R Function() computation;
@@ -164,8 +164,8 @@
/// factory Database.connect() {
/// // Wraps the connection in a nice user API,
/// // *and* closes connection if the user forgets to.
-/// var connection = DBConnection.connect();
-/// var wrapper = Database._fromConnection(connection);
+/// final connection = DBConnection.connect();
+/// final wrapper = Database._fromConnection(connection);
/// // Get finalizer callback when `wrapper` is no longer reachable.
/// _finalizer.attach(wrapper, connection, detach: wrapper);
/// return wrapper;
@@ -253,8 +253,8 @@
/// factory Database.connect() {
/// // Wraps the connection in a nice user API,
/// // *and* closes connection if the user forgets to.
- /// var connection = DBConnection.connect();
- /// var wrapper = Database._fromConnection();
+ /// final connection = DBConnection.connect();
+ /// final wrapper = Database._fromConnection();
/// // Get finalizer callback when `wrapper` is no longer reachable.
/// _finalizer.attach(wrapper, connection, detach: wrapper);
/// return wrapper;
diff --git a/sdk/lib/ffi/allocation.dart b/sdk/lib/ffi/allocation.dart
index 45673cc..0ffdbbe 100644
--- a/sdk/lib/ffi/allocation.dart
+++ b/sdk/lib/ffi/allocation.dart
@@ -4,7 +4,53 @@
part of dart.ffi;
+// Examples can assume:
+// late Allocator allocator;
+// late Allocator calloc;
+
/// Manages memory on the native heap.
+///
+/// When allocating memory, prefer calling this allocator directly as a
+/// function (see [AllocatorAlloc.call] for details).
+///
+/// This interface provides only the [allocate] method to allocate a block of
+/// bytes, and the [free] method to release such a block again.
+/// Implementations only need to provide those two methods.
+/// The [AllocatorAlloc.call] extension method is defined in terms of those
+/// lower-level operations.
+///
+/// An example of an allocator wrapping another to count the number of
+/// allocations:
+///
+/// ```dart
+/// class CountingAllocator implements Allocator {
+/// final Allocator _wrappedAllocator;
+/// int _totalAllocations = 0;
+/// int _nonFreedAllocations = 0;
+///
+/// CountingAllocator([Allocator? allocator])
+/// : _wrappedAllocator = allocator ?? calloc;
+///
+/// int get totalAllocations => _totalAllocations;
+///
+/// int get nonFreedAllocations => _nonFreedAllocations;
+///
+/// @override
+/// Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
+/// final result =
+/// _wrappedAllocator.allocate<T>(byteCount, alignment: alignment);
+/// _totalAllocations++;
+/// _nonFreedAllocations++;
+/// return result;
+/// }
+///
+/// @override
+/// void free(Pointer<NativeType> pointer) {
+/// _wrappedAllocator.free(pointer);
+/// _nonFreedAllocations--;
+/// }
+/// }
+/// ```
@Since('2.12')
abstract class Allocator {
/// This interface is meant to be implemented, not extended or mixed in.
@@ -17,6 +63,24 @@
/// If [alignment] is provided, the allocated memory will be at least aligned
/// to [alignment] bytes.
///
+ /// To allocate a multiple of `sizeOf<T>()` bytes, call the allocator
+ /// directly as a function: `allocator<T>(count)` (see [AllocatorAlloc.call]
+ /// for details).
+ ///
+ /// ```dart
+ /// // This allocates two bytes. If you intended two Int32's, this is an
+ /// // error.
+ /// allocator.allocate<Int32>(2);
+ ///
+ /// // This allocates eight bytes, which is enough space for two Int32's.
+ /// // However, this is not the idiomatic way.
+ /// allocator.allocate<Int32>(sizeOf<Int32>() * 2);
+ ///
+ /// // The idiomatic way to allocate space for two Int32 is to call the
+ /// // allocator directly as a function.
+ /// allocator<Int32>(2);
+ /// ```
+ ///
/// Throws an [ArgumentError] if the number of bytes or alignment cannot be
/// satisfied.
Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment});
@@ -31,9 +95,19 @@
/// Extension on [Allocator] to provide allocation with [NativeType].
@Since('2.12')
extension AllocatorAlloc on Allocator {
- /// Allocates `sizeOf<T>() * count` bytes of memory using
- /// `allocator.allocate`.
+ /// Allocates `sizeOf<T>() * count` bytes of memory using [allocate].
+ ///
+ /// ```dart
+ /// // This allocates eight bytes, which is enough space for two Int32's.
+ /// allocator<Int32>(2);
+ /// ```
///
/// This extension method must be invoked with a compile-time constant [T].
+ ///
+ /// To allocate a specific number of bytes, not just a multiple of
+ /// `sizeOf<T>()`, use [allocate].
+ /// To allocate with a non constant [T], use [allocate].
+ /// Prefer [call] for normal use, and use [allocate] for implementing an
+ /// [Allocator] in terms of other allocators.
external Pointer<T> call<T extends NativeType>([int count = 1]);
}
diff --git a/tests/language/inference_update_1/horizontal_inference_enabled_test.dart b/tests/language/inference_update_1/horizontal_inference_enabled_test.dart
index 1cbeeda..d7fc7e1 100644
--- a/tests/language/inference_update_1/horizontal_inference_enabled_test.dart
+++ b/tests/language/inference_update_1/horizontal_inference_enabled_test.dart
@@ -71,7 +71,7 @@
.expectStaticType<Exactly<List<int>>>();
}
-testLongDepedencyChain(
+testLongDependencyChain(
V Function<T, U, V>(T Function(), U Function(T), V Function(U)) f) {
f(() => [0], (x) => x.single..expectStaticType<Exactly<int>>(),
(y) => {y}..expectStaticType<Exactly<Set<int>>>())
diff --git a/tools/VERSION b/tools/VERSION
index b748ba7..1604640 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 77
+PRERELEASE 78
PRERELEASE_PATCH 0
\ No newline at end of file