|  | // Copyright (c) 2020, 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. | 
|  | // | 
|  | // This benchmark suite measures the overhead of dynamically calling functions | 
|  | // and closures by calling a set of functions and closures, testing non-dynamic | 
|  | // calls, calls after casting the function tearoff or closure to dynamic, and | 
|  | // similarly defined functions and closures except that the parameters and | 
|  | // return types are all dynamic. | 
|  |  | 
|  | import 'package:benchmark_harness/benchmark_harness.dart'; | 
|  |  | 
|  | const int kRepeat = 100; | 
|  |  | 
|  | void main() { | 
|  | const NonDynamicFunction().report(); | 
|  | const NonDynamicFunctionOptSkipped().report(); | 
|  | const NonDynamicFunctionOptProvided().report(); | 
|  | const NonDynamicFunctionNamedSkipped().report(); | 
|  | const NonDynamicFunctionNamedProvided().report(); | 
|  | const NonDynamicClosure().report(); | 
|  | const NonDynamicClosureOptSkipped().report(); | 
|  | const NonDynamicClosureOptProvided().report(); | 
|  | const NonDynamicClosureNamedSkipped().report(); | 
|  | const NonDynamicClosureNamedProvided().report(); | 
|  | const DynamicCastFunction().report(); | 
|  | const DynamicCastFunctionOptSkipped().report(); | 
|  | const DynamicCastFunctionOptProvided().report(); | 
|  | const DynamicCastFunctionNamedSkipped().report(); | 
|  | const DynamicCastFunctionNamedProvided().report(); | 
|  | const DynamicCastClosure().report(); | 
|  | const DynamicCastClosureOptSkipped().report(); | 
|  | const DynamicCastClosureOptProvided().report(); | 
|  | const DynamicCastClosureNamedSkipped().report(); | 
|  | const DynamicCastClosureNamedProvided().report(); | 
|  | const DynamicDefFunction().report(); | 
|  | const DynamicDefFunctionOptSkipped().report(); | 
|  | const DynamicDefFunctionOptProvided().report(); | 
|  | const DynamicDefFunctionNamedSkipped().report(); | 
|  | const DynamicDefFunctionNamedProvided().report(); | 
|  | const DynamicDefClosure().report(); | 
|  | const DynamicDefClosureOptSkipped().report(); | 
|  | const DynamicDefClosureOptProvided().report(); | 
|  | const DynamicDefClosureNamedSkipped().report(); | 
|  | const DynamicDefClosureNamedProvided().report(); | 
|  | const DynamicClassASingleton().report(); | 
|  | const DynamicClassBSingleton().report(); | 
|  | const DynamicClassCFresh().report(); | 
|  | const DynamicClassDFresh().report(); | 
|  | } | 
|  |  | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | void f1(String s) {} | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | Function(String) c1 = (String s) => {}; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | void f2(String s, [String t = 'default']) {} | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | Function(String, [String]) c2 = (String s, [String t = 'default']) => {}; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | void f3(String s, {String t = 'default'}) {} | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | Function(String, {String t}) c3 = (String s, {String t = 'default'}) => {}; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic df1 = f1 as dynamic; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic dc1 = c1 as dynamic; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic df2 = f2 as dynamic; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic dc2 = c2 as dynamic; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic df3 = f3 as dynamic; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic dc3 = c3 as dynamic; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic df1NonCast(dynamic s) {} | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | Function dc1NonCast = (dynamic s) => {}; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic df2NonCast(dynamic s, [dynamic t = 'default']) {} | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | Function dc2NonCast = (dynamic s, [dynamic t = 'default']) => {}; | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic df3NonCast(dynamic s, {dynamic t = 'default'}) {} | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | Function dc3NonCast = (dynamic s, {dynamic t = 'default'}) => {}; | 
|  |  | 
|  | class A { | 
|  | const A(); | 
|  | } | 
|  |  | 
|  | class B extends A { | 
|  | const B(); | 
|  | } | 
|  |  | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic k = (A a) {}; | 
|  |  | 
|  | class C { | 
|  | C(); | 
|  | } | 
|  |  | 
|  | class D extends C { | 
|  | D(); | 
|  | } | 
|  |  | 
|  | @pragma('vm:never-inline') | 
|  | @pragma('wasm:never-inline') | 
|  | dynamic j = (C c) {}; | 
|  |  | 
|  | class NonDynamicFunction extends BenchmarkBase { | 
|  | const NonDynamicFunction() : super('Dynamic.NonDynamicFunction'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | f1(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicClosure extends BenchmarkBase { | 
|  | const NonDynamicClosure() : super('Dynamic.NonDynamicClosure'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | c1(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicFunctionOptSkipped extends BenchmarkBase { | 
|  | const NonDynamicFunctionOptSkipped() | 
|  | : super('Dynamic.NonDynamicFunctionOptSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | f2(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicFunctionOptProvided extends BenchmarkBase { | 
|  | const NonDynamicFunctionOptProvided() | 
|  | : super('Dynamic.NonDynamicFunctionOptProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | f2('', ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicFunctionNamedSkipped extends BenchmarkBase { | 
|  | const NonDynamicFunctionNamedSkipped() | 
|  | : super('Dynamic.NonDynamicFunctionNamedSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | f3(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicFunctionNamedProvided extends BenchmarkBase { | 
|  | const NonDynamicFunctionNamedProvided() | 
|  | : super('Dynamic.NonDynamicFunctionNamedProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | f3('', t: ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicClosureOptSkipped extends BenchmarkBase { | 
|  | const NonDynamicClosureOptSkipped() | 
|  | : super('Dynamic.NonDynamicClosureOptSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | c2(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicClosureOptProvided extends BenchmarkBase { | 
|  | const NonDynamicClosureOptProvided() | 
|  | : super('Dynamic.NonDynamicClosureOptProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | c2('', ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicClosureNamedSkipped extends BenchmarkBase { | 
|  | const NonDynamicClosureNamedSkipped() | 
|  | : super('Dynamic.NonDynamicClosureNamedSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | c3(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class NonDynamicClosureNamedProvided extends BenchmarkBase { | 
|  | const NonDynamicClosureNamedProvided() | 
|  | : super('Dynamic.NonDynamicClosureNamedProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | c3('', t: ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastFunction extends BenchmarkBase { | 
|  | const DynamicCastFunction() : super('Dynamic.DynamicCastFunction'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df1(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastClosure extends BenchmarkBase { | 
|  | const DynamicCastClosure() : super('Dynamic.DynamicCastClosure'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc1(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastFunctionOptSkipped extends BenchmarkBase { | 
|  | const DynamicCastFunctionOptSkipped() | 
|  | : super('Dynamic.DynamicCastFunctionOptSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df2(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastFunctionOptProvided extends BenchmarkBase { | 
|  | const DynamicCastFunctionOptProvided() | 
|  | : super('Dynamic.DynamicCastFunctionOptProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df2('', ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastFunctionNamedSkipped extends BenchmarkBase { | 
|  | const DynamicCastFunctionNamedSkipped() | 
|  | : super('Dynamic.DynamicCastFunctionNamedSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df3(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastFunctionNamedProvided extends BenchmarkBase { | 
|  | const DynamicCastFunctionNamedProvided() | 
|  | : super('Dynamic.DynamicCastFunctionNamedProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df3('', t: ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastClosureOptSkipped extends BenchmarkBase { | 
|  | const DynamicCastClosureOptSkipped() | 
|  | : super('Dynamic.DynamicCastClosureOptSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc2(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastClosureOptProvided extends BenchmarkBase { | 
|  | const DynamicCastClosureOptProvided() | 
|  | : super('Dynamic.DynamicCastClosureOptProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc2('', ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastClosureNamedSkipped extends BenchmarkBase { | 
|  | const DynamicCastClosureNamedSkipped() | 
|  | : super('Dynamic.DynamicCastClosureNamedSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc3(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicCastClosureNamedProvided extends BenchmarkBase { | 
|  | const DynamicCastClosureNamedProvided() | 
|  | : super('Dynamic.DynamicCastClosureNamedProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc3('', t: ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefFunction extends BenchmarkBase { | 
|  | const DynamicDefFunction() : super('Dynamic.DynamicDefFunction'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df1NonCast(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefClosure extends BenchmarkBase { | 
|  | const DynamicDefClosure() : super('Dynamic.DynamicDefClosure'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc1NonCast(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefFunctionOptSkipped extends BenchmarkBase { | 
|  | const DynamicDefFunctionOptSkipped() | 
|  | : super('Dynamic.DynamicDefFunctionOptSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df2NonCast(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefFunctionOptProvided extends BenchmarkBase { | 
|  | const DynamicDefFunctionOptProvided() | 
|  | : super('Dynamic.DynamicDefFunctionOptProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df2NonCast('', ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefFunctionNamedSkipped extends BenchmarkBase { | 
|  | const DynamicDefFunctionNamedSkipped() | 
|  | : super('Dynamic.DynamicDefFunctionNamedSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df3NonCast(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefFunctionNamedProvided extends BenchmarkBase { | 
|  | const DynamicDefFunctionNamedProvided() | 
|  | : super('Dynamic.DynamicDefFunctionNamedProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | df3NonCast('', t: ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefClosureOptSkipped extends BenchmarkBase { | 
|  | const DynamicDefClosureOptSkipped() | 
|  | : super('Dynamic.DynamicDefClosureOptSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc2NonCast(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefClosureOptProvided extends BenchmarkBase { | 
|  | const DynamicDefClosureOptProvided() | 
|  | : super('Dynamic.DynamicDefClosureOptProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc2NonCast('', ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefClosureNamedSkipped extends BenchmarkBase { | 
|  | const DynamicDefClosureNamedSkipped() | 
|  | : super('Dynamic.DynamicDefClosureNamedSkipped'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc3NonCast(''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicDefClosureNamedProvided extends BenchmarkBase { | 
|  | const DynamicDefClosureNamedProvided() | 
|  | : super('Dynamic.DynamicDefClosureNamedProvided'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | dc3NonCast('', t: ''); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicClassASingleton extends BenchmarkBase { | 
|  | final A a; | 
|  | const DynamicClassASingleton() | 
|  | : a = const A(), | 
|  | super('Dynamic.DynamicClassASingleton'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | k(a); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicClassBSingleton extends BenchmarkBase { | 
|  | final B b; | 
|  | const DynamicClassBSingleton() | 
|  | : b = const B(), | 
|  | super('Dynamic.DynamicClassBSingleton'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | k(b); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicClassCFresh extends BenchmarkBase { | 
|  | const DynamicClassCFresh() : super('Dynamic.DynamicClassCFresh'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | j(C()); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | class DynamicClassDFresh extends BenchmarkBase { | 
|  | const DynamicClassDFresh() : super('Dynamic.DynamicClassDFresh'); | 
|  |  | 
|  | @override | 
|  | void run() { | 
|  | for (int i = 0; i < kRepeat; i++) { | 
|  | j(D()); | 
|  | } | 
|  | } | 
|  | } |