private InlineResult tryInlineMethodCall(JMethodCall x, Context ctx) { JMethod method = x.getTarget(); if (!method.isStatic() || method.isNative() || method.canBeImplementedExternally()) { // Only inline static methods that are not native. return InlineResult.BLACKLIST; } if (!method.isInliningAllowed()) { return InlineResult.BLACKLIST; } JMethodBody body = (JMethodBody) method.getBody(); List<JStatement> stmts = body.getStatements(); if (method.getEnclosingType() != null && method.getEnclosingType().getClinitMethod() == method && !stmts.isEmpty()) { // clinit() calls cannot be inlined unless they are empty return InlineResult.BLACKLIST; } // try to inline List<JExpression> expressions = extractExpressionsFromBody(body); if (expressions == null) { // If it will never be possible to inline the method, add it to a // blacklist return InlineResult.BLACKLIST; } return tryInlineBody(x, ctx, expressions, expressionsWhoseValuesAreIgnored.contains(x)); }
public JExpression doRebind(String clsName, ReflectionGeneratorContext params) throws UnableToCompleteException { // generate params.getLogger().log(Type.INFO, "Binding magic class for " + clsName); // JType type = params.getClazz().getRefType(); JDeclaredType type = params.getAst().searchForTypeBySource(params.getClazz().getRefType().getName()); StandardGeneratorContext ctx = params.getGeneratorContext(); Class<? extends Generator> generator = MagicClassGenerator.class; String result = ctx.runGenerator(params.getLogger(), generator, SourceUtil.toSourceName(type.getName())); ctx.finish(params.getLogger()); params.getLogger().log(Type.INFO, "Generated Class Enhancer: " + result); JDeclaredType success = params.getAst().searchForTypeBySource(result); // Okay, we've generated the correct magic class subtype; // Now pull off its static accessor method to grab our generated class. for (JMethod method : success.getMethods()) { if (method.isStatic() && method.getName().equals("enhanceClass")) { JMethodCall call = new JMethodCall(method.getSourceInfo(), null, method); call.addArg(params.getClazz().makeStatement().getExpr()); return call; } } params.getLogger().log(Type.ERROR, "Unable to load " + result + ".enhanceClass()"); throw new UnableToCompleteException(); }
public static JProgram construct( TreeLogger logger, CompilationState state, Properties properties, String... entryPoints) throws UnableToCompleteException { PrecompileTaskOptions options = new PrecompileTaskOptionsImpl(); options.setEnableAssertions(true); JProgram jprogram = AstConstructor.construct(logger, state, options, properties); // Add entry methods for entry points. for (String entryPoint : entryPoints) { JDeclaredType entryType = jprogram.getFromTypeMap(entryPoint); for (JMethod method : entryType.getMethods()) { if (method.isStatic() && JProgram.isClinit(method)) { jprogram.addEntryMethod(method); } } } // Tree is now ready to optimize. return jprogram; }
@Override public void endVisit(JMethodCall x, Context ctx) { JMethod method = x.getTarget(); if (currentMethod == method) { // Never try to inline a recursive call! return; } if (cannotInline.contains(method)) { return; } boolean possibleToInline = false; if (method.isStatic() && !method.isNative()) { JMethodBody body = (JMethodBody) method.getBody(); List<JStatement> stmts = body.getStatements(); if (method.getEnclosingType() != null && method.getEnclosingType().getClinitMethod() == method && !stmts.isEmpty()) { // clinit() calls cannot be inlined unless they are empty possibleToInline = false; } else if (!body.getLocals().isEmpty()) { // methods with local variables cannot be inlined possibleToInline = false; } else { JMultiExpression multi = createMultiExpressionFromBody(body, ignoringReturnValueFor == x); if (multi != null) { possibleToInline = tryInlineExpression(x, ctx, multi); } } } // If it will never be possible to inline the method, add it to a // blacklist if (!possibleToInline) { cannotInline.add(method); } }