Version 2.18.0-19.0.dev
Merge commit 'af39b6b9ca969d1a1fd961451c529c297df7a84b' into 'dev'
diff --git a/DEPS b/DEPS
index db8fe96..b87899a 100644
--- a/DEPS
+++ b/DEPS
@@ -165,7 +165,7 @@
"test_reflective_loader_rev": "fcfce37666672edac849d2af6dffc0f8df236a94",
"test_rev": "b6aba5544628730b7d6a38eae1aef9117a1bb235",
"typed_data_rev": "29ce5a92b03326d0b8035916ac04f528874994bd",
- "usage_rev": "f0cb8f7cce8b675255c81488dbab8cf9f2f56404",
+ "usage_rev": "e85d575d6decb921c57a43b9844bba3607479f56",
"vector_math_rev": "0cbed0914d49a6a44555e6d5444c438a4a4c3fc1",
"watcher_rev": "f76997ab0c857dc5537ac0975a9ada92b54ef949",
"webdriver_rev": "ff5ccb1522edf4bed578ead4d65e0cbc1f2c4f02",
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/process_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/process_executor.dart
index 7205ecd..01d4004 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/process_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/process_executor.dart
@@ -55,7 +55,7 @@
SerializationMode serializationMode,
String programPath,
List<String> arguments) async {
- late ServerSocket serverSocket;
+ ServerSocket serverSocket;
// Try an ipv6 address loopback first, and fall back on ipv4.
try {
serverSocket = await ServerSocket.bind(InternetAddress.loopbackIPv6, 0);
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index d43672d..0c957ae 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -274,16 +274,26 @@
: super(session, path, uri, lineInfo, isPart);
}
-class _DeclarationByElementLocator extends GeneralizingAstVisitor<void> {
+/// A visitor which locates the [AstNode] which declares [element].
+class _DeclarationByElementLocator extends UnifyingAstVisitor<void> {
+ // TODO: This visitor could be further optimized by special casing each static
+ // type of [element]. For example, for library-level elements (classes etc),
+ // we can iterate over the compilation unit's declarations.
+
final Element element;
+ final int _nameOffset;
AstNode? result;
- _DeclarationByElementLocator(this.element);
+ _DeclarationByElementLocator(this.element) : _nameOffset = element.nameOffset;
@override
void visitNode(AstNode node) {
if (result != null) return;
+ if (node.endToken.end < _nameOffset || node.offset > _nameOffset) {
+ return;
+ }
+
if (element is ClassElement) {
if (node is ClassOrMixinDeclaration) {
if (_hasOffset(node.name)) {
@@ -358,10 +368,12 @@
}
}
- super.visitNode(node);
+ if (result == null) {
+ node.visitChildren(this);
+ }
}
bool _hasOffset(AstNode? node) {
- return node?.offset == element.nameOffset;
+ return node?.offset == _nameOffset;
}
}
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 6f7a96a..8e83316 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -184,6 +184,8 @@
// Experimental flags.
static const String resolveOnly = '--resolve-only';
+ static const String cfeConstants = '--cfe-constants';
+
// `--no-shipping` and `--canary` control sets of flags. For simplicity, these
// flags live in options.dart.
// Shipping features default to on, but can be disabled individually. All
diff --git a/pkg/compiler/tool/modular_test_suite.dart b/pkg/compiler/tool/modular_test_suite.dart
index 491d6ad..430c81a 100644
--- a/pkg/compiler/tool/modular_test_suite.dart
+++ b/pkg/compiler/tool/modular_test_suite.dart
@@ -26,7 +26,9 @@
FullDillCompilationStep(onlyOnSdk: true),
ModularAnalysisStep(onlyOnSdk: true),
ModularAnalysisStep(),
- ConcatenateDillsStep(useModularAnalysis: true),
+ // TODO(joshualitt): Re-enable ConcatenateDillStep after it works
+ // correctly alongside modular analysis.
+ // ConcatenateDillsStep(useModularAnalysis: true),
ComputeClosedWorldStep(useModularAnalysis: true),
GlobalAnalysisStep(),
Dart2jsCodegenStep(codeId0),
diff --git a/pkg/compiler/tool/modular_test_suite_helper.dart b/pkg/compiler/tool/modular_test_suite_helper.dart
index 98985b9..91525b6 100644
--- a/pkg/compiler/tool/modular_test_suite_helper.dart
+++ b/pkg/compiler/tool/modular_test_suite_helper.dart
@@ -277,6 +277,7 @@
'${Flags.sources}=${sources.join(',')}'
else
'${Flags.inputDill}=${toUri(module, dillId)}',
+ '${Flags.cfeConstants}',
if (dillDependencies.isNotEmpty)
'--dill-dependencies=${dillDependencies.join(',')}',
'--out=${toUri(module, modularUpdatedDillId)}',
@@ -363,10 +364,13 @@
class ComputeClosedWorldStep extends IOModularStep {
final bool useModularAnalysis;
+ DataId get idForDill =>
+ useModularAnalysis ? modularUpdatedDillId : fullDillId;
+
ComputeClosedWorldStep({this.useModularAnalysis});
List<DataId> get dependencies => [
- fullDillId,
+ idForDill,
if (useModularAnalysis) modularDataId,
];
@@ -391,6 +395,8 @@
if (_options.verbose)
print("\nstep: dart2js compute closed world on $module");
Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
+ Iterable<String> dillDependencies =
+ transitiveDependencies.map((m) => '${toUri(m, idForDill)}');
List<String> dataDependencies = transitiveDependencies
.map((m) => '${toUri(m, modularDataId)}')
.toList();
@@ -401,8 +407,12 @@
// TODO(sigmund): remove this dependency on libraries.json
if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
'${Flags.entryUri}=$fakeRoot${module.mainSource}',
- '${Flags.inputDill}=${toUri(module, fullDillId)}',
+ '${Flags.inputDill}=${toUri(module, idForDill)}',
for (String flag in flags) '--enable-experiment=$flag',
+ if (useModularAnalysis) ...[
+ '${Flags.dillDependencies}=${dillDependencies.join(',')}',
+ '${Flags.readModularAnalysis}=${dataDependencies.join(',')}',
+ ],
'${Flags.writeClosedWorld}=${toUri(module, closedWorldId)}',
Flags.noClosedWorldInData,
'--out=${toUri(module, globalUpdatedDillId)}',
diff --git a/runtime/bin/ffi_test/clobber_arm64.S b/runtime/bin/ffi_test/clobber_arm64.S
index 38105d5..f86f277 100644
--- a/runtime/bin/ffi_test/clobber_arm64.S
+++ b/runtime/bin/ffi_test/clobber_arm64.S
@@ -3,9 +3,11 @@
#if defined(__linux__) || defined(__FreeBSD__) /* HOST_OS_LINUX */
.globl ClobberAndCall
.type ClobberAndCall, @function
+.align 4
ClobberAndCall:
#else /* HOST_OS_MACOS */
.globl _ClobberAndCall
+.align 4
_ClobberAndCall:
#endif
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 68b49e4..462413c 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -234,8 +234,8 @@
P(use_field_guards, bool, true, "Use field guards and track field types") \
C(use_osr, false, true, bool, true, "Use OSR") \
P(use_slow_path, bool, false, "Whether to avoid inlined fast paths.") \
- R(verbose_gc, false, bool, false, "Enables verbose GC.") \
- R(verbose_gc_hdr, 40, int, 40, "Print verbose GC header interval.") \
+ P(verbose_gc, bool, false, "Enables verbose GC.") \
+ P(verbose_gc_hdr, int, 40, "Print verbose GC header interval.") \
R(verify_after_gc, false, bool, false, \
"Enables heap verification after GC.") \
R(verify_before_gc, false, bool, false, \
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 481bafe..a57bcfc 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -522,7 +522,8 @@
? VMTag::kGCIdleTagId
: VMTag::kGCOldSpaceTagId);
TIMELINE_FUNCTION_GC_DURATION(thread, "CollectOldGeneration");
- old_space_.CollectGarbage(type == GCType::kMarkCompact, true /* finish */);
+ old_space_.CollectGarbage(thread, /*compact=*/type == GCType::kMarkCompact,
+ /*finalize=*/true);
RecordAfterGC(type);
PrintStats();
#if defined(SUPPORT_TIMELINE)
@@ -623,7 +624,7 @@
? VMTag::kGCIdleTagId
: VMTag::kGCOldSpaceTagId);
TIMELINE_FUNCTION_GC_DURATION(thread, "StartConcurrentMarking");
- old_space_.CollectGarbage(/*compact=*/false, /*finalize=*/false);
+ old_space_.CollectGarbage(thread, /*compact=*/false, /*finalize=*/false);
RecordAfterGC(GCType::kStartConcurrentMark);
PrintStats();
#if defined(SUPPORT_TIMELINE)
@@ -1019,8 +1020,7 @@
stats_.before_.micros_ = OS::GetCurrentMonotonicMicros();
stats_.before_.new_ = new_space_.GetCurrentUsage();
stats_.before_.old_ = old_space_.GetCurrentUsage();
- for (int i = 0; i < GCStats::kTimeEntries; i++)
- stats_.times_[i] = 0;
+ stats_.before_.store_buffer_ = isolate_group_->store_buffer()->Size();
}
static double AvgCollectionPeriod(int64_t run_time, intptr_t collections) {
@@ -1043,6 +1043,7 @@
}
stats_.after_.new_ = new_space_.GetCurrentUsage();
stats_.after_.old_ = old_space_.GetCurrentUsage();
+ stats_.after_.store_buffer_ = isolate_group_->store_buffer()->Size();
#ifndef PRODUCT
// For now we'll emit the same GC events on all isolates.
if (Service::gc_stream.enabled()) {
@@ -1114,24 +1115,20 @@
}
void Heap::PrintStats() {
-#if !defined(PRODUCT)
if (!FLAG_verbose_gc) return;
if ((FLAG_verbose_gc_hdr != 0) &&
(((stats_.num_ - 1) % FLAG_verbose_gc_hdr) == 0)) {
OS::PrintErr(
- "[ | | | | "
- "| new gen | new gen | new gen "
- "| old gen | old gen | old gen "
- "| sweep | safe- | roots/| stbuf/| tospc/| weaks/ ]\n"
- "[ GC isolate | space (reason) | GC# | start | time "
- "| used (MB) | capacity MB | external"
- "| used (MB) | capacity (MB) | external MB "
- "| thread| point |marking| reset | sweep |swplrge ]\n"
+ "[ | | | | | new "
+ "gen | new gen | new gen | old gen | old gen | old "
+ "gen | store | delta used ]\n"
+ "[ GC isolate | space (reason) | GC# | start | time | used "
+ "(MB) | capacity MB | external| used (MB) | capacity (MB) | "
+ "external MB | buffer | new | old ]\n"
"[ | | | (s) | (ms) "
- "|before| after|before| after| b4 |aftr"
- "| before| after | before| after |before| after"
- "| (ms) | (ms) | (ms) | (ms) | (ms) | (ms) ]\n");
+ "|before| after|before| after| b4 |aftr| before| after | before| after "
+ "|before| after| b4 |aftr| (MB) | (MB) ]\n");
}
// clang-format off
@@ -1146,7 +1143,8 @@
"%6.1f, %6.1f, " // old gen: in use before/after
"%6.1f, %6.1f, " // old gen: capacity before/after
"%5.1f, %5.1f, " // old gen: external before/after
- "%6.2f, %6.2f, %6.2f, %6.2f, %6.2f, %6.2f, " // times
+ "%3" Pd ", %3" Pd ", " // store buffer: before/after
+ "%5.1f, %6.1f, " // delta used: new gen/old gen
"]\n", // End with a comma to make it easier to import in spreadsheets.
isolate_group()->source()->name,
GCTypeToString(stats_.type_),
@@ -1167,14 +1165,13 @@
WordsToMB(stats_.after_.old_.capacity_in_words),
WordsToMB(stats_.before_.old_.external_in_words),
WordsToMB(stats_.after_.old_.external_in_words),
- MicrosecondsToMilliseconds(stats_.times_[0]),
- MicrosecondsToMilliseconds(stats_.times_[1]),
- MicrosecondsToMilliseconds(stats_.times_[2]),
- MicrosecondsToMilliseconds(stats_.times_[3]),
- MicrosecondsToMilliseconds(stats_.times_[4]),
- MicrosecondsToMilliseconds(stats_.times_[5]));
+ stats_.before_.store_buffer_,
+ stats_.after_.store_buffer_,
+ WordsToMB(stats_.after_.new_.used_in_words -
+ stats_.before_.new_.used_in_words),
+ WordsToMB(stats_.after_.old_.used_in_words -
+ stats_.before_.old_.used_in_words));
// clang-format on
-#endif // !defined(PRODUCT)
}
void Heap::PrintStatsToTimeline(TimelineEventScope* event, GCReason reason) {
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 179122d..112c59f 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -256,12 +256,6 @@
void ForwardWeakEntries(ObjectPtr before_object, ObjectPtr after_object);
void ForwardWeakTables(ObjectPointerVisitor* visitor);
- // Stats collection.
- void RecordTime(int id, int64_t micros) {
- ASSERT((id >= 0) && (id < GCStats::kTimeEntries));
- stats_.times_[id] = micros;
- }
-
void UpdateGlobalMaxUsed();
static bool IsAllocatableInNewSpace(intptr_t size) {
@@ -314,16 +308,14 @@
int64_t micros_;
SpaceUsage new_;
SpaceUsage old_;
+ intptr_t store_buffer_;
private:
DISALLOW_COPY_AND_ASSIGN(Data);
};
- enum { kTimeEntries = 6 };
-
Data before_;
Data after_;
- int64_t times_[kTimeEntries];
private:
DISALLOW_COPY_AND_ASSIGN(GCStats);
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 6c7c909..f1c3ed4 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -1100,7 +1100,7 @@
}
}
-void PageSpace::CollectGarbage(bool compact, bool finalize) {
+void PageSpace::CollectGarbage(Thread* thread, bool compact, bool finalize) {
ASSERT(GrowthControlState());
if (!finalize) {
@@ -1112,16 +1112,11 @@
#endif
}
- Thread* thread = Thread::Current();
- const int64_t pre_safe_point = OS::GetCurrentMonotonicMicros();
GcSafepointOperationScope safepoint_scope(thread);
- const int64_t pre_wait_for_sweepers = OS::GetCurrentMonotonicMicros();
// Wait for pending tasks to complete and then account for the driver task.
- Phase waited_for;
{
MonitorLocker locker(tasks_lock());
- waited_for = phase();
if (!finalize &&
(phase() == kMarking || phase() == kAwaitingFinalization)) {
// Concurrent mark is already running.
@@ -1136,26 +1131,11 @@
set_tasks(1);
}
- if (FLAG_verbose_gc) {
- const int64_t wait =
- OS::GetCurrentMonotonicMicros() - pre_wait_for_sweepers;
- if (waited_for == kMarking) {
- THR_Print("Waited %" Pd64 " us for concurrent marking to finish.\n",
- wait);
- } else if (waited_for == kSweepingRegular || waited_for == kSweepingLarge) {
- THR_Print("Waited %" Pd64 " us for concurrent sweeping to finish.\n",
- wait);
- }
- }
-
// Ensure that all threads for this isolate are at a safepoint (either
// stopped or in native code). We have guards around Newgen GC and oldgen GC
// to ensure that if two threads are racing to collect at the same time the
// loser skips collection and goes straight to allocation.
- {
- CollectGarbageHelper(compact, finalize, pre_wait_for_sweepers,
- pre_safe_point);
- }
+ CollectGarbageHelper(thread, compact, finalize);
// Done, reset the task count.
{
@@ -1165,11 +1145,9 @@
}
}
-void PageSpace::CollectGarbageHelper(bool compact,
- bool finalize,
- int64_t pre_wait_for_sweepers,
- int64_t pre_safe_point) {
- Thread* thread = Thread::Current();
+void PageSpace::CollectGarbageHelper(Thread* thread,
+ bool compact,
+ bool finalize) {
ASSERT(thread->IsAtSafepoint());
auto isolate_group = heap_->isolate_group();
ASSERT(isolate_group == IsolateGroup::Current());
@@ -1182,7 +1160,7 @@
[&](Isolate* isolate) { isolate->field_table()->FreeOldTables(); },
/*at_safepoint=*/true);
- NoSafepointScope no_safepoints;
+ NoSafepointScope no_safepoints(thread);
if (FLAG_print_free_list_before_gc) {
for (intptr_t i = 0; i < num_freelists_; i++) {
@@ -1224,8 +1202,6 @@
delete marker_;
marker_ = NULL;
- int64_t mid1 = OS::GetCurrentMonotonicMicros();
-
// Abandon the remainder of the bump allocation block.
AbandonBumpAllocation();
// Reset the freelists and setup sweeping.
@@ -1233,19 +1209,15 @@
freelists_[i].Reset();
}
- int64_t mid2 = OS::GetCurrentMonotonicMicros();
- int64_t mid3 = 0;
+ if (FLAG_verify_before_gc) {
+ OS::PrintErr("Verifying before sweeping...");
+ heap_->VerifyGC(kAllowMarked);
+ OS::PrintErr(" done.\n");
+ }
{
- if (FLAG_verify_before_gc) {
- OS::PrintErr("Verifying before sweeping...");
- heap_->VerifyGC(kAllowMarked);
- OS::PrintErr(" done.\n");
- }
-
// Executable pages are always swept immediately to simplify
// code protection.
-
TIMELINE_FUNCTION_GC_DURATION(thread, "SweepExecutable");
GCSweeper sweeper;
OldPage* prev_page = NULL;
@@ -1263,8 +1235,6 @@
// Advance to the next page.
page = next_page;
}
-
- mid3 = OS::GetCurrentMonotonicMicros();
}
bool has_reservation = MarkReservation();
@@ -1315,13 +1285,6 @@
page_space_controller_.EvaluateGarbageCollection(
usage_before, GetCurrentUsage(), start, end);
- heap_->RecordTime(kConcurrentSweep, pre_safe_point - pre_wait_for_sweepers);
- heap_->RecordTime(kSafePoint, start - pre_safe_point);
- heap_->RecordTime(kMarkObjects, mid1 - start);
- heap_->RecordTime(kResetFreeLists, mid2 - mid1);
- heap_->RecordTime(kSweepPages, mid3 - mid2);
- heap_->RecordTime(kSweepLargePages, end - mid3);
-
if (FLAG_print_free_list_after_gc) {
for (intptr_t i = 0; i < num_freelists_; i++) {
OS::PrintErr("After GC: Freelist %" Pd "\n", i);
@@ -1748,8 +1711,8 @@
if (FLAG_log_growth || FLAG_verbose_gc) {
THR_Print("%s: threshold=%" Pd "kB, idle_threshold=%" Pd "kB, reason=%s\n",
heap_->isolate_group()->source()->name,
- hard_gc_threshold_in_words_ / KBInWords,
- idle_gc_threshold_in_words_ / KBInWords, reason);
+ RoundWordsToKB(hard_gc_threshold_in_words_),
+ RoundWordsToKB(idle_gc_threshold_in_words_), reason);
}
}
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index 5a3c5c0..fca17a2 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -408,7 +408,7 @@
OldPage::PageType type) const;
// Collect the garbage in the page space using mark-sweep or mark-compact.
- void CollectGarbage(bool compact, bool finalize);
+ void CollectGarbage(Thread* thread, bool compact, bool finalize);
void AddRegionsToObjectSet(ObjectSet* set) const;
@@ -573,10 +573,7 @@
void FreeLargePage(OldPage* page, OldPage* previous_page);
void FreePages(OldPage* pages);
- void CollectGarbageHelper(bool compact,
- bool finalize,
- int64_t pre_wait_for_sweepers,
- int64_t pre_safe_point);
+ void CollectGarbageHelper(Thread* thread, bool compact, bool finalize);
void SweepLarge();
void Sweep(bool exclusive);
void ConcurrentSweep(IsolateGroup* isolate_group);
diff --git a/runtime/vm/heap/pointer_block.cc b/runtime/vm/heap/pointer_block.cc
index daedab8..672bdc0 100644
--- a/runtime/vm/heap/pointer_block.cc
+++ b/runtime/vm/heap/pointer_block.cc
@@ -228,6 +228,11 @@
return (full_.length() + partial_.length()) > kMaxNonEmpty;
}
+intptr_t StoreBuffer::Size() {
+ MonitorLocker ml(&monitor_);
+ return full_.length() + partial_.length();
+}
+
void StoreBuffer::VisitObjectPointers(ObjectPointerVisitor* visitor) {
for (Block* block = full_.Peek(); block != NULL; block = block->next()) {
block->VisitObjectPointers(visitor);
diff --git a/runtime/vm/heap/pointer_block.h b/runtime/vm/heap/pointer_block.h
index fb10fa6..1b6fd5a 100644
--- a/runtime/vm/heap/pointer_block.h
+++ b/runtime/vm/heap/pointer_block.h
@@ -268,6 +268,7 @@
// Check whether non-empty blocks have exceeded kMaxNonEmpty (but takes no
// action).
bool Overflowed();
+ intptr_t Size();
void VisitObjectPointers(ObjectPointerVisitor* visitor);
};
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index d2f7de4..c94c042 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -1742,9 +1742,6 @@
Thread* thread = Thread::Current();
GcSafepointOperationScope safepoint_scope(thread);
- int64_t safe_point = OS::GetCurrentMonotonicMicros();
- heap_->RecordTime(kSafePoint, safe_point - start);
-
// Scavenging is not reentrant. Make sure that is the case.
ASSERT(!scavenging_);
scavenging_ = true;
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index 5a93aec..bfd8fc5 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -180,6 +180,13 @@
bool Contains(uword addr) const;
void WriteProtect(bool read_only);
+ intptr_t used_in_words() const {
+ intptr_t size = 0;
+ for (const NewPage* p = head_; p != nullptr; p = p->next()) {
+ size += (p->object_end() - p->object_start());
+ }
+ return size >> kWordSizeLog2;
+ }
intptr_t capacity_in_words() const { return capacity_in_words_; }
intptr_t max_capacity_in_words() const { return max_capacity_in_words_; }
@@ -284,7 +291,7 @@
int64_t UsedInWords() const {
MutexLocker ml(&space_lock_);
- return to_->capacity_in_words();
+ return to_->used_in_words();
}
int64_t CapacityInWords() const { return to_->max_capacity_in_words(); }
int64_t ExternalInWords() const { return external_size_ >> kWordSizeLog2; }
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index d009f9a..bdb1a01 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -96,12 +96,19 @@
/// Throws [error] with associated stack trace [stackTrace].
///
- /// If [error] extends [Error] and has not yet been thrown,
- /// its [stackTrace] is set as well, just as if it was thrown by a `throw`.
- /// The actual stack trace captured along with the [error],
- /// or set on [error] if it is an [Error],
- /// may not be the [stackTrace] object itself,
- /// but will be a stack trace with the same content.
+ /// Behaves like `throw error` would
+ /// if the [current stack trace][StackTrace.current] was [stackTrace]
+ /// at the time of the `throw`.
+ ///
+ /// Like for a `throw`, if [error] extends [Error], and it has not been
+ /// thrown before, its [Error.stackTrace] property will be set to
+ /// the [stackTrace].
+ ///
+ /// This function does not guarantee to preserve the identity of [stackTrace].
+ /// The [StackTrace] object that is caught by a `try`/`catch` of
+ /// this error, or which is set as the [Error.stackTrace] of an [error],
+ /// may not be the same [stackTrace] object provided as argument,
+ /// but it will have the same contents according to [StackTrace.toString].
@Since("2.16")
static Never throwWithStackTrace(Object error, StackTrace stackTrace) {
checkNotNullable(error, "error");
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 32c6682..e2465cc 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -116,7 +116,7 @@
/// Shift the bits of this integer to the left by [shiftAmount].
///
/// Shifting to the left makes the number larger, effectively multiplying
- /// the number by `pow(2, shiftIndex)`.
+ /// the number by `pow(2, shiftAmount)`.
///
/// There is no limit on the size of the result. It may be relevant to
/// limit intermediate values by using the "and" operator with a suitable
@@ -136,7 +136,7 @@
///
/// Shifting to the right makes the number smaller and drops the least
/// significant bits, effectively doing an integer division by
- /// `pow(2, shiftIndex)`.
+ /// `pow(2, shiftAmount)`.
///
/// It is an error if [shiftAmount] is negative.
///
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 2a67153..ea6a330 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -15,6 +15,7 @@
import "dart:_internal" show Since, UnmodifiableListBase;
+@Since("2.10")
export "dart:_internal" show BytesBuilder;
part "unmodifiable_typed_data.dart";
diff --git a/tools/OWNERS b/tools/OWNERS
index fefa34e..d3ed883 100644
--- a/tools/OWNERS
+++ b/tools/OWNERS
@@ -3,6 +3,7 @@
# Groups administrate themselves.
per-file OWNERS_ANALYZER=file:OWNERS_ANALYZER
per-file OWNERS_CFE=file:OWNERS_CFE
+per-file OWNERS_ECOSYSTEM=file:OWNERS_ECOSYSTEM
per-file OWNERS_FOUNDATION=file:OWNERS_FOUNDATION
per-file OWNERS_INFRA=file:OWNERS_INFRA
per-file OWNERS_PRODUCT=file:OWNERS_PRODUCT
diff --git a/tools/OWNERS_ECOSYSTEM b/tools/OWNERS_ECOSYSTEM
new file mode 100644
index 0000000..1b71776
--- /dev/null
+++ b/tools/OWNERS_ECOSYSTEM
@@ -0,0 +1,5 @@
+devoncarew@google.com
+kevmoo@google.com
+mit@google.com
+nbosch@google.com
+omersa@google.com
diff --git a/tools/OWNERS_ENG b/tools/OWNERS_ENG
index ef746ec..0fc41bb 100644
--- a/tools/OWNERS_ENG
+++ b/tools/OWNERS_ENG
@@ -1,6 +1,7 @@
# All engineering teams
file:OWNERS_ANALYZER
file:OWNERS_CFE
+file:OWNERS_ECOSYSTEM
file:OWNERS_FOUNDATION
file:OWNERS_INFRA
file:OWNERS_PUB
diff --git a/tools/VERSION b/tools/VERSION
index fd91a2d..d5f67ab 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 18
+PRERELEASE 19
PRERELEASE_PATCH 0
\ No newline at end of file