# HG changeset patch # User xuelei # Date 1528485298 0 # Node ID 789118dc46c6192998a5137502af2fb7c58ac06a # Parent 25178bb3e8f5f7fe76d7454c93a98931a91063bc# Parent cb0efe0cc20ef0db0593d87f016dbfb7e61af7ee Merge diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/lang/Object.java --- a/src/java.base/share/classes/java/lang/Object.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/java.base/share/classes/java/lang/Object.java Fri Jun 08 19:14:58 2018 +0000 @@ -333,12 +333,12 @@ * by being notified or interrupted, or until a * certain amount of real time has elapsed. *

- * In all respects, this method behaves as if {@code wait(timeout, 0)} + * In all respects, this method behaves as if {@code wait(timeoutMillis, 0)} * had been called. See the specification of the {@link #wait(long, int)} method * for details. * - * @param timeout the maximum time to wait, in milliseconds - * @throws IllegalArgumentException if the value of {@code timeout} is negative + * @param timeoutMillis the maximum time to wait, in milliseconds + * @throws IllegalArgumentException if {@code timeoutMillis} is negative * @throws IllegalMonitorStateException if the current thread is not * the owner of the object's monitor * @throws InterruptedException if any thread interrupted the current thread before or @@ -349,7 +349,7 @@ * @see #wait() * @see #wait(long, int) */ - public final native void wait(long timeout) throws InterruptedException; + public final native void wait(long timeoutMillis) throws InterruptedException; /** * Causes the current thread to wait until it is awakened, typically @@ -378,7 +378,7 @@ * thread T. *

  • The specified amount of real time has elapsed, more or less. * The amount of real time, in nanoseconds, is given by the expression - * {@code 1000000 * timeout + nanos}. If {@code timeout} and {@code nanos} + * {@code 1000000 * timeoutMillis + nanos}. If {@code timeoutMillis} and {@code nanos} * are both zero, then real time is not taken into consideration and the * thread waits until awakened by one of the other causes. *
  • Thread T is awakened spuriously. (See below.) @@ -423,17 +423,17 @@ *
    {@code
          *     synchronized (obj) {
          *         while ( and ) {
    -     *             long timeout = ... ; // recompute timeout values
    +     *             long timeoutMillis = ... ; // recompute timeout values
          *             int nanos = ... ;
    -     *             obj.wait(timeout, nanos);
    +     *             obj.wait(timeoutMillis, nanos);
          *         }
          *         ... // Perform action appropriate to condition or timeout
          *     }
          * }
    * - * @param timeout the maximum time to wait, in milliseconds + * @param timeoutMillis the maximum time to wait, in milliseconds * @param nanos additional time, in nanoseconds, in the range range 0-999999 inclusive - * @throws IllegalArgumentException if the value of {@code timeout} is negative, + * @throws IllegalArgumentException if {@code timeoutMillis} is negative, * or if the value of {@code nanos} is out of range * @throws IllegalMonitorStateException if the current thread is not * the owner of the object's monitor @@ -445,9 +445,9 @@ * @see #wait() * @see #wait(long) */ - public final void wait(long timeout, int nanos) throws InterruptedException { - if (timeout < 0) { - throw new IllegalArgumentException("timeout value is negative"); + public final void wait(long timeoutMillis, int nanos) throws InterruptedException { + if (timeoutMillis < 0) { + throw new IllegalArgumentException("timeoutMillis value is negative"); } if (nanos < 0 || nanos > 999999) { @@ -456,10 +456,10 @@ } if (nanos > 0) { - timeout++; + timeoutMillis++; } - wait(timeout); + wait(timeoutMillis); } /** diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/Clock.java --- a/src/java.base/share/classes/java/time/Clock.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/java.base/share/classes/java/time/Clock.java Fri Jun 08 19:14:58 2018 +0000 @@ -586,7 +586,7 @@ * This is typically used for testing. */ static final class FixedClock extends Clock implements Serializable { - private static final long serialVersionUID = 7430389292664866958L; + private static final long serialVersionUID = 7430389292664866958L; private final Instant instant; private final ZoneId zone; @@ -636,7 +636,7 @@ * Implementation of a clock that adds an offset to an underlying clock. */ static final class OffsetClock extends Clock implements Serializable { - private static final long serialVersionUID = 2007484719125426256L; + private static final long serialVersionUID = 2007484719125426256L; private final Clock baseClock; private final Duration offset; diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/Duration.java --- a/src/java.base/share/classes/java/time/Duration.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/java.base/share/classes/java/time/Duration.java Fri Jun 08 19:14:58 2018 +0000 @@ -231,7 +231,7 @@ * This method allows an arbitrary number of nanoseconds to be passed in. * The factory will alter the values of the second and nanosecond in order * to ensure that the stored nanosecond is in the range 0 to 999,999,999. - * For example, the following will result in the exactly the same duration: + * For example, the following will result in exactly the same duration: *
          *  Duration.ofSeconds(3, 1);
          *  Duration.ofSeconds(4, -999_999_999);
    @@ -1357,12 +1357,14 @@
          * Truncating the duration returns a copy of the original with conceptual fields
          * smaller than the specified unit set to zero.
          * For example, truncating with the {@link ChronoUnit#MINUTES MINUTES} unit will
    -     * round down to the nearest minute, setting the seconds and nanoseconds to zero.
    +     * round down towards zero to the nearest minute, setting the seconds and
    +     * nanoseconds to zero.
          * 

    * The unit must have a {@linkplain TemporalUnit#getDuration() duration} * that divides into the length of a standard day without remainder. - * This includes all supplied time units on {@link ChronoUnit} and - * {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception. + * This includes all + * {@linkplain ChronoUnit#isTimeBased() time-based units on {@code ChronoUnit}} + * and {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception. *

    * This instance is immutable and unaffected by this method call. * @@ -1388,7 +1390,7 @@ throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder"); } long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos; - long result = (nod / dur) * dur ; + long result = (nod / dur) * dur; return plusNanos(result - nod); } diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/Instant.java --- a/src/java.base/share/classes/java/time/Instant.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/java.base/share/classes/java/time/Instant.java Fri Jun 08 19:14:58 2018 +0000 @@ -311,7 +311,7 @@ * This method allows an arbitrary number of nanoseconds to be passed in. * The factory will alter the values of the second and nanosecond in order * to ensure that the stored nanosecond is in the range 0 to 999,999,999. - * For example, the following will result in the exactly the same instant: + * For example, the following will result in exactly the same instant: *

          *  Instant.ofEpochSecond(3, 1);
          *  Instant.ofEpochSecond(4, -999_999_999);
    @@ -757,7 +757,7 @@
                 throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
             }
             long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
    -        long result = Math.floorDiv(nod, dur) * dur ;
    +        long result = Math.floorDiv(nod, dur) * dur;
             return plusNanos(result - nod);
         }
     
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/LocalTime.java
    --- a/src/java.base/share/classes/java/time/LocalTime.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/LocalTime.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -356,14 +356,14 @@
          * @return the local time, not null
          * @since 9
          */
    -     public static LocalTime ofInstant(Instant instant, ZoneId zone) {
    -         Objects.requireNonNull(instant, "instant");
    -         Objects.requireNonNull(zone, "zone");
    -         ZoneOffset offset = zone.getRules().getOffset(instant);
    -         long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
    -         int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
    -         return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
    -     }
    +    public static LocalTime ofInstant(Instant instant, ZoneId zone) {
    +        Objects.requireNonNull(instant, "instant");
    +        Objects.requireNonNull(zone, "zone");
    +        ZoneOffset offset = zone.getRules().getOffset(instant);
    +        long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
    +        int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
    +        return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
    +    }
     
         //-----------------------------------------------------------------------
         /**
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/chrono/ChronoLocalDateImpl.java
    --- a/src/java.base/share/classes/java/time/chrono/ChronoLocalDateImpl.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/chrono/ChronoLocalDateImpl.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -110,7 +110,7 @@
      *        int year = date.get(ChronoField.YEAR);
      *        System.out.printf("  Today is %s %s %d-%s-%d%n", date.getChronology().getID(),
      *                dow, day, month, year);
    -
    + *
      *        // Print today's date and the last day of the year
      *        ChronoLocalDate now1 = Chronology.of("Hijrah").dateNow();
      *        ChronoLocalDate first = now1.with(ChronoField.DAY_OF_MONTH, 1)
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/chrono/ChronoLocalDateTime.java
    --- a/src/java.base/share/classes/java/time/chrono/ChronoLocalDateTime.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/chrono/ChronoLocalDateTime.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -201,7 +201,7 @@
          *
          * @return the date part of this date-time, not null
          */
    -    D toLocalDate() ;
    +    D toLocalDate();
     
         /**
          * Gets the local time part of this date-time.
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/chrono/Chronology.java
    --- a/src/java.base/share/classes/java/time/chrono/Chronology.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/chrono/Chronology.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -736,8 +736,8 @@
          * @throws DateTimeException if any of the values are out of range
          * @since 9
          */
    -     public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
    -                                     int hour, int minute, int second, ZoneOffset zoneOffset) {
    +    public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
    +                                    int hour, int minute, int second, ZoneOffset zoneOffset) {
             Objects.requireNonNull(zoneOffset, "zoneOffset");
             HOUR_OF_DAY.checkValidValue(hour);
             MINUTE_OF_HOUR.checkValidValue(minute);
    @@ -765,8 +765,8 @@
          * @throws DateTimeException if any of the values are out of range
          * @since 9
          */
    -     public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
    -                                     int hour, int minute, int second, ZoneOffset zoneOffset) {
    +    public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
    +                                    int hour, int minute, int second, ZoneOffset zoneOffset) {
             Objects.requireNonNull(era, "era");
             return epochSecond(prolepticYear(era, yearOfEra), month, dayOfMonth, hour, minute, second, zoneOffset);
         }
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/chrono/IsoChronology.java
    --- a/src/java.base/share/classes/java/time/chrono/IsoChronology.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/chrono/IsoChronology.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -287,9 +287,9 @@
          *         or if the day-of-month is invalid for the month-of-year
          * @since 9
          */
    -     @Override
    -     public long epochSecond(int prolepticYear, int month, int dayOfMonth,
    -                             int hour, int minute, int second, ZoneOffset zoneOffset) {
    +    @Override
    +    public long epochSecond(int prolepticYear, int month, int dayOfMonth,
    +                            int hour, int minute, int second, ZoneOffset zoneOffset) {
             YEAR.checkValidValue(prolepticYear);
             MONTH_OF_YEAR.checkValidValue(month);
             DAY_OF_MONTH.checkValidValue(dayOfMonth);
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/chrono/JapaneseChronology.java
    --- a/src/java.base/share/classes/java/time/chrono/JapaneseChronology.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/chrono/JapaneseChronology.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -459,38 +459,38 @@
             return era.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1;
         }
     
    -     private ChronoLocalDate resolveYMD(JapaneseEra era, int yoe, Map fieldValues, ResolverStyle resolverStyle) {
    -         fieldValues.remove(ERA);
    -         fieldValues.remove(YEAR_OF_ERA);
    -         if (resolverStyle == ResolverStyle.LENIENT) {
    -             int y = prolepticYearLenient(era, yoe);
    -             long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
    -             long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1);
    -             return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS);
    -         }
    -         int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR);
    -         int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH);
    -         if (resolverStyle == ResolverStyle.SMART) {  // previous valid
    -             if (yoe < 1) {
    -                 throw new DateTimeException("Invalid YearOfEra: " + yoe);
    -             }
    -             int y = prolepticYearLenient(era, yoe);
    -             JapaneseDate result;
    -             try {
    -                 result = date(y, moy, dom);
    -             } catch (DateTimeException ex) {
    -                 result = date(y, moy, 1).with(TemporalAdjusters.lastDayOfMonth());
    -             }
    -             // handle the era being changed
    -             // only allow if the new date is in the same Jan-Dec as the era change
    -             // determine by ensuring either original yoe or result yoe is 1
    -             if (result.getEra() != era && result.get(YEAR_OF_ERA) > 1 && yoe > 1) {
    -                 throw new DateTimeException("Invalid YearOfEra for Era: " + era + " " + yoe);
    -             }
    -             return result;
    -         }
    -         return date(era, yoe, moy, dom);
    -     }
    +    private ChronoLocalDate resolveYMD(JapaneseEra era, int yoe, Map fieldValues, ResolverStyle resolverStyle) {
    +        fieldValues.remove(ERA);
    +        fieldValues.remove(YEAR_OF_ERA);
    +        if (resolverStyle == ResolverStyle.LENIENT) {
    +            int y = prolepticYearLenient(era, yoe);
    +            long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
    +            long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1);
    +            return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS);
    +        }
    +        int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR);
    +        int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH);
    +        if (resolverStyle == ResolverStyle.SMART) {  // previous valid
    +            if (yoe < 1) {
    +                throw new DateTimeException("Invalid YearOfEra: " + yoe);
    +            }
    +            int y = prolepticYearLenient(era, yoe);
    +            JapaneseDate result;
    +            try {
    +                result = date(y, moy, dom);
    +            } catch (DateTimeException ex) {
    +                result = date(y, moy, 1).with(TemporalAdjusters.lastDayOfMonth());
    +            }
    +            // handle the era being changed
    +            // only allow if the new date is in the same Jan-Dec as the era change
    +            // determine by ensuring either original yoe or result yoe is 1
    +            if (result.getEra() != era && result.get(YEAR_OF_ERA) > 1 && yoe > 1) {
    +                throw new DateTimeException("Invalid YearOfEra for Era: " + era + " " + yoe);
    +            }
    +            return result;
    +        }
    +        return date(era, yoe, moy, dom);
    +    }
     
         private ChronoLocalDate resolveYD(JapaneseEra era, int yoe, Map  fieldValues, ResolverStyle resolverStyle) {
             fieldValues.remove(ERA);
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java
    --- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -3049,7 +3049,7 @@
          * Prints and parses a numeric date-time field with optional padding.
          */
         static final class FractionPrinterParser extends NumberPrinterParser {
    -       private final boolean decimalPoint;
    +        private final boolean decimalPoint;
     
             /**
              * Constructor.
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/format/DecimalStyle.java
    --- a/src/java.base/share/classes/java/time/format/DecimalStyle.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/format/DecimalStyle.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -216,7 +216,6 @@
          *
          * @param zeroDigit  the character for zero
          * @return  a copy with a new character that represents zero, not null
    -
          */
         public DecimalStyle withZeroDigit(char zeroDigit) {
             if (zeroDigit == this.zeroDigit) {
    diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java
    --- a/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java	Fri Jun 08 11:59:34 2018 -0700
    +++ b/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java	Fri Jun 08 19:14:58 2018 +0000
    @@ -119,7 +119,7 @@
      * Providers must ensure that once a rule has been seen by the application, the
      * rule must continue to be available.
      * 

    -* Providers are encouraged to implement a meaningful {@code toString} method. + * Providers are encouraged to implement a meaningful {@code toString} method. *

    * Many systems would like to update time-zone rules dynamically without stopping the JVM. * When examined in detail, this is a complex problem. diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/util/Formatter.java --- a/src/java.base/share/classes/java/util/Formatter.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/java.base/share/classes/java/util/Formatter.java Fri Jun 08 19:14:58 2018 +0000 @@ -2914,7 +2914,7 @@ a.append(System.lineSeparator()); break; case Conversion.PERCENT_SIGN: - a.append('%'); + print("%", l); break; default: assert false; diff -r 25178bb3e8f5 -r 789118dc46c6 src/java.base/share/classes/java/util/concurrent/TimeUnit.java --- a/src/java.base/share/classes/java/util/concurrent/TimeUnit.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/java.base/share/classes/java/util/concurrent/TimeUnit.java Fri Jun 08 19:14:58 2018 +0000 @@ -35,6 +35,7 @@ package java.util.concurrent; +import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.Objects; @@ -192,6 +193,50 @@ } /** + * Converts the given time duration to this unit. + * + *

    For any TimeUnit {@code unit}, + * {@code unit.convert(Duration.ofNanos(n))} + * is equivalent to + * {@code unit.convert(n, NANOSECONDS)}, and + * {@code unit.convert(Duration.of(n, unit.toChronoUnit()))} + * is equivalent to {@code n} (in the absence of overflow). + * + * @param duration the time duration + * @return the converted duration in this unit, + * or {@code Long.MIN_VALUE} if conversion would negatively overflow, + * or {@code Long.MAX_VALUE} if it would positively overflow. + * @throws NullPointerException if {@code duration} is null + * @see Duration#of(long,TemporalUnit) + * @since 11 + */ + public long convert(Duration duration) { + long secs = duration.getSeconds(); + int nano = duration.getNano(); + if (secs < 0 && nano > 0) { + // use representation compatible with integer division + secs++; + nano -= SECOND_SCALE; + } + final long s, nanoVal; + // Optimize for the common case - NANOSECONDS without overflow + if (this == NANOSECONDS) + nanoVal = nano; + else if ((s = scale) < SECOND_SCALE) + nanoVal = nano / s; + else if (this == SECONDS) + return secs; + else + return secs / secRatio; + long val = secs * secRatio + nanoVal; + return ((secs < maxSecs && secs > -maxSecs) || + (secs == maxSecs && val > 0) || + (secs == -maxSecs && val < 0)) + ? val + : (secs > 0) ? Long.MAX_VALUE : Long.MIN_VALUE; + } + + /** * Equivalent to * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}. * @param duration the duration @@ -221,10 +266,8 @@ */ public long toMicros(long duration) { long s, m; - if ((s = scale) == MICRO_SCALE) - return duration; - else if (s < MICRO_SCALE) - return duration / microRatio; + if ((s = scale) <= MICRO_SCALE) + return (s == MICRO_SCALE) ? duration : duration / microRatio; else if (duration > (m = maxMicros)) return Long.MAX_VALUE; else if (duration < -m) @@ -243,10 +286,8 @@ */ public long toMillis(long duration) { long s, m; - if ((s = scale) == MILLI_SCALE) - return duration; - else if (s < MILLI_SCALE) - return duration / milliRatio; + if ((s = scale) <= MILLI_SCALE) + return (s == MILLI_SCALE) ? duration : duration / milliRatio; else if (duration > (m = maxMillis)) return Long.MAX_VALUE; else if (duration < -m) @@ -265,10 +306,8 @@ */ public long toSeconds(long duration) { long s, m; - if ((s = scale) == SECOND_SCALE) - return duration; - else if (s < SECOND_SCALE) - return duration / secRatio; + if ((s = scale) <= SECOND_SCALE) + return (s == SECOND_SCALE) ? duration : duration / secRatio; else if (duration > (m = maxSecs)) return Long.MAX_VALUE; else if (duration < -m) diff -r 25178bb3e8f5 -r 789118dc46c6 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Jun 08 19:14:58 2018 +0000 @@ -49,6 +49,7 @@ import sun.jvm.hotspot.debugger.Address; import sun.jvm.hotspot.debugger.OopHandle; import sun.jvm.hotspot.classfile.ClassLoaderDataGraph; +import sun.jvm.hotspot.memory.FileMapInfo; import sun.jvm.hotspot.memory.SymbolTable; import sun.jvm.hotspot.memory.SystemDictionary; import sun.jvm.hotspot.memory.Universe; @@ -89,6 +90,7 @@ import sun.jvm.hotspot.ui.tree.SimpleTreeNode; import sun.jvm.hotspot.utilities.AddressOps; import sun.jvm.hotspot.utilities.Assert; +import sun.jvm.hotspot.utilities.CompactHashTable; import sun.jvm.hotspot.utilities.HeapProgressThunk; import sun.jvm.hotspot.utilities.LivenessPathElement; import sun.jvm.hotspot.utilities.MethodArray; @@ -637,12 +639,22 @@ }, new Command("symboldump", "symboldump", false) { public void doit(Tokens t) { - SymbolTable.getTheTable().symbolsDo(new SymbolTable.SymbolVisitor() { + SymbolTable theTable = SymbolTable.getTheTable(); + theTable.symbolsDo(new SymbolTable.SymbolVisitor() { public void visit(Symbol sym) { sym.printValueOn(out); out.println(); } }); + CompactHashTable sharedTable = theTable.getSharedTable(); + if (sharedTable != null) { + sharedTable.symbolsDo(new CompactHashTable.SymbolVisitor() { + public void visit(Symbol sym) { + sym.printValueOn(out); + out.println(); + } + }); + } } }, new Command("flags", "flags [ flag | -nd ]", false) { @@ -1048,6 +1060,15 @@ } if (node == null) { Type type = VM.getVM().getTypeDataBase().guessTypeForAddress(a); + if (type == null && VM.getVM().isSharingEnabled()) { + // Check if the value falls in the _md_region + Address loc1 = a.getAddressAt(0); + FileMapInfo cdsFileMapInfo = VM.getVM().getFileMapInfo(); + if (cdsFileMapInfo.inCopiedVtableSpace(loc1)) { + type = cdsFileMapInfo.getTypeForVptrAddress(loc1); + } + + } if (type != null) { out.println("Type is " + type.getName() + " (size of " + type.getSize() + ")"); node = new CTypeTreeNodeAdapter(a, type, null); diff -r 25178bb3e8f5 -r 789118dc46c6 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Fri Jun 08 19:14:58 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,6 +65,10 @@ return table; } + public CompactHashTable getSharedTable() { + return sharedTable; + } + public static long getSeed() { return (long) seedField.getValue(); } diff -r 25178bb3e8f5 -r 789118dc46c6 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java Fri Jun 08 11:59:34 2018 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java Fri Jun 08 19:14:58 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,4 +119,39 @@ } return null; } + + public interface SymbolVisitor { + public void visit(Symbol sym); + } + + public void symbolsDo(SymbolVisitor visitor) { + long symOffset; + Symbol sym; + Address baseAddress = baseAddressField.getValue(addr); + Address bucket = bucketsField.getValue(addr); + for (long index = 0; index < bucketCount(); index++) { + int bucketInfo = (int)bucket.getCIntegerAt(index * uintSize, uintSize, true); + int bucketOffset = bucketOffset(bucketInfo); + int nextBucketInfo = (int)bucket.getCIntegerAt((index+1) * uintSize, uintSize, true); + int nextBucketOffset = bucketOffset(nextBucketInfo); + + Address entry = entriesField.getValue(addr).addOffsetTo(bucketOffset * uintSize); + + if (isValueOnlyBucket(bucketInfo)) { + symOffset = entry.getCIntegerAt(0, uintSize, true); + sym = Symbol.create(baseAddress.addOffsetTo(symOffset)); + visitor.visit(sym); + } else { + Address entryMax = entriesField.getValue(addr).addOffsetTo(nextBucketOffset * uintSize); + while (entry.lessThan(entryMax)) { + symOffset = entry.getCIntegerAt(uintSize, uintSize, true); + Address symAddr = baseAddress.addOffsetTo(symOffset); + sym = Symbol.create(symAddr); + visitor.visit(sym); + entry = entry.addOffsetTo(2 * uintSize); + } + } + } + } } + diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/Basic-X.java.template --- a/test/jdk/java/util/Formatter/Basic-X.java.template Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/Basic-X.java.template Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/Basic.java --- a/test/jdk/java/util/Formatter/Basic.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/Basic.java Fri Jun 08 19:14:58 2018 +0000 @@ -26,7 +26,7 @@ * @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937 * 5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122 * 6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160 6476168 - * 8059175 + * 8059175 8204229 * * @modules java.base * @run shell/timeout=240 Basic.sh diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicBigDecimal.java --- a/test/jdk/java/util/Formatter/BasicBigDecimal.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicBigDecimal.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicBigInteger.java --- a/test/jdk/java/util/Formatter/BasicBigInteger.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicBigInteger.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicBoolean.java --- a/test/jdk/java/util/Formatter/BasicBoolean.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicBoolean.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicBooleanObject.java --- a/test/jdk/java/util/Formatter/BasicBooleanObject.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicBooleanObject.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicByte.java --- a/test/jdk/java/util/Formatter/BasicByte.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicByte.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicByteObject.java --- a/test/jdk/java/util/Formatter/BasicByteObject.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicByteObject.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicChar.java --- a/test/jdk/java/util/Formatter/BasicChar.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicChar.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicCharObject.java --- a/test/jdk/java/util/Formatter/BasicCharObject.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicCharObject.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicDateTime.java --- a/test/jdk/java/util/Formatter/BasicDateTime.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicDateTime.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicDouble.java --- a/test/jdk/java/util/Formatter/BasicDouble.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicDouble.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicDoubleObject.java --- a/test/jdk/java/util/Formatter/BasicDoubleObject.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicDoubleObject.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicFloat.java --- a/test/jdk/java/util/Formatter/BasicFloat.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicFloat.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicFloatObject.java --- a/test/jdk/java/util/Formatter/BasicFloatObject.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicFloatObject.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicInt.java --- a/test/jdk/java/util/Formatter/BasicInt.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicInt.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicIntObject.java --- a/test/jdk/java/util/Formatter/BasicIntObject.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicIntObject.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicLong.java --- a/test/jdk/java/util/Formatter/BasicLong.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicLong.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicLongObject.java --- a/test/jdk/java/util/Formatter/BasicLongObject.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicLongObject.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicShort.java --- a/test/jdk/java/util/Formatter/BasicShort.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicShort.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/BasicShortObject.java --- a/test/jdk/java/util/Formatter/BasicShortObject.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/BasicShortObject.java Fri Jun 08 19:14:58 2018 +0000 @@ -1792,6 +1792,15 @@ //--------------------------------------------------------------------- test("%%", "%", (Object)null); test("%%", "%", ""); + + test("%5%", " %", (Object)null); + test("%5%", " %", ""); + test("%-5%", "% ", (Object)null); + test("%-5%", "% ", ""); + + tryCatch("%.5%", IllegalFormatPrecisionException.class); + tryCatch("%5.5%", IllegalFormatPrecisionException.class); + tryCatch("%%%", UnknownFormatConversionException.class); // perhaps an IllegalFormatArgumentIndexException should be defined? tryCatch("%<%", IllegalFormatFlagsException.class); diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/Formatter/genBasic.sh --- a/test/jdk/java/util/Formatter/genBasic.sh Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/Formatter/genBasic.sh Fri Jun 08 19:14:58 2018 +0000 @@ -23,7 +23,7 @@ # questions. # -javac -d . ../../../../make/src/classes/build/tools/spp/Spp.java +javac -d . ../../../../../make/jdk/src/classes/build/tools/spp/Spp.java gen() { # if [ $3 = "true" ] diff -r 25178bb3e8f5 -r 789118dc46c6 test/jdk/java/util/concurrent/tck/TimeUnit8Test.java --- a/test/jdk/java/util/concurrent/tck/TimeUnit8Test.java Fri Jun 08 11:59:34 2018 -0700 +++ b/test/jdk/java/util/concurrent/tck/TimeUnit8Test.java Fri Jun 08 19:14:58 2018 +0000 @@ -40,8 +40,12 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; +import java.time.Duration; import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; +import java.util.stream.LongStream; import junit.framework.Test; import junit.framework.TestSuite; @@ -100,4 +104,85 @@ } } + /** + * convert(Duration) roundtrips with Duration.ofXXXX and Duration.of(long, ChronoUnit) + */ + public void testConvertDuration_roundtripDurationOf() { + long n = ThreadLocalRandom.current().nextLong(); + + assertEquals(n, NANOSECONDS.convert(Duration.ofNanos(n))); + assertEquals(n, NANOSECONDS.convert(Duration.of(n, ChronoUnit.NANOS))); + assertEquals(n, MILLISECONDS.convert(Duration.ofMillis(n))); + assertEquals(n, MILLISECONDS.convert(Duration.of(n, ChronoUnit.MILLIS))); + assertEquals(n, SECONDS.convert(Duration.ofSeconds(n))); + assertEquals(n, SECONDS.convert(Duration.of(n, ChronoUnit.SECONDS))); + n /= 60; + assertEquals(n, MINUTES.convert(Duration.ofMinutes(n))); + assertEquals(n, MINUTES.convert(Duration.of(n, ChronoUnit.MINUTES))); + n /= 60; + assertEquals(n, HOURS.convert(Duration.ofHours(n))); + assertEquals(n, HOURS.convert(Duration.of(n, ChronoUnit.HOURS))); + n /= 24; + assertEquals(n, DAYS.convert(Duration.ofDays(n))); + assertEquals(n, DAYS.convert(Duration.of(n, ChronoUnit.DAYS))); + } + + /** + * convert(Duration.ofNanos(n)) agrees with convert(n, NANOSECONDS) + */ + public void testConvertDuration_roundtripDurationOfNanos() { + // Test values near unit transitions and near overflow. + LongStream.concat( + Arrays.stream(TimeUnit.values()).mapToLong(u -> u.toNanos(1)), + LongStream.of(Long.MAX_VALUE, Long.MIN_VALUE)) + .flatMap(n -> LongStream.of(n, n + 1, n - 1)) + .flatMap(n -> LongStream.of(n, n + 1_000_000_000, n - 1_000_000_000)) + .flatMap(n -> LongStream.of(n, -n)) + // .peek(System.err::println) + .forEach(n -> Arrays.stream(TimeUnit.values()).forEach( + u -> assertEquals(u.convert(n, NANOSECONDS), + u.convert(Duration.ofNanos(n))))); + } + + /** + * convert(Duration) doesn't misbehave near Long.MAX_VALUE and Long.MIN_VALUE. + */ + public void testConvertDuration_nearOverflow() { + ChronoUnit NANOS = ChronoUnit.NANOS; + Duration maxDuration = Duration.ofSeconds(Long.MAX_VALUE, 999_999_999); + Duration minDuration = Duration.ofSeconds(Long.MIN_VALUE, 0); + + for (TimeUnit u : TimeUnit.values()) { + ChronoUnit cu = u.toChronoUnit(); + long r; + if (u.toNanos(1) > SECONDS.toNanos(1)) { + r = u.toNanos(1) / SECONDS.toNanos(1); + + assertThrows(ArithmeticException.class, + () -> Duration.of(Long.MAX_VALUE, cu), + () -> Duration.of(Long.MIN_VALUE, cu)); + } else { + r = 1; + + Duration max = Duration.of(Long.MAX_VALUE, cu); + Duration min = Duration.of(Long.MIN_VALUE, cu); + assertEquals(Long.MAX_VALUE, u.convert(max)); + assertEquals(Long.MAX_VALUE - 1, u.convert(max.minus(1, NANOS))); + assertEquals(Long.MAX_VALUE - 1, u.convert(max.minus(1, cu))); + assertEquals(Long.MIN_VALUE, u.convert(min)); + assertEquals(Long.MIN_VALUE + 1, u.convert(min.plus(1, NANOS))); + assertEquals(Long.MIN_VALUE + 1, u.convert(min.plus(1, cu))); + assertEquals(Long.MAX_VALUE, u.convert(max.plus(1, NANOS))); + if (u != SECONDS) { + assertEquals(Long.MAX_VALUE, u.convert(max.plus(1, cu))); + assertEquals(Long.MIN_VALUE, u.convert(min.minus(1, NANOS))); + assertEquals(Long.MIN_VALUE, u.convert(min.minus(1, cu))); + } + } + + assertEquals(Long.MAX_VALUE / r, u.convert(maxDuration)); + assertEquals(Long.MIN_VALUE / r, u.convert(minDuration)); + } + } + }