1 // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file 2 // for details. All rights reserved. Use of this source code is governed by a 3 // BSD-style license that can be found in the LICENSE file. 4 package inlining; 5 6 class A { 7 8 int a; 9 A(int a)10 A(int a) { 11 this.a = a; 12 } 13 a()14 int a() { 15 return a; 16 } 17 } 18 19 class B extends A { 20 B(int a)21 B(int a) { 22 super(a); 23 } 24 } 25 26 class InlineConstructor { 27 28 int a; 29 30 @CheckDiscarded InlineConstructor(int a)31 InlineConstructor(int a) { 32 this.a = a; 33 } 34 35 @CheckDiscarded InlineConstructor(long a)36 InlineConstructor(long a) { 37 this((int) a); 38 } 39 create()40 static InlineConstructor create() { 41 return new InlineConstructor(10L); 42 } 43 } 44 45 class InlineConstructorOfInner { 46 47 class Inner { 48 49 int a; 50 51 @CheckDiscarded Inner(int a)52 Inner(int a) { 53 this.a = a; 54 } 55 56 // This is not inlined, even though it is only called once, as it is only called from a 57 // non-constructor, and will set a field (the outer object) before calling the other 58 // constructor. Inner(long a)59 Inner(long a) { 60 this((int) a); 61 } 62 create()63 public Inner create() { 64 return new Inner(10L); 65 } 66 } 67 68 Inner inner; 69 InlineConstructorOfInner()70 InlineConstructorOfInner() { 71 inner = new Inner(10L).create(); 72 } 73 } 74 75 public class Inlining { 76 Assert(boolean value)77 private static void Assert(boolean value) { 78 if (!value) { 79 System.out.println("FAILURE"); 80 } 81 } 82 main(String[] args)83 public static void main(String[] args) { 84 // Ensure the simple methods are called at least three times, to not be inlined due to being 85 // called only once or twice. 86 Assert(intExpression()); 87 Assert(intExpression()); 88 Assert(intExpression()); 89 Assert(longExpression()); 90 Assert(longExpression()); 91 Assert(longExpression()); 92 Assert(doubleExpression()); 93 Assert(floatExpression()); 94 Assert(floatExpression()); 95 Assert(floatExpression()); 96 Assert(stringExpression()); 97 Assert(stringExpression()); 98 Assert(stringExpression()); 99 100 Assert(intArgumentExpression()); 101 Assert(intArgumentExpression()); 102 Assert(intArgumentExpression()); 103 Assert(longArgumentExpression()); 104 Assert(longArgumentExpression()); 105 Assert(longArgumentExpression()); 106 Assert(doubleArgumentExpression()); 107 Assert(doubleArgumentExpression()); 108 Assert(doubleArgumentExpression()); 109 Assert(floatArgumentExpression()); 110 Assert(floatArgumentExpression()); 111 Assert(floatArgumentExpression()); 112 Assert(stringArgumentExpression()); 113 Assert(stringArgumentExpression()); 114 Assert(stringArgumentExpression()); 115 116 Assert(intAddExpression()); 117 Assert(intAddExpression()); 118 Assert(intAddExpression()); 119 120 A b = new B(42); 121 A a = new A(42); 122 Assert(intCmpExpression(a, b)); 123 Assert(intCmpExpression(a, b)); 124 Assert(intCmpExpression(a, b)); 125 126 // This is only called once! 127 Assert(onlyCalledOnce(10)); 128 129 // This is only called twice, and is quite small! 130 Assert(onlyCalledTwice(1) == 2); 131 Assert(onlyCalledTwice(1) == 2); 132 133 InlineConstructor ic = InlineConstructor.create(); 134 Assert(ic != null); 135 InlineConstructorOfInner icoi = new InlineConstructorOfInner(); 136 Assert(icoi != null); 137 } 138 intCmpExpression(A a, A b)139 private static boolean intCmpExpression(A a, A b) { 140 return a.a() == b.a(); 141 } 142 143 @CheckDiscarded intConstantInline()144 private static int intConstantInline() { 145 return 42; 146 } 147 148 @CheckDiscarded intExpression()149 private static boolean intExpression() { 150 return 42 == intConstantInline(); 151 } 152 153 @CheckDiscarded longConstantInline()154 private static long longConstantInline() { 155 return 50000000000L; 156 } 157 158 @CheckDiscarded longExpression()159 private static boolean longExpression() { 160 return 50000000000L == longConstantInline(); 161 } 162 163 @CheckDiscarded doubleConstantInline()164 private static double doubleConstantInline() { 165 return 42.42; 166 } 167 168 @CheckDiscarded doubleExpression()169 private static boolean doubleExpression() { 170 return 42.42 == doubleConstantInline(); 171 } 172 173 @CheckDiscarded floatConstantInline()174 private static float floatConstantInline() { 175 return 21.21F; 176 } 177 178 @CheckDiscarded floatExpression()179 private static boolean floatExpression() { 180 return 21.21F == floatConstantInline(); 181 } 182 stringConstantInline()183 private static String stringConstantInline() { 184 return "Fisk er godt"; 185 } 186 stringExpression()187 private static boolean stringExpression() { 188 return "Fisk er godt" == stringConstantInline(); 189 } 190 191 @CheckDiscarded intArgumentInline(int a, int b, int c)192 private static int intArgumentInline(int a, int b, int c) { 193 return b; 194 } 195 196 @CheckDiscarded intArgumentExpression()197 private static boolean intArgumentExpression() { 198 return 42 == intArgumentInline(-2, 42, -1); 199 } 200 201 @CheckDiscarded longArgumentInline(long a, long b, long c)202 private static long longArgumentInline(long a, long b, long c) { 203 return c; 204 } 205 206 @CheckDiscarded longArgumentExpression()207 private static boolean longArgumentExpression() { 208 return 50000000000L == longArgumentInline(-2L, -1L, 50000000000L); 209 } 210 211 @CheckDiscarded doubleArgumentInline(double a, double b, double c)212 private static double doubleArgumentInline(double a, double b, double c) { 213 return a; 214 } 215 216 @CheckDiscarded doubleArgumentExpression()217 private static boolean doubleArgumentExpression() { 218 return 42.42 == doubleArgumentInline(42.42, -2.0, -1.0); 219 } 220 221 @CheckDiscarded floatArgumentInline(float a, float b, float c)222 private static float floatArgumentInline(float a, float b, float c) { 223 return b; 224 } 225 226 @CheckDiscarded floatArgumentExpression()227 private static boolean floatArgumentExpression() { 228 return 21.21F == floatArgumentInline(-2.0F, 21.21F, -1.0F); 229 } 230 231 @CheckDiscarded stringArgumentInline(String a, String b, String c)232 private static String stringArgumentInline(String a, String b, String c) { 233 return c; 234 } 235 stringArgumentExpression()236 private static boolean stringArgumentExpression() { 237 return "Fisk er godt" == stringArgumentInline("-1", "-1", "Fisk er godt"); 238 } 239 240 @CheckDiscarded intAddInline(int a, int b)241 private static int intAddInline(int a, int b) { 242 return a + b; 243 } 244 245 @CheckDiscarded intAddExpression()246 private static boolean intAddExpression() { 247 return 42 == intAddInline(21, 21); 248 } 249 250 @CheckDiscarded onlyCalledOnce(int count)251 private static boolean onlyCalledOnce(int count) { 252 int anotherCounter = 0; 253 for (int i = 0; i < count; i++) { 254 anotherCounter += i; 255 } 256 return anotherCounter > count; 257 } 258 259 @CheckDiscarded onlyCalledTwice(int count)260 private static int onlyCalledTwice(int count) { 261 return count > 0 ? count + 1 : count - 1; 262 } 263 } 264