├── .gitignore
├── README.md
├── bin
└── ton80.dart
├── lib
└── src
│ ├── DeltaBlue
│ ├── dart
│ │ ├── DeltaBlue.dart
│ │ ├── DeltaBlue.dart.js
│ │ └── DeltaBlue.dart.js.map
│ └── javascript
│ │ └── DeltaBlue.js
│ ├── FluidMotion
│ ├── dart
│ │ ├── FluidMotion.dart
│ │ ├── FluidMotion.dart.js
│ │ └── FluidMotion.dart.js.map
│ └── javascript
│ │ └── FluidMotion.js
│ ├── Havlak
│ ├── dart
│ │ ├── Havlak.dart
│ │ ├── Havlak.dart.js
│ │ └── Havlak.dart.js.map
│ └── javascript
│ │ └── Havlak.js
│ ├── Richards
│ ├── dart
│ │ ├── Richards.dart
│ │ ├── Richards.dart.js
│ │ └── Richards.dart.js.map
│ └── javascript
│ │ └── Richards.js
│ ├── Serve
│ └── dart
│ │ ├── Serve.dart
│ │ ├── file.dat
│ │ └── server.dart
│ ├── Tracer
│ ├── dart
│ │ ├── Tracer.dart
│ │ ├── Tracer.dart.js
│ │ ├── Tracer.dart.js.map
│ │ ├── default
│ │ │ ├── color.dart
│ │ │ ├── engine.dart
│ │ │ ├── materials.dart
│ │ │ ├── renderscene.dart
│ │ │ ├── scene.dart
│ │ │ ├── shapes.dart
│ │ │ └── vector.dart
│ │ └── simd
│ │ │ ├── color.dart
│ │ │ ├── engine.dart
│ │ │ ├── materials.dart
│ │ │ ├── renderscene.dart
│ │ │ ├── scene.dart
│ │ │ ├── shapes.dart
│ │ │ └── vector.dart
│ └── javascript
│ │ └── Tracer.js
│ └── common
│ ├── dart
│ └── BenchmarkBase.dart
│ └── javascript
│ └── bench.js
├── pubspec.lock
└── pubspec.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | packages
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Ton 80
2 | ======
3 |
4 | Ton 80 is a benchmark suite for Dart.
5 |
6 | In it's current setup, the Ton80 benchmark suite is easy to run and
7 | profile from the command line. When adding new benchmarks to the suite,
8 | please use the existing harness and help us make sure we can continue to
9 | easily run and profile from the command line.
10 |
11 | You can run Ton80 using `bin/ton80.dart`. It has the following usage:
12 | ```dart ton80.dart [OPTION]... [BENCHMARK]```
13 |
14 | The following values are valid for ```[OPTION]```:
15 | ```
16 | --js: Path to JavaScript runner (this probably needs to be set)
17 | --dart: Path to Dart runner
18 | --wrk: Path to wrk benchmarking tool
19 | ```
20 |
21 | ## Contributing
22 |
23 | We're happy to review Pull Requests that fix bugs in benchmark implementations.
24 |
25 | We're intentionally keeping the list of benchmarks small. We especially want
26 | to avoid micro-benchmarks. If you have a good idea for a benchmark, please
27 | open a new issue first. Our team will respond to discuss the benchmark.
28 |
29 | Before contributed code can be merged, the author must first sign the
30 | [Google CLA](https://cla.developers.google.com/about/google-individual).
31 |
--------------------------------------------------------------------------------
/bin/ton80.dart:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 | // for details. All rights reserved. Use of this source code is governed by a
3 | // BSD-style license that can be found in the LICENSE file.
4 |
5 | import 'package:path/path.dart' as path;
6 | import 'package:quiver/strings.dart' as strings;
7 | import 'package:args/args.dart' as args;
8 | import 'dart:io' as io;
9 | import 'dart:math' as math;
10 |
11 | final Runner runnerForDart = new DartRunner();
12 | final Runner runnerForDart2JS = new Dart2JSRunner();
13 | final Runner runnerForJS = new JSRunner();
14 | final Runner runnerForWrk = new DartWrkRunner();
15 |
16 | final CATEGORIES = {
17 | 'BASE' : {
18 | 'RUNNERS': [
19 | runnerForDart,
20 | runnerForDart2JS,
21 | runnerForJS,
22 | ],
23 | 'BENCHMARKS': [
24 | 'DeltaBlue',
25 | 'Richards',
26 | 'FluidMotion',
27 | 'Tracer',
28 | 'Havlak',
29 | ],
30 | },
31 | 'WRK' : {
32 | 'RUNNERS' : [
33 | runnerForWrk
34 | ],
35 | 'BENCHMARKS': [
36 | 'Hello',
37 | 'File',
38 | 'JSON',
39 | ],
40 | }
41 | };
42 |
43 | String pathToJS;
44 | String pathToDart;
45 | String pathToWrk;
46 |
47 | void main(arguments) {
48 | args.ArgParser parser = new args.ArgParser();
49 | parser.addOption('js', abbr: 'j',
50 | help: 'Path to JavaScript runner',
51 | defaultsTo: 'd8');
52 | parser.addOption('dart', abbr: 'd',
53 | help: 'Path to Dart runner',
54 | defaultsTo: io.Platform.executable);
55 | parser.addOption('wrk', abbr: 'w',
56 | help: 'Path to wrk benchmarking tool');
57 |
58 | args.ArgResults results = parser.parse(arguments);
59 | List rest = results.rest;
60 |
61 | String filter;
62 | if (rest.isEmpty) {
63 | filter = null;
64 | } else if (rest.length == 1) {
65 | filter = rest[0];
66 | } else {
67 | print('Usage: dart ton80.dart [OPTION]... [BENCHMARK]');
68 | print('');
69 | print(parser.getUsage());
70 | print('');
71 | print('Homepage: https://github.com/dart-lang/ton80');
72 | return;
73 | }
74 |
75 | pathToJS = results['js'];
76 | pathToDart = results['dart'];
77 | pathToWrk = results['wrk'];
78 |
79 | for (Map category in CATEGORIES.values) {
80 | for (String benchmark in category['BENCHMARKS']) {
81 | if (filter != null && filter != benchmark) continue;
82 | Iterable enabled = category['RUNNERS'].where((e) => e.isEnabled);
83 | if (enabled.isEmpty) continue;
84 | print('Running $benchmark...');
85 | for (Runner runner in enabled) {
86 | runner.run(benchmark);
87 | }
88 | }
89 | }
90 | }
91 |
92 | abstract class Runner {
93 | bool get isEnabled => true;
94 | void run(String benchmark);
95 | }
96 |
97 | class DartRunner extends Runner {
98 | void run(String benchmark) {
99 | List dart = extractScores(() => io.Process.runSync(pathToDart, [
100 | source(benchmark, 'dart', '$benchmark.dart'),
101 | ]));
102 | print(' - Dart : ${format(dart, "runs/sec")}');
103 | }
104 | }
105 |
106 | class Dart2JSRunner extends Runner {
107 | void run(String benchmark) {
108 | var scores = extractScores(() => io.Process.runSync(pathToJS, [
109 | source(benchmark, 'dart', '$benchmark.dart.js'),
110 | ]));
111 | print(' - Dart2JS : ${format(scores, "runs/sec")}');
112 | }
113 | }
114 |
115 | class JSRunner extends Runner {
116 | void run(String benchmark) {
117 | var scores = extractScores(() => io.Process.runSync(pathToJS, [
118 | '-f', source('common', 'javascript', 'bench.js'),
119 | '-f', source(benchmark, 'javascript', '$benchmark.js'),
120 | ]));
121 | print(' - JS : ${format(scores, "runs/sec")}');
122 | }
123 | }
124 |
125 | class DartWrkRunner extends Runner {
126 | bool get isEnabled => pathToWrk != null;
127 | void run(String benchmark) {
128 | var scores = extractWrkScores(() => io.Process.runSync(pathToDart, [
129 | source('Serve', 'dart', 'Serve.dart'),
130 | pathToWrk,
131 | '/${benchmark.toLowerCase()}'
132 | ]));
133 | print(' - Dart : ${format(scores[0], "requests/sec")}');
134 | print(' - Dart : ${format(scores[1], "ms mean latency")}');
135 | print(' - Dart : ${format(scores[2], "ms worst latency")}');
136 | }
137 | }
138 |
139 | String format(List scores, String metric) {
140 | double mean = computeMean(scores);
141 | double best = computeBest(scores);
142 | String score = strings.padLeft(best.toStringAsFixed(2), 8, ' ');
143 | if (scores.length == 1) {
144 | return "$score $metric";
145 | } else {
146 | final int n = scores.length;
147 | double standardDeviation = computeStandardDeviation(scores, mean);
148 | double standardError = standardDeviation / math.sqrt(n);
149 | double percent = (computeTDistribution(n) * standardError / mean) * 100;
150 | String error = percent.toStringAsFixed(1);
151 | return "$score $metric (${mean.toStringAsFixed(2)}±$error%)";
152 | }
153 | }
154 |
155 | double computeBest(List scores) {
156 | double best = scores[0];
157 | for (int i = 1; i < scores.length; i++) {
158 | best = math.max(best, scores[i]);
159 | }
160 | return best;
161 | }
162 |
163 | double computeMean(List scores) {
164 | double sum = 0.0;
165 | for (int i = 0; i < scores.length; i++) {
166 | sum += scores[i];
167 | }
168 | return sum / scores.length;
169 | }
170 |
171 | double computeStandardDeviation(List scores, double mean) {
172 | double deltaSquaredSum = 0.0;
173 | for (int i = 0; i < scores.length; i++) {
174 | double delta = scores[i] - mean;
175 | deltaSquaredSum += delta * delta;
176 | }
177 | double variance = deltaSquaredSum / (scores.length - 1);
178 | return math.sqrt(variance);
179 | }
180 |
181 | double computeTDistribution(int n) {
182 | const List TABLE = const [
183 | double.NAN, double.NAN, 12.71,
184 | 4.30, 3.18, 2.78, 2.57, 2.45, 2.36, 2.31, 2.26, 2.23, 2.20, 2.18, 2.16,
185 | 2.14, 2.13, 2.12, 2.11, 2.10, 2.09, 2.09, 2.08, 2.07, 2.07, 2.06, 2.06,
186 | 2.06, 2.05, 2.05, 2.05, 2.04, 2.04, 2.04, 2.03, 2.03, 2.03, 2.03, 2.03,
187 | 2.02, 2.02, 2.02, 2.02, 2.02, 2.02, 2.02, 2.01, 2.01, 2.01, 2.01, 2.01,
188 | 2.01, 2.01, 2.01, 2.01, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00,
189 | 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 1.99, 1.99, 1.99, 1.99, 1.99,
190 | 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99,
191 | 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99 ];
192 | if (n >= 474) return 1.96;
193 | else if (n >= 160) return 1.97;
194 | else if (n >= TABLE.length) return 1.98;
195 | else return TABLE[n];
196 | }
197 |
198 | final RegExp EXTRACT = new RegExp(r"((\d)+(\.(\d)+)?) us");
199 | List extractScores(io.ProcessResult generator(),
200 | [int iterations = 10]) {
201 | List scores = [];
202 | for (int i = 0; i < iterations; i++) {
203 | io.ProcessResult result = generator();
204 | String output = result.stdout;
205 | Match match = EXTRACT.firstMatch(output);
206 | scores.add(1000000 / double.parse(match.group(1)));
207 | }
208 | return scores;
209 | }
210 |
211 | List> extractWrkScores(io.ProcessResult generator(),
212 | [int iterations = 3]) {
213 | List requestsPerSecond = [];
214 | List latency = [];
215 | List latencyMax = [];
216 | for (int i = 0; i < iterations; i++) {
217 | io.ProcessResult result = generator();
218 | String output = result.stdout;
219 | var data = output.split('\n').take(3).map(double.parse).toList();
220 | requestsPerSecond.add(data[0]);
221 | latency.add(data[1]);
222 | latencyMax.add(data[2]);
223 | }
224 | return [requestsPerSecond, latency, latencyMax];
225 | }
226 |
227 | String source(String benchmark, String kind, String file) {
228 | String base = path.dirname(io.Platform.script.path);
229 | return path.join(base, '..', 'lib', 'src', benchmark, kind, file);
230 | }
231 |
--------------------------------------------------------------------------------
/lib/src/DeltaBlue/dart/DeltaBlue.dart.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "file": "DeltaBlue.dart.js",
4 | "sourceRoot": "",
5 | "sources": ["DeltaBlue.dart","../../common/dart/BenchmarkBase.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/internal_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/interceptors.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_array.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/list.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_number.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_string.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_helper.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_rti.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/core_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/core/stopwatch.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/iterable.dart","../../../../../../Tools/dart/stable/sdk/lib/core/errors.dart","../../../../../../Tools/dart/stable/sdk/lib/core/print.dart","../../../../../../Tools/dart/stable/sdk/lib/core/bool.dart","../../../../../../Tools/dart/stable/sdk/lib/core/null.dart","../../../../../../Tools/dart/stable/sdk/lib/core/object.dart","../../../../../../Tools/dart/stable/sdk/lib/core/string_buffer.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_primitives.dart"],
6 | "names": ["main","report","chainTest","addConstraint","printToConsole","projectionTest","change","destroyConstraint","run","satisfy","isInput","addToGraph","chooseMethod","stronger","isSatisfied","markInputs","output","recalculate","markUnsatisfied","inputsKnown","removeFromGraph","execute","weaker","input","removeConstraint","incrementalAdd","incrementalRemove","nextWeaker","makePlan","extractPlanFromConstraints","addPropagate","removePropagateFrom","addConstraintsConsumingTo","getInterceptor","==","toString","checkGrowable","remove","listToString","length","moveNext","toInt","truncateToDouble","+","-","~/","_tdivSlow","codeUnitAt","substring","S","objectTypeName","formatType","objectToString","dateNow","initTicker","iae","ioore","checkInt","wrapException","toStringWrapper","throwExpression","fromTearOff","cspForwardCall","forwardCallTo","selfFieldName","cspForwardInterceptedCall","forwardInterceptedCallTo","receiverFieldName","closureFromTearOff","throwCyclicInit","getRuntimeTypeInfo","runtimeTypeToString","getRuntimeTypeAsString","joinArguments","_writeString","","call","floor","selfOf","receiverOf","computeFieldNamed","measureFor","_initTicker","elapsedMilliseconds","exercise","measure","warmup","iterableToFullString","_isToStringVisiting","safeToString","_objectToString","print","_errorName","_errorExplanation","value","start","isRunning","_now","elapsedTicks","writeAll","isEmpty","current","printString","_toStringVisiting"],
7 | "mappings": "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"
8 | }
9 |
--------------------------------------------------------------------------------
/lib/src/FluidMotion/dart/FluidMotion.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 the V8 project authors. All rights reserved.
3 | * Copyright 2009 Oliver Hunt
4 | *
5 | * Permission is hereby granted, free of charge, to any person
6 | * obtaining a copy of this software and associated documentation
7 | * files (the "Software"), to deal in the Software without
8 | * restriction, including without limitation the rights to use,
9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the
11 | * Software is furnished to do so, subject to the following
12 | * conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be
15 | * included in all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 | * OTHER DEALINGS IN THE SOFTWARE.
25 | */
26 |
27 | // Ported from the v8 benchmark suite by Google 2013.
28 | // Uses Float64List for data.
29 |
30 | import 'dart:math';
31 | import 'dart:typed_data';
32 |
33 | import "../../common/dart/BenchmarkBase.dart";
34 |
35 | main() {
36 | new FluidMotion().report();
37 | }
38 |
39 | class FluidMotion extends BenchmarkBase {
40 | static FluidField solver;
41 | static int framesTillAddingPoints = 0;
42 | static int framesBetweenAddingPoints = 5;
43 |
44 | const FluidMotion() : super('FluidMotion');
45 |
46 | static void setupFluidMotion() {
47 | framesTillAddingPoints = 0;
48 | framesBetweenAddingPoints = 5;
49 | solver = new FluidField.create(null, 128, 128, 20);
50 | solver.setDisplayFunction((a){});
51 | solver.setUICallback(prepareFrame);
52 | }
53 |
54 | static void runFluidMotion() {
55 | setupFluidMotion();
56 | for (int i = 0; i < 10; i++) {
57 | solver.update();
58 | }
59 | solver.validate(758.9012130174812, -352.56376676179076, -357.3690235879736);
60 | }
61 |
62 | static void main() {
63 | runFluidMotion();
64 | }
65 |
66 | static void addPoints(Field field) {
67 | var n = 64;
68 | for (var i = 1; i <= n; i++) {
69 | field.setVelocity(i, i, n.toDouble(), n.toDouble());
70 | field.setDensity(i, i, 5.0);
71 | field.setVelocity(i, n - i, -n.toDouble(), -n.toDouble());
72 | field.setDensity(i, n - i, 20.0);
73 | field.setVelocity(128 - i, n + i, -n.toDouble(), -n.toDouble());
74 | field.setDensity(128 - i, n + i, 30.0);
75 | }
76 | }
77 |
78 | static void prepareFrame(Field field) {
79 | if (framesTillAddingPoints == 0) {
80 | addPoints(field);
81 | framesTillAddingPoints = framesBetweenAddingPoints;
82 | framesBetweenAddingPoints++;
83 | } else {
84 | framesTillAddingPoints--;
85 | }
86 | }
87 |
88 | // Overrides of BenchmarkBase.
89 |
90 | void warmup() {
91 | runFluidMotion();
92 | }
93 |
94 | void exercise() {
95 | runFluidMotion();
96 | }
97 | }
98 |
99 |
100 | // Code from Oliver Hunt (http://nerget.com/fluidSim/pressure.js) starts here.
101 |
102 | class FluidField {
103 | final canvas;
104 | final int iterations;
105 | final double dt = 0.1;
106 | final int size;
107 | Float64List dens, dens_prev;
108 | Float64List u, u_prev;
109 | Float64List v, v_prev;
110 | final int width, height;
111 | final int rowSize;
112 | var displayFunc;
113 |
114 | static FluidField _lastCreated;
115 |
116 | static bool approxEquals(double a, double b) => (a - b).abs() < 0.000001;
117 |
118 | validate(expectedDens, expectedU, expectedV) {
119 | var sumDens = 0.0;
120 | var sumU = 0.0;
121 | var sumV = 0.0;
122 | for (int i = 0; i < dens.length; i++) {
123 | sumDens += dens[i];
124 | sumU += u[i];
125 | sumV += v[i];
126 | }
127 |
128 | if (!approxEquals(sumDens, expectedDens) ||
129 | !approxEquals(sumU, expectedU) ||
130 | !approxEquals(sumV, expectedV)) {
131 | throw "Incorrect result";
132 | }
133 | }
134 |
135 |
136 | // Allocates a new FluidField or return previously allocated field if the
137 | // size is too large.
138 | factory FluidField.create(canvas, int hRes, int wRes, int iterations) {
139 | final res = wRes * hRes;
140 | if ((res > 0) && (res < 1000000)) {
141 | _lastCreated = new FluidField(canvas, hRes, wRes, iterations);
142 | } else if (_lastCreated == null) {
143 | _lastCreated = new FluidField(canvas, 64, 64, iterations);
144 | }
145 | assert((canvas == _lastCreated.canvas) &&
146 | (iterations == _lastCreated.iterations));
147 | return _lastCreated;
148 | }
149 |
150 |
151 | FluidField(this.canvas, int hRes, int wRes, this.iterations) :
152 | width = wRes,
153 | height = hRes,
154 | rowSize = (wRes + 2),
155 | size = (wRes + 2) * (hRes + 2) {
156 | reset();
157 | }
158 |
159 | void reset() {
160 | // All Float64List elements are initialized to 0.0.
161 | dens = new Float64List(size);
162 | dens_prev = new Float64List(size);
163 | u = new Float64List(size);
164 | u_prev = new Float64List(size);
165 | v = new Float64List(size);
166 | v_prev = new Float64List(size);
167 | }
168 |
169 | void addFields(Float64List x, Float64List s, double dt) {
170 | for (var i=0; i< size ; i++) x[i] += dt*s[i];
171 | }
172 |
173 | void set_bnd(int b, Float64List x) {
174 | if (b==1) {
175 | var i = 1;
176 | for (; i <= width; i++) {
177 | x[i] = x[i + rowSize];
178 | x[i + (height+1) *rowSize] = x[i + height * rowSize];
179 | }
180 |
181 | for (var j = 1; j <= height; j++) {
182 | x[j * rowSize] = -x[1 + j * rowSize];
183 | x[(width + 1) + j * rowSize] = -x[width + j * rowSize];
184 | }
185 | } else if (b == 2) {
186 | for (var i = 1; i <= width; i++) {
187 | x[i] = -x[i + rowSize];
188 | x[i + (height + 1) * rowSize] = -x[i + height * rowSize];
189 | }
190 |
191 | for (var j = 1; j <= height; j++) {
192 | x[j * rowSize] = x[1 + j * rowSize];
193 | x[(width + 1) + j * rowSize] = x[width + j * rowSize];
194 | }
195 | } else {
196 | for (var i = 1; i <= width; i++) {
197 | x[i] = x[i + rowSize];
198 | x[i + (height + 1) * rowSize] = x[i + height * rowSize];
199 | }
200 |
201 | for (var j = 1; j <= height; j++) {
202 | x[j * rowSize] = x[1 + j * rowSize];
203 | x[(width + 1) + j * rowSize] = x[width + j * rowSize];
204 | }
205 | }
206 | var maxEdge = (height + 1) * rowSize;
207 | x[0] = 0.5 * (x[1] + x[rowSize]);
208 | x[maxEdge] = 0.5 * (x[1 + maxEdge] + x[height * rowSize]);
209 | x[(width+1)] = 0.5 * (x[width] + x[(width + 1) + rowSize]);
210 | x[(width+1)+maxEdge] = 0.5 * (x[width + maxEdge] + x[(width + 1) +
211 | height * rowSize]);
212 | }
213 |
214 | void lin_solve(int b, Float64List x, Float64List x0, int a, int c) {
215 | if (a == 0 && c == 1) {
216 | for (var j=1 ; j<=height; j++) {
217 | var currentRow = j * rowSize;
218 | ++currentRow;
219 | for (var i = 0; i < width; i++) {
220 | x[currentRow] = x0[currentRow];
221 | ++currentRow;
222 | }
223 | }
224 | set_bnd(b, x);
225 | } else {
226 | var invC = 1 / c;
227 | for (var k=0 ; k Wp5)
305 | x = Wp5;
306 | var i0 = x.toInt();
307 | var i1 = i0 + 1;
308 | if (y < 0.5)
309 | y = 0.5;
310 | else if (y > Hp5)
311 | y = Hp5;
312 | var j0 = y.toInt();
313 | var j1 = j0 + 1;
314 | var s1 = x - i0;
315 | var s0 = 1 - s1;
316 | var t1 = y - j0;
317 | var t0 = 1 - t1;
318 | var row1 = j0 * rowSize;
319 | var row2 = j1 * rowSize;
320 | d[pos] = s0 * (t0 * d0[i0 + row1] + t1 * d0[i0 + row2]) +
321 | s1 * (t0 * d0[i1 + row1] + t1 * d0[i1 + row2]);
322 | }
323 | }
324 | set_bnd(b, d);
325 | }
326 |
327 | void project(Float64List u, Float64List v,
328 | Float64List p, Float64List div) {
329 | var h = -0.5 / sqrt(width * height);
330 | for (var j = 1 ; j <= height; j++ ) {
331 | var row = j * rowSize;
332 | var previousRow = (j - 1) * rowSize;
333 | var prevValue = row - 1;
334 | var currentRow = row;
335 | var nextValue = row + 1;
336 | var nextRow = (j + 1) * rowSize;
337 | for (var i = 1; i <= width; i++ ) {
338 | div[++currentRow] = h * (u[++nextValue] - u[++prevValue] +
339 | v[++nextRow] - v[++previousRow]);
340 | p[currentRow] = 0.0;
341 | }
342 | }
343 | set_bnd(0, div);
344 | set_bnd(0, p);
345 |
346 | lin_solve(0, p, div, 1, 4 );
347 | var wScale = 0.5 * width;
348 | var hScale = 0.5 * height;
349 | for (var j = 1; j<= height; j++ ) {
350 | var prevPos = j * rowSize - 1;
351 | var currentPos = j * rowSize;
352 | var nextPos = j * rowSize + 1;
353 | var prevRow = (j - 1) * rowSize;
354 | var currentRow = j * rowSize;
355 | var nextRow = (j + 1) * rowSize;
356 |
357 | for (var i = 1; i<= width; i++) {
358 | u[++currentPos] -= wScale * (p[++nextPos] - p[++prevPos]);
359 | v[currentPos] -= hScale * (p[++nextRow] - p[++prevRow]);
360 | }
361 | }
362 | set_bnd(1, u);
363 | set_bnd(2, v);
364 | }
365 |
366 | void dens_step(Float64List x, Float64List x0,
367 | Float64List u, Float64List v, double dt) {
368 | addFields(x, x0, dt);
369 | diffuse(0, x0, x, dt );
370 | advect(0, x, x0, u, v, dt );
371 | }
372 |
373 | void vel_step(Float64List u, Float64List v,
374 | Float64List u0, Float64List v0, double dt) {
375 | addFields(u, u0, dt );
376 | addFields(v, v0, dt );
377 | var temp = u0; u0 = u; u = temp;
378 | temp = v0; v0 = v; v = temp;
379 | diffuse2(u,u0,v,v0, dt);
380 | project(u, v, u0, v0);
381 | temp = u0; u0 = u; u = temp;
382 | temp = v0; v0 = v; v = temp;
383 | advect(1, u, u0, u0, v0, dt);
384 | advect(2, v, v0, u0, v0, dt);
385 | project(u, v, u0, v0 );
386 | }
387 |
388 | var uiCallback;
389 |
390 |
391 | void setDisplayFunction(func) {
392 | displayFunc = func;
393 | }
394 |
395 | void setUICallback(callback) {
396 | uiCallback = callback;
397 | }
398 |
399 | void queryUI(Float64List d, Float64List u, Float64List v) {
400 | for (var i = 0; i < size; i++) {
401 | u[i] = v[i] = d[i] = 0.0;
402 | }
403 | uiCallback(new Field(d, u, v, rowSize));
404 | }
405 |
406 | void update() {
407 | queryUI(dens_prev, u_prev, v_prev);
408 | vel_step(u, v, u_prev, v_prev, dt);
409 | dens_step(dens, dens_prev, u, v, dt);
410 | displayFunc(new Field(dens, u, v, rowSize));
411 | }
412 | }
413 |
414 | // Difference from JS version: Field takes an argument rowSize, but this
415 | // used for display purpose only.
416 | class Field {
417 | final Float64List dens, u, v;
418 | final int rowSize;
419 |
420 | Field(this.dens, this.u, this.v, this.rowSize);
421 |
422 | void setDensity(int x, int y, double d) {
423 | dens[(x + 1) + (y + 1) * rowSize] = d;
424 | }
425 |
426 | double getDensity(int x, int y) {
427 | return dens[(x + 1) + (y + 1) * rowSize]; // rowSize from FluidField?
428 | }
429 |
430 | void setVelocity(int x, int y, double xv, double yv) {
431 | u[(x + 1) + (y + 1) * rowSize] = xv;
432 | v[(x + 1) + (y + 1) * rowSize] = yv;
433 | }
434 |
435 | double getXVelocity(int x, int y) {
436 | return u[(x + 1) + (y + 1) * rowSize];
437 | }
438 |
439 | double getYVelocity(int x, int y) {
440 | return v[(x + 1) + (y + 1) * rowSize];
441 | }
442 | }
443 |
--------------------------------------------------------------------------------
/lib/src/FluidMotion/dart/FluidMotion.dart.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "file": "FluidMotion.dart.js",
4 | "sourceRoot": "",
5 | "sources": ["FluidMotion.dart","../../common/dart/BenchmarkBase.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/internal_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/interceptors.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_array.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/list.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_number.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_string.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_helper.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_rti.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/core_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/native_helper.dart","../../../../../../Tools/dart/stable/sdk/lib/core/stopwatch.dart","../../../../../../Tools/dart/stable/sdk/lib/internal/iterable.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/iterable.dart","../../../../../../Tools/dart/stable/sdk/lib/core/errors.dart","../../../../../../Tools/dart/stable/sdk/lib/core/bool.dart","../../../../../../Tools/dart/stable/sdk/lib/core/exceptions.dart","../../../../../../Tools/dart/stable/sdk/lib/core/null.dart","../../../../../../Tools/dart/stable/sdk/lib/core/object.dart","../../../../../../Tools/dart/stable/sdk/lib/core/string_buffer.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/native_typed_data.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_primitives.dart"],
6 | "names": ["main","report","printToConsole","warmup","exercise","setupFluidMotion","create","setDisplayFunction","setUICallback","runFluidMotion","update","vel_step","diffuse2","dens_step","diffuse","addPoints","setDensity","prepareFrame","call","validate","approxEquals","addFields","set_bnd","lin_solve","lin_solve2","advect","project","queryUI","","reset","setVelocity","getInterceptor","makeDispatchRecord","getNativeInterceptor","==","toString","listToString","iterator","length","current","moveNext","toInt","truncateToDouble","+","~/","_tdivSlow","codeUnitAt","substring","isJsIndexable","S","objectHashCode","objectTypeName","formatType","objectToString","dateNow","initTicker","iae","ioore","checkInt","wrapException","toStringWrapper","throwExpression","invokeClosure","convertDartClosureToJS","fromTearOff","cspForwardCall","forwardCallTo","selfFieldName","cspForwardInterceptedCall","forwardInterceptedCallTo","receiverFieldName","closureFromTearOff","throwCyclicInit","getRuntimeTypeInfo","runtimeTypeToString","getRuntimeTypeAsString","joinArguments","_writeString","toStringForNativeObject","hashCodeForNativeObject","defineProperty","lookupAndCacheInterceptor","patchInteriorProto","makeLeafDispatchRecord","makeDefaultDispatchRecord","initNativeDispatch","initNativeDispatchContinue","initHooks","applyHooksTransformer","floor","selfOf","receiverOf","computeFieldNamed","measureFor","_initTicker","elapsedMilliseconds","measure","elementAt","iterableToFullString","_isToStringVisiting","safeToString","_objectToString","_errorName","_errorExplanation","value","start","isRunning","_now","elapsedTicks","writeAll","isEmpty","printString","_toStringVisiting"],
7 | "mappings": "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"
8 | }
9 |
--------------------------------------------------------------------------------
/lib/src/FluidMotion/javascript/FluidMotion.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2012 the V8 project authors. All rights reserved.
3 | * Copyright 2009 Oliver Hunt
4 | *
5 | * Permission is hereby granted, free of charge, to any person
6 | * obtaining a copy of this software and associated documentation
7 | * files (the "Software"), to deal in the Software without
8 | * restriction, including without limitation the rights to use,
9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the
11 | * Software is furnished to do so, subject to the following
12 | * conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be
15 | * included in all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 | * OTHER DEALINGS IN THE SOFTWARE.
25 | */
26 |
27 | // Addapted by Google 2013.
28 |
29 | var solver = null;
30 |
31 | var framesTillAddingPoints = 0;
32 | var framesBetweenAddingPoints = 5;
33 |
34 | function runFluidMotion()
35 | {
36 | setupFluidMotion();
37 | for (var i = 0; i < 10; i++) {
38 | solver.update();
39 | }
40 | solver.validate(758.9012130174812, -352.56376676179076, -357.3690235879736);
41 | }
42 |
43 | function setupFluidMotion()
44 | {
45 | framesTillAddingPoints = 0;
46 | framesBetweenAddingPoints = 5;
47 | solver = new FluidField(null);
48 | solver.setResolution(128, 128);
49 | solver.setIterations(20);
50 | solver.setDisplayFunction(function(){});
51 | solver.setUICallback(prepareFrame);
52 | }
53 |
54 | function tearDownFluidMotion()
55 | {
56 | solver = null;
57 | }
58 |
59 | function addPoints(field) {
60 | var n = 64;
61 | for (var i = 1; i <= n; i++) {
62 | field.setVelocity(i, i, n, n);
63 | field.setDensity(i, i, 5);
64 | field.setVelocity(i, n - i, -n, -n);
65 | field.setDensity(i, n - i, 20);
66 | field.setVelocity(128 - i, n + i, -n, -n);
67 | field.setDensity(128 - i, n + i, 30);
68 | }
69 | }
70 |
71 | function prepareFrame(field)
72 | {
73 | if (framesTillAddingPoints == 0) {
74 | addPoints(field);
75 | framesTillAddingPoints = framesBetweenAddingPoints;
76 | framesBetweenAddingPoints++;
77 | } else {
78 | framesTillAddingPoints--;
79 | }
80 | }
81 |
82 | // Code from Oliver Hunt (http://nerget.com/fluidSim/pressure.js) starts here.
83 | function FluidField(canvas) {
84 |
85 | function approxEquals(a, b) {
86 | return Math.abs(a - b) < 0.000001;
87 | }
88 |
89 | function validate(expectedDens, expectedU, expectedV) {
90 | var sumDens = 0.0;
91 | var sumU = 0.0;
92 | var sumV = 0.0;
93 | for (var i = 0; i < dens.length; i++) {
94 | sumDens += dens[i];
95 | sumU += u[i];
96 | sumV += v[i];
97 | }
98 |
99 | if (!approxEquals(sumDens, expectedDens) ||
100 | !approxEquals(sumU, expectedU) ||
101 | !approxEquals(sumV, expectedV)) {
102 | throw "Incorrect result";
103 | }
104 | }
105 | this.validate = validate;
106 |
107 | function addFields(x, s, dt)
108 | {
109 | for (var i=0; i Wp5)
242 | x = Wp5;
243 | var i0 = x | 0;
244 | var i1 = i0 + 1;
245 | if (y < 0.5)
246 | y = 0.5;
247 | else if (y > Hp5)
248 | y = Hp5;
249 | var j0 = y | 0;
250 | var j1 = j0 + 1;
251 | var s1 = x - i0;
252 | var s0 = 1 - s1;
253 | var t1 = y - j0;
254 | var t0 = 1 - t1;
255 | var row1 = j0 * rowSize;
256 | var row2 = j1 * rowSize;
257 | d[pos] = s0 * (t0 * d0[i0 + row1] + t1 * d0[i0 + row2]) + s1 * (t0 * d0[i1 + row1] + t1 * d0[i1 + row2]);
258 | }
259 | }
260 | set_bnd(b, d);
261 | }
262 |
263 | function project(u, v, p, div)
264 | {
265 | var h = -0.5 / Math.sqrt(width * height);
266 | for (var j = 1 ; j <= height; j++ ) {
267 | var row = j * rowSize;
268 | var previousRow = (j - 1) * rowSize;
269 | var prevValue = row - 1;
270 | var currentRow = row;
271 | var nextValue = row + 1;
272 | var nextRow = (j + 1) * rowSize;
273 | for (var i = 1; i <= width; i++ ) {
274 | div[++currentRow] = h * (u[++nextValue] - u[++prevValue] + v[++nextRow] - v[++previousRow]);
275 | p[currentRow] = 0;
276 | }
277 | }
278 | set_bnd(0, div);
279 | set_bnd(0, p);
280 |
281 | lin_solve(0, p, div, 1, 4 );
282 | var wScale = 0.5 * width;
283 | var hScale = 0.5 * height;
284 | for (var j = 1; j<= height; j++ ) {
285 | var prevPos = j * rowSize - 1;
286 | var currentPos = j * rowSize;
287 | var nextPos = j * rowSize + 1;
288 | var prevRow = (j - 1) * rowSize;
289 | var currentRow = j * rowSize;
290 | var nextRow = (j + 1) * rowSize;
291 |
292 | for (var i = 1; i<= width; i++) {
293 | u[++currentPos] -= wScale * (p[++nextPos] - p[++prevPos]);
294 | v[currentPos] -= hScale * (p[++nextRow] - p[++prevRow]);
295 | }
296 | }
297 | set_bnd(1, u);
298 | set_bnd(2, v);
299 | }
300 |
301 | function dens_step(x, x0, u, v, dt)
302 | {
303 | addFields(x, x0, dt);
304 | diffuse(0, x0, x, dt );
305 | advect(0, x, x0, u, v, dt );
306 | }
307 |
308 | function vel_step(u, v, u0, v0, dt)
309 | {
310 | addFields(u, u0, dt );
311 | addFields(v, v0, dt );
312 | var temp = u0; u0 = u; u = temp;
313 | var temp = v0; v0 = v; v = temp;
314 | diffuse2(u,u0,v,v0, dt);
315 | project(u, v, u0, v0);
316 | var temp = u0; u0 = u; u = temp;
317 | var temp = v0; v0 = v; v = temp;
318 | advect(1, u, u0, u0, v0, dt);
319 | advect(2, v, v0, u0, v0, dt);
320 | project(u, v, u0, v0 );
321 | }
322 | var uiCallback = function(d,u,v) {};
323 |
324 | function Field(dens, u, v) {
325 | // Just exposing the fields here rather than using accessors is a measurable win during display (maybe 5%)
326 | // but makes the code ugly.
327 | this.setDensity = function(x, y, d) {
328 | dens[(x + 1) + (y + 1) * rowSize] = d;
329 | }
330 | this.getDensity = function(x, y) {
331 | return dens[(x + 1) + (y + 1) * rowSize];
332 | }
333 | this.setVelocity = function(x, y, xv, yv) {
334 | u[(x + 1) + (y + 1) * rowSize] = xv;
335 | v[(x + 1) + (y + 1) * rowSize] = yv;
336 | }
337 | this.getXVelocity = function(x, y) {
338 | return u[(x + 1) + (y + 1) * rowSize];
339 | }
340 | this.getYVelocity = function(x, y) {
341 | return v[(x + 1) + (y + 1) * rowSize];
342 | }
343 | this.width = function() { return width; }
344 | this.height = function() { return height; }
345 | }
346 | function queryUI(d, u, v)
347 | {
348 | for (var i = 0; i < size; i++)
349 | u[i] = v[i] = d[i] = 0.0;
350 | uiCallback(new Field(d, u, v));
351 | }
352 |
353 | this.update = function () {
354 | queryUI(dens_prev, u_prev, v_prev);
355 | vel_step(u, v, u_prev, v_prev, dt);
356 | dens_step(dens, dens_prev, u, v, dt);
357 | displayFunc(new Field(dens, u, v));
358 | }
359 | this.setDisplayFunction = function(func) {
360 | displayFunc = func;
361 | }
362 |
363 | this.iterations = function() { return iterations; }
364 | this.setIterations = function(iters) {
365 | if (iters > 0 && iters <= 100)
366 | iterations = iters;
367 | }
368 | this.setUICallback = function(callback) {
369 | uiCallback = callback;
370 | }
371 | var iterations = 10;
372 | var visc = 0.5;
373 | var dt = 0.1;
374 | var dens;
375 | var dens_prev;
376 | var u;
377 | var u_prev;
378 | var v;
379 | var v_prev;
380 | var width;
381 | var height;
382 | var rowSize;
383 | var size;
384 | var displayFunc;
385 | function reset()
386 | {
387 | rowSize = width + 2;
388 | size = (width+2)*(height+2);
389 | dens = new Float64Array(size);
390 | dens_prev = new Float64Array(size);
391 | u = new Float64Array(size);
392 | u_prev = new Float64Array(size);
393 | v = new Float64Array(size);
394 | v_prev = new Float64Array(size);
395 | for (var i = 0; i < size; i++)
396 | dens_prev[i] = u_prev[i] = v_prev[i] = dens[i] = u[i] = v[i] = 0;
397 | }
398 | this.reset = reset;
399 | this.setResolution = function (hRes, wRes)
400 | {
401 | var res = wRes * hRes;
402 | if (res > 0 && res < 1000000 && (wRes != width || hRes != height)) {
403 | width = wRes;
404 | height = hRes;
405 | reset();
406 | return true;
407 | }
408 | return false;
409 | }
410 | this.setResolution(64, 64);
411 | }
412 |
413 | Benchmark.report("FluidMotion", runFluidMotion, runFluidMotion);
414 |
--------------------------------------------------------------------------------
/lib/src/Havlak/dart/Havlak.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Google Inc.
2 | // All Rights Reserved.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 |
16 | import "../../common/dart/BenchmarkBase.dart";
17 | import "dart:collection";
18 |
19 | main() {
20 | new Havlak().report();
21 | }
22 |
23 | int mix(int existing, int value) {
24 | return ((existing & 0x0fffffff) << 1) + value;
25 | }
26 |
27 | //======================================================
28 | // Scaffold Code
29 | //======================================================
30 |
31 | // BasicBlock's static members
32 | //
33 | int numBasicBlocks = 0;
34 | int getNumBasicBlocks() => numBasicBlocks;
35 |
36 | //
37 | // class BasicBlock
38 | //
39 | // BasicBlock only maintains a vector of in-edges and
40 | // a vector of out-edges.
41 | //
42 | class BasicBlock {
43 | final int name;
44 | List inEdges = [];
45 | List outEdges = [];
46 |
47 | BasicBlock(this.name) {
48 | numBasicBlocks++;
49 | }
50 |
51 | String toString() => "BB$name";
52 | int getNumPred() => inEdges.length;
53 | int getNumSucc() => outEdges.length;
54 | void addInEdge(BasicBlock bb) => inEdges.add(bb);
55 | void addOutEdge(BasicBlock bb) => outEdges.add(bb);
56 | }
57 |
58 | //
59 | // class BasicBlockEdge
60 | //
61 | // These data structures are stubbed out to make the code below easier
62 | // to review.
63 | //
64 | // BasicBlockEdge only maintains two pointers to BasicBlocks.
65 | //
66 | class BasicBlockEdge {
67 | BasicBlock from, to;
68 |
69 | BasicBlockEdge(CFG cfg, int fromName, int toName) {
70 | from = cfg.createNode(fromName);
71 | to = cfg.createNode(toName);
72 |
73 | from.addOutEdge(to);
74 | to.addInEdge(from);
75 |
76 | cfg.addEdge(this);
77 | }
78 | }
79 |
80 |
81 | //
82 | // class CFG
83 | //
84 | // CFG maintains a list of nodes, plus a start node.
85 | // That's it.
86 | //
87 | class CFG {
88 | final Map basicBlockMap = new HashMap();
89 | final List edgeList = [];
90 | BasicBlock startNode;
91 |
92 | BasicBlock createNode(int name) {
93 | BasicBlock node = basicBlockMap[name];
94 | if (node == null) {
95 | node = new BasicBlock(name);
96 | basicBlockMap[name] = node;
97 | }
98 |
99 | if (getNumNodes() == 1) {
100 | startNode = node;
101 | }
102 | return node;
103 | }
104 |
105 | void addEdge(BasicBlockEdge edge) => edgeList.add(edge);
106 | int getNumNodes() => basicBlockMap.length;
107 | BasicBlock getDst(edge) => edge.to;
108 | BasicBlock getSrc(edge) => edge.from;
109 | }
110 |
111 | //
112 | // class SimpleLoop
113 | //
114 | // Basic representation of loops, a loop has an entry point,
115 | // one or more exit edges, a set of basic blocks, and potentially
116 | // an outer loop - a "parent" loop.
117 | //
118 | // Furthermore, it can have any set of properties, e.g.,
119 | // it can be an irreducible loop, have control flow, be
120 | // a candidate for transformations, and what not.
121 | //
122 | class SimpleLoop {
123 | final List basicBlocks = [];
124 | final List children = [];
125 | final int counter;
126 |
127 | SimpleLoop parent;
128 | BasicBlock header;
129 |
130 | bool isRoot = false;
131 | bool isReducible = true;
132 | int nestingLevel = 0;
133 | int depthLevel = 0;
134 |
135 | SimpleLoop(this.counter);
136 |
137 | void addNode(BasicBlock bb) => basicBlocks.add(bb);
138 | void addChildLoop(SimpleLoop loop) => children.add(loop);
139 |
140 | void setParent(SimpleLoop p) {
141 | this.parent = p;
142 | p.addChildLoop(this);
143 | }
144 |
145 | void setHeader(BasicBlock bb) {
146 | basicBlocks.add(bb);
147 | header = bb;
148 | }
149 |
150 | void setNestingLevel(int level) {
151 | nestingLevel = level;
152 | if (level == 0) {
153 | isRoot = true;
154 | }
155 | }
156 |
157 | int checksum() {
158 | int result = counter;
159 | result = mix(result, isRoot ? 1 : 0);
160 | result = mix(result, isReducible ? 1 : 0);
161 | result = mix(result, nestingLevel);
162 | result = mix(result, depthLevel);
163 | if (header != null) result = mix(result, header.name);
164 | basicBlocks.forEach((e) => result = mix(result, e.name));
165 | children.forEach((e) => result = mix(result, e.checksum()));
166 | return result;
167 | }
168 | }
169 |
170 |
171 | //
172 | // LoopStructureGraph
173 | //
174 | // Maintain loop structure for a given CFG.
175 | //
176 | // Two values are maintained for this loop graph, depth, and nesting level.
177 | // For example:
178 | //
179 | // loop nesting level depth
180 | //----------------------------------------
181 | // loop-0 2 0
182 | // loop-1 1 1
183 | // loop-3 1 1
184 | // loop-2 0 2
185 | //
186 | class LSG {
187 | int loopCounter = 1;
188 | final List loops = [];
189 | final SimpleLoop root = new SimpleLoop(0);
190 |
191 | LSG() {
192 | root.setNestingLevel(0);
193 | loops.add(root);
194 | }
195 |
196 | SimpleLoop createNewLoop() {
197 | SimpleLoop loop = new SimpleLoop(loopCounter++);
198 | return loop;
199 | }
200 |
201 | void addLoop(SimpleLoop loop) => loops.add(loop);
202 |
203 | int checksum() {
204 | int result = loops.length;
205 | loops.forEach((e) => result = mix(result, e.checksum()));
206 | return mix(result, root.checksum());
207 | }
208 |
209 | int getNumLoops() => loops.length;
210 | }
211 |
212 |
213 | //======================================================
214 | // Main Algorithm
215 | //======================================================
216 |
217 | //
218 | // class UnionFindNode
219 | //
220 | // The algorithm uses the Union/Find algorithm to collapse
221 | // complete loops into a single node. These nodes and the
222 | // corresponding functionality are implemented with this class
223 | //
224 | class UnionFindNode {
225 | int dfsNumber = 0;
226 | UnionFindNode parent;
227 | BasicBlock bb;
228 | SimpleLoop loop;
229 |
230 | UnionFindNode();
231 |
232 | // Initialize this node.
233 | //
234 | void initNode(BasicBlock bb, int dfsNumber) {
235 | parent = this;
236 | this.bb = bb;
237 | this.dfsNumber = dfsNumber;
238 | }
239 |
240 | // Union/Find Algorithm - The find routine.
241 | //
242 | // Implemented with Path Compression (inner loops are only
243 | // visited and collapsed once, however, deep nests would still
244 | // result in significant traversals).
245 | //
246 | UnionFindNode findSet() {
247 | List nodeList = [];
248 |
249 | UnionFindNode node = this;
250 | while (node != node.parent) {
251 | if (node.parent != node.parent.parent)
252 | nodeList.add(node);
253 |
254 | node = node.parent;
255 | }
256 |
257 | // Path Compression, all nodes' parents point to the 1st level parent.
258 | for (int iter=0; iter < nodeList.length; ++iter) {
259 | nodeList[iter].parent = node.parent;
260 | }
261 |
262 | return node;
263 | }
264 |
265 | // Union/Find Algorithm - The union routine.
266 | //
267 | // Trivial. Assigning parent pointer is enough,
268 | // we rely on path compression.
269 | //
270 | void union(UnionFindNode unionFindNode) {
271 | parent = unionFindNode;
272 | }
273 | SimpleLoop setLoop(SimpleLoop l) => loop = l;
274 | }
275 |
276 |
277 |
278 | class HavlakLoopFinder {
279 | final CFG cfg;
280 | final LSG lsg;
281 |
282 | static const int BB_TOP = 0; // uninitialized
283 | static const int BB_NONHEADER = 1; // a regular BB
284 | static const int BB_REDUCIBLE = 2; // reducible loop
285 | static const int BB_SELF = 3; // single BB loop
286 | static const int BB_IRREDUCIBLE = 4; // irreducible loop
287 | static const int BB_DEAD = 5; // a dead BB
288 | static const int BB_LAST = 6; // Sentinel
289 |
290 | // Marker for uninitialized nodes.
291 | static const int UNVISITED = -1;
292 |
293 | // Safeguard against pathologic algorithm behavior.
294 | static const int MAXNONBACKPREDS = (32 * 1024);
295 |
296 | HavlakLoopFinder(this.cfg, this.lsg);
297 |
298 | //
299 | // IsAncestor
300 | //
301 | // As described in the paper, determine whether a node 'w' is a
302 | // "true" ancestor for node 'v'.
303 | //
304 | // Dominance can be tested quickly using a pre-order trick
305 | // for depth-first spanning trees. This is why DFS is the first
306 | // thing we run below.
307 | //
308 | bool isAncestor(int w, int v, List last) {
309 | return (w <= v) && (v <= last[w]);
310 | }
311 |
312 | //
313 | // DFS - Depth-First-Search
314 | //
315 | // DESCRIPTION:
316 | // Simple depth first traversal along out edges with node numbering.
317 | //
318 | int DFS(BasicBlock currentNode,
319 | List nodes,
320 | List number,
321 | List last, int current) {
322 | nodes[current].initNode(currentNode, current);
323 | number[currentNode.name] = current;
324 |
325 | int lastid = current;
326 | for (int target = 0; target < currentNode.outEdges.length; target++) {
327 | if (number[currentNode.outEdges[target].name] == UNVISITED)
328 | lastid = DFS(currentNode.outEdges[target], nodes, number,
329 | last, lastid + 1);
330 | }
331 |
332 | last[number[currentNode.name]] = lastid;
333 | return lastid;
334 | }
335 |
336 | //
337 | // findLoops
338 | //
339 | // Find loops and build loop forest using Havlak's algorithm, which
340 | // is derived from Tarjan. Variable names and step numbering has
341 | // been chosen to be identical to the nomenclature in Havlak's
342 | // paper (which, in turn, is similar to the one used by Tarjan).
343 | //
344 | int findLoops() {
345 | if (cfg.startNode == null) {
346 | return 0;
347 | }
348 |
349 | int size = cfg.getNumNodes();
350 |
351 | List> nonBackPreds = new List(size);
352 | List> backPreds = new List(size);
353 | List number = new List(size);
354 | List header = new List(size);
355 | List types = new List(size);
356 | List last = new List(size);
357 | List nodes = new List(size);
358 |
359 | for (int i = 0; i < size; ++i) {
360 | nonBackPreds[i] = [];
361 | backPreds[i] = [];
362 | number[i] = UNVISITED;
363 | header[i] = 0;
364 | types[i] = BB_NONHEADER;
365 | last[i] = 0;
366 | nodes[i] = new UnionFindNode();
367 | }
368 |
369 | // Step a:
370 | // - initialize all nodes as unvisited.
371 | // - depth-first traversal and numbering.
372 | // - unreached BB's are marked as dead.
373 | //
374 | DFS(cfg.startNode, nodes, number, last, 0);
375 |
376 | // Step b:
377 | // - iterate over all nodes.
378 | //
379 | // A backedge comes from a descendant in the DFS tree, and non-backedges
380 | // from non-descendants (following Tarjan).
381 | //
382 | // - check incoming edges 'v' and add them to either
383 | // - the list of backedges (backPreds) or
384 | // - the list of non-backedges (nonBackPreds)
385 | //
386 | for (int w = 0; w < size; ++w) {
387 | BasicBlock nodeW = nodes[w].bb;
388 | if (nodeW == null) {
389 | types[w] = BB_DEAD;
390 | } else {
391 | if (nodeW.getNumPred() > 0) {
392 | for (int nv = 0; nv < nodeW.inEdges.length; ++nv) {
393 | BasicBlock nodeV = nodeW.inEdges[nv];
394 | int v = number[nodeV.name];
395 | if (v != UNVISITED) {
396 | if (isAncestor(w, v, last)) {
397 | backPreds[w].add(v);
398 | } else {
399 | nonBackPreds[w].add(v);
400 | }
401 | }
402 | }
403 | }
404 | }
405 | }
406 |
407 | // Step c:
408 | //
409 | // The outer loop, unchanged from Tarjan. It does nothing except
410 | // for those nodes which are the destinations of backedges.
411 | // For a header node w, we chase backward from the sources of the
412 | // backedges adding nodes to the set P, representing the body of
413 | // the loop headed by w.
414 | //
415 | // By running through the nodes in reverse of the DFST preorder,
416 | // we ensure that inner loop headers will be processed before the
417 | // headers for surrounding loops.
418 | //
419 | for (int w = size-1; w >=0; --w) {
420 | // this is 'P' in Havlak's paper
421 | List nodePool = [];
422 |
423 | BasicBlock nodeW = nodes[w].bb;
424 | if (nodeW == null) {
425 | continue;
426 | }
427 |
428 | // Step d:
429 | for (int vi = 0; vi < backPreds[w].length; ++vi) {
430 | var v = backPreds[w][vi];
431 | if (v != w) {
432 | nodePool.add(nodes[v].findSet());
433 | } else {
434 | types[w] = BB_SELF;
435 | }
436 | }
437 |
438 | // Copy nodePool to workList.
439 | //
440 | List workList = [];
441 | for (int n = 0; n < nodePool.length; ++n) {
442 | workList.add(nodePool[n]);
443 | }
444 |
445 | if (nodePool.length != 0) {
446 | types[w] = BB_REDUCIBLE;
447 | }
448 | // work the list...
449 | //
450 | while (workList.length > 0) {
451 | UnionFindNode x = workList.removeAt(0);
452 |
453 | // Step e:
454 | //
455 | // Step e represents the main difference from Tarjan's method.
456 | // Chasing upwards from the sources of a node w's backedges. If
457 | // there is a node y' that is not a descendant of w, w is marked
458 | // the header of an irreducible loop, there is another entry
459 | // into this loop that avoids w.
460 | //
461 |
462 | // The algorithm has degenerated. Break and
463 | // return in this case.
464 | //
465 | int nonBackSize = nonBackPreds[x.dfsNumber].length;
466 | if (nonBackSize > MAXNONBACKPREDS) {
467 | return 0;
468 | }
469 |
470 | for (int iter=0; iter < nonBackPreds[x.dfsNumber].length; ++iter) {
471 | UnionFindNode y = nodes[nonBackPreds[x.dfsNumber][iter]];
472 | UnionFindNode ydash = y.findSet();
473 |
474 | if (!isAncestor(w, ydash.dfsNumber, last)) {
475 | types[w] = BB_IRREDUCIBLE;
476 | nonBackPreds[w].add(ydash.dfsNumber);
477 | } else {
478 | if (ydash.dfsNumber != w) {
479 | if (nodePool.indexOf(ydash) == -1) {
480 | workList.add(ydash);
481 | nodePool.add(ydash);
482 | }
483 | }
484 | }
485 | }
486 | }
487 |
488 | // Collapse/Unionize nodes in a SCC to a single node
489 | // For every SCC found, create a loop descriptor and link it in.
490 | //
491 | if ((nodePool.length > 0) || (types[w] == BB_SELF)) {
492 | SimpleLoop loop = lsg.createNewLoop();
493 |
494 | loop.setHeader(nodeW);
495 | if (types[w] == BB_IRREDUCIBLE) {
496 | loop.isReducible = true;
497 | } else {
498 | loop.isReducible = false;
499 | }
500 |
501 | // At this point, one can set attributes to the loop, such as:
502 | //
503 | // the bottom node:
504 | // iter = backPreds(w).begin();
505 | // loop bottom is: nodes(iter).node;
506 | //
507 | // the number of backedges:
508 | // backPreds(w).size()
509 | //
510 | // whether this loop is reducible:
511 | // types(w) != BB_IRREDUCIBLE
512 | //
513 | nodes[w].loop = loop;
514 |
515 | for (int np = 0; np < nodePool.length; ++np) {
516 | UnionFindNode node = nodePool[np];
517 |
518 | // Add nodes to loop descriptor.
519 | header[node.dfsNumber] = w;
520 | node.union(nodes[w]);
521 |
522 | // Nested loops are not added, but linked together.
523 | if (node.loop != null) {
524 | node.loop.setParent(loop);
525 | } else {
526 | loop.addNode(node.bb);
527 | }
528 | }
529 | lsg.addLoop(loop);
530 | } // nodePool.length
531 | } // Step c
532 |
533 | return lsg.getNumLoops();
534 | } // findLoops
535 | } // HavlakLoopFinder
536 |
537 |
538 | //======================================================
539 | // Testing Code
540 | //======================================================
541 |
542 | int buildDiamond(CFG cfg, int start) {
543 | var bb0 = start;
544 | new BasicBlockEdge(cfg, bb0, bb0 + 1);
545 | new BasicBlockEdge(cfg, bb0, bb0 + 2);
546 | new BasicBlockEdge(cfg, bb0 + 1, bb0 + 3);
547 | new BasicBlockEdge(cfg, bb0 + 2, bb0 + 3);
548 | return bb0 + 3;
549 | }
550 |
551 |
552 | void buildConnect(CFG cfg, int start, int end) {
553 | new BasicBlockEdge(cfg, start, end);
554 | }
555 |
556 | int buildStraight(CFG cfg, int start, int n) {
557 | for (int i=0; i < n; i++) {
558 | buildConnect(cfg, start + i, start + i + 1);
559 | }
560 | return start + n;
561 | }
562 |
563 | int buildBaseLoop(CFG cfg, int from) {
564 | int header = buildStraight(cfg, from, 1);
565 | int diamond1 = buildDiamond(cfg, header);
566 | int d11 = buildStraight(cfg, diamond1, 1);
567 | int diamond2 = buildDiamond(cfg, d11);
568 | int footer = buildStraight(cfg, diamond2, 1);
569 | buildConnect(cfg, diamond2, d11);
570 | buildConnect(cfg, diamond1, header);
571 |
572 | buildConnect(cfg, footer, from);
573 | footer = buildStraight(cfg, footer, 1);
574 | return footer;
575 | }
576 |
577 |
578 | class Havlak extends BenchmarkBase {
579 | final CFG cfg = new CFG();
580 |
581 | Havlak() : super("Havlak") {
582 | // Construct simple CFG.
583 | cfg.createNode(0); // top
584 | buildBaseLoop(cfg, 0);
585 | cfg.createNode(1); //s bottom
586 | buildConnect(cfg, 0, 2);
587 |
588 | // Construct complex CFG.
589 | var n = 2;
590 | for (int parlooptrees=0; parlooptrees < 10; parlooptrees++) {
591 | cfg.createNode(n + 1);
592 | buildConnect(cfg, n, n + 1);
593 | n = n + 1;
594 | for (int i=0; i < 2; ++i) {
595 | var top = n;
596 | n = buildStraight(cfg, n, 1);
597 | for (int j=0; j < 25; j++) {
598 | n = buildBaseLoop(cfg, n);
599 | }
600 |
601 | var bottom = buildStraight(cfg, n, 1);
602 | buildConnect(cfg, n, top);
603 | n = bottom;
604 | }
605 | }
606 | }
607 |
608 | void exercise() {
609 | LSG lsg = new LSG();
610 | HavlakLoopFinder finder = new HavlakLoopFinder(cfg, lsg);
611 | int numLoops = finder.findLoops();
612 | if (numLoops != 1522) {
613 | throw 'Wrong result - expected <1522>, but was <$numLoops>';
614 | }
615 | }
616 |
617 | void warmup() {
618 | for (int dummyloop = 0; dummyloop < 20; ++dummyloop) {
619 | var lsg = new LSG();
620 | var finder = new HavlakLoopFinder(cfg, lsg);
621 | finder.findLoops();
622 | int checksum = lsg.checksum();
623 | if (checksum != 435630002) {
624 | throw 'Wrong checksum - expected <435630002>, but was <$checksum>';
625 | }
626 | }
627 | }
628 | }
629 |
--------------------------------------------------------------------------------
/lib/src/Havlak/dart/Havlak.dart.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "file": "Havlak.dart.js",
4 | "sourceRoot": "",
5 | "sources": ["Havlak.dart","../../common/dart/BenchmarkBase.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/internal_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/collection_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/interceptors.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_array.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/list.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_number.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_string.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_helper.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_rti.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/core_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/core/stopwatch.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/hash_map.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/iterable.dart","../../../../../../Tools/dart/stable/sdk/lib/core/errors.dart","../../../../../../Tools/dart/stable/sdk/lib/core/null.dart","../../../../../../Tools/dart/stable/sdk/lib/core/object.dart","../../../../../../Tools/dart/stable/sdk/lib/core/string_buffer.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_primitives.dart"],
6 | "names": ["main","report","printToConsole","buildDiamond","buildStraight","addEdge","","buildBaseLoop","toString","getNumPred","addInEdge","addOutEdge","createNode","length","setNestingLevel","checksum","mix","call","findSet","DFS","initNode","findLoops","getNumNodes","isAncestor","addLoop","setHeader","union","setParent","addChildLoop","addNode","getNumLoops","exercise","warmup","buildConnect","basicBlockMap","getInterceptor","==","hashCode","forEach","indexOf","listToString","moveNext","toInt","truncateToDouble","+","-","~/","_tdivSlow","codeUnitAt","substring","S","objectHashCode","objectTypeName","formatType","objectToString","dateNow","initTicker","iae","ioore","checkInt","wrapException","toStringWrapper","throwExpression","fromTearOff","cspForwardCall","forwardCallTo","selfFieldName","cspForwardInterceptedCall","forwardInterceptedCallTo","receiverFieldName","closureFromTearOff","throwCyclicInit","setRuntimeTypeInfo","getRuntimeTypeInfo","runtimeTypeToString","getRuntimeTypeAsString","joinArguments","_writeString","floor","selfOf","receiverOf","computeFieldNamed","measureFor","_initTicker","elapsedMilliseconds","measure","_defaultEquals","_defaultHashCode","iterableToFullString","_isToStringVisiting","[]","_isStringKey","_get","_getBucket","[]=","_set","_addHashTableEntry","_computeHashCode","_findBucketIndex","_setTableEntry","_newHashTable","safeToString","_objectToString","identical","identityHashCode","_errorName","_errorExplanation","value","start","isRunning","_now","elapsedTicks","writeAll","isEmpty","current","printString","_toStringVisiting"],
7 | "mappings": "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"
8 | }
9 |
--------------------------------------------------------------------------------
/lib/src/Havlak/javascript/Havlak.js:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Google Inc.
2 | //
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 | // Scaffold Code
17 | //======================================================
18 |
19 | // BasicBlock's static members
20 | //
21 | var numBasicBlocks = 0;
22 |
23 | function getNumBasicBlocks() {
24 | return numBasicBlocks;
25 | }
26 |
27 | function mix(existing, value) {
28 | return ((existing & 0x0fffffff) << 1) + value;
29 | }
30 |
31 | //
32 | // class BasicBlock
33 | //
34 | // BasicBlock only maintains a vector of in-edges and
35 | // a vector of out-edges.
36 | //
37 | function BasicBlock(name)
38 | {
39 | this.name = name;
40 | this.inEdges = [];
41 | this.outEdges = [];
42 |
43 | numBasicBlocks = numBasicBlocks + 1;
44 | }
45 |
46 | BasicBlock.prototype.toString = function() {
47 | return "BB" + this.name;
48 | }
49 |
50 | BasicBlock.prototype.getNumPred = function() {
51 | return this.inEdges.length;
52 | }
53 | BasicBlock.prototype.getNumSucc = function() {
54 | return this.outEdges.length;
55 | }
56 | BasicBlock.prototype.addInEdge = function(bb) {
57 | this.inEdges.push(bb);
58 | }
59 | BasicBlock.prototype.addOutEdge = function(bb) {
60 | this.outEdges.push(bb);
61 | }
62 |
63 |
64 |
65 | //
66 | // class CFG
67 | //
68 | // CFG maintains a list of nodes, plus a start node.
69 | // That's it.
70 | //
71 | function CFG() {
72 | this.startNode = null;
73 | this.basicBlockMap = {};
74 | this.basicBlockLen = 0;
75 | this.edgeList = [];
76 | }
77 |
78 | CFG.prototype.createNode = function(name) {
79 | var node = this.basicBlockMap[name];
80 | if (!node) {
81 | node = new BasicBlock(name);
82 | this.basicBlockMap[name] = node;
83 | this.basicBlockLen++;
84 | }
85 |
86 | if (this.getNumNodes() == 1) {
87 | this.startNode = node;
88 | }
89 | return node;
90 | }
91 |
92 | CFG.prototype.addEdge = function(edge) {
93 | this.edgeList.push(edge);
94 | }
95 | CFG.prototype.getNumNodes = function() {
96 | return this.basicBlockLen;
97 | }
98 | CFG.prototype.getDst = function(edge) {
99 | return edge.To;
100 | }
101 | CFG.prototype.getSrc = function(edge) {
102 | return edge.From;
103 | }
104 |
105 | //
106 | // class BasicBlockEdge
107 | //
108 | // These data structures are stubbed out to make the code below easier
109 | // to review.
110 | //
111 | // BasicBlockEdge only maintains two pointers to BasicBlocks.
112 | // Note: from is apparently a keyword in python. Changed to uppercase
113 | //
114 | function BasicBlockEdge(cfg, fromName, toName) {
115 | this.From = cfg.createNode(fromName);
116 | this.To = cfg.createNode(toName);
117 |
118 | this.From.addOutEdge(this.To);
119 | this.To.addInEdge(this.From);
120 |
121 | cfg.addEdge(this);
122 | }
123 |
124 | //
125 | // class SimpleLoop
126 | //
127 | // Basic representation of loops, a loop has an entry point,
128 | // one or more exit edges, a set of basic blocks, and potentially
129 | // an outer loop - a "parent" loop.
130 | //
131 | // Furthermore, it can have any set of properties, e.g.,
132 | // it can be an irreducible loop, have control flow, be
133 | // a candidate for transformations, and what not.
134 | //
135 | function SimpleLoop(counter) {
136 | this.basicBlocks = [];
137 | this.children = [];
138 | this.isRoot = false;
139 | this.isReducible = true;
140 | this.counter = counter;
141 | this.nestingLevel = 0;
142 | this.depthLevel = 0;
143 | this.parent = undefined;
144 | this.header = undefined;
145 | }
146 |
147 | SimpleLoop.prototype.addNode = function(bb) {
148 | this.basicBlocks.push(bb);
149 | }
150 |
151 | SimpleLoop.prototype.addChildLoop = function(loop) {
152 | this.children.push(loop);
153 | }
154 |
155 | SimpleLoop.prototype.setParent = function(parent) {
156 | this.parent = parent;
157 | parent.addChildLoop(this);
158 | }
159 |
160 | SimpleLoop.prototype.setHeader = function(bb) {
161 | this.basicBlocks.push(bb);
162 | this.header = bb;
163 | }
164 |
165 | SimpleLoop.prototype.setNestingLevel = function(level) {
166 | this.nestingLevel = level;
167 | if (level == 0) {
168 | this.isRoot = true;
169 | }
170 | }
171 |
172 | SimpleLoop.prototype.checksum = function() {
173 | var result = this.counter;
174 | result = mix(result, this.isRoot ? 1 : 0);
175 | result = mix(result, this.isReducible ? 1 : 0);
176 | result = mix(result, this.nestingLevel);
177 | result = mix(result, this.depthLevel);
178 | if (this.header != null) result = mix(result, this.header.name);
179 | this.basicBlocks.forEach(function(e) { result = mix(result, e.name) });
180 | this.children.forEach(function(e) { result = mix(result, e.checksum()) });
181 | return result;
182 | }
183 |
184 |
185 | //
186 | // LoopStructureGraph
187 | //
188 | // Maintain loop structure for a given CFG.
189 | //
190 | // Two values are maintained for this loop graph, depth, and nesting level.
191 | // For example:
192 | //
193 | // loop nesting level depth
194 | //----------------------------------------
195 | // loop-0 2 0
196 | // loop-1 1 1
197 | // loop-3 1 1
198 | // loop-2 0 2
199 | //
200 | function LSG() {
201 | this.loopCounter = 1;
202 | this.root = new SimpleLoop(0);
203 | this.loops = [this.root];
204 | this.root.setNestingLevel(0);
205 | }
206 |
207 | LSG.prototype.createNewLoop = function() {
208 | return new SimpleLoop(this.loopCounter++);
209 | }
210 |
211 | LSG.prototype.addLoop = function(loop) {
212 | this.loops.push(loop);
213 | }
214 |
215 | LSG.prototype.getNumLoops = function() {
216 | return this.loops.length;
217 | }
218 |
219 | LSG.prototype.checksum = function() {
220 | var result = this.loops.length;
221 | this.loops.forEach(function(e) { result = mix(result, e.checksum()) });
222 | return mix(result, this.root.checksum());
223 | }
224 |
225 |
226 | //======================================================
227 | // Main Algorithm
228 | //======================================================
229 |
230 | //
231 | // class UnionFindNode
232 | //
233 | // The algorithm uses the Union/Find algorithm to collapse
234 | // complete loops into a single node. These nodes and the
235 | // corresponding functionality are implemented with this class
236 | //
237 | function UnionFindNode() {
238 | this.parent = this;
239 | this.bb = undefined;
240 | this.dfsNumber = 0;
241 | this.loop = undefined;
242 | }
243 |
244 | // Initialize this node.
245 | //
246 | UnionFindNode.prototype.initNode = function(bb, dfsNumber) {
247 | this.bb = bb;
248 | this.dfsNumber = dfsNumber;
249 | }
250 |
251 | // Union/Find Algorithm - The find routine.
252 | //
253 | // Implemented with Path Compression (inner loops are only
254 | // visited and collapsed once, however, deep nests would still
255 | // result in significant traversals).
256 | //
257 | UnionFindNode.prototype.findSet = function() {
258 | var nodeList = [];
259 |
260 | node = this;
261 | while (node != node.parent) {
262 | if (node.parent != node.parent.parent)
263 | nodeList.push(node);
264 |
265 | node = node.parent;
266 | }
267 |
268 | // Path Compression, all nodes' parents point to the 1st level parent.
269 | for (iter=0; iter < nodeList.length; ++iter) {
270 | nodeList[iter].parent = node.parent;
271 | }
272 |
273 | return node;
274 | }
275 |
276 | // Union/Find Algorithm - The union routine.
277 | //
278 | // Trivial. Assigning parent pointer is enough,
279 | // we rely on path compression.
280 | //
281 | UnionFindNode.prototype.union = function(unionFindNode) {
282 | this.parent = unionFindNode;
283 | }
284 |
285 |
286 | //
287 | // enum BasicBlockClass
288 | //
289 | // Basic Blocks and Loops are being classified as regular, irreducible,
290 | // and so on. This enum contains a symbolic name for all these
291 | // classifications. Python doesn't have enums, so we just create values.
292 | //
293 | var BB_TOP = 0; // uninitialized
294 | var BB_NONHEADER = 1; // a regular BB
295 | var BB_REDUCIBLE = 2; // reducible loop
296 | var BB_SELF = 3; // single BB loop
297 | var BB_IRREDUCIBLE = 4; // irreducible loop
298 | var BB_DEAD = 5; // a dead BB
299 | var BB_LAST = 6; // Sentinel
300 |
301 | //
302 | // Constants
303 | //
304 | // Marker for uninitialized nodes.
305 | var UNVISITED = -1;
306 |
307 | // Safeguard against pathologic algorithm behavior.
308 | var MAXNONBACKPREDS = (32 * 1024);
309 |
310 |
311 | function HavlakLoopFinder(cfgParm, lsgParm) {
312 | this.cfg = cfgParm;
313 | this.lsg = lsgParm;
314 | }
315 |
316 |
317 | //
318 | // IsAncestor
319 | //
320 | // As described in the paper, determine whether a node 'w' is a
321 | // "true" ancestor for node 'v'.
322 | //
323 | // Dominance can be tested quickly using a pre-order trick
324 | // for depth-first spanning trees. This is why DFS is the first
325 | // thing we run below.
326 | //
327 | HavlakLoopFinder.prototype.isAncestor = function(w, v, last) {
328 | return (w <= v) && (v <= last[w]);
329 | };
330 |
331 | //
332 | // DFS - Depth-First-Search
333 | //
334 | // DESCRIPTION:
335 | // Simple depth first traversal along out edges with node numbering.
336 | //
337 | HavlakLoopFinder.prototype.DFS = function(currentNode,
338 | nodes,
339 | number,
340 | last,
341 | current) {
342 | nodes[current].initNode(currentNode, current);
343 | number[currentNode.name] = current;
344 |
345 | var lastid = current;
346 | for (var target = 0; target < currentNode.outEdges.length; target++) {
347 | if (number[currentNode.outEdges[target].name] == UNVISITED) {
348 | lastid = this.DFS(currentNode.outEdges[target], nodes, number,
349 | last, lastid + 1);
350 | }
351 | }
352 |
353 | last[number[currentNode.name]] = lastid;
354 | return lastid;
355 | };
356 |
357 | //
358 | // findLoops
359 | //
360 | // Find loops and build loop forest using Havlak's algorithm, which
361 | // is derived from Tarjan. Variable names and step numbering has
362 | // been chosen to be identical to the nomenclature in Havlak's
363 | // paper (which, in turn, is similar to the one used by Tarjan).
364 | //
365 | HavlakLoopFinder.prototype.findLoops = function() {
366 | var size = this.cfg.getNumNodes();
367 |
368 | var nonBackPreds = new Array(size);
369 | var backPreds = new Array(size)
370 | var number = new Array(size);
371 | var header = new Array(size);
372 | var types = new Array(size);
373 | var last = new Array(size);
374 | var nodes = new Array(size);
375 |
376 | for (var i = 0; i < size; ++i) {
377 | nonBackPreds[i] = [];
378 | backPreds[i] = [];
379 | number[i] = UNVISITED;
380 | header[i] = 0;
381 | types[i] = BB_NONHEADER;
382 | last[i] = 0;
383 | nodes[i] = new UnionFindNode();
384 | }
385 |
386 | // Step a:
387 | // - initialize all nodes as unvisited.
388 | // - depth-first traversal and numbering.
389 | // - unreached BB's are marked as dead.
390 | //
391 | this.DFS(cfg.startNode, nodes, number, last, 0);
392 |
393 | // Step b:
394 | // - iterate over all nodes.
395 | //
396 | // A backedge comes from a descendant in the DFS tree, and non-backedges
397 | // from non-descendants (following Tarjan).
398 | //
399 | // - check incoming edges 'v' and add them to either
400 | // - the list of backedges (backPreds) or
401 | // - the list of non-backedges (nonBackPreds)
402 | //
403 | for (var w = 0; w < size; ++w) {
404 | var nodeW = nodes[w].bb;
405 | if (nodeW === undefined) {
406 | types[w] = BB_DEAD;
407 | } else {
408 | if (nodeW.getNumPred() > 0) {
409 | for (var nv = 0; nv < nodeW.inEdges.length; ++nv) {
410 | var nodeV = nodeW.inEdges[nv];
411 | var v = number[nodeV.name];
412 | if (v != UNVISITED) {
413 | if (this.isAncestor(w, v, last)) {
414 | backPreds[w].push(v);
415 | } else {
416 | nonBackPreds[w].push(v);
417 | }
418 | }
419 | }
420 | }
421 | }
422 | }
423 |
424 | // Step c:
425 | //
426 | // The outer loop, unchanged from Tarjan. It does nothing except
427 | // for those nodes which are the destinations of backedges.
428 | // For a header node w, we chase backward from the sources of the
429 | // backedges adding nodes to the set P, representing the body of
430 | // the loop headed by w.
431 | //
432 | // By running through the nodes in reverse of the DFST preorder,
433 | // we ensure that inner loop headers will be processed before the
434 | // headers for surrounding loops.
435 | //
436 | for (var w = size-1; w >=0; --w) {
437 | // this is 'P' in Havlak's paper
438 | var nodePool = [];
439 |
440 | var nodeW = nodes[w].bb;
441 | if (nodeW === undefined) {
442 | continue;
443 | }
444 |
445 | // Step d:
446 | for (var vi = 0; vi < backPreds[w].length; ++vi) {
447 | var v = backPreds[w][vi];
448 | if (v != w) {
449 | nodePool.push(nodes[v].findSet());
450 | } else {
451 | types[w] = BB_SELF;
452 | }
453 | }
454 |
455 | // Copy nodePool to workList.
456 | //
457 | var workList = [];
458 | for (var n = 0; n < nodePool.length; ++n) {
459 | workList.push(nodePool[n]);
460 | }
461 |
462 | if (nodePool.length != 0) {
463 | types[w] = BB_REDUCIBLE;
464 | }
465 | // work the list...
466 | //
467 | while (workList.length) {
468 | var x = workList.shift();
469 |
470 | // Step e:
471 | //
472 | // Step e represents the main difference from Tarjan's method.
473 | // Chasing upwards from the sources of a node w's backedges. If
474 | // there is a node y' that is not a descendant of w, w is marked
475 | // the header of an irreducible loop, there is another entry
476 | // into this loop that avoids w.
477 | //
478 |
479 | // The algorithm has degenerated. Break and
480 | // return in this case.
481 | //
482 | var nonBackSize = nonBackPreds[x.dfsNumber].length;
483 | if (nonBackSize > MAXNONBACKPREDS) {
484 | return 0;
485 | }
486 |
487 | for (var iter=0; iter < nonBackPreds[x.dfsNumber].length; ++iter) {
488 | var y = nodes[nonBackPreds[x.dfsNumber][iter]];
489 | var ydash = y.findSet();
490 |
491 | if (!this.isAncestor(w, ydash.dfsNumber, last)) {
492 | types[w] = BB_IRREDUCIBLE;
493 | nonBackPreds[w].push(ydash.dfsNumber);
494 | } else {
495 | if (ydash.dfsNumber != w) {
496 | if (nodePool.indexOf(ydash) == -1) {
497 | workList.push(ydash);
498 | nodePool.push(ydash);
499 | }
500 | }
501 | }
502 | }
503 | }
504 |
505 | // Collapse/Unionize nodes in a SCC to a single node
506 | // For every SCC found, create a loop descriptor and link it in.
507 | //
508 | if ((nodePool.length > 0) || (types[w] == BB_SELF)) {
509 | var loop = this.lsg.createNewLoop();
510 |
511 | loop.setHeader(nodeW);
512 | if (types[w] == BB_IRREDUCIBLE) {
513 | loop.isReducible = true;
514 | } else {
515 | loop.isReducible = false;
516 | }
517 |
518 | // At this point, one can set attributes to the loop, such as:
519 | //
520 | // the bottom node:
521 | // iter = backPreds(w).begin();
522 | // loop bottom is: nodes(iter).node;
523 | //
524 | // the number of backedges:
525 | // backPreds(w).size()
526 | //
527 | // whether this loop is reducible:
528 | // types(w) != BB_IRREDUCIBLE
529 | //
530 | nodes[w].loop = loop;
531 |
532 | for (var np = 0; np < nodePool.length; ++np) {
533 | var node = nodePool[np];
534 |
535 | // Add nodes to loop descriptor.
536 | header[node.dfsNumber] = w;
537 | node.union(nodes[w]);
538 |
539 | // Nested loops are not added, but linked together.
540 | if (node.loop !== undefined) {
541 | node.loop.setParent(loop);
542 | } else {
543 | loop.addNode(node.bb);
544 | }
545 | }
546 | this.lsg.addLoop(loop);
547 | } // nodePool.length
548 | } // Step c
549 | return this.lsg.getNumLoops();
550 | }; // findLoops
551 |
552 |
553 | //======================================================
554 | // Testing Code
555 | //======================================================
556 |
557 | function buildDiamond(cfg, start) {
558 | var bb0 = start;
559 | new BasicBlockEdge(cfg, bb0, bb0 + 1);
560 | new BasicBlockEdge(cfg, bb0, bb0 + 2);
561 | new BasicBlockEdge(cfg, bb0 + 1, bb0 + 3);
562 | new BasicBlockEdge(cfg, bb0 + 2, bb0 + 3);
563 | return bb0 + 3;
564 | }
565 |
566 |
567 | function buildConnect(cfg, start, end) {
568 | new BasicBlockEdge(cfg, start, end);
569 | }
570 |
571 | function buildStraight(cfg, start, n) {
572 | for (var i=0; i < n; i++) {
573 | buildConnect(cfg, start + i, start + i + 1);
574 | }
575 | return start + n;
576 | }
577 |
578 | function buildBaseLoop(cfg, From) {
579 | var header = buildStraight(cfg, From, 1);
580 | var diamond1 = buildDiamond(cfg, header);
581 | var d11 = buildStraight(cfg, diamond1, 1);
582 | var diamond2 = buildDiamond(cfg, d11);
583 | var footer = buildStraight(cfg, diamond2, 1);
584 | buildConnect(cfg, diamond2, d11);
585 | buildConnect(cfg, diamond1, header);
586 |
587 | buildConnect(cfg, footer, From);
588 | footer = buildStraight(cfg, footer, 1);
589 | return footer;
590 | }
591 |
592 | var cfg = new CFG();
593 |
594 | cfg.createNode(0); // top
595 | buildBaseLoop(cfg, 0);
596 | cfg.createNode(1); //s bottom
597 | buildConnect(cfg, 0, 2);
598 |
599 | var n = 2;
600 | for (var parlooptrees=0; parlooptrees < 10; parlooptrees++) {
601 | cfg.createNode(n + 1);
602 | buildConnect(cfg, n, n + 1);
603 | n = n + 1;
604 | for (var i=0; i < 2; ++i) {
605 | var topNode = n;
606 | n = buildStraight(cfg, n, 1);
607 | for (var j=0; j < 25; j++) {
608 | n = buildBaseLoop(cfg, n);
609 | }
610 |
611 | var bottom = buildStraight(cfg, n, 1);
612 | buildConnect(cfg, n, topNode);
613 | n = bottom;
614 | }
615 | }
616 |
617 | Benchmark.report("Havlak", function warmup() {
618 | for (var dummyloop = 0; dummyloop < 20; ++dummyloop) {
619 | var lsglocal = new LSG();
620 | var finder = new HavlakLoopFinder(cfg, lsglocal);
621 | var x = finder.findLoops();
622 | var checksum = lsglocal.checksum();
623 | if (checksum != 435630002) {
624 | throw 'Wrong checksum - expected <435630002>, but was <' + checksum + '>';
625 | }
626 | }
627 | }, function exercise() {
628 | var lsglocal = new LSG();
629 | var finder = new HavlakLoopFinder(cfg, lsglocal);
630 | var numLoops = finder.findLoops();
631 | if (numLoops != 1522) {
632 | throw 'Wrong result - expected <1522>, but was <' + numLoops + '>';
633 | }
634 | });
635 |
--------------------------------------------------------------------------------
/lib/src/Richards/dart/Richards.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 | // Redistribution and use in source and binary forms, with or without
3 | // modification, are permitted provided that the following conditions are
4 | // met:
5 | //
6 | // * Redistributions of source code must retain the above copyright
7 | // notice, this list of conditions and the following disclaimer.
8 | // * Redistributions in binary form must reproduce the above
9 | // copyright notice, this list of conditions and the following
10 | // disclaimer in the documentation and/or other materials provided
11 | // with the distribution.
12 | // * Neither the name of Google Inc. nor the names of its
13 | // contributors may be used to endorse or promote products derived
14 | // from this software without specific prior written permission.
15 | //
16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
28 | // Ported by the Dart team to Dart.
29 |
30 | // This is a Dart implementation of the Richards benchmark from:
31 | //
32 | // http://www.cl.cam.ac.uk/~mr10/Bench.html
33 | //
34 | // The benchmark was originally implemented in BCPL by
35 | // Martin Richards.
36 |
37 | import "../../common/dart/BenchmarkBase.dart";
38 |
39 | main() {
40 | new Richards().report();
41 | }
42 |
43 |
44 | /**
45 | * Richards imulates the task dispatcher of an operating system.
46 | **/
47 | class Richards extends BenchmarkBase {
48 |
49 | const Richards() : super("Richards");
50 |
51 | void run() {
52 | Scheduler scheduler = new Scheduler();
53 | scheduler.addIdleTask(ID_IDLE, 0, null, COUNT);
54 |
55 | Packet queue = new Packet(null, ID_WORKER, KIND_WORK);
56 | queue = new Packet(queue, ID_WORKER, KIND_WORK);
57 | scheduler.addWorkerTask(ID_WORKER, 1000, queue);
58 |
59 | queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE);
60 | queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
61 | queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
62 | scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue);
63 |
64 | queue = new Packet(null, ID_DEVICE_B, KIND_DEVICE);
65 | queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
66 | queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
67 | scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue);
68 |
69 | scheduler.addDeviceTask(ID_DEVICE_A, 4000, null);
70 |
71 | scheduler.addDeviceTask(ID_DEVICE_B, 5000, null);
72 |
73 | scheduler.schedule();
74 |
75 | if (scheduler.queueCount != EXPECTED_QUEUE_COUNT ||
76 | scheduler.holdCount != EXPECTED_HOLD_COUNT) {
77 | print("Error during execution: queueCount = ${scheduler.queueCount}"
78 | ", holdCount = ${scheduler.holdCount}.");
79 | }
80 | if (EXPECTED_QUEUE_COUNT != scheduler.queueCount) {
81 | throw "bad scheduler queue-count";
82 | }
83 | if (EXPECTED_HOLD_COUNT != scheduler.holdCount) {
84 | throw "bad scheduler hold-count";
85 | }
86 | }
87 |
88 | static const int DATA_SIZE = 4;
89 | static const int COUNT = 1000;
90 |
91 | /**
92 | * These two constants specify how many times a packet is queued and
93 | * how many times a task is put on hold in a correct run of richards.
94 | * They don't have any meaning a such but are characteristic of a
95 | * correct run so if the actual queue or hold count is different from
96 | * the expected there must be a bug in the implementation.
97 | **/
98 | static const int EXPECTED_QUEUE_COUNT = 2322;
99 | static const int EXPECTED_HOLD_COUNT = 928;
100 |
101 | static const int ID_IDLE = 0;
102 | static const int ID_WORKER = 1;
103 | static const int ID_HANDLER_A = 2;
104 | static const int ID_HANDLER_B = 3;
105 | static const int ID_DEVICE_A = 4;
106 | static const int ID_DEVICE_B = 5;
107 | static const int NUMBER_OF_IDS = 6;
108 |
109 | static const int KIND_DEVICE = 0;
110 | static const int KIND_WORK = 1;
111 | }
112 |
113 |
114 | /**
115 | * A scheduler can be used to schedule a set of tasks based on their relative
116 | * priorities. Scheduling is done by maintaining a list of task control blocks
117 | * which holds tasks and the data queue they are processing.
118 | */
119 | class Scheduler {
120 |
121 | int queueCount = 0;
122 | int holdCount = 0;
123 | TaskControlBlock currentTcb;
124 | int currentId;
125 | TaskControlBlock list;
126 | List blocks =
127 | new List(Richards.NUMBER_OF_IDS);
128 |
129 | /// Add an idle task to this scheduler.
130 | void addIdleTask(int id, int priority, Packet queue, int count) {
131 | addRunningTask(id, priority, queue, new IdleTask(this, 1, count));
132 | }
133 |
134 | /// Add a work task to this scheduler.
135 | void addWorkerTask(int id, int priority, Packet queue) {
136 | addTask(id,
137 | priority,
138 | queue,
139 | new WorkerTask(this, Richards.ID_HANDLER_A, 0));
140 | }
141 |
142 | /// Add a handler task to this scheduler.
143 | void addHandlerTask(int id, int priority, Packet queue) {
144 | addTask(id, priority, queue, new HandlerTask(this));
145 | }
146 |
147 | /// Add a handler task to this scheduler.
148 | void addDeviceTask(int id, int priority, Packet queue) {
149 | addTask(id, priority, queue, new DeviceTask(this));
150 | }
151 |
152 | /// Add the specified task and mark it as running.
153 | void addRunningTask(int id, int priority, Packet queue, Task task) {
154 | addTask(id, priority, queue, task);
155 | currentTcb.setRunning();
156 | }
157 |
158 | /// Add the specified task to this scheduler.
159 | void addTask(int id, int priority, Packet queue, Task task) {
160 | currentTcb = new TaskControlBlock(list, id, priority, queue, task);
161 | list = currentTcb;
162 | blocks[id] = currentTcb;
163 | }
164 |
165 | /// Execute the tasks managed by this scheduler.
166 | void schedule() {
167 | currentTcb = list;
168 | while (currentTcb != null) {
169 | if (currentTcb.isHeldOrSuspended()) {
170 | currentTcb = currentTcb.link;
171 | } else {
172 | currentId = currentTcb.id;
173 | currentTcb = currentTcb.run();
174 | }
175 | }
176 | }
177 |
178 | /// Release a task that is currently blocked and return the next block to run.
179 | TaskControlBlock release(int id) {
180 | TaskControlBlock tcb = blocks[id];
181 | if (tcb == null) return tcb;
182 | tcb.markAsNotHeld();
183 | if (tcb.priority > currentTcb.priority) return tcb;
184 | return currentTcb;
185 | }
186 |
187 | /**
188 | * Block the currently executing task and return the next task control block
189 | * to run. The blocked task will not be made runnable until it is explicitly
190 | * released, even if new work is added to it.
191 | */
192 | TaskControlBlock holdCurrent() {
193 | holdCount++;
194 | currentTcb.markAsHeld();
195 | return currentTcb.link;
196 | }
197 |
198 | /**
199 | * Suspend the currently executing task and return the next task
200 | * control block to run.
201 | * If new work is added to the suspended task it will be made runnable.
202 | */
203 | TaskControlBlock suspendCurrent() {
204 | currentTcb.markAsSuspended();
205 | return currentTcb;
206 | }
207 |
208 | /**
209 | * Add the specified packet to the end of the worklist used by the task
210 | * associated with the packet and make the task runnable if it is currently
211 | * suspended.
212 | */
213 | TaskControlBlock queue(Packet packet) {
214 | TaskControlBlock t = blocks[packet.id];
215 | if (t == null) return t;
216 | queueCount++;
217 | packet.link = null;
218 | packet.id = currentId;
219 | return t.checkPriorityAdd(currentTcb, packet);
220 | }
221 | }
222 |
223 |
224 | /**
225 | * A task control block manages a task and the queue of work packages associated
226 | * with it.
227 | */
228 | class TaskControlBlock {
229 |
230 | TaskControlBlock link;
231 | int id; // The id of this block.
232 | int priority; // The priority of this block.
233 | Packet queue; // The queue of packages to be processed by the task.
234 | Task task;
235 | int state;
236 |
237 | TaskControlBlock(this.link, this.id, this.priority, this.queue, this.task) {
238 | state = queue == null ? STATE_SUSPENDED : STATE_SUSPENDED_RUNNABLE;
239 | }
240 |
241 | /// The task is running and is currently scheduled.
242 | static const int STATE_RUNNING = 0;
243 |
244 | /// The task has packets left to process.
245 | static const int STATE_RUNNABLE = 1;
246 |
247 | /**
248 | * The task is not currently running. The task is not blocked as such and may
249 | * be started by the scheduler.
250 | */
251 | static const int STATE_SUSPENDED = 2;
252 |
253 | /// The task is blocked and cannot be run until it is explicitly released.
254 | static const int STATE_HELD = 4;
255 |
256 | static const int STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE;
257 | static const int STATE_NOT_HELD = ~STATE_HELD;
258 |
259 | void setRunning() {
260 | state = STATE_RUNNING;
261 | }
262 |
263 | void markAsNotHeld() {
264 | state = state & STATE_NOT_HELD;
265 | }
266 |
267 | void markAsHeld() {
268 | state = state | STATE_HELD;
269 | }
270 |
271 | bool isHeldOrSuspended() {
272 | return (state & STATE_HELD) != 0 ||
273 | (state == STATE_SUSPENDED);
274 | }
275 |
276 | void markAsSuspended() {
277 | state = state | STATE_SUSPENDED;
278 | }
279 |
280 | void markAsRunnable() {
281 | state = state | STATE_RUNNABLE;
282 | }
283 |
284 | /// Runs this task, if it is ready to be run, and returns the next task to run.
285 | TaskControlBlock run() {
286 | Packet packet;
287 | if (state == STATE_SUSPENDED_RUNNABLE) {
288 | packet = queue;
289 | queue = packet.link;
290 | state = queue == null ? STATE_RUNNING : STATE_RUNNABLE;
291 | } else {
292 | packet = null;
293 | }
294 | return task.run(packet);
295 | }
296 |
297 | /**
298 | * Adds a packet to the worklist of this block's task, marks this as
299 | * runnable if necessary, and returns the next runnable object to run
300 | * (the one with the highest priority).
301 | */
302 | TaskControlBlock checkPriorityAdd(TaskControlBlock task, Packet packet) {
303 | if (queue == null) {
304 | queue = packet;
305 | markAsRunnable();
306 | if (priority > task.priority) return this;
307 | } else {
308 | queue = packet.addTo(queue);
309 | }
310 | return task;
311 | }
312 |
313 | String toString() => "tcb { ${task}@${state} }";
314 | }
315 |
316 | /**
317 | * Abstract task that manipulates work packets.
318 | */
319 | abstract class Task {
320 |
321 | Scheduler scheduler; // The scheduler that manages this task.
322 |
323 | Task(this.scheduler);
324 |
325 | TaskControlBlock run(Packet packet);
326 | }
327 |
328 | /**
329 | * An idle task doesn't do any work itself but cycles control between the two
330 | * device tasks.
331 | */
332 | class IdleTask extends Task {
333 |
334 | int v1; // A seed value that controls how the device tasks are scheduled.
335 | int count; // The number of times this task should be scheduled.
336 |
337 | IdleTask(Scheduler scheduler, this.v1, this.count) : super(scheduler);
338 |
339 | TaskControlBlock run(Packet packet) {
340 | count--;
341 | if (count == 0) return scheduler.holdCurrent();
342 | if ((v1 & 1) == 0) {
343 | v1 = v1 >> 1;
344 | return scheduler.release(Richards.ID_DEVICE_A);
345 | }
346 | v1 = (v1 >> 1) ^ 0xD008;
347 | return scheduler.release(Richards.ID_DEVICE_B);
348 | }
349 |
350 | String toString() => "IdleTask";
351 | }
352 |
353 |
354 | /**
355 | * A task that suspends itself after each time it has been run to simulate
356 | * waiting for data from an external device.
357 | */
358 | class DeviceTask extends Task {
359 |
360 | Packet v1;
361 |
362 | DeviceTask(Scheduler scheduler) : super(scheduler);
363 |
364 | TaskControlBlock run(Packet packet) {
365 | if (packet == null) {
366 | if (v1 == null) return scheduler.suspendCurrent();
367 | Packet v = v1;
368 | v1 = null;
369 | return scheduler.queue(v);
370 | }
371 | v1 = packet;
372 | return scheduler.holdCurrent();
373 | }
374 |
375 | String toString() => "DeviceTask";
376 | }
377 |
378 |
379 | /**
380 | * A task that manipulates work packets.
381 | */
382 | class WorkerTask extends Task {
383 |
384 | int v1; // A seed used to specify how work packets are manipulated.
385 | int v2; // Another seed used to specify how work packets are manipulated.
386 |
387 | WorkerTask(Scheduler scheduler, this.v1, this.v2) : super(scheduler);
388 |
389 | TaskControlBlock run(Packet packet) {
390 | if (packet == null) {
391 | return scheduler.suspendCurrent();
392 | }
393 | if (v1 == Richards.ID_HANDLER_A) {
394 | v1 = Richards.ID_HANDLER_B;
395 | } else {
396 | v1 = Richards.ID_HANDLER_A;
397 | }
398 | packet.id = v1;
399 | packet.a1 = 0;
400 | for (int i = 0; i < Richards.DATA_SIZE; i++) {
401 | v2++;
402 | if (v2 > 26) v2 = 1;
403 | packet.a2[i] = v2;
404 | }
405 | return scheduler.queue(packet);
406 | }
407 |
408 | String toString() => "WorkerTask";
409 | }
410 |
411 |
412 | /**
413 | * A task that manipulates work packets and then suspends itself.
414 | */
415 | class HandlerTask extends Task {
416 |
417 | Packet v1;
418 | Packet v2;
419 |
420 | HandlerTask(Scheduler scheduler) : super(scheduler);
421 |
422 | TaskControlBlock run(Packet packet) {
423 | if (packet != null) {
424 | if (packet.kind == Richards.KIND_WORK) {
425 | v1 = packet.addTo(v1);
426 | } else {
427 | v2 = packet.addTo(v2);
428 | }
429 | }
430 | if (v1 != null) {
431 | int count = v1.a1;
432 | Packet v;
433 | if (count < Richards.DATA_SIZE) {
434 | if (v2 != null) {
435 | v = v2;
436 | v2 = v2.link;
437 | v.a1 = v1.a2[count];
438 | v1.a1 = count + 1;
439 | return scheduler.queue(v);
440 | }
441 | } else {
442 | v = v1;
443 | v1 = v1.link;
444 | return scheduler.queue(v);
445 | }
446 | }
447 | return scheduler.suspendCurrent();
448 | }
449 |
450 | String toString() => "HandlerTask";
451 | }
452 |
453 |
454 | /**
455 | * A simple package of data that is manipulated by the tasks. The exact layout
456 | * of the payload data carried by a packet is not importaint, and neither is the
457 | * nature of the work performed on packets by the tasks.
458 | * Besides carrying data, packets form linked lists and are hence used both as
459 | * data and worklists.
460 | */
461 | class Packet {
462 |
463 | Packet link; // The tail of the linked list of packets.
464 | int id; // An ID for this packet.
465 | int kind; // The type of this packet.
466 | int a1 = 0;
467 |
468 | List a2 = new List(Richards.DATA_SIZE);
469 |
470 | Packet(this.link, this.id, this.kind);
471 |
472 | /// Add this packet to the end of a worklist, and return the worklist.
473 | Packet addTo(Packet queue) {
474 | link = null;
475 | if (queue == null) return this;
476 | Packet peek, next = queue;
477 | while ((peek = next.link) != null) next = peek;
478 | next.link = this;
479 | return queue;
480 | }
481 |
482 | String toString() => "Packet";
483 | }
484 |
--------------------------------------------------------------------------------
/lib/src/Richards/dart/Richards.dart.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "file": "Richards.dart.js",
4 | "sourceRoot": "",
5 | "sources": ["Richards.dart","../../common/dart/BenchmarkBase.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/internal_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/interceptors.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_array.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/list.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_number.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_string.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_helper.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_rti.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/core_patch.dart","../../../../../../Tools/dart/stable/sdk/lib/core/stopwatch.dart","../../../../../../Tools/dart/stable/sdk/lib/collection/iterable.dart","../../../../../../Tools/dart/stable/sdk/lib/core/errors.dart","../../../../../../Tools/dart/stable/sdk/lib/core/print.dart","../../../../../../Tools/dart/stable/sdk/lib/core/bool.dart","../../../../../../Tools/dart/stable/sdk/lib/core/null.dart","../../../../../../Tools/dart/stable/sdk/lib/core/string_buffer.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/js_primitives.dart"],
6 | "names": ["main","report","run","","addTask","setRunning","printToConsole","schedule","isHeldOrSuspended","release","queue","checkPriorityAdd","toString","holdCurrent","suspendCurrent","addTo","getInterceptor","listToString","length","moveNext","toInt","truncateToDouble","+","-","~/","_tdivSlow","codeUnitAt","substring","S","objectTypeName","formatType","objectToString","dateNow","initTicker","iae","ioore","checkInt","wrapException","toStringWrapper","throwExpression","fromTearOff","cspForwardCall","forwardCallTo","selfFieldName","cspForwardInterceptedCall","forwardInterceptedCallTo","receiverFieldName","closureFromTearOff","throwCyclicInit","getRuntimeTypeInfo","runtimeTypeToString","getRuntimeTypeAsString","joinArguments","_writeString","call","floor","selfOf","receiverOf","computeFieldNamed","measureFor","_initTicker","elapsedMilliseconds","exercise","measure","warmup","iterableToFullString","_isToStringVisiting","safeToString","_objectToString","print","_errorName","_errorExplanation","value","start","isRunning","_now","elapsedTicks","writeAll","isEmpty","current","printString","_toStringVisiting"],
7 | "mappings": "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"
8 | }
9 |
--------------------------------------------------------------------------------
/lib/src/Richards/javascript/Richards.js:
--------------------------------------------------------------------------------
1 | // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 | // Redistribution and use in source and binary forms, with or without
3 | // modification, are permitted provided that the following conditions are
4 | // met:
5 | //
6 | // * Redistributions of source code must retain the above copyright
7 | // notice, this list of conditions and the following disclaimer.
8 | // * Redistributions in binary form must reproduce the above
9 | // copyright notice, this list of conditions and the following
10 | // disclaimer in the documentation and/or other materials provided
11 | // with the distribution.
12 | // * Neither the name of Google Inc. nor the names of its
13 | // contributors may be used to endorse or promote products derived
14 | // from this software without specific prior written permission.
15 | //
16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
28 |
29 | // This is a JavaScript implementation of the Richards
30 | // benchmark from:
31 | //
32 | // http://www.cl.cam.ac.uk/~mr10/Bench.html
33 | //
34 | // The benchmark was originally implemented in BCPL by
35 | // Martin Richards.
36 |
37 |
38 | /**
39 | * The Richards benchmark simulates the task dispatcher of an
40 | * operating system.
41 | **/
42 | function runRichards() {
43 | var scheduler = new Scheduler();
44 | scheduler.addIdleTask(ID_IDLE, 0, null, COUNT);
45 |
46 | var queue = new Packet(null, ID_WORKER, KIND_WORK);
47 | queue = new Packet(queue, ID_WORKER, KIND_WORK);
48 | scheduler.addWorkerTask(ID_WORKER, 1000, queue);
49 |
50 | queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE);
51 | queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
52 | queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
53 | scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue);
54 |
55 | queue = new Packet(null, ID_DEVICE_B, KIND_DEVICE);
56 | queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
57 | queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
58 | scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue);
59 |
60 | scheduler.addDeviceTask(ID_DEVICE_A, 4000, null);
61 |
62 | scheduler.addDeviceTask(ID_DEVICE_B, 5000, null);
63 |
64 | scheduler.schedule();
65 |
66 | if (scheduler.queueCount != EXPECTED_QUEUE_COUNT ||
67 | scheduler.holdCount != EXPECTED_HOLD_COUNT) {
68 | var msg =
69 | "Error during execution: queueCount = " + scheduler.queueCount +
70 | ", holdCount = " + scheduler.holdCount + ".";
71 | throw new Error(msg);
72 | }
73 | }
74 |
75 | var COUNT = 1000;
76 |
77 | /**
78 | * These two constants specify how many times a packet is queued and
79 | * how many times a task is put on hold in a correct run of richards.
80 | * They don't have any meaning a such but are characteristic of a
81 | * correct run so if the actual queue or hold count is different from
82 | * the expected there must be a bug in the implementation.
83 | **/
84 | var EXPECTED_QUEUE_COUNT = 2322;
85 | var EXPECTED_HOLD_COUNT = 928;
86 |
87 |
88 | /**
89 | * A scheduler can be used to schedule a set of tasks based on their relative
90 | * priorities. Scheduling is done by maintaining a list of task control blocks
91 | * which holds tasks and the data queue they are processing.
92 | * @constructor
93 | */
94 | function Scheduler() {
95 | this.queueCount = 0;
96 | this.holdCount = 0;
97 | this.blocks = new Array(NUMBER_OF_IDS);
98 | this.list = null;
99 | this.currentTcb = null;
100 | this.currentId = null;
101 | }
102 |
103 | var ID_IDLE = 0;
104 | var ID_WORKER = 1;
105 | var ID_HANDLER_A = 2;
106 | var ID_HANDLER_B = 3;
107 | var ID_DEVICE_A = 4;
108 | var ID_DEVICE_B = 5;
109 | var NUMBER_OF_IDS = 6;
110 |
111 | var KIND_DEVICE = 0;
112 | var KIND_WORK = 1;
113 |
114 | /**
115 | * Add an idle task to this scheduler.
116 | * @param {int} id the identity of the task
117 | * @param {int} priority the task's priority
118 | * @param {Packet} queue the queue of work to be processed by the task
119 | * @param {int} count the number of times to schedule the task
120 | */
121 | Scheduler.prototype.addIdleTask = function (id, priority, queue, count) {
122 | this.addRunningTask(id, priority, queue, new IdleTask(this, 1, count));
123 | };
124 |
125 | /**
126 | * Add a work task to this scheduler.
127 | * @param {int} id the identity of the task
128 | * @param {int} priority the task's priority
129 | * @param {Packet} queue the queue of work to be processed by the task
130 | */
131 | Scheduler.prototype.addWorkerTask = function (id, priority, queue) {
132 | this.addTask(id, priority, queue, new WorkerTask(this, ID_HANDLER_A, 0));
133 | };
134 |
135 | /**
136 | * Add a handler task to this scheduler.
137 | * @param {int} id the identity of the task
138 | * @param {int} priority the task's priority
139 | * @param {Packet} queue the queue of work to be processed by the task
140 | */
141 | Scheduler.prototype.addHandlerTask = function (id, priority, queue) {
142 | this.addTask(id, priority, queue, new HandlerTask(this));
143 | };
144 |
145 | /**
146 | * Add a handler task to this scheduler.
147 | * @param {int} id the identity of the task
148 | * @param {int} priority the task's priority
149 | * @param {Packet} queue the queue of work to be processed by the task
150 | */
151 | Scheduler.prototype.addDeviceTask = function (id, priority, queue) {
152 | this.addTask(id, priority, queue, new DeviceTask(this))
153 | };
154 |
155 | /**
156 | * Add the specified task and mark it as running.
157 | * @param {int} id the identity of the task
158 | * @param {int} priority the task's priority
159 | * @param {Packet} queue the queue of work to be processed by the task
160 | * @param {Task} task the task to add
161 | */
162 | Scheduler.prototype.addRunningTask = function (id, priority, queue, task) {
163 | this.addTask(id, priority, queue, task);
164 | this.currentTcb.setRunning();
165 | };
166 |
167 | /**
168 | * Add the specified task to this scheduler.
169 | * @param {int} id the identity of the task
170 | * @param {int} priority the task's priority
171 | * @param {Packet} queue the queue of work to be processed by the task
172 | * @param {Task} task the task to add
173 | */
174 | Scheduler.prototype.addTask = function (id, priority, queue, task) {
175 | this.currentTcb = new TaskControlBlock(this.list, id, priority, queue, task);
176 | this.list = this.currentTcb;
177 | this.blocks[id] = this.currentTcb;
178 | };
179 |
180 | /**
181 | * Execute the tasks managed by this scheduler.
182 | */
183 | Scheduler.prototype.schedule = function () {
184 | this.currentTcb = this.list;
185 | while (this.currentTcb != null) {
186 | if (this.currentTcb.isHeldOrSuspended()) {
187 | this.currentTcb = this.currentTcb.link;
188 | } else {
189 | this.currentId = this.currentTcb.id;
190 | this.currentTcb = this.currentTcb.run();
191 | }
192 | }
193 | };
194 |
195 | /**
196 | * Release a task that is currently blocked and return the next block to run.
197 | * @param {int} id the id of the task to suspend
198 | */
199 | Scheduler.prototype.release = function (id) {
200 | var tcb = this.blocks[id];
201 | if (tcb == null) return tcb;
202 | tcb.markAsNotHeld();
203 | if (tcb.priority > this.currentTcb.priority) {
204 | return tcb;
205 | } else {
206 | return this.currentTcb;
207 | }
208 | };
209 |
210 | /**
211 | * Block the currently executing task and return the next task control block
212 | * to run. The blocked task will not be made runnable until it is explicitly
213 | * released, even if new work is added to it.
214 | */
215 | Scheduler.prototype.holdCurrent = function () {
216 | this.holdCount++;
217 | this.currentTcb.markAsHeld();
218 | return this.currentTcb.link;
219 | };
220 |
221 | /**
222 | * Suspend the currently executing task and return the next task control block
223 | * to run. If new work is added to the suspended task it will be made runnable.
224 | */
225 | Scheduler.prototype.suspendCurrent = function () {
226 | this.currentTcb.markAsSuspended();
227 | return this.currentTcb;
228 | };
229 |
230 | /**
231 | * Add the specified packet to the end of the worklist used by the task
232 | * associated with the packet and make the task runnable if it is currently
233 | * suspended.
234 | * @param {Packet} packet the packet to add
235 | */
236 | Scheduler.prototype.queue = function (packet) {
237 | var t = this.blocks[packet.id];
238 | if (t == null) return t;
239 | this.queueCount++;
240 | packet.link = null;
241 | packet.id = this.currentId;
242 | return t.checkPriorityAdd(this.currentTcb, packet);
243 | };
244 |
245 | /**
246 | * A task control block manages a task and the queue of work packages associated
247 | * with it.
248 | * @param {TaskControlBlock} link the preceding block in the linked block list
249 | * @param {int} id the id of this block
250 | * @param {int} priority the priority of this block
251 | * @param {Packet} queue the queue of packages to be processed by the task
252 | * @param {Task} task the task
253 | * @constructor
254 | */
255 | function TaskControlBlock(link, id, priority, queue, task) {
256 | this.link = link;
257 | this.id = id;
258 | this.priority = priority;
259 | this.queue = queue;
260 | this.task = task;
261 | if (queue == null) {
262 | this.state = STATE_SUSPENDED;
263 | } else {
264 | this.state = STATE_SUSPENDED_RUNNABLE;
265 | }
266 | }
267 |
268 | /**
269 | * The task is running and is currently scheduled.
270 | */
271 | var STATE_RUNNING = 0;
272 |
273 | /**
274 | * The task has packets left to process.
275 | */
276 | var STATE_RUNNABLE = 1;
277 |
278 | /**
279 | * The task is not currently running. The task is not blocked as such and may
280 | * be started by the scheduler.
281 | */
282 | var STATE_SUSPENDED = 2;
283 |
284 | /**
285 | * The task is blocked and cannot be run until it is explicitly released.
286 | */
287 | var STATE_HELD = 4;
288 |
289 | var STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE;
290 | var STATE_NOT_HELD = ~STATE_HELD;
291 |
292 | TaskControlBlock.prototype.setRunning = function () {
293 | this.state = STATE_RUNNING;
294 | };
295 |
296 | TaskControlBlock.prototype.markAsNotHeld = function () {
297 | this.state = this.state & STATE_NOT_HELD;
298 | };
299 |
300 | TaskControlBlock.prototype.markAsHeld = function () {
301 | this.state = this.state | STATE_HELD;
302 | };
303 |
304 | TaskControlBlock.prototype.isHeldOrSuspended = function () {
305 | return (this.state & STATE_HELD) != 0 || (this.state == STATE_SUSPENDED);
306 | };
307 |
308 | TaskControlBlock.prototype.markAsSuspended = function () {
309 | this.state = this.state | STATE_SUSPENDED;
310 | };
311 |
312 | TaskControlBlock.prototype.markAsRunnable = function () {
313 | this.state = this.state | STATE_RUNNABLE;
314 | };
315 |
316 | /**
317 | * Runs this task, if it is ready to be run, and returns the next task to run.
318 | */
319 | TaskControlBlock.prototype.run = function () {
320 | var packet;
321 | if (this.state == STATE_SUSPENDED_RUNNABLE) {
322 | packet = this.queue;
323 | this.queue = packet.link;
324 | if (this.queue == null) {
325 | this.state = STATE_RUNNING;
326 | } else {
327 | this.state = STATE_RUNNABLE;
328 | }
329 | } else {
330 | packet = null;
331 | }
332 | return this.task.run(packet);
333 | };
334 |
335 | /**
336 | * Adds a packet to the worklist of this block's task, marks this as runnable if
337 | * necessary, and returns the next runnable object to run (the one
338 | * with the highest priority).
339 | */
340 | TaskControlBlock.prototype.checkPriorityAdd = function (task, packet) {
341 | if (this.queue == null) {
342 | this.queue = packet;
343 | this.markAsRunnable();
344 | if (this.priority > task.priority) return this;
345 | } else {
346 | this.queue = packet.addTo(this.queue);
347 | }
348 | return task;
349 | };
350 |
351 | TaskControlBlock.prototype.toString = function () {
352 | return "tcb { " + this.task + "@" + this.state + " }";
353 | };
354 |
355 | /**
356 | * An idle task doesn't do any work itself but cycles control between the two
357 | * device tasks.
358 | * @param {Scheduler} scheduler the scheduler that manages this task
359 | * @param {int} v1 a seed value that controls how the device tasks are scheduled
360 | * @param {int} count the number of times this task should be scheduled
361 | * @constructor
362 | */
363 | function IdleTask(scheduler, v1, count) {
364 | this.scheduler = scheduler;
365 | this.v1 = v1;
366 | this.count = count;
367 | }
368 |
369 | IdleTask.prototype.run = function (packet) {
370 | this.count--;
371 | if (this.count == 0) return this.scheduler.holdCurrent();
372 | if ((this.v1 & 1) == 0) {
373 | this.v1 = this.v1 >> 1;
374 | return this.scheduler.release(ID_DEVICE_A);
375 | } else {
376 | this.v1 = (this.v1 >> 1) ^ 0xD008;
377 | return this.scheduler.release(ID_DEVICE_B);
378 | }
379 | };
380 |
381 | IdleTask.prototype.toString = function () {
382 | return "IdleTask"
383 | };
384 |
385 | /**
386 | * A task that suspends itself after each time it has been run to simulate
387 | * waiting for data from an external device.
388 | * @param {Scheduler} scheduler the scheduler that manages this task
389 | * @constructor
390 | */
391 | function DeviceTask(scheduler) {
392 | this.scheduler = scheduler;
393 | this.v1 = null;
394 | }
395 |
396 | DeviceTask.prototype.run = function (packet) {
397 | if (packet == null) {
398 | if (this.v1 == null) return this.scheduler.suspendCurrent();
399 | var v = this.v1;
400 | this.v1 = null;
401 | return this.scheduler.queue(v);
402 | } else {
403 | this.v1 = packet;
404 | return this.scheduler.holdCurrent();
405 | }
406 | };
407 |
408 | DeviceTask.prototype.toString = function () {
409 | return "DeviceTask";
410 | };
411 |
412 | /**
413 | * A task that manipulates work packets.
414 | * @param {Scheduler} scheduler the scheduler that manages this task
415 | * @param {int} v1 a seed used to specify how work packets are manipulated
416 | * @param {int} v2 another seed used to specify how work packets are manipulated
417 | * @constructor
418 | */
419 | function WorkerTask(scheduler, v1, v2) {
420 | this.scheduler = scheduler;
421 | this.v1 = v1;
422 | this.v2 = v2;
423 | }
424 |
425 | WorkerTask.prototype.run = function (packet) {
426 | if (packet == null) {
427 | return this.scheduler.suspendCurrent();
428 | } else {
429 | if (this.v1 == ID_HANDLER_A) {
430 | this.v1 = ID_HANDLER_B;
431 | } else {
432 | this.v1 = ID_HANDLER_A;
433 | }
434 | packet.id = this.v1;
435 | packet.a1 = 0;
436 | for (var i = 0; i < DATA_SIZE; i++) {
437 | this.v2++;
438 | if (this.v2 > 26) this.v2 = 1;
439 | packet.a2[i] = this.v2;
440 | }
441 | return this.scheduler.queue(packet);
442 | }
443 | };
444 |
445 | WorkerTask.prototype.toString = function () {
446 | return "WorkerTask";
447 | };
448 |
449 | /**
450 | * A task that manipulates work packets and then suspends itself.
451 | * @param {Scheduler} scheduler the scheduler that manages this task
452 | * @constructor
453 | */
454 | function HandlerTask(scheduler) {
455 | this.scheduler = scheduler;
456 | this.v1 = null;
457 | this.v2 = null;
458 | }
459 |
460 | HandlerTask.prototype.run = function (packet) {
461 | if (packet != null) {
462 | if (packet.kind == KIND_WORK) {
463 | this.v1 = packet.addTo(this.v1);
464 | } else {
465 | this.v2 = packet.addTo(this.v2);
466 | }
467 | }
468 | if (this.v1 != null) {
469 | var count = this.v1.a1;
470 | var v;
471 | if (count < DATA_SIZE) {
472 | if (this.v2 != null) {
473 | v = this.v2;
474 | this.v2 = this.v2.link;
475 | v.a1 = this.v1.a2[count];
476 | this.v1.a1 = count + 1;
477 | return this.scheduler.queue(v);
478 | }
479 | } else {
480 | v = this.v1;
481 | this.v1 = this.v1.link;
482 | return this.scheduler.queue(v);
483 | }
484 | }
485 | return this.scheduler.suspendCurrent();
486 | };
487 |
488 | HandlerTask.prototype.toString = function () {
489 | return "HandlerTask";
490 | };
491 |
492 | /* --- *
493 | * P a c k e t
494 | * --- */
495 |
496 | var DATA_SIZE = 4;
497 |
498 | /**
499 | * A simple package of data that is manipulated by the tasks. The exact layout
500 | * of the payload data carried by a packet is not importaint, and neither is the
501 | * nature of the work performed on packets by the tasks.
502 | *
503 | * Besides carrying data, packets form linked lists and are hence used both as
504 | * data and worklists.
505 | * @param {Packet} link the tail of the linked list of packets
506 | * @param {int} id an ID for this packet
507 | * @param {int} kind the type of this packet
508 | * @constructor
509 | */
510 | function Packet(link, id, kind) {
511 | this.link = link;
512 | this.id = id;
513 | this.kind = kind;
514 | this.a1 = 0;
515 | this.a2 = new Array(DATA_SIZE);
516 | }
517 |
518 | /**
519 | * Add this packet to the end of a worklist, and return the worklist.
520 | * @param {Packet} queue the worklist to add this packet to
521 | */
522 | Packet.prototype.addTo = function (queue) {
523 | this.link = null;
524 | if (queue == null) return this;
525 | var peek, next = queue;
526 | while ((peek = next.link) != null)
527 | next = peek;
528 | next.link = this;
529 | return queue;
530 | };
531 |
532 | Packet.prototype.toString = function () {
533 | return "Packet";
534 | };
535 |
536 | Benchmark.report("Richards", runRichards);
537 |
--------------------------------------------------------------------------------
/lib/src/Serve/dart/Serve.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2014 the Dart project authors. All rights reserved.
2 | // Redistribution and use in source and binary forms, with or without
3 | // modification, are permitted provided that the following conditions are
4 | // met:
5 | //
6 | // * Redistributions of source code must retain the above copyright
7 | // notice, this list of conditions and the following disclaimer.
8 | // * Redistributions in binary form must reproduce the above
9 | // copyright notice, this list of conditions and the following
10 | // disclaimer in the documentation and/or other materials provided
11 | // with the distribution.
12 | // * Neither the name of Google Inc. nor the names of its
13 | // contributors may be used to endorse or promote products derived
14 | // from this software without specific prior written permission.
15 | //
16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
28 | import 'dart:io';
29 | import 'dart:convert';
30 | import 'dart:async';
31 |
32 | Future runProcess(String process, List args) {
33 | return Process.run(process, args)
34 | .then((output) {
35 | if (output.exitCode != 0) {
36 | throw 'Failed to run process $process.\n'
37 | '${output.stdout}\n'
38 | '${output.stderr}';
39 | }
40 | return output.stdout;
41 | });
42 | }
43 |
44 | Future runWrk(String wrk, int port, String path,
45 | {int duration: 5, int concurrency: 128, int threads: 2}) {
46 | return runProcess(
47 | wrk,
48 | ['-d', duration.toString(),
49 | '-c', concurrency.toString(),
50 | '-t', threads.toString(),
51 | '-H', 'Host: localhost',
52 | '-H', 'Connection: keep-alive',
53 | '-H', 'Accept: */*',
54 | '-H', 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
55 | ' (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36',
56 | 'http://localhost:$port$path']);
57 | }
58 |
59 | void printResults(String output) {
60 | // Example output:
61 | //
62 | // Running 1s test @ http://localhost:43969/ping
63 | // 2 threads and 128 connections
64 | // Thread Stats Avg Stdev Max +/- Stdev
65 | // Latency 9.60ms 2.02ms 17.13ms 89.42%
66 | // Req/Sec 4.67k 2.19k 7.31k 60.71%
67 | // 8368 requests in 999.38ms, 0.92MB read
68 | // Requests/sec: 8373.21
69 | // Transfer/sec: 0.92MB
70 | //
71 | // We then look for these two lines, and find both req/sec and avg/max
72 | // latency.
73 | if (output.contains("Non-2xx")) throw "Bad request path";
74 | var lines = output.split('\n');
75 | for (var line in lines) {
76 | const REQ_SEC_STR = 'Requests/sec:';
77 | if (line.startsWith(REQ_SEC_STR)) {
78 | print(line.substring(REQ_SEC_STR.length).trim());
79 | break;
80 | }
81 | }
82 | for (var line in lines) {
83 | const LAT_STR = ' Latency';
84 | if (line.startsWith(LAT_STR)) {
85 | var latency = line.substring(LAT_STR.length).trim();
86 | var latencies = latency.split(' ')
87 | .where((s) => !s.trim().isEmpty)
88 | .toList();
89 | print(latencies[0].substring(0, latencies[0].length - 2));
90 | print(latencies[2].substring(0, latencies[2].length - 2));
91 | }
92 | }
93 | }
94 |
95 | void main(args) {
96 | const int WARMUP_TIME = 1;
97 | const int BENCHMARK_TIME = 5;
98 |
99 | String wrk = args[0];
100 | String path = args[1];
101 | Process.start(Platform.executable,
102 | [Platform.script.resolve('server.dart').toFilePath()])
103 | .then((process) {
104 | process.stdout
105 | .transform(UTF8.decoder)
106 | .transform(const LineSplitter())
107 | .first.then((line) {
108 | // First line is the port.
109 | int port = int.parse(line);
110 | runWrk(wrk, port, path, duration: WARMUP_TIME).then((_) {
111 | runWrk(wrk, port, path, duration: BENCHMARK_TIME)
112 | .then((output) {
113 | printResults(output);
114 | process.kill();
115 | });
116 | });
117 | });
118 | });
119 | }
120 |
--------------------------------------------------------------------------------
/lib/src/Serve/dart/file.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dart-archive/ton80/00eb896d96e9fa250a54a6e99d34c02efa3e5861/lib/src/Serve/dart/file.dat
--------------------------------------------------------------------------------
/lib/src/Serve/dart/server.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2014 the Dart project authors. All rights reserved.
2 | // Redistribution and use in source and binary forms, with or without
3 | // modification, are permitted provided that the following conditions are
4 | // met:
5 | //
6 | // * Redistributions of source code must retain the above copyright
7 | // notice, this list of conditions and the following disclaimer.
8 | // * Redistributions in binary form must reproduce the above
9 | // copyright notice, this list of conditions and the following
10 | // disclaimer in the documentation and/or other materials provided
11 | // with the distribution.
12 | // * Neither the name of Google Inc. nor the names of its
13 | // contributors may be used to endorse or promote products derived
14 | // from this software without specific prior written permission.
15 | //
16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
28 | import 'dart:io';
29 | import 'dart:convert';
30 | import 'dart:async';
31 |
32 | final List