--- 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 <em>notified</em> or <em>interrupted</em>, or until a
* certain amount of real time has elapsed.
* <p>
- * 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 <var>T</var>.
* <li>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.
* <li>Thread <var>T</var> is awakened spuriously. (See below.)
@@ -423,17 +423,17 @@
* <pre>{@code
* synchronized (obj) {
* while (<condition does not hold> and <timeout not exceeded>) {
- * 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
* }
* }</pre>
*
- * @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);
}
/**
--- 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;
--- 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:
* <pre>
* 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.
* <p>
* 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.
* <p>
* 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);
}
--- 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:
* <pre>
* 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);
}
--- 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());
+ }
//-----------------------------------------------------------------------
/**
--- 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)
--- 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.
--- 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);
}
--- 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);
--- 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<TemporalField,Long> 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<TemporalField,Long> 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 <TemporalField,Long> fieldValues, ResolverStyle resolverStyle) {
fieldValues.remove(ERA);
--- 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.
--- 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) {
--- 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.
* <p>
-* Providers are encouraged to implement a meaningful {@code toString} method.
+ * Providers are encouraged to implement a meaningful {@code toString} method.
* <p>
* Many systems would like to update time-zone rules dynamically without stopping the JVM.
* When examined in detail, this is a complex problem.
--- 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;
--- 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.
+ *
+ * <p>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)
--- 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);
--- 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();
}
--- 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);
+ }
+ }
+ }
+ }
}
+
--- 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);
--- 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
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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);
--- 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" ]
--- 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));
+ }
+ }
+
}