Centralizing the stack pushes into single assign method ReducedStack
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 15 Feb 2014 14:36:43 +0100
branchReducedStack
changeset 1453e046cfcb8f00
parent 1437 3ec3ae9699ef
child 1454 ca83b2adebb5
Centralizing the stack pushes into single assign method
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java
rt/vm/src/test/java/org/apidesign/vm4brwsr/SizeOfAMethodTest.java
rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Fri Feb 07 10:03:44 2014 +0100
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sat Feb 15 14:36:43 2014 +0100
     1.3 @@ -367,72 +367,71 @@
     1.4              final int c = readUByte(byteCodes, i);
     1.5              switch (c) {
     1.6                  case opc_aload_0:
     1.7 -                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(0));
     1.8 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(0));
     1.9                      break;
    1.10                  case opc_iload_0:
    1.11 -                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(0));
    1.12 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(0));
    1.13                      break;
    1.14                  case opc_lload_0:
    1.15 -                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(0));
    1.16 +                    smapper.assign(out, VarType.LONG, lmapper.getL(0));
    1.17                      break;
    1.18                  case opc_fload_0:
    1.19 -                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(0));
    1.20 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(0));
    1.21                      break;
    1.22                  case opc_dload_0:
    1.23 -                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(0));
    1.24 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(0));
    1.25                      break;
    1.26                  case opc_aload_1:
    1.27 -                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(1));
    1.28 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(1));
    1.29                      break;
    1.30                  case opc_iload_1:
    1.31 -                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(1));
    1.32 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(1));
    1.33                      break;
    1.34                  case opc_lload_1:
    1.35 -                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(1));
    1.36 +                    smapper.assign(out, VarType.LONG, lmapper.getL(1));
    1.37                      break;
    1.38                  case opc_fload_1:
    1.39 -                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(1));
    1.40 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(1));
    1.41                      break;
    1.42                  case opc_dload_1:
    1.43 -                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(1));
    1.44 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(1));
    1.45                      break;
    1.46                  case opc_aload_2:
    1.47 -                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(2));
    1.48 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(2));
    1.49                      break;
    1.50                  case opc_iload_2:
    1.51 -                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(2));
    1.52 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(2));
    1.53                      break;
    1.54                  case opc_lload_2:
    1.55 -                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(2));
    1.56 +                    smapper.assign(out, VarType.LONG, lmapper.getL(2));
    1.57                      break;
    1.58                  case opc_fload_2:
    1.59 -                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(2));
    1.60 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(2));
    1.61                      break;
    1.62                  case opc_dload_2:
    1.63 -                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(2));
    1.64 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(2));
    1.65                      break;
    1.66                  case opc_aload_3:
    1.67 -                    emit(out, "var @1 = @2;", smapper.pushA(), lmapper.getA(3));
    1.68 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(3));
    1.69                      break;
    1.70                  case opc_iload_3:
    1.71 -                    emit(out, "var @1 = @2;", smapper.pushI(), lmapper.getI(3));
    1.72 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(3));
    1.73                      break;
    1.74                  case opc_lload_3:
    1.75 -                    emit(out, "var @1 = @2;", smapper.pushL(), lmapper.getL(3));
    1.76 +                    smapper.assign(out, VarType.LONG, lmapper.getL(3));
    1.77                      break;
    1.78                  case opc_fload_3:
    1.79 -                    emit(out, "var @1 = @2;", smapper.pushF(), lmapper.getF(3));
    1.80 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(3));
    1.81                      break;
    1.82                  case opc_dload_3:
    1.83 -                    emit(out, "var @1 = @2;", smapper.pushD(), lmapper.getD(3));
    1.84 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(3));
    1.85                      break;
    1.86                  case opc_iload: {
    1.87                      ++i;
    1.88                      final int indx = wide ? readUShort(byteCodes, i++)
    1.89                                            : readUByte(byteCodes, i);
    1.90                      wide = false;
    1.91 -                    emit(out, "var @1 = @2;",
    1.92 -                         smapper.pushI(), lmapper.getI(indx));
    1.93 +                    smapper.assign(out, VarType.INTEGER, lmapper.getI(indx));
    1.94                      break;
    1.95                  }
    1.96                  case opc_lload: {
    1.97 @@ -440,8 +439,7 @@
    1.98                      final int indx = wide ? readUShort(byteCodes, i++)
    1.99                                            : readUByte(byteCodes, i);
   1.100                      wide = false;
   1.101 -                    emit(out, "var @1 = @2;",
   1.102 -                         smapper.pushL(), lmapper.getL(indx));
   1.103 +                    smapper.assign(out, VarType.LONG, lmapper.getL(indx));
   1.104                      break;
   1.105                  }
   1.106                  case opc_fload: {
   1.107 @@ -449,8 +447,7 @@
   1.108                      final int indx = wide ? readUShort(byteCodes, i++)
   1.109                                            : readUByte(byteCodes, i);
   1.110                      wide = false;
   1.111 -                    emit(out, "var @1 = @2;",
   1.112 -                         smapper.pushF(), lmapper.getF(indx));
   1.113 +                    smapper.assign(out, VarType.FLOAT, lmapper.getF(indx));
   1.114                      break;
   1.115                  }
   1.116                  case opc_dload: {
   1.117 @@ -458,8 +455,7 @@
   1.118                      final int indx = wide ? readUShort(byteCodes, i++)
   1.119                                            : readUByte(byteCodes, i);
   1.120                      wide = false;
   1.121 -                    emit(out, "var @1 = @2;",
   1.122 -                         smapper.pushD(), lmapper.getD(indx));
   1.123 +                    smapper.assign(out, VarType.DOUBLE, lmapper.getD(indx));
   1.124                      break;
   1.125                  }
   1.126                  case opc_aload: {
   1.127 @@ -467,8 +463,7 @@
   1.128                      final int indx = wide ? readUShort(byteCodes, i++)
   1.129                                            : readUByte(byteCodes, i);
   1.130                      wide = false;
   1.131 -                    emit(out, "var @1 = @2;",
   1.132 -                         smapper.pushA(), lmapper.getA(indx));
   1.133 +                    smapper.assign(out, VarType.REFERENCE, lmapper.getA(indx));
   1.134                      break;
   1.135                  }
   1.136                  case opc_istore: {
   1.137 @@ -1935,7 +1930,7 @@
   1.138          return ",";
   1.139      }
   1.140  
   1.141 -    private static void emit(final Appendable out,
   1.142 +    static void emit(final Appendable out,
   1.143                               final String format,
   1.144                               final CharSequence... params) throws IOException {
   1.145          final int length = format.length();
     2.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java	Fri Feb 07 10:03:44 2014 +0100
     2.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java	Sat Feb 15 14:36:43 2014 +0100
     2.3 @@ -17,6 +17,7 @@
     2.4   */
     2.5  package org.apidesign.vm4brwsr;
     2.6  
     2.7 +import java.io.IOException;
     2.8  import org.apidesign.vm4brwsr.ByteCodeParser.TypeArray;
     2.9  
    2.10  final class StackMapper {
    2.11 @@ -70,6 +71,10 @@
    2.12          return getVariable(pushTypeImpl(type));
    2.13      }
    2.14  
    2.15 +    void assign(Appendable out, int varType, CharSequence s) throws IOException {
    2.16 +        ByteCodeToJavaScript.emit(out, "var @1 = @2;", pushT(varType), s);
    2.17 +    }
    2.18 +    
    2.19      public Variable popI() {
    2.20          return popT(VarType.INTEGER);
    2.21      }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/SizeOfAMethodTest.java	Sat Feb 15 14:36:43 2014 +0100
     3.3 @@ -0,0 +1,63 @@
     3.4 +/**
     3.5 + * Back 2 Browser Bytecode Translator
     3.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     3.7 + *
     3.8 + * This program is free software: you can redistribute it and/or modify
     3.9 + * it under the terms of the GNU General Public License as published by
    3.10 + * the Free Software Foundation, version 2 of the License.
    3.11 + *
    3.12 + * This program is distributed in the hope that it will be useful,
    3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.15 + * GNU General Public License for more details.
    3.16 + *
    3.17 + * You should have received a copy of the GNU General Public License
    3.18 + * along with this program. Look for COPYING file in the top folder.
    3.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    3.20 + */
    3.21 +/*
    3.22 + * To change this license header, choose License Headers in Project Properties.
    3.23 + * To change this template file, choose Tools | Templates
    3.24 + * and open the template in the editor.
    3.25 + */
    3.26 +
    3.27 +package org.apidesign.vm4brwsr;
    3.28 +
    3.29 +import static org.testng.Assert.assertEquals;
    3.30 +import static org.testng.Assert.assertTrue;
    3.31 +import org.testng.annotations.AfterClass;
    3.32 +import org.testng.annotations.BeforeClass;
    3.33 +import org.testng.annotations.Test;
    3.34 +
    3.35 +/**
    3.36 + *
    3.37 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    3.38 + */
    3.39 +public class SizeOfAMethodTest {
    3.40 +    private static TestVM code;
    3.41 +
    3.42 +    @Test public void sumXYShouldBeSmall() {
    3.43 +        String s = code.codeSeq().toString();
    3.44 +        int beg = s.indexOf("c.sum__III");
    3.45 +        int end = s.indexOf("c.sum__III.access");
    3.46 +        
    3.47 +        assertTrue(beg > 0, "Found sum method in " + code.toString());
    3.48 +        assertTrue(beg < end, "Found end of sum method in " + code.toString());
    3.49 +        
    3.50 +        String method = s.substring(beg, end);
    3.51 +        
    3.52 +        assertEquals(method.indexOf("st"), -1, "There should be no stack operations:\n" + method);
    3.53 +    }
    3.54 +    
    3.55 +    
    3.56 +    @BeforeClass 
    3.57 +    public static void compileTheCode() throws Exception {
    3.58 +        StringBuilder sb = new StringBuilder();
    3.59 +        code = TestVM.compileClass(sb, "org/apidesign/vm4brwsr/StaticMethod");
    3.60 +    }
    3.61 +    @AfterClass
    3.62 +    public static void releaseTheCode() {
    3.63 +        code = null;
    3.64 +    }
    3.65 +    
    3.66 +}
     4.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java	Fri Feb 07 10:03:44 2014 +0100
     4.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java	Sat Feb 15 14:36:43 2014 +0100
     4.3 @@ -164,7 +164,10 @@
     4.4              return ex.toString();
     4.5          }
     4.6      }
     4.7 -    
     4.8 +
     4.9 +    final CharSequence codeSeq() {
    4.10 +        return codeSeq;
    4.11 +    }
    4.12      
    4.13      private static class EmulationResources implements Bck2Brwsr.Resources {
    4.14          @Override