--- a/.hgtags Fri Apr 16 09:54:13 2010 +0100
+++ b/.hgtags Sat Apr 17 08:12:00 2010 -0700
@@ -60,3 +60,7 @@
34c8199936a1682aa8587857f44cfaf37c2b6381 jdk7-b83
b1e55627a6980b9508854ed0c0f21d4f981b4494 jdk7-b84
b6f633a93ae0ec4555ff4bf756f5e2150c9bdede jdk7-b85
+c94d9cc81f495d97817eba9d71b84fc45f7661a5 jdk7-b86
+b7456c473862048fa70ed8092313a4ef0a55d403 jdk7-b87
+7077b95d42f6b3942a8751bba033801ff50e5889 jdk7-b88
+44158f6d3b94c0fa020e33632532473d92d1ea96 jdk7-b89
--- a/.hgtags-top-repo Fri Apr 16 09:54:13 2010 +0100
+++ b/.hgtags-top-repo Sat Apr 17 08:12:00 2010 -0700
@@ -60,3 +60,7 @@
6880a3af9addb41541e80ebe8cde6f79ec402a58 jdk7-b83
2f3ea057d1ad56cf3b269cdc4de2741411151982 jdk7-b84
cf26288a114be67c39f2758959ce50b60f5ae330 jdk7-b85
+433a60a9c0bf1b26ee7e65cebaa89c541f497aed jdk7-b86
+6b1069f53fbc30663ccef49d78c31bb7d6967bde jdk7-b87
+82135c848d5fcddb065e98ae77b81077c858f593 jdk7-b88
+7f1ba4459972bf84b8201dc1cc4f62b1fe1c74f4 jdk7-b89
--- a/corba/.hgtags Fri Apr 16 09:54:13 2010 +0100
+++ b/corba/.hgtags Sat Apr 17 08:12:00 2010 -0700
@@ -60,3 +60,7 @@
fde0df7a2384f7fe33204a79678989807d9c2b98 jdk7-b83
68c8961a82e4a3ad2a67991e5d834192a81eb4cd jdk7-b84
c67a9df7bc0ca291f08f9a9cc05cb78ea15d25e6 jdk7-b85
+6253e28826d16cf1aecc39ce04c8de1f6bf2df5f jdk7-b86
+09a41111a401d327f65e453384d976a10154d9ea jdk7-b87
+39e14d2da687c7e592142137517aaf689544820f jdk7-b88
+bb4424c5e778b842c064a8b1aa902b35f4397654 jdk7-b89
--- a/hotspot/.hgtags Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/.hgtags Sat Apr 17 08:12:00 2010 -0700
@@ -83,3 +83,9 @@
ffc8d176b84bcfb5ac21302b4feb3b0c0d69b97c jdk7-b84
6c9796468b91dcbb39e09dfa1baf9779ac45eb66 jdk7-b85
418bc80ce13995149eadc9eecbba21d7a9fa02ae hs17-b10
+bf823ef06b4f211e66988d76a2e2669be5c0820e jdk7-b86
+07226e9eab8f74b37346b32715f829a2ef2c3188 hs18-b01
+e7e7e36ccdb5d56edd47e5744351202d38f3b7ad jdk7-b87
+4b60f23c42231f7ecd62ad1fcb6a9ca26fa57d1b jdk7-b88
+15836273ac2494f36ef62088bc1cb6f3f011f565 jdk7-b89
+4b60f23c42231f7ecd62ad1fcb6a9ca26fa57d1b hs18-b02
--- a/hotspot/agent/src/os/linux/libproc_impl.c Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/agent/src/os/linux/libproc_impl.c Sat Apr 17 08:12:00 2010 -0700
@@ -174,7 +174,7 @@
return NULL;
}
- newlib->symtab = build_symtab(newlib->fd);
+ newlib->symtab = build_symtab(newlib->fd, libname);
if (newlib->symtab == NULL) {
print_debug("symbol table build failed for %s\n", newlib->name);
}
--- a/hotspot/agent/src/os/linux/symtab.c Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/agent/src/os/linux/symtab.c Sat Apr 17 08:12:00 2010 -0700
@@ -53,8 +53,274 @@
struct hsearch_data *hash_table;
} symtab_t;
-// read symbol table from given fd.
-struct symtab* build_symtab(int fd) {
+
+// Directory that contains global debuginfo files. In theory it
+// should be possible to change this, but in a Java environment there
+// is no obvious place to put a user interface to do it. Maybe this
+// could be set with an environment variable.
+static const char debug_file_directory[] = "/usr/lib/debug";
+
+/* The CRC used in gnu_debuglink, retrieved from
+ http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files. */
+unsigned int gnu_debuglink_crc32 (unsigned int crc,
+ unsigned char *buf, size_t len)
+{
+ static const unsigned int crc32_table[256] =
+ {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d
+ };
+ unsigned char *end;
+
+ crc = ~crc & 0xffffffff;
+ for (end = buf + len; buf < end; ++buf)
+ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ return ~crc & 0xffffffff;
+}
+
+/* Open a debuginfo file and check its CRC. If it exists and the CRC
+ matches return its fd. */
+static int
+open_debug_file (const char *pathname, unsigned int crc)
+{
+ unsigned int file_crc = 0;
+ unsigned char buffer[8 * 1024];
+
+ int fd = pathmap_open(pathname);
+
+ if (fd < 0)
+ return -1;
+
+ lseek(fd, 0, SEEK_SET);
+
+ for (;;) {
+ int len = read(fd, buffer, sizeof buffer);
+ if (len <= 0)
+ break;
+ file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
+ }
+
+ if (crc == file_crc)
+ return fd;
+ else {
+ close(fd);
+ return -1;
+ }
+}
+
+/* Find an ELF section. */
+static struct elf_section *find_section_by_name(char *name,
+ int fd,
+ ELF_EHDR *ehdr,
+ ELF_SHDR *shbuf,
+ struct elf_section *scn_cache)
+{
+ ELF_SHDR* cursct = NULL;
+ char *strtab;
+ int cnt;
+
+ if (scn_cache[ehdr->e_shstrndx].c_data == NULL) {
+ if ((scn_cache[ehdr->e_shstrndx].c_data
+ = read_section_data(fd, ehdr, cursct)) == NULL) {
+ return NULL;
+ }
+ }
+
+ strtab = scn_cache[ehdr->e_shstrndx].c_data;
+
+ for (cursct = shbuf, cnt = 0;
+ cnt < ehdr->e_shnum;
+ cnt++, cursct++) {
+ if (strcmp(cursct->sh_name + strtab, name) == 0) {
+ scn_cache[cnt].c_data = read_section_data(fd, ehdr, cursct);
+ return &scn_cache[cnt];
+ }
+ }
+
+ return NULL;
+}
+
+/* Look for a ".gnu_debuglink" section. If one exists, try to open a
+ suitable debuginfo file. */
+static int open_file_from_debug_link(const char *name,
+ int fd,
+ ELF_EHDR *ehdr,
+ ELF_SHDR *shbuf,
+ struct elf_section *scn_cache)
+{
+ int debug_fd;
+ struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr,
+ shbuf, scn_cache);
+ if (debug_link == NULL)
+ return -1;
+ char *debug_filename = debug_link->c_data;
+ int offset = (strlen(debug_filename) + 4) >> 2;
+ static unsigned int crc;
+ crc = ((unsigned int*)debug_link->c_data)[offset];
+ char *debug_pathname = malloc(strlen(debug_filename)
+ + strlen(name)
+ + strlen(".debug/")
+ + strlen(debug_file_directory)
+ + 2);
+ strcpy(debug_pathname, name);
+ char *last_slash = strrchr(debug_pathname, '/');
+ if (last_slash == NULL)
+ return -1;
+
+ /* Look in the same directory as the object. */
+ strcpy(last_slash+1, debug_filename);
+
+ debug_fd = open_debug_file(debug_pathname, crc);
+ if (debug_fd >= 0) {
+ free(debug_pathname);
+ return debug_fd;
+ }
+
+ /* Look in a subdirectory named ".debug". */
+ strcpy(last_slash+1, ".debug/");
+ strcat(last_slash, debug_filename);
+
+ debug_fd = open_debug_file(debug_pathname, crc);
+ if (debug_fd >= 0) {
+ free(debug_pathname);
+ return debug_fd;
+ }
+
+ /* Look in /usr/lib/debug + the full pathname. */
+ strcpy(debug_pathname, debug_file_directory);
+ strcat(debug_pathname, name);
+ last_slash = strrchr(debug_pathname, '/');
+ strcpy(last_slash+1, debug_filename);
+
+ debug_fd = open_debug_file(debug_pathname, crc);
+ if (debug_fd >= 0) {
+ free(debug_pathname);
+ return debug_fd;
+ }
+
+ free(debug_pathname);
+ return -1;
+}
+
+static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo);
+
+/* Look for a ".gnu_debuglink" section. If one exists, try to open a
+ suitable debuginfo file and read a symbol table from it. */
+static struct symtab *build_symtab_from_debug_link(const char *name,
+ int fd,
+ ELF_EHDR *ehdr,
+ ELF_SHDR *shbuf,
+ struct elf_section *scn_cache)
+{
+ fd = open_file_from_debug_link(name, fd, ehdr, shbuf, scn_cache);
+
+ if (fd >= 0) {
+ struct symtab *symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false);
+ close(fd);
+ return symtab;
+ }
+
+ return NULL;
+}
+
+// Given a build_id, find the associated debuginfo file
+static char *
+build_id_to_debug_filename (size_t size, unsigned char *data)
+{
+ char *filename, *s;
+
+ filename = malloc(strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
+ + 2 * size + (sizeof ".debug" - 1) + 1);
+ s = filename + sprintf (filename, "%s/.build-id/", debug_file_directory);
+ if (size > 0)
+ {
+ size--;
+ s += sprintf (s, "%02x", *data++);
+ }
+ if (size > 0)
+ *s++ = '/';
+ while (size-- > 0)
+ s += sprintf (s, "%02x", *data++);
+ strcpy (s, ".debug");
+
+ return filename;
+}
+
+// Read a build ID note. Try to open any associated debuginfo file
+// and return its symtab
+static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note)
+{
+ int fd;
+ struct symtab *symtab = NULL;
+
+ unsigned char *bytes
+ = (unsigned char*)(note+1) + note->n_namesz;
+ unsigned char *filename
+ = (build_id_to_debug_filename (note->n_descsz, bytes));
+
+ fd = pathmap_open(filename);
+ if (fd >= 0) {
+ symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false);
+ close(fd);
+ }
+ free(filename);
+
+ return symtab;
+}
+
+// read symbol table from given fd. If try_debuginfo) is true, also
+// try to open an associated debuginfo file
+static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo) {
ELF_EHDR ehdr;
char *names = NULL;
struct symtab* symtab = NULL;
@@ -66,6 +332,7 @@
ELF_SHDR* cursct = NULL;
ELF_PHDR* phbuf = NULL;
ELF_PHDR* phdr = NULL;
+ int sym_section = SHT_DYNSYM;
uintptr_t baseaddr = (uintptr_t)-1;
@@ -90,18 +357,23 @@
for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
scn_cache[cnt].c_shdr = cursct;
- if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB) {
+ if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB
+ || cursct->sh_type == SHT_NOTE || cursct->sh_type == SHT_DYNSYM) {
if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
goto quit;
}
}
+ if (cursct->sh_type == SHT_SYMTAB) {
+ // Full symbol table available so use that
+ sym_section = cursct->sh_type;
+ }
cursct++;
}
for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
- if (shdr->sh_type == SHT_SYMTAB) {
+ if (shdr->sh_type == sym_section) {
ELF_SYM *syms;
int j, n, rslt;
size_t size;
@@ -163,6 +435,45 @@
}
}
+ // Look for a separate debuginfo file.
+ if (try_debuginfo) {
+
+ // We prefer a debug symtab to an object's own symtab, so look in
+ // the debuginfo file. We stash a copy of the old symtab in case
+ // there is no debuginfo.
+ struct symtab* prev_symtab = symtab;
+ symtab = NULL;
+
+#ifdef NT_GNU_BUILD_ID
+ // First we look for a Build ID
+ for (cursct = shbuf, cnt = 0;
+ symtab == NULL && cnt < ehdr.e_shnum;
+ cnt++) {
+ if (cursct->sh_type == SHT_NOTE) {
+ Elf64_Nhdr *note = (Elf64_Nhdr *)scn_cache[cnt].c_data;
+ if (note->n_type == NT_GNU_BUILD_ID) {
+ symtab = build_symtab_from_build_id(note);
+ }
+ }
+ cursct++;
+ }
+#endif
+
+ // Then, if that doesn't work, the debug link
+ if (symtab == NULL) {
+ symtab = build_symtab_from_debug_link(filename, fd, &ehdr, shbuf,
+ scn_cache);
+ }
+
+ // If we still haven't found a symtab, use the object's own symtab.
+ if (symtab != NULL) {
+ if (prev_symtab != NULL)
+ destroy_symtab(prev_symtab);
+ } else {
+ symtab = prev_symtab;
+ }
+ }
+
quit:
if (shbuf) free(shbuf);
if (phbuf) free(phbuf);
@@ -177,6 +488,11 @@
return symtab;
}
+struct symtab* build_symtab(int fd, const char *filename) {
+ return build_symtab_internal(fd, filename, /* try_debuginfo */ true);
+}
+
+
void destroy_symtab(struct symtab* symtab) {
if (!symtab) return;
if (symtab->strs) free(symtab->strs);
--- a/hotspot/agent/src/os/linux/symtab.h Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/agent/src/os/linux/symtab.h Sat Apr 17 08:12:00 2010 -0700
@@ -32,7 +32,7 @@
struct symtab;
// build symbol table for a given ELF file descriptor
-struct symtab* build_symtab(int fd);
+struct symtab* build_symtab(int fd, const char *filename);
// destroy the symbol table
void destroy_symtab(struct symtab* symtab);
--- a/hotspot/make/hotspot_version Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/make/hotspot_version Sat Apr 17 08:12:00 2010 -0700
@@ -31,11 +31,11 @@
#
# Don't put quotes (fail windows build).
-HOTSPOT_VM_COPYRIGHT=Copyright 2009
+HOTSPOT_VM_COPYRIGHT=Copyright 2010
-HS_MAJOR_VER=17
+HS_MAJOR_VER=18
HS_MINOR_VER=0
-HS_BUILD_NUMBER=10
+HS_BUILD_NUMBER=03
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/linux/makefiles/build_vm_def.sh Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+nm --defined-only $* | awk '
+ { if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";" }
+ '
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Sat Apr 17 08:12:00 2010 -0700
@@ -290,6 +290,9 @@
# This is for Forte Analyzer profiling support.
AsyncGetCallTrace;
+
+ # INSERT VTABLE SYMBOLS HERE
+
local:
*;
};
--- a/hotspot/make/linux/makefiles/mapfile-vers-product Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product Sat Apr 17 08:12:00 2010 -0700
@@ -285,6 +285,9 @@
# This is for Forte Analyzer profiling support.
AsyncGetCallTrace;
+
+ # INSERT VTABLE SYMBOLS HERE
+
local:
*;
};
--- a/hotspot/make/linux/makefiles/vm.make Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/make/linux/makefiles/vm.make Sat Apr 17 08:12:00 2010 -0700
@@ -121,14 +121,21 @@
vm_version.o: $(filter-out vm_version.o,$(JVM_OBJ_FILES))
-mapfile : $(MAPFILE)
+mapfile : $(MAPFILE) vm.def
rm -f $@
- cat $^ > $@
+ awk '{ if ($$0 ~ "INSERT VTABLE SYMBOLS HERE") \
+ { system ("cat vm.def"); } \
+ else \
+ { print $$0 } \
+ }' > $@ < $(MAPFILE)
mapfile_reorder : mapfile $(REORDERFILE)
rm -f $@
cat $^ > $@
+vm.def: $(Res_Files) $(Obj_Files)
+ sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
+
ifeq ($(ZERO_LIBARCH), ppc64)
STATIC_CXX = false
else
--- a/hotspot/make/windows/build.bat Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/make/windows/build.bat Sat Apr 17 08:12:00 2010 -0700
@@ -28,6 +28,9 @@
REM Since we don't have uname and we could be cross-compiling,
REM Use the compiler to determine which ARCH we are building
REM
+REM Note: Running this batch file from the Windows command shell requires
+REM that "grep" be accessible on the PATH. An MKS install does this.
+REM
cl 2>&1 | grep "IA-64" >NUL
if %errorlevel% == 0 goto isia64
cl 2>&1 | grep "AMD64" >NUL
@@ -57,11 +60,12 @@
if "%1" == "product" goto test1
if "%1" == "debug" goto test1
if "%1" == "fastdebug" goto test1
+if "%1" == "tree" goto test1
goto usage
:test1
if "%2" == "core" goto test2
-if "%2" == "kernel" goto test2
+if "%2" == "kernel" goto test2
if "%2" == "compiler1" goto test2
if "%2" == "compiler2" goto test2
if "%2" == "tiered" goto test2
@@ -70,6 +74,7 @@
goto usage
:test2
+if "%1" == "tree" goto build_tree
REM check_j2se_version
REM jvmti.make requires J2SE 1.4.x or newer.
REM If not found then fail fast.
@@ -93,6 +98,10 @@
nmake -f %3/make/windows/build.make Variant=compiler2 WorkSpace=%3 BootStrapDir=%4 BuildUser="%USERNAME%" HOTSPOT_BUILD_VERSION=%5 ADLC_ONLY=1 %1
goto end
+:build_tree
+nmake -f %3/make/windows/build.make Variant=%2 WorkSpace=%3 BootStrapDir=%4 BuildUser="%USERNAME%" HOTSPOT_BUILD_VERSION="%5" %1
+goto end
+
:usage
echo Usage: build flavor version workspace bootstrap_dir [build_id] [windbg_home]
echo.
@@ -100,8 +109,10 @@
echo flavor is "product", "debug" or "fastdebug",
echo version is "core", "kernel", "compiler1", "compiler2", or "tiered",
echo workspace is source directory without trailing slash,
-echo bootstrap_dir is a full path to echo a JDK in which bin/java
-echo and bin/javac are present and working, and echo build_id is an
+echo bootstrap_dir is a full path to a JDK in which bin/java
+echo and bin/javac are present and working, and build_id is an
echo optional build identifier displayed by java -version
+exit /b 1
:end
+exit /b %errorlevel%
--- a/hotspot/make/windows/build.make Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/make/windows/build.make Sat Apr 17 08:12:00 2010 -0700
@@ -27,6 +27,9 @@
# environment variables (Variant, WorkSpace, BootStrapDir, BuildUser, HOTSPOT_BUILD_VERSION)
# are passed in as command line arguments.
+# Note: Running nmake or build.bat from the Windows command shell requires
+# that "sh" be accessible on the PATH. An MKS install does this.
+
# SA components are built if BUILD_WIN_SA=1 is specified.
# See notes in README. This produces files:
# 1. sa-jdi.jar - This is built before building jvm.dll
@@ -233,6 +236,12 @@
cd $(variantDir)
nmake -nologo -f $(WorkSpace)\make\windows\makefiles\top.make BUILD_FLAVOR=product DEVELOP=1 ARCH=$(ARCH)
+# target to create just the directory structure
+tree: checks $(variantDir) $(variantDir)\local.make sanity
+ mkdir $(variantDir)\product
+ mkdir $(variantDir)\debug
+ mkdir $(variantDir)\fastdebug
+
sanity:
@ echo;
@ cd $(variantDir)
--- a/hotspot/make/windows/create.bat Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/make/windows/create.bat Sat Apr 17 08:12:00 2010 -0700
@@ -36,6 +36,9 @@
REM Since we don't have uname and we could be cross-compiling,
REM Use the compiler to determine which ARCH we are building
REM
+REM Note: Running this batch file from the Windows command shell requires
+REM that "grep" be accessible on the PATH. An MKS install does this.
+REM
cl 2>&1 | grep "IA-64" >NUL
if %errorlevel% == 0 goto isia64
cl 2>&1 | grep "AMD64" >NUL
--- a/hotspot/make/windows/get_msc_ver.sh Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/make/windows/get_msc_ver.sh Sat Apr 17 08:12:00 2010 -0700
@@ -22,6 +22,8 @@
#
#
+set -e
+
# This shell script echoes "MSC_VER=<munged version of cl>"
# It ignores the micro version component.
# Examples:
@@ -38,17 +40,20 @@
# sh, and it has been found that sometimes `which sh` fails.
if [ "x$HotSpotMksHome" != "x" ]; then
- MKS_HOME="$HotSpotMksHome"
+ TOOL_DIR="$HotSpotMksHome"
else
- SH=`which sh`
- MKS_HOME=`dirname "$SH"`
+ # HotSpotMksHome is not set so use the directory that contains "sh".
+ # This works with both MKS and Cygwin.
+ SH=`which sh`
+ TOOL_DIR=`dirname "$SH"`
fi
-HEAD="$MKS_HOME/head"
-ECHO="$MKS_HOME/echo"
-EXPR="$MKS_HOME/expr"
-CUT="$MKS_HOME/cut"
-SED="$MKS_HOME/sed"
+DIRNAME="$TOOL_DIR/dirname"
+HEAD="$TOOL_DIR/head"
+ECHO="$TOOL_DIR/echo"
+EXPR="$TOOL_DIR/expr"
+CUT="$TOOL_DIR/cut"
+SED="$TOOL_DIR/sed"
if [ "x$FORCE_MSC_VER" != "x" ]; then
echo "MSC_VER=$FORCE_MSC_VER"
@@ -70,7 +75,15 @@
if [ "x$FORCE_LINK_VER" != "x" ]; then
echo "LINK_VER=$FORCE_LINK_VER"
else
- LINK_VER_RAW=`link 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[\ ]*\([0-9][0-9.]*\).*/\1/'`
+ # use the "link" command that is co-located with the "cl" command
+ cl_cmd=`which cl`
+ if [ "x$cl_cmd" != "x" ]; then
+ link_cmd=`$DIRNAME "$cl_cmd"`/link
+ else
+ # which can't find "cl" so just use which ever "link" we find
+ link_cmd="link"
+ fi
+ LINK_VER_RAW=`"$link_cmd" 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[\ ]*\([0-9][0-9.]*\).*/\1/'`
LINK_VER_MAJOR=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f1`
LINK_VER_MINOR=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f2`
LINK_VER_MICRO=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f3`
--- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -377,6 +377,16 @@
}
+
+void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
+ __ bind(_entry);
+ __ call(SharedRuntime::deopt_blob()->unpack_with_reexecution());
+ __ delayed()->nop();
+ ce->add_call_info_here(_info);
+ debug_only(__ should_not_reach_here());
+}
+
+
void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
//---------------slow case: call to native-----------------
__ bind(_entry);
--- a/hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -143,3 +143,6 @@
static bool is_caller_save_register (LIR_Opr reg);
static bool is_caller_save_register (Register r);
+
+ // JSR 292
+ static LIR_Opr& method_handle_invoke_SP_save_opr() { return L7_opr; }
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -378,12 +378,7 @@
int offset = code_offset();
- if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) {
- __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
- __ delayed()->nop();
- }
-
- __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type);
+ __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
__ delayed()->nop();
debug_only(__ stop("should have gone to the caller");)
assert(code_offset() - offset <= exception_handler_size, "overflow");
@@ -685,29 +680,29 @@
}
-void LIR_Assembler::call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info) {
- __ call(entry, rtype);
+void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
+ __ call(op->addr(), rtype);
// the peephole pass fills the delay slot
}
-void LIR_Assembler::ic_call(address entry, CodeEmitInfo* info) {
+void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
RelocationHolder rspec = virtual_call_Relocation::spec(pc());
__ set_oop((jobject)Universe::non_oop_word(), G5_inline_cache_reg);
__ relocate(rspec);
- __ call(entry, relocInfo::none);
+ __ call(op->addr(), relocInfo::none);
// the peephole pass fills the delay slot
}
-void LIR_Assembler::vtable_call(int vtable_offset, CodeEmitInfo* info) {
- add_debug_info_for_null_check_here(info);
+void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
+ add_debug_info_for_null_check_here(op->info());
__ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
- if (__ is_simm13(vtable_offset) ) {
- __ ld_ptr(G3_scratch, vtable_offset, G5_method);
+ if (__ is_simm13(op->vtable_offset())) {
+ __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method);
} else {
// This will generate 2 instructions
- __ set(vtable_offset, G5_method);
+ __ set(op->vtable_offset(), G5_method);
// ld_ptr, set_hi, set
__ ld_ptr(G3_scratch, G5_method, G5_method);
}
@@ -717,6 +712,16 @@
}
+void LIR_Assembler::preserve_SP(LIR_OpJavaCall* op) {
+ Unimplemented();
+}
+
+
+void LIR_Assembler::restore_SP(LIR_OpJavaCall* op) {
+ Unimplemented();
+}
+
+
// load with 32-bit displacement
int LIR_Assembler::load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo *info) {
int load_offset = code_offset();
@@ -1067,7 +1072,8 @@
LIR_Const* c = src->as_constant_ptr();
switch (c->type()) {
case T_INT:
- case T_FLOAT: {
+ case T_FLOAT:
+ case T_ADDRESS: {
Register src_reg = O7;
int value = c->as_jint_bits();
if (value == 0) {
@@ -1123,7 +1129,8 @@
}
switch (c->type()) {
case T_INT:
- case T_FLOAT: {
+ case T_FLOAT:
+ case T_ADDRESS: {
LIR_Opr tmp = FrameMap::O7_opr;
int value = c->as_jint_bits();
if (value == 0) {
@@ -1195,6 +1202,7 @@
switch (c->type()) {
case T_INT:
+ case T_ADDRESS:
{
jint con = c->as_jint();
if (to_reg->is_single_cpu()) {
@@ -1720,9 +1728,13 @@
ShouldNotReachHere();
}
} else if (code == lir_cmp_l2i) {
+#ifdef _LP64
+ __ lcmp(left->as_register_lo(), right->as_register_lo(), dst->as_register());
+#else
__ lcmp(left->as_register_hi(), left->as_register_lo(),
right->as_register_hi(), right->as_register_lo(),
dst->as_register());
+#endif
} else {
ShouldNotReachHere();
}
@@ -2841,7 +2853,7 @@
void LIR_Assembler::align_backward_branch_target() {
- __ align(16);
+ __ align(OptoLoopAlignment);
}
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -42,17 +42,6 @@
}
-void C1_MacroAssembler::method_exit(bool restore_frame) {
- // this code must be structured this way so that the return
- // instruction can be a safepoint.
- if (restore_frame) {
- restore();
- }
- retl();
- delayed()->nop();
-}
-
-
void C1_MacroAssembler::explicit_null_check(Register base) {
Unimplemented();
}
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -677,7 +677,7 @@
__ add(I7, frame::pc_return_offset, Oissuing_pc->after_save());
__ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
- Oissuing_pc->after_save());
+ G2_thread, Oissuing_pc->after_save());
__ verify_not_null_oop(Oexception->after_save());
__ jmp(O0, 0);
__ delayed()->restore();
@@ -985,7 +985,6 @@
void Runtime1::generate_handle_exception(StubAssembler* sasm, OopMapSet* oop_maps, OopMap* oop_map, bool) {
Label no_deopt;
- Label no_handler;
__ verify_not_null_oop(Oexception);
@@ -1003,9 +1002,14 @@
// whether it had a handler or not we will deoptimize
// by entering the deopt blob with a pending exception.
+#ifdef ASSERT
+ Label done;
__ tst(O0);
- __ br(Assembler::zero, false, Assembler::pn, no_handler);
+ __ br(Assembler::notZero, false, Assembler::pn, done);
__ delayed()->nop();
+ __ stop("should have found address");
+ __ bind(done);
+#endif
// restore the registers that were saved at the beginning and jump to the exception handler.
restore_live_registers(sasm);
@@ -1013,20 +1017,6 @@
__ jmp(O0, 0);
__ delayed()->restore();
- __ bind(no_handler);
- __ mov(L0, I7); // restore return address
-
- // restore exception oop
- __ ld_ptr(G2_thread, in_bytes(JavaThread::exception_oop_offset()), Oexception->after_save());
- __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
-
- __ restore();
-
- AddressLiteral exc(Runtime1::entry_for(Runtime1::unwind_exception_id));
- __ jump_to(exc, G4);
- __ delayed()->nop();
-
-
oop_maps->add_gc_map(call_offset, oop_map);
}
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -60,9 +60,6 @@
define_pd_global(intx, INTPRESSURE, 48); // large register set
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
-// The default setting 16/16 seems to work best.
-// (For _228_jack 16/16 is 2% better than 4/4, 16/4, 32/32, 32/16, or 16/32.)
-define_pd_global(intx, OptoLoopAlignment, 16); // = 4*wordSize
define_pd_global(intx, RegisterCostAreaRatio, 12000);
define_pd_global(bool, UseTLAB, true);
define_pd_global(bool, ResizeTLAB, true);
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -40,6 +40,9 @@
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
define_pd_global(intx, CodeEntryAlignment, 32);
+// The default setting 16/16 seems to work best.
+// (For _228_jack 16/16 is 2% better than 4/4, 16/4, 32/32, 32/16, or 16/32.)
+define_pd_global(intx, OptoLoopAlignment, 16); // = 4*wordSize
define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
define_pd_global(intx, InlineSmallCode, 1500);
#ifdef _LP64
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -244,9 +244,10 @@
}
-void InterpreterMacroAssembler::super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1) {
+void InterpreterMacroAssembler::super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2) {
mov(arg_1, O0);
- MacroAssembler::call_VM_leaf_base(thread_cache, entry_point, 1);
+ mov(arg_2, O1);
+ MacroAssembler::call_VM_leaf_base(thread_cache, entry_point, 2);
}
#endif /* CC_INTERP */
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -121,7 +121,7 @@
bool check_exception = true);
#ifndef CC_INTERP
- void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1);
+ void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2);
// Generate a subtype check: branch to ok_is_subtype if sub_klass is
// a subtype of super_klass. Blows registers tmp1, tmp2 and tmp3.
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Sat Apr 17 08:12:00 2010 -0700
@@ -471,6 +471,9 @@
source %{
#define __ _masm.
+// Block initializing store
+#define ASI_BLK_INIT_QUAD_LDD_P 0xE2
+
// tertiary op of a LoadP or StoreP encoding
#define REGP_OP true
@@ -1803,8 +1806,9 @@
// to implement the UseStrictFP mode.
const bool Matcher::strict_fp_requires_explicit_rounding = false;
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = false;
+// Are floats conerted to double when stored to stack during deoptimization?
+// Sparc does not handle callee-save floats.
+bool Matcher::float_in_double() { return false; }
// Do ints take an entire long register or just half?
// Note that we if-def off of _LP64.
@@ -6146,6 +6150,7 @@
%}
instruct prefetchw( memory mem ) %{
+ predicate(AllocatePrefetchStyle != 3 );
match( PrefetchWrite mem );
ins_cost(MEMORY_REF_COST);
@@ -6155,6 +6160,23 @@
ins_pipe(iload_mem);
%}
+// Use BIS instruction to prefetch.
+instruct prefetchw_bis( memory mem ) %{
+ predicate(AllocatePrefetchStyle == 3);
+ match( PrefetchWrite mem );
+ ins_cost(MEMORY_REF_COST);
+
+ format %{ "STXA G0,$mem\t! // Block initializing store" %}
+ ins_encode %{
+ Register base = as_Register($mem$$base);
+ int disp = $mem$$disp;
+ if (disp != 0) {
+ __ add(base, AllocatePrefetchStepSize, base);
+ }
+ __ stxa(G0, base, G0, ASI_BLK_INIT_QUAD_LDD_P);
+ %}
+ ins_pipe(istore_mem_reg);
+%}
//----------Store Instructions-------------------------------------------------
// Store Byte
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -379,7 +379,7 @@
__ save_frame(0); // compensates for compiler weakness
__ add(O7->after_save(), frame::pc_return_offset, Lscratch); // save the issuing PC
BLOCK_COMMENT("call exception_handler_for_return_address");
- __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), Lscratch);
+ __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), G2_thread, Lscratch);
__ mov(O0, handler_reg);
__ restore(); // compensates for compiler weakness
@@ -1148,7 +1148,7 @@
__ andn(from, 7, from); // Align address
__ ldx(from, 0, O3);
__ inc(from, 8);
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_loop);
__ ldx(from, 0, O4);
__ deccc(count, count_dec); // Can we do next iteration after this one?
@@ -1220,7 +1220,7 @@
//
__ andn(end_from, 7, end_from); // Align address
__ ldx(end_from, 0, O3);
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_loop);
__ ldx(end_from, -8, O4);
__ deccc(count, count_dec); // Can we do next iteration after this one?
@@ -1349,7 +1349,7 @@
__ BIND(L_copy_byte);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_byte_loop);
__ ldub(from, offset, O3);
__ deccc(count);
@@ -1445,7 +1445,7 @@
L_aligned_copy, L_copy_byte);
}
// copy 4 elements (16 bytes) at a time
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_aligned_copy);
__ dec(end_from, 16);
__ ldx(end_from, 8, O3);
@@ -1461,7 +1461,7 @@
__ BIND(L_copy_byte);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_byte_loop);
__ dec(end_from);
__ dec(end_to);
@@ -1577,7 +1577,7 @@
__ BIND(L_copy_2_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_2_bytes_loop);
__ lduh(from, offset, O3);
__ deccc(count);
@@ -1684,7 +1684,7 @@
L_aligned_copy, L_copy_2_bytes);
}
// copy 4 elements (16 bytes) at a time
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_aligned_copy);
__ dec(end_from, 16);
__ ldx(end_from, 8, O3);
@@ -1781,7 +1781,7 @@
// copy with shift 4 elements (16 bytes) at a time
__ dec(count, 4); // The cmp at the beginning guaranty count >= 4
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_16_bytes);
__ ldx(from, 4, O4);
__ deccc(count, 4); // Can we do next iteration after this one?
@@ -1907,7 +1907,7 @@
// to form 2 aligned 8-bytes chunks to store.
//
__ ldx(end_from, -4, O3);
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_16_bytes);
__ ldx(end_from, -12, O4);
__ deccc(count, 4);
@@ -1929,7 +1929,7 @@
__ delayed()->inc(count, 4);
// copy 4 elements (16 bytes) at a time
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_aligned_copy);
__ dec(end_from, 16);
__ ldx(end_from, 8, O3);
@@ -2000,6 +2000,27 @@
// to: O1
// count: O2 treated as signed
//
+ // count -= 2;
+ // if ( count >= 0 ) { // >= 2 elements
+ // if ( count > 6) { // >= 8 elements
+ // count -= 6; // original count - 8
+ // do {
+ // copy_8_elements;
+ // count -= 8;
+ // } while ( count >= 0 );
+ // count += 6;
+ // }
+ // if ( count >= 0 ) { // >= 2 elements
+ // do {
+ // copy_2_elements;
+ // } while ( (count=count-2) >= 0 );
+ // }
+ // }
+ // count += 2;
+ // if ( count != 0 ) { // 1 element left
+ // copy_1_element;
+ // }
+ //
void generate_disjoint_long_copy_core(bool aligned) {
Label L_copy_8_bytes, L_copy_16_bytes, L_exit;
const Register from = O0; // source array address
@@ -2012,7 +2033,39 @@
__ mov(G0, offset0); // offset from start of arrays (0)
__ brx(Assembler::negative, false, Assembler::pn, L_copy_8_bytes );
__ delayed()->add(offset0, 8, offset8);
- __ align(16);
+
+ // Copy by 64 bytes chunks
+ Label L_copy_64_bytes;
+ const Register from64 = O3; // source address
+ const Register to64 = G3; // destination address
+ __ subcc(count, 6, O3);
+ __ brx(Assembler::negative, false, Assembler::pt, L_copy_16_bytes );
+ __ delayed()->mov(to, to64);
+ // Now we can use O4(offset0), O5(offset8) as temps
+ __ mov(O3, count);
+ __ mov(from, from64);
+
+ __ align(OptoLoopAlignment);
+ __ BIND(L_copy_64_bytes);
+ for( int off = 0; off < 64; off += 16 ) {
+ __ ldx(from64, off+0, O4);
+ __ ldx(from64, off+8, O5);
+ __ stx(O4, to64, off+0);
+ __ stx(O5, to64, off+8);
+ }
+ __ deccc(count, 8);
+ __ inc(from64, 64);
+ __ brx(Assembler::greaterEqual, false, Assembler::pt, L_copy_64_bytes);
+ __ delayed()->inc(to64, 64);
+
+ // Restore O4(offset0), O5(offset8)
+ __ sub(from64, from, offset0);
+ __ inccc(count, 6);
+ __ brx(Assembler::negative, false, Assembler::pn, L_copy_8_bytes );
+ __ delayed()->add(offset0, 8, offset8);
+
+ // Copy by 16 bytes chunks
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_16_bytes);
__ ldx(from, offset0, O3);
__ ldx(from, offset8, G3);
@@ -2023,6 +2076,7 @@
__ brx(Assembler::greaterEqual, false, Assembler::pt, L_copy_16_bytes);
__ delayed()->inc(offset8, 16);
+ // Copy last 8 bytes
__ BIND(L_copy_8_bytes);
__ inccc(count, 2);
__ brx(Assembler::zero, true, Assembler::pn, L_exit );
@@ -2085,7 +2139,7 @@
__ brx(Assembler::lessEqual, false, Assembler::pn, L_copy_8_bytes );
__ delayed()->sllx(count, LogBytesPerLong, offset8);
__ sub(offset8, 8, offset0);
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_16_bytes);
__ ldx(from, offset8, O2);
__ ldx(from, offset0, O3);
@@ -2351,7 +2405,7 @@
// (O5 = 0; ; O5 += wordSize) --- offset from src, dest arrays
// (O2 = len; O2 != 0; O2--) --- number of oops *remaining*
// G3, G4, G5 --- current oop, oop.klass, oop.klass.super
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(store_element);
__ deccc(G1_remain); // decrement the count
--- a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -37,8 +37,13 @@
enum /* platform_dependent_constants */ {
// %%%%%%%% May be able to shrink this a lot
- code_size1 = 20000, // simply increase if too small (assembler will crash if too small)
- code_size2 = 20000 // simply increase if too small (assembler will crash if too small)
+ code_size1 = 20000, // simply increase if too small (assembler will crash if too small)
+ code_size2 = 20000 // simply increase if too small (assembler will crash if too small)
+};
+
+// MethodHandles adapters
+enum method_handles_platform_dependent_constants {
+ method_handles_adapters_code_size = 5000
};
class Sparc {
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -1822,7 +1822,7 @@
__ add(issuing_pc_addr, Oissuing_pc->after_save()); // likewise set I1 to a value local to the caller
__ super_call_VM_leaf(L7_thread_cache,
CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
- Oissuing_pc->after_save());
+ G2_thread, Oissuing_pc->after_save());
// The caller's SP was adjusted upon method entry to accomodate
// the callee's non-argument locals. Undo that adjustment.
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -86,14 +86,24 @@
if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
}
+ if (is_niagara1_plus()) {
+ if (AllocatePrefetchStyle > 0 && FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
+ // Use BIS instruction for allocation prefetch.
+ FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
+ if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
+ // Use smaller prefetch distance on N2 with BIS
+ FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64);
+ }
+ }
+ if (AllocatePrefetchStyle != 3 && FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
+ // Use different prefetch distance without BIS
+ FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
+ }
+ }
+#endif
if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
}
- if (is_niagara1_plus() && FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
- // Use smaller prefetch distance on N2
- FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
- }
-#endif
}
// Use hardware population count instruction if available.
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -3365,6 +3365,13 @@
#else // LP64
+void Assembler::set_byte_if_not_zero(Register dst) {
+ int enc = prefix_and_encode(dst->encoding(), true);
+ emit_byte(0x0F);
+ emit_byte(0x95);
+ emit_byte(0xE0 | enc);
+}
+
// 64bit only pieces of the assembler
// This should only be used by 64bit instructions that can use rip-relative
// it cannot be used by instructions that want an immediate value.
@@ -8460,6 +8467,7 @@
subptr(str1, result); // Restore counter
shrl(str1, 1);
addl(cnt1, str1);
+ decrementl(cnt1);
lea(str1, Address(result, 2)); // Reload string
// Load substr
--- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -373,6 +373,14 @@
}
+void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
+ __ bind(_entry);
+ __ call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack_with_reexecution()));
+ ce->add_call_info_here(_info);
+ debug_only(__ should_not_reach_here());
+}
+
+
void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
__ bind(_entry);
--- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -126,3 +126,6 @@
assert(i >= 0 && i < nof_caller_save_xmm_regs, "out of bounds");
return _caller_save_xmm_regs[i];
}
+
+ // JSR 292
+ static LIR_Opr& method_handle_invoke_SP_save_opr() { return rbp_opr; }
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -436,40 +436,18 @@
int offset = code_offset();
- // if the method does not have an exception handler, then there is
- // no reason to search for one
- if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) {
- // the exception oop and pc are in rax, and rdx
- // no other registers need to be preserved, so invalidate them
- __ invalidate_registers(false, true, true, false, true, true);
-
- // check that there is really an exception
- __ verify_not_null_oop(rax);
-
- // search an exception handler (rax: exception oop, rdx: throwing pc)
- __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
-
- // if the call returns here, then the exception handler for particular
- // exception doesn't exist -> unwind activation and forward exception to caller
- }
-
- // the exception oop is in rax,
+ // the exception oop and pc are in rax, and rdx
// no other registers need to be preserved, so invalidate them
- __ invalidate_registers(false, true, true, true, true, true);
+ __ invalidate_registers(false, true, true, false, true, true);
// check that there is really an exception
__ verify_not_null_oop(rax);
- // unlock the receiver/klass if necessary
- // rax,: exception
- ciMethod* method = compilation()->method();
- if (method->is_synchronized() && GenerateSynchronizationCode) {
- monitorexit(FrameMap::rbx_oop_opr, FrameMap::rcx_opr, SYNC_header, 0, rax);
- }
-
- // unwind activation and forward exception to caller
- // rax,: exception
- __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
+ // search an exception handler (rax: exception oop, rdx: throwing pc)
+ __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
+
+ __ stop("should not reach here");
+
assert(code_offset() - offset <= exception_handler_size, "overflow");
__ end_a_stub();
@@ -495,8 +473,10 @@
int offset = code_offset();
InternalAddress here(__ pc());
+
__ pushptr(here.addr());
__ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
+
assert(code_offset() - offset <= deopt_handler_size, "overflow");
__ end_a_stub();
@@ -593,7 +573,7 @@
}
// Pop the stack before the safepoint code
- __ leave();
+ __ remove_frame(initial_frame_size_in_bytes());
bool result_is_oop = result->is_valid() ? result->is_oop() : false;
@@ -648,7 +628,8 @@
LIR_Const* c = src->as_constant_ptr();
switch (c->type()) {
- case T_INT: {
+ case T_INT:
+ case T_ADDRESS: {
assert(patch_code == lir_patch_none, "no patching handled here");
__ movl(dest->as_register(), c->as_jint());
break;
@@ -731,6 +712,7 @@
switch (c->type()) {
case T_INT: // fall through
case T_FLOAT:
+ case T_ADDRESS:
__ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
break;
@@ -766,6 +748,7 @@
switch (type) {
case T_INT: // fall through
case T_FLOAT:
+ case T_ADDRESS:
__ movl(as_Address(addr), c->as_jint_bits());
break;
@@ -2707,19 +2690,14 @@
} else {
assert(code == lir_cmp_l2i, "check");
#ifdef _LP64
- Register dest = dst->as_register();
- __ xorptr(dest, dest);
- Label high, done;
- __ cmpptr(left->as_register_lo(), right->as_register_lo());
- __ jcc(Assembler::equal, done);
- __ jcc(Assembler::greater, high);
- __ decrement(dest);
- __ jmp(done);
- __ bind(high);
- __ increment(dest);
-
- __ bind(done);
-
+ Label done;
+ Register dest = dst->as_register();
+ __ cmpptr(left->as_register_lo(), right->as_register_lo());
+ __ movl(dest, -1);
+ __ jccb(Assembler::less, done);
+ __ set_byte_if_not_zero(dest);
+ __ movzbl(dest, dest);
+ __ bind(done);
#else
__ lcmp2int(left->as_register_hi(),
left->as_register_lo(),
@@ -2738,6 +2716,7 @@
switch (code) {
case lir_static_call:
case lir_optvirtual_call:
+ case lir_dynamic_call:
offset += NativeCall::displacement_offset;
break;
case lir_icvirtual_call:
@@ -2753,30 +2732,41 @@
}
-void LIR_Assembler::call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info) {
+void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,
"must be aligned");
- __ call(AddressLiteral(entry, rtype));
- add_call_info(code_offset(), info);
+ __ call(AddressLiteral(op->addr(), rtype));
+ add_call_info(code_offset(), op->info(), op->is_method_handle_invoke());
}
-void LIR_Assembler::ic_call(address entry, CodeEmitInfo* info) {
+void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
RelocationHolder rh = virtual_call_Relocation::spec(pc());
__ movoop(IC_Klass, (jobject)Universe::non_oop_word());
assert(!os::is_MP() ||
(__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,
"must be aligned");
- __ call(AddressLiteral(entry, rh));
- add_call_info(code_offset(), info);
+ __ call(AddressLiteral(op->addr(), rh));
+ add_call_info(code_offset(), op->info(), op->is_method_handle_invoke());
}
/* Currently, vtable-dispatch is only enabled for sparc platforms */
-void LIR_Assembler::vtable_call(int vtable_offset, CodeEmitInfo* info) {
+void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
ShouldNotReachHere();
}
+
+void LIR_Assembler::preserve_SP(LIR_OpJavaCall* op) {
+ __ movptr(FrameMap::method_handle_invoke_SP_save_opr()->as_register(), rsp);
+}
+
+
+void LIR_Assembler::restore_SP(LIR_OpJavaCall* op) {
+ __ movptr(rsp, FrameMap::method_handle_invoke_SP_save_opr()->as_register());
+}
+
+
void LIR_Assembler::emit_static_call_stub() {
address call_pc = __ pc();
address stub = __ start_a_stub(call_stub_size);
@@ -2829,10 +2819,12 @@
} else {
unwind_id = Runtime1::handle_exception_nofpu_id;
}
+ __ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));
} else {
- unwind_id = Runtime1::unwind_exception_id;
+ // remove the activation
+ __ remove_frame(initial_frame_size_in_bytes());
+ __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
}
- __ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));
// enough room for two byte trap
__ nop();
--- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -317,14 +317,6 @@
}
-void C1_MacroAssembler::method_exit(bool restore_frame) {
- if (restore_frame) {
- leave();
- }
- ret(0);
-}
-
-
void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {
// Make sure there is enough stack space for this method's activation.
// Note that we do this before doing an enter(). This matches the
@@ -333,7 +325,7 @@
// between the two compilers.
generate_stack_overflow_check(frame_size_in_bytes);
- enter();
+ push(rbp);
#ifdef TIERED
// c2 leaves fpu stack dirty. Clean it on entry
if (UseSSE < 2 ) {
@@ -344,6 +336,12 @@
}
+void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) {
+ increment(rsp, frame_size_in_bytes); // Does not emit code for frame_size == 0
+ pop(rbp);
+}
+
+
void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) {
if (C1Breakpoint) int3();
inline_cache_check(receiver, ic_klass);
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -688,18 +688,21 @@
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
oop_maps->add_gc_map(call_offset, oop_map);
- // rax,: handler address or NULL if no handler exists
+ // rax,: handler address
// will be the deopt blob if nmethod was deoptimized while we looked up
// handler regardless of whether handler existed in the nmethod.
// only rax, is valid at this time, all other registers have been destroyed by the runtime call
__ invalidate_registers(false, true, true, true, true, true);
+#ifdef ASSERT
// Do we have an exception handler in the nmethod?
- Label no_handler;
Label done;
__ testptr(rax, rax);
- __ jcc(Assembler::zero, no_handler);
+ __ jcc(Assembler::notZero, done);
+ __ stop("no handler found");
+ __ bind(done);
+#endif
// exception handler found
// patch the return address -> the stub will directly return to the exception handler
@@ -712,36 +715,14 @@
__ leave();
__ ret(0);
- __ bind(no_handler);
- // no exception handler found in this method, so the exception is
- // forwarded to the caller (using the unwind code of the nmethod)
- // there is no need to restore the registers
-
- // restore the real return address that was saved before the RT-call
- __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size));
- __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr);
-
- // load address of JavaThread object for thread-local data
- NOT_LP64(__ get_thread(thread);)
- // restore exception oop into rax, (convention for unwind code)
- __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset()));
-
- // clear exception fields in JavaThread because they are no longer needed
- // (fields must be cleared because they are processed by GC otherwise)
- __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD);
- __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD);
-
- // pop the stub frame off
- __ leave();
-
- generate_unwind_exception(sasm);
- __ stop("should not reach here");
}
void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
// incoming parameters
const Register exception_oop = rax;
+ // callee-saved copy of exception_oop during runtime call
+ const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14);
// other registers used in this stub
const Register exception_pc = rdx;
const Register handler_addr = rbx;
@@ -769,38 +750,39 @@
// clear the FPU stack in case any FPU results are left behind
__ empty_FPU_stack();
- // leave activation of nmethod
- __ leave();
- // store return address (is on top of stack after leave)
+ // save exception_oop in callee-saved register to preserve it during runtime calls
+ __ verify_not_null_oop(exception_oop);
+ __ movptr(exception_oop_callee_saved, exception_oop);
+
+ NOT_LP64(__ get_thread(thread);)
+ // Get return address (is on top of stack after leave).
__ movptr(exception_pc, Address(rsp, 0));
- __ verify_oop(exception_oop);
-
- // save exception oop from rax, to stack before call
- __ push(exception_oop);
+ // search the exception handler address of the caller (using the return address)
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
+ // rax: exception handler address of the caller
- // search the exception handler address of the caller (using the return address)
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc);
- // rax,: exception handler address of the caller
-
- // only rax, is valid at this time, all other registers have been destroyed by the call
- __ invalidate_registers(false, true, true, true, true, true);
+ // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call.
+ __ invalidate_registers(false, true, true, true, false, true);
// move result of call into correct register
__ movptr(handler_addr, rax);
- // restore exception oop in rax, (required convention of exception handler)
- __ pop(exception_oop);
+ // Restore exception oop to RAX (required convention of exception handler).
+ __ movptr(exception_oop, exception_oop_callee_saved);
- __ verify_oop(exception_oop);
+ // verify that there is really a valid exception in rax
+ __ verify_not_null_oop(exception_oop);
// get throwing pc (= return address).
// rdx has been destroyed by the call, so it must be set again
// the pop is also necessary to simulate the effect of a ret(0)
__ pop(exception_pc);
- // verify that that there is really a valid exception in rax,
- __ verify_not_null_oop(exception_oop);
+ // Restore SP from BP if the exception PC is a MethodHandle call site.
+ NOT_LP64(__ get_thread(thread);)
+ __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
+ __ cmovptr(Assembler::notEqual, rsp, rbp);
// continue at exception handler (return address removed)
// note: do *not* remove arguments when unwinding the
@@ -808,9 +790,9 @@
// all arguments on the stack when entering the
// runtime to determine the exception handler
// (GC happens at call site with arguments!)
- // rax,: exception oop
+ // rax: exception oop
// rdx: throwing pc
- // rbx,: exception handler
+ // rbx: exception handler
__ jmp(handler_addr);
}
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -80,7 +80,6 @@
// Ergonomics related flags
define_pd_global(uint64_t,MaxRAM, 4ULL*G);
#endif // AMD64
-define_pd_global(intx, OptoLoopAlignment, 16);
define_pd_global(intx, RegisterCostAreaRatio, 16000);
// Peephole and CISC spilling both break the graph, and so makes the
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -45,6 +45,7 @@
#else
define_pd_global(intx, CodeEntryAlignment, 16);
#endif // COMPILER2
+define_pd_global(intx, OptoLoopAlignment, 16);
define_pd_global(intx, InlineFrequencyCount, 100);
define_pd_global(intx, InlineSmallCode, 1000);
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -60,13 +60,13 @@
}
#ifdef ASSERT
-static void verify_argslot(MacroAssembler* _masm, Register rax_argslot,
+static void verify_argslot(MacroAssembler* _masm, Register argslot_reg,
const char* error_message) {
// Verify that argslot lies within (rsp, rbp].
Label L_ok, L_bad;
- __ cmpptr(rax_argslot, rbp);
+ __ cmpptr(argslot_reg, rbp);
__ jccb(Assembler::above, L_bad);
- __ cmpptr(rsp, rax_argslot);
+ __ cmpptr(rsp, argslot_reg);
__ jccb(Assembler::below, L_ok);
__ bind(L_bad);
__ stop(error_message);
@@ -178,22 +178,6 @@
// Now move the argslot down, to point to the opened-up space.
__ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
-
- if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) {
- // The caller has specified a bitmask of tags to put into the opened space.
- // This only works when the arg_slots value is an assembly-time constant.
- int constant_arg_slots = arg_slots.as_constant() / stack_move_unit();
- int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();
- for (int slot = 0; slot < constant_arg_slots; slot++) {
- BasicType slot_type = ((arg_mask & (1 << slot)) == 0 ? T_OBJECT : T_INT);
- int slot_offset = Interpreter::stackElementSize() * slot;
- Address tag_addr(rax_argslot, slot_offset + tag_offset);
- __ movptr(tag_addr, frame::tag_for_basic_type(slot_type));
- }
- // Note that the new argument slots are tagged properly but contain
- // garbage at this point. The value portions must be initialized
- // by the caller. (Especially references!)
- }
}
// Helper to remove argument slots from the stack.
@@ -206,18 +190,9 @@
(!arg_slots.is_register() ? rsp : arg_slots.as_register()));
#ifdef ASSERT
- {
- // Verify that [argslot..argslot+size) lies within (rsp, rbp).
- Label L_ok, L_bad;
- __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr));
- __ cmpptr(rbx_temp, rbp);
- __ jccb(Assembler::above, L_bad);
- __ cmpptr(rsp, rax_argslot);
- __ jccb(Assembler::below, L_ok);
- __ bind(L_bad);
- __ stop("deleted argument(s) must fall within current frame");
- __ bind(L_ok);
- }
+ // Verify that [argslot..argslot+size) lies within (rsp, rbp).
+ __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr));
+ verify_argslot(_masm, rbx_temp, "deleted argument(s) must fall within current frame");
if (arg_slots.is_register()) {
Label L_ok, L_bad;
__ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
@@ -321,12 +296,6 @@
Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
Address vmarg; // __ argument_address(vmargslot)
- int tag_offset = -1;
- if (TaggedStackInterpreter) {
- tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();
- assert(tag_offset = wordSize, "stack grows as expected");
- }
-
const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
if (have_entry(ek)) {
@@ -372,11 +341,8 @@
__ mov(rsp, rsi); // cut the stack back to where the caller started
// Repush the arguments as if coming from the interpreter.
- if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_INT));
__ push(rdx_code);
- if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT));
__ push(rcx_fail);
- if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT));
__ push(rax_want);
Register rbx_method = rbx_temp;
@@ -397,7 +363,6 @@
// Do something that is at least causes a valid throw from the interpreter.
__ bind(no_method);
__ pop(rax_want);
- if (TaggedStackInterpreter) __ pop(rcx_fail);
__ pop(rcx_fail);
__ push(rax_want);
__ push(rcx_fail);
@@ -510,18 +475,10 @@
case _bound_long_direct_mh:
{
bool direct_to_method = (ek >= _bound_ref_direct_mh);
- BasicType arg_type = T_ILLEGAL;
- if (ek == _bound_long_mh || ek == _bound_long_direct_mh) {
- arg_type = T_LONG;
- } else if (ek == _bound_int_mh || ek == _bound_int_direct_mh) {
- arg_type = T_INT;
- } else {
- assert(ek == _bound_ref_mh || ek == _bound_ref_direct_mh, "must be ref");
- arg_type = T_OBJECT;
- }
- int arg_slots = type2size[arg_type];
- int arg_mask = (arg_type == T_OBJECT ? _INSERT_REF_MASK :
- arg_slots == 1 ? _INSERT_INT_MASK : _INSERT_LONG_MASK);
+ BasicType arg_type = T_ILLEGAL;
+ int arg_mask = _INSERT_NO_MASK;
+ int arg_slots = -1;
+ get_ek_bound_mh_info(ek, arg_type, arg_mask, arg_slots);
// make room for the new argument:
__ movl(rax_argslot, rcx_bmh_vmargslot);
@@ -584,7 +541,7 @@
Label done;
__ movptr(rdx_temp, vmarg);
- __ testl(rdx_temp, rdx_temp);
+ __ testptr(rdx_temp, rdx_temp);
__ jccb(Assembler::zero, done); // no cast if null
__ load_klass(rdx_temp, rdx_temp);
@@ -660,13 +617,10 @@
}
break;
default:
- assert(false, "");
+ ShouldNotReachHere();
}
- goto finish_int_conversion;
- }
- finish_int_conversion:
- {
+ // Do the requested conversion and store the value.
Register rbx_vminfo = rbx_temp;
__ movl(rbx_vminfo, rcx_amh_conversion);
assert(CONV_VMINFO_SHIFT == 0, "preshifted");
@@ -692,7 +646,7 @@
__ shrl(rdx_temp /*, rcx*/);
__ bind(done);
- __ movl(vmarg, rdx_temp);
+ __ movl(vmarg, rdx_temp); // Store the value.
__ xchgptr(rcx, rbx_vminfo); // restore rcx_recv
__ jump_to_method_handle_entry(rcx_recv, rdx_temp);
@@ -715,9 +669,14 @@
switch (ek) {
case _adapter_opt_i2l:
{
+#ifdef _LP64
+ __ movslq(rdx_temp, vmarg1); // Load sign-extended
+ __ movq(vmarg1, rdx_temp); // Store into first slot
+#else
__ movl(rdx_temp, vmarg1);
- __ sarl(rdx_temp, 31); // __ extend_sign()
+ __ sarl(rdx_temp, BitsPerInt - 1); // __ extend_sign()
__ movl(vmarg2, rdx_temp); // store second word
+#endif
}
break;
case _adapter_opt_unboxl:
@@ -727,14 +686,19 @@
int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_LONG);
assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE), "");
__ null_check(rdx_temp, value_offset);
+#ifdef _LP64
+ __ movq(rbx_temp, Address(rdx_temp, value_offset));
+ __ movq(vmarg1, rbx_temp);
+#else
__ movl(rbx_temp, Address(rdx_temp, value_offset + 0*BytesPerInt));
__ movl(rdx_temp, Address(rdx_temp, value_offset + 1*BytesPerInt));
__ movl(vmarg1, rbx_temp);
__ movl(vmarg2, rdx_temp);
+#endif
}
break;
default:
- assert(false, "");
+ ShouldNotReachHere();
}
__ movptr(rcx_recv, rcx_mh_vmtarget);
@@ -768,20 +732,9 @@
if (ek == _adapter_opt_f2d) {
__ fld_s(vmarg); // load float to ST0
__ fstp_s(vmarg); // store single
- } else if (!TaggedStackInterpreter) {
+ } else {
__ fld_d(vmarg); // load double to ST0
__ fstp_s(vmarg); // store single
- } else {
- Address vmarg_tag = vmarg.plus_disp(tag_offset);
- Address vmarg2 = vmarg.plus_disp(Interpreter::stackElementSize());
- // vmarg2_tag does not participate in this code
- Register rbx_tag = rbx_temp;
- __ movl(rbx_tag, vmarg_tag); // preserve tag
- __ movl(rdx_temp, vmarg2); // get second word of double
- __ movl(vmarg_tag, rdx_temp); // align with first word
- __ fld_d(vmarg); // load double to ST0
- __ movl(vmarg_tag, rbx_tag); // restore tag
- __ fstp_s(vmarg); // store single
}
#endif //_LP64
@@ -812,19 +765,8 @@
case _adapter_opt_rot_2_up:
case _adapter_opt_rot_2_down:
{
- int rotate = 0, swap_slots = 0;
- switch ((int)ek) {
- case _adapter_opt_swap_1: swap_slots = 1; break;
- case _adapter_opt_swap_2: swap_slots = 2; break;
- case _adapter_opt_rot_1_up: swap_slots = 1; rotate++; break;
- case _adapter_opt_rot_1_down: swap_slots = 1; rotate--; break;
- case _adapter_opt_rot_2_up: swap_slots = 2; rotate++; break;
- case _adapter_opt_rot_2_down: swap_slots = 2; rotate--; break;
- default: assert(false, "");
- }
-
- // the real size of the move must be doubled if TaggedStackInterpreter:
- int swap_bytes = (int)( swap_slots * Interpreter::stackElementWords() * wordSize );
+ int swap_bytes = 0, rotate = 0;
+ get_ek_adapter_opt_swap_rot_info(ek, swap_bytes, rotate);
// 'argslot' is the position of the first argument to swap
__ movl(rax_argslot, rcx_amh_vmargslot);
@@ -925,8 +867,8 @@
// 'stack_move' is negative number of words to duplicate
Register rdx_stack_move = rdx_temp;
- __ movl(rdx_stack_move, rcx_amh_conversion);
- __ sarl(rdx_stack_move, CONV_STACK_MOVE_SHIFT);
+ __ movl2ptr(rdx_stack_move, rcx_amh_conversion);
+ __ sarptr(rdx_stack_move, CONV_STACK_MOVE_SHIFT);
int argslot0_num = 0;
Address argslot0 = __ argument_address(RegisterOrConstant(argslot0_num));
@@ -988,8 +930,8 @@
// 'stack_move' is number of words to drop
Register rdi_stack_move = rdi;
- __ movl(rdi_stack_move, rcx_amh_conversion);
- __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
+ __ movl2ptr(rdi_stack_move, rcx_amh_conversion);
+ __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
remove_arg_slots(_masm, rdi_stack_move,
rax_argslot, rbx_temp, rdx_temp);
@@ -1014,11 +956,7 @@
case _adapter_opt_spread_more:
{
// spread an array out into a group of arguments
- int length_constant = -1;
- switch (ek) {
- case _adapter_opt_spread_0: length_constant = 0; break;
- case _adapter_opt_spread_1: length_constant = 1; break;
- }
+ int length_constant = get_ek_adapter_opt_spread_info(ek);
// find the address of the array argument
__ movl(rax_argslot, rcx_amh_vmargslot);
@@ -1079,8 +1017,8 @@
__ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize()));
// 'stack_move' is negative number of words to insert
Register rdi_stack_move = rdi;
- __ movl(rdi_stack_move, rcx_amh_conversion);
- __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
+ __ movl2ptr(rdi_stack_move, rcx_amh_conversion);
+ __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
Register rsi_temp = rsi_array; // spill this
insert_arg_slots(_masm, rdi_stack_move, -1,
rax_argslot, rbx_temp, rsi_temp);
@@ -1114,10 +1052,6 @@
__ movptr(rbx_temp, Address(rsi_source, 0));
__ movptr(Address(rax_argslot, 0), rbx_temp);
__ addptr(rsi_source, type2aelembytes(elem_type));
- if (TaggedStackInterpreter) {
- __ movptr(Address(rax_argslot, tag_offset),
- frame::tag_for_basic_type(elem_type));
- }
__ addptr(rax_argslot, Interpreter::stackElementSize());
__ cmpptr(rax_argslot, rdx_argslot_limit);
__ jccb(Assembler::less, loop);
@@ -1131,11 +1065,7 @@
__ movptr(rbx_temp, Address(rsi_array, elem_offset));
__ movptr(Address(rax_argslot, slot_offset), rbx_temp);
elem_offset += type2aelembytes(elem_type);
- if (TaggedStackInterpreter) {
- __ movptr(Address(rax_argslot, slot_offset + tag_offset),
- frame::tag_for_basic_type(elem_type));
- }
- slot_offset += Interpreter::stackElementSize();
+ slot_offset += Interpreter::stackElementSize();
}
}
--- a/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -115,8 +115,8 @@
// rax: exception handler for given <exception oop/exception pc>
- // Restore SP from BP if the exception PC is a MethodHandle call.
- __ cmpl(Address(rcx, JavaThread::is_method_handle_exception_offset()), 0);
+ // Restore SP from BP if the exception PC is a MethodHandle call site.
+ __ cmpl(Address(rcx, JavaThread::is_method_handle_return_offset()), 0);
__ cmovptr(Assembler::notEqual, rsp, rbp);
// We have a handler in rax, (could be deopt blob)
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -3328,8 +3328,8 @@
// rax: exception handler
- // Restore SP from BP if the exception PC is a MethodHandle call.
- __ cmpl(Address(r15_thread, JavaThread::is_method_handle_exception_offset()), 0);
+ // Restore SP from BP if the exception PC is a MethodHandle call site.
+ __ cmpl(Address(r15_thread, JavaThread::is_method_handle_return_offset()), 0);
__ cmovptr(Assembler::notEqual, rsp, rbp);
// We have a handler in rax (could be deopt blob).
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -369,7 +369,7 @@
// The pending exception in Thread is converted into a Java-level exception.
//
// Contract with Java-level exception handlers:
- // rax,: exception
+ // rax: exception
// rdx: throwing pc
//
// NOTE: At entry of this stub, exception-pc must be on stack !!
@@ -377,6 +377,12 @@
address generate_forward_exception() {
StubCodeMark mark(this, "StubRoutines", "forward exception");
address start = __ pc();
+ const Register thread = rcx;
+
+ // other registers used in this stub
+ const Register exception_oop = rax;
+ const Register handler_addr = rbx;
+ const Register exception_pc = rdx;
// Upon entry, the sp points to the return address returning into Java
// (interpreted or compiled) code; i.e., the return address becomes the
@@ -389,8 +395,8 @@
#ifdef ASSERT
// make sure this code is only executed if there is a pending exception
{ Label L;
- __ get_thread(rcx);
- __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
+ __ get_thread(thread);
+ __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
__ jcc(Assembler::notEqual, L);
__ stop("StubRoutines::forward exception: no pending exception (1)");
__ bind(L);
@@ -398,33 +404,40 @@
#endif
// compute exception handler into rbx,
- __ movptr(rax, Address(rsp, 0));
+ __ get_thread(thread);
+ __ movptr(exception_pc, Address(rsp, 0));
BLOCK_COMMENT("call exception_handler_for_return_address");
- __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax);
- __ mov(rbx, rax);
+ __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
+ __ mov(handler_addr, rax);
- // setup rax, & rdx, remove return address & clear pending exception
- __ get_thread(rcx);
- __ pop(rdx);
- __ movptr(rax, Address(rcx, Thread::pending_exception_offset()));
- __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD);
+ // setup rax & rdx, remove return address & clear pending exception
+ __ get_thread(thread);
+ __ pop(exception_pc);
+ __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
+ __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
#ifdef ASSERT
// make sure exception is set
{ Label L;
- __ testptr(rax, rax);
+ __ testptr(exception_oop, exception_oop);
__ jcc(Assembler::notEqual, L);
__ stop("StubRoutines::forward exception: no pending exception (2)");
__ bind(L);
}
#endif
+ // Verify that there is really a valid exception in RAX.
+ __ verify_oop(exception_oop);
+
+ // Restore SP from BP if the exception PC is a MethodHandle call site.
+ __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
+ __ cmovptr(Assembler::notEqual, rsp, rbp);
+
// continue at exception handler (return address removed)
- // rax,: exception
- // rbx,: exception handler
+ // rax: exception
+ // rbx: exception handler
// rdx: throwing pc
- __ verify_oop(rax);
- __ jmp(rbx);
+ __ jmp(handler_addr);
return start;
}
@@ -799,7 +812,7 @@
Label L_copy_64_bytes_loop, L_copy_64_bytes, L_copy_8_bytes, L_exit;
// Copy 64-byte chunks
__ jmpb(L_copy_64_bytes);
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_64_bytes_loop);
if(UseUnalignedLoadStores) {
@@ -861,7 +874,7 @@
Label L_copy_64_bytes_loop, L_copy_64_bytes, L_copy_8_bytes, L_exit;
// Copy 64-byte chunks
__ jmpb(L_copy_64_bytes);
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_64_bytes_loop);
__ movq(mmx0, Address(from, 0));
__ movq(mmx1, Address(from, 8));
@@ -1131,7 +1144,7 @@
__ movl(Address(to, count, sf, 0), rdx);
__ jmpb(L_copy_8_bytes);
- __ align(16);
+ __ align(OptoLoopAlignment);
// Move 8 bytes
__ BIND(L_copy_8_bytes_loop);
if (UseXMMForArrayCopy) {
@@ -1222,7 +1235,7 @@
}
} else {
__ jmpb(L_copy_8_bytes);
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_8_bytes_loop);
__ fild_d(Address(from, 0));
__ fistp_d(Address(from, to_from, Address::times_1));
@@ -1269,7 +1282,7 @@
__ jmpb(L_copy_8_bytes);
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_copy_8_bytes_loop);
if (VM_Version::supports_mmx()) {
if (UseXMMForArrayCopy) {
@@ -1441,7 +1454,7 @@
// Loop control:
// for (count = -count; count != 0; count++)
// Base pointers src, dst are biased by 8*count,to last element.
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_store_element);
__ movptr(to_element_addr, elem); // store the oop
@@ -2263,16 +2276,6 @@
// arraycopy stubs used by compilers
generate_arraycopy_stubs();
- // generic method handle stubs
- if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
- 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);
- }
- }
-
generate_math_stubs();
}
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -466,7 +466,7 @@
BLOCK_COMMENT("call exception_handler_for_return_address");
__ call_VM_leaf(CAST_FROM_FN_PTR(address,
SharedRuntime::exception_handler_for_return_address),
- c_rarg0);
+ r15_thread, c_rarg0);
__ mov(rbx, rax);
// setup rax & rdx, remove return address & clear pending exception
@@ -871,9 +871,8 @@
}
address generate_fp_mask(const char *stub_name, int64_t mask) {
+ __ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", stub_name);
-
- __ align(16);
address start = __ pc();
__ emit_data64( mask, relocInfo::none );
@@ -1268,7 +1267,7 @@
Label& L_copy_32_bytes, Label& L_copy_8_bytes) {
DEBUG_ONLY(__ stop("enter at entry label, not here"));
Label L_loop;
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_loop);
if(UseUnalignedLoadStores) {
__ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24));
@@ -1309,7 +1308,7 @@
Label& L_copy_32_bytes, Label& L_copy_8_bytes) {
DEBUG_ONLY(__ stop("enter at entry label, not here"));
Label L_loop;
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_loop);
if(UseUnalignedLoadStores) {
__ movdqu(xmm0, Address(from, qword_count, Address::times_8, 16));
@@ -2229,7 +2228,7 @@
// Loop control:
// for (count = -count; count != 0; count++)
// Base pointers src, dst are biased by 8*(count-1),to last element.
- __ align(16);
+ __ align(OptoLoopAlignment);
__ BIND(L_store_element);
__ store_heap_oop(to_element_addr, rax_oop); // store the oop
@@ -3009,16 +3008,6 @@
// arraycopy stubs used by compilers
generate_arraycopy_stubs();
- // generic method handle stubs
- if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
- 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);
- }
- }
-
generate_math_stubs();
}
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -31,6 +31,11 @@
code_size2 = 22000 // simply increase if too small (assembler will crash if too small)
};
+// MethodHandles adapters
+enum method_handles_platform_dependent_constants {
+ method_handles_adapters_code_size = 5000
+};
+
class x86 {
friend class StubGenerator;
friend class VMStructs;
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 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
@@ -28,12 +28,14 @@
static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; }
-enum platform_dependent_constants
-{
- code_size1 = 19000, // simply increase if too small (assembler will
- // crash if too small)
- code_size2 = 22000 // simply increase if too small (assembler will
- // crash if too small)
+enum platform_dependent_constants {
+ code_size1 = 19000, // simply increase if too small (assembler will crash if too small)
+ code_size2 = 22000 // simply increase if too small (assembler will crash if too small)
+};
+
+// MethodHandles adapters
+enum method_handles_platform_dependent_constants {
+ method_handles_adapters_code_size = 13000
};
class x86 {
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1550,6 +1550,7 @@
void TemplateInterpreterGenerator::generate_throw_exception() {
// Entry point in previous activation (i.e., if the caller was interpreted)
Interpreter::_rethrow_exception_entry = __ pc();
+ const Register thread = rcx;
// Restore sp to interpreter_frame_last_sp even though we are going
// to empty the expression stack for the exception processing.
@@ -1598,10 +1599,10 @@
// Set the popframe_processing bit in pending_popframe_condition indicating that we are
// currently handling popframe, so that call_VMs that may happen later do not trigger new
// popframe handling cycles.
- __ get_thread(rcx);
- __ movl(rdx, Address(rcx, JavaThread::popframe_condition_offset()));
+ __ get_thread(thread);
+ __ movl(rdx, Address(thread, JavaThread::popframe_condition_offset()));
__ orl(rdx, JavaThread::popframe_processing_bit);
- __ movl(Address(rcx, JavaThread::popframe_condition_offset()), rdx);
+ __ movl(Address(thread, JavaThread::popframe_condition_offset()), rdx);
{
// Check to see whether we are returning to a deoptimized frame.
@@ -1629,8 +1630,8 @@
__ subptr(rdi, rax);
__ addptr(rdi, wordSize);
// Save these arguments
- __ get_thread(rcx);
- __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), rcx, rax, rdi);
+ __ get_thread(thread);
+ __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), thread, rax, rdi);
__ remove_activation(vtos, rdx,
/* throw_monitor_exception */ false,
@@ -1638,8 +1639,8 @@
/* notify_jvmdi */ false);
// Inform deoptimization that it is responsible for restoring these arguments
- __ get_thread(rcx);
- __ movl(Address(rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit);
+ __ get_thread(thread);
+ __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit);
// Continue in deoptimization handler
__ jmp(rdx);
@@ -1665,12 +1666,12 @@
// expression stack if necessary.
__ mov(rax, rsp);
__ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
- __ get_thread(rcx);
+ __ get_thread(thread);
// PC must point into interpreter here
- __ set_last_Java_frame(rcx, noreg, rbp, __ pc());
- __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), rcx, rax, rbx);
- __ get_thread(rcx);
- __ reset_last_Java_frame(rcx, true, true);
+ __ set_last_Java_frame(thread, noreg, rbp, __ pc());
+ __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), thread, rax, rbx);
+ __ get_thread(thread);
+ __ reset_last_Java_frame(thread, true, true);
// Restore the last_sp and null it out
__ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
__ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
@@ -1684,8 +1685,8 @@
}
// Clear the popframe condition flag
- __ get_thread(rcx);
- __ movl(Address(rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
+ __ get_thread(thread);
+ __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
__ dispatch_next(vtos);
// end of PopFrame support
@@ -1694,27 +1695,27 @@
// preserve exception over this code sequence
__ pop_ptr(rax);
- __ get_thread(rcx);
- __ movptr(Address(rcx, JavaThread::vm_result_offset()), rax);
+ __ get_thread(thread);
+ __ movptr(Address(thread, JavaThread::vm_result_offset()), rax);
// remove the activation (without doing throws on illegalMonitorExceptions)
__ remove_activation(vtos, rdx, false, true, false);
// restore exception
- __ get_thread(rcx);
- __ movptr(rax, Address(rcx, JavaThread::vm_result_offset()));
- __ movptr(Address(rcx, JavaThread::vm_result_offset()), NULL_WORD);
+ __ get_thread(thread);
+ __ movptr(rax, Address(thread, JavaThread::vm_result_offset()));
+ __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
__ verify_oop(rax);
// Inbetween activations - previous activation type unknown yet
// compute continuation point - the continuation point expects
// the following registers set up:
//
- // rax,: exception
+ // rax: exception
// rdx: return address/pc that threw exception
// rsp: expression stack of caller
- // rbp,: rbp, of caller
+ // rbp: rbp, of caller
__ push(rax); // save exception
__ push(rdx); // save return address
- __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx);
+ __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, rdx);
__ mov(rbx, rax); // save exception handler
__ pop(rdx); // restore return address
__ pop(rax); // restore exception
@@ -1728,6 +1729,7 @@
//
address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) {
address entry = __ pc();
+ const Register thread = rcx;
__ restore_bcp();
__ restore_locals();
@@ -1735,8 +1737,8 @@
__ empty_FPU_stack();
__ load_earlyret_value(state);
- __ get_thread(rcx);
- __ movptr(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset()));
+ __ get_thread(thread);
+ __ movptr(rcx, Address(thread, JavaThread::jvmti_thread_state_offset()));
const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset());
// Clear the earlyret state
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1741,7 +1741,7 @@
__ push(rdx); // save return address
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address,
SharedRuntime::exception_handler_for_return_address),
- rdx);
+ r15_thread, rdx);
__ mov(rbx, rax); // save exception handler
__ pop(rdx); // restore return address
__ pop(rax); // restore exception
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -2915,12 +2915,8 @@
__ andl(recv, 0xFF);
// recv count is 0 based?
Address recv_addr(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1));
- if (is_invokedynamic) {
- __ lea(recv, recv_addr);
- } else {
- __ movptr(recv, recv_addr);
- __ verify_oop(recv);
- }
+ __ movptr(recv, recv_addr);
+ __ verify_oop(recv);
}
// do null check if needed
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 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
@@ -2860,12 +2860,8 @@
__ andl(recv, 0xFF);
if (TaggedStackInterpreter) __ shll(recv, 1); // index*2
Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1));
- if (is_invokedynamic) {
- __ lea(recv, recv_addr);
- } else {
- __ movptr(recv, recv_addr);
- __ verify_oop(recv);
- }
+ __ movptr(recv, recv_addr);
+ __ verify_oop(recv);
}
// do null check if needed
--- a/hotspot/src/cpu/x86/vm/x86_32.ad Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Sat Apr 17 08:12:00 2010 -0700
@@ -1444,8 +1444,10 @@
// to implement the UseStrictFP mode.
const bool Matcher::strict_fp_requires_explicit_rounding = true;
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = true;
+// Are floats conerted to double when stored to stack during deoptimization?
+// On x32 it is stored with convertion only when FPU is used for floats.
+bool Matcher::float_in_double() { return (UseSSE == 0); }
+
// Do ints take an entire long register or just half?
const bool Matcher::int_in_long = false;
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Sat Apr 17 08:12:00 2010 -0700
@@ -2074,8 +2074,10 @@
// implement the UseStrictFP mode.
const bool Matcher::strict_fp_requires_explicit_rounding = true;
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = true;
+// Are floats conerted to double when stored to stack during deoptimization?
+// On x64 it is stored without convertion so we can use normal access.
+bool Matcher::float_in_double() { return false; }
+
// Do ints take an entire long register or just half?
const bool Matcher::int_in_long = true;
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -206,7 +206,6 @@
// Update the invocation counter
if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) {
- thread->set_do_not_unlock();
InvocationCounter *counter = method->invocation_counter();
counter->increment();
if (counter->reached_InvocationLimit()) {
@@ -215,7 +214,6 @@
if (HAS_PENDING_EXCEPTION)
goto unwind_and_return;
}
- thread->clr_do_not_unlock();
}
// Lock if necessary
--- a/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,6 +1,6 @@
/*
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright 2009 Red Hat, Inc.
+ * Copyright 2009, 2010 Red Hat, Inc.
* 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,4 +23,10 @@
*
*/
-// This file is intentionally empty
+#include "incls/_precompiled.incl"
+#include "incls/_methodHandles_zero.cpp.incl"
+
+void MethodHandles::generate_method_handle_stub(MacroAssembler* masm,
+ MethodHandles::EntryKind ek) {
+ ShouldNotCallThis();
+}
--- a/hotspot/src/cpu/zero/vm/stubRoutines_zero.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/cpu/zero/vm/stubRoutines_zero.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,6 +1,6 @@
/*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,10 @@
code_size2 = 0 // if these are too small. Simply increase
}; // them if that happens.
+ enum method_handles_platform_dependent_constants {
+ method_handles_adapters_code_size = 0
+ };
+
#ifdef IA32
class x86 {
friend class VMStructs;
--- a/hotspot/src/os/linux/vm/attachListener_linux.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -192,7 +192,8 @@
res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
}
if (res == -1) {
- sprintf(path, "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id());
+ snprintf(path, PATH_MAX+1, "%s/.java_pid%d",
+ os::get_temp_directory(), os::current_process_id());
strcpy(addr.sun_path, path);
::unlink(path);
res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
@@ -460,13 +461,14 @@
if (init_at_startup() || is_initialized()) {
return false; // initialized at startup or already initialized
}
- char fn[32];
+ char fn[128];
sprintf(fn, ".attach_pid%d", os::current_process_id());
int ret;
struct stat64 st;
RESTARTABLE(::stat64(fn, &st), ret);
if (ret == -1) {
- sprintf(fn, "/tmp/.attach_pid%d", os::current_process_id());
+ snprintf(fn, sizeof(fn), "%s/.attach_pid%d",
+ os::get_temp_directory(), os::current_process_id());
RESTARTABLE(::stat64(fn, &st), ret);
}
if (ret == 0) {
--- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -22,6 +22,8 @@
*
*/
+# define __STDC_FORMAT_MACROS
+
// do not include precompiled header file
# include "incls/_os_linux.cpp.incl"
@@ -53,6 +55,8 @@
# include <sys/ipc.h>
# include <sys/shm.h>
# include <link.h>
+# include <stdint.h>
+# include <inttypes.h>
#define MAX_PATH (2 * K)
@@ -1518,7 +1522,10 @@
const char* os::dll_file_extension() { return ".so"; }
-const char* os::get_temp_directory() { return "/tmp/"; }
+const char* os::get_temp_directory() {
+ const char *prop = Arguments::get_property("java.io.tmpdir");
+ return prop == NULL ? "/tmp" : prop;
+}
static bool file_exists(const char* filename) {
struct stat statbuf;
@@ -2301,7 +2308,8 @@
char buf[40];
int num = Atomic::add(1, &cnt);
- sprintf(buf, "/tmp/hs-vm-%d-%d", os::current_process_id(), num);
+ snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d",
+ os::get_temp_directory(), os::current_process_id(), num);
unlink(buf);
int fd = open(buf, O_CREAT | O_RDWR, S_IRWXU);
@@ -2492,6 +2500,91 @@
!= MAP_FAILED;
}
+// Linux uses a growable mapping for the stack, and if the mapping for
+// the stack guard pages is not removed when we detach a thread the
+// stack cannot grow beyond the pages where the stack guard was
+// mapped. If at some point later in the process the stack expands to
+// that point, the Linux kernel cannot expand the stack any further
+// because the guard pages are in the way, and a segfault occurs.
+//
+// However, it's essential not to split the stack region by unmapping
+// a region (leaving a hole) that's already part of the stack mapping,
+// so if the stack mapping has already grown beyond the guard pages at
+// the time we create them, we have to truncate the stack mapping.
+// So, we need to know the extent of the stack mapping when
+// create_stack_guard_pages() is called.
+
+// Find the bounds of the stack mapping. Return true for success.
+//
+// We only need this for stacks that are growable: at the time of
+// writing thread stacks don't use growable mappings (i.e. those
+// creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
+// only applies to the main thread.
+static bool
+get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
+{
+ FILE *f = fopen("/proc/self/maps", "r");
+ if (f == NULL)
+ return false;
+
+ while (!feof(f)) {
+ size_t dummy;
+ char *str = NULL;
+ ssize_t len = getline(&str, &dummy, f);
+ if (len == -1) {
+ fclose(f);
+ return false;
+ }
+
+ if (len > 0 && str[len-1] == '\n') {
+ str[len-1] = 0;
+ len--;
+ }
+
+ static const char *stack_str = "[stack]";
+ if (len > (ssize_t)strlen(stack_str)
+ && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
+ if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
+ uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
+ if (sp >= *bottom && sp <= *top) {
+ free(str);
+ fclose(f);
+ return true;
+ }
+ }
+ }
+ free(str);
+ }
+ fclose(f);
+ return false;
+}
+
+// If the (growable) stack mapping already extends beyond the point
+// where we're going to put our guard pages, truncate the mapping at
+// that point by munmap()ping it. This ensures that when we later
+// munmap() the guard pages we don't leave a hole in the stack
+// mapping.
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+ uintptr_t stack_extent, stack_base;
+ if (get_stack_bounds(&stack_extent, &stack_base)) {
+ if (stack_extent < (uintptr_t)addr)
+ ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
+ }
+
+ return os::commit_memory(addr, size);
+}
+
+// If this is a growable mapping, remove the guard pages entirely by
+// munmap()ping them. If not, just call uncommit_memory().
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+ uintptr_t stack_extent, stack_base;
+ if (get_stack_bounds(&stack_extent, &stack_base)) {
+ return ::munmap(addr, size) == 0;
+ }
+
+ return os::uncommit_memory(addr, size);
+}
+
static address _highest_vm_reserved_address = NULL;
// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -145,11 +145,11 @@
const char* tmpdir = os::get_temp_directory();
const char* perfdir = PERFDATA_NAME;
- size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 2;
+ size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
// construct the path name to user specific tmp directory
- snprintf(dirname, nbytes, "%s%s_%s", tmpdir, perfdir, user);
+ snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
return dirname;
}
@@ -331,8 +331,9 @@
}
char* usrdir_name = NEW_C_HEAP_ARRAY(char,
- strlen(tmpdirname) + strlen(dentry->d_name) + 1);
+ strlen(tmpdirname) + strlen(dentry->d_name) + 2);
strcpy(usrdir_name, tmpdirname);
+ strcat(usrdir_name, "/");
strcat(usrdir_name, dentry->d_name);
DIR* subdirp = os::opendir(usrdir_name);
--- a/hotspot/src/os/solaris/dtrace/hotspot.d Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/solaris/dtrace/hotspot.d Sat Apr 17 08:12:00 2010 -0700
@@ -25,9 +25,20 @@
provider hotspot {
probe class__loaded(char*, uintptr_t, void*, uintptr_t);
probe class__unloaded(char*, uintptr_t, void*, uintptr_t);
+ probe class__initialization__required(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__recursive(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__concurrent(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__erroneous(char*, uintptr_t, void*, intptr_t, int);
+ probe class__initialization__super__failed(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__clinit(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__error(char*, uintptr_t, void*, intptr_t,int);
+ probe class__initialization__end(char*, uintptr_t, void*, intptr_t,int);
probe vm__init__begin();
probe vm__init__end();
probe vm__shutdown();
+ probe vmops__request(char*, uintptr_t, int);
+ probe vmops__begin(char*, uintptr_t, int);
+ probe vmops__end(char*, uintptr_t, int);
probe gc__begin(uintptr_t);
probe gc__end();
probe mem__pool__gc__begin(
@@ -38,6 +49,12 @@
uintptr_t, uintptr_t, uintptr_t, uintptr_t);
probe thread__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
probe thread__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+ probe thread__sleep__begin(long long);
+ probe thread__sleep__end(int);
+ probe thread__yield();
+ probe thread__park__begin(uintptr_t, int, long long);
+ probe thread__park__end(uintptr_t);
+ probe thread__unpark(uintptr_t);
probe method__compile__begin(
char*, uintptr_t, char*, uintptr_t, char*, uintptr_t, char*, uintptr_t);
probe method__compile__end(
--- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -375,7 +375,8 @@
return -1;
}
- sprintf(door_path, "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id());
+ snprintf(door_path, sizeof(door_path), "%s/.java_pid%d",
+ os::get_temp_directory(), os::current_process_id());
RESTARTABLE(::creat(door_path, S_IRUSR | S_IWUSR), fd);
if (fd == -1) {
@@ -591,13 +592,14 @@
if (init_at_startup() || is_initialized()) {
return false; // initialized at startup or already initialized
}
- char fn[32];
+ char fn[128];
sprintf(fn, ".attach_pid%d", os::current_process_id());
int ret;
struct stat64 st;
RESTARTABLE(::stat64(fn, &st), ret);
if (ret == -1) {
- sprintf(fn, "/tmp/.attach_pid%d", os::current_process_id());
+ snprintf(fn, sizeof(fn), "%s/.attach_pid%d",
+ os::get_temp_directory(), os::current_process_id());
RESTARTABLE(::stat64(fn, &st), ret);
}
if (ret == 0) {
@@ -668,13 +670,18 @@
}
}
- if (strcmp(name, "ExtendedDTraceProbes") != 0) {
- out->print_cr("flag '%s' cannot be changed", name);
- return JNI_ERR;
+ if (strcmp(name, "ExtendedDTraceProbes") == 0) {
+ DTrace::set_extended_dprobes(flag);
+ return JNI_OK;
}
- DTrace::set_extended_dprobes(flag);
- return JNI_OK;
+ if (strcmp(name, "DTraceMonitorProbes") == 0) {
+ DTrace::set_monitor_dprobes(flag);
+ return JNI_OK;
+ }
+
+ out->print_cr("flag '%s' cannot be changed", name);
+ return JNI_ERR;
}
void AttachListener::pd_detachall() {
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -676,15 +676,6 @@
}
-static char* get_property(char* name, char* buffer, int buffer_size) {
- if (os::getenv(name, buffer, buffer_size)) {
- return buffer;
- }
- static char empty[] = "";
- return empty;
-}
-
-
void os::init_system_properties_values() {
char arch[12];
sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
@@ -1826,7 +1817,10 @@
const char* os::dll_file_extension() { return ".so"; }
-const char* os::get_temp_directory() { return "/tmp/"; }
+const char* os::get_temp_directory() {
+ const char *prop = Arguments::get_property("java.io.tmpdir");
+ return prop == NULL ? "/tmp" : prop;
+}
static bool file_exists(const char* filename) {
struct stat statbuf;
@@ -2698,6 +2692,14 @@
}
}
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+ return os::commit_memory(addr, size);
+}
+
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+ return os::uncommit_memory(addr, size);
+}
+
// Change the page size in a given range.
void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -147,11 +147,11 @@
const char* tmpdir = os::get_temp_directory();
const char* perfdir = PERFDATA_NAME;
- size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 2;
+ size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
// construct the path name to user specific tmp directory
- snprintf(dirname, nbytes, "%s%s_%s", tmpdir, perfdir, user);
+ snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
return dirname;
}
@@ -322,8 +322,9 @@
}
char* usrdir_name = NEW_C_HEAP_ARRAY(char,
- strlen(tmpdirname) + strlen(dentry->d_name) + 1);
+ strlen(tmpdirname) + strlen(dentry->d_name) + 2);
strcpy(usrdir_name, tmpdirname);
+ strcat(usrdir_name, "/");
strcat(usrdir_name, dentry->d_name);
DIR* subdirp = os::opendir(usrdir_name);
--- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -998,15 +998,16 @@
const char* os::dll_file_extension() { return ".dll"; }
-const char * os::get_temp_directory()
-{
- static char path_buf[MAX_PATH];
- if (GetTempPath(MAX_PATH, path_buf)>0)
- return path_buf;
- else{
- path_buf[0]='\0';
- return path_buf;
- }
+const char* os::get_temp_directory() {
+ const char *prop = Arguments::get_property("java.io.tmpdir");
+ if (prop != 0) return prop;
+ static char path_buf[MAX_PATH];
+ if (GetTempPath(MAX_PATH, path_buf)>0)
+ return path_buf;
+ else{
+ path_buf[0]='\0';
+ return path_buf;
+ }
}
static bool file_exists(const char* filename) {
@@ -2803,6 +2804,14 @@
return VirtualFree(addr, 0, MEM_RELEASE) != 0;
}
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+ return os::commit_memory(addr, size);
+}
+
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+ return os::uncommit_memory(addr, size);
+}
+
// Set protections specified
bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
bool is_committed) {
--- a/hotspot/src/os/windows/vm/perfMemory_windows.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os/windows/vm/perfMemory_windows.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -149,11 +149,11 @@
const char* tmpdir = os::get_temp_directory();
const char* perfdir = PERFDATA_NAME;
- size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 2;
+ size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
// construct the path name to user specific tmp directory
- _snprintf(dirname, nbytes, "%s%s_%s", tmpdir, perfdir, user);
+ _snprintf(dirname, nbytes, "%s\\%s_%s", tmpdir, perfdir, user);
return dirname;
}
@@ -318,8 +318,9 @@
}
char* usrdir_name = NEW_C_HEAP_ARRAY(char,
- strlen(tmpdirname) + strlen(dentry->d_name) + 1);
+ strlen(tmpdirname) + strlen(dentry->d_name) + 2);
strcpy(usrdir_name, tmpdirname);
+ strcat(usrdir_name, "\\");
strcat(usrdir_name, dentry->d_name);
DIR* subdirp = os::opendir(usrdir_name);
--- a/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,6 +1,6 @@
/*
* Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright 2007, 2008 Red Hat, Inc.
+ * Copyright 2007, 2008, 2010 Red Hat, Inc.
* 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,11 +29,10 @@
//
define_pd_global(bool, DontYieldALot, false);
+define_pd_global(intx, ThreadStackSize, 1536);
#ifdef _LP64
-define_pd_global(intx, ThreadStackSize, 1536);
define_pd_global(intx, VMThreadStackSize, 1024);
#else
-define_pd_global(intx, ThreadStackSize, 1024);
define_pd_global(intx, VMThreadStackSize, 512);
#endif // _LP64
define_pd_global(intx, SurvivorRatio, 8);
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -222,11 +222,15 @@
}
} else {
LoadField* lf = x->array()->as_LoadField();
- if (lf != NULL && lf->field()->is_constant()) {
- ciObject* c = lf->field()->constant_value().as_object();
- if (c->is_array()) {
- ciArray* array = (ciArray*) c;
- set_constant(array->length());
+ if (lf != NULL) {
+ ciField* field = lf->field();
+ if (field->is_constant() && field->is_static()) {
+ // final static field
+ ciObject* c = field->constant_value().as_object();
+ if (c->is_array()) {
+ ciArray* array = (ciArray*) c;
+ set_constant(array->length());
+ }
}
}
}
--- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -415,6 +415,28 @@
};
+//------------------------------------------------------------------------------
+// DeoptimizeStub
+//
+class DeoptimizeStub : public CodeStub {
+private:
+ CodeEmitInfo* _info;
+
+public:
+ DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {}
+
+ virtual void emit_code(LIR_Assembler* e);
+ virtual CodeEmitInfo* info() const { return _info; }
+ virtual bool is_exception_throw_stub() const { return true; }
+ virtual void visit(LIR_OpVisitState* visitor) {
+ visitor->do_slow_case(_info);
+ }
+#ifndef PRODUCT
+ virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
+#endif // PRODUCT
+};
+
+
class SimpleExceptionStub: public CodeStub {
private:
LIR_Opr _obj;
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -1524,18 +1524,14 @@
code = Bytecodes::_invokespecial;
}
- if (code == Bytecodes::_invokedynamic) {
- BAILOUT("invokedynamic NYI"); // FIXME
- return;
- }
-
// NEEDS_CLEANUP
// I've added the target-is_loaded() test below but I don't really understand
// how klass->is_loaded() can be true and yet target->is_loaded() is false.
// this happened while running the JCK invokevirtual tests under doit. TKR
ciMethod* cha_monomorphic_target = NULL;
ciMethod* exact_target = NULL;
- if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded()) {
+ if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() &&
+ !target->is_method_handle_invoke()) {
Value receiver = NULL;
ciInstanceKlass* receiver_klass = NULL;
bool type_is_exact = false;
@@ -1681,11 +1677,20 @@
CHECK_BAILOUT();
// inlining not successful => standard invoke
- bool is_static = code == Bytecodes::_invokestatic;
+ bool is_loaded = target->is_loaded();
+ bool has_receiver =
+ code == Bytecodes::_invokespecial ||
+ code == Bytecodes::_invokevirtual ||
+ code == Bytecodes::_invokeinterface;
+ bool is_invokedynamic = code == Bytecodes::_invokedynamic;
ValueType* result_type = as_ValueType(target->return_type());
+
+ // We require the debug info to be the "state before" because
+ // invokedynamics may deoptimize.
+ ValueStack* state_before = is_invokedynamic ? state()->copy() : NULL;
+
Values* args = state()->pop_arguments(target->arg_size_no_receiver());
- Value recv = is_static ? NULL : apop();
- bool is_loaded = target->is_loaded();
+ Value recv = has_receiver ? apop() : NULL;
int vtable_index = methodOopDesc::invalid_vtable_index;
#ifdef SPARC
@@ -1723,7 +1728,7 @@
profile_call(recv, target_klass);
}
- Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target);
+ Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
// push result
append_split(result);
@@ -2862,20 +2867,18 @@
_initial_state = state_at_entry();
start_block->merge(_initial_state);
- BlockBegin* sync_handler = NULL;
- if (method()->is_synchronized() || _compilation->env()->dtrace_method_probes()) {
- // setup an exception handler to do the unlocking and/or notification
- sync_handler = new BlockBegin(-1);
- sync_handler->set(BlockBegin::exception_entry_flag);
- sync_handler->set(BlockBegin::is_on_work_list_flag);
- sync_handler->set(BlockBegin::default_exception_handler_flag);
-
- ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
- XHandler* h = new XHandler(desc);
- h->set_entry_block(sync_handler);
- scope_data()->xhandlers()->append(h);
- scope_data()->set_has_handler();
- }
+ // setup an exception handler to do the unlocking and/or
+ // notification and unwind the frame.
+ BlockBegin* sync_handler = new BlockBegin(-1);
+ sync_handler->set(BlockBegin::exception_entry_flag);
+ sync_handler->set(BlockBegin::is_on_work_list_flag);
+ sync_handler->set(BlockBegin::default_exception_handler_flag);
+
+ ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
+ XHandler* h = new XHandler(desc);
+ h->set_entry_block(sync_handler);
+ scope_data()->xhandlers()->append(h);
+ scope_data()->set_has_handler();
// complete graph
_vmap = new ValueMap();
--- a/hotspot/src/share/vm/c1/c1_IR.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -259,10 +259,10 @@
}
-void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) {
+void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool is_method_handle_invoke) {
// record the safepoint before recording the debug info for enclosing scopes
recorder->add_safepoint(pc_offset, _oop_map->deep_copy());
- _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/);
+ _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/, is_method_handle_invoke);
recorder->end_safepoint(pc_offset);
}
--- a/hotspot/src/share/vm/c1/c1_IR.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_IR.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -242,7 +242,7 @@
//Whether we should reexecute this bytecode for deopt
bool should_reexecute();
- void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost) {
+ void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost, bool is_method_handle_invoke = false) {
if (caller() != NULL) {
// Order is significant: Must record caller first.
caller()->record_debug_info(recorder, pc_offset, false/*topmost*/);
@@ -252,7 +252,6 @@
DebugToken* monvals = recorder->create_monitor_values(monitors());
// reexecute allowed only for the topmost frame
bool reexecute = topmost ? should_reexecute() : false;
- bool is_method_handle_invoke = false;
bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
}
@@ -303,7 +302,7 @@
int bci() const { return _bci; }
void add_register_oop(LIR_Opr opr);
- void record_debug_info(DebugInformationRecorder* recorder, int pc_offset);
+ void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool is_method_handle_invoke = false);
CodeEmitInfo* next() const { return _next; }
void set_next(CodeEmitInfo* next) { _next = next; }
--- a/hotspot/src/share/vm/c1/c1_Instruction.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_Instruction.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -334,13 +334,14 @@
Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args,
- int vtable_index, ciMethod* target)
+ int vtable_index, ciMethod* target, ValueStack* state_before)
: StateSplit(result_type)
, _code(code)
, _recv(recv)
, _args(args)
, _vtable_index(vtable_index)
, _target(target)
+ , _state_before(state_before)
{
set_flag(TargetIsLoadedFlag, target->is_loaded());
set_flag(TargetIsFinalFlag, target_is_loaded() && target->is_final_method());
@@ -355,6 +356,9 @@
_signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0));
if (has_receiver()) {
_signature->append(as_BasicType(receiver()->type()));
+ } else if (is_invokedynamic()) {
+ // Add the synthetic MethodHandle argument to the signature.
+ _signature->append(T_OBJECT);
}
for (int i = 0; i < number_of_arguments(); i++) {
ValueType* t = argument_at(i)->type();
@@ -364,6 +368,13 @@
}
+void Invoke::state_values_do(void f(Value*)) {
+ StateSplit::state_values_do(f);
+ if (state_before() != NULL) state_before()->values_do(f);
+ if (state() != NULL) state()->values_do(f);
+}
+
+
// Implementation of Contant
intx Constant::hash() const {
if (_state == NULL) {
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -1134,17 +1134,18 @@
LEAF(Invoke, StateSplit)
private:
- Bytecodes::Code _code;
- Value _recv;
- Values* _args;
- BasicTypeList* _signature;
- int _vtable_index;
- ciMethod* _target;
+ Bytecodes::Code _code;
+ Value _recv;
+ Values* _args;
+ BasicTypeList* _signature;
+ int _vtable_index;
+ ciMethod* _target;
+ ValueStack* _state_before; // Required for deoptimization.
public:
// creation
Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args,
- int vtable_index, ciMethod* target);
+ int vtable_index, ciMethod* target, ValueStack* state_before);
// accessors
Bytecodes::Code code() const { return _code; }
@@ -1155,6 +1156,7 @@
int vtable_index() const { return _vtable_index; }
BasicTypeList* signature() const { return _signature; }
ciMethod* target() const { return _target; }
+ ValueStack* state_before() const { return _state_before; }
// Returns false if target is not loaded
bool target_is_final() const { return check_flag(TargetIsFinalFlag); }
@@ -1162,6 +1164,9 @@
// Returns false if target is not loaded
bool target_is_strictfp() const { return check_flag(TargetIsStrictfpFlag); }
+ // JSR 292 support
+ bool is_invokedynamic() const { return code() == Bytecodes::_invokedynamic; }
+
// generic
virtual bool can_trap() const { return true; }
virtual void input_values_do(void f(Value*)) {
@@ -1169,6 +1174,7 @@
if (has_receiver()) f(&_recv);
for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i));
}
+ virtual void state_values_do(void f(Value*));
};
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 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
@@ -76,7 +76,7 @@
return LIR_OprFact::oopConst(type->as_ObjectType()->encoding());
}
}
- case addressTag: return LIR_OprFact::intConst(type->as_AddressConstant()->value());
+ case addressTag: return LIR_OprFact::addressConst(type->as_AddressConstant()->value());
case intTag : return LIR_OprFact::intConst(type->as_IntConstant()->value());
case floatTag : return LIR_OprFact::floatConst(type->as_FloatConstant()->value());
case longTag : return LIR_OprFact::longConst(type->as_LongConstant()->value());
@@ -89,7 +89,7 @@
LIR_Opr LIR_OprFact::dummy_value_type(ValueType* type) {
switch (type->tag()) {
case objectTag: return LIR_OprFact::oopConst(NULL);
- case addressTag:
+ case addressTag:return LIR_OprFact::addressConst(0);
case intTag: return LIR_OprFact::intConst(0);
case floatTag: return LIR_OprFact::floatConst(0.0);
case longTag: return LIR_OprFact::longConst(0);
@@ -689,9 +689,10 @@
case lir_static_call:
case lir_optvirtual_call:
case lir_icvirtual_call:
- case lir_virtual_call: {
- assert(op->as_OpJavaCall() != NULL, "must be");
- LIR_OpJavaCall* opJavaCall = (LIR_OpJavaCall*)op;
+ case lir_virtual_call:
+ case lir_dynamic_call: {
+ LIR_OpJavaCall* opJavaCall = op->as_OpJavaCall();
+ assert(opJavaCall != NULL, "must be");
if (opJavaCall->_receiver->is_valid()) do_input(opJavaCall->_receiver);
@@ -704,6 +705,7 @@
}
if (opJavaCall->_info) do_info(opJavaCall->_info);
+ if (opJavaCall->is_method_handle_invoke()) do_temp(FrameMap::method_handle_invoke_SP_save_opr());
do_call();
if (opJavaCall->_result->is_valid()) do_output(opJavaCall->_result);
@@ -1410,6 +1412,7 @@
// LIR_Address
void LIR_Const::print_value_on(outputStream* out) const {
switch (type()) {
+ case T_ADDRESS:out->print("address:%d",as_jint()); break;
case T_INT: out->print("int:%d", as_jint()); break;
case T_LONG: out->print("lng:%lld", as_jlong()); break;
case T_FLOAT: out->print("flt:%f", as_jfloat()); break;
@@ -1590,6 +1593,7 @@
case lir_optvirtual_call: s = "optvirtual"; break;
case lir_icvirtual_call: s = "icvirtual"; break;
case lir_virtual_call: s = "virtual"; break;
+ case lir_dynamic_call: s = "dynamic"; break;
// LIR_OpArrayCopy
case lir_arraycopy: s = "arraycopy"; break;
// LIR_OpLock
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -85,9 +85,10 @@
void type_check(BasicType t) const { assert(type() == t, "type check"); }
void type_check(BasicType t1, BasicType t2) const { assert(type() == t1 || type() == t2, "type check"); }
+ void type_check(BasicType t1, BasicType t2, BasicType t3) const { assert(type() == t1 || type() == t2 || type() == t3, "type check"); }
public:
- LIR_Const(jint i) { _value.set_type(T_INT); _value.set_jint(i); }
+ LIR_Const(jint i, bool is_address=false) { _value.set_type(is_address?T_ADDRESS:T_INT); _value.set_jint(i); }
LIR_Const(jlong l) { _value.set_type(T_LONG); _value.set_jlong(l); }
LIR_Const(jfloat f) { _value.set_type(T_FLOAT); _value.set_jfloat(f); }
LIR_Const(jdouble d) { _value.set_type(T_DOUBLE); _value.set_jdouble(d); }
@@ -105,7 +106,7 @@
virtual BasicType type() const { return _value.get_type(); }
virtual LIR_Const* as_constant() { return this; }
- jint as_jint() const { type_check(T_INT ); return _value.get_jint(); }
+ jint as_jint() const { type_check(T_INT, T_ADDRESS); return _value.get_jint(); }
jlong as_jlong() const { type_check(T_LONG ); return _value.get_jlong(); }
jfloat as_jfloat() const { type_check(T_FLOAT ); return _value.get_jfloat(); }
jdouble as_jdouble() const { type_check(T_DOUBLE); return _value.get_jdouble(); }
@@ -120,7 +121,7 @@
#endif
- jint as_jint_bits() const { type_check(T_FLOAT, T_INT); return _value.get_jint(); }
+ jint as_jint_bits() const { type_check(T_FLOAT, T_INT, T_ADDRESS); return _value.get_jint(); }
jint as_jint_lo_bits() const {
if (type() == T_DOUBLE) {
return low(jlong_cast(_value.get_jdouble()));
@@ -718,6 +719,7 @@
static LIR_Opr intptrConst(void* p) { return (LIR_Opr)(new LIR_Const(p)); }
static LIR_Opr intptrConst(intptr_t v) { return (LIR_Opr)(new LIR_Const((void*)v)); }
static LIR_Opr illegal() { return (LIR_Opr)-1; }
+ static LIR_Opr addressConst(jint i) { return (LIR_Opr)(new LIR_Const(i, true)); }
static LIR_Opr value_type(ValueType* type);
static LIR_Opr dummy_value_type(ValueType* type);
@@ -840,6 +842,7 @@
, lir_optvirtual_call
, lir_icvirtual_call
, lir_virtual_call
+ , lir_dynamic_call
, end_opJavaCall
, begin_opArrayCopy
, lir_arraycopy
@@ -1052,6 +1055,16 @@
LIR_Opr receiver() const { return _receiver; }
ciMethod* method() const { return _method; }
+ // JSR 292 support.
+ bool is_invokedynamic() const { return code() == lir_dynamic_call; }
+ bool is_method_handle_invoke() const {
+ return
+ is_invokedynamic() // An invokedynamic is always a MethodHandle call site.
+ ||
+ (method()->holder()->name() == ciSymbol::java_dyn_MethodHandle() &&
+ method()->name() == ciSymbol::invoke_name());
+ }
+
intptr_t vtable_offset() const {
assert(_code == lir_virtual_call, "only have vtable for real vcall");
return (intptr_t) addr();
@@ -1766,6 +1779,10 @@
intptr_t vtable_offset, LIR_OprList* arguments, CodeEmitInfo* info) {
append(new LIR_OpJavaCall(lir_virtual_call, method, receiver, result, vtable_offset, arguments, info));
}
+ void call_dynamic(ciMethod* method, LIR_Opr receiver, LIR_Opr result,
+ address dest, LIR_OprList* arguments, CodeEmitInfo* info) {
+ append(new LIR_OpJavaCall(lir_dynamic_call, method, receiver, result, dest, arguments, info));
+ }
void get_thread(LIR_Opr result) { append(new LIR_Op0(lir_get_thread, result)); }
void word_align() { append(new LIR_Op0(lir_word_align)); }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 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
@@ -301,9 +301,9 @@
}
-void LIR_Assembler::add_call_info(int pc_offset, CodeEmitInfo* cinfo) {
+void LIR_Assembler::add_call_info(int pc_offset, CodeEmitInfo* cinfo, bool is_method_handle_invoke) {
flush_debug_info(pc_offset);
- cinfo->record_debug_info(compilation()->debug_info_recorder(), pc_offset);
+ cinfo->record_debug_info(compilation()->debug_info_recorder(), pc_offset, is_method_handle_invoke);
if (cinfo->exception_handlers() != NULL) {
compilation()->add_exception_handlers_for_pco(pc_offset, cinfo->exception_handlers());
}
@@ -413,6 +413,12 @@
void LIR_Assembler::emit_call(LIR_OpJavaCall* op) {
verify_oop_map(op->info());
+ // JSR 292
+ // Preserve the SP over MethodHandle call sites.
+ if (op->is_method_handle_invoke()) {
+ preserve_SP(op);
+ }
+
if (os::is_MP()) {
// must align calls sites, otherwise they can't be updated atomically on MP hardware
align_call(op->code());
@@ -423,19 +429,25 @@
switch (op->code()) {
case lir_static_call:
- call(op->addr(), relocInfo::static_call_type, op->info());
+ call(op, relocInfo::static_call_type);
break;
case lir_optvirtual_call:
- call(op->addr(), relocInfo::opt_virtual_call_type, op->info());
+ case lir_dynamic_call:
+ call(op, relocInfo::opt_virtual_call_type);
break;
case lir_icvirtual_call:
- ic_call(op->addr(), op->info());
+ ic_call(op);
break;
case lir_virtual_call:
- vtable_call(op->vtable_offset(), op->info());
+ vtable_call(op);
break;
default: ShouldNotReachHere();
}
+
+ if (op->is_method_handle_invoke()) {
+ restore_SP(op);
+ }
+
#if defined(X86) && defined(TIERED)
// C2 leave fpu stack dirty clean it
if (UseSSE < 2) {
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -82,7 +82,7 @@
Address as_Address_hi(LIR_Address* addr);
// debug information
- void add_call_info(int pc_offset, CodeEmitInfo* cinfo);
+ void add_call_info(int pc_offset, CodeEmitInfo* cinfo, bool is_method_handle_invoke = false);
void add_debug_info_for_branch(CodeEmitInfo* info);
void add_debug_info_for_div0(int pc_offset, CodeEmitInfo* cinfo);
void add_debug_info_for_div0_here(CodeEmitInfo* info);
@@ -205,9 +205,13 @@
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 ic_call(address destination, CodeEmitInfo* info);
- void vtable_call(int vtable_offset, CodeEmitInfo* info);
- void call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info);
+ void call( LIR_OpJavaCall* op, relocInfo::relocType rtype);
+ void ic_call( LIR_OpJavaCall* op);
+ void vtable_call( LIR_OpJavaCall* op);
+
+ // JSR 292
+ void preserve_SP(LIR_OpJavaCall* op);
+ void restore_SP( LIR_OpJavaCall* op);
void osr_entry();
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -2284,7 +2284,7 @@
void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
- int i = x->has_receiver() ? 1 : 0;
+ int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0;
for (; i < args->length(); i++) {
LIRItem* param = args->at(i);
LIR_Opr loc = arg_list->at(i);
@@ -2322,6 +2322,10 @@
LIRItem* receiver = new LIRItem(x->receiver(), this);
argument_items->append(receiver);
}
+ if (x->is_invokedynamic()) {
+ // Insert a dummy for the synthetic MethodHandle argument.
+ argument_items->append(NULL);
+ }
int idx = x->has_receiver() ? 1 : 0;
for (int i = 0; i < x->number_of_arguments(); i++) {
LIRItem* param = new LIRItem(x->argument_at(i), this);
@@ -2371,6 +2375,9 @@
CodeEmitInfo* info = state_for(x, x->state());
+ // invokedynamics can deoptimize.
+ CodeEmitInfo* deopt_info = x->is_invokedynamic() ? state_for(x, x->state_before()) : NULL;
+
invoke_load_arguments(x, args, arg_list);
if (x->has_receiver()) {
@@ -2407,6 +2414,47 @@
__ call_virtual(x->target(), receiver, result_register, vtable_offset, arg_list, info);
}
break;
+ case Bytecodes::_invokedynamic: {
+ ciBytecodeStream bcs(x->scope()->method());
+ bcs.force_bci(x->bci());
+ assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream");
+ ciCPCache* cpcache = bcs.get_cpcache();
+
+ // Get CallSite offset from constant pool cache pointer.
+ int index = bcs.get_method_index();
+ size_t call_site_offset = cpcache->get_f1_offset(index);
+
+ // If this invokedynamic call site hasn't been executed yet in
+ // the interpreter, the CallSite object in the constant pool
+ // cache is still null and we need to deoptimize.
+ if (cpcache->is_f1_null_at(index)) {
+ // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
+ // clone all handlers. This is handled transparently in other
+ // places by the CodeEmitInfo cloning logic but is handled
+ // specially here because a stub isn't being used.
+ x->set_exception_handlers(new XHandlers(x->exception_handlers()));
+
+ DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info);
+ __ jump(deopt_stub);
+ }
+
+ // Use the receiver register for the synthetic MethodHandle
+ // argument.
+ receiver = LIR_Assembler::receiverOpr();
+ LIR_Opr tmp = new_register(objectType);
+
+ // Load CallSite object from constant pool cache.
+ __ oop2reg(cpcache->constant_encoding(), tmp);
+ __ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
+
+ // Load target MethodHandle from CallSite object.
+ __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
+
+ __ call_dynamic(x->target(), receiver, result_register,
+ SharedRuntime::get_resolve_opt_virtual_call_stub(),
+ arg_list, info);
+ break;
+ }
default:
ShouldNotReachHere();
break;
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -2479,6 +2479,15 @@
return 2;
}
+ case T_ADDRESS: {
+#ifdef _LP64
+ scope_values->append(new ConstantLongValue(c->as_jint()));
+#else
+ scope_values->append(new ConstantIntValue(c->as_jint()));
+#endif
+ return 1;
+ }
+
default:
ShouldNotReachHere();
return -1;
@@ -2599,12 +2608,17 @@
} else if (opr->is_double_xmm()) {
assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation");
VMReg rname_first = opr->as_xmm_double_reg()->as_VMReg();
+# ifdef _LP64
+ first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first));
+ second = &_int_0_scope_value;
+# else
first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first));
// %%% This is probably a waste but we'll keep things as they were for now
if (true) {
VMReg rname_second = rname_first->next();
second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second));
}
+# endif
#endif
} else if (opr->is_double_fpu()) {
@@ -2630,13 +2644,17 @@
#endif
VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrHi());
-
+#ifdef _LP64
+ first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first));
+ second = &_int_0_scope_value;
+#else
first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first));
// %%% This is probably a waste but we'll keep things as they were for now
if (true) {
VMReg rname_second = rname_first->next();
second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second));
}
+#endif
} else {
ShouldNotReachHere();
--- a/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 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
@@ -34,7 +34,7 @@
void inline_cache_check(Register receiver, Register iCache);
void build_frame(int frame_size_in_bytes);
- void method_exit(bool restore_frame);
+ void remove_frame(int frame_size_in_bytes);
void unverified_entry(Register receiver, Register ic_klass);
void verified_entry();
--- a/hotspot/src/share/vm/ci/ciCPCache.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/ci/ciCPCache.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009-2010 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
@@ -41,6 +41,16 @@
// ------------------------------------------------------------------
+// ciCPCache::is_f1_null_at
+bool ciCPCache::is_f1_null_at(int index) {
+ VM_ENTRY_MARK;
+ constantPoolCacheOop cpcache = (constantPoolCacheOop) get_oop();
+ oop f1 = cpcache->secondary_entry_at(index)->f1();
+ return (f1 == NULL);
+}
+
+
+// ------------------------------------------------------------------
// ciCPCache::print
//
// Print debugging information about the cache.
--- a/hotspot/src/share/vm/ci/ciCPCache.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/ci/ciCPCache.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009-2010 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
@@ -39,5 +39,7 @@
// requested entry.
size_t get_f1_offset(int index);
+ bool is_f1_null_at(int index);
+
void print();
};
--- a/hotspot/src/share/vm/ci/ciConstant.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/ci/ciConstant.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -36,7 +36,7 @@
basictype_to_str(basic_type()));
switch (basic_type()) {
case T_BOOLEAN:
- tty->print("%s", bool_to_str(_value._int == 0));
+ tty->print("%s", bool_to_str(_value._int != 0));
break;
case T_CHAR:
case T_BYTE:
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -385,11 +385,6 @@
KILL_COMPILE_ON_FATAL_(fail_type));
}
- if (found_klass != NULL) {
- // Found it. Build a CI handle.
- return get_object(found_klass)->as_klass();
- }
-
// If we fail to find an array klass, look again for its element type.
// The element type may be available either locally or via constraints.
// In either case, if we can find the element type in the system dictionary,
@@ -414,6 +409,11 @@
}
}
+ if (found_klass != NULL) {
+ // Found it. Build a CI handle.
+ return get_object(found_klass)->as_klass();
+ }
+
if (require_local) return NULL;
// Not yet loaded into the VM, or not governed by loader constraints.
// Make a CI representative for it.
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -2956,8 +2956,8 @@
#endif
bool compact_fields = CompactFields;
int allocation_style = FieldsAllocationStyle;
- if( allocation_style < 0 || allocation_style > 1 ) { // Out of range?
- assert(false, "0 <= FieldsAllocationStyle <= 1");
+ if( allocation_style < 0 || allocation_style > 2 ) { // Out of range?
+ assert(false, "0 <= FieldsAllocationStyle <= 2");
allocation_style = 1; // Optimistic
}
@@ -2993,6 +2993,25 @@
} else if( allocation_style == 1 ) {
// Fields order: longs/doubles, ints, shorts/chars, bytes, oops
next_nonstatic_double_offset = next_nonstatic_field_offset;
+ } else if( allocation_style == 2 ) {
+ // Fields allocation: oops fields in super and sub classes are together.
+ if( nonstatic_field_size > 0 && super_klass() != NULL &&
+ super_klass->nonstatic_oop_map_size() > 0 ) {
+ int map_size = super_klass->nonstatic_oop_map_size();
+ OopMapBlock* first_map = super_klass->start_of_nonstatic_oop_maps();
+ OopMapBlock* last_map = first_map + map_size - 1;
+ int next_offset = last_map->offset() + (last_map->count() * heapOopSize);
+ if (next_offset == next_nonstatic_field_offset) {
+ allocation_style = 0; // allocate oops first
+ next_nonstatic_oop_offset = next_nonstatic_field_offset;
+ next_nonstatic_double_offset = next_nonstatic_oop_offset +
+ (nonstatic_oop_count * heapOopSize);
+ }
+ }
+ if( allocation_style == 2 ) {
+ allocation_style = 1; // allocate oops last
+ next_nonstatic_double_offset = next_nonstatic_field_offset;
+ }
} else {
ShouldNotReachHere();
}
--- a/hotspot/src/share/vm/classfile/loaderConstraints.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -334,33 +334,6 @@
return NULL;
}
-
-klassOop LoaderConstraintTable::find_constrained_elem_klass(symbolHandle name,
- symbolHandle elem_name,
- Handle loader,
- TRAPS) {
- LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
- if (p != NULL) {
- assert(p->klass() == NULL, "Expecting null array klass");
-
- // The array name has a constraint, but it will not have a class. Check
- // each loader for an associated elem
- for (int i = 0; i < p->num_loaders(); i++) {
- Handle no_protection_domain;
-
- klassOop k = SystemDictionary::find(elem_name, p->loader(i), no_protection_domain, THREAD);
- if (k != NULL) {
- // Return the first elem klass found.
- return k;
- }
- }
- }
-
- // No constraints, or else no klass loaded yet.
- return NULL;
-}
-
-
void LoaderConstraintTable::ensure_loader_constraint_capacity(
LoaderConstraintEntry *p,
int nfree) {
--- a/hotspot/src/share/vm/classfile/loaderConstraints.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -66,9 +66,6 @@
// bool is_method, TRAPS)
klassOop find_constrained_klass(symbolHandle name, Handle loader);
- klassOop find_constrained_elem_klass(symbolHandle name, symbolHandle elem_name,
- Handle loader, TRAPS);
-
// Class loader constraints
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -2178,9 +2178,8 @@
// a loader constraint that would require this loader to return the
// klass that is already loaded.
if (FieldType::is_array(class_name())) {
- // Array classes are hard because their klassOops are not kept in the
- // constraint table. The array klass may be constrained, but the elem class
- // may not be.
+ // For array classes, their klassOops are not kept in the
+ // constraint table. The element klassOops are.
jint dimension;
symbolOop object_key;
BasicType t = FieldType::get_array_info(class_name(), &dimension,
@@ -2190,8 +2189,9 @@
} else {
symbolHandle elem_name(THREAD, object_key);
MutexLocker mu(SystemDictionary_lock, THREAD);
- klass = constraints()->find_constrained_elem_klass(class_name, elem_name, class_loader, THREAD);
+ klass = constraints()->find_constrained_klass(elem_name, class_loader);
}
+ // If element class already loaded, allocate array klass
if (klass != NULL) {
klass = Klass::cast(klass)->array_klass_or_null(dimension);
}
@@ -2209,22 +2209,38 @@
Handle class_loader1,
Handle class_loader2,
Thread* THREAD) {
- unsigned int d_hash1 = dictionary()->compute_hash(class_name, class_loader1);
+ symbolHandle constraint_name;
+ if (!FieldType::is_array(class_name())) {
+ constraint_name = class_name;
+ } else {
+ // For array classes, their klassOops are not kept in the
+ // constraint table. The element classes are.
+ jint dimension;
+ symbolOop object_key;
+ BasicType t = FieldType::get_array_info(class_name(), &dimension,
+ &object_key, CHECK_(false));
+ // primitive types always pass
+ if (t != T_OBJECT) {
+ return true;
+ } else {
+ constraint_name = symbolHandle(THREAD, object_key);
+ }
+ }
+ unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1);
int d_index1 = dictionary()->hash_to_index(d_hash1);
- unsigned int d_hash2 = dictionary()->compute_hash(class_name, class_loader2);
+ unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, class_loader2);
int d_index2 = dictionary()->hash_to_index(d_hash2);
-
{
- MutexLocker mu_s(SystemDictionary_lock, THREAD);
+ MutexLocker mu_s(SystemDictionary_lock, THREAD);
- // Better never do a GC while we're holding these oops
- No_Safepoint_Verifier nosafepoint;
+ // Better never do a GC while we're holding these oops
+ No_Safepoint_Verifier nosafepoint;
- klassOop klass1 = find_class(d_index1, d_hash1, class_name, class_loader1);
- klassOop klass2 = find_class(d_index2, d_hash2, class_name, class_loader2);
- return constraints()->add_entry(class_name, klass1, class_loader1,
- klass2, class_loader2);
+ klassOop klass1 = find_class(d_index1, d_hash1, constraint_name, class_loader1);
+ klassOop klass2 = find_class(d_index2, d_hash2, constraint_name, class_loader2);
+ return constraints()->add_entry(constraint_name, klass1, class_loader1,
+ klass2, class_loader2);
}
}
@@ -2301,6 +2317,7 @@
// Returns the name of the type that failed a loader constraint check, or
// NULL if no constraint failed. The returned C string needs cleaning up
// with a ResourceMark in the caller. No exception except OOME is thrown.
+// Arrays are not added to the loader constraint table, their elements are.
char* SystemDictionary::check_signature_loaders(symbolHandle signature,
Handle loader1, Handle loader2,
bool is_method, TRAPS) {
--- a/hotspot/src/share/vm/code/codeBlob.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/code/codeBlob.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2010 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
@@ -249,7 +249,6 @@
size += round_to(buffer_size, oopSize);
assert(name != NULL, "must provide a name");
{
-
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
blob = new (size) BufferBlob(name, size);
}
@@ -271,7 +270,6 @@
unsigned int size = allocation_size(cb, sizeof(BufferBlob));
assert(name != NULL, "must provide a name");
{
-
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
blob = new (size) BufferBlob(name, size, cb);
}
@@ -298,10 +296,48 @@
MemoryService::track_code_cache_memory_usage();
}
-bool BufferBlob::is_adapter_blob() const {
- return (strcmp(AdapterHandlerEntry::name, name()) == 0);
+
+//----------------------------------------------------------------------------------------------------
+// Implementation of AdapterBlob
+
+AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
+ ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
+
+ AdapterBlob* blob = NULL;
+ unsigned int size = allocation_size(cb, sizeof(AdapterBlob));
+ {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ blob = new (size) AdapterBlob(size, cb);
+ }
+ // Track memory usage statistic after releasing CodeCache_lock
+ MemoryService::track_code_cache_memory_usage();
+
+ return blob;
}
+
+//----------------------------------------------------------------------------------------------------
+// Implementation of MethodHandlesAdapterBlob
+
+MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) {
+ ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
+
+ MethodHandlesAdapterBlob* blob = NULL;
+ unsigned int size = sizeof(MethodHandlesAdapterBlob);
+ // align the size to CodeEntryAlignment
+ size = align_code_offset(size);
+ size += round_to(buffer_size, oopSize);
+ {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ blob = new (size) MethodHandlesAdapterBlob(size);
+ }
+ // Track memory usage statistic after releasing CodeCache_lock
+ MemoryService::track_code_cache_memory_usage();
+
+ return blob;
+}
+
+
//----------------------------------------------------------------------------------------------------
// Implementation of RuntimeStub
--- a/hotspot/src/share/vm/code/codeBlob.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/code/codeBlob.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2010 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
@@ -90,14 +90,15 @@
void flush();
// Typing
- virtual bool is_buffer_blob() const { return false; }
- virtual bool is_nmethod() const { return false; }
- virtual bool is_runtime_stub() const { return false; }
- virtual bool is_deoptimization_stub() const { return false; }
- virtual bool is_uncommon_trap_stub() const { return false; }
- virtual bool is_exception_stub() const { return false; }
- virtual bool is_safepoint_stub() const { return false; }
- virtual bool is_adapter_blob() const { return false; }
+ virtual bool is_buffer_blob() const { return false; }
+ virtual bool is_nmethod() const { return false; }
+ virtual bool is_runtime_stub() const { return false; }
+ virtual bool is_deoptimization_stub() const { return false; }
+ virtual bool is_uncommon_trap_stub() const { return false; }
+ virtual bool is_exception_stub() const { return false; }
+ virtual bool is_safepoint_stub() const { return false; }
+ virtual bool is_adapter_blob() const { return false; }
+ virtual bool is_method_handles_adapter_blob() const { return false; }
virtual bool is_compiled_by_c2() const { return false; }
virtual bool is_compiled_by_c1() const { return false; }
@@ -221,6 +222,9 @@
class BufferBlob: public CodeBlob {
friend class VMStructs;
+ friend class AdapterBlob;
+ friend class MethodHandlesAdapterBlob;
+
private:
// Creation support
BufferBlob(const char* name, int size);
@@ -236,8 +240,7 @@
static void free(BufferBlob* buf);
// Typing
- bool is_buffer_blob() const { return true; }
- bool is_adapter_blob() const;
+ virtual bool is_buffer_blob() const { return true; }
// GC/Verification support
void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }
@@ -255,6 +258,40 @@
//----------------------------------------------------------------------------------------------------
+// AdapterBlob: used to hold C2I/I2C adapters
+
+class AdapterBlob: public BufferBlob {
+private:
+ AdapterBlob(int size) : BufferBlob("I2C/C2I adapters", size) {}
+ AdapterBlob(int size, CodeBuffer* cb) : BufferBlob("I2C/C2I adapters", size, cb) {}
+
+public:
+ // Creation
+ static AdapterBlob* create(CodeBuffer* cb);
+
+ // Typing
+ virtual bool is_adapter_blob() const { return true; }
+};
+
+
+//----------------------------------------------------------------------------------------------------
+// MethodHandlesAdapterBlob: used to hold MethodHandles adapters
+
+class MethodHandlesAdapterBlob: public BufferBlob {
+private:
+ MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {}
+ MethodHandlesAdapterBlob(int size, CodeBuffer* cb) : BufferBlob("MethodHandles adapters", size, cb) {}
+
+public:
+ // Creation
+ static MethodHandlesAdapterBlob* create(int buffer_size);
+
+ // Typing
+ virtual bool is_method_handles_adapter_blob() const { return true; }
+};
+
+
+//----------------------------------------------------------------------------------------------------
// RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
class RuntimeStub: public CodeBlob {
--- a/hotspot/src/share/vm/code/codeCache.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/code/codeCache.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -284,9 +284,11 @@
cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr();
}
#endif //PRODUCT
- if (is_live)
+ if (is_live) {
// Perform cur->oops_do(f), maybe just once per nmethod.
f->do_code_blob(cur);
+ cur->fix_oop_relocations();
+ }
}
// Check for stray marks.
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -988,10 +988,12 @@
}
if (method->is_not_compilable(comp_level)) return NULL;
- nmethod* saved = CodeCache::find_and_remove_saved_code(method());
- if (saved != NULL) {
- method->set_code(method, saved);
- return saved;
+ if (UseCodeCacheFlushing) {
+ nmethod* saved = CodeCache::find_and_remove_saved_code(method());
+ if (saved != NULL) {
+ method->set_code(method, saved);
+ return saved;
+ }
}
} else {
@@ -1412,9 +1414,14 @@
intx thread_id = os::current_thread_id();
for (int try_temp_dir = 1; try_temp_dir >= 0; try_temp_dir--) {
const char* dir = (try_temp_dir ? os::get_temp_directory() : NULL);
- if (dir == NULL) dir = "";
- sprintf(fileBuf, "%shs_c" UINTX_FORMAT "_pid%u.log",
- dir, thread_id, os::current_process_id());
+ if (dir == NULL) {
+ jio_snprintf(fileBuf, sizeof(fileBuf), "hs_c" UINTX_FORMAT "_pid%u.log",
+ thread_id, os::current_process_id());
+ } else {
+ jio_snprintf(fileBuf, sizeof(fileBuf),
+ "%s%shs_c" UINTX_FORMAT "_pid%u.log", dir,
+ os::file_separator(), thread_id, os::current_process_id());
+ }
fp = fopen(fileBuf, "at");
if (fp != NULL) {
file = NEW_C_HEAP_ARRAY(char, strlen(fileBuf)+1);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -46,9 +46,9 @@
_processor_count = os::active_processor_count();
- if (CMSConcurrentMTEnabled && (ParallelCMSThreads > 1)) {
+ if (CMSConcurrentMTEnabled && (ConcGCThreads > 1)) {
assert(_processor_count > 0, "Processor count is suspect");
- _concurrent_processor_count = MIN2((uint) ParallelCMSThreads,
+ _concurrent_processor_count = MIN2((uint) ConcGCThreads,
(uint) _processor_count);
} else {
_concurrent_processor_count = 1;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -606,7 +606,7 @@
assert(_modUnionTable.covers(_span), "_modUnionTable inconsistency?");
}
- if (!_markStack.allocate(CMSMarkStackSize)) {
+ if (!_markStack.allocate(MarkStackSize)) {
warning("Failed to allocate CMS Marking Stack");
return;
}
@@ -617,13 +617,13 @@
// Support for multi-threaded concurrent phases
if (ParallelGCThreads > 0 && CMSConcurrentMTEnabled) {
- if (FLAG_IS_DEFAULT(ParallelCMSThreads)) {
+ if (FLAG_IS_DEFAULT(ConcGCThreads)) {
// just for now
- FLAG_SET_DEFAULT(ParallelCMSThreads, (ParallelGCThreads + 3)/4);
- }
- if (ParallelCMSThreads > 1) {
+ FLAG_SET_DEFAULT(ConcGCThreads, (ParallelGCThreads + 3)/4);
+ }
+ if (ConcGCThreads > 1) {
_conc_workers = new YieldingFlexibleWorkGang("Parallel CMS Threads",
- ParallelCMSThreads, true);
+ ConcGCThreads, true);
if (_conc_workers == NULL) {
warning("GC/CMS: _conc_workers allocation failure: "
"forcing -CMSConcurrentMTEnabled");
@@ -634,13 +634,13 @@
}
}
if (!CMSConcurrentMTEnabled) {
- ParallelCMSThreads = 0;
+ ConcGCThreads = 0;
} else {
// Turn off CMSCleanOnEnter optimization temporarily for
// the MT case where it's not fixed yet; see 6178663.
CMSCleanOnEnter = false;
}
- assert((_conc_workers != NULL) == (ParallelCMSThreads > 1),
+ assert((_conc_workers != NULL) == (ConcGCThreads > 1),
"Inconsistency");
// Parallel task queues; these are shared for the
@@ -648,7 +648,7 @@
// are not shared with parallel scavenge (ParNew).
{
uint i;
- uint num_queues = (uint) MAX2(ParallelGCThreads, ParallelCMSThreads);
+ uint num_queues = (uint) MAX2(ParallelGCThreads, ConcGCThreads);
if ((CMSParallelRemarkEnabled || CMSConcurrentMTEnabled
|| ParallelRefProcEnabled)
@@ -723,8 +723,9 @@
// Support for parallelizing survivor space rescan
if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
- size_t max_plab_samples = cp->max_gen0_size()/
- ((SurvivorRatio+2)*MinTLABSize);
+ const size_t max_plab_samples =
+ ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
+
_survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
_survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
_cursor = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
@@ -3657,7 +3658,7 @@
assert(_revisitStack.isEmpty(), "tabula rasa");
DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
bool result = false;
- if (CMSConcurrentMTEnabled && ParallelCMSThreads > 0) {
+ if (CMSConcurrentMTEnabled && ConcGCThreads > 0) {
result = do_marking_mt(asynch);
} else {
result = do_marking_st(asynch);
@@ -4174,10 +4175,10 @@
}
bool CMSCollector::do_marking_mt(bool asynch) {
- assert(ParallelCMSThreads > 0 && conc_workers() != NULL, "precondition");
+ assert(ConcGCThreads > 0 && conc_workers() != NULL, "precondition");
// In the future this would be determined ergonomically, based
// on #cpu's, # active mutator threads (and load), and mutation rate.
- int num_workers = ParallelCMSThreads;
+ int num_workers = ConcGCThreads;
CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
@@ -6429,8 +6430,8 @@
// For now we take the expedient path of just disabling the
// messages for the problematic case.)
void CMSMarkStack::expand() {
- assert(_capacity <= CMSMarkStackSizeMax, "stack bigger than permitted");
- if (_capacity == CMSMarkStackSizeMax) {
+ assert(_capacity <= MarkStackSizeMax, "stack bigger than permitted");
+ if (_capacity == MarkStackSizeMax) {
if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
// We print a warning message only once per CMS cycle.
gclog_or_tty->print_cr(" (benign) Hit CMSMarkStack max size limit");
@@ -6438,7 +6439,7 @@
return;
}
// Double capacity if possible
- size_t new_capacity = MIN2(_capacity*2, CMSMarkStackSizeMax);
+ size_t new_capacity = MIN2(_capacity*2, MarkStackSizeMax);
// Do not give up existing stack until we have managed to
// get the double capacity that we desired.
ReservedSpace rs(ReservedSpace::allocation_align_size_up(
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -44,20 +44,20 @@
{
// Ergomonically select initial concurrent refinement parameters
- if (FLAG_IS_DEFAULT(G1ConcRefineGreenZone)) {
- FLAG_SET_DEFAULT(G1ConcRefineGreenZone, MAX2<int>(ParallelGCThreads, 1));
+ if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
+ FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, MAX2<int>(ParallelGCThreads, 1));
}
- set_green_zone(G1ConcRefineGreenZone);
+ set_green_zone(G1ConcRefinementGreenZone);
- if (FLAG_IS_DEFAULT(G1ConcRefineYellowZone)) {
- FLAG_SET_DEFAULT(G1ConcRefineYellowZone, green_zone() * 3);
+ if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
+ FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3);
}
- set_yellow_zone(MAX2<int>(G1ConcRefineYellowZone, green_zone()));
+ set_yellow_zone(MAX2<int>(G1ConcRefinementYellowZone, green_zone()));
- if (FLAG_IS_DEFAULT(G1ConcRefineRedZone)) {
- FLAG_SET_DEFAULT(G1ConcRefineRedZone, yellow_zone() * 2);
+ if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
+ FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
}
- set_red_zone(MAX2<int>(G1ConcRefineRedZone, yellow_zone()));
+ set_red_zone(MAX2<int>(G1ConcRefinementRedZone, yellow_zone()));
_n_worker_threads = thread_num();
// We need one extra thread to do the young gen rset size sampling.
_n_threads = _n_worker_threads + 1;
@@ -76,15 +76,15 @@
}
void ConcurrentG1Refine::reset_threshold_step() {
- if (FLAG_IS_DEFAULT(G1ConcRefineThresholdStep)) {
+ if (FLAG_IS_DEFAULT(G1ConcRefinementThresholdStep)) {
_thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1);
} else {
- _thread_threshold_step = G1ConcRefineThresholdStep;
+ _thread_threshold_step = G1ConcRefinementThresholdStep;
}
}
int ConcurrentG1Refine::thread_num() {
- return MAX2<int>((G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads, 1);
+ return MAX2<int>((G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads : ParallelGCThreads, 1);
}
void ConcurrentG1Refine::init() {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -39,7 +39,8 @@
* running. If the length becomes red (max queue length) the mutators start
* processing the buffers.
*
- * There are some interesting cases (with G1AdaptiveConcRefine turned off):
+ * There are some interesting cases (when G1UseAdaptiveConcRefinement
+ * is turned off):
* 1) green = yellow = red = 0. In this case the mutator will process all
* buffers. Except for those that are created by the deferred updates
* machinery during a collection.
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -107,7 +107,7 @@
if (_should_terminate) {
break;
}
- _monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefineServiceInterval);
+ _monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefinementServiceIntervalMillis);
}
}
@@ -127,7 +127,7 @@
void ConcurrentG1RefineThread::activate() {
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
if (_worker_id > 0) {
- if (G1TraceConcurrentRefinement) {
+ if (G1TraceConcRefinement) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d",
_worker_id, _threshold, (int)dcqs.completed_buffers_num());
@@ -143,7 +143,7 @@
void ConcurrentG1RefineThread::deactivate() {
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
if (_worker_id > 0) {
- if (G1TraceConcurrentRefinement) {
+ if (G1TraceConcRefinement) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d",
_worker_id, _deactivation_threshold, (int)dcqs.completed_buffers_num());
@@ -218,9 +218,13 @@
void ConcurrentG1RefineThread::yield() {
- if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-yield");
+ if (G1TraceConcRefinement) {
+ gclog_or_tty->print_cr("G1-Refine-yield");
+ }
_sts.yield("G1 refine");
- if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-yield-end");
+ if (G1TraceConcRefinement) {
+ gclog_or_tty->print_cr("G1-Refine-yield-end");
+ }
}
void ConcurrentG1RefineThread::stop() {
@@ -241,7 +245,9 @@
Terminator_lock->wait();
}
}
- if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-stop");
+ if (G1TraceConcRefinement) {
+ gclog_or_tty->print_cr("G1-Refine-stop");
+ }
}
void ConcurrentG1RefineThread::print() const {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -297,6 +297,11 @@
}
}
+// Currently we do not call this at all. Normally we would call it
+// during the concurrent marking / remark phases but we now call
+// the lock-based version instead. But we might want to resurrect this
+// code in the future. So, we'll leave it here commented out.
+#if 0
MemRegion CMRegionStack::pop() {
while (true) {
// Otherwise...
@@ -321,6 +326,41 @@
// Otherwise, we need to try again.
}
}
+#endif // 0
+
+void CMRegionStack::push_with_lock(MemRegion mr) {
+ assert(mr.word_size() > 0, "Precondition");
+ MutexLockerEx x(CMRegionStack_lock, Mutex::_no_safepoint_check_flag);
+
+ if (isFull()) {
+ _overflow = true;
+ return;
+ }
+
+ _base[_index] = mr;
+ _index += 1;
+}
+
+MemRegion CMRegionStack::pop_with_lock() {
+ MutexLockerEx x(CMRegionStack_lock, Mutex::_no_safepoint_check_flag);
+
+ while (true) {
+ if (_index == 0) {
+ return MemRegion();
+ }
+ _index -= 1;
+
+ MemRegion mr = _base[_index];
+ if (mr.start() != NULL) {
+ assert(mr.end() != NULL, "invariant");
+ assert(mr.word_size() > 0, "invariant");
+ return mr;
+ } else {
+ // that entry was invalidated... let's skip it
+ assert(mr.end() == NULL, "invariant");
+ }
+ }
+}
bool CMRegionStack::invalidate_entries_into_cset() {
bool result = false;
@@ -447,7 +487,7 @@
gclog_or_tty->print_cr("[global] init, heap start = "PTR_FORMAT", "
"heap end = "PTR_FORMAT, _heap_start, _heap_end);
- _markStack.allocate(G1MarkStackSize);
+ _markStack.allocate(MarkStackSize);
_regionStack.allocate(G1MarkRegionStackSize);
// Create & start a ConcurrentMark thread.
@@ -461,7 +501,7 @@
assert(_markBitMap2.covers(rs), "_markBitMap2 inconsistency");
SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set();
- satb_qs.set_buffer_size(G1SATBLogBufferSize);
+ satb_qs.set_buffer_size(G1SATBBufferSize);
int size = (int) MAX2(ParallelGCThreads, (size_t)1);
_par_cleanup_thread_state = NEW_C_HEAP_ARRAY(ParCleanupThreadState*, size);
@@ -483,8 +523,8 @@
_accum_task_vtime[i] = 0.0;
}
- if (ParallelMarkingThreads > ParallelGCThreads) {
- vm_exit_during_initialization("Can't have more ParallelMarkingThreads "
+ if (ConcGCThreads > ParallelGCThreads) {
+ vm_exit_during_initialization("Can't have more ConcGCThreads "
"than ParallelGCThreads.");
}
if (ParallelGCThreads == 0) {
@@ -494,11 +534,11 @@
_sleep_factor = 0.0;
_marking_task_overhead = 1.0;
} else {
- if (ParallelMarkingThreads > 0) {
- // notice that ParallelMarkingThreads overwrites G1MarkingOverheadPercent
+ if (ConcGCThreads > 0) {
+ // notice that ConcGCThreads overwrites G1MarkingOverheadPercent
// if both are set
- _parallel_marking_threads = ParallelMarkingThreads;
+ _parallel_marking_threads = ConcGCThreads;
_sleep_factor = 0.0;
_marking_task_overhead = 1.0;
} else if (G1MarkingOverheadPercent > 0) {
@@ -668,24 +708,46 @@
//
void ConcurrentMark::clearNextBitmap() {
- guarantee(!G1CollectedHeap::heap()->mark_in_progress(), "Precondition.");
-
- // clear the mark bitmap (no grey objects to start with).
- // We need to do this in chunks and offer to yield in between
- // each chunk.
- HeapWord* start = _nextMarkBitMap->startWord();
- HeapWord* end = _nextMarkBitMap->endWord();
- HeapWord* cur = start;
- size_t chunkSize = M;
- while (cur < end) {
- HeapWord* next = cur + chunkSize;
- if (next > end)
- next = end;
- MemRegion mr(cur,next);
- _nextMarkBitMap->clearRange(mr);
- cur = next;
- do_yield_check();
- }
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ G1CollectorPolicy* g1p = g1h->g1_policy();
+
+ // Make sure that the concurrent mark thread looks to still be in
+ // the current cycle.
+ guarantee(cmThread()->during_cycle(), "invariant");
+
+ // We are finishing up the current cycle by clearing the next
+ // marking bitmap and getting it ready for the next cycle. During
+ // this time no other cycle can start. So, let's make sure that this
+ // is the case.
+ guarantee(!g1h->mark_in_progress(), "invariant");
+
+ // clear the mark bitmap (no grey objects to start with).
+ // We need to do this in chunks and offer to yield in between
+ // each chunk.
+ HeapWord* start = _nextMarkBitMap->startWord();
+ HeapWord* end = _nextMarkBitMap->endWord();
+ HeapWord* cur = start;
+ size_t chunkSize = M;
+ while (cur < end) {
+ HeapWord* next = cur + chunkSize;
+ if (next > end)
+ next = end;
+ MemRegion mr(cur,next);
+ _nextMarkBitMap->clearRange(mr);
+ cur = next;
+ do_yield_check();
+
+ // Repeat the asserts from above. We'll do them as asserts here to
+ // minimize their overhead on the product. However, we'll have
+ // them as guarantees at the beginning / end of the bitmap
+ // clearing to get some checking in the product.
+ assert(cmThread()->during_cycle(), "invariant");
+ assert(!g1h->mark_in_progress(), "invariant");
+ }
+
+ // Repeat the asserts from above.
+ guarantee(cmThread()->during_cycle(), "invariant");
+ guarantee(!g1h->mark_in_progress(), "invariant");
}
class NoteStartOfMarkHRClosure: public HeapRegionClosure {
@@ -760,7 +822,10 @@
rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
- satb_mq_set.set_active_all_threads(true);
+ // This is the start of the marking cycle, we're expected all
+ // threads to have SATB queues with active set to false.
+ satb_mq_set.set_active_all_threads(true, /* new active value */
+ false /* expected_active */);
// update_g1_committed() will be called at the end of an evac pause
// when marking is on. So, it's also called at the end of the
@@ -1079,7 +1144,11 @@
gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
} else {
// We're done with marking.
- JavaThread::satb_mark_queue_set().set_active_all_threads(false);
+ // This is the end of the marking cycle, we're expected all
+ // threads to have SATB queues with active set to true.
+ JavaThread::satb_mark_queue_set().set_active_all_threads(
+ false, /* new active value */
+ true /* expected_active */);
if (VerifyDuringGC) {
HandleMark hm; // handle scope
@@ -2586,7 +2655,11 @@
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
satb_mq_set.abandon_partial_marking();
- satb_mq_set.set_active_all_threads(false);
+ // This can be called either during or outside marking, we'll read
+ // the expected_active value from the SATB queue set.
+ satb_mq_set.set_active_all_threads(
+ false, /* new active value */
+ satb_mq_set.is_active() /* expected_active */);
}
static void print_ms_time_info(const char* prefix, const char* name,
@@ -3352,7 +3425,7 @@
gclog_or_tty->print_cr("[%d] draining region stack, size = %d",
_task_id, _cm->region_stack_size());
- MemRegion mr = _cm->region_stack_pop();
+ MemRegion mr = _cm->region_stack_pop_with_lock();
// it returns MemRegion() if the pop fails
statsOnly(if (mr.start() != NULL) ++_region_stack_pops );
@@ -3373,7 +3446,7 @@
if (has_aborted())
mr = MemRegion();
else {
- mr = _cm->region_stack_pop();
+ mr = _cm->region_stack_pop_with_lock();
// it returns MemRegion() if the pop fails
statsOnly(if (mr.start() != NULL) ++_region_stack_pops );
}
@@ -3406,7 +3479,7 @@
}
// Now push the part of the region we didn't scan on the
// region stack to make sure a task scans it later.
- _cm->region_stack_push(newRegion);
+ _cm->region_stack_push_with_lock(newRegion);
}
// break from while
mr = MemRegion();
@@ -3704,7 +3777,14 @@
// enough to point to the next possible object header (the
// bitmap knows by how much we need to move it as it knows its
// granularity).
- move_finger_to(_nextMarkBitMap->nextWord(_finger));
+ assert(_finger < _region_limit, "invariant");
+ HeapWord* new_finger = _nextMarkBitMap->nextWord(_finger);
+ // Check if bitmap iteration was aborted while scanning the last object
+ if (new_finger >= _region_limit) {
+ giveup_current_region();
+ } else {
+ move_finger_to(new_finger);
+ }
}
}
// At this point we have either completed iterating over the
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -24,8 +24,8 @@
class G1CollectedHeap;
class CMTask;
-typedef GenericTaskQueue<oop> CMTaskQueue;
-typedef GenericTaskQueueSet<oop> CMTaskQueueSet;
+typedef GenericTaskQueue<oop> CMTaskQueue;
+typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet;
// A generic CM bit map. This is essentially a wrapper around the BitMap
// class, with one bit per (1<<_shifter) HeapWords.
@@ -252,9 +252,19 @@
// with other "push" operations (no pops).
void push(MemRegion mr);
+#if 0
+ // This is currently not used. See the comment in the .cpp file.
+
// Lock-free; assumes that it will only be called in parallel
// with other "pop" operations (no pushes).
MemRegion pop();
+#endif // 0
+
+ // These two are the implementations that use a lock. They can be
+ // called concurrently with each other but they should not be called
+ // concurrently with the lock-free versions (push() / pop()).
+ void push_with_lock(MemRegion mr);
+ MemRegion pop_with_lock();
bool isEmpty() { return _index == 0; }
bool isFull() { return _index == _capacity; }
@@ -540,6 +550,10 @@
// Manipulation of the region stack
bool region_stack_push(MemRegion mr) {
+ // Currently we only call the lock-free version during evacuation
+ // pauses.
+ assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
+
_regionStack.push(mr);
if (_regionStack.overflow()) {
set_has_overflown();
@@ -547,7 +561,33 @@
}
return true;
}
- MemRegion region_stack_pop() { return _regionStack.pop(); }
+#if 0
+ // Currently this is not used. See the comment in the .cpp file.
+ MemRegion region_stack_pop() { return _regionStack.pop(); }
+#endif // 0
+
+ bool region_stack_push_with_lock(MemRegion mr) {
+ // Currently we only call the lock-based version during either
+ // concurrent marking or remark.
+ assert(!SafepointSynchronize::is_at_safepoint() || !concurrent(),
+ "if we are at a safepoint it should be the remark safepoint");
+
+ _regionStack.push_with_lock(mr);
+ if (_regionStack.overflow()) {
+ set_has_overflown();
+ return false;
+ }
+ return true;
+ }
+ MemRegion region_stack_pop_with_lock() {
+ // Currently we only call the lock-based version during either
+ // concurrent marking or remark.
+ assert(!SafepointSynchronize::is_at_safepoint() || !concurrent(),
+ "if we are at a safepoint it should be the remark safepoint");
+
+ return _regionStack.pop_with_lock();
+ }
+
int region_stack_size() { return _regionStack.size(); }
bool region_stack_overflow() { return _regionStack.overflow(); }
bool region_stack_empty() { return _regionStack.isEmpty(); }
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -42,8 +42,8 @@
private:
ConcurrentMark* _cm;
- bool _started;
- bool _in_progress;
+ volatile bool _started;
+ volatile bool _in_progress;
void sleepBeforeNextCycle();
@@ -67,15 +67,25 @@
// Counting virtual time so far.
double vtime_count_accum() { return _vtime_count_accum; }
- ConcurrentMark* cm() { return _cm; }
+ ConcurrentMark* cm() { return _cm; }
+
+ void set_started() { _started = true; }
+ void clear_started() { _started = false; }
+ bool started() { return _started; }
+
+ void set_in_progress() { _in_progress = true; }
+ void clear_in_progress() { _in_progress = false; }
+ bool in_progress() { return _in_progress; }
- void set_started() { _started = true; }
- void clear_started() { _started = false; }
- bool started() { return _started; }
-
- void set_in_progress() { _in_progress = true; }
- void clear_in_progress() { _in_progress = false; }
- bool in_progress() { return _in_progress; }
+ // This flag returns true from the moment a marking cycle is
+ // initiated (during the initial-mark pause when started() is set)
+ // to the moment when the cycle completes (just after the next
+ // marking bitmap has been cleared and in_progress() is
+ // cleared). While this flag is true we will not start another cycle
+ // so that cycles do not overlap. We cannot use just in_progress()
+ // as the CM thread might take some time to wake up before noticing
+ // that started() is set and set in_progress().
+ bool during_cycle() { return started() || in_progress(); }
// Yield for GC
void yield();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -583,7 +583,7 @@
res->zero_fill_state() == HeapRegion::Allocated)),
"Non-young alloc Regions must be zero filled (and non-H)");
- if (G1PrintRegions) {
+ if (G1PrintHeapRegions) {
if (res != NULL) {
gclog_or_tty->print_cr("new alloc region %d:["PTR_FORMAT", "PTR_FORMAT"], "
"top "PTR_FORMAT,
@@ -902,6 +902,10 @@
void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs,
size_t word_size) {
+ if (GC_locker::check_active_before_gc()) {
+ return; // GC is disabled (e.g. JNI GetXXXCritical operation)
+ }
+
ResourceMark rm;
if (PrintHeapAtGC) {
@@ -916,10 +920,6 @@
assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread");
- if (GC_locker::is_active()) {
- return; // GC is disabled (e.g. JNI GetXXXCritical operation)
- }
-
{
IsGCActiveMark x;
@@ -2102,18 +2102,21 @@
size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const {
// Return the remaining space in the cur alloc region, but not less than
// the min TLAB size.
- // Also, no more than half the region size, since we can't allow tlabs to
- // grow big enough to accomodate humongous objects.
-
- // We need to story it locally, since it might change between when we
- // test for NULL and when we use it later.
+
+ // Also, this value can be at most the humongous object threshold,
+ // since we can't allow tlabs to grow big enough to accomodate
+ // humongous objects.
+
+ // We need to store the cur alloc region locally, since it might change
+ // between when we test for NULL and when we use it later.
ContiguousSpace* cur_alloc_space = _cur_alloc_region;
+ size_t max_tlab_size = _humongous_object_threshold_in_words * wordSize;
+
if (cur_alloc_space == NULL) {
- return HeapRegion::GrainBytes/2;
+ return max_tlab_size;
} else {
- return MAX2(MIN2(cur_alloc_space->free(),
- (size_t)(HeapRegion::GrainBytes/2)),
- (size_t)MinTLABSize);
+ return MIN2(MAX2(cur_alloc_space->free(), (size_t)MinTLABSize),
+ max_tlab_size);
}
}
@@ -2477,7 +2480,7 @@
if (G1SummarizeRSetStats) {
g1_rem_set()->print_summary_info();
}
- if (G1SummarizeConcurrentMark) {
+ if (G1SummarizeConcMark) {
concurrent_mark()->print_summary_info();
}
if (G1SummarizeZFStats) {
@@ -2655,6 +2658,10 @@
void
G1CollectedHeap::do_collection_pause_at_safepoint() {
+ if (GC_locker::check_active_before_gc()) {
+ return; // GC is disabled (e.g. JNI GetXXXCritical operation)
+ }
+
if (PrintHeapAtGC) {
Universe::print_heap_before_gc();
}
@@ -2662,6 +2669,11 @@
{
ResourceMark rm;
+ // This call will decide whether this pause is an initial-mark
+ // pause. If it is, during_initial_mark_pause() will return true
+ // for the duration of this pause.
+ g1_policy()->decide_on_conc_mark_initiation();
+
char verbose_str[128];
sprintf(verbose_str, "GC pause ");
if (g1_policy()->in_young_gc_mode()) {
@@ -2670,7 +2682,7 @@
else
strcat(verbose_str, "(partial)");
}
- if (g1_policy()->should_initiate_conc_mark())
+ if (g1_policy()->during_initial_mark_pause())
strcat(verbose_str, " (initial-mark)");
// if PrintGCDetails is on, we'll print long statistics information
@@ -2694,10 +2706,6 @@
"young list should be well formed");
}
- if (GC_locker::is_active()) {
- return; // GC is disabled (e.g. JNI GetXXXCritical operation)
- }
-
bool abandoned = false;
{ // Call to jvmpi::post_class_unload_events must occur outside of active GC
IsGCActiveMark x;
@@ -2753,7 +2761,7 @@
_young_list->print();
#endif // SCAN_ONLY_VERBOSE
- if (g1_policy()->should_initiate_conc_mark()) {
+ if (g1_policy()->during_initial_mark_pause()) {
concurrent_mark()->checkpointRootsInitialPre();
}
save_marks();
@@ -2855,7 +2863,7 @@
}
if (g1_policy()->in_young_gc_mode() &&
- g1_policy()->should_initiate_conc_mark()) {
+ g1_policy()->during_initial_mark_pause()) {
concurrent_mark()->checkpointRootsInitialPost();
set_marking_started();
// CAUTION: after the doConcurrentMark() call below,
@@ -2934,6 +2942,9 @@
// the same region
assert(r == NULL || !r->is_gc_alloc_region(),
"shouldn't already be a GC alloc region");
+ assert(r == NULL || !r->isHumongous(),
+ "humongous regions shouldn't be used as GC alloc regions");
+
HeapWord* original_top = NULL;
if (r != NULL)
original_top = r->top();
@@ -3076,12 +3087,17 @@
if (alloc_region->in_collection_set() ||
alloc_region->top() == alloc_region->end() ||
- alloc_region->top() == alloc_region->bottom()) {
- // we will discard the current GC alloc region if it's in the
- // collection set (it can happen!), if it's already full (no
- // point in using it), or if it's empty (this means that it
- // was emptied during a cleanup and it should be on the free
- // list now).
+ alloc_region->top() == alloc_region->bottom() ||
+ alloc_region->isHumongous()) {
+ // we will discard the current GC alloc region if
+ // * it's in the collection set (it can happen!),
+ // * it's already full (no point in using it),
+ // * it's empty (this means that it was emptied during
+ // a cleanup and it should be on the free list now), or
+ // * it's humongous (this means that it was emptied
+ // during a cleanup and was added to the free list, but
+ // has been subseqently used to allocate a humongous
+ // object that may be less than the region size).
alloc_region = NULL;
}
@@ -3480,7 +3496,7 @@
HeapRegion* r = heap_region_containing(old);
if (!r->evacuation_failed()) {
r->set_evacuation_failed(true);
- if (G1PrintRegions) {
+ if (G1PrintHeapRegions) {
gclog_or_tty->print("evacuation failed in heap region "PTR_FORMAT" "
"["PTR_FORMAT","PTR_FORMAT")\n",
r, r->bottom(), r->end());
@@ -3974,7 +3990,7 @@
OopsInHeapRegionClosure *scan_perm_cl;
OopsInHeapRegionClosure *scan_so_cl;
- if (_g1h->g1_policy()->should_initiate_conc_mark()) {
+ if (_g1h->g1_policy()->during_initial_mark_pause()) {
scan_root_cl = &scan_mark_root_cl;
scan_perm_cl = &scan_mark_perm_cl;
scan_so_cl = &scan_mark_heap_rs_cl;
@@ -4002,9 +4018,7 @@
_g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms);
_g1h->g1_policy()->record_termination_time(i, term_ms);
}
- if (G1UseSurvivorSpaces) {
- _g1h->g1_policy()->record_thread_age_table(pss.age_table());
- }
+ _g1h->g1_policy()->record_thread_age_table(pss.age_table());
_g1h->update_surviving_young_words(pss.surviving_young_words()+1);
// Clean up any par-expanded rem sets.
@@ -4139,7 +4153,7 @@
FilterAndMarkInHeapRegionAndIntoCSClosure scan_and_mark(this, &boc, concurrent_mark());
OopsInHeapRegionClosure *foc;
- if (g1_policy()->should_initiate_conc_mark())
+ if (g1_policy()->during_initial_mark_pause())
foc = &scan_and_mark;
else
foc = &scan_only;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -56,8 +56,8 @@
# define IF_G1_DETAILED_STATS(code)
#endif
-typedef GenericTaskQueue<StarTask> RefToScanQueue;
-typedef GenericTaskQueueSet<StarTask> RefToScanQueueSet;
+typedef GenericTaskQueue<StarTask> RefToScanQueue;
+typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet;
typedef int RegionIdx_t; // needs to hold [ 0..max_regions() )
typedef int CardIdx_t; // needs to hold [ 0..CardsPerRegion )
@@ -1055,7 +1055,12 @@
// Returns "true" iff the given word_size is "very large".
static bool isHumongous(size_t word_size) {
- return word_size >= _humongous_object_threshold_in_words;
+ // Note this has to be strictly greater-than as the TLABs
+ // are capped at the humongous thresold and we want to
+ // ensure that we don't try to allocate a TLAB as
+ // humongous and that we don't allocate a humongous
+ // object in a TLAB.
+ return word_size > _humongous_object_threshold_in_words;
}
// Update mod union table with the set of dirty cards.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -178,8 +178,8 @@
// so the hack is to do the cast QQQ FIXME
_pauses_btwn_concurrent_mark((size_t)G1PausesBtwnConcMark),
_n_marks_since_last_pause(0),
- _conc_mark_initiated(false),
- _should_initiate_conc_mark(false),
+ _initiate_conc_mark_if_possible(false),
+ _during_initial_mark_pause(false),
_should_revert_to_full_young_gcs(false),
_last_full_young_gc(false),
@@ -198,7 +198,9 @@
_recorded_survivor_regions(0),
_recorded_survivor_head(NULL),
_recorded_survivor_tail(NULL),
- _survivors_age_table(true)
+ _survivors_age_table(true),
+
+ _gc_overhead_perc(0.0)
{
// Set up the region size and associated fields. Given that the
@@ -270,14 +272,15 @@
_concurrent_mark_cleanup_times_ms->add(0.20);
_tenuring_threshold = MaxTenuringThreshold;
- if (G1UseSurvivorSpaces) {
- // if G1FixedSurvivorSpaceSize is 0 which means the size is not
- // fixed, then _max_survivor_regions will be calculated at
- // calculate_young_list_target_config during initialization
- _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
- } else {
- _max_survivor_regions = 0;
- }
+ // if G1FixedSurvivorSpaceSize is 0 which means the size is not
+ // fixed, then _max_survivor_regions will be calculated at
+ // calculate_young_list_target_config during initialization
+ _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
+
+ assert(GCTimeRatio > 0,
+ "we should have set it to a default value set_g1_gc_flags() "
+ "if a user set it to 0");
+ _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio));
initialize_all();
}
@@ -296,28 +299,54 @@
CollectorPolicy::initialize_flags();
}
+// The easiest way to deal with the parsing of the NewSize /
+// MaxNewSize / etc. parameteres is to re-use the code in the
+// TwoGenerationCollectorPolicy class. This is similar to what
+// ParallelScavenge does with its GenerationSizer class (see
+// ParallelScavengeHeap::initialize()). We might change this in the
+// future, but it's a good start.
+class G1YoungGenSizer : public TwoGenerationCollectorPolicy {
+ size_t size_to_region_num(size_t byte_size) {
+ return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
+ }
+
+public:
+ G1YoungGenSizer() {
+ initialize_flags();
+ initialize_size_info();
+ }
+
+ size_t min_young_region_num() {
+ return size_to_region_num(_min_gen0_size);
+ }
+ size_t initial_young_region_num() {
+ return size_to_region_num(_initial_gen0_size);
+ }
+ size_t max_young_region_num() {
+ return size_to_region_num(_max_gen0_size);
+ }
+};
+
void G1CollectorPolicy::init() {
// Set aside an initial future to_space.
_g1 = G1CollectedHeap::heap();
- size_t regions = Universe::heap()->capacity() / HeapRegion::GrainBytes;
assert(Heap_lock->owned_by_self(), "Locking discipline.");
- if (G1SteadyStateUsed < 50) {
- vm_exit_during_initialization("G1SteadyStateUsed must be at least 50%.");
- }
-
initialize_gc_policy_counters();
if (G1Gen) {
_in_young_gc_mode = true;
- if (G1YoungGenSize == 0) {
+ G1YoungGenSizer sizer;
+ size_t initial_region_num = sizer.initial_young_region_num();
+
+ if (UseAdaptiveSizePolicy) {
set_adaptive_young_list_length(true);
_young_list_fixed_length = 0;
} else {
set_adaptive_young_list_length(false);
- _young_list_fixed_length = (G1YoungGenSize / HeapRegion::GrainBytes);
+ _young_list_fixed_length = initial_region_num;
}
_free_regions_at_end_of_collection = _g1->free_regions();
_scan_only_regions_at_end_of_collection = 0;
@@ -455,7 +484,7 @@
guarantee( adaptive_young_list_length(), "pre-condition" );
double start_time_sec = os::elapsedTime();
- size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1MinReservePercent);
+ size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1ReservePercent);
min_reserve_perc = MIN2((size_t) 50, min_reserve_perc);
size_t reserve_regions =
(size_t) ((double) min_reserve_perc * (double) _g1->n_regions() / 100.0);
@@ -764,7 +793,7 @@
elapsed_time_ms,
calculations,
full_young_gcs() ? "full" : "partial",
- should_initiate_conc_mark() ? " i-m" : "",
+ during_initial_mark_pause() ? " i-m" : "",
_in_marking_window,
_in_marking_window_im);
#endif // TRACE_CALC_YOUNG_CONFIG
@@ -1011,7 +1040,8 @@
set_full_young_gcs(true);
_last_full_young_gc = false;
_should_revert_to_full_young_gcs = false;
- _should_initiate_conc_mark = false;
+ clear_initiate_conc_mark_if_possible();
+ clear_during_initial_mark_pause();
_known_garbage_bytes = 0;
_known_garbage_ratio = 0.0;
_in_marking_window = false;
@@ -1110,10 +1140,7 @@
size_t short_lived_so_length = _young_list_so_prefix_length;
_short_lived_surv_rate_group->record_scan_only_prefix(short_lived_so_length);
tag_scan_only(short_lived_so_length);
-
- if (G1UseSurvivorSpaces) {
- _survivors_age_table.clear();
- }
+ _survivors_age_table.clear();
assert( verify_young_ages(), "region age verification" );
}
@@ -1160,7 +1187,8 @@
void G1CollectorPolicy::record_concurrent_mark_init_end_pre(double
mark_init_elapsed_time_ms) {
_during_marking = true;
- _should_initiate_conc_mark = false;
+ assert(!initiate_conc_mark_if_possible(), "we should have cleared it by now");
+ clear_during_initial_mark_pause();
_cur_mark_stop_world_time_ms = mark_init_elapsed_time_ms;
}
@@ -1231,7 +1259,6 @@
}
_n_pauses_at_mark_end = _n_pauses;
_n_marks_since_last_pause++;
- _conc_mark_initiated = false;
}
void
@@ -1427,17 +1454,24 @@
#endif // PRODUCT
if (in_young_gc_mode()) {
- last_pause_included_initial_mark = _should_initiate_conc_mark;
+ last_pause_included_initial_mark = during_initial_mark_pause();
if (last_pause_included_initial_mark)
record_concurrent_mark_init_end_pre(0.0);
size_t min_used_targ =
- (_g1->capacity() / 100) * (G1SteadyStateUsed - G1SteadyStateUsedDelta);
-
- if (cur_used_bytes > min_used_targ) {
- if (cur_used_bytes <= _prev_collection_pause_used_at_end_bytes) {
- } else if (!_g1->mark_in_progress() && !_last_full_young_gc) {
- _should_initiate_conc_mark = true;
+ (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent;
+
+
+ if (!_g1->mark_in_progress() && !_last_full_young_gc) {
+ assert(!last_pause_included_initial_mark, "invariant");
+ if (cur_used_bytes > min_used_targ &&
+ cur_used_bytes > _prev_collection_pause_used_at_end_bytes) {
+ assert(!during_initial_mark_pause(), "we should not see this here");
+
+ // Note: this might have already been set, if during the last
+ // pause we decided to start a cycle but at the beginning of
+ // this pause we decided to postpone it. That's OK.
+ set_initiate_conc_mark_if_possible();
}
}
@@ -1728,7 +1762,7 @@
bool new_in_marking_window = _in_marking_window;
bool new_in_marking_window_im = false;
- if (_should_initiate_conc_mark) {
+ if (during_initial_mark_pause()) {
new_in_marking_window = true;
new_in_marking_window_im = true;
}
@@ -1916,7 +1950,7 @@
calculate_young_list_target_config();
// Note that _mmu_tracker->max_gc_time() returns the time in seconds.
- double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSUpdatePauseFractionPercent / 100.0;
+ double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms);
// </NEW PREDICTION>
@@ -1932,7 +1966,7 @@
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
- if (G1AdaptiveConcRefine) {
+ if (G1UseAdaptiveConcRefinement) {
const int k_gy = 3, k_gr = 6;
const double inc_k = 1.1, dec_k = 0.9;
@@ -2147,7 +2181,13 @@
if (predicted_time_ms > _expensive_region_limit_ms) {
if (!in_young_gc_mode()) {
set_full_young_gcs(true);
- _should_initiate_conc_mark = true;
+ // We might want to do something different here. However,
+ // right now we don't support the non-generational G1 mode
+ // (and in fact we are planning to remove the associated code,
+ // see CR 6814390). So, let's leave it as is and this will be
+ // removed some time in the future
+ ShouldNotReachHere();
+ set_during_initial_mark_pause();
} else
// no point in doing another partial one
_should_revert_to_full_young_gcs = true;
@@ -2269,7 +2309,7 @@
}
size_t G1CollectorPolicy::expansion_amount() {
- if ((int)(recent_avg_pause_time_ratio() * 100.0) > G1GCPercent) {
+ if ((recent_avg_pause_time_ratio() * 100.0) > _gc_overhead_perc) {
// We will double the existing space, or take
// G1ExpandByPercentOfAvailable % of the available expansion
// space, whichever is smaller, bounded below by a minimum
@@ -2607,9 +2647,6 @@
// Calculates survivor space parameters.
void G1CollectorPolicy::calculate_survivors_policy()
{
- if (!G1UseSurvivorSpaces) {
- return;
- }
if (G1FixedSurvivorSpaceSize == 0) {
_max_survivor_regions = _young_list_target_length / SurvivorRatio;
} else {
@@ -2628,13 +2665,6 @@
G1CollectorPolicy_BestRegionsFirst::should_do_collection_pause(size_t
word_size) {
assert(_g1->regions_accounted_for(), "Region leakage!");
- // Initiate a pause when we reach the steady-state "used" target.
- size_t used_hard = (_g1->capacity() / 100) * G1SteadyStateUsed;
- size_t used_soft =
- MAX2((_g1->capacity() / 100) * (G1SteadyStateUsed - G1SteadyStateUsedDelta),
- used_hard/2);
- size_t used = _g1->used();
-
double max_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
size_t young_list_length = _g1->young_list_length();
@@ -2681,6 +2711,50 @@
#endif
void
+G1CollectorPolicy::decide_on_conc_mark_initiation() {
+ // We are about to decide on whether this pause will be an
+ // initial-mark pause.
+
+ // First, during_initial_mark_pause() should not be already set. We
+ // will set it here if we have to. However, it should be cleared by
+ // the end of the pause (it's only set for the duration of an
+ // initial-mark pause).
+ assert(!during_initial_mark_pause(), "pre-condition");
+
+ if (initiate_conc_mark_if_possible()) {
+ // We had noticed on a previous pause that the heap occupancy has
+ // gone over the initiating threshold and we should start a
+ // concurrent marking cycle. So we might initiate one.
+
+ bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
+ if (!during_cycle) {
+ // The concurrent marking thread is not "during a cycle", i.e.,
+ // it has completed the last one. So we can go ahead and
+ // initiate a new cycle.
+
+ set_during_initial_mark_pause();
+
+ // And we can now clear initiate_conc_mark_if_possible() as
+ // we've already acted on it.
+ clear_initiate_conc_mark_if_possible();
+ } else {
+ // The concurrent marking thread is still finishing up the
+ // previous cycle. If we start one right now the two cycles
+ // overlap. In particular, the concurrent marking thread might
+ // be in the process of clearing the next marking bitmap (which
+ // we will use for the next cycle if we start one). Starting a
+ // cycle now will be bad given that parts of the marking
+ // information might get cleared by the marking thread. And we
+ // cannot wait for the marking thread to finish the cycle as it
+ // periodically yields while clearing the next marking bitmap
+ // and, if it's in a yield point, it's waiting for us to
+ // finish. So, at this point we will not start a cycle and we'll
+ // let the concurrent marking thread complete the last one.
+ }
+ }
+}
+
+void
G1CollectorPolicy_BestRegionsFirst::
record_collection_pause_start(double start_time_sec, size_t start_used) {
G1CollectorPolicy::record_collection_pause_start(start_time_sec, start_used);
@@ -2867,7 +2941,7 @@
// estimate of the number of live bytes.
void G1CollectorPolicy::
add_to_collection_set(HeapRegion* hr) {
- if (G1PrintRegions) {
+ if (G1PrintHeapRegions) {
gclog_or_tty->print_cr("added region to cset %d:["PTR_FORMAT", "PTR_FORMAT"], "
"top "PTR_FORMAT", young %s",
hr->hrs_index(), hr->bottom(), hr->end(),
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -215,6 +215,8 @@
SurvRateGroup* _survivor_surv_rate_group;
// add here any more surv rate groups
+ double _gc_overhead_perc;
+
bool during_marking() {
return _during_marking;
}
@@ -722,11 +724,31 @@
size_t _n_marks_since_last_pause;
- // True iff CM has been initiated.
- bool _conc_mark_initiated;
+ // At the end of a pause we check the heap occupancy and we decide
+ // whether we will start a marking cycle during the next pause. If
+ // we decide that we want to do that, we will set this parameter to
+ // true. So, this parameter will stay true between the end of a
+ // pause and the beginning of a subsequent pause (not necessarily
+ // the next one, see the comments on the next field) when we decide
+ // that we will indeed start a marking cycle and do the initial-mark
+ // work.
+ volatile bool _initiate_conc_mark_if_possible;
- // True iff CM should be initiated
- bool _should_initiate_conc_mark;
+ // If initiate_conc_mark_if_possible() is set at the beginning of a
+ // pause, it is a suggestion that the pause should start a marking
+ // cycle by doing the initial-mark work. However, it is possible
+ // that the concurrent marking thread is still finishing up the
+ // previous marking cycle (e.g., clearing the next marking
+ // bitmap). If that is the case we cannot start a new cycle and
+ // we'll have to wait for the concurrent marking thread to finish
+ // what it is doing. In this case we will postpone the marking cycle
+ // initiation decision for the next pause. When we eventually decide
+ // to start a cycle, we will set _during_initial_mark_pause which
+ // will stay true until the end of the initial-mark pause and it's
+ // the condition that indicates that a pause is doing the
+ // initial-mark work.
+ volatile bool _during_initial_mark_pause;
+
bool _should_revert_to_full_young_gcs;
bool _last_full_young_gc;
@@ -979,9 +1001,21 @@
// Add "hr" to the CS.
void add_to_collection_set(HeapRegion* hr);
- bool should_initiate_conc_mark() { return _should_initiate_conc_mark; }
- void set_should_initiate_conc_mark() { _should_initiate_conc_mark = true; }
- void unset_should_initiate_conc_mark(){ _should_initiate_conc_mark = false; }
+ bool initiate_conc_mark_if_possible() { return _initiate_conc_mark_if_possible; }
+ void set_initiate_conc_mark_if_possible() { _initiate_conc_mark_if_possible = true; }
+ void clear_initiate_conc_mark_if_possible() { _initiate_conc_mark_if_possible = false; }
+
+ bool during_initial_mark_pause() { return _during_initial_mark_pause; }
+ void set_during_initial_mark_pause() { _during_initial_mark_pause = true; }
+ void clear_during_initial_mark_pause(){ _during_initial_mark_pause = false; }
+
+ // This is called at the very beginning of an evacuation pause (it
+ // has to be the first thing that the pause does). If
+ // initiate_conc_mark_if_possible() is true, and the concurrent
+ // marking thread has completed its work during the previous cycle,
+ // it will set during_initial_mark_pause() to so that the pause does
+ // the initial-mark work and start a marking cycle.
+ void decide_on_conc_mark_initiation();
// If an expansion would be appropriate, because recent GC overhead had
// exceeded the desired limit, return an amount to expand by.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -88,13 +88,13 @@
// the time slice than what's allowed)
// consolidate the two entries with the minimum gap between them
// (this might allow less GC time than what's allowed)
- guarantee(NOT_PRODUCT(ScavengeALot ||) G1ForgetfulMMUTracker,
- "array full, currently we can't recover unless +G1ForgetfulMMUTracker");
+ guarantee(NOT_PRODUCT(ScavengeALot ||) G1UseFixedWindowMMUTracker,
+ "array full, currently we can't recover unless +G1UseFixedWindowMMUTracker");
// In the case where ScavengeALot is true, such overflow is not
// uncommon; in such cases, we can, without much loss of precision
// or performance (we are GC'ing most of the time anyway!),
// simply overwrite the oldest entry in the tracker: this
- // is also the behaviour when G1ForgetfulMMUTracker is enabled.
+ // is also the behaviour when G1UseFixedWindowMMUTracker is enabled.
_head_index = trim_index(_head_index + 1);
assert(_head_index == _tail_index, "Because we have a full circular buffer");
_tail_index = trim_index(_tail_index + 1);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -101,7 +101,7 @@
// If the array is full, an easy fix is to look for the pauses with
// the shortest gap between them and consolidate them.
// For now, we have taken the expedient alternative of forgetting
- // the oldest entry in the event that +G1ForgetfulMMUTracker, thus
+ // the oldest entry in the event that +G1UseFixedWindowMMUTracker, thus
// potentially violating MMU specs for some time thereafter.
G1MMUTrackerQueueElem _array[QueueLength];
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -101,6 +101,8 @@
GenMarkSweep::_marking_stack =
new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
+ GenMarkSweep::_objarray_stack =
+ new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true);
int size = SystemDictionary::number_of_classes() * 2;
GenMarkSweep::_revisit_klass_stack =
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -467,7 +467,7 @@
// and they are causing failures. When we resolve said race
// conditions, we'll revert back to parallel remembered set
// updating and scanning. See CRs 6677707 and 6677708.
- if (G1ParallelRSetUpdatingEnabled || (worker_i == 0)) {
+ if (G1UseParallelRSetUpdating || (worker_i == 0)) {
updateRS(worker_i);
scanNewRefsRS(oc, worker_i);
} else {
@@ -476,7 +476,7 @@
_g1p->record_update_rs_time(worker_i, 0.0);
_g1p->record_scan_new_refs_time(worker_i, 0.0);
}
- if (G1ParallelRSetScanningEnabled || (worker_i == 0)) {
+ if (G1UseParallelRSetScanning || (worker_i == 0)) {
scanRS(oc, worker_i);
} else {
_g1p->record_scan_rs_start_time(worker_i, os::elapsedTime() * 1000.0);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -35,7 +35,7 @@
void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
assert(pre_val->is_oop_or_null(true), "Error");
- if (!JavaThread::satb_mark_queue_set().active()) return;
+ if (!JavaThread::satb_mark_queue_set().is_active()) return;
Thread* thr = Thread::current();
if (thr->is_Java_thread()) {
JavaThread* jt = (JavaThread*)thr;
@@ -51,7 +51,7 @@
G1SATBCardTableModRefBS::write_ref_field_pre_static(T* field,
oop new_val,
JavaThread* jt) {
- if (!JavaThread::satb_mark_queue_set().active()) return;
+ if (!JavaThread::satb_mark_queue_set().is_active()) return;
T heap_oop = oopDesc::load_heap_oop(field);
if (!oopDesc::is_null(heap_oop)) {
oop pre_val = oopDesc::decode_heap_oop_not_null(heap_oop);
@@ -62,7 +62,7 @@
template <class T> void
G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) {
- if (!JavaThread::satb_mark_queue_set().active()) return;
+ if (!JavaThread::satb_mark_queue_set().is_active()) return;
T* elem_ptr = dst;
for (int i = 0; i < count; i++, elem_ptr++) {
T heap_oop = oopDesc::load_heap_oop(elem_ptr);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -37,15 +37,9 @@
develop(intx, G1MarkingOverheadPercent, 0, \
"Overhead of concurrent marking") \
\
- product(uintx, G1YoungGenSize, 0, \
- "Size of the G1 young generation, 0 is the adaptive policy") \
- \
develop(bool, G1Gen, true, \
"If true, it will enable the generational G1") \
\
- develop(intx, G1GCPercent, 10, \
- "The desired percent time spent on GC") \
- \
develop(intx, G1PolicyVerbose, 0, \
"The verbosity level on G1 policy decisions") \
\
@@ -70,7 +64,7 @@
develop(intx, G1PausesBtwnConcMark, -1, \
"If positive, fixed number of pauses between conc markings") \
\
- diagnostic(bool, G1SummarizeConcurrentMark, false, \
+ diagnostic(bool, G1SummarizeConcMark, false, \
"Summarize concurrent mark info") \
\
diagnostic(bool, G1SummarizeRSetStats, false, \
@@ -85,12 +79,9 @@
diagnostic(bool, G1SummarizeZFStats, false, \
"Summarize zero-filling info") \
\
- diagnostic(bool, G1TraceConcurrentRefinement, false, \
+ diagnostic(bool, G1TraceConcRefinement, false, \
"Trace G1 concurrent refinement") \
\
- product(intx, G1MarkStackSize, 2 * 1024 * 1024, \
- "Size of the mark stack for concurrent marking.") \
- \
product(intx, G1MarkRegionStackSize, 1024 * 1024, \
"Size of the region stack for concurrent marking.") \
\
@@ -100,20 +91,13 @@
develop(intx, G1ConcZFMaxRegions, 1, \
"Stop zero-filling when # of zf'd regions reaches") \
\
- product(intx, G1SteadyStateUsed, 90, \
- "If non-0, try to maintain 'used' at this pct (of max)") \
- \
- product(intx, G1SteadyStateUsedDelta, 30, \
- "If G1SteadyStateUsed is non-0, then do pause this number of " \
- "of percentage points earlier if no marking is in progress.") \
- \
develop(bool, G1SATBBarrierPrintNullPreVals, false, \
"If true, count frac of ptr writes with null pre-vals.") \
\
- product(intx, G1SATBLogBufferSize, 1*K, \
+ product(intx, G1SATBBufferSize, 1*K, \
"Number of entries in an SATB log buffer.") \
\
- product(intx, G1SATBProcessCompletedThreshold, 20, \
+ develop(intx, G1SATBProcessCompletedThreshold, 20, \
"Number of completed buffers that triggers log processing.") \
\
develop(intx, G1ExtraRegionSurvRate, 33, \
@@ -127,7 +111,7 @@
develop(bool, G1SATBPrintStubs, false, \
"If true, print generated stubs for the SATB barrier") \
\
- product(intx, G1ExpandByPercentOfAvailable, 20, \
+ experimental(intx, G1ExpandByPercentOfAvailable, 20, \
"When expanding, % of uncommitted space to claim.") \
\
develop(bool, G1RSBarrierRegionFilter, true, \
@@ -165,36 +149,36 @@
product(intx, G1UpdateBufferSize, 256, \
"Size of an update buffer") \
\
- product(intx, G1ConcRefineYellowZone, 0, \
+ product(intx, G1ConcRefinementYellowZone, 0, \
"Number of enqueued update buffers that will " \
"trigger concurrent processing. Will be selected ergonomically " \
"by default.") \
\
- product(intx, G1ConcRefineRedZone, 0, \
+ product(intx, G1ConcRefinementRedZone, 0, \
"Maximum number of enqueued update buffers before mutator " \
"threads start processing new ones instead of enqueueing them. " \
"Will be selected ergonomically by default. Zero will disable " \
"concurrent processing.") \
\
- product(intx, G1ConcRefineGreenZone, 0, \
+ product(intx, G1ConcRefinementGreenZone, 0, \
"The number of update buffers that are left in the queue by the " \
"concurrent processing threads. Will be selected ergonomically " \
"by default.") \
\
- product(intx, G1ConcRefineServiceInterval, 300, \
+ product(intx, G1ConcRefinementServiceIntervalMillis, 300, \
"The last concurrent refinement thread wakes up every " \
"specified number of milliseconds to do miscellaneous work.") \
\
- product(intx, G1ConcRefineThresholdStep, 0, \
+ product(intx, G1ConcRefinementThresholdStep, 0, \
"Each time the rset update queue increases by this amount " \
"activate the next refinement thread if available. " \
"Will be selected ergonomically by default.") \
\
- product(intx, G1RSUpdatePauseFractionPercent, 10, \
+ product(intx, G1RSetUpdatingPauseTimePercent, 10, \
"A target percentage of time that is allowed to be spend on " \
"process RS update buffers during the collection pause.") \
\
- product(bool, G1AdaptiveConcRefine, true, \
+ product(bool, G1UseAdaptiveConcRefinement, true, \
"Select green, yellow and red zones adaptively to meet the " \
"the pause requirements.") \
\
@@ -245,15 +229,15 @@
"the number of regions for which we'll print a surv rate " \
"summary.") \
\
- product(bool, G1UseScanOnlyPrefix, false, \
+ develop(bool, G1UseScanOnlyPrefix, false, \
"It determines whether the system will calculate an optimum " \
"scan-only set.") \
\
- product(intx, G1MinReservePercent, 10, \
+ product(intx, G1ReservePercent, 10, \
"It determines the minimum reserve we should have in the heap " \
"to minimize the probability of promotion failure.") \
\
- diagnostic(bool, G1PrintRegions, false, \
+ diagnostic(bool, G1PrintHeapRegions, false, \
"If set G1 will print information on which regions are being " \
"allocated and which are reclaimed.") \
\
@@ -263,9 +247,6 @@
develop(bool, G1HRRSFlushLogBuffersOnVerify, false, \
"Forces flushing of log buffers before verification.") \
\
- product(bool, G1UseSurvivorSpaces, true, \
- "When true, use survivor space.") \
- \
develop(bool, G1FailOnFPError, false, \
"When set, G1 will fail when it encounters an FP 'error', " \
"so as to allow debugging") \
@@ -280,21 +261,21 @@
"If non-0 is the size of the G1 survivor space, " \
"otherwise SurvivorRatio is used to determine the size") \
\
- product(bool, G1ForgetfulMMUTracker, false, \
+ product(bool, G1UseFixedWindowMMUTracker, false, \
"If the MMU tracker's memory is full, forget the oldest entry") \
\
product(uintx, G1HeapRegionSize, 0, \
"Size of the G1 regions.") \
\
- experimental(bool, G1ParallelRSetUpdatingEnabled, false, \
+ experimental(bool, G1UseParallelRSetUpdating, true, \
"Enables the parallelization of remembered set updating " \
"during evacuation pauses") \
\
- experimental(bool, G1ParallelRSetScanningEnabled, false, \
+ experimental(bool, G1UseParallelRSetScanning, true, \
"Enables the parallelization of remembered set scanning " \
"during evacuation pauses") \
\
- product(uintx, G1ParallelRSetThreads, 0, \
+ product(uintx, G1ConcRefinementThreads, 0, \
"If non-0 is the number of parallel rem set update threads, " \
"otherwise the value is determined ergonomically.") \
\
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -25,8 +25,8 @@
# include "incls/_precompiled.incl"
# include "incls/_ptrQueue.cpp.incl"
-PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm) :
- _qset(qset_), _buf(NULL), _index(0), _active(false),
+PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm, bool active) :
+ _qset(qset_), _buf(NULL), _index(0), _active(active),
_perm(perm), _lock(NULL)
{}
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -62,7 +62,7 @@
public:
// Initialize this queue to contain a null buffer, and be part of the
// given PtrQueueSet.
- PtrQueue(PtrQueueSet*, bool perm = false);
+ PtrQueue(PtrQueueSet*, bool perm = false, bool active = false);
// Release any contained resources.
void flush();
// Calls flush() when destroyed.
@@ -101,6 +101,8 @@
}
}
+ bool is_active() { return _active; }
+
static int byte_index_to_index(int ind) {
assert((ind % oopSize) == 0, "Invariant.");
return ind / oopSize;
@@ -257,7 +259,7 @@
bool process_completed_buffers() { return _process_completed; }
void set_process_completed(bool x) { _process_completed = x; }
- bool active() { return _all_active; }
+ bool is_active() { return _all_active; }
// Set the buffer size. Should be called before any "enqueue" operation
// can be called. And should only be called once.
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -82,9 +82,57 @@
t->satb_mark_queue().handle_zero_index();
}
-void SATBMarkQueueSet::set_active_all_threads(bool b) {
+#ifdef ASSERT
+void SATBMarkQueueSet::dump_active_values(JavaThread* first,
+ bool expected_active) {
+ gclog_or_tty->print_cr("SATB queue active values for Java Threads");
+ gclog_or_tty->print_cr(" SATB queue set: active is %s",
+ (is_active()) ? "TRUE" : "FALSE");
+ gclog_or_tty->print_cr(" expected_active is %s",
+ (expected_active) ? "TRUE" : "FALSE");
+ for (JavaThread* t = first; t; t = t->next()) {
+ bool active = t->satb_mark_queue().is_active();
+ gclog_or_tty->print_cr(" thread %s, active is %s",
+ t->name(), (active) ? "TRUE" : "FALSE");
+ }
+}
+#endif // ASSERT
+
+void SATBMarkQueueSet::set_active_all_threads(bool b,
+ bool expected_active) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
+ JavaThread* first = Threads::first();
+
+#ifdef ASSERT
+ if (_all_active != expected_active) {
+ dump_active_values(first, expected_active);
+
+ // I leave this here as a guarantee, instead of an assert, so
+ // that it will still be compiled in if we choose to uncomment
+ // the #ifdef ASSERT in a product build. The whole block is
+ // within an #ifdef ASSERT so the guarantee will not be compiled
+ // in a product build anyway.
+ guarantee(false,
+ "SATB queue set has an unexpected active value");
+ }
+#endif // ASSERT
_all_active = b;
- for(JavaThread* t = Threads::first(); t; t = t->next()) {
+
+ for (JavaThread* t = first; t; t = t->next()) {
+#ifdef ASSERT
+ bool active = t->satb_mark_queue().is_active();
+ if (active != expected_active) {
+ dump_active_values(first, expected_active);
+
+ // I leave this here as a guarantee, instead of an assert, so
+ // that it will still be compiled in if we choose to uncomment
+ // the #ifdef ASSERT in a product build. The whole block is
+ // within an #ifdef ASSERT so the guarantee will not be compiled
+ // in a product build anyway.
+ guarantee(false,
+ "thread has an unexpected active value in its SATB queue");
+ }
+#endif // ASSERT
t->satb_mark_queue().set_active(b);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -29,8 +29,7 @@
class ObjPtrQueue: public PtrQueue {
public:
ObjPtrQueue(PtrQueueSet* qset_, bool perm = false) :
- PtrQueue(qset_, perm)
- {}
+ PtrQueue(qset_, perm, qset_->is_active()) { }
// Apply the closure to all elements, and reset the index to make the
// buffer empty.
void apply_closure(ObjectClosure* cl);
@@ -55,6 +54,9 @@
// is ignored.
bool apply_closure_to_completed_buffer_work(bool par, int worker);
+#ifdef ASSERT
+ void dump_active_values(JavaThread* first, bool expected_active);
+#endif // ASSERT
public:
SATBMarkQueueSet();
@@ -65,9 +67,11 @@
static void handle_zero_index_for_thread(JavaThread* t);
- // Apply "set_active(b)" to all thread tloq's. Should be called only
- // with the world stopped.
- void set_active_all_threads(bool b);
+ // Apply "set_active(b)" to all Java threads' SATB queues. It should be
+ // called only with the world stopped. The method will assert that the
+ // SATB queues of all threads it visits, as well as the SATB queue
+ // set itself, has an active value same as expected_active.
+ void set_active_all_threads(bool b, bool expected_active);
// Register "blk" as "the closure" for all queues. Only one such closure
// is allowed. The "apply_closure_to_completed_buffer" method will apply
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge Sat Apr 17 08:12:00 2010 -0700
@@ -175,6 +175,7 @@
psAdaptiveSizePolicy.hpp adaptiveSizePolicy.hpp
psCompactionManager.cpp gcTaskManager.hpp
+psCompactionManager.cpp objArrayKlass.inline.hpp
psCompactionManager.cpp objectStartArray.hpp
psCompactionManager.cpp oop.hpp
psCompactionManager.cpp oop.inline.hpp
@@ -189,6 +190,9 @@
psCompactionManager.hpp allocation.hpp
psCompactionManager.hpp taskqueue.hpp
+psCompactionManager.inline.hpp psCompactionManager.hpp
+psCompactionManager.inline.hpp psParallelCompact.hpp
+
psGCAdaptivePolicyCounters.hpp gcAdaptivePolicyCounters.hpp
psGCAdaptivePolicyCounters.hpp gcPolicyCounters.hpp
psGCAdaptivePolicyCounters.hpp psAdaptiveSizePolicy.hpp
@@ -379,12 +383,12 @@
pcTasks.cpp jniHandles.hpp
pcTasks.cpp jvmtiExport.hpp
pcTasks.cpp management.hpp
+pcTasks.cpp objArrayKlass.inline.hpp
pcTasks.cpp psParallelCompact.hpp
pcTasks.cpp pcTasks.hpp
pcTasks.cpp oop.inline.hpp
pcTasks.cpp oop.pcgc.inline.hpp
pcTasks.cpp systemDictionary.hpp
-pcTasks.cpp taskqueue.hpp
pcTasks.cpp thread.hpp
pcTasks.cpp universe.hpp
pcTasks.cpp vmThread.hpp
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -48,7 +48,7 @@
_vm_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
// Do the real work
- cm->drain_marking_stacks(&mark_and_push_closure);
+ cm->follow_marking_stacks();
}
@@ -118,7 +118,7 @@
}
// Do the real work
- cm->drain_marking_stacks(&mark_and_push_closure);
+ cm->follow_marking_stacks();
// cm->deallocate_stacks();
}
@@ -196,17 +196,19 @@
PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
oop obj = NULL;
+ ObjArrayTask task;
int random_seed = 17;
- while(true) {
- if (ParCompactionManager::steal(which, &random_seed, obj)) {
+ do {
+ while (ParCompactionManager::steal_objarray(which, &random_seed, task)) {
+ objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
+ k->oop_follow_contents(cm, task.obj(), task.index());
+ cm->follow_marking_stacks();
+ }
+ while (ParCompactionManager::steal(which, &random_seed, obj)) {
obj->follow_contents(cm);
- cm->drain_marking_stacks(&mark_and_push_closure);
- } else {
- if (terminator()->offer_termination()) {
- break;
- }
+ cm->follow_marking_stacks();
}
- }
+ } while (!terminator()->offer_termination());
}
//
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -28,6 +28,8 @@
PSOldGen* ParCompactionManager::_old_gen = NULL;
ParCompactionManager** ParCompactionManager::_manager_array = NULL;
OopTaskQueueSet* ParCompactionManager::_stack_array = NULL;
+ParCompactionManager::ObjArrayTaskQueueSet*
+ ParCompactionManager::_objarray_queues = NULL;
ObjectStartArray* ParCompactionManager::_start_array = NULL;
ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL;
RegionTaskQueueSet* ParCompactionManager::_region_array = NULL;
@@ -46,6 +48,11 @@
// We want the overflow stack to be permanent
_overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true);
+
+ _objarray_queue.initialize();
+ _objarray_overflow_stack =
+ new (ResourceObj::C_HEAP) ObjArrayOverflowStack(10, true);
+
#ifdef USE_RegionTaskQueueWithOverflow
region_stack()->initialize();
#else
@@ -69,6 +76,7 @@
ParCompactionManager::~ParCompactionManager() {
delete _overflow_stack;
+ delete _objarray_overflow_stack;
delete _revisit_klass_stack;
delete _revisit_mdo_stack;
// _manager_array and _stack_array are statics
@@ -86,18 +94,21 @@
assert(_manager_array == NULL, "Attempt to initialize twice");
_manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 );
- guarantee(_manager_array != NULL, "Could not initialize promotion manager");
+ guarantee(_manager_array != NULL, "Could not allocate manager_array");
_stack_array = new OopTaskQueueSet(parallel_gc_threads);
- guarantee(_stack_array != NULL, "Count not initialize promotion manager");
+ guarantee(_stack_array != NULL, "Could not allocate stack_array");
+ _objarray_queues = new ObjArrayTaskQueueSet(parallel_gc_threads);
+ guarantee(_objarray_queues != NULL, "Could not allocate objarray_queues");
_region_array = new RegionTaskQueueSet(parallel_gc_threads);
- guarantee(_region_array != NULL, "Count not initialize promotion manager");
+ guarantee(_region_array != NULL, "Could not allocate region_array");
// Create and register the ParCompactionManager(s) for the worker threads.
for(uint i=0; i<parallel_gc_threads; i++) {
_manager_array[i] = new ParCompactionManager();
guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager");
stack_array()->register_queue(i, _manager_array[i]->marking_stack());
+ _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_queue);
#ifdef USE_RegionTaskQueueWithOverflow
region_array()->register_queue(i, _manager_array[i]->region_stack()->task_queue());
#else
@@ -203,36 +214,30 @@
}
}
-void ParCompactionManager::drain_marking_stacks(OopClosure* blk) {
-#ifdef ASSERT
- ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
- assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
- MutableSpace* to_space = heap->young_gen()->to_space();
- MutableSpace* old_space = heap->old_gen()->object_space();
- MutableSpace* perm_space = heap->perm_gen()->object_space();
-#endif /* ASSERT */
-
-
+void ParCompactionManager::follow_marking_stacks() {
do {
-
- // Drain overflow stack first, so other threads can steal from
- // claimed stack while we work.
- while(!overflow_stack()->is_empty()) {
- oop obj = overflow_stack()->pop();
+ // Drain the overflow stack first, to allow stealing from the marking stack.
+ oop obj;
+ while (!overflow_stack()->is_empty()) {
+ overflow_stack()->pop()->follow_contents(this);
+ }
+ while (marking_stack()->pop_local(obj)) {
obj->follow_contents(this);
}
- oop obj;
- // obj is a reference!!!
- while (marking_stack()->pop_local(obj)) {
- // It would be nice to assert about the type of objects we might
- // pop, but they can come from anywhere, unfortunately.
- obj->follow_contents(this);
+ // Process ObjArrays one at a time to avoid marking stack bloat.
+ ObjArrayTask task;
+ if (!_objarray_overflow_stack->is_empty()) {
+ task = _objarray_overflow_stack->pop();
+ objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
+ k->oop_follow_contents(this, task.obj(), task.index());
+ } else if (_objarray_queue.pop_local(task)) {
+ objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
+ k->oop_follow_contents(this, task.obj(), task.index());
}
- } while((marking_stack()->size() != 0) || (overflow_stack()->length() != 0));
+ } while (!marking_stacks_empty());
- assert(marking_stack()->size() == 0, "Sanity");
- assert(overflow_stack()->length() == 0, "Sanity");
+ assert(marking_stacks_empty(), "Sanity");
}
void ParCompactionManager::drain_region_overflow_stack() {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -22,18 +22,6 @@
*
*/
-//
-// psPromotionManager is used by a single thread to manage object survival
-// during a scavenge. The promotion manager contains thread local data only.
-//
-// NOTE! Be carefull when allocating the stacks on cheap. If you are going
-// to use a promotion manager in more than one thread, the stacks MUST be
-// on cheap. This can lead to memory leaks, though, as they are not auto
-// deallocated.
-//
-// FIX ME FIX ME Add a destructor, and don't rely on the user to drain/flush/deallocate!
-//
-
// Move to some global location
#define HAS_BEEN_MOVED 0x1501d01d
// End move to some global location
@@ -46,8 +34,6 @@
class ParallelCompactData;
class ParMarkBitMap;
-// Move to it's own file if this works out.
-
class ParCompactionManager : public CHeapObj {
friend class ParallelTaskTerminator;
friend class ParMarkBitMap;
@@ -72,14 +58,27 @@
// ------------------------ End don't putback if not needed
private:
+ // 32-bit: 4K * 8 = 32KiB; 64-bit: 8K * 16 = 128KiB
+ #define OBJARRAY_QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13))
+ typedef GenericTaskQueue<ObjArrayTask, OBJARRAY_QUEUE_SIZE> ObjArrayTaskQueue;
+ typedef GenericTaskQueueSet<ObjArrayTaskQueue> ObjArrayTaskQueueSet;
+ #undef OBJARRAY_QUEUE_SIZE
+
static ParCompactionManager** _manager_array;
static OopTaskQueueSet* _stack_array;
+ static ObjArrayTaskQueueSet* _objarray_queues;
static ObjectStartArray* _start_array;
static RegionTaskQueueSet* _region_array;
static PSOldGen* _old_gen;
+private:
OopTaskQueue _marking_stack;
GrowableArray<oop>* _overflow_stack;
+
+ typedef GrowableArray<ObjArrayTask> ObjArrayOverflowStack;
+ ObjArrayTaskQueue _objarray_queue;
+ ObjArrayOverflowStack* _objarray_overflow_stack;
+
// Is there a way to reuse the _marking_stack for the
// saving empty regions? For now just create a different
// type of TaskQueue.
@@ -128,8 +127,8 @@
// Pushes onto the region stack. If the region stack is full,
// pushes onto the region overflow stack.
void region_stack_push(size_t region_index);
- public:
+public:
Action action() { return _action; }
void set_action(Action v) { _action = v; }
@@ -163,6 +162,8 @@
// Get a oop for scanning. If returns null, no oop were found.
oop retrieve_for_scanning();
+ inline void push_objarray(oop obj, size_t index);
+
// Save region for later processing. Must not fail.
void save_for_processing(size_t region_index);
// Get a region for processing. If returns null, no region were found.
@@ -175,12 +176,17 @@
return stack_array()->steal(queue_num, seed, t);
}
+ static bool steal_objarray(int queue_num, int* seed, ObjArrayTask& t) {
+ return _objarray_queues->steal(queue_num, seed, t);
+ }
+
static bool steal(int queue_num, int* seed, RegionTask& t) {
return region_array()->steal(queue_num, seed, t);
}
- // Process tasks remaining on any stack
- void drain_marking_stacks(OopClosure *blk);
+ // Process tasks remaining on any marking stack
+ void follow_marking_stacks();
+ inline bool marking_stacks_empty() const;
// Process tasks remaining on any stack
void drain_region_stacks();
@@ -200,3 +206,8 @@
"out of range manager_array access");
return _manager_array[index];
}
+
+bool ParCompactionManager::marking_stacks_empty() const {
+ return _marking_stack.size() == 0 && _overflow_stack->is_empty() &&
+ _objarray_queue.size() == 0 && _objarray_overflow_stack->is_empty();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.inline.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 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.
+ *
+ */
+
+void ParCompactionManager::push_objarray(oop obj, size_t index)
+{
+ ObjArrayTask task(obj, index);
+ assert(task.is_valid(), "bad ObjArrayTask");
+ if (!_objarray_queue.push(task)) {
+ _objarray_overflow_stack->push(task);
+ }
+}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -479,6 +479,7 @@
_preserved_oop_stack = NULL;
_marking_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
+ _objarray_stack = new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true);
int size = SystemDictionary::number_of_classes() * 2;
_revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true);
@@ -497,6 +498,7 @@
}
delete _marking_stack;
+ delete _objarray_stack;
delete _revisit_klass_stack;
delete _revisit_mdo_stack;
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -785,7 +785,7 @@
void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); }
void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
-void PSParallelCompact::FollowStackClosure::do_void() { follow_stack(_compaction_manager); }
+void PSParallelCompact::FollowStackClosure::do_void() { _compaction_manager->follow_marking_stacks(); }
void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(_compaction_manager, p); }
void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); }
@@ -2376,7 +2376,7 @@
// Follow code cache roots.
CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure,
purged_class);
- follow_stack(cm); // Flush marking stack.
+ cm->follow_marking_stacks(); // Flush marking stack.
// Update subklass/sibling/implementor links of live klasses
// revisit_klass_stack is used in follow_weak_klass_links().
@@ -2389,8 +2389,7 @@
SymbolTable::unlink(is_alive_closure());
StringTable::unlink(is_alive_closure());
- assert(cm->marking_stack()->size() == 0, "stack should be empty by now");
- assert(cm->overflow_stack()->is_empty(), "stack should be empty by now");
+ assert(cm->marking_stacks_empty(), "marking stacks should be empty");
}
// This should be moved to the shared markSweep code!
@@ -2709,22 +2708,6 @@
young_gen->move_and_update(cm);
}
-
-void PSParallelCompact::follow_stack(ParCompactionManager* cm) {
- while(!cm->overflow_stack()->is_empty()) {
- oop obj = cm->overflow_stack()->pop();
- obj->follow_contents(cm);
- }
-
- oop obj;
- // obj is a reference!!!
- while (cm->marking_stack()->pop_local(obj)) {
- // It would be nice to assert about the type of objects we might
- // pop, but they can come from anywhere, unfortunately.
- obj->follow_contents(cm);
- }
-}
-
void
PSParallelCompact::follow_weak_klass_links() {
// All klasses on the revisit stack are marked at this point.
@@ -2745,7 +2728,7 @@
&keep_alive_closure);
}
// revisit_klass_stack is cleared in reset()
- follow_stack(cm);
+ cm->follow_marking_stacks();
}
}
@@ -2776,7 +2759,7 @@
rms->at(j)->follow_weak_refs(is_alive_closure());
}
// revisit_mdo_stack is cleared in reset()
- follow_stack(cm);
+ cm->follow_marking_stacks();
}
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -901,7 +901,6 @@
// Mark live objects
static void marking_phase(ParCompactionManager* cm,
bool maximum_heap_compaction);
- static void follow_stack(ParCompactionManager* cm);
static void follow_weak_klass_links();
static void follow_mdo_weak_refs();
@@ -1276,7 +1275,7 @@
}
}
}
- follow_stack(cm);
+ cm->follow_marking_stacks();
}
template <class T>
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -25,8 +25,9 @@
#include "incls/_precompiled.incl"
#include "incls/_markSweep.cpp.incl"
-GrowableArray<oop>* MarkSweep::_marking_stack = NULL;
-GrowableArray<Klass*>* MarkSweep::_revisit_klass_stack = NULL;
+GrowableArray<oop>* MarkSweep::_marking_stack = NULL;
+GrowableArray<ObjArrayTask>* MarkSweep::_objarray_stack = NULL;
+GrowableArray<Klass*>* MarkSweep::_revisit_klass_stack = NULL;
GrowableArray<DataLayout*>* MarkSweep::_revisit_mdo_stack = NULL;
GrowableArray<oop>* MarkSweep::_preserved_oop_stack = NULL;
@@ -104,11 +105,19 @@
void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
void MarkSweep::follow_stack() {
- while (!_marking_stack->is_empty()) {
- oop obj = _marking_stack->pop();
- assert (obj->is_gc_marked(), "p must be marked");
- obj->follow_contents();
- }
+ do {
+ while (!_marking_stack->is_empty()) {
+ oop obj = _marking_stack->pop();
+ assert (obj->is_gc_marked(), "p must be marked");
+ obj->follow_contents();
+ }
+ // Process ObjArrays one at a time to avoid marking stack bloat.
+ if (!_objarray_stack->is_empty()) {
+ ObjArrayTask task = _objarray_stack->pop();
+ objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
+ k->oop_follow_contents(task.obj(), task.index());
+ }
+ } while (!_marking_stack->is_empty() || !_objarray_stack->is_empty());
}
MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -110,8 +110,9 @@
// Vars
//
protected:
- // Traversal stack used during phase1
+ // Traversal stacks used during phase1
static GrowableArray<oop>* _marking_stack;
+ static GrowableArray<ObjArrayTask>* _objarray_stack;
// Stack for live klasses to revisit at end of marking phase
static GrowableArray<Klass*>* _revisit_klass_stack;
// Set (stack) of MDO's to revisit at end of marking phase
@@ -188,6 +189,7 @@
template <class T> static inline void mark_and_follow(T* p);
// Check mark and maybe push on marking stack
template <class T> static inline void mark_and_push(T* p);
+ static inline void push_objarray(oop obj, size_t index);
static void follow_stack(); // Empty marking stack.
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -77,6 +77,12 @@
}
}
+void MarkSweep::push_objarray(oop obj, size_t index) {
+ ObjArrayTask task(obj, index);
+ assert(task.is_valid(), "bad ObjArrayTask");
+ _objarray_stack->push(task);
+}
+
template <class T> inline void MarkSweep::adjust_pointer(T* p, bool isroot) {
T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop)) {
--- a/hotspot/src/share/vm/includeDB_compiler1 Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/includeDB_compiler1 Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
//
-// Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+// Copyright 1999-2010 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
@@ -246,6 +246,7 @@
c1_LIRGenerator.cpp c1_LIRGenerator.hpp
c1_LIRGenerator.cpp c1_ValueStack.hpp
c1_LIRGenerator.cpp ciArrayKlass.hpp
+c1_LIRGenerator.cpp ciCPCache.hpp
c1_LIRGenerator.cpp ciInstance.hpp
c1_LIRGenerator.cpp heapRegion.hpp
c1_LIRGenerator.cpp sharedRuntime.hpp
--- a/hotspot/src/share/vm/includeDB_core Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/includeDB_core Sat Apr 17 08:12:00 2010 -0700
@@ -176,6 +176,7 @@
arguments.cpp oop.inline.hpp
arguments.cpp os_<os_family>.inline.hpp
arguments.cpp referenceProcessor.hpp
+arguments.cpp taskqueue.hpp
arguments.cpp universe.inline.hpp
arguments.cpp vm_version_<arch>.hpp
@@ -540,6 +541,7 @@
ciCPCache.cpp cpCacheOop.hpp
ciCPCache.cpp ciCPCache.hpp
+ciCPCache.cpp ciUtilities.hpp
ciCPCache.hpp ciClassList.hpp
ciCPCache.hpp ciObject.hpp
@@ -1021,6 +1023,7 @@
codeCache.cpp codeCache.hpp
codeCache.cpp dependencies.hpp
codeCache.cpp gcLocker.hpp
+codeCache.cpp handles.inline.hpp
codeCache.cpp icache.hpp
codeCache.cpp iterator.hpp
codeCache.cpp java.hpp
@@ -2014,6 +2017,7 @@
init.cpp icBuffer.hpp
init.cpp icache.hpp
init.cpp init.hpp
+init.cpp methodHandles.hpp
init.cpp safepoint.hpp
init.cpp sharedRuntime.hpp
init.cpp universe.hpp
@@ -2022,6 +2026,7 @@
instanceKlass.cpp collectedHeap.inline.hpp
instanceKlass.cpp compileBroker.hpp
+instanceKlass.cpp dtrace.hpp
instanceKlass.cpp fieldDescriptor.hpp
instanceKlass.cpp genOopClosures.inline.hpp
instanceKlass.cpp handles.inline.hpp
@@ -2481,6 +2486,7 @@
jvm.cpp collectedHeap.inline.hpp
jvm.cpp copy.hpp
jvm.cpp defaultStream.hpp
+jvm.cpp dtrace.hpp
jvm.cpp dtraceJSDT.hpp
jvm.cpp events.hpp
jvm.cpp handles.inline.hpp
@@ -2722,8 +2728,10 @@
markSweep.cpp compileBroker.hpp
markSweep.cpp methodDataOop.hpp
+markSweep.cpp objArrayKlass.inline.hpp
markSweep.hpp collectedHeap.hpp
+markSweep.hpp taskqueue.hpp
memRegion.cpp globals.hpp
memRegion.cpp memRegion.hpp
@@ -2868,6 +2876,7 @@
methodHandles.cpp oopFactory.hpp
methodHandles.cpp reflection.hpp
methodHandles.cpp signature.hpp
+methodHandles.cpp stubRoutines.hpp
methodHandles.cpp symbolTable.hpp
methodHandles_<arch>.cpp allocation.inline.hpp
@@ -3052,8 +3061,10 @@
objArrayKlass.cpp genOopClosures.inline.hpp
objArrayKlass.cpp handles.inline.hpp
objArrayKlass.cpp instanceKlass.hpp
+objArrayKlass.cpp markSweep.inline.hpp
objArrayKlass.cpp mutexLocker.hpp
objArrayKlass.cpp objArrayKlass.hpp
+objArrayKlass.cpp objArrayKlass.inline.hpp
objArrayKlass.cpp objArrayKlassKlass.hpp
objArrayKlass.cpp objArrayOop.hpp
objArrayKlass.cpp oop.inline.hpp
@@ -3064,11 +3075,12 @@
objArrayKlass.cpp universe.inline.hpp
objArrayKlass.cpp vmSymbols.hpp
-
objArrayKlass.hpp arrayKlass.hpp
objArrayKlass.hpp instanceKlass.hpp
objArrayKlass.hpp specialized_oop_closures.hpp
+objArrayKlass.inline.hpp objArrayKlass.hpp
+
objArrayKlassKlass.cpp collectedHeap.inline.hpp
objArrayKlassKlass.cpp instanceKlass.hpp
objArrayKlassKlass.cpp javaClasses.hpp
@@ -4094,6 +4106,7 @@
task.hpp top.hpp
taskqueue.cpp debug.hpp
+taskqueue.cpp oop.inline.hpp
taskqueue.cpp os.hpp
taskqueue.cpp taskqueue.hpp
taskqueue.cpp thread_<os_family>.inline.hpp
@@ -4447,6 +4460,7 @@
unsafe.cpp allocation.inline.hpp
unsafe.cpp copy.hpp
+unsafe.cpp dtrace.hpp
unsafe.cpp globals.hpp
unsafe.cpp interfaceSupport.hpp
unsafe.cpp jni.h
@@ -4618,6 +4632,7 @@
vmThread.cpp collectedHeap.hpp
vmThread.cpp compileBroker.hpp
+vmThread.cpp dtrace.hpp
vmThread.cpp events.hpp
vmThread.cpp interfaceSupport.hpp
vmThread.cpp methodOop.hpp
--- a/hotspot/src/share/vm/includeDB_gc_parallel Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/includeDB_gc_parallel Sat Apr 17 08:12:00 2010 -0700
@@ -115,10 +115,14 @@
objArrayKlass.cpp g1CollectedHeap.inline.hpp
objArrayKlass.cpp g1OopClosures.inline.hpp
objArrayKlass.cpp oop.pcgc.inline.hpp
+objArrayKlass.cpp psCompactionManager.hpp
objArrayKlass.cpp psPromotionManager.inline.hpp
objArrayKlass.cpp psScavenge.inline.hpp
objArrayKlass.cpp parOopClosures.inline.hpp
+objArrayKlass.inline.hpp psCompactionManager.inline.hpp
+objArrayKlass.inline.hpp psParallelCompact.hpp
+
oop.pcgc.inline.hpp parNewGeneration.hpp
oop.pcgc.inline.hpp parallelScavengeHeap.hpp
oop.pcgc.inline.hpp psCompactionManager.hpp
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -2328,6 +2328,17 @@
}
DEFAULT:
+#ifdef ZERO
+ // Some zero configurations use the C++ interpreter as a
+ // fallback interpreter and have support for platform
+ // specific fast bytecodes which aren't supported here, so
+ // redispatch to the equivalent non-fast bytecode when they
+ // are encountered.
+ if (Bytecodes::is_defined((Bytecodes::Code)opcode)) {
+ opcode = (jubyte)Bytecodes::java_code((Bytecodes::Code)opcode);
+ goto opcode_switch;
+ }
+#endif
fatal2("\t*** Unimplemented opcode: %d = %s\n",
opcode, Bytecodes::name((Bytecodes::Code)opcode));
goto finish;
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -159,6 +159,7 @@
_preserved_oop_stack = NULL;
_marking_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
+ _objarray_stack = new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true);
int size = SystemDictionary::number_of_classes() * 2;
_revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true);
@@ -194,7 +195,6 @@
void GenMarkSweep::deallocate_stacks() {
-
if (!UseG1GC) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
gch->release_scratch();
@@ -208,6 +208,7 @@
}
delete _marking_stack;
+ delete _objarray_stack;
delete _revisit_klass_stack;
delete _revisit_mdo_stack;
--- a/hotspot/src/share/vm/memory/genOopClosures.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/memory/genOopClosures.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -28,10 +28,10 @@
class CardTableModRefBS;
class DefNewGeneration;
-template<class E> class GenericTaskQueue;
-typedef GenericTaskQueue<oop> OopTaskQueue;
-template<class E> class GenericTaskQueueSet;
-typedef GenericTaskQueueSet<oop> OopTaskQueueSet;
+template<class E, unsigned int N> class GenericTaskQueue;
+typedef GenericTaskQueue<oop, TASKQUEUE_SIZE> OopTaskQueue;
+template<class T> class GenericTaskQueueSet;
+typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet;
// Closure for iterating roots from a particular generation
// Note: all classes deriving from this MUST call this do_barrier
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -111,7 +111,22 @@
// Allocate size HeapWords. The memory is NOT initialized to zero.
inline HeapWord* allocate(size_t size);
- static size_t alignment_reserve() { return align_object_size(typeArrayOopDesc::header_size(T_INT)); }
+
+ // Reserve space at the end of TLAB
+ static size_t end_reserve() {
+ int reserve_size = typeArrayOopDesc::header_size(T_INT);
+ if (AllocatePrefetchStyle == 3) {
+ // BIS is used to prefetch - we need a space for it.
+ // +1 for rounding up to next cache line +1 to be safe
+ int lines = AllocatePrefetchLines + 2;
+ int step_size = AllocatePrefetchStepSize;
+ int distance = AllocatePrefetchDistance;
+ int prefetch_end = (distance + step_size*lines)/(int)HeapWordSize;
+ reserve_size = MAX2(reserve_size, prefetch_end);
+ }
+ return reserve_size;
+ }
+ static size_t alignment_reserve() { return align_object_size(end_reserve()); }
static size_t alignment_reserve_in_bytes() { return alignment_reserve() * HeapWordSize; }
// Return tlab size or remaining space in eden such that the
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -25,6 +25,58 @@
# include "incls/_precompiled.incl"
# include "incls/_instanceKlass.cpp.incl"
+#ifdef DTRACE_ENABLED
+
+HS_DTRACE_PROBE_DECL4(hotspot, class__initialization__required,
+ char*, intptr_t, oop, intptr_t);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__recursive,
+ char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__concurrent,
+ char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__erroneous,
+ char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__super__failed,
+ char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__clinit,
+ char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__error,
+ char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
+ char*, intptr_t, oop, intptr_t, int);
+
+#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) \
+ { \
+ char* data = NULL; \
+ int len = 0; \
+ symbolOop name = (clss)->name(); \
+ if (name != NULL) { \
+ data = (char*)name->bytes(); \
+ len = name->utf8_length(); \
+ } \
+ HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \
+ data, len, (clss)->class_loader(), thread_type); \
+ }
+
+#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
+ { \
+ char* data = NULL; \
+ int len = 0; \
+ symbolOop name = (clss)->name(); \
+ if (name != NULL) { \
+ data = (char*)name->bytes(); \
+ len = name->utf8_length(); \
+ } \
+ HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \
+ data, len, (clss)->class_loader(), thread_type, wait); \
+ }
+
+#else // ndef DTRACE_ENABLED
+
+#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)
+#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait)
+
+#endif // ndef DTRACE_ENABLED
+
bool instanceKlass::should_be_initialized() const {
return !is_initialized();
}
@@ -292,6 +344,10 @@
// A class could already be verified, since it has been reflected upon.
this_oop->link_class(CHECK);
+ DTRACE_CLASSINIT_PROBE(required, instanceKlass::cast(this_oop()), -1);
+
+ bool wait = false;
+
// refer to the JVM book page 47 for description of steps
// Step 1
{ ObjectLocker ol(this_oop, THREAD);
@@ -303,19 +359,25 @@
// we might end up throwing IE from link/symbol resolution sites
// that aren't expected to throw. This would wreak havoc. See 6320309.
while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) {
+ wait = true;
ol.waitUninterruptibly(CHECK);
}
// Step 3
- if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self))
+ if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) {
+ DTRACE_CLASSINIT_PROBE_WAIT(recursive, instanceKlass::cast(this_oop()), -1,wait);
return;
+ }
// Step 4
- if (this_oop->is_initialized())
+ if (this_oop->is_initialized()) {
+ DTRACE_CLASSINIT_PROBE_WAIT(concurrent, instanceKlass::cast(this_oop()), -1,wait);
return;
+ }
// Step 5
if (this_oop->is_in_error_state()) {
+ DTRACE_CLASSINIT_PROBE_WAIT(erroneous, instanceKlass::cast(this_oop()), -1,wait);
ResourceMark rm(THREAD);
const char* desc = "Could not initialize class ";
const char* className = this_oop->external_name();
@@ -348,6 +410,7 @@
this_oop->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads
CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, superclass initialization error is thrown below
}
+ DTRACE_CLASSINIT_PROBE_WAIT(super__failed, instanceKlass::cast(this_oop()), -1,wait);
THROW_OOP(e());
}
}
@@ -356,6 +419,7 @@
{
assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
JavaThread* jt = (JavaThread*)THREAD;
+ DTRACE_CLASSINIT_PROBE_WAIT(clinit, instanceKlass::cast(this_oop()), -1,wait);
// Timer includes any side effects of class initialization (resolution,
// etc), but not recursive entry into call_class_initializer().
PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
@@ -383,6 +447,7 @@
this_oop->set_initialization_state_and_notify(initialization_error, THREAD);
CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below
}
+ DTRACE_CLASSINIT_PROBE_WAIT(error, instanceKlass::cast(this_oop()), -1,wait);
if (e->is_a(SystemDictionary::Error_klass())) {
THROW_OOP(e());
} else {
@@ -392,6 +457,7 @@
&args);
}
}
+ DTRACE_CLASSINIT_PROBE_WAIT(end, instanceKlass::cast(this_oop()), -1,wait);
}
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -314,24 +314,24 @@
void objArrayKlass::oop_follow_contents(oop obj) {
assert (obj->is_array(), "obj must be array");
- objArrayOop a = objArrayOop(obj);
- a->follow_header();
- ObjArrayKlass_OOP_ITERATE( \
- a, p, \
- /* we call mark_and_follow here to avoid excessive marking stack usage */ \
- MarkSweep::mark_and_follow(p))
+ objArrayOop(obj)->follow_header();
+ if (UseCompressedOops) {
+ objarray_follow_contents<narrowOop>(obj, 0);
+ } else {
+ objarray_follow_contents<oop>(obj, 0);
+ }
}
#ifndef SERIALGC
void objArrayKlass::oop_follow_contents(ParCompactionManager* cm,
oop obj) {
- assert (obj->is_array(), "obj must be array");
- objArrayOop a = objArrayOop(obj);
- a->follow_header(cm);
- ObjArrayKlass_OOP_ITERATE( \
- a, p, \
- /* we call mark_and_follow here to avoid excessive marking stack usage */ \
- PSParallelCompact::mark_and_follow(cm, p))
+ assert(obj->is_array(), "obj must be array");
+ objArrayOop(obj)->follow_header(cm);
+ if (UseCompressedOops) {
+ objarray_follow_contents<narrowOop>(cm, obj, 0);
+ } else {
+ objarray_follow_contents<oop>(cm, obj, 0);
+ }
}
#endif // SERIALGC
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -91,10 +91,18 @@
// Garbage collection
void oop_follow_contents(oop obj);
+ inline void oop_follow_contents(oop obj, int index);
+ template <class T> inline void objarray_follow_contents(oop obj, int index);
+
int oop_adjust_pointers(oop obj);
// Parallel Scavenge and Parallel Old
PARALLEL_GC_DECLS
+#ifndef SERIALGC
+ inline void oop_follow_contents(ParCompactionManager* cm, oop obj, int index);
+ template <class T> inline void
+ objarray_follow_contents(ParCompactionManager* cm, oop obj, int index);
+#endif // !SERIALGC
// Iterators
int oop_oop_iterate(oop obj, OopClosure* blk) {
@@ -131,5 +139,4 @@
void oop_verify_on(oop obj, outputStream* st);
void oop_verify_old_oop(oop obj, oop* p, bool allow_dirty);
void oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty);
-
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010 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.
+ *
+ */
+
+void objArrayKlass::oop_follow_contents(oop obj, int index) {
+ if (UseCompressedOops) {
+ objarray_follow_contents<narrowOop>(obj, index);
+ } else {
+ objarray_follow_contents<oop>(obj, index);
+ }
+}
+
+template <class T>
+void objArrayKlass::objarray_follow_contents(oop obj, int index) {
+ objArrayOop a = objArrayOop(obj);
+ const size_t len = size_t(a->length());
+ const size_t beg_index = size_t(index);
+ assert(beg_index < len || len == 0, "index too large");
+
+ const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
+ const size_t end_index = beg_index + stride;
+ T* const base = (T*)a->base();
+ T* const beg = base + beg_index;
+ T* const end = base + end_index;
+
+ // Push the non-NULL elements of the next stride on the marking stack.
+ for (T* e = beg; e < end; e++) {
+ MarkSweep::mark_and_push<T>(e);
+ }
+
+ if (end_index < len) {
+ MarkSweep::push_objarray(a, end_index); // Push the continuation.
+ }
+}
+
+#ifndef SERIALGC
+void objArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj,
+ int index) {
+ if (UseCompressedOops) {
+ objarray_follow_contents<narrowOop>(cm, obj, index);
+ } else {
+ objarray_follow_contents<oop>(cm, obj, index);
+ }
+}
+
+template <class T>
+void objArrayKlass::objarray_follow_contents(ParCompactionManager* cm, oop obj,
+ int index) {
+ objArrayOop a = objArrayOop(obj);
+ const size_t len = size_t(a->length());
+ const size_t beg_index = size_t(index);
+ assert(beg_index < len || len == 0, "index too large");
+
+ const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
+ const size_t end_index = beg_index + stride;
+ T* const base = (T*)a->base();
+ T* const beg = base + beg_index;
+ T* const end = base + end_index;
+
+ // Push the non-NULL elements of the next stride on the marking stack.
+ for (T* e = beg; e < end; e++) {
+ PSParallelCompact::mark_and_push<T>(cm, e);
+ }
+
+ if (end_index < len) {
+ cm->push_objarray(a, end_index); // Push the continuation.
+ }
+}
+#endif // #ifndef SERIALGC
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -123,16 +123,16 @@
|| (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
}
+ // Check zero copy
+ if (length == 0)
+ return;
// This is an attempt to make the copy_array fast.
- // NB: memmove takes care of overlapping memory segments.
- // Potential problem: memmove is not guaranteed to be word atomic
- // Revisit in Merlin
int l2es = log2_element_size();
int ihs = array_header_in_bytes() / wordSize;
- char* src = (char*) ((oop*)s + ihs) + (src_pos << l2es);
- char* dst = (char*) ((oop*)d + ihs) + (dst_pos << l2es);
- memmove(dst, src, length << l2es);
+ char* src = (char*) ((oop*)s + ihs) + ((size_t)src_pos << l2es);
+ char* dst = (char*) ((oop*)d + ihs) + ((size_t)dst_pos << l2es);
+ Copy::conjoint_memory_atomic(src, dst, (size_t)length << l2es);
}
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -52,9 +52,6 @@
"Code alignment for interior entry points " \
"in generated code (in bytes)") \
\
- product_pd(intx, OptoLoopAlignment, \
- "Align inner loops to zero relative to this modulus") \
- \
product(intx, MaxLoopPad, (OptoLoopAlignment-1), \
"Align a loop if padding size in bytes is less or equal to this value") \
\
--- a/hotspot/src/share/vm/opto/cfgnode.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -956,6 +956,7 @@
}
if( jtkp && ttkp ) {
if( jtkp->is_loaded() && jtkp->klass()->is_interface() &&
+ !jtkp->klass_is_exact() && // Keep exact interface klass (6894807)
ttkp->is_loaded() && !ttkp->klass()->is_interface() ) {
assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) ||
ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), "");
--- a/hotspot/src/share/vm/opto/doCall.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/doCall.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -714,8 +714,6 @@
// iterate through all entries sequentially
for (;!handlers.is_done(); handlers.next()) {
- // Do nothing if turned off
- if( !DeutschShiffmanExceptions ) break;
ciExceptionHandler* handler = handlers.handler();
if (handler->is_rethrow()) {
@@ -741,46 +739,26 @@
return; // No more handling to be done here!
}
- // %%% The following logic replicates make_from_klass_unique.
- // TO DO: Replace by a subroutine call. Then generalize
- // the type check, as noted in the next "%%%" comment.
-
+ // Get the handler's klass
ciInstanceKlass* klass = handler->catch_klass();
- if (UseUniqueSubclasses) {
- // (We use make_from_klass because it respects UseUniqueSubclasses.)
- const TypeOopPtr* tp = TypeOopPtr::make_from_klass(klass);
- klass = tp->klass()->as_instance_klass();
+
+ if (!klass->is_loaded()) { // klass is not loaded?
+ // fall through into catch_call_exceptions which will emit a
+ // handler with an uncommon trap.
+ break;
}
- // Get the handler's klass
- if (!klass->is_loaded()) // klass is not loaded?
- break; // Must call Rethrow!
if (klass->is_interface()) // should not happen, but...
break; // bail out
- // See if the loaded exception klass has no subtypes
- if (klass->has_subklass())
- break; // Cannot easily do precise test ==> Rethrow
- // %%% Now that subclass checking is very fast, we need to rewrite
- // this section and remove the option "DeutschShiffmanExceptions".
- // The exception processing chain should be a normal typecase pattern,
- // with a bailout to the interpreter only in the case of unloaded
- // classes. (The bailout should mark the method non-entrant.)
- // This rewrite should be placed in GraphKit::, not Parse::.
-
- // Add a dependence; if any subclass added we need to recompile
- // %%% should use stronger assert_unique_concrete_subtype instead
- if (!klass->is_final()) {
- C->dependencies()->assert_leaf_type(klass);
- }
-
- // Implement precise test
+ // Check the type of the exception against the catch type
const TypeKlassPtr *tk = TypeKlassPtr::make(klass);
Node* con = _gvn.makecon(tk);
- Node* cmp = _gvn.transform( new (C, 3) CmpPNode(ex_klass_node, con) );
- Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) );
- { BuildCutout unless(this, bol, PROB_LIKELY(0.7f));
- const TypeInstPtr* tinst = TypeInstPtr::make_exact(TypePtr::NotNull, klass);
+ Node* not_subtype_ctrl = gen_subtype_check(ex_klass_node, con);
+ if (!stopped()) {
+ PreserveJVMState pjvms(this);
+ const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr();
+ assert(klass->has_subklass() || tinst->klass_is_exact(), "lost exactness");
Node* ex_oop = _gvn.transform(new (C, 2) CheckCastPPNode(control(), ex_node, tinst));
push_ex_oop(ex_oop); // Push exception oop for handler
#ifndef PRODUCT
@@ -792,6 +770,7 @@
#endif
merge_exception(handler_bci);
}
+ set_control(not_subtype_ctrl);
// Come here if exception does not match handler.
// Carry on with more handler checks.
@@ -800,21 +779,6 @@
assert(!stopped(), "you should return if you finish the chain");
- if (remaining == 1) {
- // Further checks do not matter.
- }
-
- if (can_rerun_bytecode()) {
- // Do not push_ex_oop here!
- // Re-executing the bytecode will reproduce the throwing condition.
- bool must_throw = true;
- uncommon_trap(Deoptimization::Reason_unhandled,
- Deoptimization::Action_none,
- (ciKlass*)NULL, (const char*)NULL, // default args
- must_throw);
- return;
- }
-
// Oops, need to call into the VM to resolve the klasses at runtime.
// Note: This call must not deoptimize, since it is not a real at this bci!
kill_dead_locals();
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 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
@@ -1785,6 +1785,8 @@
bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, bool must_reason_predicate) {
Node *in0 = proj->in(0);
if (!in0->is_If()) return false;
+ // Variation of a dead If node.
+ if (in0->outcnt() < 2) return false;
IfNode* iff = in0->as_If();
// we need "If(Conv2B(Opaque1(...)))" pattern for must_reason_predicate
@@ -2086,29 +2088,41 @@
BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl,
int scale, Node* offset,
Node* init, Node* limit, Node* stride,
- Node* range) {
+ Node* range, bool upper) {
+ DEBUG_ONLY(ttyLocker ttyl);
+ if (TraceLoopPredicate) tty->print("rc_predicate ");
+
Node* max_idx_expr = init;
int stride_con = stride->get_int();
- if ((stride_con > 0) == (scale > 0)) {
+ if ((stride_con > 0) == (scale > 0) == upper) {
max_idx_expr = new (C, 3) SubINode(limit, stride);
register_new_node(max_idx_expr, ctrl);
+ if (TraceLoopPredicate) tty->print("(limit - stride) ");
+ } else {
+ if (TraceLoopPredicate) tty->print("init ");
}
if (scale != 1) {
ConNode* con_scale = _igvn.intcon(scale);
max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale);
register_new_node(max_idx_expr, ctrl);
+ if (TraceLoopPredicate) tty->print("* %d ", scale);
}
if (offset && (!offset->is_Con() || offset->get_int() != 0)){
max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset);
register_new_node(max_idx_expr, ctrl);
+ if (TraceLoopPredicate)
+ if (offset->is_Con()) tty->print("+ %d ", offset->get_int());
+ else tty->print("+ offset ");
}
CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range);
register_new_node(cmp, ctrl);
BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt);
register_new_node(bol, ctrl);
+
+ if (TraceLoopPredicate) tty->print_cr("<u range");
return bol;
}
@@ -2117,6 +2131,18 @@
bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
if (!UseLoopPredicate) return false;
+ if (!loop->_head->is_Loop()) {
+ // Could be a simple region when irreducible loops are present.
+ return false;
+ }
+
+ CountedLoopNode *cl = NULL;
+ if (loop->_head->is_CountedLoop()) {
+ cl = loop->_head->as_CountedLoop();
+ // do nothing for iteration-splitted loops
+ if (!cl->is_normal_loop()) return false;
+ }
+
// Too many traps seen?
bool tmt = C->too_many_traps(C->method(), 0, Deoptimization::Reason_predicate);
int tc = C->trap_count(Deoptimization::Reason_predicate);
@@ -2129,13 +2155,6 @@
return false;
}
- CountedLoopNode *cl = NULL;
- if (loop->_head->is_CountedLoop()) {
- cl = loop->_head->as_CountedLoop();
- // do nothing for iteration-splitted loops
- if(!cl->is_normal_loop()) return false;
- }
-
LoopNode *lpn = loop->_head->as_Loop();
Node* entry = lpn->in(LoopNode::EntryControl);
@@ -2180,7 +2199,6 @@
while (if_proj_list.size() > 0) {
// Following are changed to nonnull when a predicate can be hoisted
ProjNode* new_predicate_proj = NULL;
- BoolNode* new_predicate_bol = NULL;
ProjNode* proj = if_proj_list.pop()->as_Proj();
IfNode* iff = proj->in(0)->as_If();
@@ -2211,93 +2229,120 @@
// Invariant test
new_predicate_proj = create_new_if_for_predicate(predicate_proj);
Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
- new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
- if (TraceLoopPredicate) tty->print("invariant");
+ BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
+
+ // Negate test if necessary
+ bool negated = false;
+ if (proj->_con != predicate_proj->_con) {
+ new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
+ register_new_node(new_predicate_bol, ctrl);
+ negated = true;
+ }
+ IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
+ _igvn.hash_delete(new_predicate_iff);
+ new_predicate_iff->set_req(1, new_predicate_bol);
+ if (TraceLoopPredicate) tty->print_cr("invariant if%s: %d", negated ? " negated" : "", new_predicate_iff->_idx);
+
} else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) {
- // Range check (only for counted loops)
- new_predicate_proj = create_new_if_for_predicate(predicate_proj);
- Node *ctrl = new_predicate_proj->in(0)->as_If()->in(0);
+ assert(proj->_con == predicate_proj->_con, "must match");
+
+ // Range check for counted loops
const Node* cmp = bol->in(1)->as_Cmp();
Node* idx = cmp->in(1);
assert(!invar.is_invariant(idx), "index is variant");
assert(cmp->in(2)->Opcode() == Op_LoadRange, "must be");
- LoadRangeNode* ld_rng = (LoadRangeNode*)cmp->in(2); // LoadRangeNode
+ Node* ld_rng = cmp->in(2); // LoadRangeNode
assert(invar.is_invariant(ld_rng), "load range must be invariant");
- ld_rng = (LoadRangeNode*)invar.clone(ld_rng, ctrl);
int scale = 1;
Node* offset = zero;
bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset);
assert(ok, "must be index expression");
+
+ Node* init = cl->init_trip();
+ Node* limit = cl->limit();
+ Node* stride = cl->stride();
+
+ // Build if's for the upper and lower bound tests. The
+ // lower_bound test will dominate the upper bound test and all
+ // cloned or created nodes will use the lower bound test as
+ // their declared control.
+ ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj);
+ ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj);
+ assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
+ Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
+
+ // Perform cloning to keep Invariance state correct since the
+ // late schedule will place invariant things in the loop.
+ ld_rng = invar.clone(ld_rng, ctrl);
if (offset && offset != zero) {
assert(invar.is_invariant(offset), "offset must be loop invariant");
offset = invar.clone(offset, ctrl);
}
- Node* init = cl->init_trip();
- Node* limit = cl->limit();
- Node* stride = cl->stride();
- new_predicate_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng);
- if (TraceLoopPredicate) tty->print("range check");
- }
+
+ // Test the lower bound
+ Node* lower_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng, false);
+ IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
+ _igvn.hash_delete(lower_bound_iff);
+ lower_bound_iff->set_req(1, lower_bound_bol);
+ if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
- if (new_predicate_proj == NULL) {
+ // Test the upper bound
+ Node* upper_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng, true);
+ IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
+ _igvn.hash_delete(upper_bound_iff);
+ upper_bound_iff->set_req(1, upper_bound_bol);
+ if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx);
+
+ // Fall through into rest of the clean up code which will move
+ // any dependent nodes onto the upper bound test.
+ new_predicate_proj = upper_bound_proj;
+ } else {
// The other proj of the "iff" is a uncommon trap projection, and we can assume
// the other proj will not be executed ("executed" means uct raised).
continue;
- } else {
- // Success - attach condition (new_predicate_bol) to predicate if
- invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
- IfNode* new_iff = new_predicate_proj->in(0)->as_If();
+ }
- // Negate test if necessary
- if (proj->_con != predicate_proj->_con) {
- new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
- register_new_node(new_predicate_bol, new_iff->in(0));
- if (TraceLoopPredicate) tty->print_cr(" if negated: %d", iff->_idx);
- } else {
- if (TraceLoopPredicate) tty->print_cr(" if: %d", iff->_idx);
- }
+ // Success - attach condition (new_predicate_bol) to predicate if
+ invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
- _igvn.hash_delete(new_iff);
- new_iff->set_req(1, new_predicate_bol);
-
- _igvn.hash_delete(iff);
- iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true);
+ // Eliminate the old if in the loop body
+ _igvn.hash_delete(iff);
+ iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true);
- Node* ctrl = new_predicate_proj; // new control
- ProjNode* dp = proj; // old control
- assert(get_loop(dp) == loop, "guarenteed at the time of collecting proj");
- // Find nodes (depends only on the test) off the surviving projection;
- // move them outside the loop with the control of proj_clone
- for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
- Node* cd = dp->fast_out(i); // Control-dependent node
- if (cd->depends_only_on_test()) {
- assert(cd->in(0) == dp, "");
- _igvn.hash_delete(cd);
- cd->set_req(0, ctrl); // ctrl, not NULL
- set_early_ctrl(cd);
- _igvn._worklist.push(cd);
- IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
- if (new_loop != loop) {
- if (!loop->_child) loop->_body.yank(cd);
- if (!new_loop->_child ) new_loop->_body.push(cd);
- }
- --i;
- --imax;
+ Node* ctrl = new_predicate_proj; // new control
+ ProjNode* dp = proj; // old control
+ assert(get_loop(dp) == loop, "guaranteed at the time of collecting proj");
+ // Find nodes (depends only on the test) off the surviving projection;
+ // move them outside the loop with the control of proj_clone
+ for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
+ Node* cd = dp->fast_out(i); // Control-dependent node
+ if (cd->depends_only_on_test()) {
+ assert(cd->in(0) == dp, "");
+ _igvn.hash_delete(cd);
+ cd->set_req(0, ctrl); // ctrl, not NULL
+ set_early_ctrl(cd);
+ _igvn._worklist.push(cd);
+ IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
+ if (new_loop != loop) {
+ if (!loop->_child) loop->_body.yank(cd);
+ if (!new_loop->_child ) new_loop->_body.push(cd);
}
+ --i;
+ --imax;
}
+ }
- hoisted = true;
- C->set_major_progress();
- }
+ hoisted = true;
+ C->set_major_progress();
} // end while
#ifndef PRODUCT
- // report that the loop predication has been actually performed
- // for this loop
- if (TraceLoopPredicate && hoisted) {
- tty->print("Loop Predication Performed:");
- loop->dump_head();
- }
+ // report that the loop predication has been actually performed
+ // for this loop
+ if (TraceLoopPredicate && hoisted) {
+ tty->print("Loop Predication Performed:");
+ loop->dump_head();
+ }
#endif
return hoisted;
--- a/hotspot/src/share/vm/opto/loopnode.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/loopnode.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -821,7 +821,7 @@
BoolNode* rc_predicate(Node* ctrl,
int scale, Node* offset,
Node* init, Node* limit, Node* stride,
- Node* range);
+ Node* range, bool upper);
// Implementation of the loop predication to promote checks outside the loop
bool loop_predication_impl(IdealLoopTree *loop);
--- a/hotspot/src/share/vm/opto/macro.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/macro.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1487,11 +1487,11 @@
Node*& contended_phi_rawmem,
Node* old_eden_top, Node* new_eden_top,
Node* length) {
+ enum { fall_in_path = 1, pf_path = 2 };
if( UseTLAB && AllocatePrefetchStyle == 2 ) {
// Generate prefetch allocation with watermark check.
// As an allocation hits the watermark, we will prefetch starting
// at a "distance" away from watermark.
- enum { fall_in_path = 1, pf_path = 2 };
Node *pf_region = new (C, 3) RegionNode(3);
Node *pf_phi_rawmem = new (C, 3) PhiNode( pf_region, Type::MEMORY,
@@ -1570,6 +1570,45 @@
needgc_false = pf_region;
contended_phi_rawmem = pf_phi_rawmem;
i_o = pf_phi_abio;
+ } else if( UseTLAB && AllocatePrefetchStyle == 3 ) {
+ // Insert a prefetch for each allocation only on the fast-path
+ Node *pf_region = new (C, 3) RegionNode(3);
+ Node *pf_phi_rawmem = new (C, 3) PhiNode( pf_region, Type::MEMORY,
+ TypeRawPtr::BOTTOM );
+
+ // Generate several prefetch instructions only for arrays.
+ uint lines = (length != NULL) ? AllocatePrefetchLines : 1;
+ uint step_size = AllocatePrefetchStepSize;
+ uint distance = AllocatePrefetchDistance;
+
+ // Next cache address.
+ Node *cache_adr = new (C, 4) AddPNode(old_eden_top, old_eden_top,
+ _igvn.MakeConX(distance));
+ transform_later(cache_adr);
+ cache_adr = new (C, 2) CastP2XNode(needgc_false, cache_adr);
+ transform_later(cache_adr);
+ Node* mask = _igvn.MakeConX(~(intptr_t)(step_size-1));
+ cache_adr = new (C, 3) AndXNode(cache_adr, mask);
+ transform_later(cache_adr);
+ cache_adr = new (C, 2) CastX2PNode(cache_adr);
+ transform_later(cache_adr);
+
+ // Prefetch
+ Node *prefetch = new (C, 3) PrefetchWriteNode( contended_phi_rawmem, cache_adr );
+ prefetch->set_req(0, needgc_false);
+ transform_later(prefetch);
+ contended_phi_rawmem = prefetch;
+ Node *prefetch_adr;
+ distance = step_size;
+ for ( uint i = 1; i < lines; i++ ) {
+ prefetch_adr = new (C, 4) AddPNode( cache_adr, cache_adr,
+ _igvn.MakeConX(distance) );
+ transform_later(prefetch_adr);
+ prefetch = new (C, 3) PrefetchWriteNode( contended_phi_rawmem, prefetch_adr );
+ transform_later(prefetch);
+ distance += step_size;
+ contended_phi_rawmem = prefetch;
+ }
} else if( AllocatePrefetchStyle > 0 ) {
// Insert a prefetch for each allocation only on the fast-path
Node *prefetch_adr;
--- a/hotspot/src/share/vm/opto/matcher.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/matcher.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -373,8 +373,8 @@
// to implement the UseStrictFP mode.
static const bool strict_fp_requires_explicit_rounding;
- // Do floats take an entire double register or just half?
- static const bool float_in_double;
+ // Are floats conerted to double when stored to stack during deoptimization?
+ static bool float_in_double();
// Do ints take an entire long register or just half?
static const bool int_in_long;
--- a/hotspot/src/share/vm/opto/memnode.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/memnode.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1244,5 +1244,5 @@
virtual int Opcode() const;
virtual uint ideal_reg() const { return NotAMachineReg; }
virtual uint match_edge(uint idx) const { return idx==2; }
- virtual const Type *bottom_type() const { return Type::ABIO; }
+ virtual const Type *bottom_type() const { return ( AllocatePrefetchStyle == 3 ) ? Type::MEMORY : Type::ABIO; }
};
--- a/hotspot/src/share/vm/opto/output.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/output.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -678,7 +678,7 @@
#endif //_LP64
else if( (t->base() == Type::FloatBot || t->base() == Type::FloatCon) &&
OptoReg::is_reg(regnum) ) {
- array->append(new_loc_value( _regalloc, regnum, Matcher::float_in_double
+ array->append(new_loc_value( _regalloc, regnum, Matcher::float_in_double()
? Location::float_in_dbl : Location::normal ));
} else if( t->base() == Type::Int && OptoReg::is_reg(regnum) ) {
array->append(new_loc_value( _regalloc, regnum, Matcher::int_in_long
--- a/hotspot/src/share/vm/opto/parse.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/parse.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -551,9 +551,6 @@
// Also handles exceptions for individual bytecodes.
void catch_inline_exceptions(SafePointNode* ex_map);
- // Bytecode classifier, helps decide to use uncommon_trap vs. rethrow_C.
- bool can_rerun_bytecode();
-
// Merge the given map into correct exceptional exit state.
// Assumes that there is no applicable local handler.
void throw_to_exit(SafePointNode* ex_map);
--- a/hotspot/src/share/vm/opto/parse1.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/parse1.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -237,7 +237,6 @@
C->record_method_not_compilable("OSR in empty or breakpointed method");
return;
}
- MethodLivenessResult raw_live_locals = method()->raw_liveness_at_bci(osr_bci());
// Extract the needed locals from the interpreter frame.
Node *locals_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals-1)*wordSize);
@@ -306,6 +305,7 @@
SafePointNode* bad_type_exit = clone_map();
bad_type_exit->set_control(new (C, 1) RegionNode(1));
+ assert(osr_block->flow()->jsrs()->size() == 0, "should be no jsrs live at osr point");
for (index = 0; index < max_locals; index++) {
if (stopped()) break;
Node* l = local(index);
@@ -317,8 +317,18 @@
continue;
}
}
- if (type->basic_type() == T_ADDRESS && !raw_live_locals.at(index)) {
- // Skip type check for dead address locals
+ if (osr_block->flow()->local_type_at(index)->is_return_address()) {
+ // In our current system it's illegal for jsr addresses to be
+ // live into an OSR entry point because the compiler performs
+ // inlining of jsrs. ciTypeFlow has a bailout that detect this
+ // case and aborts the compile if addresses are live into an OSR
+ // entry point. Because of that we can assume that any address
+ // locals at the OSR entry point are dead. Method liveness
+ // isn't precise enought to figure out that they are dead in all
+ // cases so simply skip checking address locals all
+ // together. Any type check is guaranteed to fail since the
+ // interpreter type is the result of a load which might have any
+ // value and the expected type is a constant.
continue;
}
set_local(index, check_interpreter_type(l, type, bad_type_exit));
@@ -788,67 +798,6 @@
initial_gvn()->transform_no_reclaim(exit);
}
-bool Parse::can_rerun_bytecode() {
- switch (bc()) {
- case Bytecodes::_ldc:
- case Bytecodes::_ldc_w:
- case Bytecodes::_ldc2_w:
- case Bytecodes::_getfield:
- case Bytecodes::_putfield:
- case Bytecodes::_getstatic:
- case Bytecodes::_putstatic:
- case Bytecodes::_arraylength:
- case Bytecodes::_baload:
- case Bytecodes::_caload:
- case Bytecodes::_iaload:
- case Bytecodes::_saload:
- case Bytecodes::_faload:
- case Bytecodes::_aaload:
- case Bytecodes::_laload:
- case Bytecodes::_daload:
- case Bytecodes::_bastore:
- case Bytecodes::_castore:
- case Bytecodes::_iastore:
- case Bytecodes::_sastore:
- case Bytecodes::_fastore:
- case Bytecodes::_aastore:
- case Bytecodes::_lastore:
- case Bytecodes::_dastore:
- case Bytecodes::_irem:
- case Bytecodes::_idiv:
- case Bytecodes::_lrem:
- case Bytecodes::_ldiv:
- case Bytecodes::_frem:
- case Bytecodes::_fdiv:
- case Bytecodes::_drem:
- case Bytecodes::_ddiv:
- case Bytecodes::_checkcast:
- case Bytecodes::_instanceof:
- case Bytecodes::_anewarray:
- case Bytecodes::_newarray:
- case Bytecodes::_multianewarray:
- case Bytecodes::_new:
- case Bytecodes::_monitorenter: // can re-run initial null check, only
- case Bytecodes::_return:
- return true;
- break;
-
- // Don't rerun athrow since it's part of the exception path.
- case Bytecodes::_athrow:
- case Bytecodes::_invokestatic:
- case Bytecodes::_invokedynamic:
- case Bytecodes::_invokespecial:
- case Bytecodes::_invokevirtual:
- case Bytecodes::_invokeinterface:
- return false;
- break;
-
- default:
- assert(false, "unexpected bytecode produced an exception");
- return true;
- }
-}
-
//---------------------------do_exceptions-------------------------------------
// Process exceptions arising from the current bytecode.
// Send caught exceptions to the proper handler within this method.
@@ -862,9 +811,6 @@
return;
}
- // Make sure we can classify this bytecode if we need to.
- debug_only(can_rerun_bytecode());
-
PreserveJVMState pjvms(this, false);
SafePointNode* ex_map;
--- a/hotspot/src/share/vm/opto/runtime.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/runtime.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -864,8 +864,8 @@
thread->set_exception_handler_pc(handler_address);
thread->set_exception_stack_size(0);
- // Check if the exception PC is a MethodHandle call.
- thread->set_is_method_handle_exception(nm->is_method_handle_return(pc));
+ // Check if the exception PC is a MethodHandle call site.
+ thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
}
// Restore correct return pc. Was saved above.
@@ -952,7 +952,7 @@
thread->set_vm_result(exception);
// Frame not compiled (handles deoptimization blob)
- return SharedRuntime::raw_exception_handler_for_return_address(ret_pc);
+ return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc);
}
--- a/hotspot/src/share/vm/opto/split_if.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/split_if.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -187,10 +187,20 @@
}
#endif
+ // ConvI2L may have type information on it which becomes invalid if
+ // it moves up in the graph so change any clones so widen the type
+ // to TypeLong::INT when pushing it up.
+ const Type* rtype = NULL;
+ if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::INT) {
+ rtype = TypeLong::INT;
+ }
+
// Now actually split-up this guy. One copy per control path merging.
Node *phi = PhiNode::make_blank(blk1, n);
for( uint j = 1; j < blk1->req(); j++ ) {
Node *x = n->clone();
+ // Widen the type of the ConvI2L when pushing up.
+ if (rtype != NULL) x->as_Type()->set_type(rtype);
if( n->in(0) && n->in(0) == blk1 )
x->set_req( 0, blk1->in(j) );
for( uint i = 1; i < n->req(); i++ ) {
--- a/hotspot/src/share/vm/opto/type.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/opto/type.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -2545,12 +2545,15 @@
ftip->is_loaded() && ftip->klass()->is_interface() &&
ktip->is_loaded() && !ktip->klass()->is_interface()) {
// Happens in a CTW of rt.jar, 320-341, no extra flags
+ assert(!ftip->klass_is_exact(), "interface could not be exact");
return ktip->cast_to_ptr_type(ftip->ptr());
}
+ // Interface klass type could be exact in opposite to interface type,
+ // return it here instead of incorrect Constant ptr J/L/Object (6894807).
if (ftkp != NULL && ktkp != NULL &&
ftkp->is_loaded() && ftkp->klass()->is_interface() &&
+ !ftkp->klass_is_exact() && // Keep exact interface klass
ktkp->is_loaded() && !ktkp->klass()->is_interface()) {
- // Happens in a CTW of rt.jar, 320-341, no extra flags
return ktkp->cast_to_ptr_type(ftkp->ptr());
}
@@ -2809,7 +2812,8 @@
// then we can subclass in the Java class hierarchy.
if (klass()->equals(ciEnv::current()->Object_klass())) {
// that is, tp's array type is a subtype of my klass
- return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
+ return TypeAryPtr::make(ptr, (ptr == Constant ? tp->const_oop() : NULL),
+ tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
}
}
// The other case cannot happen, since I cannot be a subtype of an array.
@@ -3415,7 +3419,8 @@
// then we can subclass in the Java class hierarchy.
if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) {
// that is, my array type is a subtype of 'tp' klass
- return make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id );
+ return make( ptr, (ptr == Constant ? const_oop() : NULL),
+ _ary, _klass, _klass_is_exact, offset, instance_id );
}
}
// The other case cannot happen, since t cannot be a subtype of an array.
--- a/hotspot/src/share/vm/prims/forte.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/prims/forte.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -55,12 +55,11 @@
};
-static void is_decipherable_compiled_frame(frame* fr, RegisterMap* map,
- bool* is_compiled_p, bool* is_walkable_p);
+static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm);
static bool is_decipherable_interpreted_frame(JavaThread* thread,
- frame* fr,
- methodOop* method_p,
- int* bci_p);
+ frame* fr,
+ methodOop* method_p,
+ int* bci_p);
@@ -122,41 +121,43 @@
// Determine if 'fr' is a decipherable compiled frame. We are already
// assured that fr is for a java nmethod.
-static bool is_decipherable_compiled_frame(frame* fr) {
-
- assert(fr->cb() != NULL && fr->cb()->is_nmethod(), "invariant");
- nmethod* nm = (nmethod*) fr->cb();
+static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm) {
assert(nm->is_java_method(), "invariant");
- // First try and find an exact PcDesc
-
- PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
-
- // Did we find a useful PcDesc?
- if (pc_desc != NULL &&
- pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
-
- address probe_pc = fr->pc() + 1;
- pc_desc = nm->pc_desc_near(probe_pc);
+ if (thread->has_last_Java_frame() && thread->last_Java_pc() == fr->pc()) {
+ // We're stopped at a call into the JVM so look for a PcDesc with
+ // the actual pc reported by the frame.
+ PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
- // Now do we have a useful PcDesc?
-
+ // Did we find a useful PcDesc?
if (pc_desc != NULL &&
- pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
- // No debug information available for this pc
- // vframeStream would explode if we try and walk the frames.
- return false;
+ pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) {
+ return true;
}
-
- // This PcDesc is useful however we must adjust the frame's pc
- // so that the vframeStream lookups will use this same pc
-
- fr->set_pc(pc_desc->real_pc(nm));
}
+ // We're at some random pc in the nmethod so search for the PcDesc
+ // whose pc is greater than the current PC. It's done this way
+ // because the extra PcDescs that are recorded for improved debug
+ // info record the end of the region covered by the ScopeDesc
+ // instead of the beginning.
+ PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1);
+
+ // Now do we have a useful PcDesc?
+ if (pc_desc == NULL ||
+ pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
+ // No debug information available for this pc
+ // vframeStream would explode if we try and walk the frames.
+ return false;
+ }
+
+ // This PcDesc is useful however we must adjust the frame's pc
+ // so that the vframeStream lookups will use this same pc
+ fr->set_pc(pc_desc->real_pc(nm));
return true;
}
+
// Determine if 'fr' is a walkable interpreted frame. Returns false
// if it is not. *method_p, and *bci_p are not set when false is
// returned. *method_p is non-NULL if frame was executing a Java
@@ -166,9 +167,9 @@
// even if a valid BCI cannot be found.
static bool is_decipherable_interpreted_frame(JavaThread* thread,
- frame* fr,
- methodOop* method_p,
- int* bci_p) {
+ frame* fr,
+ methodOop* method_p,
+ int* bci_p) {
assert(fr->is_interpreted_frame(), "just checking");
// top frame is an interpreted frame
@@ -323,13 +324,15 @@
// have a PCDesc that can get us a bci however we did find
// a method
- if (!is_decipherable_compiled_frame(&candidate)) {
+ if (!is_decipherable_compiled_frame(thread, &candidate, nm)) {
return false;
}
// is_decipherable_compiled_frame may modify candidate's pc
*initial_frame_p = candidate;
+ assert(nm->pc_desc_at(candidate.pc()) != NULL, "if it's decipherable then pc must be valid");
+
return true;
}
--- a/hotspot/src/share/vm/prims/jni.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/prims/jni.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -3401,12 +3401,16 @@
thread->set_thread_state(_thread_in_vm);
// Must do this before initialize_thread_local_storage
thread->record_stack_base_and_size();
+
thread->initialize_thread_local_storage();
if (!os::create_attached_thread(thread)) {
delete thread;
return JNI_ERR;
}
+ // Enable stack overflow checks
+ thread->create_stack_guard_pages();
+
thread->initialize_tlab();
// Crucial that we do not have a safepoint check for this thread, since it has
@@ -3452,9 +3456,6 @@
// to regrab the threads_lock
thread->set_attached();
- // Enable stack overflow checks
- thread->create_stack_guard_pages();
-
// Set java thread status.
java_lang_Thread::set_thread_status(thread->threadObj(),
java_lang_Thread::RUNNABLE);
--- a/hotspot/src/share/vm/prims/jvm.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/prims/jvm.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -26,6 +26,10 @@
#include "incls/_jvm.cpp.incl"
#include <errno.h>
+HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__begin, long long);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__end, int);
+HS_DTRACE_PROBE_DECL0(hotspot, thread__yield);
+
/*
NOTE about use of any ctor or function call that can trigger a safepoint/GC:
such ctors and calls MUST NOT come between an oop declaration/init and its
@@ -2762,6 +2766,7 @@
JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass))
JVMWrapper("JVM_Yield");
if (os::dont_yield()) return;
+ HS_DTRACE_PROBE0(hotspot, thread__yield);
// When ConvertYieldToSleep is off (default), this matches the classic VM use of yield.
// Critical for similar threading behaviour
if (ConvertYieldToSleep) {
@@ -2787,6 +2792,8 @@
// And set new thread state to SLEEPING.
JavaThreadSleepState jtss(thread);
+ HS_DTRACE_PROBE1(hotspot, thread__sleep__begin, millis);
+
if (millis == 0) {
// When ConvertSleepToYield is on, this matches the classic VM implementation of
// JVM_Sleep. Critical for similar threading behaviour (Win32)
@@ -2807,6 +2814,7 @@
// An asynchronous exception (e.g., ThreadDeathException) could have been thrown on
// us while we were sleeping. We do not overwrite those.
if (!HAS_PENDING_EXCEPTION) {
+ HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1);
// TODO-FIXME: THROW_MSG returns which means we will not call set_state()
// to properly restore the thread state. That's likely wrong.
THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");
@@ -2814,6 +2822,7 @@
}
thread->osthread()->set_state(old_state);
}
+ HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0);
JVM_END
JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008-2010 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
@@ -82,6 +82,10 @@
NULL
};
+// Adapters.
+MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL;
+int MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size;
+
jobject MethodHandles::_raise_exception_method;
#ifdef ASSERT
@@ -95,6 +99,41 @@
}
#endif
+
+//------------------------------------------------------------------------------
+// MethodHandles::generate_adapters
+//
+void MethodHandles::generate_adapters() {
+ if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL) return;
+
+ assert(_adapter_code == NULL, "generate only once");
+
+ ResourceMark rm;
+ TraceTime timer("MethodHandles adapters generation", TraceStartupTime);
+ _adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size);
+ if (_adapter_code == NULL)
+ vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
+ CodeBuffer code(_adapter_code->instructions_begin(), _adapter_code->instructions_size());
+
+ MethodHandlesAdapterGenerator g(&code);
+ g.generate();
+}
+
+
+//------------------------------------------------------------------------------
+// MethodHandlesAdapterGenerator::generate
+//
+void MethodHandlesAdapterGenerator::generate() {
+ // 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);
+ }
+}
+
+
void MethodHandles::set_enabled(bool z) {
if (_enabled != z) {
guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles");
--- a/hotspot/src/share/vm/prims/methodHandles.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008-2010 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
@@ -115,6 +115,10 @@
static const char* _entry_names[_EK_LIMIT+1];
static jobject _raise_exception_method;
+ // Adapters.
+ static MethodHandlesAdapterBlob* _adapter_code;
+ static int _adapter_code_size;
+
static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; }
static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; }
@@ -133,6 +137,43 @@
_entries[ek] = me;
}
+ // Some adapter helper functions.
+ static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) {
+ switch (ek) {
+ case _bound_int_mh : // fall-thru
+ case _bound_int_direct_mh : arg_type = T_INT; arg_mask = _INSERT_INT_MASK; break;
+ case _bound_long_mh : // fall-thru
+ case _bound_long_direct_mh: arg_type = T_LONG; arg_mask = _INSERT_LONG_MASK; break;
+ case _bound_ref_mh : // fall-thru
+ case _bound_ref_direct_mh : arg_type = T_OBJECT; arg_mask = _INSERT_REF_MASK; break;
+ default: ShouldNotReachHere();
+ }
+ arg_slots = type2size[arg_type];
+ }
+
+ static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) {
+ int swap_slots = 0;
+ switch (ek) {
+ case _adapter_opt_swap_1: swap_slots = 1; rotate = 0; break;
+ case _adapter_opt_swap_2: swap_slots = 2; rotate = 0; break;
+ case _adapter_opt_rot_1_up: swap_slots = 1; rotate = 1; break;
+ case _adapter_opt_rot_1_down: swap_slots = 1; rotate = -1; break;
+ case _adapter_opt_rot_2_up: swap_slots = 2; rotate = 1; break;
+ case _adapter_opt_rot_2_down: swap_slots = 2; rotate = -1; break;
+ default: ShouldNotReachHere();
+ }
+ // Return the size of the stack slots to move in bytes.
+ swap_bytes = swap_slots * Interpreter::stackElementSize();
+ }
+
+ static int get_ek_adapter_opt_spread_info(EntryKind ek) {
+ switch (ek) {
+ case _adapter_opt_spread_0: return 0;
+ case _adapter_opt_spread_1: return 1;
+ default : return -1;
+ }
+ }
+
static methodOop raise_exception_method() {
oop rem = JNIHandles::resolve(_raise_exception_method);
assert(rem == NULL || rem->is_method(), "");
@@ -230,7 +271,10 @@
// bit values for suppress argument to expand_MemberName:
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
- // called from InterpreterGenerator and StubGenerator
+ // Generate MethodHandles adapters.
+ static void generate_adapters();
+
+ // Called from InterpreterGenerator and MethodHandlesAdapterGenerator.
static address generate_method_handle_interpreter_entry(MacroAssembler* _masm);
static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek);
@@ -385,13 +429,13 @@
static void insert_arg_slots(MacroAssembler* _masm,
RegisterOrConstant arg_slots,
int arg_mask,
- Register rax_argslot,
- Register rbx_temp, Register rdx_temp);
+ Register argslot_reg,
+ Register temp_reg, Register temp2_reg);
static void remove_arg_slots(MacroAssembler* _masm,
RegisterOrConstant arg_slots,
- Register rax_argslot,
- Register rbx_temp, Register rdx_temp);
+ Register argslot_reg,
+ Register temp_reg, Register temp2_reg);
};
@@ -447,3 +491,14 @@
address MethodHandles::from_compiled_entry(EntryKind ek) { return entry(ek)->from_compiled_entry(); }
address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->from_interpreted_entry(); }
+
+
+//------------------------------------------------------------------------------
+// MethodHandlesAdapterGenerator
+//
+class MethodHandlesAdapterGenerator : public StubCodeGenerator {
+public:
+ MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code) {}
+
+ void generate();
+};
--- a/hotspot/src/share/vm/prims/unsafe.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -29,6 +29,10 @@
#include "incls/_precompiled.incl"
#include "incls/_unsafe.cpp.incl"
+HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t);
+
#define MAX_OBJECT_SIZE \
( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
+ ((julong)max_jint * sizeof(double)) )
@@ -1083,8 +1087,10 @@
UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
UnsafeWrapper("Unsafe_Park");
+ HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
JavaThreadParkedState jtps(thread, time != 0);
thread->parker()->park(isAbsolute != 0, time);
+ HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker());
UNSAFE_END
UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
@@ -1116,6 +1122,7 @@
}
}
if (p != NULL) {
+ HS_DTRACE_PROBE1(hotspot, thread__unpark, p);
p->unpark();
}
UNSAFE_END
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1203,6 +1203,11 @@
if (!FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim) || !FLAG_IS_DEFAULT(OldPLABWeight)) {
CFLS_LAB::modify_initialization(OldPLABSize, OldPLABWeight);
}
+ if (PrintGCDetails && Verbose) {
+ tty->print_cr("MarkStackSize: %uk MarkStackSizeMax: %uk",
+ MarkStackSize / K, MarkStackSizeMax / K);
+ tty->print_cr("ConcGCThreads: %u", ConcGCThreads);
+ }
}
#endif // KERNEL
@@ -1339,6 +1344,25 @@
if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
FLAG_SET_DEFAULT(MaxGCPauseMillis, 200);
}
+
+ if (FLAG_IS_DEFAULT(MarkStackSize)) {
+ FLAG_SET_DEFAULT(MarkStackSize, 128 * TASKQUEUE_SIZE);
+ }
+ if (PrintGCDetails && Verbose) {
+ tty->print_cr("MarkStackSize: %uk MarkStackSizeMax: %uk",
+ MarkStackSize / K, MarkStackSizeMax / K);
+ tty->print_cr("ConcGCThreads: %u", ConcGCThreads);
+ }
+
+ if (FLAG_IS_DEFAULT(GCTimeRatio) || GCTimeRatio == 0) {
+ // In G1, we want the default GC overhead goal to be higher than
+ // say in PS. So we set it here to 10%. Otherwise the heap might
+ // be expanded more aggressively than we would like it to. In
+ // fact, even 10% seems to not be high enough in some cases
+ // (especially small GC stress tests that the main thing they do
+ // is allocation). We might consider increase it further.
+ FLAG_SET_DEFAULT(GCTimeRatio, 9);
+ }
}
void Arguments::set_heap_size() {
@@ -1737,6 +1761,11 @@
status = false;
}
+ if (UseG1GC) {
+ status = status && verify_percentage(InitiatingHeapOccupancyPercent,
+ "InitiatingHeapOccupancyPercent");
+ }
+
status = status && verify_interval(RefDiscoveryPolicy,
ReferenceProcessor::DiscoveryPolicyMin,
ReferenceProcessor::DiscoveryPolicyMax,
@@ -1795,6 +1824,29 @@
return false;
}
+bool Arguments::parse_uintx(const char* value,
+ uintx* uintx_arg,
+ uintx min_size) {
+
+ // Check the sign first since atomull() parses only unsigned values.
+ bool value_is_positive = !(*value == '-');
+
+ if (value_is_positive) {
+ julong n;
+ bool good_return = atomull(value, &n);
+ if (good_return) {
+ bool above_minimum = n >= min_size;
+ bool value_is_too_large = n > max_uintx;
+
+ if (above_minimum && !value_is_too_large) {
+ *uintx_arg = n;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
julong* long_arg,
julong min_size) {
@@ -2453,6 +2505,37 @@
jio_fprintf(defaultStream::error_stream(),
"Please use -XX:YoungPLABSize in place of "
"-XX:ParallelGCToSpaceAllocBufferSize in the future\n");
+ } else if (match_option(option, "-XX:CMSMarkStackSize=", &tail) ||
+ match_option(option, "-XX:G1MarkStackSize=", &tail)) {
+ julong stack_size = 0;
+ ArgsRange errcode = parse_memory_size(tail, &stack_size, 1);
+ if (errcode != arg_in_range) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Invalid mark stack size: %s\n", option->optionString);
+ describe_range_error(errcode);
+ return JNI_EINVAL;
+ }
+ FLAG_SET_CMDLINE(uintx, MarkStackSize, stack_size);
+ } else if (match_option(option, "-XX:CMSMarkStackSizeMax=", &tail)) {
+ julong max_stack_size = 0;
+ ArgsRange errcode = parse_memory_size(tail, &max_stack_size, 1);
+ if (errcode != arg_in_range) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Invalid maximum mark stack size: %s\n",
+ option->optionString);
+ describe_range_error(errcode);
+ return JNI_EINVAL;
+ }
+ FLAG_SET_CMDLINE(uintx, MarkStackSizeMax, max_stack_size);
+ } else if (match_option(option, "-XX:ParallelMarkingThreads=", &tail) ||
+ match_option(option, "-XX:ParallelCMSThreads=", &tail)) {
+ uintx conc_threads = 0;
+ if (!parse_uintx(tail, &conc_threads, 1)) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Invalid concurrent threads: %s\n", option->optionString);
+ return JNI_EINVAL;
+ }
+ FLAG_SET_CMDLINE(uintx, ConcGCThreads, conc_threads);
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
// Skip -XX:Flags= since that case has already been handled
if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) {
@@ -2784,6 +2867,12 @@
}
#endif // _LP64
+ // MethodHandles code does not support TaggedStackInterpreter.
+ if (EnableMethodHandles && TaggedStackInterpreter) {
+ warning("TaggedStackInterpreter is not supported by MethodHandles code. Disabling TaggedStackInterpreter.");
+ TaggedStackInterpreter = false;
+ }
+
// Check the GC selections again.
if (!check_gc_consistency()) {
return JNI_EINVAL;
--- a/hotspot/src/share/vm/runtime/arguments.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -343,6 +343,12 @@
static ArgsRange check_memory_size(julong size, julong min_size);
static ArgsRange parse_memory_size(const char* s, julong* long_arg,
julong min_size);
+ // Parse a string for a unsigned integer. Returns true if value
+ // is an unsigned integer greater than or equal to the minimum
+ // parameter passed and returns the value in uintx_arg. Returns
+ // false otherwise, with uintx_arg undefined.
+ static bool parse_uintx(const char* value, uintx* uintx_arg,
+ uintx min_size);
// methods to build strings from individual args
static void build_jvm_args(const char* arg);
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/globals.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -1052,7 +1052,8 @@
"Use SSE2 MOVDQU instruction for Arraycopy") \
\
product(intx, FieldsAllocationStyle, 1, \
- "0 - type based with oops first, 1 - with oops last") \
+ "0 - type based with oops first, 1 - with oops last, " \
+ "2 - oops in super and sub classes are together") \
\
product(bool, CompactFields, true, \
"Allocate nonstatic fields in gaps between previous fields") \
@@ -1245,9 +1246,6 @@
product(uintx, ParallelGCThreads, 0, \
"Number of parallel threads parallel gc will use") \
\
- product(uintx, ParallelCMSThreads, 0, \
- "Max number of threads CMS will use for concurrent work") \
- \
develop(bool, ParallelOldGCSplitALot, false, \
"Provoke splitting (copying data from a young gen space to" \
"multiple destination spaces)") \
@@ -1258,8 +1256,8 @@
develop(bool, TraceRegionTasksQueuing, false, \
"Trace the queuing of the region tasks") \
\
- product(uintx, ParallelMarkingThreads, 0, \
- "Number of marking threads concurrent gc will use") \
+ product(uintx, ConcGCThreads, 0, \
+ "Number of threads concurrent gc will use") \
\
product(uintx, YoungPLABSize, 4096, \
"Size of young gen promotion labs (in HeapWords)") \
@@ -1535,11 +1533,11 @@
develop(bool, CMSOverflowEarlyRestoration, false, \
"Whether preserved marks should be restored early") \
\
- product(uintx, CMSMarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M), \
- "Size of CMS marking stack") \
- \
- product(uintx, CMSMarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M), \
- "Max size of CMS marking stack") \
+ product(uintx, MarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M), \
+ "Size of marking stack") \
+ \
+ product(uintx, MarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M), \
+ "Max size of marking stack") \
\
notproduct(bool, CMSMarkStackOverflowALot, false, \
"Whether we should simulate frequent marking stack / work queue" \
@@ -1724,6 +1722,13 @@
"Percentage CMS generation occupancy to start a CMS collection " \
"cycle. A negative value means that CMSTriggerRatio is used") \
\
+ product(uintx, InitiatingHeapOccupancyPercent, 45, \
+ "Percentage of the (entire) heap occupancy to start a " \
+ "concurrent GC cycle. It us used by GCs that trigger a " \
+ "concurrent GC cycle based on the occupancy of the entire heap, " \
+ "not just one of the generations (e.g., G1). A value of 0 " \
+ "denotes 'do constant GC cycles'.") \
+ \
product(intx, CMSInitiatingPermOccupancyFraction, -1, \
"Percentage CMS perm generation occupancy to start a " \
"CMScollection cycle. A negative value means that " \
@@ -1791,6 +1796,10 @@
product(uintx, PreserveMarkStackSize, 1024, \
"Size for stack used in promotion failure handling") \
\
+ develop(uintx, ObjArrayMarkingStride, 512, \
+ "Number of ObjArray elements to push onto the marking stack" \
+ "before pushing a continuation entry") \
+ \
product_pd(bool, UseTLAB, "Use thread-local object allocation") \
\
product_pd(bool, ResizeTLAB, \
@@ -2285,6 +2294,10 @@
"print safepoint statistics only when safepoint takes" \
" more than PrintSafepointSatisticsTimeout in millis") \
\
+ product(bool, TraceSafepointCleanupTime, false, \
+ "print the break down of clean up tasks performed during" \
+ " safepoint") \
+ \
develop(bool, InlineAccessors, true, \
"inline accessor methods (get/set)") \
\
@@ -2490,10 +2503,6 @@
notproduct(bool, TraceSpilling, false, \
"Trace spilling") \
\
- develop(bool, DeutschShiffmanExceptions, true, \
- "Fast check to find exception handler for precisely typed " \
- "exceptions") \
- \
product(bool, SplitIfBlocks, true, \
"Clone compares and control flow through merge points to fold " \
"some branches") \
@@ -2699,7 +2708,8 @@
product(intx, AllocatePrefetchStyle, 1, \
"0 = no prefetch, " \
"1 = prefetch instructions for each allocation, " \
- "2 = use TLAB watermark to gate allocation prefetch") \
+ "2 = use TLAB watermark to gate allocation prefetch, " \
+ "3 = use BIS instruction on Sparc for allocation prefetch") \
\
product(intx, AllocatePrefetchDistance, -1, \
"Distance to prefetch ahead of allocation pointer") \
@@ -2925,7 +2935,7 @@
product(uintx, OldSize, ScaleForWordSize(4*M), \
"Initial tenured generation size (in bytes)") \
\
- product(uintx, NewSize, ScaleForWordSize(4*M), \
+ product(uintx, NewSize, ScaleForWordSize(1*M), \
"Initial new generation size (in bytes)") \
\
product(uintx, MaxNewSize, max_uintx, \
@@ -3102,6 +3112,9 @@
develop_pd(intx, CodeEntryAlignment, \
"Code entry alignment for generated code (in bytes)") \
\
+ product_pd(intx, OptoLoopAlignment, \
+ "Align inner loops to zero relative to this modulus") \
+ \
product_pd(uintx, InitialCodeCacheSize, \
"Initial code cache size (in bytes)") \
\
--- a/hotspot/src/share/vm/runtime/init.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/init.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -118,6 +118,9 @@
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/mutexLocker.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -70,6 +70,7 @@
Monitor* CMark_lock = NULL;
Monitor* ZF_mon = NULL;
Monitor* Cleanup_mon = NULL;
+Mutex* CMRegionStack_lock = NULL;
Mutex* SATB_Q_FL_lock = NULL;
Monitor* SATB_Q_CBL_mon = NULL;
Mutex* Shared_SATB_Q_lock = NULL;
@@ -167,6 +168,7 @@
def(CMark_lock , Monitor, nonleaf, true ); // coordinate concurrent mark thread
def(ZF_mon , Monitor, leaf, true );
def(Cleanup_mon , Monitor, nonleaf, true );
+ def(CMRegionStack_lock , Mutex, leaf, true );
def(SATB_Q_FL_lock , Mutex , special, true );
def(SATB_Q_CBL_mon , Monitor, nonleaf, true );
def(Shared_SATB_Q_lock , Mutex, nonleaf, true );
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -63,6 +63,7 @@
extern Monitor* CMark_lock; // used for concurrent mark thread coordination
extern Monitor* ZF_mon; // used for G1 conc zero-fill.
extern Monitor* Cleanup_mon; // used for G1 conc cleanup.
+extern Mutex* CMRegionStack_lock; // used for protecting accesses to the CM region stack
extern Mutex* SATB_Q_FL_lock; // Protects SATB Q
// buffer free list.
extern Monitor* SATB_Q_CBL_mon; // Protects SATB Q
--- a/hotspot/src/share/vm/runtime/os.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/os.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -218,6 +218,9 @@
static bool guard_memory(char* addr, size_t bytes);
static bool unguard_memory(char* addr, size_t bytes);
+ static bool create_stack_guard_pages(char* addr, size_t bytes);
+ static bool remove_stack_guard_pages(char* addr, size_t bytes);
+
static char* map_memory(int fd, const char* file_name, size_t file_offset,
char *addr, size_t bytes, bool read_only = false,
bool allow_exec = false);
--- a/hotspot/src/share/vm/runtime/safepoint.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -30,8 +30,8 @@
SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
volatile int SafepointSynchronize::_waiting_to_block = 0;
-jlong SafepointSynchronize::_last_safepoint = 0;
volatile int SafepointSynchronize::_safepoint_counter = 0;
+long SafepointSynchronize::_end_of_last_safepoint = 0;
static volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE
static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only
static bool timeout_error_printed = false;
@@ -42,7 +42,10 @@
Thread* myThread = Thread::current();
assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint");
- _last_safepoint = os::javaTimeNanos();
+ if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
+ _safepoint_begin_time = os::javaTimeNanos();
+ _ts_of_current_safepoint = tty->time_stamp().seconds();
+ }
#ifndef SERIALGC
if (UseConcMarkSweepGC) {
@@ -320,6 +323,11 @@
// Call stuff that needs to be run when a safepoint is just about to be completed
do_cleanup_tasks();
+
+ if (PrintSafepointStatistics) {
+ // Record how much time spend on the above cleanup tasks
+ update_statistics_on_cleanup_end(os::javaTimeNanos());
+ }
}
}
@@ -411,6 +419,9 @@
ConcurrentGCThread::safepoint_desynchronize();
}
#endif // SERIALGC
+ // record this time so VMThread can keep track how much time has elasped
+ // since last safepoint.
+ _end_of_last_safepoint = os::javaTimeMillis();
}
bool SafepointSynchronize::is_cleanup_needed() {
@@ -445,24 +456,23 @@
// Various cleaning tasks that should be done periodically at safepoints
void SafepointSynchronize::do_cleanup_tasks() {
- jlong cleanup_time;
-
- // Update fat-monitor pool, since this is a safepoint.
- if (TraceSafepoint) {
- cleanup_time = os::javaTimeNanos();
+ {
+ TraceTime t1("deflating idle monitors", TraceSafepointCleanupTime);
+ ObjectSynchronizer::deflate_idle_monitors();
}
- ObjectSynchronizer::deflate_idle_monitors();
- InlineCacheBuffer::update_inline_caches();
+ {
+ TraceTime t2("updating inline caches", TraceSafepointCleanupTime);
+ InlineCacheBuffer::update_inline_caches();
+ }
+
if(UseCounterDecay && CounterDecay::is_decay_needed()) {
+ TraceTime t3("decaying counter", TraceSafepointCleanupTime);
CounterDecay::decay();
}
+
+ TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime);
NMethodSweeper::sweep();
-
- if (TraceSafepoint) {
- tty->print_cr("do_cleanup_tasks takes "INT64_FORMAT_W(6) "ms",
- (os::javaTimeNanos() - cleanup_time) / MICROUNITS);
- }
}
@@ -979,17 +989,32 @@
// Statistics & Instrumentations
//
SafepointSynchronize::SafepointStats* SafepointSynchronize::_safepoint_stats = NULL;
+jlong SafepointSynchronize::_safepoint_begin_time = 0;
int SafepointSynchronize::_cur_stat_index = 0;
julong SafepointSynchronize::_safepoint_reasons[VM_Operation::VMOp_Terminating];
julong SafepointSynchronize::_coalesced_vmop_count = 0;
jlong SafepointSynchronize::_max_sync_time = 0;
+jlong SafepointSynchronize::_max_vmop_time = 0;
+float SafepointSynchronize::_ts_of_current_safepoint = 0.0f;
-// last_safepoint_start_time records the start time of last safepoint.
-static jlong last_safepoint_start_time = 0;
-static jlong sync_end_time = 0;
+static jlong cleanup_end_time = 0;
static bool need_to_track_page_armed_status = false;
static bool init_done = false;
+// Helper method to print the header.
+static void print_header() {
+ tty->print(" vmop "
+ "[threads: total initially_running wait_to_block] ");
+ tty->print("[time: spin block sync cleanup vmop] ");
+
+ // no page armed status printed out if it is always armed.
+ if (need_to_track_page_armed_status) {
+ tty->print("page_armed ");
+ }
+
+ tty->print_cr("page_trap_count");
+}
+
void SafepointSynchronize::deferred_initialize_stat() {
if (init_done) return;
@@ -1016,19 +1041,6 @@
if (UseCompilerSafepoints && DeferPollingPageLoopCount >= 0) {
need_to_track_page_armed_status = true;
}
-
- tty->print(" vmop_name "
- "[threads: total initially_running wait_to_block] ");
- tty->print("[time: spin block sync] "
- "[vmop_time time_elapsed] ");
-
- // no page armed status printed out if it is always armed.
- if (need_to_track_page_armed_status) {
- tty->print("page_armed ");
- }
-
- tty->print_cr("page_trap_count");
-
init_done = true;
}
@@ -1036,6 +1048,8 @@
assert(init_done, "safepoint statistics array hasn't been initialized");
SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
+ spstat->_time_stamp = _ts_of_current_safepoint;
+
VM_Operation *op = VMThread::vm_operation();
spstat->_vmop_type = (op != NULL ? op->type() : -1);
if (op != NULL) {
@@ -1054,14 +1068,6 @@
} else {
spstat->_time_to_spin = 0;
}
-
- if (last_safepoint_start_time == 0) {
- spstat->_time_elapsed_since_last_safepoint = 0;
- } else {
- spstat->_time_elapsed_since_last_safepoint = _last_safepoint -
- last_safepoint_start_time;
- }
- last_safepoint_start_time = _last_safepoint;
}
void SafepointSynchronize::update_statistics_on_spin_end() {
@@ -1097,18 +1103,31 @@
// Records the end time of sync which will be used to calculate the total
// vm operation time. Again, the real time spending in syncing will be deducted
// from the start of the sync time later when end_statistics is called.
- spstat->_time_to_sync = end_time - _last_safepoint;
+ spstat->_time_to_sync = end_time - _safepoint_begin_time;
if (spstat->_time_to_sync > _max_sync_time) {
_max_sync_time = spstat->_time_to_sync;
}
- sync_end_time = end_time;
+
+ spstat->_time_to_do_cleanups = end_time;
+}
+
+void SafepointSynchronize::update_statistics_on_cleanup_end(jlong end_time) {
+ SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
+
+ // Record how long spent in cleanup tasks.
+ spstat->_time_to_do_cleanups = end_time - spstat->_time_to_do_cleanups;
+
+ cleanup_end_time = end_time;
}
void SafepointSynchronize::end_statistics(jlong vmop_end_time) {
SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
// Update the vm operation time.
- spstat->_time_to_exec_vmop = vmop_end_time - sync_end_time;
+ spstat->_time_to_exec_vmop = vmop_end_time - cleanup_end_time;
+ if (spstat->_time_to_exec_vmop > _max_vmop_time) {
+ _max_vmop_time = spstat->_time_to_exec_vmop;
+ }
// Only the sync time longer than the specified
// PrintSafepointStatisticsTimeout will be printed out right away.
// By default, it is -1 meaning all samples will be put into the list.
@@ -1119,40 +1138,42 @@
} else {
// The safepoint statistics will be printed out when the _safepoin_stats
// array fills up.
- if (_cur_stat_index != PrintSafepointStatisticsCount - 1) {
- _cur_stat_index ++;
- } else {
+ if (_cur_stat_index == PrintSafepointStatisticsCount - 1) {
print_statistics();
_cur_stat_index = 0;
- tty->print_cr("");
+ } else {
+ _cur_stat_index++;
}
}
}
void SafepointSynchronize::print_statistics() {
- int index;
SafepointStats* sstats = _safepoint_stats;
- for (index = 0; index <= _cur_stat_index; index++) {
+ for (int index = 0; index <= _cur_stat_index; index++) {
+ if (index % 30 == 0) {
+ print_header();
+ }
sstats = &_safepoint_stats[index];
- tty->print("%-28s ["
+ tty->print("%.3f: ", sstats->_time_stamp);
+ tty->print("%-26s ["
INT32_FORMAT_W(8)INT32_FORMAT_W(11)INT32_FORMAT_W(15)
- "] ",
+ " ] ",
sstats->_vmop_type == -1 ? "no vm operation" :
VM_Operation::name(sstats->_vmop_type),
sstats->_nof_total_threads,
sstats->_nof_initial_running_threads,
sstats->_nof_threads_wait_to_block);
// "/ MICROUNITS " is to convert the unit from nanos to millis.
- tty->print(" ["
- INT64_FORMAT_W(6)INT64_FORMAT_W(6)INT64_FORMAT_W(6)
- "] "
- "["INT64_FORMAT_W(6)INT64_FORMAT_W(9) "] ",
+ tty->print(" ["
+ INT64_FORMAT_W(6)INT64_FORMAT_W(6)
+ INT64_FORMAT_W(6)INT64_FORMAT_W(6)
+ INT64_FORMAT_W(6)" ] ",
sstats->_time_to_spin / MICROUNITS,
sstats->_time_to_wait_to_block / MICROUNITS,
sstats->_time_to_sync / MICROUNITS,
- sstats->_time_to_exec_vmop / MICROUNITS,
- sstats->_time_elapsed_since_last_safepoint / MICROUNITS);
+ sstats->_time_to_do_cleanups / MICROUNITS,
+ sstats->_time_to_exec_vmop / MICROUNITS);
if (need_to_track_page_armed_status) {
tty->print(INT32_FORMAT" ", sstats->_page_armed);
@@ -1174,7 +1195,7 @@
// don't print it out.
// Approximate the vm op time.
_safepoint_stats[_cur_stat_index]._time_to_exec_vmop =
- os::javaTimeNanos() - sync_end_time;
+ os::javaTimeNanos() - cleanup_end_time;
if ( PrintSafepointStatisticsTimeout < 0 ||
spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) {
@@ -1203,6 +1224,9 @@
_coalesced_vmop_count);
tty->print_cr("Maximum sync time "INT64_FORMAT_W(5)" ms",
_max_sync_time / MICROUNITS);
+ tty->print_cr("Maximum vm operation time (except for Exit VM operation) "
+ INT64_FORMAT_W(5)" ms",
+ _max_vmop_time / MICROUNITS);
}
// ------------------------------------------------------------------------------------------------
--- a/hotspot/src/share/vm/runtime/safepoint.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/safepoint.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -65,6 +65,7 @@
};
typedef struct {
+ float _time_stamp; // record when the current safepoint occurs in seconds
int _vmop_type; // type of VM operation triggers the safepoint
int _nof_total_threads; // total number of Java threads
int _nof_initial_running_threads; // total number of initially seen running threads
@@ -73,14 +74,14 @@
int _nof_threads_hit_page_trap; // total number of threads hitting the page trap
jlong _time_to_spin; // total time in millis spent in spinning
jlong _time_to_wait_to_block; // total time in millis spent in waiting for to block
+ jlong _time_to_do_cleanups; // total time in millis spent in performing cleanups
jlong _time_to_sync; // total time in millis spent in getting to _synchronized
jlong _time_to_exec_vmop; // total time in millis spent in vm operation itself
- jlong _time_elapsed_since_last_safepoint; // time elasped since last safepoint
} SafepointStats;
private:
static volatile SynchronizeState _state; // Threads might read this flag directly, without acquireing the Threads_lock
- static volatile int _waiting_to_block; // No. of threads we are waiting for to block.
+ static volatile int _waiting_to_block; // number of threads we are waiting for to block
// This counter is used for fast versions of jni_Get<Primitive>Field.
// An even value means there is no ongoing safepoint operations.
@@ -91,19 +92,22 @@
public:
static volatile int _safepoint_counter;
private:
-
- static jlong _last_safepoint; // Time of last safepoint
+ static long _end_of_last_safepoint; // Time of last safepoint in milliseconds
// statistics
- static SafepointStats* _safepoint_stats; // array of SafepointStats struct
- static int _cur_stat_index; // current index to the above array
- static julong _safepoint_reasons[]; // safepoint count for each VM op
- static julong _coalesced_vmop_count;// coalesced vmop count
- static jlong _max_sync_time; // maximum sync time in nanos
+ static jlong _safepoint_begin_time; // time when safepoint begins
+ static SafepointStats* _safepoint_stats; // array of SafepointStats struct
+ static int _cur_stat_index; // current index to the above array
+ static julong _safepoint_reasons[]; // safepoint count for each VM op
+ static julong _coalesced_vmop_count; // coalesced vmop count
+ static jlong _max_sync_time; // maximum sync time in nanos
+ static jlong _max_vmop_time; // maximum vm operation time in nanos
+ static float _ts_of_current_safepoint; // time stamp of current safepoint in seconds
static void begin_statistics(int nof_threads, int nof_running);
static void update_statistics_on_spin_end();
static void update_statistics_on_sync_end(jlong end_time);
+ static void update_statistics_on_cleanup_end(jlong end_time);
static void end_statistics(jlong end_time);
static void print_statistics();
inline static void inc_page_trap_count() {
@@ -140,7 +144,9 @@
static void handle_polling_page_exception(JavaThread *thread);
// VM Thread interface for determining safepoint rate
- static long last_non_safepoint_interval() { return os::javaTimeMillis() - _last_safepoint; }
+ static long last_non_safepoint_interval() {
+ return os::javaTimeMillis() - _end_of_last_safepoint;
+ }
static bool is_cleanup_needed();
static void do_cleanup_tasks();
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -256,14 +256,19 @@
// The continuation address is the entry point of the exception handler of the
// previous frame depending on the return address.
-address SharedRuntime::raw_exception_handler_for_return_address(address return_address) {
+address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) {
assert(frame::verify_return_pc(return_address), "must be a return pc");
+ // Reset MethodHandle flag.
+ thread->set_is_method_handle_return(false);
+
// the fastest case first
CodeBlob* blob = CodeCache::find_blob(return_address);
if (blob != NULL && blob->is_nmethod()) {
nmethod* code = (nmethod*)blob;
assert(code != NULL, "nmethod must be present");
+ // Check if the return address is a MethodHandle call site.
+ thread->set_is_method_handle_return(code->is_method_handle_return(return_address));
// native nmethods don't have exception handlers
assert(!code->is_native_method(), "no exception handler");
assert(code->header_begin() != code->exception_begin(), "no exception handler");
@@ -289,6 +294,8 @@
if (blob->is_nmethod()) {
nmethod* code = (nmethod*)blob;
assert(code != NULL, "nmethod must be present");
+ // Check if the return address is a MethodHandle call site.
+ thread->set_is_method_handle_return(code->is_method_handle_return(return_address));
assert(code->header_begin() != code->exception_begin(), "no exception handler");
return code->exception_begin();
}
@@ -309,10 +316,11 @@
}
-JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(address return_address))
- return raw_exception_handler_for_return_address(return_address);
+JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(JavaThread* thread, address return_address))
+ return raw_exception_handler_for_return_address(thread, return_address);
JRT_END
+
address SharedRuntime::get_poll_stub(address pc) {
address stub;
// Look up the code blob
@@ -465,16 +473,6 @@
t = table.entry_for(catch_pco, -1, 0);
}
-#ifdef COMPILER1
- if (nm->is_compiled_by_c1() && t == NULL && handler_bci == -1) {
- // Exception is not handled by this frame so unwind. Note that
- // this is not the same as how C2 does this. C2 emits a table
- // entry that dispatches to the unwind code in the nmethod.
- return NULL;
- }
-#endif /* COMPILER1 */
-
-
if (t == NULL) {
tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci);
tty->print_cr(" Exception:");
@@ -587,7 +585,7 @@
// 3. Implict null exception in nmethod
if (!cb->is_nmethod()) {
- guarantee(cb->is_adapter_blob(),
+ guarantee(cb->is_adapter_blob() || cb->is_method_handles_adapter_blob(),
"exception happened outside interpreter, nmethods and vtable stubs (1)");
// There is no handler here, so we will simply unwind.
return StubRoutines::throw_NullPointerException_at_call_entry();
@@ -892,12 +890,13 @@
RegisterMap cbl_map(thread, false);
frame caller_frame = thread->last_frame().sender(&cbl_map);
- CodeBlob* cb = caller_frame.cb();
- guarantee(cb != NULL && cb->is_nmethod(), "must be called from nmethod");
+ CodeBlob* caller_cb = caller_frame.cb();
+ guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod");
+ nmethod* caller_nm = caller_cb->as_nmethod_or_null();
// make sure caller is not getting deoptimized
// and removed before we are done with it.
// CLEANUP - with lazy deopt shouldn't need this lock
- nmethodLocker caller_lock((nmethod*)cb);
+ nmethodLocker caller_lock(caller_nm);
// determine call info & receiver
@@ -929,6 +928,13 @@
}
#endif
+ // JSR 292
+ // If the resolved method is a MethodHandle invoke target the call
+ // site must be a MethodHandle call site.
+ if (callee_method->is_method_handle_invoke()) {
+ assert(caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
+ }
+
// Compute entry points. This might require generation of C2I converter
// frames, so we cannot be holding any locks here. Furthermore, the
// computation of the entry points is independent of patching the call. We
@@ -940,13 +946,12 @@
StaticCallInfo static_call_info;
CompiledICInfo virtual_call_info;
-
// Make sure the callee nmethod does not get deoptimized and removed before
// we are done patching the code.
- nmethod* nm = callee_method->code();
- nmethodLocker nl_callee(nm);
+ nmethod* callee_nm = callee_method->code();
+ nmethodLocker nl_callee(callee_nm);
#ifdef ASSERT
- address dest_entry_point = nm == NULL ? 0 : nm->entry_point(); // used below
+ address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below
#endif
if (is_virtual) {
@@ -2077,7 +2082,6 @@
// ---------------------------------------------------------------------------
// Implementation of AdapterHandlerLibrary
-const char* AdapterHandlerEntry::name = "I2C/C2I adapters";
AdapterHandlerTable* AdapterHandlerLibrary::_adapters = NULL;
AdapterHandlerEntry* AdapterHandlerLibrary::_abstract_method_handler = NULL;
const int AdapterHandlerLibrary_size = 16*K;
@@ -2129,7 +2133,7 @@
ResourceMark rm;
NOT_PRODUCT(int code_size);
- BufferBlob *B = NULL;
+ AdapterBlob* B = NULL;
AdapterHandlerEntry* entry = NULL;
AdapterFingerPrint* fingerprint = NULL;
{
@@ -2179,7 +2183,7 @@
// Create I2C & C2I handlers
- BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
+ BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
if (buf != NULL) {
CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
short buffer_locs[20];
@@ -2208,7 +2212,7 @@
}
#endif
- B = BufferBlob::create(AdapterHandlerEntry::name, &buffer);
+ B = AdapterBlob::create(&buffer);
NOT_PRODUCT(code_size = buffer.code_size());
}
if (B == NULL) {
@@ -2240,7 +2244,7 @@
jio_snprintf(blob_id,
sizeof(blob_id),
"%s(%s)@" PTR_FORMAT,
- AdapterHandlerEntry::name,
+ B->name(),
fingerprint->as_string(),
B->instructions_begin());
VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -96,10 +96,9 @@
static jdouble dexp(jdouble x);
static jdouble dpow(jdouble x, jdouble y);
-
// exception handling across interpreter/compiler boundaries
- static address raw_exception_handler_for_return_address(address return_address);
- static address exception_handler_for_return_address(address return_address);
+ static address raw_exception_handler_for_return_address(JavaThread* thread, address return_address);
+ static address exception_handler_for_return_address(JavaThread* thread, address return_address);
#ifndef SERIALGC
// G1 write barriers
@@ -568,9 +567,6 @@
AdapterHandlerEntry();
public:
- // The name we give all buffer blobs
- static const char* name;
-
address get_i2c_entry() { return _i2c_entry; }
address get_c2i_entry() { return _c2i_entry; }
address get_c2i_unverified_entry() { return _c2i_unverified_entry; }
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/thread.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1637,6 +1637,9 @@
JNIHandleBlock::release_block(block);
}
+ // These have to be removed while this is still a valid thread.
+ remove_stack_guard_pages();
+
if (UseTLAB) {
tlab().make_parsable(true); // retire TLAB, if any
}
@@ -2134,7 +2137,7 @@
int allocate = os::allocate_stack_guard_pages();
// warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
- if (allocate && !os::commit_memory((char *) low_addr, len)) {
+ if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) {
warning("Attempt to allocate stack guard pages failed.");
return;
}
@@ -2155,7 +2158,7 @@
size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
if (os::allocate_stack_guard_pages()) {
- if (os::uncommit_memory((char *) low_addr, len)) {
+ if (os::remove_stack_guard_pages((char *) low_addr, len)) {
_stack_guard_state = stack_guard_unused;
} else {
warning("Attempt to deallocate stack guard pages failed.");
--- a/hotspot/src/share/vm/runtime/thread.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/thread.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -772,7 +772,7 @@
volatile address _exception_pc; // PC where exception happened
volatile address _exception_handler_pc; // PC for handler of exception
volatile int _exception_stack_size; // Size of frame where exception happened
- volatile int _is_method_handle_exception; // True if the current exception PC is at a MethodHandle call.
+ volatile int _is_method_handle_return; // true (== 1) if the current exception PC is a MethodHandle call site.
// support for compilation
bool _is_compiling; // is true if a compilation is active inthis thread (one compilation per thread possible)
@@ -1108,13 +1108,13 @@
int exception_stack_size() const { return _exception_stack_size; }
address exception_pc() const { return _exception_pc; }
address exception_handler_pc() const { return _exception_handler_pc; }
- int is_method_handle_exception() const { return _is_method_handle_exception; }
+ bool is_method_handle_return() const { return _is_method_handle_return == 1; }
void set_exception_oop(oop o) { _exception_oop = o; }
void set_exception_pc(address a) { _exception_pc = a; }
void set_exception_handler_pc(address a) { _exception_handler_pc = a; }
void set_exception_stack_size(int size) { _exception_stack_size = size; }
- void set_is_method_handle_exception(int value) { _is_method_handle_exception = value; }
+ void set_is_method_handle_return(bool value) { _is_method_handle_return = value ? 1 : 0; }
// Stack overflow support
inline size_t stack_available(address cur_sp);
@@ -1188,7 +1188,7 @@
static ByteSize exception_pc_offset() { return byte_offset_of(JavaThread, _exception_pc ); }
static ByteSize exception_handler_pc_offset() { return byte_offset_of(JavaThread, _exception_handler_pc); }
static ByteSize exception_stack_size_offset() { return byte_offset_of(JavaThread, _exception_stack_size); }
- static ByteSize is_method_handle_exception_offset() { return byte_offset_of(JavaThread, _is_method_handle_exception); }
+ static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); }
static ByteSize stack_guard_state_offset() { return byte_offset_of(JavaThread, _stack_guard_state ); }
static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); }
--- a/hotspot/src/share/vm/runtime/vframeArray.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/vframeArray.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -223,7 +223,7 @@
break;
case Deoptimization::Unpack_exception:
// exception is pending
- pc = SharedRuntime::raw_exception_handler_for_return_address(pc);
+ pc = SharedRuntime::raw_exception_handler_for_return_address(thread, pc);
// [phh] We're going to end up in some handler or other, so it doesn't
// matter what mdp we point to. See exception_handler_for_exception()
// in interpreterRuntime.cpp.
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -25,6 +25,10 @@
# include "incls/_precompiled.incl"
# include "incls/_vmThread.cpp.incl"
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int);
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int);
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__end, char *, uintptr_t, int);
+
// Dummy VM operation to act as first element in our circular double-linked list
class VM_Dummy: public VM_Operation {
VMOp_Type type() const { return VMOp_Dummy; }
@@ -132,6 +136,10 @@
//-----------------------------------------------------------------
// High-level interface
bool VMOperationQueue::add(VM_Operation *op) {
+
+ HS_DTRACE_PROBE3(hotspot, vmops__request, op->name(), strlen(op->name()),
+ op->evaluation_mode());
+
// Encapsulates VM queue policy. Currently, that
// only involves putting them on the right list
if (op->evaluate_at_safepoint()) {
@@ -325,7 +333,11 @@
{
PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
+ HS_DTRACE_PROBE3(hotspot, vmops__begin, op->name(), strlen(op->name()),
+ op->evaluation_mode());
op->evaluate();
+ HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()),
+ op->evaluation_mode());
}
// Last access of info in _cur_vm_operation!
--- a/hotspot/src/share/vm/services/dtraceAttacher.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/services/dtraceAttacher.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -135,4 +135,9 @@
}
}
+void DTrace::set_monitor_dprobes(bool flag) {
+ // explicit setting of DTraceMonitorProbes flag
+ set_bool_flag("DTraceMonitorProbes", flag);
+}
+
#endif /* SOLARIS */
--- a/hotspot/src/share/vm/services/dtraceAttacher.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/services/dtraceAttacher.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -41,4 +41,6 @@
static void detach_all_clients();
// set ExtendedDTraceProbes flag
static void set_extended_dprobes(bool value);
+ // set DTraceMonitorProbes flag
+ static void set_monitor_dprobes(bool value);
};
--- a/hotspot/src/share/vm/services/management.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/services/management.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1537,7 +1537,6 @@
global->type = JMM_VMGLOBAL_TYPE_JSTRING;
} else {
global->type = JMM_VMGLOBAL_TYPE_UNKNOWN;
- assert(false, "Unsupported VMGlobal Type");
return false;
}
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -827,6 +827,8 @@
#define badHeapWord (::badHeapWordVal)
#define badJNIHandle ((oop)::badJNIHandleVal)
+// Default TaskQueue size is 16K (32-bit) or 128K (64-bit)
+#define TASKQUEUE_SIZE (NOT_LP64(1<<14) LP64_ONLY(1<<17))
//----------------------------------------------------------------------------------------------------
// Utility functions for bitfield manipulations
--- a/hotspot/src/share/vm/utilities/ostream.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -363,7 +363,7 @@
return _log_file != NULL;
}
-static const char* make_log_name(const char* log_name, const char* force_directory, char* buf) {
+static const char* make_log_name(const char* log_name, const char* force_directory) {
const char* basename = log_name;
char file_sep = os::file_separator()[0];
const char* cp;
@@ -374,6 +374,27 @@
}
const char* nametail = log_name;
+ // Compute buffer length
+ size_t buffer_length;
+ if (force_directory != NULL) {
+ buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
+ strlen(basename) + 1;
+ } else {
+ buffer_length = strlen(log_name) + 1;
+ }
+
+ const char* star = strchr(basename, '*');
+ int star_pos = (star == NULL) ? -1 : (star - nametail);
+
+ char pid[32];
+ if (star_pos >= 0) {
+ jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id());
+ buffer_length += strlen(pid);
+ }
+
+ // Create big enough buffer.
+ char *buf = NEW_C_HEAP_ARRAY(char, buffer_length);
+
strcpy(buf, "");
if (force_directory != NULL) {
strcat(buf, force_directory);
@@ -381,14 +402,11 @@
nametail = basename; // completely skip directory prefix
}
- const char* star = strchr(basename, '*');
- int star_pos = (star == NULL) ? -1 : (star - nametail);
-
if (star_pos >= 0) {
// convert foo*bar.log to foo123bar.log
int buf_pos = (int) strlen(buf);
strncpy(&buf[buf_pos], nametail, star_pos);
- sprintf(&buf[buf_pos + star_pos], "%u", os::current_process_id());
+ strcpy(&buf[buf_pos + star_pos], pid);
nametail += star_pos + 1; // skip prefix and star
}
@@ -399,20 +417,23 @@
void defaultStream::init_log() {
// %%% Need a MutexLocker?
const char* log_name = LogFile != NULL ? LogFile : "hotspot.log";
- char buf[O_BUFLEN*2];
- const char* try_name = make_log_name(log_name, NULL, buf);
+ const char* try_name = make_log_name(log_name, NULL);
fileStream* file = new(ResourceObj::C_HEAP) fileStream(try_name);
if (!file->is_open()) {
// Try again to open the file.
char warnbuf[O_BUFLEN*2];
- sprintf(warnbuf, "Warning: Cannot open log file: %s\n", try_name);
+ jio_snprintf(warnbuf, sizeof(warnbuf),
+ "Warning: Cannot open log file: %s\n", try_name);
// Note: This feature is for maintainer use only. No need for L10N.
jio_print(warnbuf);
- try_name = make_log_name("hs_pid*.log", os::get_temp_directory(), buf);
- sprintf(warnbuf, "Warning: Forcing option -XX:LogFile=%s\n", try_name);
+ FREE_C_HEAP_ARRAY(char, try_name);
+ try_name = make_log_name("hs_pid*.log", os::get_temp_directory());
+ jio_snprintf(warnbuf, sizeof(warnbuf),
+ "Warning: Forcing option -XX:LogFile=%s\n", try_name);
jio_print(warnbuf);
delete file;
file = new(ResourceObj::C_HEAP) fileStream(try_name);
+ FREE_C_HEAP_ARRAY(char, try_name);
}
if (file->is_open()) {
_log_file = file;
--- a/hotspot/src/share/vm/utilities/taskqueue.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/utilities/taskqueue.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -31,10 +31,6 @@
uint ParallelTaskTerminator::_total_peeks = 0;
#endif
-bool TaskQueueSuper::peek() {
- return _bottom != _age.top();
-}
-
int TaskQueueSetSuper::randomParkAndMiller(int *seed0) {
const int a = 16807;
const int m = 2147483647;
@@ -180,6 +176,13 @@
}
}
+#ifdef ASSERT
+bool ObjArrayTask::is_valid() const {
+ return _obj != NULL && _obj->is_objArray() && _index > 0 &&
+ _index < objArrayOop(_obj)->length();
+}
+#endif // ASSERT
+
bool RegionTaskQueueWithOverflow::is_empty() {
return (_region_queue.size() == 0) &&
(_overflow_stack->length() == 0);
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp Sat Apr 17 08:12:00 2010 -0700
@@ -22,6 +22,7 @@
*
*/
+template <unsigned int N>
class TaskQueueSuper: public CHeapObj {
protected:
// Internal type for indexing the queue; also used for the tag.
@@ -30,10 +31,7 @@
// The first free element after the last one pushed (mod N).
volatile uint _bottom;
- enum {
- N = 1 << NOT_LP64(14) LP64_ONLY(17), // Queue size: 16K or 128K
- MOD_N_MASK = N - 1 // To compute x mod N efficiently.
- };
+ enum { MOD_N_MASK = N - 1 };
class Age {
public:
@@ -84,12 +82,12 @@
// Returns a number in the range [0..N). If the result is "N-1", it should be
// interpreted as 0.
- uint dirty_size(uint bot, uint top) {
+ uint dirty_size(uint bot, uint top) const {
return (bot - top) & MOD_N_MASK;
}
// Returns the size corresponding to the given "bot" and "top".
- uint size(uint bot, uint top) {
+ uint size(uint bot, uint top) const {
uint sz = dirty_size(bot, top);
// Has the queue "wrapped", so that bottom is less than top? There's a
// complicated special case here. A pair of threads could perform pop_local
@@ -111,17 +109,17 @@
public:
TaskQueueSuper() : _bottom(0), _age() {}
- // Return "true" if the TaskQueue contains any tasks.
- bool peek();
+ // Return true if the TaskQueue contains any tasks.
+ bool peek() { return _bottom != _age.top(); }
// Return an estimate of the number of elements in the queue.
// The "careful" version admits the possibility of pop_local/pop_global
// races.
- uint size() {
+ uint size() const {
return size(_bottom, _age.top());
}
- uint dirty_size() {
+ uint dirty_size() const {
return dirty_size(_bottom, _age.top());
}
@@ -132,16 +130,36 @@
// Maximum number of elements allowed in the queue. This is two less
// than the actual queue size, for somewhat complicated reasons.
- uint max_elems() { return N - 2; }
+ uint max_elems() const { return N - 2; }
+
+ // Total size of queue.
+ static const uint total_size() { return N; }
};
-template<class E> class GenericTaskQueue: public TaskQueueSuper {
+template<class E, unsigned int N = TASKQUEUE_SIZE>
+class GenericTaskQueue: public TaskQueueSuper<N> {
+protected:
+ typedef typename TaskQueueSuper<N>::Age Age;
+ typedef typename TaskQueueSuper<N>::idx_t idx_t;
+
+ using TaskQueueSuper<N>::_bottom;
+ using TaskQueueSuper<N>::_age;
+ using TaskQueueSuper<N>::increment_index;
+ using TaskQueueSuper<N>::decrement_index;
+ using TaskQueueSuper<N>::dirty_size;
+
+public:
+ using TaskQueueSuper<N>::max_elems;
+ using TaskQueueSuper<N>::size;
+
private:
// Slow paths for push, pop_local. (pop_global has no fast path.)
bool push_slow(E t, uint dirty_n_elems);
bool pop_local_slow(uint localBot, Age oldAge);
public:
+ typedef E element_type;
+
// Initializes the queue to empty.
GenericTaskQueue();
@@ -172,19 +190,19 @@
volatile E* _elems;
};
-template<class E>
-GenericTaskQueue<E>::GenericTaskQueue():TaskQueueSuper() {
+template<class E, unsigned int N>
+GenericTaskQueue<E, N>::GenericTaskQueue() {
assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
}
-template<class E>
-void GenericTaskQueue<E>::initialize() {
+template<class E, unsigned int N>
+void GenericTaskQueue<E, N>::initialize() {
_elems = NEW_C_HEAP_ARRAY(E, N);
guarantee(_elems != NULL, "Allocation failed.");
}
-template<class E>
-void GenericTaskQueue<E>::oops_do(OopClosure* f) {
+template<class E, unsigned int N>
+void GenericTaskQueue<E, N>::oops_do(OopClosure* f) {
// tty->print_cr("START OopTaskQueue::oops_do");
uint iters = size();
uint index = _bottom;
@@ -200,21 +218,21 @@
// tty->print_cr("END OopTaskQueue::oops_do");
}
-
-template<class E>
-bool GenericTaskQueue<E>::push_slow(E t, uint dirty_n_elems) {
+template<class E, unsigned int N>
+bool GenericTaskQueue<E, N>::push_slow(E t, uint dirty_n_elems) {
if (dirty_n_elems == N - 1) {
// Actually means 0, so do the push.
uint localBot = _bottom;
- _elems[localBot] = t;
+ // g++ complains if the volatile result of the assignment is unused.
+ const_cast<E&>(_elems[localBot] = t);
OrderAccess::release_store(&_bottom, increment_index(localBot));
return true;
}
return false;
}
-template<class E>
-bool GenericTaskQueue<E>::
+template<class E, unsigned int N>
+bool GenericTaskQueue<E, N>::
pop_local_slow(uint localBot, Age oldAge) {
// This queue was observed to contain exactly one element; either this
// thread will claim it, or a competing "pop_global". In either case,
@@ -246,8 +264,8 @@
return false;
}
-template<class E>
-bool GenericTaskQueue<E>::pop_global(E& t) {
+template<class E, unsigned int N>
+bool GenericTaskQueue<E, N>::pop_global(E& t) {
Age oldAge = _age.get();
uint localBot = _bottom;
uint n_elems = size(localBot, oldAge.top());
@@ -255,7 +273,7 @@
return false;
}
- t = _elems[oldAge.top()];
+ const_cast<E&>(t = _elems[oldAge.top()]);
Age newAge(oldAge);
newAge.increment();
Age resAge = _age.cmpxchg(newAge, oldAge);
@@ -266,8 +284,8 @@
return resAge == oldAge;
}
-template<class E>
-GenericTaskQueue<E>::~GenericTaskQueue() {
+template<class E, unsigned int N>
+GenericTaskQueue<E, N>::~GenericTaskQueue() {
FREE_C_HEAP_ARRAY(E, _elems);
}
@@ -280,16 +298,18 @@
virtual bool peek() = 0;
};
-template<class E> class GenericTaskQueueSet: public TaskQueueSetSuper {
+template<class T>
+class GenericTaskQueueSet: public TaskQueueSetSuper {
private:
uint _n;
- GenericTaskQueue<E>** _queues;
+ T** _queues;
public:
+ typedef typename T::element_type E;
+
GenericTaskQueueSet(int n) : _n(n) {
- typedef GenericTaskQueue<E>* GenericTaskQueuePtr;
+ typedef T* GenericTaskQueuePtr;
_queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n);
- guarantee(_queues != NULL, "Allocation failure.");
for (int i = 0; i < n; i++) {
_queues[i] = NULL;
}
@@ -299,9 +319,9 @@
bool steal_best_of_2(uint queue_num, int* seed, E& t);
bool steal_best_of_all(uint queue_num, int* seed, E& t);
- void register_queue(uint i, GenericTaskQueue<E>* q);
+ void register_queue(uint i, T* q);
- GenericTaskQueue<E>* queue(uint n);
+ T* queue(uint n);
// The thread with queue number "queue_num" (and whose random number seed
// is at "seed") is trying to steal a task from some other queue. (It
@@ -313,27 +333,27 @@
bool peek();
};
-template<class E>
-void GenericTaskQueueSet<E>::register_queue(uint i, GenericTaskQueue<E>* q) {
+template<class T> void
+GenericTaskQueueSet<T>::register_queue(uint i, T* q) {
assert(i < _n, "index out of range.");
_queues[i] = q;
}
-template<class E>
-GenericTaskQueue<E>* GenericTaskQueueSet<E>::queue(uint i) {
+template<class T> T*
+GenericTaskQueueSet<T>::queue(uint i) {
return _queues[i];
}
-template<class E>
-bool GenericTaskQueueSet<E>::steal(uint queue_num, int* seed, E& t) {
+template<class T> bool
+GenericTaskQueueSet<T>::steal(uint queue_num, int* seed, E& t) {
for (uint i = 0; i < 2 * _n; i++)
if (steal_best_of_2(queue_num, seed, t))
return true;
return false;
}
-template<class E>
-bool GenericTaskQueueSet<E>::steal_best_of_all(uint queue_num, int* seed, E& t) {
+template<class T> bool
+GenericTaskQueueSet<T>::steal_best_of_all(uint queue_num, int* seed, E& t) {
if (_n > 2) {
int best_k;
uint best_sz = 0;
@@ -356,8 +376,8 @@
}
}
-template<class E>
-bool GenericTaskQueueSet<E>::steal_1_random(uint queue_num, int* seed, E& t) {
+template<class T> bool
+GenericTaskQueueSet<T>::steal_1_random(uint queue_num, int* seed, E& t) {
if (_n > 2) {
uint k = queue_num;
while (k == queue_num) k = randomParkAndMiller(seed) % _n;
@@ -372,8 +392,8 @@
}
}
-template<class E>
-bool GenericTaskQueueSet<E>::steal_best_of_2(uint queue_num, int* seed, E& t) {
+template<class T> bool
+GenericTaskQueueSet<T>::steal_best_of_2(uint queue_num, int* seed, E& t) {
if (_n > 2) {
uint k1 = queue_num;
while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
@@ -394,8 +414,8 @@
}
}
-template<class E>
-bool GenericTaskQueueSet<E>::peek() {
+template<class T>
+bool GenericTaskQueueSet<T>::peek() {
// Try all the queues.
for (uint j = 0; j < _n; j++) {
if (_queues[j]->peek())
@@ -465,14 +485,16 @@
#endif
};
-template<class E> inline bool GenericTaskQueue<E>::push(E t) {
+template<class E, unsigned int N> inline bool
+GenericTaskQueue<E, N>::push(E t) {
uint localBot = _bottom;
assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
idx_t top = _age.top();
uint dirty_n_elems = dirty_size(localBot, top);
- assert((dirty_n_elems >= 0) && (dirty_n_elems < N), "n_elems out of range.");
+ assert(dirty_n_elems < N, "n_elems out of range.");
if (dirty_n_elems < max_elems()) {
- _elems[localBot] = t;
+ // g++ complains if the volatile result of the assignment is unused.
+ const_cast<E&>(_elems[localBot] = t);
OrderAccess::release_store(&_bottom, increment_index(localBot));
return true;
} else {
@@ -480,7 +502,8 @@
}
}
-template<class E> inline bool GenericTaskQueue<E>::pop_local(E& t) {
+template<class E, unsigned int N> inline bool
+GenericTaskQueue<E, N>::pop_local(E& t) {
uint localBot = _bottom;
// This value cannot be N-1. That can only occur as a result of
// the assignment to bottom in this method. If it does, this method
@@ -494,7 +517,7 @@
// This is necessary to prevent any read below from being reordered
// before the store just above.
OrderAccess::fence();
- t = _elems[localBot];
+ const_cast<E&>(t = _elems[localBot]);
// This is a second read of "age"; the "size()" above is the first.
// If there's still at least one element in the queue, based on the
// "_bottom" and "age" we've read, then there can be no interference with
@@ -511,17 +534,23 @@
}
typedef oop Task;
-typedef GenericTaskQueue<Task> OopTaskQueue;
-typedef GenericTaskQueueSet<Task> OopTaskQueueSet;
+typedef GenericTaskQueue<Task> OopTaskQueue;
+typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet;
-
-#define COMPRESSED_OOP_MASK 1
+#ifdef _MSC_VER
+#pragma warning(push)
+// warning C4522: multiple assignment operators specified
+#pragma warning(disable:4522)
+#endif
// This is a container class for either an oop* or a narrowOop*.
// Both are pushed onto a task queue and the consumer will test is_narrow()
// to determine which should be processed.
class StarTask {
void* _holder; // either union oop* or narrowOop*
+
+ enum { COMPRESSED_OOP_MASK = 1 };
+
public:
StarTask(narrowOop* p) {
assert(((uintptr_t)p & COMPRESSED_OOP_MASK) == 0, "Information loss!");
@@ -537,20 +566,61 @@
return (narrowOop*)((uintptr_t)_holder & ~COMPRESSED_OOP_MASK);
}
- // Operators to preserve const/volatile in assignments required by gcc
- void operator=(const volatile StarTask& t) volatile { _holder = t._holder; }
+ StarTask& operator=(const StarTask& t) {
+ _holder = t._holder;
+ return *this;
+ }
+ volatile StarTask& operator=(const volatile StarTask& t) volatile {
+ _holder = t._holder;
+ return *this;
+ }
bool is_narrow() const {
return (((uintptr_t)_holder & COMPRESSED_OOP_MASK) != 0);
}
};
-typedef GenericTaskQueue<StarTask> OopStarTaskQueue;
-typedef GenericTaskQueueSet<StarTask> OopStarTaskQueueSet;
+class ObjArrayTask
+{
+public:
+ ObjArrayTask(oop o = NULL, int idx = 0): _obj(o), _index(idx) { }
+ ObjArrayTask(oop o, size_t idx): _obj(o), _index(int(idx)) {
+ assert(idx <= size_t(max_jint), "too big");
+ }
+ ObjArrayTask(const ObjArrayTask& t): _obj(t._obj), _index(t._index) { }
+
+ ObjArrayTask& operator =(const ObjArrayTask& t) {
+ _obj = t._obj;
+ _index = t._index;
+ return *this;
+ }
+ volatile ObjArrayTask&
+ operator =(const volatile ObjArrayTask& t) volatile {
+ _obj = t._obj;
+ _index = t._index;
+ return *this;
+ }
+
+ inline oop obj() const { return _obj; }
+ inline int index() const { return _index; }
+
+ DEBUG_ONLY(bool is_valid() const); // Tasks to be pushed/popped must be valid.
+
+private:
+ oop _obj;
+ int _index;
+};
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+typedef GenericTaskQueue<StarTask> OopStarTaskQueue;
+typedef GenericTaskQueueSet<OopStarTaskQueue> OopStarTaskQueueSet;
typedef size_t RegionTask; // index for region
-typedef GenericTaskQueue<RegionTask> RegionTaskQueue;
-typedef GenericTaskQueueSet<RegionTask> RegionTaskQueueSet;
+typedef GenericTaskQueue<RegionTask> RegionTaskQueue;
+typedef GenericTaskQueueSet<RegionTaskQueue> RegionTaskQueueSet;
class RegionTaskQueueWithOverflow: public CHeapObj {
protected:
--- a/hotspot/src/share/vm/utilities/vmError.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -807,8 +807,8 @@
if (fd == -1) {
// try temp directory
const char * tmpdir = os::get_temp_directory();
- jio_snprintf(buffer, sizeof(buffer), "%shs_err_pid%u.log",
- (tmpdir ? tmpdir : ""), os::current_process_id());
+ jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log",
+ tmpdir, os::file_separator(), os::current_process_id());
fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6663854/Test6663854.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,1521 @@
+/*
+ * Copyright 2010 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 6663854
+ * @summary assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
+ *
+ * @run main/othervm -Xcomp Test6663854
+ */
+
+// This is a randomly generated test that exposed a crash so don't try
+// to make sense of what's it's doing. The output produced is likely
+// to be stable but it is not being checked as part of this test.
+
+final class Test6663854_Class_0 {
+ final long var_1 = ((byte)1.2510591E38F & - ~ - - - ~3554133935918431232L) << 'g';
+ final static long var_2 = 662144491976981504L;
+ static byte[] var_3;
+ static byte var_4;
+ static float var_5;
+ final short var_6 = 4156;
+ double var_7;
+ char var_8 = 'F';
+ static long var_9;
+ char var_10;
+
+
+ public Test6663854_Class_0()
+ {
+ var_7 = (var_9 = (var_4 = (var_4 = (byte)~ -var_1)));
+ var_7 = (var_4 = (var_4 = (byte)(var_9 = 690685817))) + ~var_2;
+ long var_17 = 1755837857030316032L;
+ var_8 *= (var_7 = var_6);
+ {
+ var_4 = (var_4 = (byte)var_6);
+ }
+ var_5 = (var_4 = (var_4 = (var_4 = (var_4 = (byte)var_17))));
+ if (false)
+ {
+ var_5 = var_6;
+ var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (byte)3.2446162E38F))))));
+ }
+ else
+ {
+ var_8 &= false ? var_6 : var_6;
+ }
+ ((new Test6663854_Class_0[(byte)+ (var_5 = (var_4 = (byte)'Q'))])[var_4 = (byte)396008820]).var_8++;
+ var_5 = (var_8 ^= var_6 >>> - (var_4 = (byte)var_6)) >= 360526660 ? var_8 : var_8;
+ }
+
+
+
+ protected Object clone()
+ {
+ char var_11 = 'E';
+ var_7 = 1.2181972357945285E308 + var_6 - + (var_7 = 1269180234) * 6.244754764669101E307;
+ var_7 = (var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (byte)var_11)))));
+ {
+ var_4 = (var_4 = (var_4 = (byte)1016847968));
+ (false & true ? "nmot" : "m").charAt((false || !true ? var_6 : var_6) * var_6);
+ var_8 |= var_8-- == (long)(var_7 = (byte)var_2 & ~var_2) ? (var_4 = (var_4 = (var_4 = (var_4 = (byte)1.5012703E38F)))) : (var_4 = (byte)4795604615834685440L);
+ ++var_11;
+ var_5 = (var_9 = (int)var_6 | 302324412 - 1720735728);
+ "yfkasl".replaceAll("xlvn" + "peedfph", "awfbuujts");
+ }
+ var_9 = false ? var_6 : var_6;
+ {
+ final boolean var_12 = false;
+ }
+ var_5 = var_2;
+ {
+ var_9 = ((new byte[(byte)var_6][(byte)1.3719104187525612E308])[var_4 = (byte)var_1])[var_4 = (var_4 = (var_4 = (var_4 = (byte)2.2549062E38F)))] + 889886326;
+ }
+ var_9 = (var_2 | ~var_1) & 848602225;
+ {
+ var_4 = (var_4 = (var_4 = (var_4 = (byte)var_6)));
+ }
+ var_7 = var_6;
+ var_9 = var_6;
+ var_5 = (var_4 = (var_4 = (byte)var_8));
+ var_7 = 964691433430251520L ^ var_6;
+ var_5 = ~2571981928559810560L;
+ return "yvetn".endsWith("dtgstxcu".toLowerCase()) | true | true ? (4.2416016638902373E307 != -3.1295498440444366E307 ? "p" : "ars") : (new Object[(byte)var_1])[(byte)(var_9 = 7519039949758987264L)];
+ }
+
+ public boolean equals(Object obj)
+ {
+ var_5 = 1445825238;
+ {
+ var_7 = 2.221982E38F;
+ }
+ {
+ var_9 = var_6;
+ }
+ var_7 = true ? (var_8 ^= (byte)3588201925057082368L) : (var_7 = var_8);
+ short var_13 = var_6;
+ var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (byte)'L'))));
+ var_13--;
+ return true | !false;
+ }
+
+
+ protected char[] func_0()
+ {
+ if (!true ? !false : false)
+ {
+ var_8 %= -(new double[(byte)197311342][(byte)5.6183004E36F])[(byte)(var_5 = (var_9 = 'l'))][(byte)(var_7 = var_6)] * (1.9583867E38F * + (var_4 = (byte)1566742425));
+ var_8 >>= ~6333520277515092992L | var_8;
+ }
+ else
+ {
+ new String();
+ }
+ {
+ var_7 = (byte)5882830303456225280L % ((var_9 = var_6) << var_1);
+ }
+ var_7 = var_6;
+ float var_14;
+ var_14 = (var_4 = (var_4 = (byte)1081376784));
+ var_8 -= 3.1929636E38F;
+ var_7 = 1.5931970715760934E308;
+ var_4 = true | (!false | (var_7 = 2.4773615E37F) < (byte)(short)825088022) ? (var_4 = (byte)4.3114896E37F) : (byte)var_8;
+ final int var_15 = var_6 >> 1197848918;
+ var_9 = var_15;
+ var_14 = 983699379;
+ var_9 = var_6;
+ return (new char[var_4 = (byte)3.593425789671245E307][(byte)1.6242754453980546E308])[var_4 = (byte)(var_9 = (var_4 = (byte)var_1))];
+ }
+
+ final void func_1(final int arg_0)
+ {
+ var_5 = 6370513305314412544L == -5.201821E37F ? 2.5220462E38F : (var_5 = (byte)'f');
+ ((new Test6663854_Class_0[(byte)1250580004024059904L][(byte)(short)var_8])[(byte)(var_8 ^= 68680455462355968L)][var_4 = (var_4 = (byte)var_2)]).var_8 *= (char)(byte)(var_6 * var_6) <= - (var_7 = (var_7 = var_6)) ? ~5194741848806877184L : var_8;
+ var_5 = !"tshhykoap".endsWith("q") ? arg_0 : 'K';
+ var_8 *= (var_8 -= (var_5 = - (var_5 = var_8)));
+ int var_16;
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6663854_Class_0.var_8 = "; result += Test6663854.Printer.print(var_8);
+ result += "\n";
+ result += "Test6663854_Class_0.var_10 = "; result += Test6663854.Printer.print(var_10);
+ result += "\n";
+ result += "Test6663854_Class_0.var_3 = "; result += Test6663854.Printer.print(var_3);
+ result += "\n";
+ result += "Test6663854_Class_0.var_1 = "; result += Test6663854.Printer.print(var_1);
+ result += "\n";
+ result += "Test6663854_Class_0.var_2 = "; result += Test6663854.Printer.print(var_2);
+ result += "\n";
+ result += "Test6663854_Class_0.var_9 = "; result += Test6663854.Printer.print(var_9);
+ result += "\n";
+ result += "Test6663854_Class_0.var_7 = "; result += Test6663854.Printer.print(var_7);
+ result += "\n";
+ result += "Test6663854_Class_0.var_5 = "; result += Test6663854.Printer.print(var_5);
+ result += "\n";
+ result += "Test6663854_Class_0.var_6 = "; result += Test6663854.Printer.print(var_6);
+ result += "\n";
+ result += "Test6663854_Class_0.var_4 = "; result += Test6663854.Printer.print(var_4);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+interface Test6663854_Interface_1 {
+ public boolean func_0();
+ public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3);
+}
+
+
+interface Test6663854_Interface_2 extends Test6663854_Interface_1 {
+}
+
+
+final class Test6663854_Class_3 implements Test6663854_Interface_2, Test6663854_Interface_1 {
+ Object var_18;
+ long var_19;
+ static double var_20;
+ final static float var_21 = 2.0644203E38F;
+ Test6663854_Class_0 var_22;
+ final static byte var_23 = 110;
+ static boolean var_24 = false;
+
+
+ public Test6663854_Class_3()
+ {
+ Test6663854_Class_0.var_5 = new Test6663854_Class_0().var_6;
+ var_22 = (var_22 = (new Test6663854_Class_0[var_23])[var_23]);
+ Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23));
+ char var_37;
+ var_19 = var_23;
+ }
+
+
+ public boolean func_0()
+ {
+ if (var_24 = var_24)
+ {
+ Test6663854_Class_0.var_4 = var_24 ^ (var_24 || (var_24 = false)) ? var_23 : (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23));
+ }
+ else
+ {
+ ((Test6663854_Class_0)(var_18 = new Test6663854_Interface_1[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23)][var_23])).var_7 = ((var_22 = (var_22 = (Test6663854_Class_0)(var_18 = "uwt"))).var_8 >>>= (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23)));
+ var_24 |= !false;
+ }
+ var_18 = (var_18 = "ymmk");
+ if (var_24)
+ {
+ long var_25;
+ ((Test6663854_Class_0)(var_18 = "wsxqujs")).var_8 >>= 'F';
+ var_24 ^= false;
+ }
+ else
+ {
+ {
+ (var_22 = (Test6663854_Class_0)(var_18 = (var_18 = (var_18 = "lrgiwpwet")))).var_8++;
+ }
+ {
+ var_18 = new String[Test6663854_Class_0.var_4 = var_23];
+ }
+ {
+ new String();
+ }
+ ((var_24 |= var_24) | true ^ false ? (var_22 = (Test6663854_Class_0)(var_18 = "rpmudju")) : (var_22 = (new Test6663854_Class_0[var_23])[var_23])).var_8--;
+ var_24 ^= var_24;
+ var_19 = 206416809;
+ var_20 = 1581809112;
+ Test6663854_Class_0 var_26;
+ Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23);
+ }
+ byte var_27 = 29;
+ short var_28 = 24653;
+ var_22 = (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = "umagt")));
+ return var_24;
+ }
+
+ public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+ {
+ {
+ final Test6663854_Class_0 var_29 = (new Test6663854_Class_0[var_23])[arg_2];
+ }
+ var_18 = (var_18 = (var_22 = (Test6663854_Class_0)(var_18 = arg_0)));
+ ++(var_22 = (Test6663854_Class_0)(var_18 = (Test6663854_Class_0)(var_18 = (var_18 = new char[var_23])))).var_8;
+ {
+ (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = "xcj"))).var_8 |= arg_1 * (short)6.671469496987355E307;
+ Test6663854_Class_0.var_5 = false ? var_23 : 8012291795221583872L;
+ (var_24 ? (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = arg_0))) : (var_22 = (Test6663854_Class_0)(var_18 = arg_3))).var_8--;
+ }
+ ((new String[var_23][var_23])[var_23][var_23]).compareTo(arg_0);
+ var_18 = (var_18 = arg_0);
+ var_24 &= (var_24 ^= true) & ! !false;
+ {
+ var_18 = "lok";
+ }
+ float var_30 = 2.0346904E38F;
+ var_30 += ((Test6663854_Class_0)(var_18 = new float[var_23])).var_6 + 210775691;
+ final double var_31 = 8.865908414454469E307;
+ var_20 = 'm';
+ var_22 = (Test6663854_Class_0)(var_18 = arg_0);
+ return arg_0;
+ }
+
+
+ protected Object clone()
+ {
+ ((Test6663854_Class_0)(var_18 = new short[var_23])).var_7 = 'M';
+ if (var_24)
+ {
+ var_24 = false;
+ String var_32 = "luigad";
+ ((Test6663854_Class_0.var_5 = 1.2920056E38F) > (Test6663854_Class_0.var_4 = var_23) ? (Test6663854_Class_0)(var_18 = new Test6663854_Interface_1[var_23][var_23]) : (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = new byte[var_23])))).var_10 = 'A';
+ (var_22 = (var_22 = (var_22 = (new Test6663854_Class_0[var_23][var_23])[var_23][var_23]))).var_8 /= ((var_22 = (Test6663854_Class_0)(var_18 = (new short[var_23][var_23][var_23])[var_23])).var_7 = 'h');
+ (var_32 = var_32).toString();
+ var_32.length();
+ var_18 = (var_22 = (var_22 = new Test6663854_Class_0()));
+ }
+ else
+ {
+ Test6663854_Class_0.var_4 = var_23;
+ var_22 = (var_22 = (Test6663854_Class_0)(var_18 = "wbeuae"));
+ float var_33;
+ --(var_22 = (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = (var_18 = "irl"))))).var_8;
+ }
+ Test6663854_Class_0.var_4 = var_23;
+ Test6663854_Class_0.var_5 = true ? ((Test6663854_Class_0)(var_18 = (var_18 = new boolean[Test6663854_Class_0.var_4 = var_23]))).var_8 : 'n';
+ var_24 = (var_24 ^= ((var_22 = (Test6663854_Class_0)(var_18 = "g")).var_6 > ((Test6663854_Class_0)(var_18 = "")).var_6 ? var_24 : true) ? false : (var_24 = var_24)) ? var_24 : false;
+ var_22 = (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = new Test6663854_Interface_2[var_23])));
+ return var_18 = "qrlonljqj";
+ }
+
+ public boolean equals(Object obj)
+ {
+ Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23)));
+ Test6663854_Class_0.var_5 = var_23 % (var_22 = (var_22 = (Test6663854_Class_0)obj)).var_6;
+ Test6663854_Class_0.var_5 = (((new Test6663854_Class_0[var_23][var_23][var_23])[var_23])[var_24 | (var_24 &= var_24) ? var_23 : (Test6663854_Class_0.var_4 = var_23)][var_23]).var_8;
+ var_22 = false ? (var_22 = (var_22 = (Test6663854_Class_0)obj)) : (var_22 = new Test6663854_Class_0());
+ Test6663854_Class_0.var_5 = ((new Test6663854_Class_0[var_23])[Test6663854_Class_0.var_4 = var_23]).var_8;
+ if (! !var_24)
+ {
+ var_18 = "";
+ (var_22 = (var_22 = (var_22 = (new Test6663854_Class_0[var_23])[Test6663854_Class_0.var_4 = var_23]))).var_8 >>= true ? ~ (Test6663854_Class_0.var_4 = var_23) : (var_22 = (Test6663854_Class_0)obj).var_8++;
+ (var_24 ? (Test6663854_Class_0)(var_18 = "") : (Test6663854_Class_0)obj).var_8 <<= var_23;
+ Test6663854_Class_0.var_4 = var_23;
+ var_20 = (var_22 = (var_22 = (var_22 = (var_22 = (Test6663854_Class_0)obj)))).var_8;
+ }
+ else
+ {
+ var_19 = ((Test6663854_Class_0)obj).var_6;
+ }
+ (var_24 ? "qyukxpui" : (new String[var_23])[Test6663854_Class_0.var_4 = var_23]).substring(612084215);
+ Test6663854_Class_0.var_5 = 'B';
+ if (!false || false)
+ {
+ Test6663854_Class_0.var_4 = true & var_24 ? var_23 : var_23;
+ }
+ else
+ {
+ "eksoig".lastIndexOf('b' > (var_22 = (Test6663854_Class_0)obj).var_8 | 4782397447545636864L >= (short)'[' ? "qusgbf" : "kvmylvct");
+ }
+ Test6663854_Class_0.var_5 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23)) << var_23;
+ int var_34;
+ var_24 = (var_24 &= (var_24 &= true));
+ var_22 = (var_22 = (var_22 = (var_22 = (Test6663854_Class_0)obj)));
+ Test6663854_Interface_1 var_35 = var_24 & ((var_24 &= var_24) ^ var_24) ? (new Test6663854_Interface_1[var_23])[var_23] : (new Test6663854_Interface_1[var_23][var_23])[var_23][var_23];
+ long var_36 = 1042482863045573632L;
+ return var_24;
+ }
+
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6663854_Class_3.var_19 = "; result += Test6663854.Printer.print(var_19);
+ result += "\n";
+ result += "Test6663854_Class_3.var_20 = "; result += Test6663854.Printer.print(var_20);
+ result += "\n";
+ result += "Test6663854_Class_3.var_21 = "; result += Test6663854.Printer.print(var_21);
+ result += "\n";
+ result += "Test6663854_Class_3.var_23 = "; result += Test6663854.Printer.print(var_23);
+ result += "\n";
+ result += "Test6663854_Class_3.var_24 = "; result += Test6663854.Printer.print(var_24);
+ result += "\n";
+ result += "Test6663854_Class_3.var_22 = "; result += Test6663854.Printer.print(var_22);
+ result += "\n";
+ result += "Test6663854_Class_3.var_18 = "; result += Test6663854.Printer.print(var_18);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Test6663854_Class_4 implements Test6663854_Interface_1, Test6663854_Interface_2 {
+ long var_38 = (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_23 < (short)+3417996718812544000L) ? ~543562136204028928L : 1593726438;
+ char var_39;
+ static Test6663854_Interface_2 var_40;
+ Test6663854_Class_3 var_41;
+ final short var_42 = false ? Test6663854_Class_3.var_23 : (short)~Test6663854_Class_0.var_2;
+ byte var_43;
+ static Test6663854_Interface_1[] var_44;
+ final char var_45 = 4.321821176880639E307 < var_42 ? 'o' : 'v';
+
+
+ public Test6663854_Class_4()
+ {
+ Test6663854_Class_0.var_5 = 2137855185;
+ "nueqthqo".length();
+ {
+ Test6663854_Class_0.var_9 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23));
+ Object var_61;
+ }
+ String var_62 = "rirgfphe";
+ ((new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_22 = ((var_41 = (var_41 = new Test6663854_Class_3())).var_22 = new Test6663854_Class_0());
+ {
+ Test6663854_Class_0.var_5 = ((new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_42;
+ new Test6663854_Class_0();
+ var_41 = (var_41 = new Test6663854_Class_3());
+ new Test6663854_Class_0().var_8 %= var_38;
+ (var_41 = ((new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = new Test6663854_Class_0();
+ Test6663854_Class_0.var_4 = (Test6663854_Class_3.var_24 |= true) ? (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) : Test6663854_Class_3.var_23;
+ Test6663854_Interface_1 var_63 = ((new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[var_43 = (var_43 = Test6663854_Class_3.var_23)])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23];
+ (var_41 = (var_41 = (var_41 = (var_41 = (Test6663854_Class_3)var_63)))).var_18 = var_62;
+ }
+ if (Test6663854_Class_3.var_24 ^= false)
+ {
+ var_40 = (var_40 = new Test6663854_Class_3());
+ }
+ else
+ {
+ var_62 = "agwqc";
+ Test6663854_Class_3.var_24 ^= ((Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24 && Test6663854_Class_3.var_24) & false ? false : !Test6663854_Class_3.var_24) ? false | (Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24) : (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 |= ! (Test6663854_Class_3.var_24 |= true)));
+ var_38 *= (Test6663854_Class_3.var_20 = (Test6663854_Class_0.var_5 = var_42 + ((Test6663854_Class_3.var_20 = 5378782303770527744L) <= var_42 ? var_42 : var_42)));
+ }
+ var_38 &= ((var_41 = new Test6663854_Class_3()).var_22 = new Test6663854_Class_0()).var_6;
+ var_62 = var_62;
+ (var_41 = new Test6663854_Class_3()).var_18 = ((new Object[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (var_43 = Test6663854_Class_3.var_23))];
+ final short var_64 = (short)'C';
+ ((var_41 = new Test6663854_Class_3()).var_22 = new Test6663854_Class_0()).var_8 /= ((var_41 = new Test6663854_Class_3()).var_22 = new Test6663854_Class_0()).var_6;
+ }
+
+
+ public boolean func_0()
+ {
+ final boolean var_46 = false;
+ return Test6663854_Class_3.var_24;
+ }
+
+ public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+ {
+ {
+ --(false ? new Test6663854_Class_0() : new Test6663854_Class_0()).var_8;
+ "d".substring(Test6663854_Class_3.var_23 - (arg_2 /= + (Test6663854_Class_3.var_20 = 1483190006) * (Test6663854_Class_3.var_20 = ~Test6663854_Class_3.var_23)), 496015226);
+ {
+ var_41 = new Test6663854_Class_3();
+ }
+ var_38 ^= (! ((Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) && (new boolean[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]) ? arg_1 : (var_39 = var_45)) / var_45;
+ var_38 -= (Test6663854_Class_3.var_20 = (new short[Test6663854_Class_3.var_23])[arg_2]) != (arg_2 ^= new Test6663854_Class_0().var_6 & - (var_38 /= (Test6663854_Class_0.var_5 = var_38))) ? (Test6663854_Class_0.var_5 = - -Test6663854_Class_3.var_21) : arg_2;
+ var_41 = new Test6663854_Class_3();
+ var_40 = Test6663854_Class_3.var_24 ? new Test6663854_Class_3() : new Test6663854_Class_3();
+ }
+ int var_47;
+ (var_41 = new Test6663854_Class_3()).var_18 = "qvph";
+ {
+ ++arg_2;
+ }
+ final Test6663854_Class_3 var_48 = new Test6663854_Class_3();
+ {
+ var_48.var_22 = (Test6663854_Class_0)((var_41 = var_48).var_18 = (var_48.var_22 = (Test6663854_Class_0)(var_48.var_18 = new String[Test6663854_Class_3.var_23])));
+ {
+ final float[] var_49 = (new float[Test6663854_Class_3.var_23][arg_2])[arg_2];
+ }
+ "lcfxrlilw".replace(var_45, (char)(false ? (short)2998890687978943488L : var_42));
+ arg_0.lastIndexOf("mx");
+ final Test6663854_Class_0 var_50 = var_48.var_22 = (var_48.var_22 = (Test6663854_Class_0)((var_41 = var_48).var_18 = var_48));
+ new String();
+ ((Test6663854_Class_3)(var_40 = (var_40 = (var_41 = var_48)))).var_22 = var_50;
+ var_50.var_8 |= arg_2;
+ Test6663854_Class_3.var_20 = + - (Test6663854_Class_3.var_20 = var_42) - var_45 * Test6663854_Class_3.var_21;
+ double var_51 = false ? 1.6389923323715952E308 : (var_39 = var_45);
+ (((new Test6663854_Class_3[arg_2][arg_2])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_18 = (var_48.var_18 = new Test6663854_Class_0[arg_2 %= 2090054678][arg_2]);
+ }
+ {
+ var_47 = (arg_2 |= (((new Test6663854_Class_4[arg_2][arg_2][arg_2])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_42);
+ }
+ ((new Test6663854_Class_4[arg_2][Test6663854_Class_3.var_23])[++arg_2][arg_2 <<= 'c']).var_41 = var_48;
+ var_41 = var_48;
+ Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24 & Test6663854_Class_3.var_24;
+ final boolean var_52 = false;
+ {
+ var_40 = (var_41 = (var_41 = var_48));
+ (false ? var_48 : var_48).var_18 = ((new Test6663854_Class_0[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][arg_2])[arg_2])[++arg_2][(byte)203097731];
+ var_41 = (var_41 = var_48);
+ }
+ var_38 |= (short)Test6663854_Class_3.var_23;
+ var_40 = var_48;
+ {
+ arg_0.indexOf("lnf", var_47 = (((Test6663854_Class_0)(var_48.var_18 = arg_0)).var_8 <<= (var_39 = var_45)));
+ }
+ final boolean var_53 = true & 1.4130067467800934E308 < (arg_2 |= 'W');
+ var_48.var_18 = (var_41 = var_48);
+ (var_48.var_22 = new Test6663854_Class_0()).var_7 = Test6663854_Class_3.var_23;
+ Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 || var_52) ^ ("axg".startsWith(arg_0, var_47 = (var_47 = var_45)) | var_52);
+ {
+ Test6663854_Class_0.var_5 = 275192701;
+ }
+ Test6663854_Interface_2 var_54;
+ if (true)
+ {
+ var_54 = (var_41 = (var_41 = (var_41 = var_48)));
+ }
+ else
+ {
+ ((Test6663854_Class_0)((var_41 = var_48).var_18 = (var_41 = var_48))).var_7 = var_42;
+ }
+ Test6663854_Class_0.var_5 = --arg_2;
+ ((new String[Test6663854_Class_3.var_23])[var_53 ? arg_2 : arg_2]).length();
+ return arg_0 + "qj";
+ }
+
+
+
+
+ final String func_0(byte arg_0, Test6663854_Class_0 arg_1, final Test6663854_Class_0 arg_2, final Object arg_3)
+ {
+ arg_2.var_7 = (new long[arg_0][arg_0])[Test6663854_Class_3.var_23][arg_0 >>>= 1960882886] % arg_0;
+ Object var_55 = (((new Test6663854_Class_4[Test6663854_Class_3.var_23])[--arg_0]).var_41 = new Test6663854_Class_3()).var_18 = (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24 ? (Test6663854_Class_3.var_24 |= (Test6663854_Class_3.var_24 &= true)) : Test6663854_Class_3.var_24 | Test6663854_Class_3.var_24) ? (var_41 = (var_41 = (Test6663854_Class_3)arg_3)) : arg_3;
+ var_38 >>= ((Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24)) | (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24) ? arg_2.var_6 : (arg_0 -= 1.2264686416488313E308)) != (((new Test6663854_Class_4[arg_0])[arg_0]).var_38 >>>= arg_2.var_8) ? Test6663854_Class_3.var_23 : arg_0;
+ arg_0 += 1826349110 / (Test6663854_Class_0.var_5 = arg_0) + Test6663854_Class_3.var_21;
+ (var_41 = !Test6663854_Class_3.var_24 ? (var_41 = (new Test6663854_Class_3[arg_0])[arg_0]) : (new Test6663854_Class_3[--arg_0])[arg_0]).var_22 = ((new Test6663854_Class_0[arg_0][(byte)9.18575257519393E307][Test6663854_Class_3.var_23])[arg_0])[Test6663854_Class_3.var_23][arg_0];
+ (var_41 = new Test6663854_Class_3()).var_22 = ((var_41 = (var_41 = (var_41 = (var_41 = (var_41 = (Test6663854_Class_3)arg_3))))).var_22 = (arg_1 = arg_2));
+ Test6663854_Class_3.var_20 = Test6663854_Class_3.var_21;
+ var_40 = (var_41 = (Test6663854_Class_3)(new Test6663854_Interface_2[Test6663854_Class_3.var_23])[arg_0]);
+ Test6663854_Class_0.var_5 = Test6663854_Class_3.var_24 || (Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 &= true)) ? var_42 : arg_1.var_6;
+ Test6663854_Class_0.var_5 = arg_0;
+ {
+ arg_0 %= (short)var_45;
+ }
+ var_55 = arg_1;
+ var_40 = (var_41 = (Test6663854_Class_3.var_24 = false) ? (Test6663854_Class_3)var_55 : (Test6663854_Class_3)arg_3);
+ ((Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_20 = arg_0) == 2.2107098E38F) ? (Test6663854_Class_3)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[arg_0] : (Test6663854_Class_3)(var_55 = "unofratwy")).var_18 = var_55;
+ return "";
+ }
+
+ private static String func_1(final String arg_0, char arg_1, final boolean arg_2, Test6663854_Class_3 arg_3)
+ {
+ if (!false & Test6663854_Class_3.var_24)
+ {
+ char var_56 = 'C';
+ }
+ else
+ {
+ var_40 = (var_40 = (var_40 = arg_3));
+ }
+ ((new Test6663854_Class_0[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_7 = 2.4396145E38F + (((new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][(byte)Test6663854_Class_0.var_2]).var_43 = Test6663854_Class_3.var_23);
+ if (Test6663854_Class_3.var_24)
+ {
+ arg_3 = arg_3;
+ }
+ else
+ {
+ arg_3 = (arg_3 = arg_3);
+ }
+ ((new Test6663854_Class_4[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_38 /= '`';
+ arg_3 = (arg_3 = arg_3);
+ new Test6663854_Class_0().var_8++;
+ return "qd";
+ }
+
+ private Object func_2(short[][] arg_0, final Test6663854_Interface_2 arg_1)
+ {
+ boolean var_57 = false;
+ Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+ var_40 = arg_1;
+ ((var_41 = (var_41 = (var_41 = (Test6663854_Class_3)arg_1))).var_22 = (Test6663854_Class_0)(((Test6663854_Class_3)arg_1).var_18 = "dxrwk")).var_7 = 'c';
+ if (true)
+ {
+ var_40 = (var_40 = arg_1);
+ }
+ else
+ {
+ var_39 = 'Z';
+ }
+ Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+ var_41 = (Test6663854_Class_3)arg_1;
+ return (var_57 ? (Test6663854_Class_3.var_20 = Test6663854_Class_3.var_23) % 1271549437 : 1.1177259470512304E308) <= 1363316667 ? (new Test6663854_Class_3().var_18 = new String[var_43 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]) : new Test6663854_Class_0();
+ }
+
+ private short func_3()
+ {
+ int var_58 = true ? var_42 : 1438975079;
+ float var_59 = Test6663854_Class_3.var_21;
+ var_43 = Test6663854_Class_3.var_23;
+ (var_41 = (Test6663854_Class_3)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24) ? new Test6663854_Class_0() : new Test6663854_Class_0();
+ var_58++;
+ return Test6663854_Class_3.var_24 ? var_42 : (var_43 = Test6663854_Class_3.var_23);
+ }
+
+ protected void func_4(final long arg_0, Test6663854_Class_0 arg_1, long arg_2)
+ {
+ ++arg_2;
+ (arg_1 = (arg_1 = (arg_1 = arg_1))).var_8 /= var_42;
+ --arg_2;
+ final Test6663854_Interface_1 var_60 = ((new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[var_43 = Test6663854_Class_3.var_23])[var_43 = Test6663854_Class_3.var_23];
+ (true ? (Test6663854_Class_3)var_60 : (Test6663854_Class_3)var_60).var_22 = (Test6663854_Class_0)((var_41 = (Test6663854_Class_3)(var_40 = (Test6663854_Class_3)var_60)).var_18 = (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_23 == var_38) ? "xo" : "uocm");
+ var_38 >>= (((Test6663854_Class_3)(new Test6663854_Interface_2[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = (new Test6663854_Class_0[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)]).var_8++;
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6663854_Class_4.var_39 = "; result += Test6663854.Printer.print(var_39);
+ result += "\n";
+ result += "Test6663854_Class_4.var_45 = "; result += Test6663854.Printer.print(var_45);
+ result += "\n";
+ result += "Test6663854_Class_4.var_44 = "; result += Test6663854.Printer.print(var_44);
+ result += "\n";
+ result += "Test6663854_Class_4.var_38 = "; result += Test6663854.Printer.print(var_38);
+ result += "\n";
+ result += "Test6663854_Class_4.var_40 = "; result += Test6663854.Printer.print(var_40);
+ result += "\n";
+ result += "Test6663854_Class_4.var_42 = "; result += Test6663854.Printer.print(var_42);
+ result += "\n";
+ result += "Test6663854_Class_4.var_43 = "; result += Test6663854.Printer.print(var_43);
+ result += "\n";
+ result += "Test6663854_Class_4.var_41 = "; result += Test6663854.Printer.print(var_41);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+class Test6663854_Class_5 implements Test6663854_Interface_1 {
+ final static char var_65 = 'S';
+ static Test6663854_Interface_2 var_66;
+ static Test6663854_Class_3 var_67;
+
+
+ public Test6663854_Class_5()
+ {
+ {
+ ((new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)])[((Test6663854_Class_4)(new Object[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_43 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).func_0();
+ }
+ Test6663854_Class_0.var_5 = 1409421143;
+ Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 = false);
+ Test6663854_Class_0.var_5 = 3.1496384E38F / (((new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_45 - (Test6663854_Class_3.var_23 + Test6663854_Class_3.var_23));
+ ((new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_18 = (new Object[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+ var_66 = (Test6663854_Class_4.var_40 = (Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24)) || false ? new Test6663854_Class_3() : new Test6663854_Class_3());
+ }
+
+
+ public boolean func_0()
+ {
+ {
+ Test6663854_Class_4.var_40 = (new Test6663854_Class_4[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23];
+ }
+ Test6663854_Class_0.var_5 = (new char[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+ var_66 = (Test6663854_Class_4.var_40 = new Test6663854_Class_3());
+ Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+ ((var_67 = (var_67 = new Test6663854_Class_3())).var_22 = (Test6663854_Class_0)(new Test6663854_Class_3().var_18 = (new Test6663854_Class_3().var_22 = (new Test6663854_Class_3().var_22 = new Test6663854_Class_0())))).var_8++;
+ Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+ return (Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24) ? (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) : (Test6663854_Class_3.var_24 = true);
+ }
+
+ public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+ {
+ ((true | (Test6663854_Class_3.var_24 |= true)) ^ false ? (new Test6663854_Class_0[(byte)arg_1])[arg_2--] : new Test6663854_Class_0()).var_8 <<= 2320675830599883776L;
+ arg_2 -= ~ (Test6663854_Class_3.var_24 ? ~4954934861909065728L : 5155213238651986944L);
+ ((Test6663854_Class_4)((new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[arg_2 >>>= 1308733456])[Test6663854_Class_3.var_23]).var_43 = arg_2;
+ Test6663854_Class_0.var_5 = Test6663854_Class_3.var_21;
+ {
+ String var_68;
+ float var_69 = Test6663854_Class_3.var_21 * new Test6663854_Class_0().var_6;
+ ++arg_2;
+ Test6663854_Class_0.var_9 = arg_2;
+ --arg_2;
+ var_68 = arg_0;
+ final long[] var_70 = new long[arg_2 /= 8889610108908524544L];
+ Test6663854_Class_4 var_71;
+ }
+ new Test6663854_Class_4().var_38++;
+ Test6663854_Class_3 var_72;
+ (((new Test6663854_Class_4[arg_2 *= var_65][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[arg_2])[arg_2 ^= arg_2][Test6663854_Class_3.var_23]).var_38--;
+ new Test6663854_Class_3();
+ (((new Test6663854_Class_4[arg_2 /= 7.692983E37F][Test6663854_Class_3.var_23])[arg_2])[Test6663854_Class_3.var_23]).var_38 |= arg_1;
+ Test6663854_Class_3.var_24 ^= "dlhn".startsWith(true ? "tad" : "bssdfvig", 1125165775) ? Test6663854_Class_3.var_24 : true;
+ Test6663854_Class_3.var_20 = new Test6663854_Class_0().var_8;
+ Test6663854_Class_4.var_40 = (Test6663854_Class_4.var_40 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]);
+ var_72 = (new Test6663854_Class_3[Test6663854_Class_3.var_23][arg_2])[arg_2][arg_2];
+ Test6663854_Class_0.var_5 = 8634870161778523136L;
+ {
+ Test6663854_Class_0.var_5 = ~4420139622226571264L;
+ Test6663854_Class_3.var_24 &= (var_72 = (var_67 = (new Test6663854_Class_3[arg_2][Test6663854_Class_3.var_23])[arg_2][arg_2])).func_0();
+ arg_2 >>= false ? 'H' : ']';
+ }
+ switch (arg_2)
+ {
+ case 72:
+ String var_73 = arg_0;
+ break;
+
+ default:
+
+ }
+ ((Test6663854_Class_0)((var_72 = (Test6663854_Class_3)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[arg_2]).var_18 = (Test6663854_Class_4)(new Test6663854_Interface_2[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])).var_7 = ((new Test6663854_Class_0[arg_2])[arg_2]).var_6 + Test6663854_Class_3.var_23;
+ var_67 = (var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[(byte)7.184837949183326E307][arg_2 ^= 2188582676874919936L]);
+ return ((Test6663854_Class_3.var_24 = new Test6663854_Class_0().var_6 >= (short)3.4944631475014644E307) ? Test6663854_Class_3.var_24 : (Test6663854_Class_3.var_24 ? (Test6663854_Class_3.var_24 = false) : !Test6663854_Class_3.var_24)) ? "y" : arg_0;
+ }
+
+
+
+
+ private final static float func_0(boolean arg_0)
+ {
+ {
+ new String();
+ {
+ new String();
+ }
+ ((Test6663854_Class_3)(new Object[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[(new byte[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_18 = (new Object[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[(byte)1.577204008065932E308][Test6663854_Class_3.var_23];
+ int var_74;
+ new String();
+ Test6663854_Class_0.var_5 = ((Test6663854_Class_0)(new Object[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_1;
+ new String();
+ new String();
+ new String();
+ var_74 = '_';
+ new Test6663854_Class_0();
+ Test6663854_Class_3 var_75 = var_67 = (((new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_41 = (new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]);
+ }
+ if (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24))
+ {
+ new String();
+ arg_0 &= ~ (((new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_38 /= Test6663854_Class_3.var_23) < 2.1129417E38F;
+ }
+ else
+ {
+ Test6663854_Class_3.var_24 &= false & arg_0 ? false : (Test6663854_Class_3.var_24 &= true);
+ }
+ new Test6663854_Class_0().var_8 ^= 682270015;
+ Test6663854_Class_4.var_40 = (Test6663854_Class_4)(new Test6663854_Interface_2[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+ new Test6663854_Class_0();
+ new String();
+ new Test6663854_Class_0();
+ new Test6663854_Class_3().var_22 = new Test6663854_Class_0();
+ Test6663854_Class_4.var_40 = (new Test6663854_Class_4[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23];
+ new Test6663854_Class_0().var_8++;
+ new Test6663854_Class_0();
+ Test6663854_Interface_1 var_76;
+ return Test6663854_Class_3.var_21;
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6663854_Class_5.var_65 = "; result += Test6663854.Printer.print(var_65);
+ result += "\n";
+ result += "Test6663854_Class_5.var_66 = "; result += Test6663854.Printer.print(var_66);
+ result += "\n";
+ result += "Test6663854_Class_5.var_67 = "; result += Test6663854.Printer.print(var_67);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+class Test6663854_Class_6 implements Test6663854_Interface_1, Test6663854_Interface_2 {
+ static long var_77;
+ final byte var_78 = Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+ long var_79;
+ static Test6663854_Class_4 var_80;
+ static long var_81 = 1365276905537306624L;
+ static Test6663854_Class_3 var_82;
+
+
+ public Test6663854_Class_6()
+ {
+ Test6663854_Class_0.var_5 = Test6663854_Class_3.var_24 ? "bdouannkn".charAt(373674594) : (char)2612074035904901120L;
+ if (Test6663854_Class_3.var_24)
+ {
+ ++var_81;
+ Test6663854_Class_0.var_4 = (new byte[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)])[var_78];
+ var_81++;
+ }
+ else
+ {
+ (var_80 = (Test6663854_Class_4)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = var_78]).var_41 = (((Test6663854_Class_4)(new Object[Test6663854_Class_3.var_23])[var_78]).var_41 = new Test6663854_Class_3());
+ var_81--;
+ ((new Test6663854_Class_0[var_78])[var_78]).equals((Test6663854_Class_5.var_67 = (Test6663854_Class_3)(new Test6663854_Interface_2[var_78])[var_78]).var_18 = Test6663854_Class_3.var_23 <= var_78 ? "uvoxke" : new String());
+ {
+ Test6663854_Class_5.var_66 = (new Test6663854_Interface_2[var_78])[((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78];
+ }
+ "huxqcdmii".compareTo("owtdmma");
+ Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)));
+ var_81--;
+ }
+ {
+ Test6663854_Class_5[][] var_85;
+ }
+ Test6663854_Class_5.var_66 = (new Test6663854_Interface_2[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+ if (Test6663854_Class_3.var_24 || Test6663854_Class_3.var_24)
+ {
+ var_82 = (new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[var_78][Test6663854_Class_3.var_23];
+ Test6663854_Class_0.var_5 = ++var_81;
+ Test6663854_Class_0.var_5 = Test6663854_Class_3.var_24 ? 'n' : Test6663854_Class_5.var_65;
+ }
+ else
+ {
+ new Test6663854_Class_0();
+ }
+ Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23);
+ Test6663854_Class_5.var_66 = new Test6663854_Class_3();
+ Test6663854_Class_3 var_86 = (var_80 = (var_80 = (var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]))).var_41 = (var_82 = (Test6663854_Class_5.var_67 = ((new Test6663854_Class_3[Test6663854_Class_3.var_23][var_78][Test6663854_Class_3.var_23])[var_78])[var_78][Test6663854_Class_3.var_23]));
+ Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) ? (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) : (Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24);
+ var_86.var_22 = (new Test6663854_Class_0[var_78][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][var_78];
+ (Test6663854_Class_3.var_24 ? "evayayw" : "ndcq").startsWith("hwlik" + "tnhfsky");
+ var_86 = var_86;
+ }
+
+
+ public boolean func_0()
+ {
+ Test6663854_Class_4.var_40 = (Test6663854_Class_5.var_67 = (new Test6663854_Class_3[var_78])[Test6663854_Class_3.var_23]);
+ return Test6663854_Class_0.var_2 != (((new Test6663854_Class_0[var_78])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_7 = Test6663854_Class_3.var_23);
+ }
+
+ public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+ {
+ Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24;
+ Test6663854_Class_0.var_5 = var_78;
+ char var_83;
+ (Test6663854_Class_5.var_67 = (Test6663854_Class_5.var_67 = (Test6663854_Class_3)(new Test6663854_Interface_1[var_78])[Test6663854_Class_3.var_23])).var_18 = new Test6663854_Class_0[arg_2];
+ Test6663854_Class_4 var_84;
+ var_81++;
+ return arg_0;
+ }
+
+
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6663854_Class_6.var_77 = "; result += Test6663854.Printer.print(var_77);
+ result += "\n";
+ result += "Test6663854_Class_6.var_79 = "; result += Test6663854.Printer.print(var_79);
+ result += "\n";
+ result += "Test6663854_Class_6.var_81 = "; result += Test6663854.Printer.print(var_81);
+ result += "\n";
+ result += "Test6663854_Class_6.var_78 = "; result += Test6663854.Printer.print(var_78);
+ result += "\n";
+ result += "Test6663854_Class_6.var_80 = "; result += Test6663854.Printer.print(var_80);
+ result += "\n";
+ result += "Test6663854_Class_6.var_82 = "; result += Test6663854.Printer.print(var_82);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Test6663854_Class_7 extends Test6663854_Class_5 implements Test6663854_Interface_2 {
+ final float var_87 = 1.1671899E38F;
+ static char var_88 = var_65;
+ float var_89 = 2.166908E37F;
+
+
+ public Test6663854_Class_7()
+ {
+ var_88--;
+ (Test6663854_Class_5.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).equals(((Test6663854_Class_3)(Test6663854_Class_4.var_40 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])).var_18 = "nycb");
+ Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24 ^ false);
+ Test6663854_Class_3.var_24 ^= true;
+ var_88--;
+ Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]);
+ if (false)
+ {
+ Test6663854_Class_4.var_40 = (new Test6663854_Interface_2[Test6663854_Class_3.var_23])[((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78];
+ }
+ else
+ {
+ --Test6663854_Class_6.var_81;
+ }
+ Test6663854_Class_6.var_81--;
+ ++Test6663854_Class_6.var_81;
+ if (Test6663854_Class_3.var_24 = !Test6663854_Class_3.var_24)
+ {
+ --var_88;
+ Test6663854_Class_5.var_66 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23];
+ Test6663854_Class_6.var_81 &= 1451013276;
+ var_88--;
+ }
+ else
+ {
+ var_88 >>= --var_88;
+ }
+ Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24;
+ Test6663854_Class_6.var_81--;
+ Test6663854_Class_6.var_81++;
+ --Test6663854_Class_6.var_81;
+ ((new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_41 = new Test6663854_Class_3();
+ }
+
+
+
+
+ public final Test6663854_Class_4 func_0(int arg_0)
+ {
+ --arg_0;
+ {
+ switch ((char)var_89)
+ {
+ case 'R':
+
+ }
+ ++(Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]))).var_38;
+ ++var_88;
+ Test6663854_Class_5.var_66 = ~Test6663854_Class_6.var_81 % Test6663854_Class_6.var_81 != (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) ? (Test6663854_Class_6.var_82 = (var_67 = new Test6663854_Class_3())) : new Test6663854_Class_3();
+ }
+ (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Interface_2[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])).var_38 &= new Test6663854_Class_0().var_6;
+ Test6663854_Interface_1 var_90 = ((new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23];
+ (Test6663854_Class_5.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = new Test6663854_Class_0();
+ if (true)
+ {
+ ((Test6663854_Class_3)(Test6663854_Interface_2)var_90).var_18 = (((Test6663854_Class_3)var_90).var_22 = new Test6663854_Class_0());
+ }
+ else
+ {
+ ++((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)var_90)).var_45 > 7.093005581228189E307 ? (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)var_90)) : (Test6663854_Class_4)(var_90 = (Test6663854_Class_3)var_90)).var_38;
+ }
+ var_67 = (Test6663854_Class_3.var_24 ^= true) ^ true ? (Test6663854_Class_6.var_82 = (Test6663854_Class_3)var_90) : (Test6663854_Class_3)var_90;
+ {
+ {
+ var_90 = (var_90 = (Test6663854_Class_5)var_90);
+ }
+ Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 ? !false : true) ? (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24))) : ! !Test6663854_Class_3.var_24 && false);
+ Test6663854_Class_0 var_91;
+ Test6663854_Class_4.var_40 = (Test6663854_Class_3.var_24 |= (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24) && (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24) | ! (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24)) ? (+Test6663854_Class_3.var_21 != 4.6479454E37F ? (Test6663854_Class_6)(Test6663854_Interface_2)var_90 : (Test6663854_Class_6)var_90) : (new Test6663854_Class_6[Test6663854_Class_3.var_23])[((Test6663854_Class_6)(Test6663854_Class_5.var_66 = (Test6663854_Interface_2)var_90)).var_78];
+ }
+ arg_0 |= ((((Test6663854_Class_6.var_80 = (Test6663854_Class_4)var_90).var_41 = (((Test6663854_Class_4)var_90).var_41 = (Test6663854_Class_3)var_90)).var_22 = new Test6663854_Class_0()).var_8 += (Test6663854_Class_3.var_20 = new Test6663854_Class_0().var_1));
+ {
+ (Test6663854_Class_6.var_82 = (new Test6663854_Class_3[((Test6663854_Class_6)var_90).var_78])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_18 = ((Test6663854_Class_3.var_24 ^ (!false & Test6663854_Class_3.var_24 ? Test6663854_Class_3.var_24 : (Test6663854_Class_3.var_24 ^= true)) ? (Test6663854_Class_3)var_90 : (Test6663854_Class_3)(Test6663854_Interface_2)var_90).var_18 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)var_90)).var_41 = (Test6663854_Class_3)(((Test6663854_Class_3)(Test6663854_Class_5.var_66 = (Test6663854_Class_3)var_90)).var_18 = (((Test6663854_Class_3)(Test6663854_Interface_2)var_90).var_18 = (Test6663854_Class_3)var_90))));
+ }
+ {
+ arg_0++;
+ }
+ Test6663854_Interface_2 var_92;
+ {
+ ((Test6663854_Class_5.var_67 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_4)(var_92 = (Test6663854_Class_3)var_90)).var_41 = (Test6663854_Class_5.var_67 = (Test6663854_Class_3)var_90))).var_22 = ((Test6663854_Class_5.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = ((Test6663854_Class_6.var_82 = (((Test6663854_Class_4)var_90).var_41 = (Test6663854_Class_3)var_90)).var_22 = (Test6663854_Class_0)((Test6663854_Class_5.var_67 = (Test6663854_Class_3)var_90).var_18 = (Test6663854_Class_5)var_90)))).var_7 = Test6663854_Class_3.var_21;
+ }
+ arg_0 &= ((var_67 = (var_67 = new Test6663854_Class_3())).var_22 = (new Test6663854_Class_0[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_1 / 2084775982;
+ Test6663854_Class_3.var_20 = (Test6663854_Class_3.var_24 = false) ^ true ? Test6663854_Class_0.var_2 : var_88;
+ return Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[((Test6663854_Class_6)var_90).var_78];
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6663854_Class_7.var_65 = "; result += Test6663854.Printer.print(var_65);
+ result += "\n";
+ result += "Test6663854_Class_7.var_88 = "; result += Test6663854.Printer.print(var_88);
+ result += "\n";
+ result += "Test6663854_Class_7.var_87 = "; result += Test6663854.Printer.print(var_87);
+ result += "\n";
+ result += "Test6663854_Class_7.var_89 = "; result += Test6663854.Printer.print(var_89);
+ result += "\n";
+ result += "Test6663854_Class_7.var_66 = "; result += Test6663854.Printer.print(var_66);
+ result += "\n";
+ result += "Test6663854_Class_7.var_67 = "; result += Test6663854.Printer.print(var_67);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Test6663854_Class_8 implements Test6663854_Interface_1 {
+ long var_93 = ++Test6663854_Class_6.var_81;
+ short var_94 = (short)'H';
+ float var_95;
+ Test6663854_Interface_1 var_96;
+ final static float var_97 = 2.43397E38F;
+ final static long var_98 = 7461452158234510336L;
+ static Test6663854_Class_7[] var_99;
+
+
+ public Test6663854_Class_8()
+ {
+ Test6663854_Class_6 var_103;
+ Test6663854_Class_3.var_20 = (Test6663854_Class_3.var_20 = var_94 / ~Test6663854_Class_3.var_23);
+ if (false)
+ {
+ Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24;
+ }
+ else
+ {
+ Test6663854_Class_3.var_20 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23);
+ --Test6663854_Class_7.var_88;
+ }
+ final boolean[] var_104 = new boolean[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23];
+ Test6663854_Class_3.var_24 &= false & (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24);
+ }
+
+
+ public boolean func_0()
+ {
+ Test6663854_Class_7.var_88--;
+ Test6663854_Class_7.var_88--;
+ (((new Test6663854_Class_0[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_7 = 1.2337083709828518E307;
+ Test6663854_Class_7.var_88++;
+ if (Test6663854_Class_3.var_24)
+ {
+ byte var_100 = 25;
+ "lwmbav".toLowerCase();
+ Test6663854_Class_3.var_24 |= (Test6663854_Class_3.var_24 |= false) & ((Test6663854_Class_3.var_24 = true) ^ Test6663854_Class_3.var_24 ? (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24) : Test6663854_Class_3.var_24);
+ }
+ else
+ {
+ long var_101;
+ new Test6663854_Class_0().var_7 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23);
+ Test6663854_Class_7.var_88++;
+ ++Test6663854_Class_6.var_81;
+ Test6663854_Class_7.var_88 |= 1083041050566936576L;
+ Test6663854_Class_7.var_88--;
+ }
+ var_94 ^= (var_94 = (var_94 *= 1.9072213520938263E307));
+ var_94++;
+ boolean var_102 = true;
+ ++Test6663854_Class_7.var_88;
+ Test6663854_Class_7.var_88 += (((new Test6663854_Class_7[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_87;
+ ((new Test6663854_Class_7[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_89 /= (new double[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23] * var_97;
+ return (Test6663854_Class_3.var_24 = (var_102 &= Test6663854_Class_3.var_24 & true)) ? false : Test6663854_Class_3.var_24;
+ }
+
+ public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+ {
+ Test6663854_Class_7.var_88--;
+ --Test6663854_Class_7.var_88;
+ return arg_0;
+ }
+
+
+
+ private Test6663854_Class_0 func_0(Test6663854_Class_0 arg_0)
+ {
+ if (!Test6663854_Class_3.var_24)
+ {
+ Test6663854_Class_7.var_88 ^= (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) << ~Test6663854_Class_0.var_2;
+ }
+ else
+ {
+ (Test6663854_Class_6.var_82 = (Test6663854_Class_7.var_67 = (Test6663854_Class_3)(new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])).var_22 = (((new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_22 = (arg_0 = arg_0));
+ }
+ if ((Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))) < Test6663854_Class_3.var_21)
+ {
+ Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 ^= (arg_0.var_6 ^ Test6663854_Class_7.var_88++) != (long)"y".codePointAt((int)var_94)) | false;
+ }
+ else
+ {
+ ++Test6663854_Class_7.var_88;
+ }
+ var_94 >>= (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23);
+ {
+ Test6663854_Class_7.var_66 = (Test6663854_Class_6)(var_96 = new Test6663854_Class_3());
+ }
+ arg_0.var_8 = 'u';
+ var_94 ^= arg_0.var_8;
+ ++var_94;
+ Test6663854_Class_7.var_88++;
+ var_94 += (Test6663854_Class_3.var_20 = '^');
+ return arg_0;
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6663854_Class_8.var_99 = "; result += Test6663854.Printer.print(var_99);
+ result += "\n";
+ result += "Test6663854_Class_8.var_93 = "; result += Test6663854.Printer.print(var_93);
+ result += "\n";
+ result += "Test6663854_Class_8.var_98 = "; result += Test6663854.Printer.print(var_98);
+ result += "\n";
+ result += "Test6663854_Class_8.var_95 = "; result += Test6663854.Printer.print(var_95);
+ result += "\n";
+ result += "Test6663854_Class_8.var_97 = "; result += Test6663854.Printer.print(var_97);
+ result += "\n";
+ result += "Test6663854_Class_8.var_94 = "; result += Test6663854.Printer.print(var_94);
+ result += "\n";
+ result += "Test6663854_Class_8.var_96 = "; result += Test6663854.Printer.print(var_96);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+public class Test6663854 {
+ static short var_105 = 19709;
+ static int var_106 = (((Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 = false)) | true) & (false || !false) ? ! (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24) : Test6663854_Class_3.var_24 | false) ? (short)5430142769559462912L : Test6663854_Class_3.var_23 << Test6663854_Class_3.var_23;
+ boolean var_107 = false;
+
+
+ private static long func_0(final boolean arg_0)
+ {
+ {
+ Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Interface_2[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]);
+ }
+ var_105++;
+ ((new Test6663854_Class_7[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)][((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78]).func_0();
+ byte var_108 = 107;
+ return Test6663854_Class_8.var_98 << ((new Test6663854_Class_4[var_108][Test6663854_Class_3.var_23])[var_108][Test6663854_Class_3.var_24 ? var_108 : var_108--]).var_42;
+ }
+
+ protected final long func_1(char[] arg_0, Object arg_1, String arg_2, final int arg_3)
+ {
+ (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)))).var_43 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)))))).var_43 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23));
+ {
+ Test6663854_Class_6.var_82 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)).var_41 = (((new Test6663854[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_107 ^= var_107) ? (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23] : (Test6663854_Class_3)arg_1);
+ }
+ Test6663854_Class_7.var_88 += (Test6663854_Class_6.var_81 >>>= (var_107 &= var_107) | var_107 ? (int)- ~Test6663854_Class_6.var_81 : Test6663854_Class_3.var_23);
+ short var_109 = 11276;
+ final Test6663854_Class_8 var_110 = (Test6663854_Class_3.var_24 ^ (Test6663854_Class_3.var_24 = !true) ? 5788412835121658880L : var_109--) * (298795405395535872L << (((Test6663854_Class_0)arg_1).var_1 << (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))) != (var_107 ? var_109 : var_105) ? (Test6663854_Class_8)(arg_1 = arg_1) : ((Test6663854_Class_3.var_24 &= ! !var_107) ? new Test6663854_Class_8() : new Test6663854_Class_8());
+ new Test6663854_Class_4().var_43 = Test6663854_Class_3.var_24 ^ Test6663854_Class_3.var_24 ^ Test6663854_Class_3.var_24 ? (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)) : (new byte[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+ Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)));
+ Test6663854_Class_3.var_20 = (var_105 ^= (var_106 *= ((Test6663854_Class_7)arg_1).var_87 - ~Test6663854_Class_3.var_23));
+ Test6663854_Class_5 var_111;
+ Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1));
+ {
+ (arg_2 = "eiprceumt").compareTo(arg_2 = (arg_2 = "roae"));
+ }
+ if (false)
+ {
+ final Test6663854_Class_8 var_112 = var_110;
+ (true | (false && false) ? (Test6663854_Class_3)arg_1 : ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)).var_41 = (Test6663854_Class_6.var_82 = (Test6663854_Class_3)(var_110.var_96 = var_112)))).var_18 = var_110;
+ }
+ else
+ {
+ (Test6663854_Class_3.var_24 ? "jpunp" : "giappofq").concat(arg_2 = (arg_2 = arg_2));
+ }
+ {
+ Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24;
+ }
+ var_110.var_96 = (Test6663854_Class_7)(var_110.var_96 = (Test6663854_Class_7)arg_1);
+ {
+ ((var_107 ^= !var_107) && (!Test6663854_Class_3.var_24 | (Test6663854_Class_3.var_24 |= true) ? !false : !true) ? (Test6663854_Class_4)arg_1 : (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)).var_41 = (((var_107 &= (var_107 &= (var_107 &= (Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24))))) ? (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1) : (Test6663854_Class_4)(Test6663854_Class_4.var_40 = (Test6663854_Class_7)arg_1)).var_41 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)))).var_41 = false || Test6663854_Class_3.var_24 ? (Test6663854_Class_3)arg_1 : (Test6663854_Class_3)arg_1));
+ }
+ Test6663854_Class_5.var_66 = false ? (new Test6663854_Class_6[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23] : new Test6663854_Class_6();
+ var_105++;
+ arg_1 = (var_111 = new Test6663854_Class_7());
+ ((true ? (Test6663854_Class_3)arg_1 : (Test6663854_Class_3)arg_1).var_22 = (new Test6663854_Class_0[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_8 >>= (var_106 /= ((Test6663854_Class_4)arg_1).var_42) - ((Test6663854_Class_3.var_24 ? (Test6663854_Class_4)arg_1 : (Test6663854_Class_4)arg_1).var_43 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1))).var_43 = new Test6663854_Class_6().var_78));
+ return 5795172173382514688L | (((var_107 &= (Test6663854_Class_3.var_24 |= false) | Test6663854_Class_3.var_24) ? (Test6663854_Class_4)arg_1 : (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)).var_43 = Test6663854_Class_3.var_23);
+ }
+
+ public static String execute()
+ {
+ try {
+ Test6663854 t = new Test6663854();
+ try { t.test(); }
+ catch(Throwable e) { }
+ try { return t.toString(); }
+ catch (Throwable e) { return "Error during result conversion to String"; }
+ } catch (Throwable e) { return "Error during test execution"; }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ Test6663854 t = new Test6663854();
+ try { t.test(); }
+ catch(Throwable e) { }
+ try { System.out.println(t); }
+ catch(Throwable e) { }
+ } catch (Throwable e) { }
+ }
+
+ private void test()
+ {
+ if ((true & (false ? !false : true) || var_107 ? (var_105 <<= Test6663854_Class_5.var_65) / (Test6663854_Class_0.var_5 = var_105) : 2509076152709535744L) >= (true ? new Test6663854_Class_8().var_93 : (Test6663854_Class_3.var_20 = Test6663854_Class_3.var_23)))
+ {
+ (true ? (new Test6663854_Class_6[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23] : (Test6663854_Class_7.var_66 = new Test6663854_Class_6())).func_0();
+ (var_107 ? (new Test6663854_Class_4().var_41 = new Test6663854_Class_3()) : (Test6663854_Class_3)(new Test6663854_Class_3().var_18 = new Test6663854_Class_8())).var_18 = (new Test6663854_Class_4[new Test6663854_Class_4().var_43 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)])[Test6663854_Class_3.var_23];
+ {
+ ++var_106;
+ ((new Test6663854_Class_5().func_0() ? (Test6663854_Class_3.var_24 ^= true) : !false) ? (Test6663854_Class_7)new Test6663854_Class_5() : (Test6663854_Class_7)((Test6663854_Class_6.var_82 = new Test6663854_Class_3()).var_18 = (Test6663854_Class_6.var_80 = new Test6663854_Class_4()))).var_89 -= Test6663854_Class_3.var_23;
+ }
+ var_105 *= 4.59906108270682E307;
+ {
+ Test6663854_Class_0.var_4 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = new Test6663854_Class_4()))).var_43 = (Test6663854_Class_0.var_4 = false ? (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) : Test6663854_Class_3.var_23));
+ }
+ long var_113 = 0L;
+ var_106 %= (Test6663854_Class_7.var_88 = 'i');
+ for (short var_114 = ((Test6663854_Class_8)(new Test6663854_Interface_1[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))])[Test6663854_Class_3.var_23]).var_94; var_113 < 4 && false; "dmmntw".length())
+ {
+ var_114++;
+ var_113++;
+ Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24;
+ new String("kprvouugy");
+ }
+ {
+ new Test6663854_Class_8().var_94 /= (long)5.719961906225282E307;
+ }
+ double var_115 = 0;
+ Test6663854_Class_3.var_24 |= var_107;
+ do
+ {
+ Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 |= !Test6663854_Class_3.var_24 && var_107);
+ var_115++;
+ var_106++;
+ } while (var_115 < 29 && (var_107 = (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24)));
+ Test6663854_Class_7.var_66 = new Test6663854_Class_7();
+ Test6663854_Class_3.var_20 = (false ? (Test6663854_Class_6.var_80 = new Test6663854_Class_4()) : new Test6663854_Class_4()).var_42;
+ }
+ else
+ {
+ (((new Test6663854_Class_3[Test6663854_Class_3.var_23])[new Test6663854_Class_6().var_78]).var_22 = (new Test6663854_Class_3().var_22 = (new Test6663854_Class_3().var_22 = new Test6663854_Class_0()))).var_8 >>>= (var_106 &= new Test6663854_Class_0().var_8 << Test6663854_Class_7.var_65);
+ }
+ Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = new Test6663854_Class_4()));
+ {
+ Test6663854_Class_8 var_116;
+ (!true | (Test6663854_Class_3.var_24 &= true) ? new Test6663854_Class_7() : new Test6663854_Class_7()).var_89 /= Test6663854_Class_7.var_88--;
+ Test6663854_Class_6.var_81 &= ((new Test6663854_Class_6[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_78;
+ }
+ if (true ? var_107 : (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 |= false)))
+ {
+ Test6663854_Class_3.var_24 |= (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 &= !true)));
+ Test6663854_Class_7.var_66 = (Test6663854_Class_7)new Test6663854_Class_5();
+ Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)));
+ {
+ Test6663854_Class_7.var_88++;
+ float var_117 = 0F;
+ final long var_118 = 1388589135930756096L;
+ for (var_106++; ((Test6663854_Class_3.var_24 &= false) && (Test6663854_Class_3.var_24 |= true)) ^ true && (var_117 < 1 && Test6663854_Class_3.var_24); new Test6663854_Class_0().var_8 += !false || (new float[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23] <= Test6663854_Class_3.var_23 || Test6663854_Class_3.var_24 ? ((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78 : Test6663854_Class_3.var_23)
+ {
+ Test6663854_Class_6.var_82 = (Test6663854_Class_7.var_67 = new Test6663854_Class_3());
+ var_117++;
+ Test6663854_Class_5.var_66 = Test6663854_Class_3.var_24 & !Test6663854_Class_3.var_24 ^ var_107 ^ new Test6663854_Class_0().var_8 == new Test6663854_Class_0().var_1 ? new Test6663854_Class_6() : new Test6663854_Class_6();
+ (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)]).var_43 = (Test6663854_Class_0.var_4 = ((Test6663854_Class_6)(new Object[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_78);
+ }
+ if (false & ((var_107 = true) || ! ((Test6663854_Class_3.var_24 ^= true || !var_107) ? false : Test6663854_Class_3.var_24 ^ var_107) ? (var_107 = Test6663854_Class_3.var_24) && Test6663854_Class_3.var_24 : true))
+ {
+ "yvjk".toString();
+ }
+ else
+ {
+ Test6663854_Class_4 var_119 = Test6663854_Class_6.var_80 = ((var_107 = true) ? (Test6663854_Class_6.var_81 |= var_106) : var_118) < (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))) ? (Test6663854_Class_4)(new Test6663854_Class_3().var_18 = new float[Test6663854_Class_3.var_23]) : (new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+ }
+ (false | (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) >= var_106 ? new Test6663854_Class_3() : (Test6663854_Class_7.var_67 = new Test6663854_Class_3())).var_18 = ((false ? (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23] : new Test6663854_Class_3()).var_22 = ((Test6663854_Class_7.var_67 = (Test6663854_Class_3)(new Test6663854_Class_3().var_18 = (Test6663854_Class_8)(new Test6663854_Class_8().var_96 = new Test6663854_Class_8()))).var_22 = ((Test6663854_Class_5.var_67 = new Test6663854_Class_3()).var_22 = new Test6663854_Class_0())));
+ short var_120;
+ (Test6663854_Class_6.var_80 = new Test6663854_Class_4()).var_41 = new Test6663854_Class_3();
+ ((new Test6663854_Class_8[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_96 = (Test6663854_Class_4.var_40 = !false & var_107 ? (Test6663854_Class_7)new Test6663854_Class_5() : new Test6663854_Class_7());
+ }
+ if ((Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24)) || Test6663854_Class_3.var_24)
+ {
+ {
+ var_106--;
+ Test6663854_Class_6.var_81 -= 2.5265952E38F;
+ Test6663854_Class_7.var_88++;
+ Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]));
+ Test6663854_Class_6.var_81++;
+ (((new Test6663854_Class_7[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[(byte)(var_105 &= var_106)])[Test6663854_Class_3.var_23]).equals(((new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_18 = new Test6663854_Class_8());
+ }
+ ((((new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_41 = (Test6663854_Class_7.var_67 = (Test6663854_Class_7.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]))).var_18 = "mnxktbgv";
+ var_105++;
+ ((Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24) ? (new Test6663854_Class_3().var_22 = new Test6663854_Class_0()) : new Test6663854_Class_0()).var_7 = new Test6663854_Class_0().var_6;
+ var_105 = (var_105 >>>= Test6663854_Class_3.var_23);
+ ++var_105;
+ {
+ Test6663854_Class_0.var_4 = ((Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_43 = ((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)]).var_78);
+ ((Test6663854_Class_8)(new Object[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_96 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(Test6663854_Class_5.var_66 = (new Test6663854_Class_6[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]));
+ }
+ if (2125632862 >= Test6663854_Class_5.var_65)
+ {
+ "nfdjgd".toLowerCase();
+ ((new Test6663854_Class_8[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_96 = new Test6663854_Class_8();
+ Test6663854_Interface_2 var_121;
+ new Test6663854_Class_0().var_7 = Test6663854_Class_8.var_97;
+ --var_105;
+ --Test6663854_Class_7.var_88;
+ ((new Test6663854_Class_0[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)])[((Test6663854_Class_6)(Test6663854_Class_4.var_40 = (Test6663854_Class_3)(new Object[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])).var_78]).var_7 = (((new Test6663854_Class_8[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_94 += (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23));
+ }
+ else
+ {
+ --Test6663854_Class_6.var_81;
+ }
+ if (false)
+ {
+ Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+ }
+ else
+ {
+ var_105--;
+ (true | (Test6663854_Class_3.var_24 |= var_107) ? (Test6663854_Class_7)(new Test6663854_Class_5[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23] : (new Test6663854_Class_7[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_89 *= 2.5396491E38F;
+ var_107 = Test6663854_Class_3.var_24;
+ var_105++;
+ }
+ Test6663854_Class_6.var_81--;
+ new Test6663854_Class_5();
+ }
+ else
+ {
+ Test6663854_Class_0 var_122;
+ }
+ var_107 = false;
+ (Test6663854_Class_3.var_24 ? new Test6663854_Class_7() : (Test6663854_Class_7)(new Test6663854_Class_3().var_18 = new Test6663854_Class_6())).var_89 *= (var_106 -= (new Test6663854_Class_3().var_22 = new Test6663854_Class_0()).var_6);
+ new Test6663854_Class_8().var_94 *= Test6663854_Class_7.var_88;
+ ((new String[new Test6663854_Class_6().var_78])[Test6663854_Class_3.var_23]).codePointAt(135817988);
+ final double var_123 = 7.395191963488875E307;
+ --var_105;
+ Test6663854_Class_7.var_88++;
+ }
+ else
+ {
+ (Test6663854_Class_6.var_80 = Test6663854_Class_3.var_24 ? (Test6663854_Class_6.var_80 = new Test6663854_Class_4()) : (Test6663854_Class_6.var_80 = new Test6663854_Class_4())).var_38 <<= (Test6663854_Class_7.var_88 <<= (new Test6663854_Class_4().var_43 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))) >>> Test6663854_Class_3.var_23);
+ }
+ int var_124 = 0;
+ Test6663854_Class_7 var_125;
+ float var_126 = 2.5216562E38F;
+ int var_127 = 0;
+ Test6663854_Class_7.var_66 = (Test6663854_Class_5.var_66 = (Test6663854_Class_4)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]);
+ while (var_127 < 1 && (Test6663854_Class_3.var_24 ? (var_107 |= var_107) : false))
+ {
+ short var_128;
+ var_127++;
+ var_125 = (var_125 = (var_125 = (var_125 = (Test6663854_Class_7)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])));
+ "nkv".indexOf("ptrepiu" + "aljmjttym", var_106 << (new byte[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]);
+ }
+ {
+ Test6663854_Class_7.var_66 = (Test6663854_Class_7.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]);
+ }
+ var_125 = (new Test6663854_Class_7[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23];
+ var_126 += var_106;
+ while (var_124 < 537 && true)
+ {
+ Test6663854_Class_7.var_88 %= var_105;
+ var_124++;
+ var_106++;
+ Test6663854_Class_5.var_66 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]));
+ final long var_129 = 3230407753980990464L;
+ new Test6663854_Class_8();
+ final Test6663854_Class_3 var_130 = (Test6663854_Class_3)((Test6663854_Class_3.var_24 |= !false) | (var_107 | !var_107) | (new Test6663854_Class_8().var_94++ >= 1015752753 | !true) ? (new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23] : (new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]);
+ Test6663854_Class_5.var_66 = (Test6663854_Class_7.var_66 = (Test6663854_Class_7.var_66 = (Test6663854_Class_7.var_67 = var_130)));
+ }
+ Test6663854_Class_7.var_66 = var_126 >= (Test6663854_Class_3.var_24 || (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) ? var_106 : var_126) ? new Test6663854_Class_6() : new Test6663854_Class_6();
+ var_107 &= true;
+ (new Test6663854_Class_8().var_96 = (var_125 = (var_125 = (var_125 = new Test6663854_Class_7())))).func_0();
+ float var_131 = 0F;
+ Test6663854_Class_3 var_132 = new Test6663854_Class_3();
+ do
+ {
+ long var_133;
+ var_131++;
+ Test6663854_Interface_2 var_134 = Test6663854_Class_7.var_66 = var_132;
+ } while ((Test6663854_Class_3.var_24 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) == 1.2758309E38F) && (var_131 < 117 && ((new short[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)] == ((var_107 &= ! (Test6663854_Class_3.var_24 ^= false)) ^ ! !false ? new Test6663854_Class_0().var_6 : new Test6663854_Class_4().var_42)));
+ (var_107 ? var_132 : (Test6663854_Class_3)(Test6663854_Class_7.var_66 = var_132)).var_18 = (Test6663854_Class_0)((Test6663854_Class_5.var_67 = (Test6663854_Class_7.var_67 = (var_132 = var_132))).var_18 = ((new Test6663854_Class_8[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]);
+ long var_135 = 0L;
+ (((new Test6663854_Class_8[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (byte)+ (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)]).var_96 = var_132;
+ for (((var_107 = ((new Test6663854_Class_0[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).equals(var_132.var_18 = (Test6663854_Class_8)(new Test6663854_Class_8().var_96 = var_132))) ? "oedsntb" : "ouspr").concat("t"); var_135 < 27; (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]))).var_38 %= (double)func_0(Test6663854_Class_3.var_24 = false ? !var_107 && ! !Test6663854_Class_3.var_24 : Test6663854_Class_3.var_24 ^ ! (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24)))
+ {
+ Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Class_8().var_96 = new Test6663854_Class_8());
+ var_135++;
+ Test6663854_Class_3.var_24 &= !true;
+ new Test6663854_Class_0().var_8 += Test6663854_Class_7.var_65;
+ }
+ Test6663854_Class_3 var_136 = var_132;
+ if ((var_107 = ((Test6663854_Class_4)(Test6663854_Class_7.var_66 = (var_125 = (Test6663854_Class_7)(Test6663854_Class_7.var_66 = var_136)))).func_0() ^ true) && (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]))).var_45 <= ((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78)
+ {
+ var_126 %= ((var_107 = true) ? (var_105 *= 8272288534835139584L) : (var_105 |= var_105)) % new Test6663854_Class_7().var_89;
+ ((Test6663854_Class_3)(new Test6663854_Class_8().var_96 = (new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])).var_18 = new Test6663854_Class_0();
+ var_105 <<= ++((Test6663854_Class_3.var_24 |= false) ? new Test6663854_Class_8() : (Test6663854_Class_8)(new Test6663854_Class_8().var_96 = new Test6663854_Class_4())).var_94 % (Test6663854_Class_0.var_2 - var_106);
+ Test6663854_Interface_2 var_137;
+ var_137 = new Test6663854_Class_4();
+ int var_138;
+ }
+ else
+ {
+ final Test6663854_Interface_2 var_139 = Test6663854_Class_4.var_40 = (var_136 = var_136);
+ new Test6663854_Class_8().var_93 -= new Test6663854_Class_6().var_78;
+ --((Test6663854_Class_3.var_24 ^= var_126 < Test6663854_Class_3.var_23 | !var_107) ? (new Test6663854_Class_8[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][new Test6663854_Class_6().var_78] : new Test6663854_Class_8()).var_93;
+ var_105 >>= ! (Test6663854_Class_3.var_24 = true) || ((Test6663854_Class_8)(! (Test6663854_Class_3.var_24 |= var_107) | (false ? Test6663854_Class_3.var_23 : new Test6663854_Class_6().var_78) != new Test6663854_Class_8().var_93 ? (Test6663854_Class_6.var_82 = var_136) : (new Test6663854_Class_8().var_96 = (var_132 = var_136)))).var_94 >= Test6663854_Class_6.var_81++ ? var_124 : '`';
+ }
+ var_126 /= var_105;
+ var_105 *= var_127;
+ var_107 ^= (var_107 = true);
+ {
+ Test6663854_Class_7.var_66 = (var_125 = (Test6663854_Class_7)(new Test6663854_Class_5[Test6663854_Class_3.var_23])[new Test6663854_Class_6().var_78]);
+ }
+ (var_136.var_22 = ((var_136 = var_132).var_22 = new Test6663854_Class_0())).var_7 = ((!false ? var_132 : (Test6663854_Class_7.var_67 = var_132)).var_22 = (((Test6663854_Class_3)(var_136.var_18 = var_136)).var_22 = (Test6663854_Class_0)(var_132.var_18 = "sgybwy"))).var_6;
+ ((Test6663854_Class_3.var_20 = var_105--) >= ~Test6663854_Class_3.var_23 ? new String() : "lgcfkbsw").replace(new Test6663854_Class_0().var_8 |= 't', false ? (Test6663854_Class_7.var_88 -= var_105) : 'q');
+ Test6663854_Class_7.var_88 <<= Test6663854_Class_7.var_88;
+ }
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6663854.var_105 = "; result += Printer.print(var_105);
+ result += "\n";
+ result += "Test6663854.var_107 = "; result += Printer.print(var_107);
+ result += "\n";
+ result += "Test6663854.var_106 = "; result += Printer.print(var_106);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+ static class Printer
+ {
+ public static String print(boolean arg) { return String.valueOf(arg); }
+ public static String print(byte arg) { return String.valueOf(arg); }
+ public static String print(short arg) { return String.valueOf(arg); }
+ public static String print(char arg) { return String.valueOf((int)arg); }
+ public static String print(int arg) { return String.valueOf(arg); }
+ public static String print(long arg) { return String.valueOf(arg); }
+ public static String print(float arg) { return String.valueOf(arg); }
+ public static String print(double arg) { return String.valueOf(arg); }
+
+
+ public static String print(Object arg)
+ {
+ return print_r(new java.util.Stack(), arg);
+ }
+
+ private static String print_r(java.util.Stack visitedObjects, Object arg)
+ {
+ String result = "";
+ if (arg == null)
+ result += "null";
+ else
+ if (arg.getClass().isArray())
+ {
+ for (int i = 0; i < visitedObjects.size(); i++)
+ if (visitedObjects.elementAt(i) == arg) return "<recursive>";
+
+ visitedObjects.push(arg);
+
+ final String delimiter = ", ";
+ result += "[";
+
+ if (arg instanceof Object[])
+ {
+ Object[] array = (Object[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print_r(visitedObjects, array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof boolean[])
+ {
+ boolean[] array = (boolean[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof byte[])
+ {
+ byte[] array = (byte[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof short[])
+ {
+ short[] array = (short[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof char[])
+ {
+ char[] array = (char[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof int[])
+ {
+ int[] array = (int[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof long[])
+ {
+ long[] array = (long[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof float[])
+ {
+ float[] array = (float[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof double[])
+ {
+ double[] array = (double[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+
+ result += "]";
+ visitedObjects.pop();
+
+ } else
+ {
+ result += arg.toString();
+ }
+
+ return result;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6892265/Test.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,65 @@
+/*
+ * 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 6892265
+ * @summary System.arraycopy unable to reference elements beyond Integer.MAX_VALUE bytes
+ *
+ * @run main/othervm Test
+ */
+
+public class Test {
+ static final int NCOPY = 1;
+ static final int OVERFLOW = 1;
+ static int[] src2 = new int[NCOPY];
+ static int[] dst2;
+
+ static void test() {
+ int N;
+ int SIZE;
+
+ N = Integer.MAX_VALUE/4 + OVERFLOW;
+ System.arraycopy(src2, 0, dst2, N, NCOPY);
+ System.arraycopy(dst2, N, src2, 0, NCOPY);
+ }
+
+ public static void main(String[] args) {
+ try {
+ dst2 = new int[NCOPY + Integer.MAX_VALUE/4 + OVERFLOW];
+ } catch (OutOfMemoryError e) {
+ System.exit(95); // Not enough memory
+ }
+ System.out.println("warmup");
+ for (int i=0; i <11000; i++) {
+ test();
+ }
+ System.out.println("start");
+ for (int i=0; i <1000; i++) {
+ test();
+ }
+ System.out.println("finish");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6930043/Test6930043.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 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 6930043
+ * @summary C2: SIGSEGV in javasoft.sqe.tests.lang.arr017.arr01702.arr01702.loop_forw(II)I
+ *
+ * @run main Test6930043
+ */
+
+import java.io.PrintStream;
+
+public class Test6930043 {
+ int[] a;
+ int idx;
+
+ public int loop_back(int i, int i_0_) {
+ int i_1_ = 0;
+ int[] is = a;
+ if (is == null) return 0;
+ for (int i_2_ = i; i_2_ >= i_0_; i_2_--)
+ i_1_ += is[idx = i_2_];
+ return i_1_;
+ }
+
+ public int loop_forw(int start, int end) {
+ int result = 0;
+ int[] is = a;
+ if (is == null) return 0;
+ for (int index = start; index < end; index++)
+ result += is[index];
+ // result += is[idx = index];
+ return result;
+ }
+
+ public static void main(String[] strings) {
+ Test6930043 var_Test6930043 = new Test6930043();
+ var_Test6930043.a = new int[1000000];
+ var_Test6930043.loop_forw(10, 999990);
+ var_Test6930043.loop_forw(10, 999990);
+ for (int i = 0; i < 3; i++) {
+ try {
+ if (var_Test6930043.loop_forw(-1, 999990) != 0) throw new InternalError();
+ } catch (ArrayIndexOutOfBoundsException e) { }
+ }
+ var_Test6930043.loop_back(999990, 10);
+ var_Test6930043.loop_back(999990, 10);
+ for (int i = 0; i < 3; i++) {
+ try {
+ if (var_Test6930043.loop_back(999990, -1) != 0) throw new InternalError();
+ } catch (ArrayIndexOutOfBoundsException e) { }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6932496/Test6932496.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010 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 6932496
+ * @summary incorrect deopt of jsr subroutine on 64 bit c1
+ *
+ * @compile -source 1.5 -target 1.5 -XDjsrlimit=0 Test6932496.java
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6932496.m Test6932496
+ */
+
+public class Test6932496 {
+ static class A {
+ volatile boolean flag = false;
+ }
+
+ static void m() {
+ try {
+ } finally {
+ A a = new A();
+ a.flag = true;
+ }
+ }
+
+
+ static public void main(String[] args) {
+ m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6935535/Test.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 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 6935535
+ * @summary String.indexOf() returns incorrect result on x86 with SSE4.2
+ *
+ * @run main/othervm -Xcomp Test
+ */
+
+public class Test {
+
+ static int IndexOfTest(String str) {
+ return str.indexOf("1111111111111xx1x");
+ }
+
+ public static void main(String args[]) {
+ String str = "1111111111111xx1111111111111xx1x";
+ str = str.substring(0, 31);
+ int idx = IndexOfTest(str);
+ System.out.println("IndexOf(" + "1111111111111xx1x" + ") = " + idx + " in " + str);
+ if (idx != -1) {
+ System.exit(97);
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/6929067/T.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,12 @@
+public class T
+{
+ public static boolean foo(boolean bar)
+ {
+ return bar;
+ }
+
+ public static void printIt()
+ {
+ System.out.println("Hello");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/6929067/Test6929067.sh Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+##
+## @test Test6929067.sh
+## @bug 6929067
+## @summary Stack guard pages should be removed when thread is detached
+## @run shell Test6929067.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then TESTSRC=.
+fi
+
+if [ "${TESTJAVA}" = "" ]
+then
+ PARENT=`dirname \`which java\``
+ TESTJAVA=`dirname ${PARENT}`
+ echo "TESTJAVA not set, selecting " ${TESTJAVA}
+ echo "If this is incorrect, try setting the variable manually."
+fi
+
+BIT_FLAG=""
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Linux)
+ NULL=/dev/null
+ PS=":"
+ FS="/"
+ ;;
+ SunOS | Windows_* )
+ NULL=NUL
+ PS=";"
+ FS="\\"
+ echo "Test passed; only valid for Linux"
+ exit 0;
+ ;;
+ * )
+ echo "Unrecognized system!"
+ exit 1;
+ ;;
+esac
+
+LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/i386/client:/usr/openwin/lib:/usr/dt/lib:/usr/lib:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH
+
+THIS_DIR=`pwd`
+
+cp ${TESTSRC}${FS}invoke.c ${THIS_DIR}
+cp ${TESTSRC}${FS}T.java ${THIS_DIR}
+
+
+${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -fullversion
+
+${TESTJAVA}${FS}bin${FS}javac T.java
+
+gcc -o invoke -I${TESTJAVA}/include -I${TESTJAVA}/include/linux invoke.c ${TESTJAVA}/jre/lib/i386/client/libjvm.so
+./invoke
+exit $?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/6929067/invoke.c Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,90 @@
+#include <assert.h>
+#include <jni.h>
+#include <alloca.h>
+
+#include <pthread.h>
+
+union env_union
+{
+ void *void_env;
+ JNIEnv *jni_env;
+};
+
+union env_union tmp;
+JNIEnv* env;
+JavaVM* jvm;
+JavaVMInitArgs vm_args;
+JavaVMOption options[1];
+jclass class_id;
+jmethodID method_id;
+jint result;
+
+long product(unsigned long n, unsigned long m) {
+ if (m == 1) {
+ return n;
+ } else {
+ int *p = alloca(sizeof (int));
+ *p = n;
+ return product (n, m-1) + *p;
+ }
+}
+
+void *
+floobydust (void *p)
+{
+ (*jvm)->AttachCurrentThread(jvm, &tmp.void_env, NULL);
+ env = tmp.jni_env;
+
+ class_id = (*env)->FindClass (env, "T");
+ assert (class_id);
+
+ method_id = (*env)->GetStaticMethodID (env, class_id, "printIt", "()V");
+ assert (method_id);
+
+ (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL);
+
+ (*jvm)->DetachCurrentThread(jvm);
+
+ printf("%ld\n", product(5000,5000));
+
+ (*jvm)->AttachCurrentThread(jvm, &tmp.void_env, NULL);
+ env = tmp.jni_env;
+
+ class_id = (*env)->FindClass (env, "T");
+ assert (class_id);
+
+ method_id = (*env)->GetStaticMethodID (env, class_id, "printIt", "()V");
+ assert (method_id);
+
+ (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL);
+
+ (*jvm)->DetachCurrentThread(jvm);
+
+ printf("%ld\n", product(5000,5000));
+
+ return NULL;
+}
+
+int
+main (int argc, const char** argv)
+{
+ options[0].optionString = "-Xss320k";
+
+ vm_args.version = JNI_VERSION_1_2;
+ vm_args.ignoreUnrecognized = JNI_TRUE;
+ vm_args.options = options;
+ vm_args.nOptions = 1;
+
+ result = JNI_CreateJavaVM (&jvm, &tmp.void_env, &vm_args);
+ assert (result >= 0);
+
+ env = tmp.jni_env;
+
+ floobydust (NULL);
+
+ pthread_t thr;
+ pthread_create (&thr, NULL, floobydust, NULL);
+ pthread_join (thr, NULL);
+
+ return 0;
+}
--- a/jaxp/.hgtags Fri Apr 16 09:54:13 2010 +0100
+++ b/jaxp/.hgtags Sat Apr 17 08:12:00 2010 -0700
@@ -60,3 +60,7 @@
309a0a7fc6ceb1c9fc3a85b3608e97ef8f7b0dfd jdk7-b83
32c0cf01d555747918529a6ff9e06b0090c7a474 jdk7-b84
6c0ccabb430dacdcd4479f8b197980d5da4eeb66 jdk7-b85
+81c0f115bbe5d3bcf59864465b5eca5538567c79 jdk7-b86
+8b493f1aa136d86de0885fcba15262c4fa2b1412 jdk7-b87
+d8ebd15910034f2ba50b2f129f959f86cca01419 jdk7-b88
+d2818fd2b036f3b3154a9a7de41afcf4ac679c1b jdk7-b89
--- a/jaxws/.hgtags Fri Apr 16 09:54:13 2010 +0100
+++ b/jaxws/.hgtags Sat Apr 17 08:12:00 2010 -0700
@@ -60,3 +60,7 @@
371e3ded591d09112a9f231e37cb072781c486ac jdk7-b83
8bc02839eee4ef02cd1b50e87638874368a26535 jdk7-b84
8424512588ff95362c1f1e5f11c6efd4e7f7db6e jdk7-b85
+512b0e924a5ae0c0b7ad326182cae0dc0e4d1aa8 jdk7-b86
+3febd6fab2ac8ffddbaf7bed00d11290262af153 jdk7-b87
+8c666f8f3565974e301ccb58b7538912551a6e26 jdk7-b88
+bf3675aa7f20fc6f241ce95760005aef2a30ff41 jdk7-b89
--- a/jdk/.hgtags Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/.hgtags Sat Apr 17 08:12:00 2010 -0700
@@ -60,3 +60,7 @@
9027c6b9d7e2c9ca04a1add691b5b50d0f22b1aa jdk7-b83
7cb9388bb1a16365fa5118c5efa38b1cd58be40d jdk7-b84
b396584a3e64988839cca21ea1f7fbdcc9248783 jdk7-b85
+eae6e9ab26064d9ba0e7665dd646a1fd2506fcc1 jdk7-b86
+2cafbbe9825e911a6ca6c17d9a18eb1f0bf0873c jdk7-b87
+b3c69282f6d3c90ec21056cd1ab70dc0c895b069 jdk7-b88
+4a6abb7e224cc8d9a583c23c5782e4668739a119 jdk7-b89
--- a/jdk/make/sun/javazic/tzdata/VERSION Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/make/sun/javazic/tzdata/VERSION Sat Apr 17 08:12:00 2010 -0700
@@ -21,4 +21,4 @@
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
-tzdata2010b
+tzdata2010g
--- a/jdk/make/sun/javazic/tzdata/antarctica Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/make/sun/javazic/tzdata/antarctica Sat Apr 17 08:12:00 2010 -0700
@@ -79,6 +79,33 @@
Rule ChileAQ 1999 max - Oct Sun>=9 4:00u 1:00 S
Rule ChileAQ 2000 max - Mar Sun>=9 3:00u 0 -
+# These rules are stolen from the `australasia' file.
+Rule AusAQ 1917 only - Jan 1 0:01 1:00 -
+Rule AusAQ 1917 only - Mar 25 2:00 0 -
+Rule AusAQ 1942 only - Jan 1 2:00 1:00 -
+Rule AusAQ 1942 only - Mar 29 2:00 0 -
+Rule AusAQ 1942 only - Sep 27 2:00 1:00 -
+Rule AusAQ 1943 1944 - Mar lastSun 2:00 0 -
+Rule AusAQ 1943 only - Oct 3 2:00 1:00 -
+Rule ATAQ 1967 only - Oct Sun>=1 2:00s 1:00 -
+Rule ATAQ 1968 only - Mar lastSun 2:00s 0 -
+Rule ATAQ 1968 1985 - Oct lastSun 2:00s 1:00 -
+Rule ATAQ 1969 1971 - Mar Sun>=8 2:00s 0 -
+Rule ATAQ 1972 only - Feb lastSun 2:00s 0 -
+Rule ATAQ 1973 1981 - Mar Sun>=1 2:00s 0 -
+Rule ATAQ 1982 1983 - Mar lastSun 2:00s 0 -
+Rule ATAQ 1984 1986 - Mar Sun>=1 2:00s 0 -
+Rule ATAQ 1986 only - Oct Sun>=15 2:00s 1:00 -
+Rule ATAQ 1987 1990 - Mar Sun>=15 2:00s 0 -
+Rule ATAQ 1987 only - Oct Sun>=22 2:00s 1:00 -
+Rule ATAQ 1988 1990 - Oct lastSun 2:00s 1:00 -
+Rule ATAQ 1991 1999 - Oct Sun>=1 2:00s 1:00 -
+Rule ATAQ 1991 2005 - Mar lastSun 2:00s 0 -
+Rule ATAQ 2000 only - Aug lastSun 2:00s 1:00 -
+Rule ATAQ 2001 max - Oct Sun>=1 2:00s 1:00 -
+Rule ATAQ 2006 only - Apr Sun>=1 2:00s 0 -
+Rule ATAQ 2007 only - Mar lastSun 2:00s 0 -
+Rule ATAQ 2008 max - Apr Sun>=1 2:00s 0 -
# Argentina - year-round bases
# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@@ -120,20 +147,52 @@
# http://www.timeanddate.com/news/time/antarctica-new-times.html
# </a>
+# From Steffen Thorsen (2010-03-10):
+# We got these changes from the Australian Antarctic Division:
+# - Macquarie Island will stay on UTC+11 for winter and therefore not
+# switch back from daylight savings time when other parts of Australia do
+# on 4 April.
+#
+# - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
+# The change to UTC+11 is being considered as a regular summer thing but
+# has not been decided yet.
+#
+# - Davis station will revert to its normal time of UTC+7 at 10 March 2010
+# 20:00 UTC.
+#
+# - Mawson station stays on UTC+5.
+#
+# In addition to the Rule changes for Casey/Davis, it means that Macquarie
+# will no longer be like Hobart and will have to have its own Zone created.
+#
+# Background:
+# <a href="http://www.timeanddate.com/news/time/antartica-time-changes-2010.html">
+# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
+# </a>
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Casey 0 - zzz 1969
8:00 - WST 2009 Oct 18 2:00
# Western (Aus) Standard Time
- 11:00 - CAST # Casey Time
+ 11:00 - CAST 2010 Mar 5 2:00
+ # Casey Time
+ 8:00 - WST
Zone Antarctica/Davis 0 - zzz 1957 Jan 13
7:00 - DAVT 1964 Nov # Davis Time
0 - zzz 1969 Feb
7:00 - DAVT 2009 Oct 18 2:00
- 5:00 - DAVT
+ 5:00 - DAVT 2010 Mar 10 20:00u
+ 7:00 - DAVT
Zone Antarctica/Mawson 0 - zzz 1954 Feb 13
6:00 - MAWT 2009 Oct 18 2:00
# Mawson Time
5:00 - MAWT
+Zone Antarctica/Macquarie 0 - zzz 1911
+ 10:00 - EST 1916 Oct 1 2:00
+ 10:00 1:00 EST 1917 Feb
+ 10:00 AusAQ EST 1967
+ 10:00 ATAQ EST 2010 Apr 4 3:00
+ 11:00 - MIST # Macquarie Island Time
# References:
# <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
# Casey Weather (1998-02-26)
--- a/jdk/make/sun/javazic/tzdata/asia Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/make/sun/javazic/tzdata/asia Sat Apr 17 08:12:00 2010 -0700
@@ -236,22 +236,20 @@
# 2010 midnight. The decision came at a cabinet meeting at the Prime
# Minister's Office last night..."
-# From Danvin Ruangchan (2009-12-24):
-# ...the news mentions DST will be turned off again 7 months after March
-# 31st on Oct 31, 2010.
-
-# From Arthur David Olson (2009-12-26):
-# Indeed, "The government will advance again the Banglasdesh Standard
-# Time by one one hour on March 31 next year by enforcing the Daylight
-# Saving Time (DST) for seven months. It will continue till October 31
-# until further notice." I take that last sentence as the
-# establishment of a rule.
+# From Alexander Krivenyshev (2010-03-22):
+# According to Bangladesh newspaper "The Daily Star,"
+# Cabinet cancels Daylight Saving Time
+# <a href="http://www.thedailystar.net/newDesign/latest_news.php?nid=22817">
+# http://www.thedailystar.net/newDesign/latest_news.php?nid=22817
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html">
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html
+# </a>
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Dhaka 2009 only - Jun 19 23:00 1:00 S
-Rule Dhaka 2010 only - Jan 1 0:00 0 -
-Rule Dhaka 2010 max - Mar 31 23:00 1:00 S
-Rule Dhaka 2010 max - Nov 1 0:00 0 -
+Rule Dhaka 2009 only - Dec 31 23:59 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Dhaka 6:01:40 - LMT 1890
@@ -2131,6 +2129,32 @@
# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
# </a>
+# From Alexander Krivenyshev (2010-03-19):
+# According to Voice of Palestine DST will last for 191 days, from March
+# 26, 2010 till "the last Sunday before the tenth day of Tishri
+# (October), each year" (October 03, 2010?)
+#
+# <a href="http://palvoice.org/forums/showthread.php?t=245697">
+# http://palvoice.org/forums/showthread.php?t=245697
+# </a>
+# (in Arabic)
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_westbank03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_westbank03.html
+# </a>
+
+# From Steffen Thorsen (2010-03-24):
+# ...Ma'an News Agency reports that Hamas cabinet has decided it will
+# start one day later, at 12:01am. Not sure if they really mean 12:01am or
+# noon though:
+#
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=271178">
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=271178
+# </a>
+# (Ma'an News Agency)
+# "At 12:01am Friday, clocks in Israel and the West Bank will change to
+# 1:01am, while Gaza clocks will change at 12:01am Saturday morning."
+
# The rules for Egypt are stolen from the `africa' file.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
@@ -2148,7 +2172,8 @@
Rule Palestine 2006 only - Sep 22 0:00 0 -
Rule Palestine 2007 only - Sep Thu>=8 2:00 0 -
Rule Palestine 2008 only - Aug lastFri 2:00 0 -
-Rule Palestine 2009 max - Mar lastFri 0:00 1:00 S
+Rule Palestine 2009 only - Mar lastFri 0:00 1:00 S
+Rule Palestine 2010 max - Mar lastSat 0:01 1:00 S
Rule Palestine 2009 max - Sep Fri>=1 2:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -2440,9 +2465,18 @@
# Thursday of the month or the start of the last Friday of the month or
# something else. For now, use the start of the last Friday.
+# From Steffen Thorsen (2010-03-17):
+# The "Syrian News Station" reported on 2010-03-16 that the Council of
+# Ministers has decided that Syria will start DST on midnight Thursday
+# 2010-04-01: (midnight between Thursday and Friday):
+# <a href="http://sns.sy/sns/?path=news/read/11421">
+# http://sns.sy/sns/?path=news/read/11421 (Arabic)
+# </a>
+
Rule Syria 2008 only - Apr Fri>=1 0:00 1:00 S
Rule Syria 2008 only - Nov 1 0:00 0 -
-Rule Syria 2009 max - Mar lastFri 0:00 1:00 S
+Rule Syria 2009 only - Mar lastFri 0:00 1:00 S
+Rule Syria 2010 max - Apr Fri>=1 0:00 1:00 S
Rule Syria 2009 max - Oct lastFri 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
--- a/jdk/make/sun/javazic/tzdata/australasia Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/make/sun/javazic/tzdata/australasia Sat Apr 17 08:12:00 2010 -0700
@@ -289,11 +289,30 @@
# <a href="http://www.fiji.gov.fj/publish/page_16198.shtml">
# http://www.fiji.gov.fj/publish/page_16198.shtml
# </a>
+
+# From Steffen Thorsen (2010-03-03):
+# The Cabinet in Fiji has decided to end DST about a month early, on
+# 2010-03-28 at 03:00.
+# The plan is to observe DST again, from 2010-10-24 to sometime in March
+# 2011 (last Sunday a good guess?).
+#
+# Official source:
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166">
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166
+# </a>
+#
+# A bit more background info here:
+# <a href="http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html">
+# http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html
+# </a>
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 S
Rule Fiji 1999 2000 - Feb lastSun 3:00 0 -
Rule Fiji 2009 only - Nov 29 2:00 1:00 S
-Rule Fiji 2010 only - Apr 25 3:00 0 -
+Rule Fiji 2010 only - Mar lastSun 3:00 0 -
+Rule Fiji 2010 only - Oct 24 2:00 1:00 S
+Rule Fiji 2011 only - Mar lastSun 3:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Pacific/Fiji 11:53:40 - LMT 1915 Oct 26 # Suva
12:00 Fiji FJ%sT # Fiji Time
@@ -471,70 +490,30 @@
# Samoa
-# From Alexander Krivenyshev (2008-12-06):
-# The Samoa government (Western Samoa) may implement DST on the first Sunday of
-# October 2009 (October 4, 2009) until the last Sunday of March 2010 (March 28,
-# 2010).
-#
-# "Selected Committee reports to Cabinet on Daylight Saving Time",
-# Government of Samoa:
-# <a href="http://www.govt.ws/pr_article.cfm?pr_id=560">
-# http://www.govt.ws/pr_article.cfm?pr_id=560
-# </a>
-# or
-# <a href="http://www.worldtimezone.com/dst_news/dst_news_samoa01.html">
-# http://www.worldtimezone.com/dst_news/dst_news_samoa01.html
-# </a>
-
-# From Steffen Thorsen (2009-08-27):
-# Samoa's parliament passed the Daylight Saving Bill 2009, and will start
-# daylight saving time on the first Sunday of October 2009 and end on the
-# last Sunday of March 2010. We hope that the full text will be published
-# soon, but we believe that the bill is only valid for 2009-2010. Samoa's
-# Daylight Saving Act 2009 will be enforced as soon as the Head of State
-# executes a proclamation publicizing this Act.
+# From Steffen Thorsen (2009-10-16):
+# We have been in contact with the government of Samoa again, and received
+# the following info:
#
-# Some background information here, which will be updated once we have
-# more details:
+# "Cabinet has now approved Daylight Saving to be effected next year
+# commencing from the last Sunday of September 2010 and conclude first
+# Sunday of April 2011."
+#
+# Background info:
# <a href="http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html">
# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
# </a>
-
-# From Alexander Krivenyshev (2009-10-03):
-# First, my deepest condolences to people of Samoa islands and all families and
-# loved ones around the world who lost their lives in the earthquake and tsunami.
#
-# Considering the recent devastation on Samoa by earthquake and tsunami and that
-# many government offices/ ministers are closed- not sure if "Daylight Saving
-# Bill 2009" will be implemented in next few days- on October 4, 2009.
-#
-# Here is reply from Consulate-General of Samoa in New Zealand
-# ---------------------------
-# Consul General
-# consulgeneral@samoaconsulate.org.nz
-#
-# Talofa Alexander,
-#
-# Thank you for your sympathy for our country but at this time we have not
-# been informed about the Daylight Savings Time Change. Most Ministries in
-# Apia are closed or relocating due to weather concerns.
-#
-# When we do find out if they are still proceeding with the time change we
-# will advise you soonest.
-#
-# Kind Regards,
-# Lana
-# for: Consul General
-
-# From Steffen Thorsen (2009-10-05):
-# We have called a hotel in Samoa and asked about local time there - they
-# are still on standard time.
+# Samoa's Daylight Saving Time Act 2009 is available here, but does not
+# contain any dates:
+# <a href="http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf">
+# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf
+# </a>
Zone Pacific/Apia 12:33:04 - LMT 1879 Jul 5
-11:26:56 - LMT 1911
-11:30 - SAMT 1950 # Samoa Time
- -11:00 - WST 2009 Oct 4
- -11:00 1:00 WSDT 2010 Mar 28
+ -11:00 - WST 2010 Sep 26
+ -11:00 1:00 WSDT 2011 Apr 3
-11:00 - WST
# Solomon Is
--- a/jdk/make/sun/javazic/tzdata/europe Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/make/sun/javazic/tzdata/europe Sat Apr 17 08:12:00 2010 -0700
@@ -2063,7 +2063,9 @@
3:00 Russia KUY%sT 1991 Mar 31 2:00s
2:00 Russia KUY%sT 1991 Sep 29 2:00s
3:00 - KUYT 1991 Oct 20 3:00
- 4:00 Russia SAM%sT # Samara Time
+ 4:00 Russia SAM%sT 2010 Mar 28 2:00s # Samara Time
+ 3:00 Russia SAM%sT
+
#
# From Oscar van Vlijmen (2001-08-25): [This region consists of]
# Respublika Bashkortostan, Komi-Permyatskij avtonomnyj okrug,
@@ -2216,7 +2218,8 @@
11:00 - PETT 1930 Jun 21 # P-K Time
12:00 Russia PET%sT 1991 Mar 31 2:00s
11:00 Russia PET%sT 1992 Jan 19 2:00s
- 12:00 Russia PET%sT
+ 12:00 Russia PET%sT 2010 Mar 28 2:00s
+ 11:00 Russia PET%sT
#
# Chukotskij avtonomnyj okrug
Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2
@@ -2224,7 +2227,8 @@
13:00 Russia ANA%sT 1982 Apr 1 0:00s
12:00 Russia ANA%sT 1991 Mar 31 2:00s
11:00 Russia ANA%sT 1992 Jan 19 2:00s
- 12:00 Russia ANA%sT
+ 12:00 Russia ANA%sT 2010 Mar 28 2:00s
+ 11:00 Russia ANA%sT
# Serbia
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
--- a/jdk/make/sun/javazic/tzdata/southamerica Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/make/sun/javazic/tzdata/southamerica Sat Apr 17 08:12:00 2010 -0700
@@ -1143,6 +1143,18 @@
# http://www.shoa.cl/noticias/2008/04hora/hora.htm
# </a>.
+# From Angel Chiang (2010-03-04):
+# Subject: DST in Chile exceptionally extended to 3 April due to earthquake
+# <a href="http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098">
+# http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098
+# </a>
+# (in Spanish, last paragraph).
+#
+# This is breaking news. There should be more information available later.
+
+# From Arthur Daivd Olson (2010-03-06):
+# Angel Chiang's message confirmed by Julio Pacheco; Julio provided a patch.
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Chile 1927 1932 - Sep 1 0:00 1:00 S
Rule Chile 1928 1932 - Apr 1 0:00 0 -
@@ -1177,7 +1189,9 @@
# N.B.: the end of March 29 in Chile is March 30 in Universal time,
# which is used below in specifying the transition.
Rule Chile 2008 only - Mar 30 3:00u 0 -
-Rule Chile 2009 max - Mar Sun>=9 3:00u 0 -
+Rule Chile 2009 only - Mar Sun>=9 3:00u 0 -
+Rule Chile 2010 only - Apr 4 3:00u 0 -
+Rule Chile 2011 max - Mar Sun>=9 3:00u 0 -
# IATA SSIM anomalies: (1992-02) says 1992-03-14;
# (1996-09) says 1998-03-08. Ignore these.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -1386,8 +1400,24 @@
# Decree 1,867 (2004-03-05)
# From Carlos Raul Perasso via Jesper Norgaard Welen (2006-10-13)
# <http://www.presidencia.gov.py/decretos/D1867.pdf>
-Rule Para 2004 max - Oct Sun>=15 0:00 1:00 S
-Rule Para 2005 max - Mar Sun>=8 0:00 0 -
+Rule Para 2004 2009 - Oct Sun>=15 0:00 1:00 S
+Rule Para 2005 2009 - Mar Sun>=8 0:00 0 -
+# From Carlos Raul Perasso (2010-02-18):
+# By decree number 3958 issued yesterday (
+# <a href="http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf">
+# http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf
+# </a>
+# )
+# Paraguay changes its DST schedule, postponing the March rule to April and
+# modifying the October date. The decree reads:
+# ...
+# Art. 1. It is hereby established that from the second Sunday of the month of
+# April of this year (2010), the official time is to be set back 60 minutes,
+# and that on the first Sunday of the month of October, it is to be set
+# forward 60 minutes, in all the territory of the Paraguayan Republic.
+# ...
+Rule Para 2010 max - Oct Sun>=1 0:00 1:00 S
+Rule Para 2010 max - Apr Sun>=8 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Asuncion -3:50:40 - LMT 1890
--- a/jdk/make/sun/javazic/tzdata/zone.tab Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/make/sun/javazic/tzdata/zone.tab Sat Apr 17 08:12:00 2010 -0700
@@ -66,6 +66,7 @@
AQ -7824+10654 Antarctica/Vostok Vostok Station, S Magnetic Pole
AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Station, Terre Adelie
AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I
+AQ -5430+15857 Antarctica/Macquarie Macquarie Island Station, Macquarie Island
AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF)
AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, MN, SE, SF)
AR -2447-06525 America/Argentina/Salta (SA, LP, NQ, RN)
@@ -351,7 +352,7 @@
RU +5443+02030 Europe/Kaliningrad Moscow-01 - Kaliningrad
RU +5545+03735 Europe/Moscow Moscow+00 - west Russia
RU +4844+04425 Europe/Volgograd Moscow+00 - Caspian Sea
-RU +5312+05009 Europe/Samara Moscow+01 - Samara, Udmurtia
+RU +5312+05009 Europe/Samara Moscow - Samara, Udmurtia
RU +5651+06036 Asia/Yekaterinburg Moscow+02 - Urals
RU +5500+07324 Asia/Omsk Moscow+03 - west Siberia
RU +5502+08255 Asia/Novosibirsk Moscow+03 - Novosibirsk
@@ -362,8 +363,8 @@
RU +4310+13156 Asia/Vladivostok Moscow+07 - Amur River
RU +4658+14242 Asia/Sakhalin Moscow+07 - Sakhalin Island
RU +5934+15048 Asia/Magadan Moscow+08 - Magadan
-RU +5301+15839 Asia/Kamchatka Moscow+09 - Kamchatka
-RU +6445+17729 Asia/Anadyr Moscow+10 - Bering Sea
+RU +5301+15839 Asia/Kamchatka Moscow+08 - Kamchatka
+RU +6445+17729 Asia/Anadyr Moscow+08 - Bering Sea
RW -0157+03004 Africa/Kigali
SA +2438+04643 Asia/Riyadh
SB -0932+16012 Pacific/Guadalcanal
--- a/jdk/make/tools/src/build/tools/javazic/RuleDay.java Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/make/tools/src/build/tools/javazic/RuleDay.java Sat Apr 17 08:12:00 2010 -0700
@@ -139,7 +139,7 @@
if (isLast()) {
return -1;
}
- return getDay();
+ return isEarlier() ? -getDay() : getDay();
}
/**
@@ -147,13 +147,10 @@
* @return the SimpleTimeZone day-of-week rule value
*/
int getDayOfWeekForSimpleTimeZoneInt() {
- if (!isLater() && !isEarlier() && !isLast()) {
- return 0;
- }
- if (isLater()) {
+ if (isEarlier() || isLater()) {
return -getDayOfWeekNum();
}
- return getDayOfWeekNum();
+ return isLast() ? getDayOfWeekNum() : 0;
}
/**
--- a/jdk/src/share/classes/java/beans/Expression.java Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/share/classes/java/beans/Expression.java Sat Apr 17 08:12:00 2010 -0700
@@ -99,6 +99,29 @@
}
/**
+ * {@inheritDoc}
+ * <p>
+ * If the invoked method completes normally,
+ * the value it returns is copied in the {@code value} property.
+ * Note that the {@code value} property is set to {@code null},
+ * if the return type of the underlying method is {@code void}.
+ *
+ * @throws NullPointerException if the value of the {@code target} or
+ * {@code methodName} property is {@code null}
+ * @throws NoSuchMethodException if a matching method is not found
+ * @throws SecurityException if a security manager exists and
+ * it denies the method invocation
+ * @throws Exception that is thrown by the invoked method
+ *
+ * @see java.lang.reflect.Method
+ * @since 1.7
+ */
+ @Override
+ public void execute() throws Exception {
+ setValue(invoke());
+ }
+
+ /**
* If the value property of this instance is not already set,
* this method dynamically finds the method with the specified
* methodName on this target with these arguments and calls it.
--- a/jdk/src/share/classes/java/beans/Statement.java Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/share/classes/java/beans/Statement.java Sat Apr 17 08:12:00 2010 -0700
@@ -132,8 +132,8 @@
}
/**
- * The execute method finds a method whose name is the same
- * as the methodName property, and invokes the method on
+ * The {@code execute} method finds a method whose name is the same
+ * as the {@code methodName} property, and invokes the method on
* the target.
*
* When the target's class defines many methods with the given name
@@ -141,7 +141,7 @@
* the algorithm specified in the Java Language Specification
* (15.11). The dynamic class of the target and arguments are used
* in place of the compile-time type information and, like the
- * <code>java.lang.reflect.Method</code> class itself, conversion between
+ * {@link java.lang.reflect.Method} class itself, conversion between
* primitive values and their associated wrapper classes is handled
* internally.
* <p>
@@ -152,13 +152,22 @@
* <li>
* The reserved method name "new" may be used to call a class's constructor
* as if all classes defined static "new" methods. Constructor invocations
- * are typically considered <code>Expression</code>s rather than <code>Statement</code>s
+ * are typically considered {@code Expression}s rather than {@code Statement}s
* as they return a value.
* <li>
- * The method names "get" and "set" defined in the <code>java.util.List</code>
+ * The method names "get" and "set" defined in the {@link java.util.List}
* interface may also be applied to array instances, mapping to
- * the static methods of the same name in the <code>Array</code> class.
+ * the static methods of the same name in the {@code Array} class.
* </ul>
+ *
+ * @throws NullPointerException if the value of the {@code target} or
+ * {@code methodName} property is {@code null}
+ * @throws NoSuchMethodException if a matching method is not found
+ * @throws SecurityException if a security manager exists and
+ * it denies the method invocation
+ * @throws Exception that is thrown by the invoked method
+ *
+ * @see java.lang.reflect.Method
*/
public void execute() throws Exception {
invoke();
--- a/jdk/src/share/classes/javax/swing/JSplitPane.java Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/share/classes/javax/swing/JSplitPane.java Sat Apr 17 08:12:00 2010 -0700
@@ -246,8 +246,7 @@
* layout, using two buttons for the components.
*/
public JSplitPane() {
- this(JSplitPane.HORIZONTAL_SPLIT,
- UIManager.getBoolean("SplitPane.continuousLayout"),
+ this(JSplitPane.HORIZONTAL_SPLIT, false,
new JButton(UIManager.getString("SplitPane.leftButtonText")),
new JButton(UIManager.getString("SplitPane.rightButtonText")));
}
@@ -264,8 +263,7 @@
*/
@ConstructorProperties({"orientation"})
public JSplitPane(int newOrientation) {
- this(newOrientation,
- UIManager.getBoolean("SplitPane.continuousLayout"));
+ this(newOrientation, false);
}
@@ -309,9 +307,7 @@
public JSplitPane(int newOrientation,
Component newLeftComponent,
Component newRightComponent){
- this(newOrientation,
- UIManager.getBoolean("SplitPane.continuousLayout"),
- newLeftComponent, newRightComponent);
+ this(newOrientation, false, newLeftComponent, newRightComponent);
}
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java Sat Apr 17 08:12:00 2010 -0700
@@ -762,7 +762,9 @@
* component's background color to be painted.
* <li>
* Installs the default caret and highlighter into the
- * associated component.
+ * associated component. These properties are only set if their
+ * current value is either {@code null} or an instance of
+ * {@link UIResource}.
* <li>
* Attaches to the editor and model. If there is no
* model, a default one is created.
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/skin.laf Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/skin.laf Sat Apr 17 08:12:00 2010 -0700
@@ -21276,7 +21276,6 @@
<uiProperty name="centerOneTouchButtons" type="BOOLEAN" value="true"/>
<uiProperty name="oneTouchButtonOffset" type="INT" value="30"/>
<uiProperty name="oneTouchExpandable" type="BOOLEAN" value="false"/>
- <uiProperty name="continuousLayout" type="BOOLEAN" value="true"/>
</uiproperties>
</style>
<backgroundStates>
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java Sat Apr 17 08:12:00 2010 -0700
@@ -648,6 +648,14 @@
table.put("ColorChooser.swatchesDefaultRecentColor", Color.RED);
table.put("ColorChooser.swatchesSwatchSize", new Dimension(10, 10));
+ // These need to be defined for ImageView.
+ table.put("html.pendingImage", SwingUtilities2.makeIcon(getClass(),
+ BasicLookAndFeel.class,
+ "icons/image-delayed.png"));
+ table.put("html.missingImage", SwingUtilities2.makeIcon(getClass(),
+ BasicLookAndFeel.class,
+ "icons/image-failed.png"));
+
// These are needed for PopupMenu.
table.put("PopupMenu.selectedWindowInputMapBindings", new Object[] {
"ESCAPE", "cancel",
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Sat Apr 17 08:12:00 2010 -0700
@@ -489,23 +489,6 @@
}
- /**
- * @inheritDoc
- */
- @Override
- protected void paintTabArea(Graphics g, int tabPlacement,
- int selectedIndex) {
- // This can be invoked from ScrollabeTabPanel
- Insets insets = tabPane.getInsets();
- int x = insets.left;
- int y = insets.top;
- int width = tabPane.getWidth() - insets.left - insets.right;
- int height = tabPane.getHeight() - insets.top - insets.bottom;
-
- paintTabArea(tabAreaContext, g, tabPlacement, selectedIndex,
- new Rectangle(x, y, width, height));
- }
-
private void paintTabArea(SynthContext ss, Graphics g,
int tabPlacement, int selectedIndex,
Rectangle tabAreaBounds) {
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java Sat Apr 17 08:12:00 2010 -0700
@@ -446,12 +446,13 @@
{"America/Winnipeg", CST},
{"America/Yakutat", AKST},
{"America/Yellowknife", MST},
- {"Antarctica/Casey", new String[] {"Casey Time", "CAST",
- "Casey Summer Time", "CAST"}},
+ {"Antarctica/Casey", WST_AUS},
{"Antarctica/Davis", new String[] {"Davis Time", "DAVT",
"Davis Summer Time", "DAVST"}},
{"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Time", "DDUT",
"Dumont-d'Urville Summer Time", "DDUST"}},
+ {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+ "Macquarie Island Summer Time", "MIST"}},
{"Antarctica/Mawson", new String[] {"Mawson Time", "MAWT",
"Mawson Summer Time", "MAWST"}},
{"Antarctica/McMurdo", NZST},
--- a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Fedora.properties Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Fedora.properties Sat Apr 17 08:12:00 2010 -0700
@@ -26,134 +26,310 @@
# Version
-# Uses Fedora Core 6 fonts and file paths.
+# Uses Fedora 9 fonts and file paths.
version=1
# Component Font Mappings
-dialog.plain.latin-1=DejaVu LGC Sans
+dialog.plain.latin-1=DejaVu Sans
dialog.plain.japanese-x0208=Sazanami Gothic
dialog.plain.korean=Baekmuk Gulim
dialog.plain.chinese-big5=AR PL ShanHeiSun Uni
dialog.plain.chinese-gb18030=AR PL ShanHeiSun Uni
+dialog.plain.bengali=Lohit Bengali
+dialog.plain.gujarati=Lohit Gujarati
+dialog.plain.hindi=Lohit Hindi
+dialog.plain.malayalam=Lohit Malayalam
+dialog.plain.oriya=Lohit Oriya
+dialog.plain.punjabi=Lohit Punjabi
+dialog.plain.tamil=Lohit Tamil
+dialog.plain.telugu=Lohit Telugu
+dialog.plain.sinhala=LKLUG
-dialog.bold.latin-1=DejaVu LGC Sans Bold
+dialog.bold.latin-1=DejaVu Sans Bold
dialog.bold.japanese-x0208=Sazanami Gothic
dialog.bold.korean=Baekmuk Gulim
dialog.bold.chinese-big5=AR PL ShanHeiSun Uni
dialog.bold.chinese-gb18030=AR PL ShanHeiSun Uni
+dialog.bold.bengali=Lohit Bengali
+dialog.bold.gujarati=Lohit Gujarati
+dialog.bold.hindi=Lohit Hindi
+dialog.bold.malayalam=Lohit Malayalam
+dialog.bold.oriya=Lohit Oriya
+dialog.bold.punjabi=Lohit Punjabi
+dialog.bold.tamil=Lohit Tamil
+dialog.bold.telugu=Lohit Telugu
+dialog.bold.sinhala=LKLUG
-dialog.italic.latin-1=DejaVu LGC Sans Oblique
+dialog.italic.latin-1=DejaVu Sans Oblique
dialog.italic.japanese-x0208=Sazanami Gothic
dialog.italic.korean=Baekmuk Gulim
dialog.italic.chinese-big5=AR PL ShanHeiSun Uni
dialog.italic.chinese-gb18030=AR PL ShanHeiSun Uni
+dialog.italic.bengali=Lohit Bengali
+dialog.italic.gujarati=Lohit Gujarati
+dialog.italic.hindi=Lohit Hindi
+dialog.italic.malayalam=Lohit Malayalam
+dialog.italic.oriya=Lohit Oriya
+dialog.italic.punjabi=Lohit Punjabi
+dialog.italic.tamil=Lohit Tamil
+dialog.italic.telugu=Lohit Telugu
+dialog.italic.sinhala=LKLUG
-dialog.bolditalic.latin-1=DejaVu LGC Sans Bold Oblique
+dialog.bolditalic.latin-1=DejaVu Sans Bold Oblique
dialog.bolditalic.japanese-x0208=Sazanami Gothic
dialog.bolditalic.korean=Baekmuk Gulim
dialog.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
dialog.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-
+dialog.bolditalic.bengali=Lohit Bengali
+dialog.bolditalic.gujarati=Lohit Gujarati
+dialog.bolditalic.hindi=Lohit Hindi
+dialog.bolditalic.malayalam=Lohit Malayalam
+dialog.bolditalic.oriya=Lohit Oriya
+dialog.bolditalic.punjabi=Lohit Punjabi
+dialog.bolditalic.tamil=Lohit Tamil
+dialog.bolditalic.telugu=Lohit Telugu
+dialog.bolditalic.sinhala=LKLUG
-sansserif.plain.latin-1=DejaVu LGC Sans
+sansserif.plain.latin-1=DejaVu Sans
sansserif.plain.japanese-x0208=Sazanami Gothic
sansserif.plain.korean=Baekmuk Gulim
sansserif.plain.chinese-big5=AR PL ShanHeiSun Uni
sansserif.plain.chinese-gb18030=AR PL ShanHeiSun Uni
+sansserif.plain.bengali=Lohit Bengali
+sansserif.plain.gujarati=Lohit Gujarati
+sansserif.plain.hindi=Lohit Hindi
+sansserif.plain.malayalam=Lohit Malayalam
+sansserif.plain.oriya=Lohit Oriya
+sansserif.plain.punjabi=Lohit Punjabi
+sansserif.plain.tamil=Lohit Tamil
+sansserif.plain.telugu=Lohit Telugu
+sansserif.plain.sinhala=LKLUG
-sansserif.bold.latin-1=DejaVu LGC Sans Bold
+sansserif.bold.latin-1=DejaVu Sans Bold
sansserif.bold.japanese-x0208=Sazanami Gothic
sansserif.bold.korean=Baekmuk Gulim
sansserif.bold.chinese-big5=AR PL ShanHeiSun Uni
sansserif.bold.chinese-gb18030=AR PL ShanHeiSun Uni
+sansserif.bold.bengali=Lohit Bengali
+sansserif.bold.gujarati=Lohit Gujarati
+sansserif.bold.hindi=Lohit Hindi
+sansserif.bold.malayalam=Lohit Malayalam
+sansserif.bold.oriya=Lohit Oriya
+sansserif.bold.punjabi=Lohit Punjabi
+sansserif.bold.tamil=Lohit Tamil
+sansserif.bold.telugu=Lohit Telugu
+sansserif.bold.sinhala=LKLUG
-sansserif.italic.latin-1=DejaVu LGC Sans Oblique
+sansserif.italic.latin-1=DejaVu Sans Oblique
sansserif.italic.japanese-x0208=Sazanami Gothic
sansserif.italic.korean=Baekmuk Gulim
sansserif.italic.chinese-big5=AR PL ShanHeiSun Uni
sansserif.italic.chinese-gb18030=AR PL ShanHeiSun Uni
+sansserif.italic.bengali=Lohit Bengali
+sansserif.italic.gujarati=Lohit Gujarati
+sansserif.italic.hindi=Lohit Hindi
+sansserif.italic.malayalam=Lohit Malayalam
+sansserif.italic.oriya=Lohit Oriya
+sansserif.italic.punjabi=Lohit Punjabi
+sansserif.italic.tamil=Lohit Tamil
+sansserif.italic.telugu=Lohit Telugu
+sansserif.italic.sinhala=LKLUG
-sansserif.bolditalic.latin-1=DejaVu LGC Sans Bold Oblique
+sansserif.bolditalic.latin-1=DejaVu Sans Bold Oblique
sansserif.bolditalic.japanese-x0208=Sazanami Gothic
sansserif.bolditalic.korean=Baekmuk Gulim
sansserif.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
sansserif.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-
+sansserif.bolditalic.bengali=Lohit Bengali
+sansserif.bolditalic.gujarati=Lohit Gujarati
+sansserif.bolditalic.hindi=Lohit Hindi
+sansserif.bolditalic.malayalam=Lohit Malayalam
+sansserif.bolditalic.oriya=Lohit Oriya
+sansserif.bolditalic.punjabi=Lohit Punjabi
+sansserif.bolditalic.tamil=Lohit Tamil
+sansserif.bolditalic.telugu=Lohit Telugu
+sansserif.bolditalic.sinhala=LKLUG
-serif.plain.latin-1=DejaVu LGC Serif
+serif.plain.latin-1=DejaVu Serif
serif.plain.japanese-x0208=Sazanami Mincho
serif.plain.korean=Baekmuk Batang
serif.plain.chinese-big5=AR PL ZenKai Uni
serif.plain.chinese-gb18030=AR PL ZenKai Uni
+serif.plain.bengali=Lohit Bengali
+serif.plain.gujarati=Lohit Gujarati
+serif.plain.hindi=Lohit Hindi
+serif.plain.malayalam=Lohit Malayalam
+serif.plain.oriya=Lohit Oriya
+serif.plain.punjabi=Lohit Punjabi
+serif.plain.tamil=Lohit Tamil
+serif.plain.telugu=Lohit Telugu
+serif.plain.sinhala=LKLUG
-serif.bold.latin-1=DejaVu LGC Serif Bold
+serif.bold.latin-1=DejaVu Serif Bold
serif.bold.japanese-x0208=Sazanami Mincho
serif.bold.korean=Baekmuk Batang
serif.bold.chinese-big5=AR PL ZenKai Uni
serif.bold.chinese-gb18030=AR PL ZenKai Uni
+serif.bold.bengali=Lohit Bengali
+serif.bold.gujarati=Lohit Gujarati
+serif.bold.hindi=Lohit Hindi
+serif.bold.malayalam=Lohit Malayalam
+serif.bold.oriya=Lohit Oriya
+serif.bold.punjabi=Lohit Punjabi
+serif.bold.tamil=Lohit Tamil
+serif.bold.telugu=Lohit Telugu
+serif.bold.sinhala=LKLUG
-serif.italic.latin-1=DejaVu LGC Serif Oblique
+serif.italic.latin-1=DejaVu Serif Oblique
serif.italic.japanese-x0208=Sazanami Mincho
serif.italic.korean=Baekmuk Batang
serif.italic.chinese-big5=AR PL ZenKai Uni
serif.italic.chinese-gb18030=AR PL ZenKai Uni
+serif.italic.bengali=Lohit Bengali
+serif.italic.gujarati=Lohit Gujarati
+serif.italic.hindi=Lohit Hindi
+serif.italic.malayalam=Lohit Malayalam
+serif.italic.oriya=Lohit Oriya
+serif.italic.punjabi=Lohit Punjabi
+serif.italic.tamil=Lohit Tamil
+serif.italic.telugu=Lohit Telugu
+serif.italic.sinhala=LKLUG
-serif.bolditalic.latin-1=DejaVu LGC Serif Bold Oblique
+serif.bolditalic.latin-1=DejaVu Serif Bold Oblique
serif.bolditalic.japanese-x0208=Sazanami Mincho
serif.bolditalic.korean=Baekmuk Batang
serif.bolditalic.chinese-big5=AR PL ZenKai Uni
serif.bolditalic.chinese-gb18030=AR PL ZenKai Uni
-
+serif.bolditalic.bengali=Lohit Bengali
+serif.bolditalic.gujarati=Lohit Gujarati
+serif.bolditalic.hindi=Lohit Hindi
+serif.bolditalic.malayalam=Lohit Malayalam
+serif.bolditalic.oriya=Lohit Oriya
+serif.bolditalic.punjabi=Lohit Punjabi
+serif.bolditalic.tamil=Lohit Tamil
+serif.bolditalic.telugu=Lohit Telugu
+serif.bolditalic.sinhala=LKLUG
-monospaced.plain.latin-1=DejaVu LGC Sans Mono
+monospaced.plain.latin-1=DejaVu Sans Mono
monospaced.plain.japanese-x0208=Sazanami Gothic
monospaced.plain.korean=Baekmuk Gulim
monospaced.plain.chinese-big5=AR PL ShanHeiSun Uni
monospaced.plain.chinese-gb18030=AR PL ShanHeiSun Uni
+monospaced.plain.bengali=Lohit Bengali
+monospaced.plain.gujarati=Lohit Gujarati
+monospaced.plain.hindi=Lohit Hindi
+monospaced.plain.malayalam=Lohit Malayalam
+monospaced.plain.oriya=Lohit Oriya
+monospaced.plain.punjabi=Lohit Punjabi
+monospaced.plain.tamil=Lohit Tamil
+monospaced.plain.telugu=Lohit Telugu
+monospaced.plain.sinhala=LKLUG
-monospaced.bold.latin-1=DejaVu LGC Sans Mono Bold
+monospaced.bold.latin-1=DejaVu Sans Mono Bold
monospaced.bold.japanese-x0208=Sazanami Gothic
monospaced.bold.korean=Baekmuk Gulim
monospaced.bold.chinese-big5=AR PL ShanHeiSun Uni
monospaced.bold.chinese-gb18030=AR PL ShanHeiSun Uni
+monospaced.bold.bengali=Lohit Bengali
+monospaced.bold.gujarati=Lohit Gujarati
+monospaced.bold.hindi=Lohit Hindi
+monospaced.bold.malayalam=Lohit Malayalam
+monospaced.bold.oriya=Lohit Oriya
+monospaced.bold.punjabi=Lohit Punjabi
+monospaced.bold.tamil=Lohit Tamil
+monospaced.bold.telugu=Lohit Telugu
+monospaced.bold.sinhala=LKLUG
-monospaced.italic.latin-1=DejaVu LGC Sans Mono Oblique
+monospaced.italic.latin-1=DejaVu Sans Mono Oblique
monospaced.italic.japanese-x0208=Sazanami Gothic
monospaced.italic.korean=Baekmuk Gulim
monospaced.italic.chinese-big5=AR PL ShanHeiSun Uni
monospaced.italic.chinese-gb18030=AR PL ShanHeiSun Uni
+monospaced.italic.bengali=Lohit Bengali
+monospaced.italic.gujarati=Lohit Gujarati
+monospaced.italic.hindi=Lohit Hindi
+monospaced.italic.malayalam=Lohit Malayalam
+monospaced.italic.oriya=Lohit Oriya
+monospaced.italic.punjabi=Lohit Punjabi
+monospaced.italic.tamil=Lohit Tamil
+monospaced.italic.telugu=Lohit Telugu
+monospaced.italic.sinhala=LKLUG
-monospaced.bolditalic.latin-1=DejaVu LGC Sans Mono Bold Oblique
+monospaced.bolditalic.latin-1=DejaVu Sans Mono Bold Oblique
monospaced.bolditalic.japanese-x0208=Sazanami Gothic
monospaced.bolditalic.korean=Baekmuk Gulim
monospaced.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
monospaced.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-
+monospaced.bolditalic.bengali=Lohit Bengali
+monospaced.bolditalic.gujarati=Lohit Gujarati
+monospaced.bolditalic.hindi=Lohit Hindi
+monospaced.bolditalic.malayalam=Lohit Malayalam
+monospaced.bolditalic.oriya=Lohit Oriya
+monospaced.bolditalic.punjabi=Lohit Punjabi
+monospaced.bolditalic.tamil=Lohit Tamil
+monospaced.bolditalic.telugu=Lohit Telugu
+monospaced.bolditalic.sinhala=LKLUG
-dialoginput.plain.latin-1=DejaVu LGC Sans Mono
+dialoginput.plain.latin-1=DejaVu Sans Mono
dialoginput.plain.japanese-x0208=Sazanami Gothic
dialoginput.plain.korean=Baekmuk Gulim
dialoginput.plain.chinese-big5=AR PL ShanHeiSun Uni
dialoginput.plain.chinese-gb18030=AR PL ShanHeiSun Uni
+dialoginput.plain.bengali=Lohit Bengali
+dialoginput.plain.gujarati=Lohit Gujarati
+dialoginput.plain.hindi=Lohit Hindi
+dialoginput.plain.malayalam=Lohit Malayalam
+dialoginput.plain.oriya=Lohit Oriya
+dialoginput.plain.punjabi=Lohit Punjabi
+dialoginput.plain.tamil=Lohit Tamil
+dialoginput.plain.telugu=Lohit Telugu
+dialoginput.plain.sinhala=LKLUG
-dialoginput.bold.latin-1=DejaVu LGC Sans Mono Bold
+dialoginput.bold.latin-1=DejaVu Sans Mono Bold
dialoginput.bold.japanese-x0208=Sazanami Gothic
dialoginput.bold.korean=Baekmuk Gulim
dialoginput.bold.chinese-big5=AR PL ShanHeiSun Uni
dialoginput.bold.chinese-gb18030=AR PL ShanHeiSun Uni
+dialoginput.bold.bengali=Lohit Bengali
+dialoginput.bold.gujarati=Lohit Gujarati
+dialoginput.bold.hindi=Lohit Hindi
+dialoginput.bold.malayalam=Lohit Malayalam
+dialoginput.bold.oriya=Lohit Oriya
+dialoginput.bold.punjabi=Lohit Punjabi
+dialoginput.bold.tamil=Lohit Tamil
+dialoginput.bold.telugu=Lohit Telugu
+dialoginput.bold.sinhala=LKLUG
-dialoginput.italic.latin-1=DejaVu LGC Sans Mono Oblique
+dialoginput.italic.latin-1=DejaVu Sans Mono Oblique
dialoginput.italic.japanese-x0208=Sazanami Gothic
dialoginput.italic.korean=Baekmuk Gulim
dialoginput.italic.chinese-big5=AR PL ShanHeiSun Uni
dialoginput.italic.chinese-gb18030=AR PL ShanHeiSun Uni
+dialoginput.italic.bengali=Lohit Bengali
+dialoginput.italic.gujarati=Lohit Gujarati
+dialoginput.italic.hindi=Lohit Hindi
+dialoginput.italic.malayalam=Lohit Malayalam
+dialoginput.italic.oriya=Lohit Oriya
+dialoginput.italic.punjabi=Lohit Punjabi
+dialoginput.italic.tamil=Lohit Tamil
+dialoginput.italic.telugu=Lohit Telugu
+dialoginput.italic.sinhala=LKLUG
-dialoginput.bolditalic.latin-1=DejaVu LGC Sans Mono Bold Oblique
+dialoginput.bolditalic.latin-1=DejaVu Sans Mono Bold Oblique
dialoginput.bolditalic.japanese-x0208=Sazanami Gothic
dialoginput.bolditalic.korean=Baekmuk Gulim
dialoginput.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
dialoginput.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
+dialoginput.bolditalic.bengali=Lohit Bengali
+dialoginput.bolditalic.gujarati=Lohit Gujarati
+dialoginput.bolditalic.hindi=Lohit Hindi
+dialoginput.bolditalic.malayalam=Lohit Malayalam
+dialoginput.bolditalic.oriya=Lohit Oriya
+dialoginput.bolditalic.punjabi=Lohit Punjabi
+dialoginput.bolditalic.tamil=Lohit Tamil
+dialoginput.bolditalic.telugu=Lohit Telugu
+dialoginput.bolditalic.sinhala=LKLUG
# Search Sequences
@@ -162,28 +338,40 @@
sequence.allfonts.x-euc-jp-linux=japanese-x0208,latin-1
sequence.allfonts.EUC-KR=korean,latin-1
sequence.allfonts.GB18030=chinese-gb18030,latin-1
-sequence.fallback=chinese-big5,chinese-gb18030,japanese-x0208,korean
+sequence.fallback=chinese-big5,chinese-gb18030,japanese-x0208,korean,bengali,gujarati,hindi,oriya,punjabi,malayalam,tamil,telugu,sinhala
# Font File Names
-filename.DejaVu_LGC_Sans=/usr/share/fonts/dejavu-lgc/DejaVuLGCSans.ttf
-filename.DejaVu_LGC_Sans_Bold=/usr/share/fonts/dejavu-lgc/DejaVuLGCSans-Bold.ttf
-filename.DejaVu_LGC_Sans_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSans-Oblique.ttf
-filename.DejaVu_LGC_Sans_Bold_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSans-BoldOblique.ttf
+filename.DejaVu_Sans=/usr/share/fonts/dejavu/DejaVuSans.ttf
+filename.DejaVu_Sans_Bold=/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf
+filename.DejaVu_Sans_Oblique=/usr/share/fonts/dejavu/DejaVuSans-Oblique.ttf
+filename.DejaVu_Sans_Bold_Oblique=/usr/share/fonts/dejavu/DejaVuSans-BoldOblique.ttf
-filename.DejaVu_LGC_Sans_Mono=/usr/share/fonts/dejavu-lgc/DejaVuLGCSansMono.ttf
-filename.DejaVu_LGC_Sans_Mono_Bold=/usr/share/fonts/dejavu-lgc/DejaVuLGCSansMono-Bold.ttf
-filename.DejaVu_LGC_Sans_Mono_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSansMono-Oblique.ttf
-filename.DejaVu_LGC_Sans_Mono_Bold_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSansMono-BoldOblique.ttf
+filename.DejaVu_Sans_Mono=/usr/share/fonts/dejavu/DejaVuSansMono.ttf
+filename.DejaVu_Sans_Mono_Bold=/usr/share/fonts/dejavu/DejaVuSansMono-Bold.ttf
+filename.DejaVu_Sans_Mono_Oblique=/usr/share/fonts/dejavu/DejaVuSansMono-Oblique.ttf
+filename.DejaVu_Sans_Mono_Bold_Oblique=/usr/share/fonts/dejavu/DejaVuSansMono-BoldOblique.ttf
+
+filename.DejaVu_Serif=/usr/share/fonts/dejavu/DejaVuSerif.ttf
+filename.DejaVu_Serif_Bold=/usr/share/fonts/dejavu/DejaVuSerif-Bold.ttf
+filename.DejaVu_Serif_Oblique=/usr/share/fonts/dejavu/DejaVuSerif-Oblique.ttf
+filename.DejaVu_Serif_Bold_Oblique=/usr/share/fonts/dejavu/DejaVuSerif-BoldOblique.ttf
-filename.DejaVu_LGC_Serif=/usr/share/fonts/dejavu-lgc/DejaVuLGCSerif.ttf
-filename.DejaVu_LGC_Serif_Bold=/usr/share/fonts/dejavu-lgc/DejaVuLGCSerif-Bold.ttf
-filename.DejaVu_LGC_Serif_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSerif-Oblique.ttf
-filename.DejaVu_LGC_Serif_Bold_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSerif-BoldOblique.ttf
+filename.Sazanami_Gothic=/usr/share/fonts/sazanami-fonts-gothic/sazanami-gothic.ttf
+filename.Sazanami_Mincho=/usr/share/fonts/sazanami-fonts-mincho/sazanami-mincho.ttf
+filename.AR_PL_ShanHeiSun_Uni=/usr/share/fonts/cjkunifonts-uming/uming.ttc
+filename.AR_PL_ZenKai_Uni=/usr/share/fonts/cjkunifonts-ukai/ukai.ttc
+filename.Baekmuk_Gulim=/usr/share/fonts/baekmuk-ttf-gulim/gulim.ttf
+filename.Baekmuk_Batang=/usr/share/fonts/baekmuk-ttf-batang/batang.ttf
-filename.Sazanami_Gothic=/usr/share/fonts/japanese/TrueType/sazanami-gothic.ttf
-filename.Sazanami_Mincho=/usr/share/fonts/japanese/TrueType/sazanami-mincho.ttf
-filename.AR_PL_ShanHeiSun_Uni=/usr/share/fonts/chinese/TrueType/uming.ttf
-filename.AR_PL_ZenKai_Uni=/usr/share/fonts/chinese/TrueType/ukai.ttf
-filename.Baekmuk_Gulim=/usr/share/fonts/korean/TrueType/gulim.ttf
-filename.Baekmuk_Batang=/usr/share/fonts/korean/TrueType/batang.ttf
+filename.Lohit_Bengali=/usr/share/fonts/lohit-bengali/lohit_bn.ttf
+filename.Lohit_Gujarati=/usr/share/fonts/lohit-gujarati/lohit_gu.ttf
+filename.Lohit_Hindi=/usr/share/fonts/lohit-hindi/lohit_hi.ttf
+filename.Lohit_Kannda=/usr/share/fonts/lohit-kannada/lohit_kn.ttf
+filename.Lohit_Malayalam=/usr/share/fonts/lohit-malayalam/lohit_ml.ttf
+filename.Lohit_Oriya=/usr/share/fonts/lohit-oriya/lohit_or.ttf
+filename.Lohit_Punjabi=/usr/share/fonts/lohit-punjabi/lohit_pa.ttf
+filename.Lohit_Tamil=/usr/share/fonts/lohit-tamil/lohit_ta.ttf
+filename.Lohit_Telugu=/usr/share/fonts/lohit-telugu/lohit_te.ttf
+filename.LKLUG=/usr/share/fonts/lklug/lklug.ttf
+
--- a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Ubuntu.properties Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Ubuntu.properties Sat Apr 17 08:12:00 2010 -0700
@@ -26,106 +26,253 @@
# Version
-# Uses Ubuntu 6.10 (Edgy) fonts and file paths.
+# Uses Ubuntu 8.04 (hardy), Debian 6.0 (Squeeze) (and more recent releases) fonts and file paths.
version=1
# Component Font Mappings
-dialog.plain.latin-1=DejaVu Sans
-dialog.plain.japanese-x0208=Kochi Gothic
-dialog.plain.korean=Baekmuk Dotum
-
-dialog.bold.latin-1=DejaVu Sans Bold
-dialog.bold.japanese-x0208=Kochi Gothic
-dialog.bold.korean=Baekmuk Dotum
-
-dialog.italic.latin-1=DejaVu Sans Oblique
-dialog.italic.japanese-x0208=Kochi Gothic
-dialog.italic.korean=Baekmuk Dotum
-
-dialog.bolditalic.latin-1=DejaVu Sans Bold Oblique
-dialog.bolditalic.japanese-x0208=Kochi Gothic
-dialog.bolditalic.korean=Baekmuk Dotum
+# Chinese fonts
+allfonts.umingcn=AR PL UMing CN
+#allfonts.umingcn.motif=AR PL UMing CN
+allfonts.uminghk=AR PL UMing HK
+#allfonts.uminghk.motif=AR PL UMing HK
+allfonts.umingtw=AR PL UMing TW
+#allfonts.umingtw.motif=AR PL UMing TW
+allfonts.wqy-zenhei=WenQuanYi Zen Hei
+#allfonts.wqy-zenhei.motif=WenQuanYi Zen Hei
+allfonts.shanheisun=AR PL ShanHeiSun Uni
+#allfonts.shanheisun.motif=AR PL ShanHeiSun Uni
-
-sansserif.plain.latin-1=DejaVu Sans
-sansserif.plain.japanese-x0208=Kochi Gothic
-sansserif.plain.korean=Baekmuk Dotum
-
-sansserif.bold.latin-1=DejaVu Sans Bold
-sansserif.bold.japanese-x0208=Kochi Gothic
-sansserif.bold.korean=Baekmuk Dotum
-
-sansserif.italic.latin-1=DejaVu Sans Oblique
-sansserif.italic.japanese-x0208=Kochi Gothic
-sansserif.italic.korean=Baekmuk Dotum
-
-sansserif.bolditalic.latin-1=DejaVu Sans Bold Oblique
-sansserif.bolditalic.japanese-x0208=Kochi Gothic
-sansserif.bolditalic.korean=Baekmuk Dotum
+# Indic scripts
+allfonts.bengali=Lohit Bengali
+allfonts.gujarati=Lohit Gujarati
+allfonts.hindi=Lohit Hindi
+#allfonts.malayalam=Lohit Malayalam
+allfonts.oriya=Lohit Oriya
+allfonts.punjabi=Lohit Punjabi
+allfonts.tamil=Lohit Tamil
+allfonts.telugu=Lohit Telugu
+allfonts.sinhala=LKLUG
serif.plain.latin-1=DejaVu Serif
-serif.plain.japanese-x0208=Kochi Mincho
-serif.plain.korean=Baekmuk Batang
+#serif.plain.latin-1.motif=LuxiSerif-Regular
+serif.plain.japanese-kochi=Kochi Mincho
+serif.plain.japanese-sazanami=Sazanami Mincho
+serif.plain.japanese-vlgothic=Sazanami Mincho
+serif.plain.korean-baekmuk=Baekmuk Batang
+#serif.plain.korean-baekmuk.motif=Baekmuk Batang
+serif.plain.korean-un=UnBatang
+#serif.plain.korean-un.motif=UnBatang
serif.bold.latin-1=DejaVu Serif Bold
-serif.bold.japanese-x0208=Kochi Mincho
-serif.bold.korean=Baekmuk Batang
+#serif.bold.latin-1.motif=LuxiSerif-Bold
+serif.bold.japanese-kochi=Kochi Mincho
+serif.bold.japanese-sazanami=Sazanami Mincho
+serif.bold.japanese-vlgothic=Sazanami Mincho
+serif.bold.korean-baekmuk=Baekmuk Batang
+#serif.bold.korean-baekmuk.motif=Baekmuk Batang
+serif.bold.korean-un=UnBatang Bold
+#serif.bold.korean-un.motif=UnBatang Bold
serif.italic.latin-1=DejaVu Serif Oblique
-serif.italic.japanese-x0208=Kochi Mincho
-serif.italic.korean=Baekmuk Batang
+#serif.italic.latin-1.motif=LuxiSerif-Oblique
+serif.italic.japanese-kochi=Kochi Mincho
+serif.italic.japanese-sazanami=Sazanami Mincho
+serif.italic.japanese-vlgothic=Sazanami Mincho
+serif.italic.korean-baekmuk=Baekmuk Batang
+#serif.italic.korean-baekmuk.motif=Baekmuk Batang
+serif.italic.korean-un=UnBatang
+#serif.italic.korean-un.motif=UnBatang
serif.bolditalic.latin-1=DejaVu Serif Bold Oblique
-serif.bolditalic.japanese-x0208=Kochi Mincho
-serif.bolditalic.korean=Baekmuk Batang
+#serif.bolditalic.latin-1.motif=LuxiSerif-BoldOblique
+serif.bolditalic.japanese-kochi=Kochi Mincho
+serif.bolditalic.japanese-sazanami=Sazanami Mincho
+serif.bolditalic.japanese-vlgothic=Sazanami Mincho
+serif.bolditalic.korean-baekmuk=Baekmuk Batang
+#serif.bolditalic.korean-baekmuk.motif=Baekmuk Batang
+serif.bolditalic.korean-un=UnBatang Bold
+#serif.bolditalic.korean-un.motif=UnBatang Bold
+
+sansserif.plain.latin-1=DejaVu Sans
+#sansserif.plain.latin-1.motif=LuxiSans-Regular
+sansserif.plain.japanese-kochi=Kochi Gothic
+sansserif.plain.japanese-sazanami=Sazanami Gothic
+sansserif.plain.japanese-vlgothic=VL PGothic
+sansserif.plain.korean-baekmuk=Baekmuk Gulim
+#sansserif.plain.korean-baekmuk.motif=Baekmuk Gulim
+sansserif.plain.korean-un=UnDotum
+#sansserif.plain.korean-un.motif=UnDotum
+sansserif.bold.latin-1=DejaVu Sans Bold
+#sansserif.bold.latin-1.motif=LuxiSans-Bold
+sansserif.bold.japanese-kochi=Kochi Gothic
+sansserif.bold.japanese-sazanami=Sazanami Gothic
+sansserif.bold.japanese-vlgothic=VL PGothic
+sansserif.bold.korean-baekmuk=Baekmuk Gulim
+#sansserif.bold.korean-baekmuk.motif=Baekmuk Gulim
+sansserif.bold.korean-un=UnDotum Bold
+#sansserif.bold.korean-un.motif=UnDotum Bold
+
+sansserif.italic.latin-1=DejaVu Sans Oblique
+#sansserif.italic.latin-1.motif=LuxiSans-Oblique
+sansserif.italic.japanese-kochi=Kochi Gothic
+sansserif.italic.japanese-sazanami=Sazanami Gothic
+sansserif.italic.japanese-vlgothic=VL PGothic
+sansserif.italic.korean-baekmuk=Baekmuk Gulim
+#sansserif.italic.korean-baekmuk.motif=Baekmuk Gulim
+sansserif.italic.korean-un=UnDotum
+#sansserif.italic.korean-un.motif=UnDotum
+
+sansserif.bolditalic.latin-1=DejaVu Sans Bold Oblique
+#sansserif.bolditalic.latin-1.motif=LuxiSans-BoldOblique
+sansserif.bolditalic.japanese-kochi=Kochi Gothic
+sansserif.bolditalic.japanese-sazanami=Sazanami Gothic
+sansserif.bolditalic.japanese-vlgothic=VL PGothic
+sansserif.bolditalic.korean-baekmuk=Baekmuk Gulim
+#sansserif.bolditalic.korean-baekmuk.motif=Baekmuk Gulim
+sansserif.bolditalic.korean-un=UnDotum Bold
+#sansserif.bolditalic.korean-un.motif=UnDotum Bold
monospaced.plain.latin-1=DejaVu Sans Mono
-monospaced.plain.japanese-x0208=Kochi Gothic
-monospaced.plain.korean=Baekmuk Dotum
+#monospaced.plain.latin-1.motif=LuxiMono-Regular
+monospaced.plain.japanese-kochi=Kochi Gothic
+monospaced.plain.japanese-sazanami=Sazanami Gothic
+monospaced.plain.japanese-vlgothic=VL Gothic
+monospaced.plain.korean-baekmuk=Baekmuk Gulim
+#monospaced.plain.korean-baekmuk.motif=Baekmuk Gulim
+monospaced.plain.korean-un=UnDotum
+#monospaced.plain.korean-un.motif=UnDotum
monospaced.bold.latin-1=DejaVu Sans Mono Bold
-monospaced.bold.japanese-x0208=Kochi Gothic
-monospaced.bold.korean=Baekmuk Dotum
+#monospaced.bold.latin-1.motif=LuxiMono-Bold
+monospaced.bold.japanese-kochi=Kochi Gothic
+monospaced.bold.japanese-sazanami=Sazanami Gothic
+monospaced.bold.japanese-vlgothic=VL Gothic
+monospaced.bold.korean-baekmuk=Baekmuk Gulim
+#monospaced.bold.korean-baekmuk.motif=Baekmuk Gulim
+monospaced.bold.korean-un=UnDotum Bold
+#monospaced.bold.korean-un.motif=UnDotum Bold
monospaced.italic.latin-1=DejaVu Sans Mono Oblique
-monospaced.italic.japanese-x0208=Kochi Gothic
-monospaced.italic.korean=Baekmuk Dotum
+#monospaced.italic.latin-1.motif=LuxiMono-Oblique
+monospaced.italic.japanese-kochi=Kochi Gothic
+monospaced.italic.japanese-sazanami=Sazanami Gothic
+monospaced.italic.japanese-vlgothic=VL Gothic
+monospaced.italic.korean-baekmuk=Baekmuk Gulim
+#monospaced.italic.korean-baekmuk.motif=Baekmuk Gulim
+monospaced.italic.korean-un=UnDotum
+#monospaced.italic.korean-un.motif=UnDotum
monospaced.bolditalic.latin-1=DejaVu Sans Mono Bold Oblique
-monospaced.bolditalic.japanese-x0208=Kochi Gothic
-monospaced.bolditalic.korean=Baekmuk Dotum
+#monospaced.bolditalic.latin-1.motif=LuxiMono-BoldOblique
+monospaced.bolditalic.japanese-kochi=Kochi Gothic
+monospaced.bolditalic.japanese-sazanami=Sazanami Gothic
+monospaced.bolditalic.japanese-vlgothic=VL Gothic
+monospaced.bolditalic.korean-baekmuk=Baekmuk Gulim
+#monospaced.bolditalic.korean-baekmuk.motif=Baekmuk Gulim
+monospaced.bolditalic.korean-un=UnDotum Bold
+#monospaced.bolditalic.korean-un.motif=UnDotum Bold
+
+dialog.plain.latin-1=DejaVu Sans
+#dialog.plain.latin-1.motif=LuxiSans-Regular
+dialog.plain.japanese-kochi=Kochi Gothic
+dialog.plain.japanese-sazanami=Sazanami Gothic
+dialog.plain.japanese-vlgothic=VL PGothic
+dialog.plain.korean-baekmuk=Baekmuk Gulim
+#dialog.plain.korean-baekmuk.motif=Baekmuk Gulim
+dialog.plain.korean-un=UnDotum
+#dialog.plain.korean-un.motif=UnDotum
+dialog.bold.latin-1=DejaVu Sans Bold
+#dialog.bold.latin-1.motif=LuxiSans-Bold
+dialog.bold.japanese-kochi=Kochi Gothic
+dialog.bold.japanese-sazanami=Sazanami Gothic
+dialog.bold.japanese-vlgothic=VL PGothic
+dialog.bold.korean-baekmuk=Baekmuk Gulim
+#dialog.bold.korean-baekmuk.motif=Baekmuk Gulim
+dialog.bold.korean-un=UnDotum Bold
+#dialog.bold.korean-un.motif=UnDotum Bold
+
+dialog.italic.latin-1=DejaVu Sans Oblique
+#dialog.italic.latin-1.motif=LuxiSans-Oblique
+dialog.italic.japanese-kochi=Kochi Gothic
+dialog.italic.japanese-sazanami=Sazanami Gothic
+dialog.italic.japanese-vlgothic=VL PGothic
+dialog.italic.korean-baekmuk=Baekmuk Gulim
+#dialog.italic.korean-baekmuk.motif=Baekmuk Gulim
+dialog.italic.korean-un=UnDotum
+#dialog.italic.korean-un.motif=UnDotum
+
+dialog.bolditalic.latin-1=DejaVu Sans Bold Oblique
+#dialog.bolditalic.latin-1.motif=LuxiSans-BoldOblique
+dialog.bolditalic.japanese-kochi=Kochi Gothic
+dialog.bolditalic.japanese-sazanami=Sazanami Gothic
+dialog.bolditalic.japanese-vlgothic=VL PGothic
+dialog.bolditalic.korean-baekmuk=Baekmuk Gulim
+#dialog.bolditalic.korean-baekmuk.motif=Baekmuk Gulim
+dialog.bolditalic.korean-un=UnDotum Bold
+#dialog.bolditalic.korean-un.motif=UnDotum Bold
dialoginput.plain.latin-1=DejaVu Sans Mono
-dialoginput.plain.japanese-x0208=Kochi Gothic
-dialoginput.plain.korean=Baekmuk Dotum
+#dialoginput.plain.latin-1.motif=LuxiMono-Regular
+dialoginput.plain.japanese-kochi=Kochi Gothic
+dialoginput.plain.japanese-sazanami=Sazanami Gothic
+dialoginput.plain.japanese-vlgothic=VL Gothic
+dialoginput.plain.korean-baekmuk=Baekmuk Gulim
+#dialoginput.plain.korean-baekmuk.motif=Baekmuk Gulim
+dialoginput.plain.korean-un=UnDotum
+#dialoginput.plain.korean-un.motif=UnDotum
dialoginput.bold.latin-1=DejaVu Sans Mono Bold
-dialoginput.bold.japanese-x0208=Kochi Gothic
-dialoginput.bold.korean=Baekmuk Dotum
+#dialoginput.bold.latin-1.motif=LuxiMono-Bold
+dialoginput.bold.japanese-kochi=Kochi Gothic
+dialoginput.bold.japanese-sazanami=Sazanami Gothic
+dialoginput.bold.japanese-vlgothic=VL Gothic
+dialoginput.bold.korean-baekmuk=Baekmuk Gulim
+#dialoginput.bold.korean-baekmuk.motif=Baekmuk Gulim
+dialoginput.bold.korean-un=UnDotum Bold
+#dialoginput.bold.korean-un.motif=UnDotum Bold
dialoginput.italic.latin-1=DejaVu Sans Mono Oblique
-dialoginput.italic.japanese-x0208=Kochi Gothic
-dialoginput.italic.korean=Baekmuk Dotum
+#dialoginput.italic.latin-1.motif=LuxiMono-Oblique
+dialoginput.italic.japanese-kochi=Kochi Gothic
+dialoginput.italic.japanese-sazanami=Sazanami Gothic
+dialoginput.italic.japanese-vlgothic=VL Gothic
+dialoginput.italic.korean-baekmuk=Baekmuk Gulim
+#dialoginput.italic.korean-baekmuk.motif=Baekmuk Gulim
+dialoginput.italic.korean-un=UnDotum
+#dialoginput.italic.korean-un.motif=UnDotum
dialoginput.bolditalic.latin-1=DejaVu Sans Mono Bold Oblique
-dialoginput.bolditalic.japanese-x0208=Kochi Gothic
-dialoginput.bolditalic.korean=Baekmuk Dotum
-
-allfonts.chinese-big5=AR PL ZenKai Uni
-allfonts.chinese-gb18030=AR PL ZenKai Uni
+#dialoginput.bolditalic.latin-1.motif=LuxiMono-BoldOblique
+dialoginput.bolditalic.japanese-kochi=Kochi Gothic
+dialoginput.bolditalic.japanese-sazanami=Sazanami Gothic
+dialoginput.bolditalic.japanese-vlgothic=VL Gothic
+dialoginput.bolditalic.korean-baekmuk=Baekmuk Gulim
+#dialoginput.bolditalic.korean-baekmuk.motif=Baekmuk Gulim
+dialoginput.bolditalic.korean-un=UnDotum Bold
+#dialoginput.bolditalic.korean-un.motif=UnDotum Bold
# Search Sequences
sequence.allfonts=latin-1
-sequence.allfonts.Big5=chinese-big5,latin-1
-sequence.allfonts.x-euc-jp-linux=japanese-x0208,latin-1
-sequence.allfonts.EUC-KR=korean,latin-1
-sequence.allfonts.GB18030=chinese-gb18030,latin-1
-sequence.fallback=chinese-big5,chinese-gb18030,japanese-x0208,korean
+sequence.allfonts.GB18030=latin-1,umingcn,shanheisun,wqy-zenhei
+sequence.allfonts.GB2312=latin-1,umingcn,shanheisun,wqy-zenhei
+sequence.allfonts.GBK=latin-1,umingcn,shanheisun,wqy-zenhei
+sequence.allfonts.x-euc-jp-linux=latin-1,japanese-vlgothic,japanese-sazanami,japanese-kochi
+sequence.allfonts.EUC-KR=latin-1,korean-un,korean-baekmuk
+sequence.allfonts.Big5=latin-1,umingtw,shanheisun,wqy-zenhei
+sequence.allfonts.Big5-HKSCS=latin-1,uminghk,shanheisun,wqy-zenhei
+#sequence.fallback=uminghk,shanheisun,wqy-zenhei,japanese-vlgothic,japanese-kochi,japanese-sazanami,korean-un,korean-baekmuk,bengali,gujarati,hindi,oriya,punjabi,malayalam,tamil,telugu,sinhala
+sequence.fallback=uminghk,shanheisun,wqy-zenhei,japanese-vlgothic,japanese-sazanami,japanese-kochi,korean-un,korean-baekmuk,bengali,gujarati,hindi,oriya,punjabi,tamil,telugu
+
+# Exclusion Ranges
+
+exclusion.japanese-kochi=0390-03d6,2200-22ef,2701-27be
+exclusion.japanese-sazanami=0390-03d6,2200-22ef,2701-27be
+exclusion.japanese-vlgothic=0390-03d6,2200-22ef,2701-27be
# Font File Names
@@ -144,8 +291,58 @@
filename.DejaVu_Serif_Oblique=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Oblique.ttf
filename.DejaVu_Serif_Bold_Oblique=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-BoldOblique.ttf
-filename.Kochi_Gothic=/usr/share/fonts/truetype/kochi/kochi-gothic-subst.ttf
-filename.Kochi_Mincho=/usr/share/fonts/truetype/kochi/kochi-mincho-subst.ttf
-filename.AR_PL_ZenKai_Uni=/usr/share/fonts//truetype/arphic/ukai.ttf
-filename.Baekmuk_Dotum=/usr/share/fonts/truetype/baekmuk/dotum.ttf
+filename.AR_PL_UMing_CN=/usr/share/fonts/truetype/arphic/uming.ttc
+filename.AR_PL_UMing_HK=/usr/share/fonts/truetype/arphic/uming.ttc
+filename.AR_PL_UMing_TW=/usr/share/fonts/truetype/arphic/uming.ttc
+filename.AR_PL_ShanHeiSun_Uni=/usr/share/fonts/truetype/arphic/uming.ttf
+
+filename.WenQuanYi_Zen_Hei=/usr/share/fonts/truetype/wqy/wqy-zenhei.ttf
filename.Baekmuk_Batang=/usr/share/fonts/truetype/baekmuk/batang.ttf
+filename.UnBatang=/usr/share/fonts/truetype/unfonts/UnBatang.ttf
+filename.UnBatang_Bold=/usr/share/fonts/truetype/unfonts/UnBatangBold.ttf
+filename.Baekmuk_Gulim=/usr/share/fonts/truetype/baekmuk/gulim.ttf
+filename.UnDotum=/usr/share/fonts/truetype/unfonts/UnDotum.ttf
+filename.UnDotum_Bold=/usr/share/fonts/truetype/unfonts/UnDotumBold.ttf
+filename.Kochi_Gothic=/usr/share/fonts/truetype/kochi/kochi-gothic.ttf
+filename.Sazanami_Gothic=/usr/share/fonts/truetype/sazanami/sazanami-gothic.ttf
+filename.Kochi_Mincho=/usr/share/fonts/truetype/kochi/kochi-mincho.ttf
+filename.Sazanami_Mincho=/usr/share/fonts/truetype/sazanami/sazanami-mincho.ttf
+filename.VL_Gothic=/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf
+filename.VL_PGothic=/usr/share/fonts/truetype/vlgothic/VL-PGothic-Regular.ttf
+
+filename.Lohit_Bengali=/usr/share/fonts/truetype/ttf-bengali-fonts/lohit_bn.ttf
+filename.Lohit_Gujarati=/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_gu.ttf
+filename.Lohit_Hindi=/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_hi.ttf
+filename.Lohit_Kannda=/usr/share/fonts/truetype/ttf-kannada-fonts/lohit_kn.ttf
+#filename.Lohit_Malayalam=/usr/share/fonts/lohit-malayalam/lohit_ml.ttf
+filename.Lohit_Oriya=/usr/share/fonts/truetype/ttf-oriya-fonts/lohit_or.ttf
+filename.Lohit_Punjabi=/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_pa.ttf
+filename.Lohit_Tamil=/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_ta.ttf
+filename.Lohit_Telugu=/usr/share/fonts/truetype/ttf-telugu-fonts/lohit_te.ttf
+filename.LKLUG=/usr/share/fonts/truetype/ttf-sinhala-lklug/lklug.ttf
+
+filename.LuxiSans-Regular=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxisr.ttf
+filename.LuxiSans-Bold=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxisb.ttf
+filename.LuxiSans-Oblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxisri.ttf
+filename.LuxiSans-BoldOblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxisbi.ttf
+filename.LuxiMono-Regular=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luximr.ttf
+filename.LuxiMono-Bold=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luximb.ttf
+filename.LuxiMono-Oblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luximri.ttf
+filename.LuxiMono-BoldOblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luximbi.ttf
+filename.LuxiSerif-Regular=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxirr.ttf
+filename.LuxiSerif-Bold=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxirb.ttf
+filename.LuxiSerif-Oblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxirri.ttf
+filename.LuxiSerif-BoldOblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxirbi.ttf
+
+# AWT X11 font paths
+awtfontpath.latin-1=/usr/share/fonts/X11/Type1
+awtfontpath.umingcn=/usr/share/fonts/truetype/arphic
+awtfontpath.uminghk=/usr/share/fonts/truetype/arphic
+awtfontpath.umingtw=/usr/share/fonts/truetype/arphic
+awtfontpath.shanheisun=/usr/share/fonts/truetype/arphic
+awtfontpath.wqy-zenhei=/usr/share/fonts/truetype/wqy
+awtfontpath.japanese-kochi=/usr/share/fonts/truetype/kochi
+awtfontpath.japanese-sazanami=/usr/share/fonts/truetype/sazanami
+awtfontpath.japanese-vlgothic=/usr/share/fonts/truetype/vlgothic
+awtfontpath.korean-baekmuk=/usr/share/fonts/truetype/baekmuk
+awtfontpath.korean-un=/usr/share/fonts/truetype/unfonts
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Fri Apr 16 09:54:13 2010 +0100
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Sat Apr 17 08:12:00 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2010 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
@@ -3707,8 +3707,7 @@
if (hIMC == NULL) {
return;
}
- COMPOSITIONFORM cf = {CFS_POINT, {0, r.bottom}, NULL};
- // Place the composition window right below the client Window
+ COMPOSITIONFORM cf = {CFS_DEFAULT, {0, 0}, {0, 0, 0, 0}};
ImmSetCompositionWindow(hIMC, &cf);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Statement/Test6707226.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 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 6707226
+ * @summary Tests the value updating in Expression
+ * @author Sergey Malenkov
+ */
+
+import java.beans.Expression;
+
+public class Test6707226 {
+ public static void main(String[] args) throws Exception {
+ Object value = new Object();
+
+ Expression expression = new Expression(value, Object.class, "new", null);
+ if (!value.equals(expression.getValue()))
+ throw new Error("the value is updated unexpectedly");
+
+ expression.execute();
+ if (value.equals(expression.getValue()))
+ throw new Error("the value is not updated as expected");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/synth/Test6933784.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 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 6933784
+ @summary NIMBUS: ImageView getNoImageIcon and getLoadingImageIcon returns nulls instead of an icon
+ @author Pavel Porvatov
+ @run main Test6933784
+*/
+
+import javax.swing.*;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+import javax.swing.plaf.synth.SynthLookAndFeel;
+import javax.swing.text.Element;
+import javax.swing.text.html.HTMLDocument;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.ImageView;
+import java.io.StringReader;
+
+public class Test6933784 {
+ public static void main(String[] args) throws Exception {
+ UIManager.setLookAndFeel(new SynthLookAndFeel());
+
+ checkImages();
+
+ UIManager.setLookAndFeel(new NimbusLookAndFeel());
+
+ checkImages();
+ }
+
+ private static void checkImages() throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ HTMLEditorKit c = new HTMLEditorKit();
+ HTMLDocument doc = new HTMLDocument();
+
+ try {
+ c.read(new StringReader("<HTML><TITLE>Test</TITLE><BODY><IMG id=test></BODY></HTML>"), doc, 0);
+ } catch (Exception e) {
+ throw new RuntimeException("The test failed", e);
+ }
+
+ Element elem = doc.getElement("test");
+ ImageView iv = new ImageView(elem);
+
+ if (iv.getLoadingImageIcon() == null) {
+ throw new RuntimeException("getLoadingImageIcon returns null");
+ }
+
+ if (iv.getNoImageIcon() == null) {
+ throw new RuntimeException("getNoImageIcon returns null");
+ }
+ }
+ });
+ }
+}
--- a/langtools/.hgtags Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/.hgtags Sat Apr 17 08:12:00 2010 -0700
@@ -60,3 +60,7 @@
c9f4ae1f1480e89aaf7e72173184089d9cea397a jdk7-b83
d9cd5b8286e44f3baf90da290cd295433e21c05a jdk7-b84
136bfc67946219fb02ee223984540a4a9c5b209f jdk7-b85
+ef07347428f2198ae6b8144ac0b9086bbe39fd16 jdk7-b86
+409db93d19c002333980df5b797c6b965150c7a0 jdk7-b87
+f9b5d4867a26f8c4b90ad37fe2c345b721e93d6b jdk7-b88
+6cea9a143208bc1185ced046942c0f4e45dbeba5 jdk7-b89
--- a/langtools/make/Makefile Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/make/Makefile Sat Apr 17 08:12:00 2010 -0700
@@ -188,10 +188,16 @@
# All ant targets of interest
ANT_TARGETS = build clean sanity post-sanity diagnostics # for now
+# Create diagnostics log (careful, ant 1.8.0 -diagnostics always does an exit 1)
+$(OUTPUTDIR)/build/ant-diagnostics.log:
+ @mkdir -p $(OUTPUTDIR)/build $(ANT_TMPDIR)
+ @$(RM) $@
+ $(ANT_JAVA_HOME) $(ANT_OPTS) $(ANT) -diagnostics > $@ ; \
+ $(ANT_JAVA_HOME) $(ANT_OPTS) $(ANT) -version >> $@
+
# Create a make target for each
-$(ANT_TARGETS):
+$(ANT_TARGETS): $(OUTPUTDIR)/build/ant-diagnostics.log
@ mkdir -p $(OUTPUTDIR)/build $(ANT_TMPDIR)
- $(ANT_JAVA_HOME) $(ANT_OPTS) $(ANT) -diagnostics > $(OUTPUTDIR)/build/ant-diagnostics.log
$(ANT_JAVA_HOME) $(ANT_OPTS) $(ANT) $(ANT_OPTIONS) $@
#-------------------------------------------------------------------
--- a/langtools/make/jprt.properties Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/make/jprt.properties Sat Apr 17 08:12:00 2010 -0700
@@ -50,6 +50,5 @@
jprt.test.targets=
# Directories needed to build
-jprt.bundle.src.dirs=make src
jprt.bundle.exclude.src.dirs=build dist
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java Sat Apr 17 08:12:00 2010 -0700
@@ -229,23 +229,24 @@
if (kind == ENUM) {
List<Element> enclosedElements =
new ArrayList<Element>(e.getEnclosedElements());
+ // Handle any enum constants specially before other entities.
List<Element> enumConstants = new ArrayList<Element>();
for(Element element : enclosedElements) {
if (element.getKind() == ENUM_CONSTANT)
enumConstants.add(element);
}
-
- int i;
- for(i = 0; i < enumConstants.size()-1; i++) {
+ if (!enumConstants.isEmpty()) {
+ int i;
+ for(i = 0; i < enumConstants.size()-1; i++) {
+ this.visit(enumConstants.get(i), true);
+ writer.print(",");
+ }
this.visit(enumConstants.get(i), true);
- writer.print(",");
- }
- if (i >= 0 ) {
- this.visit(enumConstants.get(i), true);
- writer.print(";");
+ writer.println(";\n");
+
+ enclosedElements.removeAll(enumConstants);
}
- enclosedElements.removeAll(enumConstants);
for(Element element : enclosedElements)
this.visit(element);
} else {
--- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Sat Apr 17 08:12:00 2010 -0700
@@ -318,12 +318,6 @@
int run(String[] args) {
try {
handleOptions(args);
- if (classes == null || classes.size() == 0) {
- if (help || version || fullVersion)
- return 0;
- else
- return 1;
- }
boolean ok = run();
return ok ? 0 : 1;
} catch (BadArgs e) {
@@ -355,7 +349,7 @@
fileManager = getDefaultFileManager(diagnosticListener, log);
Iterator<String> iter = args.iterator();
- boolean noArgs = !iter.hasNext();
+ noArgs = !iter.hasNext();
while (iter.hasNext()) {
String arg = iter.next();
@@ -416,9 +410,9 @@
Util util = new Util(log, diagnosticListener);
- if (help) {
+ if (noArgs || help) {
showHelp();
- return true;
+ return help; // treat noArgs as an error for purposes of exit code
}
if (version || fullVersion) {
@@ -636,6 +630,7 @@
String usercp;
List<String> classes;
boolean verbose;
+ boolean noArgs;
boolean help;
boolean trace;
boolean version;
--- a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java Sat Apr 17 08:12:00 2010 -0700
@@ -225,15 +225,15 @@
writeModifiers(flags.getFieldModifiers());
Signature_attribute sigAttr = getSignature(f.attributes);
if (sigAttr == null)
- print(getFieldType(f.descriptor));
+ print(getJavaFieldType(f.descriptor));
else {
try {
Type t = sigAttr.getParsedSignature().getType(constant_pool);
- print(t);
+ print(getJavaName(t.toString()));
} catch (ConstantPoolException e) {
// report error?
// fall back on non-generic descriptor
- print(getFieldType(f.descriptor));
+ print(getJavaFieldType(f.descriptor));
}
}
print(" ");
@@ -314,14 +314,14 @@
}
if (getName(m).equals("<init>")) {
print(getJavaName(classFile));
- print(getParameterTypes(d, flags));
+ print(getJavaParameterTypes(d, flags));
} else if (getName(m).equals("<clinit>")) {
print("{}");
} else {
- print(getReturnType(d));
+ print(getJavaReturnType(d));
print(" ");
print(getName(m));
- print(getParameterTypes(d, flags));
+ print(getJavaParameterTypes(d, flags));
}
Attribute e_attr = m.attributes.get(Attribute.Exceptions);
@@ -460,9 +460,9 @@
}
}
- String getFieldType(Descriptor d) {
+ String getJavaFieldType(Descriptor d) {
try {
- return d.getFieldType(constant_pool);
+ return getJavaName(d.getFieldType(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
@@ -470,9 +470,9 @@
}
}
- String getReturnType(Descriptor d) {
+ String getJavaReturnType(Descriptor d) {
try {
- return d.getReturnType(constant_pool);
+ return getJavaName(d.getReturnType(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
@@ -480,9 +480,9 @@
}
}
- String getParameterTypes(Descriptor d, AccessFlags flags) {
+ String getJavaParameterTypes(Descriptor d, AccessFlags flags) {
try {
- return adjustVarargs(flags, d.getParameterTypes(constant_pool));
+ return getJavaName(adjustVarargs(flags, d.getParameterTypes(constant_pool)));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
--- a/langtools/test/Makefile Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/Makefile Sat Apr 17 08:12:00 2010 -0700
@@ -1,6 +1,20 @@
#
-# Makefile to run jtreg and any other tests
+# Makefile to run jtreg and other tests
+#
+
+# Product builds and langtools builds
+#
+# A full product build (or "control" build) creates a complete JDK image.
+# To test a product build, set TESTJAVA to the path for the image.
#
+# A langtools build just builds the langtools components of a JDK.
+# To test a langtools build, set TESTJAVA to the path for a recent JDK
+# build, and set TESTBOOTCLASSPATH to the compiled langtools classes --
+# for example build/classes or dist/lib/classes.jar.
+
+# JPRT
+# JPRT may invoke this Makefile directly, as part of a langtools build,
+# or indirectly, via FOREST/test/Makefile, as part of a control build.
# Get OS/ARCH specifics
OSNAME = $(shell uname -s)
@@ -41,8 +55,11 @@
# Root of this test area (important to use full paths in some places)
TEST_ROOT := $(shell pwd)
-# Default bundle of all test results (passed or not)
-JPRT_ARCHIVE_BUNDLE=$(TEST_ROOT)/JPRT_ARCHIVE_BUNDLE.zip
+# Default bundle of all test results (passed or not) (JPRT only)
+ifdef JPRT_JOB_ID
+ JPRT_CLEAN = clean
+ JPRT_ARCHIVE_BUNDLE = $(TEST_ROOT)/JPRT_ARCHIVE_BUNDLE.zip
+endif
ifeq ($(PLATFORM), windows)
SLASH_JAVA = J:
@@ -57,8 +74,21 @@
JTREG_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
endif
JTREG = $(JTREG_HOME)/$(JT_PLATFORM)/bin/jtreg
+JTDIFF = $(JTREG_HOME)/$(JT_PLATFORM)/bin/jtdiff
-# Default JDK for JTREG
+# Default JCK to run
+ifdef JPRT_JCK_HOME
+ JCK_HOME = $(JPRT_JCK_HOME)
+else
+ JCK_HOME = $(SLASH_JAVA)/re/jck/7/promoted/latest/binaries
+endif
+
+# Default JDK for JTREG and JCK
+#
+# JT_JAVA is the version of java used to run jtreg/JCK. Since it is now
+# standard to execute tests in sameVM mode, it should normally be set the
+# same as TESTJAVA (although not necessarily so.)
+#
ifdef JPRT_JAVA_HOME
JT_JAVA = $(JPRT_JAVA_HOME)
else
@@ -72,49 +102,275 @@
TESTJAVA = $(SLASH_JAVA)/re/jdk/1.7.0/promoted/latest/binaries/$(PLATFORM)-$(ARCH)
endif
-TESTBOOTCLASSPATH = $(PRODUCT_HOME)/dist/lib/classes.jar
+# PRODUCT_HOME is a JPRT variable pointing to a directory containing the output from
+# make/Makefile
+# For langtools, this is a directory containing build and dist
+# For a control build, this is build/$(PRODUCT)-$(ARCH)/j2sdk-image
+ifdef PRODUCT_HOME
+ ifeq ($(shell [ -r $(PRODUCT_HOME)/dist/lib/classes.jar ]; echo $$?),0)
+ TESTBOOTCLASSPATH = $(PRODUCT_HOME)/dist/lib/classes.jar
+ endif
+ ifeq ($(shell [ -r $(PRODUCT_HOME)/lib/tools.jar ]; echo $$?),0)
+ TESTJAVA = $(PRODUCT_HOME)
+ endif
+endif
+
+ifdef TESTBOOTCLASSPATH
+ JTREG_OPTIONS += -Xbootclasspath/p:$(TESTBOOTCLASSPATH)
+### In the following, -refvmoptions is an undocumented option
+### The following does not work JCK 7 b30 2/6/2010. Awaiting b31.
+ JCK_OPTIONS += \
+ -vmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH) \
+ -refvmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH)
+endif
+
+# Concurrency is the number of tests that can execute at once.
+# Supported for JCK, not supported for jtreg.
+# On an otherwise empty machine, suggest setting to (#cpus + 2)
+# If unset, the default is (#cpus)
+### RFE: determine and use #cpus
+ifdef JCK_CONCURRENCY
+ JCK_OPTIONS += -concurrency:$(JCK_CONCURRENCY)
+endif
+
+# JCK is executed using "Multi-JVM Group Mode", which is a hybrid
+# of otherVM and sameVM modes. New JVMs are created and reused for
+# a number of tests, then eventually discarded and a new one started.
+# This amortizes the JVM startup time. The "group size" defines
+# how many tests are run in a JVM before it is replaced.
+# If unset, the default is 100.
+JCK_GROUP_SIZE = 1000
+ifdef JCK_GROUP_SIZE
+ JCK_COMPILER_OPTIONS += \
+ -jtoptions:-Ejck.env.compiler.testCompile.groupMode.groupSize=$(JCK_GROUP_SIZE) \
+ -jtoptions:-Ejck.env.compiler.compRefExecute.groupMode.groupSize=$(JCK_GROUP_SIZE)
+### The following is not supported. Awaiting RFE 6924287
+### 6924287: Jck4Jdk: Allow to configure test group size for group mode via simple command line option
+### JCK_RUNTIME_OPTIONS += \
+### -jtoptions:-Ejck.env.runtime.testCompile.groupMode.groupSize=$(JCK_GROUP_SIZE)
+endif
+
+# Assertions: some tests show failures when assertions are enabled.
+# Since javac is typically loaded via the bootclassloader (either via TESTJAVA
+# or TESTBOOTCLASSPATH), you may need -esa to enable assertions in javac.
+JTREG_OPTIONS += $(ASSERTION_OPTIONS)
+JCK_OPTIONS += $(ASSERTION_OPTIONS:%=-vmoptions:%)
+
+# Include shared options
+JCK_COMPILER_OPTIONS += $(JCK_OPTIONS)
+JCK_RUNTIME_OPTIONS += $(JCK_OPTIONS)
+
+# Exit codes:
+# jtreg, jck: 0: OK, 1: tests failed, 2: tests error; 3+: SERIOUS
+FATAL_JTREG_EXIT = 3
+FATAL_JCK_EXIT = 3
+# jtdiff: 0: OK, 1: differences found; 2+: SERIOUS
+FATAL_JTDIFF_EXIT = 2
+#
+# Exit -- used for final "normal" exit from "make". Redefine to "true" to avoid
+# having make exit with non-zero return code.
+EXIT = exit
+# Function to exit shell if exit code of preceding command is greater than or equal
+# to a given level. Redefine function or preceding FATAL_*_EXIT codes as needed.
+EXIT_IF_FATAL = status=$$?; if [ $$status -ge $(1) ]; then exit $$status ; fi
# The test directories to run
DEFAULT_TESTDIRS = .
TESTDIRS = $(DEFAULT_TESTDIRS)
# Root of all test results
-TEST_OUTPUT_DIR = $(TEST_ROOT)/o_$(PLATFORM)-$(ARCH)
+TEST_OUTPUT_DIR = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)/test/langtools
+ABS_TEST_OUTPUT_DIR := \
+ $(shell mkdir -p $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)/test/langtools; \
+ cd $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)/test/langtools; \
+ pwd )
+# Subdirectories for different test runs
+JTREG_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jtreg
+JCK_COMPILER_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-compiler
+JCK_RUNTIME_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-runtime-Xcompile
-# Default make rule
-all apt javac javadoc javah javap: clean check jtreg-tests $(JPRT_ARCHIVE_BUNDLE)
+# Default make rule -- warning, may take a while
+all: $(JPRT_CLEAN) jtreg-tests jck-compiler-tests jck-runtime-tests $(JPRT_ARCHIVE_BUNDLE) all-summary
+ @echo "Testing completed successfully"
+
+jtreg apt javac javadoc javah javap: $(JPRT_CLEAN) jtreg-tests $(JPRT_ARCHIVE_BUNDLE) jtreg-summary
+ @echo "Testing completed successfully"
+
+jck-compiler: $(JPRT_CLEAN) jck-compiler-tests $(JPRT_ARCHIVE_BUNDLE) jck-compiler-summary
+ @echo "Testing completed successfully"
+
+jck-runtime: $(JPRT_CLEAN) jck-runtime-tests $(JPRT_ARCHIVE_BUNDLE) jck-runtime-summary
@echo "Testing completed successfully"
# for use with JPRT -testrule
-all: TESTDIRS = .
-apt: TESTDIRS = tools/apt
-javac: TESTDIRS = tools/javac
-javadoc: TESTDIRS = tools/javadoc com/sun/javadoc
-javah: TESTDIRS = tools/javah
-javap: TESTDIRS = tools/javap
+all: JTREG_TESTDIRS = .
+jtreg: JTREG_TESTDIRS = .
+apt: JTREG_TESTDIRS = tools/apt
+javac: JTREG_TESTDIRS = tools/javac
+javadoc: JTREG_TESTDIRS = tools/javadoc com/sun/javadoc
+javah: JTREG_TESTDIRS = tools/javah
+javap: JTREG_TESTDIRS = tools/javap
+
+# Run jtreg tests
+#
+# JTREG_HOME
+# Installed location of jtreg
+# JT_JAVA
+# Version of java used to run jtreg. Should normally be the same as TESTJAVA
+# TESTJAVA
+# Version of java to be tested.
+# JTREG_OPTIONS
+# Additional options for jtreg
+# JTREG_TESTDIRS
+# Directories of tests to be run
+# JTREG_OUTPUT_DIR
+# Where to write the results
+# JTREG_REFERENCE
+# (Optional) reference results (e.g. work, report or summary.txt)
+#
+jtreg-tests: check-jtreg FRC
+ @rm -f -r $(JTREG_OUTPUT_DIR)/JTwork $(JTREG_OUTPUT_DIR)/JTreport \
+ $(JTREG_OUTPUT_DIR)/diff.html $(JTREG_OUTPUT_DIR)/status.txt
+ @mkdir -p $(JTREG_OUTPUT_DIR)
+ JT_JAVA=$(JT_JAVA) $(JTREG) \
+ -J-Xmx512m \
+ -a -samevm -ignore:quiet -v:fail,error,nopass \
+ -r:$(JTREG_OUTPUT_DIR)/JTreport \
+ -w:$(JTREG_OUTPUT_DIR)/JTwork \
+ -jdk:$(TESTJAVA) \
+ $(JAVA_ARGS:%=-vmoption:%) \
+ $(JTREG_OPTIONS) \
+ $(JTREG_TESTDIRS) \
+ || ( $(call EXIT_IF_FATAL,$(FATAL_JTREG_EXIT)) ; \
+ echo $$status > $(JTREG_OUTPUT_DIR)/status.txt \
+ )
+ifdef JTREG_REFERENCE
+ JT_JAVA=$(JT_JAVA) $(JTDIFF) -o $(JTREG_OUTPUT_DIR)/diff.html \
+ $(JTREG_REFERENCE) $(JTREG_OUTPUT_DIR)/JTreport \
+ || ( $(call EXIT_IF_FATAL,$(FATAL_JTDIFF_EXIT)) )
+endif
+
+jtreg-summary: FRC
+ if [ -r $(JTREG_OUTPUT_DIR)/status.txt ]; then \
+ echo ; echo "Summary of jtreg test failures" ; \
+ cat $(JTREG_OUTPUT_DIR)/JTreport/text/summary.txt | \
+ grep -v 'Not run' | grep -v 'Passed' ; \
+ echo ; \
+ $(EXIT) `cat $(JTREG_OUTPUT_DIR)/status.txt` ; \
+ fi
# Check to make sure these directories exist
-check: $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
+check-jtreg: $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
+
+
+# Run JCK-compiler tests
+#
+# JCK_HOME
+# Installed location of JCK: should include JCK-compiler, and JCK-extras
+# JT_JAVA
+# Version of java used to run JCK. Should normally be the same as TESTJAVA
+# TESTJAVA
+# Version of java to be tested.
+# JCK_COMPILER_OPTIONS
+# Additional options for JCK-compiler
+# JCK_COMPILER_TESTDIRS
+# Directories of tests to be run
+# JCK_COMPILER_OUTPUT_DIR
+# Where to write the results
+# JCK_COMPILER_REFERENCE
+# (Optional) reference results (e.g. work, report or summary.txt)
+#
+jck-compiler-tests: check-jck FRC
+ @rm -f -r $(JCK_COMPILER_OUTPUT_DIR)/work $(JCK_COMPILER_OUTPUT_DIR)/report \
+ $(JCK_COMPILER_OUTPUT_DIR)/diff.html $(JCK_COMPILER_OUTPUT_DIR)/status.txt
+ @mkdir -p $(JCK_COMPILER_OUTPUT_DIR)
+ $(JT_JAVA)/bin/java -XX:MaxPermSize=256m -Xmx512m \
+ -jar $(JCK_HOME)/JCK-compiler-7/lib/jtjck.jar \
+ -v:non-pass \
+ -r:$(JCK_COMPILER_OUTPUT_DIR)/report \
+ -w:$(JCK_COMPILER_OUTPUT_DIR)/work \
+ -jdk:$(TESTJAVA) \
+ $(JCK_COMPILER_OPTIONS) \
+ $(JCK_COMPILER_TESTDIRS) \
+ || ( $(call EXIT_IF_FATAL,$(FATAL_JCK_EXIT)) ; \
+ echo $$status > $(JCK_COMPILER_OUTPUT_DIR)/status.txt \
+ )
+ifdef JCK_COMPILER_REFERENCE
+ JT_JAVA=$(JT_JAVA) $(JTDIFF) -o $(JCK_COMPILER_OUTPUT_DIR)/diff.html \
+ $(JCK_COMPILER_REFERENCE) $(JCK_COMPILER_OUTPUT_DIR)/report \
+ || ( $(call EXIT_IF_FATAL,$(FATAL_JTDIFF_EXIT)) )
+endif
+
+jck-compiler-summary: FRC
+ if [ -r $(JCK_COMPILER_OUTPUT_DIR)/status.txt ]; then \
+ echo ; echo "Summary of JCK-compiler test failures" ; \
+ cat $(JCK_COMPILER_OUTPUT_DIR)/report/text/summary.txt | \
+ grep -v 'Not run' | grep -v 'Passed' ; \
+ echo ; \
+ $(EXIT) `cat $(JCK_COMPILER_OUTPUT_DIR)/status.txt` ; \
+ fi
-# Run the tests
-jtreg-tests: FRC
- @echo "Using export JAVA_TOOL_OPTIONS=$(JAVA_TOOL_OPTIONS)"
- @rm -f -r $(TEST_OUTPUT_DIR)/JTwork $(TEST_OUTPUT_DIR)/JTreport
- @mkdir -p $(TEST_OUTPUT_DIR)
- JT_JAVA=$(JT_JAVA) $(JTREG) \
- -a -samevm -k:\!ignore -v:fail,error,nopass \
- -r:$(TEST_OUTPUT_DIR)/JTreport \
- -w:$(TEST_OUTPUT_DIR)/JTwork \
- -jdk:$(TESTJAVA) \
- -Xbootclasspath/p:$(TESTBOOTCLASSPATH) \
- $(JAVA_ARGS:%=-vmoption:%) \
- $(TESTDIRS) \
- || ( status=$$? ; \
- echo ; echo "Summary of test failures" ; \
- cat $(TEST_OUTPUT_DIR)/JTreport/text/summary.txt | \
- grep -v 'Not run' | grep -v 'Passed' ; \
- echo ; \
- exit $$status )
+# Run JCK-runtime tests in -Xcompile mode
+# This is a special mode to test javac by compiling the tests in the JCK-runtime test suite
+# Normal JCK-runtime invocation belongs in the jdk/ repository.
+#
+# JCK_HOME
+# Installed location of JCK: should include JCK-compiler, JCK-runtime and JCK-extras
+# JT_JAVA
+# Version of java used to run JCK. Should normally be the same as TESTJAVA
+# TESTJAVA
+# Version of java to be tested.
+# JCK_RUNTIME_OPTIONS
+# Additional options for JCK-runtime
+# JCK_RUNTIME_TESTDIRS
+# Directories of tests to be run
+# JCK_RUNTIME_OUTPUT_DIR
+# Where to write the results
+# JCK_RUNTIME_REFERENCE
+# (Optional) reference results (e.g. work, report or summary.txt)
+#
+jck-runtime-tests: check-jck FRC
+ @rm -f -r $(JCK_RUNTIME_OUTPUT_DIR)/work $(JCK_RUNTIME_OUTPUT_DIR)/report \
+ $(JCK_RUNTIME_OUTPUT_DIR)/diff.html $(JCK_RUNTIME_OUTPUT_DIR)/status.txt
+ @mkdir -p $(JCK_RUNTIME_OUTPUT_DIR)
+ $(JT_JAVA)/bin/java -XX:MaxPermSize=256m -Xmx512m \
+ -jar $(JCK_HOME)/JCK-runtime-7/lib/jtjck.jar \
+ -v:non-pass \
+ -r:$(JCK_RUNTIME_OUTPUT_DIR)/report \
+ -w:$(JCK_RUNTIME_OUTPUT_DIR)/work \
+ -jdk:$(TESTJAVA) \
+ -Xcompile \
+ $(JCK_RUNTIME_OPTIONS) \
+ $(JCK_RUNTIME_TESTDIRS) \
+ || ( $(call EXIT_IF_FATAL,$(FATAL_JCK_EXIT)) ; \
+ echo $$status > $(JCK_RUNTIME_OUTPUT_DIR)/status.txt \
+ )
+ifdef JCK_RUNTIME_REFERENCE
+ JT_JAVA=$(JT_JAVA) $(JTDIFF) -o $(JCK_RUNTIME_OUTPUT_DIR)/diff.html \
+ $(JCK_RUNTIME_REFERENCE) $(JCK_RUNTIME_OUTPUT_DIR)/report \
+ || ( $(call EXIT_IF_FATAL,$(FATAL_JTDIFF_EXIT)) )
+endif
+
+jck-runtime-summary: FRC
+ if [ -r $(JCK_RUNTIME_OUTPUT_DIR)/status.txt ]; then \
+ echo ; echo "Summary of JCK-runtime test failures" ; \
+ cat $(JCK_RUNTIME_OUTPUT_DIR)/report/text/summary.txt | \
+ grep -v 'Not run' | grep -v 'Passed' ; \
+ echo ; \
+ $(EXIT) `cat $(JCK_RUNTIME_OUTPUT_DIR)/status.txt` ; \
+ fi
+
+# Check to make sure these directories exist
+check-jck: $(JT_HOME) $(JCK_HOME) $(PRODUCT_HOME)
+
+all-summary: FRC
+ if [ -n "`find $(TEST_OUTPUT_DIR) -name status.txt`" ]; then
+ echo ; echo "Summary of test failures" ; \
+ cat `find $(TEST_OUTPUT_DIR) -name summary.txt` | \
+ grep -v 'Not run' | grep -v 'Passed' ; \
+ echo ; \
+ $(EXIT) 1
+ fi
# Bundle up the results
$(JPRT_ARCHIVE_BUNDLE): FRC
@@ -124,12 +380,17 @@
# Cleanup
clean:
- rm -f -r $(TEST_OUTPUT_DIR)
rm -f $(JPRT_ARCHIVE_BUNDLE)
# Used to force a target rules to run
FRC:
# Phony targets (e.g. these are not filenames)
-.PHONY: all tests clean check
+.PHONY: all clean \
+ jtreg javac javadoc javah javap jtreg-tests jtreg-summary check-jtreg \
+ jck-compiler jck-compiler-tests jck-compiler-summary \
+ jck-runtime jck-runtime-tests jck-runtime-summary check-jck
+# No use of suffix rules
+.SUFFIXES:
+
--- a/langtools/test/tools/javac/OverrideChecks/6738538/T6738538a.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/OverrideChecks/6738538/T6738538a.java Sat Apr 17 08:12:00 2010 -0700
@@ -41,4 +41,4 @@
public T m();
}
class Crash<T extends C<?> & I> {}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/OverrideChecks/6738538/T6738538b.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/OverrideChecks/6738538/T6738538b.java Sat Apr 17 08:12:00 2010 -0700
@@ -44,4 +44,4 @@
}
class C2<T extends C1<?> & I2> {}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/api/6731573/Erroneous.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/api/6731573/Erroneous.java Sat Apr 17 08:12:00 2010 -0700
@@ -1,4 +1,4 @@
class A {
boolean b;
boolean b;
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/api/6731573/T6731573.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/api/6731573/T6731573.java Sat Apr 17 08:12:00 2010 -0700
@@ -106,4 +106,4 @@
public static void main(String... args) throws Exception {
new T6731573().test();
}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/cast/6548436/T6548436d.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/cast/6548436/T6548436d.java Sat Apr 17 08:12:00 2010 -0700
@@ -37,4 +37,4 @@
static void test(Base<? extends Double> je) {
Object o = (Base<Integer>)je;
}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/cast/6558559/T6558559a.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/cast/6558559/T6558559a.java Sat Apr 17 08:12:00 2010 -0700
@@ -37,4 +37,4 @@
A<?> x = null;
B<?> y = (B<?>)x;
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/cast/6558559/T6558559b.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/cast/6558559/T6558559b.java Sat Apr 17 08:12:00 2010 -0700
@@ -40,4 +40,4 @@
Object o = unboundList;
Throwable t3 = (Throwable) o;
}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/cast/6586091/T6586091.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/cast/6586091/T6586091.java Sat Apr 17 08:12:00 2010 -0700
@@ -35,4 +35,4 @@
A<A<?>> t = null;
B c = (B)t;
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/enum/T6724345.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/enum/T6724345.java Sat Apr 17 08:12:00 2010 -0700
@@ -48,4 +48,4 @@
enum E implements I {
V {public void i() {}};
}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/generics/T6557954.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/generics/T6557954.java Sat Apr 17 08:12:00 2010 -0700
@@ -33,4 +33,4 @@
class T6557954<T> {
class Foo<U extends T> {}
T6557954<Number>.Foo<Integer> f;
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/generics/T6751514.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/generics/T6751514.java Sat Apr 17 08:12:00 2010 -0700
@@ -79,4 +79,4 @@
" - found: " + found + ")");
}
}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/generics/T6869075.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/generics/T6869075.java Sat Apr 17 08:12:00 2010 -0700
@@ -64,4 +64,4 @@
" - found: " + found + ")");
}
}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/generics/inference/6569789/T6569789.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/generics/inference/6569789/T6569789.java Sat Apr 17 08:12:00 2010 -0700
@@ -41,4 +41,4 @@
}
static <W extends C & I & I1 & I2, T extends W> void testMethod(T t) {}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/generics/inference/6650759/T6650759a.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/generics/inference/6650759/T6650759a.java Sat Apr 17 08:12:00 2010 -0700
@@ -42,4 +42,4 @@
Integer test = getGenericValue(new IntegerInterface());
testSet(getGenericValue(new IntegerInterface()));
}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/generics/wildcards/T6732484.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/generics/wildcards/T6732484.java Sat Apr 17 08:12:00 2010 -0700
@@ -34,4 +34,4 @@
class B extends A<B> {}
A<? super B> f;
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/processing/model/util/elements/Foo.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/processing/model/util/elements/Foo.java Sat Apr 17 08:12:00 2010 -0700
@@ -26,4 +26,4 @@
* Dummy type to compile.
*/
public class Foo {
-}
\ No newline at end of file
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/VacuousEnum.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 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 6937417
+ * @summary Test -Xprint on enum type with no constants
+ * @author Joseph D. Darcy
+ * @compile -Xprint VacuousEnum.java
+ */
+public enum VacuousEnum {
+ // But alas, no enum constants!
+}
--- a/langtools/test/tools/javac/varargs/T6746184.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javac/varargs/T6746184.java Sat Apr 17 08:12:00 2010 -0700
@@ -36,4 +36,4 @@
class A {
public static void m(final Object... varargs) {}
private static void m(final Object singleArg) {}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javah/T6893943.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javah/T6893943.java Sat Apr 17 08:12:00 2010 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6893943
+ * @bug 6893943 6937318
* @summary exit code from javah with no args is 0
*/
@@ -31,22 +31,32 @@
import java.util.*;
public class T6893943 {
+ static final String[] NO_ARGS = { };
+ static final String[] HELP = { "-help" };
+ static final String NEWLINE = System.getProperty("line.separator");
+
public static void main(String... args) throws Exception {
new T6893943().run();
}
void run() throws Exception {
- testSimpleAPI();
- testCommand();
+ testSimpleAPI(NO_ARGS, 1);
+ testSimpleAPI(HELP, 0);
+ testCommand(NO_ARGS, 1);
+ testCommand(HELP, 0);
}
- void testSimpleAPI() throws Exception {
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.err));
- int rc = com.sun.tools.javah.Main.run(new String[] { }, pw);
- expect("testSimpleAPI", rc, 1);
+ void testSimpleAPI(String[] args, int expect_rc) throws Exception {
+ System.err.println("Test simple api: " + Arrays.asList(args));
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ int rc = com.sun.tools.javah.Main.run(args, pw);
+ pw.close();
+ expect("testSimpleAPI", sw.toString(), rc, expect_rc);
}
- void testCommand() throws Exception {
+ void testCommand(String[] args, int expect_rc) throws Exception {
+ System.err.println("Test command: " + Arrays.asList(args));
File javaHome = new File(System.getProperty("java.home"));
if (javaHome.getName().equals("jre"))
javaHome = javaHome.getParentFile();
@@ -54,22 +64,32 @@
List<String> command = new ArrayList<String>();
command.add(new File(new File(javaHome, "bin"), "javah").getPath());
command.add("-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path"));
+ command.addAll(Arrays.asList(args));
//System.err.println("command: " + command);
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process p = pb.start();
p.getOutputStream().close();
+ StringWriter sw = new StringWriter();
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null)
- System.err.println("javah: " + line);
+ sw.write(line + NEWLINE);
int rc = p.waitFor();
- expect("testCommand", rc, 1);
+ expect("testCommand", sw.toString(), rc, expect_rc);
}
- void expect(String name, int actual, int expect) throws Exception {
- if (actual != expect)
- throw new Exception(name + ": unexpected exit: " + actual + ", expected: " + expect);
+ void expect(String name, String out, int actual_rc, int expect_rc) throws Exception {
+ if (out.isEmpty())
+ throw new Exception("No output from javah");
+
+ if (!out.startsWith("Usage:")) {
+ System.err.println(out);
+ throw new Exception("Unexpected output from javah");
+ }
+
+ if (actual_rc != expect_rc)
+ throw new Exception(name + ": unexpected exit: " + actual_rc + ", expected: " + expect_rc);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/6937244/T6937244.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 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 6937244
+ * @summary fields display with JVMS names, not Java names
+ */
+
+import java.io.*;
+
+public class T6937244 {
+ public static void main(String[] args) throws Exception {
+ new T6937244().run();
+ }
+
+ void run() throws Exception {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ String[] args = { "java.lang.String" };
+ int rc = com.sun.tools.javap.Main.run(args, pw);
+ pw.close();
+ String out = sw.toString();
+ System.err.println(out);
+ if (rc != 0)
+ throw new Exception("unexpected exit from javap: " + rc);
+ for (String line: out.split("[\r\n]+")) {
+ if (line.contains("CASE_INSENSITIVE_ORDER")) {
+ if (line.matches("\\s*\\Qpublic static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;\\E\\s*"))
+ return;
+ throw new Exception("declaration not shown as expected");
+ }
+ }
+ throw new Exception("declaration of CASE_INSENSITIVE_ORDER not found");
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/6937244/T6937244A.java Sat Apr 17 08:12:00 2010 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 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 6937244
+ * @summary fields display with JVMS names, not Java names
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class T6937244A {
+ public static void main(String[] args) throws Exception {
+ new T6937244A().run();
+ }
+
+ void run() throws Exception {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ String[] args = { "Test" };
+ int rc = com.sun.tools.javap.Main.run(args, pw);
+ pw.close();
+ String out = sw.toString();
+ System.err.println(out);
+ if (rc != 0)
+ throw new Exception("unexpected exit from javap: " + rc);
+
+ int count = 0;
+
+ for (String line: out.split("[\r\n]+")) {
+ if (line.contains("extends")) {
+ verify(line, "extends java.lang.Object implements java.util.List<java.lang.String>");
+ count++;
+ }
+
+ if (line.contains("field")) {
+ verify(line, "java.util.List<java.lang.String> field");
+ count++;
+ }
+
+ if (line.contains("method")) {
+ verify(line, "java.util.List<java.lang.String> method(java.util.List<java.lang.String>) throws java.lang.Exception");
+ count++;
+ }
+ }
+
+ // final backstop check
+ if (out.contains("/"))
+ throw new Exception("unexpected \"/\" in output");
+
+ if (count != 3)
+ throw new Exception("wrong number of matches found: " + count);
+ }
+
+ void verify(String line, String expect) throws Exception {
+ if (!line.contains(expect)) {
+ System.err.println("line: " + line);
+ System.err.println("expect: " + expect);
+ throw new Exception("expected string not found in line");
+ }
+ }
+}
+
+
+abstract class Test implements List<String> {
+ public List<String> field;
+ public List<String> method(List<String> arg) throws Exception { return null; }
+}
+
--- a/langtools/test/tools/javap/T6715251.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javap/T6715251.java Sat Apr 17 08:12:00 2010 -0700
@@ -71,4 +71,4 @@
String log;
int errors;
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javap/T6715753.java Fri Apr 16 09:54:13 2010 +0100
+++ b/langtools/test/tools/javap/T6715753.java Sat Apr 17 08:12:00 2010 -0700
@@ -47,4 +47,4 @@
throw new Exception("test failed");
}
}
-}
\ No newline at end of file
+}
--- a/make/jprt.properties Fri Apr 16 09:54:13 2010 +0100
+++ b/make/jprt.properties Sat Apr 17 08:12:00 2010 -0700
@@ -62,6 +62,7 @@
# Test targets in test/Makefile
jprt.make.rule.test.targets= \
+ *-product-*-langtools_jtreg, \
*-product-*-jdk_beans1, \
*-product-*-jdk_beans2, \
*-product-*-jdk_beans3, \
@@ -84,7 +85,6 @@
*-product-*-jdk_util
# Not Ready Yet:
-# *-product-*-langtools_all
# *-product-*-jdk_awt
# *-product-*-jdk_rmi
# *-product-*-jdk_swing
--- a/test/Makefile Fri Apr 16 09:54:13 2010 +0100
+++ b/test/Makefile Sat Apr 17 08:12:00 2010 -0700
@@ -42,6 +42,7 @@
$(MAKE) -C $1/test $2 ; \
else \
echo "ERROR: File does not exist: $1/test/Makefile"; \
+ exit 1; \
fi; \
else \
echo "WARNING: No testing done, directory does not exist: $1"; \
@@ -49,7 +50,7 @@
endef
# Test target list for langtools repository
-LANGTOOLS_TEST_LIST = langtools_all
+LANGTOOLS_TEST_LIST = langtools_jtreg
# Test target list for jdk repository
JDK_TEST_LIST = \
@@ -74,7 +75,7 @@
# Test targets
$(LANGTOOLS_TEST_LIST):
- @$(call SUBDIR_TEST, $(LANGTOOLS_DIR), all)
+ @$(call SUBDIR_TEST, $(LANGTOOLS_DIR), $(subst langtools_,,$@))
$(JDK_TEST_LIST):
@$(call SUBDIR_TEST, $(JDK_DIR), $@)