This commit is contained in:
Lana Steuck 2016-03-23 21:45:11 -07:00
commit 05feaeeecd
90 changed files with 5123 additions and 1648 deletions

View File

@ -25,103 +25,7 @@
include Modules.gmk
BOOT_MODULES :=
UPGRADEABLE_MDOULES :=
AGGREGATOR_MDOULES :=
OTHER_PLATFORM_MODULES :=
# Hook to include the corresponding custom file, if present.
$(eval $(call IncludeCustomExtension, jdk, gensrc/GensrcModuleLoaderMap.gmk))
BOOT_MODULES += \
java.base \
java.datatransfer \
java.desktop \
java.httpclient \
java.instrument \
java.logging \
java.management \
java.naming \
java.prefs \
java.rmi \
java.security.jgss \
java.security.sasl \
java.sql \
java.xml \
java.xml.crypto \
jdk.httpserver \
jdk.management \
jdk.sctp \
jdk.security.auth \
jdk.security.jgss \
#
# to be deprivileged
BOOT_MODULES += \
java.compiler \
java.scripting \
java.sql.rowset \
java.smartcardio \
jdk.charsets \
jdk.naming.rmi \
#
UPGRADEABLE_MODULES += \
java.activation \
java.annotations.common \
java.corba \
java.transaction \
java.xml.bind \
java.xml.ws \
#
AGGREGATOR_MODULES += \
java.compact1 \
java.compact2 \
java.compact3 \
java.se \
java.se.ee \
#
OTHER_PLATFORM_MODULES += \
jdk.accessibility \
jdk.crypto.ec \
jdk.crypto.pkcs11 \
jdk.dynalink \
jdk.jsobject \
jdk.xml.dom \
jdk.localedata \
jdk.naming.dns \
jdk.scripting.nashorn \
jdk.zipfs \
#
ifeq ($(OPENJDK_TARGET_OS), macsox)
BOOT_MODULES += jdk.deploy.osx
endif
ifeq ($(OPENJDK_TARGET_OS), windows)
OTHER_PLATFORM_MODULES += jdk.crypto.mscapi
endif
ifeq ($(OPENJDK_TARGET_OS), solaris)
OTHER_PLATFORM_MODULES += jdk.crypto.ucrypto
endif
# Param 1 - Name of module
define ReadImportMetaData
ifneq ($$(wildcard $(IMPORT_MODULES_MAKE)/$$(strip $1)/build.properties), )
classloader :=
include $(IMPORT_MODULES_MAKE)/$$(strip $1)/build.properties
ifeq ($$(classloader), boot)
BOOT_MODULES += $1
else ifeq ($$(classloader), ext)
OTHER_PLATFORM_MODULES += $1
endif
endif
endef
IMPORTED_MODULES := $(call FindImportedModules)
$(foreach m, $(IMPORTED_MODULES), $(eval $(call ReadImportMetaData, $m)))
$(eval $(call ReadImportMetaData))
# Replacing double-comma with a single comma is to workaround the issue
# with some version of make on windows that doesn't substitute spaces
@ -132,7 +36,7 @@ $(strip \
)
endef
BOOT_MODULES_LIST := $(call SubstComma, $(BOOT_MODULES))
PLATFORM_MODULES_LIST := $(call SubstComma, $(UPGRADEABLE_MODULES) $(AGGREGATOR_MODULES) $(OTHER_PLATFORM_MODULES))
PLATFORM_MODULES_LIST := $(call SubstComma, $(PLATFORM_MODULES))
VARDEPS_VALUE := $(BOOT_MODULES_LIST) $(PLATFORM_MODULES_LIST)
VARDEPS_FILE := $(call DependOnVariable, VARDEPS_VALUE)

View File

@ -27,5 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jjs, \
MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
JAVA_ARGS := -addmods ALL-SYSTEM, \
CFLAGS := -DENABLE_ARG_FILES, \
))

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2016, 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
@ -36,7 +36,7 @@ import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static java.io.ObjectStreamClass.processQueue;
@ -212,20 +212,20 @@ public class ObjectInputStream
/** marker for unshared objects in internal handle table */
private static final Object unsharedMarker = new Object();
/** table mapping primitive type names to corresponding class objects */
private static final HashMap<String, Class<?>> primClasses
= new HashMap<>(8, 1.0F);
static {
primClasses.put("boolean", boolean.class);
primClasses.put("byte", byte.class);
primClasses.put("char", char.class);
primClasses.put("short", short.class);
primClasses.put("int", int.class);
primClasses.put("long", long.class);
primClasses.put("float", float.class);
primClasses.put("double", double.class);
primClasses.put("void", void.class);
}
/**
* immutable table mapping primitive type names to corresponding
* class objects
*/
private static final Map<String, Class<?>> primClasses =
Map.of("boolean", boolean.class,
"byte", byte.class,
"char", char.class,
"short", short.class,
"int", int.class,
"long", long.class,
"float", float.class,
"double", double.class,
"void", void.class);
private static class Caches {
/** cache of subclass security audit results */

View File

@ -108,11 +108,14 @@ public class MethodHandles {
* <p>
* For now, the {@linkplain Lookup#lookupClass lookup class} of this lookup
* object is in an unnamed module.
* Consequently, the lookup context of this lookup object will be the bootstrap
* class loader, which means it cannot find user classes.
*
* <p style="font-size:smaller;">
* <em>Discussion:</em>
* The lookup class can be changed to any other class {@code C} using an expression of the form
* {@link Lookup#in publicLookup().in(C.class)}.
* but may change the lookup context by virtue of changing the class loader.
* A public lookup object is always subject to
* <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
* Also, it cannot access
@ -677,6 +680,11 @@ public class MethodHandles {
* then no members, not even public members, will be accessible.
* (In all other cases, public members will continue to be accessible.)
* </ul>
* <p>
* The resulting lookup's capabilities for loading classes
* (used during {@link #findClass} invocations)
* are determined by the lookup class' loader,
* which may change due to this operation.
*
* @param requestedLookupClass the desired lookup class for the new lookup object
* @return a lookup object which reports the desired lookup class
@ -983,13 +991,17 @@ assertEquals("[x, y, z]", pb.command().toString());
/**
* Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
* initializer of the class is not run.
* <p>
* The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
* loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
* load the requested class, and then determines whether the class is accessible to this lookup object.
*
* @param targetName the fully qualified name of the class to be looked up.
* @return the requested class.
* @exception SecurityException if a security manager is present and it
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @throws LinkageError if the linkage fails
* @throws ClassNotFoundException if the class does not exist.
* @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
* @throws IllegalAccessException if the class is not accessible, using the allowed access
* modes.
* @exception SecurityException if a security manager is present and it
@ -1004,6 +1016,9 @@ assertEquals("[x, y, z]", pb.command().toString());
/**
* Determines if a class can be accessed from the lookup context defined by this {@code Lookup} object. The
* static initializer of the class is not run.
* <p>
* The lookup context here is determined by the {@linkplain #lookupClass() lookup class} and the
* {@linkplain #lookupModes() lookup modes}.
*
* @param targetClass the class to be access-checked
*

View File

@ -1106,7 +1106,7 @@ public final class Instant
* complete units between the two instants.
* The {@code Temporal} passed to this method is converted to a
* {@code Instant} using {@link #from(TemporalAccessor)}.
* For example, the amount in days between two dates can be calculated
* For example, the amount in seconds between two dates can be calculated
* using {@code startInstant.until(endInstant, SECONDS)}.
* <p>
* There are two equivalent ways of using this method.

View File

@ -619,6 +619,9 @@ public final class DateTimeFormatter {
* The returned formatter has a chronology of ISO set to ensure dates in
* other calendar systems are correctly converted.
* It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
* The {@code FULL} and {@code LONG} styles typically require a time-zone.
* When formatting using these styles, a {@code ZoneId} must be available,
* either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
*
* @param timeStyle the formatter style to obtain, not null
* @return the time formatter, not null
@ -647,6 +650,9 @@ public final class DateTimeFormatter {
* The returned formatter has a chronology of ISO set to ensure dates in
* other calendar systems are correctly converted.
* It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
* The {@code FULL} and {@code LONG} styles typically require a time-zone.
* When formatting using these styles, a {@code ZoneId} must be available,
* either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
*
* @param dateTimeStyle the formatter style to obtain, not null
* @return the date-time formatter, not null
@ -675,6 +681,9 @@ public final class DateTimeFormatter {
* The returned formatter has a chronology of ISO set to ensure dates in
* other calendar systems are correctly converted.
* It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
* The {@code FULL} and {@code LONG} styles typically require a time-zone.
* When formatting using these styles, a {@code ZoneId} must be available,
* either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
*
* @param dateStyle the date formatter style to obtain, not null
* @param timeStyle the time formatter style to obtain, not null
@ -923,6 +932,7 @@ public final class DateTimeFormatter {
* <li>The {@link #ISO_LOCAL_DATE_TIME}
* <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
* they will be handled even though this is not part of the ISO-8601 standard.
* The offset parsing is lenient, which allows the minutes and seconds to be optional.
* Parsing is case insensitive.
* </ul>
* <p>
@ -935,7 +945,9 @@ public final class DateTimeFormatter {
ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(ISO_LOCAL_DATE_TIME)
.parseLenient()
.appendOffsetId()
.parseStrict()
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
}
@ -1160,6 +1172,7 @@ public final class DateTimeFormatter {
* <li>If the offset is not available to format or parse then the format is complete.
* <li>The {@link ZoneOffset#getId() offset ID} without colons. If the offset has
* seconds then they will be handled even though this is not part of the ISO-8601 standard.
* The offset parsing is lenient, which allows the minutes and seconds to be optional.
* Parsing is case insensitive.
* </ul>
* <p>
@ -1178,7 +1191,9 @@ public final class DateTimeFormatter {
.appendValue(MONTH_OF_YEAR, 2)
.appendValue(DAY_OF_MONTH, 2)
.optionalStart()
.parseLenient()
.appendOffset("+HHMMss", "Z")
.parseStrict()
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
}

View File

@ -866,7 +866,9 @@ public final class DateTimeFormatterBuilder {
* Appends the zone offset, such as '+01:00', to the formatter.
* <p>
* This appends an instruction to format/parse the offset ID to the builder.
* This is equivalent to calling {@code appendOffset("+HH:MM:ss", "Z")}.
* This is equivalent to calling {@code appendOffset("+HH:mm:ss", "Z")}.
* See {@link #appendOffset(String, String)} for details on formatting
* and parsing.
*
* @return this, for chaining, not null
*/
@ -886,9 +888,18 @@ public final class DateTimeFormatterBuilder {
* If the offset cannot be obtained then an exception is thrown unless the
* section of the formatter is optional.
* <p>
* During parsing, the offset is parsed using the format defined below.
* If the offset cannot be parsed then an exception is thrown unless the
* section of the formatter is optional.
* When parsing in strict mode, the input must contain the mandatory
* and optional elements are defined by the specified pattern.
* If the offset cannot be parsed then an exception is thrown unless
* the section of the formatter is optional.
* <p>
* When parsing in lenient mode, only the hours are mandatory - minutes
* and seconds are optional. The colons are required if the specified
* pattern contains a colon. If the specified pattern is "+HH", the
* presence of colons is determined by whether the character after the
* hour digits is a colon or not.
* If the offset cannot be parsed then an exception is thrown unless
* the section of the formatter is optional.
* <p>
* The format of the offset is controlled by a pattern which must be one
* of the following:
@ -902,6 +913,10 @@ public final class DateTimeFormatterBuilder {
* <li>{@code +HH:MM:ss} - hour and minute, with second if non-zero, with colon
* <li>{@code +HHMMSS} - hour, minute and second, no colon
* <li>{@code +HH:MM:SS} - hour, minute and second, with colon
* <li>{@code +HHmmss} - hour, with minute if non-zero or with minute and
* second if non-zero, no colon
* <li>{@code +HH:mm:ss} - hour, with minute if non-zero or with minute and
* second if non-zero, with colon
* </ul>
* The "no offset" text controls what text is printed when the total amount of
* the offset fields to be output is zero.
@ -1256,6 +1271,9 @@ public final class DateTimeFormatterBuilder {
* During formatting, the chronology is obtained from the temporal object
* being formatted, which may have been overridden by
* {@link DateTimeFormatter#withChronology(Chronology)}.
* The {@code FULL} and {@code LONG} styles typically require a time-zone.
* When formatting using these styles, a {@code ZoneId} must be available,
* either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
* <p>
* During parsing, if a chronology has already been parsed, then it is used.
* Otherwise the default from {@code DateTimeFormatter.withChronology(Chronology)}
@ -3315,7 +3333,7 @@ public final class DateTimeFormatterBuilder {
*/
static final class OffsetIdPrinterParser implements DateTimePrinterParser {
static final String[] PATTERNS = new String[] {
"+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
"+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS", "+HHmmss", "+HH:mm:ss",
}; // order used in pattern builder
static final OffsetIdPrinterParser INSTANCE_ID_Z = new OffsetIdPrinterParser("+HH:MM:ss", "Z");
static final OffsetIdPrinterParser INSTANCE_ID_ZERO = new OffsetIdPrinterParser("+HH:MM:ss", "0");
@ -3362,11 +3380,11 @@ public final class DateTimeFormatterBuilder {
int output = absHours;
buf.append(totalSecs < 0 ? "-" : "+")
.append((char) (absHours / 10 + '0')).append((char) (absHours % 10 + '0'));
if (type >= 3 || (type >= 1 && absMinutes > 0)) {
if ((type >= 3 && type < 9) || (type >= 9 && absSeconds > 0) || (type >= 1 && absMinutes > 0)) {
buf.append((type % 2) == 0 ? ":" : "")
.append((char) (absMinutes / 10 + '0')).append((char) (absMinutes % 10 + '0'));
output += absMinutes;
if (type >= 7 || (type >= 5 && absSeconds > 0)) {
if (type == 7 || type == 8 || (type >= 5 && absSeconds > 0)) {
buf.append((type % 2) == 0 ? ":" : "")
.append((char) (absSeconds / 10 + '0')).append((char) (absSeconds % 10 + '0'));
output += absSeconds;
@ -3384,6 +3402,15 @@ public final class DateTimeFormatterBuilder {
public int parse(DateTimeParseContext context, CharSequence text, int position) {
int length = text.length();
int noOffsetLen = noOffsetText.length();
int parseType = type;
if (context.isStrict() == false) {
if ((parseType > 0 && (parseType % 2) == 0) ||
(parseType == 0 && length > position + 3 && text.charAt(position + 3) == ':')) {
parseType = 10;
} else {
parseType = 9;
}
}
if (noOffsetLen == 0) {
if (position == length) {
return context.setParsedField(OFFSET_SECONDS, 0, position, position);
@ -3404,9 +3431,9 @@ public final class DateTimeFormatterBuilder {
int negative = (sign == '-' ? -1 : 1);
int[] array = new int[4];
array[0] = position + 1;
if ((parseNumber(array, 1, text, true) ||
parseNumber(array, 2, text, type >=3) ||
parseNumber(array, 3, text, false)) == false) {
if ((parseNumber(array, 1, text, true, parseType) ||
parseNumber(array, 2, text, parseType >= 3 && parseType < 9, parseType) ||
parseNumber(array, 3, text, parseType == 7 || parseType == 8, parseType)) == false) {
// success
long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]);
@ -3414,7 +3441,7 @@ public final class DateTimeFormatterBuilder {
}
// handle special case of empty no offset text
if (noOffsetLen == 0) {
return context.setParsedField(OFFSET_SECONDS, 0, position, position + noOffsetLen);
return context.setParsedField(OFFSET_SECONDS, 0, position, position);
}
return ~position;
}
@ -3426,14 +3453,15 @@ public final class DateTimeFormatterBuilder {
* @param arrayIndex the index to parse the value into
* @param parseText the offset ID, not null
* @param required whether this number is required
* @param parseType the offset pattern type
* @return true if an error occurred
*/
private boolean parseNumber(int[] array, int arrayIndex, CharSequence parseText, boolean required) {
if ((type + 3) / 2 < arrayIndex) {
private boolean parseNumber(int[] array, int arrayIndex, CharSequence parseText, boolean required, int parseType) {
if ((parseType + 3) / 2 < arrayIndex) {
return false; // ignore seconds/minutes
}
int pos = array[0];
if ((type % 2) == 0 && arrayIndex > 1) {
if ((parseType % 2) == 0 && arrayIndex > 1) {
if (pos + 1 > parseText.length() || parseText.charAt(pos) != ':') {
return required;
}

View File

@ -218,6 +218,13 @@ final class DateTimePrintContext {
}
return query.queryFrom(this);
}
@Override
public String toString() {
return temporal +
(effectiveChrono != null ? " with chronology " + effectiveChrono : "") +
(effectiveZone != null ? " with zone " + effectiveZone : "");
}
};
}
@ -279,7 +286,8 @@ final class DateTimePrintContext {
<R> R getValue(TemporalQuery<R> query) {
R result = temporal.query(query);
if (result == null && optional == 0) {
throw new DateTimeException("Unable to extract value: " + temporal.getClass());
throw new DateTimeException("Unable to extract " +
query + " from temporal " + temporal);
}
return result;
}

View File

@ -341,58 +341,118 @@ public final class TemporalQueries {
/**
* A strict query for the {@code ZoneId}.
*/
static final TemporalQuery<ZoneId> ZONE_ID = (temporal) ->
temporal.query(TemporalQueries.ZONE_ID);
static final TemporalQuery<ZoneId> ZONE_ID = new TemporalQuery<>() {
@Override
public ZoneId queryFrom(TemporalAccessor temporal) {
return temporal.query(TemporalQueries.ZONE_ID);
}
@Override
public String toString() {
return "ZoneId";
}
};
/**
* A query for the {@code Chronology}.
*/
static final TemporalQuery<Chronology> CHRONO = (temporal) ->
temporal.query(TemporalQueries.CHRONO);
static final TemporalQuery<Chronology> CHRONO = new TemporalQuery<>() {
@Override
public Chronology queryFrom(TemporalAccessor temporal) {
return temporal.query(TemporalQueries.CHRONO);
}
@Override
public String toString() {
return "Chronology";
}
};
/**
* A query for the smallest supported unit.
*/
static final TemporalQuery<TemporalUnit> PRECISION = (temporal) ->
temporal.query(TemporalQueries.PRECISION);
static final TemporalQuery<TemporalUnit> PRECISION = new TemporalQuery<>() {
@Override
public TemporalUnit queryFrom(TemporalAccessor temporal) {
return temporal.query(TemporalQueries.PRECISION);
}
@Override
public String toString() {
return "Precision";
}
};
//-----------------------------------------------------------------------
/**
* A query for {@code ZoneOffset} returning null if not found.
*/
static final TemporalQuery<ZoneOffset> OFFSET = (temporal) -> {
static final TemporalQuery<ZoneOffset> OFFSET = new TemporalQuery<>() {
@Override
public ZoneOffset queryFrom(TemporalAccessor temporal) {
if (temporal.isSupported(OFFSET_SECONDS)) {
return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
}
return null;
}
@Override
public String toString() {
return "ZoneOffset";
}
};
/**
* A lenient query for the {@code ZoneId}, falling back to the {@code ZoneOffset}.
*/
static final TemporalQuery<ZoneId> ZONE = (temporal) -> {
static final TemporalQuery<ZoneId> ZONE = new TemporalQuery<>() {
@Override
public ZoneId queryFrom(TemporalAccessor temporal) {
ZoneId zone = temporal.query(ZONE_ID);
return (zone != null ? zone : temporal.query(OFFSET));
}
@Override
public String toString() {
return "Zone";
}
};
/**
* A query for {@code LocalDate} returning null if not found.
*/
static final TemporalQuery<LocalDate> LOCAL_DATE = (temporal) -> {
static final TemporalQuery<LocalDate> LOCAL_DATE = new TemporalQuery<>() {
@Override
public LocalDate queryFrom(TemporalAccessor temporal) {
if (temporal.isSupported(EPOCH_DAY)) {
return LocalDate.ofEpochDay(temporal.getLong(EPOCH_DAY));
}
return null;
}
@Override
public String toString() {
return "LocalDate";
}
};
/**
* A query for {@code LocalTime} returning null if not found.
*/
static final TemporalQuery<LocalTime> LOCAL_TIME = (temporal) -> {
static final TemporalQuery<LocalTime> LOCAL_TIME = new TemporalQuery<>() {
@Override
public LocalTime queryFrom(TemporalAccessor temporal) {
if (temporal.isSupported(NANO_OF_DAY)) {
return LocalTime.ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
}
return null;
}
@Override
public String toString() {
return "LocalTime";
}
};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -1281,8 +1281,74 @@ public class ArrayList<E> extends AbstractList<E>
public Spliterator<E> spliterator() {
checkForComodification();
return new ArrayListSpliterator<>(ArrayList.this, offset,
offset + this.size, this.modCount);
return new Spliterator<>() {
private int index = offset; // current index, modified on advance/split
private int fence = -1; // -1 until used; then one past last index
private int expectedModCount; // initialized when fence set
private int getFence() { // initialize fence to size on first use
int hi; // (a specialized variant appears in method forEach)
if ((hi = fence) < 0) {
expectedModCount = modCount;
hi = fence = offset + size;
}
return hi;
}
public ArrayListSpliterator<E> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null : // divide range in half unless too small
new ArrayListSpliterator<>(ArrayList.this, lo, index = mid,
expectedModCount);
}
public boolean tryAdvance(Consumer<? super E> action) {
Objects.requireNonNull(action);
int hi = getFence(), i = index;
if (i < hi) {
index = i + 1;
@SuppressWarnings("unchecked") E e = (E)elementData[i];
action.accept(e);
if (ArrayList.this.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
return false;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
int i, hi, mc; // hoist accesses and checks from loop
ArrayList<E> lst = ArrayList.this;
Object[] a;
if ((a = lst.elementData) != null) {
if ((hi = fence) < 0) {
mc = modCount;
hi = offset + size;
}
else
mc = expectedModCount;
if ((i = index) >= 0 && (index = hi) <= a.length) {
for (; i < hi; ++i) {
@SuppressWarnings("unchecked") E e = (E) a[i];
action.accept(e);
}
if (lst.modCount == mc)
return;
}
}
throw new ConcurrentModificationException();
}
public long estimateSize() {
return (long) (getFence() - index);
}
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
};
}
}

View File

@ -718,7 +718,7 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
}
/**
* Returns a shallow copy of this enum map. (The values themselves
* Returns a shallow copy of this enum map. The values themselves
* are not cloned.
*
* @return a shallow copy of this enum map

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016, 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
@ -656,8 +656,9 @@ public final class Collectors {
*/
return new CollectorImpl<>(
() -> new double[3],
(a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t));
a[2] += mapper.applyAsDouble(t);},
(a, t) -> { double val = mapper.applyAsDouble(t);
sumWithCompensation(a, val);
a[2] += val;},
(a, b) -> { sumWithCompensation(a, b[0]);
a[2] += b[2];
return sumWithCompensation(a, b[1]); },
@ -768,7 +769,7 @@ public final class Collectors {
*/
return new CollectorImpl<>(
() -> new double[4],
(a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; a[3]+= mapper.applyAsDouble(t);},
(a, t) -> { double val = mapper.applyAsDouble(t); sumWithCompensation(a, val); a[2]++; a[3]+= val;},
(a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
CH_NOID);

View File

@ -98,7 +98,7 @@ abstract class PipelineHelper<P_OUT> {
* @implSpec
* The implementation behaves as if:
* <pre>{@code
* intoWrapped(wrapSink(sink), spliterator);
* copyInto(wrapSink(sink), spliterator);
* }</pre>
*
* @param sink the {@code Sink} to receive the results

View File

@ -40,6 +40,15 @@ import jdk.internal.HotSpotIntrinsicCandidate;
* Although the class and all methods are public, use of this class is
* limited because only trusted code can obtain instances of it.
*
* <em>Note:</em> It is the resposibility of the caller to make sure
* arguments are checked before methods of this class are
* called. While some rudimentary checks are performed on the input,
* the checks are best effort and when performance is an overriding
* priority, as when methods of this class are optimized by the
* runtime compiler, some or all checks (if any) may be elided. Hence,
* the caller must not rely on the checks and corresponding
* exceptions!
*
* @author John R. Rose
* @see #getUnsafe
*/
@ -358,6 +367,169 @@ public final class Unsafe {
@HotSpotIntrinsicCandidate
public native void putAddress(long address, long x);
/// helper methods for validating various types of objects/values
/**
* Create an exception reflecting that some of the input was invalid
*
* <em>Note:</em> It is the resposibility of the caller to make
* sure arguments are checked before the methods are called. While
* some rudimentary checks are performed on the input, the checks
* are best effort and when performance is an overriding priority,
* as when methods of this class are optimized by the runtime
* compiler, some or all checks (if any) may be elided. Hence, the
* caller must not rely on the checks and corresponding
* exceptions!
*
* @return an exception object
*/
private RuntimeException invalidInput() {
return new IllegalArgumentException();
}
/**
* Check if a value is 32-bit clean (32 MSB are all zero)
*
* @param value the 64-bit value to check
*
* @return true if the value is 32-bit clean
*/
private boolean is32BitClean(long value) {
return value >>> 32 == 0;
}
/**
* Check the validity of a size (the equivalent of a size_t)
*
* @throws RuntimeException if the size is invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void checkSize(long size) {
if (ADDRESS_SIZE == 4) {
// Note: this will also check for negative sizes
if (!is32BitClean(size)) {
throw invalidInput();
}
} else if (size < 0) {
throw invalidInput();
}
}
/**
* Check the validity of a native address (the equivalent of void*)
*
* @throws RuntimeException if the address is invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void checkNativeAddress(long address) {
if (ADDRESS_SIZE == 4) {
// Accept both zero and sign extended pointers. A valid
// pointer will, after the +1 below, either have produced
// the value 0x0 or 0x1. Masking off the low bit allows
// for testing against 0.
if ((((address >> 32) + 1) & ~1) != 0) {
throw invalidInput();
}
}
}
/**
* Check the validity of an offset, relative to a base object
*
* @param o the base object
* @param offset the offset to check
*
* @throws RuntimeException if the size is invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void checkOffset(Object o, long offset) {
if (ADDRESS_SIZE == 4) {
// Note: this will also check for negative offsets
if (!is32BitClean(offset)) {
throw invalidInput();
}
} else if (offset < 0) {
throw invalidInput();
}
}
/**
* Check the validity of a double-register pointer
*
* Note: This code deliberately does *not* check for NPE for (at
* least) three reasons:
*
* 1) NPE is not just NULL/0 - there is a range of values all
* resulting in an NPE, which is not trivial to check for
*
* 2) It is the responsibility of the callers of Unsafe methods
* to verify the input, so throwing an exception here is not really
* useful - passing in a NULL pointer is a critical error and the
* must not expect an exception to be thrown anyway.
*
* 3) the actual operations will detect NULL pointers anyway by
* means of traps and signals (like SIGSEGV).
*
* @param o Java heap object, or null
* @param offset indication of where the variable resides in a Java heap
* object, if any, else a memory address locating the variable
* statically
*
* @throws RuntimeException if the pointer is invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void checkPointer(Object o, long offset) {
if (o == null) {
checkNativeAddress(offset);
} else {
checkOffset(o, offset);
}
}
/**
* Check if a type is a primitive array type
*
* @param c the type to check
*
* @return true if the type is a primitive array type
*/
private void checkPrimitiveArray(Class<?> c) {
Class<?> componentType = c.getComponentType();
if (componentType == null || !componentType.isPrimitive()) {
throw invalidInput();
}
}
/**
* Check that a pointer is a valid primitive array type pointer
*
* Note: pointers off-heap are considered to be primitive arrays
*
* @throws RuntimeException if the pointer is invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void checkPrimitivePointer(Object o, long offset) {
checkPointer(o, offset);
if (o != null) {
// If on heap, it it must be a primitive array
checkPrimitiveArray(o.getClass());
}
}
/// wrappers for malloc, realloc, free:
/**
@ -367,7 +539,16 @@ public final class Unsafe {
* aligned for all value types. Dispose of this memory by calling {@link
* #freeMemory}, or resize it with {@link #reallocateMemory}.
*
* @throws IllegalArgumentException if the size is negative or too large
* <em>Note:</em> It is the resposibility of the caller to make
* sure arguments are checked before the methods are called. While
* some rudimentary checks are performed on the input, the checks
* are best effort and when performance is an overriding priority,
* as when methods of this class are optimized by the runtime
* compiler, some or all checks (if any) may be elided. Hence, the
* caller must not rely on the checks and corresponding
* exceptions!
*
* @throws RuntimeException if the size is negative or too large
* for the native size_t type
*
* @throws OutOfMemoryError if the allocation is refused by the system
@ -375,7 +556,32 @@ public final class Unsafe {
* @see #getByte(long)
* @see #putByte(long, byte)
*/
public native long allocateMemory(long bytes);
public long allocateMemory(long bytes) {
allocateMemoryChecks(bytes);
if (bytes == 0) {
return 0;
}
long p = allocateMemory0(bytes);
if (p == 0) {
throw new OutOfMemoryError();
}
return p;
}
/**
* Validate the arguments to allocateMemory
*
* @throws RuntimeException if the arguments are invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void allocateMemoryChecks(long bytes) {
checkSize(bytes);
}
/**
* Resizes a new block of native memory, to the given size in bytes. The
@ -387,14 +593,50 @@ public final class Unsafe {
* #reallocateMemory}. The address passed to this method may be null, in
* which case an allocation will be performed.
*
* @throws IllegalArgumentException if the size is negative or too large
* <em>Note:</em> It is the resposibility of the caller to make
* sure arguments are checked before the methods are called. While
* some rudimentary checks are performed on the input, the checks
* are best effort and when performance is an overriding priority,
* as when methods of this class are optimized by the runtime
* compiler, some or all checks (if any) may be elided. Hence, the
* caller must not rely on the checks and corresponding
* exceptions!
*
* @throws RuntimeException if the size is negative or too large
* for the native size_t type
*
* @throws OutOfMemoryError if the allocation is refused by the system
*
* @see #allocateMemory
*/
public native long reallocateMemory(long address, long bytes);
public long reallocateMemory(long address, long bytes) {
reallocateMemoryChecks(address, bytes);
if (bytes == 0) {
freeMemory(address);
return 0;
}
long p = (address == 0) ? allocateMemory0(bytes) : reallocateMemory0(address, bytes);
if (p == 0) {
throw new OutOfMemoryError();
}
return p;
}
/**
* Validate the arguments to reallocateMemory
*
* @throws RuntimeException if the arguments are invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void reallocateMemoryChecks(long address, long bytes) {
checkPointer(null, address);
checkSize(bytes);
}
/**
* Sets all bytes in a given block of memory to a fixed value
@ -411,9 +653,28 @@ public final class Unsafe {
* If the effective address and length are (resp.) even modulo 4 or 2,
* the stores take place in units of 'int' or 'short'.
*
* <em>Note:</em> It is the resposibility of the caller to make
* sure arguments are checked before the methods are called. While
* some rudimentary checks are performed on the input, the checks
* are best effort and when performance is an overriding priority,
* as when methods of this class are optimized by the runtime
* compiler, some or all checks (if any) may be elided. Hence, the
* caller must not rely on the checks and corresponding
* exceptions!
*
* @throws RuntimeException if any of the arguments is invalid
*
* @since 1.7
*/
public native void setMemory(Object o, long offset, long bytes, byte value);
public void setMemory(Object o, long offset, long bytes, byte value) {
setMemoryChecks(o, offset, bytes, value);
if (bytes == 0) {
return;
}
setMemory0(o, offset, bytes, value);
}
/**
* Sets all bytes in a given block of memory to a fixed value
@ -426,6 +687,19 @@ public final class Unsafe {
setMemory(null, address, bytes, value);
}
/**
* Validate the arguments to setMemory
*
* @throws RuntimeException if the arguments are invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void setMemoryChecks(Object o, long offset, long bytes, byte value) {
checkPrimitivePointer(o, offset);
checkSize(bytes);
}
/**
* Sets all bytes in a given block of memory to a copy of another
* block.
@ -441,12 +715,31 @@ public final class Unsafe {
* If the effective addresses and length are (resp.) even modulo 4 or 2,
* the transfer takes place in units of 'int' or 'short'.
*
* <em>Note:</em> It is the resposibility of the caller to make
* sure arguments are checked before the methods are called. While
* some rudimentary checks are performed on the input, the checks
* are best effort and when performance is an overriding priority,
* as when methods of this class are optimized by the runtime
* compiler, some or all checks (if any) may be elided. Hence, the
* caller must not rely on the checks and corresponding
* exceptions!
*
* @throws RuntimeException if any of the arguments is invalid
*
* @since 1.7
*/
@HotSpotIntrinsicCandidate
public native void copyMemory(Object srcBase, long srcOffset,
public void copyMemory(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long bytes);
long bytes) {
copyMemoryChecks(srcBase, srcOffset, destBase, destOffset, bytes);
if (bytes == 0) {
return;
}
copyMemory0(srcBase, srcOffset, destBase, destOffset, bytes);
}
/**
* Sets all bytes in a given block of memory to a copy of another
* block. This provides a <em>single-register</em> addressing mode,
@ -458,14 +751,21 @@ public final class Unsafe {
copyMemory(null, srcAddress, null, destAddress, bytes);
}
private boolean isPrimitiveArray(Class<?> c) {
Class<?> componentType = c.getComponentType();
return componentType != null && componentType.isPrimitive();
}
private native void copySwapMemory0(Object srcBase, long srcOffset,
/**
* Validate the arguments to copyMemory
*
* @throws RuntimeException if any of the arguments is invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void copyMemoryChecks(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long bytes, long elemSize);
long bytes) {
checkSize(bytes);
checkPrimitivePointer(srcBase, srcOffset);
checkPrimitivePointer(destBase, destOffset);
}
/**
* Copies all elements from one block of memory to another block,
@ -476,39 +776,23 @@ public final class Unsafe {
* as discussed in {@link #getInt(Object,long)}. When the object reference is null,
* the offset supplies an absolute base address.
*
* <em>Note:</em> It is the resposibility of the caller to make
* sure arguments are checked before the methods are called. While
* some rudimentary checks are performed on the input, the checks
* are best effort and when performance is an overriding priority,
* as when methods of this class are optimized by the runtime
* compiler, some or all checks (if any) may be elided. Hence, the
* caller must not rely on the checks and corresponding
* exceptions!
*
* @throws RuntimeException if any of the arguments is invalid
*
* @since 9
*/
public void copySwapMemory(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long bytes, long elemSize) {
if (bytes < 0) {
throw new IllegalArgumentException();
}
if (elemSize != 2 && elemSize != 4 && elemSize != 8) {
throw new IllegalArgumentException();
}
if (bytes % elemSize != 0) {
throw new IllegalArgumentException();
}
if ((srcBase == null && srcOffset == 0) ||
(destBase == null && destOffset == 0)) {
throw new NullPointerException();
}
// Must be off-heap, or primitive heap arrays
if (srcBase != null && (srcOffset < 0 || !isPrimitiveArray(srcBase.getClass()))) {
throw new IllegalArgumentException();
}
if (destBase != null && (destOffset < 0 || !isPrimitiveArray(destBase.getClass()))) {
throw new IllegalArgumentException();
}
// Sanity check size and offsets on 32-bit platforms. Most
// significant 32 bits must be zero.
if (ADDRESS_SIZE == 4 &&
(bytes >>> 32 != 0 || srcOffset >>> 32 != 0 || destOffset >>> 32 != 0)) {
throw new IllegalArgumentException();
}
copySwapMemoryChecks(srcBase, srcOffset, destBase, destOffset, bytes, elemSize);
if (bytes == 0) {
return;
@ -517,6 +801,22 @@ public final class Unsafe {
copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize);
}
private void copySwapMemoryChecks(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long bytes, long elemSize) {
checkSize(bytes);
if (elemSize != 2 && elemSize != 4 && elemSize != 8) {
throw invalidInput();
}
if (bytes % elemSize != 0) {
throw invalidInput();
}
checkPrimitivePointer(srcBase, srcOffset);
checkPrimitivePointer(destBase, destOffset);
}
/**
* Copies all elements from one block of memory to another block, byte swapping the
* elements on the fly.
@ -535,9 +835,40 @@ public final class Unsafe {
* #allocateMemory} or {@link #reallocateMemory}. The address passed to
* this method may be null, in which case no action is taken.
*
* <em>Note:</em> It is the resposibility of the caller to make
* sure arguments are checked before the methods are called. While
* some rudimentary checks are performed on the input, the checks
* are best effort and when performance is an overriding priority,
* as when methods of this class are optimized by the runtime
* compiler, some or all checks (if any) may be elided. Hence, the
* caller must not rely on the checks and corresponding
* exceptions!
*
* @throws RuntimeException if any of the arguments is invalid
*
* @see #allocateMemory
*/
public native void freeMemory(long address);
public void freeMemory(long address) {
freeMemoryChecks(address);
if (address == 0) {
return;
}
freeMemory0(address);
}
/**
* Validate the arguments to freeMemory
*
* @throws RuntimeException if the arguments are invalid
* (<em>Note:</em> after optimization, invalid inputs may
* go undetected, which will lead to unpredictable
* behavior)
*/
private void freeMemoryChecks(long address) {
checkPointer(null, address);
}
/// random queries
@ -566,7 +897,13 @@ public final class Unsafe {
* must preserve all bits of static field offsets.
* @see #getInt(Object, long)
*/
public native long objectFieldOffset(Field f);
public long objectFieldOffset(Field f) {
if (f == null) {
throw new NullPointerException();
}
return objectFieldOffset0(f);
}
/**
* Reports the location of a given static field, in conjunction with {@link
@ -585,7 +922,13 @@ public final class Unsafe {
* this method reports its result as a long value.
* @see #getInt(Object, long)
*/
public native long staticFieldOffset(Field f);
public long staticFieldOffset(Field f) {
if (f == null) {
throw new NullPointerException();
}
return staticFieldOffset0(f);
}
/**
* Reports the location of a given static field, in conjunction with {@link
@ -597,7 +940,13 @@ public final class Unsafe {
* not be used in any way except as argument to the get and put routines in
* this class.
*/
public native Object staticFieldBase(Field f);
public Object staticFieldBase(Field f) {
if (f == null) {
throw new NullPointerException();
}
return staticFieldBase0(f);
}
/**
* Detects if the given class may need to be initialized. This is often
@ -605,14 +954,26 @@ public final class Unsafe {
* class.
* @return false only if a call to {@code ensureClassInitialized} would have no effect
*/
public native boolean shouldBeInitialized(Class<?> c);
public boolean shouldBeInitialized(Class<?> c) {
if (c == null) {
throw new NullPointerException();
}
return shouldBeInitialized0(c);
}
/**
* Ensures the given class has been initialized. This is often
* needed in conjunction with obtaining the static field base of a
* class.
*/
public native void ensureClassInitialized(Class<?> c);
public void ensureClassInitialized(Class<?> c) {
if (c == null) {
throw new NullPointerException();
}
ensureClassInitialized0(c);
}
/**
* Reports the offset of the first element in the storage allocation of a
@ -624,7 +985,14 @@ public final class Unsafe {
* @see #getInt(Object, long)
* @see #putInt(Object, long, int)
*/
public native int arrayBaseOffset(Class<?> arrayClass);
public int arrayBaseOffset(Class<?> arrayClass) {
if (arrayClass == null) {
throw new NullPointerException();
}
return arrayBaseOffset0(arrayClass);
}
/** The value of {@code arrayBaseOffset(boolean[].class)} */
public static final int ARRAY_BOOLEAN_BASE_OFFSET
@ -673,7 +1041,14 @@ public final class Unsafe {
* @see #getInt(Object, long)
* @see #putInt(Object, long, int)
*/
public native int arrayIndexScale(Class<?> arrayClass);
public int arrayIndexScale(Class<?> arrayClass) {
if (arrayClass == null) {
throw new NullPointerException();
}
return arrayIndexScale0(arrayClass);
}
/** The value of {@code arrayIndexScale(boolean[].class)} */
public static final int ARRAY_BOOLEAN_INDEX_SCALE
@ -717,10 +1092,12 @@ public final class Unsafe {
* other primitive types (as stored in native memory blocks) is determined
* fully by their information content.
*/
public native int addressSize();
public int addressSize() {
return ADDRESS_SIZE;
}
/** The value of {@code addressSize()} */
public static final int ADDRESS_SIZE = theUnsafe.addressSize();
public static final int ADDRESS_SIZE = theUnsafe.addressSize0();
/**
* Reports the size in bytes of a native memory page (whatever that is).
@ -735,7 +1112,20 @@ public final class Unsafe {
* Tells the VM to define a class, without security checks. By default, the
* class loader and protection domain come from the caller's class.
*/
public native Class<?> defineClass(String name, byte[] b, int off, int len,
public Class<?> defineClass(String name, byte[] b, int off, int len,
ClassLoader loader,
ProtectionDomain protectionDomain) {
if (b == null) {
throw new NullPointerException();
}
if (len < 0) {
throw new ArrayIndexOutOfBoundsException();
}
return defineClass0(name, b, off, len, loader, protectionDomain);
}
public native Class<?> defineClass0(String name, byte[] b, int off, int len,
ClassLoader loader,
ProtectionDomain protectionDomain);
@ -755,7 +1145,13 @@ public final class Unsafe {
* @param data bytes of a class file
* @param cpPatches where non-null entries exist, they replace corresponding CP entries in data
*/
public native Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches);
public Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches) {
if (hostClass == null || data == null) {
throw new NullPointerException();
}
return defineAnonymousClass0(hostClass, data, cpPatches);
}
/**
* Allocates an instance but does not run any constructor.
@ -765,6 +1161,59 @@ public final class Unsafe {
public native Object allocateInstance(Class<?> cls)
throws InstantiationException;
/**
* Allocates an array of a given type, but does not do zeroing.
* <p>
* This method should only be used in the very rare cases where a high-performance code
* overwrites the destination array completely, and compilers cannot assist in zeroing elimination.
* In an overwhelming majority of cases, a normal Java allocation should be used instead.
* <p>
* Users of this method are <b>required</b> to overwrite the initial (garbage) array contents
* before allowing untrusted code, or code in other threads, to observe the reference
* to the newly allocated array. In addition, the publication of the array reference must be
* safe according to the Java Memory Model requirements.
* <p>
* The safest approach to deal with an uninitialized array is to keep the reference to it in local
* variable at least until the initialization is complete, and then publish it <b>once</b>, either
* by writing it to a <em>volatile</em> field, or storing it into a <em>final</em> field in constructor,
* or issuing a {@link #storeFence} before publishing the reference.
* <p>
* @implnote This method can only allocate primitive arrays, to avoid garbage reference
* elements that could break heap integrity.
*
* @param componentType array component type to allocate
* @param length array size to allocate
* @throws IllegalArgumentException if component type is null, or not a primitive class;
* or the length is negative
*/
public Object allocateUninitializedArray(Class<?> componentType, int length) {
if (componentType == null) {
throw new IllegalArgumentException("Component type is null");
}
if (!componentType.isPrimitive()) {
throw new IllegalArgumentException("Component type is not primitive");
}
if (length < 0) {
throw new IllegalArgumentException("Negative length");
}
return allocateUninitializedArray0(componentType, length);
}
@HotSpotIntrinsicCandidate
private Object allocateUninitializedArray0(Class<?> componentType, int length) {
// These fallbacks provide zeroed arrays, but intrinsic is not required to
// return the zeroed arrays.
if (componentType == byte.class) return new byte[length];
if (componentType == boolean.class) return new boolean[length];
if (componentType == short.class) return new short[length];
if (componentType == char.class) return new char[length];
if (componentType == int.class) return new int[length];
if (componentType == float.class) return new float[length];
if (componentType == long.class) return new long[length];
if (componentType == double.class) return new double[length];
return null;
}
/** Throws the exception without telling the verifier. */
public native void throwException(Throwable ee);
@ -1290,7 +1739,13 @@ public final class Unsafe {
* @return the number of samples actually retrieved; or -1
* if the load average is unobtainable.
*/
public native int getLoadAverage(double[] loadavg, int nelems);
public int getLoadAverage(double[] loadavg, int nelems) {
if (nelems < 0 || nelems > 3 || nelems > loadavg.length) {
throw new ArrayIndexOutOfBoundsException();
}
return getLoadAverage0(loadavg, nelems);
}
// The following contain CAS-based Java implementations used on
// platforms not supporting native instructions
@ -1718,9 +2173,6 @@ public final class Unsafe {
}
// JVM interface methods
private native boolean unalignedAccess0();
private native boolean isBigEndian0();
// BE is true iff the native endianness of this platform is big.
private static final boolean BE = theUnsafe.isBigEndian0();
@ -1820,4 +2272,26 @@ public final class Unsafe {
private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n) ; }
private static int convEndian(boolean big, int n) { return big == BE ? n : Integer.reverseBytes(n) ; }
private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; }
private native long allocateMemory0(long bytes);
private native long reallocateMemory0(long address, long bytes);
private native void freeMemory0(long address);
private native void setMemory0(Object o, long offset, long bytes, byte value);
@HotSpotIntrinsicCandidate
private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
private native long objectFieldOffset0(Field f);
private native long staticFieldOffset0(Field f);
private native Object staticFieldBase0(Field f);
private native boolean shouldBeInitialized0(Class<?> c);
private native void ensureClassInitialized0(Class<?> c);
private native int arrayBaseOffset0(Class<?> arrayClass);
private native int arrayIndexScale0(Class<?> arrayClass);
private native int addressSize0();
private native Class<?> defineAnonymousClass0(Class<?> hostClass, byte[] data, Object[] cpPatches);
private native int getLoadAverage0(double[] loadavg, int nelems);
private native boolean unalignedAccess0();
private native boolean isBigEndian0();
}

View File

@ -195,7 +195,7 @@ public class ClassReader {
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
if (readShort(off + 6) > Opcodes.V1_8) {
if (readShort(off + 6) > Opcodes.V1_9) {
throw new IllegalArgumentException();
}
// parses the constant pool
@ -1199,7 +1199,14 @@ public class ClassReader {
if (labels[label] == null) {
readLabel(label, labels).status |= Label.DEBUG;
}
labels[label].line = readUnsignedShort(v + 12);
Label l = labels[label];
while (l.line > 0) {
if (l.next == null) {
l.next = new Label();
}
l = l.next;
}
l.line = readUnsignedShort(v + 12);
v += 4;
}
}
@ -1314,9 +1321,15 @@ public class ClassReader {
// visits the label and line number for this offset, if any
Label l = labels[offset];
if (l != null) {
Label next = l.next;
l.next = null;
mv.visitLabel(l);
if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
mv.visitLineNumber(l.line, l);
while (next != null) {
mv.visitLineNumber(next.line, l);
next = next.next;
}
}
}
@ -1857,8 +1870,7 @@ public class ClassReader {
v += 2;
break;
case 'B': // pointer to CONSTANT_Byte
av.visit(name,
(byte) readInt(items[readUnsignedShort(v)]));
av.visit(name, (byte) readInt(items[readUnsignedShort(v)]));
v += 2;
break;
case 'Z': // pointer to CONSTANT_Boolean
@ -1868,13 +1880,11 @@ public class ClassReader {
v += 2;
break;
case 'S': // pointer to CONSTANT_Short
av.visit(name,
(short) readInt(items[readUnsignedShort(v)]));
av.visit(name, (short) readInt(items[readUnsignedShort(v)]));
v += 2;
break;
case 'C': // pointer to CONSTANT_Char
av.visit(name,
(char) readInt(items[readUnsignedShort(v)]));
av.visit(name, (char) readInt(items[readUnsignedShort(v)]));
v += 2;
break;
case 's': // pointer to CONSTANT_Utf8
@ -2515,11 +2525,12 @@ public class ClassReader {
int tag = readByte(index);
int[] items = this.items;
int cpIndex = items[readUnsignedShort(index + 1)];
boolean itf = b[cpIndex - 1] == ClassWriter.IMETH;
String owner = readClass(cpIndex, buf);
cpIndex = items[readUnsignedShort(cpIndex + 2)];
String name = readUTF8(cpIndex, buf);
String desc = readUTF8(cpIndex + 2, buf);
return new Handle(tag, owner, name, desc);
return new Handle(tag, owner, name, desc, itf);
}
}
}

View File

@ -1081,7 +1081,7 @@ public class ClassWriter extends ClassVisitor {
}
} else if (cst instanceof Handle) {
Handle h = (Handle) cst;
return newHandleItem(h.tag, h.owner, h.name, h.desc);
return newHandleItem(h.tag, h.owner, h.name, h.desc, h.itf);
} else {
throw new IllegalArgumentException("value " + cst);
}
@ -1216,10 +1216,12 @@ public class ClassWriter extends ClassVisitor {
* the name of the field or method.
* @param desc
* the descriptor of the field or method.
* @param itf
* true if the owner is an interface.
* @return a new or an already existing method type reference item.
*/
Item newHandleItem(final int tag, final String owner, final String name,
final String desc) {
final String desc, final boolean itf) {
key4.set(HANDLE_BASE + tag, owner, name, desc);
Item result = get(key4);
if (result == null) {
@ -1228,8 +1230,7 @@ public class ClassWriter extends ClassVisitor {
} else {
put112(HANDLE,
tag,
newMethod(owner, name, desc,
tag == Opcodes.H_INVOKEINTERFACE));
newMethod(owner, name, desc, itf));
}
result = new Item(index++, key4);
put(result);
@ -1259,10 +1260,44 @@ public class ClassWriter extends ClassVisitor {
* the descriptor of the field or method.
* @return the index of a new or already existing method type reference
* item.
*
* @deprecated this method is superseded by
* {@link #newHandle(int, String, String, String, boolean)}.
*/
@Deprecated
public int newHandle(final int tag, final String owner, final String name,
final String desc) {
return newHandleItem(tag, owner, name, desc).index;
return newHandle(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
}
/**
* Adds a handle to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item. <i>This method is
* intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.</i>
*
* @param tag
* the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
* {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
* {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
* {@link Opcodes#H_INVOKESTATIC},
* {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}.
* @param owner
* the internal name of the field or method owner class.
* @param name
* the name of the field or method.
* @param desc
* the descriptor of the field or method.
* @param itf
* true if the owner is an interface.
* @return the index of a new or already existing method type reference
* item.
*/
public int newHandle(final int tag, final String owner, final String name,
final String desc, final boolean itf) {
return newHandleItem(tag, owner, name, desc, itf).index;
}
/**
@ -1294,7 +1329,7 @@ public class ClassWriter extends ClassVisitor {
int hashCode = bsm.hashCode();
bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
bsm.desc));
bsm.desc, bsm.isInterface()));
int argsLength = bsmArgs.length;
bootstrapMethods.putShort(argsLength);

View File

@ -192,7 +192,7 @@ final class Frame {
private static final int LOCAL = 0x2000000;
/**
* Kind of the types that are relative to the stack of an input stack
* Kind of the the types that are relative to the stack of an input stack
* map frame. The value of such types is a position relatively to the top of
* this stack.
*/

View File

@ -93,6 +93,12 @@ public final class Handle {
*/
final String desc;
/**
* Indicate if the owner is an interface or not.
*/
final boolean itf;
/**
* Constructs a new field or method handle.
*
@ -113,12 +119,44 @@ public final class Handle {
* @param desc
* the descriptor of the field or method designated by this
* handle.
*
* @deprecated this constructor has been superseded
* by {@link #Handle(int, String, String, String, boolean)}.
*/
@Deprecated
public Handle(int tag, String owner, String name, String desc) {
this(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
}
/**
* Constructs a new field or method handle.
*
* @param tag
* the kind of field or method designated by this Handle. Must be
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_INVOKEVIRTUAL},
* {@link Opcodes#H_INVOKESTATIC},
* {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}.
* @param owner
* the internal name of the class that owns the field or method
* designated by this handle.
* @param name
* the name of the field or method designated by this handle.
* @param desc
* the descriptor of the field or method designated by this
* handle.
* @param itf
* true if the owner is an interface.
*/
public Handle(int tag, String owner, String name, String desc, boolean itf) {
this.tag = tag;
this.owner = owner;
this.name = name;
this.desc = desc;
this.itf = itf;
}
/**
@ -164,6 +202,17 @@ public final class Handle {
return desc;
}
/**
* Returns true if the owner of the field or method designated
* by this handle is an interface.
*
* @return true if the owner of the field or method designated
* by this handle is an interface.
*/
public boolean isInterface() {
return itf;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
@ -173,13 +222,13 @@ public final class Handle {
return false;
}
Handle h = (Handle) obj;
return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
&& desc.equals(h.desc);
return tag == h.tag && itf == h.itf && owner.equals(h.owner)
&& name.equals(h.name) && desc.equals(h.desc);
}
@Override
public int hashCode() {
return tag + owner.hashCode() * name.hashCode() * desc.hashCode();
return tag + (itf? 64: 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
}
/**
@ -187,13 +236,16 @@ public final class Handle {
* representation is:
*
* <pre>
* for a reference to a class:
* owner '.' name desc ' ' '(' tag ')'
* for a reference to an interface:
* owner '.' name desc ' ' '(' tag ' ' itf ')'
* </pre>
*
* . As this format is unambiguous, it can be parsed if necessary.
*/
@Override
public String toString() {
return owner + '.' + name + desc + " (" + tag + ')';
return owner + '.' + name + desc + " (" + tag + (itf? " itf": "") + ')';
}
}

View File

@ -160,7 +160,11 @@ public class Label {
int status;
/**
* The line number corresponding to this label, if known.
* The line number corresponding to this label, if known. If there are
* several lines, each line is stored in a separate label, all linked via
* their next field (these links are created in ClassReader and removed just
* before visitLabel is called, so that this does not impact the rest of the
* code).
*/
int line;
@ -268,7 +272,8 @@ public class Label {
* The next basic block in the basic block stack. This stack is used in the
* main loop of the fix point algorithm used in the second step of the
* control flow analysis algorithms. It is also used in
* {@link #visitSubroutine} to avoid using a recursive method.
* {@link #visitSubroutine} to avoid using a recursive method, and in
* ClassReader to temporarily store multiple source lines for a label.
*
* @see MethodWriter#visitMaxs
*/

View File

@ -62,15 +62,16 @@ package jdk.internal.org.objectweb.asm;
* A visitor to visit a Java method. The methods of this class must be called in
* the following order: ( <tt>visitParameter</tt> )* [
* <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* [
* <tt>visitCode</tt> ( <tt>visitFrame</tt> | <tt>visit<i>X</i>Insn</tt> |
* <tt>visitLabel</tt> | <tt>visitInsnAnnotation</tt> |
* <tt>visitTryCatchBlock</tt> | <tt>visitTryCatchBlockAnnotation</tt> |
* <tt>visitLocalVariable</tt> | <tt>visitLocalVariableAnnotation</tt> |
* <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
* addition, the <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must
* be called in the sequential order of the bytecode instructions of the visited
* code, <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
* <tt>visitParameterAnnotation</tt> <tt>visitTypeAnnotation</tt> |
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
* <tt>visit<i>X</i>Insn</tt> | <tt>visitLabel</tt> |
* <tt>visitInsnAnnotation</tt> | <tt>visitTryCatchBlock</tt> |
* <tt>visitTryCatchAnnotation</tt> | <tt>visitLocalVariable</tt> |
* <tt>visitLocalVariableAnnotation</tt> | <tt>visitLineNumber</tt> )*
* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the
* <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must be called in
* the sequential order of the bytecode instructions of the visited code,
* <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
* instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
* labels passed as arguments have been visited,
* <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i> the

View File

@ -2061,7 +2061,7 @@ class MethodWriter extends MethodVisitor {
}
int size = 8;
if (code.length > 0) {
if (code.length > 65536) {
if (code.length > 65535) {
throw new RuntimeException("Method code too large!");
}
cw.newUTF8("Code");
@ -2735,6 +2735,7 @@ class MethodWriter extends MethodVisitor {
l = l.successor;
}
// Update the offsets in the uninitialized types
if (cw.typeTable != null) {
for (i = 0; i < cw.typeTable.length; ++i) {
Item item = cw.typeTable[i];
if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
@ -2742,6 +2743,7 @@ class MethodWriter extends MethodVisitor {
item.intVal);
}
}
}
// The stack map frames are not serialized yet, so we don't need
// to update them. They will be serialized in visitMaxs.
} else if (frameCount > 0) {

View File

@ -87,6 +87,7 @@ public interface Opcodes {
int V1_6 = 0 << 16 | 50;
int V1_7 = 0 << 16 | 51;
int V1_8 = 0 << 16 | 52;
int V1_9 = 0 << 16 | 53;
// access flags

View File

@ -654,7 +654,7 @@ public class Type {
* @return the descriptor corresponding to this Java type.
*/
public String getDescriptor() {
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
getDescriptor(buf);
return buf.toString();
}
@ -672,7 +672,7 @@ public class Type {
*/
public static String getMethodDescriptor(final Type returnType,
final Type... argumentTypes) {
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
buf.append('(');
for (int i = 0; i < argumentTypes.length; ++i) {
argumentTypes[i].getDescriptor(buf);
@ -689,7 +689,7 @@ public class Type {
* @param buf
* the string buffer to which the descriptor must be appended.
*/
private void getDescriptor(final StringBuffer buf) {
private void getDescriptor(final StringBuilder buf) {
if (this.buf == null) {
// descriptor is in byte 3 of 'off' for primitive types (buf ==
// null)
@ -729,7 +729,7 @@ public class Type {
* @return the descriptor corresponding to the given class.
*/
public static String getDescriptor(final Class<?> c) {
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
getDescriptor(buf, c);
return buf.toString();
}
@ -743,7 +743,7 @@ public class Type {
*/
public static String getConstructorDescriptor(final Constructor<?> c) {
Class<?>[] parameters = c.getParameterTypes();
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
buf.append('(');
for (int i = 0; i < parameters.length; ++i) {
getDescriptor(buf, parameters[i]);
@ -760,7 +760,7 @@ public class Type {
*/
public static String getMethodDescriptor(final Method m) {
Class<?>[] parameters = m.getParameterTypes();
StringBuffer buf = new StringBuffer();
StringBuilder buf = new StringBuilder();
buf.append('(');
for (int i = 0; i < parameters.length; ++i) {
getDescriptor(buf, parameters[i]);
@ -778,7 +778,7 @@ public class Type {
* @param c
* the class whose descriptor must be computed.
*/
private static void getDescriptor(final StringBuffer buf, final Class<?> c) {
private static void getDescriptor(final StringBuilder buf, final Class<?> c) {
Class<?> d = c;
while (true) {
if (d.isPrimitive()) {

View File

@ -71,25 +71,25 @@ public class TypePath {
* A type path step that steps into the element type of an array type. See
* {@link #getStep getStep}.
*/
public static final int ARRAY_ELEMENT = 0;
public final static int ARRAY_ELEMENT = 0;
/**
* A type path step that steps into the nested type of a class type. See
* {@link #getStep getStep}.
*/
public static final int INNER_TYPE = 1;
public final static int INNER_TYPE = 1;
/**
* A type path step that steps into the bound of a wildcard type. See
* {@link #getStep getStep}.
*/
public static final int WILDCARD_BOUND = 2;
public final static int WILDCARD_BOUND = 2;
/**
* A type path step that steps into a type argument of a generic type. See
* {@link #getStep getStep}.
*/
public static final int TYPE_ARGUMENT = 3;
public final static int TYPE_ARGUMENT = 3;
/**
* The byte array where the path is stored, in Java class file format.

View File

@ -74,133 +74,133 @@ public class TypeReference {
* The sort of type references that target a type parameter of a generic
* class. See {@link #getSort getSort}.
*/
public static final int CLASS_TYPE_PARAMETER = 0x00;
public final static int CLASS_TYPE_PARAMETER = 0x00;
/**
* The sort of type references that target a type parameter of a generic
* method. See {@link #getSort getSort}.
*/
public static final int METHOD_TYPE_PARAMETER = 0x01;
public final static int METHOD_TYPE_PARAMETER = 0x01;
/**
* The sort of type references that target the super class of a class or one
* of the interfaces it implements. See {@link #getSort getSort}.
*/
public static final int CLASS_EXTENDS = 0x10;
public final static int CLASS_EXTENDS = 0x10;
/**
* The sort of type references that target a bound of a type parameter of a
* generic class. See {@link #getSort getSort}.
*/
public static final int CLASS_TYPE_PARAMETER_BOUND = 0x11;
public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
/**
* The sort of type references that target a bound of a type parameter of a
* generic method. See {@link #getSort getSort}.
*/
public static final int METHOD_TYPE_PARAMETER_BOUND = 0x12;
public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
/**
* The sort of type references that target the type of a field. See
* {@link #getSort getSort}.
*/
public static final int FIELD = 0x13;
public final static int FIELD = 0x13;
/**
* The sort of type references that target the return type of a method. See
* {@link #getSort getSort}.
*/
public static final int METHOD_RETURN = 0x14;
public final static int METHOD_RETURN = 0x14;
/**
* The sort of type references that target the receiver type of a method.
* See {@link #getSort getSort}.
*/
public static final int METHOD_RECEIVER = 0x15;
public final static int METHOD_RECEIVER = 0x15;
/**
* The sort of type references that target the type of a formal parameter of
* a method. See {@link #getSort getSort}.
*/
public static final int METHOD_FORMAL_PARAMETER = 0x16;
public final static int METHOD_FORMAL_PARAMETER = 0x16;
/**
* The sort of type references that target the type of an exception declared
* in the throws clause of a method. See {@link #getSort getSort}.
*/
public static final int THROWS = 0x17;
public final static int THROWS = 0x17;
/**
* The sort of type references that target the type of a local variable in a
* method. See {@link #getSort getSort}.
*/
public static final int LOCAL_VARIABLE = 0x40;
public final static int LOCAL_VARIABLE = 0x40;
/**
* The sort of type references that target the type of a resource variable
* in a method. See {@link #getSort getSort}.
*/
public static final int RESOURCE_VARIABLE = 0x41;
public final static int RESOURCE_VARIABLE = 0x41;
/**
* The sort of type references that target the type of the exception of a
* 'catch' clause in a method. See {@link #getSort getSort}.
*/
public static final int EXCEPTION_PARAMETER = 0x42;
public final static int EXCEPTION_PARAMETER = 0x42;
/**
* The sort of type references that target the type declared in an
* 'instanceof' instruction. See {@link #getSort getSort}.
*/
public static final int INSTANCEOF = 0x43;
public final static int INSTANCEOF = 0x43;
/**
* The sort of type references that target the type of the object created by
* a 'new' instruction. See {@link #getSort getSort}.
*/
public static final int NEW = 0x44;
public final static int NEW = 0x44;
/**
* The sort of type references that target the receiver type of a
* constructor reference. See {@link #getSort getSort}.
*/
public static final int CONSTRUCTOR_REFERENCE = 0x45;
public final static int CONSTRUCTOR_REFERENCE = 0x45;
/**
* The sort of type references that target the receiver type of a method
* reference. See {@link #getSort getSort}.
*/
public static final int METHOD_REFERENCE = 0x46;
public final static int METHOD_REFERENCE = 0x46;
/**
* The sort of type references that target the type declared in an explicit
* or implicit cast instruction. See {@link #getSort getSort}.
*/
public static final int CAST = 0x47;
public final static int CAST = 0x47;
/**
* The sort of type references that target a type parameter of a generic
* constructor in a constructor call. See {@link #getSort getSort}.
*/
public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
/**
* The sort of type references that target a type parameter of a generic
* method in a method call. See {@link #getSort getSort}.
*/
public static final int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
/**
* The sort of type references that target a type parameter of a generic
* constructor in a constructor reference. See {@link #getSort getSort}.
*/
public static final int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
/**
* The sort of type references that target a type parameter of a generic
* method in a method reference. See {@link #getSort getSort}.
*/
public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
/**
* The type reference value in Java class file format.

View File

@ -389,8 +389,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
break;
case PUTFIELD:
popValue();
if (longOrDouble) {
popValue();
if (longOrDouble) {
popValue();
}
break;
@ -619,7 +619,7 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
}
/**
* Called at the beginning of the method or after super class class call in
* Called at the beginning of the method or after super class call in
* the constructor. <br>
* <br>
*

View File

@ -0,0 +1,108 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package jdk.internal.org.objectweb.asm.commons;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* An {@link AnnotationVisitor} adapter for type remapping.
*
* @author Eugene Kuleshov
*/
public class AnnotationRemapper extends AnnotationVisitor {
protected final Remapper remapper;
public AnnotationRemapper(final AnnotationVisitor av,
final Remapper remapper) {
this(Opcodes.ASM5, av, remapper);
}
protected AnnotationRemapper(final int api, final AnnotationVisitor av,
final Remapper remapper) {
super(api, av);
this.remapper = remapper;
}
@Override
public void visit(String name, Object value) {
av.visit(name, remapper.mapValue(value));
}
@Override
public void visitEnum(String name, String desc, String value) {
av.visitEnum(name, remapper.mapDesc(desc), value);
}
@Override
public AnnotationVisitor visitAnnotation(String name, String desc) {
AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc));
return v == null ? null : (v == av ? this : new AnnotationRemapper(v,
remapper));
}
@Override
public AnnotationVisitor visitArray(String name) {
AnnotationVisitor v = av.visitArray(name);
return v == null ? null : (v == av ? this : new AnnotationRemapper(v,
remapper));
}
}

View File

@ -0,0 +1,161 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package jdk.internal.org.objectweb.asm.commons;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
/**
* A {@link ClassVisitor} for type remapping.
*
* @author Eugene Kuleshov
*/
public class ClassRemapper extends ClassVisitor {
protected final Remapper remapper;
protected String className;
public ClassRemapper(final ClassVisitor cv, final Remapper remapper) {
this(Opcodes.ASM5, cv, remapper);
}
protected ClassRemapper(final int api, final ClassVisitor cv,
final Remapper remapper) {
super(api, cv);
this.remapper = remapper;
}
@Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
this.className = name;
super.visit(version, access, remapper.mapType(name), remapper
.mapSignature(signature, false), remapper.mapType(superName),
interfaces == null ? null : remapper.mapTypes(interfaces));
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
visible);
return av == null ? null : createAnnotationRemapper(av);
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
remapper.mapDesc(desc), visible);
return av == null ? null : createAnnotationRemapper(av);
}
@Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
FieldVisitor fv = super.visitField(access,
remapper.mapFieldName(className, name, desc),
remapper.mapDesc(desc), remapper.mapSignature(signature, true),
remapper.mapValue(value));
return fv == null ? null : createFieldRemapper(fv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
String newDesc = remapper.mapMethodDesc(desc);
MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(
className, name, desc), newDesc, remapper.mapSignature(
signature, false),
exceptions == null ? null : remapper.mapTypes(exceptions));
return mv == null ? null : createMethodRemapper(mv);
}
@Override
public void visitInnerClass(String name, String outerName,
String innerName, int access) {
// TODO should innerName be changed?
super.visitInnerClass(remapper.mapType(name), outerName == null ? null
: remapper.mapType(outerName), innerName, access);
}
@Override
public void visitOuterClass(String owner, String name, String desc) {
super.visitOuterClass(remapper.mapType(owner), name == null ? null
: remapper.mapMethodName(owner, name, desc),
desc == null ? null : remapper.mapMethodDesc(desc));
}
protected FieldVisitor createFieldRemapper(FieldVisitor fv) {
return new FieldRemapper(fv, remapper);
}
protected MethodVisitor createMethodRemapper(MethodVisitor mv) {
return new MethodRemapper(mv, remapper);
}
protected AnnotationVisitor createAnnotationRemapper(AnnotationVisitor av) {
return new AnnotationRemapper(av, remapper);
}
}

View File

@ -0,0 +1,100 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package jdk.internal.org.objectweb.asm.commons;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.FieldVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
/**
* A {@link FieldVisitor} adapter for type remapping.
*
* @author Eugene Kuleshov
*/
public class FieldRemapper extends FieldVisitor {
private final Remapper remapper;
public FieldRemapper(final FieldVisitor fv, final Remapper remapper) {
this(Opcodes.ASM5, fv, remapper);
}
protected FieldRemapper(final int api, final FieldVisitor fv,
final Remapper remapper) {
super(api, fv);
this.remapper = remapper;
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc),
visible);
return av == null ? null : new AnnotationRemapper(av, remapper);
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
remapper.mapDesc(desc), visible);
return av == null ? null : new AnnotationRemapper(av, remapper);
}
}

View File

@ -73,7 +73,7 @@ import jdk.internal.org.objectweb.asm.Type;
*/
public class InstructionAdapter extends MethodVisitor {
public static final Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
public final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
/**
* Creates a new {@link InstructionAdapter}. <i>Subclasses must not use this

View File

@ -104,11 +104,6 @@ public class LocalVariablesSorter extends MethodVisitor {
*/
protected int nextLocal;
/**
* Indicates if at least one local variable has moved due to remapping.
*/
private boolean changed;
/**
* Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use
* this constructor</i>. Instead, they must use the
@ -228,11 +223,6 @@ public class LocalVariablesSorter extends MethodVisitor {
"ClassReader.accept() should be called with EXPAND_FRAMES flag");
}
if (!changed) { // optimization for the case where mapping = identity
mv.visitFrame(type, nLocal, local, nStack, stack);
return;
}
// creates a copy of newLocals
Object[] oldLocals = new Object[newLocals.length];
System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
@ -328,7 +318,6 @@ public class LocalVariablesSorter extends MethodVisitor {
int local = newLocalMapping(type);
setLocalType(local, type);
setFrameLocal(local, t);
changed = true;
return local;
}
@ -396,9 +385,6 @@ public class LocalVariablesSorter extends MethodVisitor {
} else {
value--;
}
if (value != var) {
changed = true;
}
return value;
}

View File

@ -0,0 +1,252 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package jdk.internal.org.objectweb.asm.commons;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.TypePath;
/**
* A {@link LocalVariablesSorter} for type mapping.
*
* @author Eugene Kuleshov
*/
public class MethodRemapper extends MethodVisitor {
protected final Remapper remapper;
public MethodRemapper(final MethodVisitor mv, final Remapper remapper) {
this(Opcodes.ASM5, mv, remapper);
}
protected MethodRemapper(final int api, final MethodVisitor mv,
final Remapper remapper) {
super(api, mv);
this.remapper = remapper;
}
@Override
public AnnotationVisitor visitAnnotationDefault() {
AnnotationVisitor av = super.visitAnnotationDefault();
return av == null ? av : new AnnotationRemapper(av, remapper);
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
visible);
return av == null ? av : new AnnotationRemapper(av, remapper);
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
remapper.mapDesc(desc), visible);
return av == null ? av : new AnnotationRemapper(av, remapper);
}
@Override
public AnnotationVisitor visitParameterAnnotation(int parameter,
String desc, boolean visible) {
AnnotationVisitor av = super.visitParameterAnnotation(parameter,
remapper.mapDesc(desc), visible);
return av == null ? av : new AnnotationRemapper(av, remapper);
}
@Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack,
Object[] stack) {
super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack,
remapEntries(nStack, stack));
}
private Object[] remapEntries(int n, Object[] entries) {
for (int i = 0; i < n; i++) {
if (entries[i] instanceof String) {
Object[] newEntries = new Object[n];
if (i > 0) {
System.arraycopy(entries, 0, newEntries, 0, i);
}
do {
Object t = entries[i];
newEntries[i++] = t instanceof String ? remapper
.mapType((String) t) : t;
} while (i < n);
return newEntries;
}
}
return entries;
}
@Override
public void visitFieldInsn(int opcode, String owner, String name,
String desc) {
super.visitFieldInsn(opcode, remapper.mapType(owner),
remapper.mapFieldName(owner, name, desc),
remapper.mapDesc(desc));
}
@Deprecated
@Override
public void visitMethodInsn(final int opcode, final String owner,
final String name, final String desc) {
if (api >= Opcodes.ASM5) {
super.visitMethodInsn(opcode, owner, name, desc);
return;
}
doVisitMethodInsn(opcode, owner, name, desc,
opcode == Opcodes.INVOKEINTERFACE);
}
@Override
public void visitMethodInsn(final int opcode, final String owner,
final String name, final String desc, final boolean itf) {
if (api < Opcodes.ASM5) {
super.visitMethodInsn(opcode, owner, name, desc, itf);
return;
}
doVisitMethodInsn(opcode, owner, name, desc, itf);
}
private void doVisitMethodInsn(int opcode, String owner, String name,
String desc, boolean itf) {
// Calling super.visitMethodInsn requires to call the correct version
// depending on this.api (otherwise infinite loops can occur). To
// simplify and to make it easier to automatically remove the backward
// compatibility code, we inline the code of the overridden method here.
// IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN
// LocalVariableSorter.
if (mv != null) {
mv.visitMethodInsn(opcode, remapper.mapType(owner),
remapper.mapMethodName(owner, name, desc),
remapper.mapMethodDesc(desc), itf);
}
}
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
for (int i = 0; i < bsmArgs.length; i++) {
bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
}
super.visitInvokeDynamicInsn(
remapper.mapInvokeDynamicMethodName(name, desc),
remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm),
bsmArgs);
}
@Override
public void visitTypeInsn(int opcode, String type) {
super.visitTypeInsn(opcode, remapper.mapType(type));
}
@Override
public void visitLdcInsn(Object cst) {
super.visitLdcInsn(remapper.mapValue(cst));
}
@Override
public void visitMultiANewArrayInsn(String desc, int dims) {
super.visitMultiANewArrayInsn(remapper.mapDesc(desc), dims);
}
@Override
public AnnotationVisitor visitInsnAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
AnnotationVisitor av = super.visitInsnAnnotation(typeRef, typePath,
remapper.mapDesc(desc), visible);
return av == null ? av : new AnnotationRemapper(av, remapper);
}
@Override
public void visitTryCatchBlock(Label start, Label end, Label handler,
String type) {
super.visitTryCatchBlock(start, end, handler, type == null ? null
: remapper.mapType(type));
}
@Override
public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
AnnotationVisitor av = super.visitTryCatchAnnotation(typeRef, typePath,
remapper.mapDesc(desc), visible);
return av == null ? av : new AnnotationRemapper(av, remapper);
}
@Override
public void visitLocalVariable(String name, String desc, String signature,
Label start, Label end, int index) {
super.visitLocalVariable(name, remapper.mapDesc(desc),
remapper.mapSignature(signature, true), start, end, index);
}
@Override
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
TypePath typePath, Label[] start, Label[] end, int[] index,
String desc, boolean visible) {
AnnotationVisitor av = super.visitLocalVariableAnnotation(typeRef,
typePath, start, end, index, remapper.mapDesc(desc), visible);
return av == null ? av : new AnnotationRemapper(av, remapper);
}
}

View File

@ -168,17 +168,19 @@ public abstract class Remapper {
Handle h = (Handle) value;
return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(
h.getOwner(), h.getName(), h.getDesc()),
mapMethodDesc(h.getDesc()));
mapMethodDesc(h.getDesc()), h.isInterface());
}
return value;
}
/**
*
* @param signature
* signature for mapper
* @param typeSignature
* true if signature is a FieldTypeSignature, such as the
* signature parameter of the ClassVisitor.visitField or
* MethodVisitor.visitLocalVariable methods
* @return signature rewritten as a string
*/
public String mapSignature(String signature, boolean typeSignature) {
if (signature == null) {
@ -186,7 +188,7 @@ public abstract class Remapper {
}
SignatureReader r = new SignatureReader(signature);
SignatureWriter w = new SignatureWriter();
SignatureVisitor a = createRemappingSignatureAdapter(w);
SignatureVisitor a = createSignatureRemapper(w);
if (typeSignature) {
r.acceptType(a);
} else {
@ -195,9 +197,18 @@ public abstract class Remapper {
return w.toString();
}
/**
* @deprecated use {@link #createSignatureRemapper} instead.
*/
@Deprecated
protected SignatureVisitor createRemappingSignatureAdapter(
SignatureVisitor v) {
return new RemappingSignatureAdapter(v, this);
return new SignatureRemapper(v, this);
}
protected SignatureVisitor createSignatureRemapper(
SignatureVisitor v) {
return createRemappingSignatureAdapter(v);
}
/**
@ -245,6 +256,10 @@ public abstract class Remapper {
/**
* Map type name to the new name. Subclasses can override.
*
* @param typeName
* the type name
* @return new name, default implementation is the identity.
*/
public String map(String typeName) {
return typeName;

View File

@ -65,8 +65,10 @@ import jdk.internal.org.objectweb.asm.Opcodes;
/**
* An {@link AnnotationVisitor} adapter for type remapping.
*
* //@deprecated use {@link AnnotationRemapper} instead.
* @author Eugene Kuleshov
*/
//@Deprecated
public class RemappingAnnotationAdapter extends AnnotationVisitor {
protected final Remapper remapper;

View File

@ -69,8 +69,10 @@ import jdk.internal.org.objectweb.asm.TypePath;
/**
* A {@link ClassVisitor} for type remapping.
*
* @deprecated use {@link ClassRemapper} instead.
* @author Eugene Kuleshov
*/
@Deprecated
public class RemappingClassAdapter extends ClassVisitor {
protected final Remapper remapper;

View File

@ -67,8 +67,10 @@ import jdk.internal.org.objectweb.asm.TypePath;
/**
* A {@link FieldVisitor} adapter for type remapping.
*
* @deprecated use {@link FieldRemapper} instead.
* @author Eugene Kuleshov
*/
@Deprecated
public class RemappingFieldAdapter extends FieldVisitor {
private final Remapper remapper;

View File

@ -69,8 +69,10 @@ import jdk.internal.org.objectweb.asm.TypePath;
/**
* A {@link LocalVariablesSorter} for type mapping.
*
* //@deprecated use {@link MethodRemapper} instead.
* @author Eugene Kuleshov
*/
//@Deprecated
public class RemappingMethodAdapter extends LocalVariablesSorter {
protected final Remapper remapper;

View File

@ -65,8 +65,10 @@ import jdk.internal.org.objectweb.asm.signature.SignatureVisitor;
/**
* A {@link SignatureVisitor} adapter for type mapping.
*
* @deprecated use {@link SignatureRemapper} instead.
* @author Eugene Kuleshov
*/
@Deprecated
public class RemappingSignatureAdapter extends SignatureVisitor {
private final SignatureVisitor v;

View File

@ -234,7 +234,7 @@ public class SerialVersionUIDAdder extends ClassVisitor {
public void visit(final int version, final int access, final String name,
final String signature, final String superName,
final String[] interfaces) {
computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;
computeSVUID = (access & Opcodes.ACC_ENUM) == 0;
if (computeSVUID) {
this.name = name;
@ -396,6 +396,11 @@ public class SerialVersionUIDAdder extends ClassVisitor {
/*
* 2. The class modifiers written as a 32-bit integer.
*/
int access = this.access;
if ((access & Opcodes.ACC_INTERFACE) != 0) {
access = (svuidMethods.size() > 0) ? (access | Opcodes.ACC_ABSTRACT)
: (access & ~Opcodes.ACC_ABSTRACT);
}
dos.writeInt(access
& (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL
| Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT));

View File

@ -0,0 +1,188 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package jdk.internal.org.objectweb.asm.commons;
import java.util.Stack;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.signature.SignatureVisitor;
/**
* A {@link SignatureVisitor} adapter for type mapping.
*
* @author Eugene Kuleshov
*/
public class SignatureRemapper extends SignatureVisitor {
private final SignatureVisitor v;
private final Remapper remapper;
private Stack<String> classNames = new Stack<String>();
public SignatureRemapper(final SignatureVisitor v, final Remapper remapper) {
this(Opcodes.ASM5, v, remapper);
}
protected SignatureRemapper(final int api, final SignatureVisitor v,
final Remapper remapper) {
super(api);
this.v = v;
this.remapper = remapper;
}
@Override
public void visitClassType(String name) {
classNames.push(name);
v.visitClassType(remapper.mapType(name));
}
@Override
public void visitInnerClassType(String name) {
String outerClassName = classNames.pop();
String className = outerClassName + '$' + name;
classNames.push(className);
String remappedOuter = remapper.mapType(outerClassName) + '$';
String remappedName = remapper.mapType(className);
int index = remappedName.startsWith(remappedOuter) ? remappedOuter
.length() : remappedName.lastIndexOf('$') + 1;
v.visitInnerClassType(remappedName.substring(index));
}
@Override
public void visitFormalTypeParameter(String name) {
v.visitFormalTypeParameter(name);
}
@Override
public void visitTypeVariable(String name) {
v.visitTypeVariable(name);
}
@Override
public SignatureVisitor visitArrayType() {
v.visitArrayType();
return this;
}
@Override
public void visitBaseType(char descriptor) {
v.visitBaseType(descriptor);
}
@Override
public SignatureVisitor visitClassBound() {
v.visitClassBound();
return this;
}
@Override
public SignatureVisitor visitExceptionType() {
v.visitExceptionType();
return this;
}
@Override
public SignatureVisitor visitInterface() {
v.visitInterface();
return this;
}
@Override
public SignatureVisitor visitInterfaceBound() {
v.visitInterfaceBound();
return this;
}
@Override
public SignatureVisitor visitParameterType() {
v.visitParameterType();
return this;
}
@Override
public SignatureVisitor visitReturnType() {
v.visitReturnType();
return this;
}
@Override
public SignatureVisitor visitSuperclass() {
v.visitSuperclass();
return this;
}
@Override
public void visitTypeArgument() {
v.visitTypeArgument();
}
@Override
public SignatureVisitor visitTypeArgument(char wildcard) {
v.visitTypeArgument(wildcard);
return this;
}
@Override
public void visitEnd() {
v.visitEnd();
classNames.pop();
}
}

View File

@ -85,6 +85,12 @@ public class SimpleRemapper extends Remapper {
return s == null ? name : s;
}
@Override
public String mapInvokeDynamicMethodName(String name, String desc) {
String s = map('.' + name + desc);
return s == null ? name : s;
}
@Override
public String mapFieldName(String owner, String name, String desc) {
String s = map(owner + '.' + name);

View File

@ -68,7 +68,7 @@ import jdk.internal.org.objectweb.asm.Opcodes;
* <ul>
* <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt>
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
* <tt>visitSuperClass</tt> <tt>visitInterface</tt>* )</li>
* <tt>visitSuperclass</tt> <tt>visitInterface</tt>* )</li>
* <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt>
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
* <tt>visitParameterType</tt>* <tt>visitReturnType</tt>
@ -88,17 +88,17 @@ public abstract class SignatureVisitor {
/**
* Wildcard for an "extends" type argument.
*/
public static final char EXTENDS = '+';
public final static char EXTENDS = '+';
/**
* Wildcard for a "super" type argument.
*/
public static final char SUPER = '-';
public final static char SUPER = '-';
/**
* Wildcard for a normal type argument.
*/
public static final char INSTANCEOF = '=';
public final static char INSTANCEOF = '=';
/**
* The ASM API version implemented by this visitor. The value of this field

View File

@ -69,9 +69,9 @@ import jdk.internal.org.objectweb.asm.Opcodes;
public class SignatureWriter extends SignatureVisitor {
/**
* Buffer used to construct the signature.
* Builder used to construct the signature.
*/
private final StringBuffer buf = new StringBuffer();
private final StringBuilder buf = new StringBuilder();
/**
* Indicates if the signature contains formal type parameters.

View File

@ -205,6 +205,9 @@ public class InsnList {
/**
* Returns an iterator over the instructions in this list.
*
* @param index
* index of instruction for the iterator to start at
*
* @return an iterator over the instructions in this list.
*/
@SuppressWarnings("unchecked")

View File

@ -856,7 +856,11 @@ public class ASMifier extends Printer {
buf.append("{\n").append("av0 = ").append(name)
.append(".visitLocalVariableAnnotation(");
buf.append(typeRef);
if (typePath == null) {
buf.append(", null, ");
} else {
buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
}
buf.append("new Label[] {");
for (int i = 0; i < start.length; ++i) {
buf.append(i == 0 ? " " : ", ");
@ -934,7 +938,11 @@ public class ASMifier extends Printer {
buf.append("{\n").append("av0 = ").append(name).append(".")
.append(method).append("(");
buf.append(typeRef);
if (typePath == null) {
buf.append(", null, ");
} else {
buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
}
appendConstant(desc);
buf.append(", ").append(visible).append(");\n");
text.add(buf.toString());

View File

@ -437,6 +437,9 @@ public class CheckMethodAdapter extends MethodVisitor {
* will not perform any data flow check (see
* {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
*
* @param api
* the ASM API version implemented by this CheckMethodAdapter.
* Must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
* @param mv
* the method visitor to which this adapter must delegate calls.
* @param labels

View File

@ -74,34 +74,36 @@ import jdk.internal.org.objectweb.asm.TypePath;
* visitor chain to trace the class that is visited at a given point in this
* chain. This may be useful for debugging purposes.
* <p>
* The trace printed when visiting the {@code Hello} class is the following:
* The trace printed when visiting the <tt>Hello</tt> class is the following:
* <p>
* <blockquote>
*
* <pre>{@code
* <pre>
* // class version 49.0 (49) // access flags 0x21 public class Hello {
*
* // compiled from: Hello.java
*
* // access flags 0x1 public <init> ()V ALOAD 0 INVOKESPECIAL
* java/lang/Object <init> ()V RETURN MAXSTACK = 1 MAXLOCALS = 1
* // access flags 0x1 public &lt;init&gt; ()V ALOAD 0 INVOKESPECIAL
* java/lang/Object &lt;init&gt; ()V RETURN MAXSTACK = 1 MAXLOCALS = 1
*
* // access flags 0x9 public static main ([Ljava/lang/String;)V GETSTATIC
* java/lang/System out Ljava/io/PrintStream; LDC "hello"
* java/lang/System out Ljava/io/PrintStream; LDC &quot;hello&quot;
* INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V RETURN
* MAXSTACK = 2 MAXLOCALS = 1 }
* }</pre>
* </pre>
*
* </blockquote> where {@code Hello} is defined by:
* </blockquote> where <tt>Hello</tt> is defined by:
* <p>
* <blockquote>
*
* <pre>{@code
* <pre>
* public class Hello {
*
* public static void main(String[] args) {
* System.out.println("hello");
* System.out.println(&quot;hello&quot;);
* }
* }
* }</pre>
* </pre>
*
* </blockquote>
*
@ -135,7 +137,7 @@ public final class TraceClassVisitor extends ClassVisitor {
*
* @param cv
* the {@link ClassVisitor} to which this visitor delegates
* calls. May be {@code null}.
* calls. May be <tt>null</tt>.
* @param pw
* the print writer to be used to print the class.
*/
@ -148,7 +150,7 @@ public final class TraceClassVisitor extends ClassVisitor {
*
* @param cv
* the {@link ClassVisitor} to which this visitor delegates
* calls. May be {@code null}.
* calls. May be <tt>null</tt>.
* @param p
* the object that actually converts visit events into text.
* @param pw

View File

@ -70,7 +70,7 @@ import jdk.internal.org.objectweb.asm.signature.SignatureVisitor;
*/
public final class TraceSignatureVisitor extends SignatureVisitor {
private final StringBuffer declaration;
private final StringBuilder declaration;
private boolean isInterface;
@ -82,9 +82,9 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
private boolean seenInterface;
private StringBuffer returnType;
private StringBuilder returnType;
private StringBuffer exceptions;
private StringBuilder exceptions;
/**
* Stack used to keep track of class types that have arguments. Each element
@ -106,10 +106,10 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
public TraceSignatureVisitor(final int access) {
super(Opcodes.ASM5);
isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
this.declaration = new StringBuffer();
this.declaration = new StringBuilder();
}
private TraceSignatureVisitor(final StringBuffer buf) {
private TraceSignatureVisitor(final StringBuilder buf) {
super(Opcodes.ASM5);
this.declaration = buf;
}
@ -175,14 +175,14 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
declaration.append('(');
}
declaration.append(')');
returnType = new StringBuffer();
returnType = new StringBuilder();
return new TraceSignatureVisitor(returnType);
}
@Override
public SignatureVisitor visitExceptionType() {
if (exceptions == null) {
exceptions = new StringBuffer();
exceptions = new StringBuilder();
} else {
exceptions.append(", ");
}

View File

@ -1,12 +1,12 @@
Path: .
Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2014-10-15
Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2016-01-25
URL: file:///svnroot/asm/trunk/asm
Repository Root: file:///svnroot/asm
Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
Revision: 1772
Revision: 1795
Node Kind: directory
Schedule: normal
Last Changed Author: ebruneton
Last Changed Rev: 1772
Last Changed Date: 2014-09-06 09:13:07 +0200 (Sat, 06 Sep 2014)
Last Changed Rev: 1795
Last Changed Date: 2016-01-24 14:17:10 +0100 (Sun, 24 Jan 2016)

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2016, 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
@ -115,10 +115,31 @@ final class RSAClientKeyExchange extends HandshakeMessage {
byte[] encoded = null;
try {
boolean needFailover = false;
Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
boolean needFailover = !KeyUtil.isOracleJCEProvider(
try {
// Try UNWRAP_MODE mode firstly.
cipher.init(Cipher.UNWRAP_MODE, privateKey,
new TlsRsaPremasterSecretParameterSpec(
maxVersion.v, currentVersion.v),
generator);
// The provider selection can be delayed, please don't call
// any Cipher method before the call to Cipher.init().
needFailover = !KeyUtil.isOracleJCEProvider(
cipher.getProvider().getName());
} catch (InvalidKeyException | UnsupportedOperationException iue) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("The Cipher provider " +
cipher.getProvider().getName() +
" caused exception: " + iue.getMessage());
}
needFailover = true;
}
if (needFailover) {
// Use DECRYPT_MODE and dispose the previous initialization.
cipher.init(Cipher.DECRYPT_MODE, privateKey);
boolean failed = false;
try {
@ -134,10 +155,7 @@ final class RSAClientKeyExchange extends HandshakeMessage {
maxVersion.v, currentVersion.v,
encoded, generator);
} else {
cipher.init(Cipher.UNWRAP_MODE, privateKey,
new TlsRsaPremasterSecretParameterSpec(
maxVersion.v, currentVersion.v),
generator);
// the cipher should have been initialized
preMaster = (SecretKey)cipher.unwrap(encrypted,
"TlsRsaPremasterSecret", Cipher.SECRET_KEY);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2016, 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
@ -365,17 +365,6 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
/* Class and subclass dynamic debugging support */
private static final Debug debug = Debug.getInstance("ssl");
/*
* Is it the first application record to write?
*/
private boolean isFirstAppOutputRecord = true;
/*
* If AppOutputStream needs to delay writes of small packets, we
* will use this to store the data until we actually do the write.
*/
private ByteArrayOutputStream heldRecordBuffer = null;
/*
* Whether local cipher suites preference in server side should be
* honored during handshaking?
@ -998,9 +987,21 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
Plaintext plainText = null;
while (((state = getConnectionState()) != cs_CLOSED) &&
(state != cs_ERROR) && (state != cs_APP_CLOSED)) {
// clean the buffer
/*
* clean the buffer and check if it is too small, e.g. because
* the AppInputStream did not have the chance to see the
* current packet length but rather something like that of the
* handshake before. In that case we return 0 at this point to
* give the caller the chance to adjust the buffer.
*/
if (buffer != null) {
buffer.clear();
if (buffer.remaining() <
inputRecord.bytesInCompletePacket(sockInput)) {
return 0;
}
}
/*

View File

@ -1408,7 +1408,7 @@ InflateFully(jzfile *zip, jzentry *entry, void *buf, char **msg)
case Z_OK:
break;
case Z_STREAM_END:
if (count != 0 || strm.total_out != entry->size) {
if (count != 0 || strm.total_out != (uInt)entry->size) {
*msg = "inflateFully: Unexpected end of stream";
inflateEnd(&strm);
return JNI_FALSE;
@ -1528,7 +1528,7 @@ ZIP_InflateFully(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pm
case Z_OK:
break;
case Z_STREAM_END:
if (strm.total_out != outLen) {
if (strm.total_out != (uInt)outLen) {
*pmsg = "INFLATER_inflateFully: Unexpected end of stream";
inflateEnd(&strm);
return JNI_FALSE;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2016, 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
@ -23,10 +23,6 @@
* questions.
*/
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
@ -77,21 +73,6 @@ static jfieldID backupResult_bytesTransferred;
static jfieldID backupResult_context;
/**
* Win32 APIs not available in Windows XP
*/
typedef HANDLE (WINAPI* FindFirstStream_Proc)(LPCWSTR, STREAM_INFO_LEVELS, LPVOID, DWORD);
typedef BOOL (WINAPI* FindNextStream_Proc)(HANDLE, LPVOID);
typedef BOOLEAN (WINAPI* CreateSymbolicLinkProc) (LPCWSTR, LPCWSTR, DWORD);
typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD);
static FindFirstStream_Proc FindFirstStream_func;
static FindNextStream_Proc FindNextStream_func;
static CreateSymbolicLinkProc CreateSymbolicLink_func;
static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func;
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
"(I)V", lastError);
@ -108,7 +89,6 @@ JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
{
jclass clazz;
HMODULE h;
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
CHECK_NULL(clazz);
@ -175,24 +155,6 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
CHECK_NULL(backupResult_bytesTransferred);
backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
CHECK_NULL(backupResult_context);
// get handle to kernel32
if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
(LPCWSTR)&CreateFileW, &h) != 0)
{
// requires Windows Server 2003 or newer
FindFirstStream_func =
(FindFirstStream_Proc)GetProcAddress(h, "FindFirstStreamW");
FindNextStream_func =
(FindNextStream_Proc)GetProcAddress(h, "FindNextStreamW");
// requires Windows Vista or newer
CreateSymbolicLink_func =
(CreateSymbolicLinkProc)GetProcAddress(h, "CreateSymbolicLinkW");
GetFinalPathNameByHandle_func =
(GetFinalPathNameByHandleProc)GetProcAddress(h, "GetFinalPathNameByHandleW");
}
}
JNIEXPORT jlong JNICALL
@ -404,12 +366,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstStream0(JNIEnv* env, jclass thi
LPCWSTR lpFileName = jlong_to_ptr(address);
HANDLE handle;
if (FindFirstStream_func == NULL) {
JNU_ThrowInternalError(env, "Should not get here");
return;
}
handle = (*FindFirstStream_func)(lpFileName, FindStreamInfoStandard, &data, 0);
handle = FindFirstStreamW(lpFileName, FindStreamInfoStandard, &data, 0);
if (handle != INVALID_HANDLE_VALUE) {
jstring name = (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
if (name == NULL)
@ -433,12 +390,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_FindNextStream(JNIEnv* env, jclass this,
WIN32_FIND_STREAM_DATA data;
HANDLE h = (HANDLE)jlong_to_ptr(handle);
if (FindNextStream_func == NULL) {
JNU_ThrowInternalError(env, "Should not get here");
return NULL;
}
if ((*FindNextStream_func)(h, &data) != 0) {
if (FindNextStreamW(h, &data) != 0) {
return (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
} else {
if (GetLastError() != ERROR_HANDLE_EOF)
@ -1087,13 +1039,8 @@ Java_sun_nio_fs_WindowsNativeDispatcher_CreateSymbolicLink0(JNIEnv* env,
LPCWSTR link = jlong_to_ptr(linkAddress);
LPCWSTR target = jlong_to_ptr(targetAddress);
if (CreateSymbolicLink_func == NULL) {
JNU_ThrowInternalError(env, "Should not get here");
return;
}
/* On Windows 64-bit this appears to succeed even when there is insufficient privileges */
if ((*CreateSymbolicLink_func)(link, target, (DWORD)flags) == 0)
if (CreateSymbolicLinkW(link, target, (DWORD)flags) == 0)
throwWindowsException(env, GetLastError());
}
@ -1155,12 +1102,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_GetFinalPathNameByHandle(JNIEnv* env,
HANDLE h = (HANDLE)jlong_to_ptr(handle);
DWORD len;
if (GetFinalPathNameByHandle_func == NULL) {
JNU_ThrowInternalError(env, "Should not get here");
return NULL;
}
len = (*GetFinalPathNameByHandle_func)(h, path, MAX_PATH, 0);
len = GetFinalPathNameByHandleW(h, path, MAX_PATH, 0);
if (len > 0) {
if (len < MAX_PATH) {
rv = (*env)->NewString(env, (const jchar *)path, (jsize)len);
@ -1168,7 +1110,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_GetFinalPathNameByHandle(JNIEnv* env,
len += 1; /* return length does not include terminator */
lpBuf = (WCHAR*)malloc(len * sizeof(WCHAR));
if (lpBuf != NULL) {
len = (*GetFinalPathNameByHandle_func)(h, lpBuf, len, 0);
len = GetFinalPathNameByHandleW(h, lpBuf, len, 0);
if (len > 0) {
rv = (*env)->NewString(env, (const jchar *)lpBuf, (jsize)len);
} else {

View File

@ -24,7 +24,6 @@
package java.net.http;
import java.util.Locale;
import sun.util.logging.PlatformLogger;
/**
* -Djava.net.HttpClient.log=errors,requests,headers,frames[:type:type2:..],content
@ -35,9 +34,11 @@ import sun.util.logging.PlatformLogger;
*
* Logger name is "java.net.http.HttpClient"
*/
class Log {
// implements System.Logger in order to be skipped when printing the caller's
// information
abstract class Log implements System.Logger {
final static String logProp = "java.net.http.HttpClient.log";
static final String logProp = "java.net.http.HttpClient.log";
public static final int OFF = 0;
public static final int ERRORS = 0x1;
@ -55,7 +56,7 @@ class Log {
public static final int ALL = CONTROL| DATA | WINDOW_UPDATES;
static int frametypes;
static sun.util.logging.PlatformLogger logger;
static final System.Logger logger;
static {
String s = Utils.getNetProperty(logProp);
@ -111,7 +112,9 @@ class Log {
}
}
if (logging != OFF) {
logger = PlatformLogger.getLogger("java.net.http.HttpClient");
logger = System.getLogger("java.net.http.HttpClient");
} else {
logger = null;
}
}
@ -137,34 +140,38 @@ class Log {
static void logError(String s) {
if (errors())
logger.info("ERROR: " + s);
logger.log(Level.INFO, "ERROR: " + s);
}
static void logError(Throwable t) {
if (errors()) {
String s = Utils.stackTrace(t);
logger.info("ERROR: " + s);
logger.log(Level.INFO, "ERROR: " + s);
}
}
static void logSSL(String s) {
if (ssl())
logger.info("SSL: " + s);
logger.log(Level.INFO, "SSL: " + s);
}
static void logRequest(String s) {
if (requests())
logger.info("REQUEST: " + s);
logger.log(Level.INFO, "REQUEST: " + s);
}
static void logResponse(String s) {
if (requests())
logger.info("RESPONSE: " + s);
logger.log(Level.INFO, "RESPONSE: " + s);
}
static void logHeaders(String s) {
if (headers())
logger.info("HEADERS: " + s);
logger.log(Level.INFO, "HEADERS: " + s);
}
// not instantiable
private Log() {}
// END HTTP2
}

View File

@ -155,9 +155,13 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
@Override
public void configure(Map<String, String> config) {
try {
priorityList = Arrays.stream(config.get(NAME).split(","))
.map(Locale.LanguageRange::new)
.collect(Collectors.toList());
} catch (IllegalArgumentException iae) {
throw new PluginException(iae.getLocalizedMessage());
}
}
@Override
@ -168,7 +172,7 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
// jdk.localedata module validation
Set<String> packages = module.getAllPackages();
if (!packages.containsAll(LOCALEDATA_PACKAGES)) {
throw new PluginException("Missing locale data packages in jdk.localedata:\n\t" +
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") +
LOCALEDATA_PACKAGES.stream()
.filter(pn -> !packages.contains(pn))
.collect(Collectors.joining(",\n\t")));
@ -186,6 +190,10 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
filtered = filterLocales(available);
if (filtered.isEmpty()) {
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".nomatchinglocales"));
}
try {
String value = META_FILES + filtered.stream()
.map(s -> includeLocaleFilePatterns(s))

View File

@ -68,9 +68,18 @@ zip.argument=[comma separated list of resource paths]
zip.description=ZIP Compression
include-locales.argument=<langtag>[,<langtag>]*
include-locales.argument=\
<langtag>[,<langtag>]*
include-locales.description=BCP 47 language tags separated by a comma, allowing locale matching\ndefined in RFC 4647. eg: en,ja,*-IN
include-locales.description=\
BCP 47 language tags separated by a comma, allowing locale matching\n\
defined in RFC 4647. eg: en,ja,*-IN
include-locales.missingpackages=\
Missing locale data packages in jdk.localedata:\n\t
include-locales.nomatchinglocales=\
No matching locales found. Check the specified pattern.
main.status.ok=Functional.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2016, 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
@ -67,7 +67,7 @@ public interface RuntimeConstants {
/* Class File Constants */
int JAVA_MAGIC = 0xcafebabe;
int JAVA_MIN_SUPPORTED_VERSION = 45;
int JAVA_MAX_SUPPORTED_VERSION = 52;
int JAVA_MAX_SUPPORTED_VERSION = 53;
int JAVA_MAX_SUPPORTED_MINOR_VERSION = 0;
/* Generate class file version for 1.1 by default */

View File

@ -32,6 +32,7 @@ tier1 = \
-java/util/WeakHashMap/GCDuringIteration.java \
-java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
-java/util/concurrent/forkjoin/FJExceptionTableLeak.java \
-java/util/TimeZone/Bug6772689.java \
sun/nio/cs/ISO8859x.java \
java/nio/Buffer \
com/sun/crypto/provider/Cipher \
@ -42,6 +43,7 @@ tier2 = \
java/util/WeakHashMap/GCDuringIteration.java \
java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
java/util/concurrent/forkjoin/FJExceptionTableLeak.java \
java/util/TimeZone/Bug6772689.java \
:jdk_io \
:jdk_nio \
-sun/nio/cs/ISO8859x.java \
@ -492,7 +494,8 @@ needs_jdk = \
sun/reflect/CallerSensitive/MissingCallerSensitive.java \
sun/security/util/Resources/NewNamesFormat.java \
vm/verifier/defaultMethods/DefaultMethodRegressionTestsRun.java \
javax/xml/ws/clientjar/TestWsImport.java
javax/xml/ws/clientjar/TestWsImport.java \
javax/xml/bind/xjc/8145039/JaxbMarshallTest.java
# JRE adds further tests to compact3
#

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.Utils;
/* @test
* @bug 8147456
* @summary Check that providing a non-existing -agentpath gives a proper error.
* @author Sharath Ballal
*
* @library /lib/testlibrary
* @modules java.management
* @build jdk.testlibrary.*
* @build BadAgentPath
* @run driver BadAgentPath
*/
public class BadAgentPath {
public static void main(String[] args) throws Throwable {
OutputAnalyzer output = ProcessTools.executeTestJvm("-agentpath:/badAgent/agent", "-version");
output.shouldContain("Could not find agent library /badAgent/agent");
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @compile TestAccessClass.java TestCls.java
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestAccessClass
*/
package test.java.lang.invoke.t8150782;
import java.lang.invoke.*;
import static java.lang.invoke.MethodHandles.*;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.*;
public class TestAccessClass {
private static boolean initializedClass1;
private static class Class1 {
static {
initializedClass1 = true;
}
}
@Test
public void initializerNotRun() throws IllegalAccessException {
lookup().accessClass(Class1.class);
assertFalse(initializedClass1);
}
@Test
public void returnsSameClass() throws IllegalAccessException, ClassNotFoundException {
Class<?> aClass = lookup().accessClass(Class1.class);
assertEquals(Class1.class, aClass);
}
@DataProvider
Object[][] illegalAccessAccess() {
return new Object[][] {
{publicLookup(), Class1.class},
{publicLookup(), TestCls.getPrivateSIC()}
};
}
@Test(dataProvider = "illegalAccessAccess", expectedExceptions = {IllegalAccessException.class})
public void illegalAccessExceptionTest(Lookup lookup, Class<?> klass) throws IllegalAccessException, ClassNotFoundException {
lookup.accessClass(klass);
}
@Test
public void okAccess() throws IllegalAccessException {
lookup().accessClass(TestCls.getPrivateSIC());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 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
@ -22,9 +22,17 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.java.lang.invoke.t8150782;
import static java.lang.invoke.MethodHandles.*;
public class TestCls {
public static final Lookup LOOKUP = lookup();
private static class PrivateSIC {}
public static Class getPrivateSIC() { return PrivateSIC.class; }
public static Lookup getLookupForPrivateSIC() { return lookup(); }
module jdk.deploy.osx {
requires java.desktop;
requires java.scripting;
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @compile TestFindClass.java TestCls.java
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestFindClass
*/
package test.java.lang.invoke.t8150782;
import java.lang.invoke.*;
import static java.lang.invoke.MethodHandles.*;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.*;
public class TestFindClass {
private static final String PACKAGE_PREFIX = "test.java.lang.invoke.t8150782.";
private static boolean initializedClass1;
private static class Class1 {
static {
initializedClass1 = true;
}
}
@Test
public void initializerNotRun() throws IllegalAccessException, ClassNotFoundException {
lookup().findClass(PACKAGE_PREFIX + "TestFindClass$Class1");
assertFalse(initializedClass1);
}
@Test
public void returnsRequestedClass() throws IllegalAccessException, ClassNotFoundException {
Class<?> aClass = lookup().findClass(PACKAGE_PREFIX + "TestFindClass$Class1");
assertEquals(Class1.class, aClass);
}
@Test(expectedExceptions = {ClassNotFoundException.class})
public void classNotFoundExceptionTest() throws IllegalAccessException, ClassNotFoundException {
lookup().findClass(PACKAGE_PREFIX + "TestFindClass$NonExistent");
}
@DataProvider
Object[][] illegalAccessFind() {
return new Object[][] {
{publicLookup(), PACKAGE_PREFIX + "TestFindClass$Class1"},
{publicLookup(), PACKAGE_PREFIX + "TestCls$PrivateSIC"}
};
}
/**
* Assertion: @throws IllegalAccessException if the class is not accessible, using the allowed access modes.
*/
@Test(dataProvider = "illegalAccessFind", expectedExceptions = {ClassNotFoundException.class})
public void illegalAccessExceptionTest(Lookup lookup, String className) throws IllegalAccessException, ClassNotFoundException {
lookup.findClass(className);
}
@Test
public void okAccess() throws IllegalAccessException, ClassNotFoundException {
lookup().findClass(PACKAGE_PREFIX + "TestCls$PrivateSIC");
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @compile TestLookup.java TestCls.java
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestLookup
*/
package test.java.lang.invoke.t8150782;
import org.testng.annotations.Test;
import static java.lang.invoke.MethodHandles.*;
import static org.testng.AssertJUnit.*;
public class TestLookup {
@Test
public void testClassLoaderChange() {
Lookup lookup = lookup();
assertNotNull(lookup.lookupClass().getClassLoader());
Lookup lookup2 = lookup.in(Object.class);
assertNull(lookup2.lookupClass().getClassLoader());
}
@Test(expectedExceptions = {ClassNotFoundException.class})
public void testPublicCannotLoadUserClass() throws IllegalAccessException, ClassNotFoundException {
Lookup lookup = publicLookup();
lookup.findClass("test.java.lang.invoke.t8150782.TestCls");
}
@Test
public void testPublicCanLoadSystemClass() throws IllegalAccessException, ClassNotFoundException {
Lookup lookup = publicLookup();
lookup.findClass("java.util.HashMap");
}
@Test
public void testPublicInChangesClassLoader() {
Lookup lookup = publicLookup();
// Temporarily exclude until 8148697 is resolved, specifically:
// "publicLookup changed so that the lookup class is in an unnamed module"
//assertNull(lookup.lookupClass().getClassLoader());
Lookup lookup2 = lookup.in(TestCls.class);
assertNotNull(lookup2.lookupClass().getClassLoader());
}
}

View File

@ -24,7 +24,7 @@
/**
* @test
* @build ModuleSetAccessibleTest
* @modules java.base/sun.misc
* @modules java.base/jdk.internal.misc
* @run testng ModuleSetAccessibleTest
* @summary Test java.lang.reflect.AccessibleObject with modules
*/
@ -38,7 +38,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Module;
import sun.misc.Unsafe;
import jdk.internal.misc.Unsafe;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2016, 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
@ -23,6 +23,7 @@
/* @test
* @bug 4460583 4470470 4840199 6419424 6710579 6596323 6824135 6395224 7142919
* 8151582
* @run main/othervm AsyncCloseAndInterrupt
* @summary Comprehensive test of asynchronous closing and interruption
* @author Mark Reinhold
@ -89,7 +90,7 @@ public class AsyncCloseAndInterrupt {
private static void initRefuser() throws IOException {
refuser = ServerSocketChannel.open();
refuser.socket().bind(wildcardAddress);
refuser.bind(wildcardAddress, 1); // use minimum backlog
}
// Dead pipe source and sink
@ -349,7 +350,7 @@ public class AsyncCloseAndInterrupt {
static final Op CONNECT = new Op("connect") {
void setup() {
waitPump("connect wait for pumping refuser ...");
waitPump("connect waiting for pumping refuser ...");
}
void doIO(InterruptibleChannel ich) throws IOException {
SocketChannel sc = (SocketChannel)ich;
@ -361,7 +362,7 @@ public class AsyncCloseAndInterrupt {
static final Op FINISH_CONNECT = new Op("finishConnect") {
void setup() {
waitPump("finishConnect wait for pumping refuser ...");
waitPump("finishConnect waiting for pumping refuser ...");
}
void doIO(InterruptibleChannel ich) throws IOException {
SocketChannel sc = (SocketChannel)ich;
@ -498,12 +499,11 @@ public class AsyncCloseAndInterrupt {
private static volatile boolean pumpReady = false;
private static void waitPump(String msg){
pumpReady = false;
log.println(msg);
while (!pumpReady){
sleep(200);
}
log.println(msg + " done");
}
// Create a pump thread dedicated to saturate refuser's connection backlog
@ -520,28 +520,34 @@ public class AsyncCloseAndInterrupt {
// Saturate the refuser's connection backlog so that further connection
// attempts will be blocked
pumpReady = false;
while (!pumpDone) {
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
boolean connected = sc.connect(refuser.socket().getLocalSocketAddress());
// Assume that the connection backlog is saturated if a
// client cannot connect to the refuser within 50 miliseconds
// client cannot connect to the refuser within 50 milliseconds
long start = System.currentTimeMillis();
while (!connected && (System.currentTimeMillis() - start < 50)) {
while (!pumpReady && !connected
&& (System.currentTimeMillis() - start < 50)) {
connected = sc.finishConnect();
}
if (connected) {
// Retain so that finalizer doesn't close
refuserClients.add(sc);
pumpReady = false;
} else {
sc.close();
pumpReady = true;
}
}
for (SocketChannel sc : refuserClients) {
sc.close();
}
refuser.close();
log.println("Stop pumping refuser ...");
return refuserClients.size();
}
@ -565,8 +571,6 @@ public class AsyncCloseAndInterrupt {
sleep(50);
} while (!t.ready);
sleep(100);
switch (test) {
case TEST_INTR:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016, 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
@ -23,6 +23,7 @@
/* @test
* @bug 7200742
* @key intermittent
* @summary Test that Selector doesn't spin when changing interest ops
*/

View File

@ -761,6 +761,7 @@ public class TCKZonedDateTime extends AbstractDateTimeTest {
{"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT-01:00"},
{"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UTC-01:00"},
{"2012-06-30T12:30:40+01:00[Europe/London]", 2012, 6, 30, 12, 30, 40, 0, "Europe/London"},
{"2012-06-30T12:30:40+01", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
};
}

View File

@ -59,11 +59,13 @@
*/
package tck.java.time.format;
import static java.time.format.DateTimeFormatter.BASIC_ISO_DATE;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
import static java.time.temporal.ChronoField.OFFSET_SECONDS;
import static java.time.temporal.ChronoField.YEAR;
import static org.testng.Assert.assertEquals;
@ -73,6 +75,7 @@ import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.format.SignStyle;
import java.time.format.TextStyle;
import java.time.temporal.Temporal;
@ -339,6 +342,18 @@ public class TCKDateTimeFormatterBuilder {
{"+HH", 2, 0, 45, "+02"},
{"+HH", 2, 30, 45, "+02"},
{"+HHmm", 2, 0, 0, "+02"},
{"+HHmm", -2, 0, 0, "-02"},
{"+HHmm", 2, 30, 0, "+0230"},
{"+HHmm", 2, 0, 45, "+02"},
{"+HHmm", 2, 30, 45, "+0230"},
{"+HH:mm", 2, 0, 0, "+02"},
{"+HH:mm", -2, 0, 0, "-02"},
{"+HH:mm", 2, 30, 0, "+02:30"},
{"+HH:mm", 2, 0, 45, "+02"},
{"+HH:mm", 2, 30, 45, "+02:30"},
{"+HHMM", 2, 0, 0, "+0200"},
{"+HHMM", -2, 0, 0, "-0200"},
{"+HHMM", 2, 30, 0, "+0230"},
@ -374,6 +389,20 @@ public class TCKDateTimeFormatterBuilder {
{"+HH:MM:SS", 2, 30, 0, "+02:30:00"},
{"+HH:MM:SS", 2, 0, 45, "+02:00:45"},
{"+HH:MM:SS", 2, 30, 45, "+02:30:45"},
{"+HHmmss", 2, 0, 0, "+02"},
{"+HHmmss", -2, 0, 0, "-02"},
{"+HHmmss", 2, 30, 0, "+0230"},
{"+HHmmss", 2, 0, 45, "+020045"},
{"+HHmmss", 2, 30, 45, "+023045"},
{"+HH:mm:ss", 2, 0, 0, "+02"},
{"+HH:mm:ss", -2, 0, 0, "-02"},
{"+HH:mm:ss", 2, 30, 0, "+02:30"},
{"+HH:mm:ss", 2, 0, 45, "+02:00:45"},
{"+HH:mm:ss", 2, 30, 45, "+02:30:45"},
};
}
@ -878,4 +907,82 @@ public class TCKDateTimeFormatterBuilder {
assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L);
}
@DataProvider(name="lenientOffsetParseData")
Object[][] data_lenient_offset_parse() {
return new Object[][] {
{"+HH", "+01", 3600},
{"+HH", "+0101", 3660},
{"+HH", "+010101", 3661},
{"+HH", "+01", 3600},
{"+HH", "+01:01", 3660},
{"+HH", "+01:01:01", 3661},
{"+HHmm", "+01", 3600},
{"+HHmm", "+0101", 3660},
{"+HHmm", "+010101", 3661},
{"+HH:mm", "+01", 3600},
{"+HH:mm", "+01:01", 3660},
{"+HH:mm", "+01:01:01", 3661},
{"+HHMM", "+01", 3600},
{"+HHMM", "+0101", 3660},
{"+HHMM", "+010101", 3661},
{"+HH:MM", "+01", 3600},
{"+HH:MM", "+01:01", 3660},
{"+HH:MM", "+01:01:01", 3661},
{"+HHMMss", "+01", 3600},
{"+HHMMss", "+0101", 3660},
{"+HHMMss", "+010101", 3661},
{"+HH:MM:ss", "+01", 3600},
{"+HH:MM:ss", "+01:01", 3660},
{"+HH:MM:ss", "+01:01:01", 3661},
{"+HHMMSS", "+01", 3600},
{"+HHMMSS", "+0101", 3660},
{"+HHMMSS", "+010101", 3661},
{"+HH:MM:SS", "+01", 3600},
{"+HH:MM:SS", "+01:01", 3660},
{"+HH:MM:SS", "+01:01:01", 3661},
{"+HHmmss", "+01", 3600},
{"+HHmmss", "+0101", 3660},
{"+HHmmss", "+010101", 3661},
{"+HH:mm:ss", "+01", 3600},
{"+HH:mm:ss", "+01:01", 3660},
{"+HH:mm:ss", "+01:01:01", 3661},
};
}
@Test(dataProvider="lenientOffsetParseData")
public void test_lenient_offset_parse_1(String pattern, String offset, int offsetSeconds) {
assertEquals(new DateTimeFormatterBuilder().parseLenient().appendOffset(pattern, "Z").toFormatter().parse(offset).get(OFFSET_SECONDS),
offsetSeconds);
}
@Test
public void test_lenient_offset_parse_2() {
assertEquals(new DateTimeFormatterBuilder().parseLenient().appendOffsetId().toFormatter().parse("+01").get(OFFSET_SECONDS),
3600);
}
@Test(expectedExceptions=DateTimeParseException.class)
public void test_strict_appendOffsetId() {
assertEquals(new DateTimeFormatterBuilder().appendOffsetId().toFormatter().parse("+01").get(OFFSET_SECONDS),
3600);
}
@Test(expectedExceptions=DateTimeParseException.class)
public void test_strict_appendOffset_1() {
assertEquals(new DateTimeFormatterBuilder().appendOffset("+HH:MM:ss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS),
3600);
}
@Test(expectedExceptions=DateTimeParseException.class)
public void test_strict_appendOffset_2() {
assertEquals(new DateTimeFormatterBuilder().appendOffset("+HHMMss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS),
3600);
}
@Test
public void test_basic_iso_date() {
assertEquals(BASIC_ISO_DATE.parse("20021231+01").get(OFFSET_SECONDS), 3600);
assertEquals(BASIC_ISO_DATE.parse("20021231+0101").get(OFFSET_SECONDS), 3660);
}
}

View File

@ -199,6 +199,30 @@ public class TCKOffsetPrinterParser {
{"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-00:23:00"},
{"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-01:23:45"},
{"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+01:23"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+00:23"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+01:23:45"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-01:23"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-00:23"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-01:23:45"},
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+0123"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0023"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+012345"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "+000045"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-0123"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0023"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-012345"},
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-000045"},
};
}

View File

@ -79,19 +79,24 @@ import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.chrono.Chronology;
import java.time.chrono.ThaiBuddhistChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DecimalStyle;
import java.time.format.SignStyle;
import java.time.format.TextStyle;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.util.Locale;
import java.util.function.Function;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Test DateTimeFormatter.
* @bug 8085887
*/
@Test
public class TestDateTimeFormatter {
@ -196,4 +201,75 @@ public class TestDateTimeFormatter {
assertTrue(msg.contains("11:30:56"), msg);
}
@DataProvider(name="nozone_exception_cases")
Object[][] exceptionCases() {
return new Object[][] {
{LocalDateTime.of(2000, 1, 1, 1, 1), "z", "ZoneId"},
{OffsetDateTime.of(2000, 1, 1, 3, 3, 3, 0, ZoneOffset.ofTotalSeconds(60)), "z", "ZoneId"},
};
}
// Test cases that should throw an exception with a cogent message
// containing the Type being queried and the Temporal being queried.
@Test(dataProvider="nozone_exception_cases")
public void test_throws_message(Temporal temporal, String pattern, String queryName) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern);
try {
fmt.format(temporal);
fail("Format using \"" + pattern + "\" with " +
temporal + " should have failed");
} catch (DateTimeException dte) {
String msg = dte.getMessage();
// Verify message contains the type that is missing and the temporal value
assertTrue(msg.contains(queryName),
String.format("\"%s\" missing from %s", queryName, msg));
String s = temporal.toString();
assertTrue(msg.contains(s),
String.format("\"%s\" missing from %s", s, msg));
}
}
// Test cases that should throw an exception with a cogent message when missing the Chronology
@Test
public void test_throws_message_chrono() {
Chronology chrono = ThaiBuddhistChronology.INSTANCE;
DateTimeFormatter fmt = new DateTimeFormatterBuilder().appendZoneId().toFormatter()
.withChronology(chrono);
LocalTime now = LocalTime.now();
try {
fmt.format(now);
fail("Format using appendZoneId() should have failed");
} catch (DateTimeException dte) {
String msg = dte.getMessage();
// Verify message contains the type that is missing and the temporal value
assertTrue(msg.contains("ZoneId"),
String.format("\"%s\" missing from %s", "ZoneId", msg));
assertTrue(msg.contains(chrono.toString()),
String.format("\"%s\" missing from %s", chrono.toString(), msg));
}
}
// Test cases that should throw an exception with a cogent message when missing the ZoneId
@Test
public void test_throws_message_zone() {
ZoneId zone = ZoneId.of("Pacific/Honolulu");
DateTimeFormatter fmt = new DateTimeFormatterBuilder().appendChronologyId().toFormatter()
.withZone(zone);
LocalTime now = LocalTime.now();
try {
fmt.format(now);
fail("Format using appendChronologyId() should have failed");
} catch (DateTimeException dte) {
String msg = dte.getMessage();
// Verify message contains the type that is missing and the temporal value
assertTrue(msg.contains("Chronology"),
String.format("\"%s\" missing from %s", "Chronology", msg));
assertTrue(msg.contains(zone.toString()),
String.format("\"%s\" missing from %s", zone.toString(), msg));
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2016, 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
@ -52,6 +52,7 @@ import static org.testng.Assert.*;
/**
* @test
* @bug 8148748
* @summary Spliterator last-binding and fail-fast tests
* @run testng SpliteratorLateBindingFailFastTest
*/
@ -120,8 +121,8 @@ public class SpliteratorLateBindingFailFastTest {
}
void addList(Function<Collection<T>, ? extends List<T>> l) {
// @@@ If collection is instance of List then add sub-list tests
addCollection(l);
addCollection(l.andThen(list -> list.subList(0, list.size())));
}
void addMap(Function<Map<T, T>, ? extends Map<T, T>> mapConstructor) {

View File

@ -24,6 +24,7 @@
/*
* @test
* @bug 6772689
* @key intermittent
* @summary Test for standard-to-daylight transitions at midnight:
* date stays on the given day.
*/

View File

@ -101,9 +101,6 @@ public class SSLSocketSSLEngineTemplate {
private static final boolean debug = false;
private final SSLContext sslc;
private SSLEngine serverEngine; // server-side SSLEngine
private SSLSocket sslSocket; // client-side socket
private ServerSocket serverSocket; // server-side Socket, generates the...
private Socket socket; // server-side socket that will read
private final byte[] serverMsg =
"Hi there Client, I'm a Server.".getBytes();
@ -217,20 +214,20 @@ public class SSLSocketSSLEngineTemplate {
private void runTest(boolean direct) throws Exception {
boolean serverClose = direct;
serverSocket = new ServerSocket();
// generates the server-side Socket
try (ServerSocket serverSocket = new ServerSocket()) {
serverSocket.setReuseAddress(false);
serverSocket.bind(null);
int port = serverSocket.getLocalPort();
Thread thread = createClientThread(port, serverClose);
socket = serverSocket.accept();
socket.setSoTimeout(500);
serverSocket.close();
createSSLEngine();
createBuffers(direct);
try {
// server-side socket that will read
try (Socket socket = serverSocket.accept()) {
socket.setSoTimeout(500);
boolean closed = false;
// will try to read one more time in case client message
// is fragmented to multiple pieces
@ -310,18 +307,21 @@ public class SSLSocketSSLEngineTemplate {
* A sanity check to ensure we got what was sent.
*/
if (serverIn.remaining() != clientMsg.length) {
if (retry && serverIn.remaining() < clientMsg.length) {
if (retry &&
serverIn.remaining() < clientMsg.length) {
log("Need to read more from client");
retry = false;
continue;
} else {
throw new Exception("Client: Data length error");
throw new Exception(
"Client: Data length error");
}
}
for (int i = 0; i < clientMsg.length; i++) {
if (clientMsg[i] != serverIn.get()) {
throw new Exception("Client: Data content error");
throw new Exception(
"Client: Data content error");
}
}
serverIn.compact();
@ -330,19 +330,12 @@ public class SSLSocketSSLEngineTemplate {
} catch (Exception e) {
serverException = e;
} finally {
if (socket != null) {
socket.close();
}
// Wait for the client to join up with us.
if (thread != null) {
thread.join();
}
if (sslSocket != null) {
sslSocket.close();
}
} finally {
if (serverException != null) {
if (clientException != null) {
serverException.initCause(clientException);
@ -369,11 +362,9 @@ public class SSLSocketSSLEngineTemplate {
@Override
public void run() {
try {
Thread.sleep(1000); // Give server time to finish setup.
sslSocket = (SSLSocket) sslc.getSocketFactory().
createSocket("localhost", port);
// client-side socket
try (SSLSocket sslSocket = (SSLSocket)sslc.getSocketFactory().
createSocket("localhost", port)) {
OutputStream os = sslSocket.getOutputStream();
InputStream is = sslSocket.getInputStream();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2016, 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
@ -86,8 +86,8 @@ public class SSLSocketTemplate {
void doServerSide() throws Exception {
SSLServerSocketFactory sslssf =
(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLServerSocket sslServerSocket =
(SSLServerSocket) sslssf.createServerSocket(serverPort);
try (SSLServerSocket sslServerSocket =
(SSLServerSocket)sslssf.createServerSocket(serverPort)) {
serverPort = sslServerSocket.getLocalPort();
@ -96,15 +96,15 @@ public class SSLSocketTemplate {
*/
serverReady = true;
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream();
sslIS.read();
sslOS.write(85);
sslOS.flush();
sslSocket.close();
}
}
}
/*
@ -124,8 +124,8 @@ public class SSLSocketTemplate {
SSLSocketFactory sslsf =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)
sslsf.createSocket("localhost", serverPort);
try (SSLSocket sslSocket =
(SSLSocket)sslsf.createSocket("localhost", serverPort)) {
InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream();
@ -133,8 +133,7 @@ public class SSLSocketTemplate {
sslOS.write(280);
sslOS.flush();
sslIS.read();
sslSocket.close();
}
}
/*

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8145039
* @summary Check that marshalling of xjc generated class doesn't throw
* ClassCast exception.
* @modules javax.xml.bind
* @library /lib/testlibrary
* @run testng/othervm JaxbMarshallTest
*/
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import jdk.testlibrary.JDKToolLauncher;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class JaxbMarshallTest {
@BeforeTest
public void setUp() throws IOException {
// Create test directory inside scratch
testWorkDir = Paths.get(System.getProperty("user.dir", "."));
// Save its URL
testWorkDirUrl = testWorkDir.toUri().toURL();
// Get test source directory path
testSrcDir = Paths.get(System.getProperty("test.src", "."));
// Get path of xjc result folder
xjcResultDir = testWorkDir.resolve(TEST_PACKAGE);
// Copy schema document file to scratch directory
Files.copy(testSrcDir.resolve(XSD_FILENAME), testWorkDir.resolve(XSD_FILENAME), REPLACE_EXISTING);
}
/*
* Test does the following steps to reproduce problem reported by 8145039:
* 1. Copy test schema to JTREG scratch folder
* 2. Run xjc on test schema file
* 3. Compile generated java files with test javac
* 4. Marshall the new list instance to ensure that
* ClassCastException is not thrown
*/
@Test
public void marshallClassCastExceptionTest() throws Exception {
JAXBContext jaxbContext;
Marshaller marshaller;
URLClassLoader jaxbContextClassLoader;
// Generate java classes by xjc
runXjc(XSD_FILENAME);
// Compile xjc generated java files
compileXjcGeneratedClasses();
// Create JAXB context based on xjc generated package.
// Need to create URL class loader ot make compiled classes discoverable
// by JAXB context
jaxbContextClassLoader = URLClassLoader.newInstance(new URL[] {testWorkDirUrl});
jaxbContext = JAXBContext.newInstance( TEST_PACKAGE, jaxbContextClassLoader);
// Create instance of Xjc generated data type.
// Java classes were compiled during the test execution hence reflection
// is needed here
Class classLongListClass = jaxbContextClassLoader.loadClass(TEST_CLASS);
Object objectLongListClass = classLongListClass.newInstance();
// Get 'getIn' method object
Method getInMethod = classLongListClass.getMethod( GET_LIST_METHOD, (Class [])null );
// Invoke 'getIn' method
List<Long> inList = (List<Long>)getInMethod.invoke(objectLongListClass);
// Add values into the jaxb object list
inList.add(Long.valueOf(0));
inList.add(Long.valueOf(43));
inList.add(Long.valueOf(1000000123));
// Marshall constructed complex type variable to standard output.
// In case of failure the ClassCastException will be thrown
marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(objectLongListClass, System.out);
}
// Compile schema file into java classes definitions
void runXjc(String xsdFileName) throws Exception {
// Prepare process builder to run schemagen tool and save its output
JDKToolLauncher xjcLauncher = JDKToolLauncher.createUsingTestJDK("xjc");
xjcLauncher.addToolArg(xsdFileName);
System.out.println("Executing xjc command: " + Arrays.asList(xjcLauncher.getCommand()));
ProcessBuilder pb = new ProcessBuilder(xjcLauncher.getCommand());
// Set xjc work directory with the input java file
pb.directory(testWorkDir.toFile());
pb.inheritIO();
Process p = pb.start();
p.waitFor();
p.destroy();
}
// Compile java classes with javac tool
void compileXjcGeneratedClasses() throws Exception {
JDKToolLauncher javacLauncher = JDKToolLauncher.createUsingTestJDK("javac");
javacLauncher.addToolArg(xjcResultDir.resolve("ObjectFactory.java").toString());
javacLauncher.addToolArg(xjcResultDir.resolve("TypesLongList.java").toString());
javacLauncher.addToolArg(xjcResultDir.resolve("package-info.java").toString());
System.out.println("Compiling xjc generated classes: " + Arrays.asList(javacLauncher.getCommand()));
ProcessBuilder pb = new ProcessBuilder(javacLauncher.getCommand());
pb.inheritIO();
pb.directory(testWorkDir.toFile());
Process p = pb.start();
p.waitFor();
p.destroy();
}
// Test schema filename
static final String XSD_FILENAME = "testSchema.xsd";
// Package of java classes generated by xjc
static final String TEST_PACKAGE = "testns_package";
// Name of generated java class
static final String TEST_CLASS = TEST_PACKAGE+".TypesLongList";
// Method to get the list from xjc generated class
static final String GET_LIST_METHOD = "getIn";
// Test working directory
Path testWorkDir;
// Test working directory URL
URL testWorkDirUrl;
// Directory with test src
Path testSrcDir;
// Directory with java files generated by xjc
Path xjcResultDir;
}

View File

@ -0,0 +1,21 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://testns_package"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
targetNamespace="http://testns_package">
<!-- Simple type list -->
<xsd:simpleType name="LongList">
<xsd:list>
<xsd:simpleType>
<xsd:restriction base="xsd:unsignedInt"/>
</xsd:simpleType>
</xsd:list>
</xsd:simpleType>
<!--- Complex test type -->
<xsd:element name="typesLongList">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="in" type="tns:LongList"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@ -23,14 +23,16 @@
/**
* @test
* @bug 8080679
* @modules jdk.internal.le/jdk.internal.jline.console
* @bug 8080679 8131913
* @modules jdk.internal.le/jdk.internal.jline
* jdk.internal.le/jdk.internal.jline.console
* @summary Verify ConsoleReader.stripAnsi strips escape sequences from its input correctly.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import jdk.internal.jline.UnsupportedTerminal;
import jdk.internal.jline.console.ConsoleReader;
public class StripAnsiTest {
@ -41,7 +43,7 @@ public class StripAnsiTest {
void run() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ConsoleReader reader = new ConsoleReader(in, out);
ConsoleReader reader = new ConsoleReader(in, out, new UnsupportedTerminal());
String withAnsi = "0\033[s1\033[2J2\033[37;4m3";
String expected = "0123";

View File

@ -0,0 +1,607 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import jdk.internal.misc.Unsafe;
import java.lang.reflect.Field;
/**
* Helper class to support testing of Unsafe.copyMemory and Unsafe.copySwapMemory
*/
public class CopyCommon {
private static final boolean DEBUG = Boolean.getBoolean("CopyCommon.DEBUG");
public static final long KB = 1024;
public static final long MB = KB * 1024;
public static final long GB = MB * 1024;
static final int SMALL_COPY_SIZE = 32;
static final int BASE_ALIGNMENT = 16;
protected static final Unsafe UNSAFE;
static {
try {
Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
UNSAFE = (jdk.internal.misc.Unsafe) f.get(null);
} catch (Exception e) {
throw new RuntimeException("Unable to get Unsafe instance.", e);
}
}
static long alignDown(long value, long alignment) {
return value & ~(alignment - 1);
}
static long alignUp(long value, long alignment) {
return (value + alignment - 1) & ~(alignment - 1);
}
static boolean isAligned(long value, long alignment) {
return value == alignDown(value, alignment);
}
CopyCommon() {
}
/**
* Generate verification data for a given offset
*
* The verification data is used to verify that the correct bytes
* have indeed been copied and byte swapped.
*
* The data is generated based on the offset (in bytes) into the
* source buffer. For a native buffer the offset is relative to
* the base pointer. For a heap array it is relative to the
* address of the first array element.
*
* This method will return the result of doing an elementSize byte
* read starting at offset (in bytes).
*
* @param offset offset into buffer
* @param elemSize size (in bytes) of the element
*
* @return the verification data, only the least significant
* elemSize*8 bits are set, zero extended
*/
private long getVerificationDataForOffset(long offset, long elemSize) {
byte[] bytes = new byte[(int)elemSize];
for (long i = 0; i < elemSize; i++) {
bytes[(int)i] = (byte)(offset + i);
}
long o = UNSAFE.arrayBaseOffset(byte[].class);
switch ((int)elemSize) {
case 1: return Byte.toUnsignedLong(UNSAFE.getByte(bytes, o));
case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(bytes, o));
case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(bytes, o));
case 8: return UNSAFE.getLongUnaligned(bytes, o);
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
}
}
/**
* Verify byte swapped data
*
* @param ptr the data to verify
* @param srcOffset the srcOffset (in bytes) from which the copy started,
* used as key to regenerate the verification data
* @param dstOffset the offset (in bytes) in the array at which to start
* the verification, relative to the first element in the array
* @param size size (in bytes) of data to to verify
* @param elemSize size (in bytes) of the individual array elements
*
* @throws RuntimeException if an error is found
*/
private void verifySwappedData(GenericPointer ptr, long srcOffset, long dstOffset, long size, long elemSize) {
for (long offset = 0; offset < size; offset += elemSize) {
long expectedUnswapped = getVerificationDataForOffset(srcOffset + offset, elemSize);
long expected = byteSwap(expectedUnswapped, elemSize);
long actual = getArrayElem(ptr, dstOffset + offset, elemSize);
if (expected != actual) {
throw new RuntimeException("srcOffset: 0x" + Long.toHexString(srcOffset) +
" dstOffset: 0x" + Long.toHexString(dstOffset) +
" size: 0x" + Long.toHexString(size) +
" offset: 0x" + Long.toHexString(offset) +
" expectedUnswapped: 0x" + Long.toHexString(expectedUnswapped) +
" expected: 0x" + Long.toHexString(expected) +
" != actual: 0x" + Long.toHexString(actual));
}
}
}
/**
* Initialize an array with verification friendly data
*
* @param ptr pointer to the data to initialize
* @param size size (in bytes) of the data
* @param elemSize size (in bytes) of the individual elements
*/
private void initVerificationData(GenericPointer ptr, long size, long elemSize) {
for (long offset = 0; offset < size; offset++) {
byte data = (byte)getVerificationDataForOffset(offset, 1);
if (ptr.isOnHeap()) {
UNSAFE.putByte(ptr.getObject(), ptr.getOffset() + offset, data);
} else {
UNSAFE.putByte(ptr.getOffset() + offset, data);
}
}
}
/**
* Allocate a primitive array
*
* @param size size (in bytes) of all the array elements (elemSize * length)
* @param elemSize the size of the array elements
*
* @return a newly allocated primitive array
*/
Object allocArray(long size, long elemSize) {
int length = (int)(size / elemSize);
switch ((int)elemSize) {
case 1: return new byte[length];
case 2: return new short[length];
case 4: return new int[length];
case 8: return new long[length];
default:
throw new IllegalArgumentException("Invalid element size: " + elemSize);
}
}
/**
* Get the value of a primitive array entry
*
* @param ptr pointer to the data
* @param offset offset (in bytes) of the array element, relative to the first element in the array
*
* @return the array element, as an unsigned long
*/
private long getArrayElem(GenericPointer ptr, long offset, long elemSize) {
if (ptr.isOnHeap()) {
Object o = ptr.getObject();
int index = (int)(offset / elemSize);
if (o instanceof short[]) {
short[] arr = (short[])o;
return Short.toUnsignedLong(arr[index]);
} else if (o instanceof int[]) {
int[] arr = (int[])o;
return Integer.toUnsignedLong(arr[index]);
} else if (o instanceof long[]) {
long[] arr = (long[])o;
return arr[index];
} else {
throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
}
} else {
long addr = ptr.getOffset() + offset;
switch ((int)elemSize) {
case 1: return Byte.toUnsignedLong(UNSAFE.getByte(addr));
case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(null, addr));
case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(null, addr));
case 8: return UNSAFE.getLongUnaligned(null, addr);
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
}
}
}
private void putValue(long addr, long elemSize, long value) {
switch ((int)elemSize) {
case 1: UNSAFE.putByte(addr, (byte)value); break;
case 2: UNSAFE.putShortUnaligned(null, addr, (short)value); break;
case 4: UNSAFE.putIntUnaligned(null, addr, (int)value); break;
case 8: UNSAFE.putLongUnaligned(null, addr, value); break;
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
}
}
/**
* Get the size of the elements for an array
*
* @param o a primitive heap array
*
* @return the size (in bytes) of the individual array elements
*/
private long getArrayElemSize(Object o) {
if (o instanceof short[]) {
return 2;
} else if (o instanceof int[]) {
return 4;
} else if (o instanceof long[]) {
return 8;
} else {
throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
}
}
/**
* Byte swap a value
*
* @param value the value to swap, only the bytes*8 least significant bits are used
* @param size size (in bytes) of the value
*
* @return the byte swapped value in the bytes*8 least significant bits
*/
private long byteSwap(long value, long size) {
switch ((int)size) {
case 2: return Short.toUnsignedLong(Short.reverseBytes((short)value));
case 4: return Integer.toUnsignedLong(Integer.reverseBytes((int)value));
case 8: return Long.reverseBytes(value);
default: throw new IllegalArgumentException("Invalid element size: " + size);
}
}
/**
* Verify data which has *not* been byte swapped
*
* @param ptr the data to verify
* @param startOffset the offset (in bytes) at which to start the verification
* @param size size (in bytes) of the data to verify
*
* @throws RuntimeException if an error is found
*/
private void verifyUnswappedData(GenericPointer ptr, long startOffset, long srcOffset, long size) {
for (long i = 0; i < size; i++) {
byte expected = (byte)getVerificationDataForOffset(srcOffset + i, 1);
byte actual;
if (ptr.isOnHeap()) {
actual = UNSAFE.getByte(ptr.getObject(), ptr.getOffset() + startOffset + i);
} else {
actual = UNSAFE.getByte(ptr.getOffset() + startOffset + i);
}
if (expected != actual) {
throw new RuntimeException("startOffset: 0x" + Long.toHexString(startOffset) +
" srcOffset: 0x" + Long.toHexString(srcOffset) +
" size: 0x" + Long.toHexString(size) +
" i: 0x" + Long.toHexString(i) +
" expected: 0x" + Long.toHexString(expected) +
" != actual: 0x" + Long.toHexString(actual));
}
}
}
/**
* Copy and byte swap data from the source to the destination
*
* This method will pre-populate the whole source and destination
* buffers with verification friendly data. It will then copy data
* to fill part of the destination buffer with data from the
* source, optionally byte swapping the copied elements on the
* fly. Some space (padding) will be left before and after the
* data in the destination buffer, which should not be
* touched/overwritten by the copy call.
*
* Note: Both source and destination buffers will be overwritten!
*
* @param src source buffer to copy from
* @param srcOffset the offset (in bytes) in the source buffer, relative to
* the first array element, at which to start reading data
* @param dst destination buffer to copy to
* @param dstOffset the offset (in bytes) in the destination
* buffer, relative to the first array element, at which to
* start writing data
* @param bufSize the size (in bytes) of the src and dst arrays
* @param copyBytes the size (in bytes) of the copy to perform,
* must be a multiple of elemSize
* @param elemSize the size (in bytes) of the elements
* @param swap true if elements should be byte swapped
*
* @throws RuntimeException if an error is found
*/
void testCopyGeneric(GenericPointer src, long srcOffset,
GenericPointer dst, long dstOffset,
long bufSize, long copyBytes, long elemSize, boolean swap) {
if (swap) {
if (!isAligned(copyBytes, elemSize)) {
throw new IllegalArgumentException(
"copyBytes (" + copyBytes + ") must be a multiple of elemSize (" + elemSize + ")");
}
if (src.isOnHeap() && !isAligned(srcOffset, elemSize)) {
throw new IllegalArgumentException(
"srcOffset (" + srcOffset + ") must be a multiple of elemSize (" + elemSize + ")");
}
if (dst.isOnHeap() && !isAligned(dstOffset, elemSize)) {
throw new IllegalArgumentException(
"dstOffset (" + dstOffset + ") must be a multiple of elemSize (" + elemSize + ")");
}
}
if (srcOffset + copyBytes > bufSize) {
throw new IllegalArgumentException(
"srcOffset (" + srcOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
}
if (dstOffset + copyBytes > bufSize) {
throw new IllegalArgumentException(
"dstOffset (" + dstOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
}
// Initialize the whole source buffer with a verification friendly pattern (no 0x00 bytes)
initVerificationData(src, bufSize, elemSize);
if (!src.equals(dst)) {
initVerificationData(dst, bufSize, elemSize);
}
if (DEBUG) {
System.out.println("===before===");
for (int offset = 0; offset < bufSize; offset += elemSize) {
long srcValue = getArrayElem(src, offset, elemSize);
long dstValue = getArrayElem(dst, offset, elemSize);
System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
" src=0x" + Long.toHexString(srcValue) +
" dst=0x" + Long.toHexString(dstValue));
}
}
if (swap) {
// Copy & swap data into the middle of the destination buffer
UNSAFE.copySwapMemory(src.getObject(),
src.getOffset() + srcOffset,
dst.getObject(),
dst.getOffset() + dstOffset,
copyBytes,
elemSize);
} else {
// Copy & swap data into the middle of the destination buffer
UNSAFE.copyMemory(src.getObject(),
src.getOffset() + srcOffset,
dst.getObject(),
dst.getOffset() + dstOffset,
copyBytes);
}
if (DEBUG) {
System.out.println("===after===");
for (int offset = 0; offset < bufSize; offset += elemSize) {
long srcValue = getArrayElem(src, offset, elemSize);
long dstValue = getArrayElem(dst, offset, elemSize);
System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
" src=0x" + Long.toHexString(srcValue) +
" dst=0x" + Long.toHexString(dstValue));
}
}
// Verify the the front padding is unchanged
verifyUnswappedData(dst, 0, 0, dstOffset);
if (swap) {
// Verify swapped data
verifySwappedData(dst, srcOffset, dstOffset, copyBytes, elemSize);
} else {
// Verify copied/unswapped data
verifyUnswappedData(dst, dstOffset, srcOffset, copyBytes);
}
// Verify that the back padding is unchanged
long frontAndCopyBytes = dstOffset + copyBytes;
long trailingBytes = bufSize - frontAndCopyBytes;
verifyUnswappedData(dst, frontAndCopyBytes, frontAndCopyBytes, trailingBytes);
}
/**
* Test various configurations of copying and optionally swapping data
*
* @param src the source buffer to copy from
* @param dst the destination buffer to copy to
* @param size size (in bytes) of the buffers
* @param elemSize size (in bytes) of the individual elements
*
* @throws RuntimeException if an error is found
*/
public void testBufferPair(GenericPointer src, GenericPointer dst, long size, long elemSize, boolean swap) {
// offset in source from which to start reading data
for (long srcOffset = 0; srcOffset < size; srcOffset += (src.isOnHeap() ? elemSize : 1)) {
// offset in destination at which to start writing data
for (int dstOffset = 0; dstOffset < size; dstOffset += (dst.isOnHeap() ? elemSize : 1)) {
// number of bytes to copy
long maxCopyBytes = Math.min(size - srcOffset, size - dstOffset);
for (long copyBytes = 0; copyBytes < maxCopyBytes; copyBytes += elemSize) {
try {
testCopyGeneric(src, srcOffset, dst, dstOffset, size, copyBytes, elemSize, swap);
} catch (RuntimeException e) {
// Wrap the exception in another exception to catch the relevant configuration data
throw new RuntimeException("testBufferPair: " +
"src=" + src +
" dst=" + dst +
" elemSize=0x" + Long.toHexString(elemSize) +
" copyBytes=0x" + Long.toHexString(copyBytes) +
" srcOffset=0x" + Long.toHexString(srcOffset) +
" dstOffset=0x" + Long.toHexString(dstOffset) +
" swap=" + swap,
e);
}
}
}
}
}
/**
* Test copying between various permutations of buffers
*
* @param buffers buffers to permute (src x dst)
* @param size size (in bytes) of buffers
* @param elemSize size (in bytes) of individual elements
*
* @throws RuntimeException if an error is found
*/
public void testPermuteBuffers(GenericPointer[] buffers, long size, long elemSize, boolean swap) {
System.out.println("testPermuteBuffers(buffers, " + size + ", " + elemSize + ", " + swap + ")");
for (int srcIndex = 0; srcIndex < buffers.length; srcIndex++) {
for (int dstIndex = 0; dstIndex < buffers.length; dstIndex++) {
testBufferPair(buffers[srcIndex], buffers[dstIndex], size, elemSize, swap);
}
}
}
/**
* Test copying of a specific element size
*
* @param size size (in bytes) of buffers to allocate
* @param elemSize size (in bytes) of individual elements
*
* @throws RuntimeException if an error is found
*/
private void testElemSize(long size, long elemSize, boolean swap) {
long buf1Raw = 0;
long buf2Raw = 0;
try {
buf1Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
long buf1 = alignUp(buf1Raw, BASE_ALIGNMENT);
buf2Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
long buf2 = alignUp(buf2Raw, BASE_ALIGNMENT);
GenericPointer[] buffers = {
new GenericPointer(buf1),
new GenericPointer(buf2),
new GenericPointer(allocArray(size, elemSize)),
new GenericPointer(allocArray(size, elemSize))
};
testPermuteBuffers(buffers, size, elemSize, swap);
} finally {
if (buf1Raw != 0) {
UNSAFE.freeMemory(buf1Raw);
}
if (buf2Raw != 0) {
UNSAFE.freeMemory(buf2Raw);
}
}
}
/**
* Verify that small copies work
*/
void testSmallCopy(boolean swap) {
int smallBufSize = SMALL_COPY_SIZE;
int minElemSize = swap ? 2 : 1;
int maxElemSize = swap ? 8 : 1;
// Test various element types and heap/native combinations
for (long elemSize = minElemSize; elemSize <= maxElemSize; elemSize <<= 1) {
testElemSize(smallBufSize, elemSize, swap);
}
}
/**
* Verify that large copies work
*/
void testLargeCopy(boolean swap) {
long size = 2 * GB + 8;
long bufRaw = 0;
// Check that a large native copy succeeds
try {
try {
bufRaw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
} catch (OutOfMemoryError e) {
// Accept failure, skip test
return;
}
long buf = alignUp(bufRaw, BASE_ALIGNMENT);
if (swap) {
UNSAFE.copySwapMemory(null, buf, null, buf, size, 8);
} else {
UNSAFE.copyMemory(null, buf, null, buf, size);
}
} catch (Exception e) {
throw new RuntimeException("copy of large buffer failed (swap=" + swap + ")");
} finally {
if (bufRaw != 0) {
UNSAFE.freeMemory(bufRaw);
}
}
}
/**
* Helper class to represent a "pointer" - either a heap array or
* a pointer to a native buffer.
*
* In the case of a native pointer, the Object is null and the offset is
* the absolute address of the native buffer.
*
* In the case of a heap object, the Object is a primitive array, and
* the offset will be set to the base offset to the first element, meaning
* the object and the offset together form a double-register pointer.
*/
static class GenericPointer {
private final Object o;
private final long offset;
private GenericPointer(Object o, long offset) {
this.o = o;
this.offset = offset;
}
public String toString() {
return "GenericPointer(o={" + o + "}, offset=0x" + Long.toHexString(offset) + ")";
}
public boolean equals(Object other) {
if (!(other instanceof GenericPointer)) {
return false;
}
GenericPointer otherp = (GenericPointer)other;
return o == otherp.o && offset == otherp.offset;
}
GenericPointer(Object o) {
this(o, UNSAFE.arrayBaseOffset(o.getClass()));
}
GenericPointer(long offset) {
this(null, offset);
}
public boolean isOnHeap() {
return o != null;
}
public Object getObject() {
return o;
}
public long getOffset() {
return offset;
}
}
}

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import jdk.internal.misc.Unsafe;
import java.lang.reflect.Field;
/*
* @test
* @summary Test Unsafe.copyMemory
* @modules java.base/jdk.internal.misc
*/
public class CopyMemory extends CopyCommon {
private CopyMemory() {
}
/**
* Run positive tests
*
* @throws RuntimeException if an error is found
*/
private void testPositive() {
testSmallCopy(false);
testLargeCopy(false);
}
/**
* Run negative tests, testing corner cases and the various exceptions
*
* @throws RuntimeException if an error is found
*/
private void testNegative() {
long bufRaw = 0;
try {
bufRaw = UNSAFE.allocateMemory(1024);
long buf = CopyCommon.alignUp(bufRaw, CopyCommon.BASE_ALIGNMENT);
short[] arr = new short[16];
// Check illegal sizes
System.out.println("Testing negative size");
try {
UNSAFE.copyMemory(null, buf, null, buf, -1);
throw new RuntimeException("copyMemory failed to throw IAE for size=-1");
} catch (IllegalArgumentException e) {
// good
}
System.out.println("Testing negative srcOffset");
try {
// Check that negative srcOffset throws an IAE
UNSAFE.copyMemory(arr, -1, arr, UNSAFE.arrayBaseOffset(arr.getClass()), 16);
throw new RuntimeException("copyMemory failed to throw IAE for srcOffset=-1");
} catch (IllegalArgumentException e) {
// good
}
System.out.println("Testing negative destOffset");
try {
// Check that negative dstOffset throws an IAE
UNSAFE.copyMemory(arr, UNSAFE.arrayBaseOffset(arr.getClass()), arr, -1, 16);
throw new RuntimeException("copyMemory failed to throw IAE for destOffset=-1");
} catch (IllegalArgumentException e) {
// good
}
System.out.println("Testing reference array");
try {
// Check that a reference array destination throws IAE
UNSAFE.copyMemory(null, buf, new Object[16], UNSAFE.arrayBaseOffset(Object[].class), 16);
throw new RuntimeException("copyMemory failed to throw IAE");
} catch (IllegalArgumentException e) {
// good
}
// Check that invalid source & dest pointers throw IAEs (only relevant on 32-bit platforms)
if (UNSAFE.addressSize() == 4) {
long invalidPtr = (long)1 << 35; // Pick a random bit in upper 32 bits
try {
// Check that an invalid (not 32-bit clean) source pointer throws IAE
UNSAFE.copyMemory(null, invalidPtr, null, buf, 16);
throw new RuntimeException("copyMemory failed to throw IAE for srcOffset 0x" +
Long.toHexString(invalidPtr));
} catch (IllegalArgumentException e) {
// good
}
try {
// Check that an invalid (not 32-bit clean) source pointer throws IAE
UNSAFE.copyMemory(null, buf, null, invalidPtr, 16);
throw new RuntimeException("copyMemory failed to throw IAE for destOffset 0x" +
Long.toHexString(invalidPtr));
} catch (IllegalArgumentException e) {
// good
}
}
} finally {
if (bufRaw != 0) {
UNSAFE.freeMemory(bufRaw);
}
}
}
/**
* Run all tests
*
* @throws RuntimeException if an error is found
*/
private void test() {
testPositive();
testNegative();
}
public static void main(String[] args) {
CopyMemory cs = new CopyMemory();
cs.test();
}
}

View File

@ -29,507 +29,18 @@ import java.lang.reflect.Field;
* @summary Test Unsafe.copySwapMemory
* @modules java.base/jdk.internal.misc
*/
public class CopySwap {
private static final boolean DEBUG = Boolean.getBoolean("CopySwap.DEBUG");
public static final long KB = 1024;
public static final long MB = KB * 1024;
public static final long GB = MB * 1024;
private static final Unsafe UNSAFE;
private static final int SMALL_COPY_SIZE = 32;
private static final int BASE_ALIGNMENT = 16;
static {
try {
Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
UNSAFE = (jdk.internal.misc.Unsafe) f.get(null);
} catch (Exception e) {
throw new RuntimeException("Unable to get Unsafe instance.", e);
}
}
private static long alignDown(long value, long alignment) {
return value & ~(alignment - 1);
}
private static long alignUp(long value, long alignment) {
return (value + alignment - 1) & ~(alignment - 1);
}
private static boolean isAligned(long value, long alignment) {
return value == alignDown(value, alignment);
}
public class CopySwap extends CopyCommon {
private CopySwap() {
}
/**
* Generate verification data for a given offset
*
* The verification data is used to verify that the correct bytes
* have indeed been copied and byte swapped.
*
* The data is generated based on the offset (in bytes) into the
* source buffer. For a native buffer the offset is relative to
* the base pointer. For a heap array it is relative to the
* address of the first array element.
*
* This method will return the result of doing an elementSize byte
* read starting at offset (in bytes).
*
* @param offset offset into buffer
* @param elemSize size (in bytes) of the element
*
* @return the verification data, only the least significant
* elemSize*8 bits are set, zero extended
*/
private long getVerificationDataForOffset(long offset, long elemSize) {
byte[] bytes = new byte[(int)elemSize];
for (long i = 0; i < elemSize; i++) {
bytes[(int)i] = (byte)(offset + i);
}
long o = UNSAFE.arrayBaseOffset(byte[].class);
switch ((int)elemSize) {
case 1: return Byte.toUnsignedLong(UNSAFE.getByte(bytes, o));
case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(bytes, o));
case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(bytes, o));
case 8: return UNSAFE.getLongUnaligned(bytes, o);
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
}
}
/**
* Verify byte swapped data
*
* @param ptr the data to verify
* @param srcOffset the srcOffset (in bytes) from which the copy started,
* used as key to regenerate the verification data
* @param dstOffset the offset (in bytes) in the array at which to start
* the verification, relative to the first element in the array
* @param size size (in bytes) of data to to verify
* @param elemSize size (in bytes) of the individual array elements
*
* @throws RuntimeException if an error is found
*/
private void verifySwappedData(GenericPointer ptr, long srcOffset, long dstOffset, long size, long elemSize) {
for (long offset = 0; offset < size; offset += elemSize) {
long expectedUnswapped = getVerificationDataForOffset(srcOffset + offset, elemSize);
long expected = byteSwap(expectedUnswapped, elemSize);
long actual = getArrayElem(ptr, dstOffset + offset, elemSize);
if (expected != actual) {
throw new RuntimeException("srcOffset: 0x" + Long.toHexString(srcOffset) +
" dstOffset: 0x" + Long.toHexString(dstOffset) +
" size: 0x" + Long.toHexString(size) +
" offset: 0x" + Long.toHexString(offset) +
" expectedUnswapped: 0x" + Long.toHexString(expectedUnswapped) +
" expected: 0x" + Long.toHexString(expected) +
" != actual: 0x" + Long.toHexString(actual));
}
}
}
/**
* Initialize an array with verification friendly data
*
* @param ptr pointer to the data to initialize
* @param size size (in bytes) of the data
* @param elemSize size (in bytes) of the individual elements
*/
private void initVerificationData(GenericPointer ptr, long size, long elemSize) {
for (long offset = 0; offset < size; offset++) {
byte data = (byte)getVerificationDataForOffset(offset, 1);
if (ptr.isOnHeap()) {
UNSAFE.putByte(ptr.getObject(), ptr.getOffset() + offset, data);
} else {
UNSAFE.putByte(ptr.getOffset() + offset, data);
}
}
}
/**
* Allocate a primitive array
*
* @param size size (in bytes) of all the array elements (elemSize * length)
* @param elemSize the size of the array elements
*
* @return a newly allocated primitive array
*/
Object allocArray(long size, long elemSize) {
int length = (int)(size / elemSize);
switch ((int)elemSize) {
case 2: return new short[length];
case 4: return new int[length];
case 8: return new long[length];
default:
throw new IllegalArgumentException("Invalid element size: " + elemSize);
}
}
/**
* Get the value of a primitive array entry
*
* @param ptr pointer to the data
* @param offset offset (in bytes) of the array element, relative to the first element in the array
*
* @return the array element, as an unsigned long
*/
private long getArrayElem(GenericPointer ptr, long offset, long elemSize) {
if (ptr.isOnHeap()) {
Object o = ptr.getObject();
int index = (int)(offset / elemSize);
if (o instanceof short[]) {
short[] arr = (short[])o;
return Short.toUnsignedLong(arr[index]);
} else if (o instanceof int[]) {
int[] arr = (int[])o;
return Integer.toUnsignedLong(arr[index]);
} else if (o instanceof long[]) {
long[] arr = (long[])o;
return arr[index];
} else {
throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
}
} else {
long addr = ptr.getOffset() + offset;
switch ((int)elemSize) {
case 1: return Byte.toUnsignedLong(UNSAFE.getByte(addr));
case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(null, addr));
case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(null, addr));
case 8: return UNSAFE.getLongUnaligned(null, addr);
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
}
}
}
private void putValue(long addr, long elemSize, long value) {
switch ((int)elemSize) {
case 1: UNSAFE.putByte(addr, (byte)value); break;
case 2: UNSAFE.putShortUnaligned(null, addr, (short)value); break;
case 4: UNSAFE.putIntUnaligned(null, addr, (int)value); break;
case 8: UNSAFE.putLongUnaligned(null, addr, value); break;
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
}
}
/**
* Get the size of the elements for an array
*
* @param o a primitive heap array
*
* @return the size (in bytes) of the individual array elements
*/
private long getArrayElemSize(Object o) {
if (o instanceof short[]) {
return 2;
} else if (o instanceof int[]) {
return 4;
} else if (o instanceof long[]) {
return 8;
} else {
throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
}
}
/**
* Byte swap a value
*
* @param value the value to swap, only the bytes*8 least significant bits are used
* @param size size (in bytes) of the value
*
* @return the byte swapped value in the bytes*8 least significant bits
*/
private long byteSwap(long value, long size) {
switch ((int)size) {
case 2: return Short.toUnsignedLong(Short.reverseBytes((short)value));
case 4: return Integer.toUnsignedLong(Integer.reverseBytes((int)value));
case 8: return Long.reverseBytes(value);
default: throw new IllegalArgumentException("Invalid element size: " + size);
}
}
/**
* Verify data in a heap array which has *not* been byte swapped
*
* @param ptr the data to verify
* @param startOffset the offset (in bytes) at which to start the verification
* @param size size (in bytes) of the data to verify
*
* @throws RuntimeException if an error is found
*/
private void verifyUnswappedData(GenericPointer ptr, long startOffset, long size) {
for (long elemOffset = startOffset; elemOffset < startOffset + size; elemOffset++) {
byte expected = (byte)getVerificationDataForOffset(elemOffset, 1);
byte actual;
if (ptr.isOnHeap()) {
actual = UNSAFE.getByte(ptr.getObject(), ptr.getOffset() + elemOffset);
} else {
actual = UNSAFE.getByte(ptr.getOffset() + elemOffset);
}
if (expected != actual) {
throw new RuntimeException("startOffset: 0x" + Long.toHexString(startOffset) +
" size: 0x" + Long.toHexString(size) +
" elemOffset: 0x" + Long.toHexString(elemOffset) +
" expected: 0x" + Long.toHexString(expected) +
" != actual: 0x" + Long.toHexString(actual));
}
}
}
/**
* Copy and byte swap data from the source to the destination
*
* This method will pre-populate the whole source and destination
* buffers with verification friendly data. It will then use
* copySwapMemory to fill part of the destination buffer with
* swapped data from the source. Some space (padding) will be
* left before and after the data in the destination buffer, which
* should not be touched/overwritten by the copy call.
*
* Note: Both source and destination buffers will be overwritten!
*
* @param src source buffer to copy from
* @param srcOffset the offset (in bytes) in the source buffer, relative to
* the first array element, at which to start reading data
* @param dst destination buffer to copy to
* @param dstOffset the offset (in bytes) in the destination
* buffer, relative to the first array element, at which to
* start writing data
* @param bufSize the size (in bytes) of the src and dst arrays
* @param copyBytes the size (in bytes) of the copy to perform,
* must be a multiple of elemSize
* @param elemSize the size (in bytes) of the elements to byte swap
*
* @throws RuntimeException if an error is found
*/
private void testCopySwap(GenericPointer src, long srcOffset,
GenericPointer dst, long dstOffset,
long bufSize, long copyBytes, long elemSize) {
if (!isAligned(copyBytes, elemSize)) {
throw new IllegalArgumentException(
"copyBytes (" + copyBytes + ") must be a multiple of elemSize (" + elemSize + ")");
}
if (src.isOnHeap() && !isAligned(srcOffset, elemSize)) {
throw new IllegalArgumentException(
"srcOffset (" + srcOffset + ") must be a multiple of elemSize (" + elemSize + ")");
}
if (dst.isOnHeap() && !isAligned(dstOffset, elemSize)) {
throw new IllegalArgumentException(
"dstOffset (" + dstOffset + ") must be a multiple of elemSize (" + elemSize + ")");
}
if (srcOffset + copyBytes > bufSize) {
throw new IllegalArgumentException(
"srcOffset (" + srcOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
}
if (dstOffset + copyBytes > bufSize) {
throw new IllegalArgumentException(
"dstOffset (" + dstOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
}
// Initialize the whole source buffer with a verification friendly pattern (no 0x00 bytes)
initVerificationData(src, bufSize, elemSize);
if (!src.equals(dst)) {
initVerificationData(dst, bufSize, elemSize);
}
if (DEBUG) {
System.out.println("===before===");
for (int offset = 0; offset < bufSize; offset += elemSize) {
long srcValue = getArrayElem(src, offset, elemSize);
long dstValue = getArrayElem(dst, offset, elemSize);
System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
" src=0x" + Long.toHexString(srcValue) +
" dst=0x" + Long.toHexString(dstValue));
}
}
// Copy & swap data into the middle of the destination buffer
UNSAFE.copySwapMemory(src.getObject(),
src.getOffset() + srcOffset,
dst.getObject(),
dst.getOffset() + dstOffset,
copyBytes,
elemSize);
if (DEBUG) {
System.out.println("===after===");
for (int offset = 0; offset < bufSize; offset += elemSize) {
long srcValue = getArrayElem(src, offset, elemSize);
long dstValue = getArrayElem(dst, offset, elemSize);
System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
" src=0x" + Long.toHexString(srcValue) +
" dst=0x" + Long.toHexString(dstValue));
}
}
// Verify the the front padding is unchanged
verifyUnswappedData(dst, 0, dstOffset);
// Verify swapped data
verifySwappedData(dst, srcOffset, dstOffset, copyBytes, elemSize);
// Verify that the back back padding is unchanged
long frontAndDataBytes = dstOffset + copyBytes;
long trailingBytes = bufSize - frontAndDataBytes;
verifyUnswappedData(dst, frontAndDataBytes, trailingBytes);
}
/**
* Test various configurations copy-swapping from one buffer to the other
*
* @param src the source buffer to copy from
* @param dst the destination buffer to copy to
* @param size size (in bytes) of the buffers
* @param elemSize size (in bytes) of the individual elements
*
* @throws RuntimeException if an error is found
*/
public void testBufferPair(GenericPointer src, GenericPointer dst, long size, long elemSize) {
// offset in source from which to start reading data
for (long srcOffset = 0; srcOffset < size; srcOffset += (src.isOnHeap() ? elemSize : 1)) {
// offset in destination at which to start writing data
for (int dstOffset = 0; dstOffset < size; dstOffset += (dst.isOnHeap() ? elemSize : 1)) {
// number of bytes to copy
long maxCopyBytes = Math.min(size - srcOffset, size - dstOffset);
for (long copyBytes = 0; copyBytes < maxCopyBytes; copyBytes += elemSize) {
try {
testCopySwap(src, srcOffset, dst, dstOffset, size, copyBytes, elemSize);
} catch (RuntimeException e) {
// Wrap the exception in another exception to catch the relevant configuration data
throw new RuntimeException("testBufferPair: " +
"src=" + src +
" dst=" + dst +
" elemSize=0x" + Long.toHexString(elemSize) +
" copyBytes=0x" + Long.toHexString(copyBytes) +
" srcOffset=0x" + Long.toHexString(srcOffset) +
" dstOffset=0x" + Long.toHexString(dstOffset),
e);
}
}
}
}
}
/**
* Test copying between various permutations of buffers
*
* @param buffers buffers to permute (src x dst)
* @param size size (in bytes) of buffers
* @param elemSize size (in bytes) of individual elements
*
* @throws RuntimeException if an error is found
*/
public void testPermuteBuffers(GenericPointer[] buffers, long size, long elemSize) {
for (int srcIndex = 0; srcIndex < buffers.length; srcIndex++) {
for (int dstIndex = 0; dstIndex < buffers.length; dstIndex++) {
testBufferPair(buffers[srcIndex], buffers[dstIndex], size, elemSize);
}
}
}
/**
* Test copying of a specific element size
*
* @param size size (in bytes) of buffers to allocate
* @param elemSize size (in bytes) of individual elements
*
* @throws RuntimeException if an error is found
*/
private void testElemSize(long size, long elemSize) {
long buf1Raw = 0;
long buf2Raw = 0;
try {
buf1Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
long buf1 = alignUp(buf1Raw, BASE_ALIGNMENT);
buf2Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
long buf2 = alignUp(buf2Raw, BASE_ALIGNMENT);
GenericPointer[] buffers = {
new GenericPointer(buf1),
new GenericPointer(buf2),
new GenericPointer(allocArray(size, elemSize)),
new GenericPointer(allocArray(size, elemSize))
};
testPermuteBuffers(buffers, size, elemSize);
} finally {
if (buf1Raw != 0) {
UNSAFE.freeMemory(buf1Raw);
}
if (buf2Raw != 0) {
UNSAFE.freeMemory(buf2Raw);
}
}
}
/**
* Verify that small copy swaps work
*/
private void testSmallCopy() {
int smallBufSize = SMALL_COPY_SIZE;
// Test various element types and heap/native combinations
for (long elemSize = 2; elemSize <= 8; elemSize <<= 1) {
testElemSize(smallBufSize, elemSize);
}
}
/**
* Verify that large copy swaps work
*/
private void testLargeCopy() {
long size = 2 * GB + 8;
long bufRaw = 0;
// Check that a large native copy succeeds
try {
try {
bufRaw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
} catch (OutOfMemoryError e) {
// Accept failure, skip test
return;
}
long buf = alignUp(bufRaw, BASE_ALIGNMENT);
UNSAFE.copySwapMemory(null, buf, null, buf, size, 8);
} catch (Exception e) {
throw new RuntimeException("copySwapMemory of large buffer failed");
} finally {
if (bufRaw != 0) {
UNSAFE.freeMemory(bufRaw);
}
}
}
/**
* Run positive tests
*
* @throws RuntimeException if an error is found
*/
private void testPositive() {
testSmallCopy();
testLargeCopy();
testSmallCopy(true);
testLargeCopy(true);
}
/**
@ -542,7 +53,7 @@ public class CopySwap {
try {
bufRaw = UNSAFE.allocateMemory(1024);
long buf = alignUp(bufRaw, BASE_ALIGNMENT);
long buf = CopyCommon.alignUp(bufRaw, CopyCommon.BASE_ALIGNMENT);
short[] arr = new short[16];
// Check various illegal element sizes
@ -586,22 +97,6 @@ public class CopySwap {
}
}
try {
// Check that a NULL source throws NPE
UNSAFE.copySwapMemory(null, 0, null, buf, 16, 2);
throw new RuntimeException("copySwapMemory failed to throw NPE");
} catch (NullPointerException e) {
// good
}
try {
// Check that a NULL destination throws NPE
UNSAFE.copySwapMemory(null, buf, null, 0, 16, 2);
throw new RuntimeException("copySwapMemory failed to throw NPE");
} catch (NullPointerException e) {
// good
}
try {
// Check that a reference array destination throws IAE
UNSAFE.copySwapMemory(null, buf, new Object[16], UNSAFE.arrayBaseOffset(Object[].class), 16, 8);
@ -653,59 +148,4 @@ public class CopySwap {
CopySwap cs = new CopySwap();
cs.test();
}
/**
* Helper class to represent a "pointer" - either a heap array or
* a pointer to a native buffer.
*
* In the case of a native pointer, the Object is null and the offset is
* the absolute address of the native buffer.
*
* In the case of a heap object, the Object is a primitive array, and
* the offset will be set to the base offset to the first element, meaning
* the object and the offset together form a double-register pointer.
*/
static class GenericPointer {
private final Object o;
private final long offset;
private GenericPointer(Object o, long offset) {
this.o = o;
this.offset = offset;
}
public String toString() {
return "GenericPointer(o={" + o + "}, offset=0x" + Long.toHexString(offset) + ")";
}
public boolean equals(Object other) {
if (!(other instanceof GenericPointer)) {
return false;
}
GenericPointer otherp = (GenericPointer)other;
return o == otherp.o && offset == otherp.offset;
}
GenericPointer(Object o) {
this(o, UNSAFE.arrayBaseOffset(o.getClass()));
}
GenericPointer(long offset) {
this(null, offset);
}
public boolean isOnHeap() {
return o != null;
}
public Object getObject() {
return o;
}
public long getOffset() {
return offset;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, 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
@ -24,7 +24,7 @@
/*
* @test
* @summary Unit test for sun.net.idn.Punycode
* @bug 4737170
* @bug 4737170 8060097
* @modules java.base/sun.net.idn java.base/sun.text.normalizer
* @library .
* @compile -XDignore.symbol.file TestStringPrep.java NFS4StringPrep.java
@ -41,6 +41,7 @@
import java.text.ParseException;
import java.io.InputStream;
import java.util.Locale;
import sun.net.idn.StringPrep;
import sun.text.normalizer.UCharacterIterator;
@ -209,7 +210,7 @@ public class TestStringPrep {
src = "THISISATEST";
byte[] dest = NFS4StringPrep.cs_prepare(src.getBytes("UTF-8"), false);
String destStr = new String(dest, "UTF-8");
if(!src.toLowerCase().equals(destStr)){
if(!src.toLowerCase(Locale.ROOT).equals(destStr)){
fail("Did not get expected output. Expected: "+ prettify(src)+
" Got: " + prettify(destStr));
}
@ -275,7 +276,7 @@ public class TestStringPrep {
private static String hex(char ch) {
StringBuffer result = new StringBuffer();
String foo = Integer.toString(ch,16).toUpperCase();
String foo = Integer.toString(ch,16).toUpperCase(Locale.ROOT);
for (int i = foo.length(); i < 4; ++i) {
result.append('0');
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, 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
@ -21,55 +21,52 @@
* questions.
*/
/**
* @test
* @bug 8076359 8133151
* @summary Test for jdk.security.provider.preferred security property
* @requires os.name == "SunOS"
* @run main/othervm PreferredProviderNegativeTest preJCESet AES:OracleUcrypto false
* @run main/othervm PreferredProviderNegativeTest preJCESet AES:SunNegative true
* @run main/othervm PreferredProviderNegativeTest afterJCESet AES:SunJGSS
* @run main/othervm PreferredProviderNegativeTest afterJCESet AES:SunECNegative
* @run main/othervm PreferredProviderNegativeTest invalidAlg AESNegative:SunJCE
*/
import java.security.Security;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
/**
* @test
* @bug 8076359 8133151 8150512
* @summary Test for jdk.security.provider.preferred security property
* @run main/othervm PreferredProviderNegativeTest preSet AES false
* @run main/othervm PreferredProviderNegativeTest preSet AES:SunNegative true
* @run main/othervm PreferredProviderNegativeTest afterSet AES:SunJGSS
* @run main/othervm PreferredProviderNegativeTest afterSet AES:SunECNegative
* @run main/othervm PreferredProviderNegativeTest invalidAlg AESInvalid:SunJCE
*/
public class PreferredProviderNegativeTest {
static final String SEC_PREF_PROP = "jdk.security.provider.preferred";
/*
* Test security property could be set by valid and invalid provider
* before JCE was loaded
*/
public static void preJCESet(String value, boolean negativeProvider)
throws NoSuchAlgorithmException, NoSuchPaddingException {
Security.setProperty("jdk.security.provider.preferred", value);
if (!Security.getProperty("jdk.security.provider.preferred")
.equals(value)) {
throw new RuntimeException(
"Test Failed:The property wasn't set");
Security.setProperty(SEC_PREF_PROP, value);
if (!Security.getProperty(SEC_PREF_PROP).equals(value)) {
throw new RuntimeException("Test Failed:The property wasn't set");
}
String[] arrays = value.split(":");
Cipher cipher = Cipher.getInstance(arrays[0]);
if (negativeProvider) {
if (cipher.getProvider().getName().equals(arrays[1])) {
throw new RuntimeException(
"Test Failed:The provider shouldn't be set");
"Test Failed:The provider shouldn't be set.");
}
} else {
if (!cipher.getProvider().getName().equals(arrays[1])) {
throw new RuntimeException(
"Test Faild:The provider could be set "
+ "by valid provider ");
throw new RuntimeException("Test Faild:The provider could be "
+ "set by valid provider.");
}
}
System.out.println("Test Pass");
System.out.println("Test Pass.");
}
/*
@ -81,10 +78,10 @@ public class PreferredProviderNegativeTest {
String[] arrays = value.split(":");
Cipher cipher = Cipher.getInstance(arrays[0]);
Security.setProperty("jdk.security.provider.preferred", value);
Security.setProperty(SEC_PREF_PROP, value);
if (!cipher.getProvider().getName().equals("SunJCE")) {
throw new RuntimeException(
"Test Failed:The security property can't be updated after JCE load.");
throw new RuntimeException("Test Failed:The security property can't"
+ " be updated after JCE load.");
}
System.out.println("Test Pass");
}
@ -94,10 +91,11 @@ public class PreferredProviderNegativeTest {
String[] arrays = value.split(":");
try {
Security.setProperty("jdk.security.provider.preferred", value);
Security.setProperty(SEC_PREF_PROP, value);
Cipher.getInstance(arrays[0]);
} catch (NoSuchAlgorithmException e) {
System.out.println("Test Pass:Got NoSuchAlgorithmException as expired");
System.out.println(
"Test Pass:Got NoSuchAlgorithmException as expired");
return;
}
throw new RuntimeException(
@ -106,15 +104,25 @@ public class PreferredProviderNegativeTest {
public static void main(String[] args)
throws NoSuchAlgorithmException, NoSuchPaddingException {
boolean negativeProvider;
if (args.length >= 2) {
switch (args[0]) {
case "preJCESet":
negativeProvider = Boolean.valueOf(args[2]);
PreferredProviderNegativeTest.preJCESet(args[1], negativeProvider);
case "preSet":
boolean negativeProvider = Boolean.valueOf(args[2]);
boolean solaris = System.getProperty("os.name")
.toLowerCase().contains("sun");
String value = args[1];
if (args[1].split(":").length < 2) {
if (solaris) {
value += ":OracleUcrypto";
} else {
value += ":SunJCE";
}
}
PreferredProviderNegativeTest.preJCESet(
value, negativeProvider);
break;
case "afterJCESet":
case "afterSet":
PreferredProviderNegativeTest.afterJCESet(args[1]);
break;
case "invalidAlg":
@ -127,4 +135,3 @@ public class PreferredProviderNegativeTest {
}
}
}

View File

@ -21,97 +21,131 @@
* questions.
*/
/**
* @test
* @bug 8076359 8133151 8145344
* @summary Test the value for new jdk.security.provider.preferred security property
* @requires os.name == "SunOS"
*/
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.Provider;
import java.util.Arrays;
import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
/**
* @test
* @bug 8076359 8133151 8145344 8150512
* @summary Test the value for new jdk.security.provider.preferred
* security property
*/
public class PreferredProviderTest {
private static final List<DataTuple> SPARC_DATA = Arrays.asList(
new DataTuple("SHA1", "SUN"), new DataTuple("SHA-1", "SUN"),
new DataTuple("SHA-224", "SUN"), new DataTuple("SHA-256", "SUN"),
new DataTuple("SHA-384", "SUN"), new DataTuple("SHA-512", "SUN"));
private static final List<DataTuple> X86_DATA = Arrays
.asList(new DataTuple("RSA", "SunRsaSign"));
public void RunTest(String type)
public void RunTest(String type, String os)
throws NoSuchAlgorithmException, NoSuchPaddingException {
String preferredProvider = Security
.getProperty("jdk.security.provider.preferred");
String actualProvider = null;
if (type.equals("sparcv9")) {
if (!preferredProvider.equals(
"AES:SunJCE, SHA1:SUN, SHA-224:SUN, SHA-256:SUN, SHA-384:SUN, SHA-512:SUN")) {
throw new RuntimeException(
"Test Failed: wrong jdk.security.provider.preferred "
+ "value on solaris-sparcv9");
}
for (DataTuple dataTuple : SPARC_DATA) {
MessageDigest md = MessageDigest
.getInstance(dataTuple.algorithm);
actualProvider = md.getProvider().getName();
if (!actualProvider.equals(dataTuple.provider)) {
throw new RuntimeException(String.format(
"Test Failed:Got wrong "
+ "provider from Solaris-sparcv9 platform,"
+ "Expected Provider: %s, Returned Provider: %s",
dataTuple.provider, actualProvider));
}
}
} else if (type.equals("amd64")) {
if (!preferredProvider.equals("AES:SunJCE, RSA:SunRsaSign")) {
throw new RuntimeException(
"Test Failed: wrong jdk.security.provider.preferred "
+ "value on solaris-x86");
}
for (DataTuple dataTuple : X86_DATA) {
KeyFactory keyFactory = KeyFactory
.getInstance(dataTuple.algorithm);
actualProvider = keyFactory.getProvider().getName();
if (!actualProvider.equals(dataTuple.provider)) {
throw new RuntimeException(String.format(
"Test Failed:Got wrong "
+ "provider from Solaris-x86 platform,"
+ "Expected Provider: %s, Returned Provider: %s",
dataTuple.provider, actualProvider));
}
}
boolean solaris = os.contains("sun");
String preferredProp
= "AES/GCM/NoPadding:SunJCE, MessageDigest.SHA-256:SUN";
System.out.printf("%nExecuting test for the platform '%s'%n", os);
if (!solaris) {
//For other platform it will try to set the preferred algorithm and
//Provider and verify the usage of it.
Security.setProperty(
"jdk.security.provider.preferred", preferredProp);
verifyPreferredProviderProperty(os, type, preferredProp);
verifyDigestProvider(os, type, Arrays.asList(
new DataTuple("SHA-256", "SUN")));
} else {
throw new RuntimeException("Test Failed: wrong platform value");
//For solaris the preferred algorithm/provider is already set in
//java.security file which will be verified.
switch (type) {
case "sparcv9":
preferredProp = "AES:SunJCE, SHA1:SUN, SHA-224:SUN,"
+ " SHA-256:SUN, SHA-384:SUN, SHA-512:SUN";
verifyPreferredProviderProperty(os, type, preferredProp);
verifyDigestProvider(os, type, Arrays.asList(
new DataTuple("SHA1", "SUN"),
new DataTuple("SHA-1", "SUN"),
new DataTuple("SHA-224", "SUN"),
new DataTuple("SHA-256", "SUN"),
new DataTuple("SHA-384", "SUN"),
new DataTuple("SHA-512", "SUN")));
break;
case "amd64":
preferredProp = "AES:SunJCE, RSA:SunRsaSign";
verifyPreferredProviderProperty(os, type, preferredProp);
verifyKeyFactoryProvider(os, type, Arrays.asList(
new DataTuple("RSA", "SunRsaSign")));
break;
}
verifyDigestProvider(os, type, Arrays.asList(
new DataTuple("MD5", "OracleUcrypto")));
}
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
actualProvider = cipher.getProvider().getName();
if (!actualProvider.equals("SunJCE")) {
throw new RuntimeException(String.format(
"Test Failed:Got wrong provider from Solaris-%s platform, "
+ "Expected Provider: SunJCE, Returned Provider: %s",
type, actualProvider));
throw new RuntimeException(String.format("Test Failed:Got wrong "
+ "provider from %s-%s platform, Expected Provider: SunJCE,"
+ " Returned Provider: %s", os, type, actualProvider));
}
}
MessageDigest md = MessageDigest.getInstance("MD5");
actualProvider = md.getProvider().getName();
if (!actualProvider.equals("OracleUcrypto")) {
private static void verifyPreferredProviderProperty(String os, String arch,
String preferred) {
String preferredProvider
= Security.getProperty("jdk.security.provider.preferred");
if (!preferredProvider.equals(preferred)) {
throw new RuntimeException(String.format(
"Test Failed:Got wrong provider from Solaris-%s platform,"
+ "Expected Provider: OracleUcrypto, Returned Provider: %s",
type, actualProvider));
"Test Failed: wrong jdk.security.provider.preferred value "
+ "on %s-%s", os, arch));
}
System.out.println(
"Preferred provider security property verification complete.");
}
private static void verifyDigestProvider(String os, String arch,
List<DataTuple> algoProviders) throws NoSuchAlgorithmException {
for (DataTuple dataTuple : algoProviders) {
System.out.printf(
"Verifying MessageDigest for '%s'%n", dataTuple.algorithm);
MessageDigest md = MessageDigest.getInstance(dataTuple.algorithm);
matchProvider(md.getProvider(), dataTuple.provider,
dataTuple.algorithm, os, arch);
}
System.out.println(
"Preferred MessageDigest algorithm verification successful.");
}
private static void verifyKeyFactoryProvider(String os, String arch,
List<DataTuple> algoProviders) throws NoSuchAlgorithmException {
for (DataTuple dataTuple : algoProviders) {
System.out.printf(
"Verifying KeyFactory for '%s'%n", dataTuple.algorithm);
KeyFactory kf = KeyFactory.getInstance(dataTuple.algorithm);
matchProvider(kf.getProvider(), dataTuple.provider,
dataTuple.algorithm, os, arch);
}
System.out.println(
"Preferred KeyFactory algorithm verification successful.");
}
private static void matchProvider(Provider provider, String expected,
String algo, String os, String arch) {
if (!provider.getName().equals(expected)) {
throw new RuntimeException(String.format(
"Test Failed:Got wrong provider from %s-%s platform, "
+ "for algorithm %s. Expected Provider: %s,"
+ " Returned Provider: %s", os, arch, algo,
expected, provider.getName()));
}
}
private static class DataTuple {
private final String provider;
private final String algorithm;
@ -123,10 +157,9 @@ public class PreferredProviderTest {
public static void main(String[] args)
throws NoSuchAlgorithmException, NoSuchPaddingException {
String arch = System.getProperty("os.arch");
String os = System.getProperty("os.name").toLowerCase();
String arch = System.getProperty("os.arch").toLowerCase();
PreferredProviderTest pp = new PreferredProviderTest();
pp.RunTest(arch);
pp.RunTest(arch, os);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2016, 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
@ -24,6 +24,7 @@
/*
* @test
* @bug 6844193
* @key intermittent
* @compile -XDignore.symbol.file MaxRetries.java
* @run main/othervm/timeout=300 MaxRetries
* @summary support max_retries in krb5.conf

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016, 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
@ -24,6 +24,7 @@
/*
* @test
* @bug 7162687
* @key intermittent
* @summary enhance KDC server availability detection
* @compile -XDignore.symbol.file Unreachable.java
* @run main/othervm/timeout=10 Unreachable

View File

@ -32,6 +32,7 @@ import java.security.interfaces.RSAPrivateCrtKey;
/*
* @test
* @bug 8023546
* @key intermittent
* @modules java.base/sun.security.x509
* java.base/sun.security.tools.keytool
* @summary sun/security/mscapi/ShortRSAKey1024.sh fails intermittently

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
//
// SunJSSE does not support dynamic system properties, no way to re-use
// system properties in samevm/agentvm mode.
//
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/*
* @test
* @bug 8149169
* @summary Test for BufferOverflowException during read from SSLSocket when
* large packet is coming from server after server initiated handshake
* @run main/othervm LargePacketAfterHandshakeTest
*/
public class LargePacketAfterHandshakeTest {
static String pathToStores = "../../../../javax/net/ssl/etc";
static String keyStoreFile = "keystore";
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
volatile static int serverport = -1;
volatile static boolean serverReady = false;
volatile static boolean clientDone = false;
volatile static Exception serverException = null;
public static void runServer() {
try {
System.out.println("Server: Started server thread.");
SSLServerSocketFactory ssf =
(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLServerSocket s = (SSLServerSocket)ssf.createServerSocket(0);
serverport = s.getLocalPort();
System.out.println("Server: Started, listening on port " +
serverport + ".");
serverReady = true;
SSLSocket c = (SSLSocket)s.accept();
s.close();
System.out.println(
"Server: Accepted client connection and closed server socket.");
BufferedReader r = new BufferedReader(
new InputStreamReader(c.getInputStream()));
BufferedWriter w = new BufferedWriter(
new OutputStreamWriter(c.getOutputStream()));
String echostring = r.readLine();
System.out.println("Server: Read " + echostring.length() +
" chars of input data.");
c.startHandshake();
System.out.println("Server: Kicked new handshake.");
w.write(echostring);
w.newLine();
w.flush();
System.out.println("Server: Echoed " + echostring.length() +
" chars of input data.");
while (!clientDone) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println("Server: Caught InterruptedException.");
}
}
r.close();
w.close();
c.close();
System.out.println(
"Server: Closed streams and client socket, exiting.");
} catch (Exception e) {
System.out.println("Server: Caught Exception.");
e.printStackTrace();
serverReady = true;
serverException = e;
}
}
public static void runClient() throws IOException {
try {
SSLSocketFactory f =
(SSLSocketFactory)SSLSocketFactory.getDefault();
System.out.println("Client: Initialized.");
while (!serverReady) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println("Client: Caught InterruptedException.");
}
}
SSLSocket c = (SSLSocket)f.createSocket("localhost", serverport);
BufferedWriter w = new BufferedWriter(
new OutputStreamWriter(c.getOutputStream()));
BufferedReader r = new BufferedReader(
new InputStreamReader(c.getInputStream()));
System.out.println("Client: Connected.");
String echoPattern = "Otto";
StringBuilder echoBuilder =
new StringBuilder(4500 + echoPattern.length());
while (echoBuilder.length() < 4500) {
echoBuilder.append(echoPattern);
}
String echostring = echoBuilder.toString();
w.write(echostring);
w.newLine();
w.flush();
System.out.println("Client: Sent " + echostring.length() +
" chars of data.");
String echoresponse = r.readLine();
clientDone = true;
System.out.println("Client: Read " + echoresponse.length() +
" chars of data.");
w.close();
r.close();
c.close();
System.out.println("Client: Closed streams and socket, exiting.");
} catch (IOException e) {
System.out.println("Client: Caught Exception.");
e.printStackTrace();
clientDone = true;
throw e;
}
}
public static void main(String[] args) throws Exception {
String keyFilename = System.getProperty("test.src", "./") + "/" +
pathToStores + "/" + keyStoreFile;
String trustFilename = System.getProperty("test.src", "./") + "/" +
pathToStores + "/" + trustStoreFile;
System.setProperty("javax.net.ssl.keyStore", keyFilename);
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
Thread serverThread = new Thread() {
@Override
public void run() {
runServer();
}
};
serverThread.start();
runClient();
while (serverThread.isAlive()) {
try {
serverThread.join();
} catch (InterruptedException e) {
System.out.println("Main: Caught InterruptedException " +
" waiting for server Thread.");
}
}
if (serverException != null) {
throw serverException;
}
}
}

View File

@ -21,26 +21,18 @@
* questions.
*/
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Layer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.TaskHelper;
import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
import tests.Helper;
import tests.JImageGenerator;
import tests.JImageValidator;
import tests.Result;
/*
* @test
@ -50,6 +42,7 @@ import tests.JImageValidator;
* @modules java.base/jdk.internal.jimage
* jdk.jdeps/com.sun.tools.classfile
* jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink.internal.plugins
* jdk.jlink/jdk.tools.jmod
* jdk.jlink/jdk.tools.jimage
* jdk.compiler
@ -65,6 +58,7 @@ public class IncludeLocalesPluginTest {
private final static int EXPECTED_LOCATIONS = 1;
private final static int UNEXPECTED_PATHS = 2;
private final static int AVAILABLE_LOCALES = 3;
private final static int ERROR_MESSAGE = 4;
private final static Object[][] testData = {
// without --include-locales option: should include all locales
@ -144,6 +138,7 @@ public class IncludeLocalesPluginTest {
"yav_CM yo yo_BJ yo_NG zgh zgh_MA zh zh_CN zh_CN_#Hans zh_HK " +
"zh_HK_#Hans zh_HK_#Hant zh_MO_#Hans zh_MO_#Hant zh_SG zh_SG_#Hans " +
"zh_TW zh_TW_#Hant zh__#Hans zh__#Hant zu zu_ZA",
"",
},
// All English/Japanese locales
@ -173,6 +168,7 @@ public class IncludeLocalesPluginTest {
"en_PW en_RW en_SB en_SC en_SD en_SG en_SH en_SL en_SS en_SX en_SZ " +
"en_TC en_TK en_TO en_TT en_TV en_TZ en_UG en_UM en_US en_US_POSIX " +
"en_VC en_VG en_VI en_VU en_WS en_ZA en_ZM en_ZW ja ja_JP ja_JP_JP_#u-ca-japanese",
"",
},
// All locales in India
@ -201,6 +197,7 @@ public class IncludeLocalesPluginTest {
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"),
" as_IN bn_IN bo_IN brx_IN en en_IN en_US en_US_POSIX gu_IN hi_IN kn_IN " +
"kok_IN ks_IN_#Arab ml_IN mr_IN ne_IN or_IN pa_IN_#Guru ta_IN te_IN ur_IN",
"",
},
// Thai
@ -220,6 +217,7 @@ public class IncludeLocalesPluginTest {
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"),
" en en_US en_US_POSIX th th_TH th_TH_TH_#u-nu-thai",
"",
},
// Hong Kong
@ -242,6 +240,7 @@ public class IncludeLocalesPluginTest {
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
" en en_US en_US_POSIX zh_HK zh_HK_#Hans zh_HK_#Hant",
"",
},
// Norwegian
@ -265,6 +264,7 @@ public class IncludeLocalesPluginTest {
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
" en en_US en_US_POSIX nb nb_NO nb_SJ nn nn_NO no no_NO no_NO_NY",
"",
},
// Hebrew/Indonesian/Yiddish
@ -290,6 +290,25 @@ public class IncludeLocalesPluginTest {
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
" en en_US en_US_POSIX in in_ID iw iw_IL ji ji_001",
"",
},
// Error case: No matching locales
{"--include-locales=xyz",
null,
null,
null,
new PluginException(
PluginsResourceBundle.getMessage("include-locales.nomatchinglocales"))
.toString(),
},
// Error case: Invalid argument
{"--include-locales=zh_HK",
null,
null,
null,
"range=zh_hk",
},
};
@ -304,12 +323,16 @@ public class IncludeLocalesPluginTest {
for (Object[] data : testData) {
// create image for each test data
Path image = JImageGenerator.getJLinkTask()
Result result = JImageGenerator.getJLinkTask()
.modulePath(helper.defaultModulePath())
.output(helper.createNewImageDir(moduleName))
.addMods("jdk.localedata")
.option((String)data[INCLUDE_LOCALES_OPTION])
.call().assertSuccess();
.call();
String errorMsg = (String)data[ERROR_MESSAGE];
if (errorMsg.isEmpty()) {
Path image = result.assertSuccess();
// test locale data entries
testLocaleDataEntries(image,
@ -318,6 +341,10 @@ public class IncludeLocalesPluginTest {
// test available locales
testAvailableLocales(image, (String)data[AVAILABLE_LOCALES]);
} else {
result.assertFailure(new TaskHelper(TaskHelper.JLINK_BUNDLE)
.getMessage("error.prefix") + " " +errorMsg);
}
}
}