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;
  }
      private static Type computeElementType(final Expression[] value) {
        Type widestElementType = Type.INT;

        for (final Expression elem : value) {
          if (elem == null) {
            widestElementType =
                widestElementType.widest(Type.OBJECT); // no way to represent undefined as number
            break;
          }

          final Type type = elem.getType().isUnknown() ? Type.OBJECT : elem.getType();
          if (type.isBoolean()) {
            // TODO fix this with explicit boolean types
            widestElementType = widestElementType.widest(Type.OBJECT);
            break;
          }

          widestElementType = widestElementType.widest(type);
          if (widestElementType.isObject()) {
            break;
          }
        }
        return widestElementType;
      }