• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17    This file was generated by VMB using these parameters:
18
19        Benchmarks Class:     $state_name
20        Bench Setup:          $state_setup
21        Bench Method:         $method_name -> $method_rettype
22        Parameter Set:        #$fix_id $fixture
23        Bench Full Name:      $bench_name
24        WarmUp Iterations:    $wi
25        Measure Iterations:   $mi
26        Iteration Time (sec): $it
27        Warmup Time (sec):    $wt
28        Fast Iterations:      $fi
29        GC pause (ms):        $gc (N/A)
30*/
31
32'use strict';
33
34$imports
35
36// params
37let WI = $wi;
38let MI = $mi;
39let IT = $it;
40let WT = $wt;
41let FI = $fi;
42
43const MAX_LOOP_COUNT = 10_000_000_000;
44const MS2NS = 1_000_000;
45const S2MS = 1_000;
46
47class Consumer {
48    static x1 = 0x41c64e6d;
49    static x2 = 0xd431;
50    static x3 = 1;
51
52    static boola = false;
53    static boolb = true;
54    static chara = 'X';
55    static charb = 'Y';
56    static inta = 24;
57    static intb = 53;
58    static floata = 24.0;
59    static floatb = 53.0;
60
61    static localObj = new Object();
62    static localObjs = [new Object()];
63    static pseudorand = Date.now();
64
65    static consumeBool(boolc) {
66        if (boolc === this.boola && boolc === this.boolb) {
67            throw new Error();
68        }
69    };
70
71    static consumeChar(charc) {
72        if (charc === this.chara && charc === this.charb) {
73            throw new Error();
74        }
75    };
76
77    static consumeInt(intc) {
78        if (intc === this.inta && intc === this.intb) {
79            throw new Error();
80        }
81    };
82
83    static consumeFloat(floatc) {
84        if (floatc === this.floata && floatc === this.floatb) {
85            throw new Error();
86        }
87    };
88
89    static consumeObj(obj) {
90        this.pseudorand = (this.pseudorand * this.x1 + this.x2);
91        if ((this.pseudorand & this.x3) === 0) {
92            this.x3 = (this.x3 << 1) + 0xad;
93            this.localObj = obj;
94        }
95    };
96
97    static consumeObjs(objs) {
98        this.pseudorand = (this.pseudorand * this.x1 + this.x2);
99        if ((this.pseudorand & this.x3) === 0) {
100            this.x3 = (this.x3 << 1) + 0xad;
101            this.localObjs = objs;
102        }
103    };
104};
105
106function log(msg) {
107    console.log(msg);
108}
109
110var loopCount1;
111var totalOps;
112var totalMs;
113var iter;
114
115
116let penv = process.env;
117let stsVm = require(penv.MODULE_PATH + '/ets_interop_js_napi.node');
118const stsRT = stsVm.createRuntime({
119    'boot-panda-files':
120        penv.ARK_ETS_STDLIB_PATH + ':' + penv.ARK_ETS_INTEROP_JS_GTEST_ABC_PATH,
121    'panda-files': penv.ARK_ETS_INTEROP_JS_GTEST_ABC_PATH,
122    'gc-trigger-type': 'heap-trigger',
123    'compiler-enable-jit': 'false',
124    'run-gc-in-place': 'true',
125});
126if (!stsRT) {
127    console.error('Failed to create ETS runtime');
128    return 1;
129}
130const State = stsVm.getClass('L$state_name;');
131let bench = new State();
132$state_params
133$state_setup
134
135function tune() {
136    let iterMs = 1 * S2MS;
137    let loopMs = 0;
138    let loopCount = 1;
139    while (loopMs < iterMs && loopCount < MAX_LOOP_COUNT) {
140        loopCount = loopCount * 2;
141        let start = Date.now();
142        for (let i = 0; i < loopCount; i++) {
143            $method_call
144        }
145        loopMs = Date.now() - start;
146    }
147    loopCount1 = loopCount * iterMs / loopMs >> 0;
148    if (loopCount1 == 0) loopCount1++;
149    log('Tuning: ' +  loopCount + ' ops, ' + loopMs*MS2NS/loopCount + ' ns/op => '
150        + loopCount1 + ' reps');
151}
152
153function runIters(phase, count, time) {
154    let iterMs = time * S2MS;
155    totalOps = 0;
156    // make sure zero is encoded as double to avoid deoptimization on overflow later
157    totalMs = 1/Infinity;
158    for (let k = 0; k < count; k++, iter++) {
159        let ops = 0;
160        let elapsedMs = 0;
161        let start = Date.now();
162        while (elapsedMs < iterMs) {
163            for (let i = 0; i < loopCount1; i++) {
164                $method_call
165            }
166            elapsedMs = Date.now() - start;
167            ops += loopCount1;
168        }
169        totalOps += ops;
170        totalMs += elapsedMs;
171        log(phase + ' ' + iter + ':' + ops + ' ops, ' + elapsedMs*MS2NS/ops + ' ns/op');
172    }
173}
174
175log('Startup execution started: ' + Date.now() * MS2NS);
176tune();
177if (WI > 0) {
178    iter = 1;
179    // Re-entering runIters in warmup loop to allow profiler complete the method.
180    // Possible deoptimizations and recompilations is done in warmup instead of measure phase.
181    for (let wi = 0; wi < WI; ++wi) {
182        runIters('Warmup', 1, WT);
183    }
184}
185iter = 1;
186var measure_iters = MI >> 0; // make sure it has int type
187runIters('Iter', measure_iters, IT);
188log('Benchmark result: $bench_name ' + totalMs*MS2NS/totalOps);
189Consumer.consumeObj(bench);
190