1.1 --- a/test/tools/javac/lambda/TestInvokeDynamic.java Tue Jan 08 10:17:29 2013 +0100 1.2 +++ b/test/tools/javac/lambda/TestInvokeDynamic.java Tue Jan 08 13:47:57 2013 +0000 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -28,7 +28,9 @@ 1.11 * @bug 8003280 1.12 * @summary Add lambda tests 1.13 * Add back-end support for invokedynamic 1.14 - * 1.15 + * @library ../lib 1.16 + * @build JavacTestingAbstractThreadedTest 1.17 + * @run main TestInvokeDynamic 1.18 */ 1.19 1.20 import com.sun.source.tree.MethodInvocationTree; 1.21 @@ -66,7 +68,6 @@ 1.22 1.23 import javax.tools.Diagnostic; 1.24 import javax.tools.JavaCompiler; 1.25 -import javax.tools.JavaFileManager; 1.26 import javax.tools.JavaFileObject; 1.27 import javax.tools.SimpleJavaFileObject; 1.28 import javax.tools.StandardJavaFileManager; 1.29 @@ -74,69 +75,80 @@ 1.30 1.31 import static com.sun.tools.javac.jvm.ClassFile.*; 1.32 1.33 -public class TestInvokeDynamic { 1.34 - 1.35 - static int checkCount = 0; 1.36 +public class TestInvokeDynamic 1.37 + extends JavacTestingAbstractThreadedTest 1.38 + implements Runnable { 1.39 1.40 enum StaticArgumentKind { 1.41 STRING("Hello!", "String", "Ljava/lang/String;") { 1.42 @Override 1.43 boolean check(CPInfo cpInfo) throws Exception { 1.44 return (cpInfo instanceof CONSTANT_String_info) && 1.45 - ((CONSTANT_String_info)cpInfo).getString().equals(value); 1.46 + ((CONSTANT_String_info)cpInfo).getString() 1.47 + .equals(value); 1.48 } 1.49 }, 1.50 CLASS(null, "Class<?>", "Ljava/lang/Class;") { 1.51 @Override 1.52 boolean check(CPInfo cpInfo) throws Exception { 1.53 return (cpInfo instanceof CONSTANT_Class_info) && 1.54 - ((CONSTANT_Class_info)cpInfo).getName().equals("java/lang/String"); 1.55 + ((CONSTANT_Class_info)cpInfo).getName() 1.56 + .equals("java/lang/String"); 1.57 } 1.58 }, 1.59 INTEGER(1, "int", "I") { 1.60 @Override 1.61 boolean check(CPInfo cpInfo) throws Exception { 1.62 return (cpInfo instanceof CONSTANT_Integer_info) && 1.63 - ((CONSTANT_Integer_info)cpInfo).value == ((Integer)value).intValue(); 1.64 + ((CONSTANT_Integer_info)cpInfo).value == 1.65 + ((Integer)value).intValue(); 1.66 } 1.67 }, 1.68 LONG(1L, "long", "J") { 1.69 @Override 1.70 boolean check(CPInfo cpInfo) throws Exception { 1.71 return (cpInfo instanceof CONSTANT_Long_info) && 1.72 - ((CONSTANT_Long_info)cpInfo).value == ((Long)value).longValue(); 1.73 + ((CONSTANT_Long_info)cpInfo).value == 1.74 + ((Long)value).longValue(); 1.75 } 1.76 }, 1.77 FLOAT(1.0f, "float", "F") { 1.78 @Override 1.79 boolean check(CPInfo cpInfo) throws Exception { 1.80 return (cpInfo instanceof CONSTANT_Float_info) && 1.81 - ((CONSTANT_Float_info)cpInfo).value == ((Float)value).floatValue(); 1.82 + ((CONSTANT_Float_info)cpInfo).value == 1.83 + ((Float)value).floatValue(); 1.84 } 1.85 }, 1.86 DOUBLE(1.0, "double","D") { 1.87 @Override 1.88 boolean check(CPInfo cpInfo) throws Exception { 1.89 return (cpInfo instanceof CONSTANT_Double_info) && 1.90 - ((CONSTANT_Double_info)cpInfo).value == ((Double)value).doubleValue(); 1.91 + ((CONSTANT_Double_info)cpInfo).value == 1.92 + ((Double)value).doubleValue(); 1.93 } 1.94 }, 1.95 METHOD_HANDLE(null, "MethodHandle", "Ljava/lang/invoke/MethodHandle;") { 1.96 @Override 1.97 boolean check(CPInfo cpInfo) throws Exception { 1.98 - if (!(cpInfo instanceof CONSTANT_MethodHandle_info)) return false; 1.99 - CONSTANT_MethodHandle_info handleInfo = (CONSTANT_MethodHandle_info)cpInfo; 1.100 + if (!(cpInfo instanceof CONSTANT_MethodHandle_info)) 1.101 + return false; 1.102 + CONSTANT_MethodHandle_info handleInfo = 1.103 + (CONSTANT_MethodHandle_info)cpInfo; 1.104 return handleInfo.getCPRefInfo().getClassName().equals("Array") && 1.105 handleInfo.reference_kind == RefKind.REF_invokeVirtual && 1.106 - handleInfo.getCPRefInfo().getNameAndTypeInfo().getName().equals("clone") && 1.107 - handleInfo.getCPRefInfo().getNameAndTypeInfo().getType().equals("()Ljava/lang/Object;"); 1.108 + handleInfo.getCPRefInfo() 1.109 + .getNameAndTypeInfo().getName().equals("clone") && 1.110 + handleInfo.getCPRefInfo() 1.111 + .getNameAndTypeInfo().getType().equals("()Ljava/lang/Object;"); 1.112 } 1.113 }, 1.114 METHOD_TYPE(null, "MethodType", "Ljava/lang/invoke/MethodType;") { 1.115 @Override 1.116 boolean check(CPInfo cpInfo) throws Exception { 1.117 return (cpInfo instanceof CONSTANT_MethodType_info) && 1.118 - ((CONSTANT_MethodType_info)cpInfo).getType().equals("()Ljava/lang/Object;"); 1.119 + ((CONSTANT_MethodType_info)cpInfo).getType() 1.120 + .equals("()Ljava/lang/Object;"); 1.121 } 1.122 }; 1.123 1.124 @@ -144,7 +156,8 @@ 1.125 String sourceTypeStr; 1.126 String bytecodeTypeStr; 1.127 1.128 - StaticArgumentKind(Object value, String sourceTypeStr, String bytecodeTypeStr) { 1.129 + StaticArgumentKind(Object value, String sourceTypeStr, 1.130 + String bytecodeTypeStr) { 1.131 this.value = value; 1.132 this.sourceTypeStr = sourceTypeStr; 1.133 this.bytecodeTypeStr = bytecodeTypeStr; 1.134 @@ -163,7 +176,8 @@ 1.135 case CLASS: 1.136 return syms.stringType.tsym; 1.137 case METHOD_HANDLE: 1.138 - return new Pool.MethodHandle(REF_invokeVirtual, syms.arrayCloneMethod, types); 1.139 + return new Pool.MethodHandle(REF_invokeVirtual, 1.140 + syms.arrayCloneMethod, types); 1.141 case METHOD_TYPE: 1.142 return syms.arrayCloneMethod.type; 1.143 default: 1.144 @@ -186,23 +200,21 @@ 1.145 } 1.146 1.147 public static void main(String... args) throws Exception { 1.148 - // Create a single file manager and compiler and reuse it for each compile to save time. 1.149 - StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null); 1.150 - final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); 1.151 for (StaticArgumentsArity arity : StaticArgumentsArity.values()) { 1.152 if (arity.arity == 0) { 1.153 - new TestInvokeDynamic(arity).compileAndCheck(fm, tool); 1.154 + pool.execute(new TestInvokeDynamic(arity)); 1.155 } else { 1.156 for (StaticArgumentKind sak1 : StaticArgumentKind.values()) { 1.157 if (arity.arity == 1) { 1.158 - new TestInvokeDynamic(arity, sak1).compileAndCheck(fm, tool); 1.159 + pool.execute(new TestInvokeDynamic(arity, sak1)); 1.160 } else { 1.161 for (StaticArgumentKind sak2 : StaticArgumentKind.values()) { 1.162 if (arity.arity == 2) { 1.163 - new TestInvokeDynamic(arity, sak1, sak2).compileAndCheck(fm, tool); 1.164 + pool.execute(new TestInvokeDynamic(arity, sak1, sak2)); 1.165 } else { 1.166 for (StaticArgumentKind sak3 : StaticArgumentKind.values()) { 1.167 - new TestInvokeDynamic(arity, sak1, sak2, sak3).compileAndCheck(fm, tool); 1.168 + pool.execute( 1.169 + new TestInvokeDynamic(arity, sak1, sak2, sak3)); 1.170 } 1.171 } 1.172 } 1.173 @@ -211,23 +223,23 @@ 1.174 } 1.175 } 1.176 1.177 - System.out.println("Total checks made: " + checkCount); 1.178 + checkAfterExec(); 1.179 } 1.180 1.181 StaticArgumentsArity arity; 1.182 StaticArgumentKind[] saks; 1.183 - JavaSource source; 1.184 DiagChecker dc; 1.185 1.186 TestInvokeDynamic(StaticArgumentsArity arity, StaticArgumentKind... saks) { 1.187 this.arity = arity; 1.188 this.saks = saks; 1.189 - source = new JavaSource(); 1.190 dc = new DiagChecker(); 1.191 } 1.192 1.193 - void compileAndCheck(JavaFileManager fm, JavaCompiler tool) throws Exception { 1.194 - JavacTaskImpl ct = (JavacTaskImpl)tool.getTask(null, fm, dc, 1.195 + public void run() { 1.196 + int id = checkCount.incrementAndGet(); 1.197 + JavaSource source = new JavaSource(id); 1.198 + JavacTaskImpl ct = (JavacTaskImpl)comp.getTask(null, fm.get(), dc, 1.199 null, null, Arrays.asList(source)); 1.200 Context context = ct.getContext(); 1.201 Symtab syms = Symtab.instance(context); 1.202 @@ -238,16 +250,20 @@ 1.203 ct.generate(); 1.204 } catch (Throwable t) { 1.205 t.printStackTrace(); 1.206 - throw new AssertionError(String.format("Error thrown when compiling following code\n%s", source.source)); 1.207 + throw new AssertionError( 1.208 + String.format("Error thrown when compiling following code\n%s", 1.209 + source.source)); 1.210 } 1.211 if (dc.diagFound) { 1.212 - throw new AssertionError(String.format("Diags found when compiling following code\n%s\n\n%s", source.source, dc.printDiags())); 1.213 + throw new AssertionError( 1.214 + String.format("Diags found when compiling following code\n%s\n\n%s", 1.215 + source.source, dc.printDiags())); 1.216 } 1.217 - verifyBytecode(); 1.218 + verifyBytecode(id); 1.219 } 1.220 1.221 - void verifyBytecode() { 1.222 - File compiledTest = new File("Test.class"); 1.223 + void verifyBytecode(int id) { 1.224 + File compiledTest = new File(String.format("Test%d.class", id)); 1.225 try { 1.226 ClassFile cf = ClassFile.read(compiledTest); 1.227 Method testMethod = null; 1.228 @@ -260,7 +276,8 @@ 1.229 if (testMethod == null) { 1.230 throw new Error("Test method not found"); 1.231 } 1.232 - Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code); 1.233 + Code_attribute ea = 1.234 + (Code_attribute)testMethod.attributes.get(Attribute.Code); 1.235 if (testMethod == null) { 1.236 throw new Error("Code attribute for test() method not found"); 1.237 } 1.238 @@ -270,10 +287,12 @@ 1.239 for (Instruction i : ea.getInstructions()) { 1.240 if (i.getMnemonic().equals("invokedynamic")) { 1.241 CONSTANT_InvokeDynamic_info indyInfo = 1.242 - (CONSTANT_InvokeDynamic_info)cf.constant_pool.get(i.getShort(1)); 1.243 + (CONSTANT_InvokeDynamic_info)cf 1.244 + .constant_pool.get(i.getShort(1)); 1.245 bsmIdx = indyInfo.bootstrap_method_attr_index; 1.246 if (!indyInfo.getNameAndTypeInfo().getType().equals("()V")) { 1.247 - throw new AssertionError("type mismatch for CONSTANT_InvokeDynamic_info"); 1.248 + throw new 1.249 + AssertionError("type mismatch for CONSTANT_InvokeDynamic_info"); 1.250 } 1.251 } 1.252 } 1.253 @@ -281,34 +300,41 @@ 1.254 throw new Error("Missing invokedynamic in generated code"); 1.255 } 1.256 1.257 - BootstrapMethods_attribute bsm_attr = (BootstrapMethods_attribute)cf.getAttribute(Attribute.BootstrapMethods); 1.258 + BootstrapMethods_attribute bsm_attr = 1.259 + (BootstrapMethods_attribute)cf 1.260 + .getAttribute(Attribute.BootstrapMethods); 1.261 if (bsm_attr.bootstrap_method_specifiers.length != 1) { 1.262 - throw new Error("Bad number of method specifiers in BootstrapMethods attribute"); 1.263 + throw new Error("Bad number of method specifiers " + 1.264 + "in BootstrapMethods attribute"); 1.265 } 1.266 BootstrapMethods_attribute.BootstrapMethodSpecifier bsm_spec = 1.267 bsm_attr.bootstrap_method_specifiers[0]; 1.268 1.269 if (bsm_spec.bootstrap_arguments.length != arity.arity) { 1.270 - throw new Error("Bad number of static invokedynamic args in BootstrapMethod attribute"); 1.271 + throw new Error("Bad number of static invokedynamic args " + 1.272 + "in BootstrapMethod attribute"); 1.273 } 1.274 1.275 int count = 0; 1.276 for (StaticArgumentKind sak : saks) { 1.277 - if (!sak.check(cf.constant_pool.get(bsm_spec.bootstrap_arguments[count]))) { 1.278 + if (!sak.check(cf.constant_pool 1.279 + .get(bsm_spec.bootstrap_arguments[count]))) { 1.280 throw new Error("Bad static argument value " + sak); 1.281 } 1.282 count++; 1.283 } 1.284 1.285 CONSTANT_MethodHandle_info bsm_handle = 1.286 - (CONSTANT_MethodHandle_info)cf.constant_pool.get(bsm_spec.bootstrap_method_ref); 1.287 + (CONSTANT_MethodHandle_info)cf.constant_pool 1.288 + .get(bsm_spec.bootstrap_method_ref); 1.289 1.290 if (bsm_handle.reference_kind != RefKind.REF_invokeStatic) { 1.291 throw new Error("Bad kind on boostrap method handle"); 1.292 } 1.293 1.294 CONSTANT_Methodref_info bsm_ref = 1.295 - (CONSTANT_Methodref_info)cf.constant_pool.get(bsm_handle.reference_index); 1.296 + (CONSTANT_Methodref_info)cf.constant_pool 1.297 + .get(bsm_handle.reference_index); 1.298 1.299 if (!bsm_ref.getClassInfo().getName().equals("Bootstrap")) { 1.300 throw new Error("Bad owner of boostrap method"); 1.301 @@ -318,8 +344,11 @@ 1.302 throw new Error("Bad boostrap method name"); 1.303 } 1.304 1.305 - if (!bsm_ref.getNameAndTypeInfo().getType().equals(asBSMSignatureString())) { 1.306 - throw new Error("Bad boostrap method type" + bsm_ref.getNameAndTypeInfo().getType() + " " + asBSMSignatureString()); 1.307 + if (!bsm_ref.getNameAndTypeInfo() 1.308 + .getType().equals(asBSMSignatureString())) { 1.309 + throw new Error("Bad boostrap method type" + 1.310 + bsm_ref.getNameAndTypeInfo().getType() + " " + 1.311 + asBSMSignatureString()); 1.312 } 1.313 } catch (Exception e) { 1.314 e.printStackTrace(); 1.315 @@ -341,20 +370,22 @@ 1.316 1.317 static final String source_template = "import java.lang.invoke.*;\n" + 1.318 "class Bootstrap {\n" + 1.319 - " public static CallSite bsm(MethodHandles.Lookup lookup, String name, MethodType methodType #SARGS) {\n" + 1.320 + " public static CallSite bsm(MethodHandles.Lookup lookup, " + 1.321 + "String name, MethodType methodType #SARGS) {\n" + 1.322 " return null;\n" + 1.323 " }\n" + 1.324 "}\n" + 1.325 - "class Test {\n" + 1.326 + "class Test#ID {\n" + 1.327 " void m() { }\n" + 1.328 " void test() { m(); }\n" + 1.329 "}"; 1.330 1.331 String source; 1.332 1.333 - JavaSource() { 1.334 + JavaSource(int id) { 1.335 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 1.336 - source = source_template.replace("#SARGS", asSignatureString()); 1.337 + source = source_template.replace("#SARGS", asSignatureString()) 1.338 + .replace("#ID", String.valueOf(id)); 1.339 } 1.340 1.341 @Override 1.342 @@ -411,7 +442,8 @@ 1.343 for (int i = 0; i < arity.arity ; i++) { 1.344 staticArgs[i] = saks[i].getValue(syms, names, types); 1.345 } 1.346 - ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name, oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs); 1.347 + ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name, 1.348 + oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs); 1.349 } 1.350 return null; 1.351 } 1.352 @@ -426,7 +458,8 @@ 1.353 } 1.354 } 1.355 1.356 - static class DiagChecker implements javax.tools.DiagnosticListener<JavaFileObject> { 1.357 + static class DiagChecker 1.358 + implements javax.tools.DiagnosticListener<JavaFileObject> { 1.359 1.360 boolean diagFound; 1.361 ArrayList<String> diags = new ArrayList<>(); 1.362 @@ -445,4 +478,5 @@ 1.363 return buf.toString(); 1.364 } 1.365 } 1.366 + 1.367 }