private static List<String> getParameterNames(Executable executable) { requireNonNull(executable, "executable is null"); if (executable.getParameterCount() == 0) { return emptyList(); } // first try to get the parameter names from the ThriftField annotations List<Optional<String>> parameterNamesFromThriftField = Arrays.stream(executable.getParameters()) .map(ReflectionHelper::getThriftFieldParameterName) .collect(toImmutableList()); if (parameterNamesFromThriftField.stream().allMatch(Optional::isPresent)) { return parameterNamesFromThriftField.stream() .map(Optional::get) .collect(toImmutableList()); } // otherwise get the parameter names from the class, but use any ThriftField annotations as overrides List<String> parameterNamesFromClass = ParameterNames.getParameterNames(executable); ImmutableList.Builder<String> parameterNames = ImmutableList.builder(); for (int i = 0; i < parameterNamesFromThriftField.size(); i++) { parameterNames.add(parameterNamesFromThriftField.get(i).orElse(parameterNamesFromClass.get(i))); } return parameterNames.build(); }
public static void assertPublicThrows(Executable method, Class<?>... exceptions) { Members.assertPublic(method); for(Class<?> ex : method.getExceptionTypes()) { if(!RuntimeException.class.isAssignableFrom(ex)) { boolean found = false; for(Class<?> allowed : exceptions) { if(allowed.isAssignableFrom(ex)) { found = true; break; } } if(!found) { Members.error(method, "throws unhandled exception " + ex.getName()); } } } }
/** * Generates random method descriptor * * @param executable executable used to generate descriptor * @return MethodDescriptor instance */ public MethodDescriptor generateRandomDescriptor(Executable executable) { Combination<PatternType> patterns = Utils.getRandomElement(PATTERNS_LIST); Combination<Separator> separators = Utils.getRandomElement(SEPARATORS_LIST); // Create simple mutators for signature generation List<Function<String, String>> signMutators = new ArrayList<>(); signMutators.add(input -> input); signMutators.add(input -> ""); Combination<Function<String, String>> mutators = new Combination<>( Utils.getRandomElement(ELEMENT_MUTATORS), Utils.getRandomElement(ELEMENT_MUTATORS), // use only this type of mutators Utils.getRandomElement(signMutators)); return makeMethodDescriptor(executable, patterns, separators, mutators); }
protected void checkIntrinsicForCompilationLevel(Executable method, int compLevel) throws Exception { boolean intrinsicEnabled = Boolean.valueOf(getVMOption("UseCRC32Intrinsics")); boolean intrinsicAvailable = WHITE_BOX.isIntrinsicAvailable(method, compLevel); String intrinsicEnabledMessage = intrinsicEnabled ? "enabled" : "disabled"; String intrinsicAvailableMessage = intrinsicAvailable ? "available" : "not available"; if (intrinsicEnabled == intrinsicAvailable) { System.out.println("Expected result: intrinsic for java.util.zip.CRC32.update() is " + intrinsicEnabledMessage + " and intrinsic is " + intrinsicAvailableMessage + " at compilation level " + compLevel); } else { throw new RuntimeException("Unexpected result: intrinsic for java.util.zip.CRC32.update() is " + intrinsicEnabledMessage + " but intrinsic is " + intrinsicAvailableMessage + " at compilation level " + compLevel); } }
private static Method lookupMethod(String name) { Method method = null; Method[] methods = Executable.class.getDeclaredMethods(); for(Method tmp : methods) { if (tmp.getName().equals(name)) { method = tmp; break; } } if (method == null) { throw new InjectorException("Required method (Executable." + name + ") does not exists"); } method.setAccessible(true); return method; }
@Override public void test() { Scenario.Builder builder = Scenario.getBuilder(); // Add some commands with JCMD for (int i = 0; i < AMOUNT; i++) { Executable exec = Utils.getRandomElement(METHODS).first; MethodDescriptor md = getValidMethodDescriptor(exec); CompileCommand compileCommand = new JcmdCommand(Command.COMPILEONLY, md, null, Scenario.Type.JCMD, Scenario.JcmdType.ADD); compileCommand.print(); builder.add(compileCommand); } // Remove half of them for (int i = 0; i < AMOUNT / 2; i++) { /* remove jcmd command doesn't need method, compiler etc. command will be ignored */ builder.add(new JcmdCommand(Command.NONEXISTENT, null, null, Scenario.Type.JCMD, Scenario.JcmdType.REMOVE)); } Scenario scenario = builder.build(); scenario.execute(); }
private Executable toJava() { if (toJavaCache != null) { return toJavaCache; } try { Class<?>[] parameterTypes = signatureToTypes(); Class<?> returnType = ((HotSpotResolvedJavaType) getSignature().getReturnType(holder).resolve(holder)).mirror(); Executable result; if (isConstructor()) { result = holder.mirror().getDeclaredConstructor(parameterTypes); } else { // Do not use Method.getDeclaredMethod() as it can return a bridge method // when this.isBridge() is false and vice versa. result = searchMethods(holder.mirror().getDeclaredMethods(), getName(), returnType, parameterTypes); } toJavaCache = result; return result; } catch (NoSuchMethodException | NoClassDefFoundError e) { return null; } }
/** * Waits for completion of background compilation of the given executable. * * @param executable Executable */ public static final void waitBackgroundCompilation(Executable executable) { if (!BACKGROUND_COMPILATION) { return; } final Object obj = new Object(); for (int i = 0; i < 100 && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) { synchronized (obj) { try { obj.wait(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } }
@Override public void test() { Scenario.Builder builder = Scenario.getBuilder(); // Add some commands with directives file for (int i = 0; i < AMOUNT; i++) { Executable exec = Utils.getRandomElement(METHODS).first; MethodDescriptor methodDescriptor = getValidMethodDescriptor(exec); Command command = cmdGen.generateCommand(); if (command == Command.NONEXISTENT) { // skip invalid command command = Command.COMPILEONLY; } CompileCommand compileCommand = new CompileCommand(command, methodDescriptor, cmdGen.generateCompiler(), Scenario.Type.DIRECTIVE); compileCommand.print(); builder.add(compileCommand); } // print all directives builder.add(new JcmdCommand(Command.NONEXISTENT, null, null, Scenario.Type.JCMD, Scenario.JcmdType.PRINT)); Scenario scenario = builder.build(); scenario.execute(); }
/** * Generates a test containing multiple random commands * * @param validOnly shows that all commands should be valid * @return test instance to run */ public static AbstractTestBase generateRandomTest(boolean validOnly) { CommandGenerator cmdGen = new CommandGenerator(); List<Command> commands = cmdGen.generateCommands(); List<CompileCommand> testCases = new ArrayList<>(); for (Command cmd : commands) { if (validOnly && cmd == Command.NONEXISTENT) { // replace with a valid command cmd = Command.EXCLUDE; } Executable exec = Utils.getRandomElement(METHODS).first; MethodDescriptor md; if (validOnly) { md = AbstractTestBase.getValidMethodDescriptor(exec); } else { md = AbstractTestBase.METHOD_GEN.generateRandomDescriptor(exec); } CompileCommand cc = cmdGen.generateCompileCommand(cmd, md, null); testCases.add(cc); } return new MultiCommand(testCases); }
@Override public void test() { Scenario.Builder builder = Scenario.getBuilder(); // Add some commands with JCMD for (int i = 0; i < AMOUNT; i++) { Executable exec = Utils.getRandomElement(METHODS).first; MethodDescriptor methodDescriptor = getValidMethodDescriptor(exec); CompileCommand compileCommand = new JcmdCommand( cmdGen.generateCommand(), methodDescriptor, cmdGen.generateCompiler(), Scenario.Type.JCMD, Scenario.JcmdType.ADD); compileCommand.print(); builder.add(compileCommand); } // clear the stack builder.add(new JcmdCommand(Command.NONEXISTENT, null, null, Scenario.Type.JCMD, Scenario.JcmdType.CLEAR)); // print all directives after the clear builder.add(new JcmdCommand(Command.NONEXISTENT, null, null, Scenario.Type.JCMD, Scenario.JcmdType.PRINT)); Scenario scenario = builder.build(); scenario.execute(); }
private static Map<Executable, int[]> createTestCases() { Map<Executable, int[]> testCases = new HashMap<>(); try { Class<?> aClass = DummyClass.class; Method aMethod = aClass.getDeclaredMethod("dummyInstanceFunction"); int[] bci = new int[] {0, 2, 3, 6, 7, 8, 11, 13, 15, 16, 17, 18}; testCases.put(aMethod, bci); aMethod = aClass.getDeclaredMethod("dummyEmptyFunction"); bci = new int[] {0}; testCases.put(aMethod, bci); aMethod = aClass.getDeclaredMethod("nativeFunction"); bci = new int[] {0}; testCases.put(aMethod, bci); TestCase.getAllExecutables() .forEach(c -> testCases.put(c, new int[] {0})); } catch (NoSuchMethodException e) { throw new Error("TEST BUG : test method not found", e); } return testCases; }
public ClassVisitorForLabels(ClassWriter cw, Map<Label, Integer> lines, Executable target) { super(Opcodes.ASM5, cw); this.lineNumbers = lines; StringBuilder builder = new StringBuilder("("); for (Parameter parameter : target.getParameters()) { builder.append(Utils.toJVMTypeSignature(parameter.getType())); } builder.append(")"); if (target instanceof Constructor) { targetName = "<init>"; builder.append("V"); } else { targetName = target.getName(); builder.append(Utils.toJVMTypeSignature( ((Method) target).getReturnType())); } targetDesc = builder.toString(); }
private Map<Executable, State> decodeMap(List<String> lines) { if (lines == null || lines.size() == 0) { throw new Error("TESTBUG: unexpected lines list"); } Map<Executable, State> stateMap = new HashMap<>(); int startIndex = 0; ListIterator<String> iterator = lines.listIterator(); while (iterator.hasNext()) { int index = iterator.nextIndex(); String next = iterator.next(); switch (next) { case "{" : startIndex = index; break; case "}" : // method name goes after { Executable executable = METHODS_NAMES.get(lines.get( ++startIndex)); // state description starts after method State state = State.fromString(lines.subList(++startIndex, index).toArray(new String[index - startIndex])); stateMap.put(executable, state); break; } } return stateMap; }
@Override public Executable getExecutable() { try { return getClass().getDeclaredMethod("execMathMethod"); } catch (NoSuchMethodException e) { throw new RuntimeException("Test bug, no such method: " + e); } }
@SuppressWarnings("unchecked") public static <T extends Annotation> T removeAnnotation(Executable ex, Class<T> annotationType) { if (ex.getAnnotation(annotationType) == null) { return null; } ex.getAnnotation(Annotation.class);// prevent declaredAnnotations haven't initialized Map<Class<? extends Annotation>, Annotation> annos; try { annos = (Map<Class<? extends Annotation>, Annotation>) Field_Excutable_DeclaredAnnotations.get(ex); } catch (IllegalAccessException e) { throw new IllegalStateException(e); } return (T) annos.remove(annotationType); }
public static HotSpotResolvedJavaMethod getResolvedMethod(Class<?> cls, Executable method) { if (!(method instanceof Method || method instanceof Constructor)) { throw new Error("wrong executable type " + method.getClass()); } return CompilerToVMHelper.asResolvedJavaMethod(method); }
public Object[] convertValues(final Executable executable, final ValueConverter valueConverter) { final Object[] converted = new Object[executable.getParameterCount()]; final Parameter[] parameters = executable.getParameters(); for (int i = 0; i < converted.length; i++) { final String refName = Spockito.parameterRefNameOrNull(parameters[i]); converted[i] = convertValue(refName, i, parameters[i].getType(), parameters[i].getParameterizedType(), valueConverter); } return converted; }
/** * Compile command signature that looks like java.lang.String::indexOf * * @param executable executable used to generate descriptor * @return MethodDescriptor instance */ public static MethodDescriptor logDescriptor(Executable executable) { MethodDescriptor md = new MethodDescriptor(executable); md.aClass.setSeparator(Separator.DOT); md.aMethod.setSeparator(Separator.DOUBLECOLON); md.aSignature.setSeparator(Separator.NONE); return md; }
/** * Gets all methods from the pool using specified filter * * @param filter method filter * @return pairs of Executable and appropriate Callable */ public List<Pair<Executable, Callable<?>>> getAllMethods( Predicate<Executable> filter) { return getAllMethods().stream() .filter(pair -> filter.test(pair.first)) .collect(Collectors.toList()); }
protected void checkEmittedCode(Executable executable) { final byte[] nativeCode = NMethod.get(executable, false).insts; if (!((BmiTestCase) testCase).verifyPositive(nativeCode)) { throw new AssertionError(testCase.name() + "CPU instructions expected not found: " + Utils.toHexString(nativeCode)); } else { System.out.println("CPU instructions found, PASSED"); } }
/** * Generate random valid method descriptor * * @param exec method to make descriptor for * @return a valid {@link MethodDescriptor#isValid()} descriptor instance */ public static MethodDescriptor getValidMethodDescriptor(Executable exec) { MethodDescriptor md = METHOD_GEN.generateRandomDescriptor(exec); for (int i = 0; !md.isValid() && i < ATTEMPTS; i++) { md = METHOD_GEN.generateRandomDescriptor(exec); } if (!md.isValid() || "any.method()".matches(md.getRegexp())) { /* if we haven't got a valid pattern or it matches any method leading to timeouts, then use plain standard descriptor */ md = MethodGenerator.commandDescriptor(exec); } return md; }
/** * Deoptimizes all non-osr versions of the given executable after * compilation finished. * * @param e Executable * @throws Exception */ private static void waitAndDeoptimize(Executable e) { CompilerWhiteBoxTest.waitBackgroundCompilation(e); if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) { throw new RuntimeException(e + " must not be in queue"); } // Deoptimize non-osr versions of executable WhiteBox.getWhiteBox().deoptimizeMethod(e, false); }
public MethodType(Executable method) { // Use pack/subpack/Class::method separators style super(MethodDescriptor.Separator.DOT); if (method instanceof Constructor) { element = "<init>"; } else { element = method.getName(); } regexp = element; }
private static Callable<?> getCallableFor(Executable executable) { for (Pair<Executable, Callable<?>> pair : METHODS) { if (pair.first == executable) { return pair.second; } } throw new Error("TESTBUG: wrong executable: " + executable); }
public static void runSanityTest(Executable aMethod) { HotSpotResolvedJavaMethod method = CTVMUtilities .getResolvedMethod(aMethod); long[] lineNumbers = CompilerToVMHelper.getLineNumberTable(method); long[] expectedLineNumbers = getExpectedLineNumbers(aMethod); Asserts.assertTrue(Arrays.equals(lineNumbers, expectedLineNumbers), String.format("%s : unequal table values : %n%s%n%s%n", aMethod, Arrays.toString(lineNumbers), Arrays.toString(expectedLineNumbers))); }
private static void execute(Executable executable) { Callable<?> callable = getCallableFor(executable); try { for (int i = 0; i < EXEC_AMOUNT; i++) { callable.call(); } } catch (Exception e) { throw new Error("Got exception during execution", e); } }
private State getState(Pair<Executable, Callable<?>> pair) { State state = null; MethodDescriptor execDesc = MethodGenerator.commandDescriptor( pair.first); boolean isMatchFound = false; if (stateMap.containsKey(pair.first)) { state = stateMap.get(pair.first); } for (MethodDescriptor matchDesc : matchBlocks.keySet()) { if (execDesc.getCanonicalString().matches(matchDesc.getRegexp())) { /* * if executable matches regex * then apply commands from this match to the state */ for (CompileCommand cc : matchBlocks.get(matchDesc)) { if (state == null) { state = new State(); } if (!isMatchFound) { // this is a first found match, apply all commands state.apply(cc); } else { // apply only inline directives switch (cc.command) { case INLINE: case DONTINLINE: state.apply(cc); break; } } } isMatchFound = true; } } return state; }
private static List<Executable> createTestCases() { List<Executable> testCases = new ArrayList<>(); Class<?> aClass = DummyClass.class; testCases.addAll(Arrays.asList(aClass.getDeclaredMethods())); testCases.addAll(Arrays.asList(aClass.getDeclaredConstructors())); return testCases; }
/** * Constructor * * @param isValid shows that the input given to the VM is valid and * VM shouldn't fail * @param vmOptions a list of VM input options * @param states a state map, or null for the non-checking execution * @param jcmdCommands a list of diagnostic commands to be preformed * on test VM */ public Executor(boolean isValid, List<String> vmOptions, Map<Executable, State> states, List<String> jcmdCommands) { this.isValid = isValid; if (vmOptions == null) { this.vmOptions = new ArrayList<>(); } else { this.vmOptions = vmOptions; } this.states = states; this.jcmdCommands = jcmdCommands; }
private static Map<Executable, Integer> createTestCases() { HashMap<Executable, Integer> methods = new HashMap<>(); try { Class<?> aClass; aClass = GetLocalVariableTableTest.class; methods.put(aClass.getDeclaredMethod("main", String[].class), MAIN_LOCALS_COUNT); aClass = DummyClass.class; methods.put(aClass.getMethod("dummyInstanceFunction"), INSTANCE_LOCALS_COUNT); methods.put(aClass.getMethod("dummyEmptyInstanceFunction"), EMPTY_INSTANCE_COUNT); methods.put(aClass.getMethod("dummyEmptyStaticFunction"), EMPTY_STATIC_COUNT); methods.put(aClass.getMethod("dummyFunction"), EMPTY_INSTANCE_COUNT); methods.put(aClass.getMethod("dummyAbstractFunction"), ABSTRACT_INHERIT_LOCALS_COUNT); aClass = DummyInterface.class; methods.put(aClass.getMethod("dummyFunction"), EMPTY_STATIC_COUNT); methods.put(aClass.getMethod("dummyDefaultFunction", int.class, int.class), DEFAULTFUNC_LOCALS_COUNT); aClass = DummyAbstractClass.class; methods.put(aClass.getMethod("dummyAbstractFunction"), 0); } catch (NoSuchMethodException e) { throw new Error("TEST BUG", e); } return methods; }
private static void runSanityTest(Executable aMethod, Integer expectedTableLength) { HotSpotResolvedJavaMethod method = CTVMUtilities .getResolvedMethod(aMethod); int tblLength = CompilerToVMHelper.getLocalVariableTableLength(method); Asserts.assertEQ(tblLength, expectedTableLength, aMethod + " : incorrect " + "local variable table length."); long tblStart = CompilerToVMHelper.getLocalVariableTableStart(method); if (tblLength > 0) { Asserts.assertNE(tblStart, 0L, aMethod + " : local variable table starts" + " at 0 with length " + tblLength); } }
/** * Method descriptor that matches any method. Its full signature is *.* * * @param executable executable used to generate descriptor * @return MethodDescriptor instance */ public static MethodDescriptor anyMatchDescriptor(Executable executable) { MethodDescriptor md = new MethodDescriptor(executable); Combination<PatternType> patterns = new Combination<>(PatternType.ANY, PatternType.ANY, PatternType.ANY); md.aClass.setSeparator(Separator.SLASH); md.aMethod.setSeparator(Separator.DOT); md.aSignature.setSeparator(Separator.NONE); md.setPatterns(patterns); return md; }
private static void runSanityTest(Executable aMethod, Boolean expected) { HotSpotResolvedJavaMethod method = CTVMUtilities.getResolvedMethod(aMethod); boolean isIgnored = CompilerToVMHelper .methodIsIgnoredBySecurityStackWalk(method); String msg = String.format("%s is%s ignored but must%s", aMethod, isIgnored ? "" : " not", expected ? "" : " not"); Asserts.assertEQ(isIgnored, expected, msg); }
@Override public void test() { Scenario.Builder builder = Scenario.getBuilder(); Executable exec = Utils.getRandomElement(METHODS).first; MethodDescriptor md = getValidMethodDescriptor(exec); CommandGenerator cmdGen = new CommandGenerator(); CompileCommand compileCommand = cmdGen.generateCompileCommand(command, md, type); compileCommand.print(); builder.add(compileCommand); Scenario scenario = builder.build(); scenario.execute(); }
@Advice.OnMethodExit(onThrowable = Throwable.class) static void exit(@Advice.Origin final Executable executable, @Advice.Enter final long startTime) { final long duration = System.nanoTime() - startTime; MetricsCollector.report(executable.toGenericString(), duration); }
@Advice.OnMethodExit static void exit(@Advice.Origin final Executable executable, @Advice.Enter final long startTime) { final long duration = System.nanoTime() - startTime; MetricsCollector.report(executable.toGenericString(), duration); }
@Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { Executable declaringExecutable = parameterContext.getParameter().getDeclaringExecutable(); Method testMethod = extensionContext.getTestMethod().orElse(null); return declaringExecutable.equals(testMethod) && parameterContext.getIndex() < arguments.length; }
AbstractReflectAnnotatedExecutable(final GasketAnnotationProcessor processor, final Executable executable) { super(processor, executable); this.executable = executable; }