Я хочу знать, какие оптимизации он производит при преобразовании байт-кода Java в байт-код dalvik.
Оптимизация, о которой я говорю, не похожа на преобразование в регистры или уменьшение размера байт-кода. Я хочу знать об объединении потоков управления и повторном использовании кода.
Например:
байт-код jvm:
Код: Выделить всё
public static void demo();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=4, args_size=0
0: new #2 // class java/util/Random
3: dup
4: invokespecial #3 // Method java/util/Random."":()V
7: astore_0
8: aload_0
9: invokevirtual #4 // Method java/util/Random.nextInt:()I
12: istore_1
13: iload_1
14: ifge 27
17: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
20: iload_1
21: invokevirtual #6 // Method java/io/PrintStream.println:(I)V
24: goto 147
27: iload_1
28: iconst_1
29: if_icmple 116
32: iload_1
33: iconst_4
34: if_icmpge 116
37: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
40: iload_1
41: iconst_1
42: iadd
43: invokevirtual #6 // Method java/io/PrintStream.println:(I)V
46: aload_0
47: invokevirtual #4 // Method java/util/Random.nextInt:()I
50: istore_2
51: aload_0
52: invokevirtual #4 // Method java/util/Random.nextInt:()I
55: istore_3
56: iload_2
57: bipush 10
59: if_icmple 73
62: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
65: ldc #7 // String abc is 10
67: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
70: goto 113
73: iload_2
74: bipush 20
76: if_icmple 113
79: iload_2
80: bipush 100
82: if_icmpge 113
85: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
88: ldc #9 // String abc less 100
90: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
93: iload_3
94: sipush 1000
97: if_icmple 113
100: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
103: ldc #10 // String ccc
105: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
108: aload_0
109: invokevirtual #4 // Method java/util/Random.nextInt:()I
112: istore_3
113: goto 147
116: iload_1
117: iconst_3
118: if_icmpeq 127
121: iload_1
122: bipush 10
124: if_icmple 139
127: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
130: iload_1
131: iconst_3
132: iadd
133: invokevirtual #6 // Method java/io/PrintStream.println:(I)V
136: goto 147
139: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
142: ldc #11 // String n
144: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
147: return
Код: Выделить всё
[000198] IfTest.demo:()V
0000: const/16 v3, #int 10 // #a
0002: new-instance v0, Ljava/util/Random; // type@0006
0004: invoke-direct {v0}, Ljava/util/Random;.:()V // method@0006
0007: invoke-virtual {v0}, Ljava/util/Random;.nextInt:()I // method@0007
000a: move-result v1
000b: if-gez v1, 0013 // +0008
000d: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
000f: invoke-virtual {v0, v1}, Ljava/io/PrintStream;.println:(I)V // method@0003
0012: return-void
0013: const/4 v2, #int 1 // #1
0014: if-le v1, v2, 0050 // +003c
0016: const/4 v2, #int 4 // #4
0017: if-ge v1, v2, 0050 // +0039
0019: sget-object v2, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
001b: add-int/lit8 v1, v1, #int 1 // #01
001d: invoke-virtual {v2, v1}, Ljava/io/PrintStream;.println:(I)V // method@0003
0020: invoke-virtual {v0}, Ljava/util/Random;.nextInt:()I // method@0007
0023: move-result v1
0024: invoke-virtual {v0}, Ljava/util/Random;.nextInt:()I // method@0007
0027: move-result v2
0028: if-le v1, v3, 0032 // +000a
002a: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
002c: const-string v1, "abc is 10" // string@000d
002e: invoke-virtual {v0, v1}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // method@0004
0031: goto 0012 // -001f
0032: const/16 v3, #int 20 // #14
0034: if-le v1, v3, 0012 // -0022
0036: const/16 v3, #int 100 // #64
0038: if-ge v1, v3, 0012 // -0026
003a: sget-object v1, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
003c: const-string v3, "abc less 100" // string@000e
003e: invoke-virtual {v1, v3}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // method@0004
0041: const/16 v1, #int 1000 // #3e8
0043: if-le v2, v1, 0012 // -0031
0045: sget-object v1, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
0047: const-string v2, "ccc" // string@000f
0049: invoke-virtual {v1, v2}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // method@0004
004c: invoke-virtual {v0}, Ljava/util/Random;.nextInt:()I // method@0007
004f: goto 0012 // -003d
0050: const/4 v0, #int 3 // #3
0051: if-eq v1, v0, 0055 // +0004
0053: if-le v1, v3, 005d // +000a
0055: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
0057: add-int/lit8 v1, v1, #int 3 // #03
0059: invoke-virtual {v0, v1}, Ljava/io/PrintStream;.println:(I)V // method@0003
005c: goto 0012 // -004a
005d: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
005f: const-string v1, "n" // string@0011
0061: invoke-virtual {v0, v1}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // method@0004
0064: goto 0012 // -0052
Похоже, что если произойдет возврат, то следующие места, которые необходимо вернуть, перейдут к первому возврату.
Подробнее здесь: https://stackoverflow.com/questions/791 ... ds-dx-tool
Мобильная версия