VM_Class klass = callee.getDeclaringClass(); VM_Class[] subClasses = klass.getSubClasses(); if (subClasses.length != 1) return OPT_InlineDecision.NO("abstract class doesn't have exactly one subclass"); VM_Method singleImpl = subClasses[0].findDeclaredMethod(callee.getName(), callee.getDescriptor()); if (singleImpl == null || !hasBody(singleImpl)) { return OPT_InlineDecision.NO("Implementation of abstract method is illegal candidate");
synchronized(VM_Class.OptCLDepManager) {  VM_Class klass = callee.getDeclaringClass(); VM_Class[] subClasses = klass.getSubClasses(); if (subClasses.length != 1) return OPT_InlineDecision.NO("abstract class doesn't have exactly one subclass"); VM_Method singleImpl = subClasses[0].findDeclaredMethod(callee.getName(), callee.getDescriptor()); if (singleImpl == null || !hasBody(singleImpl)) { return OPT_InlineDecision.NO("Implementation of abstract method is illegal candidate"); } if (hasNoInlinePragma(singleImpl, state)) return OPT_InlineDecision.NO("pragmaNoInline");    OPT_InlineSequence seq = state.getSequence(); if (seq.containsMethod(singleImpl)) { return OPT_InlineDecision.NO("recursive call"); }  OPT_Options opts = state.getOptions();  boolean preEx = state.getIsExtant() && opts.PREEX_INLINE && isCurrentlyFinal(singleImpl, true);   int inlinedSizeEstimate = inlinedSizeEstimate((VM_NormalMethod)singleImpl, state); int cost = inliningActionCost(inlinedSizeEstimate, true, preEx, opts); OPT_InlineDecision sizeCheck = sizeHeuristics(caller, singleImpl, state, cost); if (sizeCheck != null) return sizeCheck;  if (isForbiddenSpeculation(state.getRootMethod(), callee)) { return OPT_InlineDecision.NO("Forbidden speculation"); }   if (preEx) { if (OPT_ClassLoadingDependencyManager.TRACE || OPT_ClassLoadingDependencyManager.DEBUG) { VM_Class.OptCLDepManager.report("PREEX_INLINE: Inlined " + singleImpl + " into " + caller + "\n"); } VM_Class.OptCLDepManager.addNotOverriddenDependency(singleImpl, state.getCompiledMethod()); VM_Class.OptCLDepManager.addNotOverriddenDependency(callee, state.getCompiledMethod()); return OPT_InlineDecision.YES(singleImpl, "PREEX_INLINE passed size checks"); } else if (opts.GUARDED_INLINE && isCurrentlyFinal(singleImpl, !opts.guardWithClassTest())) { return OPT_InlineDecision.guardedYES(singleImpl, chooseGuard(caller, singleImpl, callee, state, true), "static guarded inline passsed size checks"); } return OPT_InlineDecision.NO(callee, "abstract method with multiple implementations");
  protected OPT_InlineDecision shouldInlineAbstractMethodInternal(VM_Method caller,								  VM_Method callee,								  OPT_CompilationState state) {    // see if there is only one implementation of the abstract method    VM_Class klass = callee.getDeclaringClass();    VM_Class[] subClasses = klass.getSubClasses();    if (subClasses.length != 1) return OPT_InlineDecision.NO("abstract class doesn't have exactly one subclass");    VM_Method singleImpl =       subClasses[0].findDeclaredMethod(callee.getName(), callee.getDescriptor());    if (singleImpl == null || !hasBody(singleImpl)) {      return OPT_InlineDecision.NO("Implementation of abstract method is illegal candidate");    }    if (hasNoInlinePragma(singleImpl, state))      return OPT_InlineDecision.NO("pragmaNoInline");        // Don't allow the static inline oracle to inline recursive calls.    // It isn't smart enough to do this effectively.    OPT_InlineSequence seq = state.getSequence();    if (seq.containsMethod(singleImpl)) {      return OPT_InlineDecision.NO("recursive call");    }    OPT_Options opts = state.getOptions();    // more or less figure out the guard situation early -- impacts size estimate.    boolean preEx = state.getIsExtant() && opts.PREEX_INLINE && isCurrentlyFinal(singleImpl, true);        // See if inlining action passes simple size heuristics    int inlinedSizeEstimate = inlinedSizeEstimate((VM_NormalMethod)singleImpl, state);    int cost = inliningActionCost(inlinedSizeEstimate, true, preEx, opts);    OPT_InlineDecision sizeCheck = sizeHeuristics(caller, singleImpl, state, cost);    if (sizeCheck != null) return sizeCheck;    if (isForbiddenSpeculation(state.getRootMethod(), callee)) {      return OPT_InlineDecision.NO("Forbidden speculation");    }    // Ok, the size looks good, attempt to do it.    if (preEx) {      if (OPT_ClassLoadingDependencyManager.TRACE || 	  OPT_ClassLoadingDependencyManager.DEBUG) {	VM_Class.OptCLDepManager.report("PREEX_INLINE: Inlined "					+ singleImpl + " into " + caller + "\n");      }      VM_Class.OptCLDepManager.addNotOverriddenDependency(singleImpl, 							  state.getCompiledMethod());      VM_Class.OptCLDepManager.addNotOverriddenDependency(callee, 							  state.getCompiledMethod());      return OPT_InlineDecision.YES(singleImpl, "PREEX_INLINE passed size checks");    } else if (opts.GUARDED_INLINE && isCurrentlyFinal(singleImpl, !opts.guardWithClassTest())) {      return OPT_InlineDecision.guardedYES(singleImpl, 					   chooseGuard(caller, singleImpl, callee, state, true), 					   "static guarded inline passsed size checks");    }    return OPT_InlineDecision.NO(callee, "abstract method with multiple implementations");  }