[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>
This commit is contained in:
Martin Kustermann 2024-01-31 08:43:18 +00:00 committed by Commit Queue
parent 2f0e466ca2
commit 8ea636f9f8
7 changed files with 43 additions and 4 deletions

View file

@ -2883,8 +2883,7 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
// 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;
}

View file

@ -251,8 +251,8 @@ mixin KernelNodes {
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 =

View file

@ -14,6 +14,10 @@ class Error {
return jsonEncode(string);
}
@pragma('wasm:entry-point')
static Never _throwWithCurrentStackTrace(Object object) =>
Error._throw(object, StackTrace.current);
@patch
StackTrace? get stackTrace => _stackTrace;

View file

@ -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 @@ int func7() {
}
main() {
configureStackFrameLimit();
var i = func7();
Expect.equals(1, i);
}

View file

@ -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 @@ int func7() {
}
main() {
configureStackFrameLimit();
var i = func7();
Expect.equals(1, i);
}

View file

@ -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() {}

View file

@ -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);