├── .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 resources = [ 33 | { 34 | "id": 0, 35 | "name": "bacon", 36 | "content": "The quick brown fox jumps over the lazy dog" 37 | }, 38 | { 39 | "id": 1, 40 | "name": "pony", 41 | "content": "\u0011qÌì7zçÖ¡da¥@qc+RÞ9ªê»õ÷¬tÖ×è\"ÿ\u0004µx±~\u0003Ñë" 42 | }, 43 | { 44 | "id": 2, 45 | "name": "mountain", 46 | "content": null 47 | }, 48 | { 49 | "id": 3, 50 | "name": "locomotive", 51 | "content": "" 52 | }, 53 | { 54 | "id": 4, 55 | "name": "grass", 56 | "content": "{ \"version\": 2.1 }" 57 | } 58 | ]; 59 | 60 | class Serve { 61 | static Future start() { 62 | return HttpServer.bind('localhost', 0).then((server) { 63 | return new Serve._(server); 64 | }); 65 | } 66 | 67 | static const _HANDLERS = const { 68 | '/hello' : _hello, 69 | '/file' : _file, 70 | '/json' : _json, 71 | }; 72 | 73 | final HttpServer _server; 74 | 75 | Serve._(this._server) { 76 | _server.listen((request) { 77 | final path = request.uri.path; 78 | 79 | // Select handler by path. 80 | Function handler = _HANDLERS[path]; 81 | 82 | if (handler == null) handler = _error; 83 | handler(request); 84 | }); 85 | } 86 | 87 | static void _hello(HttpRequest request) { 88 | request.response 89 | ..headers.contentType = new ContentType('text', 'plain') 90 | ..write('world') 91 | ..close(); 92 | } 93 | 94 | static void _file(HttpRequest request) { 95 | var file = new File(Platform.script.resolve('file.dat').toFilePath()); 96 | request.response.headers.contentType = 97 | new ContentType('application', 'octet-stream'); 98 | file.openRead().pipe(request.response); 99 | } 100 | 101 | static void _json(HttpRequest request) { 102 | request.response 103 | ..headers.contentType = 104 | new ContentType('text', 'plain', charset: 'utf-8') 105 | ..write(JSON.encode(resources)) 106 | ..close(); 107 | } 108 | 109 | static void _error(HttpRequest request, 110 | [int statusCode = HttpStatus.NOT_FOUND]) { 111 | request.response 112 | ..statusCode = statusCode 113 | ..close(); 114 | } 115 | 116 | int get port => _server.port; 117 | } 118 | 119 | 120 | void main() { 121 | Serve.start().then((Serve serve) { 122 | print(serve.port); 123 | }); 124 | } 125 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/Tracer.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | 8 | import '../../common/dart/BenchmarkBase.dart'; 9 | 10 | import 'default/renderscene.dart' as default_raytrace; 11 | import 'simd/renderscene.dart' as simd_raytrace; 12 | 13 | const bool useSIMD = const bool.fromEnvironment( 14 | 'dart.isVM', 15 | defaultValue: !identical(1, 1.0)); 16 | 17 | class TracerBenchmark extends BenchmarkBase { 18 | const TracerBenchmark() : super("Tracer"); 19 | 20 | void warmup() { 21 | if (useSIMD) { 22 | simd_raytrace.renderScene(null); 23 | } else { 24 | default_raytrace.renderScene(null); 25 | } 26 | } 27 | 28 | void exercise() { 29 | if (useSIMD) { 30 | simd_raytrace.renderScene(null); 31 | } else { 32 | default_raytrace.renderScene(null); 33 | } 34 | } 35 | } 36 | 37 | void main() { 38 | new TracerBenchmark().report(); 39 | } 40 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/Tracer.dart.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "Tracer.dart.js", 4 | "sourceRoot": "", 5 | "sources": ["Tracer.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/math/math.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","default/renderscene.dart","default/engine.dart","default/color.dart","default/scene.dart","default/vector.dart","default/materials.dart","default/shapes.dart","../../../../../../Tools/dart/stable/sdk/lib/_internal/compiler/js_lib/math_patch.dart"], 6 | "names": ["main","report","printToConsole","warmup","exercise","getInterceptor","makeDispatchRecord","getNativeInterceptor","==","toString","listToString","iterator","","length","current","moveNext","toInt","truncateToDouble","+","-","*","%","~/","_tdivSlow","_shrOtherPositive","codeUnitAt","substring","checkInt","isJsIndexable","S","objectHashCode","objectTypeName","formatType","objectToString","dateNow","initTicker","iae","ioore","checkNum","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","call","floor","selfOf","receiverOf","computeFieldNamed","measureFor","_initTicker","elapsedMilliseconds","measure","elementAt","iterableToFullString","_isToStringVisiting","safeToString","_objectToString","_errorName","_errorExplanation","value","start","isRunning","_now","elapsedTicks","writeAll","isEmpty","max","isNegative","printString","renderScene","limit","getRay","multiplyScalar","negateY","magnitude","normalize","brightness","setPixel","getPixelColor","testIntersection","rayTrace","dot","getReflectionRay","blend","addScalar","wrapUp","getColor","intersect","sqrt","cross","_toStringVisiting"], 7 | "mappings": "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" 8 | } 9 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/default/color.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace; 8 | 9 | class Color { 10 | final double red; 11 | final double green; 12 | final double blue; 13 | 14 | const Color(this.red, this.green, this.blue); 15 | 16 | Color limit() { 17 | var r = (red > 0.0) ? ((red > 1.0) ? 1.0 : red) : 0.0; 18 | var g = (green > 0.0) ? ((green > 1.0) ? 1.0 : green) : 0.0; 19 | var b = (blue > 0.0) ? ((blue > 1.0) ? 1.0 : blue) : 0.0; 20 | return new Color(r, g, b); 21 | } 22 | 23 | Color operator +(Color c2) { 24 | return new Color(red + c2.red, green + c2.green, blue + c2.blue); 25 | } 26 | 27 | Color addScalar(double s){ 28 | var result = new Color(red + s, green + s, blue + s); 29 | result.limit(); 30 | return result; 31 | } 32 | 33 | Color operator *(Color c2) { 34 | var result = new Color(red * c2.red, green * c2.green, blue * c2.blue); 35 | return result; 36 | } 37 | 38 | Color multiplyScalar(double f) { 39 | var result = new Color(red * f, green * f, blue * f); 40 | return result; 41 | } 42 | 43 | Color blend(Color c2, double w) { 44 | var result = multiplyScalar(1.0 - w) + c2.multiplyScalar(w); 45 | return result; 46 | } 47 | 48 | int brightness() { 49 | var r = (red * 255).toInt(); 50 | var g = (green * 255).toInt(); 51 | var b = (blue * 255).toInt(); 52 | return (r * 77 + g * 150 + b * 29) >> 8; 53 | } 54 | 55 | String toString() { 56 | var r = (red * 255).toInt(); 57 | var g = (green * 255).toInt(); 58 | var b = (blue * 255).toInt(); 59 | 60 | return 'rgb($r,$g,$b)'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/default/engine.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace; 8 | 9 | // Variable used to hold a number that can be used to verify that 10 | // the scene was ray traced correctly. 11 | var checkNumber; 12 | 13 | class IntersectionInfo { 14 | bool isHit = false; 15 | int hitCount = 0; 16 | var shape, position, normal, color, distance; 17 | 18 | IntersectionInfo() { 19 | color = const Color(0.0, 0.0, 0.0); 20 | } 21 | 22 | String toString() => 'Intersection [$position]'; 23 | } 24 | 25 | 26 | class Engine { 27 | int canvasWidth; 28 | int canvasHeight; 29 | int pixelWidth, pixelHeight; 30 | bool renderDiffuse, renderShadows, renderHighlights, renderReflections; 31 | int rayDepth; 32 | var canvas; 33 | 34 | Engine({this.canvasWidth : 100, this.canvasHeight : 100, 35 | this.pixelWidth : 2, this.pixelHeight : 2, 36 | this.renderDiffuse : false, this.renderShadows : false, 37 | this.renderHighlights : false, this.renderReflections : false, 38 | this.rayDepth : 2}) { 39 | canvasHeight = canvasHeight ~/ pixelHeight; 40 | canvasWidth = canvasWidth ~/ pixelWidth; 41 | } 42 | 43 | void setPixel(int x, int y, Color color){ 44 | var pxW, pxH; 45 | pxW = pixelWidth; 46 | pxH = pixelHeight; 47 | 48 | if (canvas != null) { 49 | canvas.fillStyle = color.toString(); 50 | canvas.fillRect(x * pxW, y * pxH, pxW, pxH); 51 | } else { 52 | checkNumber += color.brightness(); 53 | } 54 | } 55 | 56 | // 'canvas' can be null if raytracer runs as benchmark 57 | void renderScene(Scene scene, canvas) { 58 | checkNumber = 0; 59 | /* Get canvas */ 60 | this.canvas = (canvas == null) ? null : canvas.getContext("2d"); 61 | 62 | var canvasHeight = this.canvasHeight; 63 | var canvasWidth = this.canvasWidth; 64 | 65 | for(var y = 0; y < canvasHeight; y++){ 66 | for(var x = 0; x < canvasWidth; x++){ 67 | var yp = y / canvasHeight * 2 - 1; 68 | var xp = x / canvasWidth * 2 - 1; 69 | 70 | var ray = scene.camera.getRay(xp, yp); 71 | setPixel(x, y, getPixelColor(ray, scene)); 72 | } 73 | } 74 | if ((canvas == null) && (checkNumber != 55545)) { 75 | // Used for benchmarking. 76 | throw "Scene rendered incorrectly"; 77 | } 78 | } 79 | 80 | Color getPixelColor(Ray ray, Scene scene){ 81 | var info = testIntersection(ray, scene, null); 82 | if(info.isHit){ 83 | var color = rayTrace(info, ray, scene, 0); 84 | return color; 85 | } 86 | return scene.background.color; 87 | } 88 | 89 | IntersectionInfo testIntersection(Ray ray, Scene scene, BaseShape exclude) { 90 | int hits = 0; 91 | IntersectionInfo best = new IntersectionInfo(); 92 | best.distance = 2000.0; 93 | 94 | for(var i=0; i < scene.shapes.length; i++){ 95 | var shape = scene.shapes[i]; 96 | 97 | if(shape != exclude){ 98 | IntersectionInfo info = shape.intersect(ray); 99 | if (info.isHit && 100 | (info.distance >= 0) && 101 | (info.distance < best.distance)){ 102 | best = info; 103 | hits++; 104 | } 105 | } 106 | } 107 | best.hitCount = hits; 108 | return best; 109 | } 110 | 111 | Ray getReflectionRay(Vector P, Vector N, Vector V){ 112 | var c1 = -N.dot(V); 113 | var R1 = N.multiplyScalar(2*c1) + V; 114 | return new Ray(P, R1); 115 | } 116 | 117 | Color rayTrace(IntersectionInfo info, Ray ray, Scene scene, int depth) { 118 | // Calc ambient 119 | Color color = info.color.multiplyScalar(scene.background.ambience); 120 | var oldColor = color; 121 | var shininess = pow(10.0, info.shape.material.gloss + 1.0); 122 | 123 | for(var i = 0; i < scene.lights.length; i++) { 124 | var light = scene.lights[i]; 125 | 126 | // Calc diffuse lighting 127 | var v = (light.position - info.position).normalize(); 128 | 129 | if (renderDiffuse) { 130 | var L = v.dot(info.normal); 131 | if (L > 0.0) { 132 | color = color + info.color * light.color.multiplyScalar(L); 133 | } 134 | } 135 | 136 | // The greater the depth the more accurate the colours, but 137 | // this is exponentially (!) expensive 138 | if (depth <= rayDepth) { 139 | // calculate reflection ray 140 | if (renderReflections && info.shape.material.reflection > 0.0) { 141 | var reflectionRay = getReflectionRay(info.position, 142 | info.normal, 143 | ray.direction); 144 | var refl = testIntersection(reflectionRay, scene, info.shape); 145 | 146 | if (refl.isHit && refl.distance > 0.0){ 147 | refl.color = rayTrace(refl, reflectionRay, scene, depth + 1); 148 | } else { 149 | refl.color = scene.background.color; 150 | } 151 | 152 | color = color.blend(refl.color, info.shape.material.reflection); 153 | } 154 | // Refraction 155 | /* TODO */ 156 | } 157 | /* Render shadows and highlights */ 158 | 159 | IntersectionInfo shadowInfo = new IntersectionInfo(); 160 | 161 | if (renderShadows) { 162 | var shadowRay = new Ray(info.position, v); 163 | 164 | shadowInfo = testIntersection(shadowRay, scene, info.shape); 165 | if (shadowInfo.isHit && 166 | shadowInfo.shape != info.shape 167 | /*&& shadowInfo.shape.type != 'PLANE'*/) { 168 | var vA = color.multiplyScalar(0.5); 169 | var dB = (0.5 * pow(shadowInfo.shape.material.transparency, 0.5)); 170 | color = vA.addScalar(dB); 171 | } 172 | } 173 | // Phong specular highlights 174 | if (renderHighlights && 175 | !shadowInfo.isHit && 176 | (info.shape.material.gloss > 0.0)) { 177 | var Lv = (info.shape.position - light.position).normalize(); 178 | 179 | var E = (scene.camera.position - info.shape.position).normalize(); 180 | 181 | var H = (E - Lv).normalize(); 182 | 183 | var glossWeight = pow(max(info.normal.dot(H), 0.0), shininess); 184 | color = light.color.multiplyScalar(glossWeight) + color; 185 | } 186 | } 187 | return color.limit(); 188 | } 189 | 190 | String toString() { 191 | return 'Engine [canvasWidth: $canvasWidth, canvasHeight: $canvasHeight]'; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/default/materials.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace; 8 | 9 | abstract class Materials { 10 | final double gloss; // [0...infinity] 0 = matt 11 | final double transparency; // 0=opaque 12 | final double reflection; // [0...infinity] 0 = no reflection 13 | final double refraction; 14 | final bool hasTexture; 15 | 16 | const Materials(this.reflection, 17 | this.transparency, 18 | this.gloss, 19 | this.refraction, 20 | this.hasTexture); 21 | 22 | Color getColor(num u, num v); 23 | 24 | wrapUp(t) { 25 | t = t % 2.0; 26 | if(t < -1) t += 2.0; 27 | if(t >= 1) t -= 2.0; 28 | return t; 29 | } 30 | } 31 | 32 | 33 | class Chessboard extends Materials { 34 | final Color colorEven, colorOdd; 35 | final double density; 36 | 37 | const Chessboard(this.colorEven, 38 | this.colorOdd, 39 | reflection, 40 | transparency, 41 | gloss, 42 | this.density) 43 | : super(reflection, transparency, gloss, 0.5, true); 44 | 45 | Color getColor(num u, num v) { 46 | var t = wrapUp(u * density) * wrapUp(v * density); 47 | 48 | if (t < 0.0) { 49 | return colorEven; 50 | } else { 51 | return colorOdd; 52 | } 53 | } 54 | } 55 | 56 | 57 | class Solid extends Materials { 58 | final Color color; 59 | 60 | const Solid(this.color, reflection, refraction, transparency, gloss) 61 | : super(reflection, transparency, gloss, refraction, false); 62 | 63 | Color getColor(num u, num v) { 64 | return color; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/default/renderscene.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | 8 | library ray_trace; 9 | 10 | import 'dart:math'; 11 | 12 | part 'color.dart'; 13 | part 'engine.dart'; 14 | part 'materials.dart'; 15 | part 'scene.dart'; 16 | part 'shapes.dart'; 17 | part 'vector.dart'; 18 | 19 | // Dummy HTML definition. 20 | 21 | query(a) {} 22 | 23 | class Light { 24 | final position; 25 | final color; 26 | final intensity; 27 | 28 | const Light(this.position, this.color, [this.intensity = 10.0]); 29 | } 30 | 31 | 32 | // 'event' null means that we are benchmarking 33 | void renderScene(event) { 34 | var scene = new Scene(); 35 | scene.camera = new Camera(const Vector(0.0, 0.0, -15.0), 36 | const Vector(-0.2, 0.0, 5.0), 37 | const Vector(0.0, 1.0, 0.0)); 38 | scene.background = const Background(const Color(0.5, 0.5, 0.5), 0.4); 39 | 40 | var sphere = const Sphere( 41 | const Vector(-1.5, 1.5, 2.0), 42 | 1.5, 43 | const Solid( 44 | const Color(0.0, 0.5, 0.5), 45 | 0.3, 46 | 0.0, 47 | 0.0, 48 | 2.0 49 | ) 50 | ); 51 | 52 | var sphere1 = const Sphere( 53 | const Vector(1.0, 0.25, 1.0), 54 | 0.5, 55 | const Solid( 56 | const Color(0.9,0.9,0.9), 57 | 0.1, 58 | 0.0, 59 | 0.0, 60 | 1.5 61 | ) 62 | ); 63 | 64 | var plane = new Plane( 65 | new Vector(0.1, 0.9, -0.5).normalize(), 66 | 1.2, 67 | const Chessboard( 68 | const Color(1.0, 1.0, 1.0), 69 | const Color(0.0, 0.0, 0.0), 70 | 0.2, 71 | 0.0, 72 | 1.0, 73 | 0.7 74 | ) 75 | ); 76 | 77 | scene.shapes.add(plane); 78 | scene.shapes.add(sphere); 79 | scene.shapes.add(sphere1); 80 | 81 | var light = const Light( 82 | const Vector(5.0, 10.0, -1.0), 83 | const Color(0.8, 0.8, 0.8) 84 | ); 85 | 86 | var light1 = const Light( 87 | const Vector(-3.0, 5.0, -15.0), 88 | const Color(0.8, 0.8, 0.8), 89 | 100.0 90 | ); 91 | 92 | scene.lights.add(light); 93 | scene.lights.add(light1); 94 | 95 | int imageWidth, imageHeight, pixelSize; 96 | bool renderDiffuse, renderShadows, renderHighlights, renderReflections; 97 | var canvas; 98 | if (event == null) { 99 | imageWidth = 100; 100 | imageHeight = 100; 101 | pixelSize = 5; 102 | renderDiffuse = true; 103 | renderShadows = true; 104 | renderHighlights = true; 105 | renderReflections = true; 106 | canvas = null; 107 | } else { 108 | imageWidth = int.parse(query('#imageWidth').value); 109 | imageHeight = int.parse(query('#imageHeight').value); 110 | pixelSize = int.parse(query('#pixelSize').value.split(',')[0]); 111 | renderDiffuse = query('#renderDiffuse').checked; 112 | renderShadows = query('#renderShadows').checked; 113 | renderHighlights = query('#renderHighlights').checked; 114 | renderReflections = query('#renderReflections').checked; 115 | canvas = query("#canvas"); 116 | } 117 | int rayDepth = 2; 118 | 119 | var raytracer = new Engine(canvasWidth:imageWidth, 120 | canvasHeight:imageHeight, 121 | pixelWidth: pixelSize, 122 | pixelHeight: pixelSize, 123 | renderDiffuse: renderDiffuse, 124 | renderShadows: renderShadows, 125 | renderHighlights: renderHighlights, 126 | renderReflections: renderReflections, 127 | rayDepth: rayDepth 128 | ); 129 | 130 | raytracer.renderScene(scene, canvas); 131 | } 132 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/default/scene.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace; 8 | 9 | class Ray { 10 | final position; 11 | final direction; 12 | 13 | Ray(this.position, this.direction); 14 | String toString() { 15 | return 'Ray [$position, $direction]'; 16 | } 17 | } 18 | 19 | 20 | class Camera { 21 | final position; 22 | final lookAt; 23 | final up; 24 | var equator, screen; 25 | 26 | Camera(this.position, this.lookAt, this.up) { 27 | equator = lookAt.normalize().cross(up); 28 | screen = position + lookAt; 29 | } 30 | 31 | Ray getRay(double vx, double vy) { 32 | var pos = screen - (equator.multiplyScalar(vx) - up.multiplyScalar(vy)); 33 | pos = pos.negateY(); 34 | var dir = pos - position; 35 | var ray = new Ray(pos, dir.normalize()); 36 | return ray; 37 | } 38 | 39 | toString() { 40 | return 'Camera []'; 41 | } 42 | } 43 | 44 | 45 | class Background { 46 | final Color color; 47 | final double ambience; 48 | 49 | const Background(this.color, this.ambience); 50 | } 51 | 52 | 53 | class Scene { 54 | var camera; 55 | var shapes; 56 | var lights; 57 | var background; 58 | Scene() { 59 | camera = new Camera(const Vector(0.0, 0.0, -0.5), 60 | const Vector(0.0, 0.0, 1.0), 61 | const Vector(0.0, 1.0, 0.0)); 62 | shapes = new List(); 63 | lights = new List(); 64 | background = const Background(const Color(0.0, 0.0, 0.5), 0.2); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/default/shapes.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace; 8 | 9 | class BaseShape { 10 | final position; 11 | final material; 12 | 13 | const BaseShape(this.position, this.material); 14 | 15 | String toString() { 16 | return 'BaseShape'; 17 | } 18 | } 19 | 20 | 21 | class Plane extends BaseShape { 22 | final d; 23 | 24 | Plane(pos, this.d, material) : super(pos, material); 25 | 26 | IntersectionInfo intersect(Ray ray) { 27 | var info = new IntersectionInfo(); 28 | 29 | var Vd = position.dot(ray.direction); 30 | if (Vd == 0) return info; // no intersection 31 | 32 | var t = -(position.dot(ray.position) + d) / Vd; 33 | if (t <= 0) return info; 34 | 35 | info.shape = this; 36 | info.isHit = true; 37 | info.position = ray.position + ray.direction.multiplyScalar(t); 38 | info.normal = position; 39 | info.distance = t; 40 | 41 | if(material.hasTexture){ 42 | var vU = new Vector(position.y, position.z, -position.x); 43 | var vV = vU.cross(position); 44 | var u = info.position.dot(vU); 45 | var v = info.position.dot(vV); 46 | info.color = material.getColor(u,v); 47 | } else { 48 | info.color = material.getColor(0,0); 49 | } 50 | 51 | return info; 52 | } 53 | 54 | String toString() { 55 | return 'Plane [$position, d=$d]'; 56 | } 57 | } 58 | 59 | 60 | class Sphere extends BaseShape { 61 | final double radius; 62 | const Sphere(pos, this.radius, material) : super(pos, material); 63 | 64 | IntersectionInfo intersect(Ray ray){ 65 | var info = new IntersectionInfo(); 66 | info.shape = this; 67 | 68 | var dst = ray.position - position; 69 | 70 | var B = dst.dot(ray.direction); 71 | var C = dst.dot(dst) - (radius * radius); 72 | var D = (B * B) - C; 73 | 74 | if (D > 0) { // intersection! 75 | info.isHit = true; 76 | info.distance = (-B) - sqrt(D); 77 | info.position = ray.position + 78 | ray.direction.multiplyScalar(info.distance); 79 | info.normal = (info.position - position).normalize(); 80 | 81 | info.color = material.getColor(0,0); 82 | } else { 83 | info.isHit = false; 84 | } 85 | return info; 86 | } 87 | 88 | String toString() { 89 | return 'Sphere [position=$position, radius=$radius]'; 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/default/vector.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace; 8 | 9 | class Vector { 10 | final double x, y, z; 11 | const Vector(this.x, this.y, this.z); 12 | 13 | Vector normalize() { 14 | var m = magnitude(); 15 | return new Vector(x / m, y / m, z / m); 16 | } 17 | 18 | Vector negateY() { 19 | return new Vector(x, -y, z); 20 | } 21 | 22 | double magnitude() { 23 | return sqrt((x * x) + (y * y) + (z * z)); 24 | } 25 | 26 | Vector cross(Vector w) { 27 | return new Vector(-z * w.y + y * w.z, 28 | z * w.x - x * w.z, 29 | -y * w.x + x * w.y); 30 | } 31 | 32 | double dot(Vector w) { 33 | return x * w.x + y * w.y + z * w.z; 34 | } 35 | 36 | Vector operator +(Vector w) { 37 | return new Vector(w.x + x, w.y + y, w.z + z); 38 | } 39 | 40 | Vector operator -(Vector w) { 41 | return new Vector(x - w.x, y - w.y, z - w.z); 42 | } 43 | 44 | Vector operator *(Vector w) { 45 | return new Vector(x * w.x, y * w.y, z * w.z); 46 | } 47 | 48 | Vector multiplyScalar(double w) { 49 | return new Vector(x * w, y * w, z * w); 50 | } 51 | 52 | String toString() { 53 | return 'Vector [$x, $y ,$z ]'; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/simd/color.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace_simd; 8 | 9 | class Color { 10 | final double red; 11 | final double green; 12 | final double blue; 13 | 14 | const Color(this.red, this.green, this.blue); 15 | 16 | Color limit() { 17 | var r = (red > 0.0) ? ((red > 1.0) ? 1.0 : red) : 0.0; 18 | var g = (green > 0.0) ? ((green > 1.0) ? 1.0 : green) : 0.0; 19 | var b = (blue > 0.0) ? ((blue > 1.0) ? 1.0 : blue) : 0.0; 20 | return new Color(r, g, b); 21 | } 22 | 23 | Color operator +(Color c2) { 24 | return new Color(red + c2.red, green + c2.green, blue + c2.blue); 25 | } 26 | 27 | Color addScalar(double s){ 28 | var result = new Color(red + s, green + s, blue + s); 29 | result.limit(); 30 | return result; 31 | } 32 | 33 | Color operator *(Color c2) { 34 | var result = new Color(red * c2.red, green * c2.green, blue * c2.blue); 35 | return result; 36 | } 37 | 38 | Color multiplyScalar(double f) { 39 | var result = new Color(red * f, green * f, blue * f); 40 | return result; 41 | } 42 | 43 | Color blend(Color c2, double w) { 44 | var result = multiplyScalar(1.0 - w) + c2.multiplyScalar(w); 45 | return result; 46 | } 47 | 48 | int brightness() { 49 | var r = (red * 255).toInt(); 50 | var g = (green * 255).toInt(); 51 | var b = (blue * 255).toInt(); 52 | return (r * 77 + g * 150 + b * 29) >> 8; 53 | } 54 | 55 | String toString() { 56 | var r = (red * 255).toInt(); 57 | var g = (green * 255).toInt(); 58 | var b = (blue * 255).toInt(); 59 | 60 | return 'rgb($r,$g,$b)'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/simd/engine.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace_simd; 8 | 9 | // Variable used to hold a number that can be used to verify that 10 | // the scene was ray traced correctly. 11 | var checkNumber; 12 | 13 | class IntersectionInfo { 14 | bool isHit = false; 15 | int hitCount = 0; 16 | var shape, position, normal, color, distance; 17 | 18 | IntersectionInfo() { 19 | color = const Color(0.0, 0.0, 0.0); 20 | } 21 | 22 | String toString() => 'Intersection [$position]'; 23 | } 24 | 25 | 26 | class Engine { 27 | int canvasWidth; 28 | int canvasHeight; 29 | int pixelWidth, pixelHeight; 30 | bool renderDiffuse, renderShadows, renderHighlights, renderReflections; 31 | int rayDepth; 32 | var canvas; 33 | 34 | Engine({this.canvasWidth : 100, this.canvasHeight : 100, 35 | this.pixelWidth : 2, this.pixelHeight : 2, 36 | this.renderDiffuse : false, this.renderShadows : false, 37 | this.renderHighlights : false, this.renderReflections : false, 38 | this.rayDepth : 2}) { 39 | canvasHeight = canvasHeight ~/ pixelHeight; 40 | canvasWidth = canvasWidth ~/ pixelWidth; 41 | } 42 | 43 | void setPixel(int x, int y, Color color){ 44 | var pxW, pxH; 45 | pxW = pixelWidth; 46 | pxH = pixelHeight; 47 | 48 | if (canvas != null) { 49 | canvas.fillStyle = color.toString(); 50 | canvas.fillRect(x * pxW, y * pxH, pxW, pxH); 51 | } else { 52 | checkNumber += color.brightness(); 53 | } 54 | } 55 | 56 | // 'canvas' can be null if raytracer runs as benchmark 57 | void renderScene(Scene scene, canvas) { 58 | checkNumber = 0; 59 | /* Get canvas */ 60 | this.canvas = (canvas == null) ? null : canvas.getContext("2d"); 61 | 62 | var canvasHeight = this.canvasHeight; 63 | var canvasWidth = this.canvasWidth; 64 | 65 | for(var y = 0; y < canvasHeight; y++){ 66 | for(var x = 0; x < canvasWidth; x++){ 67 | var yp = y / canvasHeight * 2 - 1; 68 | var xp = x / canvasWidth * 2 - 1; 69 | 70 | var ray = scene.camera.getRay(xp, yp); 71 | setPixel(x, y, getPixelColor(ray, scene)); 72 | } 73 | } 74 | if ((canvas == null) && (checkNumber != 55545)) { 75 | // Used for benchmarking. 76 | throw "Scene rendered incorrectly"; 77 | } 78 | } 79 | 80 | Color getPixelColor(Ray ray, Scene scene){ 81 | var info = testIntersection(ray, scene, null); 82 | if(info.isHit){ 83 | var color = rayTrace(info, ray, scene, 0); 84 | return color; 85 | } 86 | return scene.background.color; 87 | } 88 | 89 | IntersectionInfo testIntersection(Ray ray, Scene scene, BaseShape exclude) { 90 | int hits = 0; 91 | IntersectionInfo best = new IntersectionInfo(); 92 | best.distance = 2000.0; 93 | 94 | for(var i=0; i < scene.shapes.length; i++){ 95 | var shape = scene.shapes[i]; 96 | 97 | if(shape != exclude){ 98 | IntersectionInfo info = shape.intersect(ray); 99 | if (info.isHit && 100 | (info.distance >= 0) && 101 | (info.distance < best.distance)){ 102 | best = info; 103 | hits++; 104 | } 105 | } 106 | } 107 | best.hitCount = hits; 108 | return best; 109 | } 110 | 111 | Ray getReflectionRay(Vector P, Vector N, Vector V){ 112 | var c1 = -N.dot(V); 113 | var R1 = N.multiplyScalar(2*c1) + V; 114 | return new Ray(P, R1); 115 | } 116 | 117 | Color rayTrace(IntersectionInfo info, Ray ray, Scene scene, int depth) { 118 | // Calc ambient 119 | Color color = info.color.multiplyScalar(scene.background.ambience); 120 | var oldColor = color; 121 | var shininess = pow(10.0, info.shape.material.gloss + 1.0); 122 | 123 | for(var i = 0; i < scene.lights.length; i++) { 124 | var light = scene.lights[i]; 125 | 126 | // Calc diffuse lighting 127 | var v = (light.position - info.position).normalize(); 128 | 129 | if (renderDiffuse) { 130 | var L = v.dot(info.normal); 131 | if (L > 0.0) { 132 | color = color + info.color * light.color.multiplyScalar(L); 133 | } 134 | } 135 | 136 | // The greater the depth the more accurate the colours, but 137 | // this is exponentially (!) expensive 138 | if (depth <= rayDepth) { 139 | // calculate reflection ray 140 | if (renderReflections && info.shape.material.reflection > 0.0) { 141 | var reflectionRay = getReflectionRay(info.position, 142 | info.normal, 143 | ray.direction); 144 | var refl = testIntersection(reflectionRay, scene, info.shape); 145 | 146 | if (refl.isHit && refl.distance > 0.0){ 147 | refl.color = rayTrace(refl, reflectionRay, scene, depth + 1); 148 | } else { 149 | refl.color = scene.background.color; 150 | } 151 | 152 | color = color.blend(refl.color, info.shape.material.reflection); 153 | } 154 | // Refraction 155 | /* TODO */ 156 | } 157 | /* Render shadows and highlights */ 158 | 159 | IntersectionInfo shadowInfo = new IntersectionInfo(); 160 | 161 | if (renderShadows) { 162 | var shadowRay = new Ray(info.position, v); 163 | 164 | shadowInfo = testIntersection(shadowRay, scene, info.shape); 165 | if (shadowInfo.isHit && 166 | shadowInfo.shape != info.shape 167 | /*&& shadowInfo.shape.type != 'PLANE'*/) { 168 | var vA = color.multiplyScalar(0.5); 169 | var dB = (0.5 * pow(shadowInfo.shape.material.transparency, 0.5)); 170 | color = vA.addScalar(dB); 171 | } 172 | } 173 | // Phong specular highlights 174 | if (renderHighlights && 175 | !shadowInfo.isHit && 176 | (info.shape.material.gloss > 0.0)) { 177 | var Lv = (info.shape.position - light.position).normalize(); 178 | 179 | var E = (scene.camera.position - info.shape.position).normalize(); 180 | 181 | var H = (E - Lv).normalize(); 182 | 183 | var glossWeight = pow(max(info.normal.dot(H), 0.0), shininess); 184 | color = light.color.multiplyScalar(glossWeight) + color; 185 | } 186 | } 187 | return color.limit(); 188 | } 189 | 190 | String toString() { 191 | return 'Engine [canvasWidth: $canvasWidth, canvasHeight: $canvasHeight]'; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/simd/materials.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace_simd; 8 | 9 | abstract class Materials { 10 | final double gloss; // [0...infinity] 0 = matt 11 | final double transparency; // 0=opaque 12 | final double reflection; // [0...infinity] 0 = no reflection 13 | final double refraction; 14 | final bool hasTexture; 15 | 16 | const Materials(this.reflection, 17 | this.transparency, 18 | this.gloss, 19 | this.refraction, 20 | this.hasTexture); 21 | 22 | Color getColor(num u, num v); 23 | 24 | wrapUp(t) { 25 | t = t % 2.0; 26 | if(t < -1) t += 2.0; 27 | if(t >= 1) t -= 2.0; 28 | return t; 29 | } 30 | } 31 | 32 | 33 | class Chessboard extends Materials { 34 | final Color colorEven, colorOdd; 35 | final double density; 36 | 37 | const Chessboard(this.colorEven, 38 | this.colorOdd, 39 | reflection, 40 | transparency, 41 | gloss, 42 | this.density) 43 | : super(reflection, transparency, gloss, 0.5, true); 44 | 45 | Color getColor(num u, num v) { 46 | var t = wrapUp(u * density) * wrapUp(v * density); 47 | 48 | if (t < 0.0) { 49 | return colorEven; 50 | } else { 51 | return colorOdd; 52 | } 53 | } 54 | } 55 | 56 | 57 | class Solid extends Materials { 58 | final Color color; 59 | 60 | const Solid(this.color, reflection, refraction, transparency, gloss) 61 | : super(reflection, transparency, gloss, refraction, false); 62 | 63 | Color getColor(num u, num v) { 64 | return color; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/simd/renderscene.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | 8 | library ray_trace_simd; 9 | 10 | import 'dart:math'; 11 | import 'dart:typed_data'; 12 | 13 | part 'color.dart'; 14 | part 'engine.dart'; 15 | part 'materials.dart'; 16 | part 'scene.dart'; 17 | part 'shapes.dart'; 18 | part 'vector.dart'; 19 | 20 | // Dummy HTML definition. 21 | 22 | query(a) {} 23 | 24 | class Light { 25 | final position; 26 | final color; 27 | final intensity; 28 | 29 | const Light(this.position, this.color, [this.intensity = 10.0]); 30 | } 31 | 32 | 33 | // 'event' null means that we are benchmarking 34 | void renderScene(event) { 35 | var scene = new Scene(); 36 | scene.camera = new Camera(new Vector(0.0, 0.0, -15.0), 37 | new Vector(-0.2, 0.0, 5.0), 38 | new Vector(0.0, 1.0, 0.0)); 39 | scene.background = const Background(const Color(0.5, 0.5, 0.5), 0.4); 40 | 41 | var sphere = new Sphere( 42 | new Vector(-1.5, 1.5, 2.0), 43 | 1.5, 44 | const Solid( 45 | const Color(0.0, 0.5, 0.5), 46 | 0.3, 47 | 0.0, 48 | 0.0, 49 | 2.0 50 | ) 51 | ); 52 | 53 | var sphere1 = new Sphere( 54 | new Vector(1.0, 0.25, 1.0), 55 | 0.5, 56 | const Solid( 57 | const Color(0.9,0.9,0.9), 58 | 0.1, 59 | 0.0, 60 | 0.0, 61 | 1.5 62 | ) 63 | ); 64 | 65 | var plane = new Plane( 66 | new Vector(0.1, 0.9, -0.5).normalize(), 67 | 1.2, 68 | const Chessboard( 69 | const Color(1.0, 1.0, 1.0), 70 | const Color(0.0, 0.0, 0.0), 71 | 0.2, 72 | 0.0, 73 | 1.0, 74 | 0.7 75 | ) 76 | ); 77 | 78 | scene.shapes.add(plane); 79 | scene.shapes.add(sphere); 80 | scene.shapes.add(sphere1); 81 | 82 | var light = new Light( 83 | new Vector(5.0, 10.0, -1.0), 84 | const Color(0.8, 0.8, 0.8) 85 | ); 86 | 87 | var light1 = new Light( 88 | new Vector(-3.0, 5.0, -15.0), 89 | const Color(0.8, 0.8, 0.8), 90 | 100.0 91 | ); 92 | 93 | scene.lights.add(light); 94 | scene.lights.add(light1); 95 | 96 | int imageWidth, imageHeight, pixelSize; 97 | bool renderDiffuse, renderShadows, renderHighlights, renderReflections; 98 | var canvas; 99 | if (event == null) { 100 | imageWidth = 100; 101 | imageHeight = 100; 102 | pixelSize = 5; 103 | renderDiffuse = true; 104 | renderShadows = true; 105 | renderHighlights = true; 106 | renderReflections = true; 107 | canvas = null; 108 | } else { 109 | imageWidth = int.parse(query('#imageWidth').value); 110 | imageHeight = int.parse(query('#imageHeight').value); 111 | pixelSize = int.parse(query('#pixelSize').value.split(',')[0]); 112 | renderDiffuse = query('#renderDiffuse').checked; 113 | renderShadows = query('#renderShadows').checked; 114 | renderHighlights = query('#renderHighlights').checked; 115 | renderReflections = query('#renderReflections').checked; 116 | canvas = query("#canvas"); 117 | } 118 | int rayDepth = 2; 119 | 120 | var raytracer = new Engine(canvasWidth:imageWidth, 121 | canvasHeight:imageHeight, 122 | pixelWidth: pixelSize, 123 | pixelHeight: pixelSize, 124 | renderDiffuse: renderDiffuse, 125 | renderShadows: renderShadows, 126 | renderHighlights: renderHighlights, 127 | renderReflections: renderReflections, 128 | rayDepth: rayDepth 129 | ); 130 | 131 | raytracer.renderScene(scene, canvas); 132 | } 133 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/simd/scene.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace_simd; 8 | 9 | class Ray { 10 | final position; 11 | final direction; 12 | 13 | Ray(this.position, this.direction); 14 | String toString() { 15 | return 'Ray [$position, $direction]'; 16 | } 17 | } 18 | 19 | 20 | class Camera { 21 | final position; 22 | final lookAt; 23 | final up; 24 | var equator, screen; 25 | 26 | Camera(this.position, this.lookAt, this.up) { 27 | equator = lookAt.normalize().cross(up); 28 | screen = position + lookAt; 29 | } 30 | 31 | Ray getRay(double vx, double vy) { 32 | var pos = screen - (equator.multiplyScalar(vx) - up.multiplyScalar(vy)); 33 | pos = pos.negateY(); 34 | var dir = pos - position; 35 | var ray = new Ray(pos, dir.normalize()); 36 | return ray; 37 | } 38 | 39 | toString() { 40 | return 'Camera []'; 41 | } 42 | } 43 | 44 | 45 | class Background { 46 | final Color color; 47 | final double ambience; 48 | 49 | const Background(this.color, this.ambience); 50 | } 51 | 52 | 53 | class Scene { 54 | var camera; 55 | var shapes; 56 | var lights; 57 | var background; 58 | Scene() { 59 | camera = new Camera(new Vector(0.0, 0.0, -0.5), 60 | new Vector(0.0, 0.0, 1.0), 61 | new Vector(0.0, 1.0, 0.0)); 62 | shapes = new List(); 63 | lights = new List(); 64 | background = const Background(const Color(0.0, 0.0, 0.5), 0.2); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/simd/shapes.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace_simd; 8 | 9 | class BaseShape { 10 | final position; 11 | final material; 12 | 13 | const BaseShape(this.position, this.material); 14 | 15 | String toString() { 16 | return 'BaseShape'; 17 | } 18 | } 19 | 20 | 21 | class Plane extends BaseShape { 22 | final d; 23 | 24 | Plane(pos, this.d, material) : super(pos, material); 25 | 26 | IntersectionInfo intersect(Ray ray) { 27 | var info = new IntersectionInfo(); 28 | 29 | var Vd = position.dot(ray.direction); 30 | if (Vd == 0) return info; // no intersection 31 | 32 | var t = -(position.dot(ray.position) + d) / Vd; 33 | if (t <= 0) return info; 34 | 35 | info.shape = this; 36 | info.isHit = true; 37 | info.position = ray.position + ray.direction.multiplyScalar(t); 38 | info.normal = position; 39 | info.distance = t; 40 | 41 | if(material.hasTexture){ 42 | var vU = new Vector(position.y, position.z, -position.x); 43 | var vV = vU.cross(position); 44 | var u = info.position.dot(vU); 45 | var v = info.position.dot(vV); 46 | info.color = material.getColor(u,v); 47 | } else { 48 | info.color = material.getColor(0,0); 49 | } 50 | 51 | return info; 52 | } 53 | 54 | String toString() { 55 | return 'Plane [$position, d=$d]'; 56 | } 57 | } 58 | 59 | 60 | class Sphere extends BaseShape { 61 | final double radius; 62 | const Sphere(pos, this.radius, material) : super(pos, material); 63 | 64 | IntersectionInfo intersect(Ray ray){ 65 | var info = new IntersectionInfo(); 66 | info.shape = this; 67 | 68 | var dst = ray.position - position; 69 | 70 | var B = dst.dot(ray.direction); 71 | var C = dst.dot(dst) - (radius * radius); 72 | var D = (B * B) - C; 73 | 74 | if (D > 0) { // intersection! 75 | info.isHit = true; 76 | info.distance = (-B) - sqrt(D); 77 | info.position = ray.position + 78 | ray.direction.multiplyScalar(info.distance); 79 | info.normal = (info.position - position).normalize(); 80 | 81 | info.color = material.getColor(0,0); 82 | } else { 83 | info.isHit = false; 84 | } 85 | return info; 86 | } 87 | 88 | String toString() { 89 | return 'Sphere [position=$position, radius=$radius]'; 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /lib/src/Tracer/dart/simd/vector.dart: -------------------------------------------------------------------------------- 1 | // The ray tracer code in this file is written by Adam Burmister. It 2 | // is available in its original form from: 3 | // 4 | // http://labs.flog.co.nz/raytracer/ 5 | // 6 | // Ported from the v8 benchmark suite by Google 2012. 7 | part of ray_trace_simd; 8 | 9 | class Vector { 10 | final Float32x4 _xyz; 11 | 12 | double get x => _xyz.x; 13 | double get y => _xyz.y; 14 | double get z => _xyz.z; 15 | 16 | factory Vector(double x, double y, double z) { 17 | return new Vector._create(new Float32x4(x, y, z, 0.0)); 18 | } 19 | 20 | Vector._create(this._xyz); 21 | 22 | Vector normalize() { 23 | var m = magnitude(); 24 | return new Vector._create(_xyz.scale(1.0 / m)); 25 | } 26 | 27 | Vector negateY() { 28 | return new Vector._create(_xyz.withY(-_xyz.y)); 29 | } 30 | 31 | double magnitude() { 32 | var prod = _xyz * _xyz; 33 | return sqrt(prod.x + prod.y + prod.z); 34 | } 35 | 36 | Vector cross(Vector w) { 37 | var v = _xyz; 38 | var x = -v.z * w.y + v.y * w.z; 39 | var y = v.z * w.x - v.x * w.z; 40 | var z = -v.y * w.x + v.x * w.y; 41 | return new Vector._create(new Float32x4(x, y, z, 0.0)); 42 | } 43 | 44 | double dot(Vector w) { 45 | var prod = _xyz * w._xyz; 46 | return prod.x + prod.y + prod.z; 47 | } 48 | 49 | Vector operator +(Vector w) { 50 | return new Vector._create(_xyz + w._xyz); 51 | } 52 | 53 | Vector operator -(Vector w) { 54 | return new Vector._create(_xyz - w._xyz); 55 | } 56 | 57 | Vector operator *(Vector w) { 58 | return new Vector._create(_xyz * w._xyz); 59 | } 60 | 61 | Vector multiplyScalar(double w) { 62 | return new Vector._create(_xyz.scale(w)); 63 | } 64 | 65 | String toString() { 66 | return 'Vector [$x, $y ,$z ]'; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/src/common/dart/BenchmarkBase.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | 3 | library benchmark_base; 4 | 5 | 6 | class Expect { 7 | static void equals(var expected, var actual) { 8 | if (expected != actual) { 9 | throw "Values not equal: $expected vs $actual"; 10 | } 11 | } 12 | 13 | static void listEquals(List expected, List actual) { 14 | if (expected.length != actual.length) { 15 | throw "Lists have different lengths: ${expected.length} vs ${actual.length}"; 16 | } 17 | for (int i = 0; i < actual.length; i++) { 18 | equals(expected[i], actual[i]); 19 | } 20 | } 21 | 22 | fail(message) { 23 | throw message; 24 | } 25 | } 26 | 27 | 28 | class BenchmarkBase { 29 | final String name; 30 | 31 | // Empty constructor. 32 | const BenchmarkBase(String name) : this.name = name; 33 | 34 | // The benchmark code. 35 | // This function is not used, if both [warmup] and [exercise] are overwritten. 36 | void run() { } 37 | 38 | // Runs a short version of the benchmark. By default invokes [run] once. 39 | void warmup() { 40 | run(); 41 | } 42 | 43 | // Exercices the benchmark. By default invokes [run] 10 times. 44 | void exercise() { 45 | for (int i = 0; i < 10; i++) { 46 | run(); 47 | } 48 | } 49 | 50 | // Not measured setup code executed prior to the benchmark runs. 51 | void setup() { } 52 | 53 | // Not measures teardown code executed after the benchark runs. 54 | void teardown() { } 55 | 56 | // Measures the score for this benchmark by executing it repeately until 57 | // time minimum has been reached. 58 | static double measureFor(Function f, int timeMinimum) { 59 | int time = 0; 60 | int iter = 0; 61 | Stopwatch watch = new Stopwatch(); 62 | watch.start(); 63 | int elapsed = 0; 64 | while (elapsed < timeMinimum) { 65 | f(); 66 | elapsed = watch.elapsedMilliseconds; 67 | iter++; 68 | } 69 | return 1000.0 * elapsed / iter; 70 | } 71 | 72 | // Measures the score for the benchmark and returns it. 73 | double measure() { 74 | setup(); 75 | // Warmup for at least 100ms. Discard result. 76 | measureFor(() { this.warmup(); }, 100); 77 | // Run the benchmark for at least 2000ms. 78 | double result = measureFor(() { this.exercise(); }, 2000); 79 | teardown(); 80 | return result; 81 | } 82 | 83 | void report() { 84 | double score = measure(); 85 | print("$name(RunTime): $score us."); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /lib/src/common/javascript/bench.js: -------------------------------------------------------------------------------- 1 | var Benchmark = { 2 | measureFor: function(f, timeMinimum) { 3 | var elapsed = 0; 4 | var iterations = 0; 5 | var start = new Date(); 6 | while (elapsed < timeMinimum) { 7 | iterations++; 8 | f(); 9 | elapsed = new Date() - start; 10 | } 11 | return 1000 * elapsed / iterations; 12 | }, 13 | 14 | measure: function(warmup, exercise) { 15 | if (!exercise) { 16 | exercise = function() { 17 | for (var i = 0; i < 10; i++) { 18 | warmup(); 19 | } 20 | }; 21 | } 22 | this.measureFor(warmup, 100); 23 | return this.measureFor(exercise, 2000); 24 | }, 25 | 26 | report: function(name, warmup, exercise) { 27 | var score = this.measure(warmup, exercise); 28 | print(name + "(RunTime): " + score + " us."); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See http://pub.dartlang.org/doc/glossary.html#lockfile 3 | packages: 4 | args: 5 | description: args 6 | source: hosted 7 | version: "0.13.0" 8 | matcher: 9 | description: matcher 10 | source: hosted 11 | version: "0.11.4+4" 12 | path: 13 | description: path 14 | source: hosted 15 | version: "1.3.1" 16 | quiver: 17 | description: quiver 18 | source: hosted 19 | version: "0.21.3" 20 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: ton80 2 | version: 0.1.0 3 | description: Ton 80 is a benchmark suite for Dart. 4 | environment: 5 | sdk: '>=1.2.0' 6 | dependencies: 7 | path: '>=1.3.0 <1.4.0' 8 | quiver: '>=0.21.0 <0.23.0' 9 | args: '>=0.13.0 <0.14.0' 10 | --------------------------------------------------------------------------------