dart-sdk/runtime/vm/snapshot_test.dart
lrn@google.com 662c2a8262 Rename RuntimeError to CyclicIntializationError, as per spec.
The RuntimeError has been used to report cyclic initialization errors in
dart2js.
It has also been used for other, unrelated, uses, where it makes
little to no sense.

The RuntimeError type has been removed, but added in js_helper.dart,
where dart2js uses it.

Uses of new RuntimeError("some message") have been converted to
other errors (Argument/State/Unsupported). In some cases, just
throwing a String might have been just as good.

BUG=http://dartbug.com/11040
R=johnniwinther@google.com

Review URL: https://codereview.chromium.org//16154017

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@23584 260f80e4-7a28-3924-810f-c04153c831b5
2013-06-04 10:33:11 +00:00

1566 lines
37 KiB
Dart

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:isolate';
import 'dart:async';
class Expect {
static void equals(x, y) {
if (x != y) throw new ArgumentError('not equal');
}
}
class Fields {
Fields(int i, int j) : fld1 = i, fld2 = j, fld5 = true {}
int fld1;
final int fld2;
static int fld3;
static const int fld4 = 10;
bool fld5;
}
class FieldsTest {
static Fields testMain() {
Fields obj = new Fields(10, 20);
Expect.equals(10, obj.fld1);
Expect.equals(20, obj.fld2);
Expect.equals(10, Fields.fld4);
Expect.equals(true, obj.fld5);
return obj;
}
}
// Benchpress: A collection of micro-benchmarks.
// Ported from internal v8 benchmark suite.
class Error {
static void error(String msg) {
throw msg;
}
}
// F i b o n a c c i
class Fibonacci {
static int fib(int n) {
if (n <= 1) return 1;
return fib(n - 1) + fib(n - 2);
}
}
class FibBenchmark extends BenchmarkBase {
const FibBenchmark() : super("Fibonacci");
void warmup() {
Fibonacci.fib(10);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
var result = Fibonacci.fib(20);
if (result != 10946)
Error.error("Wrong result: $result. Should be: 10946.");
}
static void main() {
new FibBenchmark().report();
}
}
// L o o p
class Loop {
static int loop(int outerIterations) {
int sum = 0;
for (int i = 0; i < outerIterations; i++) {
for (int j = 0; j < 100; j++) {
sum++;
}
}
return sum;
}
}
class LoopBenchmark extends BenchmarkBase {
const LoopBenchmark() : super("Loop");
void warmup() {
Loop.loop(10);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
var result = Loop.loop(200);
if (result != 20000)
Error.error("Wrong result: $result. Should be: 20000");
}
static void main() {
new LoopBenchmark().report();
}
}
// T o w e r s
class TowersDisk {
final int size;
TowersDisk next;
TowersDisk(size) : this.size = size, next = null {}
}
class Towers {
List<TowersDisk> piles;
int movesDone;
Towers(int disks)
: piles = new List<TowersDisk>(3), movesDone = 0 {
build(0, disks);
}
void build(int pile, int disks) {
for (var i = disks - 1; i >= 0; i--) {
push(pile, new TowersDisk(i));
}
}
void push(int pile, TowersDisk disk) {
TowersDisk top = piles[pile];
if ((top != null) && (disk.size >= top.size))
Error.error("Cannot put a big disk on a smaller disk.");
disk.next = top;
piles[pile] = disk;
}
TowersDisk pop(int pile) {
var top = piles[pile];
if (top == null)
Error.error("Attempting to remove a disk from an empty pile.");
piles[pile] = top.next;
top.next = null;
return top;
}
void moveTop(int from, int to) {
push(to, pop(from));
movesDone++;
}
void move(int from, int to, int disks) {
if (disks == 1) {
moveTop(from, to);
} else {
int other = 3 - from - to;
move(from, other, disks - 1);
moveTop(from, to);
move(other, to, disks - 1);
}
}
}
class TowersBenchmark extends BenchmarkBase {
const TowersBenchmark() : super("Towers");
void warmup() {
new Towers(6).move(0, 1, 6);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
var towers = new Towers(13);
towers.move(0, 1, 13);
if (towers.movesDone != 8191) {
var moves = towers.movesDone;
Error.error("Error in result: $moves should be: 8191");
}
}
static void main() {
new TowersBenchmark().report();
}
}
// S i e v e
class SieveBenchmark extends BenchmarkBase {
const SieveBenchmark() : super("Sieve");
static int sieve(int size) {
int primeCount = 0;
List<bool> flags = new List<bool>(size + 1);
for (int i = 1; i < size; i++) flags[i] = true;
for (int i = 2; i < size; i++) {
if (flags[i]) {
primeCount++;
for (int k = i + 1; k <= size; k += i)
flags[k - 1] = false;
}
}
return primeCount;
}
void warmup() {
sieve(100);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
int result = sieve(1000);
if (result != 168)
Error.error("Wrong result: $result should be: 168");
}
static void main() {
new SieveBenchmark().report();
}
}
// P e r m u t e
// The original benchmark uses one-based indexing. Even though arrays in JS and
// lists in dart are zero-based, we stay with one-based indexing
// (wasting one element).
class Permute {
int permuteCount;
Permute() {}
void swap(int n, int k, List<int> list) {
int tmp = list[n];
list[n] = list[k];
list[k] = tmp;
}
void doPermute(int n, List<int> list) {
permuteCount++;
if (n != 1) {
doPermute(n - 1, list);
for (int k = n - 1; k >= 1; k--) {
swap(n, k, list);
doPermute(n - 1, list);
swap(n, k, list);
}
}
}
int permute(int size) {
permuteCount = 0;
List<int> list = new List<int>(size);
for (int i = 1; i < size; i++) list[i] = i - 1;
doPermute(size - 1, list);
return permuteCount;
}
}
class PermuteBenchmark extends BenchmarkBase {
const PermuteBenchmark() : super("Permute");
void warmup() {
new Permute().permute(4);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
int result = new Permute().permute(8);
if (result != 8660)
Error.error("Wrong result: $result should be: 8660");
}
static void main() {
new PermuteBenchmark().report();
}
}
// Q u e e n s
// The original benchmark uses one-based indexing. Even though arrays in JS and
// lists in dart are zero-based, we stay with one-based indexing
// (wasting one element).
class Queens {
static bool tryQueens(int i,
List<bool> a,
List<bool> b,
List<bool> c,
List<int> x) {
int j = 0;
bool q = false;
while ((!q) && (j != 8)) {
j++;
q = false;
if (b[j] && a[i + j] && c[i - j + 7]) {
x[i] = j;
b[j] = false;
a[i + j] = false;
c[i - j + 7] = false;
if (i < 8) {
q = tryQueens(i + 1, a, b, c, x);
if (!q) {
b[j] = true;
a[i + j] = true;
c[i - j + 7] = true;
}
} else {
q = true;
}
}
}
return q;
}
static void queens() {
List<bool> a = new List<bool>(9);
List<bool> b = new List<bool>(17);
List<bool> c = new List<bool>(15);
List<int> x = new List<int>(9);
b[1] = false;
for (int i = -7; i <= 16; i++) {
if ((i >= 1) && (i <= 8)) a[i] = true;
if (i >= 2) b[i] = true;
if (i <= 7) c[i + 7] = true;
}
if (!tryQueens(1, b, a, c, x))
Error.error("Error in queens");
}
}
class QueensBenchmark extends BenchmarkBase {
const QueensBenchmark() : super("Queens");
void warmup() {
Queens.queens();
}
void exercise() {
Queens.queens();
}
static void main() {
new QueensBenchmark().report();
}
}
// R e c u r s e
class Recurse {
static int recurse(int n) {
if (n <= 0) return 1;
recurse(n - 1);
return recurse(n - 1);
}
}
class RecurseBenchmark extends BenchmarkBase {
const RecurseBenchmark() : super("Recurse");
void warmup() {
Recurse.recurse(7);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
Recurse.recurse(13);
}
static void main() {
new RecurseBenchmark().report();
}
}
// S u m
class SumBenchmark extends BenchmarkBase {
const SumBenchmark() : super("Sum");
static int sum(int start, int end) {
var sum = 0;
for (var i = start; i <= end; i++) sum += i;
return sum;
}
void warmup() {
sum(1, 1000);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
int result = sum(1, 10000);
if (result != 50005000)
Error.error("Wrong result: $result should be 50005000");
}
static void main() {
new SumBenchmark().report();
}
}
// H e l p e r f u n c t i o n s f o r s o r t s
class Random {
static const int INITIAL_SEED = 74755;
int seed;
Random() : seed = INITIAL_SEED {}
int random() {
seed = ((seed * 1309) + 13849) % 65536;
return seed;
}
}
//
class SortData {
List<int> list;
int min;
int max;
SortData(int length) {
Random r = new Random();
list = new List<int>(length);
for (int i = 0; i < length; i++) list[i] = r.random();
int min, max;
min = max = list[0];
for (int i = 0; i < length; i++) {
int e = list[i];
if (e > max) max = e;
if (e < min) min = e;
}
this.min = min;
this.max = max;
}
void check() {
List<int> a = list;
int len = a.length;
if ((a[0] != min) || a[len - 1] != max)
Error.error("List is not sorted");
for (var i = 1; i < len; i++) {
if (a[i - 1] > a[i]) Error.error("List is not sorted");
}
}
}
// B u b b l e S o r t
class BubbleSort {
static void sort(List<int> a) {
int len = a.length;
for (int i = len - 2; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
int c = a[j];
int n = a[j + 1];
if (c > n) {
a[j] = n;
a[j + 1] = c;
}
}
}
}
}
class BubbleSortBenchmark extends BenchmarkBase {
const BubbleSortBenchmark() : super("BubbleSort");
void warmup() {
SortData data = new SortData(30);
BubbleSort.sort(data.list);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
SortData data = new SortData(130);
BubbleSort.sort(data.list);
data.check();
}
static void main() {
new BubbleSortBenchmark().report();
}
}
// Q u i c k S o r t
class QuickSort {
static void sort(List<int> a, int low, int high) {
int pivot = a[(low + high) >> 1];
int i = low;
int j = high;
while (i <= j) {
while (a[i] < pivot) i++;
while (pivot < a[j]) j--;
if (i <= j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;
}
}
if (low < j) sort(a, low, j);
if (i < high) sort(a, i, high);
}
}
class QuickSortBenchmark extends BenchmarkBase {
const QuickSortBenchmark() : super("QuickSort");
void warmup() {
SortData data = new SortData(100);
QuickSort.sort(data.list, 0, data.list.length - 1);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
SortData data = new SortData(800);
QuickSort.sort(data.list, 0, data.list.length - 1);
data.check();
}
static void main() {
new QuickSortBenchmark().report();
}
}
// T r e e S o r t
class TreeNodePress {
int value;
TreeNodePress left;
TreeNodePress right;
TreeNodePress(int n) : value = n {}
void insert(int n) {
if (n < value) {
if (left == null) left = new TreeNodePress(n);
else left.insert(n);
} else {
if (right == null) right = new TreeNodePress(n);
else right.insert(n);
}
}
void check() {
TreeNodePress left = this.left;
TreeNodePress right = this.right;
int value = this.value;
return ((left == null) || ((left.value < value) && left.check())) &&
((right == null) || ((right.value >= value) && right.check()));
}
}
class TreeSort {
static void sort(List<int> a) {
int len = a.length;
TreeNodePress tree = new TreeNodePress(a[0]);
for (var i = 1; i < len; i++) tree.insert(a[i]);
if (!tree.check()) Error.error("Invalid result, tree not sorted");
}
}
class TreeSortBenchmark extends BenchmarkBase {
const TreeSortBenchmark() : super("TreeSort");
void warmup() {
TreeSort.sort(new SortData(100).list);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
TreeSort.sort(new SortData(1000).list);
}
}
// T a k
class TakBenchmark extends BenchmarkBase {
const TakBenchmark() : super("Tak");
static void tak(int x, int y, int z) {
if (y >= x) return z;
return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y));
}
void warmup() {
tak(9, 6, 3);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
tak(18, 12, 6);
}
static void main() {
new TakBenchmark().report();
}
}
// T a k l
class ListElement {
final int length;
final ListElement next;
const ListElement(int length, ListElement next)
: this.length = length,
this.next = next;
static ListElement makeList(int length) {
if (length == 0) return null;
return new ListElement(length, makeList(length - 1));
}
static bool isShorter(ListElement x, ListElement y) {
ListElement xTail = x;
ListElement yTail = y;
while (yTail != null) {
if (xTail == null) return true;
xTail = xTail.next;
yTail = yTail.next;
}
return false;
}
}
class Takl {
static ListElement takl(ListElement x, ListElement y, ListElement z) {
if (ListElement.isShorter(y, x)) {
return takl(takl(x.next, y, z),
takl(y.next, z, x),
takl(z.next, x, y));
} else {
return z;
}
}
}
class TaklBenchmark extends BenchmarkBase {
const TaklBenchmark() : super("Takl");
void warmup() {
Takl.takl(ListElement.makeList(8),
ListElement.makeList(4),
ListElement.makeList(3));
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
ListElement result = Takl.takl(ListElement.makeList(15),
ListElement.makeList(10),
ListElement.makeList(6));
if (result.length != 10) {
int len = result.length;
Error.error("Wrong result: $len should be: 10");
}
}
static void main() {
new TaklBenchmark().report();
}
}
// M a i n
class BenchPress {
static void mainWithArgs(List<String> args) {
List<BenchmarkBase> benchmarks = [
new BubbleSortBenchmark(),
new FibBenchmark(),
new LoopBenchmark(),
new PermuteBenchmark(),
new QueensBenchmark(),
new QuickSortBenchmark(),
new RecurseBenchmark(),
new SieveBenchmark(),
new SumBenchmark(),
new TakBenchmark(),
new TaklBenchmark(),
new TowersBenchmark(),
new TreeSortBenchmark(),
];
if (args.length > 0) {
String benchName = args[0];
bool foundBenchmark = false;
benchmarks.forEach((bench) {
if (bench.name == benchName) {
foundBenchmark = true;
bench.report();
}
});
if (!foundBenchmark) {
Error.error("Benchmark not found: $benchName");
}
return;
}
double logMean = 0.0;
benchmarks.forEach((bench) {
double benchScore = bench.measure();
String name = bench.name;
print("$name: $benchScore");
logMean += Math.log(benchScore);
});
logMean = logMean / benchmarks.length;
double score = Math.pow(Math.E, logMean);
print("BenchPress (average): $score");
}
// TODO(floitsch): let main accept arguments from the command line.
static void main() {
mainWithArgs([]);
}
}
class BenchmarkBase {
final String name;
// Empty constructor.
const BenchmarkBase(String name) : this.name = name;
// The benchmark code.
// This function is not used, if both [warmup] and [exercise] are overwritten.
void run() { }
// Runs a short version of the benchmark. By default invokes [run] once.
void warmup() {
run();
}
// Exercices the benchmark. By default invokes [run] 10 times.
void exercise() {
for (int i = 0; i < 10; i++) {
run();
}
}
// Not measured setup code executed prior to the benchmark runs.
void setup() { }
// Not measures teardown code executed after the benchark runs.
void teardown() { }
// Measures the score for this benchmark by executing it repeately until
// time minimum has been reached.
static double measureFor(Function f, int timeMinimum) {
int time = 0;
int iter = 0;
DateTime start = new DateTime.now();
while (time < timeMinimum) {
f();
time = (new DateTime.now().difference(start)).inMilliseconds;
iter++;
}
// Force double result by using a double constant.
return (1000.0 * iter) / time;
}
// Measures the score for the benchmark and returns it.
double measure() {
setup();
// Warmup for at least 100ms. Discard result.
measureFor(() { this.warmup(); }, -100);
// Run the benchmark for at least 2000ms.
double result = measureFor(() { this.exercise(); }, -2000);
teardown();
return result;
}
void report() {
double score = measure();
print("name: $score");
}
}
class Logger {
static print(object) {
printobject(object);
}
static printobject(obj) { }
}
//
// Dromaeo ObjectString
// Adapted from Mozilla JavaScript performance test suite.
// Microtests of strings (concatenation, methods).
class ObjectString extends BenchmarkBase {
const ObjectString() : super("Dromaeo.ObjectString");
static void main() {
new ObjectString().report();
}
static void print(String str) {
print(str);
}
String getRandomString(int characters) {
var result = "";
for (var i = 0; i < characters; i++) {
result += Strings.
createFromCodePoints([(25 * Math.random()).toInt() + 97]);
}
result += result;
result += result;
return result;
}
void run() {
//JS Dromeaeo uses 16384
final ITERATE1 = 384;
//JS Dromeaeo uses 80000
final ITERATE2 = 80;
//JS Dromeaeo uses 5000
final ITERATE3 = 50;
//JS Dromeaeo uses 5000
final ITERATE4 = 1;
//JS Dromaeo uses 5000
final ITERATE5 = 1000;
var result;
var text = getRandomString(ITERATE1);
ConcatStringBenchmark.test(ITERATE2);
ConcatStringFromCharCodeBenchmark.test(ITERATE2);
StringSplitBenchmark.test(text);
StringSplitOnCharBenchmark.test(text);
text += text;
CharAtBenchmark.test(text, ITERATE3);
NumberBenchmark.test(text, ITERATE3);
CodeUnitAtBenchmark.test(text, ITERATE3);
IndexOfBenchmark.test(text, ITERATE3);
LastIndexOfBenchmark.test(text, ITERATE3);
SliceBenchmark.test(text, ITERATE4);
SubstrBenchmark.test(text, ITERATE4);
SubstringBenchmark.test(text, ITERATE4);
ToLowerCaseBenchmark.test(text, ITERATE5);
ToUpperCaseBenchmark.test(text, ITERATE5);
ComparingBenchmark.test(text, ITERATE5);
}
}
class ConcatStringBenchmark {
ConcatStringBenchmark() {}
static String test(var iterations) {
var str = "";
for (var i = 0; i < iterations; i++) {
str += "a";
}
return str;
}
}
class ConcatStringFromCharCodeBenchmark {
ConcatStringFromCharCodeBenchmark() {}
static String test(var iterations) {
var str = "";
for (var i = 0; i < (iterations / 2); i++) {
str += Strings.createFromCodePoints([97]);
}
return str;
}
}
class StringSplitBenchmark {
StringSplitBenchmark() {}
static List<String> test(String input) {
return input.split("");
}
}
class StringSplitOnCharBenchmark {
StringSplitOnCharBenchmark() {}
static List<String> test(String input) {
String multiple = input;
multiple += multiple;
multiple += multiple;
multiple += multiple;
multiple += multiple;
return multiple.split("a");
}
}
class CharAtBenchmark {
CharAtBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input[0];
str = input[input.length - 1];
str = input[150]; //set it to 15000
str = input[120]; //set it to 12000
}
return str;
}
}
class NumberBenchmark {
NumberBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input[0];
str = input[input.length - 1];
str = input[150]; //set it to 15000
str = input[100]; //set it to 10000
str = input[50]; //set it to 5000
}
return str;
}
}
class CodeUnitAtBenchmark {
CodeUnitAtBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.codeUnitAt(0);
str = input.codeUnitAt(input.length - 1);
str = input.codeUnitAt(150); //set it to 15000
str = input.codeUnitAt(100); //set it to 10000
str = input.codeUnitAt(50); //set it to 5000
}
return str;
}
}
class IndexOfBenchmark {
IndexOfBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.indexOf("a", 0);
str = input.indexOf("b", 0);
str = input.indexOf("c", 0);
str = input.indexOf("d", 0);
}
return str;
}
}
class LastIndexOfBenchmark {
LastIndexOfBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.lastIndexOf("a", input.length - 1);
str = input.lastIndexOf("b", input.length - 1);
str = input.lastIndexOf("c", input.length - 1);
str = input.lastIndexOf("d", input.length - 1);
}
return str;
}
}
class SliceBenchmark {
SliceBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.substring(0, input.length - 1);
str = input.substring(0, 5);
str = input.substring(input.length - 1, input.length - 1);
str = input.substring(input.length - 6, input.length - 1);
str = input.substring(150, 155); //set to 15000 and 15005
str = input.substring(120, input.length-1); //set to 12000
}
return str;
}
}
class SubstrBenchmark {
SubstrBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.substring(0, input.length-1);
str = input.substring(0, 4);
str = input.substring(input.length - 1, input.length - 1);
str = input.substring(input.length - 6, input.length - 6);
str = input.substring(150, 154); //set to 15000 and 15005
str = input.substring(120, 124); //set to 12000
}
return str;
}
}
class SubstringBenchmark {
SubstringBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.substring(0, input.length - 1);
str = input.substring(0, 4);
str = input.substring(input.length - 1, input.length - 1);
str = input.substring(input.length - 6, input.length - 2);
str = input.substring(150, 154); //set to 15000 and 15005
str = input.substring(120, input.length - 2); //set to 12000
}
return str;
}
}
class ToLowerCaseBenchmark {
ToLowerCaseBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < (iterations / 1000); j++) {
str = Ascii.toLowerCase(input);
}
return str;
}
}
class ToUpperCaseBenchmark {
ToUpperCaseBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < (iterations / 1000); j++) {
str = Ascii.toUpperCase(input);
}
return str;
}
}
class ComparingBenchmark {
ComparingBenchmark() {}
static bool test(String input, var iterations) {
var tmp = "a${input}a";
var tmp2 = "a${input}a";
var res;
for (var j = 0; j < (iterations / 1000); j++) {
res = (tmp.compareTo(tmp2) == 0);
res = (tmp.compareTo(tmp2) < 0);
res = (tmp.compareTo(tmp2) > 0);
}
return res;
}
}
// Benchmarks basic message communication between two isolates.
class Benchmark1 {
static const MESSAGES = 10000;
static const INIT_MESSAGE = 0;
static const TERMINATION_MESSAGE = -1;
static const WARMUP_TIME = 1000;
static const RUN_TIME = 1000;
static const RUNS = 5;
static int run() {
return _run;
}
static void add_result(var opsms) {
_run++;
_opsms += opsms;
}
static void get_result() {
return _opsms / _run;
}
static void init() {
_run = 0;
_opsms = 0.0;
}
static void main() {
init();
PingPongGame pingPongGame = new PingPongGame();
}
static var _run;
static var _opsms;
}
class PingPongGame {
PingPongGame()
: _ping = new ReceivePort(),
_pingPort = _ping.toSendPort(),
_pong = null,
_warmedup = false,
_iterations = 0 {
SendPort _pong = spawnFunction(pong);
play();
}
void startRound() {
_iterations++;
_pong.send(Benchmark1.INIT_MESSAGE, _pingPort);
}
void evaluateRound() {
int time = (new DateTime.now().difference(_start)).inMilliseconds;
if (!_warmedup && time < Benchmark1.WARMUP_TIME) {
startRound();
} else if (!_warmedup) {
_warmedup = true;
_start = new DateTime.now();
_iterations = 0;
startRound();
} else if (_warmedup && time < Benchmark1.RUN_TIME) {
startRound();
} else {
shutdown();
Benchmark1.add_result((1.0 * _iterations * Benchmark1.MESSAGES) / time);
if (Benchmark1.run() < Benchmark1.RUNS) {
new PingPongGame();
} else {
print("PingPong: ", Benchmark1.get_result());
}
}
}
void play() {
_ping.receive((int message, SendPort replyTo) {
if (message < Benchmark1.MESSAGES) {
_pong.send(++message, null);
} else {
evaluateRound();
}
});
_start = new DateTime.now();
startRound();
}
void shutdown() {
_pong.send(Benchmark1.TERMINATION_MESSAGE, null);
_ping.close();
}
DateTime _start;
SendPort _pong;
SendPort _pingPort;
ReceivePort _ping;
bool _warmedup;
int _iterations;
}
void pong() {
port.receive((message, SendPort replyTo) {
if (message == Benchmark1.INIT_MESSAGE) {
replyTo.send(message, null);
} else if (message == Benchmark1.TERMINATION_MESSAGE) {
port.close();
} else {
replyTo.send(message, null);
}
});
}
class ManyGenericInstanceofTest {
static testMain() {
for (int i = 0; i < 5000; i++) {
GenericInstanceof.testMain();
}
}
}
// ---------------------------------------------------------------------------
// THE REST OF THIS FILE COULD BE AUTOGENERATED
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// tests/isolate/spawn_test.dart
// ---------------------------------------------------------------------------
spawn_test_main() {
test("spawn a new isolate", () {
SendPort port = spawnFunction(entry);
port.call(42).then(expectAsync1((message) {
Expect.equals(42, message);
}));
});
}
void entry() {
port.receive((message, SendPort replyTo) {
Expect.equals(42, message);
replyTo.send(42, null);
port.close();
});
}
// ---------------------------------------------------------------------------
// tests/isolate/isolate_negative_test.dart
// ---------------------------------------------------------------------------
void isolate_negative_entry() {
port.receive((ignored, replyTo) {
replyTo.send("foo", null);
});
}
isolate_negative_test_main() {
test("ensure isolate code is executed", () {
SendPort port = spawnFunction(isolate_negative_entry);
port.call("foo").then(expectAsync1((message) {
Expect.equals(true, "Expected fail"); // <=-------- Should fail here.
}));
});
}
// ---------------------------------------------------------------------------
// tests/isolate/message_test.dart
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Message passing test.
// ---------------------------------------------------------------------------
class MessageTest {
static const List list1 = const ["Hello", "World", "Hello", 0xfffffffffff];
static const List list2 = const [null, list1, list1, list1, list1];
static const List list3 = const [list2, 2.0, true, false, 0xfffffffffff];
static const Map map1 = const {
"a=1" : 1, "b=2" : 2, "c=3" : 3,
};
static const Map map2 = const {
"list1" : list1, "list2" : list2, "list3" : list3,
};
static const List list4 = const [map1, map2];
static const List elms = const [
list1, list2, list3, list4,
];
static void VerifyMap(Map expected, Map actual) {
Expect.equals(true, expected is Map);
Expect.equals(true, actual is Map);
Expect.equals(expected.length, actual.length);
testForEachMap(key, value) {
if (value is List) {
VerifyList(value, actual[key]);
} else {
Expect.equals(value, actual[key]);
}
}
expected.forEach(testForEachMap);
}
static void VerifyList(List expected, List actual) {
for (int i = 0; i < expected.length; i++) {
if (expected[i] is List) {
VerifyList(expected[i], actual[i]);
} else if (expected[i] is Map) {
VerifyMap(expected[i], actual[i]);
} else {
Expect.equals(expected[i], actual[i]);
}
}
}
static void VerifyObject(int index, var actual) {
var expected = elms[index];
Expect.equals(true, expected is List);
Expect.equals(true, actual is List);
Expect.equals(expected.length, actual.length);
VerifyList(expected, actual);
}
}
pingPong() {
int count = 0;
port.receive((var message, SendPort replyTo) {
if (message == -1) {
port.close();
replyTo.send(count, null);
} else {
// Check if the received object is correct.
if (count < MessageTest.elms.length) {
MessageTest.VerifyObject(count, message);
}
// Bounce the received object back so that the sender
// can make sure that the object matches.
replyTo.send(message, null);
count++;
}
});
}
message_test_main() {
test("send objects and receive them back", () {
SendPort remote = spawnFunction(pingPong);
// Send objects and receive them back.
for (int i = 0; i < MessageTest.elms.length; i++) {
var sentObject = MessageTest.elms[i];
// TODO(asiva): remove this local var idx once thew new for-loop
// semantics for closures is implemented.
var idx = i;
remote.call(sentObject).then(expectAsync1((var receivedObject) {
MessageTest.VerifyObject(idx, receivedObject);
}));
}
// Send recursive objects and receive them back.
List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
List local_list2 = [null, local_list1, local_list1 ];
List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
List sendObject = new List(5);
sendObject[0] = local_list1;
sendObject[1] = sendObject;
sendObject[2] = local_list2;
sendObject[3] = sendObject;
sendObject[4] = local_list3;
remote.call(sendObject).then((var replyObject) {
Expect.equals(true, sendObject is List);
Expect.equals(true, replyObject is List);
Expect.equals(sendObject.length, replyObject.length);
Expect.equals(true, identical(replyObject[1], replyObject));
Expect.equals(true, identical(replyObject[3], replyObject));
Expect.equals(true, identical(replyObject[0], replyObject[2][1]));
Expect.equals(true, identical(replyObject[0], replyObject[2][2]));
Expect.equals(true, identical(replyObject[2], replyObject[4][0]));
Expect.equals(true, identical(replyObject[0][0], replyObject[0][2]));
// Bigint literals are not canonicalized so do a == check.
Expect.equals(true, replyObject[0][3] == replyObject[4][4]);
});
// Shutdown the MessageServer.
remote.call(-1).then(expectAsync1((int message) {
Expect.equals(MessageTest.elms.length + 1, message);
}));
});
}
// ---------------------------------------------------------------------------
// tests/isolate/request_reply_test.dart
// ---------------------------------------------------------------------------
void request_reply_entry() {
port.receive((message, SendPort replyTo) {
replyTo.send(message + 87);
port.close();
});
}
void request_reply_main() {
test("call", () {
SendPort port = spawnFunction(request_reply_entry);
port.call(42).then(expectAsync1((message) {
Expect.equals(42 + 87, message);
}));
});
test("send", () {
SendPort port = spawnFunction(request_reply_entry);
ReceivePort reply = new ReceivePort();
port.send(99, reply.toSendPort());
reply.receive(expectAsync2((message, replyTo) {
Expect.equals(99 + 87, message);
reply.close();
}));
});
}
// ---------------------------------------------------------------------------
// tests/isolate/count_test.dart
// ---------------------------------------------------------------------------
void countMessages() {
int count = 0;
port.receive((int message, SendPort replyTo) {
if (message == -1) {
Expect.equals(10, count);
replyTo.send(-1, null);
port.close();
return;
}
Expect.equals(count, message);
count++;
replyTo.send(message * 2, null);
});
}
void count_main() {
test("count 10 consecutive messages", () {
int count = 0;
SendPort remote = spawnFunction(countMessages);
ReceivePort local = new ReceivePort();
SendPort reply = local.toSendPort();
local.receive(expectAsync2((int message, SendPort replyTo) {
if (message == -1) {
Expect.equals(11, count);
local.close();
return;
}
Expect.equals((count - 1) * 2, message);
remote.send(count++, reply);
if (count == 10) {
remote.send(-1, reply);
}
}, 11));
remote.send(count++, reply);
});
}
// ---------------------------------------------------------------------------
// tests/isolate/mandel_isolate_test.dart
// ---------------------------------------------------------------------------
const TERMINATION_MESSAGE = -1;
const N = 100;
const ISOLATES = 20;
mandel_main() {
test("Render Mandelbrot in parallel", () {
final state = new MandelbrotState();
state._validated.future.then(expectAsync1((result) {
expect(result, isTrue);
}));
for (int i = 0; i < Math.min(ISOLATES, N); i++) state.startClient(i);
});
}
class MandelbrotState {
MandelbrotState() {
_result = new List<List<int>>(N);
_lineProcessedBy = new List<LineProcessorClient>(N);
_sent = 0;
_missing = N;
_validated = new Completer<bool>();
}
void startClient(int id) {
assert(_sent < N);
final client = new LineProcessorClient(this, id);
client.processLine(_sent++);
}
void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) {
assert(_result[y] == null);
_result[y] = line;
_lineProcessedBy[y] = client;
if (_sent != N) {
client.processLine(_sent++);
} else {
client.shutdown();
}
// If all lines have been computed, validate the result.
if (--_missing == 0) {
_printResult();
_validateResult();
}
}
void _validateResult() {
// TODO(ngeoffray): Implement this.
_validated.complete(true);
}
void _printResult() {
var output = new StringBuffer();
for (int i = 0; i < _result.length; i++) {
List<int> line = _result[i];
for (int j = 0; j < line.length; j++) {
if (line[j] < 10) output.write("0");
output.write(line[j]);
}
output.write("\n");
}
// print(output);
}
List<List<int>> _result;
List<LineProcessorClient> _lineProcessedBy;
int _sent;
int _missing;
Completer<bool> _validated;
}
class LineProcessorClient {
LineProcessorClient(MandelbrotState this._state, int this._id) {
_port = spawnFunction(processLines);
}
void processLine(int y) {
_port.call(y).then((List<int> message) {
_state.notifyProcessedLine(this, y, message);
});
}
void shutdown() {
_port.send(TERMINATION_MESSAGE, null);
}
MandelbrotState _state;
int _id;
SendPort _port;
}
List<int> processLine(int y) {
double inverseN = 2.0 / N;
double Civ = y * inverseN - 1.0;
List<int> result = new List<int>(N);
for (int x = 0; x < N; x++) {
double Crv = x * inverseN - 1.5;
double Zrv = Crv;
double Ziv = Civ;
double Trv = Crv * Crv;
double Tiv = Civ * Civ;
int i = 49;
do {
Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ;
Zrv = Trv - Tiv + Crv;
Trv = Zrv * Zrv;
Tiv = Ziv * Ziv;
} while (((Trv + Tiv) <= 4.0) && (--i > 0));
result[x] = i;
}
return result;
}
void processLines() {
port.receive((message, SendPort replyTo) {
if (message == TERMINATION_MESSAGE) {
assert(replyTo == null);
port.close();
} else {
replyTo.send(processLine(message), null);
}
});
}