This commit is contained in:
Lana Steuck 2016-03-15 14:49:37 -07:00
commit 673bacafd2
54 changed files with 3762 additions and 543 deletions

View File

@ -99,13 +99,16 @@ public class MethodHandles {
* <p>
* As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
* of this lookup object will be {@link java.lang.Object}.
* 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)}.
* Since all classes have equal access to public names,
* such a change would confer no new access rights.
* such a change would confer no new access rights,
* 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
@ -641,6 +644,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
@ -939,13 +947,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
@ -960,6 +972,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

@ -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

@ -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,
Object destBase, long destOffset,
long bytes);
public void copyMemory(Object srcBase, long srcOffset,
Object destBase, long destOffset,
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,15 +751,22 @@ public final class Unsafe {
copyMemory(null, srcAddress, null, destAddress, bytes);
}
private boolean isPrimitiveArray(Class<?> c) {
Class<?> componentType = c.getComponentType();
return componentType != null && componentType.isPrimitive();
/**
* 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) {
checkSize(bytes);
checkPrimitivePointer(srcBase, srcOffset);
checkPrimitivePointer(destBase, destOffset);
}
private native void copySwapMemory0(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long bytes, long elemSize);
/**
* Copies all elements from one block of memory to another block,
* *unconditionally* byte swapping the elements on the fly.
@ -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
@ -546,7 +877,7 @@ public final class Unsafe {
* {@link #staticFieldOffset}, {@link #objectFieldOffset},
* or {@link #arrayBaseOffset}.
*/
public static final int INVALID_FIELD_OFFSET = -1;
public static final int INVALID_FIELD_OFFSET = -1;
/**
* Reports the location of a given field in the storage allocation of its
@ -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,9 +1112,22 @@ 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,
ClassLoader loader,
ProtectionDomain protectionDomain);
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);
/**
* Defines a class but does not make it known to the class loader or system dictionary.
@ -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,11 +2735,13 @@ class MethodWriter extends MethodVisitor {
l = l.successor;
}
// Update the offsets in the uninitialized types
for (i = 0; i < cw.typeTable.length; ++i) {
Item item = cw.typeTable[i];
if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
item.intVal = getNewOffset(allIndexes, allSizes, 0,
item.intVal);
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) {
item.intVal = getNewOffset(allIndexes, allSizes, 0,
item.intVal);
}
}
}
// The stack map frames are not serialized yet, so we don't need

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

@ -388,10 +388,10 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
}
break;
case PUTFIELD:
popValue();
popValue();
if (longOrDouble) {
popValue();
popValue();
}
break;
// case GETFIELD:
@ -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);
buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
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);
buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
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) 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 \

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

@ -0,0 +1,38 @@
/*
* 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.
*/
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(); }
}

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,68 @@
/*
* 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();
assertNull(lookup.lookupClass().getClassLoader());
Lookup lookup2 = lookup.in(TestCls.class);
assertNotNull(lookup2.lookupClass().getClassLoader());
}
}

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

@ -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

@ -0,0 +1,667 @@
/*
* 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 {
private static final boolean DEBUG = Boolean.getBoolean("CopyMemory.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);
}
private CopyMemory() {
}
/**
* 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 use
* copypMemory to fill part of the destination buffer with
* 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
*
* @throws RuntimeException if an error is found
*/
private void testCopy(GenericPointer src, long srcOffset,
GenericPointer dst, long dstOffset,
long bufSize, long copyBytes) {
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, 1);
if (!src.equals(dst)) {
initVerificationData(dst, bufSize, 1);
}
if (DEBUG) {
System.out.println("===before===");
for (int offset = 0; offset < bufSize; offset++) {
long srcValue = getArrayElem(src, offset, 1);
long dstValue = getArrayElem(dst, offset, 1);
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.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++) {
long srcValue = getArrayElem(src, offset, 1);
long dstValue = getArrayElem(dst, offset, 1);
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);
// Verify copied data
verifyUnswappedData(dst, dstOffset, srcOffset, copyBytes);
// Verify that the back back padding is unchanged
long frontAndDataBytes = dstOffset + copyBytes;
long trailingBytes = bufSize - frontAndDataBytes;
verifyUnswappedData(dst, frontAndDataBytes, frontAndDataBytes, trailingBytes);
}
/**
* Test various configurations copying 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 {
testCopy(src, srcOffset, dst, dstOffset, size, copyBytes);
} 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 copies work
*/
private void testSmallCopy() {
int smallBufSize = SMALL_COPY_SIZE;
testElemSize(smallBufSize, 1);
}
/**
* Verify that large copies 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.copyMemory(null, buf, null, buf, size);
} catch (Exception e) {
throw new RuntimeException("copyMemory 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();
}
/**
* 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 = alignUp(bufRaw, 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();
}
/**
* 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

@ -586,22 +586,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);

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