--- a/.hgtags Mon Jan 17 13:29:12 2011 +0530
+++ b/.hgtags Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
0ce0a2c3a6926677dc507839a820ab6625541e5a jdk7-b121
6f09ea1c034f087916d2a8cf0d22be768400118f jdk7-b122
142129d8599d1f56b29387e7f9a5fad53b6d61df jdk7-b123
+aa894c225b1a517b665ac2a58295217ea2245134 jdk7-b124
+f658ec2730fa29323c36d23c27e54c7219ef5e16 jdk7-b125
--- a/.hgtags-top-repo Mon Jan 17 13:29:12 2011 +0530
+++ b/.hgtags-top-repo Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
2c2d4f88637b488014c37e1a2eb401f68bca8838 jdk7-b121
f1591eed71f64f6eba79fb7426f5616cc4dfea73 jdk7-b122
ed6950da30cf1e8904b4bdb034d471647942271f jdk7-b123
+024a6755895bf91b5a3c98984c89ee018efbf538 jdk7-b124
+5c4df7e992775c102f08e9f1c0a124b324641b70 jdk7-b125
--- a/corba/.hgtags Mon Jan 17 13:29:12 2011 +0530
+++ b/corba/.hgtags Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
2cc9f32992101732b23730b737740e64ebc5fa89 jdk7-b121
1523a060032c8a5b7840198da8911abeff88118f jdk7-b122
a230c142628cea22475ab9dc5cd544266ddf2466 jdk7-b123
+f90b3e014e831eb4f32ef035a1dad2b8ba87949f jdk7-b124
+1ce58c72b7892cb813eb920276c7e7f17a1b79fe jdk7-b125
--- a/hotspot/.hgtags Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/.hgtags Wed Jan 19 19:00:30 2011 -0800
@@ -138,3 +138,6 @@
5484e7c53fa7da5e869902437ee08a9ae10c1c69 hs20-b03
9669f9b284108a9ee0a0ccbe215c37a130c9dcf5 jdk7-b123
9669f9b284108a9ee0a0ccbe215c37a130c9dcf5 hs20-b04
+0a8e0d4345b37b71ec49dda08ee03b68c4f1b592 jdk7-b124
+0a8e0d4345b37b71ec49dda08ee03b68c4f1b592 hs20-b05
+e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 jdk7-b125
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -99,15 +99,8 @@
long typeEntrySizeOffset;
long typeEntryArrayStride;
- typeEntryTypeNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset");
- typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset");
- typeEntryIsOopTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
- typeEntryIsIntegerTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
- typeEntryIsUnsignedOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
- typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
- typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
-
- // Fetch the address of the VMTypeEntry*
+ // Fetch the address of the VMTypeEntry*. We get this symbol first
+ // and try to use it to make sure that symbol lookup is working.
Address entryAddr = lookupInProcess("gHotSpotVMTypes");
// System.err.println("gHotSpotVMTypes address = " + entryAddr);
// Dereference this once to get the pointer to the first VMTypeEntry
@@ -118,6 +111,14 @@
throw new RuntimeException("gHotSpotVMTypes was not initialized properly in the remote process; can not continue");
}
+ typeEntryTypeNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset");
+ typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset");
+ typeEntryIsOopTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
+ typeEntryIsIntegerTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
+ typeEntryIsUnsignedOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
+ typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
+ typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
+
// Start iterating down it until we find an entry with no name
Address typeNameAddr = null;
do {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -122,10 +122,14 @@
private MemoizedObject[] sectionHeaders;
private MemoizedObject[] symbols;
+ // Init stringTable at decl time since other fields init'ed in the
+ // constructor need the String Table.
private MemoizedObject stringTable = new MemoizedObject() {
public Object computeValue() {
+ // the String Table follows the Symbol Table
int ptr = getPointerToSymbolTable();
if (ptr == 0) {
+ // no Symbol Table so no String Table
return new StringTable(0);
} else {
return new StringTable(ptr + SYMBOL_SIZE * getNumberOfSymbols());
@@ -140,6 +144,8 @@
timeDateStamp = readInt();
pointerToSymbolTable = readInt();
numberOfSymbols = readInt();
+ // String Table can be accessed at this point because
+ // pointerToSymbolTable and numberOfSymbols fields are set.
sizeOfOptionalHeader = readShort();
characteristics = readShort();
@@ -222,6 +228,8 @@
private MemoizedObject windowsSpecificFields;
private MemoizedObject dataDirectories;
+ // We use an offset of 2 because OptionalHeaderStandardFieldsImpl doesn't
+ // include the 'magic' field.
private static final int STANDARD_FIELDS_OFFSET = 2;
private static final int PE32_WINDOWS_SPECIFIC_FIELDS_OFFSET = 28;
private static final int PE32_DATA_DIRECTORIES_OFFSET = 96;
@@ -288,7 +296,7 @@
private int sizeOfUninitializedData;
private int addressOfEntryPoint;
private int baseOfCode;
- private int baseOfData;
+ private int baseOfData; // only set in PE32
OptionalHeaderStandardFieldsImpl(int offset,
boolean isPE32Plus) {
@@ -301,7 +309,8 @@
sizeOfUninitializedData = readInt();
addressOfEntryPoint = readInt();
baseOfCode = readInt();
- if (isPE32Plus) {
+ if (!isPE32Plus) {
+ // only available in PE32
baseOfData = readInt();
}
}
@@ -433,7 +442,10 @@
if (dir.getRVA() == 0 || dir.getSize() == 0) {
return null;
}
- return new ExportDirectoryTableImpl(rvaToFileOffset(dir.getRVA()), dir.getSize());
+ // ExportDirectoryTableImpl needs both the RVA and the
+ // RVA converted to a file offset.
+ return new
+ ExportDirectoryTableImpl(dir.getRVA(), dir.getSize());
}
};
@@ -526,6 +538,7 @@
}
class ExportDirectoryTableImpl implements ExportDirectoryTable {
+ private int exportDataDirRVA;
private int offset;
private int size;
@@ -548,8 +561,9 @@
private MemoizedObject exportOrdinalTable;
private MemoizedObject exportAddressTable;
- ExportDirectoryTableImpl(int offset, int size) {
- this.offset = offset;
+ ExportDirectoryTableImpl(int exportDataDirRVA, int size) {
+ this.exportDataDirRVA = exportDataDirRVA;
+ offset = rvaToFileOffset(exportDataDirRVA);
this.size = size;
seek(offset);
exportFlags = readInt();
@@ -595,6 +609,7 @@
exportOrdinalTable = new MemoizedObject() {
public Object computeValue() {
+ // number of ordinals is same as the number of name pointers
short[] ordinals = new short[getNumberOfNamePointers()];
seek(rvaToFileOffset(getOrdinalTableRVA()));
for (int i = 0; i < ordinals.length; i++) {
@@ -608,14 +623,18 @@
public Object computeValue() {
int[] addresses = new int[getNumberOfAddressTableEntries()];
seek(rvaToFileOffset(getExportAddressTableRVA()));
- // Must make two passes to avoid rvaToFileOffset
- // destroying seek() position
+ // The Export Address Table values are a union of two
+ // possible values:
+ // Export RVA - The address of the exported symbol when
+ // loaded into memory, relative to the image base.
+ // This value doesn't get converted into a file offset.
+ // Forwarder RVA - The pointer to a null-terminated ASCII
+ // string in the export section. This value gets
+ // converted into a file offset because we have to
+ // fetch the string.
for (int i = 0; i < addresses.length; i++) {
addresses[i] = readInt();
}
- for (int i = 0; i < addresses.length; i++) {
- addresses[i] = rvaToFileOffset(addresses[i]);
- }
return addresses;
}
};
@@ -648,11 +667,12 @@
public boolean isExportAddressForwarder(short ordinal) {
int addr = getExportAddress(ordinal);
- return ((offset <= addr) && (addr < (offset + size)));
+ return ((exportDataDirRVA <= addr) &&
+ (addr < (exportDataDirRVA + size)));
}
public String getExportAddressForwarder(short ordinal) {
- seek(getExportAddress(ordinal));
+ seek(rvaToFileOffset(getExportAddress(ordinal)));
return readCString();
}
@@ -3371,10 +3391,17 @@
throw new COFFException(e);
}
// Look up in string table
+ // FIXME: this index value is assumed to be in the valid range
name = getStringTable().get(index);
} else {
try {
- name = new String(tmpName, US_ASCII);
+ int length = 0;
+ // find last non-NULL
+ for (; length < tmpName.length && tmpName[length] != '\0';) {
+ length++;
+ }
+ // don't include NULL chars in returned name String
+ name = new String(tmpName, 0, length, US_ASCII);
} catch (UnsupportedEncodingException e) {
throw new COFFException(e);
}
@@ -3487,6 +3514,7 @@
tmpName[5] << 16 |
tmpName[6] << 8 |
tmpName[7]);
+ // FIXME: stringOffset is assumed to be in the valid range
name = getStringTable().getAtOffset(stringOffset);
}
@@ -3698,12 +3726,13 @@
StringTable(int offset) {
if (offset == 0) {
+ // no String Table
strings = new COFFString[0];
return;
}
seek(offset);
- int length = readInt();
+ int length = readInt(); // length includes itself
byte[] data = new byte[length - 4];
int numBytesRead = readBytes(data);
if (numBytesRead != data.length) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2010, 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,35 +37,48 @@
String filename = args[0];
COFFFile file = COFFFileParser.getParser().parse(filename);
- ExportDirectoryTable exports =
- file.getHeader().
- getOptionalHeader().
- getDataDirectories().
- getExportDirectoryTable();
+
+ // get common point for both things we want to dump
+ OptionalHeaderDataDirectories dataDirs = file.getHeader().getOptionalHeader().
+ getDataDirectories();
+
+ // dump the header data directory for the Export Table:
+ DataDirectory dir = dataDirs.getExportTable();
+ System.out.println("Export table: RVA = " + dir.getRVA() + "/0x" +
+ Integer.toHexString(dir.getRVA()) + ", size = " + dir.getSize() + "/0x" +
+ Integer.toHexString(dir.getSize()));
+
+ System.out.println(file.getHeader().getNumberOfSections() + " sections in file");
+ for (int i = 1; i <= file.getHeader().getNumberOfSections(); i++) {
+ SectionHeader sec = file.getHeader().getSectionHeader(i);
+ System.out.println(" Section " + i + ":");
+ System.out.println(" Name = '" + sec.getName() + "'");
+ System.out.println(" VirtualSize = " + sec.getSize() + "/0x" +
+ Integer.toHexString(sec.getSize()));
+ System.out.println(" VirtualAddress = " + sec.getVirtualAddress() + "/0x" +
+ Integer.toHexString(sec.getVirtualAddress()));
+ System.out.println(" SizeOfRawData = " + sec.getSizeOfRawData() + "/0x" +
+ Integer.toHexString(sec.getSizeOfRawData()));
+ System.out.println(" PointerToRawData = " + sec.getPointerToRawData() + "/0x" +
+ Integer.toHexString(sec.getPointerToRawData()));
+ }
+
+ ExportDirectoryTable exports = dataDirs.getExportDirectoryTable();
if (exports == null) {
System.out.println("No exports found.");
} else {
- System.out.println(file.getHeader().getNumberOfSections() + " sections in file");
- for (int i = 0; i < file.getHeader().getNumberOfSections(); i++) {
- System.out.println(" Section " + i + ": " + file.getHeader().getSectionHeader(1 + i).getName());
- }
-
- DataDirectory dir = file.getHeader().getOptionalHeader().getDataDirectories().getExportTable();
- System.out.println("Export table: RVA = 0x" + Integer.toHexString(dir.getRVA()) +
- ", size = 0x" + Integer.toHexString(dir.getSize()));
-
System.out.println("DLL name: " + exports.getDLLName());
System.out.println("Time/date stamp 0x" + Integer.toHexString(exports.getTimeDateStamp()));
System.out.println("Major version 0x" + Integer.toHexString(exports.getMajorVersion() & 0xFFFF));
System.out.println("Minor version 0x" + Integer.toHexString(exports.getMinorVersion() & 0xFFFF));
- System.out.println(exports.getNumberOfNamePointers() + " functions found");
+ System.out.println(exports.getNumberOfNamePointers() + " exports found");
for (int i = 0; i < exports.getNumberOfNamePointers(); i++) {
- System.out.println(" 0x" +
- Integer.toHexString(exports.getExportAddress(exports.getExportOrdinal(i))) +
- " " +
- (exports.isExportAddressForwarder(exports.getExportOrdinal(i)) ?
- ("Forwarded to " + exports.getExportAddressForwarder(exports.getExportOrdinal(i))) :
- exports.getExportName(i)));
+ short ordinal = exports.getExportOrdinal(i);
+ System.out.print("[" + i + "] '" + exports.getExportName(i) + "': [" +
+ ordinal + "] = 0x" + Integer.toHexString(exports.getExportAddress(ordinal)));
+ System.out.println(exports.isExportAddressForwarder(ordinal)
+ ? " Forwarded to '" + exports.getExportAddressForwarder(ordinal) + "'"
+ : "");
}
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -42,8 +42,8 @@
COFFHeader header = file.getHeader();
int numSections = header.getNumberOfSections();
System.out.println(numSections + " sections detected.");
- for (int i = 0; i < numSections; i++) {
- SectionHeader secHeader = header.getSectionHeader(1 + i);
+ for (int i = 1; i <= numSections; i++) {
+ SectionHeader secHeader = header.getSectionHeader(i);
System.out.println(secHeader.getName());
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -506,7 +506,6 @@
throw new DebuggerException("Unimplemented");
}
- private static String DTFWHome;
private static String imagePath;
private static String symbolPath;
private static boolean useNativeLookup;
@@ -514,81 +513,143 @@
static {
/*
- * sawindbg.dll depends on dbgeng.dll which
- * itself depends on dbghelp.dll. dbgeng.dll and dbghelp.dll.
- * On systems newer than Windows 2000, these two .dlls are
- * in the standard system directory so we will find them there.
- * On Windows 2000 and earlier, these files do not exist.
- * The user must download Debugging Tools For Windows (DTFW)
- * and install it in order to use SA.
+ * sawindbg.dll depends on dbgeng.dll which itself depends on
+ * dbghelp.dll. We have to make sure that the dbgeng.dll and
+ * dbghelp.dll that we load are compatible with each other. We
+ * load both of those libraries from the same directory based
+ * on the theory that co-located libraries are compatible.
+ *
+ * On Windows 2000 and earlier, dbgeng.dll and dbghelp.dll were
+ * not included as part of the standard system directory. On
+ * systems newer than Windows 2000, dbgeng.dll and dbghelp.dll
+ * are included in the standard system directory. However, the
+ * versions included in the standard system directory may not
+ * be able to handle symbol information for the newer compilers.
+ *
+ * We search for and explicitly load the libraries using the
+ * following directory search order:
*
- * We have to make sure we use the two files from the same directory
- * in case there are more than one copy on the system because
- * one version of dbgeng.dll might not be compatible with a
- * different version of dbghelp.dll.
- * We first look for them in the directory pointed at by
- * env. var. DEBUGGINGTOOLSFORWINDOWS, next in the default
- * installation dir for DTFW, and lastly in the standard
- * system directory. We expect that that we will find
- * them in the standard system directory on all systems
- * newer than Windows 2000.
+ * - java.home/bin (same as $JAVA_HOME/jre/bin)
+ * - dir named by DEBUGGINGTOOLSFORWINDOWS environment variable
+ * - various "Debugging Tools For Windows" program directories
+ * - the system directory ($SYSROOT/system32)
+ *
+ * If SA is invoked with -Dsun.jvm.hotspot.loadLibrary.DEBUG=1,
+ * then debug messages about library loading are printed to
+ * System.err.
*/
- String dirName = null;
- DTFWHome = System.getenv("DEBUGGINGTOOLSFORWINDOWS");
- if (DTFWHome == null) {
- // See if we have the files in the default location.
- String sysRoot = System.getenv("SYSTEMROOT");
- DTFWHome = sysRoot + File.separator +
- ".." + File.separator + "Program Files" +
- File.separator + "Debugging Tools For Windows";
- }
+ String dbgengPath = null;
+ String dbghelpPath = null;
+ String sawindbgPath = null;
+ List searchList = new ArrayList();
+
+ boolean loadLibraryDEBUG =
+ System.getProperty("sun.jvm.hotspot.loadLibrary.DEBUG") != null;
{
- String dbghelp = DTFWHome + File.separator + "dbghelp.dll";
- String dbgeng = DTFWHome + File.separator + "dbgeng.dll";
- File fhelp = new File(dbghelp);
- File feng = new File(dbgeng);
- if (fhelp.exists() && feng.exists()) {
- // found both, we are happy.
- // NOTE: The order of loads is important! If we load dbgeng.dll
- // first, then the dependency - dbghelp.dll - will be loaded
- // from usual DLL search thereby defeating the purpose!
- System.load(dbghelp);
- System.load(dbgeng);
- } else if (! fhelp.exists() && ! feng.exists()) {
- // neither exist. We will ignore this dir and assume
- // they are in the system dir.
- DTFWHome = null;
- } else {
- // one exists but not the other
- //System.err.println("Error: Both files dbghelp.dll and dbgeng.dll "
- // "must exist in directory " + DTFWHome);
- throw new UnsatisfiedLinkError("Both files dbghelp.dll and " +
- "dbgeng.dll must exist in " +
- "directory " + DTFWHome);
+ // First place to search is co-located with sawindbg.dll in
+ // $JAVA_HOME/jre/bin (java.home property is set to $JAVA_HOME/jre):
+ searchList.add(System.getProperty("java.home") + File.separator + "bin");
+ sawindbgPath = (String) searchList.get(0) + File.separator +
+ "sawindbg.dll";
+
+ // second place to search is specified by an environment variable:
+ String DTFWHome = System.getenv("DEBUGGINGTOOLSFORWINDOWS");
+ if (DTFWHome != null) {
+ searchList.add(DTFWHome);
}
- }
- if (DTFWHome == null) {
- // The files better be in the system dir.
- String sysDir = System.getenv("SYSTEMROOT") +
- File.separator + "system32";
- File feng = new File(sysDir + File.separator + "dbgeng.dll");
- if (!feng.exists()) {
- throw new UnsatisfiedLinkError("File dbgeng.dll does not exist in " +
- sysDir + ". Please search microsoft.com " +
- "for Debugging Tools For Windows, and " +
- "either download it to the default " +
- "location, or download it to a custom " +
- "location and set environment variable " +
- " DEBUGGINGTOOLSFORWINDOWS " +
- "to the pathname of that location.");
- }
+ // The third place to search is the install directory for the
+ // "Debugging Tools For Windows" package; so far there are three
+ // name variations that we know of:
+ String sysRoot = System.getenv("SYSTEMROOT");
+ DTFWHome = sysRoot + File.separator + ".." + File.separator +
+ "Program Files" + File.separator + "Debugging Tools For Windows";
+ searchList.add(DTFWHome);
+ searchList.add(DTFWHome + " (x86)");
+ searchList.add(DTFWHome + " (x64)");
+
+ // The last place to search is the system directory:
+ searchList.add(sysRoot + File.separator + "system32");
}
+ for (int i = 0; i < searchList.size(); i++) {
+ File dir = new File((String) searchList.get(i));
+ if (!dir.exists()) {
+ if (loadLibraryDEBUG) {
+ System.err.println("DEBUG: '" + searchList.get(i) +
+ "': directory does not exist.");
+ }
+ // this search directory doesn't exist so skip it
+ continue;
+ }
+
+ dbgengPath = (String) searchList.get(i) + File.separator + "dbgeng.dll";
+ dbghelpPath = (String) searchList.get(i) + File.separator + "dbghelp.dll";
+
+ File feng = new File(dbgengPath);
+ File fhelp = new File(dbghelpPath);
+ if (feng.exists() && fhelp.exists()) {
+ // both files exist so we have a match
+ break;
+ }
+
+ // At least one of the files does not exist; no warning if both
+ // don't exist. If just one doesn't exist then we don't check
+ // loadLibraryDEBUG because we have a mis-configured system.
+ if (feng.exists()) {
+ System.err.println("WARNING: found '" + dbgengPath +
+ "' but did not find '" + dbghelpPath + "'; ignoring '" +
+ dbgengPath + "'.");
+ } else if (fhelp.exists()) {
+ System.err.println("WARNING: found '" + dbghelpPath +
+ "' but did not find '" + dbgengPath + "'; ignoring '" +
+ dbghelpPath + "'.");
+ } else if (loadLibraryDEBUG) {
+ System.err.println("DEBUG: searched '" + searchList.get(i) +
+ "': dbgeng.dll and dbghelp.dll were not found.");
+ }
+ dbgengPath = null;
+ dbghelpPath = null;
+ }
+
+ if (dbgengPath == null || dbghelpPath == null) {
+ // at least one of the files wasn't found anywhere we searched
+ String mesg = null;
+
+ if (dbgengPath == null && dbghelpPath == null) {
+ mesg = "dbgeng.dll and dbghelp.dll cannot be found. ";
+ } else if (dbgengPath == null) {
+ mesg = "dbgeng.dll cannot be found (dbghelp.dll was found). ";
+ } else {
+ mesg = "dbghelp.dll cannot be found (dbgeng.dll was found). ";
+ }
+ throw new UnsatisfiedLinkError(mesg +
+ "Please search microsoft.com for 'Debugging Tools For Windows', " +
+ "and either download it to the default location, or download it " +
+ "to a custom location and set environment variable " +
+ "'DEBUGGINGTOOLSFORWINDOWS' to the pathname of that location.");
+ }
+
+ // NOTE: The order of loads is important! If we load dbgeng.dll
+ // first, then the dependency - dbghelp.dll - will be loaded
+ // from usual DLL search thereby defeating the purpose!
+ if (loadLibraryDEBUG) {
+ System.err.println("DEBUG: loading '" + dbghelpPath + "'.");
+ }
+ System.load(dbghelpPath);
+ if (loadLibraryDEBUG) {
+ System.err.println("DEBUG: loading '" + dbgengPath + "'.");
+ }
+ System.load(dbgengPath);
+
// Now, load sawindbg.dll
- System.loadLibrary("sawindbg");
+ if (loadLibraryDEBUG) {
+ System.err.println("DEBUG: loading '" + sawindbgPath + "'.");
+ }
+ System.load(sawindbgPath);
+
// where do I find '.exe', '.dll' files?
imagePath = System.getProperty("sun.jvm.hotspot.debugger.windbg.imagePath");
if (imagePath == null) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Wed Jan 19 19:00:30 2011 -0800
@@ -30,6 +30,7 @@
import sun.jvm.hotspot.asm.sparc.*;
import sun.jvm.hotspot.asm.x86.*;
import sun.jvm.hotspot.asm.ia64.*;
+import sun.jvm.hotspot.asm.amd64.*;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.compiler.*;
import sun.jvm.hotspot.debugger.*;
@@ -198,6 +199,8 @@
cpuHelper = new SPARCHelper();
} else if (cpu.equals("x86")) {
cpuHelper = new X86Helper();
+ } else if (cpu.equals("amd64")) {
+ cpuHelper = new AMD64Helper();
} else if (cpu.equals("ia64")) {
cpuHelper = new IA64Helper();
} else {
--- a/hotspot/make/hotspot_version Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/hotspot_version Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2011, 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
@@ -31,11 +31,11 @@
#
# Don't put quotes (fail windows build).
-HOTSPOT_VM_COPYRIGHT=Copyright 2010
+HOTSPOT_VM_COPYRIGHT=Copyright 2011
HS_MAJOR_VER=20
HS_MINOR_VER=0
-HS_BUILD_NUMBER=05
+HS_BUILD_NUMBER=06
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
--- a/hotspot/make/jprt.properties Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/jprt.properties Wed Jan 19 19:00:30 2011 -0800
@@ -150,6 +150,7 @@
jprt.my.solaris.sparc.test.targets= \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jvm98, \
+ ${jprt.my.solaris.sparc}-{product|fastdebug}-c2-jvm98_tiered, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark, \
${jprt.my.solaris.sparc}-product-{c1|c2}-runThese, \
${jprt.my.solaris.sparc}-fastdebug-c1-runThese_Xshare, \
@@ -168,6 +169,7 @@
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_G1, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParOldGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_default, \
+ ${jprt.my.solaris.sparc}-{product|fastdebug}-c2-jbb_default_tiered, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_CMS, \
@@ -176,6 +178,7 @@
jprt.my.solaris.sparcv9.test.targets= \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98, \
+ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98_tiered, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark, \
${jprt.my.solaris.sparcv9}-product-c2-runThese, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default, \
@@ -193,6 +196,7 @@
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_G1, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParOldGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default, \
+ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default_tiered, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_SerialGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParallelGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_CMS, \
@@ -201,6 +205,7 @@
jprt.my.solaris.x64.test.targets= \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98, \
+ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98_tiered, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-scimark, \
${jprt.my.solaris.x64}-product-c2-runThese, \
${jprt.my.solaris.x64}-product-c2-runThese_Xcomp, \
@@ -219,6 +224,7 @@
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default, \
+ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default_tiered, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_SerialGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
@@ -227,6 +233,7 @@
jprt.my.solaris.i586.test.targets= \
${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+ ${jprt.my.solaris.i586}-{product|fastdebug}-c2-jvm98_tiered, \
${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark, \
${jprt.my.solaris.i586}-product-{c1|c2}-runThese_Xcomp, \
${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xcomp, \
@@ -253,6 +260,7 @@
${jprt.my.solaris.i586}-product-c1-GCOld_G1, \
${jprt.my.solaris.i586}-product-c1-GCOld_ParOldGC, \
${jprt.my.solaris.i586}-fastdebug-c2-jbb_default, \
+ ${jprt.my.solaris.i586}-fastdebug-c2-jbb_default_tiered, \
${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParallelGC, \
${jprt.my.solaris.i586}-fastdebug-c2-jbb_CMS, \
${jprt.my.solaris.i586}-fastdebug-c2-jbb_G1, \
@@ -260,6 +268,7 @@
jprt.my.linux.i586.test.targets = \
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+ ${jprt.my.linux.i586}-{product|fastdebug}-c2-jvm98_tiered, \
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-scimark, \
${jprt.my.linux.i586}-product-c1-runThese_Xcomp, \
${jprt.my.linux.i586}-fastdebug-c1-runThese_Xshare, \
@@ -279,6 +288,7 @@
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_G1, \
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParOldGC, \
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_default, \
+ ${jprt.my.linux.i586}-{product|fastdebug}-c2-jbb_default_tiered, \
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParallelGC, \
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_CMS, \
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_G1, \
@@ -286,6 +296,7 @@
jprt.my.linux.x64.test.targets = \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98, \
+ ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98_tiered, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_default, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
@@ -302,12 +313,14 @@
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_G1, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default, \
+ ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default_tiered, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_G1, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParOldGC
jprt.my.windows.i586.test.targets = \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+ ${jprt.my.windows.i586}-{product|fastdebug}-c2-jvm98_tiered, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-scimark, \
${jprt.my.windows.i586}-product-{c1|c2}-runThese, \
${jprt.my.windows.i586}-product-{c1|c2}-runThese_Xcomp, \
@@ -327,6 +340,7 @@
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_G1, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParOldGC, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jbb_default, \
+ ${jprt.my.windows.i586}-{product|fastdebug}-c2-jbb_default_tiered, \
${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParallelGC, \
${jprt.my.windows.i586}-product-{c1|c2}-jbb_CMS, \
${jprt.my.windows.i586}-product-{c1|c2}-jbb_G1, \
@@ -334,6 +348,7 @@
jprt.my.windows.x64.test.targets = \
${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98, \
+ ${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98_tiered, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark, \
${jprt.my.windows.x64}-product-c2-runThese, \
${jprt.my.windows.x64}-product-c2-runThese_Xcomp, \
@@ -351,6 +366,7 @@
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_G1, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default, \
+ ${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default_tiered, \
${jprt.my.windows.x64}-product-c2-jbb_CMS, \
${jprt.my.windows.x64}-product-c2-jbb_ParallelGC, \
${jprt.my.windows.x64}-product-c2-jbb_G1, \
--- a/hotspot/make/solaris/makefiles/buildtree.make Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/solaris/makefiles/buildtree.make Wed Jan 19 19:00:30 2011 -0800
@@ -61,7 +61,7 @@
QUIETLY$(MAKE_VERBOSE) = @
# For now, until the compiler is less wobbly:
-TESTFLAGS = -Xbatch -showversion
+TESTFLAGS = -Xbatch -Xmx32m -showversion
### maye ARCH_XXX instead?
ifdef USE_GCC
--- a/hotspot/make/solaris/makefiles/vm.make Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/solaris/makefiles/vm.make Wed Jan 19 19:00:30 2011 -0800
@@ -119,6 +119,10 @@
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
endif # sparcWorks
+ifeq ("${Platform_arch}", "sparc")
+LIBS += -lkstat
+endif
+
# By default, link the *.o into the library, not the executable.
LINK_INTO$(LINK_INTO) = LIBJVM
--- a/hotspot/make/windows/makefiles/compile.make Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/windows/makefiles/compile.make Wed Jan 19 19:00:30 2011 -0800
@@ -152,7 +152,7 @@
!endif
# Always add the _STATIC_CPPLIB flag
-STATIC_CPPLIB_OPTION = /D _STATIC_CPPLIB
+STATIC_CPPLIB_OPTION = /D _STATIC_CPPLIB /D _DISABLE_DEPRECATE_STATIC_CPPLIB
MS_RUNTIME_OPTION = $(MS_RUNTIME_OPTION) $(STATIC_CPPLIB_OPTION)
CPP_FLAGS=$(CPP_FLAGS) $(MS_RUNTIME_OPTION)
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "asm/assembler.hpp"
#include "assembler_sparc.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
@@ -1327,37 +1328,38 @@
}
-int MacroAssembler::size_of_sethi(address a, bool worst_case) {
+int MacroAssembler::insts_for_sethi(address a, bool worst_case) {
#ifdef _LP64
- if (worst_case) return 7;
- intptr_t iaddr = (intptr_t)a;
- int hi32 = (int)(iaddr >> 32);
- int lo32 = (int)(iaddr);
- int inst_count;
- if (hi32 == 0 && lo32 >= 0)
- inst_count = 1;
- else if (hi32 == -1)
- inst_count = 2;
+ if (worst_case) return 7;
+ intptr_t iaddr = (intptr_t) a;
+ int msb32 = (int) (iaddr >> 32);
+ int lsb32 = (int) (iaddr);
+ int count;
+ if (msb32 == 0 && lsb32 >= 0)
+ count = 1;
+ else if (msb32 == -1)
+ count = 2;
else {
- inst_count = 2;
- if ( hi32 & 0x3ff )
- inst_count++;
- if ( lo32 & 0xFFFFFC00 ) {
- if( (lo32 >> 20) & 0xfff ) inst_count += 2;
- if( (lo32 >> 10) & 0x3ff ) inst_count += 2;
+ count = 2;
+ if (msb32 & 0x3ff)
+ count++;
+ if (lsb32 & 0xFFFFFC00 ) {
+ if ((lsb32 >> 20) & 0xfff) count += 2;
+ if ((lsb32 >> 10) & 0x3ff) count += 2;
}
}
- return BytesPerInstWord * inst_count;
+ return count;
#else
- return BytesPerInstWord;
+ return 1;
#endif
}
-int MacroAssembler::worst_case_size_of_set() {
- return size_of_sethi(NULL, true) + 1;
+int MacroAssembler::worst_case_insts_for_set() {
+ return insts_for_sethi(NULL, true) + 1;
}
+// Keep in sync with MacroAssembler::insts_for_internal_set
void MacroAssembler::internal_set(const AddressLiteral& addrlit, Register d, bool ForceRelocatable) {
intptr_t value = addrlit.value();
@@ -1379,6 +1381,23 @@
}
}
+// Keep in sync with MacroAssembler::internal_set
+int MacroAssembler::insts_for_internal_set(intptr_t value) {
+ // can optimize
+ if (-4096 <= value && value <= 4095) {
+ return 1;
+ }
+ if (inv_hi22(hi22(value)) == value) {
+ return insts_for_sethi((address) value);
+ }
+ int count = insts_for_sethi((address) value);
+ AddressLiteral al(value);
+ if (al.low10() != 0) {
+ count++;
+ }
+ return count;
+}
+
void MacroAssembler::set(const AddressLiteral& al, Register d) {
internal_set(al, d, false);
}
@@ -1443,11 +1462,11 @@
}
}
-int MacroAssembler::size_of_set64(jlong value) {
+int MacroAssembler::insts_for_set64(jlong value) {
v9_dep();
- int hi = (int)(value >> 32);
- int lo = (int)(value & ~0);
+ int hi = (int) (value >> 32);
+ int lo = (int) (value & ~0);
int count = 0;
// (Matcher::isSimpleConstant64 knows about the following optimizations.)
@@ -4083,11 +4102,15 @@
store_klass(t2, top);
verify_oop(top);
+ ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t1);
+ sub(top, t1, t1); // size of tlab's allocated portion
+ incr_allocated_bytes(t1, 0, t2);
+
// refill the tlab with an eden allocation
bind(do_refill);
ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t1);
sll_ptr(t1, LogHeapWordSize, t1);
- // add object_size ??
+ // allocate new tlab, address returned in top
eden_allocate(top, t1, 0, t2, t3, slow_case);
st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_start_offset()));
@@ -4115,6 +4138,22 @@
delayed()->nop();
}
+void MacroAssembler::incr_allocated_bytes(Register var_size_in_bytes,
+ int con_size_in_bytes,
+ Register t1) {
+ // Bump total bytes allocated by this thread
+ assert(t1->is_global(), "must be global reg"); // so all 64 bits are saved on a context switch
+ assert_different_registers(var_size_in_bytes, t1);
+ // v8 support has gone the way of the dodo
+ ldx(G2_thread, in_bytes(JavaThread::allocated_bytes_offset()), t1);
+ if (var_size_in_bytes->is_valid()) {
+ add(t1, var_size_in_bytes, t1);
+ } else {
+ add(t1, con_size_in_bytes, t1);
+ }
+ stx(t1, G2_thread, in_bytes(JavaThread::allocated_bytes_offset()));
+}
+
Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
switch (cond) {
// Note some conditions are synonyms for others
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -1884,23 +1884,24 @@
void sethi(const AddressLiteral& addrlit, Register d);
void patchable_sethi(const AddressLiteral& addrlit, Register d);
- // compute the size of a sethi/set
- static int size_of_sethi( address a, bool worst_case = false );
- static int worst_case_size_of_set();
+ // compute the number of instructions for a sethi/set
+ static int insts_for_sethi( address a, bool worst_case = false );
+ static int worst_case_insts_for_set();
// set may be either setsw or setuw (high 32 bits may be zero or sign)
private:
void internal_set(const AddressLiteral& al, Register d, bool ForceRelocatable);
+ static int insts_for_internal_set(intptr_t value);
public:
void set(const AddressLiteral& addrlit, Register d);
void set(intptr_t value, Register d);
void set(address addr, Register d, RelocationHolder const& rspec);
+ static int insts_for_set(intptr_t value) { return insts_for_internal_set(value); }
+
void patchable_set(const AddressLiteral& addrlit, Register d);
void patchable_set(intptr_t value, Register d);
void set64(jlong value, Register d, Register tmp);
-
- // Compute size of set64.
- static int size_of_set64(jlong value);
+ static int insts_for_set64(jlong value);
// sign-extend 32 to 64
inline void signx( Register s, Register d ) { sra( s, G0, d); }
@@ -2388,6 +2389,7 @@
Label& slow_case // continuation point if fast allocation fails
);
void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
+ void incr_allocated_bytes(Register var_size_in_bytes, int con_size_in_bytes, Register t1);
// interface method calling
void lookup_interface_method(Register recv_klass,
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1705,8 +1705,7 @@
}
-void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) {
-
+void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {
Assembler::Condition acond;
switch (condition) {
case lir_cond_equal: acond = Assembler::equal; break;
@@ -1737,7 +1736,12 @@
ShouldNotReachHere();
}
Label skip;
- __ br(acond, false, Assembler::pt, skip);
+#ifdef _LP64
+ if (type == T_INT) {
+ __ br(acond, false, Assembler::pt, skip);
+ } else
+#endif
+ __ brx(acond, false, Assembler::pt, skip); // checks icc on 32bit and xcc on 64bit
if (opr1->is_constant() && opr1->type() == T_INT) {
Register dest = result->as_register();
if (Assembler::is_simm13(opr1->as_jint())) {
@@ -2688,6 +2692,11 @@
#ifdef _LP64
__ mov(cmp_value_lo, t1);
__ mov(new_value_lo, t2);
+ // perform the compare and swap operation
+ __ casx(addr, t1, t2);
+ // generate condition code - if the swap succeeded, t2 ("new value" reg) was
+ // overwritten with the original value in "addr" and will be equal to t1.
+ __ cmp(t1, t2);
#else
// move high and low halves of long values into single registers
__ sllx(cmp_value_hi, 32, t1); // shift high half into temp reg
@@ -2696,13 +2705,15 @@
__ sllx(new_value_hi, 32, t2);
__ srl(new_value_lo, 0, new_value_lo);
__ or3(t2, new_value_lo, t2); // t2 holds 64-bit value to swap
-#endif
// perform the compare and swap operation
__ casx(addr, t1, t2);
// generate condition code - if the swap succeeded, t2 ("new value" reg) was
// overwritten with the original value in "addr" and will be equal to t1.
- __ cmp(t1, t2);
-
+ // Produce icc flag for 32bit.
+ __ sub(t1, t2, t2);
+ __ srlx(t2, 32, t1);
+ __ orcc(t2, t1, G0);
+#endif
} else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) {
Register addr = op->addr()->as_pointer_register();
Register cmp_value = op->cmp_value()->as_register();
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -662,7 +662,7 @@
// generate conditional move of boolean result
LIR_Opr result = rlock_result(x);
- __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
+ __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, T_LONG);
}
@@ -699,10 +699,10 @@
else {
ShouldNotReachHere();
}
-
// generate conditional move of boolean result
LIR_Opr result = rlock_result(x);
- __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
+ __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
+ result, as_BasicType(type));
if (type == objectType) { // Write-barrier needed for Object fields.
// Precise card mark since could either be object or array
post_barrier(addr, val.result());
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -166,7 +166,7 @@
Register obj, // result: pointer to object after successful allocation
Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
int con_size_in_bytes, // object size in bytes if known at compile time
- Register t1, // temp register
+ Register t1, // temp register, must be global register for incr_allocated_bytes
Register t2, // temp register
Label& slow_case // continuation point if fast allocation fails
) {
@@ -174,6 +174,7 @@
tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
} else {
eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
+ incr_allocated_bytes(var_size_in_bytes, con_size_in_bytes, t1);
}
}
@@ -214,7 +215,7 @@
void C1_MacroAssembler::allocate_object(
Register obj, // result: pointer to object after successful allocation
Register t1, // temp register
- Register t2, // temp register
+ Register t2, // temp register, must be a global register for try_allocate
Register t3, // temp register
int hdr_size, // object header size in words
int obj_size, // object size in words
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -448,7 +448,9 @@
// get the instance size
__ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
+
__ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
+
__ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
__ verify_oop(O0_obj);
__ mov(O0, I0);
@@ -459,6 +461,8 @@
// get the instance size
__ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
__ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
+ __ incr_allocated_bytes(G1_obj_size, 0, G3_t1);
+
__ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
__ verify_oop(O0_obj);
__ mov(O0, I0);
@@ -573,6 +577,7 @@
__ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
__ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size
+ __ incr_allocated_bytes(G1_arr_size, 0, G3_t1);
__ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
__ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -395,18 +395,23 @@
//
// Generate an "entry" field for a method handle.
// This determines how the method handle will respond to calls.
-void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
+void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) {
// Here is the register state during an interpreted call,
// as set up by generate_method_handle_interpreter_entry():
// - G5: garbage temp (was MethodHandle.invoke methodOop, unused)
// - G3: receiver method handle
// - O5_savedSP: sender SP (must preserve)
- Register O0_argslot = O0;
- Register O1_scratch = O1;
- Register O2_scratch = O2;
- Register O3_scratch = O3;
- Register G5_index = G5;
+ const Register O0_argslot = O0;
+ const Register O1_scratch = O1;
+ const Register O2_scratch = O2;
+ const Register O3_scratch = O3;
+ const Register G5_index = G5;
+
+ // Argument registers for _raise_exception.
+ const Register O0_code = O0;
+ const Register O1_actual = O1;
+ const Register O2_required = O2;
guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
@@ -439,48 +444,36 @@
case _raise_exception:
{
// Not a real MH entry, but rather shared code for raising an
- // exception. Extra local arguments are passed in scratch
- // registers, as required type in O3, failing object (or NULL)
- // in O2, failing bytecode type in O1.
+ // exception. Since we use a C2I adapter to set up the
+ // interpreter state, arguments are expected in compiler
+ // argument registers.
+ methodHandle mh(raise_exception_method());
+ address c2i_entry = methodOopDesc::make_adapters(mh, CATCH);
__ mov(O5_savedSP, SP); // Cut the stack back to where the caller started.
- // Push arguments as if coming from the interpreter.
- Register O0_scratch = O0_argslot;
- int stackElementSize = Interpreter::stackElementSize;
-
- // Make space on the stack for the arguments and set Gargs
- // correctly.
- __ sub(SP, 4*stackElementSize, SP); // Keep stack aligned.
- __ add(SP, (frame::varargs_offset)*wordSize - 1*Interpreter::stackElementSize + STACK_BIAS + BytesPerWord, Gargs);
-
- // void raiseException(int code, Object actual, Object required)
- __ st( O1_scratch, Address(Gargs, 2*stackElementSize)); // code
- __ st_ptr(O2_scratch, Address(Gargs, 1*stackElementSize)); // actual
- __ st_ptr(O3_scratch, Address(Gargs, 0*stackElementSize)); // required
-
- Label no_method;
+ Label L_no_method;
// FIXME: fill in _raise_exception_method with a suitable sun.dyn method
__ set(AddressLiteral((address) &_raise_exception_method), G5_method);
__ ld_ptr(Address(G5_method, 0), G5_method);
__ tst(G5_method);
- __ brx(Assembler::zero, false, Assembler::pn, no_method);
+ __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
__ delayed()->nop();
- int jobject_oop_offset = 0;
+ const int jobject_oop_offset = 0;
__ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);
__ tst(G5_method);
- __ brx(Assembler::zero, false, Assembler::pn, no_method);
+ __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
__ delayed()->nop();
__ verify_oop(G5_method);
- __ jump_indirect_to(G5_method_fie, O1_scratch);
+ __ jump_to(AddressLiteral(c2i_entry), O3_scratch);
__ delayed()->nop();
// If we get here, the Java runtime did not do its job of creating the exception.
// Do something that is at least causes a valid throw from the interpreter.
- __ bind(no_method);
- __ unimplemented("_raise_exception no method");
+ __ bind(L_no_method);
+ __ unimplemented("call throw_WrongMethodType_entry");
}
break;
@@ -570,10 +563,10 @@
// Throw an exception.
// For historical reasons, it will be IncompatibleClassChangeError.
__ unimplemented("not tested yet");
- __ ld_ptr(Address(O1_intf, java_mirror_offset), O3_scratch); // required interface
- __ mov(O0_klass, O2_scratch); // bad receiver
- __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot);
- __ delayed()->mov(Bytecodes::_invokeinterface, O1_scratch); // who is complaining?
+ __ ld_ptr(Address(O1_intf, java_mirror_offset), O2_required); // required interface
+ __ mov( O0_klass, O1_actual); // bad receiver
+ __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
+ __ delayed()->mov(Bytecodes::_invokeinterface, O0_code); // who is complaining?
}
break;
@@ -663,11 +656,10 @@
__ check_klass_subtype(O1_scratch, G5_klass, O0_argslot, O2_scratch, done);
// If we get here, the type check failed!
- __ ldsw(G3_amh_vmargslot, O0_argslot); // reload argslot field
- __ load_heap_oop(G3_amh_argument, O3_scratch); // required class
- __ ld_ptr(vmarg, O2_scratch); // bad object
- __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot);
- __ delayed()->mov(Bytecodes::_checkcast, O1_scratch); // who is complaining?
+ __ load_heap_oop(G3_amh_argument, O2_required); // required class
+ __ ld_ptr( vmarg, O1_actual); // bad object
+ __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
+ __ delayed()->mov(Bytecodes::_checkcast, O0_code); // who is complaining?
__ bind(done);
// Get the new MH:
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jan 19 19:00:30 2011 -0800
@@ -1086,9 +1086,9 @@
uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
if (UseRDPCForConstantTableBase) {
// This is really the worst case but generally it's only 1 instruction.
- return 4 /*rdpc*/ + 4 /*sub*/ + MacroAssembler::worst_case_size_of_set();
+ return (1 /*rdpc*/ + 1 /*sub*/ + MacroAssembler::worst_case_insts_for_set()) * BytesPerInstWord;
} else {
- return MacroAssembler::worst_case_size_of_set();
+ return MacroAssembler::worst_case_insts_for_set() * BytesPerInstWord;
}
}
@@ -1240,7 +1240,7 @@
int MachEpilogNode::safepoint_offset() const {
assert( do_polling(), "no return for this epilog node");
- return MacroAssembler::size_of_sethi(os::get_polling_page());
+ return MacroAssembler::insts_for_sethi(os::get_polling_page()) * BytesPerInstWord;
}
//=============================================================================
@@ -3553,9 +3553,10 @@
interface(CONST_INTER);
%}
-// Pointer Immediate: 32 or 64-bit
+#ifdef _LP64
+// Pointer Immediate: 64-bit
operand immP_set() %{
- predicate(!VM_Version::is_niagara1_plus());
+ predicate(!VM_Version::is_niagara_plus());
match(ConP);
op_cost(5);
@@ -3564,10 +3565,10 @@
interface(CONST_INTER);
%}
-// Pointer Immediate: 32 or 64-bit
+// Pointer Immediate: 64-bit
// From Niagara2 processors on a load should be better than materializing.
operand immP_load() %{
- predicate(VM_Version::is_niagara1_plus());
+ predicate(VM_Version::is_niagara_plus() && (n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set(n->get_ptr()) > 3)));
match(ConP);
op_cost(5);
@@ -3576,6 +3577,18 @@
interface(CONST_INTER);
%}
+// Pointer Immediate: 64-bit
+operand immP_no_oop_cheap() %{
+ predicate(VM_Version::is_niagara_plus() && !n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set(n->get_ptr()) <= 3));
+ match(ConP);
+
+ op_cost(5);
+ // formats are generated automatically for constants and base registers
+ format %{ %}
+ interface(CONST_INTER);
+%}
+#endif
+
operand immP13() %{
predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095));
match(ConP);
@@ -3673,7 +3686,7 @@
// Long Immediate: cheap (materialize in <= 3 instructions)
operand immL_cheap() %{
- predicate(!VM_Version::is_niagara1_plus() || MacroAssembler::size_of_set64(n->get_long()) <= 3);
+ predicate(!VM_Version::is_niagara_plus() || MacroAssembler::insts_for_set64(n->get_long()) <= 3);
match(ConL);
op_cost(0);
@@ -3683,7 +3696,7 @@
// Long Immediate: expensive (materialize in > 3 instructions)
operand immL_expensive() %{
- predicate(VM_Version::is_niagara1_plus() && MacroAssembler::size_of_set64(n->get_long()) > 3);
+ predicate(VM_Version::is_niagara_plus() && MacroAssembler::insts_for_set64(n->get_long()) > 3);
match(ConL);
op_cost(0);
@@ -6094,8 +6107,18 @@
ins_cost(MEMORY_REF_COST);
format %{ "LD [$constanttablebase + $constantoffset],$dst\t! load from constant table: ptr=$con" %}
ins_encode %{
- RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register);
- __ ld_ptr($constanttablebase, con_offset, $dst$$Register);
+ RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register);
+ __ ld_ptr($constanttablebase, con_offset, $dst$$Register);
+ %}
+ ins_pipe(loadConP);
+%}
+
+instruct loadConP_no_oop_cheap(iRegP dst, immP_no_oop_cheap con) %{
+ match(Set dst con);
+ ins_cost(DEFAULT_COST * 3/2);
+ format %{ "SET $con,$dst\t! non-oop ptr" %}
+ ins_encode %{
+ __ set($con$$constant, $dst$$Register);
%}
ins_pipe(loadConP);
%}
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -3393,21 +3393,21 @@
__ delayed()->st_ptr(RnewTopValue, G2_thread, in_bytes(JavaThread::tlab_top_offset()));
if (allow_shared_alloc) {
- // Check if tlab should be discarded (refill_waste_limit >= free)
- __ ld_ptr(G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), RtlabWasteLimitValue);
- __ sub(RendValue, RoldTopValue, RfreeValue);
+ // Check if tlab should be discarded (refill_waste_limit >= free)
+ __ ld_ptr(G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), RtlabWasteLimitValue);
+ __ sub(RendValue, RoldTopValue, RfreeValue);
#ifdef _LP64
- __ srlx(RfreeValue, LogHeapWordSize, RfreeValue);
+ __ srlx(RfreeValue, LogHeapWordSize, RfreeValue);
#else
- __ srl(RfreeValue, LogHeapWordSize, RfreeValue);
+ __ srl(RfreeValue, LogHeapWordSize, RfreeValue);
#endif
- __ cmp(RtlabWasteLimitValue, RfreeValue);
- __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, slow_case); // tlab waste is small
- __ delayed()->nop();
-
- // increment waste limit to prevent getting stuck on this slow path
- __ add(RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment(), RtlabWasteLimitValue);
- __ st_ptr(RtlabWasteLimitValue, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
+ __ cmp(RtlabWasteLimitValue, RfreeValue);
+ __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, slow_case); // tlab waste is small
+ __ delayed()->nop();
+
+ // increment waste limit to prevent getting stuck on this slow path
+ __ add(RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment(), RtlabWasteLimitValue);
+ __ st_ptr(RtlabWasteLimitValue, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
} else {
// No allocation in the shared eden.
__ br(Assembler::always, false, Assembler::pt, slow_case);
@@ -3445,6 +3445,9 @@
__ cmp(RoldTopValue, RnewTopValue);
__ brx(Assembler::notEqual, false, Assembler::pn, retry);
__ delayed()->nop();
+
+ // bump total bytes allocated by this thread
+ __ incr_allocated_bytes(Roffset, 0, G1_scratch);
}
if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -38,12 +38,6 @@
int VM_Version::_features = VM_Version::unknown_m;
const char* VM_Version::_features_str = "";
-bool VM_Version::is_niagara1_plus() {
- // This is a placeholder until the real test is determined.
- return is_niagara1() &&
- (os::processor_count() > maximum_niagara1_processor_count());
-}
-
void VM_Version::initialize() {
_features = determine_features();
PrefetchCopyIntervalInBytes = prefetch_copy_interval_in_bytes();
@@ -69,11 +63,21 @@
_supports_cx8 = has_v9();
- if (is_niagara1()) {
+ if (is_niagara()) {
// Indirect branch is the same cost as direct
if (FLAG_IS_DEFAULT(UseInlineCaches)) {
FLAG_SET_DEFAULT(UseInlineCaches, false);
}
+ // Align loops on a single instruction boundary.
+ if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
+ FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
+ }
+ // When using CMS, we cannot use memset() in BOT updates because
+ // the sun4v/CMT version in libc_psr uses BIS which exposes
+ // "phantom zeros" to concurrent readers. See 6948537.
+ if (FLAG_IS_DEFAULT(UseMemSetInBOT) && UseConcMarkSweepGC) {
+ FLAG_SET_DEFAULT(UseMemSetInBOT, false);
+ }
#ifdef _LP64
// 32-bit oops don't make sense for the 64-bit VM on sparc
// since the 32-bit VM has the same registers and smaller objects.
@@ -89,7 +93,7 @@
if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
}
- if (is_niagara1_plus()) {
+ if (is_niagara_plus()) {
if (has_blk_init() && AllocatePrefetchStyle > 0 &&
FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
// Use BIS instruction for allocation prefetch.
@@ -105,15 +109,6 @@
}
}
#endif
- if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
- FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
- }
- // When using CMS, we cannot use memset() in BOT updates because
- // the sun4v/CMT version in libc_psr uses BIS which exposes
- // "phantom zeros" to concurrent readers. See 6948537.
- if (FLAG_IS_DEFAULT(UseMemSetInBOT) && UseConcMarkSweepGC) {
- FLAG_SET_DEFAULT(UseMemSetInBOT, false);
- }
}
// Use hardware population count instruction if available.
@@ -129,17 +124,18 @@
#endif
char buf[512];
- jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
(has_v8() ? ", has_v8" : ""),
(has_v9() ? ", has_v9" : ""),
(has_hardware_popc() ? ", popc" : ""),
(has_vis1() ? ", has_vis1" : ""),
(has_vis2() ? ", has_vis2" : ""),
+ (has_vis3() ? ", has_vis3" : ""),
(has_blk_init() ? ", has_blk_init" : ""),
(is_ultra3() ? ", is_ultra3" : ""),
(is_sun4v() ? ", is_sun4v" : ""),
- (is_niagara1() ? ", is_niagara1" : ""),
- (is_niagara1_plus() ? ", is_niagara1_plus" : ""),
+ (is_niagara() ? ", is_niagara" : ""),
+ (is_niagara_plus() ? ", is_niagara_plus" : ""),
(is_sparc64() ? ", is_sparc64" : ""),
(!has_hardware_mul32() ? ", no-mul32" : ""),
(!has_hardware_div32() ? ", no-div32" : ""),
@@ -190,17 +186,18 @@
warning("Cannot recognize SPARC version. Default to V9");
}
- if (UseNiagaraInstrs) {
- if (is_niagara1(features)) {
+ assert(is_T_family(features) == is_niagara(features), "Niagara should be T series");
+ if (UseNiagaraInstrs) { // Force code generation for Niagara
+ if (is_T_family(features)) {
// Happy to accomodate...
} else {
NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Version is Forced-Niagara");)
- features = niagara1_m;
+ features |= T_family_m;
}
} else {
- if (is_niagara1(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
+ if (is_T_family(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Version is Forced-Not-Niagara");)
- features &= ~niagara1_unique_m;
+ features &= ~(T_family_m | T1_model_m);
} else {
// Happy to accomodate...
}
@@ -222,7 +219,7 @@
unsigned int VM_Version::calc_parallel_worker_threads() {
unsigned int result;
- if (is_niagara1_plus()) {
+ if (is_niagara_plus()) {
result = nof_parallel_worker_threads(5, 16, 8);
} else {
result = nof_parallel_worker_threads(5, 8, 8);
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -41,7 +41,12 @@
vis2_instructions = 7,
sun4v_instructions = 8,
blk_init_instructions = 9,
- fmaf_instructions = 10
+ fmaf_instructions = 10,
+ fmau_instructions = 11,
+ vis3_instructions = 12,
+ sparc64_family = 13,
+ T_family = 14,
+ T1_model = 15
};
enum Feature_Flag_Set {
@@ -59,6 +64,11 @@
sun4v_m = 1 << sun4v_instructions,
blk_init_instructions_m = 1 << blk_init_instructions,
fmaf_instructions_m = 1 << fmaf_instructions,
+ fmau_instructions_m = 1 << fmau_instructions,
+ vis3_instructions_m = 1 << vis3_instructions,
+ sparc64_family_m = 1 << sparc64_family,
+ T_family_m = 1 << T_family,
+ T1_model_m = 1 << T1_model,
generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
generic_v9_m = generic_v8_m | v9_instructions_m,
@@ -76,8 +86,13 @@
static int determine_features();
static int platform_features(int features);
- static bool is_niagara1(int features) { return (features & sun4v_m) != 0; }
- static bool is_sparc64(int features) { return (features & fmaf_instructions_m) != 0; }
+ // Returns true if the platform is in the niagara line (T series)
+ static bool is_T_family(int features) { return (features & T_family_m) != 0; }
+ static bool is_niagara() { return is_T_family(_features); }
+ DEBUG_ONLY( static bool is_niagara(int features) { return (features & sun4v_m) != 0; } )
+
+ // Returns true if it is niagara1 (T1).
+ static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
static int maximum_niagara1_processor_count() { return 32; }
@@ -94,6 +109,7 @@
static bool has_hardware_popc() { return (_features & hardware_popc_m) != 0; }
static bool has_vis1() { return (_features & vis1_instructions_m) != 0; }
static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
+ static bool has_vis3() { return (_features & vis3_instructions_m) != 0; }
static bool has_blk_init() { return (_features & blk_init_instructions_m) != 0; }
static bool supports_compare_and_exchange()
@@ -101,14 +117,14 @@
static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m; }
static bool is_sun4v() { return (_features & sun4v_m) != 0; }
- static bool is_niagara1() { return is_niagara1(_features); }
- // Returns true if the platform is in the niagara line and
- // newer than the niagara1.
- static bool is_niagara1_plus();
- static bool is_sparc64() { return is_sparc64(_features); }
+ // Returns true if the platform is in the niagara line (T series)
+ // and newer than the niagara1.
+ static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); }
+ // Fujitsu SPARC64
+ static bool is_sparc64() { return (_features & sparc64_family_m) != 0; }
- static bool has_fast_fxtof() { return has_v9() && !is_ultra3(); }
- static bool has_fast_idiv() { return is_niagara1_plus() || is_sparc64(); }
+ static bool has_fast_fxtof() { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); }
+ static bool has_fast_idiv() { return is_niagara_plus() || is_sparc64(); }
static const char* cpu_features() { return _features_str; }
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -820,7 +820,20 @@
}
-// Now the Assembler instruction (identical for 32/64 bits)
+// Now the Assembler instructions (identical for 32/64 bits)
+
+void Assembler::adcl(Address dst, int32_t imm32) {
+ InstructionMark im(this);
+ prefix(dst);
+ emit_arith_operand(0x81, rdx, dst, imm32);
+}
+
+void Assembler::adcl(Address dst, Register src) {
+ InstructionMark im(this);
+ prefix(dst, src);
+ emit_byte(0x11);
+ emit_operand(src, dst);
+}
void Assembler::adcl(Register dst, int32_t imm32) {
prefix(dst);
@@ -2195,9 +2208,7 @@
void Assembler::orl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
- emit_byte(0x81);
- emit_operand(rcx, dst, 4);
- emit_long(imm32);
+ emit_arith_operand(0x81, rcx, dst, imm32);
}
void Assembler::orl(Register dst, int32_t imm32) {
@@ -2205,7 +2216,6 @@
emit_arith(0x81, 0xC8, dst, imm32);
}
-
void Assembler::orl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
@@ -2213,7 +2223,6 @@
emit_operand(dst, src);
}
-
void Assembler::orl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
emit_arith(0x0B, 0xC0, dst, src);
@@ -2692,20 +2701,7 @@
void Assembler::subl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
- if (is8bit(imm32)) {
- emit_byte(0x83);
- emit_operand(rbp, dst, 1);
- emit_byte(imm32 & 0xFF);
- } else {
- emit_byte(0x81);
- emit_operand(rbp, dst, 4);
- emit_long(imm32);
- }
-}
-
-void Assembler::subl(Register dst, int32_t imm32) {
- prefix(dst);
- emit_arith(0x81, 0xE8, dst, imm32);
+ emit_arith_operand(0x81, rbp, dst, imm32);
}
void Assembler::subl(Address dst, Register src) {
@@ -2715,6 +2711,11 @@
emit_operand(src, dst);
}
+void Assembler::subl(Register dst, int32_t imm32) {
+ prefix(dst);
+ emit_arith(0x81, 0xE8, dst, imm32);
+}
+
void Assembler::subl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
@@ -4333,6 +4334,7 @@
emit_byte(0xD3);
emit_byte(0xF8 | encode);
}
+
void Assembler::sbbq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
@@ -4392,20 +4394,7 @@
void Assembler::subq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
- if (is8bit(imm32)) {
- emit_byte(0x83);
- emit_operand(rbp, dst, 1);
- emit_byte(imm32 & 0xFF);
- } else {
- emit_byte(0x81);
- emit_operand(rbp, dst, 4);
- emit_long(imm32);
- }
-}
-
-void Assembler::subq(Register dst, int32_t imm32) {
- (void) prefixq_and_encode(dst->encoding());
- emit_arith(0x81, 0xE8, dst, imm32);
+ emit_arith_operand(0x81, rbp, dst, imm32);
}
void Assembler::subq(Address dst, Register src) {
@@ -4415,6 +4404,11 @@
emit_operand(src, dst);
}
+void Assembler::subq(Register dst, int32_t imm32) {
+ (void) prefixq_and_encode(dst->encoding());
+ emit_arith(0x81, 0xE8, dst, imm32);
+}
+
void Assembler::subq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
@@ -7136,9 +7130,9 @@
}
// Preserves rbx, and rdx.
-void MacroAssembler::tlab_refill(Label& retry,
- Label& try_eden,
- Label& slow_case) {
+Register MacroAssembler::tlab_refill(Label& retry,
+ Label& try_eden,
+ Label& slow_case) {
Register top = rax;
Register t1 = rcx;
Register t2 = rsi;
@@ -7185,7 +7179,7 @@
// if tlab is currently allocated (top or end != null) then
// fill [top, end + alignment_reserve) with array object
- testptr (top, top);
+ testptr(top, top);
jcc(Assembler::zero, do_refill);
// set up the mark word
@@ -7197,16 +7191,20 @@
movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
// set klass to intArrayKlass
// dubious reloc why not an oop reloc?
- movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr()));
+ movptr(t1, ExternalAddress((address)Universe::intArrayKlassObj_addr()));
// store klass last. concurrent gcs assumes klass length is valid if
// klass field is not null.
store_klass(top, t1);
+ movptr(t1, top);
+ subptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
+ incr_allocated_bytes(thread_reg, t1, 0);
+
// refill the tlab with an eden allocation
bind(do_refill);
movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
shlptr(t1, LogHeapWordSize);
- // add object_size ??
+ // allocate new tlab, address returned in top
eden_allocate(top, t1, 0, t2, slow_case);
// Check that t1 was preserved in eden_allocate.
@@ -7234,6 +7232,34 @@
movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top);
verify_tlab();
jmp(retry);
+
+ return thread_reg; // for use by caller
+}
+
+void MacroAssembler::incr_allocated_bytes(Register thread,
+ Register var_size_in_bytes,
+ int con_size_in_bytes,
+ Register t1) {
+#ifdef _LP64
+ if (var_size_in_bytes->is_valid()) {
+ addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes);
+ } else {
+ addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes);
+ }
+#else
+ if (!thread->is_valid()) {
+ assert(t1->is_valid(), "need temp reg");
+ thread = t1;
+ get_thread(thread);
+ }
+
+ if (var_size_in_bytes->is_valid()) {
+ addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes);
+ } else {
+ addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes);
+ }
+ adcl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())+4), 0);
+#endif
}
static const double pi_4 = 0.7853981633974483;
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -674,12 +674,14 @@
// Utilities
#ifdef _LP64
- static bool is_simm(int64_t x, int nbits) { return -( CONST64(1) << (nbits-1) ) <= x && x < ( CONST64(1) << (nbits-1) ); }
+ static bool is_simm(int64_t x, int nbits) { return -(CONST64(1) << (nbits-1)) <= x &&
+ x < (CONST64(1) << (nbits-1)); }
static bool is_simm32(int64_t x) { return x == (int64_t)(int32_t)x; }
#else
- static bool is_simm(int32_t x, int nbits) { return -( 1 << (nbits-1) ) <= x && x < ( 1 << (nbits-1) ); }
+ static bool is_simm(int32_t x, int nbits) { return -(1 << (nbits-1)) <= x &&
+ x < (1 << (nbits-1)); }
static bool is_simm32(int32_t x) { return true; }
-#endif // LP64
+#endif // _LP64
// Generic instructions
// Does 32bit or 64bit as needed for the platform. In some sense these
@@ -705,7 +707,6 @@
void push(void* v);
void pop(void* v);
-
// These do register sized moves/scans
void rep_mov();
void rep_set();
@@ -716,6 +717,8 @@
// Vanilla instructions in lexical order
+ void adcl(Address dst, int32_t imm32);
+ void adcl(Address dst, Register src);
void adcl(Register dst, int32_t imm32);
void adcl(Register dst, Address src);
void adcl(Register dst, Register src);
@@ -724,7 +727,6 @@
void adcq(Register dst, Address src);
void adcq(Register dst, Register src);
-
void addl(Address dst, int32_t imm32);
void addl(Address dst, Register src);
void addl(Register dst, int32_t imm32);
@@ -737,7 +739,6 @@
void addq(Register dst, Address src);
void addq(Register dst, Register src);
-
void addr_nop_4();
void addr_nop_5();
void addr_nop_7();
@@ -759,7 +760,6 @@
void andq(Register dst, Address src);
void andq(Register dst, Register src);
-
// Bitwise Logical AND of Packed Double-Precision Floating-Point Values
void andpd(XMMRegister dst, Address src);
void andpd(XMMRegister dst, XMMRegister src);
@@ -1151,7 +1151,7 @@
#ifdef _LP64
void movq(Register dst, Register src);
void movq(Register dst, Address src);
- void movq(Address dst, Register src);
+ void movq(Address dst, Register src);
#endif
void movq(Address dst, MMXRegister src );
@@ -1177,7 +1177,7 @@
void movsbq(Register dst, Register src);
// Move signed 32bit immediate to 64bit extending sign
- void movslq(Address dst, int32_t imm64);
+ void movslq(Address dst, int32_t imm64);
void movslq(Register dst, int32_t imm64);
void movslq(Register dst, Address src);
@@ -1857,7 +1857,10 @@
Register t2, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
+ Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
+ void incr_allocated_bytes(Register thread,
+ Register var_size_in_bytes, int con_size_in_bytes,
+ Register t1 = noreg);
// interface method calling
void lookup_interface_method(Register recv_klass,
@@ -2180,9 +2183,9 @@
void divss(XMMRegister dst, Address src) { Assembler::divss(dst, src); }
void divss(XMMRegister dst, AddressLiteral src) { Assembler::divss(dst, as_Address(src)); }
- void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); }
- void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); }
- void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); }
+ void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); }
+ void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); }
+ void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); }
void movsd(XMMRegister dst, AddressLiteral src) { Assembler::movsd(dst, as_Address(src)); }
void mulsd(XMMRegister dst, XMMRegister src) { Assembler::mulsd(dst, src); }
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -2036,7 +2036,7 @@
}
}
-void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) {
+void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {
Assembler::Condition acond, ncond;
switch (condition) {
case lir_cond_equal: acond = Assembler::equal; ncond = Assembler::notEqual; break;
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -741,7 +741,7 @@
// generate conditional move of boolean result
LIR_Opr result = rlock_result(x);
- __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
+ __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, T_LONG);
}
@@ -810,7 +810,8 @@
// generate conditional move of boolean result
LIR_Opr result = rlock_result(x);
- __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
+ __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
+ result, as_BasicType(type));
if (type == objectType) { // Write-barrier needed for Object fields.
// Seems to be precise
post_barrier(addr, val.result());
--- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -141,6 +141,7 @@
tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
} else {
eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
+ incr_allocated_bytes(noreg, var_size_in_bytes, con_size_in_bytes, t1);
}
}
@@ -234,7 +235,7 @@
void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
assert(obj == rax, "obj must be in rax, for cmpxchg");
- assert(obj != t1 && obj != t2 && t1 != t2, "registers must be different"); // XXX really?
+ assert_different_registers(obj, t1, t2); // XXX really?
assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -977,7 +977,6 @@
// verify that that there is really a valid exception in rax,
__ verify_not_null_oop(exception_oop);
-
oop_maps = new OopMapSet();
OopMap* oop_map = generate_oop_map(sasm, 1);
generate_handle_exception(sasm, oop_maps, oop_map);
@@ -1037,13 +1036,16 @@
// if we got here then the TLAB allocation failed, so try
// refilling the TLAB or allocating directly from eden.
Label retry_tlab, try_eden;
- __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass)
+ const Register thread =
+ __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass), returns rdi
__ bind(retry_tlab);
// get the instance size (size is postive so movl is fine for 64bit)
__ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes()));
+
__ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
+
__ initialize_object(obj, klass, obj_size, 0, t1, t2);
__ verify_oop(obj);
__ pop(rbx);
@@ -1053,7 +1055,10 @@
__ bind(try_eden);
// get the instance size (size is postive so movl is fine for 64bit)
__ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes()));
+
__ eden_allocate(obj, obj_size, 0, t1, slow_path);
+ __ incr_allocated_bytes(thread, obj_size, 0);
+
__ initialize_object(obj, klass, obj_size, 0, t1, t2);
__ verify_oop(obj);
__ pop(rbx);
@@ -1143,12 +1148,13 @@
// if we got here then the TLAB allocation failed, so try
// refilling the TLAB or allocating directly from eden.
Label retry_tlab, try_eden;
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx, & rdx
+ const Register thread =
+ __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx & rdx, returns rdi
__ bind(retry_tlab);
// get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
- // since size is postive movl does right thing on 64bit
+ // since size is positive movl does right thing on 64bit
__ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes()));
// since size is postive movl does right thing on 64bit
__ movl(arr_size, length);
@@ -1175,7 +1181,7 @@
__ bind(try_eden);
// get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
- // since size is postive movl does right thing on 64bit
+ // since size is positive movl does right thing on 64bit
__ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes()));
// since size is postive movl does right thing on 64bit
__ movl(arr_size, length);
@@ -1188,6 +1194,7 @@
__ andptr(arr_size, ~MinObjAlignmentInBytesMask);
__ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size
+ __ incr_allocated_bytes(thread, arr_size, 0);
__ initialize_header(obj, klass, length, t1, t2);
__ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte)));
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -385,9 +385,12 @@
// FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
}
+//------------------------------------------------------------------------------
+// MethodHandles::generate_method_handle_stub
+//
// Generate an "entry" field for a method handle.
// This determines how the method handle will respond to calls.
-void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
+void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) {
// Here is the register state during an interpreted call,
// as set up by generate_method_handle_interpreter_entry():
// - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
@@ -396,14 +399,21 @@
// - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
// - rdx: garbage temp, can blow away
- Register rcx_recv = rcx;
- Register rax_argslot = rax;
- Register rbx_temp = rbx;
- Register rdx_temp = rdx;
+ const Register rcx_recv = rcx;
+ const Register rax_argslot = rax;
+ const Register rbx_temp = rbx;
+ const Register rdx_temp = rdx;
// This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
// and gen_c2i_adapter (from compiled calls):
- Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
+ const Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
+
+ // Argument registers for _raise_exception.
+ // 32-bit: Pass first two oop/int args in registers ECX and EDX.
+ const Register rarg0_code = LP64_ONLY(j_rarg0) NOT_LP64(rcx);
+ const Register rarg1_actual = LP64_ONLY(j_rarg1) NOT_LP64(rdx);
+ const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi);
+ assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp);
guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
@@ -437,47 +447,41 @@
switch ((int) ek) {
case _raise_exception:
{
- // Not a real MH entry, but rather shared code for raising an exception.
- // Extra local arguments are pushed on stack, as required type at TOS+8,
- // failing object (or NULL) at TOS+4, failing bytecode type at TOS.
- // Beyond those local arguments are the PC, of course.
- Register rdx_code = rdx_temp;
- Register rcx_fail = rcx_recv;
- Register rax_want = rax_argslot;
- Register rdi_pc = rdi;
- __ pop(rdx_code); // TOS+0
- __ pop(rcx_fail); // TOS+4
- __ pop(rax_want); // TOS+8
- __ pop(rdi_pc); // caller PC
+ // Not a real MH entry, but rather shared code for raising an
+ // exception. Since we use a C2I adapter to set up the
+ // interpreter state, arguments are expected in compiler
+ // argument registers.
+ methodHandle mh(raise_exception_method());
+ address c2i_entry = methodOopDesc::make_adapters(mh, CHECK);
- __ mov(rsp, rsi); // cut the stack back to where the caller started
-
- // Repush the arguments as if coming from the interpreter.
- __ push(rdx_code);
- __ push(rcx_fail);
- __ push(rax_want);
+ const Register rdi_pc = rax;
+ __ pop(rdi_pc); // caller PC
+ __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started
Register rbx_method = rbx_temp;
- Label no_method;
+ Label L_no_method;
// FIXME: fill in _raise_exception_method with a suitable sun.dyn method
__ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
__ testptr(rbx_method, rbx_method);
- __ jccb(Assembler::zero, no_method);
- int jobject_oop_offset = 0;
+ __ jccb(Assembler::zero, L_no_method);
+
+ const int jobject_oop_offset = 0;
__ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject
__ testptr(rbx_method, rbx_method);
- __ jccb(Assembler::zero, no_method);
+ __ jccb(Assembler::zero, L_no_method);
__ verify_oop(rbx_method);
- __ push(rdi_pc); // and restore caller PC
- __ jmp(rbx_method_fie);
+
+ // 32-bit: push remaining arguments as if coming from the compiler.
+ NOT_LP64(__ push(rarg2_required));
+
+ __ push(rdi_pc); // restore caller PC
+ __ jump(ExternalAddress(c2i_entry)); // do C2I transition
// If we get here, the Java runtime did not do its job of creating the exception.
// Do something that is at least causes a valid throw from the interpreter.
- __ bind(no_method);
- __ pop(rax_want);
- __ pop(rcx_fail);
- __ push(rax_want);
- __ push(rcx_fail);
+ __ bind(L_no_method);
+ __ push(rarg2_required);
+ __ push(rarg1_actual);
__ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
}
break;
@@ -572,9 +576,11 @@
__ bind(no_such_interface);
// Throw an exception.
// For historical reasons, it will be IncompatibleClassChangeError.
- __ pushptr(Address(rdx_intf, java_mirror_offset)); // required interface
- __ push(rcx_recv); // bad receiver
- __ push((int)Bytecodes::_invokeinterface); // who is complaining?
+ __ mov(rbx_temp, rcx_recv); // rarg2_required might be RCX
+ assert_different_registers(rarg2_required, rbx_temp);
+ __ movptr(rarg2_required, Address(rdx_intf, java_mirror_offset)); // required interface
+ __ mov( rarg1_actual, rbx_temp); // bad receiver
+ __ movl( rarg0_code, (int) Bytecodes::_invokeinterface); // who is complaining?
__ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
}
break;
@@ -669,10 +675,10 @@
__ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field
__ movptr(rdx_temp, vmarg);
- __ load_heap_oop(rbx_klass, rcx_amh_argument); // required class
- __ push(rbx_klass);
- __ push(rdx_temp); // bad object
- __ push((int)Bytecodes::_checkcast); // who is complaining?
+ assert_different_registers(rarg2_required, rdx_temp);
+ __ load_heap_oop(rarg2_required, rcx_amh_argument); // required class
+ __ mov( rarg1_actual, rdx_temp); // bad object
+ __ movl( rarg0_code, (int) Bytecodes::_checkcast); // who is complaining?
__ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
__ bind(done);
@@ -1189,16 +1195,18 @@
__ bind(bad_array_klass);
UNPUSH_RSI_RDI;
- __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type
- __ pushptr(vmarg); // bad array
- __ push((int)Bytecodes::_aaload); // who is complaining?
+ assert(!vmarg.uses(rarg2_required), "must be different registers");
+ __ movptr(rarg2_required, Address(rdx_array_klass, java_mirror_offset)); // required type
+ __ movptr(rarg1_actual, vmarg); // bad array
+ __ movl( rarg0_code, (int) Bytecodes::_aaload); // who is complaining?
__ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
__ bind(bad_array_length);
UNPUSH_RSI_RDI;
- __ push(rcx_recv); // AMH requiring a certain length
- __ pushptr(vmarg); // bad array
- __ push((int)Bytecodes::_arraylength); // who is complaining?
+ assert(!vmarg.uses(rarg2_required), "must be different registers");
+ __ mov (rarg2_required, rcx_recv); // AMH requiring a certain length
+ __ movptr(rarg1_actual, vmarg); // bad array
+ __ movl( rarg0_code, (int) Bytecodes::_arraylength); // who is complaining?
__ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
#undef UNPUSH_RSI_RDI
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -3203,10 +3203,12 @@
const bool allow_shared_alloc =
Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode;
+ const Register thread = rcx;
+ if (UseTLAB || allow_shared_alloc) {
+ __ get_thread(thread);
+ }
+
if (UseTLAB) {
- const Register thread = rcx;
-
- __ get_thread(thread);
__ movptr(rax, Address(thread, in_bytes(JavaThread::tlab_top_offset())));
__ lea(rbx, Address(rax, rdx, Address::times_1));
__ cmpptr(rbx, Address(thread, in_bytes(JavaThread::tlab_end_offset())));
@@ -3247,6 +3249,8 @@
// if someone beat us on the allocation, try again, otherwise continue
__ jcc(Assembler::notEqual, retry);
+
+ __ incr_allocated_bytes(thread, rdx, 0);
}
if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
@@ -3256,12 +3260,12 @@
__ decrement(rdx, sizeof(oopDesc));
__ jcc(Assembler::zero, initialize_header);
- // Initialize topmost object field, divide rdx by 8, check if odd and
- // test if zero.
+ // Initialize topmost object field, divide rdx by 8, check if odd and
+ // test if zero.
__ xorl(rcx, rcx); // use zero reg to clear memory (shorter code)
__ shrl(rdx, LogBytesPerLong); // divide by 2*oopSize and set carry flag if odd
- // rdx must have been multiple of 8
+ // rdx must have been multiple of 8
#ifdef ASSERT
// make sure rdx was multiple of 8
Label L;
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -3266,6 +3266,8 @@
// if someone beat us on the allocation, try again, otherwise continue
__ jcc(Assembler::notEqual, retry);
+
+ __ incr_allocated_bytes(r15_thread, rdx, 0);
}
if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -635,7 +635,29 @@
return -1;
}
- return fd;
+ // Verify that we have enough disk space for this file.
+ // We'll get random SIGBUS crashes on memory accesses if
+ // we don't.
+
+ for (size_t seekpos = 0; seekpos < size; seekpos += os::vm_page_size()) {
+ int zero_int = 0;
+ result = (int)os::seek_to_file_offset(fd, (jlong)(seekpos));
+ if (result == -1 ) break;
+ RESTARTABLE(::write(fd, &zero_int, 1), result);
+ if (result != 1) {
+ if (errno == ENOSPC) {
+ warning("Insufficient space for shared memory file:\n %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename);
+ }
+ break;
+ }
+ }
+
+ if (result != -1) {
+ return fd;
+ } else {
+ RESTARTABLE(::close(fd), result);
+ return -1;
+ }
}
// open the shared memory file for the given user and vmid. returns
--- a/hotspot/src/os/posix/launcher/java_md.c Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/posix/launcher/java_md.c Wed Jan 19 19:00:30 2011 -0800
@@ -28,7 +28,6 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <inttypes.h>
-#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -80,6 +80,7 @@
// put OS-includes here
# include <dlfcn.h>
# include <errno.h>
+# include <exception>
# include <link.h>
# include <poll.h>
# include <pthread.h>
@@ -282,7 +283,7 @@
is_error_reported(),
"sp must be inside of selected thread stack");
- thread->_self_raw_id = raw_id; // mark for quick retrieval
+ thread->set_self_raw_id(raw_id); // mark for quick retrieval
_get_thread_cache[ index ] = thread;
}
return thread;
@@ -1475,6 +1476,13 @@
return &allowdebug_blocked_sigs;
}
+
+void _handle_uncaught_cxx_exception() {
+ VMError err("An uncaught C++ exception");
+ err.report_and_die();
+}
+
+
// First crack at OS-specific initialization, from inside the new thread.
void os::initialize_thread() {
int r = thr_main() ;
@@ -1564,6 +1572,7 @@
// use the dynamic check for T2 libthread.
os::Solaris::init_thread_fpu_state();
+ std::set_terminate(_handle_uncaught_cxx_exception);
}
@@ -3081,7 +3090,7 @@
if (addr == NULL) {
jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
}
- warning("attempt_reserve_memory_at: couldn't reserve %d bytes at "
+ warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
"%s", bytes, requested_addr, addr, buf);
}
@@ -5188,7 +5197,7 @@
int o_delete = (oflag & O_DELETE);
oflag = oflag & ~O_DELETE;
- fd = ::open(path, oflag, mode);
+ fd = ::open64(path, oflag, mode);
if (fd == -1) return -1;
//If the open succeeded, the file might still be a directory
--- a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, 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
@@ -53,10 +53,10 @@
uintptr_t raw = pd_raw_thread_id();
int ix = pd_cache_index(raw);
- Thread *Candidate = ThreadLocalStorage::_get_thread_cache[ix];
- if (Candidate->_self_raw_id == raw) {
+ Thread* candidate = ThreadLocalStorage::_get_thread_cache[ix];
+ if (candidate->self_raw_id() == raw) {
// hit
- return Candidate;
+ return candidate;
} else {
return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix);
}
--- a/hotspot/src/os/windows/vm/os_windows.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * CopyrighT (c) 1997, 2010, 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
@@ -2004,6 +2004,16 @@
int number;
};
+// All Visual C++ exceptions thrown from code generated by the Microsoft Visual
+// C++ compiler contain this error code. Because this is a compiler-generated
+// error, the code is not listed in the Win32 API header files.
+// The code is actually a cryptic mnemonic device, with the initial "E"
+// standing for "exception" and the final 3 bytes (0x6D7363) representing the
+// ASCII values of "msc".
+
+#define EXCEPTION_UNCAUGHT_CXX_EXCEPTION 0xE06D7363
+
+
struct siglabel exceptlabels[] = {
def_excpt(EXCEPTION_ACCESS_VIOLATION),
def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),
@@ -2028,6 +2038,7 @@
def_excpt(EXCEPTION_INVALID_DISPOSITION),
def_excpt(EXCEPTION_GUARD_PAGE),
def_excpt(EXCEPTION_INVALID_HANDLE),
+ def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
NULL, 0
};
@@ -2261,7 +2272,6 @@
}
}
-
if (t != NULL && t->is_Java_thread()) {
JavaThread* thread = (JavaThread*) t;
bool in_java = thread->thread_state() == _thread_in_Java;
@@ -2465,8 +2475,9 @@
} // switch
}
#ifndef _WIN64
- if ((thread->thread_state() == _thread_in_Java) ||
- (thread->thread_state() == _thread_in_native) )
+ if (((thread->thread_state() == _thread_in_Java) ||
+ (thread->thread_state() == _thread_in_native)) &&
+ exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION)
{
LONG result=Handle_FLT_Exception(exceptionInfo);
if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
@@ -2490,6 +2501,7 @@
case EXCEPTION_ILLEGAL_INSTRUCTION_2:
case EXCEPTION_INT_OVERFLOW:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ case EXCEPTION_UNCAUGHT_CXX_EXCEPTION:
{ report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
}
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -585,6 +585,13 @@
sigaddset(&newset, sig);
sigprocmask(SIG_UNBLOCK, &newset, NULL);
+ // Determine which sort of error to throw. Out of swap may signal
+ // on the thread stack, which could get a mapping error when touched.
+ address addr = (address) info->si_addr;
+ if (sig == SIGBUS && info->si_code == BUS_OBJERR && info->si_errno == ENOMEM) {
+ vm_exit_out_of_memory(0, "Out of swap space to map in thread stack.");
+ }
+
VMError err(t, sig, pc, info, ucVoid);
err.report_and_die();
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -29,6 +29,7 @@
# include <sys/auxv.h>
# include <sys/auxv_SPARC.h>
# include <sys/systeminfo.h>
+# include <kstat.h>
// We need to keep these here as long as we have to build on Solaris
// versions before 10.
@@ -96,11 +97,23 @@
#ifndef AV_SPARC_ASI_BLK_INIT
#define AV_SPARC_ASI_BLK_INIT 0x0080 /* ASI_BLK_INIT_xxx ASI */
#endif
+ if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
+
#ifndef AV_SPARC_FMAF
-#define AV_SPARC_FMAF 0x0100 /* Sparc64 Fused Multiply-Add */
+#define AV_SPARC_FMAF 0x0100 /* Fused Multiply-Add */
#endif
- if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
if (av & AV_SPARC_FMAF) features |= fmaf_instructions_m;
+
+#ifndef AV_SPARC_FMAU
+#define AV_SPARC_FMAU 0x0200 /* Unfused Multiply-Add */
+#endif
+ if (av & AV_SPARC_FMAU) features |= fmau_instructions_m;
+
+#ifndef AV_SPARC_VIS3
+#define AV_SPARC_VIS3 0x0400 /* VIS3 instruction set extensions */
+#endif
+ if (av & AV_SPARC_VIS3) features |= vis3_instructions_m;
+
} else {
// getisax(2) failed, use the old legacy code.
#ifndef PRODUCT
@@ -140,5 +153,59 @@
// Determine the machine type.
do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m);
+ {
+ // Using kstat to determine the machine type.
+ kstat_ctl_t* kc = kstat_open();
+ kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
+ const char* implementation = "UNKNOWN";
+ if (ksp != NULL) {
+ if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
+ kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
+ for (int i = 0; i < ksp->ks_ndata; i++) {
+ if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
+#ifndef KSTAT_DATA_STRING
+#define KSTAT_DATA_STRING 9
+#endif
+ if (knm[i].data_type == KSTAT_DATA_CHAR) {
+ // VM is running on Solaris 8 which does not have value.str.
+ implementation = &(knm[i].value.c[0]);
+ } else if (knm[i].data_type == KSTAT_DATA_STRING) {
+ // VM is running on Solaris 10.
+#ifndef KSTAT_NAMED_STR_PTR
+ // Solaris 8 was used to build VM, define the structure it misses.
+ struct str_t {
+ union {
+ char *ptr; /* NULL-term string */
+ char __pad[8]; /* 64-bit padding */
+ } addr;
+ uint32_t len; /* # bytes for strlen + '\0' */
+ };
+#define KSTAT_NAMED_STR_PTR(knptr) (( (str_t*)&((knptr)->value) )->addr.ptr)
+#endif
+ implementation = KSTAT_NAMED_STR_PTR(&knm[i]);
+ }
+#ifndef PRODUCT
+ if (PrintMiscellaneous && Verbose) {
+ tty->print_cr("cpu_info.implementation: %s", implementation);
+ }
+#endif
+ if (strncmp(implementation, "SPARC64", 7) == 0) {
+ features |= sparc64_family_m;
+ } else if (strncmp(implementation, "UltraSPARC-T", 12) == 0) {
+ features |= T_family_m;
+ if (strncmp(implementation, "UltraSPARC-T1", 13) == 0) {
+ features |= T1_model_m;
+ }
+ }
+ break;
+ }
+ } // for(
+ }
+ }
+ assert(strcmp(implementation, "UNKNOWN") != 0,
+ "unknown cpu info (changed kstat interface?)");
+ kstat_close(kc);
+ }
+
return features;
}
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -742,6 +742,13 @@
sigaddset(&newset, sig);
sigprocmask(SIG_UNBLOCK, &newset, NULL);
+ // Determine which sort of error to throw. Out of swap may signal
+ // on the thread stack, which could get a mapping error when touched.
+ address addr = (address) info->si_addr;
+ if (sig == SIGBUS && info->si_code == BUS_OBJERR && info->si_errno == ENOMEM) {
+ vm_exit_out_of_memory(0, "Out of swap space to map in thread stack.");
+ }
+
VMError err(t, sig, pc, info, ucVoid);
err.report_and_die();
--- a/hotspot/src/share/vm/adlc/dict2.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/adlc/dict2.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -34,7 +34,7 @@
#define MAXID 20
static char initflag = 0; // True after 1st initialization
static char shft[MAXID] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6};
-static short xsum[MAXID + 1];
+static short xsum[MAXID];
//------------------------------bucket---------------------------------------
class bucket {
@@ -66,7 +66,7 @@
// Precompute table of null character hashes
if( !initflag ) { // Not initializated yet?
xsum[0] = (1<<shft[0])+1; // Initialize
- for( i = 1; i < MAXID + 1; i++) {
+ for( i = 1; i < MAXID; i++) {
xsum[i] = (1<<shft[i])+1+xsum[i-1];
}
initflag = 1; // Never again
@@ -291,7 +291,7 @@
c = (c<<1)+1; // Characters are always odd!
sum += c + (c<<shft[k++]); // Universal hash function
}
- assert( k < (MAXID + 1), "Exceeded maximum name length");
+ assert( k < (MAXID), "Exceeded maximum name length");
return (int)((sum+xsum[k]) >> 1); // Hash key, un-modulo'd table size
}
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -245,7 +245,7 @@
}
-void Compilation::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) {
+bool Compilation::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) {
// Preinitialize the consts section to some large size:
int locs_buffer_size = 20 * (relocInfo::length_limit + sizeof(relocInfo));
char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
@@ -253,15 +253,20 @@
locs_buffer_size / sizeof(relocInfo));
code->initialize_consts_size(Compilation::desired_max_constant_size());
// Call stubs + two deopt handlers (regular and MH) + exception handler
- code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) +
- LIR_Assembler::exception_handler_size +
- 2 * LIR_Assembler::deopt_handler_size);
+ int stub_size = (call_stub_estimate * LIR_Assembler::call_stub_size) +
+ LIR_Assembler::exception_handler_size +
+ (2 * LIR_Assembler::deopt_handler_size);
+ if (stub_size >= code->insts_capacity()) return false;
+ code->initialize_stubs_size(stub_size);
+ return true;
}
int Compilation::emit_code_body() {
// emit code
- setup_code_buffer(code(), allocator()->num_calls());
+ if (!setup_code_buffer(code(), allocator()->num_calls())) {
+ BAILOUT_("size requested greater than avail code buffer size", 0);
+ }
code()->initialize_oop_recorder(env()->oop_recorder());
_masm = new C1_MacroAssembler(code());
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -192,7 +192,7 @@
return desired_max_code_buffer_size() / 10;
}
- static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
+ static bool setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
// timers
static void print_timers();
--- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -92,7 +92,7 @@
if (opr->is_address()) {
LIR_Address* addr = opr->as_address_ptr();
assert(addr->disp() == (int)addr->disp(), "out of range value");
- out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4);
+ out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4);
}
i += type2size[t];
}
@@ -143,7 +143,7 @@
args->append(opr);
if (opr->is_address()) {
LIR_Address* addr = opr->as_address_ptr();
- out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4);
+ out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4);
}
i += type2size[t];
}
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1568,15 +1568,16 @@
assert(code == lir_cmp, "code check");
}
- LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result)
+ LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type)
: LIR_Op(code, result, NULL)
, _opr1(opr1)
, _opr2(opr2)
- , _type(T_ILLEGAL)
+ , _type(type)
, _condition(condition)
, _fpu_stack_size(0)
, _tmp(LIR_OprFact::illegalOpr) {
assert(code == lir_cmove, "code check");
+ assert(type != T_ILLEGAL, "cmove should have type");
}
LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result = LIR_OprFact::illegalOpr,
@@ -1993,8 +1994,8 @@
void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info);
void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Address* addr, CodeEmitInfo* info);
- void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst) {
- append(new LIR_Op2(lir_cmove, condition, src1, src2, dst));
+ void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type) {
+ append(new LIR_Op2(lir_cmove, condition, src1, src2, dst, type));
}
void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -685,7 +685,7 @@
break;
case lir_cmove:
- cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr());
+ cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->type());
break;
case lir_shl:
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -217,7 +217,7 @@
void volatile_move_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info);
void comp_mem_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); // info set for null exceptions
void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op);
- void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result);
+ void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result, BasicType type);
void call( LIR_OpJavaCall* op, relocInfo::relocType rtype);
void ic_call( LIR_OpJavaCall* op);
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -856,7 +856,7 @@
__ cmove(lir_cond(cond),
LIR_OprFact::intptrConst(taken_count_offset),
LIR_OprFact::intptrConst(not_taken_count_offset),
- data_offset_reg);
+ data_offset_reg, as_BasicType(if_instr->x()->type()));
// MDO cells are intptr_t, so the data_reg width is arch-dependent.
LIR_Opr data_reg = new_pointer_register();
@@ -2591,7 +2591,7 @@
LIR_Opr reg = rlock_result(x);
__ cmp(lir_cond(x->cond()), left.result(), right.result());
- __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg);
+ __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type()));
}
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -90,6 +90,7 @@
, _intervals(0) // initialized later with correct length
, _new_intervals_from_allocation(new IntervalList())
, _sorted_intervals(NULL)
+ , _needs_full_resort(false)
, _lir_ops(0) // initialized later with correct length
, _block_of_op(0) // initialized later with correct length
, _has_info(0)
@@ -1520,6 +1521,14 @@
void LinearScan::sort_intervals_before_allocation() {
TIME_LINEAR_SCAN(timer_sort_intervals_before);
+ if (_needs_full_resort) {
+ // There is no known reason why this should occur but just in case...
+ assert(false, "should never occur");
+ // Re-sort existing interval list because an Interval::from() has changed
+ _sorted_intervals->sort(interval_cmp);
+ _needs_full_resort = false;
+ }
+
IntervalList* unsorted_list = &_intervals;
int unsorted_len = unsorted_list->length();
int sorted_len = 0;
@@ -1559,11 +1568,18 @@
}
}
_sorted_intervals = sorted_list;
+ assert(is_sorted(_sorted_intervals), "intervals unsorted");
}
void LinearScan::sort_intervals_after_allocation() {
TIME_LINEAR_SCAN(timer_sort_intervals_after);
+ if (_needs_full_resort) {
+ // Re-sort existing interval list because an Interval::from() has changed
+ _sorted_intervals->sort(interval_cmp);
+ _needs_full_resort = false;
+ }
+
IntervalArray* old_list = _sorted_intervals;
IntervalList* new_list = _new_intervals_from_allocation;
int old_len = old_list->length();
@@ -1571,6 +1587,7 @@
if (new_len == 0) {
// no intervals have been added during allocation, so sorted list is already up to date
+ assert(is_sorted(_sorted_intervals), "intervals unsorted");
return;
}
@@ -1593,6 +1610,7 @@
}
_sorted_intervals = combined_list;
+ assert(is_sorted(_sorted_intervals), "intervals unsorted");
}
@@ -1825,6 +1843,8 @@
interval = interval->split(from_op_id);
interval->assign_reg(reg, regHi);
append_interval(interval);
+ } else {
+ _needs_full_resort = true;
}
assert(interval->from() == from_op_id, "must be true now");
@@ -4492,7 +4512,8 @@
}
} else {
type_name = type2name(type());
- if (assigned_reg() != -1) {
+ if (assigned_reg() != -1 &&
+ (LinearScan::num_physical_regs(type()) == 1 || assigned_regHi() != -1)) {
opr = LinearScan::calc_operand_for_interval(this);
}
}
--- a/hotspot/src/share/vm/c1/c1_LinearScan.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -148,6 +148,7 @@
IntervalList _intervals; // mapping from register number to interval
IntervalList* _new_intervals_from_allocation; // list with all intervals created during allocation when an existing interval is split
IntervalArray* _sorted_intervals; // intervals sorted by Interval::from()
+ bool _needs_full_resort; // set to true if an Interval::from() is changed and _sorted_intervals must be resorted
LIR_OpArray _lir_ops; // mapping from LIR_Op id to LIR_Op node
BlockBeginArray _block_of_op; // mapping from LIR_Op id to the BlockBegin containing this instruction
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -2386,19 +2386,21 @@
valid_cp_range(bootstrap_method_index, cp_size) &&
cp->tag_at(bootstrap_method_index).is_method_handle(),
"bootstrap_method_index %u has bad constant type in class file %s",
+ bootstrap_method_index,
CHECK);
operands->short_at_put(operand_fill_index++, bootstrap_method_index);
operands->short_at_put(operand_fill_index++, argument_count);
cfs->guarantee_more(sizeof(u2) * argument_count, CHECK); // argv[argc]
for (int j = 0; j < argument_count; j++) {
- u2 arg_index = cfs->get_u2_fast();
+ u2 argument_index = cfs->get_u2_fast();
check_property(
- valid_cp_range(arg_index, cp_size) &&
- cp->tag_at(arg_index).is_loadable_constant(),
+ valid_cp_range(argument_index, cp_size) &&
+ cp->tag_at(argument_index).is_loadable_constant(),
"argument_index %u has bad constant type in class file %s",
+ argument_index,
CHECK);
- operands->short_at_put(operand_fill_index++, arg_index);
+ operands->short_at_put(operand_fill_index++, argument_index);
}
}
--- a/hotspot/src/share/vm/code/codeCache.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -939,7 +939,9 @@
_heap->high(),
_heap->high_boundary());
st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
- " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT,
+ " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT
+ " largest_free_block=" SIZE_FORMAT,
CodeCache::nof_blobs(), CodeCache::nof_nmethods(),
- CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
+ CodeCache::nof_adapters(), CodeCache::unallocated_capacity(),
+ CodeCache::largest_free_block());
}
--- a/hotspot/src/share/vm/code/codeCache.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/code/codeCache.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -158,6 +158,7 @@
static size_t capacity() { return _heap->capacity(); }
static size_t max_capacity() { return _heap->max_capacity(); }
static size_t unallocated_capacity() { return _heap->unallocated_capacity(); }
+ static size_t largest_free_block() { return _heap->largest_free_block(); }
static bool needs_flushing() { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
static bool needs_cache_clean() { return _needs_cache_clean; }
--- a/hotspot/src/share/vm/code/nmethod.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -811,9 +811,11 @@
_stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs());
// Exception handler and deopt handler are in the stub section
+ assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
+ assert(offsets->value(CodeOffsets::Deopt ) != -1, "must be set");
_exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions);
_deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt);
- if (has_method_handle_invokes()) {
+ if (offsets->value(CodeOffsets::DeoptMH) != -1) {
_deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH);
} else {
_deoptimize_mh_offset = -1;
@@ -1909,6 +1911,7 @@
break;
}
}
+ assert(has_method_handle_invokes() == (_deoptimize_mh_offset != -1), "must have deopt mh handler");
int size = count * sizeof(PcDesc);
assert(scopes_pcs_size() >= size, "oob");
--- a/hotspot/src/share/vm/compiler/abstractCompiler.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -33,6 +33,7 @@
bool do_initialization = false;
{
ThreadInVMfromNative tv(thread);
+ ResetNoHandleMark rnhm;
MutexLocker only_one(CompileThread_lock, thread);
if ( *state == uninitialized) {
do_initialization = true;
@@ -53,6 +54,7 @@
// To in_vm so we can use the lock
ThreadInVMfromNative tv(thread);
+ ResetNoHandleMark rnhm;
MutexLocker only_one(CompileThread_lock, thread);
assert(*state == initializing, "wrong state");
*state = initialized;
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -332,7 +332,7 @@
"command_names size mismatch");
*bytes_read = 0;
- char command[32];
+ char command[33];
int result = sscanf(line, "%32[a-z]%n", command, bytes_read);
for (uint i = 0; i < ARRAY_SIZE(command_names); i++) {
if (strcmp(command, command_names[i]) == 0) {
@@ -470,6 +470,12 @@
OracleCommand command = parse_command_name(line, &bytes_read);
line += bytes_read;
+ if (command == UnknownCommand) {
+ tty->print_cr("CompilerOracle: unrecognized line");
+ tty->print_cr(" \"%s\"", original_line);
+ return;
+ }
+
if (command == QuietCommand) {
_quiet = true;
return;
@@ -498,7 +504,7 @@
line += bytes_read;
// there might be a signature following the method.
// signatures always begin with ( so match that by hand
- if (1 == sscanf(line, "%*[ \t](%254[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
+ if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
sig[0] = '(';
line += bytes_read;
signature = oopFactory::new_symbol_handle(sig, CHECK);
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, 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
@@ -153,6 +153,7 @@
check_for_non_bad_heap_word_value(result, size));
assert(!HAS_PENDING_EXCEPTION,
"Unexpected exception, will result in uninitialized storage");
+ THREAD->incr_allocated_bytes(size * HeapWordSize);
return result;
}
--- a/hotspot/src/share/vm/memory/heap.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/heap.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -315,6 +315,15 @@
return l;
}
+size_t CodeHeap::largest_free_block() const {
+ size_t len = 0;
+ for (FreeBlock* b = _freelist; b != NULL; b = b->link()) {
+ if (b->length() > len)
+ len = b->length();
+ }
+ return size(len);
+}
+
// Free list management
FreeBlock *CodeHeap::following_block(FreeBlock *b) {
--- a/hotspot/src/share/vm/memory/heap.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/heap.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -161,6 +161,7 @@
size_t max_capacity() const;
size_t allocated_capacity() const;
size_t unallocated_capacity() const { return max_capacity() - allocated_capacity(); }
+ size_t largest_free_block() const;
// Debugging
void verify();
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -114,6 +114,11 @@
void ThreadLocalAllocBuffer::make_parsable(bool retire) {
if (end() != NULL) {
invariants();
+
+ if (retire) {
+ myThread()->incr_allocated_bytes(used_bytes());
+ }
+
CollectedHeap::fill_with_object(top(), hard_end(), retire);
if (retire || ZeroTLAB) { // "Reset" the TLAB
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -112,6 +112,8 @@
HeapWord* top() const { return _top; }
HeapWord* pf_top() const { return _pf_top; }
size_t desired_size() const { return _desired_size; }
+ size_t used() const { return pointer_delta(top(), start()); }
+ size_t used_bytes() const { return pointer_delta(top(), start(), 1); }
size_t free() const { return pointer_delta(end(), top()); }
// Don't discard tlab if remaining space is larger than this.
size_t refill_waste_limit() const { return _refill_waste_limit; }
--- a/hotspot/src/share/vm/memory/universe.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -934,7 +934,8 @@
// See needs_explicit_null_check.
// Only set the heap base for compressed oops because it indicates
// compressed oops for pstack code.
- if (PrintCompressedOopsMode) {
+ bool verbose = PrintCompressedOopsMode || (PrintMiscellaneous && Verbose);
+ if (verbose) {
tty->cr();
tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
@@ -943,12 +944,12 @@
// Can't reserve heap below 32Gb.
Universe::set_narrow_oop_base(Universe::heap()->base() - os::vm_page_size());
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
- if (PrintCompressedOopsMode) {
+ if (verbose) {
tty->print(", Compressed Oops with base: "PTR_FORMAT, Universe::narrow_oop_base());
}
} else {
Universe::set_narrow_oop_base(0);
- if (PrintCompressedOopsMode) {
+ if (verbose) {
tty->print(", zero based Compressed Oops");
}
#ifdef _WIN64
@@ -963,12 +964,12 @@
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
} else {
Universe::set_narrow_oop_shift(0);
- if (PrintCompressedOopsMode) {
+ if (verbose) {
tty->print(", 32-bits Oops");
}
}
}
- if (PrintCompressedOopsMode) {
+ if (verbose) {
tty->cr();
tty->cr();
}
--- a/hotspot/src/share/vm/opto/compile.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -444,22 +444,32 @@
}
+//-----------------------init_scratch_buffer_blob------------------------------
+// Construct a temporary BufferBlob and cache it for this compile.
void Compile::init_scratch_buffer_blob(int const_size) {
- if (scratch_buffer_blob() != NULL) return;
+ // If there is already a scratch buffer blob allocated and the
+ // constant section is big enough, use it. Otherwise free the
+ // current and allocate a new one.
+ BufferBlob* blob = scratch_buffer_blob();
+ if ((blob != NULL) && (const_size <= _scratch_const_size)) {
+ // Use the current blob.
+ } else {
+ if (blob != NULL) {
+ BufferBlob::free(blob);
+ }
- // Construct a temporary CodeBuffer to have it construct a BufferBlob
- // Cache this BufferBlob for this compile.
- ResourceMark rm;
- _scratch_const_size = const_size;
- int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size);
- BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size);
- // Record the buffer blob for next time.
- set_scratch_buffer_blob(blob);
- // Have we run out of code space?
- if (scratch_buffer_blob() == NULL) {
- // Let CompilerBroker disable further compilations.
- record_failure("Not enough space for scratch buffer in CodeCache");
- return;
+ ResourceMark rm;
+ _scratch_const_size = const_size;
+ int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size);
+ blob = BufferBlob::create("Compile::scratch_buffer", size);
+ // Record the buffer blob for next time.
+ set_scratch_buffer_blob(blob);
+ // Have we run out of code space?
+ if (scratch_buffer_blob() == NULL) {
+ // Let CompilerBroker disable further compilations.
+ record_failure("Not enough space for scratch buffer in CodeCache");
+ return;
+ }
}
// Initialize the relocation buffers
@@ -468,13 +478,6 @@
}
-void Compile::clear_scratch_buffer_blob() {
- assert(scratch_buffer_blob(), "no BufferBlob set");
- set_scratch_buffer_blob(NULL);
- set_scratch_locs_memory(NULL);
-}
-
-
//-----------------------scratch_emit_size-------------------------------------
// Helper function that computes size by emitting code
uint Compile::scratch_emit_size(const Node* n) {
--- a/hotspot/src/share/vm/opto/escape.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/escape.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1609,10 +1609,11 @@
//
// Normally only 1-3 passes needed to build
// Connection Graph depending on graph complexity.
- // Set limit to 10 to catch situation when something
+ // Observed 8 passes in jvm2008 compiler.compiler.
+ // Set limit to 20 to catch situation when something
// did go wrong and recompile the method without EA.
-#define CG_BUILD_ITER_LIMIT 10
+#define CG_BUILD_ITER_LIMIT 20
uint length = worklist.length();
int iterations = 0;
--- a/hotspot/src/share/vm/opto/macro.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, 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
@@ -1158,7 +1158,7 @@
// Note: We set the control input on "eden_end" and "old_eden_top" when using
// a TLAB to work around a bug where these values were being moved across
// a safepoint. These are not oops, so they cannot be include in the oop
- // map, but the can be changed by a GC. The proper way to fix this would
+ // map, but they can be changed by a GC. The proper way to fix this would
// be to set the raw memory state when generating a SafepointNode. However
// this will require extensive changes to the loop optimization in order to
// prevent a degradation of the optimization.
@@ -1167,24 +1167,24 @@
// allocate the Region and Phi nodes for the result
result_region = new (C, 3) RegionNode(3);
- result_phi_rawmem = new (C, 3) PhiNode( result_region, Type::MEMORY, TypeRawPtr::BOTTOM );
- result_phi_rawoop = new (C, 3) PhiNode( result_region, TypeRawPtr::BOTTOM );
- result_phi_i_o = new (C, 3) PhiNode( result_region, Type::ABIO ); // I/O is used for Prefetch
+ result_phi_rawmem = new (C, 3) PhiNode(result_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+ result_phi_rawoop = new (C, 3) PhiNode(result_region, TypeRawPtr::BOTTOM);
+ result_phi_i_o = new (C, 3) PhiNode(result_region, Type::ABIO); // I/O is used for Prefetch
// We need a Region for the loop-back contended case.
enum { fall_in_path = 1, contended_loopback_path = 2 };
Node *contended_region;
Node *contended_phi_rawmem;
- if( UseTLAB ) {
+ if (UseTLAB) {
contended_region = toobig_false;
contended_phi_rawmem = mem;
} else {
contended_region = new (C, 3) RegionNode(3);
- contended_phi_rawmem = new (C, 3) PhiNode( contended_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+ contended_phi_rawmem = new (C, 3) PhiNode(contended_region, Type::MEMORY, TypeRawPtr::BOTTOM);
// Now handle the passing-too-big test. We fall into the contended
// loop-back merge point.
- contended_region ->init_req( fall_in_path, toobig_false );
- contended_phi_rawmem->init_req( fall_in_path, mem );
+ contended_region ->init_req(fall_in_path, toobig_false);
+ contended_phi_rawmem->init_req(fall_in_path, mem);
transform_later(contended_region);
transform_later(contended_phi_rawmem);
}
@@ -1192,78 +1192,101 @@
// Load(-locked) the heap top.
// See note above concerning the control input when using a TLAB
Node *old_eden_top = UseTLAB
- ? new (C, 3) LoadPNode ( ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM )
- : new (C, 3) LoadPLockedNode( contended_region, contended_phi_rawmem, eden_top_adr );
+ ? new (C, 3) LoadPNode (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM)
+ : new (C, 3) LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr);
transform_later(old_eden_top);
// Add to heap top to get a new heap top
- Node *new_eden_top = new (C, 4) AddPNode( top(), old_eden_top, size_in_bytes );
+ Node *new_eden_top = new (C, 4) AddPNode(top(), old_eden_top, size_in_bytes);
transform_later(new_eden_top);
// Check for needing a GC; compare against heap end
- Node *needgc_cmp = new (C, 3) CmpPNode( new_eden_top, eden_end );
+ Node *needgc_cmp = new (C, 3) CmpPNode(new_eden_top, eden_end);
transform_later(needgc_cmp);
- Node *needgc_bol = new (C, 2) BoolNode( needgc_cmp, BoolTest::ge );
+ Node *needgc_bol = new (C, 2) BoolNode(needgc_cmp, BoolTest::ge);
transform_later(needgc_bol);
- IfNode *needgc_iff = new (C, 2) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN );
+ IfNode *needgc_iff = new (C, 2) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN);
transform_later(needgc_iff);
// Plug the failing-heap-space-need-gc test into the slow-path region
- Node *needgc_true = new (C, 1) IfTrueNode( needgc_iff );
+ Node *needgc_true = new (C, 1) IfTrueNode(needgc_iff);
transform_later(needgc_true);
- if( initial_slow_test ) {
- slow_region ->init_req( need_gc_path, needgc_true );
+ if (initial_slow_test) {
+ slow_region->init_req(need_gc_path, needgc_true);
// This completes all paths into the slow merge point
transform_later(slow_region);
} else { // No initial slow path needed!
// Just fall from the need-GC path straight into the VM call.
- slow_region = needgc_true;
+ slow_region = needgc_true;
}
// No need for a GC. Setup for the Store-Conditional
- Node *needgc_false = new (C, 1) IfFalseNode( needgc_iff );
+ Node *needgc_false = new (C, 1) IfFalseNode(needgc_iff);
transform_later(needgc_false);
// Grab regular I/O before optional prefetch may change it.
// Slow-path does no I/O so just set it to the original I/O.
- result_phi_i_o->init_req( slow_result_path, i_o );
+ result_phi_i_o->init_req(slow_result_path, i_o);
i_o = prefetch_allocation(i_o, needgc_false, contended_phi_rawmem,
old_eden_top, new_eden_top, length);
+ // Name successful fast-path variables
+ Node* fast_oop = old_eden_top;
+ Node* fast_oop_ctrl;
+ Node* fast_oop_rawmem;
+
// Store (-conditional) the modified eden top back down.
// StorePConditional produces flags for a test PLUS a modified raw
// memory state.
- Node *store_eden_top;
- Node *fast_oop_ctrl;
- if( UseTLAB ) {
- store_eden_top = new (C, 4) StorePNode( needgc_false, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, new_eden_top );
+ if (UseTLAB) {
+ Node* store_eden_top =
+ new (C, 4) StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr,
+ TypeRawPtr::BOTTOM, new_eden_top);
transform_later(store_eden_top);
fast_oop_ctrl = needgc_false; // No contention, so this is the fast path
+ fast_oop_rawmem = store_eden_top;
} else {
- store_eden_top = new (C, 5) StorePConditionalNode( needgc_false, contended_phi_rawmem, eden_top_adr, new_eden_top, old_eden_top );
+ Node* store_eden_top =
+ new (C, 5) StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr,
+ new_eden_top, fast_oop/*old_eden_top*/);
transform_later(store_eden_top);
- Node *contention_check = new (C, 2) BoolNode( store_eden_top, BoolTest::ne );
+ Node *contention_check = new (C, 2) BoolNode(store_eden_top, BoolTest::ne);
transform_later(contention_check);
store_eden_top = new (C, 1) SCMemProjNode(store_eden_top);
transform_later(store_eden_top);
// If not using TLABs, check to see if there was contention.
- IfNode *contention_iff = new (C, 2) IfNode ( needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN );
+ IfNode *contention_iff = new (C, 2) IfNode (needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN);
transform_later(contention_iff);
- Node *contention_true = new (C, 1) IfTrueNode( contention_iff );
+ Node *contention_true = new (C, 1) IfTrueNode(contention_iff);
transform_later(contention_true);
// If contention, loopback and try again.
- contended_region->init_req( contended_loopback_path, contention_true );
- contended_phi_rawmem->init_req( contended_loopback_path, store_eden_top );
+ contended_region->init_req(contended_loopback_path, contention_true);
+ contended_phi_rawmem->init_req(contended_loopback_path, store_eden_top);
// Fast-path succeeded with no contention!
- Node *contention_false = new (C, 1) IfFalseNode( contention_iff );
+ Node *contention_false = new (C, 1) IfFalseNode(contention_iff);
transform_later(contention_false);
fast_oop_ctrl = contention_false;
+
+ // Bump total allocated bytes for this thread
+ Node* thread = new (C, 1) ThreadLocalNode();
+ transform_later(thread);
+ Node* alloc_bytes_adr = basic_plus_adr(top()/*not oop*/, thread,
+ in_bytes(JavaThread::allocated_bytes_offset()));
+ Node* alloc_bytes = make_load(fast_oop_ctrl, store_eden_top, alloc_bytes_adr,
+ 0, TypeLong::LONG, T_LONG);
+#ifdef _LP64
+ Node* alloc_size = size_in_bytes;
+#else
+ Node* alloc_size = new (C, 2) ConvI2LNode(size_in_bytes);
+ transform_later(alloc_size);
+#endif
+ Node* new_alloc_bytes = new (C, 3) AddLNode(alloc_bytes, alloc_size);
+ transform_later(new_alloc_bytes);
+ fast_oop_rawmem = make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr,
+ 0, new_alloc_bytes, T_LONG);
}
- // Rename successful fast-path variables to make meaning more obvious
- Node* fast_oop = old_eden_top;
- Node* fast_oop_rawmem = store_eden_top;
fast_oop_rawmem = initialize_object(alloc,
fast_oop_ctrl, fast_oop_rawmem, fast_oop,
klass_node, length, size_in_bytes);
@@ -1282,11 +1305,11 @@
call->init_req(TypeFunc::Parms+0, thread);
call->init_req(TypeFunc::Parms+1, fast_oop);
- call->init_req( TypeFunc::Control, fast_oop_ctrl );
- call->init_req( TypeFunc::I_O , top() ) ; // does no i/o
- call->init_req( TypeFunc::Memory , fast_oop_rawmem );
- call->init_req( TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr) );
- call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) );
+ call->init_req(TypeFunc::Control, fast_oop_ctrl);
+ call->init_req(TypeFunc::I_O , top()); // does no i/o
+ call->init_req(TypeFunc::Memory , fast_oop_rawmem);
+ call->init_req(TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr));
+ call->init_req(TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr));
transform_later(call);
fast_oop_ctrl = new (C, 1) ProjNode(call,TypeFunc::Control);
transform_later(fast_oop_ctrl);
@@ -1295,10 +1318,10 @@
}
// Plug in the successful fast-path into the result merge point
- result_region ->init_req( fast_result_path, fast_oop_ctrl );
- result_phi_rawoop->init_req( fast_result_path, fast_oop );
- result_phi_i_o ->init_req( fast_result_path, i_o );
- result_phi_rawmem->init_req( fast_result_path, fast_oop_rawmem );
+ result_region ->init_req(fast_result_path, fast_oop_ctrl);
+ result_phi_rawoop->init_req(fast_result_path, fast_oop);
+ result_phi_i_o ->init_req(fast_result_path, i_o);
+ result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem);
} else {
slow_region = ctrl;
}
--- a/hotspot/src/share/vm/opto/output.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/output.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1746,9 +1746,6 @@
// Walk backwards over each basic block, computing the needed alignment
// Walk over all the basic blocks
scheduling.DoScheduling();
-
- // Clear the BufferBlob used for scheduling.
- clear_scratch_buffer_blob();
}
//------------------------------ComputeLocalLatenciesForward-------------------
--- a/hotspot/src/share/vm/opto/stringopts.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/stringopts.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -59,7 +59,8 @@
enum {
StringMode,
IntMode,
- CharMode
+ CharMode,
+ StringNullCheckMode
};
StringConcat(PhaseStringOpts* stringopts, CallStaticJavaNode* end):
@@ -114,6 +115,9 @@
void push_string(Node* value) {
push(value, StringMode);
}
+ void push_string_null_check(Node* value) {
+ push(value, StringNullCheckMode);
+ }
void push_int(Node* value) {
push(value, IntMode);
}
@@ -416,7 +420,19 @@
if (sig == ciSymbol::string_void_signature()) {
// StringBuilder(String) so pick this up as the first argument
assert(use->in(TypeFunc::Parms + 1) != NULL, "what?");
- sc->push_string(use->in(TypeFunc::Parms + 1));
+ const Type* type = _gvn->type(use->in(TypeFunc::Parms + 1));
+ if (type == TypePtr::NULL_PTR) {
+ // StringBuilder(null) throws exception.
+#ifndef PRODUCT
+ if (PrintOptimizeStringConcat) {
+ tty->print("giving up because StringBuilder(null) throws exception");
+ alloc->jvms()->dump_spec(tty); tty->cr();
+ }
+#endif
+ return NULL;
+ }
+ // StringBuilder(str) argument needs null check.
+ sc->push_string_null_check(use->in(TypeFunc::Parms + 1));
}
// The int variant takes an initial size for the backing
// array so just treat it like the void version.
@@ -436,7 +452,7 @@
#ifndef PRODUCT
if (PrintOptimizeStringConcat) {
tty->print("giving up because couldn't find constructor ");
- alloc->jvms()->dump_spec(tty);
+ alloc->jvms()->dump_spec(tty); tty->cr();
}
#endif
break;
@@ -1269,6 +1285,25 @@
string_sizes->init_req(argi, string_size);
break;
}
+ case StringConcat::StringNullCheckMode: {
+ const Type* type = kit.gvn().type(arg);
+ assert(type != TypePtr::NULL_PTR, "missing check");
+ if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
+ // Null check with uncommont trap since
+ // StringBuilder(null) throws exception.
+ // Use special uncommon trap instead of
+ // calling normal do_null_check().
+ Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
+ IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
+ overflow->add_req(__ IfFalse(iff));
+ Node* notnull = __ IfTrue(iff);
+ kit.set_control(notnull); // set control for the cast_not_null
+ arg = kit.cast_not_null(arg, false);
+ sc->set_argument(argi, arg);
+ }
+ assert(kit.gvn().type(arg)->higher_equal(TypeInstPtr::NOTNULL), "sanity");
+ // Fallthrough to add string length.
+ }
case StringConcat::StringMode: {
const Type* type = kit.gvn().type(arg);
if (type == TypePtr::NULL_PTR) {
@@ -1328,6 +1363,7 @@
// Hook
PreserveJVMState pjvms(&kit);
kit.set_control(overflow);
+ C->record_for_igvn(overflow);
kit.uncommon_trap(Deoptimization::Reason_intrinsic,
Deoptimization::Action_make_not_entrant);
}
@@ -1363,6 +1399,7 @@
start = end;
break;
}
+ case StringConcat::StringNullCheckMode:
case StringConcat::StringMode: {
start = copy_string(kit, arg, char_array, start);
break;
--- a/hotspot/src/share/vm/prims/jvmti.xml Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/prims/jvmti.xml Wed Jan 19 19:00:30 2011 -0800
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="jvmti.xsl"?>
<!--
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, 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
@@ -10697,7 +10697,7 @@
<internallink id="mUTF">modified UTF-8</internallink> string.
</description>
</param>
- <param id="value">
+ <param id="value_ptr">
<inbuf>
<char/>
<nullok>
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -1802,7 +1802,7 @@
// depth - pre-checked as non-negative
// value - pre-checked for NULL
jvmtiError
-JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value){
+JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value_ptr){
JavaThread* current_thread = JavaThread::current();
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
@@ -1814,7 +1814,7 @@
if (err != JVMTI_ERROR_NONE) {
return err;
} else {
- *value = op.value().l;
+ *value_ptr = op.value().l;
return JVMTI_ERROR_NONE;
}
} /* end GetLocalInstance */
@@ -3440,12 +3440,12 @@
// property - pre-checked for NULL
// value - NULL is a valid value, must be checked
jvmtiError
-JvmtiEnv::SetSystemProperty(const char* property, const char* value) {
+JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {
jvmtiError err =JVMTI_ERROR_NOT_AVAILABLE;
for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
if (strcmp(property, p->key()) == 0) {
- if (p->set_value((char *)value)) {
+ if (p->set_value((char *)value_ptr)) {
err = JVMTI_ERROR_NONE;
}
}
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -111,7 +111,7 @@
//------------------------------------------------------------------------------
// MethodHandles::generate_adapters
//
-void MethodHandles::generate_adapters() {
+void MethodHandles::generate_adapters(TRAPS) {
if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL) return;
assert(_adapter_code == NULL, "generate only once");
@@ -123,20 +123,20 @@
vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
CodeBuffer code(_adapter_code);
MethodHandlesAdapterGenerator g(&code);
- g.generate();
+ g.generate(CHECK);
}
//------------------------------------------------------------------------------
// MethodHandlesAdapterGenerator::generate
//
-void MethodHandlesAdapterGenerator::generate() {
+void MethodHandlesAdapterGenerator::generate(TRAPS) {
// Generate generic method handle adapters.
for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
ek < MethodHandles::_EK_LIMIT;
ek = MethodHandles::EntryKind(1 + (int)ek)) {
StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
- MethodHandles::generate_method_handle_stub(_masm, ek);
+ MethodHandles::generate_method_handle_stub(_masm, ek, CHECK);
}
}
@@ -2645,5 +2645,10 @@
MethodHandles::set_enabled(true);
}
}
+
+ // Generate method handles adapters if enabled.
+ if (MethodHandles::enabled()) {
+ MethodHandles::generate_adapters(CHECK);
+ }
}
JVM_END
--- a/hotspot/src/share/vm/prims/methodHandles.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -294,11 +294,11 @@
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
// Generate MethodHandles adapters.
- static void generate_adapters();
+ static void generate_adapters(TRAPS);
// Called from InterpreterGenerator and MethodHandlesAdapterGenerator.
static address generate_method_handle_interpreter_entry(MacroAssembler* _masm);
- static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek);
+ static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek, TRAPS);
// argument list parsing
static int argument_slot(oop method_type, int arg);
@@ -530,7 +530,7 @@
public:
MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code) {}
- void generate();
+ void generate(TRAPS);
};
#endif // SHARE_VM_PRIMS_METHODHANDLES_HPP
--- a/hotspot/src/share/vm/runtime/arguments.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -2297,14 +2297,15 @@
} else if (match_option(option, "-Xoss", &tail)) {
// HotSpot does not have separate native and Java stacks, ignore silently for compatibility
// -Xmaxjitcodesize
- } else if (match_option(option, "-Xmaxjitcodesize", &tail)) {
+ } else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
+ match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
julong long_ReservedCodeCacheSize = 0;
ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize,
(size_t)InitialCodeCacheSize);
if (errcode != arg_in_range) {
jio_fprintf(defaultStream::error_stream(),
- "Invalid maximum code cache size: %s\n",
- option->optionString);
+ "Invalid maximum code cache size: %s. Should be greater than InitialCodeCacheSize=%dK\n",
+ option->optionString, InitialCodeCacheSize/K);
describe_range_error(errcode);
return JNI_EINVAL;
}
--- a/hotspot/src/share/vm/runtime/init.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/init.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -125,9 +125,6 @@
javaClasses_init(); // must happen after vtable initialization
stubRoutines_init2(); // note: StubRoutines need 2-phase init
- // Generate MethodHandles adapters.
- MethodHandles::generate_adapters();
-
// Although we'd like to, we can't easily do a heap verify
// here because the main thread isn't yet a JavaThread, so
// its TLAB may not be made parseable from the usual interfaces.
--- a/hotspot/src/share/vm/runtime/java.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/java.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -515,8 +515,8 @@
}
void vm_exit(int code) {
- Thread* thread = ThreadLocalStorage::thread_index() == -1 ? NULL
- : ThreadLocalStorage::get_thread_slow();
+ Thread* thread = ThreadLocalStorage::is_initialized() ?
+ ThreadLocalStorage::get_thread_slow() : NULL;
if (thread == NULL) {
// we have serious problems -- just exit
vm_direct_exit(code);
@@ -553,8 +553,9 @@
// Calling 'exit_globals()' will disable thread-local-storage and cause all
// kinds of assertions to trigger in debug mode.
if (is_init_completed()) {
- Thread* thread = Thread::current();
- if (thread->is_Java_thread()) {
+ Thread* thread = ThreadLocalStorage::is_initialized() ?
+ ThreadLocalStorage::get_thread_slow() : NULL;
+ if (thread != NULL && thread->is_Java_thread()) {
// We are leaving the VM, set state to native (in case any OS exit
// handlers call back to the VM)
JavaThread* jt = (JavaThread*)thread;
--- a/hotspot/src/share/vm/runtime/thread.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -177,20 +177,19 @@
Thread::Thread() {
- // stack
- _stack_base = NULL;
- _stack_size = 0;
- _self_raw_id = 0;
- _lgrp_id = -1;
- _osthread = NULL;
+ // stack and get_thread
+ set_stack_base(NULL);
+ set_stack_size(0);
+ set_self_raw_id(0);
+ set_lgrp_id(-1);
// allocated data structures
+ set_osthread(NULL);
set_resource_area(new ResourceArea());
set_handle_area(new HandleArea(NULL));
set_active_handles(NULL);
set_free_handle_block(NULL);
set_last_handle_mark(NULL);
- set_osthread(NULL);
// This initial value ==> never claimed.
_oops_do_parity = 0;
@@ -205,6 +204,7 @@
NOT_PRODUCT(_skip_gcalot = false;)
CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
_jvmti_env_iteration_count = 0;
+ set_allocated_bytes(0);
_vm_operation_started_count = 0;
_vm_operation_completed_count = 0;
_current_pending_monitor = NULL;
@@ -3231,7 +3231,7 @@
warning("java.lang.ArithmeticException has not been initialized");
warning("java.lang.StackOverflowError has not been initialized");
}
- }
+ }
// See : bugid 4211085.
// Background : the static initializer of java.lang.Compiler tries to read
--- a/hotspot/src/share/vm/runtime/thread.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/thread.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -60,7 +60,7 @@
class JvmtiGetLoadedClassesClosure;
class ThreadStatistics;
class ConcurrentLocksDump;
-class ParkEvent ;
+class ParkEvent;
class Parker;
class ciEnv;
@@ -170,7 +170,7 @@
//
// suspend/resume lock: used for self-suspend
- Monitor* _SR_lock;
+ Monitor* _SR_lock;
protected:
enum SuspendFlags {
@@ -194,7 +194,7 @@
public:
void enter_signal_handler() { _num_nested_signal++; }
void leave_signal_handler() { _num_nested_signal--; }
- bool is_inside_signal_handler() const { return _num_nested_signal > 0; }
+ bool is_inside_signal_handler() const { return _num_nested_signal > 0; }
private:
// Debug tracing
@@ -215,7 +215,7 @@
public:
void set_last_handle_mark(HandleMark* mark) { _last_handle_mark = mark; }
- HandleMark* last_handle_mark() const { return _last_handle_mark; }
+ HandleMark* last_handle_mark() const { return _last_handle_mark; }
private:
// debug support for checking if code does allow safepoints or not
@@ -227,11 +227,11 @@
//
// The two classes No_Safepoint_Verifier and No_Allocation_Verifier are used to set these counters.
//
- NOT_PRODUCT(int _allow_safepoint_count;) // If 0, thread allow a safepoint to happen
- debug_only (int _allow_allocation_count;) // If 0, the thread is allowed to allocate oops.
+ NOT_PRODUCT(int _allow_safepoint_count;) // If 0, thread allow a safepoint to happen
+ debug_only (int _allow_allocation_count;) // If 0, the thread is allowed to allocate oops.
// Used by SkipGCALot class.
- NOT_PRODUCT(bool _skip_gcalot;) // Should we elide gc-a-lot?
+ NOT_PRODUCT(bool _skip_gcalot;) // Should we elide gc-a-lot?
// Record when GC is locked out via the GC_locker mechanism
CHECK_UNHANDLED_OOPS_ONLY(int _gc_locked_out_count;)
@@ -242,24 +242,26 @@
friend class ThreadLocalStorage;
friend class GC_locker;
- ThreadLocalAllocBuffer _tlab; // Thread-local eden
+ ThreadLocalAllocBuffer _tlab; // Thread-local eden
+ jlong _allocated_bytes; // Cumulative number of bytes allocated on
+ // the Java heap
- int _vm_operation_started_count; // VM_Operation support
- int _vm_operation_completed_count; // VM_Operation support
+ int _vm_operation_started_count; // VM_Operation support
+ int _vm_operation_completed_count; // VM_Operation support
- ObjectMonitor* _current_pending_monitor; // ObjectMonitor this thread
- // is waiting to lock
- bool _current_pending_monitor_is_from_java; // locking is from Java code
+ ObjectMonitor* _current_pending_monitor; // ObjectMonitor this thread
+ // is waiting to lock
+ bool _current_pending_monitor_is_from_java; // locking is from Java code
// ObjectMonitor on which this thread called Object.wait()
ObjectMonitor* _current_waiting_monitor;
// Private thread-local objectmonitor list - a simple cache organized as a SLL.
public:
- ObjectMonitor * omFreeList ;
- int omFreeCount ; // length of omFreeList
- int omFreeProvision ; // reload chunk size
- ObjectMonitor * omInUseList; // SLL to track monitors in circulation
+ ObjectMonitor* omFreeList;
+ int omFreeCount; // length of omFreeList
+ int omFreeProvision; // reload chunk size
+ ObjectMonitor* omInUseList; // SLL to track monitors in circulation
int omInUseCount; // length of omInUseList
public:
@@ -280,7 +282,6 @@
// Testers
virtual bool is_VM_thread() const { return false; }
virtual bool is_Java_thread() const { return false; }
- // Remove this ifdef when C1 is ported to the compiler interface.
virtual bool is_Compiler_thread() const { return false; }
virtual bool is_hidden_from_external_view() const { return false; }
virtual bool is_jvmti_agent_thread() const { return false; }
@@ -344,15 +345,15 @@
// Support for Unhandled Oop detection
#ifdef CHECK_UNHANDLED_OOPS
private:
- UnhandledOops *_unhandled_oops;
+ UnhandledOops* _unhandled_oops;
public:
- UnhandledOops* unhandled_oops() { return _unhandled_oops; }
+ UnhandledOops* unhandled_oops() { return _unhandled_oops; }
// Mark oop safe for gc. It may be stack allocated but won't move.
- void allow_unhandled_oop(oop *op) {
+ void allow_unhandled_oop(oop *op) {
if (CheckUnhandledOops) unhandled_oops()->allow_unhandled_oop(op);
}
// Clear oops at safepoint so crashes point to unhandled oop violator
- void clear_unhandled_oops() {
+ void clear_unhandled_oops() {
if (CheckUnhandledOops) unhandled_oops()->clear_unhandled_oops();
}
bool is_gc_locked_out() { return _gc_locked_out_count > 0; }
@@ -392,6 +393,22 @@
}
}
+ jlong allocated_bytes() { return _allocated_bytes; }
+ void set_allocated_bytes(jlong value) { _allocated_bytes = value; }
+ void incr_allocated_bytes(jlong size) { _allocated_bytes += size; }
+ jlong cooked_allocated_bytes() {
+ jlong allocated_bytes = OrderAccess::load_acquire(&_allocated_bytes);
+ if (UseTLAB) {
+ size_t used_bytes = tlab().used_bytes();
+ if ((ssize_t)used_bytes > 0) {
+ // More-or-less valid tlab. The load_acquire above should ensure
+ // that the result of the add is <= the instantaneous value
+ return allocated_bytes + used_bytes;
+ }
+ }
+ return allocated_bytes;
+ }
+
// VM operation support
int vm_operation_ticket() { return ++_vm_operation_started_count; }
int vm_operation_completed_count() { return _vm_operation_completed_count; }
@@ -489,8 +506,11 @@
return (_stack_base >= adr && adr >= (_stack_base - _stack_size));
}
- int lgrp_id() const { return _lgrp_id; }
- void set_lgrp_id(int value) { _lgrp_id = value; }
+ uintptr_t self_raw_id() { return _self_raw_id; }
+ void set_self_raw_id(uintptr_t value) { _self_raw_id = value; }
+
+ int lgrp_id() const { return _lgrp_id; }
+ void set_lgrp_id(int value) { _lgrp_id = value; }
// Printing
void print_on(outputStream* st) const;
@@ -502,7 +522,7 @@
#ifdef ASSERT
private:
// Deadlock detection support for Mutex locks. List of locks own by thread.
- Monitor *_owned_locks;
+ Monitor* _owned_locks;
// Mutex::set_owner_implementation is the only place where _owned_locks is modified,
// thus the friendship
friend class Mutex;
@@ -511,7 +531,7 @@
public:
void print_owned_locks_on(outputStream* st) const;
void print_owned_locks() const { print_owned_locks_on(tty); }
- Monitor * owned_locks() const { return _owned_locks; }
+ Monitor* owned_locks() const { return _owned_locks; }
bool owns_locks() const { return owned_locks() != NULL; }
bool owns_locks_but_compiled_lock() const;
@@ -538,7 +558,7 @@
static ByteSize stack_size_offset() { return byte_offset_of(Thread, _stack_size ); }
#define TLAB_FIELD_OFFSET(name) \
- static ByteSize tlab_##name##_offset() { return byte_offset_of(Thread, _tlab) + ThreadLocalAllocBuffer::name##_offset(); }
+ static ByteSize tlab_##name##_offset() { return byte_offset_of(Thread, _tlab) + ThreadLocalAllocBuffer::name##_offset(); }
TLAB_FIELD_OFFSET(start)
TLAB_FIELD_OFFSET(end)
@@ -552,6 +572,8 @@
#undef TLAB_FIELD_OFFSET
+ static ByteSize allocated_bytes_offset() { return byte_offset_of(Thread, _allocated_bytes ); }
+
public:
volatile intptr_t _Stalled ;
volatile int _TypeTag ;
--- a/hotspot/src/share/vm/services/jmm.h Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/services/jmm.h Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -60,7 +60,8 @@
unsigned int isBootClassPathSupported : 1;
unsigned int isObjectMonitorUsageSupported : 1;
unsigned int isSynchronizerUsageSupported : 1;
- unsigned int : 24;
+ unsigned int isThreadAllocatedMemorySupported : 1;
+ unsigned int : 23;
} jmmOptionalSupport;
typedef enum {
@@ -105,7 +106,8 @@
JMM_VERBOSE_GC = 21,
JMM_VERBOSE_CLASS = 22,
JMM_THREAD_CONTENTION_MONITORING = 23,
- JMM_THREAD_CPU_TIME = 24
+ JMM_THREAD_CPU_TIME = 24,
+ JMM_THREAD_ALLOCATED_MEMORY = 25
} jmmBoolAttribute;
@@ -213,7 +215,10 @@
jobject (JNICALL *GetMemoryPoolUsage) (JNIEnv* env, jobject pool);
jobject (JNICALL *GetPeakMemoryPoolUsage) (JNIEnv* env, jobject pool);
- void* reserved4;
+ void (JNICALL *GetThreadAllocatedMemory)
+ (JNIEnv *env,
+ jlongArray ids,
+ jlongArray sizeArray);
jobject (JNICALL *GetMemoryUsage) (JNIEnv* env, jboolean heap);
@@ -228,6 +233,8 @@
jlong* result);
jobjectArray (JNICALL *FindCircularBlockedThreads) (JNIEnv *env);
+
+ // Not used in JDK 6 or JDK 7
jlong (JNICALL *GetThreadCpuTime) (JNIEnv *env, jlong thread_id);
jobjectArray (JNICALL *GetVMGlobalNames) (JNIEnv *env);
@@ -262,14 +269,22 @@
void (JNICALL *GetLastGCStat) (JNIEnv *env,
jobject mgr,
jmmGCStat *gc_stat);
- jlong (JNICALL *GetThreadCpuTimeWithKind) (JNIEnv *env,
- jlong thread_id,
- jboolean user_sys_cpu_time);
- void* reserved5;
+
+ jlong (JNICALL *GetThreadCpuTimeWithKind)
+ (JNIEnv *env,
+ jlong thread_id,
+ jboolean user_sys_cpu_time);
+ void (JNICALL *GetThreadCpuTimesWithKind)
+ (JNIEnv *env,
+ jlongArray ids,
+ jlongArray timeArray,
+ jboolean user_sys_cpu_time);
+
jint (JNICALL *DumpHeap0) (JNIEnv *env,
jstring outputfile,
jboolean live);
- jobjectArray (JNICALL *FindDeadlocks) (JNIEnv *env, jboolean object_monitors_only);
+ jobjectArray (JNICALL *FindDeadlocks) (JNIEnv *env,
+ jboolean object_monitors_only);
void (JNICALL *SetVMGlobal) (JNIEnv *env,
jstring flag_name,
jvalue new_value);
--- a/hotspot/src/share/vm/services/management.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/services/management.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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,12 +101,14 @@
_optional_support.isCurrentThreadCpuTimeSupported = 0;
_optional_support.isOtherThreadCpuTimeSupported = 0;
}
+
_optional_support.isBootClassPathSupported = 1;
_optional_support.isObjectMonitorUsageSupported = 1;
#ifndef SERVICES_KERNEL
// This depends on the heap inspector
_optional_support.isSynchronizerUsageSupported = 1;
#endif // SERVICES_KERNEL
+ _optional_support.isThreadAllocatedMemorySupported = 1;
}
void Management::initialize(TRAPS) {
@@ -386,11 +388,6 @@
static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
int num_threads = ids_ah->length();
- // should be non-empty array
- if (num_threads == 0) {
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "Empty array of thread IDs");
- }
// Validate input thread IDs
int i = 0;
@@ -402,11 +399,9 @@
"Invalid thread ID entry");
}
}
-
}
static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
-
// check if the element of infoArray is of type ThreadInfo class
klassOop threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
klassOop element_klass = objArrayKlass::cast(infoArray_h->klass())->element_klass();
@@ -414,7 +409,6 @@
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"infoArray element type is not ThreadInfo class");
}
-
}
@@ -770,6 +764,45 @@
return prev;
JVM_END
+// Gets an array containing the amount of memory allocated on the Java
+// heap for a set of threads (in bytes). Each element of the array is
+// the amount of memory allocated for the thread ID specified in the
+// corresponding entry in the given array of thread IDs; or -1 if the
+// thread does not exist or has terminated.
+JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
+ jlongArray sizeArray))
+ // Check if threads is null
+ if (ids == NULL || sizeArray == NULL) {
+ THROW(vmSymbols::java_lang_NullPointerException());
+ }
+
+ ResourceMark rm(THREAD);
+ typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
+ typeArrayHandle ids_ah(THREAD, ta);
+
+ typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
+ typeArrayHandle sizeArray_h(THREAD, sa);
+
+ // validate the thread id array
+ validate_thread_id_array(ids_ah, CHECK);
+
+ // sizeArray must be of the same length as the given array of thread IDs
+ int num_threads = ids_ah->length();
+ if (num_threads != sizeArray_h->length()) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "The length of the given long array does not match the length of "
+ "the given array of thread IDs");
+ }
+
+ MutexLockerEx ml(Threads_lock);
+ for (int i = 0; i < num_threads; i++) {
+ JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
+ if (java_thread != NULL) {
+ sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
+ }
+ }
+JVM_END
+
// Returns a java/lang/management/MemoryUsage object representing
// the memory usage for the heap or non-heap memory.
JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
@@ -834,6 +867,8 @@
return ThreadService::is_thread_monitoring_contention();
case JMM_THREAD_CPU_TIME:
return ThreadService::is_thread_cpu_time_enabled();
+ case JMM_THREAD_ALLOCATED_MEMORY:
+ return ThreadService::is_thread_allocated_memory_enabled();
default:
assert(0, "Unrecognized attribute");
return false;
@@ -851,6 +886,8 @@
return ThreadService::set_thread_monitoring_contention(flag != 0);
case JMM_THREAD_CPU_TIME:
return ThreadService::set_thread_cpu_time_enabled(flag != 0);
+ case JMM_THREAD_ALLOCATED_MEMORY:
+ return ThreadService::set_thread_allocated_memory_enabled(flag != 0);
default:
assert(0, "Unrecognized attribute");
return false;
@@ -1096,6 +1133,7 @@
// maxDepth == 0 requests no stack trace.
// infoArray - array of ThreadInfo objects
//
+// QQQ - Why does this method return a value instead of void?
JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray))
// Check if threads is null
if (ids == NULL || infoArray == NULL) {
@@ -1159,7 +1197,6 @@
}
} else {
// obtain thread dump with the specific list of threads with stack trace
-
do_thread_dump(&dump_result,
ids_ah,
num_threads,
@@ -1252,8 +1289,6 @@
continue;
}
-
-
ThreadStackTrace* stacktrace = ts->get_stack_trace();
assert(stacktrace != NULL, "Must have a stack trace dumped");
@@ -1500,6 +1535,49 @@
return -1;
JVM_END
+// Gets an array containing the CPU times consumed by a set of threads
+// (in nanoseconds). Each element of the array is the CPU time for the
+// thread ID specified in the corresponding entry in the given array
+// of thread IDs; or -1 if the thread does not exist or has terminated.
+// If user_sys_cpu_time = true, the sum of user level and system CPU time
+// for the given thread is returned; otherwise, only user level CPU time
+// is returned.
+JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
+ jlongArray timeArray,
+ jboolean user_sys_cpu_time))
+ // Check if threads is null
+ if (ids == NULL || timeArray == NULL) {
+ THROW(vmSymbols::java_lang_NullPointerException());
+ }
+
+ ResourceMark rm(THREAD);
+ typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
+ typeArrayHandle ids_ah(THREAD, ta);
+
+ typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
+ typeArrayHandle timeArray_h(THREAD, tia);
+
+ // validate the thread id array
+ validate_thread_id_array(ids_ah, CHECK);
+
+ // timeArray must be of the same length as the given array of thread IDs
+ int num_threads = ids_ah->length();
+ if (num_threads != timeArray_h->length()) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "The length of the given long array does not match the length of "
+ "the given array of thread IDs");
+ }
+
+ MutexLockerEx ml(Threads_lock);
+ for (int i = 0; i < num_threads; i++) {
+ JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
+ if (java_thread != NULL) {
+ timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
+ user_sys_cpu_time != 0));
+ }
+ }
+JVM_END
+
// Returns a String array of all VM global flag names
JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
// last flag entry is always NULL, so subtract 1
@@ -2020,7 +2098,7 @@
jmm_GetMemoryManagers,
jmm_GetMemoryPoolUsage,
jmm_GetPeakMemoryPoolUsage,
- NULL,
+ jmm_GetThreadAllocatedMemory,
jmm_GetMemoryUsage,
jmm_GetLongAttribute,
jmm_GetBoolAttribute,
@@ -2038,7 +2116,7 @@
jmm_GetGCExtAttributeInfo,
jmm_GetLastGCStat,
jmm_GetThreadCpuTimeWithKind,
- NULL,
+ jmm_GetThreadCpuTimesWithKind,
jmm_DumpHeap0,
jmm_FindDeadlockedThreads,
jmm_SetVMGlobal,
--- a/hotspot/src/share/vm/services/threadService.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/services/threadService.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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,6 +46,7 @@
// Default is disabled.
bool ThreadService::_thread_monitoring_contention_enabled = false;
bool ThreadService::_thread_cpu_time_enabled = false;
+bool ThreadService::_thread_allocated_memory_enabled = false;
PerfCounter* ThreadService::_total_threads_count = NULL;
PerfVariable* ThreadService::_live_threads_count = NULL;
@@ -84,6 +85,8 @@
if (os::is_thread_cpu_time_supported()) {
_thread_cpu_time_enabled = true;
}
+
+ _thread_allocated_memory_enabled = true; // Always on, so enable it
}
void ThreadService::reset_peak_thread_count() {
@@ -181,6 +184,15 @@
return prev;
}
+bool ThreadService::set_thread_allocated_memory_enabled(bool flag) {
+ MutexLocker m(Management_lock);
+
+ bool prev = _thread_allocated_memory_enabled;
+ _thread_allocated_memory_enabled = flag;
+
+ return prev;
+}
+
// GC support
void ThreadService::oops_do(OopClosure* f) {
for (ThreadDumpResult* dump = _threaddump_list; dump != NULL; dump = dump->next()) {
--- a/hotspot/src/share/vm/services/threadService.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/services/threadService.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,6 +65,7 @@
static bool _thread_monitoring_contention_enabled;
static bool _thread_cpu_time_enabled;
+ static bool _thread_allocated_memory_enabled;
// Need to keep the list of thread dump result that
// keep references to methodOop since thread dump can be
@@ -83,6 +84,9 @@
static bool set_thread_cpu_time_enabled(bool flag);
static bool is_thread_cpu_time_enabled() { return _thread_cpu_time_enabled; }
+ static bool set_thread_allocated_memory_enabled(bool flag);
+ static bool is_thread_allocated_memory_enabled() { return _thread_cpu_time_enabled; }
+
static jlong get_total_thread_count() { return _total_threads_count->get_value(); }
static jlong get_peak_thread_count() { return _peak_threads_count->get_value(); }
static jlong get_live_thread_count() { return _live_threads_count->get_value() - _exiting_threads_count; }
--- a/hotspot/src/share/vm/utilities/debug.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/utilities/debug.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -226,7 +226,7 @@
void report_vm_out_of_memory(const char* file, int line, size_t size,
const char* message) {
- if (Debugging || error_is_suppressed(file, line)) return;
+ if (Debugging) return;
// We try to gather additional information for the first out of memory
// error only; gathering additional data might cause an allocation and a
--- a/hotspot/src/share/vm/utilities/vmError.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -67,7 +67,7 @@
// threads are blocked forever inside report_and_die().
// Constructor for crashes
-VMError::VMError(Thread* thread, int sig, address pc, void* siginfo, void* context) {
+VMError::VMError(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context) {
_thread = thread;
_id = sig;
_pc = pc;
@@ -322,29 +322,51 @@
STEP(10, "(printing fatal error message)")
- st->print_cr("#");
- st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
+ st->print_cr("#");
+ if (should_report_bug(_id)) {
+ st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
+ } else {
+ st->print_cr("# There is insufficient memory for the Java "
+ "Runtime Environment to continue.");
+ }
STEP(15, "(printing type of error)")
switch(_id) {
case oom_error:
- st->print_cr("#");
- st->print("# java.lang.OutOfMemoryError: ");
if (_size) {
- st->print("requested ");
- sprintf(buf,SIZE_FORMAT,_size);
+ st->print("# Native memory allocation (malloc) failed to allocate ");
+ jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
st->print(buf);
st->print(" bytes");
if (_message != NULL) {
st->print(" for ");
st->print(_message);
}
- st->print_cr(". Out of swap space?");
+ st->cr();
} else {
if (_message != NULL)
+ st->print("# ");
st->print_cr(_message);
}
+ // In error file give some solutions
+ if (_verbose) {
+ st->print_cr("# Possible reasons:");
+ st->print_cr("# The system is out of physical RAM or swap space");
+ st->print_cr("# In 32 bit mode, the process size limit was hit");
+ st->print_cr("# Possible solutions:");
+ st->print_cr("# Reduce memory load on the system");
+ st->print_cr("# Increase physical memory or swap space");
+ st->print_cr("# Check if swap backing store is full");
+ st->print_cr("# Use 64 bit Java on a 64 bit OS");
+ st->print_cr("# Decrease Java heap size (-Xmx/-Xms)");
+ st->print_cr("# Decrease number of Java threads");
+ st->print_cr("# Decrease Java thread stack sizes (-Xss)");
+ st->print_cr("# Set larger code cache with -XX:ReservedCodeCacheSize=");
+ st->print_cr("# This output file may be truncated or incomplete.");
+ } else {
+ return; // that's enough for the screen
+ }
break;
case internal_error:
default:
@@ -361,7 +383,11 @@
st->print(" (0x%x)", _id); // signal number
st->print(" at pc=" PTR_FORMAT, _pc);
} else {
- st->print("Internal Error");
+ if (should_report_bug(_id)) {
+ st->print("Internal Error");
+ } else {
+ st->print("Out of Memory Error");
+ }
if (_filename != NULL && _lineno > 0) {
#ifdef PRODUCT
// In product mode chop off pathname?
@@ -393,12 +419,14 @@
STEP(40, "(printing error message)")
- // error message
- if (_detail_msg) {
- st->print_cr("# %s: %s", _message ? _message : "Error", _detail_msg);
- } else if (_message) {
- st->print_cr("# Error: %s", _message);
- }
+ if (should_report_bug(_id)) { // already printed the message.
+ // error message
+ if (_detail_msg) {
+ st->print_cr("# %s: %s", _message ? _message : "Error", _detail_msg);
+ } else if (_message) {
+ st->print_cr("# Error: %s", _message);
+ }
+ }
STEP(50, "(printing Java version string)")
@@ -428,7 +456,9 @@
STEP(65, "(printing bug submit message)")
- if (_verbose) print_bug_submit_message(st, _thread);
+ if (should_report_bug(_id) && _verbose) {
+ print_bug_submit_message(st, _thread);
+ }
STEP(70, "(printing thread)" )
@@ -906,7 +936,7 @@
OnError = NULL;
}
- static bool skip_bug_url = false;
+ static bool skip_bug_url = !should_report_bug(first_error->_id);
if (!skip_bug_url) {
skip_bug_url = true;
@@ -919,7 +949,8 @@
static bool skip_os_abort = false;
if (!skip_os_abort) {
skip_os_abort = true;
- os::abort();
+ bool dump_core = should_report_bug(first_error->_id);
+ os::abort(dump_core);
}
// if os::abort() doesn't abort, try os::die();
--- a/hotspot/src/share/vm/utilities/vmError.hpp Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/utilities/vmError.hpp Wed Jan 19 19:00:30 2011 -0800
@@ -87,10 +87,12 @@
// accessor
const char* message() const { return _message; }
const char* detail_msg() const { return _detail_msg; }
+ bool should_report_bug(unsigned int id) { return id != oom_error; }
public:
// Constructor for crashes
- VMError(Thread* thread, int sig, address pc, void* siginfo, void* context);
+ VMError(Thread* thread, unsigned int sig, address pc, void* siginfo,
+ void* context);
// Constructor for VM internal errors
VMError(Thread* thread, const char* filename, int lineno,
const char* message, const char * detail_msg);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6579789/Test6579789.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, 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 6579789
+ * @summary Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
+ * @run main/othervm -Xcomp -XX:UseSSE=0 -XX:CompileOnly=Test6579789.bug Test6579789
+ */
+
+public class Test6579789 {
+ public static void main(String[] args) {
+ bug(4);
+ }
+ public static void bug(int n) {
+ float f = 1;
+ int i = 1;
+ try {
+ int x = 1 / n; // instruction that can trap
+ f = 2;
+ i = 2;
+ int y = 2 / n; // instruction that can trap
+ } catch (Exception ex) {
+ f++;
+ i++;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7009231/Test7009231.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010, 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 7009231
+ * @summary C1: Incorrect CAS code for longs on SPARC 32bit
+ *
+ * @run main/othervm -Xbatch Test7009231
+ *
+ */
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicLong;
+
+
+public class Test7009231 {
+ public static void main(String[] args) throws InterruptedException {
+ doTest(8);
+ }
+
+ private static void doTest(int nThreads) throws InterruptedException {
+ Thread[] aThreads = new Thread[nThreads];
+ final AtomicLong atl = new AtomicLong();
+
+ for (int i = 0; i < nThreads; i++) {
+ aThreads[i] = new RunnerThread(atl, 1L << (8 * i));
+ }
+
+ for (int i = 0; i < nThreads; i++) {
+ aThreads[i].start();
+ }
+
+ for (int i = 0; i < nThreads; i++) {
+ aThreads[i].join();
+ }
+ }
+
+ public static class RunnerThread extends Thread {
+ public RunnerThread(AtomicLong atomic, long lMask) {
+ m_lMask = lMask;
+ m_atomic = atomic;
+ }
+
+ public void run() {
+ AtomicLong atomic = m_atomic;
+ long lMask = m_lMask;
+ for (int i = 0; i < 100000; i++) {
+ setBit(atomic, lMask);
+ clearBit(atomic, lMask);
+ }
+ }
+
+ protected void setBit(AtomicLong atomic, long lMask) {
+ long lWord;
+ do {
+ lWord = atomic.get();
+ } while (!atomic.compareAndSet(lWord, lWord | lMask));
+
+ if ((atomic.get() & lMask) == 0L) {
+ throw new InternalError();
+ }
+ }
+
+ protected void clearBit(AtomicLong atomic, long lMask) {
+ long lWord;
+ do {
+ lWord = atomic.get();
+ } while (!atomic.compareAndSet(lWord, lWord & ~lMask));
+
+ if ((atomic.get() & lMask) != 0L) {
+ throw new InternalError();
+ }
+ }
+
+ private long m_lMask;
+ private AtomicLong m_atomic;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7009359/Test7009359.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010, 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 7009359
+ * @summary HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
+ *
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+OptimizeStringConcat -XX:CompileCommand=exclude,Test7009359,main Test7009359
+ *
+ */
+
+public class Test7009359 {
+ public static void main (String[] args) {
+ for(int i = 0; i < 1000000; i++) {
+ if(!stringmakerBUG(null).equals("NPE")) {
+ System.out.println("StringBuffer(null) does not throw NPE");
+ System.exit(97);
+ }
+ }
+ }
+
+ public static String stringmakerBUG(String str) {
+ try {
+ return new StringBuffer(str).toString();
+ } catch (NullPointerException e) {
+ return "NPE";
+ }
+ }
+}
+
--- a/jaxp/.hgtags Mon Jan 17 13:29:12 2011 +0530
+++ b/jaxp/.hgtags Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
63dae40fa19fd3bf4689ea2f3c1d9d690e1abcee jdk7-b121
03ff13d19c8fa983cbab6542930a7f352e9b5b33 jdk7-b122
e2aedea6495d61557326928de20dbb2d78fdd9aa jdk7-b123
+57ed1f3bec72924cdad102f9bf90f7449ea7bb83 jdk7-b124
+6c9bdee0cc3a8912acc5189cc092b8cba6851f9d jdk7-b125
--- a/jaxp/jaxp.properties Mon Jan 17 13:29:12 2011 +0530
+++ b/jaxp/jaxp.properties Wed Jan 19 19:00:30 2011 -0800
@@ -25,13 +25,13 @@
drops.master.copy.base=${drops.dir}
-jaxp_src.bundle.name=jaxp-1_4_4.zip
-jaxp_src.bundle.md5.checksum=2c40a758392c4abf2d59f355240df46a
+jaxp_src.bundle.name=jaxp-1_4_5-dev.zip
+jaxp_src.bundle.md5.checksum=84e2c26853262c9144133c6ff7ef5dc9
jaxp_src.master.bundle.dir=${drops.master.copy.base}
-jaxp_src.master.bundle.url.base=https://java.net/downloads/jaxp/jdk7
+jaxp_src.master.bundle.url.base=http://download.java.net/jaxp/1.4.5/dev
-#jaxp_tests.bundle.name=jaxp-unittests-1_4_4.zip
-#jaxp_tests.bundle.md5.checksum=51845e38b02920cf5374d0331ab3a4ee
-#jaxp_tests.master.bundle.dir=${drops.master.copy.base}
-#jaxp_tests.master.bundle.url.base=https://java.net/downloads/jaxp/jdk7
+jaxp_tests.bundle.name=jaxp-1_4_5-dev-unittests.zip
+jaxp_tests.bundle.md5.checksum=0377e715fa21814cb8006768c5967dc5
+jaxp_tests.master.bundle.dir=${drops.master.copy.base}
+jaxp_tests.master.bundle.url.base=http://download.java.net/jaxp/1.4.5/dev
--- a/jaxws/.hgtags Mon Jan 17 13:29:12 2011 +0530
+++ b/jaxws/.hgtags Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
0fa950117faac7bdbc94e6c46b88f6f892031c17 jdk7-b121
17b6c48a344968880925dcef1178fec282feb335 jdk7-b122
5a8e43bcce56b7cd5576419067a929b74575ae71 jdk7-b123
+86f60e5b3975840968f3147ddce047a27a9fc83e jdk7-b124
+d72eea121c3bc2b649272a37b80d9417855b7146 jdk7-b125
--- a/jaxws/jaxws.properties Mon Jan 17 13:29:12 2011 +0530
+++ b/jaxws/jaxws.properties Wed Jan 19 19:00:30 2011 -0800
@@ -25,10 +25,10 @@
drops.master.copy.base=${drops.dir}
-jaxws_src.bundle.name= jdk7-jaxws2_2-2010_08_19.zip
-jaxws_src.bundle.md5.checksum=8775ccefd3b4fa2dde5155ec4b7e4ceb
+jaxws_src.bundle.name=jdk7-jaxws2_2_2-2010_12_14.zip
+jaxws_src.bundle.md5.checksum=fee9ac72fabc96719eefc66ecaff4bc3
jaxws_src.master.bundle.dir=${drops.master.copy.base}
-jaxws_src.master.bundle.url.base=https://java.net/downloads/jax-ws/JDK7
+jaxws_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk7
jaf_src.bundle.name=jdk7-jaf-2010_08_19.zip
jaf_src.bundle.md5.checksum=18d15dfd71117daadb332af003d08212
--- a/jdk/.hgtags Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/.hgtags Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
a661d8587b5d8986aacae086f5df66af9e1a96b1 jdk7-b121
ac311eb325bfc763698219252bf3cee9e091f3af jdk7-b122
869190935eedee7750d955019ab2a1b80f0a13a8 jdk7-b123
+1c72adc9d5f331cb882cf5354ba0dcb118a60b23 jdk7-b124
+0a56bdd709d01c1663047e55201d19152ffd3d69 jdk7-b125
--- a/jdk/make/sun/Makefile Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/Makefile Wed Jan 19 19:00:30 2011 -0800
@@ -42,7 +42,15 @@
ifndef OPENJDK
ifeq ($(PLATFORM), solaris)
ifneq ($(ARCH), amd64)
- DGA_SUBDIR = jdga
+ # Solaris 11 does not have support for new compilation of DGA code.
+ OS_VERSION = $(shell uname -r)
+ OS_MAJOR_VERSION := $(call MajorVersion,$(OS_VERSION))
+ OS_MINOR_VERSION := $(call MinorVersion,$(OS_VERSION))
+ ifeq ($(shell $(EXPR) $(OS_MAJOR_VERSION) == 5), 1)
+ ifeq ($(shell $(EXPR) $(OS_MINOR_VERSION) \<= 10), 1)
+ DGA_SUBDIR = jdga
+ endif
+ endif
endif
endif
endif
--- a/jdk/make/sun/awt/Makefile Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/awt/Makefile Wed Jan 19 19:00:30 2011 -0800
@@ -175,6 +175,10 @@
include $(BUILDDIR)/common/Mapfile-vers.gmk
include $(BUILDDIR)/common/Library.gmk
+COMPILEFONTCONFIG_FLAGS =
+ifdef ALT_COMPILEFONTCONFIG_FLAGS
+ COMPILEFONTCONFIG_FLAGS += $(ALT_COMPILEFONTCONFIG_FLAGS)
+endif
build: fontconfigs
@@ -406,7 +410,7 @@
$(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \
$(COMPILEFONTCONFIG_JARFILE)
$(prep-target)
- $(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $< $@
+ $(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $(COMPILEFONTCONFIG_FLAGS) $< $@
$(install-module-file)
$(call chmod-file, 444)
@$(java-vm-cleanup)
--- a/jdk/make/sun/awt/make.depend Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/awt/make.depend Wed Jan 19 19:00:30 2011 -0800
@@ -224,7 +224,7 @@
$(OBJDIR)/DrawLine.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawLine.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
-$(OBJDIR)/DrawParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawParallelogram.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/LoopMacros.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
+$(OBJDIR)/DrawParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawParallelogram.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/DrawPath.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
@@ -232,7 +232,7 @@
$(OBJDIR)/DrawRect.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawRect.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
-$(OBJDIR)/FillParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
+$(OBJDIR)/FillParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/FillPath.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
@@ -284,7 +284,7 @@
$(OBJDIR)/MaskBlit.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskBlit.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/Region.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/awt/utility/rect.h ../../../src/windows/native/sun/java2d/j2d_md.h
-$(OBJDIR)/MaskFill.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskFill.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
+$(OBJDIR)/MaskFill.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskFill.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/MouseInfo.obj:: $(CLASSHDRDIR)/java_awt_AWTEvent.h $(CLASSHDRDIR)/java_awt_Component.h $(CLASSHDRDIR)/java_awt_Dimension.h $(CLASSHDRDIR)/java_awt_Event.h $(CLASSHDRDIR)/java_awt_event_FocusEvent.h $(CLASSHDRDIR)/java_awt_event_KeyEvent.h $(CLASSHDRDIR)/java_awt_event_MouseEvent.h $(CLASSHDRDIR)/java_awt_event_WindowEvent.h $(CLASSHDRDIR)/java_awt_Font.h $(CLASSHDRDIR)/sun_awt_FontDescriptor.h $(CLASSHDRDIR)/sun_awt_PlatformFont.h $(CLASSHDRDIR)/sun_awt_windows_WComponentPeer.h $(CLASSHDRDIR)/sun_awt_windows_WFontMetrics.h $(CLASSHDRDIR)/sun_awt_windows_WObjectPeer.h $(CLASSHDRDIR)/sun_awt_windows_WToolkit.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/awt/image/cvutils/img_globals.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.h ../../../src/windows/native/sun/windows/alloc.h ../../../src/windows/native/sun/windows/awt.h ../../../src/windows/native/sun/windows/awtmsg.h ../../../src/windows/native/sun/windows/awt_Brush.h ../../../src/windows/native/sun/windows/awt_Component.h ../../../src/windows/native/sun/windows/awt_Debug.h ../../../src/windows/native/sun/windows/awt_Font.h ../../../src/windows/native/sun/windows/awt_GDIObject.h ../../../src/windows/native/sun/windows/awt_Object.h ../../../src/windows/native/sun/windows/awt_Palette.h ../../../src/windows/native/sun/windows/awt_Pen.h ../../../src/windows/native/sun/windows/awt_Toolkit.h ../../../src/windows/native/sun/windows/awt_Win32GraphicsDevice.h ../../../src/windows/native/sun/windows/colordata.h ../../../src/windows/native/sun/windows/Devices.h ../../../src/windows/native/sun/windows/GDIHashtable.h ../../../src/windows/native/sun/windows/Hashtable.h ../../../src/windows/native/sun/windows/ObjectList.h ../../../src/windows/native/sun/windows/stdhdrs.h
--- a/jdk/make/sun/awt/mapfile-vers Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/awt/mapfile-vers Wed Jan 19 19:00:30 2011 -0800
@@ -118,6 +118,8 @@
Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops;
Java_sun_java2d_loops_MaskBlit_MaskBlit;
Java_sun_java2d_loops_MaskFill_MaskFill;
+ Java_sun_java2d_loops_MaskFill_FillAAPgram;
+ Java_sun_java2d_loops_MaskFill_DrawAAPgram;
Java_sun_java2d_loops_TransformHelper_Transform;
Java_sun_java2d_pipe_Region_initIDs;
Java_sun_java2d_pipe_SpanClipRenderer_initIDs;
--- a/jdk/make/sun/awt/mapfile-vers-linux Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/awt/mapfile-vers-linux Wed Jan 19 19:00:30 2011 -0800
@@ -115,6 +115,8 @@
Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops;
Java_sun_java2d_loops_MaskBlit_MaskBlit;
Java_sun_java2d_loops_MaskFill_MaskFill;
+ Java_sun_java2d_loops_MaskFill_FillAAPgram;
+ Java_sun_java2d_loops_MaskFill_DrawAAPgram;
Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans;
Java_sun_java2d_pipe_SpanClipRenderer_initIDs;
sun_awt_image_GifImageDecoder_initIDs;
--- a/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java Wed Jan 19 19:00:30 2011 -0800
@@ -222,6 +222,7 @@
boolean continued = false;
Zone zone = null;
String l;
+ lineNum = 0;
try {
while ((line = in.readLine()) != null) {
--- a/jdk/src/share/classes/java/awt/SplashScreen.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/SplashScreen.java Wed Jan 19 19:00:30 2011 -0800
@@ -33,27 +33,17 @@
import sun.awt.image.SunWritableRaster;
/**
- * The splash screen can be created at application startup, before the
+ * The splash screen can be displayed at application startup, before the
* Java Virtual Machine (JVM) starts. The splash screen is displayed as an
- * undecorated window containing an image. You can use GIF, JPEG, and PNG files
- * for the image. Animation (for GIF) and transparency (for GIF, PNG) are
- * supported. The window is positioned at the center of the screen (the
- * position on multi-monitor systems is not specified - it is platform and
- * implementation dependent).
- * The window is closed automatically as soon as the first window is displayed by
- * Swing/AWT (may be also closed manually using the Java API, see below).
+ * undecorated window containing an image. You can use GIF, JPEG, or PNG files
+ * for the image. Animation is supported for the GIF format, while transparency
+ * is supported both for GIF and PNG. The window is positioned at the center
+ * of the screen. The position on multi-monitor systems is not specified. It is
+ * platform and implementation dependent. The splash screen window is closed
+ * automatically as soon as the first window is displayed by Swing/AWT (may be
+ * also closed manually using the Java API, see below).
* <P>
- * There are two ways to show the native splash screen:
- * <P>
- * <UL>
- * <LI>If your application is run from the command line or from a shortcut,
- * use the "-splash:" Java application launcher option to show a splash screen.
- * <BR>
- * For example:
- * <PRE>
- * java -splash:filename.gif Test
- * </PRE>
- * <LI>If your application is packaged in a jar file, you can use the
+ * If your application is packaged in a jar file, you can use the
* "SplashScreen-Image" option in a manifest file to show a splash screen.
* Place the image in the jar archive and specify the path in the option.
* The path should not have a leading slash.
@@ -64,18 +54,39 @@
* Main-Class: Test
* SplashScreen-Image: filename.gif
* </PRE>
+ * <P>
+ * If the Java implementation provides the command-line interface and you run
+ * your application by using the command line or a shortcut, use the Java
+ * application launcher option to show a splash screen. The Oracle reference
+ * implementation allows you to specify the splash screen image location with
+ * the {@code -splash:} option.
+ * <BR>
+ * For example:
+ * <PRE>
+ * java -splash:filename.gif Test
+ * </PRE>
* The command line interface has higher precedence over the manifest
* setting.
- * </UL>
+ * <p>
+ * The splash screen will be displayed as faithfully as possible to present the
+ * whole splash screen image given the limitations of the target platform and
+ * display.
+ * <p>
+ * It is implied that the specified image is presented on the screen "as is",
+ * i.e. preserving the exact color values as specified in the image file. Under
+ * certain circumstances, though, the presented image may differ, e.g. when
+ * applying color dithering to present a 32 bits per pixel (bpp) image on a 16
+ * or 8 bpp screen. The native platform display configuration may also affect
+ * the colors of the displayed image (e.g. color profiles, etc.)
* <p>
* The {@code SplashScreen} class provides the API for controlling the splash
* screen. This class may be used to close the splash screen, change the splash
- * screen image, get the image position/size and paint in the splash screen. It
- * cannot be used to create the splash screen; you should use the command line or manifest
- * file option for that.
+ * screen image, get the splash screen native window position/size, and paint
+ * in the splash screen. It cannot be used to create the splash screen. You
+ * should use the options provided by the Java implementation for that.
* <p>
* This class cannot be instantiated. Only a single instance of this class
- * can exist, and it may be obtained using the {@link #getSplashScreen()}
+ * can exist, and it may be obtained by using the {@link #getSplashScreen()}
* static method. In case the splash screen has not been created at
* application startup via the command line or manifest file option,
* the <code>getSplashScreen</code> method returns <code>null</code>.
@@ -91,7 +102,7 @@
/**
* Returns the {@code SplashScreen} object used for
- * Java startup splash screen control.
+ * Java startup splash screen control on systems that support display.
*
* @throws UnsupportedOperationException if the splash screen feature is not
* supported by the current toolkit
@@ -219,6 +230,9 @@
* <p>
* You cannot control the size or position of the splash screen.
* The splash screen size is adjusted automatically when the image changes.
+ * <p>
+ * The image may contain transparent areas, and thus the reported bounds may
+ * be larger than the visible splash screen image on the screen.
*
* @return a {@code Rectangle} containing the splash screen bounds
* @throws IllegalStateException if the splash screen has already been closed
@@ -237,6 +251,9 @@
* <p>
* You cannot control the size or position of the splash screen.
* The splash screen size is adjusted automatically when the image changes.
+ * <p>
+ * The image may contain transparent areas, and thus the reported size may
+ * be larger than the visible splash screen image on the screen.
*
* @return a {@link Dimension} object indicating the splash screen size
* @throws IllegalStateException if the splash screen has already been closed
@@ -254,6 +271,10 @@
* screen window. You should call {@code update()} on the
* <code>SplashScreen</code> when you want the splash screen to be
* updated immediately.
+ * <p>
+ * The pixel (0, 0) in the coordinate space of the graphics context
+ * corresponds to the origin of the splash screen native window bounds (see
+ * {@link #getBounds()}).
*
* @return graphics context for the splash screen overlay surface
* @throws IllegalStateException if the splash screen has already been closed
@@ -334,6 +355,11 @@
* Determines whether the splash screen is visible. The splash screen may
* be hidden using {@link #close()}, it is also hidden automatically when
* the first AWT/Swing window is made visible.
+ * <p>
+ * Note that the native platform may delay presenting the splash screen
+ * native window on the screen. The return value of {@code true} for this
+ * method only guarantees that the conditions to hide the splash screen
+ * window have not occurred yet.
*
* @return true if the splash screen is visible (has not been closed yet),
* false otherwise
--- a/jdk/src/share/classes/java/awt/font/NumericShaper.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/font/NumericShaper.java Wed Jan 19 19:00:30 2011 -0800
@@ -58,20 +58,20 @@
* It is also possible to perform numeric shaping explicitly using instances
* of <code>NumericShaper</code>, as this code snippet demonstrates:<br>
* <blockquote><pre>
- * char[] text = ...;
- * // shape all EUROPEAN digits (except zero) to ARABIC digits
- * NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC);
- * shaper.shape(text, start, count);
+ * char[] text = ...;
+ * // shape all EUROPEAN digits (except zero) to ARABIC digits
+ * NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC);
+ * shaper.shape(text, start, count);
*
- * // shape European digits to ARABIC digits if preceding text is Arabic, or
- * // shape European digits to TAMIL digits if preceding text is Tamil, or
- * // leave European digits alone if there is no preceding text, or
- * // preceding text is neither Arabic nor Tamil
- * NumericShaper shaper =
- * NumericShaper.getContextualShaper(NumericShaper.ARABIC |
- * NumericShaper.TAMIL,
- * NumericShaper.EUROPEAN);
- * shaper.shape(text, start, count);
+ * // shape European digits to ARABIC digits if preceding text is Arabic, or
+ * // shape European digits to TAMIL digits if preceding text is Tamil, or
+ * // leave European digits alone if there is no preceding text, or
+ * // preceding text is neither Arabic nor Tamil
+ * NumericShaper shaper =
+ * NumericShaper.getContextualShaper(NumericShaper.ARABIC |
+ * NumericShaper.TAMIL,
+ * NumericShaper.EUROPEAN);
+ * shaper.shape(text, start, count);
* </pre></blockquote>
*
* <p><b>Bit mask- and enum-based Unicode ranges</b></p>
@@ -99,6 +99,37 @@
* values are specified, such as {@code NumericShaper.Range.BALINESE},
* those ranges are ignored.
*
+ * <p><b>Decimal Digits Precedence</b></p>
+ *
+ * <p>A Unicode range may have more than one set of decimal digits. If
+ * multiple decimal digits sets are specified for the same Unicode
+ * range, one of the sets will take precedence as follows.
+ *
+ * <table border=1 cellspacing=3 cellpadding=0 summary="NumericShaper constants precedence.">
+ * <tr>
+ * <th class="TableHeadingColor">Unicode Range</th>
+ * <th class="TableHeadingColor"><code>NumericShaper</code> Constants</th>
+ * <th class="TableHeadingColor">Precedence</th>
+ * </tr>
+ * <tr>
+ * <td rowspan="2">Arabic</td>
+ * <td>{@link NumericShaper#ARABIC NumericShaper.ARABIC}<br>
+ * {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
+ * <td>{@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link NumericShaper.Range#ARABIC}<br>
+ * {@link NumericShaper.Range#EASTERN_ARABIC}</td>
+ * <td>{@link NumericShaper.Range#EASTERN_ARABIC}</td>
+ * </tr>
+ * <tr>
+ * <td>Tai Tham</td>
+ * <td>{@link NumericShaper.Range#TAI_THAM_HORA}<br>
+ * {@link NumericShaper.Range#TAI_THAM_THAM}</td>
+ * <td>{@link NumericShaper.Range#TAI_THAM_THAM}</td>
+ * </tr>
+ * </table>
+ *
* @since 1.4
*/
--- a/jdk/src/share/classes/java/awt/image/IndexColorModel.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/image/IndexColorModel.java Wed Jan 19 19:00:30 2011 -0800
@@ -625,7 +625,7 @@
}
nBits[0] = nBits[1] = nBits[2] = 8;
}
- return nBits;
+ return nBits.clone();
}
/**
--- a/jdk/src/share/classes/java/awt/image/SampleModel.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/image/SampleModel.java Wed Jan 19 19:00:30 2011 -0800
@@ -121,7 +121,7 @@
*/
public SampleModel(int dataType, int w, int h, int numBands)
{
- float size = (float)w*h;
+ long size = (long)w * h;
if (w <= 0 || h <= 0) {
throw new IllegalArgumentException("Width ("+w+") and height ("+
h+") must be > 0");
--- a/jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java Wed Jan 19 19:00:30 2011 -0800
@@ -92,7 +92,8 @@
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
* Each sample is stored in a data array element in the position of
* its corresponding bit mask. Each bit mask must be contiguous and
- * masks must not overlap.
+ * masks must not overlap. Bit masks exceeding data type capacity are
+ * truncated.
* @param dataType The data type for storing samples.
* @param w The width (in pixels) of the region of the
* image data described.
@@ -120,7 +121,8 @@
* and a scanline stride equal to scanlineStride data array elements.
* Each sample is stored in a data array element in the position of
* its corresponding bit mask. Each bit mask must be contiguous and
- * masks must not overlap.
+ * masks must not overlap. Bit masks exceeding data type capacity are
+ * truncated.
* @param dataType The data type for storing samples.
* @param w The width (in pixels) of the region of
* image data described.
@@ -153,11 +155,13 @@
this.bitOffsets = new int[numBands];
this.bitSizes = new int[numBands];
+ int maxMask = (int)((1L << DataBuffer.getDataTypeSize(dataType)) - 1);
+
this.maxBitSize = 0;
for (int i=0; i<numBands; i++) {
int bitOffset = 0, bitSize = 0, mask;
- mask = bitMasks[i];
-
+ this.bitMasks[i] &= maxMask;
+ mask = this.bitMasks[i];
if (mask != 0) {
while ((mask & 1) == 0) {
mask = mask >>> 1;
@@ -243,30 +247,12 @@
/** Returns the number of bits per sample for all bands. */
public int[] getSampleSize() {
- int mask;
- int sampleSize[] = new int [numBands];
- for (int i=0; i<numBands; i++) {
- sampleSize[i] = 0;
- mask = bitMasks[i] >>> bitOffsets[i];
- while ((mask & 1) != 0) {
- sampleSize[i] ++;
- mask = mask >>> 1;
- }
- }
-
- return sampleSize;
+ return bitSizes.clone();
}
/** Returns the number of bits per sample for the specified band. */
public int getSampleSize(int band) {
- int sampleSize = 0;
- int mask = bitMasks[band] >>> bitOffsets[band];
- while ((mask & 1) != 0) {
- sampleSize ++;
- mask = mask >>> 1;
- }
-
- return sampleSize;
+ return bitSizes[band];
}
/** Returns the offset (in data array elements) of pixel (x,y).
--- a/jdk/src/share/classes/java/text/MessageFormat.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/text/MessageFormat.java Wed Jan 19 19:00:30 2011 -0800
@@ -93,73 +93,65 @@
* currency
* percent
* <i>SubformatPattern</i>
- *
- * <i>String:</i>
- * <i>StringPart<sub>opt</sub></i>
- * <i>String</i> <i>StringPart</i>
- *
- * <i>StringPart:</i>
- * ''
- * ' <i>QuotedString</i> '
- * <i>UnquotedString</i>
- *
- * <i>SubformatPattern:</i>
- * <i>SubformatPatternPart<sub>opt</sub></i>
- * <i>SubformatPattern</i> <i>SubformatPatternPart</i>
- *
- * <i>SubFormatPatternPart:</i>
- * ' <i>QuotedPattern</i> '
- * <i>UnquotedPattern</i>
* </pre></blockquote>
*
- * <p>
- * Within a <i>String</i>, <code>"''"</code> represents a single
- * quote. A <i>QuotedString</i> can contain arbitrary characters
- * except single quotes; the surrounding single quotes are removed.
- * An <i>UnquotedString</i> can contain arbitrary characters
- * except single quotes and left curly brackets. Thus, a string that
- * should result in the formatted message "'{0}'" can be written as
- * <code>"'''{'0}''"</code> or <code>"'''{0}'''"</code>.
- * <p>
- * Within a <i>SubformatPattern</i>, different rules apply.
- * A <i>QuotedPattern</i> can contain arbitrary characters
- * except single quotes; but the surrounding single quotes are
- * <strong>not</strong> removed, so they may be interpreted by the
- * subformat. For example, <code>"{1,number,$'#',##}"</code> will
- * produce a number format with the pound-sign quoted, with a result
- * such as: "$#31,45".
- * An <i>UnquotedPattern</i> can contain arbitrary characters
- * except single quotes, but curly braces within it must be balanced.
- * For example, <code>"ab {0} de"</code> and <code>"ab '}' de"</code>
- * are valid subformat patterns, but <code>"ab {0'}' de"</code> and
- * <code>"ab } de"</code> are not.
+ * <p>Within a <i>String</i>, a pair of single quotes can be used to
+ * quote any arbitrary characters except single quotes. For example,
+ * pattern string <code>"'{0}'"</code> represents string
+ * <code>"{0}"</code>, not a <i>FormatElement</i>. A single quote itself
+ * must be represented by doubled single quotes {@code ''} throughout a
+ * <i>String</i>. For example, pattern string <code>"'{''}'"</code> is
+ * interpreted as a sequence of <code>'{</code> (start of quoting and a
+ * left curly brace), <code>''</code> (a single quote), and
+ * <code>}'</code> (a right curly brace and end of quoting),
+ * <em>not</em> <code>'{'</code> and <code>'}'</code> (quoted left and
+ * right curly braces): representing string <code>"{'}"</code>,
+ * <em>not</em> <code>"{}"</code>.
+ *
+ * <p>A <i>SubformatPattern</i> is interpreted by its corresponding
+ * subformat, and subformat-dependent pattern rules apply. For example,
+ * pattern string <code>"{1,number,<u>$'#',##</u>}"</code>
+ * (<i>SubformatPattern</i> with underline) will produce a number format
+ * with the pound-sign quoted, with a result such as: {@code
+ * "$#31,45"}. Refer to each {@code Format} subclass documentation for
+ * details.
+ *
+ * <p>Any unmatched quote is treated as closed at the end of the given
+ * pattern. For example, pattern string {@code "'{0}"} is treated as
+ * pattern {@code "'{0}'"}.
+ *
+ * <p>Any curly braces within an unquoted pattern must be balanced. For
+ * example, <code>"ab {0} de"</code> and <code>"ab '}' de"</code> are
+ * valid patterns, but <code>"ab {0'}' de"</code>, <code>"ab } de"</code>
+ * and <code>"''{''"</code> are not.
+ *
* <p>
* <dl><dt><b>Warning:</b><dd>The rules for using quotes within message
* format patterns unfortunately have shown to be somewhat confusing.
* In particular, it isn't always obvious to localizers whether single
* quotes need to be doubled or not. Make sure to inform localizers about
* the rules, and tell them (for example, by using comments in resource
- * bundle source files) which strings will be processed by MessageFormat.
+ * bundle source files) which strings will be processed by {@code MessageFormat}.
* Note that localizers may need to use single quotes in translated
* strings where the original version doesn't have them.
* </dl>
* <p>
* The <i>ArgumentIndex</i> value is a non-negative integer written
- * using the digits '0' through '9', and represents an index into the
- * <code>arguments</code> array passed to the <code>format</code> methods
- * or the result array returned by the <code>parse</code> methods.
+ * using the digits {@code '0'} through {@code '9'}, and represents an index into the
+ * {@code arguments} array passed to the {@code format} methods
+ * or the result array returned by the {@code parse} methods.
* <p>
* The <i>FormatType</i> and <i>FormatStyle</i> values are used to create
- * a <code>Format</code> instance for the format element. The following
- * table shows how the values map to Format instances. Combinations not
+ * a {@code Format} instance for the format element. The following
+ * table shows how the values map to {@code Format} instances. Combinations not
* shown in the table are illegal. A <i>SubformatPattern</i> must
- * be a valid pattern string for the Format subclass used.
+ * be a valid pattern string for the {@code Format} subclass used.
* <p>
* <table border=1 summary="Shows how FormatType and FormatStyle values map to Format instances">
* <tr>
- * <th id="ft">Format Type
- * <th id="fs">Format Style
- * <th id="sc">Subformat Created
+ * <th id="ft" class="TableHeadingColor">FormatType
+ * <th id="fs" class="TableHeadingColor">FormatStyle
+ * <th id="sc" class="TableHeadingColor">Subformat Created
* <tr>
* <td headers="ft"><i>(none)</i>
* <td headers="fs"><i>(none)</i>
@@ -167,61 +159,61 @@
* <tr>
* <td headers="ft" rowspan=5><code>number</code>
* <td headers="fs"><i>(none)</i>
- * <td headers="sc"><code>NumberFormat.getInstance(getLocale())</code>
+ * <td headers="sc">{@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())}
* <tr>
* <td headers="fs"><code>integer</code>
- * <td headers="sc"><code>NumberFormat.getIntegerInstance(getLocale())</code>
+ * <td headers="sc">{@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())}
* <tr>
* <td headers="fs"><code>currency</code>
- * <td headers="sc"><code>NumberFormat.getCurrencyInstance(getLocale())</code>
+ * <td headers="sc">{@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())}
* <tr>
* <td headers="fs"><code>percent</code>
- * <td headers="sc"><code>NumberFormat.getPercentInstance(getLocale())</code>
+ * <td headers="sc">{@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())}
* <tr>
* <td headers="fs"><i>SubformatPattern</i>
- * <td headers="sc"><code>new DecimalFormat(subformatPattern, DecimalFormatSymbols.getInstance(getLocale()))</code>
+ * <td headers="sc">{@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))}
* <tr>
* <td headers="ft" rowspan=6><code>date</code>
* <td headers="fs"><i>(none)</i>
- * <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
* <tr>
* <td headers="fs"><code>short</code>
- * <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.SHORT, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())}
* <tr>
* <td headers="fs"><code>medium</code>
- * <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
* <tr>
* <td headers="fs"><code>long</code>
- * <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.LONG, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())}
* <tr>
* <td headers="fs"><code>full</code>
- * <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.FULL, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())}
* <tr>
* <td headers="fs"><i>SubformatPattern</i>
- * <td headers="sc"><code>new SimpleDateFormat(subformatPattern, getLocale())</code>
+ * <td headers="sc">{@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())}
* <tr>
* <td headers="ft" rowspan=6><code>time</code>
* <td headers="fs"><i>(none)</i>
- * <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
* <tr>
* <td headers="fs"><code>short</code>
- * <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())}
* <tr>
* <td headers="fs"><code>medium</code>
- * <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
* <tr>
* <td headers="fs"><code>long</code>
- * <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.LONG, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())}
* <tr>
* <td headers="fs"><code>full</code>
- * <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.FULL, getLocale())</code>
+ * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())}
* <tr>
* <td headers="fs"><i>SubformatPattern</i>
- * <td headers="sc"><code>new SimpleDateFormat(subformatPattern, getLocale())</code>
+ * <td headers="sc">{@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())}
* <tr>
* <td headers="ft"><code>choice</code>
* <td headers="fs"><i>SubformatPattern</i>
- * <td headers="sc"><code>new ChoiceFormat(subformatPattern)</code>
+ * <td headers="sc">{@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)}
* </table>
* <p>
*
@@ -321,7 +313,7 @@
* </pre></blockquote>
*
* <p>
- * Likewise, parsing with a MessageFormat object using patterns containing
+ * Likewise, parsing with a {@code MessageFormat} object using patterns containing
* multiple occurrences of the same argument would return the last match. For
* example,
* <blockquote><pre>
@@ -343,7 +335,11 @@
* @see Format
* @see NumberFormat
* @see DecimalFormat
+ * @see DecimalFormatSymbols
* @see ChoiceFormat
+ * @see DateFormat
+ * @see SimpleDateFormat
+ *
* @author Mark Davis
*/
@@ -427,18 +423,19 @@
* @exception IllegalArgumentException if the pattern is invalid
*/
public void applyPattern(String pattern) {
- StringBuffer[] segments = new StringBuffer[4];
- for (int i = 0; i < segments.length; ++i) {
- segments[i] = new StringBuffer();
- }
- int part = 0;
+ StringBuilder[] segments = new StringBuilder[4];
+ // Allocate only segments[SEG_RAW] here. The rest are
+ // allocated on demand.
+ segments[SEG_RAW] = new StringBuilder();
+
+ int part = SEG_RAW;
int formatNumber = 0;
boolean inQuote = false;
int braceStack = 0;
maxOffset = -1;
for (int i = 0; i < pattern.length(); ++i) {
char ch = pattern.charAt(i);
- if (part == 0) {
+ if (part == SEG_RAW) {
if (ch == '\'') {
if (i + 1 < pattern.length()
&& pattern.charAt(i+1) == '\'') {
@@ -448,43 +445,61 @@
inQuote = !inQuote;
}
} else if (ch == '{' && !inQuote) {
- part = 1;
+ part = SEG_INDEX;
+ if (segments[SEG_INDEX] == null) {
+ segments[SEG_INDEX] = new StringBuilder();
+ }
} else {
segments[part].append(ch);
}
- } else if (inQuote) { // just copy quotes in parts
- segments[part].append(ch);
- if (ch == '\'') {
- inQuote = false;
- }
- } else {
- switch (ch) {
- case ',':
- if (part < 3)
- part += 1;
- else
- segments[part].append(ch);
- break;
- case '{':
- ++braceStack;
+ } else {
+ if (inQuote) { // just copy quotes in parts
segments[part].append(ch);
- break;
- case '}':
- if (braceStack == 0) {
- part = 0;
- makeFormat(i, formatNumber, segments);
- formatNumber++;
- } else {
- --braceStack;
+ if (ch == '\'') {
+ inQuote = false;
+ }
+ } else {
+ switch (ch) {
+ case ',':
+ if (part < SEG_MODIFIER) {
+ if (segments[++part] == null) {
+ segments[part] = new StringBuilder();
+ }
+ } else {
+ segments[part].append(ch);
+ }
+ break;
+ case '{':
+ ++braceStack;
segments[part].append(ch);
+ break;
+ case '}':
+ if (braceStack == 0) {
+ part = SEG_RAW;
+ makeFormat(i, formatNumber, segments);
+ formatNumber++;
+ // throw away other segments
+ segments[SEG_INDEX] = null;
+ segments[SEG_TYPE] = null;
+ segments[SEG_MODIFIER] = null;
+ } else {
+ --braceStack;
+ segments[part].append(ch);
+ }
+ break;
+ case ' ':
+ // Skip any leading space chars for SEG_TYPE.
+ if (part != SEG_TYPE || segments[SEG_TYPE].length() > 0) {
+ segments[part].append(ch);
+ }
+ break;
+ case '\'':
+ inQuote = true;
+ // fall through, so we keep quotes in other parts
+ default:
+ segments[part].append(ch);
+ break;
}
- break;
- case '\'':
- inQuote = true;
- // fall through, so we keep quotes in other parts
- default:
- segments[part].append(ch);
- break;
}
}
}
@@ -506,65 +521,57 @@
public String toPattern() {
// later, make this more extensible
int lastOffset = 0;
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
for (int i = 0; i <= maxOffset; ++i) {
- copyAndFixQuotes(pattern, lastOffset, offsets[i],result);
+ copyAndFixQuotes(pattern, lastOffset, offsets[i], result);
lastOffset = offsets[i];
- result.append('{');
- result.append(argumentNumbers[i]);
- if (formats[i] == null) {
+ result.append('{').append(argumentNumbers[i]);
+ Format fmt = formats[i];
+ if (fmt == null) {
// do nothing, string format
- } else if (formats[i] instanceof DecimalFormat) {
- if (formats[i].equals(NumberFormat.getInstance(locale))) {
+ } else if (fmt instanceof NumberFormat) {
+ if (fmt.equals(NumberFormat.getInstance(locale))) {
result.append(",number");
- } else if (formats[i].equals(NumberFormat.getCurrencyInstance(locale))) {
+ } else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) {
result.append(",number,currency");
- } else if (formats[i].equals(NumberFormat.getPercentInstance(locale))) {
+ } else if (fmt.equals(NumberFormat.getPercentInstance(locale))) {
result.append(",number,percent");
- } else if (formats[i].equals(NumberFormat.getIntegerInstance(locale))) {
+ } else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) {
result.append(",number,integer");
} else {
- result.append(",number," +
- ((DecimalFormat)formats[i]).toPattern());
+ if (fmt instanceof DecimalFormat) {
+ result.append(",number,").append(((DecimalFormat)fmt).toPattern());
+ } else if (fmt instanceof ChoiceFormat) {
+ result.append(",choice,").append(((ChoiceFormat)fmt).toPattern());
+ } else {
+ // UNKNOWN
+ }
}
- } else if (formats[i] instanceof SimpleDateFormat) {
- if (formats[i].equals(DateFormat.getDateInstance(
- DateFormat.DEFAULT,locale))) {
- result.append(",date");
- } else if (formats[i].equals(DateFormat.getDateInstance(
- DateFormat.SHORT,locale))) {
- result.append(",date,short");
- } else if (formats[i].equals(DateFormat.getDateInstance(
- DateFormat.DEFAULT,locale))) {
- result.append(",date,medium");
- } else if (formats[i].equals(DateFormat.getDateInstance(
- DateFormat.LONG,locale))) {
- result.append(",date,long");
- } else if (formats[i].equals(DateFormat.getDateInstance(
- DateFormat.FULL,locale))) {
- result.append(",date,full");
- } else if (formats[i].equals(DateFormat.getTimeInstance(
- DateFormat.DEFAULT,locale))) {
- result.append(",time");
- } else if (formats[i].equals(DateFormat.getTimeInstance(
- DateFormat.SHORT,locale))) {
- result.append(",time,short");
- } else if (formats[i].equals(DateFormat.getTimeInstance(
- DateFormat.DEFAULT,locale))) {
- result.append(",time,medium");
- } else if (formats[i].equals(DateFormat.getTimeInstance(
- DateFormat.LONG,locale))) {
- result.append(",time,long");
- } else if (formats[i].equals(DateFormat.getTimeInstance(
- DateFormat.FULL,locale))) {
- result.append(",time,full");
- } else {
- result.append(",date,"
- + ((SimpleDateFormat)formats[i]).toPattern());
+ } else if (fmt instanceof DateFormat) {
+ int index;
+ for (index = MODIFIER_DEFAULT; index < DATE_TIME_MODIFIERS.length; index++) {
+ DateFormat df = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[index],
+ locale);
+ if (fmt.equals(df)) {
+ result.append(",date");
+ break;
+ }
+ df = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[index],
+ locale);
+ if (fmt.equals(df)) {
+ result.append(",time");
+ break;
+ }
}
- } else if (formats[i] instanceof ChoiceFormat) {
- result.append(",choice,"
- + ((ChoiceFormat)formats[i]).toPattern());
+ if (index >= DATE_TIME_MODIFIERS.length) {
+ if (fmt instanceof SimpleDateFormat) {
+ result.append(",date,").append(((SimpleDateFormat)fmt).toPattern());
+ } else {
+ // UNKNOWN
+ }
+ } else if (index != MODIFIER_DEFAULT) {
+ result.append(',').append(DATE_TIME_MODIFIER_KEYWORDS[index]);
+ }
} else {
//result.append(", unknown");
}
@@ -678,7 +685,7 @@
*
* @param formatElementIndex the index of a format element within the pattern
* @param newFormat the format to use for the specified format element
- * @exception ArrayIndexOutOfBoundsException if formatElementIndex is equal to or
+ * @exception ArrayIndexOutOfBoundsException if {@code formatElementIndex} is equal to or
* larger than the number of format elements in the pattern string
*/
public void setFormat(int formatElementIndex, Format newFormat) {
@@ -972,7 +979,8 @@
if (patternOffset >= tempLength) {
next = source.length();
}else{
- next = source.indexOf( pattern.substring(patternOffset,tempLength), sourceOffset);
+ next = source.indexOf(pattern.substring(patternOffset, tempLength),
+ sourceOffset);
}
if (next < 0) {
@@ -1226,7 +1234,7 @@
lastOffset = offsets[i];
int argumentNumber = argumentNumbers[i];
if (arguments == null || argumentNumber >= arguments.length) {
- result.append("{" + argumentNumber + "}");
+ result.append('{').append(argumentNumber).append('}');
continue;
}
// int argRecursion = ((recursionProtection >> (argumentNumber*2)) & 0x3);
@@ -1338,25 +1346,83 @@
}
}
- private static final String[] typeList =
- {"", "", "number", "", "date", "", "time", "", "choice"};
- private static final String[] modifierList =
- {"", "", "currency", "", "percent", "", "integer"};
- private static final String[] dateModifierList =
- {"", "", "short", "", "medium", "", "long", "", "full"};
+ // Indices for segments
+ private static final int SEG_RAW = 0;
+ private static final int SEG_INDEX = 1;
+ private static final int SEG_TYPE = 2;
+ private static final int SEG_MODIFIER = 3; // modifier or subformat
+
+ // Indices for type keywords
+ private static final int TYPE_NULL = 0;
+ private static final int TYPE_NUMBER = 1;
+ private static final int TYPE_DATE = 2;
+ private static final int TYPE_TIME = 3;
+ private static final int TYPE_CHOICE = 4;
+
+ private static final String[] TYPE_KEYWORDS = {
+ "",
+ "number",
+ "date",
+ "time",
+ "choice"
+ };
+
+ // Indices for number modifiers
+ private static final int MODIFIER_DEFAULT = 0; // common in number and date-time
+ private static final int MODIFIER_CURRENCY = 1;
+ private static final int MODIFIER_PERCENT = 2;
+ private static final int MODIFIER_INTEGER = 3;
+
+ private static final String[] NUMBER_MODIFIER_KEYWORDS = {
+ "",
+ "currency",
+ "percent",
+ "integer"
+ };
+
+ // Indices for date-time modifiers
+ private static final int MODIFIER_SHORT = 1;
+ private static final int MODIFIER_MEDIUM = 2;
+ private static final int MODIFIER_LONG = 3;
+ private static final int MODIFIER_FULL = 4;
+
+ private static final String[] DATE_TIME_MODIFIER_KEYWORDS = {
+ "",
+ "short",
+ "medium",
+ "long",
+ "full"
+ };
+
+ // Date-time style values corresponding to the date-time modifiers.
+ private static final int[] DATE_TIME_MODIFIERS = {
+ DateFormat.DEFAULT,
+ DateFormat.SHORT,
+ DateFormat.MEDIUM,
+ DateFormat.LONG,
+ DateFormat.FULL,
+ };
private void makeFormat(int position, int offsetNumber,
- StringBuffer[] segments)
+ StringBuilder[] textSegments)
{
+ String[] segments = new String[textSegments.length];
+ for (int i = 0; i < textSegments.length; i++) {
+ StringBuilder oneseg = textSegments[i];
+ segments[i] = (oneseg != null) ? oneseg.toString() : "";
+ }
+
// get the argument number
int argumentNumber;
try {
- argumentNumber = Integer.parseInt(segments[1].toString()); // always unlocalized!
+ argumentNumber = Integer.parseInt(segments[SEG_INDEX]); // always unlocalized!
} catch (NumberFormatException e) {
- throw new IllegalArgumentException("can't parse argument number: " + segments[1]);
+ throw new IllegalArgumentException("can't parse argument number: "
+ + segments[SEG_INDEX], e);
}
if (argumentNumber < 0) {
- throw new IllegalArgumentException("negative argument number: " + argumentNumber);
+ throw new IllegalArgumentException("negative argument number: "
+ + argumentNumber);
}
// resize format information arrays if necessary
@@ -1374,120 +1440,129 @@
}
int oldMaxOffset = maxOffset;
maxOffset = offsetNumber;
- offsets[offsetNumber] = segments[0].length();
+ offsets[offsetNumber] = segments[SEG_RAW].length();
argumentNumbers[offsetNumber] = argumentNumber;
// now get the format
Format newFormat = null;
- switch (findKeyword(segments[2].toString(), typeList)) {
- case 0:
- break;
- case 1: case 2:// number
- switch (findKeyword(segments[3].toString(), modifierList)) {
- case 0: // default;
- newFormat = NumberFormat.getInstance(locale);
+ if (segments[SEG_TYPE].length() != 0) {
+ int type = findKeyword(segments[SEG_TYPE], TYPE_KEYWORDS);
+ switch (type) {
+ case TYPE_NULL:
+ // Type "" is allowed. e.g., "{0,}", "{0,,}", and "{0,,#}"
+ // are treated as "{0}".
break;
- case 1: case 2:// currency
- newFormat = NumberFormat.getCurrencyInstance(locale);
- break;
- case 3: case 4:// percent
- newFormat = NumberFormat.getPercentInstance(locale);
- break;
- case 5: case 6:// integer
- newFormat = NumberFormat.getIntegerInstance(locale);
- break;
- default: // pattern
- newFormat = new DecimalFormat(segments[3].toString(), DecimalFormatSymbols.getInstance(locale));
+
+ case TYPE_NUMBER:
+ switch (findKeyword(segments[SEG_MODIFIER], NUMBER_MODIFIER_KEYWORDS)) {
+ case MODIFIER_DEFAULT:
+ newFormat = NumberFormat.getInstance(locale);
+ break;
+ case MODIFIER_CURRENCY:
+ newFormat = NumberFormat.getCurrencyInstance(locale);
+ break;
+ case MODIFIER_PERCENT:
+ newFormat = NumberFormat.getPercentInstance(locale);
+ break;
+ case MODIFIER_INTEGER:
+ newFormat = NumberFormat.getIntegerInstance(locale);
+ break;
+ default: // DecimalFormat pattern
+ try {
+ newFormat = new DecimalFormat(segments[SEG_MODIFIER],
+ DecimalFormatSymbols.getInstance(locale));
+ } catch (IllegalArgumentException e) {
+ maxOffset = oldMaxOffset;
+ throw e;
+ }
+ break;
+ }
break;
- }
- break;
- case 3: case 4: // date
- switch (findKeyword(segments[3].toString(), dateModifierList)) {
- case 0: // default
- newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
- break;
- case 1: case 2: // short
- newFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+
+ case TYPE_DATE:
+ case TYPE_TIME:
+ int mod = findKeyword(segments[SEG_MODIFIER], DATE_TIME_MODIFIER_KEYWORDS);
+ if (mod >= 0 && mod < DATE_TIME_MODIFIER_KEYWORDS.length) {
+ if (type == TYPE_DATE) {
+ newFormat = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[mod],
+ locale);
+ } else {
+ newFormat = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[mod],
+ locale);
+ }
+ } else {
+ // SimpleDateFormat pattern
+ try {
+ newFormat = new SimpleDateFormat(segments[SEG_MODIFIER], locale);
+ } catch (IllegalArgumentException e) {
+ maxOffset = oldMaxOffset;
+ throw e;
+ }
+ }
break;
- case 3: case 4: // medium
- newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
+
+ case TYPE_CHOICE:
+ try {
+ // ChoiceFormat pattern
+ newFormat = new ChoiceFormat(segments[SEG_MODIFIER]);
+ } catch (Exception e) {
+ maxOffset = oldMaxOffset;
+ throw new IllegalArgumentException("Choice Pattern incorrect: "
+ + segments[SEG_MODIFIER], e);
+ }
break;
- case 5: case 6: // long
- newFormat = DateFormat.getDateInstance(DateFormat.LONG, locale);
- break;
- case 7: case 8: // full
- newFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);
- break;
+
default:
- newFormat = new SimpleDateFormat(segments[3].toString(), locale);
- break;
+ maxOffset = oldMaxOffset;
+ throw new IllegalArgumentException("unknown format type: " +
+ segments[SEG_TYPE]);
}
- break;
- case 5: case 6:// time
- switch (findKeyword(segments[3].toString(), dateModifierList)) {
- case 0: // default
- newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
- break;
- case 1: case 2: // short
- newFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
- break;
- case 3: case 4: // medium
- newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
- break;
- case 5: case 6: // long
- newFormat = DateFormat.getTimeInstance(DateFormat.LONG, locale);
- break;
- case 7: case 8: // full
- newFormat = DateFormat.getTimeInstance(DateFormat.FULL, locale);
- break;
- default:
- newFormat = new SimpleDateFormat(segments[3].toString(), locale);
- break;
- }
- break;
- case 7: case 8:// choice
- try {
- newFormat = new ChoiceFormat(segments[3].toString());
- } catch (Exception e) {
- maxOffset = oldMaxOffset;
- throw new IllegalArgumentException(
- "Choice Pattern incorrect");
- }
- break;
- default:
- maxOffset = oldMaxOffset;
- throw new IllegalArgumentException("unknown format type: " +
- segments[2].toString());
}
formats[offsetNumber] = newFormat;
- segments[1].setLength(0); // throw away other segments
- segments[2].setLength(0);
- segments[3].setLength(0);
}
private static final int findKeyword(String s, String[] list) {
- s = s.trim().toLowerCase();
for (int i = 0; i < list.length; ++i) {
if (s.equals(list[i]))
return i;
}
+
+ // Try trimmed lowercase.
+ String ls = s.trim().toLowerCase(Locale.ROOT);
+ if (ls != s) {
+ for (int i = 0; i < list.length; ++i) {
+ if (ls.equals(list[i]))
+ return i;
+ }
+ }
return -1;
}
- private static final void copyAndFixQuotes(
- String source, int start, int end, StringBuffer target) {
+ private static final void copyAndFixQuotes(String source, int start, int end,
+ StringBuilder target) {
+ boolean quoted = false;
+
for (int i = start; i < end; ++i) {
char ch = source.charAt(i);
if (ch == '{') {
- target.append("'{'");
- } else if (ch == '}') {
- target.append("'}'");
+ if (!quoted) {
+ target.append('\'');
+ quoted = true;
+ }
+ target.append(ch);
} else if (ch == '\'') {
target.append("''");
} else {
+ if (quoted) {
+ target.append('\'');
+ quoted = false;
+ }
target.append(ch);
}
}
+ if (quoted) {
+ target.append('\'');
+ }
}
/**
--- a/jdk/src/share/classes/java/text/SimpleDateFormat.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/text/SimpleDateFormat.java Wed Jan 19 19:00:30 2011 -0800
@@ -1663,6 +1663,81 @@
}
/**
+ * Parses numeric forms of time zone offset, such as "hh:mm", and
+ * sets calb to the parsed value.
+ *
+ * @param text the text to be parsed
+ * @param start the character position to start parsing
+ * @param sign 1: positive; -1: negative
+ * @param count 0: 'Z' or "GMT+hh:mm" parsing; 1 - 3: the number of 'X's
+ * @param colon true - colon required between hh and mm; false - no colon required
+ * @param calb a CalendarBuilder in which the parsed value is stored
+ * @return updated parsed position, or its negative value to indicate a parsing error
+ */
+ private int subParseNumericZone(String text, int start, int sign, int count,
+ boolean colon, CalendarBuilder calb) {
+ int index = start;
+
+ parse:
+ try {
+ char c = text.charAt(index++);
+ // Parse hh
+ int hours;
+ if (!isDigit(c)) {
+ break parse;
+ }
+ hours = c - '0';
+ c = text.charAt(index++);
+ if (isDigit(c)) {
+ hours = hours * 10 + (c - '0');
+ } else {
+ // If no colon in RFC 822 or 'X' (ISO), two digits are
+ // required.
+ if (count > 0 || !colon) {
+ break parse;
+ }
+ --index;
+ }
+ if (hours > 23) {
+ break parse;
+ }
+ int minutes = 0;
+ if (count != 1) {
+ // Proceed with parsing mm
+ c = text.charAt(index++);
+ if (colon) {
+ if (c != ':') {
+ break parse;
+ }
+ c = text.charAt(index++);
+ }
+ if (!isDigit(c)) {
+ break parse;
+ }
+ minutes = c - '0';
+ c = text.charAt(index++);
+ if (!isDigit(c)) {
+ break parse;
+ }
+ minutes = minutes * 10 + (c - '0');
+ if (minutes > 59) {
+ break parse;
+ }
+ }
+ minutes += hours * 60;
+ calb.set(Calendar.ZONE_OFFSET, minutes * MILLIS_PER_MINUTE * sign)
+ .set(Calendar.DST_OFFSET, 0);
+ return index;
+ } catch (IndexOutOfBoundsException e) {
+ }
+ return 1 - index; // -(index - 1)
+ }
+
+ private boolean isDigit(char c) {
+ return c >= '0' && c <= '9';
+ }
+
+ /**
* Private member function that converts the parsed date strings into
* timeFields. Returns -start (for ParsePosition) if failed.
* @param text the time text to be parsed.
@@ -1907,248 +1982,95 @@
case PATTERN_ZONE_NAME: // 'z'
case PATTERN_ZONE_VALUE: // 'Z'
- // First try to parse generic forms such as GMT-07:00. Do this first
- // in case localized TimeZoneNames contains the string "GMT"
- // for a zone; in that case, we don't want to match the first three
- // characters of GMT+/-hh:mm etc.
{
int sign = 0;
- int offset;
-
- // For time zones that have no known names, look for strings
- // of the form:
- // GMT[+-]hours:minutes or
- // GMT.
- if ((text.length() - start) >= GMT.length() &&
- text.regionMatches(true, start, GMT, 0, GMT.length())) {
- int num;
- calb.set(Calendar.DST_OFFSET, 0);
- pos.index = start + GMT.length();
-
- try { // try-catch for "GMT" only time zone string
- char c = text.charAt(pos.index);
- if (c == '+') {
- sign = 1;
- } else if (c == '-') {
- sign = -1;
- }
+ try {
+ char c = text.charAt(pos.index);
+ if (c == '+') {
+ sign = 1;
+ } else if (c == '-') {
+ sign = -1;
}
- catch(StringIndexOutOfBoundsException e) {}
-
- if (sign == 0) { /* "GMT" without offset */
- calb.set(Calendar.ZONE_OFFSET, 0);
- return pos.index;
- }
+ if (sign == 0) {
+ // Try parsing a custom time zone "GMT+hh:mm" or "GMT".
+ if ((c == 'G' || c == 'g')
+ && (text.length() - start) >= GMT.length()
+ && text.regionMatches(true, start, GMT, 0, GMT.length())) {
+ pos.index = start + GMT.length();
- // Look for hours.
- try {
- char c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- num = c - '0';
-
- if (text.charAt(++pos.index) != ':') {
- c = text.charAt(pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
+ if ((text.length() - pos.index) > 0) {
+ c = text.charAt(pos.index);
+ if (c == '+') {
+ sign = 1;
+ } else if (c == '-') {
+ sign = -1;
+ }
}
- num *= 10;
- num += c - '0';
- pos.index++;
- }
- if (num > 23) {
- --pos.index;
- break parsing;
- }
- if (text.charAt(pos.index) != ':') {
- break parsing;
- }
- // Look for minutes.
- offset = num * 60;
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- num = c - '0';
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- num *= 10;
- num += c - '0';
+ if (sign == 0) { /* "GMT" without offset */
+ calb.set(Calendar.ZONE_OFFSET, 0)
+ .set(Calendar.DST_OFFSET, 0);
+ return pos.index;
+ }
- if (num > 59) {
- break parsing;
- }
- } catch (StringIndexOutOfBoundsException e) {
- break parsing;
- }
- offset += num;
- // Fall through for final processing below of 'offset' and 'sign'.
- } else {
- // If the first character is a sign, look for numeric timezones of
- // the form [+-]hhmm as specified by RFC 822. Otherwise, check
- // for named time zones by looking through the locale data from
- // the TimeZoneNames strings.
- try {
- char c = text.charAt(pos.index);
- if (c == '+') {
- sign = 1;
- } else if (c == '-') {
- sign = -1;
- } else {
- // Try parsing the text as a time zone name (abbr).
- int i = subParseZoneString(text, pos.index, calb);
- if (i != 0) {
+ // Parse the rest as "hh:mm"
+ int i = subParseNumericZone(text, ++pos.index,
+ sign, 0, true, calb);
+ if (i > 0) {
return i;
}
- break parsing;
- }
-
- // Parse the text as an RFC 822 time zone string. This code is
- // actually a little more permissive than RFC 822. It will
- // try to do its best with numbers that aren't strictly 4
- // digits long.
-
- // Look for hh.
- int hours = 0;
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- hours = c - '0';
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- hours *= 10;
- hours += c - '0';
-
- if (hours > 23) {
- break parsing;
+ pos.index = -i;
+ } else {
+ // Try parsing the text as a time zone
+ // name or abbreviation.
+ int i = subParseZoneString(text, pos.index, calb);
+ if (i > 0) {
+ return i;
+ }
+ pos.index = -i;
}
-
- // Look for mm.
- int minutes = 0;
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- minutes = c - '0';
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
+ } else {
+ // Parse the rest as "hhmm" (RFC 822)
+ int i = subParseNumericZone(text, ++pos.index,
+ sign, 0, false, calb);
+ if (i > 0) {
+ return i;
}
- minutes *= 10;
- minutes += c - '0';
-
- if (minutes > 59) {
- break parsing;
- }
-
- offset = hours * 60 + minutes;
- } catch (StringIndexOutOfBoundsException e) {
- break parsing;
+ pos.index = -i;
}
- }
-
- // Do the final processing for both of the above cases. We only
- // arrive here if the form GMT+/-... or an RFC 822 form was seen.
- if (sign != 0) {
- offset *= MILLIS_PER_MINUTE * sign;
- calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0);
- return ++pos.index;
+ } catch (IndexOutOfBoundsException e) {
}
}
break parsing;
case PATTERN_ISO_ZONE: // 'X'
{
- int sign = 0;
- int offset = 0;
-
- iso8601: {
- try {
- char c = text.charAt(pos.index);
- if (c == 'Z') {
- calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
- return ++pos.index;
- }
-
- // parse text as "+/-hh[[:]mm]" based on count
- if (c == '+') {
- sign = 1;
- } else if (c == '-') {
- sign = -1;
- }
- // Look for hh.
- int hours = 0;
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- hours = c - '0';
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- hours *= 10;
- hours += c - '0';
- if (hours > 23) {
- break parsing;
- }
+ if ((text.length() - pos.index) <= 0) {
+ break parsing;
+ }
- if (count == 1) { // "X"
- offset = hours * 60;
- break iso8601;
- }
-
- c = text.charAt(++pos.index);
- // Skip ':' if "XXX"
- if (c == ':') {
- if (count == 2) {
- break parsing;
- }
- c = text.charAt(++pos.index);
- } else {
- if (count == 3) {
- // missing ':'
- break parsing;
- }
- }
-
- // Look for mm.
- int minutes = 0;
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- minutes = c - '0';
- c = text.charAt(++pos.index);
- if (c < '0' || c > '9') { /* must be from '0' to '9'. */
- break parsing;
- }
- minutes *= 10;
- minutes += c - '0';
-
- if (minutes > 59) {
- break parsing;
- }
-
- offset = hours * 60 + minutes;
- } catch (StringIndexOutOfBoundsException e) {
- break parsing;
- }
+ int sign = 0;
+ char c = text.charAt(pos.index);
+ if (c == 'Z') {
+ calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
+ return ++pos.index;
}
- // Do the final processing for both of the above cases. We only
- // arrive here if the form GMT+/-... or an RFC 822 form was seen.
- if (sign != 0) {
- offset *= MILLIS_PER_MINUTE * sign;
- calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0);
- return ++pos.index;
+ // parse text as "+/-hh[[:]mm]" based on count
+ if (c == '+') {
+ sign = 1;
+ } else if (c == '-') {
+ sign = -1;
+ } else {
+ ++pos.index;
+ break parsing;
}
+ int i = subParseNumericZone(text, ++pos.index, sign, count,
+ count == 3, calb);
+ if (i > 0) {
+ return i;
+ }
+ pos.index = -i;
}
break parsing;
--- a/jdk/src/share/classes/java/util/Locale.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/util/Locale.java Wed Jan 19 19:00:30 2011 -0800
@@ -1449,10 +1449,15 @@
* three-letter language abbreviation is not available for this locale.
*/
public String getISO3Language() throws MissingResourceException {
- String language3 = getISO3Code(_baseLocale.getLanguage(), LocaleISOData.isoLanguageTable);
+ String lang = _baseLocale.getLanguage();
+ if (lang.length() == 3) {
+ return lang;
+ }
+
+ String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
if (language3 == null) {
throw new MissingResourceException("Couldn't find 3-letter language code for "
- + _baseLocale.getLanguage(), "FormatData_" + toString(), "ShortLanguage");
+ + lang, "FormatData_" + toString(), "ShortLanguage");
}
return language3;
}
--- a/jdk/src/share/classes/javax/print/attribute/standard/DialogTypeSelection.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/print/attribute/standard/DialogTypeSelection.java Wed Jan 19 19:00:30 2011 -0800
@@ -52,6 +52,8 @@
public final class DialogTypeSelection extends EnumSyntax
implements PrintRequestAttribute {
+ private static final long serialVersionUID = 7518682952133256029L;
+
/**
*
*/
--- a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java Wed Jan 19 19:00:30 2011 -0800
@@ -310,7 +310,7 @@
} else {
transmitter = device.getTransmitter();
}
- if (!(transmitter instanceof MidiDeviceReceiver)) {
+ if (!(transmitter instanceof MidiDeviceTransmitter)) {
transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter);
}
return transmitter;
--- a/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java Wed Jan 19 19:00:30 2011 -0800
@@ -359,7 +359,22 @@
f.getWidth()-1, f.getHeight()-1);
}
g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1);
- currentLoc = new Point (newX, newY);
+ /* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.
+ * Swing doesn't expect that its XOR drawRect did
+ * not complete, so believes that on re-entering at
+ * the next update location, that there is an XOR rect
+ * to draw out at "currentLoc". But in fact
+ * its now got a new clean surface without that rect,
+ * so drawing it "out" in fact draws it on, leaving garbage.
+ * So only update/set currentLoc if the draw completed.
+ */
+ sun.java2d.SurfaceData sData =
+ ((sun.java2d.SunGraphics2D)g).getSurfaceData();
+
+ if (!sData.isSurfaceLost()) {
+ currentLoc = new Point (newX, newY);
+ }
+;
g.dispose();
}
} else if (dragMode == FASTER_DRAG_MODE) {
@@ -412,7 +427,14 @@
g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1);
}
g.drawRect( newX, newY, newWidth-1, newHeight-1);
- currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
+
+ // Work around for 6635462, see comment in dragFrame()
+ sun.java2d.SurfaceData sData =
+ ((sun.java2d.SunGraphics2D)g).getSurfaceData();
+ if (!sData.isSurfaceLost()) {
+ currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
+ }
+
g.setPaintMode();
g.dispose();
}
--- a/jdk/src/share/classes/javax/swing/JSlider.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/swing/JSlider.java Wed Jan 19 19:00:30 2011 -0800
@@ -40,7 +40,8 @@
/**
* A component that lets the user graphically select a value by sliding
- * a knob within a bounded interval.
+ * a knob within a bounded interval. The knob is always positioned
+ * at the points that match integer values within the specified interval.
* <p>
* The slider can show both
* major tick marks, and minor tick marks between the major ones. The number of
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java Wed Jan 19 19:00:30 2011 -0800
@@ -908,6 +908,14 @@
int height = parent.getHeight();
Insets insets = parent.getInsets();
+
+ if (nextButton == null && previousButton == null) {
+ setBounds(editor, insets.left, insets.top, width - insets.left - insets.right,
+ height - insets.top - insets.bottom);
+
+ return;
+ }
+
Dimension nextD = preferredSize(nextButton);
Dimension previousD = preferredSize(previousButton);
int buttonsWidth = Math.max(nextD.width, previousD.width);
--- a/jdk/src/share/classes/sun/awt/FontConfiguration.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/awt/FontConfiguration.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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,10 +37,10 @@
import java.nio.charset.CharsetEncoder;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
-import java.util.Iterator;
import java.util.Locale;
import java.util.Map.Entry;
import java.util.Properties;
@@ -329,6 +329,8 @@
* tables.
*/
public static void saveBinary(OutputStream out) throws IOException {
+ sanityCheck();
+
DataOutputStream dataOut = new DataOutputStream(out);
writeShortTable(dataOut, head);
writeShortTable(dataOut, table_scriptIDs);
@@ -350,7 +352,6 @@
if (verbose) {
dump();
}
- sanityCheck();
}
//private static boolean loadingProperties;
@@ -1343,6 +1344,11 @@
private static short[] table_stringIDs;
private static char[] table_stringTable;
+ /**
+ * Checks consistencies of complied fontconfig data. This method
+ * is called only at the build-time from
+ * build.tools.compilefontconfig.CompileFontConfig.
+ */
private static void sanityCheck() {
int errors = 0;
@@ -1358,12 +1364,20 @@
//componentFontNameID starts from "1"
for (int ii = 1; ii < table_filenames.length; ii++) {
if (table_filenames[ii] == -1) {
- System.out.println("\n Warning: "
- + "<filename."
- + getString(table_componentFontNameIDs[ii])
- + "> entry is missing!!!");
- if (!osName.contains("Linux")) {
+ // The corresponding finename entry for a component
+ // font name is mandatory on Windows, but it's
+ // optional on Solaris and Linux.
+ if (osName.contains("Windows")) {
+ System.err.println("\n Error: <filename."
+ + getString(table_componentFontNameIDs[ii])
+ + "> entry is missing!!!");
errors++;
+ } else {
+ if (verbose && !isEmpty(table_filenames)) {
+ System.err.println("\n Note: 'filename' entry is undefined for \""
+ + getString(table_componentFontNameIDs[ii])
+ + "\"");
+ }
}
}
}
@@ -1382,7 +1396,7 @@
int jj = iii * NUM_STYLES + iij;
short ffid = table_scriptFonts[fid + jj];
if (ffid == 0) {
- System.out.println("\n Error: <"
+ System.err.println("\n Error: <"
+ getFontName(iii) + "."
+ getStyleName(iij) + "."
+ getString(table_scriptIDs[ii])
@@ -1402,7 +1416,7 @@
script.contains("symbol")) {
continue;
}
- System.out.println("\nError: "
+ System.err.println("\nError: "
+ "<awtfontpath."
+ script
+ "> entry is missing!!!");
@@ -1411,11 +1425,19 @@
}
}
if (errors != 0) {
- System.out.println("!!THERE ARE " + errors + " ERROR(S) IN "
+ System.err.println("!!THERE ARE " + errors + " ERROR(S) IN "
+ "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n");
System.exit(1);
+ }
+ }
+ private static boolean isEmpty(short[] a) {
+ for (short s : a) {
+ if (s != -1) {
+ return false;
+ }
}
+ return true;
}
//dump the fontconfig data tables
@@ -1652,20 +1674,16 @@
private static void writeShortTable(DataOutputStream out, short[] data)
throws IOException {
- for (int i = 0; i < data.length; i++) {
- out.writeShort(data[i]);
+ for (short val : data) {
+ out.writeShort(val);
}
}
- private static short[] toList(HashMap map) {
+ private static short[] toList(HashMap<String, Short> map) {
short[] list = new short[map.size()];
- for (int i = 0; i < list.length; i++) {
- list[i] = -1;
- }
- Iterator iterator = map.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<String, Short> entry = (Entry <String, Short>)iterator.next();
- list[entry.getValue().shortValue()] = getStringID(entry.getKey());
+ Arrays.fill(list, (short) -1);
+ for (Entry<String, Short> entry : map.entrySet()) {
+ list[entry.getValue()] = getStringID(entry.getKey());
}
return list;
}
@@ -1763,25 +1781,19 @@
int len = table_scriptIDs.length + scriptFonts.size() * 20;
table_scriptFonts = new short[len];
- Iterator iterator = scriptAllfonts.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
- table_scriptFonts[entry.getKey().intValue()] = (short)entry.getValue().shortValue();
+ for (Entry<Short, Short> entry : scriptAllfonts.entrySet()) {
+ table_scriptFonts[entry.getKey().intValue()] = entry.getValue();
}
int off = table_scriptIDs.length;
- iterator = scriptFonts.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<Short, Short[]> entry = (Entry <Short, Short[]>)iterator.next();
+ for (Entry<Short, Short[]> entry : scriptFonts.entrySet()) {
table_scriptFonts[entry.getKey().intValue()] = (short)-off;
Short[] v = entry.getValue();
- int i = 0;
- while (i < 20) {
+ for (int i = 0; i < 20; i++) {
if (v[i] != null) {
- table_scriptFonts[off++] = v[i].shortValue();
+ table_scriptFonts[off++] = v[i];
} else {
table_scriptFonts[off++] = 0;
}
- i++;
}
}
@@ -1792,9 +1804,7 @@
//(3) sequences elcID -> XXXX[1|5] -> scriptID[]
head[INDEX_sequences] = (short)(head[INDEX_elcIDs] + table_elcIDs.length);
table_sequences = new short[elcIDs.size() * NUM_FONTS];
- iterator = sequences.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<Short, short[]> entry = (Entry <Short, short[]>)iterator.next();
+ for (Entry<Short, short[]> entry : sequences.entrySet()) {
//table_sequences[entry.getKey().intValue()] = (short)-off;
int k = entry.getKey().intValue();
short[] v = entry.getValue();
@@ -1827,31 +1837,24 @@
//(6)componentFontNameID -> filenameID
head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs] + table_componentFontNameIDs.length);
table_filenames = new short[table_componentFontNameIDs.length];
- for (int i = 0; i < table_filenames.length; i++) {
- table_filenames[i] = -1;
- }
- iterator = filenames.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
- table_filenames[entry.getKey().shortValue()] = entry.getValue().shortValue();
+ Arrays.fill(table_filenames, (short) -1);
+
+ for (Entry<Short, Short> entry : filenames.entrySet()) {
+ table_filenames[entry.getKey()] = entry.getValue();
}
//(7)scriptID-> awtfontpath
//the paths are stored as scriptID -> stringID in awtfontpahts
head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames] + table_filenames.length);
table_awtfontpaths = new short[table_scriptIDs.length];
- iterator = awtfontpaths.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
- table_awtfontpaths[entry.getKey().shortValue()] = entry.getValue().shortValue();
+ for (Entry<Short, Short> entry : awtfontpaths.entrySet()) {
+ table_awtfontpaths[entry.getKey()] = entry.getValue();
}
//(8)exclusions
head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths] + table_awtfontpaths.length);
table_exclusions = new short[scriptIDs.size()];
- iterator = exclusions.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<Short, int[]> entry = (Entry <Short, int[]>)iterator.next();
+ for (Entry<Short, int[]> entry : exclusions.entrySet()) {
int[] exI = entry.getValue();
char[] exC = new char[exI.length * 2];
int j = 0;
@@ -1859,17 +1862,15 @@
exC[j++] = (char) (exI[i] >> 16);
exC[j++] = (char) (exI[i] & 0xffff);
}
- table_exclusions[entry.getKey().shortValue()] = getStringID(new String (exC));
+ table_exclusions[entry.getKey()] = getStringID(new String (exC));
}
//(9)proportionals
head[INDEX_proportionals] = (short)(head[INDEX_exclusions] + table_exclusions.length);
table_proportionals = new short[proportionals.size() * 2];
- iterator = proportionals.entrySet().iterator();
int j = 0;
- while (iterator.hasNext()) {
- Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
- table_proportionals[j++] = entry.getKey().shortValue();
- table_proportionals[j++] = entry.getValue().shortValue();
+ for (Entry<Short, Short> entry : proportionals.entrySet()) {
+ table_proportionals[j++] = entry.getKey();
+ table_proportionals[j++] = entry.getValue();
}
//(10) see (1) for info, the only difference is "xxx.motif"
@@ -1878,22 +1879,18 @@
len = table_scriptIDs.length + scriptFontsMotif.size() * 20;
table_scriptFontsMotif = new short[len];
- iterator = scriptAllfontsMotif.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
+ for (Entry<Short, Short> entry : scriptAllfontsMotif.entrySet()) {
table_scriptFontsMotif[entry.getKey().intValue()] =
- (short)entry.getValue().shortValue();
+ (short)entry.getValue();
}
off = table_scriptIDs.length;
- iterator = scriptFontsMotif.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<Short, Short[]> entry = (Entry <Short, Short[]>)iterator.next();
+ for (Entry<Short, Short[]> entry : scriptFontsMotif.entrySet()) {
table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off;
Short[] v = entry.getValue();
int i = 0;
while (i < 20) {
if (v[i] != null) {
- table_scriptFontsMotif[off++] = v[i].shortValue();
+ table_scriptFontsMotif[off++] = v[i];
} else {
table_scriptFontsMotif[off++] = 0;
}
@@ -1907,12 +1904,10 @@
//(11)short[] alphabeticSuffix
head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length);
table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2];
- iterator = alphabeticSuffix.entrySet().iterator();
j = 0;
- while (iterator.hasNext()) {
- Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
- table_alphabeticSuffix[j++] = entry.getKey().shortValue();
- table_alphabeticSuffix[j++] = entry.getValue().shortValue();
+ for (Entry<Short, Short> entry : alphabeticSuffix.entrySet()) {
+ table_alphabeticSuffix[j++] = entry.getKey();
+ table_alphabeticSuffix[j++] = entry.getValue();
}
//(15)short[] fallbackScriptIDs; just put the ID in head
--- a/jdk/src/share/classes/sun/awt/SunToolkit.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/awt/SunToolkit.java Wed Jan 19 19:00:30 2011 -0800
@@ -102,26 +102,6 @@
public final static int MAX_BUTTONS_SUPPORTED = 20;
public SunToolkit() {
- /* If awt.threadgroup is set to class name the instance of
- * this class is created (should be subclass of ThreadGroup)
- * and EventDispatchThread is created inside of it
- *
- * If loaded class overrides uncaughtException instance
- * handles all uncaught exception on EventDispatchThread
- */
- ThreadGroup threadGroup = null;
- String tgName = System.getProperty("awt.threadgroup", "");
-
- if (tgName.length() != 0) {
- try {
- Constructor ctor = Class.forName(tgName).
- getConstructor(new Class[] {String.class});
- threadGroup = (ThreadGroup)ctor.newInstance(new Object[] {"AWT-ThreadGroup"});
- } catch (Exception e) {
- System.err.println("Failed loading " + tgName + ": " + e);
- }
- }
-
Runnable initEQ = new Runnable() {
public void run () {
EventQueue eventQueue;
@@ -144,17 +124,7 @@
}
};
- if (threadGroup != null) {
- Thread eqInitThread = new Thread(threadGroup, initEQ, "EventQueue-Init");
- eqInitThread.start();
- try {
- eqInitThread.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- } else {
- initEQ.run();
- }
+ initEQ.run();
}
public boolean useBufferPerWindow() {
--- a/jdk/src/share/classes/sun/dc/DuctusRenderingEngine.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/dc/DuctusRenderingEngine.java Wed Jan 19 19:00:30 2011 -0800
@@ -635,6 +635,88 @@
return r;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AATileGenerator getAATileGenerator(double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ double lw1, double lw2,
+ Region clip,
+ int bbox[])
+ {
+ // REMIND: Deal with large coordinates!
+ double ldx1, ldy1, ldx2, ldy2;
+ boolean innerpgram = (lw1 > 0 && lw2 > 0);
+
+ if (innerpgram) {
+ ldx1 = dx1 * lw1;
+ ldy1 = dy1 * lw1;
+ ldx2 = dx2 * lw2;
+ ldy2 = dy2 * lw2;
+ x -= (ldx1 + ldx2) / 2.0;
+ y -= (ldy1 + ldy2) / 2.0;
+ dx1 += ldx1;
+ dy1 += ldy1;
+ dx2 += ldx2;
+ dy2 += ldy2;
+ if (lw1 > 1 && lw2 > 1) {
+ // Inner parallelogram was entirely consumed by stroke...
+ innerpgram = false;
+ }
+ } else {
+ ldx1 = ldy1 = ldx2 = ldy2 = 0;
+ }
+
+ Rasterizer r = getRasterizer();
+
+ r.setUsage(Rasterizer.EOFILL);
+
+ r.beginPath();
+ r.beginSubpath((float) x, (float) y);
+ r.appendLine((float) (x+dx1), (float) (y+dy1));
+ r.appendLine((float) (x+dx1+dx2), (float) (y+dy1+dy2));
+ r.appendLine((float) (x+dx2), (float) (y+dy2));
+ r.closedSubpath();
+ if (innerpgram) {
+ x += ldx1 + ldx2;
+ y += ldy1 + ldy2;
+ dx1 -= 2.0 * ldx1;
+ dy1 -= 2.0 * ldy1;
+ dx2 -= 2.0 * ldx2;
+ dy2 -= 2.0 * ldy2;
+ r.beginSubpath((float) x, (float) y);
+ r.appendLine((float) (x+dx1), (float) (y+dy1));
+ r.appendLine((float) (x+dx1+dx2), (float) (y+dy1+dy2));
+ r.appendLine((float) (x+dx2), (float) (y+dy2));
+ r.closedSubpath();
+ }
+
+ try {
+ r.endPath();
+ r.getAlphaBox(bbox);
+ clip.clipBoxToBounds(bbox);
+ if (bbox[0] >= bbox[2] || bbox[1] >= bbox[3]) {
+ dropRasterizer(r);
+ return null;
+ }
+ r.setOutputArea(bbox[0], bbox[1],
+ bbox[2] - bbox[0],
+ bbox[3] - bbox[1]);
+ } catch (PRException e) {
+ /*
+ * This exeption is thrown from the native part of the Ductus
+ * (only in case of a debug build) to indicate that some
+ * segments of the path have very large coordinates.
+ * See 4485298 for more info.
+ */
+ System.err.println("DuctusRenderingEngine.getAATileGenerator: "+e);
+ }
+
+ return r;
+ }
+
private void feedConsumer(PathConsumer consumer, PathIterator pi) {
try {
consumer.beginPath();
--- a/jdk/src/share/classes/sun/font/FileFontStrike.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/font/FileFontStrike.java Wed Jan 19 19:00:30 2011 -0800
@@ -58,10 +58,10 @@
private static final int SEGINTARRAY = 3;
private static final int SEGLONGARRAY = 4;
- private int glyphCacheFormat = UNINITIALISED;
+ private volatile int glyphCacheFormat = UNINITIALISED;
- /* segmented arrays are blocks of 256 */
- private static final int SEGSHIFT = 8;
+ /* segmented arrays are blocks of 32 */
+ private static final int SEGSHIFT = 5;
private static final int SEGSIZE = 1 << SEGSHIFT;
private boolean segmentedCache;
@@ -171,7 +171,7 @@
mapper = fileFont.getMapper();
int numGlyphs = mapper.getNumGlyphs();
- /* Always segment for fonts with > 2K glyphs, but also for smaller
+ /* Always segment for fonts with > 256 glyphs, but also for smaller
* fonts with non-typical sizes and transforms.
* Segmenting for all non-typical pt sizes helps to minimise memory
* usage when very many distinct strikes are created.
@@ -522,32 +522,33 @@
}
/* Called only from synchronized code or constructor */
- private void initGlyphCache() {
+ private synchronized void initGlyphCache() {
int numGlyphs = mapper.getNumGlyphs();
-
+ int tmpFormat = UNINITIALISED;
if (segmentedCache) {
int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE;
if (longAddresses) {
- glyphCacheFormat = SEGLONGARRAY;
+ tmpFormat = SEGLONGARRAY;
segLongGlyphImages = new long[numSegments][];
this.disposer.segLongGlyphImages = segLongGlyphImages;
} else {
- glyphCacheFormat = SEGINTARRAY;
+ tmpFormat = SEGINTARRAY;
segIntGlyphImages = new int[numSegments][];
this.disposer.segIntGlyphImages = segIntGlyphImages;
}
} else {
if (longAddresses) {
- glyphCacheFormat = LONGARRAY;
+ tmpFormat = LONGARRAY;
longGlyphImages = new long[numGlyphs];
this.disposer.longGlyphImages = longGlyphImages;
} else {
- glyphCacheFormat = INTARRAY;
+ tmpFormat = INTARRAY;
intGlyphImages = new int[numGlyphs];
this.disposer.intGlyphImages = intGlyphImages;
}
}
+ glyphCacheFormat = tmpFormat;
}
float getGlyphAdvance(int glyphCode) {
--- a/jdk/src/share/classes/sun/font/Font2D.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/font/Font2D.java Wed Jan 19 19:00:30 2011 -0800
@@ -343,7 +343,21 @@
}
strike = createStrike(desc);
//StrikeCache.addStrike();
- strikeRef = StrikeCache.getStrikeRef(strike);
+ /* If we are creating many strikes on this font which
+ * involve non-quadrant rotations, or more general
+ * transforms which include shears, then force the use
+ * of weak references rather than soft references.
+ * This means that it won't live much beyond the next GC,
+ * which is what we want for what is likely a transient strike.
+ */
+ int txType = desc.glyphTx.getType();
+ if (txType == AffineTransform.TYPE_GENERAL_TRANSFORM ||
+ (txType & AffineTransform.TYPE_GENERAL_ROTATION) != 0 &&
+ strikeCache.size() > 10) {
+ strikeRef = StrikeCache.getStrikeRef(strike, true);
+ } else {
+ strikeRef = StrikeCache.getStrikeRef(strike);
+ }
strikeCache.put(desc, strikeRef);
//strike.lastlookupTime = System.currentTimeMillis();
lastFontStrike = new SoftReference(strike);
--- a/jdk/src/share/classes/sun/java2d/SurfaceData.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/SurfaceData.java Wed Jan 19 19:00:30 2011 -0800
@@ -367,16 +367,17 @@
public static final TextPipe aaTextRenderer;
public static final TextPipe lcdTextRenderer;
- protected static final CompositePipe colorPipe;
+ protected static final AlphaColorPipe colorPipe;
protected static final PixelToShapeConverter colorViaShape;
protected static final PixelToParallelogramConverter colorViaPgram;
protected static final TextPipe colorText;
protected static final CompositePipe clipColorPipe;
protected static final TextPipe clipColorText;
protected static final AAShapePipe AAColorShape;
- protected static final PixelToShapeConverter AAColorViaShape;
+ protected static final PixelToParallelogramConverter AAColorViaShape;
+ protected static final PixelToParallelogramConverter AAColorViaPgram;
protected static final AAShapePipe AAClipColorShape;
- protected static final PixelToShapeConverter AAClipColorViaShape;
+ protected static final PixelToParallelogramConverter AAClipColorViaShape;
protected static final CompositePipe paintPipe;
protected static final SpanShapeRenderer paintShape;
@@ -385,9 +386,9 @@
protected static final CompositePipe clipPaintPipe;
protected static final TextPipe clipPaintText;
protected static final AAShapePipe AAPaintShape;
- protected static final PixelToShapeConverter AAPaintViaShape;
+ protected static final PixelToParallelogramConverter AAPaintViaShape;
protected static final AAShapePipe AAClipPaintShape;
- protected static final PixelToShapeConverter AAClipPaintViaShape;
+ protected static final PixelToParallelogramConverter AAClipPaintViaShape;
protected static final CompositePipe compPipe;
protected static final SpanShapeRenderer compShape;
@@ -396,9 +397,9 @@
protected static final CompositePipe clipCompPipe;
protected static final TextPipe clipCompText;
protected static final AAShapePipe AACompShape;
- protected static final PixelToShapeConverter AACompViaShape;
+ protected static final PixelToParallelogramConverter AACompViaShape;
protected static final AAShapePipe AAClipCompShape;
- protected static final PixelToShapeConverter AAClipCompViaShape;
+ protected static final PixelToParallelogramConverter AAClipCompViaShape;
protected static final DrawImagePipe imagepipe;
@@ -427,6 +428,22 @@
}
}
+ private static PixelToParallelogramConverter
+ makeConverter(AAShapePipe renderer,
+ ParallelogramPipe pgrampipe)
+ {
+ return new PixelToParallelogramConverter(renderer,
+ pgrampipe,
+ 1.0/8.0, 0.499,
+ false);
+ }
+
+ private static PixelToParallelogramConverter
+ makeConverter(AAShapePipe renderer)
+ {
+ return makeConverter(renderer, renderer);
+ }
+
static {
colorPrimitives = new LoopPipe();
@@ -445,9 +462,10 @@
clipColorPipe = new SpanClipRenderer(colorPipe);
clipColorText = new TextRenderer(clipColorPipe);
AAColorShape = new AAShapePipe(colorPipe);
- AAColorViaShape = new PixelToShapeConverter(AAColorShape);
+ AAColorViaShape = makeConverter(AAColorShape);
+ AAColorViaPgram = makeConverter(AAColorShape, colorPipe);
AAClipColorShape = new AAShapePipe(clipColorPipe);
- AAClipColorViaShape = new PixelToShapeConverter(AAClipColorShape);
+ AAClipColorViaShape = makeConverter(AAClipColorShape);
paintPipe = new AlphaPaintPipe();
paintShape = new SpanShapeRenderer.Composite(paintPipe);
@@ -456,9 +474,9 @@
clipPaintPipe = new SpanClipRenderer(paintPipe);
clipPaintText = new TextRenderer(clipPaintPipe);
AAPaintShape = new AAShapePipe(paintPipe);
- AAPaintViaShape = new PixelToShapeConverter(AAPaintShape);
+ AAPaintViaShape = makeConverter(AAPaintShape);
AAClipPaintShape = new AAShapePipe(clipPaintPipe);
- AAClipPaintViaShape = new PixelToShapeConverter(AAClipPaintShape);
+ AAClipPaintViaShape = makeConverter(AAClipPaintShape);
compPipe = new GeneralCompositePipe();
compShape = new SpanShapeRenderer.Composite(compPipe);
@@ -467,9 +485,9 @@
clipCompPipe = new SpanClipRenderer(compPipe);
clipCompText = new TextRenderer(clipCompPipe);
AACompShape = new AAShapePipe(compPipe);
- AACompViaShape = new PixelToShapeConverter(AACompShape);
+ AACompViaShape = makeConverter(AACompShape);
AAClipCompShape = new AAShapePipe(clipCompPipe);
- AAClipCompViaShape = new PixelToShapeConverter(AAClipCompShape);
+ AAClipCompViaShape = makeConverter(AAClipCompShape);
imagepipe = new DrawImage();
}
@@ -591,12 +609,12 @@
if (sg2d.clipState == sg2d.CLIP_SHAPE) {
sg2d.drawpipe = AAClipCompViaShape;
sg2d.fillpipe = AAClipCompViaShape;
- sg2d.shapepipe = AAClipCompShape;
+ sg2d.shapepipe = AAClipCompViaShape;
sg2d.textpipe = clipCompText;
} else {
sg2d.drawpipe = AACompViaShape;
sg2d.fillpipe = AACompViaShape;
- sg2d.shapepipe = AACompShape;
+ sg2d.shapepipe = AACompViaShape;
sg2d.textpipe = compText;
}
} else {
@@ -616,13 +634,17 @@
if (sg2d.clipState == sg2d.CLIP_SHAPE) {
sg2d.drawpipe = AAClipColorViaShape;
sg2d.fillpipe = AAClipColorViaShape;
- sg2d.shapepipe = AAClipColorShape;
+ sg2d.shapepipe = AAClipColorViaShape;
sg2d.textpipe = clipColorText;
} else {
- sg2d.drawpipe = AAColorViaShape;
- sg2d.fillpipe = AAColorViaShape;
- sg2d.shapepipe = AAColorShape;
- if (sg2d.paintState > sg2d.PAINT_OPAQUECOLOR ||
+ PixelToParallelogramConverter converter =
+ (sg2d.alphafill.canDoParallelograms()
+ ? AAColorViaPgram
+ : AAColorViaShape);
+ sg2d.drawpipe = converter;
+ sg2d.fillpipe = converter;
+ sg2d.shapepipe = converter;
+ if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||
sg2d.compositeState > sg2d.COMP_ISCOPY)
{
sg2d.textpipe = colorText;
@@ -634,12 +656,12 @@
if (sg2d.clipState == sg2d.CLIP_SHAPE) {
sg2d.drawpipe = AAClipPaintViaShape;
sg2d.fillpipe = AAClipPaintViaShape;
- sg2d.shapepipe = AAClipPaintShape;
+ sg2d.shapepipe = AAClipPaintViaShape;
sg2d.textpipe = clipPaintText;
} else {
sg2d.drawpipe = AAPaintViaShape;
sg2d.fillpipe = AAPaintViaShape;
- sg2d.shapepipe = AAPaintShape;
+ sg2d.shapepipe = AAPaintViaShape;
sg2d.textpipe = paintText;
}
}
@@ -793,6 +815,18 @@
}
}
+ private static CompositeType getFillCompositeType(SunGraphics2D sg2d) {
+ CompositeType compType = sg2d.imageComp;
+ if (sg2d.compositeState == sg2d.COMP_ISCOPY) {
+ if (compType == CompositeType.SrcOverNoEa) {
+ compType = CompositeType.OpaqueSrcOverNoEa;
+ } else {
+ compType = CompositeType.SrcNoEa;
+ }
+ }
+ return compType;
+ }
+
/**
* Returns a MaskFill object that can be used on this destination
* with the source (paint) and composite types determined by the given
@@ -802,9 +836,10 @@
* surface) before returning a specific MaskFill object.
*/
protected MaskFill getMaskFill(SunGraphics2D sg2d) {
- return MaskFill.getFromCache(getPaintSurfaceType(sg2d),
- sg2d.imageComp,
- getSurfaceType());
+ SurfaceType src = getPaintSurfaceType(sg2d);
+ CompositeType comp = getFillCompositeType(sg2d);
+ SurfaceType dst = getSurfaceType();
+ return MaskFill.getFromCache(src, comp, dst);
}
private static RenderCache loopcache = new RenderCache(30);
@@ -816,9 +851,7 @@
*/
public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
SurfaceType src = getPaintSurfaceType(sg2d);
- CompositeType comp = (sg2d.compositeState == sg2d.COMP_ISCOPY
- ? CompositeType.SrcNoEa
- : sg2d.imageComp);
+ CompositeType comp = getFillCompositeType(sg2d);
SurfaceType dst = sg2d.getSurfaceData().getSurfaceType();
Object o = loopcache.get(src, comp, dst);
--- a/jdk/src/share/classes/sun/java2d/loops/CompositeType.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/loops/CompositeType.java Wed Jan 19 19:00:30 2011 -0800
@@ -27,6 +27,7 @@
import java.awt.image.BufferedImage;
import java.awt.AlphaComposite;
+import java.util.HashMap;
/**
* A CompositeType object provides a chained description of a type of
@@ -51,6 +52,11 @@
* the indicated algorithm if all of the more specific searches fail.
*/
public final class CompositeType {
+
+ private static int unusedUID = 1;
+ private static final HashMap<String,Integer> compositeUIDMap =
+ new HashMap<String,Integer>(100);
+
/*
* CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE COMPOSITING
* ALGORITHMS THEY CAN PERFORM
@@ -153,6 +159,22 @@
SrcOverNoEa = SrcOver.deriveSubType(DESC_SRC_OVER_NO_EA);
/*
+ * A special CompositeType for the case where we are filling in
+ * SrcOverNoEa mode with an opaque color. In that case then the
+ * best loop for us to use would be a SrcNoEa loop, but what if
+ * there is no such loop? In that case then we would end up
+ * backing off to a Src loop (which should still be fine) or an
+ * AnyAlpha loop which would be slower than a SrcOver loop in
+ * most cases.
+ * The fix is to use the following chain which looks for loops
+ * in the following order:
+ * SrcNoEa, Src, SrcOverNoEa, SrcOver, AnyAlpha
+ */
+ public static final CompositeType
+ OpaqueSrcOverNoEa = SrcOverNoEa.deriveSubType(DESC_SRC)
+ .deriveSubType(DESC_SRC_NO_EA);
+
+ /*
* END OF CompositeType OBJECTS FOR THE VARIOUS CONSTANTS
*/
@@ -210,7 +232,6 @@
}
}
- private static int unusedUID = 1;
private int uniqueID;
private String desc;
private CompositeType next;
@@ -218,14 +239,20 @@
private CompositeType(CompositeType parent, String desc) {
next = parent;
this.desc = desc;
- this.uniqueID = makeUniqueID();
+ this.uniqueID = makeUniqueID(desc);
}
- private synchronized static final int makeUniqueID() {
- if (unusedUID > 255) {
- throw new InternalError("composite type id overflow");
+ public synchronized static final int makeUniqueID(String desc) {
+ Integer i = compositeUIDMap.get(desc);
+
+ if (i == null) {
+ if (unusedUID > 255) {
+ throw new InternalError("composite type id overflow");
+ }
+ i = unusedUID++;
+ compositeUIDMap.put(desc, i);
}
- return unusedUID++;
+ return i;
}
public int getUniqueID() {
--- a/jdk/src/share/classes/sun/java2d/loops/MaskFill.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/loops/MaskFill.java Wed Jan 19 19:00:30 2011 -0800
@@ -50,6 +50,10 @@
public class MaskFill extends GraphicsPrimitive
{
public static final String methodSignature = "MaskFill(...)".toString();
+ public static final String fillPgramSignature =
+ "FillAAPgram(...)".toString();
+ public static final String drawPgramSignature =
+ "DrawAAPgram(...)".toString();
public static final int primTypeID = makePrimTypeID();
@@ -92,6 +96,14 @@
return fill;
}
+ protected MaskFill(String alternateSignature,
+ SurfaceType srctype,
+ CompositeType comptype,
+ SurfaceType dsttype)
+ {
+ super(alternateSignature, primTypeID, srctype, comptype, dsttype);
+ }
+
protected MaskFill(SurfaceType srctype,
CompositeType comptype,
SurfaceType dsttype)
@@ -115,6 +127,23 @@
int x, int y, int w, int h,
byte[] mask, int maskoff, int maskscan);
+ public native void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,
+ Composite comp,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2);
+
+ public native void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,
+ Composite comp,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ double lw1, double lw2);
+
+ public boolean canDoParallelograms() {
+ return (getNativePrim() != 0);
+ }
+
static {
GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null));
}
@@ -182,12 +211,22 @@
private static class TraceMaskFill extends MaskFill {
MaskFill target;
+ MaskFill fillPgramTarget;
+ MaskFill drawPgramTarget;
public TraceMaskFill(MaskFill target) {
super(target.getSourceType(),
target.getCompositeType(),
target.getDestType());
this.target = target;
+ this.fillPgramTarget = new MaskFill(fillPgramSignature,
+ target.getSourceType(),
+ target.getCompositeType(),
+ target.getDestType());
+ this.drawPgramTarget = new MaskFill(drawPgramSignature,
+ target.getSourceType(),
+ target.getCompositeType(),
+ target.getDestType());
}
public GraphicsPrimitive traceWrap() {
@@ -203,5 +242,32 @@
target.MaskFill(sg2d, sData, comp, x, y, w, h,
mask, maskoff, maskscan);
}
+
+ public void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,
+ Composite comp,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2)
+ {
+ tracePrimitive(fillPgramTarget);
+ target.FillAAPgram(sg2d, sData, comp,
+ x, y, dx1, dy1, dx2, dy2);
+ }
+
+ public void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,
+ Composite comp,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ double lw1, double lw2)
+ {
+ tracePrimitive(drawPgramTarget);
+ target.DrawAAPgram(sg2d, sData, comp,
+ x, y, dx1, dy1, dx2, dy2, lw1, lw2);
+ }
+
+ public boolean canDoParallelograms() {
+ return target.canDoParallelograms();
+ }
}
}
--- a/jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java Wed Jan 19 19:00:30 2011 -0800
@@ -28,6 +28,7 @@
import java.awt.BasicStroke;
import java.awt.Rectangle;
import java.awt.Shape;
+import java.awt.geom.Rectangle2D;
import java.awt.geom.PathIterator;
import sun.awt.SunHints;
import sun.java2d.SunGraphics2D;
@@ -39,7 +40,9 @@
* This class sets up the Generator and computes the alpha tiles
* and then passes them on to a CompositePipe object for painting.
*/
-public class AAShapePipe implements ShapeDrawPipe {
+public class AAShapePipe
+ implements ShapeDrawPipe, ParallelogramPipe
+{
static RenderingEngine renderengine = RenderingEngine.getInstance();
CompositePipe outpipe;
@@ -65,6 +68,59 @@
renderPath(sg, s, null);
}
+ private static Rectangle2D computeBBox(double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2)
+ {
+ double lox, loy, hix, hiy;
+ lox = hix = x;
+ loy = hiy = y;
+ if (dx1 < 0) { lox += dx1; } else { hix += dx1; }
+ if (dy1 < 0) { loy += dy1; } else { hiy += dy1; }
+ if (dx2 < 0) { lox += dx2; } else { hix += dx2; }
+ if (dy2 < 0) { loy += dy2; } else { hiy += dy2; }
+ return new Rectangle2D.Double(lox, loy, hix-lox, hiy-loy);
+ }
+
+ public void fillParallelogram(SunGraphics2D sg,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2)
+ {
+ Region clip = sg.getCompClip();
+ int abox[] = new int[4];
+ AATileGenerator aatg =
+ renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
+ clip, abox);
+ if (aatg == null) {
+ // Nothing to render
+ return;
+ }
+
+ renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
+ }
+
+ public void drawParallelogram(SunGraphics2D sg,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ double lw1, double lw2)
+ {
+ Region clip = sg.getCompClip();
+ int abox[] = new int[4];
+ AATileGenerator aatg =
+ renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
+ clip, abox);
+ if (aatg == null) {
+ // Nothing to render
+ return;
+ }
+
+ // Note that bbox is of the original shape, not the wide path.
+ // This is appropriate for handing to Paint methods...
+ renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
+ }
+
private static byte[] theTile;
public synchronized static byte[] getAlphaTile(int len) {
@@ -85,8 +141,6 @@
boolean adjust = (bs != null &&
sg.strokeHint != SunHints.INTVAL_STROKE_PURE);
boolean thin = (sg.strokeState <= sg.STROKE_THINDASHED);
- Object context = null;
- byte alpha[] = null;
Region clip = sg.getCompClip();
int abox[] = new int[4];
@@ -98,6 +152,14 @@
return;
}
+ renderTiles(sg, s, aatg, abox);
+ }
+
+ public void renderTiles(SunGraphics2D sg, Shape s,
+ AATileGenerator aatg, int abox[])
+ {
+ Object context = null;
+ byte alpha[] = null;
try {
context = outpipe.startSequence(sg, s,
new Rectangle(abox[0], abox[1],
--- a/jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java Wed Jan 19 19:00:30 2011 -0800
@@ -34,7 +34,7 @@
* into a destination that supports direct alpha compositing of a solid
* color, according to one of the rules in the AlphaComposite class.
*/
-public class AlphaColorPipe implements CompositePipe {
+public class AlphaColorPipe implements CompositePipe, ParallelogramPipe {
public AlphaColorPipe() {
}
@@ -64,4 +64,23 @@
public void endSequence(Object context) {
return;
}
+
+ public void fillParallelogram(SunGraphics2D sg,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2)
+ {
+ sg.alphafill.FillAAPgram(sg, sg.getSurfaceData(), sg.composite,
+ x, y, dx1, dy1, dx2, dy2);
+ }
+
+ public void drawParallelogram(SunGraphics2D sg,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ double lw1, double lw2)
+ {
+ sg.alphafill.DrawAAPgram(sg, sg.getSurfaceData(), sg.composite,
+ x, y, dx1, dy1, dx2, dy2, lw1, lw2);
+ }
}
--- a/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java Wed Jan 19 19:00:30 2011 -0800
@@ -281,6 +281,72 @@
int bbox[]);
/**
+ * Construct an antialiased tile generator for the given parallelogram
+ * store the bounds of the tile iteration in the bbox parameter.
+ * The parallelogram is specified as a starting point and 2 delta
+ * vectors that indicate the slopes of the 2 pairs of sides of the
+ * parallelogram.
+ * The 4 corners of the parallelogram are defined by the 4 points:
+ * <ul>
+ * <li> {@code x}, {@code y}
+ * <li> {@code x+dx1}, {@code y+dy1}
+ * <li> {@code x+dx1+dx2}, {@code y+dy1+dy2}
+ * <li> {@code x+dx2}, {@code y+dy2}
+ * </ul>
+ * The {@code lw1} and {@code lw2} parameters provide a specification
+ * for an optionally stroked parallelogram if they are positive numbers.
+ * The {@code lw1} parameter is the ratio of the length of the {@code dx1},
+ * {@code dx2} delta vector to half of the line width in that same
+ * direction.
+ * The {@code lw2} parameter provides the same ratio for the other delta
+ * vector.
+ * If {@code lw1} and {@code lw2} are both greater than zero, then
+ * the parallelogram figure is doubled by both expanding and contracting
+ * each delta vector by its corresponding {@code lw} value.
+ * If either (@code lw1) or {@code lw2} are also greater than 1, then
+ * the inner (contracted) parallelogram disappears and the figure is
+ * simply a single expanded parallelogram.
+ * The {@code clip} parameter specifies the current clip in effect
+ * in device coordinates and can be used to prune the data for the
+ * operation, but the renderer is not required to perform any
+ * clipping.
+ * <p>
+ * Upon returning, this method will fill the {@code bbox} parameter
+ * with 4 values indicating the bounds of the iteration of the
+ * tile generator.
+ * The iteration order of the tiles will be as specified by the
+ * pseudo-code:
+ * <pre>
+ * for (y = bbox[1]; y < bbox[3]; y += tileheight) {
+ * for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
+ * }
+ * }
+ * </pre>
+ * If there is no output to be rendered, this method may return
+ * null.
+ *
+ * @param x the X coordinate of the first corner of the parallelogram
+ * @param y the Y coordinate of the first corner of the parallelogram
+ * @param dx1 the X coordinate delta of the first leg of the parallelogram
+ * @param dy1 the Y coordinate delta of the first leg of the parallelogram
+ * @param dx2 the X coordinate delta of the second leg of the parallelogram
+ * @param dy2 the Y coordinate delta of the second leg of the parallelogram
+ * @param lw1 the line width ratio for the first leg of the parallelogram
+ * @param lw2 the line width ratio for the second leg of the parallelogram
+ * @param clip the current clip in effect in device coordinates
+ * @param bbox returns the bounds of the iteration
+ * @return the {@code AATileGenerator} instance to be consulted
+ * for tile coverages, or null if there is no output to render
+ * @since 1.7
+ */
+ public abstract AATileGenerator getAATileGenerator(double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ double lw1, double lw2,
+ Region clip,
+ int bbox[]);
+
+ /**
* Returns the minimum pen width that the antialiasing rasterizer
* can represent without dropouts occuring.
* @since 1.7
@@ -393,5 +459,24 @@
bs, thin, normalize,
bbox);
}
+ public AATileGenerator getAATileGenerator(double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ double lw1, double lw2,
+ Region clip,
+ int bbox[])
+ {
+ System.out.println(name+".getAATileGenerator("+
+ x+", "+y+", "+
+ dx1+", "+dy1+", "+
+ dx2+", "+dy2+", "+
+ lw1+", "+lw2+", "+
+ clip+")");
+ return target.getAATileGenerator(x, y,
+ dx1, dy1,
+ dx2, dy2,
+ lw1, lw2,
+ clip, bbox);
+ }
}
}
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Wed Jan 19 19:00:30 2011 -0800
@@ -557,6 +557,69 @@
return ptg;
}
+ public AATileGenerator getAATileGenerator(double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ double lw1, double lw2,
+ Region clip,
+ int bbox[])
+ {
+ // REMIND: Deal with large coordinates!
+ double ldx1, ldy1, ldx2, ldy2;
+ boolean innerpgram = (lw1 > 0 && lw2 > 0);
+
+ if (innerpgram) {
+ ldx1 = dx1 * lw1;
+ ldy1 = dy1 * lw1;
+ ldx2 = dx2 * lw2;
+ ldy2 = dy2 * lw2;
+ x -= (ldx1 + ldx2) / 2.0;
+ y -= (ldy1 + ldy2) / 2.0;
+ dx1 += ldx1;
+ dy1 += ldy1;
+ dx2 += ldx2;
+ dy2 += ldy2;
+ if (lw1 > 1 && lw2 > 1) {
+ // Inner parallelogram was entirely consumed by stroke...
+ innerpgram = false;
+ }
+ } else {
+ ldx1 = ldy1 = ldx2 = ldy2 = 0;
+ }
+
+ Renderer r = new Renderer(3, 3,
+ clip.getLoX(), clip.getLoY(),
+ clip.getWidth(), clip.getHeight(),
+ PathIterator.WIND_EVEN_ODD);
+
+ r.moveTo((float) x, (float) y);
+ r.lineTo((float) (x+dx1), (float) (y+dy1));
+ r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2));
+ r.lineTo((float) (x+dx2), (float) (y+dy2));
+ r.closePath();
+
+ if (innerpgram) {
+ x += ldx1 + ldx2;
+ y += ldy1 + ldy2;
+ dx1 -= 2.0 * ldx1;
+ dy1 -= 2.0 * ldy1;
+ dx2 -= 2.0 * ldx2;
+ dy2 -= 2.0 * ldy2;
+ r.moveTo((float) x, (float) y);
+ r.lineTo((float) (x+dx1), (float) (y+dy1));
+ r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2));
+ r.lineTo((float) (x+dx2), (float) (y+dy2));
+ r.closePath();
+ }
+
+ r.pathDone();
+
+ r.endRendering();
+ PiscesTileGenerator ptg = new PiscesTileGenerator(r, r.MAX_AA_ALPHA);
+ ptg.getBbox(bbox);
+ return ptg;
+ }
+
/**
* Returns the minimum pen width that the antialiasing rasterizer
* can represent without dropouts occuring.
--- a/jdk/src/share/native/sun/awt/image/awt_parseImage.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/awt/image/awt_parseImage.c Wed Jan 19 19:00:30 2011 -0800
@@ -178,7 +178,7 @@
jnbits = (*env)->GetObjectField(env, rasterP->jsampleModel,
g_SPPSMnBitsID);
if (jmask == NULL || joffs == NULL || jnbits == NULL ||
- rasterP->sppsm.maxBitSize < 0 || rasterP->sppsm.maxBitSize > 8)
+ rasterP->sppsm.maxBitSize < 0)
{
JNU_ThrowInternalError(env, "Can't grab SPPSM fields");
return -1;
@@ -280,6 +280,17 @@
rasterP->chanOffsets);
}
+ /* additioanl check for sppsm fields validity: make sure that
+ * size of raster samples doesn't exceed the data type cpacity.
+ */
+ if (rasterP->dataType > UNKNOWN_DATA_TYPE && /* data type has been recognized */
+ rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */
+ rasterP->sppsm.maxBitSize > (rasterP->dataSize * 8))
+ {
+ JNU_ThrowInternalError(env, "Raster samples are too big");
+ return -1;
+ }
+
#if 0
fprintf(stderr,"---------------------\n");
fprintf(stderr,"Width : %d\n",rasterP->width);
--- a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h Wed Jan 19 19:00:30 2011 -0800
@@ -88,27 +88,18 @@
/* blend (lerp between) two rgb quads
src and dst alpha is ignored
the algorithm: src*alpha+dst*(1-alpha)=(src-dst)*alpha+dst, rb and g are done separately
- it's possible to verify that it's almost accurate indeed */
-
+*/
INLINE rgbquad_t
blendRGB(rgbquad_t dst, rgbquad_t src, rgbquad_t alpha)
{
- const rgbquad_t dstrb = dst & 0xFF00FF;
- const rgbquad_t dstg = dst & 0xFF00;
- const rgbquad_t srcrb = src & 0xFF00FF;
- const rgbquad_t srcg = src & 0xFF00;
-
- rgbquad_t drb = srcrb - dstrb;
- rgbquad_t dg = srcg - dstg;
+ const rgbquad_t a = alpha;
+ const rgbquad_t a1 = 0xFF - alpha;
- alpha += 1;
-
- drb *= alpha;
- dg *= alpha;
- drb >>= 8;
- dg >>= 8;
-
- return ((drb + dstrb) & 0xFF00FF) | ((dg + dstg) & 0xFF00);
+ return MAKE_QUAD(
+ (rgbquad_t)((QUAD_RED(src) * a + QUAD_RED(dst) * a1) / 0xFF),
+ (rgbquad_t)((QUAD_GREEN(src) * a + QUAD_GREEN(dst) * a1) / 0xFF),
+ (rgbquad_t)((QUAD_BLUE(src) * a + QUAD_BLUE(dst) * a1) / 0xFF),
+ 0);
}
/* scales rgb quad by alpha. basically similar to what's above. src alpha is retained.
--- a/jdk/src/share/native/sun/java2d/loops/DrawParallelogram.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/java2d/loops/DrawParallelogram.c Wed Jan 19 19:00:30 2011 -0800
@@ -26,14 +26,11 @@
#include "math.h"
#include "GraphicsPrimitiveMgr.h"
#include "LineUtils.h"
-#include "LoopMacros.h"
#include "Trace.h"
+#include "ParallelogramUtils.h"
-#include "sun_java2d_loops_FillParallelogram.h"
#include "sun_java2d_loops_DrawParallelogram.h"
-DECLARE_SOLID_DRAWLINE(AnyInt);
-
#define HANDLE_PGRAM_EDGE(X1, Y1, X2, Y2, \
pRasInfo, pixel, pPrim, pFunc, pCompInfo) \
do { \
@@ -46,28 +43,6 @@
ix1, iy1, ix2, iy2, JNI_TRUE); \
} while (0)
-#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
- do { \
- double vmin, vmax; \
- if (dv1 < 0) { \
- vmin = v0+dv1; \
- vmax = v0; \
- } else { \
- vmin = v0; \
- vmax = v0+dv1; \
- } \
- if (dv2 < 0) { \
- vmin -= dv2; \
- } else { \
- vmax += dv2; \
- } \
- bmin = (jint) floor(vmin + 0.5); \
- bmax = (jint) floor(vmax + 0.5); \
- } while(0)
-
-#define PGRAM_INIT_X(starty, x, y, slope) \
- (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
-
typedef struct {
jdouble x0;
jdouble y0;
@@ -136,20 +111,8 @@
* Sort parallelogram by y values, ensure that each delta vector
* has a non-negative y delta.
*/
- if (dy1 < 0) {
- x0 += dx1; y0 += dy1;
- dx1 = -dx1; dy1 = -dy1;
- }
- if (dy2 < 0) {
- x0 += dx2; y0 += dy2;
- dx2 = -dx2; dy2 = -dy2;
- }
- /* Sort delta vectors so dxy1 is left of dxy2. */
- if (dx1 * dy2 > dx2 * dy1) {
- double v = dx1; dx1 = dx2; dx2 = v;
- v = dy1; dy1 = dy2; dy2 = v;
- v = lw1; lw1 = lw2; lw2 = v;
- }
+ SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2,
+ v = lw1; lw1 = lw2; lw2 = v;);
// dx,dy for line width in the "1" and "2" directions.
ldx1 = dx1 * lw1;
@@ -161,7 +124,7 @@
ox0 = x0 - (ldx1 + ldx2) / 2.0;
oy0 = y0 - (ldy1 + ldy2) / 2.0;
- PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2);
+ PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2, JNI_FALSE);
iy1 = (jint) floor(oy0 + 0.5);
iy2 = (jint) floor(oy0 + dy1 + ldy1 + dy2 + ldy2 + 0.5);
@@ -212,7 +175,7 @@
// Only need to generate 4 quads if the interior still
// has a hole in it (i.e. if the line width ratios were
// both less than 1.0)
- if (lw1 < 1.0f && lw2 < 1.0f) {
+ if (lw1 < 1.0 && lw2 < 1.0) {
// If the line widths are both less than a pixel wide
// then we can use a drawline function instead for even
// more performance.
--- a/jdk/src/share/native/sun/java2d/loops/FillParallelogram.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/java2d/loops/FillParallelogram.c Wed Jan 19 19:00:30 2011 -0800
@@ -25,31 +25,10 @@
#include "math.h"
#include "GraphicsPrimitiveMgr.h"
+#include "ParallelogramUtils.h"
#include "sun_java2d_loops_FillParallelogram.h"
-#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
- do { \
- double vmin, vmax; \
- if (dv1 < 0) { \
- vmin = v0+dv1; \
- vmax = v0; \
- } else { \
- vmin = v0; \
- vmax = v0+dv1; \
- } \
- if (dv2 < 0) { \
- vmin -= dv2; \
- } else { \
- vmax += dv2; \
- } \
- bmin = (jint) floor(vmin + 0.5); \
- bmax = (jint) floor(vmax + 0.5); \
- } while(0)
-
-#define PGRAM_INIT_X(starty, x, y, slope) \
- (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
-
/*
* Class: sun_java2d_loops_FillParallelogram
* Method: FillParallelogram
@@ -76,22 +55,11 @@
/*
* Sort parallelogram by y values, ensure that each delta vector
- * has a non-negative y delta, and eliminate degenerate parallelograms.
+ * has a non-negative y delta.
*/
- if (dy1 < 0) {
- x0 += dx1; y0 += dy1;
- dx1 = -dx1; dy1 = -dy1;
- }
- if (dy2 < 0) {
- x0 += dx2; y0 += dy2;
- dx2 = -dx2; dy2 = -dy2;
- }
- /* Sort delta vectors so dxy1 is left of dxy2. */
- if (dx1 * dy2 > dx2 * dy1) {
- double v = dx1; dx1 = dx2; dx2 = v;
- v = dy1; dy1 = dy2; dy2 = v;
- }
- PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2);
+ SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, );
+
+ PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2, JNI_FALSE);
iy1 = (jint) floor(y0 + 0.5);
iy2 = (jint) floor(y0 + dy1 + dy2 + 0.5);
--- a/jdk/src/share/native/sun/java2d/loops/MaskFill.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/java2d/loops/MaskFill.c Wed Jan 19 19:00:30 2011 -0800
@@ -23,7 +23,11 @@
* questions.
*/
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
#include "GraphicsPrimitiveMgr.h"
+#include "ParallelogramUtils.h"
#include "sun_java2d_loops_MaskFill.h"
@@ -93,6 +97,967 @@
}
}
SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+ }
+ SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
+}
+
+#define MASK_BUF_LEN 1024
+
+#define DblToMask(v) ((unsigned char) ((v)*255.9999))
+
+/* Fills an aligned rectangle with potentially translucent edges. */
+static void
+fillAARect(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+ CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+ void *pDst,
+ jdouble x1, jdouble y1, jdouble x2, jdouble y2)
+{
+ jint cx1 = pRasInfo->bounds.x1;
+ jint cy1 = pRasInfo->bounds.y1;
+ jint cx2 = pRasInfo->bounds.x2;
+ jint cy2 = pRasInfo->bounds.y2;
+ jint rx1 = (jint) ceil(x1);
+ jint ry1 = (jint) ceil(y1);
+ jint rx2 = (jint) floor(x2);
+ jint ry2 = (jint) floor(y2);
+ jint width = cx2 - cx1;
+ jint scan = pRasInfo->scanStride;
+ /* Convert xy12 into the edge coverage fractions for those edges. */
+ x1 = rx1-x1;
+ y1 = ry1-y1;
+ x2 = x2-rx2;
+ y2 = y2-ry2;
+ if (ry2 < ry1) {
+ /* Accumulate bottom coverage into top coverage. */
+ y1 = y1 + y2 - 1.0;
+ /* prevent processing of "bottom fractional row" */
+ ry2 = cy2;
+ }
+ if (rx2 < rx1) {
+ /* Accumulate right coverage into left coverage. */
+ x1 = x1 + x2 - 1.0;
+ /* prevent processing of "right fractional column" */
+ rx2 = cx2;
+ }
+ /* Check for a visible "top fractional row" and process it */
+ if (cy1 < ry1) {
+ unsigned char midcov = DblToMask(y1);
+ jint x;
+ for (x = 0; x < width; x++) {
+ pMask[x] = midcov;
+ }
+ if (cx1 < rx1) {
+ pMask[0] = DblToMask(y1 * x1);
+ }
+ if (cx2 > rx2) {
+ pMask[width-1] = DblToMask(y1 * x2);
+ }
+ (*pPrim->funcs.maskfill)(pDst,
+ pMask, 0, 0,
+ width, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ pDst = PtrAddBytes(pDst, scan);
+ cy1++;
+ }
+ /* Check for a visible "left fract, solid middle, right fract" section. */
+ if (cy1 < ry2 && cy1 < cy2) {
+ jint midh = ((ry2 < cy2) ? ry2 : cy2) - cy1;
+ jint midx = cx1;
+ void *pMid = pDst;
+ /* First process the left "fractional column" if it is visible. */
+ if (midx < rx1) {
+ pMask[0] = DblToMask(x1);
+ /* Note: maskscan == 0 means we reuse this value for every row. */
+ (*pPrim->funcs.maskfill)(pMid,
+ pMask, 0, 0,
+ 1, midh,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ pMid = PtrAddBytes(pMid, pRasInfo->pixelStride);
+ midx++;
+ }
+ /* Process the central solid section if it is visible. */
+ if (midx < rx2 && midx < cx2) {
+ jint midw = ((rx2 < cx2) ? rx2 : cx2) - midx;
+ /* A NULL mask buffer means "all coverages are 0xff" */
+ (*pPrim->funcs.maskfill)(pMid,
+ NULL, 0, 0,
+ midw, midh,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ pMid = PtrCoord(pMid, midw, pRasInfo->pixelStride, 0, 0);
+ midx += midw;
+ }
+ /* Finally process the right "fractional column" if it is visible. */
+ if (midx < cx2) {
+ pMask[0] = DblToMask(x2);
+ /* Note: maskscan == 0 means we reuse this value for every row. */
+ (*pPrim->funcs.maskfill)(pMid,
+ pMask, 0, 0,
+ 1, midh,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ }
+ cy1 += midh;
+ pDst = PtrCoord(pDst, 0, 0, midh, scan);
+ }
+ /* Check for a visible "bottom fractional row" and process it */
+ if (cy1 < cy2) {
+ unsigned char midcov = DblToMask(y2);
+ jint x;
+ for (x = 0; x < width; x++) {
+ pMask[x] = midcov;
+ }
+ if (cx1 < rx1) {
+ pMask[0] = DblToMask(y2 * x1);
+ }
+ if (cx2 > rx2) {
+ pMask[width-1] = DblToMask(y2 * x2);
+ }
+ (*pPrim->funcs.maskfill)(pDst,
+ pMask, 0, 0,
+ width, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ }
+}
+
+/*
+ * Support code for arbitrary tracing and MaskFill filling of
+ * non-rectilinear (diagonal) parallelograms.
+ *
+ * This code is based upon the following model of AA coverage.
+ *
+ * Each edge of a parallelogram (for fillPgram) or a double
+ * parallelogram (inner and outer parallelograms for drawPgram)
+ * can be rasterized independently because the geometry is well
+ * defined in such a way that none of the sides will ever cross
+ * each other and they have a fixed ordering that is fairly
+ * well predetermined.
+ *
+ * So, for each edge we will look at the diagonal line that
+ * the edge makes as it passes through a row of pixels. Some
+ * such diagonal lines may pass entirely through the row of
+ * pixels in a single pixel column. Some may cut across the
+ * row and pass through several pixel columns before they pass
+ * on to the next row.
+ *
+ * As the edge passes through the row of pixels it will affect
+ * the coverage of the pixels it passes through as well as all
+ * of the pixels to the right of the edge. The coverage will
+ * either be increased (by a left edge of a parallelogram) or
+ * decreased (by a right edge) for all pixels to the right, until
+ * another edge passing the opposite direction is encountered.
+ *
+ * The coverage added or subtracted by an edge as it crosses a
+ * given pixel is calculated using a trapezoid formula in the
+ * following manner:
+ *
+ * /
+ * +-----+---/-+-----+
+ * | | / | |
+ * | | / | |
+ * +-----+/----+-----+
+ * /
+ *
+ * The area to the right of that edge for the pixel where it
+ * crosses is given as:
+ *
+ * trapheight * (topedge + bottomedge)/2
+ *
+ * Another thing to note is that the above formula gives the
+ * contribution of that edge to the given pixel where it crossed,
+ * but in so crossing the pixel row, it also created 100% coverage
+ * for all of the pixels to the right.
+ *
+ * This example was simplified in that the edge depicted crossed
+ * the complete pixel row and it did so entirely within the bounds
+ * of a single pixel column. In practice, many edges may start or
+ * end in a given row and thus provide only partial row coverage
+ * (i.e. the total "trapheight" in the formula never reaches 1.0).
+ * And in other cases, edges may travel sideways through several
+ * pixel columns on a given pixel row from where they enter it to
+ * where the leave it (which also mans that the trapheight for a
+ * given pixel will be less than 1.0, but by the time the edge
+ * completes its journey through the pixel row the "coverage shadow"
+ * that it casts on all pixels to the right eventually reaches 100%).
+ *
+ * In order to simplify the calculations so that we don't have to
+ * keep propagating coverages we calculate for one edge "until we
+ * reach another edge" we will process one edge at a time and
+ * simply record in a buffer the amount that an edge added to
+ * or subtracted from the coverage for a given pixel and its
+ * following right-side neighbors. Thus, the true total coverage
+ * of a given pixel is only determined by summing the deltas for
+ * that pixel and all of the pixels to its left. Since we already
+ * have to scan the buffer to change floating point coverages into
+ * mask values for a MaskFill loop, it is simple enough to sum the
+ * values as we perform that scan from left to right.
+ *
+ * In the above example, note that 2 deltas need to be recorded even
+ * though the edge only intersected a single pixel. The delta recorded
+ * for the pixel where the edge crossed will be approximately 55%
+ * (guesstimating by examining the poor ascii art) which is fine for
+ * determining how to render that pixel, but the rest of the pixels
+ * to its right should have their coverage modified by a full 100%
+ * and the 55% delta value we recorded for the pixel that the edge
+ * crossed will not get them there. We adjust for this by adding
+ * the "remainder" of the coverage implied by the shadow to the
+ * pixel immediately to the right of where we record a trapezoidal
+ * contribution. In this case a delta of 45% will be recorded in
+ * the pixel immediately to the right to raise the total to 100%.
+ *
+ * As we sum these delta values as we process the line from left
+ * to right, these delta values will typically drive the sum from
+ * 0% up to 100% and back down to 0% over the course of a single
+ * pixel row. In the case of a drawn (double) parallelogram the
+ * sum will go to 100% and back to 0% twice on most scanlines.
+ *
+ * The fillAAPgram and drawAAPgram functions drive the main flow
+ * of the algorithm with help from the following structures,
+ * macros, and functions. It is probably best to start with
+ * those 2 functions to gain an understanding of the algorithm.
+ */
+typedef struct {
+ jdouble x;
+ jdouble y;
+ jdouble xbot;
+ jdouble ybot;
+ jdouble xnexty;
+ jdouble ynextx;
+ jdouble xnextx;
+ jdouble linedx;
+ jdouble celldx;
+ jdouble celldy;
+ jboolean isTrailing;
+} EdgeInfo;
+
+#define MIN_DELTA (1.0/256.0)
+
+/*
+ * Calculates slopes and deltas for an edge and stores results in an EdgeInfo.
+ * Returns true if the edge was valid (i.e. not ignored for some reason).
+ */
+static jboolean
+storeEdge(EdgeInfo *pEdge,
+ jdouble x, jdouble y, jdouble dx, jdouble dy,
+ jint cx1, jint cy1, jint cx2, jint cy2,
+ jboolean isTrailing)
+{
+ jdouble xbot = x + dx;
+ jdouble ybot = y + dy;
+ jboolean ret;
+
+ pEdge->x = x;
+ pEdge->y = y;
+ pEdge->xbot = xbot;
+ pEdge->ybot = ybot;
+
+ /* Note that parallelograms are sorted so dy is always non-negative */
+ if (dy > MIN_DELTA && /* NaN and horizontal protection */
+ ybot > cy1 && /* NaN and "OUT_ABOVE" protection */
+ y < cy2 && /* NaN and "OUT_BELOW" protection */
+ xbot == xbot && /* NaN protection */
+ (x < cx2 || xbot < cx2)) /* "OUT_RIGHT" protection */
+ /* Note: "OUT_LEFT" segments may still contribute coverage... */
+ {
+ /* no NaNs, dy is not horizontal, and segment contributes to clip */
+ if (dx < -MIN_DELTA || dx > MIN_DELTA) {
+ /* dx is not vertical */
+ jdouble linedx;
+ jdouble celldy;
+ jdouble nextx;
+
+ linedx = dx / dy;
+ celldy = dy / dx;
+ if (y < cy1) {
+ pEdge->x = x = x + (cy1 - y) * linedx;
+ pEdge->y = y = cy1;
+ }
+ pEdge->linedx = linedx;
+ if (dx < 0) {
+ pEdge->celldx = -1.0;
+ pEdge->celldy = -celldy;
+ pEdge->xnextx = nextx = ceil(x) - 1.0;
+ } else {
+ pEdge->celldx = +1.0;
+ pEdge->celldy = celldy;
+ pEdge->xnextx = nextx = floor(x) + 1.0;
+ }
+ pEdge->ynextx = y + (nextx - x) * celldy;
+ pEdge->xnexty = x + ((floor(y) + 1) - y) * linedx;
+ } else {
+ /* dx is essentially vertical */
+ if (y < cy1) {
+ pEdge->y = y = cy1;
+ }
+ pEdge->xbot = x;
+ pEdge->linedx = 0.0;
+ pEdge->celldx = 0.0;
+ pEdge->celldy = 1.0;
+ pEdge->xnextx = x;
+ pEdge->xnexty = x;
+ pEdge->ynextx = ybot;
+ }
+ ret = JNI_TRUE;
+ } else {
+ /* There is some reason to ignore this segment, "celldy=0" omits it */
+ pEdge->ybot = y;
+ pEdge->linedx = dx;
+ pEdge->celldx = dx;
+ pEdge->celldy = 0.0;
+ pEdge->xnextx = xbot;
+ pEdge->xnexty = xbot;
+ pEdge->ynextx = y;
+ ret = JNI_FALSE;
+ }
+ pEdge->isTrailing = isTrailing;
+ return ret;
+}
+
+/*
+ * Calculates and stores slopes and deltas for all edges of a parallelogram.
+ * Returns true if at least 1 edge was valid (i.e. not ignored for some reason).
+ *
+ * The inverted flag is true for an outer parallelogram (left and right
+ * edges are leading and trailing) and false for an inner parallelogram
+ * (where the left edge is trailing and the right edge is leading).
+ */
+static jboolean
+storePgram(EdgeInfo *pLeftEdge, EdgeInfo *pRightEdge,
+ jdouble x, jdouble y,
+ jdouble dx1, jdouble dy1,
+ jdouble dx2, jdouble dy2,
+ jint cx1, jint cy1, jint cx2, jint cy2,
+ jboolean inverted)
+{
+ jboolean ret = JNI_FALSE;
+ ret = (storeEdge(pLeftEdge + 0,
+ x , y , dx1, dy1,
+ cx1, cy1, cx2, cy2, inverted) || ret);
+ ret = (storeEdge(pLeftEdge + 1,
+ x+dx1, y+dy1, dx2, dy2,
+ cx1, cy1, cx2, cy2, inverted) || ret);
+ ret = (storeEdge(pRightEdge + 0,
+ x , y , dx2, dy2,
+ cx1, cy1, cx2, cy2, !inverted) || ret);
+ ret = (storeEdge(pRightEdge + 1,
+ x+dx2, y+dy2, dx1, dy1,
+ cx1, cy1, cx2, cy2, !inverted) || ret);
+ return ret;
+}
+
+/*
+ * The X0,Y0,X1,Y1 values represent a trapezoidal fragment whose
+ * coverage must be accounted for in the accum buffer.
+ *
+ * All four values are assumed to fall within (or on the edge of)
+ * a single pixel.
+ *
+ * The trapezoid area is accumulated into the proper element of
+ * the accum buffer and the remainder of the "slice height" is
+ * accumulated into the element to its right.
+ */
+#define INSERT_ACCUM(pACCUM, IMIN, IMAX, X0, Y0, X1, Y1, CX1, CX2, MULT) \
+ do { \
+ jdouble xmid = ((X0) + (X1)) * 0.5; \
+ if (xmid <= (CX2)) { \
+ jdouble sliceh = ((Y1) - (Y0)); \
+ jdouble slicearea; \
+ jint i; \
+ if (xmid < (CX1)) { \
+ /* Accumulate the entire slice height into accum[0]. */ \
+ i = 0; \
+ slicearea = sliceh; \
+ } else { \
+ jdouble xpos = floor(xmid); \
+ i = ((jint) xpos) - (CX1); \
+ slicearea = (xpos+1-xmid) * sliceh; \
+ } \
+ if (IMIN > i) { \
+ IMIN = i; \
+ } \
+ (pACCUM)[i++] += (jfloat) ((MULT) * slicearea); \
+ (pACCUM)[i++] += (jfloat) ((MULT) * (sliceh - slicearea)); \
+ if (IMAX < i) { \
+ IMAX = i; \
+ } \
+ } \
+ } while (0)
+
+/*
+ * Accumulate the contributions for a given edge crossing a given
+ * scan line into the corresponding entries of the accum buffer.
+ * CY1 is the Y coordinate of the top edge of the scanline and CY2
+ * is equal to (CY1 + 1) and is the Y coordinate of the bottom edge
+ * of the scanline. CX1 and CX2 are the left and right edges of the
+ * clip (or area of interest) being rendered.
+ *
+ * The edge is processed from the top edge to the bottom edge and
+ * a single pixel column at a time.
+ */
+#define ACCUM_EDGE(pEDGE, pACCUM, IMIN, IMAX, CX1, CY1, CX2, CY2) \
+ do { \
+ jdouble x, y, xnext, ynext, xlast, ylast, dx, dy, mult; \
+ y = (pEDGE)->y; \
+ dy = (pEDGE)->celldy; \
+ ylast = (pEDGE)->ybot; \
+ if (ylast <= (CY1) || y >= (CY2) || dy == 0.0) { \
+ break; \
+ } \
+ x = (pEDGE)->x; \
+ dx = (pEDGE)->celldx; \
+ if (ylast > (CY2)) { \
+ ylast = (CY2); \
+ xlast = (pEDGE)->xnexty; \
+ } else { \
+ xlast = (pEDGE)->xbot; \
+ } \
+ xnext = (pEDGE)->xnextx; \
+ ynext = (pEDGE)->ynextx; \
+ mult = ((pEDGE)->isTrailing) ? -1.0 : 1.0; \
+ while (ynext <= ylast) { \
+ INSERT_ACCUM(pACCUM, IMIN, IMAX, \
+ x, y, xnext, ynext, \
+ CX1, CX2, mult); \
+ x = xnext; \
+ y = ynext; \
+ xnext += dx; \
+ ynext += dy; \
+ } \
+ (pEDGE)->ynextx = ynext; \
+ (pEDGE)->xnextx = xnext; \
+ INSERT_ACCUM(pACCUM, IMIN, IMAX, \
+ x, y, xlast, ylast, \
+ CX1, CX2, mult); \
+ (pEDGE)->x = xlast; \
+ (pEDGE)->y = ylast; \
+ (pEDGE)->xnexty = xlast + (pEDGE)->linedx; \
+ } while(0)
+
+/* Main function to fill a single Parallelogram */
+static void
+fillAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+ CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+ void *pDst,
+ jdouble x1, jdouble y1,
+ jdouble dx1, jdouble dy1,
+ jdouble dx2, jdouble dy2)
+{
+ jint cx1 = pRasInfo->bounds.x1;
+ jint cy1 = pRasInfo->bounds.y1;
+ jint cx2 = pRasInfo->bounds.x2;
+ jint cy2 = pRasInfo->bounds.y2;
+ jint width = cx2 - cx1;
+ EdgeInfo edges[4];
+ jfloat localaccum[MASK_BUF_LEN + 1];
+ jfloat *pAccum;
+
+ if (!storePgram(edges + 0, edges + 2,
+ x1, y1, dx1, dy1, dx2, dy2,
+ cx1, cy1, cx2, cy2,
+ JNI_FALSE))
+ {
+ return;
+ }
+
+ pAccum = ((width > MASK_BUF_LEN)
+ ? malloc((width + 1) * sizeof(jfloat))
+ : localaccum);
+ if (pAccum == NULL) {
+ return;
+ }
+ memset(pAccum, 0, (width+1) * sizeof(jfloat));
+
+ while (cy1 < cy2) {
+ jint lmin, lmax, rmin, rmax;
+ jint moff, x;
+ jdouble accum;
+ unsigned char lastcov;
+
+ lmin = rmin = width + 2;
+ lmax = rmax = 0;
+ ACCUM_EDGE(&edges[0], pAccum, lmin, lmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[1], pAccum, lmin, lmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[2], pAccum, rmin, rmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[3], pAccum, rmin, rmax,
+ cx1, cy1, cx2, cy1+1);
+ if (lmax > width) {
+ lmax = width; /* Extra col has data we do not need. */
+ }
+ if (rmax > width) {
+ rmax = width; /* Extra col has data we do not need. */
+ }
+ /* If ranges overlap, handle both in the first pass. */
+ if (rmin <= lmax) {
+ lmax = rmax;
+ }
+
+ x = lmin;
+ accum = 0.0;
+ moff = 0;
+ lastcov = 0;
+ while (x < lmax) {
+ accum += pAccum[x];
+ pAccum[x] = 0.0f;
+ pMask[moff++] = lastcov = DblToMask(accum);
+ x++;
+ }
+ /* Check for a solid center section. */
+ if (lastcov == 0xFF) {
+ jint endx;
+ void *pRow;
+
+ /* First process the existing partial coverage data. */
+ if (moff > 0) {
+ pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+ (*pPrim->funcs.maskfill)(pRow,
+ pMask, 0, 0,
+ moff, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ moff = 0;
+ }
+
+ /* Where does the center section end? */
+ /* If there is no right AA edge in the accum buffer, then */
+ /* the right edge was beyond the clip, so fill out to width */
+ endx = (rmin < rmax) ? rmin : width;
+ if (x < endx) {
+ pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+ (*pPrim->funcs.maskfill)(pRow,
+ NULL, 0, 0,
+ endx - x, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ x = endx;
+ }
+ } else if (lastcov > 0 && rmin >= rmax) {
+ /* We are not at 0 coverage, but there is no right edge, */
+ /* force a right edge so we process pixels out to width. */
+ rmax = width;
+ }
+ /* The following loop will process the right AA edge and/or any */
+ /* partial coverage center section not processed above. */
+ while (x < rmax) {
+ accum += pAccum[x];
+ pAccum[x] = 0.0f;
+ pMask[moff++] = DblToMask(accum);
+ x++;
+ }
+ if (moff > 0) {
+ void *pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+ (*pPrim->funcs.maskfill)(pRow,
+ pMask, 0, 0,
+ moff, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ }
+ pDst = PtrAddBytes(pDst, pRasInfo->scanStride);
+ cy1++;
+ }
+ if (pAccum != localaccum) {
+ free(pAccum);
+ }
+}
+
+/*
+ * Class: sun_java2d_loops_MaskFill
+ * Method: FillAAPgram
+ * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Ljava/awt/Composite;DDDDDD)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_loops_MaskFill_FillAAPgram
+ (JNIEnv *env, jobject self,
+ jobject sg2d, jobject sData, jobject comp,
+ jdouble x0, jdouble y0,
+ jdouble dx1, jdouble dy1,
+ jdouble dx2, jdouble dy2)
+{
+ SurfaceDataOps *sdOps;
+ SurfaceDataRasInfo rasInfo;
+ NativePrimitive *pPrim;
+ CompositeInfo compInfo;
+ jint ix1, iy1, ix2, iy2;
+
+ if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
+ return;
+ }
+
+ /*
+ * Sort parallelogram by y values, ensure that each delta vector
+ * has a non-negative y delta.
+ */
+ SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, );
+
+ PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2, JNI_TRUE);
+ iy1 = (jint) floor(y0);
+ iy2 = (jint) ceil(y0 + dy1 + dy2);
+
+ pPrim = GetNativePrim(env, self);
+ if (pPrim == NULL) {
+ return;
+ }
+ if (pPrim->pCompType->getCompInfo != NULL) {
+ (*pPrim->pCompType->getCompInfo)(env, &compInfo, comp);
+ }
+
+ sdOps = SurfaceData_GetOps(env, sData);
+ if (sdOps == 0) {
+ return;
+ }
+
+ GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
+ SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
+ if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
+ rasInfo.bounds.x2 <= rasInfo.bounds.x1)
+ {
+ return;
+ }
+
+ if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
+ return;
+ }
+
+ ix1 = rasInfo.bounds.x1;
+ iy1 = rasInfo.bounds.y1;
+ ix2 = rasInfo.bounds.x2;
+ iy2 = rasInfo.bounds.y2;
+ if (ix2 > ix1 && iy2 > iy1) {
+ jint width = ix2 - ix1;
+ jint color = GrPrim_Sg2dGetEaRGB(env, sg2d);
+ unsigned char localmask[MASK_BUF_LEN];
+ unsigned char *pMask = ((width > MASK_BUF_LEN)
+ ? malloc(width)
+ : localmask);
+
+ sdOps->GetRasInfo(env, sdOps, &rasInfo);
+ if (rasInfo.rasBase != NULL && pMask != NULL) {
+ void *pDst = PtrCoord(rasInfo.rasBase,
+ ix1, rasInfo.pixelStride,
+ iy1, rasInfo.scanStride);
+ if (dy1 == 0 && dx2 == 0) {
+ if (dx1 < 0) {
+ // We sorted by Y above, but not by X
+ x0 += dx1;
+ dx1 = -dx1;
+ }
+ fillAARect(pPrim, &rasInfo, &compInfo,
+ color, pMask, pDst,
+ x0, y0, x0+dx1, y0+dy2);
+ } else if (dx1 == 0 && dy2 == 0) {
+ if (dx2 < 0) {
+ // We sorted by Y above, but not by X
+ x0 += dx2;
+ dx2 = -dx2;
+ }
+ fillAARect(pPrim, &rasInfo, &compInfo,
+ color, pMask, pDst,
+ x0, y0, x0+dx2, y0+dy1);
+ } else {
+ fillAAPgram(pPrim, &rasInfo, &compInfo,
+ color, pMask, pDst,
+ x0, y0, dx1, dy1, dx2, dy2);
+ }
+ }
+ SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+ if (pMask != NULL && pMask != localmask) {
+ free(pMask);
+ }
}
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
}
+
+/* Main function to fill a double pair of (inner and outer) parallelograms */
+static void
+drawAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+ CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+ void *pDst,
+ jdouble ox0, jdouble oy0,
+ jdouble dx1, jdouble dy1,
+ jdouble dx2, jdouble dy2,
+ jdouble ldx1, jdouble ldy1,
+ jdouble ldx2, jdouble ldy2)
+{
+ jint cx1 = pRasInfo->bounds.x1;
+ jint cy1 = pRasInfo->bounds.y1;
+ jint cx2 = pRasInfo->bounds.x2;
+ jint cy2 = pRasInfo->bounds.y2;
+ jint width = cx2 - cx1;
+ EdgeInfo edges[8];
+ jfloat localaccum[MASK_BUF_LEN + 1];
+ jfloat *pAccum;
+
+ if (!storePgram(edges + 0, edges + 6,
+ ox0, oy0,
+ dx1 + ldx1, dy1 + ldy1,
+ dx2 + ldx2, dy2 + ldy2,
+ cx1, cy1, cx2, cy2,
+ JNI_FALSE))
+ {
+ /* If outer pgram does not contribute, then inner cannot either. */
+ return;
+ }
+ storePgram(edges + 2, edges + 4,
+ ox0 + ldx1 + ldx2, oy0 + ldy1 + ldy2,
+ dx1 - ldx1, dy1 - ldy1,
+ dx2 - ldx2, dy2 - ldy2,
+ cx1, cy1, cx2, cy2,
+ JNI_TRUE);
+
+ pAccum = ((width > MASK_BUF_LEN)
+ ? malloc((width + 1) * sizeof(jfloat))
+ : localaccum);
+ if (pAccum == NULL) {
+ return;
+ }
+ memset(pAccum, 0, (width+1) * sizeof(jfloat));
+
+ while (cy1 < cy2) {
+ jint lmin, lmax, rmin, rmax;
+ jint moff, x;
+ jdouble accum;
+ unsigned char lastcov;
+
+ lmin = rmin = width + 2;
+ lmax = rmax = 0;
+ ACCUM_EDGE(&edges[0], pAccum, lmin, lmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[1], pAccum, lmin, lmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[2], pAccum, lmin, lmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[3], pAccum, lmin, lmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[4], pAccum, rmin, rmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[5], pAccum, rmin, rmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[6], pAccum, rmin, rmax,
+ cx1, cy1, cx2, cy1+1);
+ ACCUM_EDGE(&edges[7], pAccum, rmin, rmax,
+ cx1, cy1, cx2, cy1+1);
+ if (lmax > width) {
+ lmax = width; /* Extra col has data we do not need. */
+ }
+ if (rmax > width) {
+ rmax = width; /* Extra col has data we do not need. */
+ }
+ /* If ranges overlap, handle both in the first pass. */
+ if (rmin <= lmax) {
+ lmax = rmax;
+ }
+
+ x = lmin;
+ accum = 0.0;
+ moff = 0;
+ lastcov = 0;
+ while (x < lmax) {
+ accum += pAccum[x];
+ pAccum[x] = 0.0f;
+ pMask[moff++] = lastcov = DblToMask(accum);
+ x++;
+ }
+ /* Check for an empty or solidcenter section. */
+ if (lastcov == 0 || lastcov == 0xFF) {
+ jint endx;
+ void *pRow;
+
+ /* First process the existing partial coverage data. */
+ if (moff > 0) {
+ pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+ (*pPrim->funcs.maskfill)(pRow,
+ pMask, 0, 0,
+ moff, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ moff = 0;
+ }
+
+ /* Where does the center section end? */
+ /* If there is no right AA edge in the accum buffer, then */
+ /* the right edge was beyond the clip, so fill out to width */
+ endx = (rmin < rmax) ? rmin : width;
+ if (x < endx) {
+ if (lastcov == 0xFF) {
+ pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+ (*pPrim->funcs.maskfill)(pRow,
+ NULL, 0, 0,
+ endx - x, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ }
+ x = endx;
+ }
+ } else if (rmin >= rmax) {
+ /* We are not at 0 coverage, but there is no right edge, */
+ /* force a right edge so we process pixels out to width. */
+ rmax = width;
+ }
+ /* The following loop will process the right AA edge and/or any */
+ /* partial coverage center section not processed above. */
+ while (x < rmax) {
+ accum += pAccum[x];
+ pAccum[x] = 0.0f;
+ pMask[moff++] = lastcov = DblToMask(accum);
+ x++;
+ }
+ if (moff > 0) {
+ void *pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+ (*pPrim->funcs.maskfill)(pRow,
+ pMask, 0, 0,
+ moff, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ }
+ if (lastcov == 0xFF && x < width) {
+ void *pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+ (*pPrim->funcs.maskfill)(pRow,
+ NULL, 0, 0,
+ width - x, 1,
+ color, pRasInfo,
+ pPrim, pCompInfo);
+ }
+ pDst = PtrAddBytes(pDst, pRasInfo->scanStride);
+ cy1++;
+ }
+ if (pAccum != localaccum) {
+ free(pAccum);
+ }
+}
+
+/*
+ * Class: sun_java2d_loops_MaskFill
+ * Method: DrawAAPgram
+ * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Ljava/awt/Composite;DDDDDDDD)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_loops_MaskFill_DrawAAPgram
+ (JNIEnv *env, jobject self,
+ jobject sg2d, jobject sData, jobject comp,
+ jdouble x0, jdouble y0,
+ jdouble dx1, jdouble dy1,
+ jdouble dx2, jdouble dy2,
+ jdouble lw1, jdouble lw2)
+{
+ SurfaceDataOps *sdOps;
+ SurfaceDataRasInfo rasInfo;
+ NativePrimitive *pPrim;
+ CompositeInfo compInfo;
+ jint ix1, iy1, ix2, iy2;
+ jdouble ldx1, ldy1, ldx2, ldy2;
+ jdouble ox0, oy0;
+
+ if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
+ return;
+ }
+
+ /*
+ * Sort parallelogram by y values, ensure that each delta vector
+ * has a non-negative y delta.
+ */
+ SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2,
+ v = lw1; lw1 = lw2; lw2 = v;);
+
+ // dx,dy for line width in the "1" and "2" directions.
+ ldx1 = dx1 * lw1;
+ ldy1 = dy1 * lw1;
+ ldx2 = dx2 * lw2;
+ ldy2 = dy2 * lw2;
+
+ // calculate origin of the outer parallelogram
+ ox0 = x0 - (ldx1 + ldx2) / 2.0;
+ oy0 = y0 - (ldy1 + ldy2) / 2.0;
+
+ if (lw1 >= 1.0 || lw2 >= 1.0) {
+ /* Only need to fill an outer pgram if the interior no longer
+ * has a hole in it (i.e. if either of the line width ratios
+ * were greater than or equal to 1.0).
+ */
+ Java_sun_java2d_loops_MaskFill_FillAAPgram(env, self,
+ sg2d, sData, comp,
+ ox0, oy0,
+ dx1 + ldx1, dy1 + ldy1,
+ dx2 + ldx2, dy2 + ldy2);
+ return;
+ }
+
+ PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2, JNI_TRUE);
+ iy1 = (jint) floor(oy0);
+ iy2 = (jint) ceil(oy0 + dy1 + ldy1 + dy2 + ldy2);
+
+ pPrim = GetNativePrim(env, self);
+ if (pPrim == NULL) {
+ return;
+ }
+ if (pPrim->pCompType->getCompInfo != NULL) {
+ (*pPrim->pCompType->getCompInfo)(env, &compInfo, comp);
+ }
+
+ sdOps = SurfaceData_GetOps(env, sData);
+ if (sdOps == 0) {
+ return;
+ }
+
+ GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
+ SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
+ if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
+ rasInfo.bounds.x2 <= rasInfo.bounds.x1)
+ {
+ return;
+ }
+
+ if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
+ return;
+ }
+
+ ix1 = rasInfo.bounds.x1;
+ iy1 = rasInfo.bounds.y1;
+ ix2 = rasInfo.bounds.x2;
+ iy2 = rasInfo.bounds.y2;
+ if (ix2 > ix1 && iy2 > iy1) {
+ jint width = ix2 - ix1;
+ jint color = GrPrim_Sg2dGetEaRGB(env, sg2d);
+ unsigned char localmask[MASK_BUF_LEN];
+ unsigned char *pMask = ((width > MASK_BUF_LEN)
+ ? malloc(width)
+ : localmask);
+
+ sdOps->GetRasInfo(env, sdOps, &rasInfo);
+ if (rasInfo.rasBase != NULL && pMask != NULL) {
+ void *pDst = PtrCoord(rasInfo.rasBase,
+ ix1, rasInfo.pixelStride,
+ iy1, rasInfo.scanStride);
+ /*
+ * NOTE: aligned rects could probably be drawn
+ * even faster with a little work here.
+ * if (dy1 == 0 && dx2 == 0) {
+ * drawAARect(pPrim, &rasInfo, &compInfo,
+ * color, pMask, pDst,
+ * ox0, oy0, ox0+dx1+ldx1, oy0+dy2+ldy2, ldx1, ldy2);
+ * } else if (dx1 == 0 && dy2 == 0) {
+ * drawAARect(pPrim, &rasInfo, &compInfo,
+ * color, pMask, pDst,
+ * ox0, oy0, ox0+dx2+ldx2, oy0+dy1+ldy1, ldx2, ldy1);
+ * } else {
+ */
+ drawAAPgram(pPrim, &rasInfo, &compInfo,
+ color, pMask, pDst,
+ ox0, oy0,
+ dx1, dy1, dx2, dy2,
+ ldx1, ldy1, ldx2, ldy2);
+ /*
+ * }
+ */
+ }
+ SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+ if (pMask != NULL && pMask != localmask) {
+ free(pMask);
+ }
+ }
+ SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/java2d/loops/ParallelogramUtils.h Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 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.
+ */
+
+#ifndef ParallelogramUtils_h_Included
+#define ParallelogramUtils_h_Included
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2, AA) \
+ do { \
+ double vmin, vmax; \
+ if (dv1 < 0) { \
+ vmin = v0+dv1; \
+ vmax = v0; \
+ } else { \
+ vmin = v0; \
+ vmax = v0+dv1; \
+ } \
+ if (dv2 < 0) { \
+ vmin += dv2; \
+ } else { \
+ vmax += dv2; \
+ } \
+ if (AA) { \
+ bmin = (jint) floor(vmin); \
+ bmax = (jint) ceil(vmax); \
+ } else { \
+ bmin = (jint) floor(vmin + 0.5); \
+ bmax = (jint) floor(vmax + 0.5); \
+ } \
+ } while(0)
+
+#define PGRAM_INIT_X(starty, x, y, slope) \
+ (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
+
+/*
+ * Sort parallelogram by y values, ensure that each delta vector
+ * has a non-negative y delta.
+ */
+#define SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, OTHER_SWAP_CODE) \
+ do { \
+ if (dy1 < 0) { \
+ x0 += dx1; y0 += dy1; \
+ dx1 = -dx1; dy1 = -dy1; \
+ } \
+ if (dy2 < 0) { \
+ x0 += dx2; y0 += dy2; \
+ dx2 = -dx2; dy2 = -dy2; \
+ } \
+ /* Sort delta vectors so dxy1 is left of dxy2. */ \
+ if (dx1 * dy2 > dx2 * dy1) { \
+ double v; \
+ v = dx1; dx1 = dx2; dx2 = v; \
+ v = dy1; dy1 = dy2; dy2 = v; \
+ OTHER_SWAP_CODE \
+ } \
+ } while(0)
+
+#endif /* ParallelogramUtils_h_Included */
--- a/jdk/src/share/native/sun/java2d/pipe/BufferedMaskBlit.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/java2d/pipe/BufferedMaskBlit.c Wed Jan 19 19:00:30 2011 -0800
@@ -119,7 +119,8 @@
PtrCoord(srcInfo.rasBase,
srcInfo.bounds.x1, srcInfo.pixelStride,
srcInfo.bounds.y1, srcInfo.scanStride);
- unsigned char *pMask =
+ unsigned char *pMask, *pMaskAlloc;
+ pMask = pMaskAlloc =
(*env)->GetPrimitiveArrayCritical(env, maskArray, 0);
if (pMask == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
@@ -274,7 +275,7 @@
bpos += width * height * sizeof(jint);
(*env)->ReleasePrimitiveArrayCritical(env, maskArray,
- pMask, JNI_ABORT);
+ pMaskAlloc, JNI_ABORT);
}
SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
}
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c Wed Jan 19 19:00:30 2011 -0800
@@ -137,41 +137,43 @@
file = fopen(ALSA_VERSION_PROC_FILE, "r");
ALSAVersionString[0] = 0;
if (file) {
- fgets(ALSAVersionString, ALSAVersionString_LENGTH, file);
- // parse for version number
- totalLen = strlen(ALSAVersionString);
- inVersionString = FALSE;
- len = 0;
- curr = 0;
- while (curr < totalLen) {
- if (!inVersionString) {
- // is this char the beginning of a version string ?
- if (ALSAVersionString[curr] >= '0'
- && ALSAVersionString[curr] <= '9') {
- inVersionString = TRUE;
+ if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
+ // parse for version number
+ totalLen = strlen(ALSAVersionString);
+ inVersionString = FALSE;
+ len = 0;
+ curr = 0;
+ while (curr < totalLen) {
+ if (!inVersionString) {
+ // is this char the beginning of a version string ?
+ if (ALSAVersionString[curr] >= '0'
+ && ALSAVersionString[curr] <= '9') {
+ inVersionString = TRUE;
+ }
}
+ if (inVersionString) {
+ // the version string ends with white space
+ if (ALSAVersionString[curr] <= 32) {
+ break;
+ }
+ if (curr != len) {
+ // copy this char to the beginning of the string
+ ALSAVersionString[len] = ALSAVersionString[curr];
+ }
+ len++;
+ }
+ curr++;
}
- if (inVersionString) {
- // the version string ends with white space
- if (ALSAVersionString[curr] <= 32) {
- break;
- }
- if (curr != len) {
- // copy this char to the beginning of the string
- ALSAVersionString[len] = ALSAVersionString[curr];
- }
- len++;
+ // remove trailing dots
+ while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
+ len--;
}
- curr++;
+ // null terminate
+ ALSAVersionString[len] = 0;
}
- // remove trailing dots
- while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
- len--;
- }
- // null terminate
- ALSAVersionString[len] = 0;
+ fclose(file);
+ hasGottenALSAVersion = TRUE;
}
- hasGottenALSAVersion = TRUE;
}
strncpy(buffer, ALSAVersionString, len);
}
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c Wed Jan 19 19:00:30 2011 -0800
@@ -32,6 +32,9 @@
#include <alsa/asoundlib.h>
#include "PlatformMidi.h"
#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+#if defined(i586)
+#include <sys/utsname.h>
+#endif
/*
* Helper methods
@@ -73,9 +76,38 @@
return (char*) getErrorStr(err);
}
+INT32 MIDI_IN_GetNumDevices() {
+/* Workaround for 6842956: 32bit app on 64bit linux
+ * gets assertion failure trying to open midiIn ports.
+ * Untill the issue is fixed in ALSA
+ * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
+ * report no midi in devices in the configuration.
+ */
+#if defined(i586)
+ static int jre32onlinux64 = -1;
+ if (jre32onlinux64 < 0) {
+ jre32onlinux64 = 0;
+ /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
+ * environment variable.
+ */
+ if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
+ struct utsname u;
+ jre32onlinux64 = 0;
+ if (uname(&u) == 0) {
+ if (strstr(u.machine, "64") != NULL) {
+ TRACE0("jre32 on linux64 detected - report no midiIn devices\n");
+ jre32onlinux64 = 1;
+ }
+ }
+ }
+ }
+ if (jre32onlinux64) {
+ return 0;
+ }
+#endif
-INT32 MIDI_IN_GetNumDevices() {
TRACE0("MIDI_IN_GetNumDevices()\n");
+
return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
}
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -372,7 +372,7 @@
snd_rawmidi_t* native_handle;
snd_midi_event_t* event_parser = NULL;
int err;
- UINT32 deviceID;
+ UINT32 deviceID = 0;
char devicename[100];
#ifdef ALSA_MIDI_USE_PLUGHW
int usePlugHw = 1;
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -127,7 +127,7 @@
int ret;
int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
int origSampleSizeInBytes, origSignificantBits;
- int channels, minChannels, maxChannels;
+ unsigned int channels, minChannels, maxChannels;
int rate, bitIndex;
for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
@@ -152,7 +152,6 @@
}
}
snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
if (ret == 0) {
ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
if (ret != 0) {
@@ -165,13 +164,6 @@
ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
}
}
-#else
- minChannels = snd_pcm_hw_params_get_channels_min(hwParams);
- maxChannels = snd_pcm_hw_params_get_channels_max(hwParams);
- if (minChannels > maxChannels) {
- ERROR2("MinChannels=%d, maxChannels=%d\n", minChannels, maxChannels);
- }
-#endif
// since we queried the hw: device, for many soundcards, it will only
// report the maximum number of channels (which is the only way to talk
@@ -222,7 +214,7 @@
} else {
for (channels = minChannels; channels <= maxChannels; channels++) {
DAUDIO_AddAudioFormat(creator, significantBits,
- (channels < 0)?-1:(sampleSizeInBytes * channels),
+ sampleSizeInBytes * channels,
channels, rate,
enc, isSigned, isBigEndian);
}
@@ -254,7 +246,7 @@
snd_pcm_sw_params_t* swParams;
int bufferSizeInBytes;
int frameSize; // storage size in Bytes
- int periods;
+ unsigned int periods;
snd_pcm_uframes_t periodSize;
#ifdef GET_POSITION_METHOD2
// to be used exclusively by getBytePosition!
@@ -305,8 +297,8 @@
int channels,
int bufferSizeInFrames,
snd_pcm_format_t format) {
- unsigned int rrate;
- int ret, dir, periods, periodTime;
+ unsigned int rrate, periodTime, periods;
+ int ret, dir;
snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
/* choose all parameters */
@@ -335,12 +327,8 @@
}
/* set the stream rate */
rrate = (int) (sampleRate + 0.5f);
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
dir = 0;
ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
-#else
- ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, rrate, 0);
-#endif
if (ret < 0) {
ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
return FALSE;
@@ -350,12 +338,7 @@
return FALSE;
}
/* set the buffer time */
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
-
ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
-#else
- ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, alsaBufferSizeInFrames);
-#endif
if (ret < 0) {
ERROR2("Unable to set buffer size to %d frames: %s\n",
(int) alsaBufferSizeInFrames, snd_strerror(ret));
@@ -366,12 +349,7 @@
if (bufferSizeInFrames > 1024) {
dir = 0;
periodTime = DEFAULT_PERIOD_TIME;
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
-#else
- periodTime = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, periodTime, &dir);
- ret = periodTime;
-#endif
if (ret < 0) {
ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
return FALSE;
@@ -380,12 +358,7 @@
/* set the period count for very small buffer sizes to 2 */
dir = 0;
periods = 2;
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
-#else
- periods = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, periods, &dir);
- ret = periods;
-#endif
if (ret < 0) {
ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
return FALSE;
@@ -421,12 +394,6 @@
ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
return FALSE;
}
- /* align all transfers to 1 sample */
- ret = snd_pcm_sw_params_set_xfer_align(info->handle, info->swParams, 1);
- if (ret < 0) {
- ERROR1("Unable to set transfer align: %s\n", snd_strerror(ret));
- return FALSE;
- }
/* write the parameters to the playback device */
ret = snd_pcm_sw_params(info->handle, info->swParams);
if (ret < 0) {
@@ -448,7 +415,6 @@
int ret = 0;
AlsaPcmInfo* info = NULL;
/* snd_pcm_uframes_t is 64 bit on 64-bit systems */
- snd_pcm_uframes_t alsaPeriodSize = 0;
snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
@@ -484,21 +450,13 @@
bufferSizeInBytes / frameSize,
format)) {
info->frameSize = frameSize;
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
- ret = snd_pcm_hw_params_get_period_size(info->hwParams, &alsaPeriodSize, &dir);
- info->periodSize = (int) alsaPeriodSize;
+ ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
if (ret < 0) {
ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
}
snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
-#else
- info->periodSize = snd_pcm_hw_params_get_period_size(info->hwParams, &dir);
- info->periods = snd_pcm_hw_params_get_periods(info->hwParams, &dir);
- info->bufferSizeInBytes = snd_pcm_hw_params_get_buffer_size(info->hwParams) * frameSize;
- ret = 0;
-#endif
TRACE3(" DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
(int) info->periodSize, info->periods, info->bufferSizeInBytes);
}
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
*/
// define this with a later version of ALSA than 0.9.0rc3
+// (starting from 1.0.0 it became default behaviour)
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
#include "Utilities.h"
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_Ports.c Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -380,7 +380,7 @@
void* controls[10];
int numControls;
char* portName;
- int isPlayback;
+ int isPlayback = 0;
int isMono;
int isStereo;
char* type;
--- a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Wed Jan 19 19:00:30 2011 -0800
@@ -191,7 +191,7 @@
fp_gdk_threads_enter();
- const char *title = (*env)->GetStringUTFChars(env, jtitle, 0);
+ const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
if (mode == 1) {
/* Save action */
@@ -212,7 +212,9 @@
}
}
- (*env)->ReleaseStringUTFChars(env, jtitle, title);
+ if (jtitle != NULL) {
+ (*env)->ReleaseStringUTFChars(env, jtitle, title);
+ }
/* Set the directory */
if (jdir != NULL) {
--- a/jdk/src/solaris/native/sun/java2d/loops/vis_IntArgbPre_Mask.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/sun/java2d/loops/vis_IntArgbPre_Mask.c Wed Jan 19 19:00:30 2011 -0800
@@ -517,13 +517,15 @@
ADD_SUFF(AnyIntSetRect)(pRasInfo, 0, 0, width, height,
fgColor, pPrim, pCompInfo);
#else
+ void *pBase = pRasInfo->rasBase;
+ pRasInfo->rasBase = rasBase;
if (cnstA != 0xff) {
fgColor = (cnstA << 24) | (cnstR << 16) | (cnstG << 8) | cnstB;
}
ADD_SUFF(AnyIntSetRect)(pRasInfo,
- pRasInfo->bounds.x1, pRasInfo->bounds.y1,
- pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+ 0, 0, width, height,
fgColor, pPrim, pCompInfo);
+ pRasInfo->rasBase = pBase;
#endif
return;
}
@@ -582,11 +584,13 @@
}
if (pMask == NULL) {
+ void *pBase = pRasInfo->rasBase;
+ pRasInfo->rasBase = rasBase;
fgColor = (cnstR << 24) | (cnstG << 16) | (cnstB << 8) | cnstA;
ADD_SUFF(Any4ByteSetRect)(pRasInfo,
- pRasInfo->bounds.x1, pRasInfo->bounds.y1,
- pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+ 0, 0, width, height,
fgColor, pPrim, pCompInfo);
+ pRasInfo->rasBase = pBase;
return;
}
--- a/jdk/src/solaris/native/sun/java2d/loops/vis_SrcMaskFill.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/sun/java2d/loops/vis_SrcMaskFill.c Wed Jan 19 19:00:30 2011 -0800
@@ -150,10 +150,12 @@
}
if (pMask == NULL) {
+ void *pBase = pRasInfo->rasBase;
+ pRasInfo->rasBase = rasBase;
ADD_SUFF(AnyIntSetRect)(pRasInfo,
- pRasInfo->bounds.x1, pRasInfo->bounds.y1,
- pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+ 0, 0, width, height,
fgColor, pPrim, pCompInfo);
+ pRasInfo->rasBase = pBase;
return;
}
@@ -214,15 +216,17 @@
cnstB = (fgColor ) & 0xff;
if (pMask == NULL) {
+ void *pBase = pRasInfo->rasBase;
+ pRasInfo->rasBase = rasBase;
if (cnstA == 0) {
fgColor = 0;
} else {
fgColor = (fgColor << 8) | cnstA;
}
ADD_SUFF(Any4ByteSetRect)(pRasInfo,
- pRasInfo->bounds.x1, pRasInfo->bounds.y1,
- pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+ 0, 0, width, height,
fgColor, pPrim, pCompInfo);
+ pRasInfo->rasBase = pBase;
return;
}
@@ -390,10 +394,12 @@
if (cnstA == 0) fgColor = 0;
if (pMask == NULL) {
+ void *pBase = pRasInfo->rasBase;
+ pRasInfo->rasBase = rasBase;
ADD_SUFF(AnyIntSetRect)(pRasInfo,
- pRasInfo->bounds.x1, pRasInfo->bounds.y1,
- pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+ 0, 0, width, height,
fgColor, pPrim, pCompInfo);
+ pRasInfo->rasBase = pBase;
return;
}
@@ -458,10 +464,12 @@
}
if (pMask == NULL) {
+ void *pBase = pRasInfo->rasBase;
+ pRasInfo->rasBase = rasBase;
ADD_SUFF(AnyIntSetRect)(pRasInfo,
- pRasInfo->bounds.x1, pRasInfo->bounds.y1,
- pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+ 0, 0, width, height,
fgColor, pPrim, pCompInfo);
+ pRasInfo->rasBase = pBase;
return;
}
@@ -526,10 +534,12 @@
}
if (pMask == NULL) {
+ void *pBase = pRasInfo->rasBase;
+ pRasInfo->rasBase = rasBase;
ADD_SUFF(Any3ByteSetRect)(pRasInfo,
- pRasInfo->bounds.x1, pRasInfo->bounds.y1,
- pRasInfo->bounds.x2, pRasInfo->bounds.y2,
+ 0, 0, width, height,
fgColor, pPrim, pCompInfo);
+ pRasInfo->rasBase = pBase;
return;
}
--- a/jdk/src/solaris/native/sun/xawt/XToolkit.c Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/sun/xawt/XToolkit.c Wed Jan 19 19:00:30 2011 -0800
@@ -187,7 +187,9 @@
"()Ljava/awt/Point;");
keyclass = (*env)->FindClass(env, "java/awt/event/KeyEvent");
- DASSERT (keyclass != NULL);
+ if (JNU_IsNull(env, keyclass)) {
+ return;
+ }
componentIDs.isProxyActive =
(*env)->GetFieldID(env, keyclass, "isProxyActive",
@@ -715,8 +717,10 @@
if (xawt_root_shell == None){
if (classXRootWindow == NULL){
jclass cls_tmp = (*env)->FindClass(env, "sun/awt/X11/XRootWindow");
- classXRootWindow = (jclass)(*env)->NewGlobalRef(env, cls_tmp);
- (*env)->DeleteLocalRef(env, cls_tmp);
+ if (!JNU_IsNull(env, cls_tmp)) {
+ classXRootWindow = (jclass)(*env)->NewGlobalRef(env, cls_tmp);
+ (*env)->DeleteLocalRef(env, cls_tmp);
+ }
}
if( classXRootWindow != NULL) {
methodGetXRootWindow = (*env)->GetStaticMethodID(env, classXRootWindow, "getXRootWindow", "()J");
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Wed Jan 19 19:00:30 2011 -0800
@@ -999,6 +999,8 @@
public void setBoundsOperation(int operation) {
}
+ private volatile boolean isAccelCapable = true;
+
/**
* Returns whether this component is capable of being hw accelerated.
* More specifically, whether rendering to this component or a
@@ -1009,11 +1011,22 @@
* {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
* PERPIXEL_TRANSLUCENT}.
*
+ * Another condition is if Xor paint mode was detected when rendering
+ * to an on-screen accelerated surface associated with this peer.
+ * in this case both on- and off-screen acceleration for this peer is
+ * disabled.
+ *
* @return {@code true} if this component is capable of being hw
* accelerated, {@code false} otherwise
* @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
*/
public boolean isAccelCapable() {
+ if (!isAccelCapable ||
+ !isContainingTopLevelAccelCapable((Component)target))
+ {
+ return false;
+ }
+
boolean isTranslucent =
SunToolkit.isContainingTopLevelTranslucent((Component)target);
// D3D/OGL and translucent windows interacted poorly in Windows XP;
@@ -1021,6 +1034,14 @@
return !isTranslucent || Win32GraphicsEnvironment.isVistaOS();
}
+ /**
+ * Disables acceleration for this peer.
+ */
+ public void disableAcceleration() {
+ isAccelCapable = false;
+ }
+
+
native void setRectangularShape(int lox, int loy, int hix, int hiy,
Region region);
--- a/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Wed Jan 19 19:00:30 2011 -0800
@@ -437,6 +437,10 @@
protected int getElem(final int x, final int y,
final SurfaceData sData)
{
+ if (sData.isSurfaceLost()) {
+ return 0;
+ }
+
int retPixel;
D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock();
@@ -456,6 +460,10 @@
protected void setElem(final int x, final int y, final int pixel,
final SurfaceData sData)
{
+ if (sData.isSurfaceLost()) {
+ return;
+ }
+
D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock();
try {
@@ -512,15 +520,32 @@
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE;
}
+ /**
+ * If acceleration should no longer be used for this surface.
+ * This implementation flags to the manager that it should no
+ * longer attempt to re-create a D3DSurface.
+ */
+ void disableAccelerationForSurface() {
+ if (offscreenImage != null) {
+ SurfaceManager sm = SurfaceManager.getManager(offscreenImage);
+ if (sm instanceof D3DVolatileSurfaceManager) {
+ setSurfaceLost(true);
+ ((D3DVolatileSurfaceManager)sm).setAccelerationEnabled(false);
+ }
+ }
+ }
+
public void validatePipe(SunGraphics2D sg2d) {
TextPipe textpipe;
boolean validated = false;
// REMIND: the D3D pipeline doesn't support XOR!, more
- // fixes will be needed below
+ // fixes will be needed below. For now we disable D3D rendering
+ // for the surface which had any XOR rendering done to.
if (sg2d.compositeState >= sg2d.COMP_XOR) {
super.validatePipe(sg2d);
sg2d.imagepipe = d3dImagePipe;
+ disableAccelerationForSurface();
return;
}
@@ -895,7 +920,25 @@
}
@Override
+ void disableAccelerationForSurface() {
+ // for on-screen surfaces we need to make sure a backup GDI surface is
+ // is used until a new one is set (which may happen during a resize). We
+ // don't want the screen update maanger to replace the surface right way
+ // because it causes repainting issues in Swing, so we invalidate it,
+ // this will prevent SUM from issuing a replaceSurfaceData call.
+ setSurfaceLost(true);
+ invalidate();
+ flush();
+ peer.disableAcceleration();
+ ScreenUpdateManager.getInstance().dropScreenSurface(this);
+ }
+
+ @Override
void restoreSurface() {
+ if (!peer.isAccelCapable()) {
+ throw new InvalidPipeException("Onscreen acceleration " +
+ "disabled for this surface");
+ }
Window fsw = graphicsDevice.getFullScreenWindow();
if (fsw != null && fsw != peer.getTarget()) {
throw new InvalidPipeException("Can't restore onscreen surface"+
--- a/jdk/src/windows/classes/sun/java2d/opengl/WGLVolatileSurfaceManager.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/classes/sun/java2d/opengl/WGLVolatileSurfaceManager.java Wed Jan 19 19:00:30 2011 -0800
@@ -133,7 +133,9 @@
@Override
protected boolean isConfigValid(GraphicsConfiguration gc) {
- return ((gc == null) || (gc == vImg.getGraphicsConfig()));
+ return ((gc == null) ||
+ ((gc instanceof WGLGraphicsConfig) &&
+ (gc == vImg.getGraphicsConfig())));
}
@Override
--- a/jdk/src/windows/lib/tzmappings Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/lib/tzmappings Wed Jan 19 19:00:30 2011 -0800
@@ -188,5 +188,6 @@
UTC-11:921,921::GMT-1100:
Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
Venezuela Standard Time:923,923::America/Caracas:
-Western Brazilian Standard Time:924,924:BR:America/Rio_Branco:
-Armenian Standard Time:925,925:AM:Asia/Yerevan:
+Magadan Standard Time:924,924::Asia/Magadan:
+Western Brazilian Standard Time:925,925:BR:America/Rio_Branco:
+Armenian Standard Time:926,926:AM:Asia/Yerevan:
--- a/jdk/src/windows/native/sun/windows/Devices.h Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/Devices.h Wed Jan 19 19:00:30 2011 -0800
@@ -54,7 +54,7 @@
InstanceAccess& operator=(const InstanceAccess&);
InstanceAccess* operator&();
};
-friend InstanceAccess;
+friend class InstanceAccess;
private:
Devices(int numElements);
--- a/jdk/src/windows/native/sun/windows/awt.h Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/awt.h Wed Jan 19 19:00:30 2011 -0800
@@ -173,7 +173,7 @@
// Platform encoding is Unicode (UTF-16), re-define JNU_ functions
// to proper JNI functions.
-#define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast<jchar*>(x), static_cast<jsize>(_tcslen(x)))
+#define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast<const jchar*>(x), static_cast<jsize>(_tcslen(x)))
#define JNU_GetStringPlatformChars(env, x, y) reinterpret_cast<LPCWSTR>(env->GetStringChars(x, y))
#define JNU_ReleaseStringPlatformChars(env, x, y) env->ReleaseStringChars(x, reinterpret_cast<const jchar*>(y))
--- a/jdk/src/windows/native/sun/windows/awt_Debug.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/awt_Debug.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -47,12 +47,21 @@
return ptr;
}
+void * operator new[](size_t size, const char * filename, int linenumber) {
+ void * ptr = DMem_AllocateBlock(size, filename, linenumber);
+ if (ptr == NULL) {
+ throw std::bad_alloc();
+ }
+
+ return ptr;
+}
+
#if _MSC_VER >= 1200
void operator delete(void *ptr, const char*, int) {
DASSERTMSG(FALSE, "This version of 'delete' should never get called!!!");
}
#endif
-void operator delete(void *ptr) {
+void operator delete(void *ptr) throw() {
DMem_FreeBlock(ptr);
}
--- a/jdk/src/windows/native/sun/windows/awt_Debug.h Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/awt_Debug.h Wed Jan 19 19:00:30 2011 -0800
@@ -48,11 +48,14 @@
};
extern void * operator new(size_t size, const char * filename, int linenumber);
+ extern void * operator new[](size_t size, const char * filename, int linenumber);
+
#if _MSC_VER >= 1200
/* VC 6.0 is more strict about enforcing matching placement new & delete */
extern void operator delete(void *ptr, const char*, int);
#endif
- extern void operator delete(void *ptr);
+
+ extern void operator delete(void *ptr) throw();
extern void DumpClipRectangle(const char * file, int line, int argc, const char * fmt, va_list arglist);
extern void DumpUpdateRectangle(const char * file, int line, int argc, const char * fmt, va_list arglist);
--- a/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -650,7 +650,7 @@
}
void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) {
- jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName));
+ jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setStringPropertyID,
key, JNU_NewStringPlatform(GetEnv(), value));
@@ -658,7 +658,7 @@
}
void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
- jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName));
+ jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setIntegerPropertyID,
key, (jint)value);
@@ -666,7 +666,7 @@
}
void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
- jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName));
+ jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setBooleanPropertyID,
key, value ? JNI_TRUE : JNI_FALSE);
@@ -674,7 +674,7 @@
}
void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) {
- jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName));
+ jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setColorPropertyID,
key, GetRValue(value), GetGValue(value),
@@ -726,7 +726,7 @@
style |= java_awt_Font_ITALIC;
}
- jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName));
+ jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setFontPropertyID,
key, fontName, style, pointSize);
@@ -744,7 +744,7 @@
jint pointSize;
jint style;
- fontName = JNU_NewStringPlatform(GetEnv(), const_cast<LPWSTR>(font.lfFaceName));
+ fontName = JNU_NewStringPlatform(GetEnv(), font.lfFaceName);
#if 0
HDC hdc;
@@ -767,7 +767,7 @@
style |= java_awt_Font_ITALIC;
}
- jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName));
+ jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setFontPropertyID,
key, fontName, style, pointSize);
@@ -776,8 +776,8 @@
}
void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventName) {
- jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName));
- jstring event = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(winEventName));
+ jstring key = JNU_NewStringPlatform(GetEnv(), propName);
+ jstring event = JNU_NewStringPlatform(GetEnv(), winEventName);
GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setSoundPropertyID,
key, event);
--- a/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Wed Jan 19 19:00:30 2011 -0800
@@ -230,7 +230,7 @@
if (::IsIconic(hWnd)) {
::ShowWindow(hWnd, SW_RESTORE);
}
- PopupAllDialogs(blocker, TRUE, ::GetForegroundWindow(), FALSE);
+ PopupBlockers(blocker, TRUE, ::GetForegroundWindow(), FALSE);
// return 1 to prevent the system from allowing the operation
return 1;
}
@@ -256,7 +256,7 @@
HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
if (::IsWindow(blocker)) {
BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd);
- PopupAllDialogs(hWnd, FALSE, ::GetForegroundWindow(), onTaskbar);
+ PopupBlockers(blocker, FALSE, ::GetForegroundWindow(), onTaskbar);
// return a nonzero value to prevent the system from passing
// the message to the target window procedure
return 1;
@@ -268,60 +268,60 @@
}
/*
- * The function goes through the heirarchy of the blocker dialogs and
- * popups all the dialogs. Note that the function starts from the top
- * blocker dialog and goes down to the dialog which is the bottom dialog.
- * Using another traversal may cause to the flickering issue as a bottom
- * dialog will cover a top dialog for some period of time.
+ * The function goes through the hierarchy of the blockers and
+ * popups all the blockers. Note that the function starts from the top
+ * blocker and goes down to the blocker which is the bottom one.
+ * Using another traversal algorithm (bottom->top) may cause to flickering
+ * as the bottom blocker will cover the top blocker for a while.
*/
-void AwtDialog::PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
+void AwtDialog::PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
{
- HWND blocker = AwtWindow::GetModalBlocker(dialog);
- BOOL isBlocked = ::IsWindow(blocker);
- if (isBlocked) {
- PopupAllDialogs(blocker, isModalHook, prevFGWindow, onTaskbar);
+ HWND nextBlocker = AwtWindow::GetModalBlocker(blocker);
+ BOOL nextBlockerExists = ::IsWindow(nextBlocker);
+ if (nextBlockerExists) {
+ PopupBlockers(nextBlocker, isModalHook, prevFGWindow, onTaskbar);
}
- PopupOneDialog(dialog, blocker, isModalHook, prevFGWindow, onTaskbar);
+ PopupBlocker(blocker, nextBlocker, isModalHook, prevFGWindow, onTaskbar);
}
/*
- * The function popups the dialog, it distinguishes non-blocked dialogs
- * and activates the dialogs (sets as foreground window). If the dialog is
- * blocked, then it changes the Z-order of the dialog.
+ * The function popups the blocker, for a non-blocked blocker we need
+ * to activate the blocker but if a blocker is blocked, then we need
+ * to change z-order of the blocker placing the blocker under the next blocker.
*/
-void AwtDialog::PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
+void AwtDialog::PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
{
- if (dialog == AwtToolkit::GetInstance().GetHWnd()) {
+ if (blocker == AwtToolkit::GetInstance().GetHWnd()) {
return;
}
// fix for 6494032
- if (isModalHook && !::IsWindowVisible(dialog)) {
- ::ShowWindow(dialog, SW_SHOWNA);
+ if (isModalHook && !::IsWindowVisible(blocker)) {
+ ::ShowWindow(blocker, SW_SHOWNA);
}
- BOOL isBlocked = ::IsWindow(blocker);
+ BOOL nextBlockerExists = ::IsWindow(nextBlocker);
UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
- if (isBlocked) {
+ if (nextBlockerExists) {
// Fix for 6829546: if blocker is a top-most window, but window isn't, then
// calling ::SetWindowPos(dialog, blocker, ...) makes window top-most as well
- BOOL isBlockerTopmost = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
- BOOL isDialogTopmost = (::GetWindowLong(dialog, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
- if (!isBlockerTopmost || isDialogTopmost) {
- ::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags);
+ BOOL topmostNextBlocker = (::GetWindowLong(nextBlocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
+ BOOL topmostBlocker = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
+ if (!topmostNextBlocker || topmostBlocker) {
+ ::SetWindowPos(blocker, nextBlocker, 0, 0, 0, 0, flags);
} else {
- ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags);
+ ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags);
}
} else {
- ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags);
+ ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags);
// no beep/flash if the mouse was clicked in the taskbar menu
// or the dialog is currently inactive
- if (!isModalHook && !onTaskbar && (dialog == prevFGWindow)) {
- AnimateModalBlocker(dialog);
+ if (!isModalHook && !onTaskbar && (blocker == prevFGWindow)) {
+ AnimateModalBlocker(blocker);
}
- ::BringWindowToTop(dialog);
- ::SetForegroundWindow(dialog);
+ ::BringWindowToTop(blocker);
+ ::SetForegroundWindow(blocker);
}
}
--- a/jdk/src/windows/native/sun/windows/awt_Dialog.h Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/awt_Dialog.h Wed Jan 19 19:00:30 2011 -0800
@@ -113,8 +113,8 @@
*/
static void ModalPerformActivation(HWND hWnd);
- static void PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
- static void PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
+ static void PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
+ static void PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
public:
--- a/jdk/src/windows/native/sun/windows/awt_TextArea.h Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/awt_TextArea.h Wed Jan 19 19:00:30 2011 -0800
@@ -41,9 +41,6 @@
class AwtTextArea : public AwtTextComponent {
- // inner classes
- class OleCallback;
-
public:
/* java.awt.TextArea fields ids */
@@ -89,6 +86,37 @@
static void _ReplaceText(void *param);
protected:
+
+ /*****************************************************************
+ * Inner class OleCallback declaration.
+ */
+ class OleCallback : public IRichEditOleCallback {
+ public:
+ OleCallback();
+
+ STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
+ STDMETHODIMP_(ULONG) AddRef();
+ STDMETHODIMP_(ULONG) Release();
+ STDMETHODIMP GetNewStorage(LPSTORAGE FAR * ppstg);
+ STDMETHODIMP GetInPlaceContext(LPOLEINPLACEFRAME FAR * ppipframe,
+ LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
+ LPOLEINPLACEFRAMEINFO pipfinfo);
+ STDMETHODIMP ShowContainerUI(BOOL fShow);
+ STDMETHODIMP QueryInsertObject(LPCLSID pclsid, LPSTORAGE pstg, LONG cp);
+ STDMETHODIMP DeleteObject(LPOLEOBJECT poleobj);
+ STDMETHODIMP QueryAcceptData(LPDATAOBJECT pdataobj, CLIPFORMAT *pcfFormat,
+ DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
+ STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
+ STDMETHODIMP GetClipboardData(CHARRANGE *pchrg, DWORD reco,
+ LPDATAOBJECT *ppdataobj);
+ STDMETHODIMP GetDragDropEffect(BOOL fDrag, DWORD grfKeyState,
+ LPDWORD pdwEffect);
+ STDMETHODIMP GetContextMenu(WORD seltype, LPOLEOBJECT poleobj,
+ CHARRANGE FAR * pchrg, HMENU FAR * phmenu);
+ private:
+ ULONG m_refs; // Reference count
+ };//OleCallback class
+
INLINE static OleCallback& GetOleCallback() { return sm_oleCallback; }
void EditSetSel(CHARRANGE &cr);
void EditGetSel(CHARRANGE &cr);
@@ -114,37 +142,6 @@
static OleCallback sm_oleCallback;
- /*****************************************************************
- * Inner class OleCallback declaration.
- */
-
- class AwtTextArea::OleCallback : public IRichEditOleCallback {
- public:
- OleCallback();
-
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
- STDMETHODIMP GetNewStorage(LPSTORAGE FAR * ppstg);
- STDMETHODIMP GetInPlaceContext(LPOLEINPLACEFRAME FAR * ppipframe,
- LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
- LPOLEINPLACEFRAMEINFO pipfinfo);
- STDMETHODIMP ShowContainerUI(BOOL fShow);
- STDMETHODIMP QueryInsertObject(LPCLSID pclsid, LPSTORAGE pstg, LONG cp);
- STDMETHODIMP DeleteObject(LPOLEOBJECT poleobj);
- STDMETHODIMP QueryAcceptData(LPDATAOBJECT pdataobj, CLIPFORMAT *pcfFormat,
- DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
- STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
- STDMETHODIMP GetClipboardData(CHARRANGE *pchrg, DWORD reco,
- LPDATAOBJECT *ppdataobj);
- STDMETHODIMP GetDragDropEffect(BOOL fDrag, DWORD grfKeyState,
- LPDWORD pdwEffect);
- STDMETHODIMP GetContextMenu(WORD seltype, LPOLEOBJECT poleobj,
- CHARRANGE FAR * pchrg, HMENU FAR * phmenu);
- private:
- ULONG m_refs; // Reference count
- };
-
};
#endif /* AWT_TEXTAREA_H */
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h Wed Jan 19 19:00:30 2011 -0800
@@ -110,7 +110,7 @@
private:
const CriticalSection& critSec;
};
- friend Lock;
+ friend class Lock;
private:
CRITICAL_SECTION rep;
--- a/jdk/test/com/sun/awt/Translucency/WindowOpacity.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/com/sun/awt/Translucency/WindowOpacity.java Wed Jan 19 19:00:30 2011 -0800
@@ -64,6 +64,7 @@
boolean passed;
Frame f = new Frame("Opacity test");
+ f.setUndecorated(true);
passed = false;
try {
--- a/jdk/test/java/awt/FontClass/FontPrivilege.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/awt/FontClass/FontPrivilege.java Wed Jan 19 19:00:30 2011 -0800
@@ -25,7 +25,7 @@
* @test
* @bug 5010310 6319835 6904882 6968373
* @summary test fonts can be created in the presence of a security manager
- * @run main/othervm/secure=java.lang.SecurityManager FontPrivilege
+ * @run main FontPrivilege
*/
import java.awt.Font;
@@ -33,6 +33,8 @@
public class FontPrivilege {
public static void main(String[] args) throws Exception {
+ System.setSecurityManager(new SecurityManager());
+
new Font("Helvetica", Font.PLAIN, 12).getFamily();
new Font("foo bar", Font.PLAIN, 12).getFamily();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics2D/DrawString/LCDTextSrcEa.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010, 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 6996867
+ * @summary Render as LCD Text in SrcEa composite mode.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+
+public class LCDTextSrcEa extends Component {
+
+ static int SZ=150;
+ BufferedImage target =
+ new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
+
+ public static void main(String args[]) {
+ Frame f = new Frame("LCD Text SrcEa Test");
+ f.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+ LCDTextSrcEa td = new LCDTextSrcEa();
+ f.add("Center", td);
+ f.pack();
+ f.setVisible(true);
+ }
+
+ public Dimension getPreferredSize() {
+ return new Dimension(SZ,SZ);
+ }
+
+ public void paint(Graphics gx) {
+
+ Graphics2D g2d = (Graphics2D) target.getGraphics();
+ g2d.setColor(Color.white);
+ g2d.fillRect(0, 0, getWidth(), getHeight());
+
+ g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.01f));
+ g2d.setRenderingHint(
+ RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR);
+ g2d.setRenderingHint(
+ RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ g2d.setColor(Color.black);
+ g2d.drawString("Some sample text.", 10, 20);
+ gx.drawImage(target, 0, 0, null);
+ boolean nongrey = false;
+ //Test BI: should be some non-greyscale color
+ for (int px=0;px<SZ;px++) {
+ for (int py=0;py<SZ;py++) {
+ int rgb = target.getRGB(px, py);
+ int r = (rgb & 0xff0000) >> 16;
+ int g = (rgb & 0x00ff00) >> 8;
+ int b = (rgb & 0x0000ff);
+ if (r != g || r !=b || g != b) {
+ nongrey=true;
+ break;
+ }
+ }
+ }
+ if (!nongrey) {
+ throw new RuntimeException("No LCD text found");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics2D/RenderClipTest/6766342.tests Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,3 @@
+Filled AA Pure Rect(5, 29.4, 10, 10)
+Stroked AA Pure Rect(5, 4.4, 10, 10)
+Stroked AA Line(20, 20, -10, 20)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics2D/RenderClipTest/RenderClipTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,1634 @@
+/*
+ * Copyright (c) 2008, 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 6766342
+ * @summary Tests clipping invariance for AA rectangle and line primitives
+ * @run main RenderClipTest -strict -readfile 6766342.tests
+ * @run main RenderClipTest -rectsuite -count 10
+ */
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.*;
+import java.awt.event.*;
+import java.util.Vector;
+import java.io.*;
+
+public class RenderClipTest {
+ public static double randDblCoord() {
+ return Math.random()*60 - 10;
+ }
+
+ public static float randFltCoord() {
+ return (float) randDblCoord();
+ }
+
+ public static int randIntCoord() {
+ return (int) Math.round(randDblCoord());
+ }
+
+ public static int randInt(int n) {
+ return ((int) (Math.random() * (n*4))) >> 2;
+ }
+
+ static int numtests;
+ static int numerrors;
+ static int numfillfailures;
+ static int numstrokefailures;
+ static int maxerr;
+
+ static boolean useAA;
+ static boolean strokePure;
+ static boolean testFill;
+ static boolean testDraw;
+ static boolean silent;
+ static boolean verbose;
+ static boolean strict;
+ static boolean showErrors;
+ static float lw;
+ static double rot;
+
+ static BufferedImage imgref;
+ static BufferedImage imgtst;
+
+ static Graphics2D grefclear;
+ static Graphics2D gtstclear;
+ static Graphics2D grefrender;
+ static Graphics2D gtstrender;
+
+ public static abstract class AnnotatedRenderOp {
+ public static AnnotatedRenderOp parse(String str) {
+ AnnotatedRenderOp ar;
+ if (((ar = Cubic.tryparse(str)) != null) ||
+ ((ar = Quad.tryparse(str)) != null) ||
+ ((ar = Poly.tryparse(str)) != null) ||
+ ((ar = Path.tryparse(str)) != null) ||
+ ((ar = Rect.tryparse(str)) != null) ||
+ ((ar = Line.tryparse(str)) != null) ||
+ ((ar = RectMethod.tryparse(str)) != null) ||
+ ((ar = LineMethod.tryparse(str)) != null))
+ {
+ return ar;
+ }
+ System.err.println("Unable to parse shape: "+str);
+ return null;
+ }
+
+ public abstract void randomize();
+
+ public abstract void fill(Graphics2D g2d);
+
+ public abstract void draw(Graphics2D g2d);
+ }
+
+ public static abstract class AnnotatedShapeOp extends AnnotatedRenderOp {
+ public abstract Shape getShape();
+
+ public void fill(Graphics2D g2d) {
+ g2d.fill(getShape());
+ }
+
+ public void draw(Graphics2D g2d) {
+ g2d.draw(getShape());
+ }
+ }
+
+ public static void usage(String err) {
+ if (err != null) {
+ System.err.println(err);
+ }
+ System.err.println("usage: java RenderClipTest "+
+ "[-read[file F]] [-rectsuite] [-fill] [-draw]");
+ System.err.println(" "+
+ "[-aa] [-pure] [-lw N] [-rot N]");
+ System.err.println(" "+
+ "[-rectmethod] [-linemethod] [-rect] [-line]");
+ System.err.println(" "+
+ "[-cubic] [-quad] [-poly] [-path]");
+ System.err.println(" "+
+ "[-silent] [-verbose] [-showerr] [-count N]");
+ System.err.println(" "+
+ "[-strict] [-usage]");
+ System.err.println(" -read Read test data from stdin");
+ System.err.println(" -readfile F Read test data from file F");
+ System.err.println(" -rectsuite Run a suite of rect/line tests");
+ System.err.println(" -fill Test g.fill*(...)");
+ System.err.println(" -draw Test g.draw*(...)");
+ System.err.println(" -aa Use antialiased rendering");
+ System.err.println(" -pure Use STROKE_PURE hint");
+ System.err.println(" -lw N Test line widths of N "+
+ "(default 1.0)");
+ System.err.println(" -rot N Test rotation by N degrees "+
+ "(default 0.0)");
+ System.err.println(" -rectmethod Test fillRect/drawRect methods");
+ System.err.println(" -linemethod Test drawLine method");
+ System.err.println(" -rect Test Rectangle2D shapes");
+ System.err.println(" -line Test Line2D shapes");
+ System.err.println(" -cubic Test CubicCurve2D shapes");
+ System.err.println(" -quad Test QuadCurve2D shapes");
+ System.err.println(" -poly Test Polygon shapes");
+ System.err.println(" -path Test GeneralPath shapes");
+ System.err.println(" -silent Do not print out error curves");
+ System.err.println(" -verbose Print out progress info");
+ System.err.println(" -showerr Display errors on screen");
+ System.err.println(" -count N N tests per shape, then exit "+
+ "(default 1000)");
+ System.err.println(" -strict All failures are important");
+ System.err.println(" -usage Print this help, then exit");
+ System.exit((err != null) ? -1 : 0);
+ }
+
+ public static void main(String argv[]) {
+ boolean readTests = false;
+ String readFile = null;
+ boolean rectsuite = false;
+ int count = 1000;
+ lw = 1.0f;
+ rot = 0.0;
+ Vector<AnnotatedRenderOp> testOps = new Vector<AnnotatedRenderOp>();
+ for (int i = 0; i < argv.length; i++) {
+ String arg = argv[i].toLowerCase();
+ if (arg.equals("-aa")) {
+ useAA = true;
+ } else if (arg.equals("-pure")) {
+ strokePure = true;
+ } else if (arg.equals("-fill")) {
+ testFill = true;
+ } else if (arg.equals("-draw")) {
+ testDraw = true;
+ } else if (arg.equals("-lw")) {
+ if (i+1 >= argv.length) {
+ usage("Missing argument: "+argv[i]);
+ }
+ lw = Float.parseFloat(argv[++i]);
+ } else if (arg.equals("-rot")) {
+ if (i+1 >= argv.length) {
+ usage("Missing argument: "+argv[i]);
+ }
+ rot = Double.parseDouble(argv[++i]);
+ } else if (arg.equals("-cubic")) {
+ testOps.add(new Cubic());
+ } else if (arg.equals("-quad")) {
+ testOps.add(new Quad());
+ } else if (arg.equals("-poly")) {
+ testOps.add(new Poly());
+ } else if (arg.equals("-path")) {
+ testOps.add(new Path());
+ } else if (arg.equals("-rect")) {
+ testOps.add(new Rect());
+ } else if (arg.equals("-line")) {
+ testOps.add(new Line());
+ } else if (arg.equals("-rectmethod")) {
+ testOps.add(new RectMethod());
+ } else if (arg.equals("-linemethod")) {
+ testOps.add(new LineMethod());
+ } else if (arg.equals("-verbose")) {
+ verbose = true;
+ } else if (arg.equals("-strict")) {
+ strict = true;
+ } else if (arg.equals("-silent")) {
+ silent = true;
+ } else if (arg.equals("-showerr")) {
+ showErrors = true;
+ } else if (arg.equals("-readfile")) {
+ if (i+1 >= argv.length) {
+ usage("Missing argument: "+argv[i]);
+ }
+ readTests = true;
+ readFile = argv[++i];
+ } else if (arg.equals("-read")) {
+ readTests = true;
+ readFile = null;
+ } else if (arg.equals("-rectsuite")) {
+ rectsuite = true;
+ } else if (arg.equals("-count")) {
+ if (i+1 >= argv.length) {
+ usage("Missing argument: "+argv[i]);
+ }
+ count = Integer.parseInt(argv[++i]);
+ } else if (arg.equals("-usage")) {
+ usage(null);
+ } else {
+ usage("Unknown argument: "+argv[i]);
+ }
+ }
+ if (readTests) {
+ if (rectsuite || testDraw || testFill ||
+ useAA || strokePure ||
+ lw != 1.0f || rot != 0.0 ||
+ testOps.size() > 0)
+ {
+ usage("Should not specify test types with -read options");
+ }
+ } else if (rectsuite) {
+ if (testDraw || testFill ||
+ useAA || strokePure ||
+ lw != 1.0f || rot != 0.0 ||
+ testOps.size() > 0)
+ {
+ usage("Should not specify test types with -rectsuite option");
+ }
+ } else {
+ if (!testDraw && !testFill) {
+ usage("No work: Must specify one or both of "+
+ "-fill or -draw");
+ }
+ if (testOps.size() == 0) {
+ usage("No work: Must specify one or more of "+
+ "-rect[method], -line[method], "+
+ "-cubic, -quad, -poly, or -path");
+ }
+ }
+ initImages();
+ if (readTests) {
+ try {
+ InputStream is;
+ if (readFile == null) {
+ is = System.in;
+ } else {
+ File f =
+ new File(System.getProperty("test.src", "."),
+ readFile);
+ is = new FileInputStream(f);
+ }
+ parseAndRun(is);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (rectsuite) {
+ runRectSuite(count);
+ } else {
+ initGCs();
+ for (int k = 0; k < testOps.size(); k++) {
+ AnnotatedRenderOp ar = testOps.get(k);
+ runRandomTests(ar, count);
+ }
+ disposeGCs();
+ }
+ grefclear.dispose();
+ gtstclear.dispose();
+ grefclear = gtstclear = null;
+ reportStatistics();
+ }
+
+ public static int reportStatistics() {
+ String connector = "";
+ if (numfillfailures > 0) {
+ System.out.print(numfillfailures+" fills ");
+ connector = "and ";
+ }
+ if (numstrokefailures > 0) {
+ System.out.print(connector+numstrokefailures+" strokes ");
+ }
+ int totalfailures = numfillfailures + numstrokefailures;
+ if (totalfailures == 0) {
+ System.out.print("0 ");
+ }
+ System.out.println("out of "+numtests+" tests failed...");
+ int critical = numerrors;
+ if (strict) {
+ critical += totalfailures;
+ }
+ if (critical > 0) {
+ throw new RuntimeException(critical+" tests had critical errors");
+ }
+ System.out.println("No tests had critical errors");
+ return (numerrors+totalfailures);
+ }
+
+ public static void runRectSuite(int count) {
+ AnnotatedRenderOp ops[] = {
+ new Rect(),
+ new RectMethod(),
+ new Line(),
+ new LineMethod(),
+ };
+ // Sometimes different fill algorithms are chosen for
+ // thin and wide line modes, make sure we test both...
+ float filllinewidths[] = { 0.0f, 2.0f };
+ float drawlinewidths[] = { 0.0f, 0.5f, 1.0f,
+ 2.0f, 2.5f,
+ 5.0f, 5.3f };
+ double rotations[] = { 0.0, 15.0, 90.0,
+ 135.0, 180.0,
+ 200.0, 270.0,
+ 300.0};
+ for (AnnotatedRenderOp ar: ops) {
+ for (double r: rotations) {
+ rot = r;
+ for (int i = 0; i < 8; i++) {
+ float linewidths[];
+ if ((i & 1) == 0) {
+ if ((ar instanceof Line) ||
+ (ar instanceof LineMethod))
+ {
+ continue;
+ }
+ testFill = true;
+ testDraw = false;
+ linewidths = filllinewidths;
+ } else {
+ testFill = false;
+ testDraw = true;
+ linewidths = drawlinewidths;
+ }
+ useAA = ((i & 2) != 0);
+ strokePure = ((i & 4) != 0);
+ for (float w : linewidths) {
+ lw = w;
+ runSuiteTests(ar, count);
+ }
+ }
+ }
+ }
+ }
+
+ public static void runSuiteTests(AnnotatedRenderOp ar, int count) {
+ if (verbose) {
+ System.out.print("Running ");
+ System.out.print(testFill ? "Fill " : "Draw ");
+ System.out.print(BaseName(ar));
+ if (useAA) {
+ System.out.print(" AA");
+ }
+ if (strokePure) {
+ System.out.print(" Pure");
+ }
+ if (lw != 1.0f) {
+ System.out.print(" lw="+lw);
+ }
+ if (rot != 0.0f) {
+ System.out.print(" rot="+rot);
+ }
+ System.out.println();
+ }
+ initGCs();
+ runRandomTests(ar, count);
+ disposeGCs();
+ }
+
+ public static String BaseName(AnnotatedRenderOp ar) {
+ String s = ar.toString();
+ int leftparen = s.indexOf('(');
+ if (leftparen >= 0) {
+ s = s.substring(0, leftparen);
+ }
+ return s;
+ }
+
+ public static void runRandomTests(AnnotatedRenderOp ar, int count) {
+ for (int i = 0; i < count; i++) {
+ ar.randomize();
+ if (testDraw) {
+ test(ar, false);
+ }
+ if (testFill) {
+ test(ar, true);
+ }
+ }
+ }
+
+ public static void initImages() {
+ imgref = new BufferedImage(40, 40, BufferedImage.TYPE_INT_RGB);
+ imgtst = new BufferedImage(40, 40, BufferedImage.TYPE_INT_RGB);
+ grefclear = imgref.createGraphics();
+ gtstclear = imgtst.createGraphics();
+ grefclear.setColor(Color.white);
+ gtstclear.setColor(Color.white);
+ }
+
+ public static void initGCs() {
+ grefrender = imgref.createGraphics();
+ gtstrender = imgtst.createGraphics();
+ gtstrender.clipRect(10, 10, 20, 20);
+ grefrender.setColor(Color.blue);
+ gtstrender.setColor(Color.blue);
+ if (lw != 1.0f) {
+ BasicStroke bs = new BasicStroke(lw);
+ grefrender.setStroke(bs);
+ gtstrender.setStroke(bs);
+ }
+ if (rot != 0.0) {
+ double rotrad = Math.toRadians(rot);
+ grefrender.rotate(rotrad, 20, 20);
+ gtstrender.rotate(rotrad, 20, 20);
+ }
+ if (strokePure) {
+ grefrender.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+ RenderingHints.VALUE_STROKE_PURE);
+ gtstrender.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+ RenderingHints.VALUE_STROKE_PURE);
+ }
+ if (useAA) {
+ grefrender.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ gtstrender.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ maxerr = 1;
+ }
+ }
+
+ public static void disposeGCs() {
+ grefrender.dispose();
+ gtstrender.dispose();
+ grefrender = gtstrender = null;
+ }
+
+ public static void parseAndRun(InputStream in) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ String str;
+ while ((str = br.readLine()) != null) {
+ if (str.startsWith("Stroked ") || str.startsWith("Filled ")) {
+ parseTest(str);
+ continue;
+ }
+ if (str.startsWith("Running ")) {
+ continue;
+ }
+ if (str.startsWith("Failed: ")) {
+ continue;
+ }
+ if (str.indexOf(" out of ") > 0 &&
+ str.indexOf(" tests failed...") > 0)
+ {
+ continue;
+ }
+ if (str.indexOf(" tests had critical errors") > 0) {
+ continue;
+ }
+ System.err.println("Unparseable line: "+str);
+ }
+ }
+
+ public static void parseTest(String origstr) {
+ String str = origstr;
+ boolean isfill = false;
+ useAA = strokePure = false;
+ lw = 1.0f;
+ rot = 0.0;
+ if (str.startsWith("Stroked ")) {
+ str = str.substring(8);
+ isfill = false;
+ } else if (str.startsWith("Filled ")) {
+ str = str.substring(7);
+ isfill = true;
+ } else {
+ System.err.println("Unparseable test line: "+origstr);
+ }
+ if (str.startsWith("AA ")) {
+ str = str.substring(3);
+ useAA = true;
+ }
+ if (str.startsWith("Pure ")) {
+ str = str.substring(5);
+ strokePure = true;
+ }
+ if (str.startsWith("Lw=")) {
+ int index = str.indexOf(' ', 3);
+ if (index > 0) {
+ lw = Float.parseFloat(str.substring(3, index));
+ str = str.substring(index+1);
+ }
+ }
+ if (str.startsWith("Rot=")) {
+ int index = str.indexOf(' ', 4);
+ if (index > 0) {
+ rot = Double.parseDouble(str.substring(4, index));
+ str = str.substring(index+1);
+ }
+ }
+ AnnotatedRenderOp ar = AnnotatedRenderOp.parse(str);
+ if (ar != null) {
+ initGCs();
+ test(ar, isfill);
+ disposeGCs();
+ } else {
+ System.err.println("Unparseable test line: "+origstr);
+ }
+ }
+
+ public static void test(AnnotatedRenderOp ar, boolean isfill) {
+ grefclear.fillRect(0, 0, 40, 40);
+ gtstclear.fillRect(0, 0, 40, 40);
+ if (isfill) {
+ ar.fill(grefrender);
+ ar.fill(gtstrender);
+ } else {
+ ar.draw(grefrender);
+ ar.draw(gtstrender);
+ }
+ check(imgref, imgtst, ar, isfill);
+ }
+
+ public static int[] getData(BufferedImage img) {
+ Raster r = img.getRaster();
+ DataBufferInt dbi = (DataBufferInt) r.getDataBuffer();
+ return dbi.getData();
+ }
+
+ public static int getScan(BufferedImage img) {
+ Raster r = img.getRaster();
+ SinglePixelPackedSampleModel sppsm =
+ (SinglePixelPackedSampleModel) r.getSampleModel();
+ return sppsm.getScanlineStride();
+ }
+
+ public static int getOffset(BufferedImage img) {
+ Raster r = img.getRaster();
+ SinglePixelPackedSampleModel sppsm =
+ (SinglePixelPackedSampleModel) r.getSampleModel();
+ return sppsm.getOffset(-r.getSampleModelTranslateX(),
+ -r.getSampleModelTranslateY());
+ }
+
+ final static int opaque = 0xff000000;
+ final static int whitergb = Color.white.getRGB();
+
+ public static final int maxdiff(int rgb1, int rgb2) {
+ int maxd = 0;
+ for (int i = 0; i < 32; i += 8) {
+ int c1 = (rgb1 >> i) & 0xff;
+ int c2 = (rgb2 >> i) & 0xff;
+ int d = Math.abs(c1-c2);
+ if (maxd < d) {
+ maxd = d;
+ }
+ }
+ return maxd;
+ }
+
+ public static void check(BufferedImage imgref, BufferedImage imgtst,
+ AnnotatedRenderOp ar, boolean wasfill)
+ {
+ numtests++;
+ int dataref[] = getData(imgref);
+ int datatst[] = getData(imgtst);
+ int scanref = getScan(imgref);
+ int scantst = getScan(imgtst);
+ int offref = getOffset(imgref);
+ int offtst = getOffset(imgtst);
+
+ // We want to check for errors outside the clip at a higher
+ // priority than errors involving different pixels touched
+ // inside the clip.
+
+ // Check above clip
+ if (check(ar, wasfill,
+ null, 0, 0,
+ datatst, scantst, offtst,
+ 0, 0, 40, 10))
+ {
+ return;
+ }
+ // Check below clip
+ if (check(ar, wasfill,
+ null, 0, 0,
+ datatst, scantst, offtst,
+ 0, 30, 40, 40))
+ {
+ return;
+ }
+ // Check left of clip
+ if (check(ar, wasfill,
+ null, 0, 0,
+ datatst, scantst, offtst,
+ 0, 10, 10, 30))
+ {
+ return;
+ }
+ // Check right of clip
+ if (check(ar, wasfill,
+ null, 0, 0,
+ datatst, scantst, offtst,
+ 30, 10, 40, 30))
+ {
+ return;
+ }
+ // Check inside clip
+ check(ar, wasfill,
+ dataref, scanref, offref,
+ datatst, scantst, offtst,
+ 10, 10, 30, 30);
+ }
+
+ public static boolean check(AnnotatedRenderOp ar, boolean wasfill,
+ int dataref[], int scanref, int offref,
+ int datatst[], int scantst, int offtst,
+ int x0, int y0, int x1, int y1)
+ {
+ offref += scanref * y0;
+ offtst += scantst * y0;
+ for (int y = y0; y < y1; y++) {
+ for (int x = x0; x < x1; x++) {
+ boolean failed;
+ String reason;
+ int rgbref;
+ int rgbtst;
+
+ rgbtst = datatst[offtst+x] | opaque;
+ if (dataref == null) {
+ /* Outside of clip, must be white, no error tolerance */
+ rgbref = whitergb;
+ failed = (rgbtst != rgbref);
+ reason = "stray pixel rendered outside of clip";
+ } else {
+ /* Inside of clip, check for maxerr delta in components */
+ rgbref = dataref[offref+x] | opaque;
+ failed = (rgbref != rgbtst &&
+ maxdiff(rgbref, rgbtst) > maxerr);
+ reason = "different pixel rendered inside clip";
+ }
+ if (failed) {
+ if (dataref == null) {
+ numerrors++;
+ }
+ if (wasfill) {
+ numfillfailures++;
+ } else {
+ numstrokefailures++;
+ }
+ if (!silent) {
+ System.out.println("Failed: "+reason+" at "+x+", "+y+
+ " ["+Integer.toHexString(rgbref)+
+ " != "+Integer.toHexString(rgbtst)+
+ "]");
+ System.out.print(wasfill ? "Filled " : "Stroked ");
+ if (useAA) System.out.print("AA ");
+ if (strokePure) System.out.print("Pure ");
+ if (lw != 1) System.out.print("Lw="+lw+" ");
+ if (rot != 0) System.out.print("Rot="+rot+" ");
+ System.out.println(ar);
+ }
+ if (showErrors) {
+ show(imgref, imgtst);
+ }
+ return true;
+ }
+ }
+ offref += scanref;
+ offtst += scantst;
+ }
+ return false;
+ }
+
+ static ErrorWindow errw;
+
+ public static void show(BufferedImage imgref, BufferedImage imgtst) {
+ ErrorWindow errw = new ErrorWindow();
+ errw.setImages(imgref, imgtst);
+ errw.setVisible(true);
+ errw.waitForHide();
+ errw.dispose();
+ }
+
+ public static class Cubic extends AnnotatedShapeOp {
+ public static Cubic tryparse(String str) {
+ str = str.trim();
+ if (!str.startsWith("Cubic(")) {
+ return null;
+ }
+ str = str.substring(6);
+ double coords[] = new double[8];
+ boolean foundparen = false;
+ for (int i = 0; i < coords.length; i++) {
+ int index = str.indexOf(",");
+ if (index < 0) {
+ if (i < coords.length-1) {
+ return null;
+ }
+ index = str.indexOf(")");
+ if (index < 0) {
+ return null;
+ }
+ foundparen = true;
+ }
+ String num = str.substring(0, index);
+ try {
+ coords[i] = Double.parseDouble(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1);
+ }
+ if (!foundparen || str.length() > 0) {
+ return null;
+ }
+ Cubic c = new Cubic();
+ c.cubic.setCurve(coords[0], coords[1],
+ coords[2], coords[3],
+ coords[4], coords[5],
+ coords[6], coords[7]);
+ return c;
+ }
+
+ private CubicCurve2D cubic = new CubicCurve2D.Double();
+
+ public void randomize() {
+ cubic.setCurve(randDblCoord(), randDblCoord(),
+ randDblCoord(), randDblCoord(),
+ randDblCoord(), randDblCoord(),
+ randDblCoord(), randDblCoord());
+ }
+
+ public Shape getShape() {
+ return cubic;
+ }
+
+ public String toString() {
+ return ("Cubic("+
+ cubic.getX1()+", "+
+ cubic.getY1()+", "+
+ cubic.getCtrlX1()+", "+
+ cubic.getCtrlY1()+", "+
+ cubic.getCtrlX2()+", "+
+ cubic.getCtrlY2()+", "+
+ cubic.getX2()+", "+
+ cubic.getY2()
+ +")");
+ }
+ }
+
+ public static class Quad extends AnnotatedShapeOp {
+ public static Quad tryparse(String str) {
+ str = str.trim();
+ if (!str.startsWith("Quad(")) {
+ return null;
+ }
+ str = str.substring(5);
+ double coords[] = new double[6];
+ boolean foundparen = false;
+ for (int i = 0; i < coords.length; i++) {
+ int index = str.indexOf(",");
+ if (index < 0) {
+ if (i < coords.length-1) {
+ return null;
+ }
+ index = str.indexOf(")");
+ if (index < 0) {
+ return null;
+ }
+ foundparen = true;
+ }
+ String num = str.substring(0, index);
+ try {
+ coords[i] = Double.parseDouble(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1);
+ }
+ if (!foundparen || str.length() > 0) {
+ return null;
+ }
+ Quad c = new Quad();
+ c.quad.setCurve(coords[0], coords[1],
+ coords[2], coords[3],
+ coords[4], coords[5]);
+ return c;
+ }
+
+ private QuadCurve2D quad = new QuadCurve2D.Double();
+
+ public void randomize() {
+ quad.setCurve(randDblCoord(), randDblCoord(),
+ randDblCoord(), randDblCoord(),
+ randDblCoord(), randDblCoord());
+ }
+
+ public Shape getShape() {
+ return quad;
+ }
+
+ public String toString() {
+ return ("Quad("+
+ quad.getX1()+", "+
+ quad.getY1()+", "+
+ quad.getCtrlX()+", "+
+ quad.getCtrlY()+", "+
+ quad.getX2()+", "+
+ quad.getY2()
+ +")");
+ }
+ }
+
+ public static class Poly extends AnnotatedShapeOp {
+ public static Poly tryparse(String str) {
+ str = str.trim();
+ if (!str.startsWith("Poly(")) {
+ return null;
+ }
+ str = str.substring(5);
+ Polygon p = new Polygon();
+ while (true) {
+ int x, y;
+ str = str.trim();
+ if (str.startsWith(")")) {
+ str = str.substring(1);
+ break;
+ }
+ if (p.npoints > 0) {
+ if (str.startsWith(",")) {
+ str = str.substring(2).trim();
+ } else {
+ return null;
+ }
+ }
+ if (str.startsWith("[")) {
+ str = str.substring(1);
+ } else {
+ return null;
+ }
+ int index = str.indexOf(",");
+ if (index < 0) {
+ return null;
+ }
+ String num = str.substring(0, index);
+ try {
+ x = Integer.parseInt(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1);
+ index = str.indexOf("]");
+ if (index < 0) {
+ return null;
+ }
+ num = str.substring(0, index).trim();
+ try {
+ y = Integer.parseInt(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1);
+ p.addPoint(x, y);
+ }
+ if (str.length() > 0) {
+ return null;
+ }
+ if (p.npoints < 3) {
+ return null;
+ }
+ return new Poly(p);
+ }
+
+ private Polygon poly;
+
+ public Poly() {
+ this.poly = new Polygon();
+ }
+
+ private Poly(Polygon p) {
+ this.poly = p;
+ }
+
+ public void randomize() {
+ poly.reset();
+ poly.addPoint(randIntCoord(), randIntCoord());
+ poly.addPoint(randIntCoord(), randIntCoord());
+ poly.addPoint(randIntCoord(), randIntCoord());
+ poly.addPoint(randIntCoord(), randIntCoord());
+ poly.addPoint(randIntCoord(), randIntCoord());
+ }
+
+ public Shape getShape() {
+ return poly;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer(100);
+ sb.append("Poly(");
+ for (int i = 0; i < poly.npoints; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append("[");
+ sb.append(poly.xpoints[i]);
+ sb.append(", ");
+ sb.append(poly.ypoints[i]);
+ sb.append("]");
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+ }
+
+ public static class Path extends AnnotatedShapeOp {
+ public static Path tryparse(String str) {
+ str = str.trim();
+ if (!str.startsWith("Path(")) {
+ return null;
+ }
+ str = str.substring(5);
+ GeneralPath gp = new GeneralPath();
+ float coords[] = new float[6];
+ int numsegs = 0;
+ while (true) {
+ int type;
+ int n;
+ str = str.trim();
+ if (str.startsWith(")")) {
+ str = str.substring(1);
+ break;
+ }
+ if (str.startsWith("M[")) {
+ type = PathIterator.SEG_MOVETO;
+ n = 2;
+ } else if (str.startsWith("L[")) {
+ type = PathIterator.SEG_LINETO;
+ n = 2;
+ } else if (str.startsWith("Q[")) {
+ type = PathIterator.SEG_QUADTO;
+ n = 4;
+ } else if (str.startsWith("C[")) {
+ type = PathIterator.SEG_CUBICTO;
+ n = 6;
+ } else if (str.startsWith("E[")) {
+ type = PathIterator.SEG_CLOSE;
+ n = 0;
+ } else {
+ return null;
+ }
+ str = str.substring(2);
+ if (n == 0) {
+ if (str.startsWith("]")) {
+ str = str.substring(1);
+ } else {
+ return null;
+ }
+ }
+ for (int i = 0; i < n; i++) {
+ int index;
+ if (i < n-1) {
+ index = str.indexOf(",");
+ } else {
+ index = str.indexOf("]");
+ }
+ if (index < 0) {
+ return null;
+ }
+ String num = str.substring(0, index);
+ try {
+ coords[i] = Float.parseFloat(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1).trim();
+ }
+ switch (type) {
+ case PathIterator.SEG_MOVETO:
+ gp.moveTo(coords[0], coords[1]);
+ break;
+ case PathIterator.SEG_LINETO:
+ gp.lineTo(coords[0], coords[1]);
+ break;
+ case PathIterator.SEG_QUADTO:
+ gp.quadTo(coords[0], coords[1],
+ coords[2], coords[3]);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ gp.curveTo(coords[0], coords[1],
+ coords[2], coords[3],
+ coords[4], coords[5]);
+ break;
+ case PathIterator.SEG_CLOSE:
+ gp.closePath();
+ break;
+ }
+ numsegs++;
+ }
+ if (str.length() > 0) {
+ return null;
+ }
+ if (numsegs < 2) {
+ return null;
+ }
+ return new Path(gp);
+ }
+
+ private GeneralPath path;
+
+ public Path() {
+ this.path = new GeneralPath();
+ }
+
+ private Path(GeneralPath gp) {
+ this.path = gp;
+ }
+
+ public void randomize() {
+ path.reset();
+ path.moveTo(randFltCoord(), randFltCoord());
+ for (int i = randInt(5)+3; i > 0; --i) {
+ switch(randInt(5)) {
+ case 0:
+ path.moveTo(randFltCoord(), randFltCoord());
+ break;
+ case 1:
+ path.lineTo(randFltCoord(), randFltCoord());
+ break;
+ case 2:
+ path.quadTo(randFltCoord(), randFltCoord(),
+ randFltCoord(), randFltCoord());
+ break;
+ case 3:
+ path.curveTo(randFltCoord(), randFltCoord(),
+ randFltCoord(), randFltCoord(),
+ randFltCoord(), randFltCoord());
+ break;
+ case 4:
+ path.closePath();
+ break;
+ }
+ }
+ }
+
+ public Shape getShape() {
+ return path;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer(100);
+ sb.append("Path(");
+ PathIterator pi = path.getPathIterator(null);
+ float coords[] = new float[6];
+ boolean first = true;
+ while (!pi.isDone()) {
+ int n;
+ char c;
+ switch(pi.currentSegment(coords)) {
+ case PathIterator.SEG_MOVETO:
+ c = 'M';
+ n = 2;
+ break;
+ case PathIterator.SEG_LINETO:
+ c = 'L';
+ n = 2;
+ break;
+ case PathIterator.SEG_QUADTO:
+ c = 'Q';
+ n = 4;
+ break;
+ case PathIterator.SEG_CUBICTO:
+ c = 'C';
+ n = 6;
+ break;
+ case PathIterator.SEG_CLOSE:
+ c = 'E';
+ n = 0;
+ break;
+ default:
+ throw new InternalError("Unknown segment!");
+ }
+ sb.append(c);
+ sb.append("[");
+ for (int i = 0; i < n; i++) {
+ if (i != 0) {
+ sb.append(",");
+ }
+ sb.append(coords[i]);
+ }
+ sb.append("]");
+ pi.next();
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+ }
+
+ public static class Rect extends AnnotatedShapeOp {
+ public static Rect tryparse(String str) {
+ str = str.trim();
+ if (!str.startsWith("Rect(")) {
+ return null;
+ }
+ str = str.substring(5);
+ double coords[] = new double[4];
+ boolean foundparen = false;
+ for (int i = 0; i < coords.length; i++) {
+ int index = str.indexOf(",");
+ if (index < 0) {
+ if (i < coords.length-1) {
+ return null;
+ }
+ index = str.indexOf(")");
+ if (index < 0) {
+ return null;
+ }
+ foundparen = true;
+ }
+ String num = str.substring(0, index);
+ try {
+ coords[i] = Double.parseDouble(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1);
+ }
+ if (!foundparen || str.length() > 0) {
+ return null;
+ }
+ Rect r = new Rect();
+ r.rect.setRect(coords[0], coords[1],
+ coords[2], coords[3]);
+ return r;
+ }
+
+ private Rectangle2D rect = new Rectangle2D.Double();
+
+ public void randomize() {
+ rect.setRect(randDblCoord(), randDblCoord(),
+ randDblCoord(), randDblCoord());
+ }
+
+ public Shape getShape() {
+ return rect;
+ }
+
+ public String toString() {
+ return ("Rect("+
+ rect.getX()+", "+
+ rect.getY()+", "+
+ rect.getWidth()+", "+
+ rect.getHeight()
+ +")");
+ }
+ }
+
+ public static class Line extends AnnotatedShapeOp {
+ public static Line tryparse(String str) {
+ str = str.trim();
+ if (!str.startsWith("Line(")) {
+ return null;
+ }
+ str = str.substring(5);
+ double coords[] = new double[4];
+ boolean foundparen = false;
+ for (int i = 0; i < coords.length; i++) {
+ int index = str.indexOf(",");
+ if (index < 0) {
+ if (i < coords.length-1) {
+ return null;
+ }
+ index = str.indexOf(")");
+ if (index < 0) {
+ return null;
+ }
+ foundparen = true;
+ }
+ String num = str.substring(0, index);
+ try {
+ coords[i] = Double.parseDouble(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1);
+ }
+ if (!foundparen || str.length() > 0) {
+ return null;
+ }
+ Line l = new Line();
+ l.line.setLine(coords[0], coords[1],
+ coords[2], coords[3]);
+ return l;
+ }
+
+ private Line2D line = new Line2D.Double();
+
+ public void randomize() {
+ line.setLine(randDblCoord(), randDblCoord(),
+ randDblCoord(), randDblCoord());
+ }
+
+ public Shape getShape() {
+ return line;
+ }
+
+ public String toString() {
+ return ("Line("+
+ line.getX1()+", "+
+ line.getY1()+", "+
+ line.getX2()+", "+
+ line.getY2()
+ +")");
+ }
+ }
+
+ public static class RectMethod extends AnnotatedRenderOp {
+ public static RectMethod tryparse(String str) {
+ str = str.trim();
+ if (!str.startsWith("RectMethod(")) {
+ return null;
+ }
+ str = str.substring(11);
+ int coords[] = new int[4];
+ boolean foundparen = false;
+ for (int i = 0; i < coords.length; i++) {
+ int index = str.indexOf(",");
+ if (index < 0) {
+ if (i < coords.length-1) {
+ return null;
+ }
+ index = str.indexOf(")");
+ if (index < 0) {
+ return null;
+ }
+ foundparen = true;
+ }
+ String num = str.substring(0, index).trim();
+ try {
+ coords[i] = Integer.parseInt(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1);
+ }
+ if (!foundparen || str.length() > 0) {
+ return null;
+ }
+ RectMethod rm = new RectMethod();
+ rm.rect.setBounds(coords[0], coords[1],
+ coords[2], coords[3]);
+ return rm;
+ }
+
+ private Rectangle rect = new Rectangle();
+
+ public void randomize() {
+ rect.setBounds(randIntCoord(), randIntCoord(),
+ randIntCoord(), randIntCoord());
+ }
+
+ public void fill(Graphics2D g2d) {
+ g2d.fillRect(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ public void draw(Graphics2D g2d) {
+ g2d.drawRect(rect.x, rect.y, rect.width, rect.height);
+ }
+
+ public String toString() {
+ return ("RectMethod("+
+ rect.x+", "+
+ rect.y+", "+
+ rect.width+", "+
+ rect.height
+ +")");
+ }
+ }
+
+ public static class LineMethod extends AnnotatedRenderOp {
+ public static LineMethod tryparse(String str) {
+ str = str.trim();
+ if (!str.startsWith("LineMethod(")) {
+ return null;
+ }
+ str = str.substring(11);
+ int coords[] = new int[4];
+ boolean foundparen = false;
+ for (int i = 0; i < coords.length; i++) {
+ int index = str.indexOf(",");
+ if (index < 0) {
+ if (i < coords.length-1) {
+ return null;
+ }
+ index = str.indexOf(")");
+ if (index < 0) {
+ return null;
+ }
+ foundparen = true;
+ }
+ String num = str.substring(0, index).trim();
+ try {
+ coords[i] = Integer.parseInt(num);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ str = str.substring(index+1);
+ }
+ if (!foundparen || str.length() > 0) {
+ return null;
+ }
+ LineMethod lm = new LineMethod();
+ lm.line = coords;
+ return lm;
+ }
+
+ private int line[] = new int[4];
+
+ public void randomize() {
+ line[0] = randIntCoord();
+ line[1] = randIntCoord();
+ line[2] = randIntCoord();
+ line[3] = randIntCoord();
+ }
+
+ public void fill(Graphics2D g2d) {
+ }
+
+ public void draw(Graphics2D g2d) {
+ g2d.drawLine(line[0], line[1], line[2], line[3]);
+ }
+
+ public String toString() {
+ return ("LineMethod("+
+ line[0]+", "+
+ line[1]+", "+
+ line[2]+", "+
+ line[3]
+ +")");
+ }
+ }
+
+ public static class ErrorWindow extends Frame {
+ ImageCanvas unclipped;
+ ImageCanvas reference;
+ ImageCanvas actual;
+ ImageCanvas diff;
+
+ public ErrorWindow() {
+ super("Error Comparison Window");
+
+ unclipped = new ImageCanvas();
+ reference = new ImageCanvas();
+ actual = new ImageCanvas();
+ diff = new ImageCanvas();
+
+ setLayout(new SmartGridLayout(0, 2, 5, 5));
+ addImagePanel(unclipped, "Unclipped rendering");
+ addImagePanel(reference, "Clipped reference");
+ addImagePanel(actual, "Actual clipped");
+ addImagePanel(diff, "Difference");
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ setVisible(false);
+ }
+ });
+ }
+
+ public void addImagePanel(ImageCanvas ic, String label) {
+ add(ic);
+ add(new Label(label));
+ }
+
+ public void setImages(BufferedImage imgref, BufferedImage imgtst) {
+ unclipped.setImage(imgref);
+ reference.setReference(imgref);
+ actual.setImage(imgtst);
+ diff.setDiff(reference.getImage(), imgtst);
+ invalidate();
+ pack();
+ repaint();
+ }
+
+ public void setVisible(boolean vis) {
+ super.setVisible(vis);
+ synchronized (this) {
+ notifyAll();
+ }
+ }
+
+ public synchronized void waitForHide() {
+ while (isShowing()) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ System.exit(2);
+ }
+ }
+ }
+ }
+
+ public static class SmartGridLayout implements LayoutManager {
+ int rows;
+ int cols;
+ int hgap;
+ int vgap;
+
+ public SmartGridLayout(int r, int c, int h, int v) {
+ this.rows = r;
+ this.cols = c;
+ this.hgap = h;
+ this.vgap = v;
+ }
+
+ public void addLayoutComponent(String name, Component comp) {
+ }
+
+ public void removeLayoutComponent(Component comp) {
+ }
+
+ public int[][] getGridSizes(Container parent, boolean min) {
+ int ncomponents = parent.getComponentCount();
+ int nrows = rows;
+ int ncols = cols;
+
+ if (nrows > 0) {
+ ncols = (ncomponents + nrows - 1) / nrows;
+ } else {
+ nrows = (ncomponents + ncols - 1) / ncols;
+ }
+ int widths[] = new int[ncols+1];
+ int heights[] = new int[nrows+1];
+ int x = 0;
+ int y = 0;
+ for (int i = 0 ; i < ncomponents ; i++) {
+ Component comp = parent.getComponent(i);
+ Dimension d = (min
+ ? comp.getMinimumSize()
+ : comp.getPreferredSize());
+ if (widths[x] < d.width) {
+ widths[x] = d.width;
+ }
+ if (heights[y] < d.height) {
+ heights[y] = d.height;
+ }
+ x++;
+ if (x >= ncols) {
+ x = 0;
+ y++;
+ }
+ }
+ for (int i = 0; i < ncols; i++) {
+ widths[ncols] += widths[i];
+ }
+ for (int i = 0; i < nrows; i++) {
+ heights[nrows] += heights[i];
+ }
+ return new int[][] { widths, heights };
+ }
+
+ public Dimension getSize(Container parent, boolean min) {
+ int sizes[][] = getGridSizes(parent, min);
+ int widths[] = sizes[0];
+ int heights[] = sizes[1];
+ int nrows = heights.length-1;
+ int ncols = widths.length-1;
+ int w = widths[ncols];
+ int h = heights[nrows];
+ Insets insets = parent.getInsets();
+ return new Dimension(insets.left+insets.right + w+(ncols+1)*hgap,
+ insets.top+insets.bottom + h+(nrows+1)*vgap);
+ }
+
+ public Dimension preferredLayoutSize(Container parent) {
+ return getSize(parent, false);
+ }
+
+ public Dimension minimumLayoutSize(Container parent) {
+ return getSize(parent, true);
+ }
+
+ public void layoutContainer(Container parent) {
+ int pref[][] = getGridSizes(parent, false);
+ int min[][] = getGridSizes(parent, true);
+ int minwidths[] = min[0];
+ int minheights[] = min[1];
+ int prefwidths[] = pref[0];
+ int prefheights[] = pref[1];
+ int nrows = minheights.length - 1;
+ int ncols = minwidths.length - 1;
+ Insets insets = parent.getInsets();
+ int w = parent.getWidth() - insets.left - insets.right;
+ int h = parent.getHeight() - insets.top - insets.bottom;
+ w = w - (ncols+1)*hgap;
+ h = h - (nrows+1)*vgap;
+ int widths[] = calculateSizes(w, ncols, minwidths, prefwidths);
+ int heights[] = calculateSizes(h, nrows, minheights, prefheights);
+ int ncomponents = parent.getComponentCount();
+ int x = insets.left + hgap;
+ int y = insets.top + vgap;
+ int r = 0;
+ int c = 0;
+ for (int i = 0; i < ncomponents; i++) {
+ parent.getComponent(i).setBounds(x, y, widths[c], heights[r]);
+ x += widths[c++] + hgap;
+ if (c >= ncols) {
+ c = 0;
+ x = insets.left + hgap;
+ y += heights[r++] + vgap;
+ if (r >= nrows) {
+ // just in case
+ break;
+ }
+ }
+ }
+ }
+
+ public static int[] calculateSizes(int total, int num,
+ int minsizes[], int prefsizes[])
+ {
+ if (total <= minsizes[num]) {
+ return minsizes;
+ }
+ if (total >= prefsizes[num]) {
+ return prefsizes;
+ }
+ int sizes[] = new int[total];
+ int prevhappy = 0;
+ int nhappy = 0;
+ int happysize = 0;
+ do {
+ int addsize = (total - happysize) / (num - nhappy);
+ happysize = 0;
+ for (int i = 0; i < num; i++) {
+ if (sizes[i] >= prefsizes[i] ||
+ minsizes[i] + addsize > prefsizes[i])
+ {
+ happysize += (sizes[i] = prefsizes[i]);
+ nhappy++;
+ } else {
+ sizes[i] = minsizes[i] + addsize;
+ }
+ }
+ } while (nhappy < num && nhappy > prevhappy);
+ return sizes;
+ }
+ }
+
+ public static class ImageCanvas extends Canvas {
+ BufferedImage image;
+
+ public void setImage(BufferedImage img) {
+ this.image = img;
+ }
+
+ public BufferedImage getImage() {
+ return image;
+ }
+
+ public void checkImage(int w, int h) {
+ if (image == null ||
+ image.getWidth() < w ||
+ image.getHeight() < h)
+ {
+ image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+ }
+ }
+
+ public void setReference(BufferedImage img) {
+ checkImage(img.getWidth(), img.getHeight());
+ Graphics g = image.createGraphics();
+ g.drawImage(img, 0, 0, null);
+ g.setColor(Color.white);
+ g.fillRect(0, 0, 30, 10);
+ g.fillRect(30, 0, 10, 30);
+ g.fillRect(10, 30, 30, 10);
+ g.fillRect(0, 10, 10, 30);
+ g.dispose();
+ }
+
+ public void setDiff(BufferedImage imgref, BufferedImage imgtst) {
+ int w = Math.max(imgref.getWidth(), imgtst.getWidth());
+ int h = Math.max(imgref.getHeight(), imgtst.getHeight());
+ checkImage(w, h);
+ Graphics g = image.createGraphics();
+ g.drawImage(imgref, 0, 0, null);
+ g.setXORMode(Color.white);
+ g.drawImage(imgtst, 0, 0, null);
+ g.setPaintMode();
+ g.setColor(new Color(1f, 1f, 0f, 0.25f));
+ g.fillRect(10, 10, 20, 20);
+ g.setColor(new Color(1f, 0f, 0f, 0.25f));
+ g.fillRect(0, 0, 30, 10);
+ g.fillRect(30, 0, 10, 30);
+ g.fillRect(10, 30, 30, 10);
+ g.fillRect(0, 10, 10, 30);
+ g.dispose();
+ }
+
+ public Dimension getPreferredSize() {
+ if (image == null) {
+ return new Dimension();
+ } else {
+ return new Dimension(image.getWidth(), image.getHeight());
+ }
+ }
+
+ public void paint(Graphics g) {
+ g.drawImage(image, 0, 0, null);
+ }
+ }
+}
--- a/jdk/test/java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.html Mon Jan 17 13:29:12 2011 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<html>
-<!--
- @test
- @bug 6391770
- @summary Content of the Window should be laid out in the area left after WarningWindow was added.
- @author Yuri Nesterenko
- @run applet WindowWithWarningTest.html
--->
-
- <head>
- <title>WindowWithWarningTest</title>
- </head>
- <pre>
- This test will run automatically.
- </pre>
- <body>
- <applet code="WindowWithWarningTest.class" width=350 height=300></applet>
- </body>
-</html>
-
--- a/jdk/test/java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.java Mon Jan 17 13:29:12 2011 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) 2006, 2008, 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 6391770
- @summary Content of the Window should be laid out in the area left after WarningWindow was added.
- @author yuri nesterenko: area=
- @run applet WindowWithWarningTest.html
-*/
-
-// Note there is no @ in front of test above. This is so that the
-// harness will not mistake this file as a test file. It should
-// only see the html file as a test file. (the harness runs all
-// valid test files, so it would run this test twice if this file
-// were valid as well as the html file.)
-// Also, note the area= after Your Name in the author tag. Here, you
-// should put which functional area the test falls in. See the
-// AWT-core home page -> test areas and/or -> AWT team for a list of
-// areas.
-// Note also the 'AutomaticAppletTest.html' in the run tag. This should
-// be changed to the name of the test.
-
-
-/**
- * WindowWithWarningTest.java
- *
- * summary:
- */
-
-import java.applet.Applet;
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-
-//Automated tests should run as applet tests if possible because they
-// get their environments cleaned up, including AWT threads, any
-// test created threads, and any system resources used by the test
-// such as file descriptors. (This is normally not a problem as
-// main tests usually run in a separate VM, however on some platforms
-// such as the Mac, separate VMs are not possible and non-applet
-// tests will cause problems). Also, you don't have to worry about
-// synchronisation stuff in Applet tests they way you do in main
-// tests...
-
-
-public class WindowWithWarningTest extends Applet
-{
- //Declare things used in the test, like buttons and labels here
- boolean buttonClicked = false;
- public static final int MAX_COUNT = 100;
-
- public void init()
- {
- //Create instructions for the user here, as well as set up
- // the environment -- set the layout manager, add buttons,
- // etc.
-
- this.setLayout (new BorderLayout ());
-
- String[] instructions =
- {
- "This is an AUTOMATIC test",
- "simply wait until it is done"
- };
- //Sysout.createDialog( );
- //Sysout.printInstructions( instructions );
-
- }//End init()
- public void start ()
- {
- //Get things going. Request focus, set size, et cetera
- System.setSecurityManager( new SecurityManager() {
- // deny AWTPermission("showWindowWithoutWarningBanner")
- public boolean checkTopLevelWindow(Object window) {
- return false;
- }
- });
- JFrame frame = new JFrame("Window Test");
- frame.setBounds(50, 50, 200, 200);
- frame.show();
-
- JWindow window = new JWindow( frame );
- JButton jbutton1 = new JButton( "First" );
- jbutton1.addMouseListener( new MouseAdapter() {
- public void mousePressed( MouseEvent me ) {
- buttonClicked = true;
- }
- });
- JButton jbutton2 = new JButton( "Second" );
- window.setLocation( 300, 300 );
-
- window.add("North", jbutton1);
- window.add("South", jbutton2);
-
- window.pack();
- window.show();
- //wait for frame to show:
- getLocation( frame );
- window.toFront();
-
- Dimension size0 = window.getSize();
- Dimension size1 = null;
- try {
- Robot robot = new Robot();
-
- robot.delay(500);
- window.pack();
- robot.delay(500);
- window.pack();
- // size1 must be the same as size0
- size1 = window.getSize();
- robot.delay(500);
- Point pt = jbutton1.getLocationOnScreen();
- robot.mouseMove((int) jbutton1.getLocationOnScreen().x + jbutton1.getWidth() / 2,
- (int) jbutton1.getLocationOnScreen().y + jbutton1.getHeight() / 2);
- robot.delay(500);
- robot.mousePress(MouseEvent.BUTTON1_MASK);
- robot.delay(100);
- robot.mouseRelease(MouseEvent.BUTTON1_MASK);
- robot.delay(2000);
- }catch(Exception e) {
- throw new RuntimeException( "Exception "+e );
- }
- if( !size0.equals(size1) ) {
- throw new RuntimeException( "Wrong Window size after multiple pack()s");
- }
- if( !buttonClicked ) {
- throw new RuntimeException( "Button was not clicked");
- }
- window.dispose();
- frame.dispose();
-
- System.out.println("Test Passed.");
- }// start()
- public static Point getLocation( Component co ) throws RuntimeException {
- Point pt = null;
- boolean bFound = false;
- int count = 0;
- while( !bFound ) {
- try {
- pt = co.getLocationOnScreen();
- bFound = true;
- }catch( Exception ex ) {
- bFound = false;
- count++;
- }
- if( !bFound && count > MAX_COUNT ) {
- throw new RuntimeException("don't see a component to get location");
- }
- }
- return pt;
- }
-
-
-}// class AutomaticAppletTest
-
-
-/****************************************************
- Standard Test Machinery
- DO NOT modify anything below -- it's a standard
- chunk of code whose purpose is to make user
- interaction uniform, and thereby make it simpler
- to read and understand someone else's test.
- ****************************************************/
-
-/**
- This is part of the standard test machinery.
- It creates a dialog (with the instructions), and is the interface
- for sending text messages to the user.
- To print the instructions, send an array of strings to Sysout.createDialog
- WithInstructions method. Put one line of instructions per array entry.
- To display a message for the tester to see, simply call Sysout.println
- with the string to be displayed.
- This mimics System.out.println but works within the test harness as well
- as standalone.
- */
-
-class Sysout
-{
- private static TestDialog dialog;
-
- public static void createDialogWithInstructions( String[] instructions )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- dialog.printInstructions( instructions );
- dialog.setVisible(true);
- println( "Any messages for the tester will display here." );
- }
-
- public static void createDialog( )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- String[] defInstr = { "Instructions will appear here. ", "" } ;
- dialog.printInstructions( defInstr );
- dialog.setVisible(true);
- println( "Any messages for the tester will display here." );
- }
-
-
- public static void printInstructions( String[] instructions )
- {
- dialog.printInstructions( instructions );
- }
-
-
- public static void println( String messageIn )
- {
- dialog.displayMessage( messageIn );
- }
-
-}// Sysout class
-
-/**
- This is part of the standard test machinery. It provides a place for the
- test instructions to be displayed, and a place for interactive messages
- to the user to be displayed.
- To have the test instructions displayed, see Sysout.
- To have a message to the user be displayed, see Sysout.
- Do not call anything in this dialog directly.
- */
-class TestDialog extends Dialog
-{
-
- TextArea instructionsText;
- TextArea messageText;
- int maxStringLength = 80;
-
- //DO NOT call this directly, go through Sysout
- public TestDialog( Frame frame, String name )
- {
- super( frame, name );
- int scrollBoth = TextArea.SCROLLBARS_BOTH;
- instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
- add( "North", instructionsText );
-
- messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
- add("Center", messageText);
-
- pack();
-
- show();
- }// TestDialog()
-
- //DO NOT call this directly, go through Sysout
- public void printInstructions( String[] instructions )
- {
- //Clear out any current instructions
- instructionsText.setText( "" );
-
- //Go down array of instruction strings
-
- String printStr, remainingStr;
- for( int i=0; i < instructions.length; i++ )
- {
- //chop up each into pieces maxSringLength long
- remainingStr = instructions[ i ];
- while( remainingStr.length() > 0 )
- {
- //if longer than max then chop off first max chars to print
- if( remainingStr.length() >= maxStringLength )
- {
- //Try to chop on a word boundary
- int posOfSpace = remainingStr.
- lastIndexOf( ' ', maxStringLength - 1 );
-
- if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
-
- printStr = remainingStr.substring( 0, posOfSpace + 1 );
- remainingStr = remainingStr.substring( posOfSpace + 1 );
- }
- //else just print
- else
- {
- printStr = remainingStr;
- remainingStr = "";
- }
-
- instructionsText.append( printStr + "\n" );
-
- }// while
-
- }// for
-
- }//printInstructions()
-
- //DO NOT call this directly, go through Sysout
- public void displayMessage( String messageIn )
- {
- messageText.append( messageIn + "\n" );
- System.out.println(messageIn);
- }
-
-}// TestDialog class
--- a/jdk/test/java/awt/PrintJob/Text/StringWidth.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/awt/PrintJob/Text/StringWidth.java Wed Jan 19 19:00:30 2011 -0800
@@ -60,7 +60,6 @@
pg.dispose();
pj.end();
setVisible(false);
- System.exit(0);
}
public static void main(String[] args) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/IncorrectSampleMaskTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6782574
+ * @summary Test verifies that incorrect sample masks are correctly handled
+ * by the constructor of the SinglePixelPackedSampleModel class
+ * and do not cause internal error in the medialib glue code.
+ *
+ * @run main IncorrectSampleMaskTest
+ */
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.Raster;
+import java.awt.image.RasterOp;
+import java.awt.image.WritableRaster;
+import java.awt.image.SinglePixelPackedSampleModel;
+
+public class IncorrectSampleMaskTest {
+ public static void main(String[] args) {
+ int[] dataTypes = new int[] {
+ DataBuffer.TYPE_BYTE,
+ DataBuffer.TYPE_USHORT,
+ DataBuffer.TYPE_INT };
+
+ for (int type : dataTypes) {
+ doTest(type);
+ }
+ }
+
+ private static final int w = 100;
+ private static final int h = 100;
+
+ private static AffineTransform at =
+ AffineTransform.getScaleInstance(0.5, 0.5);
+
+ private static RasterOp op =
+ new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+
+ private static void doTest(int dataType) {
+ int maxSize = DataBuffer.getDataTypeSize(dataType);
+ System.out.println("Type size: " + maxSize);
+
+ int theMask = (int)(1L << (maxSize + 2)) - 1;
+ System.out.printf("theMask=%x\n", theMask);
+
+ SinglePixelPackedSampleModel sm =
+ new SinglePixelPackedSampleModel(dataType, w, h,
+ new int[] { theMask });
+
+
+ int[] sampleSize = sm.getSampleSize();
+ for (int s : sampleSize) {
+ if (s > maxSize) {
+ throw new RuntimeException("Test failed: sample size is too big:" + s);
+ }
+ }
+
+ System.out.println("Test medialib...");
+ DataBuffer buf = createDataBuffer(dataType);
+
+ WritableRaster wr = Raster.createWritableRaster(sm, buf, null);
+
+ op.filter(wr, null);
+ System.out.println("Test PASSED.");
+ }
+
+ private static DataBuffer createDataBuffer(int type) {
+ switch (type) {
+ case DataBuffer.TYPE_BYTE: {
+ byte[] buf = new byte[w * h];
+ return new DataBufferByte(buf, buf.length);
+ }
+ case DataBuffer.TYPE_USHORT: {
+ short[] buf = new short[w * h];
+ return new DataBufferUShort(buf, buf.length);
+ }
+ case DataBuffer.TYPE_INT: {
+ int[] buf = new int[w * h];
+ return new DataBufferInt(buf, buf.length);
+ }
+ default :
+ throw new RuntimeException("Unsupported data type.");
+ }
+ }
+}
--- a/jdk/test/java/text/Format/DateFormat/ISO8601ZoneTest.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/text/Format/DateFormat/ISO8601ZoneTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -60,48 +60,51 @@
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
};
+ // badData[][0] - format
+ // badData[][1] - (bad) text to be parsed
+ // badData[][2] - subtext at the end of which a parse error is detected
static final String[][] badData = {
- { "X", "1" },
- { "X", "+1" },
- { "X", "-2" },
- { "X", "-24" },
- { "X", "+24" },
+ { "X", "1", "1" },
+ { "X", "+1", "+1" },
+ { "X", "-2", "-2" },
+ { "X", "-24", "-2" },
+ { "X", "+24", "+2" },
- { "XX", "9" },
- { "XX", "23" },
- { "XX", "234" },
- { "XX", "3456" },
- { "XX", "23456" },
- { "XX", "+1" },
- { "XX", "-12" },
- { "XX", "+123" },
- { "XX", "-12:34" },
- { "XX", "+12:34" },
- { "XX", "-2423" },
- { "XX", "+2423" },
- { "XX", "-1260" },
- { "XX", "+1260" },
+ { "XX", "9", "9" },
+ { "XX", "23", "2" },
+ { "XX", "234", "2" },
+ { "XX", "3456", "3" },
+ { "XX", "23456", "2" },
+ { "XX", "+1", "+1" },
+ { "XX", "-12", "-12" },
+ { "XX", "+123", "+123" },
+ { "XX", "-12:34", "-12" },
+ { "XX", "+12:34", "+12" },
+ { "XX", "-2423", "-2" },
+ { "XX", "+2423", "+2" },
+ { "XX", "-1260", "-126" },
+ { "XX", "+1260", "+126" },
- { "XXX", "9" },
- { "XXX", "23" },
- { "XXX", "234" },
- { "XXX", "3456" },
- { "XXX", "23456" },
- { "XXX", "2:34" },
- { "XXX", "12:4" },
- { "XXX", "12:34" },
- { "XXX", "-1" },
- { "XXX", "+1" },
- { "XXX", "-12" },
- { "XXX", "+12" },
- { "XXX", "-123" },
- { "XXX", "+123" },
- { "XXX", "-1234" },
- { "XXX", "+1234" },
- { "XXX", "+24:23" },
- { "XXX", "+12:60" },
- { "XXX", "+1:23" },
- { "XXX", "+12:3" },
+ { "XXX", "9", "9" },
+ { "XXX", "23", "2" },
+ { "XXX", "234", "2" },
+ { "XXX", "3456", "3" },
+ { "XXX", "23456", "2" },
+ { "XXX", "2:34", "2" },
+ { "XXX", "12:4", "1" },
+ { "XXX", "12:34", "1" },
+ { "XXX", "-1", "-1" },
+ { "XXX", "+1", "+1" },
+ { "XXX", "-12", "-12" },
+ { "XXX", "+12", "+12" },
+ { "XXX", "-123", "-12" },
+ { "XXX", "+123", "+12" },
+ { "XXX", "-1234", "-12" },
+ { "XXX", "+1234", "+12" },
+ { "XXX", "+24:23", "+2" },
+ { "XXX", "+12:60", "+12:6" },
+ { "XXX", "+1:23", "+1" },
+ { "XXX", "+12:3", "+12:3" },
};
static String[] badFormats = {
@@ -110,6 +113,8 @@
public static void main(String[] args) throws Exception {
TimeZone tz = TimeZone.getDefault();
+ Locale loc = Locale.getDefault();
+ Locale.setDefault(Locale.US);
try {
for (int i = 0; i < formatData.length; i++) {
@@ -128,7 +133,7 @@
}
for (String[] d : badData) {
- badDataParsing(d[0], d[1]);
+ badDataParsing(d[0], d[1], d[2].length());
}
for (String fmt : badFormats) {
@@ -136,6 +141,7 @@
}
} finally {
TimeZone.setDefault(tz);
+ Locale.setDefault(loc);
}
}
@@ -188,15 +194,24 @@
}
- static void badDataParsing(String fmt, String text) {
+ static void badDataParsing(String fmt, String text, int expectedErrorIndex) {
+ SimpleDateFormat sdf = new SimpleDateFormat(fmt);
try {
- SimpleDateFormat sdf = new SimpleDateFormat(fmt);
sdf.parse(text);
throw new RuntimeException("didn't throw an exception: fmt=" + fmt
+ ", text=" + text);
} catch (ParseException e) {
// OK
}
+
+ ParsePosition pos = new ParsePosition(0);
+ Date d = sdf.parse(text, pos);
+ int errorIndex = pos.getErrorIndex();
+ if (d != null || errorIndex != expectedErrorIndex) {
+ throw new RuntimeException("Bad error index=" + errorIndex
+ + ", expected=" + expectedErrorIndex
+ + ", fmt=" + fmt + ", text=" + text);
+ }
}
static void badFormat(String fmt) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Format/MessageFormat/Bug7003643.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010, 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 7003643
+ * @summary Make sure MessageFormat.toPattern produces correct quoting. (SPI part is tested in PluggableLocale tests.)
+ */
+
+import java.text.*;
+import java.util.*;
+
+public class Bug7003643 {
+ private static final int N = 5;
+
+ private static final String[] elements = {
+ "'{'", "'{", "{", "''", "}", "a", "'",
+ };
+
+ public static void main(String[] args) {
+ Random rand = new Random();
+ int count = 0;
+ int max = (int) (Math.pow((double)elements.length, (double)N)/0.52);
+ while (count < max) {
+ // Create a random pattern. If the produced pattern is
+ // valid, then proceed with the round-trip testing.
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < N; i++) {
+ sb.append(elements[rand.nextInt(elements.length)]);
+ }
+ String pattern = sb.toString();
+ MessageFormat mf = null;
+ try {
+ mf = new MessageFormat(pattern);
+ } catch (IllegalArgumentException e) {
+ // bad pattern data
+ }
+ if (mf == null) {
+ continue;
+ }
+ count++;
+ String res1 = MessageFormat.format(pattern, 123);
+ String toPattern = mf.toPattern();
+ String res2 = MessageFormat.format(toPattern, 123);
+ if (!res1.equals(res2)) {
+ String s = String.format("Failed%n pattern=\"%s\" => result=\"%s\"%n"
+ + " toPattern()=\"%s\" => result=\"%s\"%n",
+ pattern, res1, toPattern, res2);
+ throw new RuntimeException(s);
+ }
+ }
+ }
+}
--- a/jdk/test/java/util/Locale/LocaleTest.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/util/Locale/LocaleTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -24,7 +24,8 @@
* @test
* @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613
* 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951
- * 4147315 4147317 4147552 4335196 4778440 5010672 6475525 6544471 6627549 6786276
+ * 4147315 4147317 4147552 4335196 4778440 4940539 5010672 6475525 6544471 6627549
+ * 6786276
* @summary test Locales
*/
/*
@@ -895,17 +896,28 @@
}
/**
- * @bug 4147317
- * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
- * Should throw an exception for unknown locales
+ * @bug 4147317 4940539
+ * java.util.Locale.getISO3Language() works wrong for non ISO-639 codes.
+ * Should throw an exception for unknown locales, except they have three
+ * letter language codes.
*/
public void Test4147317() {
- // Try with codes that are the wrong length but happen to match text
- // at a valid offset in the mapping table
+ // Try a three letter language code, and check whether it is
+ // returned as is.
Locale locale = new Locale("aaa", "CCC");
+ String result = locale.getISO3Language();
+ if (!result.equals("aaa")) {
+ errln("ERROR: getISO3Language() returns: " + result +
+ " for locale '" + locale + "' rather than returning it as is" );
+ }
+
+ // Try an invalid two letter language code, and check whether it
+ // throws a MissingResourceException.
+ locale = new Locale("zz", "CCC");
+
try {
- String result = locale.getISO3Language();
+ result = locale.getISO3Language();
errln("ERROR: getISO3Language() returns: " + result +
" for locale '" + locale + "' rather than exception" );
--- a/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, 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,6 +44,7 @@
availableLocalesTest();
objectValidityTest();
extendedVariantTest();
+ messageFormatTest();
}
void availableLocalesTest() {
@@ -118,4 +119,48 @@
}
}
}
+
+
+ private static final String[] TYPES = {
+ "date",
+ "time"
+ };
+ private static final String[] MODIFIERS = {
+ "",
+ "short",
+ "medium", // Same as DEFAULT
+ "long",
+ "full"
+ };
+
+ void messageFormatTest() {
+ for (Locale target : providerloc) {
+ for (String type : TYPES) {
+ for (String modifier : MODIFIERS) {
+ String pattern, expected;
+ if (modifier.equals("")) {
+ pattern = String.format("%s={0,%s}", type, type);
+ } else {
+ pattern = String.format("%s={0,%s,%s}", type, type, modifier);
+ }
+ if (modifier.equals("medium")) {
+ // medium is default.
+ expected = String.format("%s={0,%s}", type, type);
+ } else {
+ expected = pattern;
+ }
+ MessageFormat mf = new MessageFormat(pattern, target);
+ Format[] fmts = mf.getFormats();
+ if (fmts[0] instanceof SimpleDateFormat) {
+ continue;
+ }
+ String toPattern = mf.toPattern();
+ if (!toPattern.equals(expected)) {
+ throw new RuntimeException("messageFormatTest: got '" + toPattern
+ + "', expected '" + expected + "'");
+ }
+ }
+ }
+ }
+ }
}
--- a/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.sh Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.sh Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,6 @@
#!/bin/sh
#
# @test
-# @bug 4052440
+# @bug 4052440 7003643
# @summary DateFormatProvider tests
# @run shell ExecTest.sh foo DateFormatProviderTest true
--- a/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, 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,6 +29,8 @@
import sun.util.*;
import sun.util.resources.*;
+import com.foo.FooNumberFormat;
+
public class NumberFormatProviderTest extends ProviderTest {
com.foo.NumberFormatProviderImpl nfp = new com.foo.NumberFormatProviderImpl();
@@ -43,6 +45,7 @@
NumberFormatProviderTest() {
availableLocalesTest();
objectValidityTest();
+ messageFormatTest();
}
void availableLocalesTest() {
@@ -72,14 +75,10 @@
}
// result object
- String resultCur =
- ((DecimalFormat)NumberFormat.getCurrencyInstance(target)).toPattern();
- String resultInt =
- ((DecimalFormat)NumberFormat.getIntegerInstance(target)).toPattern();
- String resultNum =
- ((DecimalFormat)NumberFormat.getNumberInstance(target)).toPattern();
- String resultPer =
- ((DecimalFormat)NumberFormat.getPercentInstance(target)).toPattern();
+ String resultCur = getPattern(NumberFormat.getCurrencyInstance(target));
+ String resultInt = getPattern(NumberFormat.getIntegerInstance(target));
+ String resultNum = getPattern(NumberFormat.getNumberInstance(target));
+ String resultPer = getPattern(NumberFormat.getPercentInstance(target));
// provider's object (if any)
String providersCur = null;
@@ -87,21 +86,21 @@
String providersNum = null;
String providersPer = null;
if (providerloc.contains(target)) {
- DecimalFormat dfCur = (DecimalFormat)nfp.getCurrencyInstance(target);
+ NumberFormat dfCur = nfp.getCurrencyInstance(target);
if (dfCur != null) {
- providersCur = dfCur.toPattern();
+ providersCur = getPattern(dfCur);
}
- DecimalFormat dfInt = (DecimalFormat)nfp.getIntegerInstance(target);
+ NumberFormat dfInt = nfp.getIntegerInstance(target);
if (dfInt != null) {
- providersInt = dfInt.toPattern();
+ providersInt = getPattern(dfInt);
}
- DecimalFormat dfNum = (DecimalFormat)nfp.getNumberInstance(target);
+ NumberFormat dfNum = nfp.getNumberInstance(target);
if (dfNum != null) {
- providersNum = dfNum.toPattern();
+ providersNum = getPattern(dfNum);
}
- DecimalFormat dfPer = (DecimalFormat)nfp.getPercentInstance(target);
+ NumberFormat dfPer = nfp.getPercentInstance(target);
if (dfPer != null) {
- providersPer = dfPer.toPattern();
+ providersPer = getPattern(dfPer);
}
}
@@ -174,4 +173,35 @@
}
}
}
+
+ private static String getPattern(NumberFormat nf) {
+ if (nf instanceof DecimalFormat) {
+ return ((DecimalFormat)nf).toPattern();
+ }
+ if (nf instanceof FooNumberFormat) {
+ return ((FooNumberFormat)nf).toPattern();
+ }
+ return null;
+ }
+
+ private static final String[] NUMBER_PATTERNS = {
+ "num={0,number}",
+ "num={0,number,currency}",
+ "num={0,number,percent}",
+ "num={0,number,integer}"
+ };
+
+ void messageFormatTest() {
+ for (Locale target : providerloc) {
+ for (String pattern : NUMBER_PATTERNS) {
+ MessageFormat mf = new MessageFormat(pattern, target);
+ String toPattern = mf.toPattern();
+ if (!pattern.equals(toPattern)) {
+ throw new RuntimeException("MessageFormat.toPattern: got '"
+ + toPattern
+ + "', expected '" + pattern + "'");
+ }
+ }
+ }
+ }
}
--- a/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.sh Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.sh Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,6 @@
#!/bin/sh
#
# @test
-# @bug 4052440
+# @bug 4052440 7003643
# @summary NumberFormatProvider tests
# @run shell ExecTest.sh foo NumberFormatProviderTest true
Binary file jdk/test/java/util/PluggableLocale/fooprovider.jar has changed
--- a/jdk/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/util/PluggableLocale/providersrc/DateFormatProviderImpl.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, 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
@@ -42,7 +42,7 @@
static String[] datePattern = {
"yyyy'\u5e74'M'\u6708'd'\u65e5'", // full date pattern
- "yyyy/MM/dd", // long date pattern
+ "yyyy/MMM/dd", // long date pattern
"yyyy/MM/dd", // medium date pattern
"yy/MM/dd" // short date pattern
};
@@ -68,7 +68,7 @@
public DateFormat getDateInstance(int style, Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
- return new SimpleDateFormat(datePattern[style]+dialect[i], locale);
+ return new FooDateFormat(datePattern[style]+dialect[i], locale);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
@@ -77,7 +77,7 @@
public DateFormat getTimeInstance(int style, Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
- return new SimpleDateFormat(timePattern[style]+dialect[i], locale);
+ return new FooDateFormat(timePattern[style]+dialect[i], locale);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
@@ -86,7 +86,7 @@
public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
- return new SimpleDateFormat(
+ return new FooDateFormat(
datePattern[dateStyle]+" "+timePattern[timeStyle]+dialect[i], locale);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/providersrc/FooDateFormat.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 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 com.foo;
+
+import java.text.*;
+import java.util.*;
+
+/**
+ * FooDateFormat provides SimpleDateFormat methods required for the SPI testing.
+ */
+public class FooDateFormat extends DateFormat {
+ private SimpleDateFormat sdf;
+
+ public FooDateFormat(String pattern, Locale loc) {
+ sdf = new SimpleDateFormat(pattern, loc);
+ }
+
+ @Override
+ public StringBuffer format(Date date,
+ StringBuffer toAppendTo,
+ FieldPosition fieldPosition) {
+ return sdf.format(date, toAppendTo, fieldPosition);
+ }
+
+ @Override
+ public Date parse(String source, ParsePosition pos) {
+ return sdf.parse(source, pos);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other instanceof FooDateFormat
+ && sdf.equals(((FooDateFormat)other).sdf);
+ }
+
+ @Override
+ public int hashCode() {
+ return sdf.hashCode();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/providersrc/FooNumberFormat.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010, 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 com.foo;
+
+import java.text.*;
+
+/**
+ * FooNumberFormat provides DecimalFormat methods required for the SPI testing.
+ */
+public class FooNumberFormat extends NumberFormat {
+ private DecimalFormat df;
+
+ public FooNumberFormat(String pattern, DecimalFormatSymbols dfs) {
+ df = new DecimalFormat(pattern, dfs);
+ }
+
+ @Override
+ public StringBuffer format(double number,
+ StringBuffer toAppendTo,
+ FieldPosition pos) {
+ return df.format(number, toAppendTo, pos);
+ }
+
+ @Override
+ public StringBuffer format(long number,
+ StringBuffer toAppendTo,
+ FieldPosition pos) {
+ return df.format(number, toAppendTo, pos);
+ }
+
+ @Override
+ public Number parse(String source, ParsePosition parsePosition) {
+ return df.parse(source, parsePosition);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other instanceof FooNumberFormat
+ && df.equals(((FooNumberFormat)other).df);
+ }
+
+ @Override
+ public int hashCode() {
+ return df.hashCode();
+ }
+
+ // DecimalFormat specific methods required for testing
+
+ public String toPattern() {
+ return df.toPattern();
+ }
+
+ public DecimalFormatSymbols getDecimalFormatSymbols() {
+ return df.getDecimalFormatSymbols();
+ }
+
+ public void setDecimalSeparatorAlwaysShown(boolean newValue) {
+ df.setDecimalSeparatorAlwaysShown(newValue);
+ }
+}
--- a/jdk/test/java/util/PluggableLocale/providersrc/Makefile Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/util/PluggableLocale/providersrc/Makefile Wed Jan 19 19:00:30 2011 -0800
@@ -28,6 +28,8 @@
DateFormatSymbolsProviderImpl.java \
DecimalFormatSymbolsProviderImpl.java \
NumberFormatProviderImpl.java \
+ FooDateFormat.java \
+ FooNumberFormat.java \
Utils.java
BARFILES_JAVA = \
--- a/jdk/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/java/util/PluggableLocale/providersrc/NumberFormatProviderImpl.java Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, 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
@@ -49,13 +49,15 @@
static String[] patterns = {
"#,##0.###{0};-#,##0.###{1}", // decimal pattern
+ "#{0};(#){1}", // integer pattern
"\u00A4#,##0{0};-\u00A4#,##0{1}", // currency pattern
"#,##0%{0}" // percent pattern
};
// Constants used by factory methods to specify a style of format.
static final int NUMBERSTYLE = 0;
- static final int CURRENCYSTYLE = 1;
- static final int PERCENTSTYLE = 2;
+ static final int INTEGERSTYLE = 1;
+ static final int CURRENCYSTYLE = 2;
+ static final int PERCENTSTYLE = 3;
public Locale[] getAvailableLocales() {
return avail;
@@ -68,10 +70,10 @@
MessageFormat.format(patterns[CURRENCYSTYLE],
dialect[i],
dialect[i]);
- DecimalFormat df = new DecimalFormat(pattern,
+ FooNumberFormat nf = new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale));
- adjustForCurrencyDefaultFractionDigits(df);
- return df;
+ adjustForCurrencyDefaultFractionDigits(nf);
+ return nf;
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
@@ -81,15 +83,15 @@
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
String pattern =
- MessageFormat.format(patterns[NUMBERSTYLE],
+ MessageFormat.format(patterns[INTEGERSTYLE],
dialect[i],
dialect[i]);
- DecimalFormat df = new DecimalFormat(pattern,
+ FooNumberFormat nf = new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale));
- df.setMaximumFractionDigits(0);
- df.setDecimalSeparatorAlwaysShown(false);
- df.setParseIntegerOnly(true);
- return df;
+ nf.setMaximumFractionDigits(0);
+ nf.setDecimalSeparatorAlwaysShown(false);
+ nf.setParseIntegerOnly(true);
+ return nf;
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
@@ -102,7 +104,7 @@
MessageFormat.format(patterns[NUMBERSTYLE],
dialect[i],
dialect[i]);
- return new DecimalFormat(pattern,
+ return new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale));
}
}
@@ -115,7 +117,7 @@
String pattern =
MessageFormat.format(patterns[PERCENTSTYLE],
dialect[i]);
- return new DecimalFormat(pattern,
+ return new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale));
}
}
@@ -126,8 +128,8 @@
* Adjusts the minimum and maximum fraction digits to values that
* are reasonable for the currency's default fraction digits.
*/
- void adjustForCurrencyDefaultFractionDigits(DecimalFormat df) {
- DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
+ void adjustForCurrencyDefaultFractionDigits(FooNumberFormat nf) {
+ DecimalFormatSymbols dfs = nf.getDecimalFormatSymbols();
Currency currency = dfs.getCurrency();
if (currency == null) {
try {
@@ -138,15 +140,15 @@
if (currency != null) {
int digits = currency.getDefaultFractionDigits();
if (digits != -1) {
- int oldMinDigits = df.getMinimumFractionDigits();
+ int oldMinDigits = nf.getMinimumFractionDigits();
// Common patterns are "#.##", "#.00", "#".
// Try to adjust all of them in a reasonable way.
- if (oldMinDigits == df.getMaximumFractionDigits()) {
- df.setMinimumFractionDigits(digits);
- df.setMaximumFractionDigits(digits);
+ if (oldMinDigits == nf.getMaximumFractionDigits()) {
+ nf.setMinimumFractionDigits(digits);
+ nf.setMaximumFractionDigits(digits);
} else {
- df.setMinimumFractionDigits(Math.min(digits, oldMinDigits));
- df.setMaximumFractionDigits(digits);
+ nf.setMinimumFractionDigits(Math.min(digits, oldMinDigits));
+ nf.setMaximumFractionDigits(digits);
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/4847375/bug4847375.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2010, 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 4847375
+ * @summary JFileChooser Create New Folder button is disabled incorrectly
+ * @author Pavel Porvatov
+ */
+
+import sun.awt.OSInfo;
+import sun.awt.shell.ShellFolder;
+
+import javax.swing.*;
+import java.awt.*;
+import java.lang.reflect.Method;
+
+public class bug4847375 {
+ private final String newFolderToolTipText;
+
+ private final String lookAndFeel;
+
+ public static void main(String[] args) throws Exception {
+ if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+ System.out.println("The test is suitable only for Windows OS. Skipped.");
+
+ return;
+ }
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ new bug4847375("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+
+ new bug4847375("javax.swing.plaf.metal.MetalLookAndFeel");
+ }
+ });
+ }
+
+ private static Object[][] DIRECTORIES = new Object[][]{
+ {"getDesktop", Boolean.TRUE},
+ {"getDrives", Boolean.FALSE}, // My computer
+ {"getRecent", Boolean.TRUE},
+ {"getNetwork", Boolean.FALSE},
+ {"getPersonal", Boolean.TRUE},
+ };
+
+ private bug4847375(String lookAndFeel) {
+ this.lookAndFeel = lookAndFeel;
+
+ try {
+ UIManager.setLookAndFeel(lookAndFeel);
+ } catch (Exception e) {
+ fail("Cannot set LookAndFeel", e);
+ }
+
+ JFileChooser fileChooser = new JFileChooser();
+
+ // Find button NewFolder
+ newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText", fileChooser.getLocale());
+
+ if (newFolderToolTipText == null || newFolderToolTipText.length() == 0) {
+ fail("Cannot find NewFolderButton in FileChooser (tooltip doesn't exist)");
+
+ return;
+ }
+
+ JButton newFolderButton = findNewFolderButton(fileChooser);
+
+ if (newFolderButton == null) {
+ fail("Cannot find NewFolderButton in FileChooser");
+
+ return;
+ }
+
+ for (Object[] objects : DIRECTORIES) {
+ String getterName = (String) objects[0];
+ Boolean enabledNewFolder = (Boolean) objects[1];
+
+ fileChooser.setCurrentDirectory(getWin32Folder(getterName));
+
+ if (newFolderButton.isEnabled() != enabledNewFolder) {
+ fail("Enabled state of NewFolderButton should be " + enabledNewFolder +
+ " for Win32ShellFolderManager2." + getterName + "()");
+ }
+ }
+ }
+
+ private JButton findNewFolderButton(Container container) {
+ JButton result = null;
+
+ for (int i = 0; i < container.getComponentCount(); i++) {
+ Component c = container.getComponent(i);
+
+ if (c instanceof JButton && newFolderToolTipText.equals(((JButton) c).getToolTipText())) {
+ if (result != null) {
+ fail("Two or more NewFolderButton found in FileChooser");
+ }
+
+ result = (JButton) c;
+ }
+
+ if (c instanceof Container) {
+ JButton button = findNewFolderButton((Container) c);
+
+ if (result == null) {
+ result = button;
+ } else {
+ if (button != null) {
+ fail("Two or more NewFolderButton found in FileChooser");
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private ShellFolder getWin32Folder(String getterName) {
+ try {
+ Class win32ShellFolderManager2 = Class.forName("sun.awt.shell.Win32ShellFolderManager2");
+
+ Method method = win32ShellFolderManager2.getDeclaredMethod(getterName);
+ method.setAccessible(true);
+
+ return (ShellFolder) method.invoke(null);
+ } catch (Exception e) {
+ fail("Cannot call '" + getterName + "' in the Win32ShellFolderManager2 class", e);
+
+ return null;
+ }
+ }
+
+ private void fail(String s) {
+ throw new RuntimeException("Test failed: " + s);
+ }
+
+ private void fail(String s, Throwable e) {
+ throw new RuntimeException("Test failed for LookAndFeel " + lookAndFeel + ": " + s, e);
+ }
+}
--- a/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java Wed Jan 19 19:00:30 2011 -0800
@@ -40,11 +40,13 @@
private static MyScrollBarUI ui;
public static void main(String[] args) throws Exception {
- Robot robot = new Robot();
+ final Robot robot = new Robot();
robot.setAutoDelay(10);
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ final Rectangle[] thumbBounds = new Rectangle[1];
+
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
final JFrame frame = new JFrame("bug6542335");
@@ -63,25 +65,39 @@
rangeModel.setValue(50);
sb.setModel(rangeModel);
- frame.add(sb);
+ frame.add(sb, BorderLayout.NORTH);
frame.setSize(200, 100);
frame.setVisible(true);
+
+ thumbBounds[0] = new Rectangle(ui.getThumbBounds());
}
});
- Rectangle thumbBounds = new Rectangle(ui.getThumbBounds());
+ toolkit.realSync();
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ Point l = sb.getLocationOnScreen();
+
+ robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight() / 2);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ }
+ });
toolkit.realSync();
- Point l = sb.getLocationOnScreen();
- robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2);
- robot.mousePress(InputEvent.BUTTON1_MASK);
- robot.mouseRelease(InputEvent.BUTTON1_MASK);
- toolkit.realSync();
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ Rectangle newThumbBounds = ui.getThumbBounds();
- if (!thumbBounds.equals(ui.getThumbBounds())) {
- throw new RuntimeException("Test failed");
- }
+ if (!thumbBounds[0].equals(newThumbBounds)) {
+ throw new RuntimeException("Test failed.\nOld bounds: " + thumbBounds[0] +
+ "\nNew bounds: " + newThumbBounds);
+ }
+ }
+ });
}
static class MyScrollBarUI extends BasicScrollBarUI {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JSpinner/6532833/bug6532833.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010, 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 6532833
+ @summary PIT: Metal LAF - The right side border is not shown for the Spinner after the removing the buttons
+ @author Pavel Porvatov
+*/
+
+import javax.swing.*;
+import java.awt.*;
+
+public class bug6532833 {
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ JSpinner[] spinners = new JSpinner[2];
+
+ for (int i = 0; i < spinners.length; i++) {
+ JSpinner spinner = new JSpinner();
+
+ spinner.setValue(2010);
+
+ Component arrowUp = spinner.getComponent(0);
+ Component arrowDown = spinner.getComponent(1);
+
+ LayoutManager layout = spinner.getLayout();
+
+ layout.removeLayoutComponent(arrowUp);
+ layout.removeLayoutComponent(arrowDown);
+
+ if (i == 1) {
+ spinner.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
+ }
+
+ spinners[i] = spinner;
+ }
+
+ // Do layout of spinners components
+ JFrame frame = new JFrame();
+
+ for (JSpinner spinner : spinners) {
+ frame.getContentPane().add(spinner);
+ }
+
+ frame.pack();
+
+ for (JSpinner spinner : spinners) {
+ Insets insets = spinner.getInsets();
+
+ if (spinner.getWidth() != insets.left + insets.right + spinner.getEditor().getWidth()) {
+ throw new RuntimeException("Spinner editor width is invalid");
+ }
+ }
+
+ frame.dispose();
+ }
+ });
+ }
+}
--- a/jdk/test/javax/swing/SwingWorker/6480289/bug6480289.java Mon Jan 17 13:29:12 2011 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2007, 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 6480289
- * @author Igor Kushnirskiy
- * @summary tests if consequent workers are executed on the same thread and that VM can exit.
- */
-
-import java.util.*;
-import javax.swing.SwingWorker;
-
-public class bug6480289 {
- private static final int ITERATIONS = 5;
- private static final Map<Thread, Integer> threadMap =
- Collections.synchronizedMap(new HashMap<Thread, Integer>());
- public static void main(String[] args) throws Exception {
-
- for (int i = 0; i < ITERATIONS; i++) {
- if (i != 0) {
- Thread.sleep(1000 * 5);
- }
- SwingWorker<?,?> worker =
- new SwingWorker<Void, Void>() {
- @Override
- protected Void doInBackground() {
- Integer value = threadMap.get(Thread.currentThread());
- value = Integer.valueOf(
- ((value == null) ? 0 : value.intValue())
- + 1);
- threadMap.put(Thread.currentThread(), value);
- return null;
- }
- };
- worker.execute();
- }
- if (threadMap.keySet().size() != 1) {
- throw new RuntimeException("failed. More than one thread.");
- }
- }
-}
--- a/langtools/.hgtags Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/.hgtags Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
1bf969e9792f977a8593496681539840a54fe644 jdk7-b121
11e7b4c0476e4d6085d8d28c4aa2833d46714a2a jdk7-b122
a3b5b531542a372f30e014b1543a619a15a90780 jdk7-b123
+4868a36f6fd8972505c466013813eeb28f0482ea jdk7-b124
+4b0560c72b529d4b952924b2da94d8436af79d05 jdk7-b125
--- a/langtools/make/Makefile Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/make/Makefile Wed Jan 19 19:00:30 2011 -0800
@@ -187,7 +187,7 @@
clobber: clean
# All ant targets of interest
-ANT_TARGETS = build clean sanity post-sanity diagnostics # for now
+ANT_TARGETS = build clean sanity post-sanity diagnostics build-all-tools # for now
# Create diagnostics log (careful, ant 1.8.0 -diagnostics always does an exit 1)
$(OUTPUTDIR)/build/ant-diagnostics.log:
--- a/langtools/src/share/bin/launcher.sh-template Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/src/share/bin/launcher.sh-template Wed Jan 19 19:00:30 2011 -0800
@@ -26,6 +26,12 @@
#
mydir="`dirname $0`"
+case `uname -s` in
+ CYGWIN*)
+ mydir=`cygpath -m $mydir`
+ ;;
+esac
+
mylib="`dirname $mydir`"/lib
# By default, put the jar file and its dependencies on the bootclasspath.
--- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Jan 19 19:00:30 2011 -0800
@@ -266,82 +266,116 @@
System.out.println(message);
}
+
/**
- * Insert all files in subdirectory `subdirectory' of `directory' which end
- * in one of the extensions in `extensions' into packageSym.
+ * Insert all files in subdirectory subdirectory of directory directory
+ * which match fileKinds into resultList
*/
private void listDirectory(File directory,
RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds,
boolean recurse,
- ListBuffer<JavaFileObject> l) {
- Archive archive = archives.get(directory);
+ ListBuffer<JavaFileObject> resultList) {
+ File d = subdirectory.getFile(directory);
+ if (!caseMapCheck(d, subdirectory))
+ return;
- boolean isFile = fsInfo.isFile(directory);
+ File[] files = d.listFiles();
+ if (files == null)
+ return;
- if (archive != null || isFile) {
- if (archive == null) {
- try {
- archive = openArchive(directory);
- } catch (IOException ex) {
- log.error("error.reading.file",
- directory, getMessage(ex));
- return;
- }
- }
+ if (sortFiles != null)
+ Arrays.sort(files, sortFiles);
- List<String> files = archive.getFiles(subdirectory);
- if (files != null) {
- for (String file; !files.isEmpty(); files = files.tail) {
- file = files.head;
- if (isValidFile(file, fileKinds)) {
- l.append(archive.getFileObject(subdirectory, file));
- }
+ for (File f: files) {
+ String fname = f.getName();
+ if (f.isDirectory()) {
+ if (recurse && SourceVersion.isIdentifier(fname)) {
+ listDirectory(directory,
+ new RelativeDirectory(subdirectory, fname),
+ fileKinds,
+ recurse,
+ resultList);
}
- }
- if (recurse) {
- for (RelativeDirectory s: archive.getSubdirectories()) {
- if (subdirectory.contains(s)) {
- // Because the archive map is a flat list of directories,
- // the enclosing loop will pick up all child subdirectories.
- // Therefore, there is no need to recurse deeper.
- listDirectory(directory, s, fileKinds, false, l);
- }
- }
- }
- } else {
- File d = subdirectory.getFile(directory);
- if (!caseMapCheck(d, subdirectory))
- return;
-
- File[] files = d.listFiles();
- if (files == null)
- return;
-
- if (sortFiles != null)
- Arrays.sort(files, sortFiles);
-
- for (File f: files) {
- String fname = f.getName();
- if (f.isDirectory()) {
- if (recurse && SourceVersion.isIdentifier(fname)) {
- listDirectory(directory,
- new RelativeDirectory(subdirectory, fname),
- fileKinds,
- recurse,
- l);
- }
- } else {
- if (isValidFile(fname, fileKinds)) {
- JavaFileObject fe =
- new RegularFileObject(this, fname, new File(d, fname));
- l.append(fe);
- }
+ } else {
+ if (isValidFile(fname, fileKinds)) {
+ JavaFileObject fe =
+ new RegularFileObject(this, fname, new File(d, fname));
+ resultList.append(fe);
}
}
}
}
+ /**
+ * Insert all files in subdirectory subdirectory of archive archive
+ * which match fileKinds into resultList
+ */
+ private void listArchive(Archive archive,
+ RelativeDirectory subdirectory,
+ Set<JavaFileObject.Kind> fileKinds,
+ boolean recurse,
+ ListBuffer<JavaFileObject> resultList) {
+ // Get the files directly in the subdir
+ List<String> files = archive.getFiles(subdirectory);
+ if (files != null) {
+ for (; !files.isEmpty(); files = files.tail) {
+ String file = files.head;
+ if (isValidFile(file, fileKinds)) {
+ resultList.append(archive.getFileObject(subdirectory, file));
+ }
+ }
+ }
+ if (recurse) {
+ for (RelativeDirectory s: archive.getSubdirectories()) {
+ if (subdirectory.contains(s)) {
+ // Because the archive map is a flat list of directories,
+ // the enclosing loop will pick up all child subdirectories.
+ // Therefore, there is no need to recurse deeper.
+ listArchive(archive, s, fileKinds, false, resultList);
+ }
+ }
+ }
+ }
+
+ /**
+ * container is a directory, a zip file, or a non-existant path.
+ * Insert all files in subdirectory subdirectory of container which
+ * match fileKinds into resultList
+ */
+ private void listContainer(File container,
+ RelativeDirectory subdirectory,
+ Set<JavaFileObject.Kind> fileKinds,
+ boolean recurse,
+ ListBuffer<JavaFileObject> resultList) {
+ Archive archive = archives.get(container);
+ if (archive == null) {
+ // archives are not created for directories.
+ if (fsInfo.isDirectory(container)) {
+ listDirectory(container,
+ subdirectory,
+ fileKinds,
+ recurse,
+ resultList);
+ return;
+ }
+
+ // Not a directory; either a file or non-existant, create the archive
+ try {
+ archive = openArchive(container);
+ } catch (IOException ex) {
+ log.error("error.reading.file",
+ container, getMessage(ex));
+ return;
+ }
+ }
+ listArchive(archive,
+ subdirectory,
+ fileKinds,
+ recurse,
+ resultList);
+ }
+
private boolean isValidFile(String s, Set<JavaFileObject.Kind> fileKinds) {
JavaFileObject.Kind kind = getKind(s);
return fileKinds.contains(kind);
@@ -434,95 +468,92 @@
private static final RelativeDirectory symbolFilePrefix
= new RelativeDirectory("META-INF/sym/rt.jar/");
- /** Open a new zip file directory.
+ /** Open a new zip file directory, and cache it.
*/
protected Archive openArchive(File zipFileName) throws IOException {
- Archive archive = archives.get(zipFileName);
- if (archive == null) {
- File origZipFileName = zipFileName;
- if (!ignoreSymbolFile && paths.isBootClassPathRtJar(zipFileName)) {
- File file = zipFileName.getParentFile().getParentFile(); // ${java.home}
- if (new File(file.getName()).equals(new File("jre")))
- file = file.getParentFile();
- // file == ${jdk.home}
- for (String name : symbolFileLocation)
- file = new File(file, name);
- // file == ${jdk.home}/lib/ct.sym
- if (file.exists())
- zipFileName = file;
- }
+ File origZipFileName = zipFileName;
+ if (!ignoreSymbolFile && paths.isBootClassPathRtJar(zipFileName)) {
+ File file = zipFileName.getParentFile().getParentFile(); // ${java.home}
+ if (new File(file.getName()).equals(new File("jre")))
+ file = file.getParentFile();
+ // file == ${jdk.home}
+ for (String name : symbolFileLocation)
+ file = new File(file, name);
+ // file == ${jdk.home}/lib/ct.sym
+ if (file.exists())
+ zipFileName = file;
+ }
- try {
+ Archive archive;
+ try {
- ZipFile zdir = null;
+ ZipFile zdir = null;
- boolean usePreindexedCache = false;
- String preindexCacheLocation = null;
+ boolean usePreindexedCache = false;
+ String preindexCacheLocation = null;
- if (!useZipFileIndex) {
- zdir = new ZipFile(zipFileName);
- }
- else {
- usePreindexedCache = options.isSet("usezipindex");
- preindexCacheLocation = options.get("java.io.tmpdir");
- String optCacheLoc = options.get("cachezipindexdir");
+ if (!useZipFileIndex) {
+ zdir = new ZipFile(zipFileName);
+ }
+ else {
+ usePreindexedCache = options.isSet("usezipindex");
+ preindexCacheLocation = options.get("java.io.tmpdir");
+ String optCacheLoc = options.get("cachezipindexdir");
- if (optCacheLoc != null && optCacheLoc.length() != 0) {
- if (optCacheLoc.startsWith("\"")) {
- if (optCacheLoc.endsWith("\"")) {
- optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1);
- }
- else {
- optCacheLoc = optCacheLoc.substring(1);
- }
+ if (optCacheLoc != null && optCacheLoc.length() != 0) {
+ if (optCacheLoc.startsWith("\"")) {
+ if (optCacheLoc.endsWith("\"")) {
+ optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1);
+ }
+ else {
+ optCacheLoc = optCacheLoc.substring(1);
}
+ }
- File cacheDir = new File(optCacheLoc);
- if (cacheDir.exists() && cacheDir.canWrite()) {
- preindexCacheLocation = optCacheLoc;
- if (!preindexCacheLocation.endsWith("/") &&
- !preindexCacheLocation.endsWith(File.separator)) {
- preindexCacheLocation += File.separator;
- }
+ File cacheDir = new File(optCacheLoc);
+ if (cacheDir.exists() && cacheDir.canWrite()) {
+ preindexCacheLocation = optCacheLoc;
+ if (!preindexCacheLocation.endsWith("/") &&
+ !preindexCacheLocation.endsWith(File.separator)) {
+ preindexCacheLocation += File.separator;
}
}
}
+ }
- if (origZipFileName == zipFileName) {
- if (!useZipFileIndex) {
- archive = new ZipArchive(this, zdir);
- } else {
- archive = new ZipFileIndexArchive(this,
+ if (origZipFileName == zipFileName) {
+ if (!useZipFileIndex) {
+ archive = new ZipArchive(this, zdir);
+ } else {
+ archive = new ZipFileIndexArchive(this,
ZipFileIndex.getZipFileIndex(zipFileName,
null,
usePreindexedCache,
preindexCacheLocation,
options.isSet("writezipindexfiles")));
- }
+ }
+ } else {
+ if (!useZipFileIndex) {
+ archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix);
}
else {
- if (!useZipFileIndex) {
- archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix);
- }
- else {
- archive = new ZipFileIndexArchive(this,
+ archive = new ZipFileIndexArchive(this,
ZipFileIndex.getZipFileIndex(zipFileName,
symbolFilePrefix,
usePreindexedCache,
preindexCacheLocation,
options.isSet("writezipindexfiles")));
- }
}
- } catch (FileNotFoundException ex) {
- archive = new MissingArchive(zipFileName);
- } catch (IOException ex) {
- if (zipFileName.exists())
- log.error("error.reading.file", zipFileName, getMessage(ex));
- archive = new MissingArchive(zipFileName);
}
+ } catch (FileNotFoundException ex) {
+ archive = new MissingArchive(zipFileName);
+ } catch (IOException ex) {
+ if (zipFileName.exists())
+ log.error("error.reading.file", zipFileName, getMessage(ex));
+ archive = new MissingArchive(zipFileName);
+ }
- archives.put(origZipFileName, archive);
- }
+ archives.put(origZipFileName, archive);
return archive;
}
@@ -589,8 +620,7 @@
ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>();
for (File directory : path)
- listDirectory(directory, subdirectory, kinds, recurse, results);
-
+ listContainer(directory, subdirectory, kinds, recurse, results);
return results.toList();
}
@@ -659,19 +689,22 @@
return null;
for (File dir: path) {
- if (dir.isDirectory()) {
- File f = name.getFile(dir);
- if (f.exists())
- return new RegularFileObject(this, f);
- } else {
- Archive a = openArchive(dir);
- if (a.contains(name)) {
- return a.getFileObject(name.dirname(), name.basename());
+ Archive a = archives.get(dir);
+ if (a == null) {
+ if (fsInfo.isDirectory(dir)) {
+ File f = name.getFile(dir);
+ if (f.exists())
+ return new RegularFileObject(this, f);
+ continue;
}
-
+ // Not a directory, create the archive
+ a = openArchive(dir);
+ }
+ // Process the archive
+ if (a.contains(name)) {
+ return a.getFileObject(name.dirname(), name.basename());
}
}
-
return null;
}
@@ -836,8 +869,9 @@
return false;
if (!path.equals(uri.getPath())) // implicitly checks for embedded . and ..
return false;
- char first = path.charAt(0);
- return first != '.' && first != '/';
+ if (path.startsWith("/") || path.startsWith("./") || path.startsWith("../"))
+ return false;
+ return true;
}
// Convenience method
--- a/langtools/src/share/classes/com/sun/tools/javac/file/Paths.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/Paths.java Wed Jan 19 19:00:30 2011 -0800
@@ -286,9 +286,8 @@
}
public void addFile(File file, boolean warn) {
- File canonFile = fsInfo.getCanonicalFile(file);
- if (contains(file) || canonicalValues.contains(canonFile)) {
- /* Discard duplicates and avoid infinite recursion */
+ if (contains(file)) {
+ // discard duplicates
return;
}
@@ -298,7 +297,17 @@
log.warning(Lint.LintCategory.PATH,
"path.element.not.found", file);
}
- } else if (fsInfo.isFile(file)) {
+ super.add(file);
+ return;
+ }
+
+ File canonFile = fsInfo.getCanonicalFile(file);
+ if (canonicalValues.contains(canonFile)) {
+ /* Discard duplicates and avoid infinite recursion */
+ return;
+ }
+
+ if (fsInfo.isFile(file)) {
/* File is an ordinary file. */
if (!isArchive(file)) {
/* Not a recognized extension; open it to see if
@@ -322,11 +331,11 @@
}
/* Now what we have left is either a directory or a file name
- confirming to archive naming convention */
+ conforming to archive naming convention */
super.add(file);
canonicalValues.add(canonFile);
- if (expandJarClassPaths && fsInfo.exists(file) && fsInfo.isFile(file))
+ if (expandJarClassPaths && fsInfo.isFile(file))
addJarClassPath(file, warn);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jan 19 19:00:30 2011 -0800
@@ -77,6 +77,8 @@
protected static final Context.Key<ClassReader> classReaderKey =
new Context.Key<ClassReader>();
+ public static final int INITIAL_BUFFER_SIZE = 0x0fff0;
+
Annotate annotate;
/** Switch: verbose output.
@@ -185,7 +187,7 @@
/** The buffer containing the currently read class file.
*/
- byte[] buf = new byte[0x0fff0];
+ byte[] buf = new byte[INITIAL_BUFFER_SIZE];
/** The current input pointer.
*/
@@ -2419,8 +2421,14 @@
}
}
}
+ /*
+ * ensureCapacity will increase the buffer as needed, taking note that
+ * the new buffer will always be greater than the needed and never
+ * exactly equal to the needed size or bp. If equal then the read (above)
+ * will infinitely loop as buf.length - bp == 0.
+ */
private static byte[] ensureCapacity(byte[] buf, int needed) {
- if (buf.length < needed) {
+ if (buf.length <= needed) {
byte[] old = buf;
buf = new byte[Integer.highestOneBit(needed) << 1];
System.arraycopy(old, 0, buf, 0, old.length);
--- a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Wed Jan 19 19:00:30 2011 -0800
@@ -376,7 +376,8 @@
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- if (SourceVersion.isIdentifier(dir.getName().toString())) // JSR 292?
+ Path name = dir.getName();
+ if (name == null || SourceVersion.isIdentifier(name.toString())) // JSR 292?
return FileVisitResult.CONTINUE;
else
return FileVisitResult.SKIP_SUBTREE;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6567415/T6567415.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2010, 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 6567415
+ * @summary Test to ensure javac does not go into an infinite loop, while
+ * reading a classfile of a specific length.
+ * @compile -XDignore.symbol.file T6567415.java
+ * @run main T6567415
+ * @author ksrini
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+
+/*
+ * this test compiles Bar.java into a classfile and enlarges the file to the
+ * magic file length, then use this mutated file on the classpath to compile
+ * Foo.java which references Bar.java and Ka-boom. QED.
+ */
+public class T6567415 {
+ final static String TEST_FILE_NAME = "Bar";
+ final static String TEST_JAVA = TEST_FILE_NAME + ".java";
+ final static String TEST_CLASS = TEST_FILE_NAME + ".class";
+
+ final static String TEST2_FILE_NAME = "Foo";
+ final static String TEST2_JAVA = TEST2_FILE_NAME + ".java";
+
+ /*
+ * the following is the initial buffer length set in ClassReader.java
+ * thus this value needs to change if ClassReader buf length changes.
+ */
+
+ final static int BAD_FILE_LENGTH =
+ com.sun.tools.javac.jvm.ClassReader.INITIAL_BUFFER_SIZE;
+
+ static void createClassFile() throws IOException {
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(TEST_JAVA);
+ PrintStream ps = new PrintStream(fos);
+ ps.println("public class " + TEST_FILE_NAME + " {}");
+ } finally {
+ fos.close();
+ }
+ String cmds[] = {TEST_JAVA};
+ com.sun.tools.javac.Main.compile(cmds);
+ }
+
+ static void enlargeClassFile() throws IOException {
+ File f = new File(TEST_CLASS);
+ if (!f.exists()) {
+ System.out.println("file not found: " + TEST_CLASS);
+ System.exit(1);
+ }
+ File tfile = new File(f.getAbsolutePath() + ".tmp");
+ f.renameTo(tfile);
+
+ RandomAccessFile raf = null;
+ FileChannel wfc = null;
+
+ FileInputStream fis = null;
+ FileChannel rfc = null;
+
+ try {
+ raf = new RandomAccessFile(f, "rw");
+ wfc = raf.getChannel();
+
+ fis = new FileInputStream(tfile);
+ rfc = fis.getChannel();
+
+ ByteBuffer bb = MappedByteBuffer.allocate(BAD_FILE_LENGTH);
+ rfc.read(bb);
+ bb.rewind();
+ wfc.write(bb);
+ wfc.truncate(BAD_FILE_LENGTH);
+ } finally {
+ wfc.close();
+ raf.close();
+ rfc.close();
+ fis.close();
+ }
+ System.out.println("file length = " + f.length());
+ }
+
+ static void createJavaFile() throws IOException {
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(TEST2_JAVA);
+ PrintStream ps = new PrintStream(fos);
+ ps.println("public class " + TEST2_FILE_NAME +
+ " {" + TEST_FILE_NAME + " b = new " +
+ TEST_FILE_NAME + " ();}");
+ } finally {
+ fos.close();
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ createClassFile();
+ enlargeClassFile();
+ createJavaFile();
+ Thread t = new Thread () {
+ @Override
+ public void run() {
+ String cmds[] = {"-verbose", "-cp", ".", TEST2_JAVA};
+ int ret = com.sun.tools.javac.Main.compile(cmds);
+ System.out.println("test compilation returns: " + ret);
+ }
+ };
+ t.start();
+ t.join(1000*10);
+ System.out.println(t.getState());
+ if (t.isAlive()) {
+ throw new RuntimeException("Error: compilation is looping");
+ }
+ }
+}
--- a/langtools/test/tools/javac/diags/examples/TypeParameterOnPolymorphicSignature.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/test/tools/javac/diags/examples/TypeParameterOnPolymorphicSignature.java Wed Jan 19 19:00:30 2011 -0800
@@ -24,8 +24,10 @@
// key: compiler.warn.type.parameter.on.polymorphic.signature
// key: compiler.err.unreported.exception.need.to.catch.or.throw
-import java.dyn.InvokeDynamic;
+import java.dyn.MethodHandle;
class TypeParameterOnPolymorphicSignature {
- { InvokeDynamic.<void>call("",123); }
+ void test(MethodHandle mh) {
+ mh.<void>invokeExact("",123);
+ }
}
--- a/langtools/test/tools/javac/failover/CheckAttributedTree.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java Wed Jan 19 19:00:30 2011 -0800
@@ -252,6 +252,13 @@
error("File " + file + " ignored");
}
+ // See CR: 6982992 Tests CheckAttributedTree.java, JavacTreeScannerTest.java, and SourceTreeeScannerTest.java timeout
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ Reporter r = new Reporter(pw);
+ JavacTool tool = JavacTool.create();
+ StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
+
/**
* Read a file.
* @param file the file to be read
@@ -260,12 +267,8 @@
* @throws TreePosTest.ParseException if any errors occur while parsing the file
*/
List<Pair<JCCompilationUnit, JCTree>> read(File file) throws IOException, AttributionException {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- Reporter r = new Reporter(pw);
JavacTool tool = JavacTool.create();
- Charset cs = (encoding == null ? null : Charset.forName(encoding));
- StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
+ r.errors = 0;
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file);
String[] opts = { "-XDshouldStopPolicy=ATTR", "-XDverboseCompilePolicy" };
JavacTask task = tool.getTask(pw, fm, r, Arrays.asList(opts), null, files);
--- a/langtools/test/tools/javac/meth/InvokeDyn.java Mon Jan 17 13:29:12 2011 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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 6754038 6979327
- * @summary Generate call sites for method handle
- * @author jrose
- *
- * @library ..
- * @compile -source 7 -target 7 -XDinvokedynamic -XDallowTransitionalJSR292=no InvokeDyn.java
- */
-//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn
-
-/*
- * Standalone testing:
- * <code>
- * $ cd $MY_REPO_DIR/langtools
- * $ (cd make; make)
- * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeDyn.java
- * $ javap -c -classpath dist meth.InvokeDyn
- * </code>
- */
-
-package meth;
-
-import java.dyn.*;
-
-public class InvokeDyn {
- class CS extends CallSite {
- CS(Object x, Object y, Object z) { throw new RuntimeException(); }
- }
- //@BootstrapMethod(CS.class) //note: requires 6964498
- void test() throws Throwable {
- Object x = "hello";
- Object ojunk; int ijunk;
- ojunk = InvokeDynamic.greet(x, "world", 123);
- ojunk = InvokeDynamic.greet(x, "mundus", 456);
- ojunk = InvokeDynamic.greet(x, "kosmos", 789);
- ojunk = (String) InvokeDynamic.cogitate(10.11121, 3.14);
- //InvokeDynamic.#"yow: what I mean to say is, please treat this one specially"(null);
- ijunk = (int) InvokeDynamic.invoke("goodbye");
- }
-}
--- a/langtools/test/tools/javac/meth/InvokeDynTrans.java Mon Jan 17 13:29:12 2011 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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 6754038 6979327
- * @summary Generate call sites for method handle
- * @author jrose
- *
- * @library ..
- * @compile/fail/ref=InvokeDynTrans.out -Werror -XDrawDiagnostics -source 7 -target 7 InvokeDynTrans.java
- */
-//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn
-
-/*
- * Standalone testing:
- * <code>
- * $ cd $MY_REPO_DIR/langtools
- * $ (cd make; make)
- * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeDyn.java
- * $ javap -c -classpath dist meth.InvokeDyn
- * </code>
- */
-
-package meth;
-
-import java.dyn.InvokeDynamic;
-
-public class InvokeDynTrans {
- void test() throws Throwable {
- Object x = "hello";
- InvokeDynamic.greet(x, "world", 123);
- InvokeDynamic.greet(x, "mundus", 456);
- InvokeDynamic.greet(x, "kosmos", 789);
- InvokeDynamic.<String>cogitate(10.11121, 3.14);
- //InvokeDynamic.<void>#"yow: what I mean to say is, please treat this one specially"(null);
- InvokeDynamic.<int>invoke("goodbye");
- }
-}
--- a/langtools/test/tools/javac/meth/XlintWarn.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/test/tools/javac/meth/XlintWarn.java Wed Jan 19 19:00:30 2011 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6999067
+ * @bug 6999067 7010194
* @summary cast for invokeExact call gets redundant cast to <type> warnings
* @author mcimadamore
*
@@ -34,9 +34,7 @@
class XlintWarn {
void test(MethodHandle mh) throws Throwable {
- int i1 = (int)mh.invoke();
- int i2 = (int)mh.invokeExact();
- int i3 = (int)mh.invokeVarargs();
- int i4 = (int)InvokeDynamic.test();
+ int i1 = (int)mh.invokeExact();
+ int i2 = (int)mh.invokeVarargs();
}
}
--- a/langtools/test/tools/javac/nio/compileTest/CompileTest.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/test/tools/javac/nio/compileTest/CompileTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6906175 6915476 6915497
+ * @bug 6906175 6915476 6915497 7006564
* @summary Path-based JavaFileManager
* @compile -g HelloPathWorld.java
* @run main CompileTest
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/filer/TestValidRelativeNames.java Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2010, 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 6999891
+ * @summary Test valid relative names for Filer.createResource and Filer.getResource
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor
+ * @compile TestValidRelativeNames.java
+ * @compile/process -processor TestValidRelativeNames -Amode=create java.lang.Object
+ * @compile/process -processor TestValidRelativeNames -Amode=get java.lang.Object
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic;
+import javax.tools.StandardLocation;
+
+@SupportedOptions("mode")
+public class TestValidRelativeNames extends JavacTestingAbstractProcessor {
+ enum Kind { READER_WRITER, INPUT_OUTPUT_STREAM };
+
+ static final String[] validRelativeNames = {
+ "foo", "foo.bar", ".foo", ".foo.bar", "foodir/bar", "foodir/.bar"
+ };
+
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver()) {
+ String mode = options.get("mode");
+ for (String relativeBase: validRelativeNames) {
+ for (Kind kind: Kind.values()) {
+ if (mode.equals("create"))
+ testCreate(relativeBase, kind);
+ else
+ testGet(relativeBase, kind);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ void testCreate(String relativeBase, Kind kind) {
+ String relative = getRelative(relativeBase, kind);
+ System.out.println("test create relative path: " + relative + ", kind: " + kind);
+ try {
+ switch (kind) {
+ case READER_WRITER:
+ try (Writer writer = filer.createResource(
+ StandardLocation.CLASS_OUTPUT, "", relative).openWriter()) {
+ writer.write(relative);
+ }
+ break;
+
+ case INPUT_OUTPUT_STREAM:
+ try (OutputStream out = filer.createResource(
+ StandardLocation.CLASS_OUTPUT, "", relative).openOutputStream()) {
+ out.write(relative.getBytes());
+ }
+ break;
+ }
+ } catch (Exception e) {
+ messager.printMessage(Diagnostic.Kind.ERROR,
+ "relative path: " + relative + ", kind: " + kind + ", unexpected exception: " + e);
+ }
+ }
+
+ void testGet(String relativeBase, Kind kind) {
+ String relative = getRelative(relativeBase, kind);
+ System.out.println("test get relative path: " + relative + ", kind: " + kind);
+ try {
+ switch (kind) {
+ case READER_WRITER:
+ try (Reader reader = new BufferedReader(filer.getResource(
+ StandardLocation.CLASS_OUTPUT, "", relative).openReader(true))) {
+ StringBuilder sb = new StringBuilder();
+ char[] buf = new char[1024];
+ int n;
+ while ((n = reader.read(buf, 0, buf.length)) > 0)
+ sb.append(new String(buf, 0, n));
+ if (!sb.toString().equals(relative)) {
+ messager.printMessage(Diagnostic.Kind.ERROR, "unexpected content: " + sb);
+ }
+ }
+ break;
+
+ case INPUT_OUTPUT_STREAM:
+ try (InputStream in = new DataInputStream(filer.getResource(
+ StandardLocation.CLASS_OUTPUT, "", relative).openInputStream())) {
+ StringBuilder sb = new StringBuilder();
+ byte[] buf = new byte[1024];
+ int n;
+ while ((n = in.read(buf, 0, buf.length)) > 0)
+ sb.append(new String(buf, 0, n));
+ if (!sb.toString().equals(relative)) {
+ messager.printMessage(Diagnostic.Kind.ERROR, "unexpected content: " + sb);
+ }
+ }
+ break;
+ }
+ } catch (Exception e) {
+ messager.printMessage(Diagnostic.Kind.ERROR,
+ "relative path: " + relative + ", kind: " + kind + ", unexpected exception: " + e);
+ }
+ }
+
+ String getRelative(String relativeBase, Kind kind) {
+ String suffix = (kind == Kind.READER_WRITER ? "RW" : "IOS");
+ return relativeBase.replace("foo", "foo" + suffix);
+ }
+}
+
--- a/langtools/test/tools/javac/tree/AbstractTreeScannerTest.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/test/tools/javac/tree/AbstractTreeScannerTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -143,6 +143,13 @@
abstract int test(JCCompilationUnit t);
+ // See CR: 6982992 Tests CheckAttributedTree.java, JavacTreeScannerTest.java, and SourceTreeeScannerTest.java timeout
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ Reporter r = new Reporter(pw);
+ JavacTool tool = JavacTool.create();
+ StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
+
/**
* Read a file.
* @param file the file to be read
@@ -151,11 +158,8 @@
* @throws TreePosTest.ParseException if any errors occur while parsing the file
*/
JCCompilationUnit read(File file) throws IOException, ParseException {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- Reporter r = new Reporter(pw);
JavacTool tool = JavacTool.create();
- StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
+ r.errors = 0;
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file);
JavacTask task = tool.getTask(pw, fm, r, Collections.<String>emptyList(), null, files);
Iterable<? extends CompilationUnitTree> trees = task.parse();
--- a/langtools/test/tools/javac/tree/TreePosTest.java Mon Jan 17 13:29:12 2011 +0530
+++ b/langtools/test/tools/javac/tree/TreePosTest.java Wed Jan 19 19:00:30 2011 -0800
@@ -249,6 +249,13 @@
error("File " + file + " ignored");
}
+ // See CR: 6982992 Tests CheckAttributedTree.java, JavacTreeScannerTest.java, and SourceTreeeScannerTest.java timeout
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ Reporter r = new Reporter(pw);
+ JavacTool tool = JavacTool.create();
+ StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
+
/**
* Read a file.
* @param file the file to be read
@@ -257,12 +264,8 @@
* @throws TreePosTest.ParseException if any errors occur while parsing the file
*/
JCCompilationUnit read(File file) throws IOException, ParseException {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- Reporter r = new Reporter(pw);
JavacTool tool = JavacTool.create();
- Charset cs = (encoding == null ? null : Charset.forName(encoding));
- StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
+ r.errors = 0;
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file);
JavacTask task = tool.getTask(pw, fm, r, Collections.<String>emptyList(), null, files);
Iterable<? extends CompilationUnitTree> trees = task.parse();