[dart2wasm] Make throw call to helper function that gets stacktrace and throws object
This reduces flute complex compiled with `-O4` by 3.2% (or 41kb)
Change-Id: I46e1e933b5b283a7e502571971802885c1c79372
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/349261
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart
index bb43d23..509ff61 100644
--- a/pkg/dart2wasm/lib/code_generator.dart
+++ b/pkg/dart2wasm/lib/code_generator.dart
@@ -2883,8 +2883,7 @@
// assume non-nullable here.
assert(!dartTypeOf(node.expression).isPotentiallyNullable);
wrap(node.expression, translator.topInfo.nonNullableType);
- call(translator.stackTraceCurrent.reference);
- call(translator.errorThrow.reference);
+ call(translator.errorThrowWithCurrentStackTrace.reference);
b.unreachable();
return expectedType;
}
diff --git a/pkg/dart2wasm/lib/kernel_nodes.dart b/pkg/dart2wasm/lib/kernel_nodes.dart
index 062ea04..4688c39 100644
--- a/pkg/dart2wasm/lib/kernel_nodes.dart
+++ b/pkg/dart2wasm/lib/kernel_nodes.dart
@@ -251,8 +251,8 @@
late final Class errorClass = index.getClass("dart:core", "Error");
late final Field errorClassStackTraceField =
index.getField("dart:core", "Error", "_stackTrace");
- late final Procedure errorThrow =
- index.getProcedure("dart:core", "Error", "_throw");
+ late final Procedure errorThrowWithCurrentStackTrace =
+ index.getProcedure("dart:core", "Error", "_throwWithCurrentStackTrace");
// dart:core type procedures
late final Procedure getClosureRuntimeType =
diff --git a/sdk/lib/_internal/wasm/lib/errors_patch.dart b/sdk/lib/_internal/wasm/lib/errors_patch.dart
index 37decf4..2b04b0e 100644
--- a/sdk/lib/_internal/wasm/lib/errors_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/errors_patch.dart
@@ -14,6 +14,10 @@
return jsonEncode(string);
}
+ @pragma('wasm:entry-point')
+ static Never _throwWithCurrentStackTrace(Object object) =>
+ Error._throw(object, StackTrace.current);
+
@patch
StackTrace? get stackTrace => _stackTrace;
diff --git a/tests/language/stack_trace/full2_test.dart b/tests/language/stack_trace/full2_test.dart
index ece2252..ae1e936 100644
--- a/tests/language/stack_trace/full2_test.dart
+++ b/tests/language/stack_trace/full2_test.dart
@@ -12,6 +12,8 @@
import "package:expect/expect.dart";
+import 'non_web_helper.dart' if (dart.library.js_interop) 'web_helper.dart';
+
@pragma("vm:entry-point") // Prevent obfuscation.
void func1() {
throw new Exception("Test full stacktrace");
@@ -78,6 +80,7 @@
}
main() {
+ configureStackFrameLimit();
var i = func7();
Expect.equals(1, i);
}
diff --git a/tests/language/stack_trace/full3_test.dart b/tests/language/stack_trace/full3_test.dart
index 92eac16..5dc16ae 100644
--- a/tests/language/stack_trace/full3_test.dart
+++ b/tests/language/stack_trace/full3_test.dart
@@ -12,6 +12,8 @@
import "package:expect/expect.dart";
+import 'non_web_helper.dart' if (dart.library.js_interop) 'web_helper.dart';
+
@pragma("vm:entry-point") // Prevent obfuscation
void func1() {
throw new Exception("Test full stacktrace");
@@ -77,6 +79,7 @@
}
main() {
+ configureStackFrameLimit();
var i = func7();
Expect.equals(1, i);
}
diff --git a/tests/language/stack_trace/non_web_helper.dart b/tests/language/stack_trace/non_web_helper.dart
new file mode 100644
index 0000000..c4d11d2
--- /dev/null
+++ b/tests/language/stack_trace/non_web_helper.dart
@@ -0,0 +1,5 @@
+// (c) 2024, 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.
+
+void configureStackFrameLimit() {}
diff --git a/tests/language/stack_trace/web_helper.dart b/tests/language/stack_trace/web_helper.dart
new file mode 100644
index 0000000..ecdf245
--- /dev/null
+++ b/tests/language/stack_trace/web_helper.dart
@@ -0,0 +1,25 @@
+// (c) 2024, 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.
+
+import 'dart:js_interop';
+
+void configureStackFrameLimit() {
+ // Different browsers have different limits on how many top frames
+ // are captured in stack traces (e.g. Chrome's limit is 10).
+ // We can configure that here manually, to ensure the tests pass
+ // on all compiler+browser combinations.
+ eval('''
+ var globalState = (typeof window != "undefined") ? window
+ : (typeof global != "undefined") ? global
+ : (typeof self != "undefined") ? self : null;
+
+ // By default, stack traces cutoff at 10 in Chrome.
+ if (globalState.Error) {
+ globalState.Error.stackTraceLimit = Infinity;
+ }
+''');
+}
+
+@JS()
+external void eval(String code);