# HG changeset patch # User Jaroslav Tulach # Date 1453784077 -3600 # Node ID fa00fb053c7242049f39b00a7d6da0d865936ea4 # Parent 433856f897ddeb83da306e4c682f3fe09ab34072 Extracting direct references to 64-bit operations diff -r 433856f897dd -r fa00fb053c72 benchmarks/sieve/src/main/java/org/apidesign/benchmark/sieve/n64/Filter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/benchmarks/sieve/src/main/java/org/apidesign/benchmark/sieve/n64/Filter.java Tue Jan 26 05:54:37 2016 +0100 @@ -0,0 +1,41 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012-2015 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.benchmark.sieve.n64; + +final class Filter { + private final long number; + private final Filter next; + + public Filter(long number, Filter next) { + this.number = number; + this.next = next; + } + + public boolean accept(long n) { + Filter filter = this; + for (;;) { + if (n % filter.number == 0) { + return false; + } + filter = filter.next; + if (filter == null) { + return true; + } + } + } +} diff -r 433856f897dd -r fa00fb053c72 benchmarks/sieve/src/main/java/org/apidesign/benchmark/sieve/n64/Natural.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/benchmarks/sieve/src/main/java/org/apidesign/benchmark/sieve/n64/Natural.java Tue Jan 26 05:54:37 2016 +0100 @@ -0,0 +1,26 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012-2015 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.benchmark.sieve.n64; + +final class Natural { + private long cnt = 2; + + long next() { + return cnt++; + } +} diff -r 433856f897dd -r fa00fb053c72 benchmarks/sieve/src/main/java/org/apidesign/benchmark/sieve/n64/Primes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/benchmarks/sieve/src/main/java/org/apidesign/benchmark/sieve/n64/Primes.java Tue Jan 26 05:54:37 2016 +0100 @@ -0,0 +1,55 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012-2015 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.benchmark.sieve.n64; + +abstract class Primes { + private final Natural natural; + private Filter filter; + + protected Primes() { + this.natural = new Natural(); + } + + long next() { + for (;;) { + long n = natural.next(); + if (filter == null || filter.accept(n)) { + filter = new Filter(n, filter); + return n; + } + } + } + + protected abstract void log(String msg); + + public final long compute(long count) { + long cnt = 0; + long res; + for (;;) { + res = next(); + cnt += 1; + if (cnt % 1000 == 0) { + log("Computed " + cnt + " primes. Last one is " + res); + } + if (cnt >= count) { + break; + } + } + return res; + } +} diff -r 433856f897dd -r fa00fb053c72 benchmarks/sieve/src/test/java/org/apidesign/benchmark/sieve/n64/LongSieveTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/benchmarks/sieve/src/test/java/org/apidesign/benchmark/sieve/n64/LongSieveTest.java Tue Jan 26 05:54:37 2016 +0100 @@ -0,0 +1,79 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012-2015 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.benchmark.sieve.n64; + +import java.io.IOException; +import net.java.html.js.JavaScriptBody; +import org.apidesign.bck2brwsr.vmtest.Compare; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +public class LongSieveTest extends Primes { + public LongSieveTest() { + } + + @JavaScriptBody(args = { }, body = "return new Date().getTime();") + protected int time() { + return (int) System.currentTimeMillis(); + } + + @Compare + public long oneThousand() throws IOException { + LongSieveTest sieve = new LongSieveTest(); + int now = time(); + long res = sieve.compute(1000); + int took = time() - now; + log("oneThousand in " + took + " ms"); + return res; + } + +/* + @Compare(slowdown = 3.0) + public long fiveThousand() throws IOException { + LongSieveTest sieve = new LongSieveTest(); + int now = time(); + long res = sieve.compute(5000); + int took = time() - now; + log("oneThousand in " + took + " ms"); + return res; + } + @Compare(slowdown = 3.0) + public long tenThousand() throws IOException { + LongSieveTest sieve = new LongSieveTest(); + int now = time(); + long res = sieve.compute(10000); + int took = time() - now; + log("oneThousand in " + took + " ms"); + return res; + } +*/ + @Factory + public static Object[] create() { + return VMTest.create(LongSieveTest.class); + } + + @JavaScriptBody(args = { "msg" }, body = "if (typeof console !== 'undefined') console.log(msg);") + @Override + protected void log(String msg) { + System.err.println(msg); + } +} diff -r 433856f897dd -r fa00fb053c72 rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Jan 26 04:42:06 2016 +0100 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Jan 26 05:54:37 2016 +0100 @@ -735,7 +735,7 @@ smapper.replace(this, VarType.INTEGER, "(((@1) + (@2)) | 0)", smapper.getI(1), smapper.popI()); break; case opc_ladd: - smapper.replace(this, VarType.LONG, "(@1).add64(@2)", smapper.getL(1), smapper.popL()); + smapper.replace(this, VarType.LONG, numbers.add64(), smapper.getL(1), smapper.popL()); break; case opc_fadd: smapper.replace(this, VarType.FLOAT, "(@1 + @2)", smapper.getF(1), smapper.popF()); @@ -747,7 +747,7 @@ smapper.replace(this, VarType.INTEGER, "(((@1) - (@2)) | 0)", smapper.getI(1), smapper.popI()); break; case opc_lsub: - smapper.replace(this, VarType.LONG, "(@1).sub64(@2)", smapper.getL(1), smapper.popL()); + smapper.replace(this, VarType.LONG, numbers.sub64(), smapper.getL(1), smapper.popL()); break; case opc_fsub: smapper.replace(this, VarType.FLOAT, "(@1 - @2)", smapper.getF(1), smapper.popF()); @@ -759,7 +759,7 @@ smapper.replace(this, VarType.INTEGER, numbers.mul32(), smapper.getI(1), smapper.popI()); break; case opc_lmul: - smapper.replace(this, VarType.LONG, "(@1).mul64(@2)", smapper.getL(1), smapper.popL()); + smapper.replace(this, VarType.LONG, numbers.mul64(), smapper.getL(1), smapper.popL()); break; case opc_fmul: smapper.replace(this, VarType.FLOAT, "(@1 * @2)", smapper.getF(1), smapper.popF()); @@ -772,7 +772,7 @@ smapper.getI(1), smapper.popI()); break; case opc_ldiv: - smapper.replace(this, VarType.LONG, "(@1).div64(@2)", + smapper.replace(this, VarType.LONG, numbers.div64(), smapper.getL(1), smapper.popL()); break; case opc_fdiv: @@ -786,7 +786,7 @@ smapper.getI(1), smapper.popI()); break; case opc_lrem: - smapper.replace(this, VarType.LONG, "(@1).mod64(@2)", + smapper.replace(this, VarType.LONG, numbers.mod64(), smapper.getL(1), smapper.popL()); break; case opc_frem: @@ -799,25 +799,25 @@ smapper.replace(this, VarType.INTEGER, "(@1 & @2)", smapper.getI(1), smapper.popI()); break; case opc_land: - smapper.replace(this, VarType.LONG, "(@1).and64(@2)", smapper.getL(1), smapper.popL()); + smapper.replace(this, VarType.LONG, numbers.and64(), smapper.getL(1), smapper.popL()); break; case opc_ior: smapper.replace(this, VarType.INTEGER, "(@1 | @2)", smapper.getI(1), smapper.popI()); break; case opc_lor: - smapper.replace(this, VarType.LONG, "(@1).or64(@2)", smapper.getL(1), smapper.popL()); + smapper.replace(this, VarType.LONG, numbers.or64(), smapper.getL(1), smapper.popL()); break; case opc_ixor: smapper.replace(this, VarType.INTEGER, "(@1 ^ @2)", smapper.getI(1), smapper.popI()); break; case opc_lxor: - smapper.replace(this, VarType.LONG, "(@1).xor64(@2)", smapper.getL(1), smapper.popL()); + smapper.replace(this, VarType.LONG, numbers.xor64(), smapper.getL(1), smapper.popL()); break; case opc_ineg: smapper.replace(this, VarType.INTEGER, "(-(@1))", smapper.getI(0)); break; case opc_lneg: - smapper.replace(this, VarType.LONG, "(@1).neg64()", smapper.getL(0)); + smapper.replace(this, VarType.LONG, numbers.neg64(), smapper.getL(0)); break; case opc_fneg: smapper.replace(this, VarType.FLOAT, "(-@1)", smapper.getF(0)); @@ -829,19 +829,19 @@ smapper.replace(this, VarType.INTEGER, "(@1 << @2)", smapper.getI(1), smapper.popI()); break; case opc_lshl: - smapper.replace(this, VarType.LONG, "(@1).shl64(@2)", smapper.getL(1), smapper.popI()); + smapper.replace(this, VarType.LONG, numbers.shl64(), smapper.getL(1), smapper.popI()); break; case opc_ishr: smapper.replace(this, VarType.INTEGER, "(@1 >> @2)", smapper.getI(1), smapper.popI()); break; case opc_lshr: - smapper.replace(this, VarType.LONG, "(@1).shr64(@2)", smapper.getL(1), smapper.popI()); + smapper.replace(this, VarType.LONG, numbers.shr64(), smapper.getL(1), smapper.popI()); break; case opc_iushr: smapper.replace(this, VarType.INTEGER, "(@1 >>> @2)", smapper.getI(1), smapper.popI()); break; case opc_lushr: - smapper.replace(this, VarType.LONG, "(@1).ushr64(@2)", smapper.getL(1), smapper.popI()); + smapper.replace(this, VarType.LONG, numbers.ushr64(), smapper.getL(1), smapper.popI()); break; case opc_iinc: { ++i; @@ -1003,7 +1003,7 @@ break; } case opc_lcmp: - smapper.replace(this, VarType.INTEGER, "(@2).compare64(@1)", smapper.popL(), smapper.getL(0)); + smapper.replace(this, VarType.INTEGER, numbers.compare64(), smapper.popL(), smapper.getL(0)); break; case opc_fcmpl: case opc_fcmpg: diff -r 433856f897dd -r fa00fb053c72 rt/vm/src/main/java/org/apidesign/vm4brwsr/NumberOperations.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/NumberOperations.java Tue Jan 26 04:42:06 2016 +0100 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/NumberOperations.java Tue Jan 26 05:54:37 2016 +0100 @@ -38,6 +38,58 @@ return "__mod32(@1,@2)"; } + public String add64() { + return "(@1).add64(@2)"; + } + + public String sub64() { + return "(@1).sub64(@2)"; + } + + public String mul64() { + return "(@1).mul64(@2)"; + } + + public String div64() { + return "(@1).div64(@2)"; + } + + public String mod64() { + return "(@1).mod64(@2)"; + } + + public String and64() { + return "(@1).and64(@2)"; + } + + public String or64() { + return "(@1).or64(@2)"; + } + + public String xor64() { + return "(@1).xor64(@2)"; + } + + public String neg64() { + return "(@1).neg64()"; + } + + public String shl64() { + return "(@1).shl64(@2)"; + } + + public String shr64() { + return "(@1).shr64(@2)"; + } + + public String ushr64() { + return "(@1).ushr64(@2)"; + } + + public String compare64() { + return "(@2).compare64(@1)"; + } + public String generate() { if (used == 0) { return "";