/* * Copyright (c) 2013-2016 Chris Newland. * Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD * Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki */ package org.adoptopenjdk.jitwatch.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.adoptopenjdk.jitwatch.model.LogParseException; import org.adoptopenjdk.jitwatch.model.MemberSignatureParts; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.*; import org.junit.Test; public class TestMemberSignatureParts { // used in this class to test static initialiser bytecode matching public static long timestamp = 0; static { timestamp = System.currentTimeMillis(); } private void checkSame(MemberSignatureParts bc, MemberSignatureParts log) { assertEquals("return type", bc.getReturnType(), log.getReturnType()); assertEquals("member name", bc.getMemberName(), log.getMemberName()); assertEquals("param count", bc.getParamTypes().size(), log.getParamTypes().size()); for (int i = 0; i < bc.getParamTypes().size(); i++) { assertEquals("param " + i, bc.getParamTypes().get(i), log.getParamTypes().get(i)); } } @Test public void testPackageConstructorNoParams() throws Exception { String sigBC = "java.lang.String();"; String sigLog = "java.lang.String <init> ()V"; MemberSignatureParts mspBC = MemberSignatureParts.fromBytecodeSignature("java.lang.String", sigBC); MemberSignatureParts mspLog = MemberSignatureParts.fromLogCompilationSignature(sigLog); List<String> modListBC = mspBC.getModifiers(); assertEquals(0, modListBC.size()); assertEquals(0, mspBC.getGenerics().size()); assertEquals(S_TYPE_NAME_VOID, mspBC.getReturnType()); assertEquals("String", mspBC.getMemberName()); assertEquals(0, mspBC.getParamTypes().size()); checkSame(mspBC, mspLog); } @Test public void testPublicConstructorNoParams() throws Exception { String sigBC = "public java.lang.String()"; String sigLog = "java.lang.String <init> ()V"; MemberSignatureParts mspBC = MemberSignatureParts.fromBytecodeSignature("java.lang.String", sigBC); MemberSignatureParts mspLog = MemberSignatureParts.fromLogCompilationSignature(sigLog); List<String> modListBC = mspBC.getModifiers(); assertEquals(1, modListBC.size()); assertEquals("public", modListBC.get(0)); assertEquals(0, mspBC.getGenerics().size()); assertEquals(S_TYPE_NAME_VOID, mspBC.getReturnType()); assertEquals("String", mspBC.getMemberName()); assertEquals(0, mspBC.getParamTypes().size()); checkSame(mspBC, mspLog); } @Test public void testConstructorWithParams() throws Exception { String sigBC = "public java.lang.String(java.lang.String, int)"; String sigLog = "java.lang.String <init> (Ljava.lang.String;I)V"; MemberSignatureParts mspBC = MemberSignatureParts.fromBytecodeSignature("java.lang.String", sigBC); MemberSignatureParts mspLog = MemberSignatureParts.fromLogCompilationSignature(sigLog); List<String> modListBC = mspBC.getModifiers(); assertEquals(1, modListBC.size()); assertEquals("public", modListBC.get(0)); assertEquals(0, mspBC.getGenerics().size()); assertEquals(S_TYPE_NAME_VOID, mspBC.getReturnType()); assertEquals("String", mspBC.getMemberName()); assertEquals(2, mspBC.getParamTypes().size()); List<String> paramTypeListBC = mspBC.getParamTypes(); assertEquals("java.lang.String", paramTypeListBC.get(0)); assertEquals("int", paramTypeListBC.get(1)); checkSame(mspBC, mspLog); } @Test public void testSimpleMethodNoParams() throws Exception { String sigBC = "public void gc()"; String sigLog = "java.lang.System gc ()V"; MemberSignatureParts mspBC = MemberSignatureParts.fromBytecodeSignature("java.lang.String", sigBC); MemberSignatureParts mspLog = MemberSignatureParts.fromLogCompilationSignature(sigLog); List<String> modListBC = mspBC.getModifiers(); assertEquals(1, modListBC.size()); assertEquals("public", modListBC.get(0)); assertEquals(0, mspBC.getGenerics().size()); assertEquals(S_TYPE_NAME_VOID, mspBC.getReturnType()); assertEquals("gc", mspBC.getMemberName()); assertEquals(0, mspBC.getParamTypes().size()); checkSame(mspBC, mspLog); } @Test public void testSimpleMethodWithParams() throws Exception { String sigBC = "public boolean matches(java.lang.String)"; String sigLog = "java.lang.String matches (Ljava.lang.String;)Z"; MemberSignatureParts mspBC = MemberSignatureParts.fromBytecodeSignature("java.lang.String", sigBC); MemberSignatureParts mspLog = MemberSignatureParts.fromLogCompilationSignature(sigLog); List<String> modListBC = mspBC.getModifiers(); assertEquals(1, modListBC.size()); assertEquals("public", modListBC.get(0)); assertEquals(0, mspBC.getGenerics().size()); assertEquals("boolean", mspBC.getReturnType()); assertEquals("matches", mspBC.getMemberName()); assertEquals(1, mspBC.getParamTypes().size()); List<String> paramTypeList = mspBC.getParamTypes(); assertEquals("java.lang.String", paramTypeList.get(0)); checkSame(mspBC, mspLog); } @Test public void testSimpleMethodWithParamsAndParamNames() throws Exception { String sigBC = "public boolean startsWith(java.lang.String foo, int bar)"; String sigLog = "java.lang.String startsWith (Ljava.lang.String;I)Z"; MemberSignatureParts mspBC = MemberSignatureParts.fromBytecodeSignature("java.lang.String", sigBC); MemberSignatureParts mspLog = MemberSignatureParts.fromLogCompilationSignature(sigLog); List<String> modListBC = mspBC.getModifiers(); assertEquals(1, modListBC.size()); assertEquals("public", modListBC.get(0)); assertEquals(0, mspBC.getGenerics().size()); assertEquals("boolean", mspBC.getReturnType()); assertEquals("startsWith", mspBC.getMemberName()); assertEquals(2, mspBC.getParamTypes().size()); List<String> paramTypeListBC = mspBC.getParamTypes(); assertEquals("java.lang.String", paramTypeListBC.get(0)); assertEquals("int", paramTypeListBC.get(1)); checkSame(mspBC, mspLog); } @Test public void testSimpleGenericMethod() { String sig = "public Map<String,String> copy(Map<String,String>)"; MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature("com.chrisnewland.Test", sig); List<String> modList = msp.getModifiers(); assertEquals(1, modList.size()); assertEquals("public", modList.get(0)); assertEquals(0, msp.getGenerics().size()); assertEquals("Map<String,String>", msp.getReturnType()); assertEquals("copy", msp.getMemberName()); assertEquals(1, msp.getParamTypes().size()); List<String> paramTypeList = msp.getParamTypes(); assertEquals("Map<String,String>", paramTypeList.get(0)); } @Test public void testSignatureWithGenericExtends() { String sig = "public static <T extends java.lang.Object, U extends java.lang.Object> T[] copyOf(U[], int, java.lang.Class<? extends T[]>)"; MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature("java.util.Arrays", sig); List<String> modList = msp.getModifiers(); assertEquals(2, modList.size()); assertEquals("public", modList.get(0)); assertEquals("static", modList.get(1)); Map<String, String> genMap = msp.getGenerics(); assertEquals(2, genMap.size()); assertEquals(true, genMap.containsKey("T")); assertEquals(true, genMap.containsKey("U")); assertEquals("java.lang.Object", genMap.get("T")); assertEquals("java.lang.Object", genMap.get("U")); assertEquals("T[]", msp.getReturnType()); assertEquals("copyOf", msp.getMemberName()); List<String> paramTypes = msp.getParamTypes(); assertEquals(3, paramTypes.size()); assertEquals("U[]", paramTypes.get(0)); assertEquals("int", paramTypes.get(1)); assertEquals("java.lang.Class<? extends T[]>", paramTypes.get(2)); } @Test public void testSignatureWithGenericRegressionReturnTypeHasGenerics() { String sig = "public static <T extends java.lang.Object> java.lang.Class<T> asWrapperType(java.lang.Class<T>)"; MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature("sun.invoke.util.Wrapper", sig); List<String> modList = msp.getModifiers(); assertEquals(2, modList.size()); assertEquals("public", modList.get(0)); assertEquals("static", modList.get(1)); Map<String, String> genMap = msp.getGenerics(); assertEquals(1, genMap.size()); assertEquals(true, genMap.containsKey("T")); assertEquals("java.lang.Object", genMap.get("T")); assertEquals("java.lang.Class<T>", msp.getReturnType()); assertEquals("asWrapperType", msp.getMemberName()); List<String> paramTypes = msp.getParamTypes(); assertEquals(1, paramTypes.size()); assertEquals("java.lang.Class<T>", paramTypes.get(0)); } @Test public void testSignatureWithGenericNoExtends() { String sig = "public static <T,U> T[] copyOf(U[], int, java.lang.Class<? extends T[]>)"; MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature("java.util.Arrays", sig); List<String> modList = msp.getModifiers(); assertEquals(2, modList.size()); assertEquals("public", modList.get(0)); assertEquals("static", modList.get(1)); Map<String, String> genMap = msp.getGenerics(); assertEquals(2, genMap.size()); assertEquals(true, genMap.containsKey("T")); assertEquals(true, genMap.containsKey("U")); assertEquals(null, genMap.get("T")); assertEquals(null, genMap.get("U")); assertEquals("T[]", msp.getReturnType()); assertEquals("copyOf", msp.getMemberName()); List<String> paramTypes = msp.getParamTypes(); assertEquals(3, paramTypes.size()); assertEquals("U[]", paramTypes.get(0)); assertEquals("int", paramTypes.get(1)); assertEquals("java.lang.Class<? extends T[]>", paramTypes.get(2)); } @Test public void testStaticInitialiserBytecode() throws Exception { String sigBC = "static {}"; MemberSignatureParts mspBC = MemberSignatureParts.fromBytecodeSignature("java.lang.String", sigBC); List<String> modListBC = mspBC.getModifiers(); assertEquals(0, modListBC.size()); assertEquals(0, mspBC.getGenerics().size()); assertEquals(S_TYPE_NAME_VOID, mspBC.getReturnType()); assertEquals(S_STATIC_INIT, mspBC.getMemberName()); assertEquals(0, mspBC.getParamTypes().size()); } @Test public void testJava7DisassemblySignature() throws LogParseException { String sig = "# {method} 'chainA2' '(J)J' in 'org/adoptopenjdk/jitwatch/demo/MakeHotSpotLog'"; MemberSignatureParts msp = MemberSignatureParts.fromAssembly(sig); List<String> modList = msp.getModifiers(); assertEquals(0, modList.size()); assertEquals(0, msp.getGenerics().size()); assertEquals("long", msp.getReturnType()); assertEquals("org.adoptopenjdk.jitwatch.demo.MakeHotSpotLog", msp.getFullyQualifiedClassName()); assertEquals("chainA2", msp.getMemberName()); assertEquals(1, msp.getParamTypes().size()); assertEquals("long", msp.getParamTypes().get(0)); } @Test public void testJava8DisassemblySignature() throws LogParseException { String sig = " # {method} {0x00007fb6a89c4f80} 'hashCode' '()I' in 'java/lang/String'"; MemberSignatureParts msp = MemberSignatureParts.fromAssembly(sig); List<String> modList = msp.getModifiers(); assertEquals(0, modList.size()); assertEquals(0, msp.getGenerics().size()); assertEquals("int", msp.getReturnType()); assertEquals("java.lang.String", msp.getFullyQualifiedClassName()); assertEquals("hashCode", msp.getMemberName()); assertEquals(0, msp.getParamTypes().size()); } @Test public void testFromAssemblyRegression() throws LogParseException { String toParse = "# {method} 'write' '(Ljava/lang/String;II)V' in 'java/io/BufferedWriter'"; MemberSignatureParts msp = MemberSignatureParts.fromAssembly(toParse); List<String> modList = msp.getModifiers(); assertEquals(0, modList.size()); assertEquals(0, msp.getGenerics().size()); assertEquals(S_TYPE_NAME_VOID, msp.getReturnType()); assertEquals("java.io.BufferedWriter", msp.getFullyQualifiedClassName()); assertEquals("write", msp.getMemberName()); assertEquals(3, msp.getParamTypes().size()); assertEquals("java.lang.String", msp.getParamTypes().get(0)); assertEquals("int", msp.getParamTypes().get(1)); assertEquals("int", msp.getParamTypes().get(2)); } /* * TODO: class initialiser <clinit> does not appear in * Class.getDeclared{Methods|Constructors}() Need to detect access and * return dummy member. Bytecode for <clinit> is available via ClassBC * * @Test public void testMatchStaticInitialiser() { JITDataModel model = new * JITDataModel(); * * MetaClass metaClassThis = model.buildAndGetMetaClass(getClass()); * * MemberSignatureParts msp = * MemberSignatureParts.fromBytecodeSignature(getClass().getName(), * ParseUtil.STATIC_BYTECODE_SIGNATURE); * * IMetaMember memberFromSig = metaClassThis.getMemberFromSignature(msp); * * ClassBC classBC = metaClassThis.getClassBytecode(null); * * for (String sig : classBC.getBytecodeMethodSignatures()) { * System.out.println("BC: " + sig); } * * assertNotNull(memberFromSig); * * } */ @Test public void testNashornSignatureWithColon() { String bcSig = "public static jdk.nashorn.internal.runtime.ScriptFunction :createProgramFunction(jdk.nashorn.internal.runtime.ScriptObject);"; MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature(getClass().getName(), bcSig); assertNotNull(msp); List<String> paramTypes = new ArrayList<>(); paramTypes.add("jdk.nashorn.internal.runtime.ScriptObject"); assertEquals(paramTypes, msp.getParamTypes()); assertEquals("jdk.nashorn.internal.runtime.ScriptFunction", msp.getReturnType()); assertEquals(":createProgramFunction", msp.getMemberName()); List<String> modifiers = new ArrayList<>(); modifiers.add("public"); modifiers.add("static"); assertEquals(modifiers, msp.getModifiers()); } @Test public void testRegressionSubstituteGenericsForClassloading() { String sig = "public static <T extends java.lang.Object, U extends java.lang.Object> T[] copyOf(U[], int, java.lang.Class<? extends T[]>)"; MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature("java.util.Arrays", sig); assertEquals("T[]", msp.getReturnType()); assertEquals("java.lang.Object[]", msp.applyGenericSubstitutionsForClassLoading(msp.getReturnType())); } @Test public void testRegressionGenericsWithSuper() { String sig = "public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>)"; MemberSignatureParts msp = MemberSignatureParts.fromBytecodeSignature("java.util.Collections", sig); List<String> modList = msp.getModifiers(); assertEquals(2, modList.size()); assertEquals("public", modList.get(0)); assertEquals("static", modList.get(1)); Map<String, String> genMap = msp.getGenerics(); assertEquals(1, genMap.size()); assertEquals(true, genMap.containsKey("T")); assertEquals("java.lang.Comparable<? super T>", genMap.get("T")); assertEquals("void", msp.getReturnType()); assertEquals("sort", msp.getMemberName()); List<String> paramTypes = msp.getParamTypes(); assertEquals(1, paramTypes.size()); assertEquals("java.util.List<T>", paramTypes.get(0)); } }