Reputation: 5463
I'm learning Dalvik bytecode now, it has many differences from the JVM bytecode. I want to know what optimizations it makes when converting java bytecode into dalvik bytecode.
The optimization I'm talking about is not like converting to registers or reducing the size of bytecode, I want to know about control flow merging and code reuse.
For example: jvm's byetcode:
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."<init>":()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
same method in dalvik bytecode
[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;.<init>:()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
the dalvik bytecode reuses return-void at offset 0012, and if statement's true target also can reuses the return-void.
This looks like if a return occurs, then the following places that need to return will jump to the first return.
Upvotes: 0
Views: 76