private Expression leaveOptimistic(final Optimistic opt) { final int pp = opt.getProgramPoint(); if (isValid(pp) && !neverOptimistic.peek().get(pp)) { return (Expression) opt.setType(compiler.getOptimisticType(opt)); } return (Expression) opt; }
Type getOptimisticType(final Optimistic node) { assert compiler.useOptimisticTypes(); final int programPoint = node.getProgramPoint(); final Type validType = compiler.getInvalidatedProgramPointType(programPoint); if (validType != null) { return validType; } final Type mostOptimisticType = node.getMostOptimisticType(); final Type evaluatedType = getEvaluatedType(node); if (evaluatedType != null) { if (evaluatedType.widerThan(mostOptimisticType)) { final Type newValidType = evaluatedType.isObject() || evaluatedType.isBoolean() ? Type.OBJECT : evaluatedType; // Update invalidatedProgramPoints so we don't re-evaluate the expression next time. This is // a heuristic // as we're doing a tradeoff. Re-evaluating expressions on each recompile takes time, but it // might // notice a widening in the type of the expression and thus prevent an unnecessary // deoptimization later. // We'll presume though that the types of expressions are mostly stable, so if we evaluated // it in one // compilation, we'll keep to that and risk a low-probability deoptimization if its type // gets widened // in the future. compiler.addInvalidatedProgramPoint(node.getProgramPoint(), newValidType); } return evaluatedType; } return mostOptimisticType; }