--- a/.hgtags Fri Sep 16 10:57:21 2016 -0700
+++ b/.hgtags Wed Sep 21 09:29:30 2016 -0700
@@ -378,3 +378,4 @@
e17429a7e843c4a4ed3651458d0f950970edcbcc jdk-9+133
a71210c0d9800eb6925b61ecd6198abd554f90ee jdk-9+134
e384420383a5b79fa0012ebcb25d8f83cff7f777 jdk-9+135
+1b4b5d01aa11edf24b6fadbe3d2f3e411e3b02cd jdk-9+136
--- a/.hgtags-top-repo Fri Sep 16 10:57:21 2016 -0700
+++ b/.hgtags-top-repo Wed Sep 21 09:29:30 2016 -0700
@@ -378,3 +378,4 @@
be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133
065724348690eda41fc69112278d8da6dcde548c jdk-9+134
82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135
+3ec350f5f32af249b59620d7e37b54bdcd77b233 jdk-9+136
--- a/corba/.hgtags Fri Sep 16 10:57:21 2016 -0700
+++ b/corba/.hgtags Wed Sep 21 09:29:30 2016 -0700
@@ -378,3 +378,4 @@
2021bfedf1c478a4808a7711a6090682a12f4c0e jdk-9+133
1a497f5ca0cfd88115cc7daa8af8a62b8741caf2 jdk-9+134
094d0db606db976045f594dba47d4593b715cc81 jdk-9+135
+aa053a3faf266c12b4fd5272da431a3e08e4a3e3 jdk-9+136
--- a/hotspot/.hgtags Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/.hgtags Wed Sep 21 09:29:30 2016 -0700
@@ -538,3 +538,4 @@
a25e0fb6033245ab075136e744d362ce765464cd jdk-9+133
b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134
3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135
+a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136
--- a/hotspot/make/symbols/symbols-unix Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/make/symbols/symbols-unix Wed Sep 21 09:29:30 2016 -0700
@@ -67,6 +67,7 @@
JVM_FreeMemory
JVM_GC
JVM_GetAllThreads
+JVM_GetAndClearReferencePendingList
JVM_GetArrayElement
JVM_GetArrayLength
JVM_GetCallerClass
@@ -130,6 +131,7 @@
JVM_GetTemporaryDirectory
JVM_GetVmArguments
JVM_Halt
+JVM_HasReferencePendingList
JVM_HoldsLock
JVM_IHashCode
JVM_InitProperties
@@ -179,6 +181,7 @@
JVM_ToStackTraceElement
JVM_TotalMemory
JVM_UnloadLibrary
+JVM_WaitForReferencePendingList
JVM_Yield
# Module related API's
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -65,10 +65,10 @@
#ifdef AMD64
// Very large C++ stack frames using solaris-amd64 optimized builds
// due to lack of optimization caused by C++ compiler bugs
-#define DEFAULT_STACK_SHADOW_PAGES (NOT_WIN64(20) WIN64_ONLY(6) DEBUG_ONLY(+2))
+#define DEFAULT_STACK_SHADOW_PAGES (NOT_WIN64(20) WIN64_ONLY(7) DEBUG_ONLY(+2))
// For those clients that do not use write socket, we allow
// the min range value to be below that of the default
-#define MIN_STACK_SHADOW_PAGES (NOT_WIN64(10) WIN64_ONLY(6) DEBUG_ONLY(+2))
+#define MIN_STACK_SHADOW_PAGES (NOT_WIN64(10) WIN64_ONLY(7) DEBUG_ONLY(+2))
#else
#define DEFAULT_STACK_SHADOW_PAGES (4 DEBUG_ONLY(+5))
#define MIN_STACK_SHADOW_PAGES DEFAULT_STACK_SHADOW_PAGES
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java Wed Sep 21 09:29:30 2016 -0700
@@ -24,6 +24,7 @@
package sun.jvm.hotspot.gc.g1;
+import java.io.PrintStream;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
@@ -125,6 +126,15 @@
return CollectedHeapName.G1_COLLECTED_HEAP;
}
+ @Override
+ public void printOn(PrintStream tty) {
+ MemRegion mr = reservedRegion();
+
+ tty.print("garbage-first heap");
+ tty.print(" [" + mr.start() + ", " + mr.end() + "]");
+ tty.println(" region size " + (HeapRegion.grainBytes() / 1024) + "K");
+ }
+
public G1CollectedHeap(Address addr) {
super(addr);
}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodData.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodData.java Wed Sep 21 09:29:30 2016 -0700
@@ -36,6 +36,7 @@
public class MethodData extends Metadata implements MethodDataInterface<Klass,Method> {
static int TypeProfileWidth = 2;
static int BciProfileWidth = 2;
+ static int MethodProfileWidth = 0;
static int CompileThreshold;
static int Reason_many; // indicates presence of several reasons
@@ -142,6 +143,8 @@
TypeProfileWidth = (int)flag.getIntx();
} else if (flag.getName().equals("BciProfileWidth")) {
BciProfileWidth = (int)flag.getIntx();
+ } else if (flag.getName().equals("MethodProfileWidth")) {
+ MethodProfileWidth = (int)flag.getIntx();
} else if (flag.getName().equals("CompileThreshold")) {
CompileThreshold = (int)flag.getIntx();
}
@@ -154,7 +157,7 @@
parametersTypeDataDi = new CIntField(type.getCIntegerField("_parameters_type_data_di"), 0);
- sizeofMethodDataOopDesc = (int)type.getSize();;
+ sizeofMethodDataOopDesc = (int)type.getSize();
Reason_many = db.lookupIntConstant("Deoptimization::Reason_many").intValue();
Reason_none = db.lookupIntConstant("Deoptimization::Reason_none").intValue();
@@ -257,7 +260,7 @@
ParametersTypeData<Klass,Method> parametersTypeData() {
int di = (int)parametersTypeDataDi.getValue(getAddress());
- if (di == -1) {
+ if (di == -1 || di == -2) {
return null;
}
DataLayout dataLayout = new DataLayout(this, di + (int)data.getOffset());
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -38,9 +38,21 @@
// that the check is reached, and a series of (Klass, count) pairs
// which are used to store a type profile for the receiver of the check.
public class ReceiverTypeData<K,M> extends CounterData {
- static final int receiver0Offset = counterCellCount;
- static final int count0Offset = receiver0Offset + 1;
- static final int receiverTypeRowCellCount = (count0Offset + 1) - receiver0Offset;
+ static final int INCLUDE_JVMCI;
+ static final int nonProfiledCountOffset = counterCellCount;
+ static final int receiver0Offset;
+ static final int count0Offset;
+ static final int receiverTypeRowCellCount;
+ static {
+ INCLUDE_JVMCI = VM.getVM().getTypeDataBase().lookupIntConstant("INCLUDE_JVMCI");
+ if (INCLUDE_JVMCI == 1) {
+ receiver0Offset = nonProfiledCountOffset + 1;
+ } else {
+ receiver0Offset = counterCellCount;
+ }
+ count0Offset = receiver0Offset + 1;
+ receiverTypeRowCellCount = (count0Offset + 1) - receiver0Offset;
+ }
final MethodDataInterface<K,M> methodData;
public ReceiverTypeData(MethodDataInterface<K,M> methodData, DataLayout layout) {
@@ -53,7 +65,11 @@
boolean isReceivertypedata() { return true; }
static int staticCellCount() {
- return counterCellCount + MethodData.TypeProfileWidth * receiverTypeRowCellCount;
+ int cellCount = counterCellCount + MethodData.TypeProfileWidth * receiverTypeRowCellCount;
+ if (INCLUDE_JVMCI == 1) {
+ cellCount += 1;
+ }
+ return cellCount;
}
public int cellCount() {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -44,7 +44,11 @@
static int staticCellCount() {
// At this point we could add more profile state, e.g., for arguments.
// But for now it's the same size as the base record type.
- return ReceiverTypeData.staticCellCount();
+ int cellCount = ReceiverTypeData.staticCellCount();
+ if (INCLUDE_JVMCI == 1) {
+ cellCount += MethodData.MethodProfileWidth * receiverTypeRowCellCount;
+ }
+ return cellCount;
}
public int cellCount() {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java Wed Sep 21 09:29:30 2016 -0700
@@ -129,8 +129,6 @@
virtualConstructor.addMapping("CompilerThread", CompilerThread.class);
virtualConstructor.addMapping("CodeCacheSweeperThread", CodeCacheSweeperThread.class);
}
- // for now, use JavaThread itself. fix it later with appropriate class if needed
- virtualConstructor.addMapping("ReferencePendingListLockerThread", JavaThread.class);
virtualConstructor.addMapping("JvmtiAgentThread", JvmtiAgentThread.class);
virtualConstructor.addMapping("ServiceThread", ServiceThread.class);
}
@@ -172,7 +170,7 @@
return thread;
} catch (Exception e) {
throw new RuntimeException("Unable to deduce type of thread from address " + threadAddr +
- " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, ReferencePendingListLockerThread, or CodeCacheSweeperThread)", e);
+ " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread or CodeCacheSweeperThread)", e);
}
}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Wed Sep 21 09:29:30 2016 -0700
@@ -837,7 +837,6 @@
vmType2Class["JavaThread"] = sapkg.runtime.JavaThread;
vmType2Class["CompilerThread"] = sapkg.runtime.CompilerThread;
vmType2Class["CodeCacheSweeperThread"] = sapkg.runtime.CodeCacheSweeperThread;
-vmType2Class["ReferencePendingListLockerThread"] = sapkg.runtime.JavaThread;
vmType2Class["DebuggerThread"] = sapkg.runtime.DebuggerThread;
// gc
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Sep 21 09:29:30 2016 -0700
@@ -244,17 +244,21 @@
native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi);
/**
- * Ensures that the type referenced by the entry for a
+ * If {@code cpi} denotes an entry representing a
* <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
- * polymorphic</a> method at index {@code cpi} in {@code constantPool} is loaded and
- * initialized.
- *
- * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
- * a signature polymorphic method.
+ * polymorphic</a> method, this method ensures that the type referenced by the entry is loaded
+ * and initialized. It {@code cpi} does not denote a signature polymorphic method, this method
+ * does nothing.
*/
native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
/**
+ * Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the
+ * classes that define signature polymorphic methods.
+ */
+ native String[] getSignaturePolymorphicHolders();
+
+ /**
* Gets the resolved type denoted by the entry at index {@code cpi} in {@code constantPool}.
*
* The behavior of this method is undefined if {@code cpi} does not denote an entry representing
@@ -348,6 +352,7 @@
* [String name, Long value, ...] vmConstants,
* [String name, Long value, ...] vmAddresses,
* VMFlag[] vmFlags
+ * VMIntrinsicMethod[] vmIntrinsics
* ]
* </pre>
*
@@ -610,4 +615,5 @@
* @return the number of bytes required for deoptimization of this frame state
*/
native int interpreterFrameSize(BytecodeFrame frame);
+
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Wed Sep 21 09:29:30 2016 -0700
@@ -282,7 +282,7 @@
* @return constant pool tag
*/
private JVM_CONSTANT getTagAt(int index) {
- assertBounds(index);
+ assert checkBounds(index);
HotSpotVMConfig config = config();
final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset);
final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
@@ -299,7 +299,7 @@
* @return constant pool entry
*/
private long getEntryAt(int index) {
- assertBounds(index);
+ assert checkBounds(index);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getAddress(getMetaspaceConstantPool() + config().constantPoolSize + offset);
}
@@ -311,7 +311,7 @@
* @return integer constant pool entry at index
*/
private int getIntAt(int index) {
- assertTag(index, JVM_CONSTANT.Integer);
+ assert checkTag(index, JVM_CONSTANT.Integer);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset);
}
@@ -323,7 +323,7 @@
* @return long constant pool entry
*/
private long getLongAt(int index) {
- assertTag(index, JVM_CONSTANT.Long);
+ assert checkTag(index, JVM_CONSTANT.Long);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getLong(getMetaspaceConstantPool() + config().constantPoolSize + offset);
}
@@ -335,7 +335,7 @@
* @return float constant pool entry
*/
private float getFloatAt(int index) {
- assertTag(index, JVM_CONSTANT.Float);
+ assert checkTag(index, JVM_CONSTANT.Float);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getFloat(getMetaspaceConstantPool() + config().constantPoolSize + offset);
}
@@ -347,7 +347,7 @@
* @return float constant pool entry
*/
private double getDoubleAt(int index) {
- assertTag(index, JVM_CONSTANT.Double);
+ assert checkTag(index, JVM_CONSTANT.Double);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getDouble(getMetaspaceConstantPool() + config().constantPoolSize + offset);
}
@@ -359,7 +359,7 @@
* @return {@code JVM_CONSTANT_NameAndType} constant pool entry
*/
private int getNameAndTypeAt(int index) {
- assertTag(index, JVM_CONSTANT.NameAndType);
+ assert checkTag(index, JVM_CONSTANT.NameAndType);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset);
}
@@ -441,7 +441,7 @@
* @return klass reference index
*/
private int getUncachedKlassRefIndexAt(int index) {
- assertTagIsFieldOrMethod(index);
+ assert checkTagIsFieldOrMethod(index);
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset);
// klass ref index is in the low 16-bits.
@@ -449,23 +449,27 @@
}
/**
- * Asserts that the constant pool index {@code index} is in the bounds of the constant pool.
+ * Checks that the constant pool index {@code index} is in the bounds of the constant pool.
*
* @param index constant pool index
+ * @throws AssertionError if the check fails
*/
- private void assertBounds(int index) {
+ private boolean checkBounds(int index) {
assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length();
+ return true;
}
/**
- * Asserts that the constant pool tag at index {@code index} is equal to {@code tag}.
+ * Checks that the constant pool tag at index {@code index} is equal to {@code tag}.
*
* @param index constant pool index
* @param tag expected tag
+ * @throws AssertionError if the check fails
*/
- private void assertTag(int index, JVM_CONSTANT tag) {
+ private boolean checkTag(int index, JVM_CONSTANT tag) {
final JVM_CONSTANT tagAt = getTagAt(index);
assert tagAt == tag : "constant pool tag at index " + index + " is " + tagAt + " but expected " + tag;
+ return true;
}
/**
@@ -473,10 +477,12 @@
* or a {@link JVM_CONSTANT#MethodRef}, or a {@link JVM_CONSTANT#InterfaceMethodref}.
*
* @param index constant pool index
+ * @throws AssertionError if the check fails
*/
- private void assertTagIsFieldOrMethod(int index) {
+ private boolean checkTagIsFieldOrMethod(int index) {
final JVM_CONSTANT tagAt = getTagAt(index);
assert tagAt == JVM_CONSTANT.Fieldref || tagAt == JVM_CONSTANT.MethodRef || tagAt == JVM_CONSTANT.InterfaceMethodref : tagAt;
+ return true;
}
@Override
@@ -523,7 +529,7 @@
@Override
public String lookupUtf8(int cpi) {
- assertTag(cpi, JVM_CONSTANT.Utf8);
+ assert checkTag(cpi, JVM_CONSTANT.Utf8);
return compilerToVM().getSymbol(getEntryAt(cpi));
}
@@ -690,11 +696,10 @@
UNSAFE.ensureClassInitialized(klass);
}
if (tag == JVM_CONSTANT.MethodRef) {
- if (Bytecodes.isInvokeHandleAlias(opcode)) {
+ if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) {
final int methodRefCacheIndex = rawIndexToConstantPoolIndex(cpi, opcode);
- if (isInvokeHandle(methodRefCacheIndex, type)) {
- compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
- }
+ assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
+ compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
}
}
@@ -708,11 +713,26 @@
// nothing
break;
}
+
}
- private boolean isInvokeHandle(int methodRefCacheIndex, HotSpotResolvedObjectTypeImpl klass) {
- assertTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
- return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameOf(methodRefCacheIndex), runtime().getHostJVMCIBackend().getMetaAccess());
+ // Lazily initialized.
+ private static String[] signaturePolymorphicHolders;
+
+ /**
+ * Determines if {@code type} contains signature polymorphic methods.
+ */
+ private static boolean isSignaturePolymorphicHolder(final HotSpotResolvedObjectTypeImpl type) {
+ String name = type.getName();
+ if (signaturePolymorphicHolders == null) {
+ signaturePolymorphicHolders = compilerToVM().getSignaturePolymorphicHolders();
+ }
+ for (String holder : signaturePolymorphicHolders) {
+ if (name.equals(holder)) {
+ return true;
+ }
+ }
+ return false;
}
@Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Wed Sep 21 09:29:30 2016 -0700
@@ -497,6 +497,9 @@
for (Map.Entry<String, Long> e : typeSizes.entrySet()) {
printConfigLine(vm, "[vmconfig:type size] %s = %d%n", e.getKey(), e.getValue());
}
+ for (VMIntrinsicMethod e : store.getIntrinsics()) {
+ printConfigLine(vm, "[vmconfig:intrinsic] %d = %s.%s %s%n", e.id, e.declaringClass, e.name, e.descriptor);
+ }
}
public OutputStream getLogStream() {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java Wed Sep 21 09:29:30 2016 -0700
@@ -112,6 +112,15 @@
int intrinsicId();
/**
+ * Determines if this method denotes itself as a candidate for intrinsification. As of JDK 9,
+ * this is denoted by the {@code HotSpotIntrinsicCandidate} annotation. In earlier JDK versions,
+ * this method returns true.
+ *
+ * @see <a href="https://bugs.openjdk.java.net/browse/JDK-8076112">JDK-8076112</a>
+ */
+ boolean isIntrinsicCandidate();
+
+ /**
* Allocates a compile id for this method by asking the VM for one.
*
* @param entryBCI entry bci
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Wed Sep 21 09:29:30 2016 -0700
@@ -693,6 +693,10 @@
return UNSAFE.getChar(metaspaceMethod + config.methodIntrinsicIdOffset);
}
+ public boolean isIntrinsicCandidate() {
+ return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0;
+ }
+
@Override
public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) {
assert !isConstructor();
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Wed Sep 21 09:29:30 2016 -0700
@@ -144,6 +144,7 @@
final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class);
final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class);
+ final int methodFlagsIntrinsicCandidate = getConstant("Method::_intrinsic_candidate", Integer.class);
final int methodFlagsDontInline = getConstant("Method::_dont_inline", Integer.class);
final int methodFlagsReservedStackAccess = getConstant("Method::_reserved_stack_access", Integer.class);
final int nonvirtualVtableIndex = getConstant("Method::nonvirtual_vtable_index", Integer.class);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,6 +30,13 @@
public class HotSpotVMConfigAccess {
/**
+ * Gets the available configuration data.
+ */
+ public HotSpotVMConfigStore getStore() {
+ return store;
+ }
+
+ /**
* Gets the address of a C++ symbol.
*
* @param name name of C++ symbol
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java Wed Sep 21 09:29:30 2016 -0700
@@ -24,8 +24,10 @@
import static jdk.vm.ci.common.InitTimer.timer;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import jdk.vm.ci.common.InitTimer;
@@ -80,11 +82,19 @@
return Collections.unmodifiableMap(vmFields);
}
+ /**
+ * Gets the VM intrinsic descriptions exposed by this object.
+ */
+ public List<VMIntrinsicMethod> getIntrinsics() {
+ return Collections.unmodifiableList(vmIntrinsics);
+ }
+
final HashMap<String, VMField> vmFields;
final HashMap<String, Long> vmTypeSizes;
final HashMap<String, Long> vmConstants;
final HashMap<String, Long> vmAddresses;
final HashMap<String, VMFlag> vmFlags;
+ final List<VMIntrinsicMethod> vmIntrinsics;
/**
* Reads the database of VM info. The return value encodes the info in a nested object array
@@ -97,6 +107,7 @@
* [String name, Long value, ...] vmConstants,
* [String name, Long value, ...] vmAddresses,
* VMFlag[] vmFlags
+ * VMIntrinsicMethod[] vmIntrinsics
* ]
* </pre>
*/
@@ -106,7 +117,7 @@
try (InitTimer t = timer("CompilerToVm readConfiguration")) {
data = compilerToVm.readConfiguration();
}
- assert data.length == 5 : data.length;
+ assert data.length == 6 : data.length;
// @formatter:off
VMField[] vmFieldsInfo = (VMField[]) data[0];
@@ -115,11 +126,12 @@
Object[] vmAddressesInfo = (Object[]) data[3];
VMFlag[] vmFlagsInfo = (VMFlag[]) data[4];
- vmFields = new HashMap<>(vmFieldsInfo.length);
- vmTypeSizes = new HashMap<>(vmTypesSizesInfo.length);
- vmConstants = new HashMap<>(vmConstantsInfo.length);
- vmAddresses = new HashMap<>(vmAddressesInfo.length);
- vmFlags = new HashMap<>(vmFlagsInfo.length);
+ vmFields = new HashMap<>(vmFieldsInfo.length);
+ vmTypeSizes = new HashMap<>(vmTypesSizesInfo.length);
+ vmConstants = new HashMap<>(vmConstantsInfo.length);
+ vmAddresses = new HashMap<>(vmAddressesInfo.length);
+ vmFlags = new HashMap<>(vmFlagsInfo.length);
+ vmIntrinsics = Arrays.asList((VMIntrinsicMethod[]) data[5]);
// @formatter:on
try (InitTimer t = timer("HotSpotVMConfigStore<init> fill maps")) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMIntrinsicMethod.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.meta.Signature;
+
+/**
+ * Describes a method for which the VM has an intrinsic implementation.
+ */
+public final class VMIntrinsicMethod {
+
+ /**
+ * The name of the class declaring the intrinsified method. The name is in
+ * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.2.1">class
+ * file format</a> (e.g., {@code "java/lang/Thread"} instead of {@code "java.lang.Thread"}).
+ */
+ public final String declaringClass;
+
+ /**
+ * The name of the intrinsified method. This is not guaranteed to be a legal method name (e.g.,
+ * there is a HotSpot intrinsic with the name {@code "<compiledLambdaForm>"}).
+ */
+ public final String name;
+
+ /**
+ * The {@link Signature#toMethodDescriptor() descriptor} of the intrinsified method. This is not
+ * guaranteed to be a legal method descriptor (e.g., intrinsics for signature polymorphic
+ * methods have a descriptor of {@code "*"}).
+ */
+ public final String descriptor;
+
+ /**
+ * The unique VM identifier for the intrinsic.
+ */
+ public final int id;
+
+ VMIntrinsicMethod(String declaringClass, String name, String descriptor, int id) {
+ this.declaringClass = declaringClass;
+ this.name = name;
+ this.descriptor = descriptor;
+ this.id = id;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof VMIntrinsicMethod) {
+ VMIntrinsicMethod that = (VMIntrinsicMethod) obj;
+ if (that.id == this.id) {
+ assert that.name.equals(this.name) &&
+ that.declaringClass.equals(this.declaringClass) &&
+ that.descriptor.equals(this.descriptor);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return id;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("IntrinsicMethod[declaringClass=%s, name=%s, descriptor=%s, id=%d]", declaringClass, name, descriptor, id);
+ }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java Wed Sep 21 09:29:30 2016 -0700
@@ -23,7 +23,6 @@
package jdk.vm.ci.meta;
import java.lang.annotation.Annotation;
-import java.lang.invoke.MethodHandle;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
@@ -330,22 +329,4 @@
}
SpeculationLog getSpeculationLog();
-
- /**
- * Determines if the method identified by its holder and name is a
- * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
- * polymorphic</a> method.
- */
- static boolean isSignaturePolymorphic(JavaType holder, String name, MetaAccessProvider metaAccess) {
- if (!holder.getName().equals("Ljava/lang/invoke/MethodHandle;")) {
- return false;
- }
- ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class);
- Signature signature = metaAccess.parseMethodDescriptor("([Ljava/lang/Object;)Ljava/lang/Object;");
- ResolvedJavaMethod method = methodHandleType.findMethod(name, signature);
- if (method == null) {
- return false;
- }
- return method.isNative() && method.isVarArgs();
- }
}
--- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -2875,7 +2875,7 @@
// in the library.
const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
- size_t cpu_num = os::active_processor_count();
+ size_t cpu_num = processor_count();
size_t cpu_map_size = NCPUS / BitsPerCLong;
size_t cpu_map_valid_size =
MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
--- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -2504,13 +2504,15 @@
// It write enables the page immediately after protecting it
// so just return.
if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
- JavaThread* thread = (JavaThread*) t;
- PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
- address addr = (address) exceptionRecord->ExceptionInformation[1];
- if (os::is_memory_serialize_page(thread, addr)) {
- // Block current thread until the memory serialize page permission restored.
- os::block_on_serialize_page_trap();
- return EXCEPTION_CONTINUE_EXECUTION;
+ if (t != NULL && t->is_Java_thread()) {
+ JavaThread* thread = (JavaThread*) t;
+ PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
+ address addr = (address) exceptionRecord->ExceptionInformation[1];
+ if (os::is_memory_serialize_page(thread, addr)) {
+ // Block current thread until the memory serialize page permission restored.
+ os::block_on_serialize_page_trap();
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
}
}
@@ -2564,7 +2566,7 @@
}
#endif
if (thread->stack_guards_enabled()) {
- if (_thread_in_Java) {
+ if (in_java) {
frame fr;
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
@@ -2576,6 +2578,7 @@
// Yellow zone violation. The o/s has unprotected the first yellow
// zone page for us. Note: must call disable_stack_yellow_zone to
// update the enabled status, even if the zone contains only one page.
+ assert(thread->thread_state() != _thread_in_vm, "Undersized StackShadowPages");
thread->disable_stack_yellow_reserved_zone();
// If not in java code, return and hope for the best.
return in_java
@@ -3793,6 +3796,11 @@
GlobalMemoryStatusEx(&ms);
_physical_memory = ms.ullTotalPhys;
+ if (FLAG_IS_DEFAULT(MaxRAM)) {
+ // Adjust MaxRAM according to the maximum virtual address space available.
+ FLAG_SET_DEFAULT(MaxRAM, MIN2(MaxRAM, (uint64_t) ms.ullTotalVirtual));
+ }
+
OSVERSIONINFOEX oi;
oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO*)&oi);
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -444,7 +444,7 @@
if (thread->thread_state() == _thread_in_vm) {
- if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
+ if (sig == SIGBUS && thread->doing_unsafe_access()) {
stub = SharedRuntime::handle_unsafe_access(thread, npc);
}
}
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -221,6 +221,9 @@
case vmIntrinsics::_putCharStringU:
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime:
+#if defined(_LP64) || !defined(TRACE_ID_CLASS_SHIFT)
+ case vmIntrinsics::_getClassId:
+#endif
#endif
break;
default:
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -683,6 +683,7 @@
, _cleanup_block(NULL)
, _cleanup_return_prev(NULL)
, _cleanup_state(NULL)
+ , _ignore_return(false)
{
if (parent != NULL) {
_max_inline_size = (intx) ((float) NestedInliningSizeRatio * (float) parent->max_inline_size() / 100.0f);
@@ -1445,7 +1446,7 @@
}
-void GraphBuilder::method_return(Value x) {
+void GraphBuilder::method_return(Value x, bool ignore_return) {
if (RegisterFinalizersAtInit &&
method()->intrinsic_id() == vmIntrinsics::_Object_init) {
call_register_finalizer();
@@ -1518,7 +1519,9 @@
int invoke_bci = state()->caller_state()->bci();
set_state(state()->caller_state()->copy_for_parsing());
if (x != NULL) {
- state()->push(x->type(), x);
+ if (!ignore_return) {
+ state()->push(x->type(), x);
+ }
if (profile_return() && x->type()->is_object_kind()) {
ciMethod* caller = state()->scope()->method();
ciMethodData* md = caller->method_data_or_null();
@@ -1563,6 +1566,7 @@
append(new MemBar(lir_membar_storestore));
}
+ assert(!ignore_return, "Ignoring return value works only for inlining");
append(new Return(x));
}
@@ -1981,7 +1985,7 @@
code == Bytecodes::_invokedynamic) {
ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
// static binding => check if callee is ok
- bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
+ bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), false, code, better_receiver);
CHECK_BAILOUT();
clear_inline_bailout();
@@ -2611,6 +2615,8 @@
push_exception = true;
}
+ bool ignore_return = scope_data()->ignore_return();
+
while (!bailed_out() && last()->as_BlockEnd() == NULL &&
(code = stream()->next()) != ciBytecodeStream::EOBC() &&
(block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) {
@@ -2806,12 +2812,12 @@
case Bytecodes::_ret : ret(s.get_index()); break;
case Bytecodes::_tableswitch : table_switch(); break;
case Bytecodes::_lookupswitch : lookup_switch(); break;
- case Bytecodes::_ireturn : method_return(ipop()); break;
- case Bytecodes::_lreturn : method_return(lpop()); break;
- case Bytecodes::_freturn : method_return(fpop()); break;
- case Bytecodes::_dreturn : method_return(dpop()); break;
- case Bytecodes::_areturn : method_return(apop()); break;
- case Bytecodes::_return : method_return(NULL ); break;
+ case Bytecodes::_ireturn : method_return(ipop(), ignore_return); break;
+ case Bytecodes::_lreturn : method_return(lpop(), ignore_return); break;
+ case Bytecodes::_freturn : method_return(fpop(), ignore_return); break;
+ case Bytecodes::_dreturn : method_return(dpop(), ignore_return); break;
+ case Bytecodes::_areturn : method_return(apop(), ignore_return); break;
+ case Bytecodes::_return : method_return(NULL , ignore_return); break;
case Bytecodes::_getstatic : // fall through
case Bytecodes::_putstatic : // fall through
case Bytecodes::_getfield : // fall through
@@ -3336,7 +3342,7 @@
}
-bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
+bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
const char* msg = NULL;
// clear out any existing inline bailout condition
@@ -3351,7 +3357,7 @@
// method handle invokes
if (callee->is_method_handle_intrinsic()) {
- if (try_method_handle_inline(callee)) {
+ if (try_method_handle_inline(callee, ignore_return)) {
if (callee->has_reserved_stack_access()) {
compilation()->set_has_reserved_stack_access(true);
}
@@ -3363,7 +3369,7 @@
// handle intrinsics
if (callee->intrinsic_id() != vmIntrinsics::_none &&
(CheckIntrinsics ? callee->intrinsic_candidate() : true)) {
- if (try_inline_intrinsics(callee)) {
+ if (try_inline_intrinsics(callee, ignore_return)) {
print_inlining(callee, "intrinsic");
if (callee->has_reserved_stack_access()) {
compilation()->set_has_reserved_stack_access(true);
@@ -3384,7 +3390,7 @@
if (bc == Bytecodes::_illegal) {
bc = code();
}
- if (try_inline_full(callee, holder_known, bc, receiver)) {
+ if (try_inline_full(callee, holder_known, ignore_return, bc, receiver)) {
if (callee->has_reserved_stack_access()) {
compilation()->set_has_reserved_stack_access(true);
}
@@ -3415,7 +3421,7 @@
return NULL;
}
-void GraphBuilder::build_graph_for_intrinsic(ciMethod* callee) {
+void GraphBuilder::build_graph_for_intrinsic(ciMethod* callee, bool ignore_return) {
vmIntrinsics::ID id = callee->intrinsic_id();
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
@@ -3509,14 +3515,16 @@
vmIntrinsics::can_trap(id));
// append instruction & push result
Value value = append_split(result);
- if (result_type != voidType) push(result_type, value);
+ if (result_type != voidType && !ignore_return) {
+ push(result_type, value);
+ }
if (callee != method() && profile_return() && result_type->is_object_kind()) {
profile_return_type(result, callee);
}
}
-bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
+bool GraphBuilder::try_inline_intrinsics(ciMethod* callee, bool ignore_return) {
// For calling is_intrinsic_available we need to transition to
// the '_thread_in_vm' state because is_intrinsic_available()
// accesses critical VM-internal data.
@@ -3536,7 +3544,7 @@
return false;
}
}
- build_graph_for_intrinsic(callee);
+ build_graph_for_intrinsic(callee, ignore_return);
return true;
}
@@ -3691,7 +3699,7 @@
}
-bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
+bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
assert(!callee->is_native(), "callee must not be native");
if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
INLINE_BAILOUT("inlining prohibited by policy");
@@ -3889,6 +3897,7 @@
// Clear out bytecode stream
scope_data()->set_stream(NULL);
+ scope_data()->set_ignore_return(ignore_return);
CompileLog* log = compilation()->log();
if (log != NULL) log->head("parse method='%d'", log->identify(callee));
@@ -3958,7 +3967,7 @@
}
-bool GraphBuilder::try_method_handle_inline(ciMethod* callee) {
+bool GraphBuilder::try_method_handle_inline(ciMethod* callee, bool ignore_return) {
ValueStack* state_before = copy_state_before();
vmIntrinsics::ID iid = callee->intrinsic_id();
switch (iid) {
@@ -3972,7 +3981,8 @@
// We don't do CHA here so only inline static and statically bindable methods.
if (target->is_static() || target->can_be_statically_bound()) {
Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
- if (try_inline(target, /*holder_known*/ true, bc)) {
+ ignore_return = ignore_return || (callee->return_type()->is_void() && !target->return_type()->is_void());
+ if (try_inline(target, /*holder_known*/ true, ignore_return, bc)) {
return true;
}
} else {
@@ -3994,10 +4004,11 @@
ValueType* type = apop()->type();
if (type->is_constant()) {
ciMethod* target = type->as_ObjectType()->constant_value()->as_member_name()->get_vmtarget();
+ ignore_return = ignore_return || (callee->return_type()->is_void() && !target->return_type()->is_void());
// If the target is another method handle invoke, try to recursively get
// a better target.
if (target->is_method_handle_intrinsic()) {
- if (try_method_handle_inline(target)) {
+ if (try_method_handle_inline(target, ignore_return)) {
return true;
}
} else {
@@ -4032,7 +4043,7 @@
// We don't do CHA here so only inline static and statically bindable methods.
if (target->is_static() || target->can_be_statically_bound()) {
Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
- if (try_inline(target, /*holder_known*/ true, bc)) {
+ if (try_inline(target, /*holder_known*/ true, ignore_return, bc)) {
return true;
}
} else {
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -100,6 +100,9 @@
Instruction* _cleanup_return_prev; // Instruction before return instruction
ValueStack* _cleanup_state; // State of that block (not yet pinned)
+ // When inlining do not push the result on the stack
+ bool _ignore_return;
+
public:
ScopeData(ScopeData* parent);
@@ -163,6 +166,9 @@
BlockBegin* inline_cleanup_block() const { return _cleanup_block; }
Instruction* inline_cleanup_return_prev() const{ return _cleanup_return_prev; }
ValueStack* inline_cleanup_state() const { return _cleanup_state; }
+
+ bool ignore_return() const { return _ignore_return; }
+ void set_ignore_return(bool ignore_return) { _ignore_return = ignore_return; }
};
// for all GraphBuilders
@@ -246,7 +252,7 @@
void ret(int local_index);
void table_switch();
void lookup_switch();
- void method_return(Value x);
+ void method_return(Value x, bool ignore_return = false);
void call_register_finalizer();
void access_field(Bytecodes::Code code);
void invoke(Bytecodes::Code code);
@@ -340,19 +346,19 @@
void inline_sync_entry(Value lock, BlockBegin* sync_handler);
void fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler = false);
- void build_graph_for_intrinsic(ciMethod* callee);
+ void build_graph_for_intrinsic(ciMethod* callee, bool ignore_return);
// inliners
- bool try_inline( ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
- bool try_inline_intrinsics(ciMethod* callee);
- bool try_inline_full( ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
+ bool try_inline( ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
+ bool try_inline_intrinsics(ciMethod* callee, bool ignore_return = false);
+ bool try_inline_full( ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
bool try_inline_jsr(int jsr_dest_bci);
const char* check_can_parse(ciMethod* callee) const;
const char* should_not_inline(ciMethod* callee) const;
// JSR 292 support
- bool try_method_handle_inline(ciMethod* callee);
+ bool try_method_handle_inline(ciMethod* callee, bool ignore_return);
// helpers
void inline_bailout(const char* msg);
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -3083,6 +3083,37 @@
__ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type()));
}
+#ifdef TRACE_HAVE_INTRINSICS
+void LIRGenerator::do_ClassIDIntrinsic(Intrinsic* x) {
+ CodeEmitInfo* info = state_for(x);
+ CodeEmitInfo* info2 = new CodeEmitInfo(info); // Clone for the second null check
+
+ assert(info != NULL, "must have info");
+ LIRItem arg(x->argument_at(0), this);
+
+ arg.load_item();
+ LIR_Opr klass = new_register(T_METADATA);
+ __ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), T_ADDRESS), klass, info);
+ LIR_Opr id = new_register(T_LONG);
+ ByteSize offset = TRACE_KLASS_TRACE_ID_OFFSET;
+ LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG);
+
+ __ move(trace_id_addr, id);
+ __ logical_or(id, LIR_OprFact::longConst(0x01l), id);
+ __ store(id, trace_id_addr);
+
+#ifdef TRACE_ID_META_BITS
+ __ logical_and(id, LIR_OprFact::longConst(~TRACE_ID_META_BITS), id);
+#endif
+#ifdef TRACE_ID_CLASS_SHIFT
+ __ unsigned_shift_right(id, TRACE_ID_CLASS_SHIFT, id);
+#endif
+
+ __ move(id, rlock_result(x));
+}
+#endif
+
+
void LIRGenerator::do_RuntimeCall(address routine, Intrinsic* x) {
assert(x->number_of_arguments() == 0, "wrong type");
// Enforce computation of _reserved_argument_area_size which is required on some platforms.
@@ -3108,6 +3139,9 @@
}
#ifdef TRACE_HAVE_INTRINSICS
+ case vmIntrinsics::_getClassId:
+ do_ClassIDIntrinsic(x);
+ break;
case vmIntrinsics::_counterTime:
do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), x);
break;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -438,6 +438,10 @@
SwitchRangeArray* create_lookup_ranges(LookupSwitch* x);
void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux);
+#ifdef TRACE_HAVE_INTRINSICS
+ void do_ClassIDIntrinsic(Intrinsic* x);
+#endif
+
void do_RuntimeCall(address routine, Intrinsic* x);
ciKlass* profile_type(ciMethodData* md, int md_first_offset, int md_offset, intptr_t profiled_k,
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -29,7 +29,6 @@
#include "ci/ciKlass.hpp"
#include "ci/ciUtilities.hpp"
#include "compiler/compileBroker.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
@@ -577,9 +576,7 @@
Method* method = parse_method(CHECK);
if (had_error()) return;
/* just copied from Method, to build interpret data*/
- if (ReferencePendingListLocker::is_locked_by_self()) {
- return;
- }
+
// To be properly initialized, some profiling in the MDO needs the
// method to be rewritten (number of arguments at a call for
// instance)
--- a/hotspot/src/share/vm/classfile/altHashing.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/altHashing.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014, 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
@@ -205,103 +205,3 @@
juint AltHashing::murmur3_32(const int* data, int len) {
return murmur3_32(0, data, len);
}
-
-#ifndef PRODUCT
-// Overloaded versions for internal test.
-juint AltHashing::murmur3_32(const jbyte* data, int len) {
- return murmur3_32(0, data, len);
-}
-
-juint AltHashing::murmur3_32(const jchar* data, int len) {
- return murmur3_32(0, data, len);
-}
-
-// Internal test for alternate hashing. Translated from JDK version
-// test/sun/misc/Hashing.java
-static const jbyte ONE_BYTE[] = { (jbyte) 0x80};
-static const jbyte TWO_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81};
-static const jchar ONE_CHAR[] = { (jchar) 0x8180};
-static const jbyte THREE_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82};
-static const jbyte FOUR_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83};
-static const jchar TWO_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382};
-static const jint ONE_INT[] = { (jint)0x83828180};
-static const jbyte SIX_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85};
-static const jchar THREE_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584};
-static const jbyte EIGHT_BYTE[] = {
- (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82,
- (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85,
- (jbyte) 0x86, (jbyte) 0x87};
-static const jchar FOUR_CHAR[] = {
- (jchar) 0x8180, (jchar) 0x8382,
- (jchar) 0x8584, (jchar) 0x8786};
-
-static const jint TWO_INT[] = { (jint)0x83828180, (jint)0x87868584};
-
-static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3;
-
-void AltHashing::testMurmur3_32_ByteArray() {
- // printf("testMurmur3_32_ByteArray\n");
-
- jbyte vector[256];
- jbyte hashes[4 * 256];
-
- for (int i = 0; i < 256; i++) {
- vector[i] = (jbyte) i;
- }
-
- // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
- for (int i = 0; i < 256; i++) {
- juint hash = murmur3_32(256 - i, vector, i);
- hashes[i * 4] = (jbyte) hash;
- hashes[i * 4 + 1] = (jbyte)(hash >> 8);
- hashes[i * 4 + 2] = (jbyte)(hash >> 16);
- hashes[i * 4 + 3] = (jbyte)(hash >> 24);
- }
-
- // hash to get const result.
- juint final_hash = murmur3_32(hashes, 4*256);
-
- assert (MURMUR3_32_X86_CHECK_VALUE == final_hash,
- "Calculated hash result not as expected. Expected %08X got %08X\n",
- MURMUR3_32_X86_CHECK_VALUE,
- final_hash);
-}
-
-void AltHashing::testEquivalentHashes() {
- juint jbytes, jchars, ints;
-
- // printf("testEquivalentHashes\n");
-
- jbytes = murmur3_32(TWO_BYTE, 2);
- jchars = murmur3_32(ONE_CHAR, 1);
- assert (jbytes == jchars,
- "Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars);
-
- jbytes = murmur3_32(FOUR_BYTE, 4);
- jchars = murmur3_32(TWO_CHAR, 2);
- ints = murmur3_32(ONE_INT, 1);
- assert ((jbytes == jchars) && (jbytes == ints),
- "Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints);
-
- jbytes = murmur3_32(SIX_BYTE, 6);
- jchars = murmur3_32(THREE_CHAR, 3);
- assert (jbytes == jchars,
- "Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars);
-
- jbytes = murmur3_32(EIGHT_BYTE, 8);
- jchars = murmur3_32(FOUR_CHAR, 4);
- ints = murmur3_32(TWO_INT, 2);
- assert ((jbytes == jchars) && (jbytes == ints),
- "Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints);
-}
-
-// Returns true if the alternate hashcode is correct
-void AltHashing::test_alt_hash() {
- testMurmur3_32_ByteArray();
- testEquivalentHashes();
-}
-
-void AltHashing_test() {
- AltHashing::test_alt_hash();
-}
-#endif // PRODUCT
--- a/hotspot/src/share/vm/classfile/altHashing.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/altHashing.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014, 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
@@ -37,26 +37,18 @@
*/
class AltHashing : AllStatic {
+ friend class AltHashingTest;
// utility function copied from java/lang/Integer
static juint Integer_rotateLeft(juint i, int distance) {
- return (i << distance) | (i >> (32-distance));
+ return (i << distance) | (i >> (32 - distance));
}
static juint murmur3_32(const int* data, int len);
static juint murmur3_32(juint seed, const int* data, int len);
-#ifndef PRODUCT
- // Hashing functions used for internal testing
- static juint murmur3_32(const jbyte* data, int len);
- static juint murmur3_32(const jchar* data, int len);
- static void testMurmur3_32_ByteArray();
- static void testEquivalentHashes();
-#endif // PRODUCT
-
public:
static juint compute_seed();
static juint murmur3_32(juint seed, const jbyte* data, int len);
static juint murmur3_32(juint seed, const jchar* data, int len);
- NOT_PRODUCT(static void test_alt_hash();)
};
#endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -95,7 +95,6 @@
#define JAVA_6_VERSION 50
// Used for backward compatibility reasons:
-// - to check NameAndType_info signatures more aggressively
// - to disallow argument and require ACC_STATIC for <clinit> methods
#define JAVA_7_VERSION 51
@@ -564,7 +563,7 @@
break;
}
case JVM_CONSTANT_NameAndType: {
- if (_need_verify && _major_version >= JAVA_7_VERSION) {
+ if (_need_verify) {
const int sig_index = cp->signature_ref_index_at(index);
const int name_index = cp->name_ref_index_at(index);
const Symbol* const name = cp->symbol_at(name_index);
@@ -572,9 +571,17 @@
guarantee_property(sig->utf8_length() != 0,
"Illegal zero length constant pool entry at %d in class %s",
sig_index, CHECK);
+ guarantee_property(name->utf8_length() != 0,
+ "Illegal zero length constant pool entry at %d in class %s",
+ name_index, CHECK);
+
if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) {
+ // Format check method name and signature
+ verify_legal_method_name(name, CHECK);
verify_legal_method_signature(name, sig, CHECK);
} else {
+ // Format check field name and signature
+ verify_legal_field_name(name, CHECK);
verify_legal_field_signature(name, sig, CHECK);
}
}
@@ -595,42 +602,32 @@
const Symbol* const name = cp->symbol_at(name_ref_index);
const Symbol* const signature = cp->symbol_at(signature_ref_index);
if (tag == JVM_CONSTANT_Fieldref) {
- verify_legal_field_name(name, CHECK);
- if (_need_verify && _major_version >= JAVA_7_VERSION) {
- // Signature is verified above, when iterating NameAndType_info.
- // Need only to be sure it's non-zero length and the right type.
+ if (_need_verify) {
+ // Field name and signature are verified above, when iterating NameAndType_info.
+ // Need only to be sure signature is non-zero length and the right type.
if (signature->utf8_length() == 0 ||
signature->byte_at(0) == JVM_SIGNATURE_FUNC) {
- throwIllegalSignature(
- "Field", name, signature, CHECK);
+ throwIllegalSignature("Field", name, signature, CHECK);
}
- } else {
- verify_legal_field_signature(name, signature, CHECK);
}
} else {
- verify_legal_method_name(name, CHECK);
- if (_need_verify && _major_version >= JAVA_7_VERSION) {
- // Signature is verified above, when iterating NameAndType_info.
- // Need only to be sure it's non-zero length and the right type.
+ if (_need_verify) {
+ // Method name and signature are verified above, when iterating NameAndType_info.
+ // Need only to be sure signature is non-zero length and the right type.
if (signature->utf8_length() == 0 ||
signature->byte_at(0) != JVM_SIGNATURE_FUNC) {
- throwIllegalSignature(
- "Method", name, signature, CHECK);
+ throwIllegalSignature("Method", name, signature, CHECK);
}
- } else {
- verify_legal_method_signature(name, signature, CHECK);
}
- if (tag == JVM_CONSTANT_Methodref) {
- // 4509014: If a class method name begins with '<', it must be "<init>".
- assert(name != NULL, "method name in constant pool is null");
- const unsigned int name_len = name->utf8_length();
- if (name_len != 0 && name->byte_at(0) == '<') {
- if (name != vmSymbols::object_initializer_name()) {
- classfile_parse_error(
- "Bad method name at constant pool index %u in class file %s",
- name_ref_index, CHECK);
- }
- }
+ // 4509014: If a class method name begins with '<', it must be "<init>"
+ const unsigned int name_len = name->utf8_length();
+ if (tag == JVM_CONSTANT_Methodref &&
+ name_len != 0 &&
+ name->byte_at(0) == '<' &&
+ name != vmSymbols::object_initializer_name()) {
+ classfile_parse_error(
+ "Bad method name at constant pool index %u in class file %s",
+ name_ref_index, CHECK);
}
}
break;
@@ -4843,19 +4840,28 @@
}
}
else {
- // 4900761: For class version > 48, any unicode is allowed in class name.
+ // Skip leading 'L' and ignore first appearance of ';'
length--;
signature++;
- while (length > 0 && signature[0] != ';') {
- if (signature[0] == '.') {
- classfile_parse_error("Class name contains illegal character '.' in descriptor in class file %s", CHECK_0);
+ char* c = strchr((char*) signature, ';');
+ // Format check signature
+ if (c != NULL) {
+ ResourceMark rm(THREAD);
+ int newlen = c - (char*) signature;
+ char* sig = NEW_RESOURCE_ARRAY(char, newlen + 1);
+ strncpy(sig, signature, newlen);
+ sig[newlen] = '\0';
+
+ bool legal = verify_unqualified_name(sig, newlen, LegalClass);
+ if (!legal) {
+ classfile_parse_error("Class name contains illegal character "
+ "in descriptor in class file %s",
+ CHECK_0);
+ return NULL;
}
- length--;
- signature++;
+ return signature + newlen + 1;
}
- if (signature[0] == ';') { return signature + 1; }
}
-
return NULL;
}
case JVM_SIGNATURE_ARRAY:
@@ -4869,7 +4875,6 @@
length--;
void_ok = false;
break;
-
default:
return NULL;
}
@@ -5402,11 +5407,75 @@
debug_only(ik->verify();)
}
+// For an anonymous class that is in the unnamed package, move it to its host class's
+// package by prepending its host class's package name to its class name and setting
+// its _class_name field.
+void ClassFileParser::prepend_host_package_name(const InstanceKlass* host_klass, TRAPS) {
+ ResourceMark rm(THREAD);
+ assert(strrchr(_class_name->as_C_string(), '/') == NULL,
+ "Anonymous class should not be in a package");
+ const char* host_pkg_name =
+ ClassLoader::package_from_name(host_klass->name()->as_C_string(), NULL);
+
+ if (host_pkg_name != NULL) {
+ size_t host_pkg_len = strlen(host_pkg_name);
+ int class_name_len = _class_name->utf8_length();
+ char* new_anon_name =
+ NEW_RESOURCE_ARRAY(char, host_pkg_len + 1 + class_name_len);
+ // Copy host package name and trailing /.
+ strncpy(new_anon_name, host_pkg_name, host_pkg_len);
+ new_anon_name[host_pkg_len] = '/';
+ // Append anonymous class name. The anonymous class name can contain odd
+ // characters. So, do a strncpy instead of using sprintf("%s...").
+ strncpy(new_anon_name + host_pkg_len + 1, (char *)_class_name->base(), class_name_len);
+
+ // Create a symbol and update the anonymous class name.
+ _class_name = SymbolTable::new_symbol(new_anon_name,
+ (int)host_pkg_len + 1 + class_name_len,
+ CHECK);
+ }
+}
+
+// If the host class and the anonymous class are in the same package then do
+// nothing. If the anonymous class is in the unnamed package then move it to its
+// host's package. If the classes are in different packages then throw an IAE
+// exception.
+void ClassFileParser::fix_anonymous_class_name(TRAPS) {
+ assert(_host_klass != NULL, "Expected an anonymous class");
+
+ const jbyte* anon_last_slash = UTF8::strrchr(_class_name->base(),
+ _class_name->utf8_length(), '/');
+ if (anon_last_slash == NULL) { // Unnamed package
+ prepend_host_package_name(_host_klass, CHECK);
+ } else {
+ if (!InstanceKlass::is_same_class_package(_host_klass->class_loader(),
+ _host_klass->name(),
+ _host_klass->class_loader(),
+ _class_name)) {
+ ResourceMark rm(THREAD);
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ err_msg("Host class %s and anonymous class %s are in different packages",
+ _host_klass->name()->as_C_string(), _class_name->as_C_string()));
+ }
+ }
+}
+
+static bool relax_format_check_for(ClassLoaderData* loader_data) {
+ bool trusted = (loader_data->is_the_null_class_loader_data() ||
+ SystemDictionary::is_platform_class_loader(loader_data->class_loader()));
+ bool need_verify =
+ // verifyAll
+ (BytecodeVerificationLocal && BytecodeVerificationRemote) ||
+ // verifyRemote
+ (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted);
+ return !need_verify;
+}
+
ClassFileParser::ClassFileParser(ClassFileStream* stream,
Symbol* name,
ClassLoaderData* loader_data,
Handle protection_domain,
- const Klass* host_klass,
+ const InstanceKlass* host_klass,
GrowableArray<Handle>* cp_patches,
Publicity pub_level,
TRAPS) :
@@ -5490,7 +5559,7 @@
// Check if verification needs to be relaxed for this class file
// Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376)
- _relax_verify = Verifier::relax_verify_for(_loader_data->class_loader());
+ _relax_verify = relax_format_check_for(_loader_data);
parse_stream(stream, CHECK);
@@ -5681,6 +5750,13 @@
return;
}
+ // if this is an anonymous class fix up its name if it's in the unnamed
+ // package. Otherwise, throw IAE if it is in a different package than
+ // its host class.
+ if (_host_klass != NULL) {
+ fix_anonymous_class_name(CHECK);
+ }
+
// Verification prevents us from creating names with dots in them, this
// asserts that that's the case.
assert(is_internal_format(_class_name), "external class name format used internally");
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -79,7 +79,7 @@
const Symbol* _requested_name;
Symbol* _class_name;
mutable ClassLoaderData* _loader_data;
- const Klass* _host_klass;
+ const InstanceKlass* _host_klass;
GrowableArray<Handle>* _cp_patches; // overrides for CP entries
// Metadata created before the instance klass is created. Must be deallocated
@@ -155,6 +155,9 @@
ConstantPool* cp,
TRAPS);
+ void prepend_host_package_name(const InstanceKlass* host_klass, TRAPS);
+ void fix_anonymous_class_name(TRAPS);
+
void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH, TRAPS);
void set_klass(InstanceKlass* instance);
@@ -474,7 +477,7 @@
Symbol* name,
ClassLoaderData* loader_data,
Handle protection_domain,
- const Klass* host_klass,
+ const InstanceKlass* host_klass,
GrowableArray<Handle>* cp_patches,
Publicity pub_level,
TRAPS);
@@ -500,7 +503,7 @@
bool is_anonymous() const { return _host_klass != NULL; }
bool is_interface() const { return _access_flags.is_interface(); }
- const Klass* host_klass() const { return _host_klass; }
+ const InstanceKlass* host_klass() const { return _host_klass; }
const GrowableArray<Handle>* cp_patches() const { return _cp_patches; }
ClassLoaderData* loader_data() const { return _loader_data; }
const Symbol* class_name() const { return _class_name; }
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -50,12 +50,14 @@
class ClassPathEntry : public CHeapObj<mtClass> {
private:
- ClassPathEntry* _next;
+ ClassPathEntry* volatile _next;
public:
// Next entry in class path
- ClassPathEntry* next() const { return _next; }
+ ClassPathEntry* next() const {
+ return (ClassPathEntry*) OrderAccess::load_ptr_acquire(&_next);
+ }
void set_next(ClassPathEntry* next) {
- // may have unlocked readers, so write atomically.
+ // may have unlocked readers, so ensure visibility.
OrderAccess::release_store_ptr(&_next, next);
}
virtual bool is_jrt() = 0;
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -966,7 +966,7 @@
// Klasses to delete.
bool walk_all_metadata = clean_previous_versions &&
JvmtiExport::has_redefined_a_class() &&
- InstanceKlass::has_previous_versions();
+ InstanceKlass::has_previous_versions_and_reset();
MetadataOnStackMark md_on_stack(walk_all_metadata);
// Save previous _unloading pointer for CMS which may add to unloading list before
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -3015,41 +3015,6 @@
}
}
-
-// Support for java_lang_ref_Reference
-HeapWord *java_lang_ref_Reference::pending_list_lock_addr() {
- InstanceKlass* ik = SystemDictionary::Reference_klass();
- address addr = ik->static_field_addr(static_lock_offset);
- return (HeapWord*) addr;
-}
-
-oop java_lang_ref_Reference::pending_list_lock() {
- InstanceKlass* ik = SystemDictionary::Reference_klass();
- address addr = ik->static_field_addr(static_lock_offset);
- if (UseCompressedOops) {
- return oopDesc::load_decode_heap_oop((narrowOop *)addr);
- } else {
- return oopDesc::load_decode_heap_oop((oop*)addr);
- }
-}
-
-HeapWord *java_lang_ref_Reference::pending_list_addr() {
- InstanceKlass* ik = SystemDictionary::Reference_klass();
- address addr = ik->static_field_addr(static_pending_offset);
- // XXX This might not be HeapWord aligned, almost rather be char *.
- return (HeapWord*)addr;
-}
-
-oop java_lang_ref_Reference::pending_list() {
- char *addr = (char *)pending_list_addr();
- if (UseCompressedOops) {
- return oopDesc::load_decode_heap_oop((narrowOop *)addr);
- } else {
- return oopDesc::load_decode_heap_oop((oop*)addr);
- }
-}
-
-
// Support for java_lang_ref_SoftReference
jlong java_lang_ref_SoftReference::timestamp(oop ref) {
@@ -3616,8 +3581,6 @@
int java_lang_ref_Reference::queue_offset;
int java_lang_ref_Reference::next_offset;
int java_lang_ref_Reference::discovered_offset;
-int java_lang_ref_Reference::static_lock_offset;
-int java_lang_ref_Reference::static_pending_offset;
int java_lang_ref_Reference::number_of_fake_oop_fields;
int java_lang_ref_SoftReference::timestamp_offset;
int java_lang_ref_SoftReference::static_clock_offset;
@@ -3772,8 +3735,6 @@
java_lang_ref_Reference::queue_offset = java_lang_ref_Reference::hc_queue_offset * x + header;
java_lang_ref_Reference::next_offset = java_lang_ref_Reference::hc_next_offset * x + header;
java_lang_ref_Reference::discovered_offset = java_lang_ref_Reference::hc_discovered_offset * x + header;
- java_lang_ref_Reference::static_lock_offset = java_lang_ref_Reference::hc_static_lock_offset * x;
- java_lang_ref_Reference::static_pending_offset = java_lang_ref_Reference::hc_static_pending_offset * x;
// Artificial fields for java_lang_ref_Reference
// The first field is for the discovered field added in 1.4
java_lang_ref_Reference::number_of_fake_oop_fields = 1;
@@ -4006,8 +3967,6 @@
CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, next, "Ljava/lang/ref/Reference;");
// Fake field
//CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, discovered, "Ljava/lang/ref/Reference;");
- CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, lock, "Ljava/lang/ref/Reference$Lock;");
- CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, pending, "Ljava/lang/ref/Reference;");
// java.lang.ref.SoftReference
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -886,17 +886,11 @@
hc_next_offset = 2,
hc_discovered_offset = 3 // Is not last, see SoftRefs.
};
- enum {
- hc_static_lock_offset = 0,
- hc_static_pending_offset = 1
- };
static int referent_offset;
static int queue_offset;
static int next_offset;
static int discovered_offset;
- static int static_lock_offset;
- static int static_pending_offset;
static int number_of_fake_oop_fields;
// Accessors
@@ -912,13 +906,6 @@
static inline void set_discovered(oop ref, oop value);
static inline void set_discovered_raw(oop ref, oop value);
static inline HeapWord* discovered_addr(oop ref);
-
- // Accessors for statics
- static oop pending_list_lock();
- static oop pending_list();
-
- static HeapWord* pending_list_lock_addr();
- static HeapWord* pending_list_addr();
};
--- a/hotspot/src/share/vm/classfile/klassFactory.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/klassFactory.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -94,7 +94,7 @@
Symbol* name,
ClassLoaderData* loader_data,
Handle protection_domain,
- const Klass* host_klass,
+ const InstanceKlass* host_klass,
GrowableArray<Handle>* cp_patches,
TRAPS) {
--- a/hotspot/src/share/vm/classfile/klassFactory.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/klassFactory.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -72,7 +72,7 @@
Symbol* name,
ClassLoaderData* loader_data,
Handle protection_domain,
- const Klass* host_klass,
+ const InstanceKlass* host_klass,
GrowableArray<Handle>* cp_patches,
TRAPS);
};
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1027,7 +1027,7 @@
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
- const Klass* host_klass,
+ const InstanceKlass* host_klass,
GrowableArray<Handle>* cp_patches,
TRAPS) {
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -299,7 +299,7 @@
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
- const Klass* host_klass,
+ const InstanceKlass* host_klass,
GrowableArray<Handle>* cp_patches,
TRAPS);
--- a/hotspot/src/share/vm/classfile/verifier.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -67,12 +67,12 @@
static volatile jint _is_new_verify_byte_codes_fn = (jint) true;
static void* verify_byte_codes_fn() {
- if (_verify_byte_codes_fn == NULL) {
+ if (OrderAccess::load_ptr_acquire(&_verify_byte_codes_fn) == NULL) {
void *lib_handle = os::native_java_library();
void *func = os::dll_lookup(lib_handle, "VerifyClassCodesForMajorVersion");
OrderAccess::release_store_ptr(&_verify_byte_codes_fn, func);
if (func == NULL) {
- OrderAccess::release_store(&_is_new_verify_byte_codes_fn, false);
+ _is_new_verify_byte_codes_fn = false;
func = os::dll_lookup(lib_handle, "VerifyClassCodes");
OrderAccess::release_store_ptr(&_verify_byte_codes_fn, func);
}
@@ -88,7 +88,7 @@
BytecodeVerificationLocal : BytecodeVerificationRemote;
}
-bool Verifier::relax_verify_for(oop loader) {
+bool Verifier::relax_access_for(oop loader) {
bool trusted = java_lang_ClassLoader::is_trusted_loader(loader);
bool need_verify =
// verifyAll
@@ -2786,7 +2786,7 @@
// direct interface relative to the host class
have_imr_indirect = (have_imr_indirect &&
!is_same_or_direct_interface(
- InstanceKlass::cast(current_class()->host_klass()),
+ current_class()->host_klass(),
host_klass_type, ref_class_type));
}
if (!subtype) {
--- a/hotspot/src/share/vm/classfile/verifier.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, 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
@@ -58,8 +58,8 @@
// -Xverify:all/none override this value
static bool should_verify_for(oop class_loader, bool should_verify_class);
- // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2.
- static bool relax_verify_for(oop class_loader);
+ // Relax certain access checks to enable some broken 1.1 apps to run on 1.2.
+ static bool relax_access_for(oop class_loader);
// Print output for class+resolve
static void trace_class_resolution(Klass* resolve_class, InstanceKlass* verify_class);
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -366,6 +366,7 @@
switch(id) {
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime:
+ case vmIntrinsics::_getClassId:
#endif
case vmIntrinsics::_currentTimeMillis:
case vmIntrinsics::_nanoTime:
--- a/hotspot/src/share/vm/code/codeCache.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -437,7 +437,7 @@
* run the constructor for the CodeBlob subclass he is busy
* instantiating.
*/
-CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool strict) {
+CodeBlob* CodeCache::allocate(int size, int code_blob_type, int orig_code_blob_type) {
// Possibly wakes up the sweeper thread.
NMethodSweeper::notify(code_blob_type);
assert_locked_or_safepoint(CodeCache_lock);
@@ -455,32 +455,41 @@
cb = (CodeBlob*)heap->allocate(size);
if (cb != NULL) break;
if (!heap->expand_by(CodeCacheExpansionSize)) {
+ // Save original type for error reporting
+ if (orig_code_blob_type == CodeBlobType::All) {
+ orig_code_blob_type = code_blob_type;
+ }
// Expansion failed
- if (SegmentedCodeCache && !strict) {
+ if (SegmentedCodeCache) {
// Fallback solution: Try to store code in another code heap.
+ // NonNMethod -> MethodNonProfiled -> MethodProfiled (-> MethodNonProfiled)
// Note that in the sweeper, we check the reverse_free_ratio of the code heap
// and force stack scanning if less than 10% of the code heap are free.
int type = code_blob_type;
switch (type) {
case CodeBlobType::NonNMethod:
type = CodeBlobType::MethodNonProfiled;
- strict = false; // Allow recursive search for other heaps
- break;
- case CodeBlobType::MethodProfiled:
- type = CodeBlobType::MethodNonProfiled;
- strict = true;
break;
case CodeBlobType::MethodNonProfiled:
type = CodeBlobType::MethodProfiled;
- strict = true;
+ break;
+ case CodeBlobType::MethodProfiled:
+ // Avoid loop if we already tried that code heap
+ if (type == orig_code_blob_type) {
+ type = CodeBlobType::MethodNonProfiled;
+ }
break;
}
- if (heap_available(type)) {
- return allocate(size, type, strict);
+ if (type != code_blob_type && type != orig_code_blob_type && heap_available(type)) {
+ if (PrintCodeCacheExtension) {
+ tty->print_cr("Extension of %s failed. Trying to allocate in %s.",
+ heap->name(), get_code_heap(type)->name());
+ }
+ return allocate(size, type, orig_code_blob_type);
}
}
MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- CompileBroker::handle_full_code_cache(code_blob_type);
+ CompileBroker::handle_full_code_cache(orig_code_blob_type);
return NULL;
}
if (PrintCodeCacheExtension) {
--- a/hotspot/src/share/vm/code/codeCache.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/code/codeCache.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -126,7 +126,7 @@
static void initialize();
// Allocation/administration
- static CodeBlob* allocate(int size, int code_blob_type, bool strict = false); // allocates a new CodeBlob
+ static CodeBlob* allocate(int size, int code_blob_type, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob
static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled
static int alignment_unit(); // guaranteed alignment of all CodeBlobs
static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -32,7 +32,6 @@
#include "compiler/compileLog.hpp"
#include "compiler/compilerOracle.hpp"
#include "compiler/directivesParser.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
@@ -893,15 +892,6 @@
return;
}
- // If the requesting thread is holding the pending list lock
- // then we just return. We can't risk blocking while holding
- // the pending list lock or a 3-way deadlock may occur
- // between the reference handler thread, a GC (instigated
- // by a compiler thread), and compiled method registration.
- if (ReferencePendingListLocker::is_locked_by_self()) {
- return;
- }
-
if (TieredCompilation) {
// Tiered policy requires MethodCounters to exist before adding a method to
// the queue. Create if we don't have them yet.
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -3511,6 +3511,7 @@
conc_workers()->active_workers(),
Threads::number_of_non_daemon_threads());
num_workers = conc_workers()->update_active_workers(num_workers);
+ log_info(gc,task)("Using %u workers of %u for marking", num_workers, conc_workers()->total_workers());
CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -28,7 +28,6 @@
#include "gc/cms/concurrentMarkSweepThread.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -77,23 +76,6 @@
log_warning(gc)("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread);
}
- {
- MutexLockerEx x(CGC_lock, true);
- set_CMS_flag(CMS_cms_wants_token);
- assert(is_init_completed() && Universe::is_fully_initialized(), "ConcurrentGCThread::run() should have waited for this.");
-
- // Wait until the surrogate locker thread that will do
- // pending list locking on our behalf has been created.
- // We cannot start the SLT thread ourselves since we need
- // to be a JavaThread to do so.
- CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2);
- while (!ReferencePendingListLocker::is_initialized() && !should_terminate()) {
- CGC_lock->wait(true, 200);
- loopY.tick();
- }
- clear_CMS_flag(CMS_cms_wants_token);
- }
-
while (!should_terminate()) {
sleepBeforeNextCycle();
if (should_terminate()) break;
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -899,6 +899,8 @@
workers->active_workers(),
Threads::number_of_non_daemon_threads());
active_workers = workers->update_active_workers(active_workers);
+ log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers->total_workers());
+
_old_gen = gch->old_gen();
// If the next generation is too full to accommodate worst-case promotion
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -37,14 +37,6 @@
//////////////////////////////////////////////////////////
// Methods in abstract class VM_CMS_Operation
//////////////////////////////////////////////////////////
-void VM_CMS_Operation::acquire_pending_list_lock() {
- _pending_list_locker.lock();
-}
-
-void VM_CMS_Operation::release_and_notify_pending_list_lock() {
- _pending_list_locker.unlock();
-}
-
void VM_CMS_Operation::verify_before_gc() {
if (VerifyBeforeGC &&
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
@@ -85,17 +77,10 @@
assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
"Possible deadlock");
- if (needs_pending_list_lock()) {
- acquire_pending_list_lock();
- }
- // Get the Heap_lock after the pending_list_lock.
Heap_lock->lock();
if (lost_race()) {
assert(_prologue_succeeded == false, "Initialized in c'tor");
Heap_lock->unlock();
- if (needs_pending_list_lock()) {
- release_and_notify_pending_list_lock();
- }
} else {
_prologue_succeeded = true;
}
@@ -108,11 +93,10 @@
assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
"Possible deadlock");
- // Release the Heap_lock first.
+ if (Universe::has_reference_pending_list()) {
+ Heap_lock->notify_all();
+ }
Heap_lock->unlock();
- if (needs_pending_list_lock()) {
- release_and_notify_pending_list_lock();
- }
}
//////////////////////////////////////////////////////////
@@ -230,9 +214,11 @@
Thread* thr = Thread::current();
assert(thr->is_Java_thread(), "just checking");
JavaThread* jt = (JavaThread*)thr;
- // Release the Heap_lock first.
+
+ if (Universe::has_reference_pending_list()) {
+ Heap_lock->notify_all();
+ }
Heap_lock->unlock();
- release_and_notify_pending_list_lock();
// It is fine to test whether completed collections has
// exceeded our request count without locking because
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -28,7 +28,6 @@
#include "gc/cms/concurrentMarkSweepGeneration.hpp"
#include "gc/shared/gcCause.hpp"
#include "gc/shared/gcId.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "gc/shared/vmGCOperations.hpp"
#include "runtime/vm_operations.hpp"
@@ -52,9 +51,6 @@
class CMSCollector;
class VM_CMS_Operation: public VM_Operation {
- private:
- ReferencePendingListLocker _pending_list_locker;
-
protected:
CMSCollector* _collector; // associated collector
bool _prologue_succeeded; // whether doit_prologue succeeded
@@ -62,10 +58,6 @@
bool lost_race() const;
- // java.lang.ref.Reference support
- void acquire_pending_list_lock();
- void release_and_notify_pending_list_lock();
-
public:
VM_CMS_Operation(CMSCollector* collector):
_collector(collector),
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -175,7 +175,7 @@
TimeHelper::counter_to_millis(mark_end - mark_start));
CMCheckpointRootsFinalClosure final_cl(_cm);
- VM_CGC_Operation op(&final_cl, "Pause Remark", true /* needs_pll */);
+ VM_CGC_Operation op(&final_cl, "Pause Remark");
VMThread::execute(&op);
}
if (cm()->restart_for_overflow()) {
@@ -199,7 +199,7 @@
delay_to_keep_mmu(g1_policy, false /* cleanup */);
CMCleanUp cl_cl(_cm);
- VM_CGC_Operation op(&cl_cl, "Pause Cleanup", false /* needs_pll */);
+ VM_CGC_Operation op(&cl_cl, "Pause Cleanup");
VMThread::execute(&op);
} else {
// We don't want to update the marking status if a GC pause
--- a/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "code/codeCache.hpp"
#include "code/nmethod.hpp"
+#include "gc/g1/g1CodeRootSetTable.hpp"
#include "gc/g1/g1CodeCacheRemSet.hpp"
#include "gc/g1/heapRegion.hpp"
#include "memory/heap.hpp"
@@ -33,58 +34,13 @@
#include "utilities/hashtable.inline.hpp"
#include "utilities/stack.inline.hpp"
-class CodeRootSetTable : public Hashtable<nmethod*, mtGC> {
- friend class G1CodeRootSetTest;
- typedef HashtableEntry<nmethod*, mtGC> Entry;
-
- static CodeRootSetTable* volatile _purge_list;
-
- CodeRootSetTable* _purge_next;
-
- unsigned int compute_hash(nmethod* nm) {
- uintptr_t hash = (uintptr_t)nm;
- return hash ^ (hash >> 7); // code heap blocks are 128byte aligned
- }
-
- void remove_entry(Entry* e, Entry* previous);
- Entry* new_entry(nmethod* nm);
-
- public:
- CodeRootSetTable(int size) : Hashtable<nmethod*, mtGC>(size, sizeof(Entry)), _purge_next(NULL) {}
- ~CodeRootSetTable();
-
- // Needs to be protected locks
- bool add(nmethod* nm);
- bool remove(nmethod* nm);
+G1CodeRootSetTable* volatile G1CodeRootSetTable::_purge_list = NULL;
- // Can be called without locking
- bool contains(nmethod* nm);
-
- int entry_size() const { return BasicHashtable<mtGC>::entry_size(); }
-
- void copy_to(CodeRootSetTable* new_table);
- void nmethods_do(CodeBlobClosure* blk);
-
- template<typename CB>
- int remove_if(CB& should_remove);
-
- static void purge_list_append(CodeRootSetTable* tbl);
- static void purge();
-
- static size_t static_mem_size() {
- return sizeof(_purge_list);
- }
-
- size_t mem_size();
-};
-
-CodeRootSetTable* volatile CodeRootSetTable::_purge_list = NULL;
-
-size_t CodeRootSetTable::mem_size() {
- return sizeof(CodeRootSetTable) + (entry_size() * number_of_entries()) + (sizeof(HashtableBucket<mtGC>) * table_size());
+size_t G1CodeRootSetTable::mem_size() {
+ return sizeof(G1CodeRootSetTable) + (entry_size() * number_of_entries()) + (sizeof(HashtableBucket<mtGC>) * table_size());
}
-CodeRootSetTable::Entry* CodeRootSetTable::new_entry(nmethod* nm) {
+G1CodeRootSetTable::Entry* G1CodeRootSetTable::new_entry(nmethod* nm) {
unsigned int hash = compute_hash(nm);
Entry* entry = (Entry*) new_entry_free_list();
if (entry == NULL) {
@@ -96,7 +52,7 @@
return entry;
}
-void CodeRootSetTable::remove_entry(Entry* e, Entry* previous) {
+void G1CodeRootSetTable::remove_entry(Entry* e, Entry* previous) {
int index = hash_to_index(e->hash());
assert((e == bucket(index)) == (previous == NULL), "if e is the first entry then previous should be null");
@@ -108,7 +64,7 @@
free_entry(e);
}
-CodeRootSetTable::~CodeRootSetTable() {
+G1CodeRootSetTable::~G1CodeRootSetTable() {
for (int index = 0; index < table_size(); ++index) {
for (Entry* e = bucket(index); e != NULL; ) {
Entry* to_remove = e;
@@ -125,7 +81,7 @@
}
}
-bool CodeRootSetTable::add(nmethod* nm) {
+bool G1CodeRootSetTable::add(nmethod* nm) {
if (!contains(nm)) {
Entry* e = new_entry(nm);
int index = hash_to_index(e->hash());
@@ -135,7 +91,7 @@
return false;
}
-bool CodeRootSetTable::contains(nmethod* nm) {
+bool G1CodeRootSetTable::contains(nmethod* nm) {
int index = hash_to_index(compute_hash(nm));
for (Entry* e = bucket(index); e != NULL; e = e->next()) {
if (e->literal() == nm) {
@@ -145,7 +101,7 @@
return false;
}
-bool CodeRootSetTable::remove(nmethod* nm) {
+bool G1CodeRootSetTable::remove(nmethod* nm) {
int index = hash_to_index(compute_hash(nm));
Entry* previous = NULL;
for (Entry* e = bucket(index); e != NULL; previous = e, e = e->next()) {
@@ -157,7 +113,7 @@
return false;
}
-void CodeRootSetTable::copy_to(CodeRootSetTable* new_table) {
+void G1CodeRootSetTable::copy_to(G1CodeRootSetTable* new_table) {
for (int index = 0; index < table_size(); ++index) {
for (Entry* e = bucket(index); e != NULL; e = e->next()) {
new_table->add(e->literal());
@@ -166,7 +122,7 @@
new_table->copy_freelist(this);
}
-void CodeRootSetTable::nmethods_do(CodeBlobClosure* blk) {
+void G1CodeRootSetTable::nmethods_do(CodeBlobClosure* blk) {
for (int index = 0; index < table_size(); ++index) {
for (Entry* e = bucket(index); e != NULL; e = e->next()) {
blk->do_code_blob(e->literal());
@@ -175,7 +131,7 @@
}
template<typename CB>
-int CodeRootSetTable::remove_if(CB& should_remove) {
+int G1CodeRootSetTable::remove_if(CB& should_remove) {
int num_removed = 0;
for (int index = 0; index < table_size(); ++index) {
Entry* previous = NULL;
@@ -198,52 +154,52 @@
delete _table;
}
-CodeRootSetTable* G1CodeRootSet::load_acquire_table() {
- return (CodeRootSetTable*) OrderAccess::load_ptr_acquire(&_table);
+G1CodeRootSetTable* G1CodeRootSet::load_acquire_table() {
+ return (G1CodeRootSetTable*) OrderAccess::load_ptr_acquire(&_table);
}
void G1CodeRootSet::allocate_small_table() {
- CodeRootSetTable* temp = new CodeRootSetTable(SmallSize);
+ G1CodeRootSetTable* temp = new G1CodeRootSetTable(SmallSize);
OrderAccess::release_store_ptr(&_table, temp);
}
-void CodeRootSetTable::purge_list_append(CodeRootSetTable* table) {
+void G1CodeRootSetTable::purge_list_append(G1CodeRootSetTable* table) {
for (;;) {
table->_purge_next = _purge_list;
- CodeRootSetTable* old = (CodeRootSetTable*) Atomic::cmpxchg_ptr(table, &_purge_list, table->_purge_next);
+ G1CodeRootSetTable* old = (G1CodeRootSetTable*) Atomic::cmpxchg_ptr(table, &_purge_list, table->_purge_next);
if (old == table->_purge_next) {
break;
}
}
}
-void CodeRootSetTable::purge() {
- CodeRootSetTable* table = _purge_list;
+void G1CodeRootSetTable::purge() {
+ G1CodeRootSetTable* table = _purge_list;
_purge_list = NULL;
while (table != NULL) {
- CodeRootSetTable* to_purge = table;
+ G1CodeRootSetTable* to_purge = table;
table = table->_purge_next;
delete to_purge;
}
}
void G1CodeRootSet::move_to_large() {
- CodeRootSetTable* temp = new CodeRootSetTable(LargeSize);
+ G1CodeRootSetTable* temp = new G1CodeRootSetTable(LargeSize);
_table->copy_to(temp);
- CodeRootSetTable::purge_list_append(_table);
+ G1CodeRootSetTable::purge_list_append(_table);
OrderAccess::release_store_ptr(&_table, temp);
}
void G1CodeRootSet::purge() {
- CodeRootSetTable::purge();
+ G1CodeRootSetTable::purge();
}
size_t G1CodeRootSet::static_mem_size() {
- return CodeRootSetTable::static_mem_size();
+ return G1CodeRootSetTable::static_mem_size();
}
void G1CodeRootSet::add(nmethod* method) {
@@ -278,7 +234,7 @@
}
bool G1CodeRootSet::contains(nmethod* method) {
- CodeRootSetTable* table = load_acquire_table(); // contains() may be called outside of lock, so ensure mem sync.
+ G1CodeRootSetTable* table = load_acquire_table(); // contains() may be called outside of lock, so ensure mem sync.
if (table != NULL) {
return table->contains(method);
}
@@ -348,67 +304,3 @@
clear();
}
}
-
-#ifndef PRODUCT
-
-class G1CodeRootSetTest {
- public:
- static void test() {
- {
- G1CodeRootSet set1;
- assert(set1.is_empty(), "Code root set must be initially empty but is not.");
-
- assert(G1CodeRootSet::static_mem_size() == sizeof(void*),
- "The code root set's static memory usage is incorrect, " SIZE_FORMAT " bytes", G1CodeRootSet::static_mem_size());
-
- set1.add((nmethod*)1);
- assert(set1.length() == 1, "Added exactly one element, but set contains "
- SIZE_FORMAT " elements", set1.length());
-
- const size_t num_to_add = (size_t)G1CodeRootSet::Threshold + 1;
-
- for (size_t i = 1; i <= num_to_add; i++) {
- set1.add((nmethod*)1);
- }
- assert(set1.length() == 1,
- "Duplicate detection should not have increased the set size but "
- "is " SIZE_FORMAT, set1.length());
-
- for (size_t i = 2; i <= num_to_add; i++) {
- set1.add((nmethod*)(uintptr_t)(i));
- }
- assert(set1.length() == num_to_add,
- "After adding in total " SIZE_FORMAT " distinct code roots, they "
- "need to be in the set, but there are only " SIZE_FORMAT,
- num_to_add, set1.length());
-
- assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
-
- size_t num_popped = 0;
- for (size_t i = 1; i <= num_to_add; i++) {
- bool removed = set1.remove((nmethod*)i);
- if (removed) {
- num_popped += 1;
- } else {
- break;
- }
- }
- assert(num_popped == num_to_add,
- "Managed to pop " SIZE_FORMAT " code roots, but only " SIZE_FORMAT " "
- "were added", num_popped, num_to_add);
- assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
-
- G1CodeRootSet::purge();
-
- assert(CodeRootSetTable::_purge_list == NULL, "should have purged old small tables");
-
- }
-
- }
-};
-
-void TestCodeCacheRemSet_test() {
- G1CodeRootSetTest::test();
-}
-
-#endif
--- a/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -28,7 +28,7 @@
#include "memory/allocation.hpp"
class CodeBlobClosure;
-class CodeRootSetTable;
+class G1CodeRootSetTable;
class HeapRegion;
class nmethod;
@@ -42,8 +42,8 @@
const static size_t Threshold = 24;
const static size_t LargeSize = 512;
- CodeRootSetTable* _table;
- CodeRootSetTable* load_acquire_table();
+ G1CodeRootSetTable* _table;
+ G1CodeRootSetTable* load_acquire_table();
size_t _length;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CodeRootSetTable.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CODEROOTSETTABLE_HPP
+#define SHARE_VM_GC_G1_G1CODEROOTSETTABLE_HPP
+
+#include "utilities/hashtable.hpp"
+
+class nmethod;
+
+class G1CodeRootSetTable : public Hashtable<nmethod*, mtGC> {
+ friend class G1CodeRootSetTest;
+ typedef HashtableEntry<nmethod*, mtGC> Entry;
+
+ static G1CodeRootSetTable* volatile _purge_list;
+
+ G1CodeRootSetTable* _purge_next;
+
+ unsigned int compute_hash(nmethod* nm) {
+ uintptr_t hash = (uintptr_t)nm;
+ return hash ^ (hash >> 7); // code heap blocks are 128byte aligned
+ }
+
+ void remove_entry(Entry* e, Entry* previous);
+ Entry* new_entry(nmethod* nm);
+
+ public:
+ G1CodeRootSetTable(int size) : Hashtable<nmethod*, mtGC>(size, sizeof(Entry)), _purge_next(NULL) {}
+ ~G1CodeRootSetTable();
+
+ // Needs to be protected by locks
+ bool add(nmethod* nm);
+ bool remove(nmethod* nm);
+
+ // Can be called without locking
+ bool contains(nmethod* nm);
+
+ int entry_size() const { return BasicHashtable<mtGC>::entry_size(); }
+
+ void copy_to(G1CodeRootSetTable* new_table);
+ void nmethods_do(CodeBlobClosure* blk);
+
+ template<typename CB>
+ int remove_if(CB& should_remove);
+
+ static void purge_list_append(G1CodeRootSetTable* tbl);
+ static void purge();
+
+ static size_t static_mem_size() {
+ return sizeof(_purge_list);
+ }
+
+ size_t mem_size();
+};
+
+#endif /* SHARE_VM_GC_G1_G1CODEROOTSETTABLE_HPP */
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1332,6 +1332,7 @@
workers()->active_workers(),
Threads::number_of_non_daemon_threads());
workers()->update_active_workers(n_workers);
+ log_info(gc,task)("Using %u workers of %u to rebuild remembered set", n_workers, workers()->total_workers());
ParRebuildRSTask rebuild_rs_task(this);
workers()->run_task(&rebuild_rs_task);
@@ -3068,6 +3069,7 @@
workers()->active_workers(),
Threads::number_of_non_daemon_threads());
workers()->update_active_workers(active_workers);
+ log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers()->total_workers());
TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
@@ -4513,6 +4515,7 @@
#if defined(COMPILER2) || INCLUDE_JVMCI
DerivedPointerTable::update_pointers();
#endif
+ g1_policy()->print_age_table();
}
void G1CollectedHeap::record_obj_copy_mem_stats() {
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -1273,12 +1273,6 @@
return true;
}
- // The reference pending list lock is acquired from from the
- // ConcurrentMarkThread.
- virtual bool needs_reference_pending_list_locker_thread() const {
- return true;
- }
-
inline bool is_in_young(const oop obj);
virtual bool is_scavengable(const void* addr);
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1035,6 +1035,8 @@
// worker threads may currently exist and more may not be
// available.
active_workers = _parallel_workers->update_active_workers(active_workers);
+ log_info(gc, task)("Using %u workers of %u for marking", active_workers, _parallel_workers->total_workers());
+
// Parallel task terminator is set in "set_concurrency_and_phase()"
set_concurrency_and_phase(active_workers, true /* concurrent */);
--- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -885,6 +885,15 @@
return _young_gen_sizer.adaptive_young_list_length();
}
+size_t G1DefaultPolicy::desired_survivor_size() const {
+ size_t const survivor_capacity = HeapRegion::GrainWords * _max_survivor_regions;
+ return (size_t)((((double)survivor_capacity) * TargetSurvivorRatio) / 100);
+}
+
+void G1DefaultPolicy::print_age_table() {
+ _survivors_age_table.print_age_table(_tenuring_threshold);
+}
+
void G1DefaultPolicy::update_max_gc_locker_expansion() {
uint expansion_region_num = 0;
if (GCLockerEdenExpansionPercent > 0) {
@@ -908,8 +917,11 @@
// smaller than 1.0) we'll get 1.
_max_survivor_regions = (uint) ceil(max_survivor_regions_d);
- _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
- HeapRegion::GrainWords * _max_survivor_regions, _policy_counters);
+ _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(desired_survivor_size());
+ if (UsePerfData) {
+ _policy_counters->tenuring_threshold()->set_value(_tenuring_threshold);
+ _policy_counters->desired_survivor_size()->set_value(desired_survivor_size() * oopSize);
+ }
}
bool G1DefaultPolicy::force_initial_mark_if_outside_cycle(GCCause::Cause gc_cause) {
--- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -360,6 +360,8 @@
AgeTable _survivors_age_table;
+protected:
+ size_t desired_survivor_size() const;
public:
uint tenuring_threshold() const { return _tenuring_threshold; }
@@ -379,6 +381,8 @@
_survivors_age_table.merge(age_table);
}
+ void print_age_table();
+
void update_max_gc_locker_expansion();
void update_survivors_policy();
--- a/hotspot/src/share/vm/gc/g1/g1Policy.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1Policy.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -181,6 +181,9 @@
virtual void note_stop_adding_survivor_regions() = 0;
virtual void record_age_table(AgeTable* age_table) = 0;
+ virtual void print_age_table() = 0;
+protected:
+ virtual size_t desired_survivor_size() const = 0;
};
#endif // SHARE_VM_GC_G1_G1POLICY_HPP
--- a/hotspot/src/share/vm/gc/g1/g1Predictions.cpp Fri Sep 16 10:57:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/g1Predictions.hpp"
-
-#ifndef PRODUCT
-
-void G1Predictions::test() {
- double const epsilon = 1e-6;
- {
- // Some basic formula tests with confidence = 0.0
- G1Predictions predictor(0.0);
- TruncatedSeq s;
-
- double p0 = predictor.get_new_prediction(&s);
- assert(p0 < epsilon, "Initial prediction of empty sequence must be 0.0 but is %f", p0);
-
- s.add(5.0);
- double p1 = predictor.get_new_prediction(&s);
- assert(fabs(p1 - 5.0) < epsilon, "Prediction should be 5.0 but is %f", p1);
- for (int i = 0; i < 40; i++) {
- s.add(5.0);
- }
- double p2 = predictor.get_new_prediction(&s);
- assert(fabs(p2 - 5.0) < epsilon, "Prediction should be 5.0 but is %f", p1);
- }
-
- {
- // The following tests checks that the initial predictions are based on the
- // average of the sequence and not on the stddev (which is 0).
- G1Predictions predictor(0.5);
- TruncatedSeq s;
-
- s.add(1.0);
- double p1 = predictor.get_new_prediction(&s);
- assert(p1 > 1.0, "First prediction must be larger than average, but avg is %f and prediction %f", s.davg(), p1);
- s.add(1.0);
- double p2 = predictor.get_new_prediction(&s);
- assert(p2 < p1, "First prediction must be larger than second, but they are %f %f", p1, p2);
- s.add(1.0);
- double p3 = predictor.get_new_prediction(&s);
- assert(p3 < p2, "Second prediction must be larger than third, but they are %f %f", p2, p3);
- s.add(1.0);
- s.add(1.0); // Five elements are now in the sequence.
- double p5 = predictor.get_new_prediction(&s);
- assert(p5 < p3, "Fifth prediction must be smaller than third, but they are %f %f", p3, p5);
- assert(fabs(p5 - 1.0) < epsilon, "Prediction must be 1.0+epsilon, but is %f", p5);
- }
-
- {
- // The following tests checks that initially prediction based on the average is
- // used, that gets overridden by the stddev prediction at the end.
- G1Predictions predictor(0.5);
- TruncatedSeq s;
-
- s.add(0.5);
- double p1 = predictor.get_new_prediction(&s);
- assert(p1 > 0.5, "First prediction must be larger than average, but avg is %f and prediction %f", s.davg(), p1);
- s.add(0.2);
- double p2 = predictor.get_new_prediction(&s);
- assert(p2 < p1, "First prediction must be larger than second, but they are %f %f", p1, p2);
- s.add(0.5);
- double p3 = predictor.get_new_prediction(&s);
- assert(p3 < p2, "Second prediction must be larger than third, but they are %f %f", p2, p3);
- s.add(0.2);
- s.add(2.0);
- double p5 = predictor.get_new_prediction(&s);
- assert(p5 > p3, "Fifth prediction must be bigger than third, but they are %f %f", p3, p5);
- }
-}
-
-void TestPredictions_test() {
- G1Predictions::test();
-}
-
-#endif
--- a/hotspot/src/share/vm/gc/g1/g1Predictions.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1Predictions.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,10 +57,6 @@
double get_new_prediction(TruncatedSeq const* seq) const {
return seq->davg() + _sigma * stddev_estimate(seq);
}
-
-#ifndef PRODUCT
- static void test();
-#endif
};
#endif // SHARE_VM_GC_G1_G1PREDICTIONS_HPP
--- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -204,14 +204,6 @@
}
}
-void VM_CGC_Operation::acquire_pending_list_lock() {
- _pending_list_locker.lock();
-}
-
-void VM_CGC_Operation::release_and_notify_pending_list_lock() {
- _pending_list_locker.unlock();
-}
-
void VM_CGC_Operation::doit() {
GCIdMark gc_id_mark(_gc_id);
GCTraceCPUTime tcpu;
@@ -222,20 +214,13 @@
}
bool VM_CGC_Operation::doit_prologue() {
- // Note the relative order of the locks must match that in
- // VM_GC_Operation::doit_prologue() or deadlocks can occur
- if (_needs_pending_list_lock) {
- acquire_pending_list_lock();
- }
Heap_lock->lock();
return true;
}
void VM_CGC_Operation::doit_epilogue() {
- // Note the relative order of the unlocks must match that in
- // VM_GC_Operation::doit_epilogue()
+ if (Universe::has_reference_pending_list()) {
+ Heap_lock->notify_all();
+ }
Heap_lock->unlock();
- if (_needs_pending_list_lock) {
- release_and_notify_pending_list_lock();
- }
}
--- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -27,7 +27,6 @@
#include "gc/g1/g1AllocationContext.hpp"
#include "gc/shared/gcId.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "gc/shared/vmGCOperations.hpp"
// VM_operations for the G1 collector.
@@ -103,20 +102,13 @@
// Concurrent GC stop-the-world operations such as remark and cleanup;
// consider sharing these with CMS's counterparts.
class VM_CGC_Operation: public VM_Operation {
- VoidClosure* _cl;
- const char* _printGCMessage;
- bool _needs_pending_list_lock;
- ReferencePendingListLocker _pending_list_locker;
- uint _gc_id;
-
-protected:
- // java.lang.ref.Reference support
- void acquire_pending_list_lock();
- void release_and_notify_pending_list_lock();
+ VoidClosure* _cl;
+ const char* _printGCMessage;
+ uint _gc_id;
public:
- VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg, bool needs_pending_list_lock)
- : _cl(cl), _printGCMessage(printGCMsg), _needs_pending_list_lock(needs_pending_list_lock), _gc_id(GCId::current()) {}
+ VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg)
+ : _cl(cl), _printGCMessage(printGCMsg), _gc_id(GCId::current()) {}
virtual VMOp_Type type() const { return VMOp_CGC_Operation; }
virtual void doit();
virtual bool doit_prologue();
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1133,18 +1133,3 @@
return false;
}
-
-#ifndef PRODUCT
-
-void TestOldFreeSpaceCalculation_test() {
- assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 20) == 25, "Calculation of free memory failed");
- assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 50) == 100, "Calculation of free memory failed");
- assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 60) == 150, "Calculation of free memory failed");
- assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 75) == 300, "Calculation of free memory failed");
- assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 20) == 100, "Calculation of free memory failed");
- assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 50) == 400, "Calculation of free memory failed");
- assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 60) == 600, "Calculation of free memory failed");
- assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 75) == 1200, "Calculation of free memory failed");
-}
-
-#endif /* !PRODUCT */
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -564,9 +564,18 @@
void DefNewGeneration::adjust_desired_tenuring_threshold() {
// Set the desired survivor size to half the real survivor space
- GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->gen_policy()->counters();
- _tenuring_threshold =
- age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize, gc_counters);
+ size_t const survivor_capacity = to()->capacity() / HeapWordSize;
+ size_t const desired_survivor_size = (size_t)((((double)survivor_capacity) * TargetSurvivorRatio) / 100);
+
+ _tenuring_threshold = age_table()->compute_tenuring_threshold(desired_survivor_size);
+
+ if (UsePerfData) {
+ GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->gen_policy()->counters();
+ gc_counters->tenuring_threshold()->set_value(_tenuring_threshold);
+ gc_counters->desired_survivor_size()->set_value(desired_survivor_size * oopSize);
+ }
+
+ age_table()->print_age_table(_tenuring_threshold);
}
void DefNewGeneration::collect(bool full,
--- a/hotspot/src/share/vm/gc/shared/ageTable.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/ageTable.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -27,7 +27,6 @@
#include "gc/shared/ageTableTracer.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/collectorPolicy.hpp"
-#include "gc/shared/gcPolicyCounters.hpp"
#include "memory/resourceArea.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp"
@@ -75,8 +74,7 @@
}
}
-uint AgeTable::compute_tenuring_threshold(size_t survivor_capacity, GCPolicyCounters* gc_counters) {
- size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
+uint AgeTable::compute_tenuring_threshold(size_t desired_survivor_size) {
uint result;
if (AlwaysTenure || NeverTenure) {
@@ -99,9 +97,16 @@
log_debug(gc, age)("Desired survivor size " SIZE_FORMAT " bytes, new threshold " UINTX_FORMAT " (max threshold " UINTX_FORMAT ")",
- desired_survivor_size*oopSize, (uintx) result, MaxTenuringThreshold);
+ desired_survivor_size * oopSize, (uintx) result, MaxTenuringThreshold);
+
+ return result;
+}
+void AgeTable::print_age_table(uint tenuring_threshold) {
if (log_is_enabled(Trace, gc, age) || UsePerfData || AgeTableTracer::is_tenuring_distribution_event_enabled()) {
+ log_trace(gc, age)("Age table with threshold %u (max threshold " UINTX_FORMAT ")",
+ tenuring_threshold, MaxTenuringThreshold);
+
size_t total = 0;
uint age = 1;
while (age < table_size) {
@@ -109,20 +114,14 @@
total += wordSize;
if (wordSize > 0) {
log_trace(gc, age)("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total",
- age, wordSize*oopSize, total*oopSize);
+ age, wordSize * oopSize, total * oopSize);
}
- AgeTableTracer::send_tenuring_distribution_event(age, wordSize*oopSize);
+ AgeTableTracer::send_tenuring_distribution_event(age, wordSize * oopSize);
if (UsePerfData) {
- _perf_sizes[age]->set_value(wordSize*oopSize);
+ _perf_sizes[age]->set_value(wordSize * oopSize);
}
age++;
}
- if (UsePerfData) {
- gc_counters->tenuring_threshold()->set_value(result);
- gc_counters->desired_survivor_size()->set_value(
- desired_survivor_size*oopSize);
- }
}
+}
- return result;
-}
--- a/hotspot/src/share/vm/gc/shared/ageTable.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/ageTable.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -29,8 +29,6 @@
#include "oops/oop.hpp"
#include "runtime/perfData.hpp"
-class GCPolicyCounters;
-
/* Copyright (c) 1992, 2016, Oracle and/or its affiliates, and Stanford University.
See the LICENSE file for license information. */
@@ -67,10 +65,12 @@
// for parallel young generation gc.
void merge(AgeTable* subTable);
- // calculate new tenuring threshold based on age information
- uint compute_tenuring_threshold(size_t survivor_capacity, GCPolicyCounters* gc_counters);
+ // Calculate new tenuring threshold based on age information.
+ uint compute_tenuring_threshold(size_t desired_survivor_size);
+ void print_age_table(uint tenuring_threshold);
private:
+
PerfVariable* _perf_sizes[table_size];
};
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -441,12 +441,6 @@
// remembered set.
virtual void flush_deferred_store_barrier(JavaThread* thread);
- // Should return true if the reference pending list lock is
- // acquired from non-Java threads, such as a concurrent GC thread.
- virtual bool needs_reference_pending_list_locker_thread() const {
- return false;
- }
-
// Perform a collection of the heap; intended for use in implementing
// "System.gc". This probably implies as full a collection as the
// "CollectedHeap" supports.
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -281,10 +281,6 @@
return UseConcMarkSweepGC;
}
- virtual bool needs_reference_pending_list_locker_thread() const {
- return UseConcMarkSweepGC;
- }
-
// We don't need barriers for stores to objects in the
// young gen and, a fortiori, for initializing stores to
// objects therein. This applies to DefNew+Tenured and ParNew+CMS
--- a/hotspot/src/share/vm/gc/shared/memset_with_concurrent_readers.cpp Fri Sep 16 10:57:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- *
- */
-
-#include "precompiled.hpp"
-
-#include <string.h>
-#include "gc/shared/memset_with_concurrent_readers.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/macros.hpp"
-#include "utilities/ostream.hpp"
-
-#if INCLUDE_ALL_GCS
-
-// Unit test
-#ifndef PRODUCT
-
-static unsigned line_byte(const char* line, size_t i) {
- return unsigned(line[i]) & 0xFF;
-}
-
-// Verify memset_with_concurrent_readers mimics memset.
-// We don't attempt to verify the concurrent reader case.
-void test_memset_with_concurrent_readers() {
- const size_t chunk_size = 8 * BytesPerWord;
- const unsigned chunk_count = 4;
- const size_t block_size = (chunk_count + 4) * chunk_size;
- char block[block_size];
- char clear_block[block_size];
- char set_block[block_size];
-
- // block format:
- // 0: unused leading chunk
- // 1: chunk written from start index to end of chunk
- // ... nchunks fully written chunks
- // N: chunk written from start of chunk to end index
- // N+1: unused trailing chunk
-
- const int clear_value = 0;
- const int set_value = 0xAC;
-
- memset(clear_block, clear_value, block_size);
- memset(set_block, set_value, block_size);
-
- for (unsigned nchunks = 0; nchunks <= chunk_count; ++nchunks) {
- for (size_t start = 1; start <= chunk_size; ++start) {
- for (size_t end = 0; end <= chunk_size; ++end) {
- size_t set_start = chunk_size + start;
- size_t set_end = (2 + nchunks) * chunk_size + end;
- size_t set_size = set_end - set_start;
-
- memset(block, clear_value, block_size);
- memset_with_concurrent_readers(&block[set_start], set_value, set_size);
- bool head_clear = !memcmp(clear_block, block, set_start);
- bool middle_set = !memcmp(set_block, block + set_start, set_size);
- bool tail_clear = !memcmp(clear_block, block + set_end, block_size - set_end);
- if (!(head_clear && middle_set && tail_clear)) {
- tty->print_cr("*** memset_with_concurrent_readers failed: "
- "set start " SIZE_FORMAT ", set end " SIZE_FORMAT,
- set_start, set_end);
- for (unsigned chunk = 0; chunk < (block_size / chunk_size); ++chunk) {
- for (unsigned line = 0; line < (chunk_size / BytesPerWord); ++line) {
- const char* lp = &block[chunk * chunk_size + line * BytesPerWord];
- tty->print_cr("%d,%d: %2x %2x %2x %2x %2x %2x %2x %2x",
- chunk, line,
- line_byte(lp, 0), line_byte(lp, 1),
- line_byte(lp, 2), line_byte(lp, 3),
- line_byte(lp, 4), line_byte(lp, 5),
- line_byte(lp, 6), line_byte(lp, 7));
- }
- }
- assert(head_clear, "leading byte not clear");
- assert(middle_set, "memset byte not set");
- assert(tail_clear, "trailing bye not clear");
- }
- }
- }
- }
-}
-
-#endif // end unit test
-
-#endif // INCLUDE_ALL_GCS
--- a/hotspot/src/share/vm/gc/shared/referencePendingListLocker.cpp Fri Sep 16 10:57:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/javaClasses.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "gc/shared/collectedHeap.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
-#include "memory/universe.hpp"
-#include "runtime/javaCalls.hpp"
-#include "utilities/preserveException.hpp"
-
-ReferencePendingListLockerThread::ReferencePendingListLockerThread() :
- JavaThread(&start),
- _monitor(Monitor::nonleaf, "ReferencePendingListLocker", false, Monitor::_safepoint_check_sometimes),
- _message(NONE) {}
-
-ReferencePendingListLockerThread* ReferencePendingListLockerThread::create(TRAPS) {
- // Create Java thread objects
- instanceKlassHandle thread_klass = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL);
- instanceHandle thread_object = thread_klass->allocate_instance_handle(CHECK_NULL);
- Handle thread_name = java_lang_String::create_from_str("Reference Pending List Locker", CHECK_NULL);
- Handle thread_group = Universe::system_thread_group();
- JavaValue result(T_VOID);
- JavaCalls::call_special(&result,
- thread_object,
- thread_klass,
- vmSymbols::object_initializer_name(),
- vmSymbols::threadgroup_string_void_signature(),
- thread_group,
- thread_name,
- CHECK_NULL);
-
- {
- MutexLocker ml(Threads_lock);
-
- // Allocate thread
- ReferencePendingListLockerThread* thread = new ReferencePendingListLockerThread();
- if (thread == NULL || thread->osthread() == NULL) {
- vm_exit_during_initialization("java.lang.OutOfMemoryError",
- os::native_thread_creation_failed_msg());
- }
-
- // Initialize thread
- java_lang_Thread::set_thread(thread_object(), thread);
- java_lang_Thread::set_priority(thread_object(), NearMaxPriority);
- java_lang_Thread::set_daemon(thread_object());
- thread->set_threadObj(thread_object());
-
- // Start thread
- Threads::add(thread);
- Thread::start(thread);
-
- return thread;
- }
-}
-
-void ReferencePendingListLockerThread::start(JavaThread* thread, TRAPS) {
- ReferencePendingListLockerThread* locker_thread = static_cast<ReferencePendingListLockerThread*>(thread);
- locker_thread->receive_and_handle_messages();
-}
-
-bool ReferencePendingListLockerThread::is_hidden_from_external_view() const {
- return true;
-}
-
-void ReferencePendingListLockerThread::send_message(Message message) {
- assert(message != NONE, "Should not be none");
- MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
-
- // Wait for completion of current message
- while (_message != NONE) {
- ml.wait(Monitor::_no_safepoint_check_flag);
- }
-
- // Send new message
- _message = message;
- ml.notify_all();
-
- // Wait for completion of new message
- while (_message != NONE) {
- ml.wait(Monitor::_no_safepoint_check_flag);
- }
-}
-
-void ReferencePendingListLockerThread::receive_and_handle_messages() {
- ReferencePendingListLocker pending_list_locker;
- MonitorLockerEx ml(&_monitor);
-
- // Main loop, never terminates
- for (;;) {
- // Wait for message
- while (_message == NONE) {
- ml.wait();
- }
-
- // Handle message
- if (_message == LOCK) {
- pending_list_locker.lock();
- } else if (_message == UNLOCK) {
- pending_list_locker.unlock();
- } else {
- ShouldNotReachHere();
- }
-
- // Clear message
- _message = NONE;
- ml.notify_all();
- }
-}
-
-void ReferencePendingListLockerThread::lock() {
- send_message(LOCK);
-}
-
-void ReferencePendingListLockerThread::unlock() {
- send_message(UNLOCK);
-}
-
-bool ReferencePendingListLocker::_is_initialized = false;
-ReferencePendingListLockerThread* ReferencePendingListLocker::_locker_thread = NULL;
-
-void ReferencePendingListLocker::initialize(bool needs_locker_thread, TRAPS) {
- if (needs_locker_thread) {
- _locker_thread = ReferencePendingListLockerThread::create(CHECK);
- }
-
- _is_initialized = true;
-}
-
-bool ReferencePendingListLocker::is_initialized() {
- return _is_initialized;
-}
-
-bool ReferencePendingListLocker::is_locked_by_self() {
- oop pending_list_lock = java_lang_ref_Reference::pending_list_lock();
- if (pending_list_lock == NULL) {
- return false;
- }
-
- JavaThread* thread = JavaThread::current();
- Handle handle(thread, pending_list_lock);
- return ObjectSynchronizer::current_thread_holds_lock(thread, handle);
-}
-
-void ReferencePendingListLocker::lock() {
- assert(!Heap_lock->owned_by_self(), "Heap_lock must not be owned by requesting thread");
-
- if (Thread::current()->is_Java_thread()) {
- assert(java_lang_ref_Reference::pending_list_lock() != NULL, "Not initialized");
-
- // We may enter this with a pending exception
- PRESERVE_EXCEPTION_MARK;
-
- HandleMark hm;
- Handle handle(THREAD, java_lang_ref_Reference::pending_list_lock());
-
- // Lock
- ObjectSynchronizer::fast_enter(handle, &_basic_lock, false, THREAD);
-
- assert(is_locked_by_self(), "Locking failed");
-
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- }
- } else {
- // Delegate operation to locker thread
- assert(_locker_thread != NULL, "Locker thread not created");
- _locker_thread->lock();
- }
-}
-
-void ReferencePendingListLocker::unlock() {
- if (Thread::current()->is_Java_thread()) {
- assert(java_lang_ref_Reference::pending_list_lock() != NULL, "Not initialized");
-
- // We may enter this with a pending exception
- PRESERVE_EXCEPTION_MARK;
-
- HandleMark hm;
- Handle handle(THREAD, java_lang_ref_Reference::pending_list_lock());
-
- assert(is_locked_by_self(), "Should be locked by self");
-
- // Notify waiters if the pending list is non-empty
- if (java_lang_ref_Reference::pending_list() != NULL) {
- ObjectSynchronizer::notifyall(handle, THREAD);
- }
-
- // Unlock
- ObjectSynchronizer::fast_exit(handle(), &_basic_lock, THREAD);
-
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- }
- } else {
- // Delegate operation to locker thread
- assert(_locker_thread != NULL, "Locker thread not created");
- _locker_thread->unlock();
- }
-}
--- a/hotspot/src/share/vm/gc/shared/referencePendingListLocker.hpp Fri Sep 16 10:57:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * 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.
- *
- */
-
-#ifndef SHARE_VM_GC_SHARED_REFERENCEPENDINGLISTLOCKER_HPP
-#define SHARE_VM_GC_SHARED_REFERENCEPENDINGLISTLOCKER_HPP
-
-#include "memory/allocation.hpp"
-#include "runtime/basicLock.hpp"
-#include "runtime/mutex.hpp"
-#include "runtime/thread.hpp"
-#include "utilities/exceptions.hpp"
-
-//
-// The ReferencePendingListLockerThread locks and unlocks the reference
-// pending list lock on behalf a non-Java thread, typically a concurrent
-// GC thread. This interface should not be directly accessed. All uses
-// should instead go through the ReferencePendingListLocker, which calls
-// this thread if needed.
-//
-class ReferencePendingListLockerThread : public JavaThread {
-private:
- enum Message {
- NONE,
- LOCK,
- UNLOCK
- };
-
- Monitor _monitor;
- Message _message;
-
- ReferencePendingListLockerThread();
-
- static void start(JavaThread* thread, TRAPS);
-
- void send_message(Message message);
- void receive_and_handle_messages();
-
-public:
- static ReferencePendingListLockerThread* create(TRAPS);
-
- virtual bool is_hidden_from_external_view() const;
-
- void lock();
- void unlock();
-};
-
-//
-// The ReferencePendingListLocker is the main interface for locking and
-// unlocking the reference pending list lock, which needs to be held by
-// the GC when adding references to the pending list. Since this is a
-// Java-level monitor it can only be locked/unlocked by a Java thread.
-// For this reason there is an option to spawn a helper thread, the
-// ReferencePendingListLockerThread, during initialization. If a helper
-// thread is spawned all lock operations from non-Java threads will be
-// delegated to the helper thread. The helper thread is typically needed
-// by concurrent GCs.
-//
-class ReferencePendingListLocker VALUE_OBJ_CLASS_SPEC {
-private:
- static bool _is_initialized;
- static ReferencePendingListLockerThread* _locker_thread;
- BasicLock _basic_lock;
-
-public:
- static void initialize(bool needs_locker_thread, TRAPS);
- static bool is_initialized();
-
- static bool is_locked_by_self();
-
- void lock();
- void unlock();
-};
-
-#endif // SHARE_VM_GC_SHARED_REFERENCEPENDINGLISTLOCKER_HPP
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -289,39 +289,16 @@
complete_gc->do_void();
}
-
-template <class T>
-bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
- AbstractRefProcTaskExecutor* task_executor) {
-
- // Remember old value of pending references list
- T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr();
- T old_pending_list_value = *pending_list_addr;
-
+void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
// Enqueue references that are not made active again, and
// clear the decks for the next collection (cycle).
- ref->enqueue_discovered_reflists((HeapWord*)pending_list_addr, task_executor);
- // Do the post-barrier on pending_list_addr missed in
- // enqueue_discovered_reflist.
- oopDesc::bs()->write_ref_field(pending_list_addr, oopDesc::load_decode_heap_oop(pending_list_addr));
+ enqueue_discovered_reflists(task_executor);
// Stop treating discovered references specially.
- ref->disable_discovery();
-
- // Return true if new pending references were added
- return old_pending_list_value != *pending_list_addr;
+ disable_discovery();
}
-bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
- if (UseCompressedOops) {
- return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
- } else {
- return enqueue_discovered_ref_helper<oop>(this, task_executor);
- }
-}
-
-void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
- HeapWord* pending_list_addr) {
+void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
// Given a list of refs linked through the "discovered" field
// (java.lang.ref.Reference.discovered), self-loop their "next" field
// thus distinguishing them from active References, then
@@ -354,10 +331,9 @@
oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
} else {
// This is the last object.
- // Swap refs_list into pending_list_addr and
- // set obj's discovered to what we read from pending_list_addr.
- oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
- // Need post-barrier on pending_list_addr. See enqueue_discovered_ref_helper() above.
+ // Swap refs_list into pending list and set obj's
+ // discovered to what we read from the pending list.
+ oop old = Universe::swap_reference_pending_list(refs_list.head());
java_lang_ref_Reference::set_discovered_raw(obj, old); // old may be NULL
oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), old);
}
@@ -369,10 +345,8 @@
public:
RefProcEnqueueTask(ReferenceProcessor& ref_processor,
DiscoveredList discovered_refs[],
- HeapWord* pending_list_addr,
int n_queues)
- : EnqueueTask(ref_processor, discovered_refs,
- pending_list_addr, n_queues)
+ : EnqueueTask(ref_processor, discovered_refs, n_queues)
{ }
virtual void work(unsigned int work_id) {
@@ -387,8 +361,7 @@
for (int j = 0;
j < ReferenceProcessor::number_of_subclasses_of_ref();
j++, index += _n_queues) {
- _ref_processor.enqueue_discovered_reflist(
- _refs_lists[index], _pending_list_addr);
+ _ref_processor.enqueue_discovered_reflist(_refs_lists[index]);
_refs_lists[index].set_head(NULL);
_refs_lists[index].set_length(0);
}
@@ -396,17 +369,15 @@
};
// Enqueue references that are not made active again
-void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
- AbstractRefProcTaskExecutor* task_executor) {
+void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor) {
if (_processing_is_mt && task_executor != NULL) {
// Parallel code
- RefProcEnqueueTask tsk(*this, _discovered_refs,
- pending_list_addr, _max_num_q);
+ RefProcEnqueueTask tsk(*this, _discovered_refs, _max_num_q);
task_executor->execute(tsk);
} else {
// Serial code: call the parent class's implementation
for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
- enqueue_discovered_reflist(_discovered_refs[i], pending_list_addr);
+ enqueue_discovered_reflist(_discovered_refs[i]);
_discovered_refs[i].set_head(NULL);
_discovered_refs[i].set_length(0);
}
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -290,7 +290,7 @@
VoidClosure* complete_gc);
// Enqueue references with a certain reachability level
- void enqueue_discovered_reflist(DiscoveredList& refs_list, HeapWord* pending_list_addr);
+ void enqueue_discovered_reflist(DiscoveredList& refs_list);
// "Preclean" all the discovered reference lists
// by removing references with strongly reachable referents.
@@ -311,7 +311,7 @@
// occupying the i / _num_q slot.
const char* list_name(uint i);
- void enqueue_discovered_reflists(HeapWord* pending_list_addr, AbstractRefProcTaskExecutor* task_executor);
+ void enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor);
protected:
// "Preclean" the given discovered reference list
@@ -424,7 +424,7 @@
GCTimer *gc_timer);
// Enqueue references at end of GC (called by the garbage collector)
- bool enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
+ void enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
// If a discovery is in process that is being superceded, abandon it: all
// the discovered lists will be empty, and all the objects on them will
@@ -613,11 +613,9 @@
protected:
EnqueueTask(ReferenceProcessor& ref_processor,
DiscoveredList refs_lists[],
- HeapWord* pending_list_addr,
int n_queues)
: _ref_processor(ref_processor),
_refs_lists(refs_lists),
- _pending_list_addr(pending_list_addr),
_n_queues(n_queues)
{ }
@@ -627,7 +625,6 @@
protected:
ReferenceProcessor& _ref_processor;
DiscoveredList* _refs_lists;
- HeapWord* _pending_list_addr;
int _n_queues;
};
--- a/hotspot/src/share/vm/gc/shared/space.inline.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/space.inline.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -293,10 +293,11 @@
verify_up_to_first_dead(space);
+ HeapWord* const bottom = space->bottom();
HeapWord* const end_of_live = space->_end_of_live;
assert(space->_first_dead <= end_of_live, "Invariant. _first_dead: " PTR_FORMAT " <= end_of_live: " PTR_FORMAT, p2i(space->_first_dead), p2i(end_of_live));
- if (space->_first_dead == end_of_live && !oop(space->bottom())->is_gc_marked()) {
+ if (space->_first_dead == end_of_live && (bottom == end_of_live || !oop(bottom)->is_gc_marked())) {
// Nothing to compact. The space is either empty or all live object should be left in place.
clear_empty_region(space);
return;
@@ -305,8 +306,8 @@
const intx scan_interval = PrefetchScanIntervalInBytes;
const intx copy_interval = PrefetchCopyIntervalInBytes;
- assert(space->bottom() < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(space->bottom()), p2i(end_of_live));
- HeapWord* cur_obj = space->bottom();
+ assert(bottom < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(bottom), p2i(end_of_live));
+ HeapWord* cur_obj = bottom;
if (space->_first_dead > cur_obj && !oop(cur_obj)->is_gc_marked()) {
// All object before _first_dead can be skipped. They should not be moved.
// A pointer to the first live object is stored at the memory location for _first_dead.
--- a/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -62,14 +62,6 @@
HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
}
-void VM_GC_Operation::acquire_pending_list_lock() {
- _pending_list_locker.lock();
-}
-
-void VM_GC_Operation::release_and_notify_pending_list_lock() {
- _pending_list_locker.unlock();
-}
-
// Allocations may fail in several threads at about the same time,
// resulting in multiple gc requests. We only want to do one of them.
// In case a GC locker is active and the need for a GC is already signaled,
@@ -102,16 +94,13 @@
proper_unit_for_byte_size(NewSize)));
}
- acquire_pending_list_lock();
// If the GC count has changed someone beat us to the collection
- // Get the Heap_lock after the pending_list_lock.
Heap_lock->lock();
// Check invocations
if (skip_operation()) {
// skip collection
Heap_lock->unlock();
- release_and_notify_pending_list_lock();
_prologue_succeeded = false;
} else {
_prologue_succeeded = true;
@@ -122,9 +111,10 @@
void VM_GC_Operation::doit_epilogue() {
assert(Thread::current()->is_Java_thread(), "just checking");
- // Release the Heap_lock first.
+ if (Universe::has_reference_pending_list()) {
+ Heap_lock->notify_all();
+ }
Heap_lock->unlock();
- release_and_notify_pending_list_lock();
}
bool VM_GC_HeapInspection::skip_operation() const {
--- a/hotspot/src/share/vm/gc/shared/vmGCOperations.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/vmGCOperations.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -27,7 +27,6 @@
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "memory/heapInspection.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/handles.hpp"
@@ -70,9 +69,6 @@
//
class VM_GC_Operation: public VM_Operation {
- private:
- ReferencePendingListLocker _pending_list_locker;
-
protected:
uint _gc_count_before; // gc count before acquiring PLL
uint _full_gc_count_before; // full gc count before acquiring PLL
@@ -83,10 +79,6 @@
virtual bool skip_operation() const;
- // java.lang.ref.Reference support
- void acquire_pending_list_lock();
- void release_and_notify_pending_list_lock();
-
public:
VM_GC_Operation(uint gc_count_before,
GCCause::Cause _cause,
--- a/hotspot/src/share/vm/gc/shared/workgroup.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -162,7 +162,7 @@
_active_workers = MIN2(v, _total_workers);
add_workers(false /* exit_on_failure */);
assert(v != 0, "Trying to set active workers to 0");
- log_info(gc, task)("GC Workers: using %d out of %d", _active_workers, _total_workers);
+ log_trace(gc, task)("%s: using %d out of %d workers", name(), _active_workers, _total_workers);
return _active_workers;
}
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -203,6 +203,40 @@
#undef SET_TRIGFUNC
}
+objArrayHandle CompilerToVM::initialize_intrinsics(TRAPS) {
+ objArrayHandle vmIntrinsics = oopFactory::new_objArray(VMIntrinsicMethod::klass(), (vmIntrinsics::ID_LIMIT - 1), CHECK_(objArrayHandle()));
+ int index = 0;
+ // The intrinsics for a class are usually adjacent to each other.
+ // When they are, the string for the class name can be reused.
+ vmSymbols::SID kls_sid = vmSymbols::NO_SID;
+ Handle kls_str;
+#define SID_ENUM(n) vmSymbols::VM_SYMBOL_ENUM_NAME(n)
+#define VM_SYMBOL_TO_STRING(s) \
+ java_lang_String::create_from_symbol(vmSymbols::symbol_at(SID_ENUM(s)), CHECK_(objArrayHandle()))
+#define VM_INTRINSIC_INFO(id, kls, name, sig, ignore_fcode) { \
+ instanceHandle vmIntrinsicMethod = InstanceKlass::cast(VMIntrinsicMethod::klass())->allocate_instance_handle(CHECK_(objArrayHandle())); \
+ if (kls_sid != SID_ENUM(kls)) { \
+ kls_str = VM_SYMBOL_TO_STRING(kls); \
+ kls_sid = SID_ENUM(kls); \
+ } \
+ Handle name_str = VM_SYMBOL_TO_STRING(name); \
+ Handle sig_str = VM_SYMBOL_TO_STRING(sig); \
+ VMIntrinsicMethod::set_declaringClass(vmIntrinsicMethod, kls_str()); \
+ VMIntrinsicMethod::set_name(vmIntrinsicMethod, name_str()); \
+ VMIntrinsicMethod::set_descriptor(vmIntrinsicMethod, sig_str()); \
+ VMIntrinsicMethod::set_id(vmIntrinsicMethod, vmIntrinsics::id); \
+ vmIntrinsics->obj_at_put(index++, vmIntrinsicMethod()); \
+ }
+
+ VM_INTRINSICS_DO(VM_INTRINSIC_INFO, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
+#undef SID_ENUM
+#undef VM_SYMBOL_TO_STRING
+#undef VM_INTRINSIC_INFO
+ assert(index == vmIntrinsics::ID_LIMIT - 1, "must be");
+
+ return vmIntrinsics;
+}
+
C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv *env))
#define BOXED_LONG(name, value) oop name; do { jvalue p; p.j = (jlong) (value); name = java_lang_boxing_object::create(T_LONG, &p, CHECK_NULL);} while(0)
#define BOXED_DOUBLE(name, value) oop name; do { jvalue p; p.d = (jdouble) (value); name = java_lang_boxing_object::create(T_DOUBLE, &p, CHECK_NULL);} while(0)
@@ -211,8 +245,9 @@
CompilerToVM::Data::initialize();
- VMField::klass()->initialize(thread);
- VMFlag::klass()->initialize(thread);
+ VMField::klass()->initialize(CHECK_NULL);
+ VMFlag::klass()->initialize(CHECK_NULL);
+ VMIntrinsicMethod::klass()->initialize(CHECK_NULL);
int len = JVMCIVMStructs::localHotSpotVMStructs_count();
objArrayHandle vmFields = oopFactory::new_objArray(VMField::klass(), len, CHECK_NULL);
@@ -220,7 +255,7 @@
VMStructEntry vmField = JVMCIVMStructs::localHotSpotVMStructs[i];
instanceHandle vmFieldObj = InstanceKlass::cast(VMField::klass())->allocate_instance_handle(CHECK_NULL);
size_t name_buf_len = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 /* "::" */;
- char* name_buf = NEW_RESOURCE_ARRAY(char, name_buf_len + 1);
+ char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_len + 1);
sprintf(name_buf, "%s::%s", vmField.typeName, vmField.fieldName);
Handle name = java_lang_String::create_from_str(name_buf, CHECK_NULL);
Handle type = java_lang_String::create_from_str(vmField.typeString, CHECK_NULL);
@@ -338,12 +373,15 @@
vmFlags->obj_at_put(i, vmFlagObj());
}
- objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 5, CHECK_NULL);
+ objArrayHandle vmIntrinsics = CompilerToVM::initialize_intrinsics(CHECK_NULL);
+
+ objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 6, CHECK_NULL);
data->obj_at_put(0, vmFields());
data->obj_at_put(1, vmTypes());
data->obj_at_put(2, vmConstants());
data->obj_at_put(3, vmAddresses());
data->obj_at_put(4, vmFlags());
+ data->obj_at_put(5, vmIntrinsics());
return (jobjectArray) JNIHandles::make_local(THREAD, data);
#undef BOXED_LONG
@@ -1266,10 +1304,23 @@
C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
- CallInfo callInfo;
- LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);
- ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
- cp_cache_entry->set_method_handle(cp, callInfo);
+ KlassHandle holder = cp->klass_ref_at(index, CHECK);
+ Symbol* name = cp->name_ref_at(index);
+ if (MethodHandles::is_signature_polymorphic_name(holder(), name)) {
+ CallInfo callInfo;
+ LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);
+ ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
+ cp_cache_entry->set_method_handle(cp, callInfo);
+ }
+C2V_END
+
+C2V_VMENTRY(jobject, getSignaturePolymorphicHolders, (JNIEnv*, jobject))
+ objArrayHandle holders = oopFactory::new_objArray(SystemDictionary::String_klass(), 2, CHECK_NULL);
+ Handle mh = java_lang_String::create_from_str("Ljava/lang/invoke/MethodHandle;", CHECK_NULL);
+ Handle vh = java_lang_String::create_from_str("Ljava/lang/invoke/VarHandle;", CHECK_NULL);
+ holders->obj_at_put(0, mh());
+ holders->obj_at_put(1, vh());
+ return JNIHandles::make_local(THREAD, holders());
C2V_END
C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv*, jobject))
@@ -1511,6 +1562,7 @@
{CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeDynamicInPool)},
{CC "resolveInvokeHandleInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeHandleInPool)},
{CC "resolveMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},
+ {CC "getSignaturePolymorphicHolders", CC "()[" STRING, FN_PTR(getSignaturePolymorphicHolders)},
{CC "getVtableIndexForInterfaceMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")I", FN_PTR(getVtableIndexForInterfaceMethod)},
{CC "getClassInitializer", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(getClassInitializer)},
{CC "hasFinalizableSubclass", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(hasFinalizableSubclass)},
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -83,8 +83,10 @@
}
};
+ static JNINativeMethod methods[];
+
+ static objArrayHandle initialize_intrinsics(TRAPS);
public:
- static JNINativeMethod methods[];
static int methods_count();
static inline Method* asMethod(jobject jvmci_method) {
--- a/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -124,6 +124,12 @@
oop_field(VMFlag, type, "Ljava/lang/String;") \
oop_field(VMFlag, value, "Ljava/lang/Object;") \
end_class \
+ start_class(VMIntrinsicMethod) \
+ oop_field(VMIntrinsicMethod, declaringClass, "Ljava/lang/String;") \
+ oop_field(VMIntrinsicMethod, name, "Ljava/lang/String;") \
+ oop_field(VMIntrinsicMethod, descriptor, "Ljava/lang/String;") \
+ int_field(VMIntrinsicMethod, id) \
+ end_class \
start_class(Assumptions_NoFinalizableSubclass) \
oop_field(Assumptions_NoFinalizableSubclass, receiverType, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
end_class \
--- a/hotspot/src/share/vm/jvmci/jvmci_globals.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -84,6 +84,7 @@
CHECK_NOT_SET(JVMCICountersExcludeCompiler, EnableJVMCI)
CHECK_NOT_SET(JVMCIUseFastLocking, EnableJVMCI)
CHECK_NOT_SET(JVMCINMethodSizeLimit, EnableJVMCI)
+ CHECK_NOT_SET(MethodProfileWidth, EnableJVMCI)
CHECK_NOT_SET(TraceUncollectedSpeculations, EnableJVMCI)
#ifndef PRODUCT
--- a/hotspot/src/share/vm/jvmci/jvmci_globals.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -88,6 +88,9 @@
experimental(intx, JVMCINMethodSizeLimit, (80*K)*wordSize, \
"Maximum size of a compiled method.") \
\
+ experimental(intx, MethodProfileWidth, 0, \
+ "Number of methods to record in call profile") \
+ \
develop(bool, TraceUncollectedSpeculations, false, \
"Print message when a failed speculation was not collected")
--- a/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -51,6 +51,7 @@
do_klass(HotSpotCompilationRequestResult_klass, jdk_vm_ci_hotspot_HotSpotCompilationRequestResult, Jvmci) \
do_klass(VMField_klass, jdk_vm_ci_hotspot_VMField, Jvmci) \
do_klass(VMFlag_klass, jdk_vm_ci_hotspot_VMFlag, Jvmci) \
+ do_klass(VMIntrinsicMethod_klass, jdk_vm_ci_hotspot_VMIntrinsicMethod, Jvmci) \
do_klass(Assumptions_ConcreteMethod_klass, jdk_vm_ci_meta_Assumptions_ConcreteMethod, Jvmci) \
do_klass(Assumptions_NoFinalizableSubclass_klass, jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass, Jvmci) \
do_klass(Assumptions_ConcreteSubtype_klass, jdk_vm_ci_meta_Assumptions_ConcreteSubtype, Jvmci) \
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -493,6 +493,7 @@
declare_constant(Method::_force_inline) \
declare_constant(Method::_dont_inline) \
declare_constant(Method::_hidden) \
+ declare_constant(Method::_intrinsic_candidate) \
declare_constant(Method::_reserved_stack_access) \
\
declare_constant(Method::nonvirtual_vtable_index) \
--- a/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -52,6 +52,7 @@
template(jdk_vm_ci_hotspot_HotSpotCompilationRequestResult, "jdk/vm/ci/hotspot/HotSpotCompilationRequestResult") \
template(jdk_vm_ci_hotspot_VMField, "jdk/vm/ci/hotspot/VMField") \
template(jdk_vm_ci_hotspot_VMFlag, "jdk/vm/ci/hotspot/VMFlag") \
+ template(jdk_vm_ci_hotspot_VMIntrinsicMethod, "jdk/vm/ci/hotspot/VMIntrinsicMethod") \
template(jdk_vm_ci_meta_JavaConstant, "jdk/vm/ci/meta/JavaConstant") \
template(jdk_vm_ci_meta_PrimitiveConstant, "jdk/vm/ci/meta/PrimitiveConstant") \
template(jdk_vm_ci_meta_RawConstant, "jdk/vm/ci/meta/RawConstant") \
--- a/hotspot/src/share/vm/logging/log.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/log.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1161,7 +1161,7 @@
// Attempt to log to a directory (existing log not a regular file)
create_directory(target_name);
- LogFileOutput bad_file("tmplogdir");
+ LogFileOutput bad_file("file=tmplogdir");
assert(bad_file.initialize("", &ss) == false, "file was initialized "
"when there was an existing directory with the same name");
assert(strstr(ss.as_string(), "tmplogdir is not a regular file") != NULL,
--- a/hotspot/src/share/vm/logging/logConfiguration.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logConfiguration.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -44,6 +44,9 @@
LogConfiguration::UpdateListenerFunction* LogConfiguration::_listener_callbacks = NULL;
size_t LogConfiguration::_n_listener_callbacks = 0;
+// LogFileOutput is the default type of output, its type prefix should be used if no type was specified
+static const char* implicit_output_prefix = LogFileOutput::Prefix;
+
// Stack object to take the lock for configuring the logging.
// Should only be held during the critical parts of the configuration
// (when calling configure_output or reading/modifying the outputs array).
@@ -107,6 +110,55 @@
FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
}
+// Normalizes the given LogOutput name to type=name form.
+// For example, foo, "foo", file="foo", will all be normalized to file=foo (no quotes, prefixed).
+static bool normalize_output_name(const char* full_name, char* buffer, size_t len, outputStream* errstream) {
+ const char* start_quote = strchr(full_name, '"');
+ const char* equals = strchr(full_name, '=');
+ const bool quoted = start_quote != NULL;
+ const bool is_stdout_or_stderr = (strcmp(full_name, "stdout") == 0 || strcmp(full_name, "stderr") == 0);
+
+ // ignore equals sign within quotes
+ if (quoted && equals > start_quote) {
+ equals = NULL;
+ }
+
+ const char* prefix = "";
+ size_t prefix_len = 0;
+ const char* name = full_name;
+ if (equals != NULL) {
+ // split on equals sign
+ name = equals + 1;
+ prefix = full_name;
+ prefix_len = equals - full_name + 1;
+ } else if (!is_stdout_or_stderr) {
+ prefix = implicit_output_prefix;
+ prefix_len = strlen(prefix);
+ }
+ size_t name_len = strlen(name);
+
+ if (quoted) {
+ const char* end_quote = strchr(start_quote + 1, '"');
+ if (end_quote == NULL) {
+ errstream->print_cr("Output name has opening quote but is missing a terminating quote.");
+ return false;
+ }
+ if (start_quote != name || end_quote[1] != '\0') {
+ errstream->print_cr("Output name can not be partially quoted."
+ " Either surround the whole name with quotation marks,"
+ " or do not use quotation marks at all.");
+ return false;
+ }
+ // strip start and end quote
+ name++;
+ name_len -= 2;
+ }
+
+ int ret = jio_snprintf(buffer, len, "%.*s%.*s", prefix_len, prefix, name_len, name);
+ assert(ret > 0, "buffer issue");
+ return true;
+}
+
size_t LogConfiguration::find_output(const char* name) {
for (size_t i = 0; i < _n_outputs; i++) {
if (strcmp(_outputs[i]->name(), name) == 0) {
@@ -116,39 +168,14 @@
return SIZE_MAX;
}
-LogOutput* LogConfiguration::new_output(char* name, const char* options, outputStream* errstream) {
- const char* type;
- char* equals_pos = strchr(name, '=');
- if (equals_pos == NULL) {
- type = "file";
- } else {
- *equals_pos = '\0';
- type = name;
- name = equals_pos + 1;
- }
-
- // Check if name is quoted, and if so, strip the quotes
- char* quote = strchr(name, '"');
- if (quote != NULL) {
- char* end_quote = strchr(name + 1, '"');
- if (end_quote == NULL) {
- errstream->print_cr("Output name has opening quote but is missing a terminating quote.");
- return NULL;
- } else if (quote != name || end_quote[1] != '\0') {
- errstream->print_cr("Output name can not be partially quoted."
- " Either surround the whole name with quotation marks,"
- " or do not use quotation marks at all.");
- return NULL;
- }
- name++;
- *end_quote = '\0';
- }
-
+LogOutput* LogConfiguration::new_output(const char* name,
+ const char* options,
+ outputStream* errstream) {
LogOutput* output;
- if (strcmp(type, "file") == 0) {
+ if (strncmp(name, LogFileOutput::Prefix, strlen(LogFileOutput::Prefix)) == 0) {
output = new LogFileOutput(name);
} else {
- errstream->print_cr("Unsupported log output type.");
+ errstream->print_cr("Unsupported log output type: %s", name);
return NULL;
}
@@ -243,6 +270,7 @@
}
void LogConfiguration::disable_output(size_t idx) {
+ assert(idx < _n_outputs, "invalid index: " SIZE_FORMAT " (_n_outputs: " SIZE_FORMAT ")", idx, _n_outputs);
LogOutput* out = _outputs[idx];
// Remove the output from all tagsets.
@@ -253,7 +281,7 @@
// Delete the output unless stdout/stderr
if (out != LogOutput::Stderr && out != LogOutput::Stdout) {
- delete_output(find_output(out->name()));
+ delete_output(idx);
} else {
out->set_config_string("all=off");
}
@@ -261,8 +289,8 @@
void LogConfiguration::disable_logging() {
ConfigurationLock cl;
- for (size_t i = 0; i < _n_outputs; i++) {
- disable_output(i);
+ for (size_t i = _n_outputs; i > 0; i--) {
+ disable_output(i - 1);
}
notify_update_listeners();
}
@@ -289,6 +317,8 @@
}
expr.set_level(level);
expr.new_combination();
+ assert(expr.verify_tagsets(),
+ "configure_stdout() called with invalid/non-existing tag set");
// Apply configuration to stdout (output #0), with the same decorators as before.
ConfigurationLock cl;
@@ -334,9 +364,16 @@
char errbuf[512];
stringStream ss(errbuf, sizeof(errbuf));
bool success = parse_log_arguments(output, what, decorators, output_options, &ss);
- if (!success) {
- errbuf[strlen(errbuf) - 1] = '\0'; // Strip trailing newline.
- log_error(logging)("%s", errbuf);
+
+ if (ss.size() > 0) {
+ errbuf[strlen(errbuf) - 1] = '\0'; // Strip trailing newline
+ // If it failed, log the error. If it didn't fail, but something was written
+ // to the stream, log it as a warning.
+ if (!success) {
+ log_error(logging)("%s", ss.base());
+ } else {
+ log_warning(logging)("%s", ss.base());
+ }
}
os::free(copy);
@@ -348,6 +385,7 @@
const char* decoratorstr,
const char* output_options,
outputStream* errstream) {
+ assert(errstream != NULL, "errstream can not be NULL");
if (outputstr == NULL || strlen(outputstr) == 0) {
outputstr = "stdout";
}
@@ -364,28 +402,39 @@
ConfigurationLock cl;
size_t idx;
- if (outputstr[0] == '#') {
- int ret = sscanf(outputstr+1, SIZE_FORMAT, &idx);
+ if (outputstr[0] == '#') { // Output specified using index
+ int ret = sscanf(outputstr + 1, SIZE_FORMAT, &idx);
if (ret != 1 || idx >= _n_outputs) {
errstream->print_cr("Invalid output index '%s'", outputstr);
return false;
}
- } else {
- idx = find_output(outputstr);
+ } else { // Output specified using name
+ // Normalize the name, stripping quotes and ensures it includes type prefix
+ size_t len = strlen(outputstr) + strlen(implicit_output_prefix) + 1;
+ char* normalized = NEW_C_HEAP_ARRAY(char, len, mtLogging);
+ if (!normalize_output_name(outputstr, normalized, len, errstream)) {
+ return false;
+ }
+
+ idx = find_output(normalized);
if (idx == SIZE_MAX) {
- char* tmp = os::strdup_check_oom(outputstr, mtLogging);
- LogOutput* output = new_output(tmp, output_options, errstream);
- os::free(tmp);
- if (output == NULL) {
- return false;
+ // Attempt to create and add the output
+ LogOutput* output = new_output(normalized, output_options, errstream);
+ if (output != NULL) {
+ idx = add_output(output);
}
- idx = add_output(output);
} else if (output_options != NULL && strlen(output_options) > 0) {
errstream->print_cr("Output options for existing outputs are ignored.");
}
+
+ FREE_C_HEAP_ARRAY(char, normalized);
+ if (idx == SIZE_MAX) {
+ return false;
+ }
}
configure_output(idx, expr, decorators);
notify_update_listeners();
+ expr.verify_tagsets(errstream);
return true;
}
--- a/hotspot/src/share/vm/logging/logConfiguration.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logConfiguration.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -59,7 +59,7 @@
static size_t _n_listener_callbacks;
// Create a new output. Returns NULL if failed.
- static LogOutput* new_output(char* name, const char* options, outputStream* errstream);
+ static LogOutput* new_output(const char* name, const char* options, outputStream* errstream);
// Add an output to the list of configured outputs. Returns the assigned index.
static size_t add_output(LogOutput* out);
--- a/hotspot/src/share/vm/logging/logFileOutput.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileOutput.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -31,6 +31,7 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/defaultStream.hpp"
+const char* LogFileOutput::Prefix = "file=";
const char* LogFileOutput::FileOpenMode = "a";
const char* LogFileOutput::PidFilenamePlaceholder = "%p";
const char* LogFileOutput::TimestampFilenamePlaceholder = "%t";
@@ -45,7 +46,8 @@
_file_name(NULL), _archive_name(NULL), _archive_name_len(0),
_rotate_size(DefaultFileSize), _file_count(DefaultFileCount),
_current_size(0), _current_file(0), _rotation_semaphore(1) {
- _file_name = make_file_name(name, _pid_str, _vm_start_time_str);
+ assert(strstr(name, Prefix) == name, "invalid output name '%s': missing prefix: %s", name, Prefix);
+ _file_name = make_file_name(name + strlen(Prefix), _pid_str, _vm_start_time_str);
}
void LogFileOutput::set_file_name_parameters(jlong vm_start_time) {
--- a/hotspot/src/share/vm/logging/logFileOutput.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logFileOutput.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -91,6 +91,7 @@
return _name;
}
+ static const char* Prefix;
static void set_file_name_parameters(jlong start_time);
};
--- a/hotspot/src/share/vm/logging/logTagLevelExpression.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -29,6 +29,65 @@
const char* LogTagLevelExpression::DefaultExpressionString = "all";
+static bool matches_tagset(const LogTagType tags[],
+ bool allow_other_tags,
+ const LogTagSet& ts) {
+ bool contains_all = true;
+ size_t tag_idx;
+ for (tag_idx = 0; tag_idx < LogTag::MaxTags && tags[tag_idx] != LogTag::__NO_TAG; tag_idx++) {
+ if (!ts.contains(tags[tag_idx])) {
+ contains_all = false;
+ break;
+ }
+ }
+ // All tags in the expression must be part of the tagset,
+ // and either the expression allows other tags (has a wildcard),
+ // or the number of tags in the expression and tagset must match.
+ return contains_all && (allow_other_tags || tag_idx == ts.ntags());
+}
+
+bool LogTagLevelExpression::verify_tagsets(outputStream* out) const {
+ bool valid = true;
+
+ for (size_t i = 0; i < _ncombinations; i++) {
+ bool matched = false;
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ if (matches_tagset(_tags[i], _allow_other_tags[i], *ts)) {
+ matched = true;
+ break;
+ }
+ }
+
+ if (!matched) {
+ // If this was the first invalid combination, write the message header
+ if (valid && out != NULL) {
+ out->print("No tag set matches selection(s): ");
+ }
+ valid = false;
+
+ // Break as soon as possible unless listing all invalid combinations
+ if (out == NULL) {
+ break;
+ }
+
+ // List the combination on the outputStream
+ for (size_t t = 0; t < LogTag::MaxTags && _tags[i][t] != LogTag::__NO_TAG; t++) {
+ out->print("%s%s", (t == 0 ? "" : "+"), LogTag::name(_tags[i][t]));
+ }
+ if (_allow_other_tags[i]) {
+ out->print("*");
+ }
+ out->print(" ");
+ }
+ }
+
+ if (!valid && out != NULL) {
+ out->cr();
+ }
+
+ return valid;
+}
+
bool LogTagLevelExpression::parse(const char* str, outputStream* errstream) {
bool success = true;
if (str == NULL || strcmp(str, "") == 0) {
@@ -105,7 +164,14 @@
success = false;
break;
}
- add_tag(tag);
+ if (!add_tag(tag)) {
+ if (errstream != NULL) {
+ errstream->print_cr("Tag combination have duplicate tag '%s' in what-expression.",
+ cur_tag);
+ }
+ success = false;
+ break;
+ }
cur_tag = plus_pos + 1;
} while (plus_pos != NULL);
@@ -120,20 +186,10 @@
// Return NotMentioned if the given tagset isn't covered by this expression.
LogLevelType level = LogLevel::NotMentioned;
for (size_t combination = 0; combination < _ncombinations; combination++) {
- bool contains_all = true;
- size_t tag_idx;
- for (tag_idx = 0; tag_idx < LogTag::MaxTags && _tags[combination][tag_idx] != LogTag::__NO_TAG; tag_idx++) {
- if (!ts.contains(_tags[combination][tag_idx])) {
- contains_all = false;
- break;
- }
- }
- // All tags in the expression must be part of the tagset,
- // and either the expression allows other tags (has a wildcard),
- // or the number of tags in the expression and tagset must match.
- if (contains_all && (_allow_other_tags[combination] || tag_idx == ts.ntags())) {
+ if (matches_tagset(_tags[combination], _allow_other_tags[combination], ts)) {
level = _level[combination];
}
}
return level;
}
+
--- a/hotspot/src/share/vm/logging/logTagLevelExpression.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -59,9 +59,15 @@
_ntags = 0;
}
- void add_tag(LogTagType tag) {
+ bool add_tag(LogTagType tag) {
assert(_ntags < LogTag::MaxTags, "Can't have more tags than MaxTags!");
+ for (size_t i = 0; i < _ntags; i++) {
+ if (_tags[_ncombinations][i] == tag) {
+ return false;
+ }
+ }
_tags[_ncombinations][_ntags++] = tag;
+ return true;
}
void set_level(LogLevelType level) {
@@ -83,6 +89,11 @@
bool parse(const char* str, outputStream* errstream = NULL);
LogLevelType level_for(const LogTagSet& ts) const;
+
+ // Verify the tagsets/selections mentioned in this expression.
+ // Returns false if some invalid tagset was found. If given an outputstream,
+ // this function will list all the invalid selections on the stream.
+ bool verify_tagsets(outputStream* out = NULL) const;
};
#endif // SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
--- a/hotspot/src/share/vm/logging/logTagSet.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -86,7 +86,7 @@
}
bool contains(LogTagType tag) const {
- for (size_t i = 0; _tag[i] != LogTag::__NO_TAG; i++) {
+ for (size_t i = 0; i < LogTag::MaxTags && _tag[i] != LogTag::__NO_TAG; i++) {
if (tag == _tag[i]) {
return true;
}
--- a/hotspot/src/share/vm/memory/universe.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -135,6 +135,7 @@
oop Universe::_virtual_machine_error_instance = NULL;
oop Universe::_vm_exception = NULL;
oop Universe::_allocation_context_notification_obj = NULL;
+oop Universe::_reference_pending_list = NULL;
Array<int>* Universe::_the_empty_int_array = NULL;
Array<u2>* Universe::_the_empty_short_array = NULL;
@@ -212,6 +213,7 @@
f->do_oop((oop*)&_system_thread_group);
f->do_oop((oop*)&_vm_exception);
f->do_oop((oop*)&_allocation_context_notification_obj);
+ f->do_oop((oop*)&_reference_pending_list);
debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);)
}
@@ -488,6 +490,35 @@
java_lang_Class::set_fixup_mirror_list(NULL);
}
+#define assert_pll_locked(test) \
+ assert(Heap_lock->test(), "Reference pending list access requires lock")
+
+#define assert_pll_ownership() assert_pll_locked(owned_by_self)
+
+oop Universe::reference_pending_list() {
+ assert_pll_ownership();
+ return _reference_pending_list;
+}
+
+void Universe::set_reference_pending_list(oop list) {
+ assert_pll_ownership();
+ _reference_pending_list = list;
+}
+
+bool Universe::has_reference_pending_list() {
+ assert_pll_ownership();
+ return _reference_pending_list != NULL;
+}
+
+oop Universe::swap_reference_pending_list(oop list) {
+ assert_pll_locked(is_locked);
+ return (oop)Atomic::xchg_ptr(list, &_reference_pending_list);
+}
+
+#undef assert_pll_locked
+#undef assert_pll_ownership
+
+
static bool has_run_finalizers_on_exit = false;
void Universe::run_finalizers_on_exit() {
@@ -565,12 +596,14 @@
oop Universe::gen_out_of_memory_error(oop default_err) {
// generate an out of memory error:
- // - if there is a preallocated error with backtrace available then return it wth
- // a filled in stack trace.
- // - if there are no preallocated errors with backtrace available then return
- // an error without backtrace.
+ // - if there is a preallocated error and stack traces are available
+ // (j.l.Throwable is initialized), then return the preallocated
+ // error with a filled in stack trace, and with the message
+ // provided by the default error.
+ // - otherwise, return the default error, without a stack trace.
int next;
- if (_preallocated_out_of_memory_error_avail_count > 0) {
+ if ((_preallocated_out_of_memory_error_avail_count > 0) &&
+ SystemDictionary::Throwable_klass()->is_initialized()) {
next = (int)Atomic::add(-1, &_preallocated_out_of_memory_error_avail_count);
assert(next < (int)PreallocatedOutOfMemoryErrorCount, "avail count is corrupt");
} else {
--- a/hotspot/src/share/vm/memory/universe.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -185,6 +185,9 @@
static oop _allocation_context_notification_obj;
+ // References waiting to be transferred to the ReferenceHandler
+ static oop _reference_pending_list;
+
// The particular choice of collected heap.
static CollectedHeap* _collectedHeap;
@@ -334,6 +337,17 @@
static inline oop allocation_context_notification_obj();
static inline void set_allocation_context_notification_obj(oop obj);
+ // Reference pending list manipulation. Access is protected by
+ // Heap_lock. The getter, setter and predicate require the caller
+ // owns the lock. Swap is used by parallel non-concurrent reference
+ // processing threads, where some higher level controller owns
+ // Heap_lock, so requires the lock is locked, but not necessarily by
+ // the current thread.
+ static oop reference_pending_list();
+ static void set_reference_pending_list(oop list);
+ static bool has_reference_pending_list();
+ static oop swap_reference_pending_list(oop list);
+
static Array<int>* the_empty_int_array() { return _the_empty_int_array; }
static Array<u2>* the_empty_short_array() { return _the_empty_short_array; }
static Array<Method*>* the_empty_method_array() { return _the_empty_method_array; }
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/arrayKlass.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -56,7 +56,9 @@
void set_dimension(int dimension) { _dimension = dimension; }
Klass* higher_dimension() const { return _higher_dimension; }
+ inline Klass* higher_dimension_acquire() const; // load with acquire semantics
void set_higher_dimension(Klass* k) { _higher_dimension = k; }
+ inline void release_set_higher_dimension(Klass* k); // store with release semantics
Klass** adr_higher_dimension() { return (Klass**)&this->_higher_dimension;}
Klass* lower_dimension() const { return _lower_dimension; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/arrayKlass.inline.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_ARRAYKLASS_INLINE_HPP
+#define SHARE_VM_OOPS_ARRAYKLASS_INLINE_HPP
+
+#include "runtime/orderAccess.inline.hpp"
+#include "oops/arrayKlass.hpp"
+
+inline Klass* ArrayKlass::higher_dimension_acquire() const {
+ return (Klass*) OrderAccess::load_ptr_acquire(&_higher_dimension);
+}
+
+inline void ArrayKlass::release_set_higher_dimension(Klass* k) {
+ OrderAccess::release_store_ptr(&_higher_dimension, k);
+}
+
+#endif // SHARE_VM_OOPS_ARRAYKLASS_INLINE_HPP
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1041,7 +1041,8 @@
}
Klass* InstanceKlass::array_klass_impl(instanceKlassHandle this_k, bool or_null, int n, TRAPS) {
- if (this_k->array_klasses() == NULL) {
+ // Need load-acquire for lock-free read
+ if (this_k->array_klasses_acquire() == NULL) {
if (or_null) return NULL;
ResourceMark rm;
@@ -1054,7 +1055,8 @@
// Check if update has already taken place
if (this_k->array_klasses() == NULL) {
Klass* k = ObjArrayKlass::allocate_objArray_klass(this_k->class_loader_data(), 1, this_k, CHECK_NULL);
- this_k->set_array_klasses(k);
+ // use 'release' to pair with lock-free load
+ this_k->release_set_array_klasses(k);
}
}
}
@@ -3363,88 +3365,119 @@
#if INCLUDE_JVMTI
-// RedefineClasses() support for previous versions:
-int InstanceKlass::_previous_version_count = 0;
-
-// Purge previous versions before adding new previous versions of the class.
-void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
- if (ik->previous_versions() != NULL) {
- // This klass has previous versions so see what we can cleanup
- // while it is safe to do so.
-
- int deleted_count = 0; // leave debugging breadcrumbs
- int live_count = 0;
- ClassLoaderData* loader_data = ik->class_loader_data();
- assert(loader_data != NULL, "should never be null");
-
- ResourceMark rm;
- log_trace(redefine, class, iklass, purge)("%s: previous versions", ik->external_name());
-
- // previous versions are linked together through the InstanceKlass
- InstanceKlass* pv_node = ik->previous_versions();
- InstanceKlass* last = ik;
- int version = 0;
-
- // check the previous versions list
- for (; pv_node != NULL; ) {
-
- ConstantPool* pvcp = pv_node->constants();
- assert(pvcp != NULL, "cp ref was unexpectedly cleared");
-
- if (!pvcp->on_stack()) {
- // If the constant pool isn't on stack, none of the methods
- // are executing. Unlink this previous_version.
- // The previous version InstanceKlass is on the ClassLoaderData deallocate list
- // so will be deallocated during the next phase of class unloading.
- log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is dead", p2i(pv_node));
- // For debugging purposes.
- pv_node->set_is_scratch_class();
- pv_node->class_loader_data()->add_to_deallocate_list(pv_node);
- pv_node = pv_node->previous_versions();
- last->link_previous_versions(pv_node);
- deleted_count++;
- version++;
- continue;
- } else {
- log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is alive", p2i(pv_node));
- assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
- guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
- live_count++;
- }
-
- // At least one method is live in this previous version.
- // Reset dead EMCP methods not to get breakpoints.
- // All methods are deallocated when all of the methods for this class are no
- // longer running.
- Array<Method*>* method_refs = pv_node->methods();
- if (method_refs != NULL) {
- log_trace(redefine, class, iklass, purge)("previous methods length=%d", method_refs->length());
- for (int j = 0; j < method_refs->length(); j++) {
- Method* method = method_refs->at(j);
-
- if (!method->on_stack()) {
- // no breakpoints for non-running methods
- if (method->is_running_emcp()) {
- method->set_running_emcp(false);
- }
- } else {
- assert (method->is_obsolete() || method->is_running_emcp(),
- "emcp method cannot run after emcp bit is cleared");
- log_trace(redefine, class, iklass, purge)
- ("purge: %s(%s): prev method @%d in version @%d is alive",
- method->name()->as_C_string(), method->signature()->as_C_string(), j, version);
+// RedefineClasses() support for previous versions
+
+// Globally, there is at least one previous version of a class to walk
+// during class unloading, which is saved because old methods in the class
+// are still running. Otherwise the previous version list is cleaned up.
+bool InstanceKlass::_has_previous_versions = false;
+
+// Returns true if there are previous versions of a class for class
+// unloading only. Also resets the flag to false. purge_previous_version
+// will set the flag to true if there are any left, i.e., if there's any
+// work to do for next time. This is to avoid the expensive code cache
+// walk in CLDG::do_unloading().
+bool InstanceKlass::has_previous_versions_and_reset() {
+ bool ret = _has_previous_versions;
+ log_trace(redefine, class, iklass, purge)("Class unloading: has_previous_versions = %s",
+ ret ? "true" : "false");
+ _has_previous_versions = false;
+ return ret;
+}
+
+// Purge previous versions before adding new previous versions of the class and
+// during class unloading.
+void InstanceKlass::purge_previous_version_list() {
+ assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
+ assert(has_been_redefined(), "Should only be called for main class");
+
+ // Quick exit.
+ if (previous_versions() == NULL) {
+ return;
+ }
+
+ // This klass has previous versions so see what we can cleanup
+ // while it is safe to do so.
+
+ int deleted_count = 0; // leave debugging breadcrumbs
+ int live_count = 0;
+ ClassLoaderData* loader_data = class_loader_data();
+ assert(loader_data != NULL, "should never be null");
+
+ ResourceMark rm;
+ log_trace(redefine, class, iklass, purge)("%s: previous versions", external_name());
+
+ // previous versions are linked together through the InstanceKlass
+ InstanceKlass* pv_node = previous_versions();
+ InstanceKlass* last = this;
+ int version = 0;
+
+ // check the previous versions list
+ for (; pv_node != NULL; ) {
+
+ ConstantPool* pvcp = pv_node->constants();
+ assert(pvcp != NULL, "cp ref was unexpectedly cleared");
+
+ if (!pvcp->on_stack()) {
+ // If the constant pool isn't on stack, none of the methods
+ // are executing. Unlink this previous_version.
+ // The previous version InstanceKlass is on the ClassLoaderData deallocate list
+ // so will be deallocated during the next phase of class unloading.
+ log_trace(redefine, class, iklass, purge)
+ ("previous version " INTPTR_FORMAT " is dead.", p2i(pv_node));
+ // For debugging purposes.
+ pv_node->set_is_scratch_class();
+ // Unlink from previous version list.
+ assert(pv_node->class_loader_data() == loader_data, "wrong loader_data");
+ InstanceKlass* next = pv_node->previous_versions();
+ pv_node->link_previous_versions(NULL); // point next to NULL
+ last->link_previous_versions(next);
+ // Add to the deallocate list after unlinking
+ loader_data->add_to_deallocate_list(pv_node);
+ pv_node = next;
+ deleted_count++;
+ version++;
+ continue;
+ } else {
+ log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is alive", p2i(pv_node));
+ assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
+ guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
+ live_count++;
+ // found a previous version for next time we do class unloading
+ _has_previous_versions = true;
+ }
+
+ // At least one method is live in this previous version.
+ // Reset dead EMCP methods not to get breakpoints.
+ // All methods are deallocated when all of the methods for this class are no
+ // longer running.
+ Array<Method*>* method_refs = pv_node->methods();
+ if (method_refs != NULL) {
+ log_trace(redefine, class, iklass, purge)("previous methods length=%d", method_refs->length());
+ for (int j = 0; j < method_refs->length(); j++) {
+ Method* method = method_refs->at(j);
+
+ if (!method->on_stack()) {
+ // no breakpoints for non-running methods
+ if (method->is_running_emcp()) {
+ method->set_running_emcp(false);
}
+ } else {
+ assert (method->is_obsolete() || method->is_running_emcp(),
+ "emcp method cannot run after emcp bit is cleared");
+ log_trace(redefine, class, iklass, purge)
+ ("purge: %s(%s): prev method @%d in version @%d is alive",
+ method->name()->as_C_string(), method->signature()->as_C_string(), j, version);
}
}
- // next previous version
- last = pv_node;
- pv_node = pv_node->previous_versions();
- version++;
}
- log_trace(redefine, class, iklass, purge)
- ("previous version stats: live=%d, deleted=%d",
- live_count, deleted_count);
+ // next previous version
+ last = pv_node;
+ pv_node = pv_node->previous_versions();
+ version++;
}
+ log_trace(redefine, class, iklass, purge)
+ ("previous version stats: live=%d, deleted=%d", live_count, deleted_count);
}
void InstanceKlass::mark_newly_obsolete_methods(Array<Method*>* old_methods,
@@ -3516,8 +3549,8 @@
log_trace(redefine, class, iklass, add)
("adding previous version ref for %s, EMCP_cnt=%d", scratch_class->external_name(), emcp_method_count);
- // Clean out old previous versions
- purge_previous_versions(this);
+ // Clean out old previous versions for this class
+ purge_previous_version_list();
// Mark newly obsolete methods in remaining previous versions. An EMCP method from
// a previous redefinition may be made obsolete by this redefinition.
@@ -3534,8 +3567,6 @@
// For debugging purposes.
scratch_class->set_is_scratch_class();
scratch_class->class_loader_data()->add_to_deallocate_list(scratch_class());
- // Update count for class unloading.
- _previous_version_count--;
return;
}
@@ -3563,12 +3594,12 @@
}
// Add previous version if any methods are still running.
- log_trace(redefine, class, iklass, add)("scratch class added; one of its methods is on_stack");
+ // Set has_previous_version flag for processing during class unloading.
+ _has_previous_versions = true;
+ log_trace(redefine, class, iklass, add) ("scratch class added; one of its methods is on_stack.");
assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version");
scratch_class->link_previous_versions(previous_versions());
link_previous_versions(scratch_class());
- // Update count for class unloading.
- _previous_version_count++;
} // end add_previous_version()
#endif // INCLUDE_JVMTI
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -148,7 +148,7 @@
// Package this class is defined in
PackageEntry* _package_entry;
// Array classes holding elements of this class.
- Klass* _array_klasses;
+ Klass* volatile _array_klasses;
// Constant pool for this class.
ConstantPool* _constants;
// The InnerClasses attribute and EnclosingMethod attribute. The
@@ -230,7 +230,7 @@
OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily)
MemberNameTable* _member_names; // Member names
JNIid* _jni_ids; // First JNI identifier for static fields in this class
- jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none
+ jmethodID* volatile _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none
intptr_t _dep_context; // packed DependencyContext structure
nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class
#if INCLUDE_JVMTI
@@ -368,7 +368,9 @@
// array klasses
Klass* array_klasses() const { return _array_klasses; }
+ inline Klass* array_klasses_acquire() const; // load with acquire semantics
void set_array_klasses(Klass* k) { _array_klasses = k; }
+ inline void release_set_array_klasses(Klass* k); // store with release semantics
// methods
Array<Method*>* methods() const { return _methods; }
@@ -617,8 +619,8 @@
objArrayOop signers() const;
// host class
- Klass* host_klass() const {
- Klass** hk = (Klass**)adr_host_klass();
+ InstanceKlass* host_klass() const {
+ InstanceKlass** hk = adr_host_klass();
if (hk == NULL) {
return NULL;
} else {
@@ -626,9 +628,9 @@
return *hk;
}
}
- void set_host_klass(const Klass* host) {
+ void set_host_klass(const InstanceKlass* host) {
assert(is_anonymous(), "not anonymous");
- const Klass** addr = (const Klass**)adr_host_klass();
+ const InstanceKlass** addr = (const InstanceKlass **)adr_host_klass();
assert(addr != NULL, "no reversed space");
if (addr != NULL) {
*addr = host;
@@ -707,6 +709,7 @@
// RedefineClasses() support for previous versions:
void add_previous_version(instanceKlassHandle ikh, int emcp_method_count);
+ void purge_previous_version_list();
InstanceKlass* previous_versions() const { return _previous_versions; }
#else
@@ -766,10 +769,15 @@
}
private:
- static int _previous_version_count;
+ static bool _has_previous_versions;
public:
- static void purge_previous_versions(InstanceKlass* ik);
- static bool has_previous_versions() { return _previous_version_count > 0; }
+ static void purge_previous_versions(InstanceKlass* ik) {
+ if (ik->has_been_redefined()) {
+ ik->purge_previous_version_list();
+ }
+ }
+
+ static bool has_previous_versions_and_reset();
// JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation
void set_cached_class_file(JvmtiCachedClassFileData *data) {
@@ -790,7 +798,7 @@
#else // INCLUDE_JVMTI
static void purge_previous_versions(InstanceKlass* ik) { return; };
- static bool has_previous_versions() { return false; }
+ static bool has_previous_versions_and_reset() { return false; }
void set_cached_class_file(JvmtiCachedClassFileData *data) {
assert(data == NULL, "unexpected call with JVMTI disabled");
@@ -1055,13 +1063,13 @@
}
};
- Klass** adr_host_klass() const {
+ InstanceKlass** adr_host_klass() const {
if (is_anonymous()) {
- Klass** adr_impl = adr_implementor();
+ InstanceKlass** adr_impl = (InstanceKlass **)adr_implementor();
if (adr_impl != NULL) {
return adr_impl + 1;
} else {
- return end_of_nonstatic_oop_maps();
+ return (InstanceKlass **)end_of_nonstatic_oop_maps();
}
} else {
return NULL;
@@ -1238,10 +1246,8 @@
// cache management logic if the caches can grow instead of just
// going from NULL to non-NULL.
bool idnum_can_increment() const { return has_been_redefined(); }
- jmethodID* methods_jmethod_ids_acquire() const
- { return (jmethodID*)OrderAccess::load_ptr_acquire(&_methods_jmethod_ids); }
- void release_set_methods_jmethod_ids(jmethodID* jmeths)
- { OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths); }
+ inline jmethodID* methods_jmethod_ids_acquire() const;
+ inline void release_set_methods_jmethod_ids(jmethodID* jmeths);
// Lock during initialization
public:
--- a/hotspot/src/share/vm/oops/instanceKlass.inline.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.inline.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -29,10 +29,27 @@
#include "oops/instanceKlass.hpp"
#include "oops/klass.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/orderAccess.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
+inline Klass* InstanceKlass::array_klasses_acquire() const {
+ return (Klass*) OrderAccess::load_ptr_acquire(&_array_klasses);
+}
+
+inline void InstanceKlass::release_set_array_klasses(Klass* k) {
+ OrderAccess::release_store_ptr(&_array_klasses, k);
+}
+
+inline jmethodID* InstanceKlass::methods_jmethod_ids_acquire() const {
+ return (jmethodID*)OrderAccess::load_ptr_acquire(&_methods_jmethod_ids);
+}
+
+inline void InstanceKlass::release_set_methods_jmethod_ids(jmethodID* jmeths) {
+ OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths);
+}
+
// The iteration over the oops in objects is a hot path in the GC code.
// By force inlining the following functions, we get similar GC performance
// as the previous macro based implementation.
--- a/hotspot/src/share/vm/oops/method.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -30,7 +30,6 @@
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/gcLocker.hpp"
#include "gc/shared/generation.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/bytecodeTracer.hpp"
#include "interpreter/bytecodes.hpp"
@@ -400,12 +399,6 @@
return;
}
- // Do not profile method if current thread holds the pending list lock,
- // which avoids deadlock for acquiring the MethodData_lock.
- if (ReferencePendingListLocker::is_locked_by_self()) {
- return;
- }
-
// Grab a lock here to prevent multiple
// MethodData*s from being created.
MutexLocker ml(MethodData_lock, THREAD);
--- a/hotspot/src/share/vm/oops/methodData.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/methodData.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -30,6 +30,9 @@
#include "oops/method.hpp"
#include "oops/oop.hpp"
#include "runtime/orderAccess.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
class BytecodeStream;
class KlassSizeStats;
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -34,6 +34,7 @@
#include "memory/metadataFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
+#include "oops/arrayKlass.inline.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.inline.hpp"
@@ -42,7 +43,6 @@
#include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
-#include "runtime/orderAccess.inline.hpp"
#include "utilities/copy.hpp"
#include "utilities/macros.hpp"
@@ -321,7 +321,8 @@
int dim = dimension();
if (dim == n) return this;
- if (higher_dimension() == NULL) {
+ // lock-free read needs acquire semantics
+ if (higher_dimension_acquire() == NULL) {
if (or_null) return NULL;
ResourceMark rm;
@@ -339,8 +340,8 @@
ObjArrayKlass::allocate_objArray_klass(class_loader_data(), dim + 1, this, CHECK_NULL);
ObjArrayKlass* ak = ObjArrayKlass::cast(k);
ak->set_lower_dimension(this);
- OrderAccess::storestore();
- set_higher_dimension(ak);
+ // use 'release' to pair with lock-free load
+ release_set_higher_dimension(ak);
assert(ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass");
}
}
--- a/hotspot/src/share/vm/oops/symbol.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/symbol.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -229,24 +229,25 @@
}
void Symbol::increment_refcount() {
- // Only increment the refcount if positive. If negative either
+ // Only increment the refcount if non-negative. If negative either
// overflow has occurred or it is a permanent symbol in a read only
// shared archive.
- if (_refcount >= 0) {
+ if (_refcount >= 0) { // not a permanent symbol
Atomic::inc(&_refcount);
NOT_PRODUCT(Atomic::inc(&_total_count);)
}
}
void Symbol::decrement_refcount() {
- if (_refcount >= 0) {
- Atomic::dec(&_refcount);
+ if (_refcount >= 0) { // not a permanent symbol
+ jshort new_value = Atomic::add(-1, &_refcount);
#ifdef ASSERT
- if (_refcount < 0) {
+ if (new_value == -1) { // we have transitioned from 0 -> -1
print();
assert(false, "reference count underflow for symbol");
}
#endif
+ (void)new_value;
}
}
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -34,6 +34,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "memory/universe.inline.hpp"
+#include "oops/arrayKlass.inline.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
@@ -41,7 +42,6 @@
#include "oops/typeArrayKlass.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/orderAccess.inline.hpp"
#include "utilities/macros.hpp"
bool TypeArrayKlass::compute_is_subtype_of(Klass* k) {
@@ -166,7 +166,8 @@
if (dim == n)
return this;
- if (higher_dimension() == NULL) {
+ // lock-free read needs acquire semantics
+ if (higher_dimension_acquire() == NULL) {
if (or_null) return NULL;
ResourceMark rm;
@@ -181,8 +182,8 @@
class_loader_data(), dim + 1, this, CHECK_NULL);
ObjArrayKlass* h_ak = ObjArrayKlass::cast(oak);
h_ak->set_lower_dimension(this);
- OrderAccess::storestore();
- set_higher_dimension(h_ak);
+ // use 'release' to pair with lock-free load
+ release_set_higher_dimension(h_ak);
assert(h_ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass");
}
}
--- a/hotspot/src/share/vm/opto/block.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/block.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1212,6 +1212,9 @@
if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block");
}
+ if (n->needs_anti_dependence_check()) {
+ verify_anti_dependences(block, n);
+ }
for (uint k = 0; k < n->req(); k++) {
Node *def = n->in(k);
if (def && def != n) {
--- a/hotspot/src/share/vm/opto/block.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/block.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -186,14 +186,13 @@
Block* lone_fall_through(); // Return lone fall-through Block or null
Block* dom_lca(Block* that); // Compute LCA in dominator tree.
-#ifdef ASSERT
+
bool dominates(Block* that) {
int dom_diff = this->_dom_depth - that->_dom_depth;
if (dom_diff > 0) return false;
for (; dom_diff < 0; dom_diff++) that = that->_idom;
return this == that;
}
-#endif
// Report the alignment required by this block. Must be a power of 2.
// The previous block will insert nops to get this alignment.
@@ -481,9 +480,9 @@
MachNode* _goto;
Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
- void verify_anti_dependences(Block* LCA, Node* load) {
+ void verify_anti_dependences(Block* LCA, Node* load) const {
assert(LCA == get_block_for_node(load), "should already be scheduled");
- insert_anti_dependences(LCA, load, true);
+ const_cast<PhaseCFG*>(this)->insert_anti_dependences(LCA, load, true);
}
bool move_to_next(Block* bx, uint b_index);
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -530,6 +530,7 @@
case vmIntrinsics::_isInterrupted:
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime:
+ case vmIntrinsics::_getClassId:
#endif
case vmIntrinsics::_currentTimeMillis:
case vmIntrinsics::_nanoTime:
--- a/hotspot/src/share/vm/opto/callGenerator.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1164,7 +1164,10 @@
GraphKit kit(jvms);
kit.C->print_inlining_update(this);
// Take the trap with arguments pushed on the stack. (Cf. null_check_receiver).
- int nargs = method()->arg_size();
+ // Callsite signature can be different from actual method being called (i.e _linkTo* sites).
+ // Use callsite signature always.
+ ciMethod* declared_method = kit.method()->get_method_at_bci(kit.bci());
+ int nargs = declared_method->arg_size();
kit.inc_sp(nargs);
assert(nargs <= kit.sp() && kit.sp() <= jvms->stk_size(), "sane sp w/ args pushed");
if (_reason == Deoptimization::Reason_class_check &&
--- a/hotspot/src/share/vm/opto/cfgnode.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/cfgnode.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -119,6 +119,9 @@
// input in slot 0.
class PhiNode : public TypeNode {
const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes.
+ // The following fields are only used for data PhiNodes to indicate
+ // that the PhiNode represents the value of a known instance field.
+ int _inst_mem_id; // Instance memory id (node index of the memory Phi)
const int _inst_id; // Instance id of the memory slice.
const int _inst_index; // Alias index of the instance memory slice.
// Array elements references have the same alias_idx but different offset.
@@ -138,11 +141,13 @@
};
PhiNode( Node *r, const Type *t, const TypePtr* at = NULL,
+ const int imid = -1,
const int iid = TypeOopPtr::InstanceTop,
const int iidx = Compile::AliasIdxTop,
const int ioffs = Type::OffsetTop )
: TypeNode(t,r->req()),
_adr_type(at),
+ _inst_mem_id(imid),
_inst_id(iid),
_inst_index(iidx),
_inst_offset(ioffs)
@@ -194,11 +199,14 @@
virtual bool pinned() const { return in(0) != 0; }
virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; }
+ void set_inst_mem_id(int inst_mem_id) { _inst_mem_id = inst_mem_id; }
+ const int inst_mem_id() const { return _inst_mem_id; }
const int inst_id() const { return _inst_id; }
const int inst_index() const { return _inst_index; }
const int inst_offset() const { return _inst_offset; }
- bool is_same_inst_field(const Type* tp, int id, int index, int offset) {
+ bool is_same_inst_field(const Type* tp, int mem_id, int id, int index, int offset) {
return type()->basic_type() == tp->basic_type() &&
+ inst_mem_id() == mem_id &&
inst_id() == id &&
inst_index() == index &&
inst_offset() == offset &&
--- a/hotspot/src/share/vm/opto/compile.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1708,16 +1708,21 @@
const TypePtr* flat = flatten_alias_type(adr_type);
#ifdef ASSERT
- assert(flat == flatten_alias_type(flat), "idempotent");
- assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr");
- if (flat->isa_oopptr() && !flat->isa_klassptr()) {
- const TypeOopPtr* foop = flat->is_oopptr();
- // Scalarizable allocations have exact klass always.
- bool exact = !foop->klass_is_exact() || foop->is_known_instance();
- const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr();
- assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type");
+ {
+ ResourceMark rm;
+ assert(flat == flatten_alias_type(flat), "not idempotent: adr_type = %s; flat = %s => %s",
+ Type::str(adr_type), Type::str(flat), Type::str(flatten_alias_type(flat)));
+ assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr: adr_type = %s",
+ Type::str(adr_type));
+ if (flat->isa_oopptr() && !flat->isa_klassptr()) {
+ const TypeOopPtr* foop = flat->is_oopptr();
+ // Scalarizable allocations have exact klass always.
+ bool exact = !foop->klass_is_exact() || foop->is_known_instance();
+ const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr();
+ assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type: foop = %s; xoop = %s",
+ Type::str(foop), Type::str(xoop));
+ }
}
- assert(flat == flatten_alias_type(flat), "exact bit doesn't matter");
#endif
int idx = AliasIdxTop;
@@ -3159,45 +3164,65 @@
break;
#endif
- case Op_ModI:
+ case Op_ModI: {
+ Node* di = NULL;
if (UseDivMod) {
// Check if a%b and a/b both exist
- Node* d = n->find_similar(Op_DivI);
- if (d) {
+ di = n->find_similar(Op_DivI);
+ if (di) {
// Replace them with a fused divmod if supported
if (Matcher::has_match_rule(Op_DivModI)) {
DivModINode* divmod = DivModINode::make(n);
- d->subsume_by(divmod->div_proj(), this);
+ di->subsume_by(divmod->div_proj(), this);
n->subsume_by(divmod->mod_proj(), this);
} else {
// replace a%b with a-((a/b)*b)
- Node* mult = new MulINode(d, d->in(2));
- Node* sub = new SubINode(d->in(1), mult);
+ Node* mult = new MulINode(di, di->in(2));
+ Node* sub = new SubINode(di->in(1), mult);
n->subsume_by(sub, this);
}
}
}
+ if (di == NULL) {
+ // Remove useless control edge in case of not mod-zero.
+ const Type *t = n->in(2)->bottom_type();
+ const TypeInt *ti = t->is_int();
+ if (n->in(0) && (ti->_hi < 0 || ti->_lo > 0)) {
+ n->set_req(0, NULL);
+ }
+ }
break;
-
- case Op_ModL:
+ }
+
+ case Op_ModL: {
+ Node* dl = NULL;
if (UseDivMod) {
// Check if a%b and a/b both exist
- Node* d = n->find_similar(Op_DivL);
- if (d) {
+ dl = n->find_similar(Op_DivL);
+ if (dl) {
// Replace them with a fused divmod if supported
if (Matcher::has_match_rule(Op_DivModL)) {
DivModLNode* divmod = DivModLNode::make(n);
- d->subsume_by(divmod->div_proj(), this);
+ dl->subsume_by(divmod->div_proj(), this);
n->subsume_by(divmod->mod_proj(), this);
} else {
// replace a%b with a-((a/b)*b)
- Node* mult = new MulLNode(d, d->in(2));
- Node* sub = new SubLNode(d->in(1), mult);
+ Node* mult = new MulLNode(dl, dl->in(2));
+ Node* sub = new SubLNode(dl->in(1), mult);
n->subsume_by(sub, this);
}
}
}
+ if (dl == NULL) {
+ // Remove useless control edge in case of not mod-zero.
+ const Type *t = n->in(2)->bottom_type();
+ const TypeLong *tl = t->is_long();
+ if (n->in(0) && (tl->_hi < 0 || tl->_lo > 0)) {
+ n->set_req(0, NULL);
+ }
+ }
break;
+ }
case Op_LoadVector:
case Op_StoreVector:
--- a/hotspot/src/share/vm/opto/divnode.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/divnode.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -853,13 +853,6 @@
if( t == Type::TOP ) return NULL;
const TypeInt *ti = t->is_int();
- // Check for useless control input
- // Check for excluding mod-zero case
- if( in(0) && (ti->_hi < 0 || ti->_lo > 0) ) {
- set_req(0, NULL); // Yank control input
- return this;
- }
-
// See if we are MOD'ing by 2^k or 2^k-1.
if( !ti->is_con() ) return NULL;
jint con = ti->get_con();
@@ -1024,13 +1017,6 @@
if( t == Type::TOP ) return NULL;
const TypeLong *tl = t->is_long();
- // Check for useless control input
- // Check for excluding mod-zero case
- if( in(0) && (tl->_hi < 0 || tl->_lo > 0) ) {
- set_req(0, NULL); // Yank control input
- return this;
- }
-
// See if we are MOD'ing by 2^k or 2^k-1.
if( !tl->is_con() ) return NULL;
jlong con = tl->get_con();
--- a/hotspot/src/share/vm/opto/graphKit.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -664,7 +664,10 @@
// callee (with all arguments still on the stack).
Node* null_check_receiver_before_call(ciMethod* callee) {
assert(!callee->is_static(), "must be a virtual method");
- const int nargs = callee->arg_size();
+ // Callsite signature can be different from actual method being called (i.e _linkTo* sites).
+ // Use callsite signature always.
+ ciMethod* declared_method = method()->get_method_at_bci(bci());
+ const int nargs = declared_method->arg_size();
inc_sp(nargs);
Node* n = null_check_receiver();
dec_sp(nargs);
--- a/hotspot/src/share/vm/opto/lcm.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -240,6 +240,14 @@
continue;
}
+ // Check that node's control edge is not-null block's head or dominates it,
+ // otherwise we can't hoist it because there are other control dependencies.
+ Node* ctrl = mach->in(0);
+ if (ctrl != NULL && !(ctrl == not_null_block->head() ||
+ get_block_for_node(ctrl)->dominates(not_null_block))) {
+ continue;
+ }
+
// check if the offset is not too high for implicit exception
{
intptr_t offset = 0;
@@ -379,9 +387,12 @@
block->add_inst(best);
map_node_to_block(best, block);
- // Move the control dependence
- if (best->in(0) && best->in(0) == old_block->head())
- best->set_req(0, block->head());
+ // Move the control dependence if it is pinned to not-null block.
+ // Don't change it in other cases: NULL or dominating control.
+ if (best->in(0) == not_null_block->head()) {
+ // Set it to control edge of null check.
+ best->set_req(0, proj->in(0)->in(0));
+ }
// Check for flag-killing projections that also need to be hoisted
// Should be DU safe because no edge updates.
@@ -437,6 +448,18 @@
latency_from_uses(nul_chk);
latency_from_uses(best);
+
+ // insert anti-dependences to defs in this block
+ if (! best->needs_anti_dependence_check()) {
+ for (uint k = 1; k < block->number_of_nodes(); k++) {
+ Node *n = block->get_node(k);
+ if (n->needs_anti_dependence_check() &&
+ n->in(LoadNode::Memory) == best->in(StoreNode::Memory)) {
+ // Found anti-dependent load
+ insert_anti_dependences(block, n);
+ }
+ }
+ }
}
--- a/hotspot/src/share/vm/opto/library_call.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -254,6 +254,9 @@
bool inline_native_currentThread();
bool inline_native_time_funcs(address method, const char* funcName);
+#ifdef TRACE_HAVE_INTRINSICS
+ bool inline_native_classID();
+#endif
bool inline_native_isInterrupted();
bool inline_native_Class_query(vmIntrinsics::ID id);
bool inline_native_subtype_check();
@@ -708,6 +711,7 @@
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), "counterTime");
+ case vmIntrinsics::_getClassId: return inline_native_classID();
#endif
case vmIntrinsics::_currentTimeMillis: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeMillis), "currentTimeMillis");
case vmIntrinsics::_nanoTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeNanos), "nanoTime");
@@ -2242,8 +2246,8 @@
#ifndef PRODUCT
if (C->print_intrinsics() || C->print_inlining()) {
- tty->print(" from base type: "); adr_type->dump();
- tty->print(" sharpened value: "); tjp->dump();
+ tty->print(" from base type: "); adr_type->dump(); tty->cr();
+ tty->print(" sharpened value: "); tjp->dump(); tty->cr();
}
#endif
// Sharpen the value type.
@@ -2308,26 +2312,30 @@
adr = make_unsafe_address(base, offset);
if (_gvn.type(base)->isa_ptr() != TypePtr::NULL_PTR) {
heap_base_oop = base;
- }
+ } else if (type == T_OBJECT) {
+ return false; // off-heap oop accesses are not supported
+ }
+
+ // Can base be NULL? Otherwise, always on-heap access.
+ bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop));
+
val = is_store ? argument(4) : NULL;
const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
- // Try to categorize the address. If it comes up as TypeJavaPtr::BOTTOM,
- // there was not enough information to nail it down.
+ // Try to categorize the address.
Compile::AliasType* alias_type = C->alias_type(adr_type);
assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
- // Only field, array element or unknown locations are supported.
- if (alias_type->adr_type() != TypeRawPtr::BOTTOM &&
- alias_type->adr_type() != TypeOopPtr::BOTTOM &&
- alias_type->basic_type() == T_ILLEGAL) {
- return false;
+ if (alias_type->adr_type() == TypeInstPtr::KLASS ||
+ alias_type->adr_type() == TypeAryPtr::RANGE) {
+ return false; // not supported
}
bool mismatched = false;
BasicType bt = alias_type->basic_type();
if (bt != T_ILLEGAL) {
+ assert(alias_type->adr_type()->is_oopptr(), "should be on-heap access");
if (bt == T_BYTE && adr_type->isa_aryptr()) {
// Alias type doesn't differentiate between byte[] and boolean[]).
// Use address type to get the element type.
@@ -2342,10 +2350,12 @@
return false;
}
mismatched = (bt != type);
- } else if (alias_type->adr_type() == TypeOopPtr::BOTTOM) {
+ } else if (alias_type->adr_type()->isa_oopptr()) {
mismatched = true; // conservatively mark all "wide" on-heap accesses as mismatched
}
+ assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched");
+
// First guess at the value type.
const Type *value_type = Type::get_const_basic_type(type);
@@ -2357,7 +2367,7 @@
bool need_mem_bar;
switch (kind) {
case Relaxed:
- need_mem_bar = (alias_type->adr_type() == TypeOopPtr::BOTTOM);
+ need_mem_bar = mismatched || can_access_non_heap;
break;
case Opaque:
// Opaque uses CPUOrder membars for protection against code movement.
@@ -2508,34 +2518,10 @@
break;
}
- if (type != T_OBJECT) {
- (void) store_to_memory(control(), adr, val, type, adr_type, mo, requires_atomic_access, unaligned, mismatched);
+ if (type == T_OBJECT) {
+ store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched);
} else {
- // Possibly an oop being stored to Java heap or native memory
- if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) {
- // oop to Java heap.
- (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched);
- } else {
- // We can't tell at compile time if we are storing in the Java heap or outside
- // of it. So we need to emit code to conditionally do the proper type of
- // store.
-
- IdealKit ideal(this);
-#define __ ideal.
- // QQQ who knows what probability is here??
- __ if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); {
- // Sync IdealKit and graphKit.
- sync_kit(ideal);
- Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo, mismatched);
- // Update IdealKit memory.
- __ sync_kit(this);
- } __ else_(); {
- __ store(__ ctrl(), adr, val, type, alias_type->index(), mo, requires_atomic_access, mismatched);
- } __ end_if();
- // Final sync IdealKit and GraphKit.
- final_sync(ideal);
-#undef __
- }
+ store_to_memory(control(), adr, val, type, adr_type, mo, requires_atomic_access, unaligned, mismatched);
}
}
@@ -3150,6 +3136,43 @@
return true;
}
+#ifdef TRACE_HAVE_INTRINSICS
+
+/*
+* oop -> myklass
+* myklass->trace_id |= USED
+* return myklass->trace_id & ~0x3
+*/
+bool LibraryCallKit::inline_native_classID() {
+ Node* cls = null_check(argument(0), T_OBJECT);
+ Node* kls = load_klass_from_mirror(cls, false, NULL, 0);
+ kls = null_check(kls, T_OBJECT);
+
+ ByteSize offset = TRACE_KLASS_TRACE_ID_OFFSET;
+ Node* insp = basic_plus_adr(kls, in_bytes(offset));
+ Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered);
+
+ Node* clsused = longcon(0x01l); // set the class bit
+ Node* orl = _gvn.transform(new OrLNode(tvalue, clsused));
+ const TypePtr *adr_type = _gvn.type(insp)->isa_ptr();
+ store_to_memory(control(), insp, orl, T_LONG, adr_type, MemNode::unordered);
+
+#ifdef TRACE_ID_META_BITS
+ Node* mbits = longcon(~TRACE_ID_META_BITS);
+ tvalue = _gvn.transform(new AndLNode(tvalue, mbits));
+#endif
+#ifdef TRACE_ID_CLASS_SHIFT
+ Node* cbits = intcon(TRACE_ID_CLASS_SHIFT);
+ tvalue = _gvn.transform(new URShiftLNode(tvalue, cbits));
+#endif
+
+ set_result(tvalue);
+ return true;
+
+}
+
+#endif
+
//------------------------inline_native_currentThread------------------
bool LibraryCallKit::inline_native_currentThread() {
Node* junk = NULL;
--- a/hotspot/src/share/vm/opto/macro.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -491,7 +491,7 @@
for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
Node* phi = region->fast_out(k);
if (phi->is_Phi() && phi != mem &&
- phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) {
+ phi->as_Phi()->is_same_inst_field(phi_type, (int)mem->_idx, instance_id, alias_idx, offset)) {
return phi;
}
}
@@ -510,7 +510,7 @@
GrowableArray <Node *> values(length, length, NULL, false);
// create a new Phi for the value
- PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
+ PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, mem->_idx, instance_id, alias_idx, offset);
transform_later(phi);
value_phis->push(phi, mem->_idx);
--- a/hotspot/src/share/vm/opto/memnode.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1112,7 +1112,7 @@
for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
Node* phi = region->fast_out(i);
if (phi->is_Phi() && phi != mem &&
- phi->as_Phi()->is_same_inst_field(this_type, this_iid, this_index, this_offset)) {
+ phi->as_Phi()->is_same_inst_field(this_type, (int)mem->_idx, this_iid, this_index, this_offset)) {
return phi;
}
}
@@ -1395,7 +1395,7 @@
this_iid = base->_idx;
}
PhaseIterGVN* igvn = phase->is_IterGVN();
- Node* phi = new PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
+ Node* phi = new PhiNode(region, this_type, NULL, mem->_idx, this_iid, this_index, this_offset);
for (uint i = 1; i < region->req(); i++) {
Node* x;
Node* the_clone = NULL;
--- a/hotspot/src/share/vm/opto/phaseX.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -491,6 +491,8 @@
uint current_idx = 0; // The current new node ID. Incremented after every assignment.
for (uint i = 0; i < _useful.size(); i++) {
Node* n = _useful.at(i);
+ // Sanity check that fails if we ever decide to execute this phase after EA
+ assert(!n->is_Phi() || n->as_Phi()->inst_mem_id() == -1, "should not be linked to data Phi");
const Type* type = gvn->type_or_null(n);
new_type_array.map(current_idx, type);
@@ -1448,6 +1450,18 @@
i -= num_edges; // we deleted 1 or more copies of this edge
}
+ // Search for instance field data PhiNodes in the same region pointing to the old
+ // memory PhiNode and update their instance memory ids to point to the new node.
+ if (old->is_Phi() && old->as_Phi()->type()->has_memory() && old->in(0) != NULL) {
+ Node* region = old->in(0);
+ for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
+ PhiNode* phi = region->fast_out(i)->isa_Phi();
+ if (phi != NULL && phi->inst_mem_id() == (int)old->_idx) {
+ phi->set_inst_mem_id((int)nn->_idx);
+ }
+ }
+ }
+
// Smash all inputs to 'old', isolating him completely
Node *temp = new Node(1);
temp->init_req(0,nn); // Add a use to nn to prevent him from dying
--- a/hotspot/src/share/vm/opto/type.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1015,6 +1015,13 @@
st->print(" [narrowklass]");
}
}
+
+//-----------------------------------------------------------------------------
+const char* Type::str(const Type* t) {
+ stringStream ss;
+ t->dump_on(&ss);
+ return ss.as_string();
+}
#endif
//------------------------------singleton--------------------------------------
--- a/hotspot/src/share/vm/opto/type.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/opto/type.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -210,11 +210,11 @@
static int cmp( const Type *const t1, const Type *const t2 );
// Test for higher or equal in lattice
// Variant that drops the speculative part of the types
- int higher_equal(const Type *t) const {
+ bool higher_equal(const Type *t) const {
return !cmp(meet(t),t->remove_speculative());
}
// Variant that keeps the speculative part of the types
- int higher_equal_speculative(const Type *t) const {
+ bool higher_equal_speculative(const Type *t) const {
return !cmp(meet_speculative(t),t);
}
@@ -359,6 +359,8 @@
}
virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
static void dump_stats();
+
+ static const char* str(const Type* t);
#endif
void typerr(const Type *t) const; // Mixing types error
@@ -963,7 +965,7 @@
// If not InstanceTop or InstanceBot, indicates that this is
// a particular instance of this type which is distinct.
- // This is the the node index of the allocation node creating this instance.
+ // This is the node index of the allocation node creating this instance.
int _instance_id;
static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
--- a/hotspot/src/share/vm/prims/jvm.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -3352,6 +3352,35 @@
JVM_END
+// java.lang.ref.Reference ///////////////////////////////////////////////////////////////
+
+
+JVM_ENTRY(jobject, JVM_GetAndClearReferencePendingList(JNIEnv* env))
+ JVMWrapper("JVM_GetAndClearReferencePendingList");
+
+ MonitorLockerEx ml(Heap_lock);
+ oop ref = Universe::reference_pending_list();
+ if (ref != NULL) {
+ Universe::set_reference_pending_list(NULL);
+ }
+ return JNIHandles::make_local(env, ref);
+JVM_END
+
+JVM_ENTRY(jboolean, JVM_HasReferencePendingList(JNIEnv* env))
+ JVMWrapper("JVM_HasReferencePendingList");
+ MonitorLockerEx ml(Heap_lock);
+ return Universe::has_reference_pending_list();
+JVM_END
+
+JVM_ENTRY(void, JVM_WaitForReferencePendingList(JNIEnv* env))
+ JVMWrapper("JVM_WaitForReferencePendingList");
+ MonitorLockerEx ml(Heap_lock);
+ while (!Universe::has_reference_pending_list()) {
+ ml.wait();
+ }
+JVM_END
+
+
// ObjectInputStream ///////////////////////////////////////////////////////////////
bool force_verify_field_access(Klass* current_class, Klass* field_class, AccessFlags access, bool classloader_only) {
--- a/hotspot/src/share/vm/prims/jvm.h Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h Wed Sep 21 09:29:30 2016 -0700
@@ -297,6 +297,18 @@
JVM_GetSystemPackages(JNIEnv *env);
/*
+ * java.lang.ref.Reference
+ */
+JNIEXPORT jobject JNICALL
+JVM_GetAndClearReferencePendingList(JNIEnv *env);
+
+JNIEXPORT jboolean JNICALL
+JVM_HasReferencePendingList(JNIEnv *env);
+
+JNIEXPORT void JNICALL
+JVM_WaitForReferencePendingList(JNIEnv *env);
+
+/*
* java.io.ObjectInputStream
*/
JNIEXPORT jobject JNICALL
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -649,18 +649,14 @@
jvmtiError
JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {
+ LogLevelType level = value == 0 ? LogLevel::Off : LogLevel::Info;
switch (flag) {
case JVMTI_VERBOSE_OTHER:
// ignore
break;
case JVMTI_VERBOSE_CLASS:
- if (value == 0) {
- LogConfiguration::parse_log_arguments("stdout", "class+unload=off", NULL, NULL, NULL);
- LogConfiguration::parse_log_arguments("stdout", "class+load=off", NULL, NULL, NULL);
- } else {
- LogConfiguration::parse_log_arguments("stdout", "class+load=info", NULL, NULL, NULL);
- LogConfiguration::parse_log_arguments("stdout", "class+unload=info", NULL, NULL, NULL);
- }
+ LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, unload));
+ LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, load));
break;
case JVMTI_VERBOSE_GC:
if (value == 0) {
--- a/hotspot/src/share/vm/prims/unsafe.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -324,6 +324,10 @@
volatile oop v;
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ OrderAccess::fence();
+ }
+
if (UseCompressedOops) {
volatile narrowOop n = *(volatile narrowOop*) addr;
(void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
@@ -779,6 +783,7 @@
// define a class but do not make it known to the class loader or system dictionary
// - host_class: supplies context for linkage, access control, protection domain, and class loader
+// if host_class is itself anonymous then it is replaced with its host class.
// - data: bytes of a class file, a raw memory address (length gives the number of bytes)
// - cp_patches: where non-null entries exist, they replace corresponding CP entries in data
@@ -787,8 +792,12 @@
// link to any member of U. Just after U is loaded, the only way to use it is reflectively,
// through java.lang.Class methods like Class.newInstance.
+// The package of an anonymous class must either match its host's class's package or be in the
+// unnamed package. If it is in the unnamed package then it will be put in its host class's
+// package.
+//
+
// Access checks for linkage sites within U continue to follow the same rules as for named classes.
-// The package of an anonymous class is given by the package qualifier on the name under which it was loaded.
// An anonymous class also has special privileges to access any member of its host class.
// This is the main reason why this loading operation is unsafe. The purpose of this is to
// allow language implementations to simulate "open classes"; a host class in effect gets
@@ -870,9 +879,11 @@
// Primitive types have NULL Klass* fields in their java.lang.Class instances.
if (host_klass == NULL) {
- THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Host class is null");
}
+ assert(host_klass->is_instance_klass(), "Host class must be an instance class");
+
const char* host_source = host_klass->external_name();
Handle host_loader(THREAD, host_klass->class_loader());
Handle host_domain(THREAD, host_klass->protection_domain());
@@ -903,7 +914,7 @@
host_loader,
host_domain,
&st,
- host_klass,
+ InstanceKlass::cast(host_klass),
cp_patches,
CHECK_NULL);
if (anonk == NULL) {
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -33,8 +33,9 @@
#include "gc/shared/referenceProcessor.hpp"
#include "gc/shared/taskqueue.hpp"
#include "logging/log.hpp"
+#include "logging/logConfiguration.hpp"
+#include "logging/logStream.hpp"
#include "logging/logTag.hpp"
-#include "logging/logConfiguration.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/universe.inline.hpp"
#include "oops/oop.inline.hpp"
@@ -163,26 +164,47 @@
bool needs_module_property_warning = false;
-#define MODULE_PROPERTY_PREFIX "jdk.module"
-#define MODULE_PROPERTY_PREFIX_LEN 10
-#define MODULE_MAIN_PROPERTY "jdk.module.main"
-#define MODULE_MAIN_PROPERTY_LEN 15
-
-// Return TRUE if option matches property, or property=, or property..
-static bool matches_property_prefix(const char* option, const char* property, size_t len) {
- return (strncmp(option, property, len) == 0) &&
- (option[len] == '=' || option[len] == '.' || option[len] == '\0');
+#define MODULE_PROPERTY_PREFIX "jdk.module."
+#define MODULE_PROPERTY_PREFIX_LEN 11
+#define ADDEXPORTS "addexports"
+#define ADDEXPORTS_LEN 10
+#define ADDREADS "addreads"
+#define ADDREADS_LEN 8
+#define PATCH "patch"
+#define PATCH_LEN 5
+#define ADDMODS "addmods"
+#define ADDMODS_LEN 7
+#define LIMITMODS "limitmods"
+#define LIMITMODS_LEN 9
+#define PATH "path"
+#define PATH_LEN 4
+#define UPGRADE_PATH "upgrade.path"
+#define UPGRADE_PATH_LEN 12
+
+// Return TRUE if option matches 'property', or 'property=', or 'property.'.
+static bool matches_property_suffix(const char* option, const char* property, size_t len) {
+ return ((strncmp(option, property, len) == 0) &&
+ (option[len] == '=' || option[len] == '.' || option[len] == '\0'));
}
-// Return true if the property is either "jdk.module" or starts with "jdk.module.",
-// but does not start with "jdk.module.main".
-// Return false if jdk.module.main because jdk.module.main and jdk.module.main.class
-// are valid non-internal system properties.
-// "property" should be passed without the leading "-D".
+// Return true if property starts with "jdk.module." and its ensuing chars match
+// any of the reserved module properties.
+// property should be passed without the leading "-D".
bool Arguments::is_internal_module_property(const char* property) {
assert((strncmp(property, "-D", 2) != 0), "Unexpected leading -D");
- return (matches_property_prefix(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) &&
- !matches_property_prefix(property, MODULE_MAIN_PROPERTY, MODULE_MAIN_PROPERTY_LEN));
+ if (strncmp(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) == 0) {
+ const char* property_suffix = property + MODULE_PROPERTY_PREFIX_LEN;
+ if (matches_property_suffix(property_suffix, ADDEXPORTS, ADDEXPORTS_LEN) ||
+ matches_property_suffix(property_suffix, ADDREADS, ADDREADS_LEN) ||
+ matches_property_suffix(property_suffix, PATCH, PATCH_LEN) ||
+ matches_property_suffix(property_suffix, ADDMODS, ADDMODS_LEN) ||
+ matches_property_suffix(property_suffix, LIMITMODS, LIMITMODS_LEN) ||
+ matches_property_suffix(property_suffix, PATH, PATH_LEN) ||
+ matches_property_suffix(property_suffix, UPGRADE_PATH, UPGRADE_PATH_LEN)) {
+ return true;
+ }
+ }
+ return false;
}
// Process java launcher properties.
@@ -4155,7 +4177,10 @@
if (_gc_log_filename != NULL) {
// -Xloggc was used to specify a filename
const char* gc_conf = PrintGCDetails ? "gc*" : "gc";
- return LogConfiguration::parse_log_arguments(_gc_log_filename, gc_conf, NULL, NULL, NULL);
+
+ LogTarget(Error, logging) target;
+ LogStreamCHeap errstream(target);
+ return LogConfiguration::parse_log_arguments(_gc_log_filename, gc_conf, NULL, NULL, &errstream);
} else if (PrintGC || PrintGCDetails) {
LogConfiguration::configure_stdout(LogLevel::Info, !PrintGCDetails, LOG_TAGS(gc));
}
@@ -4287,8 +4312,8 @@
}
if (needs_module_property_warning) {
- warning("Ignoring system property options whose names start with '-Djdk.module'."
- " They are reserved for internal use.");
+ warning("Ignoring system property options whose names match the '-Djdk.module.*'."
+ " names that are reserved for internal use.");
}
#if defined(_ALLBSD_SOURCE) || defined(AIX) // UseLargePages is not yet supported on BSD and AIX.
--- a/hotspot/src/share/vm/runtime/atomic.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/atomic.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -76,6 +76,7 @@
// Atomically add to a location. Returns updated value. add*() provide:
// <fence> add-value-to-dest <membar StoreLoad|StoreStore>
+ inline static jshort add (jshort add_value, volatile jshort* dest);
inline static jint add (jint add_value, volatile jint* dest);
inline static size_t add (size_t add_value, volatile size_t* dest);
inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
@@ -208,10 +209,11 @@
return old;
}
-inline void Atomic::inc(volatile short* dest) {
- // Most platforms do not support atomic increment on a 2-byte value. However,
+inline jshort Atomic::add(jshort add_value, volatile jshort* dest) {
+ // Most platforms do not support atomic add on a 2-byte value. However,
// if the value occupies the most significant 16 bits of an aligned 32-bit
- // word, then we can do this with an atomic add of 0x10000 to the 32-bit word.
+ // word, then we can do this with an atomic add of (add_value << 16)
+ // to the 32-bit word.
//
// The least significant parts of this 32-bit word will never be affected, even
// in case of overflow/underflow.
@@ -219,21 +221,20 @@
// Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
#ifdef VM_LITTLE_ENDIAN
assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
- (void)Atomic::add(0x10000, (volatile int*)(dest-1));
+ jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest-1));
#else
assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
- (void)Atomic::add(0x10000, (volatile int*)(dest));
+ jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest));
#endif
+ return (jshort)(new_value >> 16); // preserves sign
}
-inline void Atomic::dec(volatile short* dest) {
-#ifdef VM_LITTLE_ENDIAN
- assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
- (void)Atomic::add(-0x10000, (volatile int*)(dest-1));
-#else
- assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
- (void)Atomic::add(-0x10000, (volatile int*)(dest));
-#endif
+inline void Atomic::inc(volatile jshort* dest) {
+ (void)add(1, dest);
+}
+
+inline void Atomic::dec(volatile jshort* dest) {
+ (void)add(-1, dest);
}
#endif // SHARE_VM_RUNTIME_ATOMIC_HPP
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -3017,9 +3017,6 @@
"Number of receiver types to record in call/cast profile") \
range(0, 8) \
\
- experimental(intx, MethodProfileWidth, 0, \
- "Number of methods to record in call profile") \
- \
develop(intx, BciProfileWidth, 2, \
"Number of return bci's to record in ret profile") \
\
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp Wed Sep 21 09:29:30 2016 -0700
@@ -219,6 +219,9 @@
trans_from_java(_thread_in_vm);
}
~ThreadInVMfromJava() {
+ if (_thread->stack_yellow_reserved_zone_disabled()) {
+ _thread->enable_stack_yellow_reserved_zone();
+ }
trans(_thread_in_vm, _thread_in_Java);
// Check for pending. async. exceptions or suspends.
if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
@@ -306,6 +309,9 @@
trans_from_java(_thread_in_vm);
}
~ThreadInVMfromJavaNoAsyncException() {
+ if (_thread->stack_yellow_reserved_zone_disabled()) {
+ _thread->enable_stack_yellow_reserved_zone();
+ }
trans(_thread_in_vm, _thread_in_Java);
// NOTE: We do not check for pending. async. exceptions.
// If we did and moved the pending async exception over into the
@@ -314,6 +320,7 @@
// to the _thread_in_vm state. Instead we postpone the handling of
// the async exception.
+
// Check for pending. suspends only.
if (_thread->has_special_runtime_exit_condition())
_thread->handle_special_runtime_exit_condition(false);
--- a/hotspot/src/share/vm/runtime/reflection.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -412,13 +412,13 @@
return result;
}
-static bool under_host_klass(const InstanceKlass* ik, const Klass* host_klass) {
+static bool under_host_klass(const InstanceKlass* ik, const InstanceKlass* host_klass) {
DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
for (;;) {
- const Klass* hc = (const Klass*)ik->host_klass();
+ const InstanceKlass* hc = ik->host_klass();
if (hc == NULL) return false;
if (hc == host_klass) return true;
- ik = InstanceKlass::cast(hc);
+ ik = hc;
// There's no way to make a host class loop short of patching memory.
// Therefore there cannot be a loop here unless there's another bug.
@@ -436,8 +436,8 @@
// If either is on the other's host_klass chain, access is OK,
// because one is inside the other.
- if (under_host_klass(accessor_ik, accessee) ||
- under_host_klass(accessee_ik, accessor))
+ if (under_host_klass(accessor_ik, accessee_ik) ||
+ under_host_klass(accessee_ik, accessor_ik))
return true;
if ((RelaxAccessControlCheck &&
@@ -446,7 +446,7 @@
(accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION &&
accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) {
return classloader_only &&
- Verifier::relax_verify_for(accessor_ik->class_loader()) &&
+ Verifier::relax_access_for(accessor_ik->class_loader()) &&
accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
accessor_ik->class_loader() == accessee_ik->class_loader();
}
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -35,7 +35,6 @@
#include "compiler/compileTask.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcLocker.inline.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "gc/shared/workgroup.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/linkResolver.hpp"
@@ -3718,14 +3717,6 @@
Management::record_vm_init_completed();
#endif // INCLUDE_MANAGEMENT
- // Note that we do not use CHECK_0 here since we are inside an EXCEPTION_MARK and
- // set_init_completed has just been called, causing exceptions not to be shortcut
- // anymore. We call vm_exit_during_initialization directly instead.
-
- // Initialize reference pending list locker
- bool needs_locker_thread = Universe::heap()->needs_reference_pending_list_locker_thread();
- ReferencePendingListLocker::initialize(needs_locker_thread, CHECK_JNI_ERR);
-
// Signal Dispatcher needs to be started before VMInit event is posted
os::signal_init();
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -54,7 +54,6 @@
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/generation.hpp"
#include "gc/shared/generationSpec.hpp"
-#include "gc/shared/referencePendingListLocker.hpp"
#include "gc/shared/space.hpp"
#include "interpreter/bytecodeInterpreter.hpp"
#include "interpreter/bytecodes.hpp"
@@ -242,7 +241,7 @@
nonstatic_field(ConstantPool, _reference_map, Array<u2>*) \
nonstatic_field(ConstantPoolCache, _length, int) \
nonstatic_field(ConstantPoolCache, _constant_pool, ConstantPool*) \
- nonstatic_field(InstanceKlass, _array_klasses, Klass*) \
+ volatile_nonstatic_field(InstanceKlass, _array_klasses, Klass*) \
nonstatic_field(InstanceKlass, _methods, Array<Method*>*) \
nonstatic_field(InstanceKlass, _default_methods, Array<Method*>*) \
nonstatic_field(InstanceKlass, _local_interfaces, Array<Klass*>*) \
@@ -271,7 +270,7 @@
nonstatic_field(InstanceKlass, _osr_nmethods_head, nmethod*) \
JVMTI_ONLY(nonstatic_field(InstanceKlass, _breakpoints, BreakpointInfo*)) \
nonstatic_field(InstanceKlass, _generic_signature_index, u2) \
- nonstatic_field(InstanceKlass, _methods_jmethod_ids, jmethodID*) \
+ volatile_nonstatic_field(InstanceKlass, _methods_jmethod_ids, jmethodID*) \
volatile_nonstatic_field(InstanceKlass, _idnum_allocated_count, u2) \
nonstatic_field(InstanceKlass, _annotations, Annotations*) \
nonstatic_field(InstanceKlass, _method_ordering, Array<int>*) \
@@ -1637,7 +1636,6 @@
declare_type(JavaThread, Thread) \
declare_type(JvmtiAgentThread, JavaThread) \
declare_type(ServiceThread, JavaThread) \
- declare_type(ReferencePendingListLockerThread, JavaThread) \
declare_type(CompilerThread, JavaThread) \
declare_type(CodeCacheSweeperThread, JavaThread) \
declare_toplevel_type(OSThread) \
@@ -2628,6 +2626,11 @@
declare_constant(Deoptimization::Reason_rtm_state_change) \
declare_constant(Deoptimization::Reason_unstable_if) \
declare_constant(Deoptimization::Reason_unstable_fused_if) \
+ NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_aliasing))) \
+ NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_transfer_to_interpreter))) \
+ NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_not_compiled_exception_handler))) \
+ NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_unresolved))) \
+ NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_jsr_mismatch))) \
declare_constant(Deoptimization::Reason_tenured) \
declare_constant(Deoptimization::Reason_LIMIT) \
declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \
@@ -2752,7 +2755,13 @@
declare_constant(ConcreteRegisterImpl::number_of_registers) \
declare_preprocessor_constant("REG_COUNT", REG_COUNT) \
declare_c2_preprocessor_constant("SAVED_ON_ENTRY_REG_COUNT", SAVED_ON_ENTRY_REG_COUNT) \
- declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT)
+ declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT) \
+ \
+ /****************/ \
+ /* JVMCI */ \
+ /****************/ \
+ \
+ declare_preprocessor_constant("INCLUDE_JVMCI", INCLUDE_JVMCI)
//--------------------------------------------------------------------------------
--- a/hotspot/src/share/vm/services/classLoadingService.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/services/classLoadingService.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -183,11 +183,8 @@
bool ClassLoadingService::set_verbose(bool verbose) {
MutexLocker m(Management_lock);
// verbose will be set to the previous value
- if (verbose) {
- LogConfiguration::parse_log_arguments("stdout", "class+load=info", NULL, NULL, NULL);
- } else {
- LogConfiguration::parse_log_arguments("stdout", "class+load=off", NULL, NULL, NULL);
- }
+ LogLevelType level = verbose ? LogLevel::Info : LogLevel::Off;
+ LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, load));
reset_trace_class_unloading();
return verbose;
}
@@ -196,11 +193,8 @@
void ClassLoadingService::reset_trace_class_unloading() {
assert(Management_lock->owned_by_self(), "Must own the Management_lock");
bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
- if (value) {
- LogConfiguration::parse_log_arguments("stdout", "class+unload=info", NULL, NULL, NULL);
- } else {
- LogConfiguration::parse_log_arguments("stdout", "class+unload=off", NULL, NULL, NULL);
- }
+ LogLevelType level = value ? LogLevel::Info : LogLevel::Off;
+ LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, unload));
}
GrowableArray<KlassHandle>* LoadedClassesEnumerator::_loaded_classes = NULL;
--- a/hotspot/src/share/vm/utilities/internalVMTests.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -56,12 +56,10 @@
run_unit_test(CollectedHeap_test);
run_unit_test(QuickSort_test);
run_unit_test(GuardedMemory_test);
- run_unit_test(AltHashing_test);
run_unit_test(TestNewSize_test);
run_unit_test(TestOldSize_test);
run_unit_test(TestKlass_test);
run_unit_test(TestBitMap_test);
- run_unit_test(TestAsUtf8);
run_unit_test(TestResourcehash_test);
run_unit_test(ObjectMonitor_test);
run_unit_test(Test_linked_list);
@@ -89,16 +87,12 @@
run_unit_test(VMStructs_test);
#endif
#if INCLUDE_ALL_GCS
- run_unit_test(TestOldFreeSpaceCalculation_test);
run_unit_test(TestG1BiasedArray_test);
run_unit_test(TestBufferingOopClosure_test);
- run_unit_test(TestCodeCacheRemSet_test);
if (UseG1GC) {
run_unit_test(FreeRegionList_test);
run_unit_test(IHOP_test);
}
- run_unit_test(test_memset_with_concurrent_readers);
- run_unit_test(TestPredictions_test);
run_unit_test(WorkerDataArray_test);
run_unit_test(ParallelCompact_test);
#endif
--- a/hotspot/src/share/vm/utilities/utf8.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/src/share/vm/utilities/utf8.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -547,30 +547,3 @@
template int UNICODE::quoted_ascii_length<jchar>(jchar* base, int length);
template void UNICODE::as_quoted_ascii<jbyte>(const jbyte* base, int length, char* buf, int buflen);
template void UNICODE::as_quoted_ascii<jchar>(const jchar* base, int length, char* buf, int buflen);
-
-
-#ifndef PRODUCT
-void TestAsUtf8() {
- char res[60];
- jchar str[20];
-
- for (int i = 0; i < 20; i++) {
- str[i] = 0x0800; // char that is 2B in UTF-16 but 3B in UTF-8
- }
- str[19] = (jchar)'\0';
-
- // The resulting string in UTF-8 is 3*19 bytes long, but should be truncated
- UNICODE::as_utf8(str, 19, res, 10);
- assert(strlen(res) == 9, "string should be truncated here");
-
- UNICODE::as_utf8(str, 19, res, 18);
- assert(strlen(res) == 15, "string should be truncated here");
-
- UNICODE::as_utf8(str, 19, res, 20);
- assert(strlen(res) == 18, "string should be truncated here");
-
- // Test with an "unbounded" buffer
- UNICODE::as_utf8(str, 19, res, INT_MAX);
- assert(strlen(res) == 3*19, "string should end here");
-}
-#endif
--- a/hotspot/test/TEST.groups Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/TEST.groups Wed Sep 21 09:29:30 2016 -0700
@@ -168,7 +168,6 @@
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
runtime/NMT/JcmdSummaryDiff.java \
runtime/RedefineTests/RedefineAnnotations.java \
- serviceability/sa/jmap-hashcode/Test8028623.java \
serviceability/threads/TestFalseDeadLock.java \
compiler/codecache/jmx \
compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java \
--- a/hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java Wed Sep 21 09:29:30 2016 -0700
@@ -36,11 +36,11 @@
package compiler.intrinsics.unsafe;
import jdk.internal.misc.Unsafe;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
public class TestUnsafeMismatchedArrayFieldAccess {
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
static {
try {
--- a/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -62,7 +62,7 @@
public class CallSiteDepContextTest {
static final Unsafe UNSAFE = Unsafe.getUnsafe();
static final MethodHandles.Lookup LOOKUP = MethodHandleHelper.IMPL_LOOKUP;
- static final String CLASS_NAME = "java/lang/invoke/Test";
+ static final String CLASS_NAME = "compiler/jsr292/Test";
static final String METHOD_NAME = "m";
static final MethodType TYPE = MethodType.methodType(int.class);
@@ -129,8 +129,8 @@
}
public static void testSharedCallSite() throws Throwable {
- Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_1"), null);
- Class<?> cls2 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_2"), null);
+ Class<?> cls1 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("CS_1"), null);
+ Class<?> cls2 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("CS_2"), null);
MethodHandle[] mhs = new MethodHandle[] {
LOOKUP.findStatic(cls1, METHOD_NAME, TYPE),
@@ -151,7 +151,7 @@
execute(1, mh);
// mcs.context == cls1
- Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("NonBound_1"), null);
+ Class<?> cls1 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("NonBound_1"), null);
MethodHandle mh1 = LOOKUP.findStatic(cls1, METHOD_NAME, TYPE);
execute(1, mh1);
@@ -170,8 +170,8 @@
mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
Class<?>[] cls = new Class[] {
- UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_1" + id), null),
- UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_2" + id), null),
+ UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_1" + id), null),
+ UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_2" + id), null),
};
MethodHandle[] mhs = new MethodHandle[] {
@@ -185,7 +185,7 @@
execute(1, mhs);
ref = new PhantomReference<>(cls[0], rq);
- cls[0] = UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_3" + id), null);
+ cls[0] = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_3" + id), null);
mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
do {
--- a/hotspot/test/compiler/jsr292/NullConstantReceiver.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jsr292/NullConstantReceiver.java Wed Sep 21 09:29:30 2016 -0700
@@ -23,9 +23,10 @@
/**
* @test
- * @bug 8059556
+ * @bug 8059556 8158639
*
* @run main/othervm -Xbatch compiler.jsr292.NullConstantReceiver
+ * @run main/othervm -Xbatch -XX:CompileCommand=exclude,*::run compiler.jsr292.NullConstantReceiver
*/
package compiler.jsr292;
--- a/hotspot/test/compiler/jvmci/compilerToVM/CompileCodeTestCase.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/CompileCodeTestCase.java Wed Sep 21 09:29:30 2016 -0700
@@ -107,6 +107,12 @@
}
public NMethod compile(int level) {
+ String directive = "[{ match: \"" + executable.getDeclaringClass().getName().replace('.', '/')
+ + "." + (executable instanceof Constructor ? "<init>" : executable.getName())
+ + "\", " + "BackgroundCompilation: false }]";
+ if (WB.addCompilerDirective(directive) != 1) {
+ throw new Error("Failed to add compiler directive: " + directive);
+ }
boolean enqueued = WB.enqueueMethodForCompilation(executable,
level, bci);
if (!enqueued) {
--- a/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -34,8 +34,9 @@
* jdk.vm.ci/jdk.vm.ci.hotspot
* jdk.vm.ci/jdk.vm.ci.code
*
- * @ignore 8139700
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
+ * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @build sun.hotspot.WhiteBox
+ * compiler.jvmci.compilerToVM.DisassembleCodeBlobTest
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:.
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -45,7 +45,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Asserts;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject;
@@ -114,7 +114,7 @@
abstract HotSpotResolvedJavaMethod getResolvedJavaMethod();
}
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
private static final WhiteBox WB = WhiteBox.getWhiteBox();
private static final Field METASPACE_METHOD_FIELD;
private static final Class<?> TEST_CLASS = GetResolvedJavaMethodTest.class;
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -53,7 +53,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Asserts;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
@@ -154,7 +154,7 @@
abstract HotSpotResolvedObjectType getResolvedJavaType();
}
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
private static final WhiteBox WB = WhiteBox.getWhiteBox();
private static final Class TEST_CLASS = GetResolvedJavaTypeTest.class;
/* a compressed parameter for tested method is set to false because
--- a/hotspot/test/compiler/jvmci/compilerToVM/InitializeConfigurationTest.java Fri Sep 16 10:57:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8136421
- * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64")
- * @library / /test/lib
- * @library ../common/patches
- * @modules java.base/jdk.internal.misc
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- * compiler.jvmci.compilerToVM.InitializeConfigurationTest
- */
-
-package compiler.jvmci.compilerToVM;
-
-import jdk.test.lib.Asserts;
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
-import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
-
-public class InitializeConfigurationTest {
- public static void main(String args[]) {
- new InitializeConfigurationTest().runTest();
- }
-
- private void runTest() {
- TestHotSpotVMConfig config = new TestHotSpotVMConfig(HotSpotJVMCIRuntime.runtime().getConfigStore());
- Asserts.assertNE(config.codeCacheHighBound, 0L, "Got null address");
- Asserts.assertNE(config.stubRoutineJintArrayCopy, 0L, "Got null address");
- }
-
- private static class TestHotSpotVMConfig extends HotSpotVMConfigAccess {
-
- private TestHotSpotVMConfig(HotSpotVMConfigStore store) {
- super(store);
- }
-
- final long codeCacheHighBound = getFieldValue("CodeCache::_high_bound", Long.class);
- final long stubRoutineJintArrayCopy = getFieldValue("StubRoutines::_jint_arraycopy", Long.class);
- }
-}
--- a/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -35,8 +35,10 @@
* jdk.vm.ci/jdk.vm.ci.code
* jdk.vm.ci/jdk.vm.ci.runtime
*
- * @ignore 8139700
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
+ * @ignore 8163894
+ * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @build compiler.jvmci.compilerToVM.InvalidateInstalledCodeTest
+ * @build sun.hotspot.WhiteBox
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ReadConfigurationTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8136421
+ * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64")
+ * @library / /test/lib
+ * @library ../common/patches
+ * @modules java.base/jdk.internal.misc
+ * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @build compiler.jvmci.compilerToVM.ReadConfigurationTest
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ * compiler.jvmci.compilerToVM.ReadConfigurationTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import jdk.test.lib.Asserts;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
+import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
+import jdk.vm.ci.hotspot.VMIntrinsicMethod;
+
+public class ReadConfigurationTest {
+ public static void main(String args[]) {
+ new ReadConfigurationTest().runTest();
+ }
+
+ private void runTest() {
+ TestHotSpotVMConfig config = new TestHotSpotVMConfig(HotSpotJVMCIRuntime.runtime().getConfigStore());
+ Asserts.assertNE(config.codeCacheHighBound, 0L, "Got null address");
+ Asserts.assertNE(config.stubRoutineJintArrayCopy, 0L, "Got null address");
+
+ for (VMIntrinsicMethod m : config.getStore().getIntrinsics()) {
+ Asserts.assertNotNull(m);
+ Asserts.assertNotNull(m.declaringClass);
+ Asserts.assertFalse(m.declaringClass.contains("."),
+ "declaringClass should be in class file format: " + m.declaringClass);
+ Asserts.assertNotNull(m.name);
+ Asserts.assertNotNull(m.descriptor);
+ Asserts.assertTrue(m.id > 0);
+ }
+ }
+
+ private static class TestHotSpotVMConfig extends HotSpotVMConfigAccess {
+
+ private TestHotSpotVMConfig(HotSpotVMConfigStore store) {
+ super(store);
+ }
+
+ final long codeCacheHighBound = getFieldValue("CodeCache::_high_bound", Long.class);
+ final long stubRoutineJintArrayCopy = getFieldValue("StubRoutines::_jint_arraycopy", Long.class);
+ }
+}
--- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -53,7 +53,7 @@
import jdk.internal.misc.Unsafe;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.test.lib.Asserts;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.meta.ConstantPool;
@@ -69,7 +69,7 @@
*/
public class ResolveFieldInPoolTest {
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
public static void main(String[] args) throws Exception {
Map<ConstantTypes, Validator> typeTests = new HashMap<>();
--- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -52,6 +52,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
@@ -60,7 +61,7 @@
import java.util.Set;
public class ResolveMethodTest {
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
public static void main(String args[]) {
ResolveMethodTest test = new ResolveMethodTest();
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64"
* @library /
* @modules jdk.vm.ci/jdk.vm.ci.hotspot
* jdk.vm.ci/jdk.vm.ci.meta
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9") & os.arch != "aarch64"
* @library /test/lib /
* @modules jdk.vm.ci/jdk.vm.ci.hotspot
* jdk.vm.ci/jdk.vm.ci.code
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java Wed Sep 21 09:29:30 2016 -0700
@@ -33,19 +33,16 @@
package jdk.vm.ci.runtime.test;
-import jdk.vm.ci.meta.ConstantPool;
-import jdk.vm.ci.meta.ExceptionHandler;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import org.junit.Assert;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -57,10 +54,13 @@
import java.util.Map;
import java.util.Set;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.ExceptionHandler;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Tests for {@link ResolvedJavaMethod}.
@@ -407,20 +407,6 @@
}
}
- @Test
- public void isSignaturePolymorphicTest() {
- ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class);
- assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invokeExact", metaAccess));
- assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invoke", metaAccess));
- assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invokeBasic", metaAccess));
- assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToVirtual", metaAccess));
- assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToStatic", metaAccess));
- assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToSpecial", metaAccess));
- assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToInterface", metaAccess));
- assertFalse(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "type", metaAccess));
- assertFalse(ResolvedJavaMethod.isSignaturePolymorphic(metaAccess.lookupJavaType(Object.class), "toString", metaAccess));
- }
-
/**
* All public non-final methods should be available in the vtable.
*/
--- a/hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java Wed Sep 21 09:29:30 2016 -0700
@@ -34,7 +34,7 @@
package compiler.loopopts.superword;
import jdk.internal.misc.Unsafe;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
public class TestVectorizationWithInvariant {
@@ -43,7 +43,7 @@
private static final long CHAR_ARRAY_OFFSET;
static {
- unsafe = Utils.getUnsafe();
+ unsafe = UnsafeHelper.getUnsafe();
BYTE_ARRAY_OFFSET = unsafe.arrayBaseOffset(byte[].class);
CHAR_ARRAY_OFFSET = unsafe.arrayBaseOffset(char[].class);
}
--- a/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java Wed Sep 21 09:29:30 2016 -0700
@@ -40,7 +40,7 @@
package compiler.profiling.spectrapredefineclass;
import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.process.OutputAnalyzer;
import java.io.File;
import java.io.IOException;
--- a/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java Wed Sep 21 09:29:30 2016 -0700
@@ -43,7 +43,7 @@
package compiler.profiling.spectrapredefineclass_classloaders;
import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.process.OutputAnalyzer;
import java.io.File;
import java.io.IOException;
--- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Wed Sep 21 09:29:30 2016 -0700
@@ -49,7 +49,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.test.lib.cli.CommandLineOptionTest;
import jdk.test.lib.cli.predicate.AndPredicate;
@@ -125,7 +125,7 @@
public static class Test implements CompilableTest {
private static final int TOTAL_ITERATIONS = 10000;
private static final int WARMUP_ITERATIONS = 1000;
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
private final Object monitor = new Object();
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
--- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Wed Sep 21 09:29:30 2016 -0700
@@ -51,7 +51,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.test.lib.cli.CommandLineOptionTest;
import jdk.test.lib.cli.predicate.AndPredicate;
@@ -158,7 +158,7 @@
private static int field = 0;
private static final int ITERATIONS = 10000;
private static final int RANGE_CHECK_AT = ITERATIONS / 2;
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
private final Object monitor = new Object();
@Override
--- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Wed Sep 21 09:29:30 2016 -0700
@@ -48,7 +48,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.test.lib.cli.CommandLineOptionTest;
import jdk.test.lib.cli.predicate.AndPredicate;
@@ -133,7 +133,7 @@
}
public static class Test implements CompilableTest {
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
private final Object monitor = new Object();
@Override
--- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Wed Sep 21 09:29:30 2016 -0700
@@ -49,7 +49,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.test.lib.cli.CommandLineOptionTest;
import jdk.test.lib.cli.predicate.AndPredicate;
@@ -142,7 +142,7 @@
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
private static final int TOTAL_ITERATIONS = 10000;
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
private final Object monitor = new Object();
--- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Wed Sep 21 09:29:30 2016 -0700
@@ -49,7 +49,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.test.lib.cli.CommandLineOptionTest;
import jdk.test.lib.cli.predicate.AndPredicate;
@@ -113,7 +113,7 @@
public static class Test implements CompilableTest {
private static final long TOTAL_ITERATIONS = 10000L;
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
private final Object monitor = new Object();
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
--- a/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,7 +25,7 @@
package compiler.testlibrary.rtm;
import jdk.internal.misc.Unsafe;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
/**
* Current RTM locking implementation force transaction abort
@@ -35,7 +35,7 @@
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
- private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
public XAbortProvoker() {
this(new Object());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/unsafe/MixedUnsafeStoreObject.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8155635
+ * @modules java.base/jdk.internal.misc
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:-TieredCompilation compiler.unsafe.MixedUnsafeStoreObject
+ * @run main/othervm -Xbatch compiler.unsafe.MixedUnsafeStoreObject
+ */
+
+package compiler.unsafe;
+
+import jdk.internal.misc.Unsafe;
+
+public class MixedUnsafeStoreObject {
+ static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
+ static final long F_OFFSET;
+
+ static {
+ try {
+ F_OFFSET = UNSAFE.objectFieldOffset(T.class.getDeclaredField("f"));
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ static class T {
+ Object f;
+ }
+
+ public static void testFieldInstanceObject(Object t) {
+ for (int c = 0; c < 20000; c++) { // trigger OSR compilation
+ // java/lang/Object+12 *
+ // _base = InstPtr, _ptr = BotPTR, _field = NULL, mismatched = true
+ UNSAFE.putObject(t, F_OFFSET, "foo");
+ }
+ }
+
+ public static void testFieldInstanceT(T t) {
+ for (int c = 0; c < 20000; c++) { // trigger OSR compilation
+ // ...$T+12 *
+ // _base = InstPtr, _ptr = BotPTR, _field = T.f, mismatched = false
+ UNSAFE.putObject(t, F_OFFSET, "foo");
+ }
+ }
+ public static void main(String[] args) {
+ testFieldInstanceObject(new T());
+ testFieldInstanceT(new T());
+ }
+}
+
--- a/hotspot/test/compiler/unsafe/OpaqueAccesses.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/unsafe/OpaqueAccesses.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,6 +30,22 @@
*
* @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
* -XX:-TieredCompilation -Xbatch
+ * -XX:+UseCompressedOops -XX:+UseCompressedClassPointers
+ * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
+ * compiler.unsafe.OpaqueAccesses
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:-TieredCompilation -Xbatch
+ * -XX:+UseCompressedOops -XX:-UseCompressedClassPointers
+ * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
+ * compiler.unsafe.OpaqueAccesses
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:-TieredCompilation -Xbatch
+ * -XX:-UseCompressedOops -XX:+UseCompressedClassPointers
+ * -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
+ * compiler.unsafe.OpaqueAccesses
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:-TieredCompilation -Xbatch
+ * -XX:-UseCompressedOops -XX:-UseCompressedClassPointers
* -XX:CompileCommand=dontinline,compiler.unsafe.OpaqueAccesses::test*
* compiler.unsafe.OpaqueAccesses
*/
@@ -61,6 +77,7 @@
}
private Object f = new Object();
+ private long l1, l2;
static Object testFixedOffsetField(Object o) {
return UNSAFE.getObject(o, F_OFFSET);
@@ -74,6 +91,22 @@
return UNSAFE.getInt(o, 4);
}
+ static int testFixedOffsetHeader8(Object o) {
+ return UNSAFE.getInt(o, 8);
+ }
+
+ static int testFixedOffsetHeader12(Object o) {
+ return UNSAFE.getInt(o, 12);
+ }
+
+ static int testFixedOffsetHeader16(Object o) {
+ return UNSAFE.getInt(o, 16);
+ }
+
+ static int testFixedOffsetHeader17(Object o) {
+ return UNSAFE.getIntUnaligned(o, 17);
+ }
+
static Object testFixedBase(long off) {
return UNSAFE.getObject(INSTANCE, off);
}
@@ -90,6 +123,22 @@
return UNSAFE.getInt(arr, 4);
}
+ static int testFixedOffsetHeaderArray8(Object[] arr) {
+ return UNSAFE.getInt(arr, 8);
+ }
+
+ static int testFixedOffsetHeaderArray12(Object[] arr) {
+ return UNSAFE.getInt(arr, 12);
+ }
+
+ static int testFixedOffsetHeaderArray16(Object[] arr) {
+ return UNSAFE.getInt(arr, 16);
+ }
+
+ static int testFixedOffsetHeaderArray17(Object[] arr) {
+ return UNSAFE.getIntUnaligned(arr, 17);
+ }
+
static Object testFixedOffsetArray(Object[] arr) {
return UNSAFE.getObject(arr, E_OFFSET);
}
@@ -118,6 +167,10 @@
testFixedOffsetField(INSTANCE);
testFixedOffsetHeader0(INSTANCE);
testFixedOffsetHeader4(INSTANCE);
+ testFixedOffsetHeader8(INSTANCE);
+ testFixedOffsetHeader12(INSTANCE);
+ testFixedOffsetHeader16(INSTANCE);
+ testFixedOffsetHeader17(INSTANCE);
testFixedBase(F_OFFSET);
testOpaque(INSTANCE, F_OFFSET);
testMixedAccess();
@@ -125,6 +178,10 @@
// Array
testFixedOffsetHeaderArray0(ARRAY);
testFixedOffsetHeaderArray4(ARRAY);
+ testFixedOffsetHeaderArray8(ARRAY);
+ testFixedOffsetHeaderArray12(ARRAY);
+ testFixedOffsetHeaderArray16(ARRAY);
+ testFixedOffsetHeaderArray17(ARRAY);
testFixedOffsetArray(ARRAY);
testFixedBaseArray(E_OFFSET);
testOpaqueArray(ARRAY, E_OFFSET);
--- a/hotspot/test/compiler/unsafe/UnsafeRaw.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/compiler/unsafe/UnsafeRaw.java Wed Sep 21 09:29:30 2016 -0700
@@ -35,6 +35,7 @@
import jdk.internal.misc.Unsafe;
import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import java.util.Random;
@@ -81,7 +82,7 @@
}
public static void main(String[] args) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
final int array_size = 128;
final int element_size = 4;
final int magic = 0x12345678;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/TestAgeOutput.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestAgeOutput
+ * @bug 8164936
+ * @summary Check that collectors using age table based aging print an age table even for the first garbage collection
+ * @key gc
+ * @requires vm.gc=="null"
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -XX:+UseSerialGC TestAgeOutput UseSerialGC
+ * @run main/othervm -XX:+UseConcMarkSweepGC TestAgeOutput UseConcMarkSweepGC
+ * @run main/othervm -XX:+UseG1GC TestAgeOutput UseG1GC
+ */
+
+import sun.hotspot.WhiteBox;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import static jdk.test.lib.Asserts.*;
+
+public class TestAgeOutput {
+
+ public static void checkPattern(String pattern, String what) throws Exception {
+ Pattern r = Pattern.compile(pattern);
+ Matcher m = r.matcher(what);
+
+ if (!m.find()) {
+ throw new RuntimeException("Could not find pattern " + pattern + " in output");
+ }
+ }
+
+ public static void runTest(String gcArg) throws Exception {
+ final String[] arguments = {
+ "-Xbootclasspath/a:.",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+WhiteBoxAPI",
+ "-XX:+" + gcArg,
+ "-Xmx10M",
+ "-Xlog:gc+age=trace",
+ GCTest.class.getName()
+ };
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(arguments);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ output.shouldHaveExitValue(0);
+
+ System.out.println(output.getStdout());
+
+ String stdout = output.getStdout();
+
+ checkPattern(".*GC\\(0\\) .*Desired survivor size.*", stdout);
+ checkPattern(".*GC\\(0\\) .*Age table with threshold.*", stdout);
+ checkPattern(".*GC\\(0\\) .*- age 1:.*", stdout);
+ }
+
+ public static void main(String[] args) throws Exception {
+ runTest(args[0]);
+ }
+
+ static class GCTest {
+ private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+ public static Object holder;
+
+ public static void main(String [] args) {
+ holder = new byte[100];
+ WB.youngGC();
+ System.out.println(holder);
+ }
+ }
+}
+
--- a/hotspot/test/gc/TestCardTablePageCommits.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/TestCardTablePageCommits.java Wed Sep 21 09:29:30 2016 -0700
@@ -34,7 +34,6 @@
* @requires vm.gc.Parallel
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * java.management
* @run driver TestCardTablePageCommits
*/
public class TestCardTablePageCommits {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/TestNumWorkerOutput.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestNumWorkerOutput
+ * @bug 8165292
+ * @summary Check that when PrintGCDetails is enabled, gc,task output is printed only once per collection.
+ * @key gc
+ * @requires vm.gc=="null"
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -XX:+UseConcMarkSweepGC TestNumWorkerOutput UseConcMarkSweepGC
+ * @run main/othervm -XX:+UseG1GC TestNumWorkerOutput UseG1GC
+ */
+
+import sun.hotspot.WhiteBox;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import static jdk.test.lib.Asserts.*;
+
+public class TestNumWorkerOutput {
+
+ public static void checkPatternOnce(String pattern, String what) throws Exception {
+ Pattern r = Pattern.compile(pattern);
+ Matcher m = r.matcher(what);
+
+ if (!m.find()) {
+ throw new RuntimeException("Could not find pattern " + pattern + " in output");
+ }
+ if (m.find()) {
+ throw new RuntimeException("Could find pattern " + pattern + " in output more than once");
+ }
+ }
+
+ public static void runTest(String gcArg) throws Exception {
+ final String[] arguments = {
+ "-Xbootclasspath/a:.",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+WhiteBoxAPI",
+ "-XX:+" + gcArg,
+ "-Xmx10M",
+ "-XX:+PrintGCDetails",
+ GCTest.class.getName()
+ };
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(arguments);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ output.shouldHaveExitValue(0);
+
+ System.out.println(output.getStdout());
+
+ String stdout = output.getStdout();
+
+ checkPatternOnce(".*[info.*].*[gc,task.*].*GC\\(0\\) .*Using \\d+ workers of \\d+ for evacuation.*", stdout);
+ }
+
+ public static void main(String[] args) throws Exception {
+ runTest(args[0]);
+ }
+
+ static class GCTest {
+ private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+ public static Object holder;
+
+ public static void main(String [] args) {
+ holder = new byte[100];
+ WB.youngGC();
+ System.out.println(holder);
+ }
+ }
+}
+
--- a/hotspot/test/gc/TestObjectAlignment.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/TestObjectAlignment.java Wed Sep 21 09:29:30 2016 -0700
@@ -28,7 +28,6 @@
* @summary G1: Concurrent marking crashes with -XX:ObjectAlignmentInBytes>=32 in 64bit VMs
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * java.management
* @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8
* @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16
* @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32
--- a/hotspot/test/gc/TestSmallHeap.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/TestSmallHeap.java Wed Sep 21 09:29:30 2016 -0700
@@ -28,7 +28,6 @@
* @summary Verify that starting the VM with a small heap works
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * @modules java.management/sun.management
* @build sun.hotspot.WhiteBox
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestSmallHeap
--- a/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/TestSoftReferencesBehaviorOnOOME.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,7 +27,6 @@
* @summary Tests that all SoftReferences has been cleared at time of OOM.
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * java.management
* @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 512 2k
* @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 128k 256k
* @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 2k 32k
--- a/hotspot/test/gc/TestVerifyDuringStartup.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/TestVerifyDuringStartup.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,7 +27,6 @@
* @summary Simple test run with -XX:+VerifyDuringStartup -XX:-UseTLAB to verify 8010463
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * java.management
*/
import jdk.test.lib.JDKToolFinder;
--- a/hotspot/test/gc/TestVerifySilently.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/TestVerifySilently.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,7 +27,6 @@
* @summary Test silent verification.
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * java.management
*/
import jdk.test.lib.process.ProcessTools;
--- a/hotspot/test/gc/TestVerifySubSet.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/TestVerifySubSet.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,7 +27,6 @@
* @summary Test VerifySubSet option
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * java.management
*/
import jdk.test.lib.process.ProcessTools;
--- a/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,16 +29,16 @@
* @key gc
* @key regression
* @requires vm.gc=="null"
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:+UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:-UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:+UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:-UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:+UseLargePages TestAlignmentToUseLargePages
- * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseSerialGC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseSerialGC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseConcMarkSweepGC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseConcMarkSweepGC -XX:-UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseG1GC -XX:+UseLargePages TestAlignmentToUseLargePages
+ * @run main/othervm -Xms71M -Xmx91M -XX:+UseG1GC -XX:-UseLargePages TestAlignmentToUseLargePages
*/
public class TestAlignmentToUseLargePages {
--- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Wed Sep 21 09:29:30 2016 -0700
@@ -37,6 +37,7 @@
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
public class TestMaxMinHeapFreeRatioFlags {
@@ -133,7 +134,7 @@
*/
public static class RatioVerifier {
- private static final Unsafe unsafe = Utils.getUnsafe();
+ private static final Unsafe unsafe = UnsafeHelper.getUnsafe();
// Size of byte array that will be allocated
public static final int CHUNK_SIZE = 1024;
--- a/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java Wed Sep 21 09:29:30 2016 -0700
@@ -46,6 +46,7 @@
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import sun.hotspot.WhiteBox;
/* In order to test that TargetSurvivorRatio affects survivor space occupancy
@@ -248,7 +249,7 @@
public static class TargetSurvivorRatioVerifier {
static final WhiteBox wb = WhiteBox.getWhiteBox();
- static final Unsafe unsafe = Utils.getUnsafe();
+ static final Unsafe unsafe = UnsafeHelper.getUnsafe();
// Desired size of memory allocated at once
public static final int CHUNK_SIZE = 1024;
--- a/hotspot/test/gc/cms/TestBubbleUpRef.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/cms/TestBubbleUpRef.java Wed Sep 21 09:29:30 2016 -0700
@@ -35,7 +35,7 @@
* stays nearly full.
* @run main/othervm
* -XX:+UseConcMarkSweepGC -XX:-CMSYield -XX:-CMSPrecleanRefLists1
- * -XX:CMSInitiatingOccupancyFraction=0 -Xmx8m TestBubbleUpRef 16000 50 10000
+ * -XX:CMSInitiatingOccupancyFraction=0 -Xmx80m TestBubbleUpRef 16000 50 10000
*/
/**
@@ -53,7 +53,7 @@
* Do it again.
*
* Use the following VM options
- * -Xmx8m -XX:-CMSYield [-XX:+UseConcMarkSweepGC] -XX:-CMSPrecleanRefLists1
+ * -Xmx80m -XX:-CMSYield [-XX:+UseConcMarkSweepGC] -XX:-CMSPrecleanRefLists1
* -XX:CMSInitiatingOccupancyFraction=0
*
* Use parameter:
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,6 +27,7 @@
* @summary Test to make sure that eager reclaim of humongous objects work. We simply try to fill
* up the heap with humongous objects that should be eagerly reclaimable to avoid Full GC.
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,6 +27,7 @@
* @summary Test to make sure that eager reclaim of humongous objects correctly clears
* mark bitmaps at reclaim.
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,6 +30,7 @@
* referencing that we know is in the old gen. After changing this reference, the object
* should still be eagerly reclaimable to avoid Full GC.
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,6 +27,7 @@
* @summary Ensure that the output for a G1TraceEagerReclaimHumongousObjects
* includes the expected necessary messages.
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestGCLogMessages.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestGCLogMessages.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,6 +27,7 @@
* @summary Ensure the output for a minor GC with G1
* includes the expected necessary messages.
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,6 +25,7 @@
* @test TestHumongousAllocInitialMark
* @bug 7168848
* @summary G1: humongous object allocations should initiate marking cycles when necessary
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestHumongousAllocNearlyFullRegion.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestHumongousAllocNearlyFullRegion.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @bug 8143587
* @summary G1: humongous object allocations should work even when there is
* not enough space in the heapRegion to fit a filler object.
+ * @requires vm.gc.G1
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @run driver TestHumongousAllocNearlyFullRegion
--- a/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @key regression
* @key gc
* @bug 8027756
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @key gc
* @bug 8014240
* @summary Test output of G1PrintRegionRememberedSetInfo
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationAgeThreshold.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationAgeThreshold.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @summary Test string deduplication age threshold
* @bug 8029075
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationFullGC.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationFullGC.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @summary Test string deduplication during full GC
* @bug 8029075
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationInterned.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationInterned.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @summary Test string deduplication of interned strings
* @bug 8029075
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationPrintOptions.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationPrintOptions.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @summary Test string deduplication print options
* @bug 8029075
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationTableRehash.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationTableRehash.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @summary Test string deduplication table rehash
* @bug 8029075
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationTableResize.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationTableResize.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @summary Test string deduplication table resize
* @bug 8029075
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestStringDeduplicationYoungGC.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringDeduplicationYoungGC.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @summary Test string deduplication during young GC
* @bug 8029075
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/g1/TestStringSymbolTableStats.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/g1/TestStringSymbolTableStats.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @bug 8027476 8027455
* @summary Ensure that the G1TraceStringSymbolTableScrubbing prints the expected message.
* @key gc
+ * @requires vm.gc.G1
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/hotspot/test/gc/serial/HeapChangeLogging.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/serial/HeapChangeLogging.java Wed Sep 21 09:29:30 2016 -0700
@@ -24,9 +24,9 @@
/*
* @test HeapChangeLogging.java
* @bug 8027440
+ * @requires vm.gc.Serial
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * java.management
* @summary Allocate to get a promotion failure and verify that that heap change logging is present.
* @run main HeapChangeLogging
*/
--- a/hotspot/test/gc/testlibrary/Helpers.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/gc/testlibrary/Helpers.java Wed Sep 21 09:29:30 2016 -0700
@@ -32,7 +32,6 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
public class Helpers {
@@ -124,20 +123,13 @@
*/
public static String generate(String className, String superClass, String constructor, long fieldCount) {
- StringBuilder builder = new StringBuilder();
- builder.append(String.format("public class %s%s {\n", className, superClass == null ? ""
- : " extends " + superClass));
-
- if (constructor != null) {
- builder.append(constructor);
- }
-
- for (int i = 0; i < fieldCount; ++i) {
- builder.append(String.format("long f%d;\n", i));
- }
-
- builder.append("}\n");
- return builder.toString();
+ return new StringBuilder()
+ .append(String.format("public class %s%s {\n", className, superClass == null ? ""
+ : " extends " + superClass))
+ .append(constructor == null ? "" : constructor)
+ .append(fieldsGenerator(fieldCount))
+ .append("}\n")
+ .toString();
}
/**
@@ -212,50 +204,9 @@
Path workDir, String prefix)
throws IOException, ClassNotFoundException {
- if (instanceSize % SIZE_OF_LONG != 0L) {
- throw new Error(String.format("Test bug: only sizes aligned by 8 bytes are supported and %d was specified",
- instanceSize));
- }
-
- long instanceSizeWithoutObjectHeader = instanceSize - WhiteBox.getWhiteBox().getObjectSize(new Object());
-
- int generatedClassesCount;
- int fieldsInLastClassCount;
-
- int sizeOfLastFile = (int) (instanceSizeWithoutObjectHeader
- % (MAXIMUM_AMOUNT_OF_FIELDS_IN_CLASS * SIZE_OF_LONG));
+ generateByTemplateAndCompile(className, null, "public class ${ClassName} extends ${BaseClass} {\n${Fields}}\n",
+ "", instanceSize, workDir, prefix);
- if (sizeOfLastFile != 0) {
- generatedClassesCount = (int) instanceSizeWithoutObjectHeader
- / (MAXIMUM_AMOUNT_OF_FIELDS_IN_CLASS * SIZE_OF_LONG) + 1;
- fieldsInLastClassCount = sizeOfLastFile / SIZE_OF_LONG;
- } else {
- generatedClassesCount = (int) instanceSizeWithoutObjectHeader
- / (MAXIMUM_AMOUNT_OF_FIELDS_IN_CLASS * SIZE_OF_LONG);
- fieldsInLastClassCount = MAXIMUM_AMOUNT_OF_FIELDS_IN_CLASS;
- }
-
- for (int i = 0; i < generatedClassesCount; i++) {
- // for the last generated class we use specified class name
- String clsName = (i == generatedClassesCount - 1) ? className : prefix + i;
-
- // If we already have a file with the same name we do not create it again
- if (Files.notExists(Paths.get(clsName + ".java"))) {
- Helpers.compileClass(clsName, workDir,
- Helpers.generate(
- clsName,
- // for first generated class we don't have 'extends'
- (i == 0 ? null : prefix + (i - 1)),
- null,
- // for the last generated class we use different field count
- (i == generatedClassesCount - 1) ? fieldsInLastClassCount
- : MAXIMUM_AMOUNT_OF_FIELDS_IN_CLASS));
- } else {
- System.out.println("Class " + clsName +
- ".java already exists, skipping class' generation and compilation");
- }
-
- }
return classLoader.loadClass(className);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/classfile/test_AltHashing.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+#include "precompiled.hpp"
+#include "classfile/altHashing.hpp"
+#include "unittest.hpp"
+
+// Internal test for alternate hashing. Translated from JDK version
+// test/sun/misc/Hashing.java
+static const jbyte ONE_BYTE[] = {(jbyte) 0x80};
+static const jbyte TWO_BYTE[] = {(jbyte) 0x80, (jbyte) 0x81};
+static const jchar ONE_CHAR[] = {(jchar) 0x8180};
+static const jbyte THREE_BYTE[] = {(jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82};
+static const jbyte FOUR_BYTE[] = {(jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83};
+static const jchar TWO_CHAR[] = {(jchar) 0x8180, (jchar) 0x8382};
+static const jint ONE_INT[] = {(jint) 0x83828180};
+static const jbyte SIX_BYTE[] = {(jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85};
+static const jchar THREE_CHAR[] = {(jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584};
+static const jbyte EIGHT_BYTE[] = {
+ (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82,
+ (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85,
+ (jbyte) 0x86, (jbyte) 0x87
+};
+static const jchar FOUR_CHAR[] = {
+ (jchar) 0x8180, (jchar) 0x8382,
+ (jchar) 0x8584, (jchar) 0x8786
+};
+
+static const jint TWO_INT[] = {(jint) 0x83828180, (jint) 0x87868584};
+static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3;
+
+class AltHashingTest : public ::testing::Test {
+ public:
+
+ static juint murmur3_32(const int* data, int len) {
+ return AltHashing::murmur3_32(data, len);
+ }
+};
+
+TEST_F(AltHashingTest, murmur3_32_byte_array_test) {
+ jbyte vector[256];
+ jbyte hashes[4 * 256];
+
+ for (int i = 0; i < 256; i++) {
+ vector[i] = (jbyte) i;
+ }
+
+ // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
+ for (int i = 0; i < 256; i++) {
+ juint hash = AltHashing::murmur3_32(256 - i, vector, i);
+ hashes[i * 4] = (jbyte) hash;
+ hashes[i * 4 + 1] = (jbyte) (hash >> 8);
+ hashes[i * 4 + 2] = (jbyte) (hash >> 16);
+ hashes[i * 4 + 3] = (jbyte) (hash >> 24);
+ }
+
+ // hash to get const result.
+ juint final_hash = AltHashing::murmur3_32(0, hashes, 4 * 256);
+
+ ASSERT_EQ(MURMUR3_32_X86_CHECK_VALUE, final_hash)
+ << "Calculated hash result not as expected.";
+}
+
+TEST_F(AltHashingTest, equivalent_hashes_test) {
+ juint jbytes, jchars, ints;
+
+ jbytes = AltHashing::murmur3_32(0, TWO_BYTE, 2);
+ jchars = AltHashing::murmur3_32(0, ONE_CHAR, 1);
+ ASSERT_EQ(jbytes, jchars) << "Hashes did not match.";
+
+ jbytes = AltHashing::murmur3_32(0, FOUR_BYTE, 4);
+ jchars = AltHashing::murmur3_32(0, TWO_CHAR, 2);
+ ints = AltHashingTest::murmur3_32(ONE_INT, 1);
+
+ ASSERT_EQ(jbytes, jchars) << "Hashes did not match.";
+ ASSERT_EQ(jbytes, ints) << "Hashes did not match.";
+
+ jbytes = AltHashing::murmur3_32(0, SIX_BYTE, 6);
+ jchars = AltHashing::murmur3_32(0, THREE_CHAR, 3);
+ ASSERT_EQ(jbytes, jchars) << "Hashes did not match.";
+
+ jbytes = AltHashing::murmur3_32(0, EIGHT_BYTE, 8);
+ jchars = AltHashing::murmur3_32(0, FOUR_CHAR, 4);
+ ints = AltHashingTest::murmur3_32(TWO_INT, 2);
+
+ ASSERT_EQ(jbytes, jchars) << "Hashes did not match.";
+ ASSERT_EQ(jbytes, ints) << "Hashes did not match.";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/g1/test_g1CodeCacheRemSet.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CodeRootSetTable.hpp"
+#include "gc/g1/g1CodeCacheRemSet.hpp"
+#include "unittest.hpp"
+
+class G1CodeRootSetTest : public ::testing::Test {
+ public:
+
+ size_t threshold() {
+ return G1CodeRootSet::Threshold;
+ }
+
+ G1CodeRootSetTable* purge_list() {
+ return G1CodeRootSetTable::_purge_list;
+ }
+};
+
+TEST_VM_F(G1CodeRootSetTest, g1_code_cache_rem_set) {
+ G1CodeRootSet root_set;
+
+ ASSERT_TRUE(root_set.is_empty()) << "Code root set must be initially empty "
+ "but is not.";
+
+ ASSERT_EQ(G1CodeRootSet::static_mem_size(), sizeof (void*)) <<
+ "The code root set's static memory usage is incorrect, "
+ << G1CodeRootSet::static_mem_size() << " bytes";
+
+ root_set.add((nmethod*) 1);
+ ASSERT_EQ(root_set.length(), (size_t) 1) << "Added exactly one element, but"
+ " set contains " << root_set.length() << " elements";
+
+ const size_t num_to_add = (size_t) threshold() + 1;
+
+ for (size_t i = 1; i <= num_to_add; i++) {
+ root_set.add((nmethod*) 1);
+ }
+ ASSERT_EQ(root_set.length(), (size_t) 1)
+ << "Duplicate detection should not have increased the set size but "
+ << "is " << root_set.length();
+
+ for (size_t i = 2; i <= num_to_add; i++) {
+ root_set.add((nmethod*) (uintptr_t) (i));
+ }
+
+ ASSERT_EQ(root_set.length(), num_to_add)
+ << "After adding in total " << num_to_add << " distinct code roots, "
+ "they need to be in the set, but there are only " << root_set.length();
+
+ ASSERT_NE(purge_list(), (G1CodeRootSetTable*) NULL)
+ << "should have grown to large hashtable";
+
+ size_t num_popped = 0;
+ for (size_t i = 1; i <= num_to_add; i++) {
+ bool removed = root_set.remove((nmethod*) i);
+ if (removed) {
+ num_popped += 1;
+ } else {
+ break;
+ }
+ }
+ ASSERT_EQ(num_popped, num_to_add)
+ << "Managed to pop " << num_popped << " code roots, but only "
+ << num_to_add << " were added";
+ ASSERT_NE(purge_list(), (G1CodeRootSetTable*) NULL)
+ << "should have grown to large hashtable";
+
+ G1CodeRootSet::purge();
+
+ ASSERT_EQ(purge_list(), (G1CodeRootSetTable*) NULL)
+ << "should have purged old small tables";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/g1/test_g1Predictions.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1Predictions.hpp"
+#include "unittest.hpp"
+
+static const double epsilon = 1e-6;
+
+// Some basic formula tests with confidence = 0.0
+TEST_VM(G1Predictions, basic_predictions) {
+ G1Predictions predictor(0.0);
+ TruncatedSeq s;
+
+ double p0 = predictor.get_new_prediction(&s);
+ ASSERT_LT(p0, epsilon) << "Initial prediction of empty sequence must be 0.0";
+
+ s.add(5.0);
+ double p1 = predictor.get_new_prediction(&s);
+ ASSERT_NEAR(p1, 5.0, epsilon);
+
+ for (int i = 0; i < 40; i++) {
+ s.add(5.0);
+ }
+ double p2 = predictor.get_new_prediction(&s);
+ ASSERT_NEAR(p2, 5.0, epsilon);
+}
+
+// The following tests checks that the initial predictions are based on
+// the average of the sequence and not on the stddev (which is 0).
+TEST_VM(G1Predictions, average_not_stdev_predictions) {
+ G1Predictions predictor(0.5);
+ TruncatedSeq s;
+
+ s.add(1.0);
+ double p1 = predictor.get_new_prediction(&s);
+ ASSERT_GT(p1, s.davg()) << "First prediction must be greater than average";
+
+ s.add(1.0);
+ double p2 = predictor.get_new_prediction(&s);
+ ASSERT_GT(p1, p2) << "First prediction must be greater than second";
+
+ s.add(1.0);
+ double p3 = predictor.get_new_prediction(&s);
+ ASSERT_GT(p2, p3) << "Second prediction must be greater than third";
+
+ s.add(1.0);
+ s.add(1.0); // Five elements are now in the sequence.
+ double p4 = predictor.get_new_prediction(&s);
+ ASSERT_LT(p4, p3) << "Fourth prediction must be smaller than third";
+ ASSERT_NEAR(p4, 1.0, epsilon);
+}
+
+// The following tests checks that initially prediction based on
+// the average is used, that gets overridden by the stddev prediction at
+// the end.
+TEST_VM(G1Predictions, average_stdev_predictions) {
+ G1Predictions predictor(0.5);
+ TruncatedSeq s;
+
+ s.add(0.5);
+ double p1 = predictor.get_new_prediction(&s);
+ ASSERT_GT(p1, s.davg()) << "First prediction must be greater than average";
+
+ s.add(0.2);
+ double p2 = predictor.get_new_prediction(&s);
+ ASSERT_GT(p1, p2) << "First prediction must be greater than second";
+
+ s.add(0.5);
+ double p3 = predictor.get_new_prediction(&s);
+ ASSERT_GT(p2, p3) << "Second prediction must be greater than third";
+
+ s.add(0.2);
+ s.add(2.0);
+ double p4 = predictor.get_new_prediction(&s);
+ ASSERT_GT(p4, p3) << "Fourth prediction must be greater than third";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/parallel/test_psAdaptiveSizePolicy.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "utilities/macros.hpp"
+#include "gc/parallel/psAdaptiveSizePolicy.hpp"
+#include "unittest.hpp"
+
+#if INCLUDE_ALL_GCS
+
+ TEST_VM(gc, oldFreeSpaceCalculation) {
+
+ struct TestCase {
+ size_t live;
+ uintx ratio;
+ size_t expectedResult;
+ };
+
+ TestCase test_cases[] = {
+ {100, 20, 25},
+ {100, 50, 100},
+ {100, 60, 150},
+ {100, 75, 300},
+ {400, 20, 100},
+ {400, 50, 400},
+ {400, 60, 600},
+ {400, 75, 1200},
+ };
+
+ size_t array_len = sizeof(test_cases) / sizeof(TestCase);
+ for (size_t i = 0; i < array_len; ++i) {
+ ASSERT_EQ(PSAdaptiveSizePolicy::calculate_free_based_on_live(
+ test_cases[i].live, test_cases[i].ratio),
+ test_cases[i].expectedResult)
+ << " Calculation of free memory failed"
+ << " - Test case " << i << ": live = " << test_cases[i].live
+ << "; ratio = " << test_cases[i].ratio;
+ }
+ }
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gc/shared/test_memset_with_concurrent_readers.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include <string.h>
+#include "utilities/globalDefinitions.hpp"
+#include <sstream>
+#include "gc/shared/memset_with_concurrent_readers.hpp"
+#include "unittest.hpp"
+
+#if INCLUDE_ALL_GCS
+
+static unsigned line_byte(const char* line, size_t i) {
+ return unsigned(line[i]) & 0xFF;
+}
+
+TEST(gc, memset_with_concurrent_readers) {
+ const size_t chunk_size = 8 * BytesPerWord;
+ const unsigned chunk_count = 4;
+ const size_t block_size = (chunk_count + 4) * chunk_size;
+ char block[block_size];
+ char clear_block[block_size];
+ char set_block[block_size];
+
+ // block format:
+ // 0: unused leading chunk
+ // 1: chunk written from start index to end of chunk
+ // ... nchunks fully written chunks
+ // N: chunk written from start of chunk to end index
+ // N+1: unused trailing chunk
+
+ const int clear_value = 0;
+ const int set_value = 0xAC;
+
+ memset(clear_block, clear_value, block_size);
+ memset(set_block, set_value, block_size);
+
+ for (unsigned nchunks = 0; nchunks <= chunk_count; ++nchunks) {
+ for (size_t start = 1; start <= chunk_size; ++start) {
+ for (size_t end = 0; end <= chunk_size; ++end) {
+ size_t set_start = chunk_size + start;
+ size_t set_end = (2 + nchunks) * chunk_size + end;
+ size_t set_size = set_end - set_start;
+
+ memset(block, clear_value, block_size);
+ memset_with_concurrent_readers(&block[set_start], set_value, set_size);
+ bool head_clear = !memcmp(clear_block, block, set_start);
+ bool middle_set = !memcmp(set_block, block + set_start, set_size);
+ bool tail_clear = !memcmp(clear_block, block + set_end, block_size - set_end);
+ if (!(head_clear && middle_set && tail_clear)) {
+ std::ostringstream err_stream;
+ err_stream << "*** memset_with_concurrent_readers failed: set start "
+ << set_start << ", set end " << set_end << std::endl;
+ for (unsigned chunk = 0; chunk < (block_size / chunk_size); ++chunk) {
+ for (unsigned line = 0; line < (chunk_size / BytesPerWord); ++line) {
+
+ const char* lp = &block[chunk * chunk_size + line * BytesPerWord];
+
+ err_stream << std::dec << chunk << "," << line << ": " << std::hex
+ << std::setw(2) << line_byte(lp, 0) << " "
+ << std::setw(2) << line_byte(lp, 1) << " "
+ << std::setw(2) << line_byte(lp, 2) << " "
+ << std::setw(2) << line_byte(lp, 3) << " "
+ << std::setw(2) << line_byte(lp, 4) << " "
+ << std::setw(2) << line_byte(lp, 5) << " "
+ << std::setw(2) << line_byte(lp, 6) << " "
+ << std::setw(2) << line_byte(lp, 7) << std::endl;
+ }
+ }
+ EXPECT_TRUE(head_clear) << "leading byte not clear";
+ EXPECT_TRUE(middle_set) << "memset byte not set";
+ EXPECT_TRUE(tail_clear) << "trailing bye not clear";
+ ASSERT_TRUE(head_clear && middle_set && tail_clear) << err_stream.str();
+ }
+ }
+ }
+ }
+}
+#endif
--- a/hotspot/test/native/logging/test_logConfiguration.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/native/logging/test_logConfiguration.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -164,10 +164,17 @@
// Add TestLogFileName as an output
set_log_config(TestLogFileName, "logging=info");
+ // Add a second file output
+ char other_file_name[2 * K];
+ jio_snprintf(other_file_name, sizeof(other_file_name), "%s-other", TestLogFileName);
+ set_log_config(other_file_name, "logging=info");
+
LogConfiguration::disable_logging();
- // Verify TestLogFileName was disabled
+ // Verify that both file outputs were disabled
EXPECT_FALSE(is_described(TestLogFileName));
+ EXPECT_FALSE(is_described(other_file_name));
+ delete_file(other_file_name);
// Verify that no tagset has logging enabled
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
@@ -287,5 +294,44 @@
const LogDecorators::Decorator decorator = static_cast<LogDecorators::Decorator>(d);
EXPECT_TRUE(LogConfiguration::parse_log_arguments("#0", "", LogDecorators::name(decorator), "", &ss));
}
- EXPECT_STREQ("", ss.as_string()) << "Error reported while parsing: " << ss.as_string();
+}
+
+TEST_F(LogConfigurationTest, parse_invalid_tagset) {
+ static const char* invalid_tagset = "logging+start+exit+safepoint+gc"; // Must not exist for test to function.
+
+ // Make sure warning is produced if one or more configured tagsets are invalid
+ ResourceMark rm;
+ stringStream ss;
+ bool success = LogConfiguration::parse_log_arguments("stdout", invalid_tagset, NULL, NULL, &ss);
+ const char* msg = ss.as_string();
+ EXPECT_TRUE(success) << "Should only cause a warning, not an error";
+ EXPECT_TRUE(string_contains_substring(msg, "No tag set matches selection(s):"));
+ EXPECT_TRUE(string_contains_substring(msg, invalid_tagset));
}
+
+TEST_F(LogConfigurationTest, output_name_normalization) {
+ const char* patterns[] = { "%s", "file=%s", "\"%s\"", "file=\"%s\"" };
+ char buf[1 * K];
+ for (size_t i = 0; i < ARRAY_SIZE(patterns); i++) {
+ int ret = jio_snprintf(buf, sizeof(buf), patterns[i], TestLogFileName);
+ ASSERT_NE(-1, ret);
+ set_log_config(buf, "logging=trace");
+ EXPECT_TRUE(is_described("#2: "));
+ EXPECT_TRUE(is_described(TestLogFileName));
+ EXPECT_FALSE(is_described("#3: "))
+ << "duplicate file output due to incorrect normalization for pattern: " << patterns[i];
+ }
+
+ // Make sure prefixes are ignored when used within quotes
+ // (this should create a log with "file=" in its filename)
+ int ret = jio_snprintf(buf, sizeof(buf), "\"file=%s\"", TestLogFileName);
+ ASSERT_NE(-1, ret);
+ set_log_config(buf, "logging=trace");
+ EXPECT_TRUE(is_described("#3: ")) << "prefix within quotes not ignored as it should be";
+ set_log_config(buf, "all=off");
+
+ // Remove the extra log file created
+ ret = jio_snprintf(buf, sizeof(buf), "file=%s", TestLogFileName);
+ ASSERT_NE(-1, ret);
+ delete_file(buf);
+}
--- a/hotspot/test/native/logging/test_logDecorations.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/native/logging/test_logDecorations.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -144,7 +144,7 @@
reported_time.tm_hour = h;
reported_time.tm_min = m;
reported_time.tm_sec = s;
- reported_time.tm_isdst = daylight;
+ reported_time.tm_isdst = -1; // let mktime deduce DST settings
time_t reported_ts = mktime(&reported_time);
expected_ts = mktime(localtime(&expected_ts));
time_t diff = reported_ts - expected_ts;
--- a/hotspot/test/native/logging/test_logFileOutput.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/native/logging/test_logFileOutput.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -29,7 +29,7 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
-static const char* name = "testlog.pid%p.%t.log";
+static const char* name = "file=testlog.pid%p.%t.log";
// Test parsing a bunch of valid file output options
TEST(LogFileOutput, parse_valid) {
--- a/hotspot/test/native/logging/test_logTagLevelExpression.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/native/logging/test_logTagLevelExpression.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -33,7 +33,7 @@
const char* invalid_substr[] = {
"=", "+", " ", "+=", "+=*", "*+", " +", "**", "++", ".", ",", ",," ",+",
" *", "all+", "all*", "+all", "+all=Warning", "==Info", "=InfoWarning",
- "BadTag+", "logging++", "logging*+", ",=", "gc+gc+gc+gc+gc+gc"
+ "BadTag+", "logging++", "logging*+", ",=", "gc+gc+"
};
const char* valid_expression[] = {
"all", "gc", "gc,logging", "gc+logging", "logging+gc", "logging+gc,gc", "logging+gc*", "gc=trace",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/utilities/test_utf8.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "utilities/utf8.hpp"
+#include "unittest.hpp"
+
+TEST(utf8, length) {
+ char res[60];
+ jchar str[20];
+
+ for (int i = 0; i < 20; i++) {
+ str[i] = 0x0800; // char that is 2B in UTF-16 but 3B in UTF-8
+ }
+ str[19] = (jchar) '\0';
+
+ // The resulting string in UTF-8 is 3*19 bytes long, but should be truncated
+ UNICODE::as_utf8(str, 19, res, 10);
+ ASSERT_EQ(strlen(res), (size_t) 9) << "string should be truncated here";
+
+ UNICODE::as_utf8(str, 19, res, 18);
+ ASSERT_EQ(strlen(res), (size_t) 15) << "string should be truncated here";
+
+ UNICODE::as_utf8(str, 19, res, 20);
+ ASSERT_EQ(strlen(res), (size_t) 18) << "string should be truncated here";
+
+ // Test with an "unbounded" buffer
+ UNICODE::as_utf8(str, 19, res, INT_MAX);
+ ASSERT_EQ(strlen(res), (size_t) 3 * 19) << "string should end here";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ClassFile/BadHelloWorld.jcod Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file fuzzes the class name #15 to have a leading 'L' and ending ';'.
+ */
+
+class BadHelloWorld {
+ 0xCAFEBABE;
+ 0; // minor version
+ 52; // version
+ [31] { // Constant Pool
+ ; // first element is empty
+ Utf8 "BadHelloWorld"; // #1 at 0x0A
+ class #1; // #2 at 0x1A
+ Utf8 "java/lang/Object"; // #3 at 0x1D
+ class #3; // #4 at 0x30
+ Utf8 "<init>"; // #5 at 0x33
+ Utf8 "()V"; // #6 at 0x3C
+ NameAndType #5 #6; // #7 at 0x42
+ Method #4 #7; // #8 at 0x47
+ Utf8 "toString"; // #9 at 0x4C
+ Utf8 "()Ljava/lang/String;"; // #10 at 0x57
+ Utf8 "Hello, world!"; // #11 at 0x6E
+ String #11; // #12 at 0x7E
+ Utf8 "main"; // #13 at 0x81
+ Utf8 "([Ljava/lang/String;)V"; // #14 at 0x88
+ Utf8 "LBadHelloWorld;"; // #15 at 0xA1
+ class #15; // #16 at 0xB3
+ Method #16 #7; // #17 at 0xB6
+ Utf8 "java/lang/System"; // #18 at 0xBB
+ class #18; // #19 at 0xCE
+ Utf8 "out"; // #20 at 0xD1
+ Utf8 "Ljava/io/PrintStream;"; // #21 at 0xD7
+ NameAndType #20 #21; // #22 at 0xEF
+ Field #19 #22; // #23 at 0xF4
+ Utf8 "java/io/PrintStream"; // #24 at 0xF9
+ class #24; // #25 at 0x010F
+ Utf8 "println"; // #26 at 0x0112
+ Utf8 "(Ljava/lang/Object;)V"; // #27 at 0x011C
+ NameAndType #26 #27; // #28 at 0x0134
+ Method #25 #28; // #29 at 0x0139
+ Utf8 "Code"; // #30 at 0x013E
+ } // Constant Pool
+
+ 0x0021; // access
+ #2;// this_cpx
+ #4;// super_cpx
+
+ [0] { // Interfaces
+ } // Interfaces
+
+ [0] { // fields
+ } // fields
+
+ [3] { // methods
+ { // Member at 0x0151
+ 0x0001; // access
+ #5; // name_cpx
+ #6; // sig_cpx
+ [1] { // Attributes
+ Attr(#30, 17) { // Code at 0x0159
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[5]{
+ 0x2AB70008B1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x0170
+ 0x0001; // access
+ #9; // name_cpx
+ #10; // sig_cpx
+ [1] { // Attributes
+ Attr(#30, 15) { // Code at 0x0178
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[3]{
+ 0x120CB0;
+ };
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x018D
+ 0x0089; // access
+ #13; // name_cpx
+ #14; // sig_cpx
+ [1] { // Attributes
+ Attr(#30, 28) { // Code at 0x0195
+ 2; // max_stack
+ 2; // max_locals
+ Bytes[16]{
+ 0xBB001059B700114C;
+ 0xB200172BB6001DB1;
+ };
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [0] { // Attributes
+ } // Attributes
+} // end class BadHelloWorld
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ClassFile/FormatCheckingTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8148854
+ * @summary Ensure class name loaded by app class loader is format checked by default
+ * @library /test/lib
+ * @compile BadHelloWorld.jcod
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @run main FormatCheckingTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class FormatCheckingTest {
+ public static void main(String args[]) throws Throwable {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("BadHelloWorld");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("java.lang.ClassFormatError: Illegal class name");
+ output.shouldHaveExitValue(1);
+ }
+}
--- a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java Wed Sep 21 09:29:30 2016 -0700
@@ -34,13 +34,13 @@
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.Platform;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
public class CreateCoredumpOnCrash {
private static class Crasher {
public static void main(String[] args) {
- Utils.getUnsafe().putInt(0L, 0);
+ UnsafeHelper.getUnsafe().putInt(0L, 0);
}
}
--- a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -35,14 +35,14 @@
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
public class ProblematicFrameTest {
private static class Crasher {
public static void main(String[] args) {
- Utils.getUnsafe().getInt(0);
+ UnsafeHelper.getUnsafe().getInt(0);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/RedefineTests/RedefinePreviousVersions.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8165246
+ * @summary Test has_previous_versions flag and processing during class unloading.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.compiler
+ * java.instrument
+ * jdk.jartool/sun.tools.jar
+ * @run main RedefineClassHelper
+ * @run main/othervm RedefinePreviousVersions test
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class RedefinePreviousVersions {
+
+ public static String newB =
+ "class RedefinePreviousVersions$B {" +
+ "}";
+
+ static class B { }
+
+ public static String newRunning =
+ "class RedefinePreviousVersions$Running {" +
+ " public static volatile boolean stop = true;" +
+ " static void localSleep() { }" +
+ " public static void infinite() { }" +
+ "}";
+
+ static class Running {
+ public static volatile boolean stop = false;
+ static void localSleep() {
+ try{
+ Thread.currentThread().sleep(10);//sleep for 10 ms
+ } catch(InterruptedException ie) {
+ }
+ }
+
+ public static void infinite() {
+ while (!stop) { localSleep(); }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ if (args.length > 0) {
+
+ String jarFile = System.getProperty("test.src") + "/testcase.jar";
+
+ // java -javaagent:redefineagent.jar -Xlog:stuff RedefinePreviousVersions
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-javaagent:redefineagent.jar",
+ "-Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace",
+ "RedefinePreviousVersions");
+ new OutputAnalyzer(pb.start())
+ .shouldContain("Class unloading: has_previous_versions = false")
+ .shouldContain("Class unloading: has_previous_versions = true")
+ .shouldHaveExitValue(0);
+ return;
+ }
+
+ // Redefine a class and create some garbage
+ // Since there are no methods running, the previous version is never added to the
+ // previous_version_list and the flag _has_previous_versions should stay false
+ RedefineClassHelper.redefineClass(B.class, newB);
+
+ for (int i = 0; i < 10 ; i++) {
+ String s = new String("some garbage");
+ System.gc();
+ }
+
+ // Start a class that has a method running
+ new Thread() {
+ public void run() {
+ Running.infinite();
+ }
+ }.start();
+
+ // Since a method of newRunning is running, this class should be added to the previous_version_list
+ // of Running, and _has_previous_versions should return true at class unloading.
+ RedefineClassHelper.redefineClass(Running.class, newRunning);
+
+ for (int i = 0; i < 10 ; i++) {
+ String s = new String("some garbage");
+ System.gc();
+ }
+
+ // purge should clean everything up, except Xcomp it might not.
+ Running.stop = true;
+
+ for (int i = 0; i < 10 ; i++) {
+ String s = new String("some garbage");
+ System.gc();
+ }
+ }
+}
--- a/hotspot/test/runtime/Unsafe/AllocateInstance.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/AllocateInstance.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,12 +30,12 @@
* @run main AllocateInstance
*/
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class AllocateInstance {
- static final Unsafe UNSAFE = Utils.getUnsafe();
+ static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
class TestClass {
public boolean calledConstructor = false;
--- a/hotspot/test/runtime/Unsafe/AllocateMemory.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/AllocateMemory.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m AllocateMemory
*/
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class AllocateMemory {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
// Allocate a byte, write to the location and read back the value
long address = unsafe.allocateMemory(1);
--- a/hotspot/test/runtime/Unsafe/CopyMemory.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/CopyMemory.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,14 +30,14 @@
* @run main CopyMemory
*/
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class CopyMemory {
final static int LENGTH = 8;
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
long src = unsafe.allocateMemory(LENGTH);
long dst = unsafe.allocateMemory(LENGTH);
assertNotEquals(src, 0L);
--- a/hotspot/test/runtime/Unsafe/DefineClass.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/DefineClass.java Wed Sep 21 09:29:30 2016 -0700
@@ -34,13 +34,13 @@
import java.security.ProtectionDomain;
import java.io.InputStream;
import jdk.test.lib.InMemoryJavaCompiler;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class DefineClass {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
TestClassLoader classloader = new TestClassLoader();
ProtectionDomain pd = new ProtectionDomain(null, null);
--- a/hotspot/test/runtime/Unsafe/FieldOffset.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/FieldOffset.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,14 +31,14 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import java.lang.reflect.*;
import static jdk.test.lib.Asserts.*;
public class FieldOffset {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Field[] fields = Test.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
--- a/hotspot/test/runtime/Unsafe/GetField.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetField.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,14 +30,14 @@
* @run main GetField
*/
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import java.lang.reflect.*;
import static jdk.test.lib.Asserts.*;
public class GetField {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
// Unsafe.INVALID_FIELD_OFFSET is a static final int field,
// make sure getField returns the correct field
Field field = Unsafe.class.getField("INVALID_FIELD_OFFSET");
--- a/hotspot/test/runtime/Unsafe/GetPutAddress.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutAddress.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import jdk.test.lib.Platform;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutAddress {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
int addressSize = unsafe.addressSize();
// Ensure the size returned from Unsafe.addressSize is correct
assertEquals(unsafe.addressSize(), Platform.is32bit() ? 4 : 8);
--- a/hotspot/test/runtime/Unsafe/GetPutBoolean.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutBoolean.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutBoolean {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Field field = Test.class.getField("b1");
--- a/hotspot/test/runtime/Unsafe/GetPutByte.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutByte.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutByte {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Field field = Test.class.getField("b");
--- a/hotspot/test/runtime/Unsafe/GetPutChar.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutChar.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutChar {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Field field = Test.class.getField("c");
--- a/hotspot/test/runtime/Unsafe/GetPutDouble.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutDouble.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutDouble {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Field field = Test.class.getField("d");
--- a/hotspot/test/runtime/Unsafe/GetPutFloat.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutFloat.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutFloat {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Field field = Test.class.getField("f");
--- a/hotspot/test/runtime/Unsafe/GetPutInt.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutInt.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,13 +30,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutInt {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Field field = Test.class.getField("i");
--- a/hotspot/test/runtime/Unsafe/GetPutLong.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutLong.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutLong {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Field field = Test.class.getField("l");
--- a/hotspot/test/runtime/Unsafe/GetPutObject.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutObject.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutObject {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Object o = new Object();
Field field = Test.class.getField("o");
--- a/hotspot/test/runtime/Unsafe/GetPutShort.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetPutShort.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class GetPutShort {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Test t = new Test();
Field field = Test.class.getField("s");
--- a/hotspot/test/runtime/Unsafe/GetUncompressedObject.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/GetUncompressedObject.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,13 +30,13 @@
import static jdk.test.lib.Asserts.*;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
public class GetUncompressedObject {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
// Allocate some memory and fill it with non-zero values.
final int size = 32;
--- a/hotspot/test/runtime/Unsafe/NestedUnsafe.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/NestedUnsafe.java Wed Sep 21 09:29:30 2016 -0700
@@ -35,7 +35,7 @@
import java.io.InputStream;
import java.lang.*;
import jdk.test.lib.InMemoryJavaCompiler;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
@@ -50,7 +50,7 @@
" } } ");
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
Class klass = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf, new Object[0]);
unsafe.ensureClassInitialized(klass);
--- a/hotspot/test/runtime/Unsafe/PageSize.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/PageSize.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
*/
import java.lang.reflect.Field;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class PageSize {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
int pageSize = unsafe.pageSize();
for (int n = 1; n != 0; n <<= 1) {
--- a/hotspot/test/runtime/Unsafe/RangeCheck.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/RangeCheck.java Wed Sep 21 09:29:30 2016 -0700
@@ -33,7 +33,7 @@
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.Platform;
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
@@ -60,7 +60,7 @@
public static class DummyClassWithMainRangeCheck {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
unsafe.getObject(new DummyClassWithMainRangeCheck(), Short.MAX_VALUE);
}
}
--- a/hotspot/test/runtime/Unsafe/Reallocate.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/Reallocate.java Wed Sep 21 09:29:30 2016 -0700
@@ -31,13 +31,13 @@
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m Reallocate
*/
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class Reallocate {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
long address = unsafe.allocateMemory(1);
assertNotEquals(address, 0L);
--- a/hotspot/test/runtime/Unsafe/SetMemory.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/SetMemory.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,13 +30,13 @@
* @run main SetMemory
*/
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class SetMemory {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
long address = unsafe.allocateMemory(1);
assertNotEquals(address, 0L);
unsafe.setMemory(address, 1, (byte)17);
--- a/hotspot/test/runtime/Unsafe/ThrowException.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/Unsafe/ThrowException.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,13 +30,13 @@
* @run main ThrowException
*/
-import jdk.test.lib.Utils;
+import jdk.test.lib.unsafe.UnsafeHelper;
import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.*;
public class ThrowException {
public static void main(String args[]) throws Exception {
- Unsafe unsafe = Utils.getUnsafe();
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
try {
unsafe.throwException(new TestException());
} catch (Throwable t) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/defineAnonClass/DefineAnon.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test DefineAnon
+ * @bug 8058575
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * java.management
+ * @compile -XDignore.symbol.file=true DefineAnon.java
+ * @run main/othervm p1.DefineAnon
+ */
+
+package p1;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import sun.misc.Unsafe;
+
+
+class T {
+ static protected void test0() { System.out.println("test0 (public)"); }
+ static protected void test1() { System.out.println("test1 (protected)"); }
+ static /*package-private*/ void test2() { System.out.println("test2 (package)"); }
+ static private void test3() { System.out.println("test3 (private)"); }
+}
+
+public class DefineAnon {
+
+ private static Unsafe getUnsafe() {
+ try {
+ java.lang.reflect.Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
+ singleoneInstanceField.setAccessible(true);
+ return (Unsafe) singleoneInstanceField.get(null);
+ } catch (Throwable ex) {
+ throw new RuntimeException("Was unable to get Unsafe instance.");
+ }
+ }
+
+ static Unsafe UNSAFE = DefineAnon.getUnsafe();
+
+ static Class<?> getAnonClass(Class<?> hostClass, final String className) {
+ final String superName = "java/lang/Object";
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+ cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, superName, null);
+
+ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, "test", "()V", null, null);
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "p1/T", "test0", "()V", false);
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "p1/T", "test1", "()V", false);
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "p1/T", "test2", "()V", false);
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "p1/T", "test3", "()V", false);
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ final byte[] classBytes = cw.toByteArray();
+ Class<?> invokerClass = UNSAFE.defineAnonymousClass(hostClass, classBytes, new Object[0]);
+ UNSAFE.ensureClassInitialized(invokerClass);
+ return invokerClass;
+ }
+
+ public static void main(String[] args) throws Throwable {
+ Throwable fail = null;
+
+ // Anonymous class has the privileges of its host class, so test[0123] should all work.
+ System.out.println("Injecting from the same package (p1):");
+ Class<?> p1cls = getAnonClass(T.class, "p1/AnonClass");
+ try {
+ p1cls.getMethod("test").invoke(null);
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ fail = ex; // throw this to make test fail, since subtest failed
+ }
+
+ // Anonymous class has different package name from host class. Should throw
+ // IllegalArgumentException.
+ System.out.println("Injecting from the wrong package (p2):");
+ try {
+ Class<?> p2cls = getAnonClass(DefineAnon.class, "p2/AnonClass");
+ p2cls.getMethod("test").invoke(null);
+ System.out.println("Failed, did not get expected IllegalArgumentException");
+ } catch (java.lang.IllegalArgumentException e) {
+ if (e.getMessage().contains("Host class p1/DefineAnon and anonymous class p2/AnonClass")) {
+ System.out.println("Got expected IllegalArgumentException: " + e.getMessage());
+ } else {
+ throw new RuntimeException("Unexpected message: " + e.getMessage());
+ }
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ fail = ex; // throw this to make test fail, since subtest failed
+ }
+
+ // Inject a class in the unnamed package into p1.T. It should be able
+ // to access all methods in p1.T.
+ System.out.println("Injecting unnamed package into correct host class:");
+ try {
+ Class<?> p3cls = getAnonClass(T.class, "AnonClass");
+ p3cls.getMethod("test").invoke(null);
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ fail = ex; // throw this to make test fail, since subtest failed
+ }
+
+ // Try using an array class as the host class. This should throw IllegalArgumentException.
+ try {
+ Class<?> p3cls = getAnonClass(String[].class, "AnonClass");
+ throw new RuntimeException("Expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ex) {
+ }
+
+ if (fail != null) throw fail; // make test fail, since subtest failed
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/defineAnonClass/NestedUnsafe.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058575
+ * @summary Creates an anonymous class inside of an anonymous class.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.compiler
+ * java.management
+ * @run main p.NestedUnsafe
+ */
+
+package p;
+
+import java.security.ProtectionDomain;
+import java.io.InputStream;
+import java.lang.*;
+import jdk.test.lib.*;
+import jdk.internal.misc.Unsafe;
+import jdk.test.lib.unsafe.UnsafeHelper;
+
+
+// Test that an anonymous class in package 'p' cannot define its own anonymous class
+// in another package.
+public class NestedUnsafe {
+ // The String concatenation should create the nested anonymous class.
+ static byte klassbuf[] = InMemoryJavaCompiler.compile("q.TestClass",
+ "package q; " +
+ "public class TestClass { " +
+ " public static void concat(String one, String two) throws Throwable { " +
+ " System.out.println(one + two);" +
+ " } } ");
+
+ public static void main(String args[]) throws Exception {
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
+
+ // The anonymous class calls defineAnonymousClass creating a nested anonymous class.
+ byte klassbuf2[] = InMemoryJavaCompiler.compile("p.TestClass2",
+ "package p; " +
+ "import jdk.internal.misc.Unsafe; " +
+ "public class TestClass2 { " +
+ " public static void doit() throws Throwable { " +
+ " Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); " +
+ " Class klass2 = unsafe.defineAnonymousClass(TestClass2.class, p.NestedUnsafe.klassbuf, new Object[0]); " +
+ " unsafe.ensureClassInitialized(klass2); " +
+ " Class[] dArgs = new Class[2]; " +
+ " dArgs[0] = String.class; " +
+ " dArgs[1] = String.class; " +
+ " try { " +
+ " klass2.getMethod(\"concat\", dArgs).invoke(null, \"CC\", \"DD\"); " +
+ " } catch (Throwable ex) { " +
+ " throw new RuntimeException(\"Exception: \" + ex.toString()); " +
+ " } " +
+ "} } ",
+ "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED");
+
+ Class klass2 = unsafe.defineAnonymousClass(p.NestedUnsafe.class, klassbuf2, new Object[0]);
+ try {
+ klass2.getMethod("doit").invoke(null);
+ throw new RuntimeException("Expected exception not thrown");
+ } catch (Throwable ex) {
+ Throwable iae = ex.getCause();
+ if (!iae.toString().contains(
+ "IllegalArgumentException: Host class p/NestedUnsafe and anonymous class q/TestClass")) {
+ throw new RuntimeException("Exception: " + iae.toString());
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/defineAnonClass/NestedUnsafe2.java Wed Sep 21 09:29:30 2016 -0700
@@ -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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058575
+ * @summary Creates an anonymous class inside of an anonymous class.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.compiler
+ * java.management
+ * @run main p.NestedUnsafe2
+ */
+
+package p;
+
+import java.security.ProtectionDomain;
+import java.io.InputStream;
+import java.lang.*;
+import jdk.test.lib.*;
+import jdk.internal.misc.Unsafe;
+import jdk.test.lib.unsafe.UnsafeHelper;
+
+
+// Test that an anonymous class that gets put in its host's package cannot define
+// an anonymous class in another package.
+public class NestedUnsafe2 {
+ // The String concatenation should create the nested anonymous class.
+ public static byte klassbuf[] = InMemoryJavaCompiler.compile("q.TestClass",
+ "package q; " +
+ "public class TestClass { " +
+ " public static void concat(String one, String two) throws Throwable { " +
+ " System.out.println(one + two);" +
+ " } } ");
+
+ public static void main(String args[]) throws Exception {
+ Unsafe unsafe = UnsafeHelper.getUnsafe();
+
+ // The anonymous class calls defineAnonymousClass creating a nested anonymous class.
+ byte klassbuf2[] = InMemoryJavaCompiler.compile("TestClass2",
+ "import jdk.internal.misc.Unsafe; " +
+ "public class TestClass2 { " +
+ " public static void doit() throws Throwable { " +
+ " Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); " +
+ " Class klass2 = unsafe.defineAnonymousClass(TestClass2.class, p.NestedUnsafe2.klassbuf, new Object[0]); " +
+ " unsafe.ensureClassInitialized(klass2); " +
+ " Class[] dArgs = new Class[2]; " +
+ " dArgs[0] = String.class; " +
+ " dArgs[1] = String.class; " +
+ " try { " +
+ " klass2.getMethod(\"concat\", dArgs).invoke(null, \"CC\", \"DD\"); " +
+ " } catch (Throwable ex) { " +
+ " throw new RuntimeException(\"Exception: \" + ex.toString()); " +
+ " } " +
+ "} } ",
+ "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED");
+
+ Class klass2 = unsafe.defineAnonymousClass(p.NestedUnsafe2.class, klassbuf2, new Object[0]);
+ try {
+ klass2.getMethod("doit").invoke(null);
+ throw new RuntimeException("Expected exception not thrown");
+ } catch (Throwable ex) {
+ Throwable iae = ex.getCause();
+ if (!iae.toString().contains(
+ "IllegalArgumentException: Host class p/NestedUnsafe2 and anonymous class q/TestClass")) {
+ throw new RuntimeException("Exception: " + iae.toString());
+ }
+ }
+ }
+}
--- a/hotspot/test/runtime/modules/ModuleOptionsWarn.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/runtime/modules/ModuleOptionsWarn.java Wed Sep 21 09:29:30 2016 -0700
@@ -29,6 +29,7 @@
* @library /test/lib
*/
+import java.util.Map;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
@@ -37,16 +38,65 @@
public static void main(String[] args) throws Exception {
- // Test that a warning is issued for module related properties that get ignored.
+ // Test that a warning is not issued for extraneous jdk.module properties.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+PrintWarnings", "-Djdk.module.ignored", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("Ignoring system property option");
+ output.shouldHaveExitValue(0);
+
+ // Test that a warning is issued for a reserved jdk.module property.
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+PrintWarnings", "-Djdk.module.addmods", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring system property option");
+ output.shouldHaveExitValue(0);
+
+ // Test that a warning is issued for a reserved jdk.module property ending in '.'.
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+PrintWarnings", "-Djdk.module.limitmods.", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring system property option");
+ output.shouldHaveExitValue(0);
+
+ // Test that a warning is issued for a reserved jdk.module property ending in '='.
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+PrintWarnings", "-Djdk.module.addexports=", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring system property option");
+ output.shouldHaveExitValue(0);
+
+ // Test that a warning is issued for a reserved jdk.module property ending in ".stuff"
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+PrintWarnings", "-Djdk.module.addreads.stuff", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring system property option");
+ output.shouldHaveExitValue(0);
+
+ // Test that a warning is issued for a reserved jdk.module property ending in "=stuff"
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+PrintWarnings", "-Djdk.module.path=stuff", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring system property option");
+ output.shouldHaveExitValue(0);
+
+ // Test that a warning is issued for a reserved jdk.module property ending in ".="
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+PrintWarnings", "-Djdk.module.upgrade.path.=xx", "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring system property option");
+ output.shouldHaveExitValue(0);
+
+ // Test that a warning is issued for a reserved jdk.module property ending in ".<num>"
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+PrintWarnings", "-Djdk.module.patch.3=xx", "-version");
+ output = new OutputAnalyzer(pb.start());
output.shouldContain("Ignoring system property option");
output.shouldHaveExitValue(0);
// Test that a warning can be suppressed for module related properties that get ignored.
pb = ProcessTools.createJavaProcessBuilder(
- "-Djdk.module.ignored", "-XX:-PrintWarnings", "-version");
+ "-Djdk.module.addmods", "-XX:-PrintWarnings", "-version");
output = new OutputAnalyzer(pb.start());
output.shouldNotContain("Ignoring system property option");
output.shouldHaveExitValue(0);
@@ -57,5 +107,13 @@
output = new OutputAnalyzer(pb.start());
output.shouldNotContain("Ignoring system property option");
output.shouldHaveExitValue(0);
+
+ // Test that a warning is issued for module related properties specified using _JAVA_OPTIONS.
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+PrintWarnings", "-version");
+ Map<String, String> env = pb.environment();
+ env.put("_JAVA_OPTIONS", "-Djdk.module.addreads");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring system property option");
+ output.shouldHaveExitValue(0);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/AllModulesCommandTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,149 @@
+/*
+ * 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 java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.Set;
+import java.util.HashSet;
+import static jdk.test.lib.Asserts.assertTrue;
+
+/**
+ * @test
+ * @summary Tests AllModules JDWP command
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @compile AllModulesCommandTestDebuggee.java
+ * @run main/othervm AllModulesCommandTest
+ */
+public class AllModulesCommandTest implements DebuggeeLauncher.Listener {
+
+ private DebuggeeLauncher launcher;
+ private JdwpChannel channel;
+ private CountDownLatch jdwpLatch = new CountDownLatch(1);
+ private Set<String> jdwpModuleNames = new HashSet<>();
+ private Set<String> javaModuleNames = new HashSet<>();
+
+ public static void main(String[] args) throws Throwable {
+ new AllModulesCommandTest().doTest();
+ }
+
+ private void doTest() throws Throwable {
+ launcher = new DebuggeeLauncher(this);
+ launcher.launchDebuggee();
+ // Await till the debuggee sends all the necessary modules info to check against
+ // then start the JDWP session
+ jdwpLatch.await();
+ doJdwp();
+ }
+
+ @Override
+ public void onDebuggeeModuleInfo(String modName) {
+ // The debuggee has sent out info about a loaded module
+ javaModuleNames.add(modName);
+ }
+
+ @Override
+ public void onDebuggeeSendingCompleted() {
+ // The debuggee has completed sending all the info
+ // We can start the JDWP session
+ jdwpLatch.countDown();
+ }
+
+ @Override
+ public void onDebuggeeError(String message) {
+ System.err.println("Debuggee error: '" + message + "'");
+ System.exit(1);
+ }
+
+ private void doJdwp() throws Exception {
+ try {
+ // Establish JDWP socket connection
+ channel = new JdwpChannel();
+ channel.connect();
+ // Send out ALLMODULES JDWP command
+ // and verify the reply
+ JdwpAllModulesReply reply = new JdwpAllModulesCmd().send(channel);
+ assertReply(reply);
+ for (int i = 0; i < reply.getModulesCount(); ++i) {
+ long modId = reply.getModuleId(i);
+ // For each module reported by JDWP get its name using the JDWP NAME command
+ getModuleName(modId);
+ // Assert the JDWP CANREAD and CLASSLOADER commands
+ assertCanRead(modId);
+ assertClassLoader(modId);
+ }
+
+ System.out.println("Module names reported by JDWP: " + Arrays.toString(jdwpModuleNames.toArray()));
+ System.out.println("Module names reported by Java: " + Arrays.toString(javaModuleNames.toArray()));
+
+ // Modules reported by the JDWP should be the same as reported by the Java API
+ if (!jdwpModuleNames.equals(javaModuleNames)) {
+ throw new RuntimeException("Modules info reported by Java API differs from that reported by JDWP.");
+ } else {
+ System.out.println("Test passed!");
+ }
+
+ } finally {
+ launcher.terminateDebuggee();
+ try {
+ new JdwpExitCmd(0).send(channel);
+ channel.disconnect();
+ } catch (Exception x) {
+ }
+ }
+ }
+
+ private void getModuleName(long modId) throws IOException {
+ // Send out the JDWP NAME command and store the reply
+ JdwpModNameReply reply = new JdwpModNameCmd(modId).send(channel);
+ assertReply(reply);
+ String modName = reply.getModuleName();
+ if (modName != null) { // JDWP reports unnamed modules, ignore them
+ jdwpModuleNames.add(modName);
+ }
+ }
+
+ private void assertReply(JdwpReply reply) {
+ // Simple assert for any JDWP reply
+ if (reply.getErrorCode() != 0) {
+ throw new RuntimeException("Unexpected reply error code " + reply.getErrorCode() + " for reply " + reply);
+ }
+ }
+
+ private void assertCanRead(long modId) throws IOException {
+ // Simple assert for the CANREAD command
+ JdwpCanReadReply reply = new JdwpCanReadCmd(modId, modId).send(channel);
+ assertReply(reply);
+ assertTrue(reply.canRead(), "canRead() reports false for reading from the same module");
+ }
+
+ private void assertClassLoader(long modId) throws IOException {
+ // Simple assert for the CLASSLOADER command
+ JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel);
+ assertReply(reply);
+ long clId = reply.getClassLoaderId();
+ assertTrue(clId >= 0, "bad classloader refId " + clId + " for module id " + modId);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/AllModulesCommandTestDebuggee.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,55 @@
+/*
+ * 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 java.lang.reflect.Module;
+import java.lang.reflect.Layer;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * The debuggee to be launched by the test
+ * Sends out the info about the loaded modules
+ * then stays to respond to the JDWP commands
+ */
+public class AllModulesCommandTestDebuggee {
+
+ public static void main(String[] args) throws InterruptedException {
+
+ int modCount = Layer.boot().modules().size();
+
+ // Send all modules names via the process output
+ for (Module mod : Layer.boot().modules()) {
+ String info = String.format("module %s", mod.getName());
+ write(info);
+ }
+ // Signal that the sending is done
+ write("ready");
+ Thread.sleep(Long.MAX_VALUE);
+ }
+
+ private static void write(String s) {
+ System.out.println(s);
+ System.out.flush();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/DebuggeeLauncher.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,166 @@
+/*
+ * 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 java.io.IOException;
+import java.net.ServerSocket;
+import java.util.StringTokenizer;
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.Utils;
+import static jdk.test.lib.Asserts.assertFalse;
+
+/**
+ * Launches the debuggee with the necessary JDWP options and handles the output
+ */
+public class DebuggeeLauncher implements StreamHandler.Listener {
+
+ public interface Listener {
+
+ /**
+ * Callback to use when a module name is received from the debuggee
+ *
+ * @param modName module name reported by the debuggee
+ */
+ void onDebuggeeModuleInfo(String modName);
+
+ /**
+ * Callback to use when the debuggee completes sending out the info
+ */
+ void onDebuggeeSendingCompleted();
+
+ /**
+ * Callback to handle any debuggee error
+ *
+ * @param line line from the debuggee's stderr
+ */
+ void onDebuggeeError(String line);
+ }
+
+ private static int jdwpPort = -1;
+ private static final String CLS_DIR = System.getProperty("test.classes", "").trim();
+ private static final String DEBUGGEE = "AllModulesCommandTestDebuggee";
+ private Process p;
+ private final Listener listener;
+ private StreamHandler inputHandler;
+ private StreamHandler errorHandler;
+
+ /**
+ * @param listener the listener we report the debuggee events to
+ */
+ public DebuggeeLauncher(Listener listener) {
+ this.listener = listener;
+ }
+
+ /**
+ * Starts the debuggee with the necessary JDWP options and handles the
+ * debuggee's stdout and stderr outputs
+ *
+ * @throws Throwable
+ */
+ public void launchDebuggee() throws Throwable {
+
+ ProcessBuilder pb = new ProcessBuilder(getCommand());
+ p = pb.start();
+ inputHandler = new StreamHandler(p.getInputStream(), this);
+ errorHandler = new StreamHandler(p.getErrorStream(), this);
+ inputHandler.start();
+ errorHandler.start();
+ }
+
+ /**
+ * Command to start the debuggee with the JDWP options and using the JDK
+ * under test
+ *
+ * @return the command
+ */
+ private String[] getCommand() {
+ return new String[]{
+ JDKToolFinder.getTestJDKTool("java"),
+ getJdwpOptions(),
+ "-cp",
+ CLS_DIR,
+ DEBUGGEE
+ };
+ }
+
+ /**
+ * Terminates the debuggee
+ */
+ public void terminateDebuggee() {
+ if (p.isAlive()) {
+ p.destroyForcibly();
+ }
+ }
+
+ /**
+ * Debuggee JDWP options
+ *
+ * @return the JDWP options to start the debuggee with
+ */
+ private static String getJdwpOptions() {
+ return "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + getJdwpPort();
+ }
+
+ /**
+ * Find an available port for the JDWP session
+ *
+ * @return JDWP port
+ */
+ public static int getJdwpPort() {
+ if (jdwpPort == -1) {
+ jdwpPort = findFreePort();
+ assertFalse(jdwpPort == -1, "Can not find vailbale port for JDWP");
+ }
+ return jdwpPort;
+ }
+
+ private static int findFreePort() {
+ try (ServerSocket socket = new ServerSocket(0)) {
+ return socket.getLocalPort();
+ } catch (IOException e) {
+ }
+ return -1;
+ }
+
+ @Override
+ public void onStringRead(StreamHandler handler, String line) {
+ if (handler.equals(errorHandler)) {
+ terminateDebuggee();
+ listener.onDebuggeeError(line);
+ } else {
+ processDebuggeeOutput(line);
+ }
+ }
+
+ private void processDebuggeeOutput(String line) {
+ StringTokenizer st = new StringTokenizer(line);
+ String token = st.nextToken();
+ switch (token) {
+ case "module":
+ listener.onDebuggeeModuleInfo(st.nextToken());
+ break;
+ case "ready":
+ listener.onDebuggeeSendingCompleted();
+ break;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpAllModulesCmd.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * The JDWP ALLMODULES command
+ */
+public class JdwpAllModulesCmd extends JdwpCmd<JdwpAllModulesReply> {
+
+ public JdwpAllModulesCmd() {
+ super(22, 1, JdwpAllModulesReply.class, 0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpAllModulesReply.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * 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 java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The JDWP reply to the ALLMODULES command
+ */
+public class JdwpAllModulesReply extends JdwpReply {
+
+ private int modulesCount;
+ private long[] modulesId;
+
+ protected void parseData(DataInputStream ds) throws IOException {
+ modulesCount = ds.readInt();
+ modulesId = new long[modulesCount];
+ for (int nmod = 0; nmod < modulesCount; ++nmod) {
+ modulesId[nmod] = readRefId(ds);
+ }
+ }
+
+ /**
+ * Number of modules reported
+ *
+ * @return modules count
+ */
+ public int getModulesCount() {
+ return modulesCount;
+ }
+
+ /**
+ * The id of a module reported
+ *
+ * @param ndx module index in the array of the reported ids
+ * @return module id
+ */
+ public long getModuleId(int ndx) {
+ return modulesId[ndx];
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpCanReadCmd.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/**
+ * The JDWP CANREAD command
+ */
+public class JdwpCanReadCmd extends JdwpCmd<JdwpCanReadReply> {
+
+ public JdwpCanReadCmd(long modId, long srcModId) {
+ super(3, 18, JdwpCanReadReply.class, 2 * refLen());
+ putRefId(modId);
+ putRefId(srcModId);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpCanReadReply.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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 java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The reply to the JDWP CANREAD command
+ */
+public class JdwpCanReadReply extends JdwpReply {
+
+ private boolean canRead;
+
+ protected void parseData(DataInputStream ds) throws IOException {
+ canRead = ds.read() == 1;
+ }
+
+ public boolean canRead() {
+ return canRead;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpChannel.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,71 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.Arrays;
+
+/**
+ * JDWP socket transport
+ */
+public class JdwpChannel {
+
+ private Socket sock;
+
+ public void connect() throws IOException {
+ sock = new Socket("localhost", DebuggeeLauncher.getJdwpPort());
+ handshake();
+ }
+
+ /**
+ * Sends JDWP handshake and verifies the reply
+ * @throws IOException
+ */
+ private void handshake() throws IOException {
+ final byte[] HANDSHAKE = "JDWP-Handshake".getBytes();
+ sock.getOutputStream().write(HANDSHAKE, 0, HANDSHAKE.length);
+
+ byte[] reply = new byte[14];
+ sock.getInputStream().read(reply, 0, 14);
+ if (!Arrays.equals(HANDSHAKE, reply)) {
+ throw new RuntimeException("Error during handshake. Reply was: " + new String(reply) + " expected " + new String(HANDSHAKE));
+ }
+ }
+
+ public void disconnect() {
+ try {
+ sock.close();
+ } catch (IOException x) {
+ }
+ }
+
+ public void write(byte[] data, int length) throws IOException {
+ sock.getOutputStream().write(data, 0, length);
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return sock.getInputStream();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpClassLoaderCmd.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * The JDWP CLASSLOADER command
+ */
+public class JdwpClassLoaderCmd extends JdwpCmd<JdwpClassLoaderReply> {
+
+ public JdwpClassLoaderCmd(long modId) {
+ super(2, 18, JdwpClassLoaderReply.class, refLen());
+ putRefId(modId);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpClassLoaderReply.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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 java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The JDWP CLASSLOADER reply
+ */
+public class JdwpClassLoaderReply extends JdwpReply {
+
+ private long refId;
+
+ protected void parseData(DataInputStream ds) throws IOException {
+ refId = readRefId(ds);
+ }
+
+ public long getClassLoaderId() {
+ return refId;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpCmd.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,93 @@
+/*
+ * 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 java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Generic JDWP command
+ * @param <T> the corresponding JDWP reply class, to construct a reply object
+ */
+public abstract class JdwpCmd<T extends JdwpReply> {
+
+ private ByteBuffer data;
+ private static int id = 1;
+ private final byte FLAGS = 0;
+ private T reply;
+ private final int dataLen;
+ private final int HEADER_LEN = 11;
+
+ /**
+ * JDWWp command
+ * @param cmd command code
+ * @param cmdSet command set
+ * @param replyClz command reply class
+ * @param dataLen length of additional data for the command
+ */
+ JdwpCmd(int cmd, int cmdSet, Class<T> replyClz, int dataLen) {
+ this.dataLen = dataLen;
+ data = ByteBuffer.allocate(HEADER_LEN + dataLen);
+ data.putInt(HEADER_LEN + dataLen);
+ data.putInt(id++);
+ data.put(FLAGS);
+ data.put((byte) cmdSet);
+ data.put((byte) cmd);
+ if (replyClz != null) {
+ try {
+ reply = replyClz.newInstance();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ JdwpCmd(int cmd, int cmdSet, Class<T> replyClz) {
+ this(cmd, cmdSet, replyClz, 0);
+ }
+
+ int getDataLength() {
+ return dataLen;
+ }
+
+ public final T send(JdwpChannel channel) throws IOException {
+ System.err.println("Sending command: " + this);
+ channel.write(data.array(), HEADER_LEN + getDataLength());
+ if (reply != null) {
+ reply.initFromStream(channel.getInputStream());
+ }
+ return (T) reply;
+ }
+
+ protected void putRefId(long refId) {
+ data.putLong(refId);
+ }
+
+ protected void putInt(int val) {
+ data.putInt(val);
+ }
+
+ protected static int refLen() {
+ return 8;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpExitCmd.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * The JDWP EXIT command to terminate the debuggee
+ */
+public class JdwpExitCmd extends JdwpCmd {
+
+ public JdwpExitCmd(int exitCode) {
+ super(10, 1, null, 4);
+ putInt(exitCode);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpModNameCmd.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * The JDWP NAME command
+ */
+public class JdwpModNameCmd extends JdwpCmd<JdwpModNameReply> {
+
+ public JdwpModNameCmd(long modId) {
+ super(1, 18, JdwpModNameReply.class, refLen());
+ putRefId(modId);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpModNameReply.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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 java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * JDWP reply to the NAME command
+ */
+public class JdwpModNameReply extends JdwpReply {
+
+ private byte[] name;
+
+ protected void parseData(DataInputStream ds) throws IOException {
+ name = readJdwpString(ds);
+ }
+
+ public String getModuleName() {
+ return name == null ? null : new String(name);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/JdwpReply.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,75 @@
+/*
+ * 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 java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Generic JDWP reply
+ */
+public abstract class JdwpReply {
+
+ protected final static int HEADER_LEN = 11;
+ private byte[] errCode = new byte[2];
+ private byte[] data;
+
+ public final void initFromStream(InputStream is) throws IOException {
+ DataInputStream ds = new DataInputStream(is);
+
+ int length = ds.readInt();
+ int id = ds.readInt();
+ byte flags = (byte) ds.read();
+
+ ds.read(errCode, 0, 2);
+
+ int dataLength = length - HEADER_LEN;
+ if (dataLength > 0) {
+ data = new byte[dataLength];
+ ds.read(data, 0, dataLength);
+ parseData(new DataInputStream(new ByteArrayInputStream(data)));
+ }
+ }
+
+ protected void parseData(DataInputStream ds) throws IOException {
+ }
+
+ protected byte[] readJdwpString(DataInputStream ds) throws IOException {
+ byte[] str = null;
+ int len = ds.readInt();
+ if (len > 0) {
+ str = new byte[len];
+ ds.read(str, 0, len);
+ }
+ return str;
+ }
+
+ protected long readRefId(DataInputStream ds) throws IOException {
+ return ds.readLong();
+ }
+
+ public int getErrorCode() {
+ return (((errCode[0] & 0xFF) << 8) | (errCode[1] & 0xFF));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jdwp/StreamHandler.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,81 @@
+/*
+ * 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 java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Handles the process output (either stdin or stdout)
+ * passing the lines to a listener
+ */
+public class StreamHandler implements Runnable {
+
+ public interface Listener {
+ /**
+ * Called when a line has been read from the process output stream
+ * @param handler this StreamHandler
+ * @param s the line
+ */
+ void onStringRead(StreamHandler handler, String s);
+ }
+
+ private final ExecutorService executor;
+ private final InputStream is;
+ private final Listener listener;
+
+ /**
+ * @param is input stream to read from
+ * @param listener listener to pass the read lines to
+ * @throws IOException
+ */
+ public StreamHandler(InputStream is, Listener listener) throws IOException {
+ this.is = is;
+ this.listener = listener;
+ executor = Executors.newSingleThreadExecutor();
+ }
+
+ /**
+ * Starts asynchronous reading
+ */
+ public void start() {
+ executor.submit(this);
+ }
+
+ @Override
+ public void run() {
+ try {
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ String line;
+ while ((line = br.readLine()) != null) {
+ listener.onStringRead(this, line);
+ }
+ } catch (Exception x) {
+ throw new RuntimeException(x);
+ }
+ }
+
+}
--- a/hotspot/test/serviceability/sa/TestInstanceKlassSize.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/serviceability/sa/TestInstanceKlassSize.java Wed Sep 21 09:29:30 2016 -0700
@@ -23,6 +23,7 @@
import sun.jvm.hotspot.HotSpotAgent;
import sun.jvm.hotspot.utilities.SystemDictionaryHelper;
+import sun.jvm.hotspot.oops.InstanceKlass;
import sun.jvm.hotspot.debugger.*;
import java.util.ArrayList;
@@ -44,15 +45,19 @@
* @test
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * @modules jdk.hotspot.agent
- * @modules jdk.hotspot.agent/sun.jvm.hotspot
- * @modules jdk.hotspot.agent/sun.jvm.hotspot.utilities
- * @modules jdk.hotspot.agent/sun.jvm.hotspot.oops
- * @compile -XDignore.symbol.file=true -Xmodule:jdk.hotspot.agent
- * -XaddExports:java.base/jdk.internal.misc=jdk.hotspot.agent
- * -XaddExports:java.management/java.lang.management=jdk.hotspot.agent
+ * @compile -XDignore.symbol.file=true
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED
* TestInstanceKlassSize.java
- * @run main/othervm TestInstanceKlassSize
+ * @run main/othervm
+ * --add-modules=jdk.hotspot.agent
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED
+ * TestInstanceKlassSize
*/
public class TestInstanceKlassSize {
@@ -112,11 +117,11 @@
" java.lang.Byte",
};
String[] toolArgs = {
- "-XX:+UnlockDiagnosticVMOptions",
"--add-modules=jdk.hotspot.agent",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
+ "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED",
"TestInstanceKlassSize",
Long.toString(app.getPid())
};
@@ -136,6 +141,8 @@
String jcmdInstanceKlassSize = getJcmdInstanceKlassSize(
jcmdOutput,
instanceKlassName);
+ Asserts.assertNotNull(jcmdInstanceKlassSize,
+ "Could not get the instance klass size from the jcmd output");
for (String s : output.asLines()) {
if (s.contains(instanceKlassName)) {
Asserts.assertTrue(
@@ -165,10 +172,12 @@
}
for (String SAInstanceKlassName : SAInstanceKlassNames) {
- Long size = SystemDictionaryHelper.findInstanceKlass(
- SAInstanceKlassName).getSize();
+ InstanceKlass ik = SystemDictionaryHelper.findInstanceKlass(
+ SAInstanceKlassName);
+ Asserts.assertNotNull(ik,
+ String.format("Unable to find instance klass for %s", ik));
System.out.println("SA: The size of " + SAInstanceKlassName +
- " is " + size);
+ " is " + ik.getSize());
}
agent.detach();
}
--- a/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java Wed Sep 21 09:29:30 2016 -0700
@@ -38,15 +38,20 @@
* @test
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * @modules jdk.hotspot.agent
- * @modules jdk.hotspot.agent/sun.jvm.hotspot
- * @modules jdk.hotspot.agent/sun.jvm.hotspot.utilities
- * @modules jdk.hotspot.agent/sun.jvm.hotspot.oops
- * @compile -XDignore.symbol.file=true -Xmodule:jdk.hotspot.agent
- * -XaddExports:java.base/jdk.internal.misc=jdk.hotspot.agent
- * -XaddExports:java.management/java.lang.management=jdk.hotspot.agent
+ * @compile -XDignore.symbol.file=true
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED
* TestInstanceKlassSizeForInterface.java
- * @run main/othervm TestInstanceKlassSizeForInterface
+ * @run main/othervm
+ * -XX:+UnlockDiagnosticVMOptions
+ * --add-modules=jdk.hotspot.agent
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED
+ * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED
+ * TestInstanceKlassSizeForInterface
*/
interface Language {
@@ -80,6 +85,8 @@
for (String instanceKlassName : instanceKlassNames) {
InstanceKlass iKlass = SystemDictionaryHelper.findInstanceKlass(
instanceKlassName);
+ Asserts.assertNotNull(iKlass,
+ String.format("Unable to find instance klass for %s", instanceKlassName));
System.out.println("SA: The size of " + instanceKlassName +
" is " + iKlass.getSize());
}
@@ -106,11 +113,11 @@
// Grab the pid from the current java process and pass it
String[] toolArgs = {
- "-XX:+UnlockDiagnosticVMOptions",
"--add-modules=jdk.hotspot.agent",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
+ "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED",
"TestInstanceKlassSizeForInterface",
Long.toString(ProcessTools.getProcessId())
};
@@ -138,6 +145,8 @@
String jcmdInstanceKlassSize = getJcmdInstanceKlassSize(
jcmdOutput,
instanceKlassName);
+ Asserts.assertNotNull(jcmdInstanceKlassSize,
+ "Could not get the instance klass size from the jcmd output");
for (String s : SAOutput.asLines()) {
if (s.contains(instanceKlassName)) {
Asserts.assertTrue(
@@ -162,7 +171,7 @@
return;
}
- if ( args == null || args.length == 0 ) {
+ if (args == null || args.length == 0) {
ParselTongue lang = new ParselTongue();
Language ventro = new Language() {
--- a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java Fri Sep 16 10:57:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2014, 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.test.lib.JDKToolLauncher;
-import jdk.test.lib.process.OutputBuffer;
-import jdk.test.lib.Platform;
-import jdk.test.lib.process.ProcessTools;
-
-import java.io.File;
-
-/*
- * @test
- * @bug 8028623
- * @summary Test hashing of extended characters in Serviceability Agent.
- * @library /test/lib
- * @modules java.base/jdk.internal.misc
- * java.compiler
- * java.management
- * jdk.jvmstat/sun.jvmstat.monitor
- * @compile -encoding utf8 Test8028623.java
- * @run main/othervm -XX:+UsePerfData Test8028623
- */
-public class Test8028623 {
-
- public static int \u00CB = 1;
- public static String dumpFile = "heap.bin";
-
- public static void main (String[] args) {
-
- System.out.println(\u00CB);
-
- try {
- if (!Platform.shouldSAAttach()) {
- System.out.println("SA attach not expected to work - test skipped.");
- return;
- }
- long pid = ProcessTools.getProcessId();
- JDKToolLauncher jmap = JDKToolLauncher.create("jhsdb")
- .addToolArg("jmap")
- .addToolArg("--binaryheap")
- .addToolArg("--pid")
- .addToolArg(Long.toString(pid));
- ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
- OutputBuffer output = ProcessTools.getOutput(pb);
- Process p = pb.start();
- int e = p.waitFor();
- System.out.println("stdout:");
- System.out.println(output.getStdout());
- System.out.println("stderr:");
- System.out.println(output.getStderr());
-
- if (e != 0) {
- throw new RuntimeException("jmap returns: " + e);
- }
- if (! new File(dumpFile).exists()) {
- throw new RuntimeException("dump file NOT created: '" + dumpFile + "'");
- }
- } catch (Throwable t) {
- t.printStackTrace();
- throw new RuntimeException("Test failed with: " + t);
- }
- }
-}
--- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Wed Sep 21 09:29:30 2016 -0700
@@ -39,7 +39,7 @@
* Concrete subclasses should implement method {@link #process()}.
*/
public abstract class PathHandler {
- private static final Unsafe UNSAFE = jdk.test.lib.Utils.getUnsafe();
+ private static final Unsafe UNSAFE = jdk.test.lib.unsafe.UnsafeHelper.getUnsafe();
private static final AtomicLong CLASS_COUNT = new AtomicLong(0L);
private static volatile boolean CLASSES_LIMIT_REACHED = false;
private static final Pattern JAR_IN_DIR_PATTERN
--- a/hotspot/test/testlibrary/jittester/Makefile Fri Sep 16 10:57:21 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/Makefile Wed Sep 21 09:29:30 2016 -0700
@@ -70,17 +70,17 @@
DIST_JAR = $(DIST_DIR)/JITtester.jar
SRC_FILES = $(shell find $(SRC_DIR) -name '*.java')
-TESTLIBRARY_SRC_DIR = ../jdk/test/lib
+TESTLIBRARY_SRC_DIR = ../../../../test/lib/jdk/test/lib
TESTLIBRARY_SRC_FILES = $(TESTLIBRARY_SRC_DIR)/Asserts.java \
$(TESTLIBRARY_SRC_DIR)/JDKToolFinder.java \
$(TESTLIBRARY_SRC_DIR)/JDKToolLauncher.java \
- $(TESTLIBRARY_SRC_DIR)/OutputAnalyzer.java \
- $(TESTLIBRARY_SRC_DIR)/OutputBuffer.java \
- $(TESTLIBRARY_SRC_DIR)/Pair.java \
$(TESTLIBRARY_SRC_DIR)/Platform.java \
- $(TESTLIBRARY_SRC_DIR)/ProcessTools.java \
- $(TESTLIBRARY_SRC_DIR)/StreamPumper.java \
- $(TESTLIBRARY_SRC_DIR)/Utils.java
+ $(TESTLIBRARY_SRC_DIR)/Utils.java \
+ $(TESTLIBRARY_SRC_DIR)/process/OutputAnalyzer.java \
+ $(TESTLIBRARY_SRC_DIR)/process/OutputBuffer.java \
+ $(TESTLIBRARY_SRC_DIR)/process/ProcessTools.java \
+ $(TESTLIBRARY_SRC_DIR)/process/StreamPumper.java \
+ $(TESTLIBRARY_SRC_DIR)/util/Pair.java
.PHONY: cleantmp
@@ -120,7 +120,6 @@
copytestlibrary: $(DRIVER_DIR)
@cp -r src/jdk/test/lib/jittester/jtreg/*.java $(DRIVER_DIR)
- @cp -r ../jdk $(TESTBASE_DIR)/
testgroup: $(TESTBASE_DIR)
@echo 'jittester_all = \\' > $(TESTGROUP_FILE)
--- a/jaxp/.hgtags Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/.hgtags Wed Sep 21 09:29:30 2016 -0700
@@ -378,3 +378,4 @@
9490ba2e5e41685c858a0ca2a6ec87611eb011c6 jdk-9+133
1c6c21d87aa459d82425e1fddc9ce8647aebde34 jdk-9+134
f695240370c77a25fed88225a392e7d530cb4d78 jdk-9+135
+f1eafcb0eb7182b937bc93f214d8cabd01ec4d59 jdk-9+136
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLCatalogResolver.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLCatalogResolver.java Wed Sep 21 09:29:30 2016 -0700
@@ -61,9 +61,19 @@
* catalog resolution outside of a parsing context. It may be shared
* between several parsers and the application.</p>
*
+ * @deprecated This class and the JDK internal Catalog API in package
+ * {@code com.sun.org.apache.xml.internal.resolver}
+ * is encapsulated in JDK 9. The entire implementation under the package is now
+ * deprecated and subject to removal in a future release. Users of the API should
+ * migrate to the {@linkplain javax.xml.catalog new public API}.
+ * <p>
+ * The new Catalog API is supported throughout the JDK XML Processors, which allows
+ * the use of Catalog by simply setting a path to a Catalog file as a property.
+ *
* @author Michael Glavassevich, IBM
*
*/
+@Deprecated(since="9", forRemoval=true)
public class XMLCatalogResolver
implements XMLEntityResolver, EntityResolver2, LSResourceResolver {
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/Catalog.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/Catalog.java Wed Sep 21 09:29:30 2016 -0700
@@ -178,6 +178,14 @@
*
* @see CatalogReader
* @see CatalogEntry
+ * @deprecated The JDK internal Catalog API in package
+ * {@code com.sun.org.apache.xml.internal.resolver}
+ * is encapsulated in JDK 9. The entire implementation under the package is now
+ * deprecated and subject to removal in a future release. Users of the API
+ * should migrate to the {@linkplain javax.xml.catalog new public API}.
+ * <p>
+ * The new Catalog API is supported throughout the JDK XML Processors, which allows
+ * the use of Catalog by simply setting a path to a Catalog file as a property.
*
* @author Norman Walsh
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
@@ -187,6 +195,7 @@
* <p>Derived from public domain code originally published by Arbortext,
* Inc.</p>
*/
+@Deprecated(since="9", forRemoval=true)
public class Catalog {
/** The BASE Catalog Entry type. */
public static final int BASE = CatalogEntry.addEntryType("BASE", 1);
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/CatalogManager.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/CatalogManager.java Wed Sep 21 09:29:30 2016 -0700
@@ -110,13 +110,21 @@
* </table>
*
* @see Catalog
+ * @deprecated The JDK internal Catalog API in package
+ * {@code com.sun.org.apache.xml.internal.resolver}
+ * is encapsulated in JDK 9. The entire implementation under the package is now
+ * deprecated and subject to removal in a future release. Users of the API
+ * should migrate to the {@linkplain javax.xml.catalog new public API}.
+ * <p>
+ * The new Catalog API is supported throughout the JDK XML Processors, which allows
+ * the use of Catalog by simply setting a path to a Catalog file as a property.
*
* @author Norman Walsh
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
*
* @version 1.0
*/
-
+@Deprecated(since="9", forRemoval=true)
public class CatalogManager {
private static final String pFiles = "xml.catalog.files";
private static final String pVerbosity = "xml.catalog.verbosity";
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/Resolver.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/Resolver.java Wed Sep 21 09:29:30 2016 -0700
@@ -37,12 +37,21 @@
* suffix-based matching and an external RFC2483 resolver.
*
* @see Catalog
+ * @deprecated The JDK internal Catalog API in package
+ * {@code com.sun.org.apache.xml.internal.resolver}
+ * is encapsulated in JDK 9. The entire implementation under the package is now
+ * deprecated and subject to removal in a future release. Users of the API
+ * should migrate to the {@linkplain javax.xml.catalog new public API}.
+ * <p>
+ * The new Catalog API is supported throughout the JDK XML Processors, which allows
+ * the use of Catalog by simply setting a path to a Catalog file as a property.
*
* @author Norman Walsh
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
*
* @version 1.0
*/
+@Deprecated(since="9", forRemoval=true)
public class Resolver extends Catalog {
/**
* The URISUFFIX Catalog Entry type.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/tools/CatalogResolver.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/tools/CatalogResolver.java Wed Sep 21 09:29:30 2016 -0700
@@ -52,12 +52,21 @@
* @see Catalog
* @see org.xml.sax.EntityResolver
* @see javax.xml.transform.URIResolver
+ * @deprecated The JDK internal Catalog API in package
+ * {@code com.sun.org.apache.xml.internal.resolver}
+ * is encapsulated in JDK 9. The entire implementation under the package is now
+ * deprecated and subject to removal in a future release. Users of the API
+ * should migrate to the {@linkplain javax.xml.catalog new public API}.
+ * <p>
+ * The new Catalog API is supported throughout the JDK XML Processors, which allows
+ * the use of Catalog by simply setting a path to a Catalog file as a property.
*
* @author Norman Walsh
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
*
* @version 1.0
*/
+@Deprecated(since="9", forRemoval=true)
public class CatalogResolver implements EntityResolver, URIResolver {
/** Make the parser Namespace aware? */
public boolean namespaceAware = true;
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,7 +25,7 @@
import java.io.File;
import java.io.StringReader;
-
+import javax.xml.stream.XMLResolver;
import javax.xml.transform.Source;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
@@ -42,7 +42,7 @@
/**
* @test
- * @bug 8158084 8162438 8162442
+ * @bug 8158084 8162438 8162442 8166220
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport
* @run testng/othervm catalog.CatalogSupport
@@ -114,6 +114,15 @@
}
/*
+ Verifies the Catalog support on XMLStreamReader.
+ */
+ @Test(dataProvider = "data_StAXA")
+ public void testStAXA(boolean setUseCatalog, boolean useCatalog, String catalog,
+ String xml, XMLResolver resolver, String expected) throws Exception {
+ testStAX(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
+ }
+
+ /*
Verifies the Catalog support on resolving DTD, xsd import and include in
Schema files.
*/
@@ -212,6 +221,20 @@
};
}
+ /*
+ DataProvider: for testing the StAX parser
+ Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
+ */
+ @DataProvider(name = "data_StAXA")
+ public Object[][] getDataStAX() {
+
+ return new Object[][]{
+ {false, true, xml_catalog, xml_system, null, expectedWCatalog},
+ {false, true, xml_catalog, xml_system, null, expectedWResolver},
+ {true, true, xml_catalog, xml_system, null, expectedWResolver}
+ };
+ }
+
MyEntityHandler getMyEntityHandler(String elementName, String[] systemIds, InputSource... returnValues) {
return new MyEntityHandler(systemIds, returnValues, elementName);
}
@@ -262,8 +285,8 @@
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
- StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
- StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
+ StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
+ StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
StreamSource source = new StreamSource(new File(xml_val_test));
@@ -271,8 +294,7 @@
XmlInput[] returnValues = {new XmlInput(null, dtd_system, null), new XmlInput(null, xsd_val_test, null)};
LSResourceResolver resolver = new SourceResolver(null, systemIds, returnValues);
- StAXSource stax2 = getStaxSource(xml_val_test, xml_val_test_id);
- StAXSource stax3 = getStaxSource(xml_val_test, xml_val_test_id);
+ StAXSource stax2 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
return new Object[][]{
// use catalog
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport1.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport1.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,6 +30,7 @@
import java.io.StringReader;
import javax.xml.catalog.CatalogFeatures.Feature;
+import javax.xml.stream.XMLResolver;
import javax.xml.transform.Source;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
@@ -47,7 +48,7 @@
/*
* @test
- * @bug 8158084 8162438 8162442
+ * @bug 8158084 8162438 8162442 8166220
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport1
* @run testng/othervm catalog.CatalogSupport1
@@ -110,6 +111,15 @@
}
/*
+ Verifies the Catalog support on XMLStreamReader.
+ */
+ @Test(dataProvider = "data_StAXC")
+ public void testStAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
+ String xml, XMLResolver resolver, String expected) throws Exception {
+ testStAX(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
+ }
+
+ /*
Verifies the Catalog support on resolving DTD, xsd import and include in
Schema files.
*/
@@ -190,6 +200,18 @@
}
/*
+ DataProvider: for testing the StAX parser
+ Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
+ */
+ @DataProvider(name = "data_StAXC")
+ public Object[][] getDataStAX() {
+
+ return new Object[][]{
+ {false, true, null, xml_system, null, expectedWCatalog},
+ };
+ }
+
+ /*
DataProvider: for testing Schema validation
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
*/
@@ -218,8 +240,8 @@
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
- StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
- StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
+ StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
+ StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
StreamSource source = new StreamSource(new File(xml_val_test));
@@ -227,8 +249,7 @@
XmlInput[] returnValues = {new XmlInput(null, dtd_system, null), new XmlInput(null, xsd_val_test, null)};
LSResourceResolver resolver = new SourceResolver(null, systemIds, returnValues);
- StAXSource stax2 = getStaxSource(xml_val_test, xml_val_test_id);
- StAXSource stax3 = getStaxSource(xml_val_test, xml_val_test_id);
+ StAXSource stax2 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
return new Object[][]{
// use catalog
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport2.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport2.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,6 +30,8 @@
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
@@ -50,7 +52,7 @@
/*
* @test
- * @bug 8158084 8162438 8162442 8163535
+ * @bug 8158084 8162438 8162442 8163535 8166220
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport2
* @run testng/othervm catalog.CatalogSupport2
@@ -129,6 +131,15 @@
}
/*
+ Verifies the Catalog support on XMLStreamReader.
+ */
+ @Test(dataProvider = "data_StAXC")
+ public void testStAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
+ String xml, XMLResolver resolver, String expected) throws Exception {
+ testStAXNegative(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
+ }
+
+ /*
Verifies the Catalog support on resolving DTD, xsd import and include in
Schema files.
*/
@@ -205,6 +216,17 @@
}
/*
+ DataProvider: for testing the StAX parser
+ Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
+ */
+ @DataProvider(name = "data_StAXC")
+ public Object[][] getDataStAX() {
+ return new Object[][]{
+ {false, true, xml_catalog, xml_system, null, "null"},
+ };
+ }
+
+ /*
DataProvider: for testing Schema validation
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
*/
@@ -233,8 +255,8 @@
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
- StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
- StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
+ StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
+ StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
StreamSource source = new StreamSource(new File(xml_val_test));
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport3.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport3.java Wed Sep 21 09:29:30 2016 -0700
@@ -29,6 +29,8 @@
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
@@ -49,7 +51,7 @@
/*
* @test
- * @bug 8158084 8162438 8162442 8163535
+ * @bug 8158084 8162438 8162442 8163535 8166220
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport3
* @run testng/othervm catalog.CatalogSupport3
@@ -125,6 +127,15 @@
}
/*
+ Verifies the Catalog support on XMLStreamReader.
+ */
+ @Test(dataProvider = "data_StAXC")
+ public void testStAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
+ String xml, XMLResolver resolver, String expected) throws Exception {
+ testStAXNegative(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
+ }
+
+ /*
Verifies the Catalog support on resolving DTD, xsd import and include in
Schema files.
*/
@@ -206,6 +217,17 @@
}
/*
+ DataProvider: for testing the StAX parser
+ Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
+ */
+ @DataProvider(name = "data_StAXC")
+ public Object[][] getDataStAX() {
+ return new Object[][]{
+ {true, false, xml_catalog, xml_system, null, "null"},
+ };
+ }
+
+ /*
DataProvider: for testing Schema validation
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
*/
@@ -234,8 +256,8 @@
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
- StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
- StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
+ StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
+ StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
StreamSource source = new StreamSource(new File(xml_val_test));
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport4.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport4.java Wed Sep 21 09:29:30 2016 -0700
@@ -28,7 +28,7 @@
import java.io.File;
import java.io.StringReader;
-
+import javax.xml.stream.XMLResolver;
import javax.xml.transform.Source;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
@@ -46,7 +46,7 @@
/**
* @test
- * @bug 8158084 8162438 8162442
+ * @bug 8158084 8162438 8162442 8166220
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport4
* @run testng/othervm catalog.CatalogSupport4
@@ -118,6 +118,15 @@
}
/*
+ Verifies the Catalog support on XMLStreamReader.
+ */
+ @Test(dataProvider = "data_StAXA")
+ public void testStAXA(boolean setUseCatalog, boolean useCatalog, String catalog,
+ String xml, XMLResolver resolver, String expected) throws Exception {
+ testStAX(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
+ }
+
+ /*
Verifies the Catalog support on resolving DTD, xsd import and include in
Schema files.
*/
@@ -199,6 +208,18 @@
};
}
+ /*
+ DataProvider: for testing the StAX parser
+ Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
+ */
+ @DataProvider(name = "data_StAXA")
+ public Object[][] getDataStAX() {
+
+ return new Object[][]{
+ {true, true, xml_catalog, xml_system, null, expectedWCatalog},
+ };
+ }
+
MyEntityHandler getMyEntityHandler(String elementName, String[] systemIds, InputSource... returnValues) {
return new MyEntityHandler(systemIds, returnValues, elementName);
}
@@ -230,8 +251,8 @@
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
- StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
- StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
+ StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, true, true, xml_catalog);
+ StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, true, true, xml_catalog);
StreamSource source = new StreamSource(new File(xml_val_test));
@@ -241,8 +262,8 @@
{false, true, true, ds, null, null, null, xml_catalog},
{true, false, true, ss, null, null, xml_catalog, null},
{false, true, true, ss, null, null, null, xml_catalog},
- {true, false, true, stax, null, null, xml_catalog, null},
- {false, true, true, stax1, null, null, null, xml_catalog},
+ {true, false, true, stax, null, null, xml_catalog, xml_catalog},
+ {false, true, true, stax1, null, null, xml_catalog, xml_catalog},
{true, false, true, source, null, null, xml_catalog, null},
{false, true, true, source, null, null, null, xml_catalog},
};
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport5.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport5.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,6 +25,8 @@
import java.io.File;
import java.io.StringReader;
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
@@ -43,7 +45,7 @@
/*
* @test
- * @bug 8158084 8163232
+ * @bug 8158084 8163232 8166220
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport5
* @run testng/othervm catalog.CatalogSupport5
@@ -107,6 +109,15 @@
}
/*
+ Verifies the Catalog support on XMLStreamReader.
+ */
+ @Test(dataProvider = "data_StAXC", expectedExceptions = XMLStreamException.class)
+ public void testStAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
+ String xml, XMLResolver resolver, String expected) throws Exception {
+ testStAX(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
+ }
+
+ /*
Verifies the Catalog support on resolving DTD, xsd import and include in
Schema files.
*/
@@ -183,6 +194,18 @@
}
/*
+ DataProvider: for testing the StAX parser
+ Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
+ */
+ @DataProvider(name = "data_StAXC")
+ public Object[][] getDataStAX() {
+
+ return new Object[][]{
+ {false, true, xml_bogus_catalog, xml_system, null, expectedWCatalog},
+ };
+ }
+
+ /*
DataProvider: for testing Schema validation
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
*/
@@ -211,8 +234,8 @@
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
- StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
- StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
+ StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
+ StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
StreamSource source = new StreamSource(new File(xml_val_test));
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java Wed Sep 21 09:29:30 2016 -0700
@@ -319,6 +319,31 @@
}
/*
+ Verifies the Catalog support on StAX parser.
+ */
+ public void testStAX(boolean setUseCatalog, boolean useCatalog, String catalog,
+ String xml, XMLResolver resolver, String expected) throws Exception {
+
+ XMLStreamReader streamReader = getStreamReader(
+ setUseCatalog, useCatalog, catalog, xml, resolver);
+ String text = getText(streamReader, XMLStreamConstants.CHARACTERS);
+ assertEquals(expected, text.trim(), "Catalog support for StAX");
+ }
+
+ /*
+ Verifies that the Catalog support for StAX parser is disabled when
+ USE_CATALOG == false.
+ */
+ public void testStAXNegative(boolean setUseCatalog, boolean useCatalog, String catalog,
+ String xml, XMLResolver resolver, String expected) throws Exception {
+
+ XMLStreamReader streamReader = getStreamReader(
+ setUseCatalog, useCatalog, catalog, xml, resolver);
+ String text = getText(streamReader, XMLStreamConstants.ENTITY_REFERENCE);
+ assertEquals(expected, text.trim(), "Catalog support for StAX");
+ }
+
+ /*
Verifies the Catalog support on resolving DTD, xsd import and include in
Schema files.
*/
@@ -514,15 +539,24 @@
*
* @param xmlFile the XML source file
* @param xmlFileId the systemId of the source
+ * @param setUseCatalog a flag indicates whether USE_CATALOG shall be set
+ * through the factory
+ * @param useCatalog the value of USE_CATALOG
+ * @param catalog a catalog
* @return a StAXSource
* @throws XMLStreamException
* @throws FileNotFoundException
*/
- StAXSource getStaxSource(String xmlFile, String xmlFileId) {
+ StAXSource getStaxSource(String xmlFile, String xmlFileId, boolean setUseCatalog,
+ boolean useCatalog, String catalog) {
StAXSource ss = null;
try {
- ss = new StAXSource(
- XMLInputFactory.newFactory().createXMLEventReader(
+ XMLInputFactory xif = XMLInputFactory.newFactory();
+ if (setUseCatalog) {
+ xif.setProperty(XMLConstants.USE_CATALOG, useCatalog);
+ }
+ xif.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
+ ss = new StAXSource(xif.createXMLEventReader(
xmlFileId, new FileInputStream(xmlFile)));
} catch (Exception e) {}
@@ -531,6 +565,10 @@
/**
* Creates an XMLStreamReader.
+ *
+ * @param setUseCatalog a flag indicates whether USE_CATALOG shall be set
+ * through the factory
+ * @param useCatalog the value of USE_CATALOG
* @param catalog the path to a catalog
* @param xml the xml to be parsed
* @param resolver a resolver to be set on the reader
@@ -542,9 +580,17 @@
String catalog, String xml, XMLResolver resolver)
throws FileNotFoundException, XMLStreamException {
XMLInputFactory factory = XMLInputFactory.newInstance();
- factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
+ if (catalog != null) {
+ factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
+ }
+
+ factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, true);
factory.setProperty(XMLInputFactory.IS_COALESCING, true);
- factory.setProperty(XMLInputFactory.RESOLVER, resolver);
+
+ if (resolver != null) {
+ factory.setProperty(XMLInputFactory.RESOLVER, resolver);
+ }
+
if (setUseCatalog) {
factory.setProperty(XMLConstants.USE_CATALOG, useCatalog);
}
@@ -560,17 +606,28 @@
* @return the text of the first element
* @throws XMLStreamException
*/
- String getText(XMLStreamReader streamReader) throws XMLStreamException {
+ String getText(XMLStreamReader streamReader, int type) throws XMLStreamException {
+ StringBuilder text = new StringBuilder();
+ StringBuilder entityRef = new StringBuilder();
+
while(streamReader.hasNext()){
- int eventType = streamReader.next() ;
- if(eventType == XMLStreamConstants.START_ELEMENT){
- eventType = streamReader.next() ;
- if(eventType == XMLStreamConstants.CHARACTERS){
- return streamReader.getText() ;
- }
+ int eventType = streamReader.next();
+ switch (eventType) {
+ case XMLStreamConstants.START_ELEMENT:
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ text.append(streamReader.getText());
+ break;
+ case XMLStreamConstants.ENTITY_REFERENCE:
+ entityRef.append(streamReader.getText());
+ break;
}
}
- return null;
+ if (type == XMLStreamConstants.CHARACTERS) {
+ return text.toString();
+ } else {
+ return entityRef.toString();
+ }
}
/**
--- a/jaxws/.hgtags Fri Sep 16 10:57:21 2016 -0700
+++ b/jaxws/.hgtags Wed Sep 21 09:29:30 2016 -0700
@@ -381,3 +381,4 @@
05e99eefda2b58d1ed176e411302d9d6b35dca16 jdk-9+133
ab1d78d395d4cb8be426ff181211da1a4085cf01 jdk-9+134
22631824f55128a7ab6605493b3001a37af6a168 jdk-9+135
+09ec13a99f50a4a346180d1e3b0fd8bc1ee399ce jdk-9+136
--- a/jdk/make/data/currency/CurrencyData.properties Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/make/data/currency/CurrencyData.properties Wed Sep 21 09:29:30 2016 -0700
@@ -32,14 +32,14 @@
# Version of the currency code information in this class.
# It is a serial number that accompanies with each amendment.
-dataVersion=160
+dataVersion=162
# List of all valid ISO 4217 currency codes.
# To ensure compatibility, do not remove codes.
all=ADP020-AED784-AFA004-AFN971-ALL008-AMD051-ANG532-AOA973-ARS032-ATS040-AUD036-\
AWG533-AYM945-AZM031-AZN944-BAM977-BBD052-BDT050-BEF056-BGL100-BGN975-BHD048-BIF108-\
- BMD060-BND096-BOB068-BOV984-BRL986-BSD044-BTN064-BWP072-BYB112-BYR974-\
+ BMD060-BND096-BOB068-BOV984-BRL986-BSD044-BTN064-BWP072-BYB112-BYR974-BYN933-\
BZD084-CAD124-CDF976-CHE947-CHF756-CHW948-CLF990-CLP152-CNY156-COP170-COU970-CRC188-CSD891-CUP192-CUC931-\
CVE132-CYP196-CZK203-DEM276-DJF262-DKK208-DOP214-DZD012-EEK233-EGP818-\
ERN232-ESP724-ETB230-EUR978-FIM246-FJD242-FKP238-FRF250-GBP826-GEL981-\
@@ -119,7 +119,7 @@
# BARBADOS
BB=BBD
# BELARUS
-BY=BYR
+BY=BYN
# BELGIUM
BE=EUR
# BELIZE
--- a/jdk/make/mapfiles/libjpeg/mapfile-vers Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/make/mapfiles/libjpeg/mapfile-vers Wed Sep 21 09:29:30 2016 -0700
@@ -42,6 +42,7 @@
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetReader;
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_disposeReader;
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetLibraryState;
+ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_clearNativeReadAbortFlag;
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initWriterIDs;
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter;
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/aix/native/libjli/java_md_aix.c Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 SAP SE. 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.
+ */
+#include <stdio.h>
+#include <sys/ldr.h>
+
+#include "java_md_aix.h"
+
+static unsigned char dladdr_buffer[0x4000];
+
+static int fill_dll_info(void) {
+ return loadquery(L_GETINFO, dladdr_buffer, sizeof(dladdr_buffer));
+}
+
+static int dladdr_dont_reload(void *addr, Dl_info *info) {
+ const struct ld_info *p = (struct ld_info *)dladdr_buffer;
+ memset((void *)info, 0, sizeof(Dl_info));
+ for (;;) {
+ if (addr >= p->ldinfo_textorg &&
+ addr < (((char*)p->ldinfo_textorg) + p->ldinfo_textsize))
+ {
+ info->dli_fname = p->ldinfo_filename;
+ return 1;
+ }
+ if (!p->ldinfo_next) {
+ break;
+ }
+ p = (struct ld_info *)(((char *)p) + p->ldinfo_next);
+ }
+ return 0;
+}
+
+int dladdr(void *addr, Dl_info *info) {
+ static int loaded = 0;
+ int rc = 0;
+ void *addr0;
+ if (!addr) {
+ return rc;
+ }
+ if (!loaded) {
+ if (fill_dll_info() == -1)
+ return rc;
+ loaded = 1;
+ }
+
+ // first try with addr on cached data
+ rc = dladdr_dont_reload(addr, info);
+
+ // addr could be an AIX function descriptor, so try dereferenced version
+ if (rc == 0) {
+ addr0 = *((void **)addr);
+ rc = dladdr_dont_reload(addr0, info);
+ }
+
+ // if we had no success until now, maybe loadquery info is outdated.
+ // refresh and retry
+ if (rc == 0) {
+ if (fill_dll_info() == -1)
+ return rc;
+ rc = dladdr_dont_reload(addr, info);
+ if (rc == 0) {
+ rc = dladdr_dont_reload(addr0, info);
+ }
+ }
+ return rc;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/aix/native/libjli/java_md_aix.h Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 SAP SE. 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.
+ */
+
+#ifndef JAVA_MD_AIX_H
+#define JAVA_MD_AIX_H
+
+/*
+ * Very limited AIX port of dladdr() for libjli.so.
+ *
+ * We try to mimick dladdr(3) on Linux (see http://linux.die.net/man/3/dladdr)
+ * dladdr(3) is not POSIX but a GNU extension, and is not available on AIX.
+ *
+ * We only support Dl_info.dli_fname here as this is the only thing that is
+ * used of it by libjli.so. A more comprehensive port of dladdr can be found
+ * in the hotspot implementation which is not available at this place, though.
+ */
+
+typedef struct {
+ const char *dli_fname; /* file path of loaded library */
+ void *dli_fbase; /* unsupported */
+ const char *dli_sname; /* unsupported */
+ void *dli_saddr; /* unsupported */
+} Dl_info;
+
+int dladdr(void *addr, Dl_info *info);
+
+#endif /* JAVA_MD_AIX_H */
--- a/jdk/src/java.base/share/classes/java/util/ListResourceBundle.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/ListResourceBundle.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -206,5 +206,5 @@
lookup = temp;
}
- private Map<String,Object> lookup = null;
+ private volatile Map<String,Object> lookup = null;
}
--- a/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,8 +46,6 @@
import java.nio.charset.MalformedInputException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnmappableCharacterException;
-import java.security.AccessController;
-import java.util.Locale;
import sun.security.action.GetPropertyAction;
import sun.util.PropertyResourceBundleCharset;
import sun.util.ResourceBundleEnumeration;
@@ -236,5 +234,5 @@
// ==================privates====================
- private Map<String,Object> lookup;
+ private final Map<String,Object> lookup;
}
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Wed Sep 21 09:29:30 2016 -0700
@@ -103,34 +103,42 @@
# Translators please note do not translate the options themselves
java.launcher.X.usage=\
-\ -Xmixed mixed mode execution (default)\n\
-\ -Xint interpreted mode execution only\n\
+\ -Xbatch disable background compilation\n\
\ -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n\
\ append to end of bootstrap class path\n\
+\ -Xcheck:jni perform additional checks for JNI functions\n\
+\ -Xcomp forces compilation of methods on first invocation\n\
+\ -Xdebug provided for backward compatibility\n\
\ -Xdiag show additional diagnostic messages\n\
\ -Xdiag:resolver show resolver diagnostic messages\n\
-\ -Xnoclassgc disable class garbage collection\n\
+\ -Xdisable-@files disable further argument file expansion\n\
+\ -Xfuture enable strictest checks, anticipating future default\n\
+\ -Xint interpreted mode execution only\n\
+\ -Xinternalversion\n\
+\ displays more detailed JVM version information than the\n\
+\ -version option\n\
\ -Xloggc:<file> log GC status to a file with time stamps\n\
-\ -Xbatch disable background compilation\n\
+\ -Xmixed mixed mode execution (default)\n\
+\ -Xmn<size> sets the initial and maximum size (in bytes) of the heap\n\
+\ for the young generation (nursery)\n\
\ -Xms<size> set initial Java heap size\n\
\ -Xmx<size> set maximum Java heap size\n\
-\ -Xss<size> set java thread stack size\n\
+\ -Xnoclassgc disable class garbage collection\n\
\ -Xprof output cpu profiling data\n\
-\ -Xfuture enable strictest checks, anticipating future default\n\
\ -Xrs reduce use of OS signals by Java/VM (see documentation)\n\
-\ -Xcheck:jni perform additional checks for JNI functions\n\
+\ -Xshare:auto use shared class data if possible (default)\n\
\ -Xshare:off do not attempt to use shared class data\n\
-\ -Xshare:auto use shared class data if possible (default)\n\
\ -Xshare:on require using shared class data, otherwise fail.\n\
\ -XshowSettings show all settings and continue\n\
\ -XshowSettings:all\n\
\ show all settings and continue\n\
-\ -XshowSettings:vm show all vm related settings and continue\n\
+\ -XshowSettings:locale\n\
+\ show all locale related settings and continue\n\
\ -XshowSettings:properties\n\
\ show all property settings and continue\n\
-\ -XshowSettings:locale\n\
-\ show all locale related settings and continue\n\
-\ -Xdisable-@files disable further argument file expansion\n\
+\ -XshowSettings:vm show all vm related settings and continue\n\
+\ -Xss<size> set java thread stack size\n\
+\ -Xverify sets the mode of the bytecode verifier\n\
\ --add-reads <module>=<target-module>(,<target-module>)*\n\
\ updates <module> to read <target-module>, regardless\n\
\ of module declaration. \n\
--- a/jdk/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties Wed Sep 21 09:29:30 2016 -0700
@@ -92,6 +92,7 @@
BTN=BTN
BWP=BWP
BYB=BYB
+BYN=BYN
BYR=BYR
BZD=BZD
CAD=CAD
@@ -310,8 +311,9 @@
bsd=Bahamian Dollar
btn=Bhutanese Ngultrum
bwp=Botswanan Pula
-byb=Belarusian New Ruble (1994-1999)
-byr=Belarusian Ruble
+byb=Belarusian Ruble (1994-1999)
+byn=Belarusian Ruble
+byr=Belarusian Ruble (2000-2016)
bzd=Belize Dollar
cad=Canadian Dollar
cdf=Congolese Franc
@@ -399,7 +401,7 @@
mtl=Maltese Lira
mur=Mauritian Rupee
mvr=Maldivian Rufiyaa
-mwk=Malawian Kwacha
+mwk=Malawian Malawi Kwacha
mxn=Mexican Peso
mxv=Mexican Investment Unit
myr=Malaysian Ringgit
@@ -414,7 +416,7 @@
nzd=New Zealand Dollar
omr=Omani Rial
pab=Panamanian Balboa
-pen=Peruvian Nuevo Sol
+pen=Peruvian Sol
pgk=Papua New Guinean Kina
php=Philippine Peso
pkr=Pakistani Rupee
--- a/jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c Wed Sep 21 09:29:30 2016 -0700
@@ -152,8 +152,8 @@
#ifdef __solaris__
/* These really are the Solaris defaults! */
return (geteuid() == 0 || getuid() == 0) ?
- "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" :
- "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:";
+ "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" :
+ "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:";
#else
return ":/bin:/usr/bin"; /* glibc */
#endif
--- a/jdk/src/java.base/unix/native/libjli/java_md.h Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.base/unix/native/libjli/java_md.h Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, 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
@@ -35,12 +35,12 @@
#include "manifest_info.h"
#include "jli_util.h"
-#define PATH_SEPARATOR ':'
-#define FILESEP "/"
-#define FILE_SEPARATOR '/'
+#define PATH_SEPARATOR ':'
+#define FILESEP "/"
+#define FILE_SEPARATOR '/'
#define IS_FILE_SEPARATOR(c) ((c) == '/')
#ifndef MAXNAMELEN
-#define MAXNAMELEN PATH_MAX
+#define MAXNAMELEN PATH_MAX
#endif
#ifdef _LP64
@@ -59,10 +59,13 @@
static jboolean GetJREPath(char *path, jint pathsize, const char * arch,
jboolean speculative);
+#if defined(_AIX)
+#include "java_md_aix.h"
+#endif
+
#ifdef MACOSX
#include "java_md_macosx.h"
#else /* !MACOSX */
#include "java_md_solinux.h"
#endif /* MACOSX */
-
#endif /* JAVA_MD_H */
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java Wed Sep 21 09:29:30 2016 -0700
@@ -187,6 +187,7 @@
updateAlwaysOnTopState();
updateMinimumSize();
+ updateFocusableWindowState();
final Shape shape = getTarget().getShape();
if (shape != null) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Sep 21 09:29:30 2016 -0700
@@ -63,6 +63,7 @@
private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled);
private static native void nativeSynthesizeMouseEnteredExitedEvents();
+ private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr, int eventType);
private static native void nativeDispose(long nsWindowPtr);
private static native void nativeEnterFullScreenMode(long nsWindowPtr);
private static native void nativeExitFullScreenMode(long nsWindowPtr);
@@ -825,6 +826,13 @@
return;
}
+ if (blocked) {
+ // We are going to show a modal window. Previously displayed window will be
+ // blocked/disabled. So we have to send mouse exited event to it now, since
+ // all mouse events are discarded for blocked/disabled windows.
+ nativeSynthesizeMouseEnteredExitedEvents(getNSWindowPtr(), CocoaConstants.NSMouseExited);
+ }
+
nativeSetEnabled(getNSWindowPtr(), !blocked);
checkBlockingAndOrder();
}
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Wed Sep 21 09:29:30 2016 -0700
@@ -1333,9 +1333,9 @@
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeSynthesizeMouseEnteredExitedEvents
- * Signature: (J)V
+ * Signature: ()V
*/
-JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__
(JNIEnv *env, jclass clazz)
{
JNF_COCOA_ENTER(env);
@@ -1349,6 +1349,29 @@
/*
* Class: sun_lwawt_macosx_CPlatformWindow
+ * Method: nativeSynthesizeMouseEnteredExitedEvents
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__JI
+(JNIEnv *env, jclass clazz, jlong windowPtr, jint eventType)
+{
+JNF_COCOA_ENTER(env);
+
+ if (eventType == NSMouseEntered || eventType == NSMouseExited) {
+ NSWindow *nsWindow = OBJC(windowPtr);
+
+ [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
+ [AWTWindow synthesizeMouseEnteredExitedEvents:nsWindow withType:eventType];
+ }];
+ } else {
+ [JNFException raise:env as:kIllegalArgumentException reason:"unknown event type"];
+ }
+
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPlatformWindow
* Method: _toggleFullScreenMode
* Signature: (J)V
*/
--- a/jdk/src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java Wed Sep 21 09:29:30 2016 -0700
@@ -447,6 +447,7 @@
* @param shape the new 'mixing-cutout' shape
* @throws NullPointerException if the component argument is {@code null}
*/
+ @Deprecated(since = "9")
public static void setComponentMixingCutoutShape(Component component,
Shape shape)
{
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -749,6 +749,10 @@
checkIndex(imageIndex);
clearAbortRequest();
processImageStarted(imageIndex);
+ if (abortRequested()) {
+ processReadAborted();
+ return bi;
+ }
if (param == null)
param = getDefaultReadParam();
@@ -1005,9 +1009,6 @@
int j = isBottomUp ? (height -1)*bytesPerScanline : 0;
for (int i=0; i<height; i++) {
- if (abortRequested()) {
- break;
- }
iis.readFully(bdata, j, bytesPerScanline);
iis.skipBytes(padding);
j += isBottomUp ? -bytesPerScanline : bytesPerScanline;
@@ -1015,6 +1016,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F * i/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
} else {
byte[] buf = new byte[lineLength];
@@ -1051,9 +1055,6 @@
for (int j = 0, y = sourceRegion.y;
j < destinationRegion.height; j++, y+=scaleY) {
-
- if (abortRequested())
- break;
iis.read(buf, 0, lineLength);
for (int i = 0; i < destinationRegion.width; i++) {
//get the bit and assign to the data buffer of the raster
@@ -1067,6 +1068,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F*j/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
}
}
@@ -1087,9 +1091,6 @@
int j = isBottomUp ? (height -1) * bytesPerScanline : 0;
for (int i=0; i<height; i++) {
- if (abortRequested()) {
- break;
- }
iis.readFully(bdata, j, bytesPerScanline);
iis.skipBytes(padding);
j += isBottomUp ? -bytesPerScanline : bytesPerScanline;
@@ -1097,6 +1098,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F * i/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
} else {
byte[] buf = new byte[lineLength];
@@ -1133,9 +1137,6 @@
for (int j = 0, y = sourceRegion.y;
j < destinationRegion.height; j++, y+=scaleY) {
-
- if (abortRequested())
- break;
iis.read(buf, 0, lineLength);
for (int i = 0; i < destinationRegion.width; i++) {
//get the bit and assign to the data buffer of the raster
@@ -1149,6 +1150,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F*j/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
}
}
@@ -1168,9 +1172,6 @@
int j = isBottomUp ? (height -1) * width : 0;
for (int i=0; i<height; i++) {
- if (abortRequested()) {
- break;
- }
iis.readFully(bdata, j, width);
iis.skipBytes(padding);
j += isBottomUp ? -width : width;
@@ -1178,6 +1179,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F * i/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
} else {
byte[] buf = new byte[lineLength];
@@ -1200,9 +1204,6 @@
for (int j = 0, y = sourceRegion.y;
j < destinationRegion.height; j++, y+=scaleY) {
-
- if (abortRequested())
- break;
iis.read(buf, 0, lineLength);
for (int i = 0, m = sourceRegion.x;
i < destinationRegion.width; i++, m += scaleX) {
@@ -1216,6 +1217,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F*j/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
}
}
@@ -1235,9 +1239,6 @@
int j = isBottomUp ? (height -1) * width * 3 : 0;
for (int i=0; i<height; i++) {
- if (abortRequested()) {
- break;
- }
iis.readFully(bdata, j, lineStride);
iis.skipBytes(padding);
j += isBottomUp ? -lineStride : lineStride;
@@ -1245,6 +1246,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F * i/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
} else {
byte[] buf = new byte[lineLength];
@@ -1267,9 +1271,6 @@
for (int j = 0, y = sourceRegion.y;
j < destinationRegion.height; j++, y+=scaleY) {
-
- if (abortRequested())
- break;
iis.read(buf, 0, lineLength);
for (int i = 0, m = 3 * sourceRegion.x;
i < destinationRegion.width; i++, m += 3 * scaleX) {
@@ -1285,6 +1286,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F*j/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
}
}
@@ -1302,10 +1306,6 @@
if (noTransform) {
int j = isBottomUp ? (height -1) * width : 0;
for (int i=0; i<height; i++) {
- if (abortRequested()) {
- break;
- }
-
iis.readFully(sdata, j, width);
iis.skipBytes(padding);
@@ -1314,6 +1314,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F * i/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
} else {
short[] buf = new short[lineLength];
@@ -1336,9 +1339,6 @@
for (int j = 0, y = sourceRegion.y;
j < destinationRegion.height; j++, y+=scaleY) {
-
- if (abortRequested())
- break;
iis.readFully(buf, 0, lineLength);
for (int i = 0, m = sourceRegion.x;
i < destinationRegion.width; i++, m += scaleX) {
@@ -1352,6 +1352,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F*j/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
}
}
@@ -1361,15 +1364,15 @@
int j = isBottomUp ? (height -1) * width : 0;
for (int i=0; i<height; i++) {
- if (abortRequested()) {
- break;
- }
iis.readFully(idata, j, width);
j += isBottomUp ? -width : width;
processImageUpdate(bi, 0, i,
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F * i/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
} else {
int[] buf = new int[width];
@@ -1392,9 +1395,6 @@
for (int j = 0, y = sourceRegion.y;
j < destinationRegion.height; j++, y+=scaleY) {
-
- if (abortRequested())
- break;
iis.readFully(buf, 0, width);
for (int i = 0, m = sourceRegion.x;
i < destinationRegion.width; i++, m += scaleX) {
@@ -1408,6 +1408,9 @@
destinationRegion.width, 1, 1, 1,
new int[]{0});
processImageProgress(100.0F*j/destinationRegion.height);
+ if (abortRequested()) {
+ break;
+ }
}
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -456,6 +456,9 @@
// Update IIOReadProgressListeners
++rowsDone;
processImageProgress(100.0F*rowsDone/height);
+ if (abortRequested()) {
+ return;
+ }
if (decodeThisRow) {
outputRow();
@@ -860,7 +863,6 @@
throw new IndexOutOfBoundsException("imageIndex out of bounds!");
}
- clearAbortRequest();
readMetadata();
// A null ImageReadParam means we use the default
@@ -903,8 +905,13 @@
(streamY - sourceRegion.y)/sourceYSubsampling;
computeDecodeThisRow();
+ clearAbortRequest();
// Inform IIOReadProgressListeners of start of image
processImageStarted(imageIndex);
+ if (abortRequested()) {
+ processReadAborted();
+ return theImage;
+ }
startPass(0);
this.rowBuf = new byte[width];
@@ -947,7 +954,7 @@
int codeSize = initCodeSize + 1;
int codeMask = (1 << codeSize) - 1;
- while (!abortRequested()) {
+ do {
code = getCode(codeSize, codeMask);
if (code == clearCode) {
@@ -1005,7 +1012,7 @@
outputPixels(string, len);
oldCode = code;
- }
+ } while (!abortRequested());
processReadAborted();
return theImage;
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -1327,28 +1327,32 @@
System.out.println("callbackUpdates is " + callbackUpdates);
}
- // Finally, we are ready to read
-
+ /*
+ * All the Jpeg processing happens in native, we should clear
+ * abortFlag of imageIODataStruct in imageioJPEG.c. And we need to
+ * clear abortFlag because if in previous read() if we had called
+ * reader.abort() that will continue to be valid for present call also.
+ */
+ clearNativeReadAbortFlag(structPointer);
processImageStarted(currentImage);
-
- boolean aborted = false;
-
- // Note that getData disables acceleration on buffer, but it is
- // just a 1-line intermediate data transfer buffer that will not
- // affect the acceleration of the resulting image.
- aborted = readImage(structPointer,
- buffer.getData(),
- numRasterBands,
- srcBands,
- bandSizes,
- srcROI.x, srcROI.y,
- srcROI.width, srcROI.height,
- periodX, periodY,
- abbrevQTables,
- abbrevDCHuffmanTables,
- abbrevACHuffmanTables,
- minProgressivePass, maxProgressivePass,
- callbackUpdates);
+ /*
+ * Note that getData disables acceleration on buffer, but it is
+ * just a 1-line intermediate data transfer buffer that will not
+ * affect the acceleration of the resulting image.
+ */
+ boolean aborted = readImage(structPointer,
+ buffer.getData(),
+ numRasterBands,
+ srcBands,
+ bandSizes,
+ srcROI.x, srcROI.y,
+ srcROI.width, srcROI.height,
+ periodX, periodY,
+ abbrevQTables,
+ abbrevDCHuffmanTables,
+ abbrevACHuffmanTables,
+ minProgressivePass, maxProgressivePass,
+ callbackUpdates);
if (aborted) {
processReadAborted();
@@ -1513,6 +1517,12 @@
int maxProgressivePass,
boolean wantUpdates);
+ /*
+ * We should call clearNativeReadAbortFlag() before we start reading
+ * jpeg image as image processing happens at native side.
+ */
+ private native void clearNativeReadAbortFlag(long structPointer);
+
public void abort() {
setThreadLock();
try {
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -937,12 +937,6 @@
for (int srcY = 0; srcY < passHeight; srcY++) {
// Skip filter byte and the remaining row bytes
pixelStream.skipBytes(1 + bytesPerRow);
-
- // If read has been aborted, just return
- // processReadAborted will be called later
- if (abortRequested()) {
- return;
- }
}
}
@@ -996,6 +990,13 @@
for (int srcY = 0; srcY < passHeight; srcY++) {
// Update count of pixels read
updateImageProgress(passWidth);
+ /*
+ * If read has been aborted, just return
+ * processReadAborted will be called later
+ */
+ if (abortRequested()) {
+ return;
+ }
// Skip filter byte and the remaining row bytes
pixelStream.skipBytes(1 + bytesPerRow);
}
@@ -1105,7 +1106,13 @@
for (int srcY = 0; srcY < passHeight; srcY++) {
// Update count of pixels read
updateImageProgress(passWidth);
-
+ /*
+ * If read has been aborted, just return
+ * processReadAborted will be called later
+ */
+ if (abortRequested()) {
+ return;
+ }
// Read the filter type byte and a row of data
int filter = pixelStream.read();
try {
@@ -1195,12 +1202,6 @@
updateWidth, 1,
updateXStep, updateYStep,
destinationBands);
-
- // If read has been aborted, just return
- // processReadAborted will be called later
- if (abortRequested()) {
- return;
- }
}
}
@@ -1215,8 +1216,6 @@
this.pixelsDone = 0;
this.totalPixels = width*height;
- clearAbortRequest();
-
if (metadata.IHDR_interlaceMethod == 0) {
decodePass(0, 0, 0, 1, 1, width, height);
} else {
@@ -1241,8 +1240,10 @@
(height + ybump)/YSubsampling);
}
- // If read has been aborted, just return
- // processReadAborted will be called later
+ /*
+ * If read has been aborted, just return
+ * processReadAborted will be called later
+ */
if (abortRequested()) {
return;
}
@@ -1332,13 +1333,19 @@
inputBandsForColorType[colorType],
theImage.getSampleModel().getNumBands());
+ clearAbortRequest();
processImageStarted(0);
- decodeImage();
if (abortRequested()) {
processReadAborted();
} else {
- processImageComplete();
+ decodeImage();
+ if (abortRequested()) {
+ processReadAborted();
+ } else {
+ processImageComplete();
+ }
}
+
} catch (IOException e) {
throw new IIOException("Error reading PNG image data", e);
} finally {
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDeflateDecompressor.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDeflateDecompressor.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -101,13 +101,17 @@
if (predictor ==
BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING) {
+ int step = planar || samplesPerPixel == 1 ? 1 : samplesPerPixel;
+ int samplesPerRow = step * srcWidth;
+ int off = bufOffset + step;
for (int j = 0; j < srcHeight; j++) {
- int count = bufOffset + samplesPerPixel * (j * srcWidth + 1);
- for (int i=samplesPerPixel; i<srcWidth*samplesPerPixel; i++) {
- buf[count] += buf[count - samplesPerPixel];
+ int count = off;
+ for (int i = step; i < samplesPerRow; i++) {
+ buf[count] += buf[count - step];
count++;
}
+ off += samplesPerRow;
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageReader.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageReader.java Wed Sep 21 09:29:30 2016 -0700
@@ -1131,8 +1131,12 @@
pixelsToRead = destRegion.width * destRegion.height;
pixelsRead = 0;
+ clearAbortRequest();
processImageStarted(imageIndex);
- processImageProgress(0.0f);
+ if (abortRequested()) {
+ processReadAborted();
+ return theImage;
+ }
tilesAcross = (width + tileOrStripWidth - 1) / tileOrStripWidth;
tilesDown = (height + tileOrStripHeight - 1) / tileOrStripHeight;
@@ -1286,6 +1290,10 @@
}
reportProgress();
+ if (abortRequested()) {
+ processReadAborted();
+ return theImage;
+ }
}
}
} else {
@@ -1294,16 +1302,14 @@
decodeTile(ti, tj, -1);
reportProgress();
+ if (abortRequested()) {
+ processReadAborted();
+ return theImage;
+ }
}
}
}
-
- if (abortRequested()) {
- processReadAborted();
- } else {
- processImageComplete();
- }
-
+ processImageComplete();
return theImage;
}
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java Wed Sep 21 09:29:30 2016 -0700
@@ -162,16 +162,18 @@
if (predictor ==
BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING) {
+ int step = planar || samplesPerPixel == 1 ? 1 : samplesPerPixel;
- for (int j = 0; j < srcHeight; j++) {
+ int samplesPerRow = step * srcWidth;
- int count = dstOffset + samplesPerPixel * (j * srcWidth + 1);
-
- for (int i = samplesPerPixel; i < srcWidth * samplesPerPixel; i++) {
-
- dstData[count] += dstData[count - samplesPerPixel];
+ int off = dstOffset + step;
+ for (int j = 0; j < srcHeight; j++) {
+ int count = off;
+ for (int i = step; i < samplesPerRow; i++) {
+ dstData[count] += dstData[count - step];
count++;
}
+ off += samplesPerRow;
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java Wed Sep 21 09:29:30 2016 -0700
@@ -504,7 +504,7 @@
public Object createValue(UIDefaults table) {
GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory();
GTKStyle style = (GTKStyle)factory.getStyle(null, region);
- return style.getFontForState(null);
+ return style.getDefaultFont();
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java Wed Sep 21 09:29:30 2016 -0700
@@ -282,7 +282,17 @@
return getColorForState(context, type);
}
+ Font getDefaultFont() {
+ return font;
+ }
+
protected Font getFontForState(SynthContext context) {
+ Font propFont = UIManager
+ .getFont(context.getRegion().getName() + ".font");
+ if (propFont != null) {
+ // if font property got a value then return it
+ return propFont;
+ }
return font;
}
--- a/jdk/src/java.desktop/share/classes/java/awt/Component.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java Wed Sep 21 09:29:30 2016 -0700
@@ -843,32 +843,7 @@
return new Rectangle(comp.x, comp.y, comp.width, comp.height);
}
public void setMixingCutoutShape(Component comp, Shape shape) {
- Region region = shape == null ? null :
- Region.getInstance(shape, null);
-
- synchronized (comp.getTreeLock()) {
- boolean needShowing = false;
- boolean needHiding = false;
-
- if (!comp.isNonOpaqueForMixing()) {
- needHiding = true;
- }
-
- comp.mixingCutoutRegion = region;
-
- if (!comp.isNonOpaqueForMixing()) {
- needShowing = true;
- }
-
- if (comp.isMixingNeeded()) {
- if (needHiding) {
- comp.mixOnHiding(comp.isLightweight());
- }
- if (needShowing) {
- comp.mixOnShowing();
- }
- }
- }
+ comp.setMixingCutoutShape(shape);
}
public void setGraphicsConfiguration(Component comp,
@@ -10238,6 +10213,71 @@
return true;
}
+ /**
+ * Sets a 'mixing-cutout' shape for the given component.
+ *
+ * By default a lightweight component is treated as an opaque rectangle for
+ * the purposes of the Heavyweight/Lightweight Components Mixing feature.
+ * This method enables developers to set an arbitrary shape to be cut out
+ * from heavyweight components positioned underneath the lightweight
+ * component in the z-order.
+ * <p>
+ * The {@code shape} argument may have the following values:
+ * <ul>
+ * <li>{@code null} - reverts the default cutout shape (the rectangle equal
+ * to the component's {@code getBounds()})
+ * <li><i>empty-shape</i> - does not cut out anything from heavyweight
+ * components. This makes the given lightweight component effectively
+ * transparent. Note that descendants of the lightweight component still
+ * affect the shapes of heavyweight components. An example of an
+ * <i>empty-shape</i> is {@code new Rectangle()}.
+ * <li><i>non-empty-shape</i> - the given shape will be cut out from
+ * heavyweight components.
+ * </ul>
+ * <p>
+ * The most common example when the 'mixing-cutout' shape is needed is a
+ * glass pane component. The {@link JRootPane#setGlassPane()} method
+ * automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape
+ * for the given glass pane component. If a developer needs some other
+ * 'mixing-cutout' shape for the glass pane (which is rare), this must be
+ * changed manually after installing the glass pane to the root pane.
+ * <p>
+ * Note that the 'mixing-cutout' shape neither affects painting, nor the
+ * mouse events handling for the given component. It is used exclusively
+ * for the purposes of the Heavyweight/Lightweight Components Mixing
+ * feature.
+ *
+ * @param shape the new 'mixing-cutout' shape
+ * @since 9
+ */
+ void setMixingCutoutShape(Shape shape) {
+ Region region = shape == null ? null : Region.getInstance(shape, null);
+
+ synchronized (getTreeLock()) {
+ boolean needShowing = false;
+ boolean needHiding = false;
+
+ if (!isNonOpaqueForMixing()) {
+ needHiding = true;
+ }
+
+ mixingCutoutRegion = region;
+
+ if (!isNonOpaqueForMixing()) {
+ needShowing = true;
+ }
+
+ if (isMixingNeeded()) {
+ if (needHiding) {
+ mixOnHiding(isLightweight());
+ }
+ if (needShowing) {
+ mixOnShowing();
+ }
+ }
+ }
+ }
+
// ****************** END OF MIXING CODE ********************************
// Note that the method is overriden in the Window class,
--- a/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java Wed Sep 21 09:29:30 2016 -0700
@@ -273,9 +273,7 @@
}
/**
- * Requests user attention to the specified window until it is activated.
- *
- * On an already active window requesting attention does nothing.
+ * Requests user attention to the specified window.
*
* @param w window
* @throws SecurityException if a security manager exists and it denies the
--- a/jdk/src/java.desktop/share/classes/java/awt/Toolkit.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/Toolkit.java Wed Sep 21 09:29:30 2016 -0700
@@ -208,7 +208,7 @@
/**
* Returns whether dynamic layout of Containers on resize is currently
- * enabled on the underlying operating system and/or window manager). If the
+ * enabled on the underlying operating system and/or window manager. If the
* platform supports it, {@code setDynamicLayout(boolean)} may be used to
* programmatically enable or disable platform dynamic layout. Regardless of
* whether that toggling is supported, or whether {@code true} or {@code
--- a/jdk/src/java.desktop/share/classes/java/awt/peer/TaskbarPeer.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/peer/TaskbarPeer.java Wed Sep 21 09:29:30 2016 -0700
@@ -49,9 +49,7 @@
default void requestUserAttention(boolean enabled, final boolean critical) {}
/**
- * Requests user attention to the specified window until it is activated.
- *
- * On an already active window requesting attention does nothing.
+ * Requests user attention to the specified window.
*
* @param w window
*/
--- a/jdk/src/java.desktop/share/classes/javax/swing/SortingFocusTraversalPolicy.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/SortingFocusTraversalPolicy.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -26,15 +26,11 @@
import java.awt.Component;
import java.awt.Container;
-import java.awt.Window;
import java.util.*;
import java.awt.FocusTraversalPolicy;
import sun.util.logging.PlatformLogger;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import sun.security.action.GetPropertyAction;
import java.security.AccessController;
-import java.security.PrivilegedAction;
/**
* A FocusTraversalPolicy that determines traversal order by sorting the
@@ -100,27 +96,10 @@
* See: JDK-8048887
*/
private static final boolean legacySortingFTPEnabled;
- private static final Method legacyMergeSortMethod;
static {
legacySortingFTPEnabled = "true".equals(AccessController.doPrivileged(
new GetPropertyAction("swing.legacySortingFTPEnabled", "true")));
- legacyMergeSortMethod = legacySortingFTPEnabled ?
- AccessController.doPrivileged(new PrivilegedAction<Method>() {
- public Method run() {
- try {
- Method m = java.util.Arrays.class.getDeclaredMethod("legacyMergeSort",
- new Class<?>[]{Object[].class,
- Comparator.class});
- m.setAccessible(true);
- return m;
- } catch (NoSuchMethodException e) {
- // using default sorting algo
- return null;
- }
- }
- }) :
- null;
}
/**
@@ -169,30 +148,25 @@
private void enumerateAndSortCycle(Container focusCycleRoot, List<Component> cycle) {
if (focusCycleRoot.isShowing()) {
enumerateCycle(focusCycleRoot, cycle);
- if (!legacySortingFTPEnabled ||
- !legacySort(cycle, comparator))
- {
- Collections.sort(cycle, comparator);
+ if (legacySortingFTPEnabled) {
+ legacySort(cycle, comparator);
+ } else {
+ cycle.sort(comparator);
}
}
}
- private boolean legacySort(List<Component> l, Comparator<? super Component> c) {
- if (legacyMergeSortMethod == null)
- return false;
-
- Object[] a = l.toArray();
- try {
- legacyMergeSortMethod.invoke(null, a, c);
- } catch (IllegalAccessException | InvocationTargetException e) {
- return false;
+ private void legacySort(List<Component> l,
+ Comparator<? super Component> c) {
+ if (c != null && l.size() > 1) {
+ Component[] a = l.toArray(new Component[l.size()]);
+ mergeSort(a.clone(), a, 0, a.length, 0, c);
+ ListIterator<Component> i = l.listIterator();
+ for (Component e : a) {
+ i.next();
+ i.set(e);
+ }
}
- ListIterator<Component> i = l.listIterator();
- for (Object e : a) {
- i.next();
- i.set((Component)e);
- }
- return true;
}
@SuppressWarnings("deprecation")
@@ -665,6 +639,48 @@
protected boolean accept(Component aComponent) {
return fitnessTestPolicy.accept(aComponent);
}
+
+ // merge sort implementation copied from java.utils.Arrays
+ private <T> void mergeSort(T[] src, T[] dest,
+ int low, int high, int off,
+ Comparator<? super T> c) {
+ int length = high - low;
+
+ // Insertion sort on smallest arrays
+ if (length < 7) {
+ for (int i=low; i<high; i++)
+ for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--) {
+ T t = dest[j];
+ dest[j] = dest[j-1];
+ dest[j-1] = t;
+ }
+ return;
+ }
+
+ // Recursively sort halves of dest into src
+ int destLow = low;
+ int destHigh = high;
+ low += off;
+ high += off;
+ int mid = (low + high) >>> 1;
+ mergeSort(dest, src, low, mid, -off, c);
+ mergeSort(dest, src, mid, high, -off, c);
+
+ // If list is already sorted, just copy from src to dest. This is an
+ // optimization that results in faster sorts for nearly ordered lists.
+ if (c.compare(src[mid-1], src[mid]) <= 0) {
+ System.arraycopy(src, low, dest, destLow, length);
+ return;
+ }
+
+ // Merge sorted halves (now in src) into dest
+ for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
+ if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
+ dest[i] = src[p++];
+ else
+ dest[i] = src[q++];
+ }
+ }
}
// Create our own subclass and change accept to public so that we can call
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSliderUI.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSliderUI.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1603,13 +1603,18 @@
blockIncrement = 1;
}
+ int tickSpacing = getTickSpacing();
if (slider.getSnapToTicks()) {
- int tickSpacing = getTickSpacing();
if (blockIncrement < tickSpacing) {
blockIncrement = tickSpacing;
}
}
+ else {
+ if (tickSpacing > 0) {
+ blockIncrement = tickSpacing;
+ }
+ }
int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL);
slider.setValue(slider.getValue() + delta);
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Wed Sep 21 09:29:30 2016 -0700
@@ -391,21 +391,8 @@
}
private Icon getRolloverIcon(AbstractButton b, Icon defaultIcon) {
- ButtonModel model = b.getModel();
- Icon icon = null;
- if (model.isSelected()) {
- icon = getIcon(b, b.getRolloverSelectedIcon(), null,
- SynthConstants.MOUSE_OVER | SynthConstants.SELECTED);
- if (icon == null) {
- icon = getIcon(b, b.getSelectedIcon(), null,
- SynthConstants.SELECTED);
- }
- }
- if (icon == null) {
- icon = getIcon(b, b.getRolloverIcon(), defaultIcon,
- SynthConstants.MOUSE_OVER);
- }
- return icon;
+ return getSpecificIcon(b, b.getRolloverSelectedIcon(), b.getRolloverIcon(),
+ defaultIcon, SynthConstants.MOUSE_OVER);
}
private Icon getPressedIcon(AbstractButton b, Icon defaultIcon) {
@@ -414,21 +401,44 @@
}
private Icon getSynthDisabledIcon(AbstractButton b, Icon defaultIcon) {
- ButtonModel model = b.getModel();
+ return getSpecificIcon(b, b.getDisabledSelectedIcon(), b.getDisabledIcon(),
+ defaultIcon, SynthConstants.DISABLED);
+ }
+
+ private Icon getSpecificIcon(AbstractButton b, Icon specificSelectedIcon,
+ Icon specificIcon, Icon defaultIcon,
+ int state) {
+ boolean selected = b.getModel().isSelected();
Icon icon = null;
- if (model.isSelected()) {
- icon = getIcon(b, b.getDisabledSelectedIcon(), null,
- SynthConstants.DISABLED | SynthConstants.SELECTED);
+
+ if (selected) {
+ icon = specificSelectedIcon;
if (icon == null) {
- icon = getIcon(b, b.getSelectedIcon(), null,
- SynthConstants.SELECTED);
+ icon = b.getSelectedIcon();
}
}
+
if (icon == null) {
- icon = getIcon(b, b.getDisabledIcon(), defaultIcon,
- SynthConstants.DISABLED);
+ icon = specificIcon;
+ }
+
+ if (icon != null) {
+ return icon;
}
- return icon;
+
+ if (defaultIcon == null || defaultIcon instanceof UIResource) {
+ if (selected) {
+ icon = getSynthIcon(b, state | SynthConstants.SELECTED);
+ if (icon == null) {
+ icon = getSynthIcon(b, SynthConstants.SELECTED);
+ }
+ }
+ if (icon == null) {
+ icon = getSynthIcon(b, state);
+ }
+ }
+
+ return icon != null ? icon : defaultIcon;
}
/**
--- a/jdk/src/java.desktop/share/classes/sun/font/ExtendedTextSourceLabel.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/font/ExtendedTextSourceLabel.java Wed Sep 21 09:29:30 2016 -0700
@@ -550,13 +550,16 @@
return charinfo;
}
+ private static final boolean DEBUG = FontUtilities.debugFonts();
/*
* This takes the glyph info record obtained from the glyph vector and converts it into a similar record
* adjusted to represent character data instead. For economy we don't use glyph info records in this processing.
*
* Here are some constraints:
* - there can be more glyphs than characters (glyph insertion, perhaps based on normalization, has taken place)
-* - there can not be fewer glyphs than characters (0xffff glyphs are inserted for characters ligaturized away)
+* - there can be fewer glyphs than characters
+* Some layout engines may insert 0xffff glyphs for characters ligaturized away, but
+* not all do, and it cannot be relied upon.
* - each glyph maps to a single character, when multiple glyphs exist for a character they all map to it, but
* no two characters map to the same glyph
* - multiple glyphs mapping to the same character need not be in sequence (thai, tamil have split characters)
@@ -578,7 +581,8 @@
*
* The algorithm works in the following way:
* 1) we scan the glyphs ltr or rtl based on the bidi run direction
-* 2) we can work in place, since we always consume a glyph for each char we write
+* 2) Since the may be fewer glyphs than chars we cannot work in place.
+* A new array is allocated for output.
* a) if the line is ltr, we start writing at position 0 until we finish, there may be leftver space
* b) if the line is rtl and 1-1, we start writing at position numChars/glyphs - 1 until we finish at 0
* c) otherwise if we don't finish at 0, we have to copy the data down
@@ -594,7 +598,7 @@
* iii) the x advance is the distance to the maximum x + adv of all glyphs whose advance is not zero
* iv) the y advance is the baseline
* v) vis x,y,w,h tightly encloses the vis x,y,w,h of all the glyphs with nonzero w and h
-* 4) we can make some simple optimizations if we know some things:
+* 4) In the future, we can make some simple optimizations to avoid copying if we know some things:
* a) if the mapping is 1-1, unidirectional, and there are no zero-adv glyphs, we just return the glyphinfo
* b) if the mapping is 1-1, unidirectional, we just adjust the remaining glyphs to originate at right/left of the base
* c) if the mapping is 1-1, we compute the base position and advance as we go, then go back to adjust the remaining glyphs
@@ -625,23 +629,20 @@
System.out.println(source);
}
- /*
- if ((gv.getDescriptionFlags() & 0x7) == 0) {
- return glyphinfo;
- }
- */
-
int numGlyphs = gv.getNumGlyphs();
if (numGlyphs == 0) {
return glyphinfo;
}
int[] indices = gv.getGlyphCharIndices(0, numGlyphs, null);
+ float[] charInfo = new float[source.getLength() * numvals];
- boolean DEBUG = false;
if (DEBUG) {
System.err.println("number of glyphs: " + numGlyphs);
+ System.err.println("glyphinfo.len: " + glyphinfo.length);
+ System.err.println("indices.len: " + indices.length);
for (int i = 0; i < numGlyphs; ++i) {
System.err.println("g: " + i +
+ " v: " + gv.getGlyphCode(i) +
", x: " + glyphinfo[i*numvals+posx] +
", a: " + glyphinfo[i*numvals+advx] +
", n: " + indices[i]);
@@ -650,22 +651,19 @@
int minIndex = indices[0]; // smallest index seen this cluster
int maxIndex = minIndex; // largest index seen this cluster
- int nextMin = 0; // expected smallest index for this cluster
int cp = 0; // character position
- int cx = 0; // character index (logical)
+ int cc = 0;
int gp = 0; // glyph position
int gx = 0; // glyph index (visual)
int gxlimit = numGlyphs; // limit of gx, when we reach this we're done
int pdelta = numvals; // delta for incrementing positions
int xdelta = 1; // delta for incrementing indices
- boolean ltr = (source.getLayoutFlags() & 0x1) == 0;
- if (!ltr) {
+ boolean rtl = (source.getLayoutFlags() & 0x1) == 1;
+ if (rtl) {
minIndex = indices[numGlyphs - 1];
maxIndex = minIndex;
- nextMin = 0; // still logical
- cp = glyphinfo.length - numvals;
- cx = 0; // still logical
+ cp = charInfo.length - numvals;
gp = glyphinfo.length - numvals;
gx = numGlyphs - 1;
gxlimit = -1;
@@ -693,47 +691,36 @@
float cposl = 0, cposr = 0, cvisl = 0, cvist = 0, cvisr = 0, cvisb = 0;
float baseline = 0;
- // record if we have to copy data even when no cluster
- boolean mustCopy = false;
-
while (gx != gxlimit) {
// start of new cluster
- boolean haveCopy = false;
int clusterExtraGlyphs = 0;
minIndex = indices[gx];
maxIndex = minIndex;
+ cposl = glyphinfo[gp + posx];
+ cposr = cposl + glyphinfo[gp + advx];
+ cvisl = glyphinfo[gp + visx];
+ cvist = glyphinfo[gp + visy];
+ cvisr = cvisl + glyphinfo[gp + visw];
+ cvisb = cvist + glyphinfo[gp + vish];
+
// advance to next glyph
gx += xdelta;
gp += pdelta;
- /*
- while (gx != gxlimit && (glyphinfo[gp + advx] == 0 ||
- minIndex != nextMin || indices[gx] <= maxIndex)) {
- */
while (gx != gxlimit &&
((glyphinfo[gp + advx] == 0) ||
- (minIndex != nextMin) ||
(indices[gx] <= maxIndex) ||
(maxIndex - minIndex > clusterExtraGlyphs))) {
- // initialize base data first time through, using base glyph
- if (!haveCopy) {
- int gps = gp - pdelta;
- cposl = glyphinfo[gps + posx];
- cposr = cposl + glyphinfo[gps + advx];
- cvisl = glyphinfo[gps + visx];
- cvist = glyphinfo[gps + visy];
- cvisr = cvisl + glyphinfo[gps + visw];
- cvisb = cvist + glyphinfo[gps + vish];
-
- haveCopy = true;
+ ++clusterExtraGlyphs; // have an extra glyph in this cluster
+ if (DEBUG) {
+ System.err.println("gp=" +gp +" adv=" + glyphinfo[gp + advx] +
+ " gx="+ gx+ " i[gx]="+indices[gx] +
+ " clusterExtraGlyphs="+clusterExtraGlyphs);
}
- // have an extra glyph in this cluster
- ++clusterExtraGlyphs;
-
// adjust advance only if new glyph has non-zero advance
float radvx = glyphinfo[gp + advx];
if (radvx != 0) {
@@ -764,110 +751,90 @@
// done with cluster, gx and gp are set for next glyph
if (DEBUG) {
- System.out.println("minIndex = " + minIndex + ", maxIndex = " + maxIndex);
+ System.err.println("minIndex = " + minIndex + ", maxIndex = " + maxIndex);
}
- nextMin = maxIndex + 1;
-
- // do common character adjustments
- glyphinfo[cp + posy] = baseline;
- glyphinfo[cp + advy] = 0;
+ // save adjustments to the base character and do common adjustments.
+ charInfo[cp + posx] = cposl;
+ charInfo[cp + posy] = baseline;
+ charInfo[cp + advx] = cposr - cposl;
+ charInfo[cp + advy] = 0;
+ charInfo[cp + visx] = cvisl;
+ charInfo[cp + visy] = cvist;
+ charInfo[cp + visw] = cvisr - cvisl;
+ charInfo[cp + vish] = cvisb - cvist;
+ cc++;
- if (haveCopy) {
- // save adjustments to the base character
- glyphinfo[cp + posx] = cposl;
- glyphinfo[cp + advx] = cposr - cposl;
- glyphinfo[cp + visx] = cvisl;
- glyphinfo[cp + visy] = cvist;
- glyphinfo[cp + visw] = cvisr - cvisl;
- glyphinfo[cp + vish] = cvisb - cvist;
+ /* We may have consumed multiple glyphs for this char position.
+ * Map those extra consumed glyphs to char positions that would follow
+ * up to the index prior to that which begins the next cluster.
+ * If we have reached the last glyph (reached gxlimit) then we need to
+ * map remaining unmapped chars to the same location as the last one.
+ */
+ int tgt;
+ if (gx == gxlimit) {
+ tgt = charInfo.length / numvals;
+ } else {
+ tgt = indices[gx]-1;
+ }
+ if (DEBUG) {
+ System.err.println("gx=" + gx + " gxlimit=" + gxlimit +
+ " charInfo.len=" + charInfo.length +
+ " tgt=" + tgt + " cc=" + cc + " cp=" + cp);
+ }
+ while (cc < tgt) {
+ if (rtl) {
+ // if rtl, characters to left of base, else to right. reuse cposr.
+ cposr = cposl;
+ }
+ cvisr -= cvisl; // reuse, convert to deltas.
+ cvisb -= cvist;
- // compare number of chars read with number of glyphs read.
- // if more glyphs than chars, set mustCopy to true, as we'll always have
- // to copy the data from here on out.
- if (maxIndex - minIndex < clusterExtraGlyphs) {
- mustCopy = true;
+ cp += pdelta;
+
+ if (cp < 0 || cp >= charInfo.length) {
+ if (DEBUG) {
+ System.err.println("Error : cp=" + cp +
+ " charInfo.length=" + charInfo.length);
+ }
+ break;
}
- // Fix the characters that follow the base character.
- // New values are all the same. Note we fix the number of characters
- // we saw, not the number of glyphs we saw.
- if (minIndex < maxIndex) {
- if (!ltr) {
- // if rtl, characters to left of base, else to right. reuse cposr.
- cposr = cposl;
- }
- cvisr -= cvisl; // reuse, convert to deltas.
- cvisb -= cvist;
-
- int iMinIndex = minIndex, icp = cp / 8;
-
- while (minIndex < maxIndex) {
- ++minIndex;
- cx += xdelta;
- cp += pdelta;
-
- if (cp < 0 || cp >= glyphinfo.length) {
- if (DEBUG) System.out.println("minIndex = " + iMinIndex + ", maxIndex = " + maxIndex + ", cp = " + icp);
- }
-
- glyphinfo[cp + posx] = cposr;
- glyphinfo[cp + posy] = baseline;
- glyphinfo[cp + advx] = 0;
- glyphinfo[cp + advy] = 0;
- glyphinfo[cp + visx] = cvisl;
- glyphinfo[cp + visy] = cvist;
- glyphinfo[cp + visw] = cvisr;
- glyphinfo[cp + vish] = cvisb;
- }
+ if (DEBUG) {
+ System.err.println("Insert charIndex " + cc + " at pos="+cp);
}
-
- // no longer using this copy
- haveCopy = false;
- } else if (mustCopy) {
- // out of synch, so we have to copy all the time now
- int gpr = gp - pdelta;
-
- glyphinfo[cp + posx] = glyphinfo[gpr + posx];
- glyphinfo[cp + advx] = glyphinfo[gpr + advx];
- glyphinfo[cp + visx] = glyphinfo[gpr + visx];
- glyphinfo[cp + visy] = glyphinfo[gpr + visy];
- glyphinfo[cp + visw] = glyphinfo[gpr + visw];
- glyphinfo[cp + vish] = glyphinfo[gpr + vish];
+ charInfo[cp + posx] = cposr;
+ charInfo[cp + posy] = baseline;
+ charInfo[cp + advx] = 0;
+ charInfo[cp + advy] = 0;
+ charInfo[cp + visx] = cvisl;
+ charInfo[cp + visy] = cvist;
+ charInfo[cp + visw] = cvisr;
+ charInfo[cp + vish] = cvisb;
+ cc++;
}
- // else glyphinfo is already at the correct character position, and is unchanged, so just leave it
-
- // reset for new cluster
- cp += pdelta;
- cx += xdelta;
- }
-
- if (mustCopy && !ltr) {
- // data written to wrong end of array, need to shift down
-
- cp -= pdelta; // undo last increment, get start of valid character data in array
- System.arraycopy(glyphinfo, cp, glyphinfo, 0, glyphinfo.length - cp);
+ cp += pdelta; // reset for new cluster
}
if (DEBUG) {
- char[] chars = source.getChars();
- int start = source.getStart();
- int length = source.getLength();
- System.out.println("char info for " + length + " characters");
- for(int i = 0; i < length * numvals;) {
- System.out.println(" ch: " + Integer.toHexString(chars[start + v2l(i / numvals)]) +
- " x: " + glyphinfo[i++] +
- " y: " + glyphinfo[i++] +
- " xa: " + glyphinfo[i++] +
- " ya: " + glyphinfo[i++] +
- " l: " + glyphinfo[i++] +
- " t: " + glyphinfo[i++] +
- " w: " + glyphinfo[i++] +
- " h: " + glyphinfo[i++]);
+ char[] chars = source.getChars();
+ int start = source.getStart();
+ int length = source.getLength();
+ System.err.println("char info for " + length + " characters");
+
+ for (int i = 0; i < length * numvals;) {
+ System.err.println(" ch: " + Integer.toHexString(chars[start + v2l(i / numvals)]) +
+ " x: " + charInfo[i++] +
+ " y: " + charInfo[i++] +
+ " xa: " + charInfo[i++] +
+ " ya: " + charInfo[i++] +
+ " l: " + charInfo[i++] +
+ " t: " + charInfo[i++] +
+ " w: " + charInfo[i++] +
+ " h: " + charInfo[i++]);
}
}
-
- return glyphinfo;
+ return charInfo;
}
/**
--- a/jdk/src/java.desktop/share/classes/sun/print/DialogOwner.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/print/DialogOwner.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,9 +25,11 @@
package sun.print;
+import java.awt.Dialog;
import javax.print.attribute.Attribute;
import javax.print.attribute.PrintRequestAttribute;
import java.awt.Frame;
+import java.awt.Window;
/**
* Class DialogOwner is a printing attribute class that identifies
@@ -42,7 +44,7 @@
public final class DialogOwner
implements PrintRequestAttribute {
- private Frame dlgOwner;
+ private Window dlgOwner;
/**
* Construct a new dialog owner attribute with the given frame.
@@ -53,11 +55,19 @@
dlgOwner = frame;
}
+ /**
+ * Construct a new dialog owner attribute with the given dialog.
+ *
+ * @param dialog the dialog that owns the print dialog
+ */
+ public DialogOwner(Dialog dialog) {
+ dlgOwner = dialog;
+ }
/**
* Returns the string table for class DialogOwner.
*/
- public Frame getOwner() {
+ public Window getOwner() {
return dlgOwner;
}
--- a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java Wed Sep 21 09:29:30 2016 -0700
@@ -30,7 +30,6 @@
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Frame;
-import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
@@ -39,7 +38,6 @@
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
@@ -55,7 +53,6 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.Locale;
import sun.awt.image.ByteInterleavedRaster;
@@ -74,7 +71,6 @@
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.ResolutionSyntax;
import javax.print.attribute.Size2DSyntax;
-import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.DialogTypeSelection;
@@ -96,11 +92,6 @@
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;
-import sun.print.PageableDoc;
-import sun.print.ServiceDialog;
-import sun.print.SunPrinterJobService;
-import sun.print.SunPageSelection;
-
/**
* A class which rasterizes a printer job.
*
@@ -836,9 +827,16 @@
Rectangle gcBounds = gc.getBounds();
int x = gcBounds.x+50;
int y = gcBounds.y+50;
- ServiceDialog pageDialog = new ServiceDialog(gc, x, y, service,
- DocFlavor.SERVICE_FORMATTED.PAGEABLE,
- attributes, (Frame)null);
+ ServiceDialog pageDialog;
+ if (w instanceof Frame) {
+ pageDialog = new ServiceDialog(gc, x, y, service,
+ DocFlavor.SERVICE_FORMATTED.PAGEABLE,
+ attributes,(Frame)w);
+ } else {
+ pageDialog = new ServiceDialog(gc, x, y, service,
+ DocFlavor.SERVICE_FORMATTED.PAGEABLE,
+ attributes, (Dialog)w);
+ }
Rectangle dlgBounds = pageDialog.getBounds();
// if portion of dialog is not within the gc boundary
@@ -944,6 +942,14 @@
Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
if (w != null) {
grCfg = w.getGraphicsConfiguration();
+ /* Add DialogOwner attribute to set the owner of this print dialog
+ * only if it is not set already
+ * (it might be set in java.awt.PrintJob.printDialog)
+ */
+ if (attributes.get(DialogOwner.class) == null) {
+ attributes.add(w instanceof Frame ? new DialogOwner((Frame)w) :
+ new DialogOwner((Dialog)w));
+ }
} else {
grCfg = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
@@ -1001,6 +1007,10 @@
// temporarily add an attribute pointing back to this job.
PrinterJobWrapper jobWrapper = new PrinterJobWrapper(this);
attributes.add(jobWrapper);
+ PageRanges pgRng = (PageRanges)attributes.get(PageRanges.class);
+ if (pgRng == null && mDocument.getNumberOfPages() > 1) {
+ attributes.add(new PageRanges(1, mDocument.getNumberOfPages()));
+ }
try {
newService =
ServiceUI.printDialog(gc, x, y,
@@ -1014,6 +1024,7 @@
attributes);
}
attributes.remove(PrinterJobWrapper.class);
+ attributes.remove(DialogOwner.class);
if (newService == null) {
return false;
--- a/jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/swing/CachedPainter.java Wed Sep 21 09:29:30 2016 -0700
@@ -107,13 +107,16 @@
ImageCache cache = getCache(key);
Image image = cache.getImage(key, config, w, h, args);
int attempts = 0;
+ VolatileImage volatileImage = (image instanceof VolatileImage)
+ ? (VolatileImage) image
+ : null;
do {
boolean draw = false;
- if (image instanceof VolatileImage) {
+ if (volatileImage != null) {
// See if we need to recreate the image
- switch (((VolatileImage)image).validate(config)) {
+ switch (volatileImage.validate(config)) {
case VolatileImage.IMAGE_INCOMPATIBLE:
- ((VolatileImage)image).flush();
+ volatileImage.flush();
image = null;
break;
case VolatileImage.IMAGE_RESTORED:
@@ -126,11 +129,14 @@
image = createImage(c, w, h, config, args);
cache.setImage(key, config, w, h, args, image);
draw = true;
+ volatileImage = (image instanceof VolatileImage)
+ ? (VolatileImage) image
+ : null;
}
if (draw) {
// Render to the Image
Graphics2D g2 = (Graphics2D) image.getGraphics();
- if (w != baseWidth || h != baseHeight) {
+ if (volatileImage == null && (w != baseWidth || h != baseHeight)) {
g2.scale((double) w / baseWidth, (double) h / baseHeight);
}
paintToImage(c, image, g2, baseWidth, baseHeight, args);
@@ -140,8 +146,8 @@
// If we did this 3 times and the contents are still lost
// assume we're painting to a VolatileImage that is bogus and
// give up. Presumably we'll be called again to paint.
- } while ((image instanceof VolatileImage) &&
- ((VolatileImage)image).contentsLost() && ++attempts < 3);
+ } while ((volatileImage != null) &&
+ volatileImage.contentsLost() && ++attempts < 3);
return image;
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c Wed Sep 21 09:29:30 2016 -0700
@@ -40,6 +40,7 @@
static jfieldID gvdGlyphsFID = 0;
static jfieldID gvdPositionsFID = 0;
static jfieldID gvdIndicesFID = 0;
+static jmethodID gvdGrowMID = 0;
static int jniInited = 0;
static void getFloat(JNIEnv* env, jobject pt, jfloat *x, jfloat *y) {
@@ -63,73 +64,88 @@
CHECK_NULL_RETURN(gvdGlyphsFID = (*env)->GetFieldID(env, gvdClass, "_glyphs", "[I"), 0);
CHECK_NULL_RETURN(gvdPositionsFID = (*env)->GetFieldID(env, gvdClass, "_positions", "[F"), 0);
CHECK_NULL_RETURN(gvdIndicesFID = (*env)->GetFieldID(env, gvdClass, "_indices", "[I"), 0);
+ CHECK_NULL_RETURN(gvdGrowMID = (*env)->GetMethodID(env, gvdClass, "grow", "()V"), 0);
jniInited = 1;
return jniInited;
}
// gmask is the composite font slot mask
// baseindex is to be added to the character (code point) index.
-int storeGVData(JNIEnv* env,
- jobject gvdata, jint slot, jint baseIndex, jobject startPt,
- int glyphCount, hb_glyph_info_t *glyphInfo,
- hb_glyph_position_t *glyphPos, hb_direction_t direction,
- float devScale) {
+jboolean storeGVData(JNIEnv* env,
+ jobject gvdata, jint slot,
+ jint baseIndex, int offset, jobject startPt,
+ int charCount, int glyphCount, hb_glyph_info_t *glyphInfo,
+ hb_glyph_position_t *glyphPos, float devScale) {
- int i;
+ int i, needToGrow;
float x=0, y=0;
- float startX, startY;
- float scale = 1.0f/64.0f/devScale;
+ float startX, startY, advX, advY;
+ float scale = 1.0f / HBFloatToFixedScale / devScale;
unsigned int* glyphs;
float* positions;
- int initialCount, glyphArrayLen, posArrayLen, maxGlyphs, storeadv;
+ int initialCount, glyphArrayLen, posArrayLen, maxGlyphs, storeadv, maxStore;
unsigned int* indices;
jarray glyphArray, posArray, inxArray;
if (!init_JNI_IDs(env)) {
- return 0;
+ return JNI_FALSE;
}
initialCount = (*env)->GetIntField(env, gvdata, gvdCountFID);
- glyphArray =
- (jarray)(*env)->GetObjectField(env, gvdata, gvdGlyphsFID);
- posArray =
- (jarray)(*env)->GetObjectField(env, gvdata, gvdPositionsFID);
-
- if (glyphArray == NULL || posArray == NULL)
- {
- JNU_ThrowArrayIndexOutOfBoundsException(env, "");
- return 0;
- }
-
- // The Java code catches the IIOBE and expands the storage
- // and re-invokes layout. I suppose this is expected to be rare
- // because at least in a single threaded case there should be
- // re-use of the same container, but it is a little wasteful/distateful.
- glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
- posArrayLen = (*env)->GetArrayLength(env, posArray);
- maxGlyphs = glyphCount + initialCount;
- if ((maxGlyphs > glyphArrayLen) ||
- (maxGlyphs * 2 + 2 > posArrayLen))
- {
- JNU_ThrowArrayIndexOutOfBoundsException(env, "");
- return 0;
- }
+ do {
+ glyphArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdGlyphsFID);
+ posArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdPositionsFID);
+ inxArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdIndicesFID);
+ if (glyphArray == NULL || posArray == NULL || inxArray == NULL) {
+ JNU_ThrowArrayIndexOutOfBoundsException(env, "");
+ return JNI_FALSE;
+ }
+ glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
+ posArrayLen = (*env)->GetArrayLength(env, posArray);
+ maxGlyphs = (charCount > glyphCount) ? charCount : glyphCount;
+ maxStore = maxGlyphs + initialCount;
+ needToGrow = (maxStore > glyphArrayLen) ||
+ (maxStore * 2 + 2 > posArrayLen);
+ if (needToGrow) {
+ (*env)->CallVoidMethod(env, gvdata, gvdGrowMID);
+ if ((*env)->ExceptionCheck(env)) {
+ return JNI_FALSE;
+ }
+ }
+ } while (needToGrow);
getFloat(env, startPt, &startX, &startY);
glyphs =
(unsigned int*)(*env)->GetPrimitiveArrayCritical(env, glyphArray, NULL);
+ if (glyphs == NULL) {
+ return JNI_FALSE;
+ }
positions = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, posArray, NULL);
+ if (positions == NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
+ return JNI_FALSE;
+ }
+ indices =
+ (unsigned int*)(*env)->GetPrimitiveArrayCritical(env, inxArray, NULL);
+ if (indices == NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
+ (*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0);
+ return JNI_FALSE;
+ }
+
for (i = 0; i < glyphCount; i++) {
int storei = i + initialCount;
- int index = glyphInfo[i].codepoint | slot;
- if (i<glyphCount)glyphs[storei] = (unsigned int)index;
- positions[(storei*2)] = startX + x + glyphPos[i].x_offset * scale;
- positions[(storei*2)+1] = startY + y - glyphPos[i].y_offset * scale;
+ int cluster = glyphInfo[i].cluster - offset;
+ indices[storei] = baseIndex + cluster;
+ glyphs[storei] = (unsigned int)(glyphInfo[i].codepoint | slot);
+ positions[storei*2] = startX + x + glyphPos[i].x_offset * scale;
+ positions[(storei*2)+1] = startY + y + glyphPos[i].y_offset * scale;
x += glyphPos[i].x_advance * scale;
y += glyphPos[i].y_advance * scale;
+ storei++;
}
- storeadv = initialCount+glyphCount;
+ storeadv = initialCount + glyphCount;
// The final slot in the positions array is important
// because when the GlyphVector is created from this
// data it determines the overall advance of the glyphvector
@@ -137,30 +153,17 @@
// during rendering where text is broken into runs.
// We also need to report it back into "pt", so layout can
// pass it back down for that next run in this code.
- positions[(storeadv*2)] = startX + x;
- positions[(storeadv*2)+1] = startY + y;
+ advX = startX + x;
+ advY = startY + y;
+ positions[(storeadv*2)] = advX;
+ positions[(storeadv*2)+1] = advY;
(*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
(*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0);
- putFloat(env, startPt,positions[(storeadv*2)],positions[(storeadv*2)+1] );
- inxArray =
- (jarray)(*env)->GetObjectField(env, gvdata, gvdIndicesFID);
- indices =
- (unsigned int*)(*env)->GetPrimitiveArrayCritical(env, inxArray, NULL);
- for (i = 0; i < glyphCount; i++) {
- int cluster = glyphInfo[i].cluster;
- if (direction == HB_DIRECTION_LTR) {
- // I need to understand what hb does when processing a substring
- // I expected the cluster index to be from the start of the text
- // to process.
- // Instead it appears to be from the start of the whole thing.
- indices[i+initialCount] = cluster;
- } else {
- indices[i+initialCount] = baseIndex + glyphCount -1 -i;
- }
- }
(*env)->ReleasePrimitiveArrayCritical(env, inxArray, indices, 0);
- (*env)->SetIntField(env, gvdata, gvdCountFID, initialCount+glyphCount);
- return initialCount+glyphCount;
+ putFloat(env, startPt, advX, advY);
+ (*env)->SetIntField(env, gvdata, gvdCountFID, storeadv);
+
+ return JNI_TRUE;
}
static float euclidianDistance(float a, float b)
@@ -226,7 +229,9 @@
}
-#define TYPO_RTL 0x80000000
+#define TYPO_KERN 0x00000001
+#define TYPO_LIGA 0x00000002
+#define TYPO_RTL 0x80000000
JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
(JNIEnv *env, jclass cls,
@@ -255,10 +260,11 @@
hb_glyph_info_t *glyphInfo;
hb_glyph_position_t *glyphPos;
hb_direction_t direction = HB_DIRECTION_LTR;
- hb_feature_t *features = NULL;
+ hb_feature_t *features = NULL;
int featureCount = 0;
-
- int i;
+ char* kern = (flags & TYPO_KERN) ? "kern" : "-kern";
+ char* liga = (flags & TYPO_LIGA) ? "liga" : "-liga";
+ jboolean ret;
unsigned int buflen;
JDKFontInfo *jdkFontInfo =
@@ -281,6 +287,8 @@
direction = HB_DIRECTION_RTL;
}
hb_buffer_set_direction(buffer, direction);
+ hb_buffer_set_cluster_level(buffer,
+ HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
chars = (*env)->GetCharArrayElements(env, text, NULL);
if ((*env)->ExceptionCheck(env)) {
@@ -293,36 +301,26 @@
hb_buffer_add_utf16(buffer, chars, len, offset, limit-offset);
+ features = calloc(2, sizeof(hb_feature_t));
+ if (features) {
+ hb_feature_from_string(kern, -1, &features[featureCount++]);
+ hb_feature_from_string(liga, -1, &features[featureCount++]);
+ }
+
hb_shape_full(hbfont, buffer, features, featureCount, 0);
glyphCount = hb_buffer_get_length(buffer);
glyphInfo = hb_buffer_get_glyph_infos(buffer, 0);
glyphPos = hb_buffer_get_glyph_positions(buffer, &buflen);
- for (i = 0; i < glyphCount; i++) {
- int index = glyphInfo[i].codepoint;
- int xadv = (glyphPos[i].x_advance);
- int yadv = (glyphPos[i].y_advance);
- }
- // On "input" HB assigns a cluster index to each character in UTF-16.
- // On output where a sequence of characters have been mapped to
- // a glyph they are all mapped to the cluster index of the first character.
- // The next cluster index will be that of the first character in the
- // next cluster. So cluster indexes may 'skip' on output.
- // This can also happen if there are supplementary code-points
- // such that two UTF-16 characters are needed to make one codepoint.
- // In RTL text you need to count down.
- // So the following code tries to build the reverse map as expected
- // by calling code.
- storeGVData(env, gvdata, slot, baseIndex, startPt,
- glyphCount, glyphInfo, glyphPos, direction,
- jdkFontInfo->devScale);
+ ret = storeGVData(env, gvdata, slot, baseIndex, offset, startPt,
+ limit - offset, glyphCount, glyphInfo, glyphPos,
+ jdkFontInfo->devScale);
hb_buffer_destroy (buffer);
hb_font_destroy(hbfont);
free((void*)jdkFontInfo);
if (features != NULL) free(features);
(*env)->ReleaseCharArrayElements(env, text, chars, JNI_ABORT);
-
- return JNI_TRUE;
+ return ret;
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc Wed Sep 21 09:29:30 2016 -0700
@@ -55,10 +55,6 @@
return (*glyph != 0);
}
-// This is also define in freetypescaler.c and similar macros are
-// in fontscalerdefs.h. Consider tidying this up.
-#define FloatToF26Dot6(x) ((unsigned int) ((x)*64))
-
static hb_position_t
hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
void *font_data,
@@ -84,7 +80,7 @@
fadv *= jdkFontInfo->devScale;
env->DeleteLocalRef(pt);
- return FloatToF26Dot6(fadv); // should this round ?
+ return HBFloatToFixed(fadv);
}
static hb_position_t
@@ -111,7 +107,7 @@
fadv = env->GetFloatField(pt, sunFontIDs.yFID);
env->DeleteLocalRef(pt);
- return FloatToF26Dot6(fadv); // should this round ?
+ return HBFloatToFixed(fadv);
}
@@ -205,8 +201,8 @@
*x = 0; *y = 0;
return true;
}
- *x = FloatToF26Dot6(env->GetFloatField(pt, sunFontIDs.xFID));
- *y = FloatToF26Dot6(env->GetFloatField(pt, sunFontIDs.yFID));
+ *x = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.xFID));
+ *y = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.yFID));
env->DeleteLocalRef(pt);
return true;
@@ -325,8 +321,8 @@
_hb_jdk_get_font_funcs (),
jdkFontInfo, (hb_destroy_func_t) _do_nothing);
hb_font_set_scale (font,
- FloatToF26Dot6(jdkFontInfo->ptSize*jdkFontInfo->devScale),
- FloatToF26Dot6(jdkFontInfo->ptSize*jdkFontInfo->devScale));
+ HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale),
+ HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale));
return font;
}
@@ -343,8 +339,8 @@
hb_face_destroy(face);
hb_font_set_scale(font,
- FloatToF26Dot6(jdkFontInfo->ptSize),
- FloatToF26Dot6(jdkFontInfo->ptSize));
+ HBFloatToFixed(jdkFontInfo->ptSize),
+ HBFloatToFixed(jdkFontInfo->ptSize));
return font;
}
#endif
--- a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk.h Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk.h Wed Sep 21 09:29:30 2016 -0700
@@ -48,6 +48,10 @@
} JDKFontInfo;
+// Use 16.16 for better precision than 26.6
+#define HBFloatToFixedScale ((float)(1 << 16))
+#define HBFloatToFixed(f) ((unsigned int)((f) * HBFloatToFixedScale))
+
/*
* Note:
*
--- a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c Wed Sep 21 09:29:30 2016 -0700
@@ -2162,6 +2162,25 @@
}
JNIEXPORT void JNICALL
+Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_clearNativeReadAbortFlag
+ (JNIEnv *env,
+ jobject this,
+ jlong ptr) {
+
+ imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
+
+ if (data == NULL) {
+ JNU_ThrowByName(env,
+ "java/lang/IllegalStateException",
+ "Attempting to use reader after dispose()");
+ return;
+ }
+
+ data->abortFlag = JNI_FALSE;
+
+}
+
+JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_abortRead
(JNIEnv *env,
jobject this,
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Wed Sep 21 09:29:30 2016 -0700
@@ -1570,6 +1570,10 @@
Integer.valueOf(getMultiClickTime()));
desktopProperties.put("awt.mouse.numButtons",
Integer.valueOf(getNumberOfButtons()));
+ if(SunGraphicsEnvironment.isUIScaleEnabled()) {
+ addPropertyChangeListener("gnome.Xft/DPI", evt ->
+ localEnv.displayChanged());
+ }
}
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java Wed Sep 21 09:29:30 2016 -0700
@@ -63,7 +63,7 @@
private SunDisplayChanger topLevels = new SunDisplayChanger();
private DisplayMode origDisplayMode;
private boolean shutdownHookRegistered;
- private final int scale;
+ private int scale;
public X11GraphicsDevice(int screennum) {
this.screen = screennum;
@@ -488,6 +488,7 @@
* X11GraphicsEnvironment when the display mode has been changed.
*/
public synchronized void displayChanged() {
+ scale = initScaleFactor();
// On X11 the visuals do not change, and therefore we don't need
// to reset the defaultConfig, config, doubleBufferVisuals,
// neither do we need to reset the native data.
--- a/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.c Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.c Wed Sep 21 09:29:30 2016 -0700
@@ -148,7 +148,7 @@
void *scale = fp_g_variant_get_child_value(entry, 1);
if (screen && scale) {
char *name = fp_g_variant_get_string(screen, NULL);
- if (name && strcmp(name, output_name)) {
+ if (name && !strcmp(name, output_name)) {
result = fp_g_variant_get_int32(scale) / 8.;
}
fp_g_variant_unref(screen);
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Wed Sep 21 09:29:30 2016 -0700
@@ -442,7 +442,7 @@
#ifndef __linux__ /* SOLARIS */
if (xrenderLibHandle == NULL) {
- xrenderLibHandle = dlopen("/usr/sfw/lib/libXrender.so.1",
+ xrenderLibHandle = dlopen("/usr/lib/libXrender.so.1",
RTLD_LAZY | RTLD_GLOBAL);
}
#endif
@@ -2181,7 +2181,8 @@
JNIEXPORT jdouble JNICALL
Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor
(JNIEnv *env, jobject this, jint screen) {
- char *name = get_output_screen_name(env, screen);
+ // in case of Xinerama individual screen scales are not supported
+ char *name = get_output_screen_name(env, usingXinerama ? 0 : screen);
double scale = getNativeScaleFactor(name);
if (name) {
free(name);
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/TranslucentWindowPainter.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/TranslucentWindowPainter.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -303,10 +303,10 @@
if (bb instanceof DestSurfaceProvider) {
Surface s = ((DestSurfaceProvider)bb).getDestSurface();
if (s instanceof AccelSurface) {
- final int w = bb.getWidth(null);
- final int h = bb.getHeight(null);
final boolean arr[] = { false };
final AccelSurface as = (AccelSurface)s;
+ final int w = as.getBounds().width;
+ final int h = as.getBounds().height;
RenderQueue rq = as.getContext().getRenderQueue();
rq.lock();
try {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java Wed Sep 21 09:29:30 2016 -0700
@@ -478,9 +478,12 @@
}
DialogOwner dlgOwner = (DialogOwner)attributes.get(DialogOwner.class);
- Frame ownerFrame = (dlgOwner != null) ? dlgOwner.getOwner() : null;
+ Window owner = (dlgOwner != null) ? dlgOwner.getOwner() : null;
- WPrintDialog dialog = new WPrintDialog(ownerFrame, this);
+ WPrintDialog dialog = (owner instanceof Frame) ?
+ new WPrintDialog((Frame)owner, this) :
+ new WPrintDialog((Dialog)owner, this);
+
dialog.setRetVal(false);
dialog.setVisible(true);
boolean prv = dialog.getRetVal();
@@ -498,8 +501,9 @@
title = rb.getString("dialog.printtofile");
} catch (MissingResourceException e) {
}
- FileDialog fileDialog = new FileDialog(ownerFrame, title,
- FileDialog.SAVE);
+ FileDialog fileDialog = (owner instanceof Frame) ?
+ new FileDialog((Frame)owner, title, FileDialog.SAVE) :
+ new FileDialog((Dialog)owner, title, FileDialog.SAVE);
URI destURI = dest.getURI();
// Old code destURI.getPath() would return null for "file:out.prn"
@@ -531,10 +535,17 @@
((pFile != null) &&
(!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) {
- (new PrintToFileErrorDialog(ownerFrame,
+ if (owner instanceof Frame) {
+ (new PrintToFileErrorDialog((Frame)owner,
ServiceDialog.getMsg("dialog.owtitle"),
ServiceDialog.getMsg("dialog.writeerror")+" "+fullName,
ServiceDialog.getMsg("button.ok"))).setVisible(true);
+ } else {
+ (new PrintToFileErrorDialog((Dialog)owner,
+ ServiceDialog.getMsg("dialog.owtitle"),
+ ServiceDialog.getMsg("dialog.writeerror")+" "+fullName,
+ ServiceDialog.getMsg("button.ok"))).setVisible(true);
+ }
fileDialog.setVisible(true);
fileName = fileDialog.getFile();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -753,10 +753,15 @@
}
void rescale(SIZE *size) {
- HWND hWnd = ::GetDesktopWindow();
- HDC hDC = ::GetDC(hWnd);
- int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
- int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
+ static int dpiX = -1;
+ static int dpiY = -1;
+ if (dpiX == -1 || dpiY == -1) {
+ HWND hWnd = ::GetDesktopWindow();
+ HDC hDC = ::GetDC(hWnd);
+ dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
+ dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
+ ::ReleaseDC(hWnd, hDC);
+ }
if (dpiX !=0 && dpiX != 96) {
float invScaleX = 96.0f / dpiX;
@@ -766,7 +771,6 @@
float invScaleY = 96.0f / dpiY;
size->cy = ROUND_TO_INT(size->cy * invScaleY);
}
- ::ReleaseDC(hWnd, hDC);
}
/*
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -88,11 +88,16 @@
}
void getInvScale(float &invScaleX, float &invScaleY) {
- HWND hWnd = ::GetDesktopWindow();
- HDC hDC = ::GetDC(hWnd);
- int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
- int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
- ::ReleaseDC(hWnd, hDC);
+ static int dpiX = -1;
+ static int dpiY = -1;
+ if (dpiX == -1 || dpiY == -1) {
+ HWND hWnd = ::GetDesktopWindow();
+ HDC hDC = ::GetDC(hWnd);
+ dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
+ dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
+ ::ReleaseDC(hWnd, hDC);
+ }
+
invScaleX = (dpiX == 0.0f) ? 1.0f : 96.0f / dpiX;
invScaleY = (dpiY == 0.0f) ? 1.0f : 96.0f / dpiY;
}
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.cpp Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.cpp Wed Sep 21 09:29:30 2016 -0700
@@ -108,7 +108,7 @@
JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_flashWindow
(JNIEnv *, jobject, jlong window)
{
- AwtWindow::FlashWindowEx((HWND) window, 3, 0, FLASHW_TIMERNOFG);
+ ::FlashWindow((HWND) window, TRUE);
}
/*
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java Wed Sep 21 09:29:30 2016 -0700
@@ -45,7 +45,7 @@
* <pre>
* Secmod secmod = Secmod.getInstance();
* if (secmod.isInitialized() == false) {
- * secmod.initialize("/home/myself/.mozilla", "/usr/sfw/lib/mozilla");
+ * secmod.initialize("/home/myself/.mozilla");
* }
*
* Provider p = secmod.getModule(ModuleType.KEYSTORE).getProvider();
--- a/jdk/src/jdk.jdi/share/classes/module-info.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/jdk.jdi/share/classes/module-info.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,6 +25,7 @@
module jdk.jdi {
requires jdk.attach;
+ requires jdk.jdwp.agent;
exports com.sun.jdi;
exports com.sun.jdi.connect;
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_be_BY.properties Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_be_BY.properties Wed Sep 21 09:29:30 2016 -0700
@@ -35,4 +35,5 @@
# This notice and attribution to Taligent may not be removed.
# Taligent is a registered trademark of Taligent, Inc.
+BYN=\u0420\u0443\u0431
BYR=\u0420\u0443\u0431
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties Wed Sep 21 09:29:30 2016 -0700
@@ -265,8 +265,6 @@
No constructor matching {0} found in {1}.
javac.err.wrong.number.args=\
Wrong number of arguments in {0}.
-javac.err.wrong.number.args=\
- Wrong number of arguments in {0}.
javac.err.forward.ref=\
Can''t make forward reference to {0} in {1}.
javac.err.array.dim.missing=\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/*
+ @test
+ @bug 8160570
+ @summary Tests that a modal dialog receives WINDOW_ACTIVATED & WINDOW_GAINED_FOCUS on first show.
+*/
+public class ModalDialogActivationTest {
+ static final Object lock = new Object();
+ static volatile boolean activated;
+ static volatile boolean focused;
+
+ public static void main(String[] args) throws InterruptedException {
+ EventQueue.invokeLater(() -> runGUI());
+
+ long time = System.currentTimeMillis();
+ synchronized (lock) {
+ while (!activated || !focused) {
+ lock.wait(5000);
+ if (System.currentTimeMillis() - time >= 5000) break;
+ }
+ }
+ if (!activated || !focused) {
+ throw new RuntimeException("Test FAILED: activated: " + activated + ", focused: " + focused);
+ }
+ System.out.println("Test PASSED");
+ }
+
+ static void runGUI() {
+ JFrame f = new JFrame("frame");
+ final JDialog d = new MyModalDialog(f, "dialog");
+ d.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowActivated(WindowEvent e) {
+ synchronized (lock) {
+ activated = true;
+ lock.notifyAll();
+ }
+ }
+ });
+ d.addWindowFocusListener(new WindowAdapter() {
+ @Override
+ public void windowGainedFocus(WindowEvent e) {
+ synchronized (lock) {
+ focused = true;
+ lock.notifyAll();
+ }
+ }
+ });
+ f.setVisible(true);
+ d.setVisible(true);
+ }
+
+ static class MyModalDialog extends JDialog {
+ public MyModalDialog(Frame owner, String title)ª {
+ super(owner, title, true);
+ }
+
+ @Override
+ public boolean getFocusableWindowState() {
+ try {
+ // let Toolkit thread go ahead
+ Thread.sleep(100);
+ } catch (InterruptedException ignore) {
+ }
+ return super.getFocusableWindowState();
+ }
+ }
+}
--- a/jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
@test
- @bug 8048887
+ @bug 8048887 8164937
@summary Tests SortingFTP for an exception caused by the tim-sort algo.
@author anton.tarasov: area=awt.focus
@run main JDK8048887
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/EnterExitEvents/ModalDialogEnterExitEventsTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key headful
+ * @bug 8050478
+ * @summary Cursor not updating correctly after closing a modal dialog.
+ * The root cause of the issue was the lack of a mouse exit event
+ * during displaying of a modal dialog.
+ * @author Dmitry Markov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main ModalDialogEnterExitEventsTest
+ */
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import test.java.awt.regtesthelpers.Util;
+
+public class ModalDialogEnterExitEventsTest {
+ private static volatile AtomicInteger mouseEnterCount = new AtomicInteger();
+ private static volatile AtomicInteger mouseExitCount = new AtomicInteger();
+
+ private static JFrame frame;
+ private static JButton openButton;
+ private static JButton closeButton;
+
+ public static void main(String[] args) {
+ Robot robot = Util.createRobot();
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+ Util.waitForIdle(robot);
+
+ Util.clickOnComp(frame, robot, 500);
+ Util.waitForIdle(robot);
+
+ mouseEnterCount.set(0);
+ mouseExitCount.set(0);
+
+ Util.clickOnComp(openButton, robot, 500);
+ Util.waitForIdle(robot);
+ if (mouseExitCount.get() != 1) {
+ throw new RuntimeException("Test FAILED. Wrong number of MouseExited events = " + mouseExitCount.get());
+ }
+
+ Util.clickOnComp(closeButton, robot, 500);
+ Util.waitForIdle(robot);
+ if (mouseEnterCount.get() != 1) {
+ throw new RuntimeException("Test FAILED. Wrong number of MouseEntered events = "+ mouseEnterCount.get());
+ }
+ }
+
+ private static void createAndShowGUI() {
+ frame = new JFrame("ModalDialogEnterExitEventsTest");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setLayout(new FlowLayout());
+ frame.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseExited(MouseEvent e) {
+ mouseExitCount.getAndIncrement();
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ mouseEnterCount.getAndIncrement();
+ }
+ });
+ openButton = new JButton("Open Dialog");
+ openButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JDialog dialog = new JDialog(frame, "Modal Dialog", true);
+ dialog.setLayout(new FlowLayout());
+ closeButton = new JButton("Close");
+ closeButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ dialog.dispose();
+ }
+ });
+ dialog.add(closeButton);
+ dialog.setSize(200, 200);
+ dialog.setLocationRelativeTo(null);
+ dialog.setVisible(true);
+ }
+ });
+ frame.add(openButton);
+ frame.setExtendedState(Frame.MAXIMIZED_BOTH);
+ frame.setVisible(true);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/GlyphVector/GetGlyphCharIndexTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @summary Test getGlyphCharIndex() results from layout
+ * @bug 8152680
+ */
+
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+
+public class GetGlyphCharIndexTest {
+ public static void main(String[] args) {
+ Font font = new Font(Font.MONOSPACED, Font.PLAIN, 12);
+ FontRenderContext frc = new FontRenderContext(null, false, false);
+ GlyphVector gv = font.layoutGlyphVector(frc, "abc".toCharArray(), 1, 3,
+ Font.LAYOUT_LEFT_TO_RIGHT);
+ int idx0 = gv.getGlyphCharIndex(0);
+ if (idx0 != 0) {
+ throw new RuntimeException("Expected 0, got " + idx0);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/LineBreakMeasurer/TestLineBreakWithFontSub.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4175418 8158924
+ * @author John Raley
+ * @summary This insures that bug 4175418: Font substitution in TextLayout /
+ * LineBreakMeasurer is inconsistent has been fixed. The problem was
+ * that text was measured in one Font, but lines were produced
+ * in a different font.
+ */
+
+/*
+ * (C) Copyright IBM Corp. 1999, All Rights Reserved
+ */
+
+import java.text.AttributedString;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextLayout;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextAttribute;
+
+/**
+ * This insures that bug 4175418: Font substitution in TextLayout /
+ * LineBreakMeasurer is inconsistent has been fixed. The problem was
+ * that text was measured in one Font, but lines were produced
+ * in a different font. One symptom of this problem is that lines are
+ * either too short or too long. This test line-breaks a paragraph
+ * and checks the line lengths to make sure breaks were chosen well.
+ * This can be checked because the paragraph is so simple.
+ */
+public class TestLineBreakWithFontSub {
+
+ public static void main(String[] args) {
+
+ new TestLineBreakWithFontSub().test();
+ System.out.println("Line break / font substitution test PASSED");
+ }
+
+ private static final String WORD = "word";
+ private static final String SPACING = " ";
+ // The Hebrew character in this string can trigger font substitution
+ private static final String MIXED = "A\u05D0";
+
+ private static final int NUM_WORDS = 12;
+
+ private static final FontRenderContext DEFAULT_FRC =
+ new FontRenderContext(null, false, false);
+
+ public void test() {
+
+ // construct a paragraph as follows: MIXED + [SPACING + WORD] + ...
+ StringBuffer text = new StringBuffer(MIXED);
+ for (int i=0; i < NUM_WORDS; i++) {
+ text.append(SPACING);
+ text.append(WORD);
+ }
+
+ AttributedString attrString = new AttributedString(text.toString());
+ attrString.addAttribute(TextAttribute.SIZE, new Float(24.0));
+
+ LineBreakMeasurer measurer = new LineBreakMeasurer(attrString.getIterator(),
+ DEFAULT_FRC);
+
+ // get width of a space-word sequence, in context
+ int sequenceLength = WORD.length()+SPACING.length();
+ measurer.setPosition(text.length() - sequenceLength);
+
+ TextLayout layout = measurer.nextLayout(10000.0f);
+
+ if (layout.getCharacterCount() != sequenceLength) {
+ throw new Error("layout length is incorrect!");
+ }
+
+ final float sequenceAdvance = layout.getVisibleAdvance();
+
+ float wrappingWidth = sequenceAdvance * 2;
+
+ // now run test with a variety of widths
+ while (wrappingWidth < (sequenceAdvance*NUM_WORDS)) {
+ measurer.setPosition(0);
+ checkMeasurer(measurer,
+ wrappingWidth,
+ sequenceAdvance,
+ text.length());
+ wrappingWidth += sequenceAdvance / 5;
+ }
+ }
+
+ /**
+ * Iterate through measurer and check that every line is
+ * not too long and not too short, but just right.
+ */
+ private void checkMeasurer(LineBreakMeasurer measurer,
+ float wrappingWidth,
+ float sequenceAdvance,
+ int endPosition) {
+
+ do {
+ TextLayout layout = measurer.nextLayout(wrappingWidth);
+ float visAdvance = layout.getVisibleAdvance();
+
+ // Check that wrappingWidth-sequenceAdvance < visAdvance
+ // Also, if we're not at the end of the paragraph,
+ // check that visAdvance <= wrappingWidth
+
+ if (visAdvance > wrappingWidth) {
+ // line is too long for given wrapping width
+ throw new Error("layout is too long");
+ }
+
+ if (measurer.getPosition() < endPosition) {
+ if (visAdvance <= wrappingWidth - sequenceAdvance) {
+ // line is too short for given wrapping width;
+ // another word would have fit
+ throw new Error("room for more words on line. diff=" +
+ (wrappingWidth - sequenceAdvance - visAdvance));
+ }
+ }
+ } while (measurer.getPosition() != endPosition);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/TextLayout/LigatureCaretTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,167 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4178145 8144015
+*/
+
+/*
+ * Copyright 1998 IBM Corp. All Rights Reserved.
+ */
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextLayout;
+import java.awt.font.TextHitInfo;
+import java.awt.font.FontRenderContext;
+import java.util.Hashtable;
+
+/**
+ * This test ensures that TextLayout will not place a caret within
+ * an Arabic lam-alef ligature, and will correctly caret through
+ * bidirectional text with numbers.
+ */
+
+public class LigatureCaretTest {
+
+ public static void main(String[] args) {
+
+ //testBidiWithNumbers();
+ testLamAlef();
+ System.out.println("LigatureCaretTest PASSED");
+ }
+
+ // These values are for TextLayout constructors
+ private static final Hashtable map = new Hashtable();
+ static {
+ map.put(TextAttribute.FONT, new Font("Lucida Sans", Font.PLAIN, 24));
+ }
+ private static final FontRenderContext frc =
+ new FontRenderContext(null, false, false);
+
+ /**
+ * Caret through text mixed-direction text and check the results.
+ * If the test fails an Error is thrown.
+ * @exception an Error is thrown if the test fails
+ */
+ public static void testBidiWithNumbers() {
+
+ String bidiWithNumbers = "abc\u05D0\u05D1\u05D2123abc";
+ // visual order for the text:
+ // abc123<gimel><bet><aleph>abc
+
+ int[] carets = { 0, 1, 2, 3, 7, 8, 6, 5, 4, 9, 10, 11, 12 };
+ TextLayout layout = new TextLayout(bidiWithNumbers, map, frc);
+
+ // Caret through TextLayout in both directions and check results.
+ for (int i=0; i < carets.length-1; i++) {
+
+ TextHitInfo hit = layout.getNextRightHit(carets[i]);
+ if (hit.getInsertionIndex() != carets[i+1]) {
+ throw new Error("right hit failed within layout");
+ }
+ }
+
+ if (layout.getNextRightHit(carets[carets.length-1]) != null) {
+ throw new Error("right hit failed at end of layout");
+ }
+
+ for (int i=carets.length-1; i > 0; i--) {
+
+ TextHitInfo hit = layout.getNextLeftHit(carets[i]);
+ if (hit.getInsertionIndex() != carets[i-1]) {
+ throw new Error("left hit failed within layout");
+ }
+ }
+
+ if (layout.getNextLeftHit(carets[0]) != null) {
+ throw new Error("left hit failed at end of layout");
+ }
+ }
+
+ /**
+ * Ensure proper careting and hit-testing behavior with
+ * a lam-alef ligature.
+ * If the test fails, an Error is thrown.
+ * @exception an Error is thrown if the test fails
+ */
+ public static void testLamAlef() {
+
+ // lam-alef form a mandantory ligature.
+ final String lamAlef = "\u0644\u0627";
+ final String ltrText = "abcd";
+
+ // Create a TextLayout with just a lam-alef sequence. There
+ // should only be two valid caret positions: one at
+ // insertion offset 0 and the other at insertion offset 2.
+ TextLayout layout = new TextLayout(lamAlef, map, frc);
+
+ TextHitInfo hit;
+
+ hit = layout.getNextLeftHit(0);
+ if (hit.getInsertionIndex() != 2) {
+ throw new Error("Left hit failed. Hit:" + hit);
+ }
+
+ hit = layout.getNextRightHit(2);
+ if (hit.getInsertionIndex() != 0) {
+ throw new Error("Right hit failed. Hit:" + hit);
+ }
+
+ hit = layout.hitTestChar(layout.getAdvance()/2, 0);
+ if (hit.getInsertionIndex() != 0 && hit.getInsertionIndex() != 2) {
+ throw new Error("Hit-test allowed incorrect caret. Hit:" + hit);
+ }
+
+
+ // Create a TextLayout with some left-to-right text
+ // before the lam-alef sequence. There should not be
+ // a caret position between the lam and alef.
+ layout = new TextLayout(ltrText+lamAlef, map, frc);
+
+ final int ltrLen = ltrText.length();
+ final int layoutLen = layout.getCharacterCount();
+
+ for (int i=0; i < ltrLen; i++) {
+ hit = layout.getNextRightHit(i);
+ if (hit.getInsertionIndex() != i+1) {
+ throw new Error("Right hit failed in ltr text.");
+ }
+ }
+
+ hit = layout.getNextRightHit(ltrLen);
+ if (layoutLen != hit.getInsertionIndex()) {
+ throw new Error("Right hit failed at direction boundary.");
+ }
+
+ hit = layout.getNextLeftHit(layoutLen);
+ if (hit.getInsertionIndex() != ltrLen) {
+ throw new Error("Left hit failed at end of text.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/TextLayout/TestJustification.html Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,52 @@
+<!--
+ Copyright (c) 1999, 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.
+-->
+
+<html>
+<head>
+<title>Test Justification</title>
+</head>
+<body>
+<!--
+ @test
+ @bug 4211728 4178140 8145542
+ @summary Justify several lines of text and verify that the lines are the same
+ length and cursor positions are correct.
+Bug 4211728: TextLayout.draw() draws characters at wrong position.
+Bug 4178140: TextLayout does not justify
+ @run applet/manual=yesno TestJustification.html
+-->
+<h3>Test Justification</h1>
+<hr>
+<p>Five lines of text should appear, all justified to the same width,
+followed by a sixth line containing only roman characters and no spaces
+which is not justified, and instead is centered.
+Carets should appear between all characters. Pass the test if this is
+true.
+<p>
+<applet code=TestJustification.class width=500 height=500>
+alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason."
+Your browser is completely ignoring the <APPLET> tag!
+</applet>
+</body>
+</html>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/TextLayout/TestJustification.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+
+/*
+ *
+ * See TestJustification.html for main test.
+ */
+
+import java.applet.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+import java.text.*;
+
+public class TestJustification extends Applet {
+ JustificationPanel panel;
+
+ public void init() {
+ setLayout(new BorderLayout());
+ panel = new JustificationPanel("Bitstream Cyberbit");
+ add("Center", panel);
+ }
+
+ public void destroy() {
+ remove(panel);
+ }
+
+ // calls system.exit, not for use in tests.
+ public static void main(String args[]) {
+ TestJustification justificationTest = new TestJustification();
+ justificationTest.init();
+ justificationTest.start();
+
+ Frame f = new Frame("Test Justification");
+ f.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+
+ f.add("Center", justificationTest);
+ f.setSize(500, 500);
+ f.show();
+ }
+
+ public String getAppletInfo() {
+ return "Test TextLayout.getJustifiedLayout()";
+ }
+
+ static class JustificationPanel extends Panel {
+ TextLayout[] layouts;
+ String fontname;
+ float height;
+ float oldfsize;
+
+ AttributedCharacterIterator lineText;
+ TextLayout[] lines;
+ int linecount;
+ float oldwidth;
+
+ JustificationPanel(String fontname) {
+ this.fontname = fontname;
+ }
+
+ private static final String[] texts = {
+ "This is an english Highlighting demo.", "Highlighting",
+ "This is an arabic \u0627\u0628\u062a\u062c \u062e\u0644\u0627\u062e demo.", "arabic \u0627\u0628\u062a\u062c",
+ "This is a hebrew \u05d0\u05d1\u05d2 \u05d3\u05d4\u05d5 demo.", "hebrew \u05d0\u05d1\u05d2",
+ "This is a cjk \u4e00\u4e01\u4e02\uac00\uac01\uc4fa\uf900\uf901\uf902 demo.", "cjk",
+ "NoSpaceCJK:\u4e00\u4e01\u4e02and\uac00\uac01\uc4faand\uf900\uf901\uf902", "No",
+ "NoSpaceRoman", "Space"
+ };
+
+ public void paint(Graphics g) {
+ Graphics2D g2d = (Graphics2D)g;
+
+ Dimension d = getSize();
+ Insets insets = getInsets();
+
+ float w = d.width - insets.left - insets.right;
+ float h = d.height - insets.top - insets.bottom;
+ int fsize = (int)w/25;
+
+ FontRenderContext frc = g2d.getFontRenderContext();
+
+ if (layouts == null || fsize != oldfsize) {
+ oldfsize = fsize;
+
+ Font f0 = new Font(fontname, Font.PLAIN, fsize);
+ Font f1 = new Font(fontname, Font.ITALIC, (int)(fsize * 1.5));
+
+ if (layouts == null) {
+ layouts = new TextLayout[texts.length / 2];
+ }
+
+ height = 0;
+ for (int i = 0; i < layouts.length; ++i) {
+ String text = texts[i*2];
+ String target = texts[i*2+1];
+
+ AttributedString astr = new AttributedString(text);
+ astr.addAttribute(TextAttribute.FONT, f0, 0, text.length());
+
+ int start = text.indexOf(target);
+ int limit = start + target.length();
+ astr.addAttribute(TextAttribute.FONT, f1, start, limit);
+
+ TextLayout layout = new TextLayout(astr.getIterator(), frc);
+
+ layout = layout.getJustifiedLayout(w - 20);
+
+ layouts[i] = layout;
+
+ height += layout.getAscent() + layout.getDescent() + layout.getLeading();
+ }
+ }
+
+ g2d.setColor(Color.white);
+ g2d.fill(new Rectangle.Float(insets.left, insets.top, w, h));
+
+ float basey = 20;
+
+ for (int i = 0; i < layouts.length; ++i) {
+ TextLayout layout = layouts[i];
+
+ float la = layout.getAscent();
+ float ld = layout.getDescent();
+ float ll = layout.getLeading();
+ float lw = layout.getAdvance();
+ float lh = la + ld + ll;
+ float lx = (w - lw) / 2f;
+ float ly = basey + layout.getAscent();
+
+ g2d.setColor(Color.black);
+ g2d.translate(insets.left + lx, insets.top + ly);
+
+ Rectangle2D bounds = new Rectangle2D.Float(0, -la, lw, lh);
+ g2d.draw(bounds);
+
+ layout.draw(g2d, 0, 0);
+
+ g2d.setColor(Color.red);
+ for (int j = 0, e = layout.getCharacterCount(); j <= e; ++j) {
+ Shape[] carets = layout.getCaretShapes(j, bounds);
+ g2d.draw(carets[0]);
+ }
+
+ g2d.translate(-insets.left - lx, -insets.top - ly);
+ basey += layout.getAscent() + layout.getDescent() + layout.getLeading();
+ }
+
+ // add LineBreakMeasurer-generated layouts
+
+ if (lineText == null) {
+ String text = "This is a long line of text that should be broken across multiple "
+ + "lines and then justified to fit the break width. This test should pass if "
+ + "these lines are justified to the same width, and fail otherwise. It should "
+ + "also format the hebrew (\u05d0\u05d1\u05d2 \u05d3\u05d4\u05d5) and arabic "
+ + "(\u0627\u0628\u062a\u062c \u062e\u0644\u0627\u062e) and CJK "
+ + "(\u4e00\u4e01\u4e02\uac00\uac01\uc4fa\u67b1\u67b2\u67b3\u67b4\u67b5\u67b6\u67b7"
+ + "\u67b8\u67b9) text correctly.";
+
+ Float regular = new Float(16.0);
+ Float big = new Float(24.0);
+ AttributedString astr = new AttributedString(text);
+ astr.addAttribute(TextAttribute.SIZE, regular, 0, text.length());
+ astr.addAttribute(TextAttribute.FAMILY, fontname, 0, text.length());
+
+ int ix = text.indexOf("broken");
+ astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
+ ix = text.indexOf("hebrew");
+ astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
+ ix = text.indexOf("arabic");
+ astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 6);
+ ix = text.indexOf("CJK");
+ astr.addAttribute(TextAttribute.SIZE, big, ix, ix + 3);
+
+ lineText = astr.getIterator();
+ }
+
+ float width = w - 20;
+ if (lines == null || width != oldwidth) {
+ oldwidth = width;
+
+ lines = new TextLayout[10];
+ linecount = 0;
+
+ LineBreakMeasurer measurer = new LineBreakMeasurer(lineText, frc);
+
+ for (;;) {
+ TextLayout layout = measurer.nextLayout(width);
+ if (layout == null) {
+ break;
+ }
+
+ // justify all but last line
+ if (linecount > 0) {
+ lines[linecount - 1] = lines[linecount - 1].getJustifiedLayout(width);
+ }
+
+ if (linecount == lines.length) {
+ TextLayout[] nlines = new TextLayout[lines.length * 2];
+ System.arraycopy(lines, 0, nlines, 0, lines.length);
+ lines = nlines;
+ }
+
+ lines[linecount++] = layout;
+ }
+ }
+
+ float basex = insets.left + 10;
+ basey += 10;
+ g2d.setColor(Color.black);
+
+ for (int i = 0; i < linecount; ++i) {
+ TextLayout layout = lines[i];
+
+ basey += layout.getAscent();
+ float adv = layout.getAdvance();
+ float dx = layout.isLeftToRight() ? 0 : width - adv;
+
+ layout.draw(g2d, basex + dx, basey);
+
+ basey += layout.getDescent() + layout.getLeading();
+ }
+ }
+ }
+}
--- a/jdk/test/java/awt/font/TextLayout/VisibleAdvance.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/awt/font/TextLayout/VisibleAdvance.java Wed Sep 21 09:29:30 2016 -0700
@@ -29,7 +29,7 @@
/* @test
* @summary verify TextLine advance
- * @bug 6582460
+ * @bug 6582460 8164818
*/
/*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/PrintDlgPageable.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 4885375
+ * @summary Verifies if PageRanges To Field is populated based on Pageable
+ * for COMMON print dialog
+ * @run main/manual PrintDlgPageable
+ */
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.standard.DialogTypeSelection;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class PrintDlgPageable implements Printable {
+
+ private static Thread mainThread;
+ private static boolean testPassed;
+ private static boolean testGeneratedInterrupt;
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ doTest(PrintDlgPageable::printTest);
+ });
+ mainThread = Thread.currentThread();
+ try {
+ Thread.sleep(30000);
+ } catch (InterruptedException e) {
+ if (!testPassed && testGeneratedInterrupt) {
+ throw new RuntimeException("Print Dialog does not " +
+ "`reflect Copies or Page Ranges");
+ }
+ }
+ if (!testGeneratedInterrupt) {
+ throw new RuntimeException("user has not executed the test");
+ }
+ }
+
+ private static void printTest() {
+ PrinterJob pj = PrinterJob.getPrinterJob();
+ PageableHandler handler = new PageableHandler();
+ pj.setPageable(handler);
+
+ PrintRequestAttributeSet pSet = new HashPrintRequestAttributeSet();
+ pSet.add(DialogTypeSelection.COMMON);
+ pj.printDialog(pSet);
+ }
+
+
+ public static synchronized void pass() {
+ testPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ public static synchronized void fail() {
+ testPassed = false;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ private static void doTest(Runnable action) {
+ String description
+ = " Visual inspection of print dialog is required.\n"
+ + " A print dialog will be shown.\n "
+ + " Please verify Page Range is populated \n"
+ + " with \"From\" 1 and \"To\" 5.\n"
+ + " If ok, press PASS else press FAIL";
+
+ final JDialog dialog = new JDialog();
+ dialog.setTitle("printSelectionTest");
+ JTextArea textArea = new JTextArea(description);
+ textArea.setEditable(false);
+ final JButton testButton = new JButton("Start Test");
+ final JButton passButton = new JButton("PASS");
+ passButton.setEnabled(false);
+ passButton.addActionListener((e) -> {
+ dialog.dispose();
+ pass();
+ });
+ final JButton failButton = new JButton("FAIL");
+ failButton.setEnabled(false);
+ failButton.addActionListener((e) -> {
+ dialog.dispose();
+ fail();
+ });
+ testButton.addActionListener((e) -> {
+ testButton.setEnabled(false);
+ action.run();
+ passButton.setEnabled(true);
+ failButton.setEnabled(true);
+ });
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(textArea, BorderLayout.CENTER);
+ JPanel buttonPanel = new JPanel(new FlowLayout());
+ buttonPanel.add(testButton);
+ buttonPanel.add(passButton);
+ buttonPanel.add(failButton);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialog.add(mainPanel);
+ dialog.pack();
+ dialog.setVisible(true);
+ dialog.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ System.out.println("main dialog closing");
+ testGeneratedInterrupt = false;
+ mainThread.interrupt();
+ }
+ });
+ }
+
+ @Override
+ public int print(Graphics g, PageFormat pf, int pi) throws PrinterException {
+ return NO_SUCH_PAGE;
+ }
+}
+
+class PageableHandler implements Pageable {
+
+ PageFormat pf = new PageFormat();
+
+ @Override
+ public int getNumberOfPages() {
+ return 5;
+ }
+
+ @Override
+ public Printable getPrintable(int pageIndex) {
+ return new PrintDlgPageable();
+ }
+
+ @Override
+ public PageFormat getPageFormat(int pageIndex) {
+ return pf;
+ }
+}
--- a/jdk/test/java/awt/print/PrinterJob/TestMediaTraySelection.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/awt/print/PrinterJob/TestMediaTraySelection.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,8 +21,7 @@
* questions.
*/
/*
- * @test
- * @bug 6357887
+ * @bug 6357887 8165146
* @summary Verifies if selected printertray is used
* @requires (os.family == "linux" | os.family == "solaris")
* @run main/manual TestMediaTraySelection
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/TestPageDlgFrameAssociation.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 7064425 6948907
+ * @summary Verifies if owner Frame is associated with page dialog of PrinterJob
+ * @run main/manual TestPageDlgFrameAssociation
+ */
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class TestPageDlgFrameAssociation {
+ private static Thread mainThread;
+ private static boolean testPassed;
+ private static boolean testGeneratedInterrupt;
+ private static Button print;
+ private static Frame frame;
+ private static boolean start;
+ private static Thread t;
+
+ public static void main(String args[]) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ doTest(TestPageDlgFrameAssociation::frameTest);
+ });
+ mainThread = Thread.currentThread();
+ try {
+ Thread.sleep(60000);
+ } catch (InterruptedException e) {
+ if (!testPassed && testGeneratedInterrupt) {
+ throw new RuntimeException("Page dialog not disposed."
+ + " Page dialog is not associated with owner Frame`");
+ }
+ }
+ if (!testGeneratedInterrupt) {
+ throw new RuntimeException("user has not executed the test");
+ }
+ }
+
+ private static void frameTest() {
+ Panel panel =new Panel();
+
+ print = new Button("PageDialog");
+ print.setActionCommand("PageDialog");
+ print.addActionListener((e) -> {
+ PrinterJob job = PrinterJob.getPrinterJob();
+ PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
+ t.start();
+ start = true;
+ PageFormat pf = job.pageDialog(aset);
+ });
+
+ panel.add(print);
+
+ frame = new Frame("Test Frame");
+ frame.setLayout (new BorderLayout ());
+ frame.add(panel,"South");
+ frame.pack();
+ frame.setVisible(true);
+
+ t = new Thread (() -> {
+ if (start) {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException ex) {}
+ frame.dispose();
+ }
+ });
+ }
+
+ public static synchronized void pass() {
+ testPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ public static synchronized void fail() {
+ testPassed = false;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ private static void doTest(Runnable action) {
+ String description
+ = " A Frame with PageDialog Button is shown. Press PageDialog.\n"
+ + " A page dialog will be shown. Do not press any button.\n"
+ + " After 5 secs the frame along with this page dialog will be disposed.\n"
+ + " If the page dialog is not disposed, press FAIL else press PASS";
+
+ final JDialog dialog = new JDialog();
+ dialog.setTitle("printSelectionTest");
+ JTextArea textArea = new JTextArea(description);
+ textArea.setEditable(false);
+ final JButton testButton = new JButton("Start Test");
+ final JButton passButton = new JButton("PASS");
+ passButton.setEnabled(false);
+ passButton.addActionListener((e) -> {
+ dialog.dispose();
+ pass();
+ });
+ final JButton failButton = new JButton("FAIL");
+ failButton.setEnabled(false);
+ failButton.addActionListener((e) -> {
+ dialog.dispose();
+ fail();
+ });
+ testButton.addActionListener((e) -> {
+ testButton.setEnabled(false);
+ action.run();
+ passButton.setEnabled(true);
+ failButton.setEnabled(true);
+ });
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(textArea, BorderLayout.CENTER);
+ JPanel buttonPanel = new JPanel(new FlowLayout());
+ buttonPanel.add(testButton);
+ buttonPanel.add(passButton);
+ buttonPanel.add(failButton);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialog.add(mainPanel);
+ dialog.pack();
+ dialog.setVisible(true);
+ dialog.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ System.out.println("main dialog closing");
+ testGeneratedInterrupt = false;
+ mainThread.interrupt();
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/TestPrintDlgFrameAssociation.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 7064425 6948907
+ * @summary Verifies if owner Frame is associated with print dialog of PrinterJob
+ * @run main/manual TestPrintDlgFrameAssociation
+ */
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class TestPrintDlgFrameAssociation {
+ private static Thread mainThread;
+ private static boolean testPassed;
+ private static boolean testGeneratedInterrupt;
+ private static Button print;
+ private static Frame frame;
+ private static boolean start;
+ private static Thread t;
+
+ public static void main(String args[]) throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ doTest(TestPrintDlgFrameAssociation::frameTest);
+ });
+ mainThread = Thread.currentThread();
+ try {
+ Thread.sleep(60000);
+ } catch (InterruptedException e) {
+ if (!testPassed && testGeneratedInterrupt) {
+ throw new RuntimeException("Print dialog not disposed."
+ + " Print dialog is not associated with owner Frame`");
+ }
+ }
+ if (!testGeneratedInterrupt) {
+ throw new RuntimeException("user has not executed the test");
+ }
+ }
+
+ private static void frameTest() {
+ Panel panel =new Panel();
+
+ print = new Button("PrintDialog");
+ print.setActionCommand("PrintDialog");
+ print.addActionListener((e) -> {
+ PrinterJob job = PrinterJob.getPrinterJob();
+ PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
+ t.start();
+ start = true;
+ job.printDialog(aset);
+ });
+
+ panel.add(print);
+
+ frame = new Frame("Test Frame");
+ frame.setLayout (new BorderLayout ());
+ frame.add(panel,"South");
+ frame.pack();
+ frame.setVisible(true);
+
+ t = new Thread (() -> {
+ if (start) {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException ex) {}
+ frame.dispose();
+ }
+ });
+ }
+
+ public static synchronized void pass() {
+ testPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ public static synchronized void fail() {
+ testPassed = false;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ private static void doTest(Runnable action) {
+ String description
+ = " A Frame with PrintDialog Button is shown. Press PrintDialog.\n"
+ + " A print dialog will be shown. Do not press any button.\n"
+ + " After 5 secs the frame along with this print dialog will be disposed.\n"
+ + " If the print dialog is not disposed, press FAIL else press PASS";
+
+ final JDialog dialog = new JDialog();
+ dialog.setTitle("printSelectionTest");
+ JTextArea textArea = new JTextArea(description);
+ textArea.setEditable(false);
+ final JButton testButton = new JButton("Start Test");
+ final JButton passButton = new JButton("PASS");
+ passButton.setEnabled(false);
+ passButton.addActionListener((e) -> {
+ dialog.dispose();
+ pass();
+ });
+ final JButton failButton = new JButton("FAIL");
+ failButton.setEnabled(false);
+ failButton.addActionListener((e) -> {
+ dialog.dispose();
+ fail();
+ });
+ testButton.addActionListener((e) -> {
+ testButton.setEnabled(false);
+ action.run();
+ passButton.setEnabled(true);
+ failButton.setEnabled(true);
+ });
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(textArea, BorderLayout.CENTER);
+ JPanel buttonPanel = new JPanel(new FlowLayout());
+ buttonPanel.add(testButton);
+ buttonPanel.add(passButton);
+ buttonPanel.add(failButton);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialog.add(mainPanel);
+ dialog.pack();
+ dialog.setVisible(true);
+ dialog.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ System.out.println("main dialog closing");
+ testGeneratedInterrupt = false;
+ mainThread.interrupt();
+ }
+ });
+ }
+}
--- a/jdk/test/java/net/URLClassLoader/definePackage/SplitPackage.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/net/URLClassLoader/definePackage/SplitPackage.java Wed Sep 21 09:29:30 2016 -0700
@@ -27,6 +27,7 @@
* @summary Test two URLClassLoader define Package object of the same name
* @library /lib/testlibrary
* @build CompilerUtils
+ * @modules jdk.compiler
* @run testng SplitPackage
*/
--- a/jdk/test/java/net/URLPermission/nstest/LookupTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/net/URLPermission/nstest/LookupTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -37,6 +37,7 @@
String url, boolean throwsSecException, boolean throwsIOException)
{
try {
+ ProxySelector.setDefault(null);
URL u = new URL(url);
System.err.println ("Connecting to " + u);
URLConnection urlc = u.openConnection();
@@ -71,7 +72,7 @@
System.out.print(port);
} else if (cmd.equals("-runtest")) {
port = Integer.parseInt(args[1]);
- String hostsFileName = System.getProperty("test.src", ".") + "/LookupTestHosts";
+ String hostsFileName = System.getProperty("user.dir", ".") + "/LookupTestHosts";
System.setProperty("jdk.net.hosts.file", hostsFileName);
addMappingToHostsFile("allowedAndFound.com", "127.0.0.1", hostsFileName, false);
addMappingToHostsFile("notAllowedButFound.com", "99.99.99.99", hostsFileName, true);
--- a/jdk/test/java/net/URLPermission/nstest/LookupTestHosts Fri Sep 16 10:57:21 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-127.0.0.1 allowedAndFound.com
-99.99.99.99 notAllowedButFound.com
--- a/jdk/test/java/net/URLPermission/nstest/lookup.sh Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/net/URLPermission/nstest/lookup.sh Wed Sep 21 09:29:30 2016 -0700
@@ -48,6 +48,7 @@
grant {
permission java.net.URLPermission "http://allowedAndFound.com:${port}/-", "*:*";
permission java.net.URLPermission "http://allowedButNotfound.com:${port}/-", "*:*";
+ permission java.net.NetPermission "setProxySelector";
permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
permission java.util.PropertyPermission "java.io.tmpdir", "read";
--- a/jdk/test/java/net/httpclient/HeadersTest1.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/net/httpclient/HeadersTest1.java Wed Sep 21 09:29:30 2016 -0700
@@ -23,9 +23,11 @@
* questions.
*/
-/**
+/*
* @test
* @bug 8153142
+ * @modules java.httpclient
+ * jdk.httpserver
* @run main/othervm HeadersTest1
* @summary HeadersTest1
*/
@@ -39,9 +41,11 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
-import java.net.PasswordAuthentication;
import java.net.URI;
-import java.net.http.*;
+import java.net.http.HttpClient;
+import java.net.http.HttpHeaders;
+import java.net.http.HttpResponse;
+import java.net.http.HttpRequest;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.List;
--- a/jdk/test/java/net/httpclient/ProxyAuthTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/net/httpclient/ProxyAuthTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @test
* @bug 8163561
* @modules java.base/sun.net.www
+ * java.httpclient
* @summary Verify that Proxy-Authenticate header is correctly handled
*
* @run main/othervm ProxyAuthTest
--- a/jdk/test/java/net/httpclient/whitebox/Driver.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/net/httpclient/whitebox/Driver.java Wed Sep 21 09:29:30 2016 -0700
@@ -24,5 +24,6 @@
/*
* @test
* @bug 8151299
+ * @modules java.httpclient
* @run testng java.httpclient/java.net.http.SelectorTest
*/
--- a/jdk/test/java/util/Currency/ValidateISO4217.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/util/Currency/ValidateISO4217.java Wed Sep 21 09:29:30 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
* @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759
- * 8039317 8074350 8074351
+ * 8039317 8074350 8074351 8145952
* @summary Validate ISO 4217 data for Currency class.
*/
@@ -93,7 +93,7 @@
/* Codes that are obsolete, do not have related country */
static final String otherCodes =
- "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-CHE-CHW-CLF-COU-CUC-CYP-DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LUF-MGF-MTL-MXV-MZM-NLG-PTE-ROL-RUR-SDD-SIT-SKK-SRG-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-YUM-ZMK-ZWD-ZWN-ZWR";
+ "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LUF-MGF-MTL-MXV-MZM-NLG-PTE-ROL-RUR-SDD-SIT-SKK-SRG-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-YUM-ZMK-ZWD-ZWN-ZWR";
static boolean err = false;
--- a/jdk/test/java/util/Currency/tablea1.txt Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/java/util/Currency/tablea1.txt Wed Sep 21 09:29:30 2016 -0700
@@ -1,12 +1,12 @@
#
#
-# Amendments up until ISO 4217 AMENDMENT NUMBER 160
-# (As of 19 June 2015)
+# Amendments up until ISO 4217 AMENDMENT NUMBER 162
+# (As of 30 Auguest 2016)
#
# Version
FILEVERSION=3
-DATAVERSION=160
+DATAVERSION=162
# ISO 4217 currency data
AF AFN 971 2
@@ -28,7 +28,7 @@
BH BHD 48 3
BD BDT 50 2
BB BBD 52 2
-BY BYR 974 0
+BY BYN 933 2
BE EUR 978 2
BZ BZD 84 2
BJ XOF 952 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/ReadAbortTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @bug 4924727
+ * @summary Test verifies that if we call ImageReader.abort() in
+ * IIOReadProgressListener.imageStarted() or
+ * IIOReadProgressListener.imageProgress() are we
+ * calling IIOReadProgressListener.readAborted() for all readers.
+ * @run main ReadAbortTest
+ */
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.util.Iterator;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.event.IIOReadProgressListener;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.nio.file.Files;
+
+public class ReadAbortTest implements IIOReadProgressListener {
+
+ ImageReader reader = null;
+ ImageInputStream iis = null;
+ BufferedImage bimg = null;
+ File file;
+ boolean startAbort = false;
+ boolean startAborted = false;
+ boolean progressAbort = false;
+ boolean progressAborted = false;
+ Color srccolor = Color.red;
+ int width = 100;
+ int heght = 100;
+
+ public ReadAbortTest(String format) throws Exception {
+ try {
+ System.out.println("Test for format " + format);
+ bimg = new BufferedImage(width, heght,
+ BufferedImage.TYPE_INT_RGB);
+
+ Graphics2D g = bimg.createGraphics();
+ g.setColor(srccolor);
+ g.fillRect(0, 0, width, heght);
+ g.dispose();
+
+ file = File.createTempFile("src_", "." + format, new File("."));
+ ImageIO.write(bimg, format, file);
+ ImageInputStream iis = ImageIO.createImageInputStream(file);
+
+ Iterator iter = ImageIO.getImageReaders(iis);
+ while (iter.hasNext()) {
+ reader = (ImageReader) iter.next();
+ break;
+ }
+ reader.setInput(iis);
+ reader.addIIOReadProgressListener(this);
+
+ // Abort reading in IIOReadProgressListener.imageStarted().
+ startAbort = true;
+ bimg = reader.read(0);
+ startAbort = false;
+
+ // Abort reading in IIOReadProgressListener.imageProgress().
+ progressAbort = true;
+ bimg = reader.read(0);
+ progressAbort = false;
+
+ iis.close();
+ /*
+ * All abort requests from imageStarted,imageProgress and
+ * imageComplete from IIOReadProgressListener should be reached
+ * otherwise throw RuntimeException.
+ */
+ if (!(startAborted
+ && progressAborted)) {
+ throw new RuntimeException("All IIOReadProgressListener abort"
+ + " requests are not processed for format "
+ + format);
+ }
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ Files.delete(file.toPath());
+ }
+ }
+
+ /*
+ * Abstract methods that we need to implement from
+ * IIOReadProgressListener, and relevant for this test case.
+ */
+ @Override
+ public void imageStarted(ImageReader source, int imageIndex) {
+ System.out.println("imageStarted called");
+ if (startAbort) {
+ source.abort();
+ }
+ }
+
+ @Override
+ public void imageProgress(ImageReader source, float percentageDone) {
+ System.out.println("imageProgress called");
+ if (progressAbort) {
+ source.abort();
+ }
+ }
+
+ @Override
+ public void readAborted(ImageReader source) {
+ System.out.println("readAborted called");
+ // Verify IIOReadProgressListener.imageStarted() abort request.
+ if (startAbort) {
+ System.out.println("imageStarted aborted ");
+ startAborted = true;
+ }
+
+ // Verify IIOReadProgressListener.imageProgress() abort request.
+ if (progressAbort) {
+ System.out.println("imageProgress aborted ");
+ progressAborted = true;
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ final String[] formats = {"bmp", "png", "gif", "jpg", "tif"};
+ for (String format : formats) {
+ new ReadAbortTest(format);
+ }
+ }
+
+ /*
+ * Remaining abstract methods that we need to implement from
+ * IIOReadProgressListener, but not relevant for this test case.
+ */
+ @Override
+ public void imageComplete(ImageReader source) {
+ }
+
+ @Override
+ public void sequenceStarted(ImageReader reader, int i) {
+ }
+
+ @Override
+ public void sequenceComplete(ImageReader reader) {
+ }
+
+ @Override
+ public void thumbnailStarted(ImageReader reader, int i, int i1) {
+ }
+
+ @Override
+ public void thumbnailProgress(ImageReader reader, float f) {
+ }
+
+ @Override
+ public void thumbnailComplete(ImageReader reader) {
+ }
+}
+
--- a/jdk/test/javax/swing/JColorChooser/Test7194184.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/javax/swing/JColorChooser/Test7194184.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,19 +25,15 @@
* Portions Copyright (c) 2012 IBM Corporation
*/
-/*
- * @test
- * @key headful
- * @bug 7194184
+/* @test
+ @key headful
+ * @bug 7194184 8163274
* @summary Tests JColorChooser Swatch keyboard accessibility.
- * @author Sean Chou
* @library ../regtesthelpers
* @build Util
- * @run main Test7194184
+ * @run main/timeout=500 Test7194184
*/
-
import java.awt.Component;
-import java.awt.AWTException;
import java.awt.Color;
import java.awt.Robot;
import java.awt.event.KeyEvent;
@@ -46,66 +42,81 @@
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
-import java.util.concurrent.Callable;
+public class Test7194184 {
-public class Test7194184 implements Runnable {
private static JFrame frame;
private static JColorChooser colorChooser;
- private static Color selectedColor;
+ private static Color testColor;
+ private static Color newColor;
+
+ private static Robot robot;
public static void main(String[] args) throws Exception {
- testKeyBoardAccess();
+ robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+ createUI();
+ accessRecentSwatch();
+ runRobot();
+ testColorChooser();
+ cleanUpUI();
}
- private static void testKeyBoardAccess() throws Exception {
- Robot robot = new Robot();
-
- SwingUtilities.invokeLater(new Test7194184());
- robot.waitForIdle();
-
+ private static void createUI() throws Exception {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- selectedColor = colorChooser.getColor();
+ String title = getClass().getName();
+ frame = new JFrame(title);
+ colorChooser = new JColorChooser();
+ frame.add(colorChooser);
+ frame.pack();
+ frame.setVisible(true);
+ }
+ });
+ }
+ private static void accessRecentSwatch() throws Exception {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
Component recentSwatchPanel = Util.findSubComponent(colorChooser, "RecentSwatchPanel");
if (recentSwatchPanel == null) {
throw new RuntimeException("RecentSwatchPanel not found");
}
recentSwatchPanel.requestFocusInWindow();
+ testColor = colorChooser.getColor();
+
}
});
+ }
- robot.waitForIdle();
-
+ private static void runRobot() {
// Tab to move the focus to MainSwatch
Util.hitKeys(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
-
// Select the color on right
Util.hitKeys(robot, KeyEvent.VK_RIGHT);
Util.hitKeys(robot, KeyEvent.VK_RIGHT);
Util.hitKeys(robot, KeyEvent.VK_SPACE);
- robot.waitForIdle();
+ }
+ private static void testColorChooser() throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
- frame.dispose();
- if (selectedColor == colorChooser.getColor()) {
+ newColor = colorChooser.getColor();
+ if (newColor == testColor) {
throw new RuntimeException("JColorChooser misses keyboard accessibility");
}
}
});
}
- public void run() {
- String title = getClass().getName();
- frame = new JFrame(title);
- colorChooser = new JColorChooser();
-
- frame.add(colorChooser);
- frame.pack();
- frame.setVisible(true);
+ private static void cleanUpUI() throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ frame.dispose();
+ }
+ });
}
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JSlider/SliderTick/SliderTickTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @bug 8009477
+ * @summary Verify PageUp/PageDown key moves slider to Next/Previous minor tick.
+ * @run main/manual SliderTickTest
+ */
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.util.concurrent.CountDownLatch;
+import javax.swing.BorderFactory;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.concurrent.TimeUnit;
+import javax.swing.JSlider;
+
+public class SliderTickTest {
+
+ public static void main(String args[]) throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ TestUI test = new TestUI(latch);
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ test.createUI();
+ } catch (Exception ex) {
+ throw new RuntimeException("Exception while creating UI");
+ }
+ }
+ });
+
+ boolean status = latch.await(5, TimeUnit.MINUTES);
+
+ if (!status) {
+ System.out.println("Test timed out.");
+ }
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ test.disposeUI();
+ } catch (Exception ex) {
+ throw new RuntimeException("Exception while disposing UI");
+ }
+ }
+ });
+
+ if (test.testResult == false) {
+ throw new RuntimeException("Test Failed.");
+ }
+ }
+}
+
+class TestUI {
+
+ private static JFrame mainFrame;
+ private static JPanel mainControlPanel;
+
+ private static JTextArea instructionTextArea;
+
+ private static JPanel resultButtonPanel;
+ private static JButton passButton;
+ private static JButton failButton;
+
+ private static GridBagLayout layout;
+ private final CountDownLatch latch;
+ public boolean testResult = false;
+
+ public TestUI(CountDownLatch latch) throws Exception {
+ this.latch = latch;
+ }
+
+ public final void createUI() throws Exception {
+
+ mainFrame = new JFrame("SliderTickTest");
+
+ layout = new GridBagLayout();
+ mainControlPanel = new JPanel(layout);
+ resultButtonPanel = new JPanel(layout);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ // Create Test instructions
+ String instructions
+ = "INSTRUCTIONS:"
+ + "\n Click PageUp/PageDown key. If the slider indicator"
+ + "\n moves to Next/Previous immediate minor tick, then "
+ + "\n test passes else failed.";
+
+ instructionTextArea = new JTextArea();
+ instructionTextArea.setText(instructions);
+ instructionTextArea.setEnabled(false);
+ instructionTextArea.setDisabledTextColor(Color.black);
+ instructionTextArea.setBackground(Color.white);
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(instructionTextArea, gbc);
+
+ JSlider slider = new JSlider(0, 50);
+ slider.setMajorTickSpacing(10);
+ slider.setMinorTickSpacing(2);
+ slider.setPaintTicks(true);
+ slider.setPaintLabels(true);
+ slider.setValue(30);
+ slider.setBorder(BorderFactory.createTitledBorder("Ticks"));
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ mainControlPanel.add(slider, gbc);
+
+ passButton = new JButton("Pass");
+ passButton.setActionCommand("Pass");
+ passButton.addActionListener((ActionEvent e) -> {
+ testResult = true;
+ mainFrame.dispose();
+ latch.countDown();
+
+ });
+ failButton = new JButton("Fail");
+ failButton.setActionCommand("Fail");
+ failButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ testResult = false;
+ mainFrame.dispose();
+ latch.countDown();
+ }
+ });
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ resultButtonPanel.add(passButton, gbc);
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ resultButtonPanel.add(failButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy = 2;
+ mainControlPanel.add(resultButtonPanel, gbc);
+
+ mainFrame.add(mainControlPanel);
+ mainFrame.pack();
+ mainFrame.setVisible(true);
+ }
+
+ public void disposeUI() {
+ mainFrame.setVisible(false);
+ mainFrame.dispose();
+ }
+}
--- a/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentPerPixelTranslucentGradient.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentPerPixelTranslucentGradient.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,6 +25,7 @@
/*
* @test
+ * @bug 8144735
* @key headful
* @summary Check if a per-pixel translucent and translucent window is dragged
* and resized by mouse correctly
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/metal/MetalGradient/8163193/ButtonGradientTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,134 @@
+/*
+ * 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 java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.image.BufferedImage;
+import java.util.List;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+
+/*
+ * @test
+ * @bug 8163193
+ * @key headful
+ * @summary Metal L&F gradient is lighter on HiDPI display
+ * @run main/othervm -Dsun.java2d.uiScale=2 ButtonGradientTest
+ */
+public class ButtonGradientTest {
+
+ private static JFrame frame;
+ private static JButton button;
+
+ public static void main(String[] args) throws Exception {
+ try {
+ testGradient();
+ } finally {
+ SwingUtilities.invokeAndWait(() -> {
+ if (frame != null) {
+ frame.dispose();
+ }
+ });
+ }
+ }
+
+ private static void testGradient() throws Exception {
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+
+ SwingUtilities.invokeAndWait(ButtonGradientTest::createAndShowGUI);
+ robot.waitForIdle();
+
+ Rectangle rect = getButtonBounds();
+ List<?> gradient = (List) UIManager.get("Button.gradient");
+ float ratio = ((Number) gradient.get(0)).floatValue();
+ Color c1 = (Color) gradient.get(2);
+ Color c2 = (Color) gradient.get(3);
+ int mid = (int) (ratio * rect.height);
+
+ Color gradientColor = getGradientColor(rect.width, mid, c1, c2);
+ int x = rect.x + rect.width / 2;
+ int y = rect.y + mid / 2;
+ Color buttonColor = robot.getPixelColor(x, y);
+
+ if (!similarColors(buttonColor, gradientColor)) {
+ throw new RuntimeException("Button gradient is changed!");
+ }
+ }
+
+ private static void createAndShowGUI() {
+
+ try {
+ UIManager.setLookAndFeel(new MetalLookAndFeel());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ frame = new JFrame();
+ frame.setSize(300, 300);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JPanel panel = new JPanel(new BorderLayout());
+ button = new JButton("");
+ panel.add(button);
+ frame.getContentPane().add(panel);
+ frame.setVisible(true);
+ }
+
+ private static Rectangle getButtonBounds() throws Exception {
+ Rectangle[] rectangles = new Rectangle[1];
+ SwingUtilities.invokeAndWait(() -> {
+ rectangles[0] = button.getBounds();
+ rectangles[0].setLocation(button.getLocationOnScreen());
+ });
+ return rectangles[0];
+ }
+
+ private static Color getGradientColor(int w, int h, Color c1, Color c2) {
+ GradientPaint gradient = new GradientPaint(0, 0, c1, 0, h, c2, true);
+ BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = img.createGraphics();
+ g.setPaint(gradient);
+ g.fillRect(0, 0, w, h);
+ g.dispose();
+ return new Color(img.getRGB(w / 2, h / 2));
+ }
+
+ private static boolean similarColors(Color c1, Color c2) {
+ return similar(c1.getRed(), c2.getRed())
+ && similar(c1.getGreen(), c2.getGreen())
+ && similar(c1.getBlue(), c2.getBlue());
+ }
+
+ private static boolean similar(int i1, int i2) {
+ return Math.abs(i2 - i1) < 7;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/DevanagariEditor.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8151725
+ * @summary Tests no exception creating a JEditorPane with Devanagari
+ */
+
+import javax.swing.JEditorPane;
+
+public class DevanagariEditor {
+ public static void main(String[] args) {
+ new JEditorPane().setText("\u0930\u093E\u0915\u094D\u0937\u0938");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/GlyphPainter2/6427244/bug6427244.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/* @test
+ @bug 6427244 8144240
+ @summary Test that pressing HOME correctly moves caret in I18N document.
+ @author Sergey Groznyh
+ @library ../../../regtesthelpers
+ @build JRobot Util TestCase
+ @run main bug6427244
+*/
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Shape;
+import java.awt.event.KeyEvent;
+import javax.swing.JFrame;
+import javax.swing.JTextPane;
+import javax.swing.SwingUtilities;
+import javax.swing.text.Position;
+
+public class bug6427244 extends TestCase {
+ private static final JRobot ROBOT = JRobot.getRobot();
+
+ final static int TP_SIZE = 200;
+ final static String[] SPACES = new String[] {
+ "\u0020", // ASCII space
+ "\u2002", // EN space
+ "\u2003", // EM space
+ "\u2004", // THREE-PER-EM space
+ "\u2005", // ... etc.
+ "\u2006",
+ //"\u2007",
+ "\u2008",
+ "\u2009",
+ "\u200a",
+ "\u200b",
+ "\u205f",
+ "\u3000",
+ };
+ final static String[] WORDS = new String[] {
+ "It", "is", "a", "long", "paragraph", "for", "testing", "GlyphPainter2\n\n",
+ };
+
+ public static void main(String[] args) {
+ bug6427244 t = new bug6427244();
+ for (String space: SPACES) {
+ t.init(space);
+ t.runAllTests();
+ }
+
+ System.out.println("OK");
+ }
+
+ void init(final String space) {
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ String text = null;
+ for (String word: WORDS) {
+ if (text == null) {
+ text = "";
+ } else {
+ text += space;
+ }
+ text += word;
+ }
+ tp = new JTextPane();
+ tp.setText(text +
+ "Some arabic: \u062a\u0641\u0627\u062d and some not.");
+ if (jf == null) {
+ jf = new JFrame();
+ jf.setTitle("bug6427244");
+ jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ jf.setSize(TP_SIZE, TP_SIZE);
+ jf.setVisible(true);
+ }
+ Container c = jf.getContentPane();
+ c.removeAll();
+ c.add(tp);
+ c.invalidate();
+ c.validate();
+ dim = c.getSize();
+ }
+ });
+ Util.blockTillDisplayed(tp);
+ ROBOT.waitForIdle();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public void testCaretPosition() {
+ Point p = tp.getLocationOnScreen();
+ // the right-top corner position
+ p.x += (dim.width - 5);
+ p.y += 5;
+ ROBOT.mouseMove(p.x, p.y);
+ ROBOT.clickMouse();
+ ROBOT.hitKey(KeyEvent.VK_HOME);
+ ROBOT.waitForIdle();
+ // this will fail if caret moves out of the 1st line.
+ assertEquals(0, getCaretOrdinate());
+ }
+
+ int getCaretOrdinate() {
+ final int[] y = new int[1];
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ Shape s;
+ try {
+ s = tp.getUI().getRootView(tp).modelToView(
+ tp.getCaretPosition(), tp.getBounds(),
+ Position.Bias.Forward);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ y[0] = s.getBounds().y;
+ }
+ });
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return y[0];
+ }
+
+ JFrame jf;
+ JTextPane tp;
+ Dimension dim;
+}
--- a/jdk/test/jdk/nio/zipfs/jarfs/JFSTester.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/jdk/nio/zipfs/jarfs/JFSTester.java Wed Sep 21 09:29:30 2016 -0700
@@ -26,6 +26,7 @@
* @bug 8164389
* @summary walk entries in a jdk.nio.zipfs.JarFileSystem
* @modules jdk.jartool/sun.tools.jar
+ * jdk.zipfs
* @run testng JFSTester
*/
--- a/jdk/test/jprt.config Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/jprt.config Wed Sep 21 09:29:30 2016 -0700
@@ -82,15 +82,12 @@
fi
# Add basic solaris system paths
- path4sdk=/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin
+ path4sdk=/usr/bin:/usr/gnu/bin
# Find GNU make
- make=/usr/sfw/bin/gmake
+ make=/usr/bin/gmake
if [ ! -f ${make} ] ; then
- make=/opt/sfw/bin/gmake
- if [ ! -f ${make} ] ; then
- make=${slashjava}/devtools/${solaris_arch}/bin/gnumake
- fi
+ make=${slashjava}/devtools/${solaris_arch}/bin/gnumake
fi
fileMustExist "${make}" make
--- a/jdk/test/start-Xvfb.sh Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/start-Xvfb.sh Wed Sep 21 09:29:30 2016 -0700
@@ -59,9 +59,6 @@
/usr/bin/nohup /usr/bin/X11/Xvfb -fbdir ${currentDir} -pixdepths 8 16 24 32 ${DISPLAY} > ${currentDir}/nohup.$$ 2>&1 &
fi
WM="/usr/bin/X11/fvwm2"
-if [ ! -x ${WM} ] ; then
- WM="/opt/sfw/bin/fvwm2"
-fi
#
# Wait for Xvfb to initialize:
sleep 5
--- a/jdk/test/sun/security/smartcardio/README.txt Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/README.txt Wed Sep 21 09:29:30 2016 -0700
@@ -1,17 +1,17 @@
Rough hints for setting up MUSCLE on Solaris:
-Make sure you have libusb, usually in /usr/sfw:
+Make sure you have libusb, usually in /usr/lib:
-ls -l /usr/sfw/lib/libusb.so
-lrwxrwxrwx 1 root other 11 Jan 12 16:02 /usr/sfw/lib/libusb.so -> libusb.so.1
+ls -l /usr/lib/libusb.so
+lrwxrwxrwx 1 root other 11 Jan 12 16:02 /usr/lib/libusb.so -> libusb.so.1
Get PCSC and CCID.
-rwx------ 1 user staff 529540 Jun 16 18:24 ccid-1.0.1.tar.gz
-rwx------ 1 user staff 842654 Jun 16 18:24 pcsc-lite-1.3.1.tar.gz
Unpack pcsc
-Run ./configure --enable-libusb=/usr/sfw (??)
+Run ./configure --enable-libusb (??)
gnumake
Make /usr/local writeable for user
gnumake install
--- a/jdk/test/sun/security/smartcardio/TestChannel.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestChannel.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6239117
* @summary test logical channels work
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestChannel
*/
--- a/jdk/test/sun/security/smartcardio/TestConnect.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestConnect.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6293769 6294527 6309280
* @summary test connect() works
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestConnect
*/
--- a/jdk/test/sun/security/smartcardio/TestConnectAgain.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestConnectAgain.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6239117
* @summary test connect works correctly if called multiple times/card removed
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestConnectAgain
*/
--- a/jdk/test/sun/security/smartcardio/TestControl.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestControl.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6239117 6470320
* @summary test if transmitControlCommand() works
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestControl
*/
--- a/jdk/test/sun/security/smartcardio/TestDefault.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestDefault.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6327047
* @summary verify that TerminalFactory.getDefault() works
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestDefault
*/
--- a/jdk/test/sun/security/smartcardio/TestDirect.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestDirect.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,10 +21,11 @@
* questions.
*/
-/**
+/*
* @test
* @bug 8046343
* @summary Make sure that direct protocol is available
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestDirect
*/
--- a/jdk/test/sun/security/smartcardio/TestExclusive.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestExclusive.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6239117
* @summary verify that beginExclusive()/endExclusive() works
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestExclusive
*/
--- a/jdk/test/sun/security/smartcardio/TestMultiplePresent.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestMultiplePresent.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6239117 6445367
* @summary test that CardTerminals.waitForCard() works
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestMultiplePresent
*/
--- a/jdk/test/sun/security/smartcardio/TestPresent.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestPresent.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6293769 6294527
* @summary test that the isCardPresent()/waitForX() APIs work correctly
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestPresent
*/
--- a/jdk/test/sun/security/smartcardio/TestTransmit.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/smartcardio/TestTransmit.java Wed Sep 21 09:29:30 2016 -0700
@@ -21,11 +21,12 @@
* questions.
*/
-/**
+/*
* @test
* @bug 6293769 6294527
* @summary test transmit() works
* @author Andreas Sterbenz
+ * @modules java.smartcardio/javax.smartcardio
* @run main/manual TestTransmit
*/
--- a/jdk/test/sun/security/ssl/SocketCreation/SocketCreation.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/ssl/SocketCreation/SocketCreation.java Wed Sep 21 09:29:30 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -139,7 +139,7 @@
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
System.out.println("Server: Will call createServerSocket(int)");
- ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort);
+ ServerSocket sslServerSocket = sslssf.createServerSocket(0);
serverPort = sslServerSocket.getLocalPort();
System.out.println("Server: Will accept on SSL server socket...");
@@ -157,7 +157,7 @@
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
System.out.println("Server: Will call createServerSocket(int, int)");
- ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort,
+ ServerSocket sslServerSocket = sslssf.createServerSocket(0,
1);
serverPort = sslServerSocket.getLocalPort();
@@ -177,7 +177,7 @@
System.out.println("Server: Will call createServerSocket(int, " +
" int, InetAddress)");
- ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort,
+ ServerSocket sslServerSocket = sslssf.createServerSocket(0,
1,
InetAddress.getByName("localhost"));
serverPort = sslServerSocket.getLocalPort();
@@ -203,14 +203,15 @@
if (sslServerSocket.isBound())
throw new Exception("Server socket is already bound!");
- System.out.println("Server: Will bind SSL server socket to port " +
- serverPort + "...");
-
- sslServerSocket.bind(new java.net.InetSocketAddress(serverPort));
+ sslServerSocket.bind(new java.net.InetSocketAddress(0));
if (!sslServerSocket.isBound())
throw new Exception("Server socket is not bound!");
+ serverPort = sslServerSocket.getLocalPort();
+ System.out.println("Server: Bound SSL server socket to port " +
+ serverPort + "...");
+
serverReady = true;
System.out.println("Server: Will accept on SSL server socket...");
@@ -224,11 +225,10 @@
SSLSocketFactory sslsf =
(SSLSocketFactory) SSLSocketFactory.getDefault();
- System.out.println("Server: Will create normal server socket bound"
- + " to port " + serverPort + "...");
-
- ServerSocket ss = new ServerSocket(serverPort);
+ ServerSocket ss = new ServerSocket(0);
serverPort = ss.getLocalPort();
+ System.out.println("Server: Created normal server socket bound"
+ + " to port " + serverPort + "...");
System.out.println("Server: Will accept on server socket...");
serverReady = true;
Socket s = ss.accept();
--- a/jdk/test/sun/security/tools/keytool/KeyToolTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/security/tools/keytool/KeyToolTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -1761,7 +1761,7 @@
//PKCS#11 tests
// 1. sccs edit cert8.db key3.db
- //Runtime.getRuntime().exec("/usr/ccs/bin/sccs edit cert8.db key3.db");
+ //Runtime.getRuntime().exec("/usr/bin/sccs edit cert8.db key3.db");
testOK("", p11Arg + ("-storepass test12 -genkey -alias genkey" +
" -dname cn=genkey -keysize 512 -keyalg rsa"));
testOK("", p11Arg + "-storepass test12 -list");
@@ -1781,7 +1781,7 @@
testOK("", p11Arg + "-storepass test12 -list");
assertTrue(out.indexOf("Your keystore contains 0 entries") != -1);
//(check for empty database listing)
- //Runtime.getRuntime().exec("/usr/ccs/bin/sccs unedit cert8.db key3.db");
+ //Runtime.getRuntime().exec("/usr/bin/sccs unedit cert8.db key3.db");
remove("genkey.cert");
remove("genkey.certreq");
// 12. sccs unedit cert8.db key3.db
--- a/jdk/test/sun/text/resources/LocaleData Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/text/resources/LocaleData Wed Sep 21 09:29:30 2016 -0700
@@ -6403,8 +6403,8 @@
CurrencyNames//bif=Burundian Franc
CurrencyNames//bob=Bolivian Boliviano
CurrencyNames//btn=Bhutanese Ngultrum
-CurrencyNames//byb=Belarusian New Ruble (1994-1999)
-CurrencyNames//byr=Belarusian Ruble
+CurrencyNames//byb=Belarusian Ruble (1994-1999)
+CurrencyNames//byr=Belarusian Ruble (2000-2016)
CurrencyNames//cdf=Congolese Franc
CurrencyNames//clf=Chilean Unit of Account (UF)
CurrencyNames//cny=Chinese Yuan
@@ -6436,7 +6436,6 @@
CurrencyNames//mro=Mauritanian Ouguiya
CurrencyNames//mur=Mauritian Rupee
CurrencyNames//mvr=Maldivian Rufiyaa
-CurrencyNames//mwk=Malawian Kwacha
CurrencyNames//mxv=Mexican Investment Unit
CurrencyNames//mzm=Mozambican Metical (1980-2006)
CurrencyNames//mzn=Mozambican Metical
@@ -6444,7 +6443,6 @@
CurrencyNames//nio=Nicaraguan C\u00f3rdoba
CurrencyNames//nlg=Dutch Guilder
CurrencyNames//omr=Omani Rial
-CurrencyNames//pen=Peruvian Nuevo Sol
CurrencyNames//pgk=Papua New Guinean Kina
CurrencyNames//pkr=Pakistani Rupee
CurrencyNames//pyg=Paraguayan Guarani
@@ -8287,3 +8285,11 @@
# bug #8129361
CurrencyNames//hrk=Kuna
+
+# bug #8164784
+CurrencyNames//mwk=Malawian Malawi Kwacha
+CurrencyNames//pen=Peruvian Sol
+
+# bug #8145952
+CurrencyNames//byn=Belarusian Ruble
+CurrencyNames/be_BY/BYN=\u0420\u0443\u0431
--- a/jdk/test/sun/text/resources/LocaleDataTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/sun/text/resources/LocaleDataTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -37,7 +37,7 @@
* 7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509
* 7114053 7074882 7040556 8008577 8013836 8021121 6192407 6931564 8027695
* 8017142 8037343 8055222 8042126 8074791 8075173 8080774 8129361 8134916
- * 8145136
+ * 8145136 8145952 8164784
* @summary Verify locale data
* @modules java.base/sun.util.resources
* @modules jdk.localedata
--- a/jdk/test/tools/launcher/RunpathTest.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/tools/launcher/RunpathTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -40,7 +40,7 @@
}
final String findElfReader() {
- String[] paths = {"/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/ccs/bin"};
+ String[] paths = {"/usr/sbin", "/usr/bin"};
final String cmd = isSolaris ? "elfdump" : "readelf";
for (String x : paths) {
File p = new File(x);
--- a/jdk/test/tools/pack200/Pack200Test.java Fri Sep 16 10:57:21 2016 -0700
+++ b/jdk/test/tools/pack200/Pack200Test.java Wed Sep 21 09:29:30 2016 -0700
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6521334 6712743 8007902 8151901
+ * @requires (sun.arch.data.model == "64" & os.maxMemory >= 4g)
* @summary test general packer/unpacker functionality
* using native and java unpackers
* @compile -XDignore.symbol.file Utils.java Pack200Test.java
--- a/langtools/.hgtags Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/.hgtags Wed Sep 21 09:29:30 2016 -0700
@@ -378,3 +378,4 @@
7efa4b3477b2b93edbdb4abf827b74c6391f056e jdk-9+133
f08683786207a48b652266b3b7b908e6c863c3fc jdk-9+134
af5eb8f3ffd21288305a54ea177ffad75021a741 jdk-9+135
+c8f02f0ecbd7cd6700f47416e4b7e9d5ec20ad77 jdk-9+136
--- a/langtools/make/tools/crules/MutableFieldsAnalyzer.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/make/tools/crules/MutableFieldsAnalyzer.java Wed Sep 21 09:29:30 2016 -0700
@@ -105,12 +105,12 @@
"configurationClass", "resolveRequiresAndUsesMethod");
ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$Layer",
"layerClass", "bootMethod", "defineModulesWithOneLoaderMethod", "configurationMethod");
+ ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$Module",
+ "addExportsMethod", "addUsesMethod", "getModuleMethod", "getUnnamedModuleMethod");
ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$ServiceLoaderHelper",
"loadMethod");
ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$VMHelper",
"vmClass", "getRuntimeArgumentsMethod");
- ignoreFields("com.sun.tools.javac.util.ModuleHelper",
- "addExportsMethod", "getUnnamedModuleMethod", "getModuleMethod");
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Sep 21 09:29:30 2016 -0700
@@ -92,6 +92,7 @@
private final Attribute theUnfinishedDefaultValue;
private final boolean allowRepeatedAnnos;
+ private final String sourceName;
protected Annotate(Context context) {
context.put(annotateKey, this);
@@ -114,6 +115,7 @@
Source source = Source.instance(context);
allowRepeatedAnnos = source.allowRepeatedAnnotations();
+ sourceName = source.name;
}
/** Semaphore to delay annotation processing */
@@ -322,7 +324,7 @@
if (annotated.containsKey(a.type.tsym)) {
if (!allowRepeatedAnnos) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), "repeatable.annotations.not.supported.in.source");
+ log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), "repeatable.annotations.not.supported.in.source", sourceName);
}
ListBuffer<T> l = annotated.get(a.type.tsym);
l = l.append(c);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed Sep 21 09:29:30 2016 -0700
@@ -2256,6 +2256,12 @@
types.erasure(owner.enclClass().asType()));
}
+ boolean isProtectedInSuperClassOfEnclosingClassInOtherPackage() {
+ return ((tree.sym.flags() & PROTECTED) != 0 &&
+ tree.sym.packge() != owner.packge() &&
+ !owner.enclClass().isSubClass(tree.sym.owner, types));
+ }
+
/**
* Signature polymorphic methods need special handling.
* e.g. MethodHandle.invoke() MethodHandle.invokeExact()
@@ -2293,6 +2299,7 @@
needsVarArgsConversion() ||
isArrayOp() ||
isPrivateInOtherClass() ||
+ isProtectedInSuperClassOfEnclosingClassInOtherPackage() ||
!receiverAccessible() ||
(tree.getMode() == ReferenceMode.NEW &&
tree.kind != ReferenceKind.ARRAY_CTOR &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Sep 21 09:29:30 2016 -0700
@@ -78,6 +78,7 @@
import com.sun.tools.javac.util.JDK9Wrappers.Configuration;
import com.sun.tools.javac.util.JDK9Wrappers.Layer;
import com.sun.tools.javac.util.JDK9Wrappers.ModuleFinder;
+import com.sun.tools.javac.util.JDK9Wrappers.Module;
import com.sun.tools.javac.util.JDK9Wrappers.ServiceLoaderHelper;
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
@@ -957,6 +958,7 @@
public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
nullCheck(location);
nullCheck(service);
+ Module.getModule(getClass()).addUses(service);
if (location.isModuleLocation()) {
Collection<Path> paths = locations.getLocation(location);
ModuleFinder finder = ModuleFinder.of(paths.toArray(new Path[paths.size()]));
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Sep 21 09:29:30 2016 -0700
@@ -1232,7 +1232,7 @@
Chain exit = switchEnv.info.exit;
if (exit != null) {
code.resolve(exit);
- exit.state.defined.excludeFrom(code.nextreg);
+ exit.state.defined.excludeFrom(limit);
}
// If we have not set the default offset, we do so now.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Sep 21 09:29:30 2016 -0700
@@ -79,6 +79,7 @@
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.Iterators;
import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JDK9Wrappers.Module;
import com.sun.tools.javac.util.JavacMessages;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Log;
@@ -119,7 +120,6 @@
private final JavacTypes typeUtils;
private final JavaCompiler compiler;
private final Modules modules;
- private final ModuleHelper moduleHelper;
private final Types types;
/**
@@ -227,7 +227,6 @@
enter = Enter.instance(context);
initialCompleter = ClassFinder.instance(context).getCompleter();
chk = Check.instance(context);
- moduleHelper = ModuleHelper.instance(context);
initProcessorLoader();
defaultModule = source.allowModules() && options.isUnset("noModules")
@@ -265,7 +264,8 @@
? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
: fileManager.getClassLoader(CLASS_PATH);
- moduleHelper.addExports(processorClassLoader);
+ if (options.isSet("accessInternalAPI"))
+ ModuleHelper.addExports(Module.getModule(getClass()), Module.getUnnamedModule(processorClassLoader));
if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JDK9Wrappers.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JDK9Wrappers.java Wed Sep 21 09:29:30 2016 -0700
@@ -130,6 +130,85 @@
}
/**
+ * Wrapper class for java.lang.reflect.Module. To materialize a handle use the static factory
+ * methods Module#getModule(Class<?>) or Module#getUnnamedModule(ClassLoader).
+ */
+ public static class Module {
+
+ private final Object theRealModule;
+
+ private Module(Object module) {
+ this.theRealModule = module;
+ init();
+ }
+
+ public static Module getModule(Class<?> clazz) {
+ try {
+ init();
+ Object result = getModuleMethod.invoke(clazz, new Object[0]);
+ return new Module(result);
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
+ | SecurityException ex) {
+ throw new Abort(ex);
+ }
+ }
+
+ public static Module getUnnamedModule(ClassLoader classLoader) {
+ try {
+ init();
+ Object result = getUnnamedModuleMethod.invoke(classLoader, new Object[0]);
+ return new Module(result);
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
+ | SecurityException ex) {
+ throw new Abort(ex);
+ }
+ }
+
+ public Module addExports(String pn, Module other) {
+ try {
+ addExportsMethod.invoke(theRealModule, new Object[] { pn, other.theRealModule});
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new Abort(ex);
+ }
+ return this;
+ }
+
+ public Module addUses(Class<?> st) {
+ try {
+ addUsesMethod.invoke(theRealModule, new Object[] { st });
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new Abort(ex);
+ }
+ return this;
+ }
+
+ // -----------------------------------------------------------------------------------------
+ // on java.lang.reflect.Module
+ private static Method addExportsMethod = null;
+ // on java.lang.reflect.Module
+ private static Method addUsesMethod = null;
+ // on java.lang.Class
+ private static Method getModuleMethod;
+ // on java.lang.ClassLoader
+ private static Method getUnnamedModuleMethod;
+
+ private static void init() {
+ if (addExportsMethod == null) {
+ try {
+ Class<?> moduleClass = Class.forName("java.lang.reflect.Module", false, null);
+ addUsesMethod = moduleClass.getDeclaredMethod("addUses", new Class<?>[] { Class.class });
+ addExportsMethod = moduleClass.getDeclaredMethod("addExports",
+ new Class<?>[] { String.class, moduleClass });
+ getModuleMethod = Class.class.getDeclaredMethod("getModule", new Class<?>[0]);
+ getUnnamedModuleMethod = ClassLoader.class.getDeclaredMethod("getUnnamedModule", new Class<?>[0]);
+ } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) {
+ throw new Abort(ex);
+ }
+ }
+ }
+ }
+
+ /**
* Wrapper class for java.lang.module.Configuration.
*/
public static final class Configuration {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ModuleHelper.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ModuleHelper.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,88 +25,30 @@
package com.sun.tools.javac.util;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import com.sun.tools.javac.util.JDK9Wrappers.Module;
public class ModuleHelper {
- /** The context key for the module helper. */
- protected static final Context.Key<ModuleHelper> moduleHelperKey = new Context.Key<>();
-
- /** Get the JavaCompiler instance for this context. */
- public static ModuleHelper instance(Context context) {
- ModuleHelper instance = context.get(moduleHelperKey);
- if (instance == null)
- instance = new ModuleHelper(context);
- return instance;
- }
-
- public ModuleHelper(Context context) {
- context.put(moduleHelperKey, this);
- Options options = Options.instance(context);
- allowAccessToInternalAPI = options.isSet("accessInternalAPI");
- }
-
- final boolean allowAccessToInternalAPI;
- private void exportPackageToModule(String packageName, Object target)
- throws ClassNotFoundException, NoSuchMethodException, IllegalArgumentException,
- InvocationTargetException, IllegalAccessException {
- if (addExportsMethod == null) {
- Class<?> moduleClass = Class.forName("java.lang.reflect.Module");
- addExportsMethod = moduleClass.getDeclaredMethod("addExports",
- new Class<?>[] { String.class, moduleClass });
- }
- addExportsMethod.invoke(from, new Object[] { packageName, target });
- }
+ private static final String[] javacInternalPackages = new String[] {
+ "com.sun.tools.javac.api",
+ "com.sun.tools.javac.code",
+ "com.sun.tools.javac.comp",
+ "com.sun.tools.javac.file",
+ "com.sun.tools.javac.jvm",
+ "com.sun.tools.javac.main",
+ "com.sun.tools.javac.model",
+ "com.sun.tools.javac.parser",
+ "com.sun.tools.javac.platform",
+ "com.sun.tools.javac.processing",
+ "com.sun.tools.javac.tree",
+ "com.sun.tools.javac.util",
- static final String[] javacInternalPackages = new String[] {
- "com.sun.tools.javac.api",
- "com.sun.tools.javac.code",
- "com.sun.tools.javac.comp",
- "com.sun.tools.javac.file",
- "com.sun.tools.javac.jvm",
- "com.sun.tools.javac.main",
- "com.sun.tools.javac.model",
- "com.sun.tools.javac.parser",
- "com.sun.tools.javac.platform",
- "com.sun.tools.javac.processing",
- "com.sun.tools.javac.tree",
- "com.sun.tools.javac.util",
-
- "com.sun.tools.doclint",
+ "com.sun.tools.doclint",
};
- public void addExports(ClassLoader classLoader) {
- try {
- if (allowAccessToInternalAPI) {
- if (from == null) {
- if (getModuleMethod == null) {
- getModuleMethod = Class.class.getDeclaredMethod("getModule", new Class<?>[0]);
- }
- from = getModuleMethod.invoke(getClass(), new Object[0]);
- }
- if (getUnnamedModuleMethod == null) {
- getUnnamedModuleMethod = ClassLoader.class.getDeclaredMethod("getUnnamedModule", new Class<?>[0]);
- }
- Object target = getUnnamedModuleMethod.invoke(classLoader, new Object[0]);
- for (String pack: javacInternalPackages) {
- exportPackageToModule(pack, target);
- }
- }
- } catch (Exception e) {
- // do nothing
+ public static void addExports(Module from, Module to) {
+ for (String pack: javacInternalPackages) {
+ from.addExports(pack, to);
}
}
-
- // a module instance
- private Object from = null;
-
- // on java.lang.reflect.Module
- private static Method addExportsMethod = null;
-
- // on java.lang.ClassLoader
- private static Method getUnnamedModuleMethod = null;
-
- // on java.lang.Class
- private static Method getModuleMethod = null;
-}
+}
\ No newline at end of file
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Wed Sep 21 09:29:30 2016 -0700
@@ -263,18 +263,18 @@
if (ui.item.l !== noResult.l) {
var url = "";
if (ui.item.category === catModules) {
- url = "/" + ui.item.l + "-summary.html";
+ url = ui.item.l + "-summary.html";
} else if (ui.item.category === catPackages) {
url = ui.item.l.replace(/\./g, '/') + "/package-summary.html";
} else if (ui.item.category === catTypes) {
if (ui.item.p === "<Unnamed>") {
- url = "/" + ui.item.l + ".html";
+ url = ui.item.l + ".html";
} else {
url = ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html";
}
} else if (ui.item.category === catMembers) {
if (ui.item.p === "<Unnamed>") {
- url = "/" + ui.item.c + ".html" + "#";
+ url = ui.item.c + ".html" + "#";
} else {
url = ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#";
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/SwitchExitStateTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8160699
+ * @summary Verify that having finished executing a switch statement live locals are exactly the same as it was upon entry of the switch.
+ * @run main SwitchExitStateTest
+ */
+
+public class SwitchExitStateTest {
+ public static void main(String[] args) throws Exception {
+ switch (0) {
+ case 0:
+ String a = "";
+ break;
+ default:
+ throw new Exception("Unknown ");
+ }
+
+ switch (0) {
+ case 0:
+ String b = "";
+ break;
+ default:
+ throw new Exception("Unknown ");
+ }
+ }
+}
\ No newline at end of file
--- a/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java Fri Sep 16 10:57:21 2016 -0700
+++ b/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java Wed Sep 21 09:29:30 2016 -0700
@@ -106,12 +106,12 @@
// The following static fields are used for caches of information obtained
// by reflective lookup, to avoid explicit references that are not available
// when running javac on JDK 8.
- ignore("com/sun/tools/javac/util/ModuleHelper",
- "addExportsMethod", "getModuleMethod", "getUnnamedModuleMethod");
ignore("com/sun/tools/javac/util/JDK9Wrappers$Configuration",
"resolveRequiresAndUsesMethod", "configurationClass");
ignore("com/sun/tools/javac/util/JDK9Wrappers$Layer",
"bootMethod", "defineModulesWithOneLoaderMethod", "configurationMethod", "layerClass");
+ ignore("com/sun/tools/javac/util/JDK9Wrappers$Module",
+ "addExportsMethod", "addUsesMethod", "getModuleMethod", "getUnnamedModuleMethod");
ignore("com/sun/tools/javac/util/JDK9Wrappers$ModuleFinder",
"moduleFinderClass", "ofMethod");
ignore("com/sun/tools/javac/util/JDK9Wrappers$ServiceLoaderHelper",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongVersion.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8138822
+ * @summary test that only Java 8+ allows repeating annotations
+ * @compile WrongVersion.java
+ * @compile -Xlint:-options -source 8 WrongVersion.java
+ * @compile/fail/ref=WrongVersion7.out -XDrawDiagnostics -Xlint:-options -source 7 WrongVersion.java
+ * @compile/fail/ref=WrongVersion6.out -XDrawDiagnostics -Xlint:-options -source 6 WrongVersion.java
+ */
+import java.lang.annotation.Repeatable;
+
+@Ann(1) @Ann(2)
+class C {
+}
+
+@Repeatable(AnnContainer.class)
+@interface Ann {
+ int value();
+}
+
+@interface AnnContainer {
+ Ann[] value();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongVersion6.out Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,2 @@
+WrongVersion.java:12:9: compiler.err.repeatable.annotations.not.supported.in.source: 1.6
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongVersion7.out Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,2 @@
+WrongVersion.java:12:9: compiler.err.repeatable.annotations.not.supported.in.source: 1.7
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/ProtectedInaccessibleMethodRefTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8138667
+ * @summary Verify that javac emits suitable accessors when a method reference mentions a protected method that would need an accessor
+ * @run main ProtectedInaccessibleMethodRefTest
+ */
+
+
+import pack.SuperClass;
+
+import java.util.concurrent.Callable;
+
+public final class ProtectedInaccessibleMethodRefTest extends SuperClass {
+
+ static String message = "NOT OK";
+
+ public void doTest() throws Exception {
+ new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ final Runnable r = ProtectedInaccessibleMethodRefTest.this::myDo;
+ r.run();
+ return null;
+ }
+ }.call();
+
+ new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ final Runnable r = ProtectedInaccessibleMethodRefTest::myStaticDo;
+ r.run();
+ return null;
+ }
+ }.call();
+ }
+
+ public void message(String s) {
+ message = s;
+ }
+
+ public static void main(String[] args) throws Exception {
+ new ProtectedInaccessibleMethodRefTest().doTest();
+ if (!message.equals("OK!"))
+ throw new AssertionError("Unexpected output");
+ if (!sMessage.equals("OK!"))
+ throw new AssertionError("Unexpected output");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/pack/SuperClass.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+package pack;
+
+public class SuperClass {
+
+ public static String sMessage = "Not OK";
+
+ protected final void myDo() {
+ message("OK!");
+ }
+
+ protected static final void myStaticDo() {
+ sMessage = "OK!";
+ }
+
+ public void message(String s) {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/FileManagerGetServiceLoaderTest.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8164742
+ * @summary Test that jdk.compiler can materialize a service loader for arbitrary services
+ * @run main FileManagerGetServiceLoaderTest
+ */
+
+import javax.tools.*;
+
+public class FileManagerGetServiceLoaderTest {
+
+ public static void main(String... args) throws Exception {
+
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null);
+
+ /* FileManagerGetServiceLoaderTest.class is not really a service, but that is
+ immaterial to the test which just verifies addUses would have been called
+ so module boundary is not an issue for a class outside of jdk.compiler
+ */
+ java.util.ServiceLoader<?> loader = fm.getServiceLoader(StandardLocation.CLASS_PATH,
+ FileManagerGetServiceLoaderTest.class);
+ if (loader == null) {
+ throw new AssertionError("Could not obtain service loader");
+ }
+ }
+}
--- a/make/Images.gmk Fri Sep 16 10:57:21 2016 -0700
+++ b/make/Images.gmk Wed Sep 21 09:29:30 2016 -0700
@@ -75,11 +75,6 @@
# Param 1 - The file containing the MODULES list
define create-info-file
- $(call info-file-item, "JAVA_VERSION", "$(VERSION_NUMBER)")
- $(call info-file-item, "JAVA_FULL_VERSION", "$(VERSION_STRING)")
- $(call info-file-item, "OS_NAME", "$(REQUIRED_OS_NAME)")
- $(call info-file-item, "OS_VERSION", "$(REQUIRED_OS_VERSION)")
- $(call info-file-item, "OS_ARCH", "$(OPENJDK_TARGET_CPU_LEGACY)")
$(if $(JDK_ARCH_ABI_PROP_NAME), \
$(call info-file-item, "SUN_ARCH_ABI", "$(JDK_ARCH_ABI_PROP_NAME)"))
$(call info-file-item, "SOURCE", "$(strip $(ALL_SOURCE_TIPS))")
--- a/nashorn/.hgtags Fri Sep 16 10:57:21 2016 -0700
+++ b/nashorn/.hgtags Wed Sep 21 09:29:30 2016 -0700
@@ -369,3 +369,4 @@
3a924b820d02b108cf57b51e145b5150d1eedcca jdk-9+133
e05400ba935753c77697af936db24657eb811022 jdk-9+134
cb00d5ef023a18a66fcb4311ed4474d4145c66e9 jdk-9+135
+f11b8f5c4ccbf9c87d283815abac6c0117fba3c0 jdk-9+136
--- a/test/lib/jdk/test/lib/Utils.java Fri Sep 16 10:57:21 2016 -0700
+++ b/test/lib/jdk/test/lib/Utils.java Wed Sep 21 09:29:30 2016 -0700
@@ -25,7 +25,6 @@
import java.io.File;
import java.io.IOException;
-import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.ServerSocket;
@@ -51,7 +50,6 @@
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import jdk.internal.misc.Unsafe;
import static jdk.test.lib.Asserts.assertTrue;
import jdk.test.lib.process.ProcessTools;
@@ -87,9 +85,16 @@
*/
public static final String TEST_SRC = System.getProperty("test.src", "").trim();
- private static Unsafe unsafe = null;
+ /*
+ * Returns the value of 'test.jdk' system property
+ */
+ public static final String TEST_JDK = System.getProperty("test.jdk");
/**
+ * Returns the value of 'test.classes' system property
+ */
+ public static final String TEST_CLASSES = System.getProperty("test.classes", ".");
+ /**
* Defines property name for seed value.
*/
public static final String SEED_PROPERTY_NAME = "jdk.test.lib.random.seed";
@@ -373,21 +378,6 @@
return new String(Files.readAllBytes(filePath));
}
- /**
- * @return Unsafe instance.
- */
- public static synchronized Unsafe getUnsafe() {
- if (unsafe == null) {
- try {
- Field f = Unsafe.class.getDeclaredField("theUnsafe");
- f.setAccessible(true);
- unsafe = (Unsafe) f.get(null);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- throw new RuntimeException("Unable to get Unsafe instance.", e);
- }
- }
- return unsafe;
- }
private static final char[] hexArray = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/unsafe/UnsafeHelper.java Wed Sep 21 09:29:30 2016 -0700
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+package jdk.test.lib.unsafe;
+
+import jdk.internal.misc.Unsafe;
+import java.lang.reflect.Field;
+
+
+/**
+ * Helper class for accessing the jdk.internal.misc.Unsafe functionality
+ */
+public final class UnsafeHelper {
+ private static Unsafe unsafe = null;
+
+ /**
+ * @return Unsafe instance.
+ */
+ public static synchronized Unsafe getUnsafe() {
+ if (unsafe == null) {
+ try {
+ Field f = Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe) f.get(null);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new RuntimeException("Unable to get Unsafe instance.", e);
+ }
+ }
+ return unsafe;
+ }
+}
+