Skip to content

Commit 87e04d5

Browse files
osa1Commit Queue
authored andcommitted
[dart2wasm] Cache closure implementations in Translator
Change-Id: I9afd348d81cfababd445bdb9c46cf3e6628f947a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/397320 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Ömer Ağacan <[email protected]>
1 parent 33bdacc commit 87e04d5

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

pkg/dart2wasm/lib/translator.dart

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ class Translator with KernelNodes {
159159
final Map<w.BaseFunction, w.Global> functionRefCache = {};
160160
final Map<Procedure, ClosureImplementation> tearOffFunctionCache = {};
161161

162+
final Map<FunctionNode, ClosureImplementation> closureImplementations = {};
163+
162164
// Some convenience accessors for commonly used values.
163165
late final ClassInfo topInfo = classes[0];
164166
late final ClassInfo objectInfo = classInfo[coreTypes.objectClass]!;
@@ -723,6 +725,23 @@ class Translator with KernelNodes {
723725

724726
ClosureImplementation getClosure(FunctionNode functionNode,
725727
w.BaseFunction target, ParameterInfo paramInfo, String name) {
728+
// We compile a block multiple times in try-catch, to catch Dart exceptions
729+
// and then again to catch JS exceptions. We may also ask for
730+
// `ClosureImplementation` for a local function multiple times as we see
731+
// direct calls to the closure (in TFA direct-call metadata). Avoid
732+
// recompiling the closures in these cases by caching implementations.
733+
//
734+
// Note that every `FunctionNode` passed to this method will have one
735+
// `ParameterInfo` for them. For local functions, the `ParameterInfo` will
736+
// be the one generated by `ParameterInfo.fromLocalFunction`, for others it
737+
// will be the value returned by `paramInfoForDirectCall`. So the key for
738+
// this cache can be just `FunctionNode`, instead of `(FunctionNode,
739+
// ParameterInfo)`.
740+
final existingImplementation = closureImplementations[functionNode];
741+
if (existingImplementation != null) {
742+
return existingImplementation;
743+
}
744+
726745
final targetModule = target.enclosingModule;
727746

728747
// Look up the closure representation for the signature.
@@ -850,8 +869,10 @@ class Translator with KernelNodes {
850869
ib.struct_new(representation.vtableStruct);
851870
ib.end();
852871

853-
return ClosureImplementation(
872+
final implementation = ClosureImplementation(
854873
representation, functions, dynamicCallEntry, vtable, targetModule);
874+
closureImplementations[functionNode] = implementation;
875+
return implementation;
855876
}
856877

857878
w.ValueType outputOrVoid(List<w.ValueType> outputs) {

0 commit comments

Comments
 (0)