From 909fd203877002a3b1b1e2cf5fd4c4bad8a9b806 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Mon, 17 Feb 2014 16:26:37 -0800 Subject: [PATCH] more Java8 fixes --- j8code/.classpath | 1 + j8code/.project | 2 +- j8code/lib/asm-5.0_BETA.jar | Bin 0 -> 52810 bytes j8code/readme.txt | 3 + .../springsource/loaded/support/Java8.java | 175 ++++++++++---- springloaded/.classpath | 2 +- .../springsource/loaded/test/Java8Tests.java | 226 +++++++++++++----- .../loaded/test/SpringLoadedTests.java | 4 + testdata-java8/build.sh | 3 +- testdata-java8/code.jar | Bin 577 -> 0 bytes 10 files changed, 305 insertions(+), 111 deletions(-) create mode 100644 j8code/lib/asm-5.0_BETA.jar create mode 100644 j8code/readme.txt delete mode 100644 testdata-java8/code.jar diff --git a/j8code/.classpath b/j8code/.classpath index 4ad1cf5..0fe6ce4 100644 --- a/j8code/.classpath +++ b/j8code/.classpath @@ -2,5 +2,6 @@ + diff --git a/j8code/.project b/j8code/.project index 2970a0c..835cd67 100644 --- a/j8code/.project +++ b/j8code/.project @@ -1,6 +1,6 @@ - j8code + springloaded-java8 diff --git a/j8code/lib/asm-5.0_BETA.jar b/j8code/lib/asm-5.0_BETA.jar new file mode 100644 index 0000000000000000000000000000000000000000..2e26615968c67b8478703c5a34cb866ca53ffad5 GIT binary patch literal 52810 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 literal 0 HcmV?d00001 diff --git a/j8code/readme.txt b/j8code/readme.txt new file mode 100644 index 0000000..ea23a76 --- /dev/null +++ b/j8code/readme.txt @@ -0,0 +1,3 @@ +The main springloaded codebase is not yet using Java8. The Java8 'stuff' is captured here in this +project and included in the distributed agent. It should only be loaded if we find ourselves on a +Java8 VM. This code is not using Java8 source constructs, it is calling Java8 APIs. \ No newline at end of file diff --git a/j8code/src/org/springsource/loaded/support/Java8.java b/j8code/src/org/springsource/loaded/support/Java8.java index 4e3c942..028e481 100644 --- a/j8code/src/org/springsource/loaded/support/Java8.java +++ b/j8code/src/org/springsource/loaded/support/Java8.java @@ -1,4 +1,19 @@ -package j8code; +/* + * Copyright 2014 Pivotal Software Inc. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springsource.loaded.support; import java.lang.invoke.CallSite; import java.lang.invoke.LambdaMetafactory; @@ -6,64 +21,122 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -public class J8Helper { +import org.objectweb.asm.Handle; +import org.objectweb.asm.Type; - public static Object simulateInvokeDynamic(Object lookup) { +/** + * This class encapsulates dependencies on Java 8 APIs (e.g. LambdaMetafactory). + * + * @author Andy Clement + * @since 1.2 + */ +public class Java8 { + + /** + * Notes: + * + * Useful to have an example of how this code behaves. Here is a bit of code: + * + * class basic.LambdaA { + * interface Foo { int m(); } + * static int run() { + * Foo f = null; + * f = () -> 77; + * return f.m(); + * } + * } + * + * Here is a bootstrap method entry in the constant pool: + * + * 0: #31 invokestatic java/lang/invoke/LambdaMetafactory.metafactory: + * (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType; + * Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; + * Method arguments: + * #32 ()I + * #33 invokestatic basic/LambdaA.lambda$run$0:()I + * #32 ()I + * + * At the invokedynamic site: + * bsmId = 0 + * nameAndDescriptor = m()Lbasic/LambdaA$Foo; + * + * When invoking the metafactory bootstrap method the first two parameters are stacked by the VM automatically, namely the MethodHandles$Lookup + * instance (caller) and the first String (invokedName). What the VM actually sees is this: + * + * metaFactory parameters: + * 0:MethodHandles$Lookup caller = basic.LambdaA + * 1:String invokedName = "m" + * 2:MethodType invokedType = "()Foo" + * 3:MethodType samMethodType = "()int" + * 4:MethodHandle implMethod = (actually a DirectMethodHandle where memberName is "basic.LambdaA.lambda$run$0()int/invokeStatic") + * 5:MethodType instantiatedMethodType = "()int" + * + * With all that information then the calls in this case are relatively straightforward: + * CallSite callsite = LambdaMetafactory.metafactory(caller, invokedName, invokedType, samMethodType, implMethod, instantiatedMethodType); + * callsite.dynamicInvoker().invokeWithArguments((Object[])null); + */ + + /** + * Programmatic emulation of INVOKEDYNAMIC so initialize the callsite via use of the bootstrap method then + * invoke the result. + * + * @param executorClass null if not yet reloaded + * @param handle + * @param bsmArgs + * @param lookup + * @return + */ + public static Object emulateInvokeDynamic(Class executorClass, Handle handle, Object[] bsmArgs, Object lookup, String indyNameAndDescriptor, Object[] indyParams) { try { - CallSite callsite = callLambdaMetaFactory(lookup); - // java.lang.invoke.ConstantCallSite@1e965684 - // nameAndDescriptor at invokedynamic: m()Lbasic/LambdaA$Foo; - MethodHandles.Lookup caller = (MethodHandles.Lookup)lookup; - return callsite.dynamicInvoker().invokeWithArguments((Object[])null);//asType(MethodType.methodType())invoke(new Object[]{"m", MethodType.methodType(Class.forName("basic.LambdaA$Foo",false,caller.lookupClass().getClassLoader()))}); + CallSite callsite = callLambdaMetaFactory(bsmArgs,lookup,indyNameAndDescriptor,executorClass); + return callsite.dynamicInvoker().invokeWithArguments(indyParams); } catch (Throwable t) { throw new RuntimeException(t); } } - - - public static CallSite callLambdaMetaFactory(Object lookup) throws Exception { - // At invokedynamic: - // bsmId = 0 - // nameAndDescriptor = m()Lbasic/LambdaA$Foo; + // TODO [perf] How about a table of CallSites indexed by invokedynamic number through the class file. Computed on first reference but cleared on reload. Possibly extend this to all invoke types! -// 0: #31 invokestatic java/lang/invoke/LambdaMetafactory.metafactory: - // (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType; - // Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; -// Method arguments: -// #32 ()I -// #33 invokestatic basic/LambdaA.lambda$run$0:()I -// #32 ()I + // TODO [lambda] Need to handle altMetaFactory which is used when the lambdas are more 'complex' (e.g. Serializable) + public static CallSite callLambdaMetaFactory(Object[] bsmArgs, Object lookup, String indyNameAndDescriptor,Class executorClass) throws Exception { + MethodHandles.Lookup caller = (MethodHandles.Lookup)lookup; + + ClassLoader callerLoader = caller.lookupClass().getClassLoader(); + + int descriptorStart = indyNameAndDescriptor.indexOf('('); + String invokedName = indyNameAndDescriptor.substring(0,descriptorStart); + MethodType invokedType = MethodType.fromMethodDescriptorString(indyNameAndDescriptor.substring(descriptorStart), callerLoader); - // First two stacked by VM when used with invokedynamic + // Use bsmArgs to build the parameters + MethodType samMethodType = MethodType.fromMethodDescriptorString((String)(((Type)bsmArgs[0]).getDescriptor()), callerLoader); + + Handle bsmArgsHandle = (Handle)bsmArgs[1]; + String owner = bsmArgsHandle.getOwner(); + String name = bsmArgsHandle.getName(); + String descriptor = bsmArgsHandle.getDesc(); + MethodType implMethodType = MethodType.fromMethodDescriptorString(descriptor, callerLoader); + // Looking up the lambda$run method in the caller class (note the caller class is the executor, which gets us around the + // problem of having to hack into LambdaMetafactory to intercept reflection) + MethodHandle implMethod = null; + // TODO [lambda] need to handle invokevirtual, surely + switch (bsmArgsHandle.getTag()) { + case 6: // INVOKESSTATIC + implMethod = caller.findStatic(caller.lookupClass(), name, implMethodType); + break; + case 7: // INVOKESPECIAL + // If there is an executor, the lambda function is actually modified from 'private instance' to 'public static' so adjust lookup: + if (executorClass == null) { + implMethod = caller.findSpecial(caller.lookupClass(), name, implMethodType, caller.lookupClass()); + } + else { + implMethod = caller.findStatic(caller.lookupClass(), name, MethodType.fromMethodDescriptorString("(L"+owner+";"+descriptor.substring(1),callerLoader)); + } + break; + default: + throw new IllegalStateException("nyi "+bsmArgsHandle.getTag()); + } + + MethodType instantiatedMethodType = MethodType.fromMethodDescriptorString((String)(((Type)bsmArgs[2]).getDescriptor()), callerLoader); -// 0: #31 invokestatic java/lang/invoke/LambdaMetafactory.metafactory: - // (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType; - // Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; -// Method arguments: -// #32 ()I -// #33 invokestatic basic/LambdaA.lambda$run$0:()I -// #32 ()I - - // caller = basic.LambdaA (MethodHandles$Lookup) - - // invokedName = m (String) - // invokedType = ()Foo (MethodType) - - // samMethodType=()int (MethodType) - // implMethod=MethodHandle()int (DirectMethodHandle - membername in this object is "basic.LambdaA.lambda$run$0()int/invokeStatic") - // form members is: -// -// DMH.invokeStatic__I=Lambda(a0:L)=>{ -// t1:L=DirectMethodHandle.internalMemberName(a0:L); -// t2:I=MethodHandle.linkToStatic(t1:L);t2:I} - // instantiatedMethodType=()int (MethodType) - MethodHandles.Lookup caller = (MethodHandles.Lookup)lookup; - MethodType invokedType = MethodType.methodType(Class.forName("basic.LambdaA$Foo",false,caller.lookupClass().getClassLoader())); - - MethodType samMethodType = MethodType.methodType(Integer.TYPE); - // Cheating here by changing first param to pretend the original type is looking for it rather than the executor - MethodHandle implMethod = caller.findStatic(caller.lookupClass(), "lambda$run$0",MethodType.methodType(Integer.TYPE)); - MethodType instantiatedMethodType = MethodType.methodType(Integer.TYPE); - return LambdaMetafactory.metafactory(caller, "m", invokedType, samMethodType, implMethod, instantiatedMethodType); + return LambdaMetafactory.metafactory(caller, invokedName, invokedType, samMethodType, implMethod, instantiatedMethodType); } } diff --git a/springloaded/.classpath b/springloaded/.classpath index ea09e62..b5dde87 100644 --- a/springloaded/.classpath +++ b/springloaded/.classpath @@ -6,6 +6,6 @@ - + diff --git a/springloaded/src/test/java/org/springsource/loaded/test/Java8Tests.java b/springloaded/src/test/java/org/springsource/loaded/test/Java8Tests.java index dea5524..95aa5e8 100644 --- a/springloaded/src/test/java/org/springsource/loaded/test/Java8Tests.java +++ b/springloaded/src/test/java/org/springsource/loaded/test/Java8Tests.java @@ -1,8 +1,24 @@ +/* + * Copyright 2014 Pivotal Software Inc. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springsource.loaded.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import org.junit.Ignore; import org.junit.Test; import org.springsource.loaded.ReloadableType; import org.springsource.loaded.TypeRegistry; @@ -13,7 +29,7 @@ import org.springsource.loaded.test.infra.Result; * Test reloading of Java 8. * * @author Andy Clement - * @since 1.1.5 + * @since 1.2 */ public class Java8Tests extends SpringLoadedTests { @@ -77,74 +93,172 @@ public class Java8Tests extends SpringLoadedTests { ReloadableType rtype = typeRegistry.addType(t, sc); Class simpleClass = rtype.getClazz(); - ClassPrinter.print(rtype.bytesLoaded); Result r = runUnguarded(simpleClass, "run"); r = runUnguarded(simpleClass, "run"); assertEquals(77, r.returnValue); - rtype.loadNewVersion("002", retrieveRename(t,t+"2")); + byte[] renamed = retrieveRename(t,t+"2",t+"2$Foo:"+t+"$Foo"); + rtype.loadNewVersion("002", renamed); + r = runUnguarded(simpleClass, "run"); + assertEquals(88, r.returnValue); + } + + @Test + public void lambdaWithParameter() throws Exception { + String t = "basic.LambdaB"; + TypeRegistry typeRegistry = getTypeRegistry(t); + byte[] sc = loadBytesForClass(t); + ReloadableType rtype = typeRegistry.addType(t, sc); + + Class simpleClass = rtype.getClazz(); + Result r = runUnguarded(simpleClass, "run"); + + r = runUnguarded(simpleClass, "run"); + assertEquals(99L, r.returnValue); + + byte[] renamed = retrieveRename(t,t+"2",t+"2$Foo:"+t+"$Foo"); + rtype.loadNewVersion("002", renamed); + r = runUnguarded(simpleClass, "run"); + assertEquals(176L, r.returnValue); + } + + + @Test + public void lambdaWithTwoParameters() throws Exception { + String t = "basic.LambdaC"; + TypeRegistry typeRegistry = getTypeRegistry(t); + byte[] sc = loadBytesForClass(t); + ReloadableType rtype = typeRegistry.addType(t, sc); + + Class simpleClass = rtype.getClazz(); + Result r = runUnguarded(simpleClass, "run"); + + r = runUnguarded(simpleClass, "run"); + assertEquals(6L, r.returnValue); + + byte[] renamed = retrieveRename(t,t+"2",t+"2$Boo:"+t+"$Boo"); + rtype.loadNewVersion("002", renamed); + r = runUnguarded(simpleClass, "run"); + assertEquals(5L, r.returnValue); + } + + @Test + public void lambdaWithThreeMixedTypeParameters() throws Exception { + String t = "basic.LambdaD"; + TypeRegistry typeRegistry = getTypeRegistry(t); + byte[] sc = loadBytesForClass(t); + ReloadableType rtype = typeRegistry.addType(t, sc); + + Class simpleClass = rtype.getClazz(); + Result r = runUnguarded(simpleClass, "run"); + + r = runUnguarded(simpleClass, "run"); + assertEquals("true342abc", r.returnValue); + + byte[] renamed = retrieveRename(t,t+"2",t+"2$Boo:"+t+"$Boo"); + rtype.loadNewVersion("002", renamed); + r = runUnguarded(simpleClass, "run"); + assertEquals("def264true", r.returnValue); + } + + @Test + public void lambdaWithCapturedVariable() throws Exception { + String t = "basic.LambdaE"; + TypeRegistry typeRegistry = getTypeRegistry(t); + byte[] sc = loadBytesForClass(t); + ReloadableType rtype = typeRegistry.addType(t, sc); + + Class simpleClass = rtype.getClazz(); + Result r = runUnguarded(simpleClass, "run"); + + r = runUnguarded(simpleClass, "run"); + assertEquals("aaaa", r.returnValue); + + byte[] renamed = retrieveRename(t,t+"2",t+"2$Boo:"+t+"$Boo"); + rtype.loadNewVersion("002", renamed); + r = runUnguarded(simpleClass, "run"); + assertEquals("aaaaaaaa", r.returnValue); + } + + @Test + public void lambdaWithThis() throws Exception { + String t = "basic.LambdaF"; + TypeRegistry typeRegistry = getTypeRegistry(t); + byte[] sc = loadBytesForClass(t); + ReloadableType rtype = typeRegistry.addType(t, sc); + + Class simpleClass = rtype.getClazz(); + Result r = runUnguarded(simpleClass, "run"); + + r = runUnguarded(simpleClass, "run"); + assertEquals("aaaaaaa", r.returnValue); + + byte[] renamed = retrieveRename(t,t+"2",t+"2$Boo:"+t+"$Boo"); + rtype.loadNewVersion("002", renamed); ClassPrinter.print(rtype.getLatestExecutorBytes()); r = runUnguarded(simpleClass, "run"); - assertEquals(77, r.returnValue); + assertEquals("a:a:a:", r.returnValue); } - // TODO changing a lambda body - // TODO changing a lambda signature - // TODO adding a lambda that wasn't there before - // TODO deleting a lambda - // TODO make that inner interface non-public in LambdaA - seems to break things. + @Test + public void lambdaWithNonPublicInnerInterface() throws Exception { + String t = "basic.LambdaG"; + TypeRegistry typeRegistry = getTypeRegistry("basic..*"); + + // Since Boo needs promoting to public, have to ensure it is directly loaded: + typeRegistry.addType(t+"$Boo", loadBytesForClass(t+"$Boo")); - // Bytecode for LambdaA - /* - BootstrapMethods: - 0: #31 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; - Method arguments: - #32 ()I - #33 invokestatic basic/LambdaA.lambda$run$0:()I - #32 ()I + byte[] sc = loadBytesForClass(t); + ReloadableType rtype = typeRegistry.addType(t, sc); - public static int run(); - descriptor: ()I - flags: ACC_PUBLIC, ACC_STATIC - Code: - stack=1, locals=1, args_size=0 - 0: aconst_null - 1: astore_0 - 2: invokedynamic #3, 0 // InvokeDynamic #0:m:()Lbasic/LambdaA$Foo; - 7: astore_0 - 8: aload_0 - 9: invokeinterface #4, 1 // InterfaceMethod basic/LambdaA$Foo.m:()I - 14: ireturn - */ - /* - static void test() throws Throwable { - // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION - InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14); - } - private static void printArgs(Object... args) { - System.out.println(java.util.Arrays.deepToString(args)); - } - private static final MethodHandle printArgs; - static { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - Class thisClass = lookup.lookupClass(); // (who am I?) - printArgs = lookup.findStatic(thisClass, - "printArgs", MethodType.methodType(void.class, Object[].class)); - } - private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) { - // ignore caller and name, but match the type: - return new ConstantCallSite(printArgs.asType(type)); - } - } -*/ + Class simpleClass = rtype.getClazz(); + Result r = runUnguarded(simpleClass, "run"); + r = runUnguarded(simpleClass, "run"); + assertEquals(99, r.returnValue); + ClassPrinter.print(rtype.bytesLoaded); + + byte[] renamed = retrieveRename(t,t+"2",t+"2$Boo:"+t+"$Boo"); + rtype.loadNewVersion("002", renamed); + r = runUnguarded(simpleClass, "run"); + assertEquals(44, r.returnValue); + } + @Test + public void multipleLambdasInOneMethod() throws Exception { + String t = "basic.LambdaH"; + TypeRegistry typeRegistry = getTypeRegistry("basic..*"); + + // Since Foo needs promoting to public, have to ensure it is directly loaded: + typeRegistry.addType(t+"$Foo", loadBytesForClass(t+"$Foo")); - - // -- - - private String slashed(String dotted) { - return dotted.replaceAll("\\.", "/"); + byte[] sc = loadBytesForClass(t); + ReloadableType rtype = typeRegistry.addType(t, sc); + + Class simpleClass = rtype.getClazz(); + Result r = runUnguarded(simpleClass, "run"); + + r = runUnguarded(simpleClass, "run"); + assertEquals(56, r.returnValue); + + rtype.loadNewVersion("002", rtype.bytesInitial); + r = runUnguarded(simpleClass, "run"); + assertEquals(56, r.returnValue); + } + + @Ignore + @Test + public void lambdaWithVirtualMethodUse() throws Exception { + } + + // TODO before commit + // copyrights + // tidyup up invokedynamic rewriting to only intercept metafactory usages + // decide about altmetafactory handling (marker interfaces on multicasts) + // Guard idyrun on whether anything reloaded + // Cache result of idyrun for reuse? + + } diff --git a/springloaded/src/test/java/org/springsource/loaded/test/SpringLoadedTests.java b/springloaded/src/test/java/org/springsource/loaded/test/SpringLoadedTests.java index 9b14528..84e8a57 100644 --- a/springloaded/src/test/java/org/springsource/loaded/test/SpringLoadedTests.java +++ b/springloaded/src/test/java/org/springsource/loaded/test/SpringLoadedTests.java @@ -1261,6 +1261,10 @@ public abstract class SpringLoadedTests implements Constants { return captureOff(); } + protected String slashed(String dotted) { + return dotted.replaceAll("\\.", "/"); + } + protected final static void pause(int seconds) { try { Thread.sleep(seconds*1000); diff --git a/testdata-java8/build.sh b/testdata-java8/build.sh index 9157ee6..70a6758 100755 --- a/testdata-java8/build.sh +++ b/testdata-java8/build.sh @@ -1,2 +1 @@ -cd src/main/java -find . -name "*.java" | javac +../gradlew build diff --git a/testdata-java8/code.jar b/testdata-java8/code.jar deleted file mode 100644 index 36dd8e917522c05d2808eb01d9d3b341f17f11fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 577 zcmWIWW@h1HVBlb2&`oi3VL$?G3@i*uiN%@8`u|QbFa!YAi7;?*a4^`SsS^Y0fv9uK zEGjN>&PgmT)=LJFxdA7=m>mUb=Xx4-3#+TC=^5&=D^?Zg$+dJ$cW~g;QmOcOMR@j& zM6sE!ALj3Q;droF{(*bv)no;Y%vr16g@28^{(AlUet(AJH#P*|zx#TKS(a^cFx zWyy0F)@V7;oM)IZw^_O^Nq?6x&pC&-M@HN>g8e(53kUJ+;E|j)_x8al_C?p9KRhD4 zY$K0)tm~CWI%izZNv=tpay0qk^sX0QQs*qOov(g!V$!V(i7#$!*w`uNoLZtkIrf%# zi1o#dsf&Aa+g2SHwk&&|()5f!zB1U*@4v(0