Fri, 26 Mar 2010 11:10:26 -0400
Merge
1.1 --- a/.hgtags Thu Mar 25 16:54:59 2010 -0700 1.2 +++ b/.hgtags Fri Mar 26 11:10:26 2010 -0400 1.3 @@ -81,3 +81,5 @@ 1.4 fafab5d5349c7c066d677538db67a1ee0fb33bd2 hs15-b05 1.5 3f370a32906eb5ba993fabd7b4279be7f31052b9 jdk7-b83 1.6 ffc8d176b84bcfb5ac21302b4feb3b0c0d69b97c jdk7-b84 1.7 +6c9796468b91dcbb39e09dfa1baf9779ac45eb66 jdk7-b85 1.8 +418bc80ce13995149eadc9eecbba21d7a9fa02ae hs17-b10
2.1 --- a/agent/src/os/linux/libproc_impl.c Thu Mar 25 16:54:59 2010 -0700 2.2 +++ b/agent/src/os/linux/libproc_impl.c Fri Mar 26 11:10:26 2010 -0400 2.3 @@ -174,7 +174,7 @@ 2.4 return NULL; 2.5 } 2.6 2.7 - newlib->symtab = build_symtab(newlib->fd); 2.8 + newlib->symtab = build_symtab(newlib->fd, libname); 2.9 if (newlib->symtab == NULL) { 2.10 print_debug("symbol table build failed for %s\n", newlib->name); 2.11 }
3.1 --- a/agent/src/os/linux/symtab.c Thu Mar 25 16:54:59 2010 -0700 3.2 +++ b/agent/src/os/linux/symtab.c Fri Mar 26 11:10:26 2010 -0400 3.3 @@ -53,8 +53,274 @@ 3.4 struct hsearch_data *hash_table; 3.5 } symtab_t; 3.6 3.7 -// read symbol table from given fd. 3.8 -struct symtab* build_symtab(int fd) { 3.9 + 3.10 +// Directory that contains global debuginfo files. In theory it 3.11 +// should be possible to change this, but in a Java environment there 3.12 +// is no obvious place to put a user interface to do it. Maybe this 3.13 +// could be set with an environment variable. 3.14 +static const char debug_file_directory[] = "/usr/lib/debug"; 3.15 + 3.16 +/* The CRC used in gnu_debuglink, retrieved from 3.17 + http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files. */ 3.18 +unsigned int gnu_debuglink_crc32 (unsigned int crc, 3.19 + unsigned char *buf, size_t len) 3.20 +{ 3.21 + static const unsigned int crc32_table[256] = 3.22 + { 3.23 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 3.24 + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 3.25 + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 3.26 + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 3.27 + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 3.28 + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 3.29 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 3.30 + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 3.31 + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 3.32 + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 3.33 + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 3.34 + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 3.35 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 3.36 + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 3.37 + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 3.38 + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 3.39 + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 3.40 + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 3.41 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 3.42 + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 3.43 + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 3.44 + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 3.45 + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 3.46 + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 3.47 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 3.48 + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 3.49 + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 3.50 + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 3.51 + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 3.52 + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 3.53 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 3.54 + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 3.55 + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 3.56 + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 3.57 + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 3.58 + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 3.59 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 3.60 + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 3.61 + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 3.62 + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 3.63 + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 3.64 + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 3.65 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 3.66 + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 3.67 + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 3.68 + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 3.69 + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 3.70 + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 3.71 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 3.72 + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 3.73 + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 3.74 + 0x2d02ef8d 3.75 + }; 3.76 + unsigned char *end; 3.77 + 3.78 + crc = ~crc & 0xffffffff; 3.79 + for (end = buf + len; buf < end; ++buf) 3.80 + crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); 3.81 + return ~crc & 0xffffffff; 3.82 +} 3.83 + 3.84 +/* Open a debuginfo file and check its CRC. If it exists and the CRC 3.85 + matches return its fd. */ 3.86 +static int 3.87 +open_debug_file (const char *pathname, unsigned int crc) 3.88 +{ 3.89 + unsigned int file_crc = 0; 3.90 + unsigned char buffer[8 * 1024]; 3.91 + 3.92 + int fd = pathmap_open(pathname); 3.93 + 3.94 + if (fd < 0) 3.95 + return -1; 3.96 + 3.97 + lseek(fd, 0, SEEK_SET); 3.98 + 3.99 + for (;;) { 3.100 + int len = read(fd, buffer, sizeof buffer); 3.101 + if (len <= 0) 3.102 + break; 3.103 + file_crc = gnu_debuglink_crc32(file_crc, buffer, len); 3.104 + } 3.105 + 3.106 + if (crc == file_crc) 3.107 + return fd; 3.108 + else { 3.109 + close(fd); 3.110 + return -1; 3.111 + } 3.112 +} 3.113 + 3.114 +/* Find an ELF section. */ 3.115 +static struct elf_section *find_section_by_name(char *name, 3.116 + int fd, 3.117 + ELF_EHDR *ehdr, 3.118 + ELF_SHDR *shbuf, 3.119 + struct elf_section *scn_cache) 3.120 +{ 3.121 + ELF_SHDR* cursct = NULL; 3.122 + char *strtab; 3.123 + int cnt; 3.124 + 3.125 + if (scn_cache[ehdr->e_shstrndx].c_data == NULL) { 3.126 + if ((scn_cache[ehdr->e_shstrndx].c_data 3.127 + = read_section_data(fd, ehdr, cursct)) == NULL) { 3.128 + return NULL; 3.129 + } 3.130 + } 3.131 + 3.132 + strtab = scn_cache[ehdr->e_shstrndx].c_data; 3.133 + 3.134 + for (cursct = shbuf, cnt = 0; 3.135 + cnt < ehdr->e_shnum; 3.136 + cnt++, cursct++) { 3.137 + if (strcmp(cursct->sh_name + strtab, name) == 0) { 3.138 + scn_cache[cnt].c_data = read_section_data(fd, ehdr, cursct); 3.139 + return &scn_cache[cnt]; 3.140 + } 3.141 + } 3.142 + 3.143 + return NULL; 3.144 +} 3.145 + 3.146 +/* Look for a ".gnu_debuglink" section. If one exists, try to open a 3.147 + suitable debuginfo file. */ 3.148 +static int open_file_from_debug_link(const char *name, 3.149 + int fd, 3.150 + ELF_EHDR *ehdr, 3.151 + ELF_SHDR *shbuf, 3.152 + struct elf_section *scn_cache) 3.153 +{ 3.154 + int debug_fd; 3.155 + struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr, 3.156 + shbuf, scn_cache); 3.157 + if (debug_link == NULL) 3.158 + return -1; 3.159 + char *debug_filename = debug_link->c_data; 3.160 + int offset = (strlen(debug_filename) + 4) >> 2; 3.161 + static unsigned int crc; 3.162 + crc = ((unsigned int*)debug_link->c_data)[offset]; 3.163 + char *debug_pathname = malloc(strlen(debug_filename) 3.164 + + strlen(name) 3.165 + + strlen(".debug/") 3.166 + + strlen(debug_file_directory) 3.167 + + 2); 3.168 + strcpy(debug_pathname, name); 3.169 + char *last_slash = strrchr(debug_pathname, '/'); 3.170 + if (last_slash == NULL) 3.171 + return -1; 3.172 + 3.173 + /* Look in the same directory as the object. */ 3.174 + strcpy(last_slash+1, debug_filename); 3.175 + 3.176 + debug_fd = open_debug_file(debug_pathname, crc); 3.177 + if (debug_fd >= 0) { 3.178 + free(debug_pathname); 3.179 + return debug_fd; 3.180 + } 3.181 + 3.182 + /* Look in a subdirectory named ".debug". */ 3.183 + strcpy(last_slash+1, ".debug/"); 3.184 + strcat(last_slash, debug_filename); 3.185 + 3.186 + debug_fd = open_debug_file(debug_pathname, crc); 3.187 + if (debug_fd >= 0) { 3.188 + free(debug_pathname); 3.189 + return debug_fd; 3.190 + } 3.191 + 3.192 + /* Look in /usr/lib/debug + the full pathname. */ 3.193 + strcpy(debug_pathname, debug_file_directory); 3.194 + strcat(debug_pathname, name); 3.195 + last_slash = strrchr(debug_pathname, '/'); 3.196 + strcpy(last_slash+1, debug_filename); 3.197 + 3.198 + debug_fd = open_debug_file(debug_pathname, crc); 3.199 + if (debug_fd >= 0) { 3.200 + free(debug_pathname); 3.201 + return debug_fd; 3.202 + } 3.203 + 3.204 + free(debug_pathname); 3.205 + return -1; 3.206 +} 3.207 + 3.208 +static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo); 3.209 + 3.210 +/* Look for a ".gnu_debuglink" section. If one exists, try to open a 3.211 + suitable debuginfo file and read a symbol table from it. */ 3.212 +static struct symtab *build_symtab_from_debug_link(const char *name, 3.213 + int fd, 3.214 + ELF_EHDR *ehdr, 3.215 + ELF_SHDR *shbuf, 3.216 + struct elf_section *scn_cache) 3.217 +{ 3.218 + fd = open_file_from_debug_link(name, fd, ehdr, shbuf, scn_cache); 3.219 + 3.220 + if (fd >= 0) { 3.221 + struct symtab *symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false); 3.222 + close(fd); 3.223 + return symtab; 3.224 + } 3.225 + 3.226 + return NULL; 3.227 +} 3.228 + 3.229 +// Given a build_id, find the associated debuginfo file 3.230 +static char * 3.231 +build_id_to_debug_filename (size_t size, unsigned char *data) 3.232 +{ 3.233 + char *filename, *s; 3.234 + 3.235 + filename = malloc(strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 3.236 + + 2 * size + (sizeof ".debug" - 1) + 1); 3.237 + s = filename + sprintf (filename, "%s/.build-id/", debug_file_directory); 3.238 + if (size > 0) 3.239 + { 3.240 + size--; 3.241 + s += sprintf (s, "%02x", *data++); 3.242 + } 3.243 + if (size > 0) 3.244 + *s++ = '/'; 3.245 + while (size-- > 0) 3.246 + s += sprintf (s, "%02x", *data++); 3.247 + strcpy (s, ".debug"); 3.248 + 3.249 + return filename; 3.250 +} 3.251 + 3.252 +// Read a build ID note. Try to open any associated debuginfo file 3.253 +// and return its symtab 3.254 +static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note) 3.255 +{ 3.256 + int fd; 3.257 + struct symtab *symtab = NULL; 3.258 + 3.259 + unsigned char *bytes 3.260 + = (unsigned char*)(note+1) + note->n_namesz; 3.261 + unsigned char *filename 3.262 + = (build_id_to_debug_filename (note->n_descsz, bytes)); 3.263 + 3.264 + fd = pathmap_open(filename); 3.265 + if (fd >= 0) { 3.266 + symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false); 3.267 + close(fd); 3.268 + } 3.269 + free(filename); 3.270 + 3.271 + return symtab; 3.272 +} 3.273 + 3.274 +// read symbol table from given fd. If try_debuginfo) is true, also 3.275 +// try to open an associated debuginfo file 3.276 +static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo) { 3.277 ELF_EHDR ehdr; 3.278 char *names = NULL; 3.279 struct symtab* symtab = NULL; 3.280 @@ -66,6 +332,7 @@ 3.281 ELF_SHDR* cursct = NULL; 3.282 ELF_PHDR* phbuf = NULL; 3.283 ELF_PHDR* phdr = NULL; 3.284 + int sym_section = SHT_DYNSYM; 3.285 3.286 uintptr_t baseaddr = (uintptr_t)-1; 3.287 3.288 @@ -90,18 +357,23 @@ 3.289 3.290 for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) { 3.291 scn_cache[cnt].c_shdr = cursct; 3.292 - if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB) { 3.293 + if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB 3.294 + || cursct->sh_type == SHT_NOTE || cursct->sh_type == SHT_DYNSYM) { 3.295 if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) { 3.296 goto quit; 3.297 } 3.298 } 3.299 + if (cursct->sh_type == SHT_SYMTAB) { 3.300 + // Full symbol table available so use that 3.301 + sym_section = cursct->sh_type; 3.302 + } 3.303 cursct++; 3.304 } 3.305 3.306 for (cnt = 1; cnt < ehdr.e_shnum; cnt++) { 3.307 ELF_SHDR *shdr = scn_cache[cnt].c_shdr; 3.308 3.309 - if (shdr->sh_type == SHT_SYMTAB) { 3.310 + if (shdr->sh_type == sym_section) { 3.311 ELF_SYM *syms; 3.312 int j, n, rslt; 3.313 size_t size; 3.314 @@ -163,6 +435,45 @@ 3.315 } 3.316 } 3.317 3.318 + // Look for a separate debuginfo file. 3.319 + if (try_debuginfo) { 3.320 + 3.321 + // We prefer a debug symtab to an object's own symtab, so look in 3.322 + // the debuginfo file. We stash a copy of the old symtab in case 3.323 + // there is no debuginfo. 3.324 + struct symtab* prev_symtab = symtab; 3.325 + symtab = NULL; 3.326 + 3.327 +#ifdef NT_GNU_BUILD_ID 3.328 + // First we look for a Build ID 3.329 + for (cursct = shbuf, cnt = 0; 3.330 + symtab == NULL && cnt < ehdr.e_shnum; 3.331 + cnt++) { 3.332 + if (cursct->sh_type == SHT_NOTE) { 3.333 + Elf64_Nhdr *note = (Elf64_Nhdr *)scn_cache[cnt].c_data; 3.334 + if (note->n_type == NT_GNU_BUILD_ID) { 3.335 + symtab = build_symtab_from_build_id(note); 3.336 + } 3.337 + } 3.338 + cursct++; 3.339 + } 3.340 +#endif 3.341 + 3.342 + // Then, if that doesn't work, the debug link 3.343 + if (symtab == NULL) { 3.344 + symtab = build_symtab_from_debug_link(filename, fd, &ehdr, shbuf, 3.345 + scn_cache); 3.346 + } 3.347 + 3.348 + // If we still haven't found a symtab, use the object's own symtab. 3.349 + if (symtab != NULL) { 3.350 + if (prev_symtab != NULL) 3.351 + destroy_symtab(prev_symtab); 3.352 + } else { 3.353 + symtab = prev_symtab; 3.354 + } 3.355 + } 3.356 + 3.357 quit: 3.358 if (shbuf) free(shbuf); 3.359 if (phbuf) free(phbuf); 3.360 @@ -177,6 +488,11 @@ 3.361 return symtab; 3.362 } 3.363 3.364 +struct symtab* build_symtab(int fd, const char *filename) { 3.365 + return build_symtab_internal(fd, filename, /* try_debuginfo */ true); 3.366 +} 3.367 + 3.368 + 3.369 void destroy_symtab(struct symtab* symtab) { 3.370 if (!symtab) return; 3.371 if (symtab->strs) free(symtab->strs);
4.1 --- a/agent/src/os/linux/symtab.h Thu Mar 25 16:54:59 2010 -0700 4.2 +++ b/agent/src/os/linux/symtab.h Fri Mar 26 11:10:26 2010 -0400 4.3 @@ -32,7 +32,7 @@ 4.4 struct symtab; 4.5 4.6 // build symbol table for a given ELF file descriptor 4.7 -struct symtab* build_symtab(int fd); 4.8 +struct symtab* build_symtab(int fd, const char *filename); 4.9 4.10 // destroy the symbol table 4.11 void destroy_symtab(struct symtab* symtab);
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/make/linux/makefiles/build_vm_def.sh Fri Mar 26 11:10:26 2010 -0400 5.3 @@ -0,0 +1,5 @@ 5.4 +#!/bin/sh 5.5 + 5.6 +nm --defined-only $* | awk ' 5.7 + { if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";" } 5.8 + '
6.1 --- a/make/linux/makefiles/mapfile-vers-debug Thu Mar 25 16:54:59 2010 -0700 6.2 +++ b/make/linux/makefiles/mapfile-vers-debug Fri Mar 26 11:10:26 2010 -0400 6.3 @@ -290,6 +290,9 @@ 6.4 6.5 # This is for Forte Analyzer profiling support. 6.6 AsyncGetCallTrace; 6.7 + 6.8 + # INSERT VTABLE SYMBOLS HERE 6.9 + 6.10 local: 6.11 *; 6.12 };
7.1 --- a/make/linux/makefiles/mapfile-vers-product Thu Mar 25 16:54:59 2010 -0700 7.2 +++ b/make/linux/makefiles/mapfile-vers-product Fri Mar 26 11:10:26 2010 -0400 7.3 @@ -285,6 +285,9 @@ 7.4 7.5 # This is for Forte Analyzer profiling support. 7.6 AsyncGetCallTrace; 7.7 + 7.8 + # INSERT VTABLE SYMBOLS HERE 7.9 + 7.10 local: 7.11 *; 7.12 };
8.1 --- a/make/linux/makefiles/vm.make Thu Mar 25 16:54:59 2010 -0700 8.2 +++ b/make/linux/makefiles/vm.make Fri Mar 26 11:10:26 2010 -0400 8.3 @@ -121,14 +121,21 @@ 8.4 8.5 vm_version.o: $(filter-out vm_version.o,$(JVM_OBJ_FILES)) 8.6 8.7 -mapfile : $(MAPFILE) 8.8 +mapfile : $(MAPFILE) vm.def 8.9 rm -f $@ 8.10 - cat $^ > $@ 8.11 + awk '{ if ($$0 ~ "INSERT VTABLE SYMBOLS HERE") \ 8.12 + { system ("cat vm.def"); } \ 8.13 + else \ 8.14 + { print $$0 } \ 8.15 + }' > $@ < $(MAPFILE) 8.16 8.17 mapfile_reorder : mapfile $(REORDERFILE) 8.18 rm -f $@ 8.19 cat $^ > $@ 8.20 8.21 +vm.def: $(Res_Files) $(Obj_Files) 8.22 + sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@ 8.23 + 8.24 ifeq ($(ZERO_LIBARCH), ppc64) 8.25 STATIC_CXX = false 8.26 else
9.1 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Mar 25 16:54:59 2010 -0700 9.2 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Mar 26 11:10:26 2010 -0400 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 9.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -377,6 +377,16 @@ 9.11 9.12 } 9.13 9.14 + 9.15 +void DeoptimizeStub::emit_code(LIR_Assembler* ce) { 9.16 + __ bind(_entry); 9.17 + __ call(SharedRuntime::deopt_blob()->unpack_with_reexecution()); 9.18 + __ delayed()->nop(); 9.19 + ce->add_call_info_here(_info); 9.20 + debug_only(__ should_not_reach_here()); 9.21 +} 9.22 + 9.23 + 9.24 void ArrayCopyStub::emit_code(LIR_Assembler* ce) { 9.25 //---------------slow case: call to native----------------- 9.26 __ bind(_entry);
10.1 --- a/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp Thu Mar 25 16:54:59 2010 -0700 10.2 +++ b/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp Fri Mar 26 11:10:26 2010 -0400 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 10.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -143,3 +143,6 @@ 10.11 10.12 static bool is_caller_save_register (LIR_Opr reg); 10.13 static bool is_caller_save_register (Register r); 10.14 + 10.15 + // JSR 292 10.16 + static LIR_Opr& method_handle_invoke_SP_save_opr() { return L7_opr; }
11.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Mar 25 16:54:59 2010 -0700 11.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Mar 26 11:10:26 2010 -0400 11.3 @@ -378,12 +378,7 @@ 11.4 11.5 int offset = code_offset(); 11.6 11.7 - if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) { 11.8 - __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type); 11.9 - __ delayed()->nop(); 11.10 - } 11.11 - 11.12 - __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type); 11.13 + __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type); 11.14 __ delayed()->nop(); 11.15 debug_only(__ stop("should have gone to the caller");) 11.16 assert(code_offset() - offset <= exception_handler_size, "overflow"); 11.17 @@ -685,29 +680,29 @@ 11.18 } 11.19 11.20 11.21 -void LIR_Assembler::call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info) { 11.22 - __ call(entry, rtype); 11.23 +void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { 11.24 + __ call(op->addr(), rtype); 11.25 // the peephole pass fills the delay slot 11.26 } 11.27 11.28 11.29 -void LIR_Assembler::ic_call(address entry, CodeEmitInfo* info) { 11.30 +void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { 11.31 RelocationHolder rspec = virtual_call_Relocation::spec(pc()); 11.32 __ set_oop((jobject)Universe::non_oop_word(), G5_inline_cache_reg); 11.33 __ relocate(rspec); 11.34 - __ call(entry, relocInfo::none); 11.35 + __ call(op->addr(), relocInfo::none); 11.36 // the peephole pass fills the delay slot 11.37 } 11.38 11.39 11.40 -void LIR_Assembler::vtable_call(int vtable_offset, CodeEmitInfo* info) { 11.41 - add_debug_info_for_null_check_here(info); 11.42 +void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { 11.43 + add_debug_info_for_null_check_here(op->info()); 11.44 __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); 11.45 - if (__ is_simm13(vtable_offset) ) { 11.46 - __ ld_ptr(G3_scratch, vtable_offset, G5_method); 11.47 + if (__ is_simm13(op->vtable_offset())) { 11.48 + __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method); 11.49 } else { 11.50 // This will generate 2 instructions 11.51 - __ set(vtable_offset, G5_method); 11.52 + __ set(op->vtable_offset(), G5_method); 11.53 // ld_ptr, set_hi, set 11.54 __ ld_ptr(G3_scratch, G5_method, G5_method); 11.55 } 11.56 @@ -717,6 +712,16 @@ 11.57 } 11.58 11.59 11.60 +void LIR_Assembler::preserve_SP(LIR_OpJavaCall* op) { 11.61 + Unimplemented(); 11.62 +} 11.63 + 11.64 + 11.65 +void LIR_Assembler::restore_SP(LIR_OpJavaCall* op) { 11.66 + Unimplemented(); 11.67 +} 11.68 + 11.69 + 11.70 // load with 32-bit displacement 11.71 int LIR_Assembler::load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo *info) { 11.72 int load_offset = code_offset(); 11.73 @@ -1067,7 +1072,8 @@ 11.74 LIR_Const* c = src->as_constant_ptr(); 11.75 switch (c->type()) { 11.76 case T_INT: 11.77 - case T_FLOAT: { 11.78 + case T_FLOAT: 11.79 + case T_ADDRESS: { 11.80 Register src_reg = O7; 11.81 int value = c->as_jint_bits(); 11.82 if (value == 0) { 11.83 @@ -1123,7 +1129,8 @@ 11.84 } 11.85 switch (c->type()) { 11.86 case T_INT: 11.87 - case T_FLOAT: { 11.88 + case T_FLOAT: 11.89 + case T_ADDRESS: { 11.90 LIR_Opr tmp = FrameMap::O7_opr; 11.91 int value = c->as_jint_bits(); 11.92 if (value == 0) { 11.93 @@ -1195,6 +1202,7 @@ 11.94 11.95 switch (c->type()) { 11.96 case T_INT: 11.97 + case T_ADDRESS: 11.98 { 11.99 jint con = c->as_jint(); 11.100 if (to_reg->is_single_cpu()) {
12.1 --- a/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Thu Mar 25 16:54:59 2010 -0700 12.2 +++ b/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Fri Mar 26 11:10:26 2010 -0400 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 12.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -42,17 +42,6 @@ 12.11 } 12.12 12.13 12.14 -void C1_MacroAssembler::method_exit(bool restore_frame) { 12.15 - // this code must be structured this way so that the return 12.16 - // instruction can be a safepoint. 12.17 - if (restore_frame) { 12.18 - restore(); 12.19 - } 12.20 - retl(); 12.21 - delayed()->nop(); 12.22 -} 12.23 - 12.24 - 12.25 void C1_MacroAssembler::explicit_null_check(Register base) { 12.26 Unimplemented(); 12.27 }
13.1 --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Thu Mar 25 16:54:59 2010 -0700 13.2 +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Mar 26 11:10:26 2010 -0400 13.3 @@ -1,5 +1,5 @@ 13.4 /* 13.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 13.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 * 13.9 * This code is free software; you can redistribute it and/or modify it 13.10 @@ -677,7 +677,7 @@ 13.11 __ add(I7, frame::pc_return_offset, Oissuing_pc->after_save()); 13.12 13.13 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), 13.14 - Oissuing_pc->after_save()); 13.15 + G2_thread, Oissuing_pc->after_save()); 13.16 __ verify_not_null_oop(Oexception->after_save()); 13.17 __ jmp(O0, 0); 13.18 __ delayed()->restore(); 13.19 @@ -985,7 +985,6 @@ 13.20 13.21 void Runtime1::generate_handle_exception(StubAssembler* sasm, OopMapSet* oop_maps, OopMap* oop_map, bool) { 13.22 Label no_deopt; 13.23 - Label no_handler; 13.24 13.25 __ verify_not_null_oop(Oexception); 13.26 13.27 @@ -1003,9 +1002,14 @@ 13.28 // whether it had a handler or not we will deoptimize 13.29 // by entering the deopt blob with a pending exception. 13.30 13.31 +#ifdef ASSERT 13.32 + Label done; 13.33 __ tst(O0); 13.34 - __ br(Assembler::zero, false, Assembler::pn, no_handler); 13.35 + __ br(Assembler::notZero, false, Assembler::pn, done); 13.36 __ delayed()->nop(); 13.37 + __ stop("should have found address"); 13.38 + __ bind(done); 13.39 +#endif 13.40 13.41 // restore the registers that were saved at the beginning and jump to the exception handler. 13.42 restore_live_registers(sasm); 13.43 @@ -1013,20 +1017,6 @@ 13.44 __ jmp(O0, 0); 13.45 __ delayed()->restore(); 13.46 13.47 - __ bind(no_handler); 13.48 - __ mov(L0, I7); // restore return address 13.49 - 13.50 - // restore exception oop 13.51 - __ ld_ptr(G2_thread, in_bytes(JavaThread::exception_oop_offset()), Oexception->after_save()); 13.52 - __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_oop_offset())); 13.53 - 13.54 - __ restore(); 13.55 - 13.56 - AddressLiteral exc(Runtime1::entry_for(Runtime1::unwind_exception_id)); 13.57 - __ jump_to(exc, G4); 13.58 - __ delayed()->nop(); 13.59 - 13.60 - 13.61 oop_maps->add_gc_map(call_offset, oop_map); 13.62 } 13.63
14.1 --- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Mar 25 16:54:59 2010 -0700 14.2 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri Mar 26 11:10:26 2010 -0400 14.3 @@ -244,9 +244,10 @@ 14.4 } 14.5 14.6 14.7 -void InterpreterMacroAssembler::super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1) { 14.8 +void InterpreterMacroAssembler::super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2) { 14.9 mov(arg_1, O0); 14.10 - MacroAssembler::call_VM_leaf_base(thread_cache, entry_point, 1); 14.11 + mov(arg_2, O1); 14.12 + MacroAssembler::call_VM_leaf_base(thread_cache, entry_point, 2); 14.13 } 14.14 #endif /* CC_INTERP */ 14.15
15.1 --- a/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Mar 25 16:54:59 2010 -0700 15.2 +++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp Fri Mar 26 11:10:26 2010 -0400 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 15.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -121,7 +121,7 @@ 15.11 bool check_exception = true); 15.12 15.13 #ifndef CC_INTERP 15.14 - void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1); 15.15 + void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2); 15.16 15.17 // Generate a subtype check: branch to ok_is_subtype if sub_klass is 15.18 // a subtype of super_klass. Blows registers tmp1, tmp2 and tmp3.
16.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Mar 25 16:54:59 2010 -0700 16.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Mar 26 11:10:26 2010 -0400 16.3 @@ -379,7 +379,7 @@ 16.4 __ save_frame(0); // compensates for compiler weakness 16.5 __ add(O7->after_save(), frame::pc_return_offset, Lscratch); // save the issuing PC 16.6 BLOCK_COMMENT("call exception_handler_for_return_address"); 16.7 - __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), Lscratch); 16.8 + __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), G2_thread, Lscratch); 16.9 __ mov(O0, handler_reg); 16.10 __ restore(); // compensates for compiler weakness 16.11
17.1 --- a/src/cpu/sparc/vm/stubRoutines_sparc.hpp Thu Mar 25 16:54:59 2010 -0700 17.2 +++ b/src/cpu/sparc/vm/stubRoutines_sparc.hpp Fri Mar 26 11:10:26 2010 -0400 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 17.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -37,8 +37,13 @@ 17.11 17.12 enum /* platform_dependent_constants */ { 17.13 // %%%%%%%% May be able to shrink this a lot 17.14 - code_size1 = 20000, // simply increase if too small (assembler will crash if too small) 17.15 - code_size2 = 20000 // simply increase if too small (assembler will crash if too small) 17.16 + code_size1 = 20000, // simply increase if too small (assembler will crash if too small) 17.17 + code_size2 = 20000 // simply increase if too small (assembler will crash if too small) 17.18 +}; 17.19 + 17.20 +// MethodHandles adapters 17.21 +enum method_handles_platform_dependent_constants { 17.22 + method_handles_adapters_code_size = 5000 17.23 }; 17.24 17.25 class Sparc {
18.1 --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Mar 25 16:54:59 2010 -0700 18.2 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Mar 26 11:10:26 2010 -0400 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 18.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 * 18.9 * This code is free software; you can redistribute it and/or modify it 18.10 @@ -1822,7 +1822,7 @@ 18.11 __ add(issuing_pc_addr, Oissuing_pc->after_save()); // likewise set I1 to a value local to the caller 18.12 __ super_call_VM_leaf(L7_thread_cache, 18.13 CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), 18.14 - Oissuing_pc->after_save()); 18.15 + G2_thread, Oissuing_pc->after_save()); 18.16 18.17 // The caller's SP was adjusted upon method entry to accomodate 18.18 // the callee's non-argument locals. Undo that adjustment.
19.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Thu Mar 25 16:54:59 2010 -0700 19.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Fri Mar 26 11:10:26 2010 -0400 19.3 @@ -8460,6 +8460,7 @@ 19.4 subptr(str1, result); // Restore counter 19.5 shrl(str1, 1); 19.6 addl(cnt1, str1); 19.7 + decrementl(cnt1); 19.8 lea(str1, Address(result, 2)); // Reload string 19.9 19.10 // Load substr
20.1 --- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Mar 25 16:54:59 2010 -0700 20.2 +++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Fri Mar 26 11:10:26 2010 -0400 20.3 @@ -1,5 +1,5 @@ 20.4 /* 20.5 - * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. 20.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 20.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.8 * 20.9 * This code is free software; you can redistribute it and/or modify it 20.10 @@ -373,6 +373,14 @@ 20.11 } 20.12 20.13 20.14 +void DeoptimizeStub::emit_code(LIR_Assembler* ce) { 20.15 + __ bind(_entry); 20.16 + __ call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack_with_reexecution())); 20.17 + ce->add_call_info_here(_info); 20.18 + debug_only(__ should_not_reach_here()); 20.19 +} 20.20 + 20.21 + 20.22 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) { 20.23 ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); 20.24 __ bind(_entry);
21.1 --- a/src/cpu/x86/vm/c1_FrameMap_x86.hpp Thu Mar 25 16:54:59 2010 -0700 21.2 +++ b/src/cpu/x86/vm/c1_FrameMap_x86.hpp Fri Mar 26 11:10:26 2010 -0400 21.3 @@ -1,5 +1,5 @@ 21.4 /* 21.5 - * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. 21.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.8 * 21.9 * This code is free software; you can redistribute it and/or modify it 21.10 @@ -126,3 +126,6 @@ 21.11 assert(i >= 0 && i < nof_caller_save_xmm_regs, "out of bounds"); 21.12 return _caller_save_xmm_regs[i]; 21.13 } 21.14 + 21.15 + // JSR 292 21.16 + static LIR_Opr& method_handle_invoke_SP_save_opr() { return rbp_opr; }
22.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Mar 25 16:54:59 2010 -0700 22.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Mar 26 11:10:26 2010 -0400 22.3 @@ -436,40 +436,18 @@ 22.4 22.5 int offset = code_offset(); 22.6 22.7 - // if the method does not have an exception handler, then there is 22.8 - // no reason to search for one 22.9 - if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) { 22.10 - // the exception oop and pc are in rax, and rdx 22.11 - // no other registers need to be preserved, so invalidate them 22.12 - __ invalidate_registers(false, true, true, false, true, true); 22.13 - 22.14 - // check that there is really an exception 22.15 - __ verify_not_null_oop(rax); 22.16 - 22.17 - // search an exception handler (rax: exception oop, rdx: throwing pc) 22.18 - __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id))); 22.19 - 22.20 - // if the call returns here, then the exception handler for particular 22.21 - // exception doesn't exist -> unwind activation and forward exception to caller 22.22 - } 22.23 - 22.24 - // the exception oop is in rax, 22.25 + // the exception oop and pc are in rax, and rdx 22.26 // no other registers need to be preserved, so invalidate them 22.27 - __ invalidate_registers(false, true, true, true, true, true); 22.28 + __ invalidate_registers(false, true, true, false, true, true); 22.29 22.30 // check that there is really an exception 22.31 __ verify_not_null_oop(rax); 22.32 22.33 - // unlock the receiver/klass if necessary 22.34 - // rax,: exception 22.35 - ciMethod* method = compilation()->method(); 22.36 - if (method->is_synchronized() && GenerateSynchronizationCode) { 22.37 - monitorexit(FrameMap::rbx_oop_opr, FrameMap::rcx_opr, SYNC_header, 0, rax); 22.38 - } 22.39 - 22.40 - // unwind activation and forward exception to caller 22.41 - // rax,: exception 22.42 - __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); 22.43 + // search an exception handler (rax: exception oop, rdx: throwing pc) 22.44 + __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id))); 22.45 + 22.46 + __ stop("should not reach here"); 22.47 + 22.48 assert(code_offset() - offset <= exception_handler_size, "overflow"); 22.49 __ end_a_stub(); 22.50 22.51 @@ -495,8 +473,10 @@ 22.52 22.53 int offset = code_offset(); 22.54 InternalAddress here(__ pc()); 22.55 + 22.56 __ pushptr(here.addr()); 22.57 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 22.58 + 22.59 assert(code_offset() - offset <= deopt_handler_size, "overflow"); 22.60 __ end_a_stub(); 22.61 22.62 @@ -593,7 +573,7 @@ 22.63 } 22.64 22.65 // Pop the stack before the safepoint code 22.66 - __ leave(); 22.67 + __ remove_frame(initial_frame_size_in_bytes()); 22.68 22.69 bool result_is_oop = result->is_valid() ? result->is_oop() : false; 22.70 22.71 @@ -648,7 +628,8 @@ 22.72 LIR_Const* c = src->as_constant_ptr(); 22.73 22.74 switch (c->type()) { 22.75 - case T_INT: { 22.76 + case T_INT: 22.77 + case T_ADDRESS: { 22.78 assert(patch_code == lir_patch_none, "no patching handled here"); 22.79 __ movl(dest->as_register(), c->as_jint()); 22.80 break; 22.81 @@ -731,6 +712,7 @@ 22.82 switch (c->type()) { 22.83 case T_INT: // fall through 22.84 case T_FLOAT: 22.85 + case T_ADDRESS: 22.86 __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); 22.87 break; 22.88 22.89 @@ -766,6 +748,7 @@ 22.90 switch (type) { 22.91 case T_INT: // fall through 22.92 case T_FLOAT: 22.93 + case T_ADDRESS: 22.94 __ movl(as_Address(addr), c->as_jint_bits()); 22.95 break; 22.96 22.97 @@ -2738,6 +2721,7 @@ 22.98 switch (code) { 22.99 case lir_static_call: 22.100 case lir_optvirtual_call: 22.101 + case lir_dynamic_call: 22.102 offset += NativeCall::displacement_offset; 22.103 break; 22.104 case lir_icvirtual_call: 22.105 @@ -2753,30 +2737,41 @@ 22.106 } 22.107 22.108 22.109 -void LIR_Assembler::call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info) { 22.110 +void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { 22.111 assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, 22.112 "must be aligned"); 22.113 - __ call(AddressLiteral(entry, rtype)); 22.114 - add_call_info(code_offset(), info); 22.115 + __ call(AddressLiteral(op->addr(), rtype)); 22.116 + add_call_info(code_offset(), op->info(), op->is_method_handle_invoke()); 22.117 } 22.118 22.119 22.120 -void LIR_Assembler::ic_call(address entry, CodeEmitInfo* info) { 22.121 +void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { 22.122 RelocationHolder rh = virtual_call_Relocation::spec(pc()); 22.123 __ movoop(IC_Klass, (jobject)Universe::non_oop_word()); 22.124 assert(!os::is_MP() || 22.125 (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, 22.126 "must be aligned"); 22.127 - __ call(AddressLiteral(entry, rh)); 22.128 - add_call_info(code_offset(), info); 22.129 + __ call(AddressLiteral(op->addr(), rh)); 22.130 + add_call_info(code_offset(), op->info(), op->is_method_handle_invoke()); 22.131 } 22.132 22.133 22.134 /* Currently, vtable-dispatch is only enabled for sparc platforms */ 22.135 -void LIR_Assembler::vtable_call(int vtable_offset, CodeEmitInfo* info) { 22.136 +void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { 22.137 ShouldNotReachHere(); 22.138 } 22.139 22.140 + 22.141 +void LIR_Assembler::preserve_SP(LIR_OpJavaCall* op) { 22.142 + __ movptr(FrameMap::method_handle_invoke_SP_save_opr()->as_register(), rsp); 22.143 +} 22.144 + 22.145 + 22.146 +void LIR_Assembler::restore_SP(LIR_OpJavaCall* op) { 22.147 + __ movptr(rsp, FrameMap::method_handle_invoke_SP_save_opr()->as_register()); 22.148 +} 22.149 + 22.150 + 22.151 void LIR_Assembler::emit_static_call_stub() { 22.152 address call_pc = __ pc(); 22.153 address stub = __ start_a_stub(call_stub_size); 22.154 @@ -2829,10 +2824,12 @@ 22.155 } else { 22.156 unwind_id = Runtime1::handle_exception_nofpu_id; 22.157 } 22.158 + __ call(RuntimeAddress(Runtime1::entry_for(unwind_id))); 22.159 } else { 22.160 - unwind_id = Runtime1::unwind_exception_id; 22.161 + // remove the activation 22.162 + __ remove_frame(initial_frame_size_in_bytes()); 22.163 + __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); 22.164 } 22.165 - __ call(RuntimeAddress(Runtime1::entry_for(unwind_id))); 22.166 22.167 // enough room for two byte trap 22.168 __ nop();
23.1 --- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Thu Mar 25 16:54:59 2010 -0700 23.2 +++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Fri Mar 26 11:10:26 2010 -0400 23.3 @@ -1,5 +1,5 @@ 23.4 /* 23.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 23.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 23.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.8 * 23.9 * This code is free software; you can redistribute it and/or modify it 23.10 @@ -317,14 +317,6 @@ 23.11 } 23.12 23.13 23.14 -void C1_MacroAssembler::method_exit(bool restore_frame) { 23.15 - if (restore_frame) { 23.16 - leave(); 23.17 - } 23.18 - ret(0); 23.19 -} 23.20 - 23.21 - 23.22 void C1_MacroAssembler::build_frame(int frame_size_in_bytes) { 23.23 // Make sure there is enough stack space for this method's activation. 23.24 // Note that we do this before doing an enter(). This matches the 23.25 @@ -333,7 +325,7 @@ 23.26 // between the two compilers. 23.27 generate_stack_overflow_check(frame_size_in_bytes); 23.28 23.29 - enter(); 23.30 + push(rbp); 23.31 #ifdef TIERED 23.32 // c2 leaves fpu stack dirty. Clean it on entry 23.33 if (UseSSE < 2 ) { 23.34 @@ -344,6 +336,12 @@ 23.35 } 23.36 23.37 23.38 +void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) { 23.39 + increment(rsp, frame_size_in_bytes); // Does not emit code for frame_size == 0 23.40 + pop(rbp); 23.41 +} 23.42 + 23.43 + 23.44 void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) { 23.45 if (C1Breakpoint) int3(); 23.46 inline_cache_check(receiver, ic_klass);
24.1 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Mar 25 16:54:59 2010 -0700 24.2 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Mar 26 11:10:26 2010 -0400 24.3 @@ -1,5 +1,5 @@ 24.4 /* 24.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 24.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 24.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.8 * 24.9 * This code is free software; you can redistribute it and/or modify it 24.10 @@ -688,18 +688,21 @@ 24.11 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); 24.12 oop_maps->add_gc_map(call_offset, oop_map); 24.13 24.14 - // rax,: handler address or NULL if no handler exists 24.15 + // rax,: handler address 24.16 // will be the deopt blob if nmethod was deoptimized while we looked up 24.17 // handler regardless of whether handler existed in the nmethod. 24.18 24.19 // only rax, is valid at this time, all other registers have been destroyed by the runtime call 24.20 __ invalidate_registers(false, true, true, true, true, true); 24.21 24.22 +#ifdef ASSERT 24.23 // Do we have an exception handler in the nmethod? 24.24 - Label no_handler; 24.25 Label done; 24.26 __ testptr(rax, rax); 24.27 - __ jcc(Assembler::zero, no_handler); 24.28 + __ jcc(Assembler::notZero, done); 24.29 + __ stop("no handler found"); 24.30 + __ bind(done); 24.31 +#endif 24.32 24.33 // exception handler found 24.34 // patch the return address -> the stub will directly return to the exception handler 24.35 @@ -712,36 +715,14 @@ 24.36 __ leave(); 24.37 __ ret(0); 24.38 24.39 - __ bind(no_handler); 24.40 - // no exception handler found in this method, so the exception is 24.41 - // forwarded to the caller (using the unwind code of the nmethod) 24.42 - // there is no need to restore the registers 24.43 - 24.44 - // restore the real return address that was saved before the RT-call 24.45 - __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size)); 24.46 - __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr); 24.47 - 24.48 - // load address of JavaThread object for thread-local data 24.49 - NOT_LP64(__ get_thread(thread);) 24.50 - // restore exception oop into rax, (convention for unwind code) 24.51 - __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset())); 24.52 - 24.53 - // clear exception fields in JavaThread because they are no longer needed 24.54 - // (fields must be cleared because they are processed by GC otherwise) 24.55 - __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD); 24.56 - __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD); 24.57 - 24.58 - // pop the stub frame off 24.59 - __ leave(); 24.60 - 24.61 - generate_unwind_exception(sasm); 24.62 - __ stop("should not reach here"); 24.63 } 24.64 24.65 24.66 void Runtime1::generate_unwind_exception(StubAssembler *sasm) { 24.67 // incoming parameters 24.68 const Register exception_oop = rax; 24.69 + // callee-saved copy of exception_oop during runtime call 24.70 + const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14); 24.71 // other registers used in this stub 24.72 const Register exception_pc = rdx; 24.73 const Register handler_addr = rbx; 24.74 @@ -769,38 +750,39 @@ 24.75 // clear the FPU stack in case any FPU results are left behind 24.76 __ empty_FPU_stack(); 24.77 24.78 - // leave activation of nmethod 24.79 - __ leave(); 24.80 - // store return address (is on top of stack after leave) 24.81 + // save exception_oop in callee-saved register to preserve it during runtime calls 24.82 + __ verify_not_null_oop(exception_oop); 24.83 + __ movptr(exception_oop_callee_saved, exception_oop); 24.84 + 24.85 + NOT_LP64(__ get_thread(thread);) 24.86 + // Get return address (is on top of stack after leave). 24.87 __ movptr(exception_pc, Address(rsp, 0)); 24.88 24.89 - __ verify_oop(exception_oop); 24.90 + // search the exception handler address of the caller (using the return address) 24.91 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); 24.92 + // rax: exception handler address of the caller 24.93 24.94 - // save exception oop from rax, to stack before call 24.95 - __ push(exception_oop); 24.96 - 24.97 - // search the exception handler address of the caller (using the return address) 24.98 - __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc); 24.99 - // rax,: exception handler address of the caller 24.100 - 24.101 - // only rax, is valid at this time, all other registers have been destroyed by the call 24.102 - __ invalidate_registers(false, true, true, true, true, true); 24.103 + // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call. 24.104 + __ invalidate_registers(false, true, true, true, false, true); 24.105 24.106 // move result of call into correct register 24.107 __ movptr(handler_addr, rax); 24.108 24.109 - // restore exception oop in rax, (required convention of exception handler) 24.110 - __ pop(exception_oop); 24.111 + // Restore exception oop to RAX (required convention of exception handler). 24.112 + __ movptr(exception_oop, exception_oop_callee_saved); 24.113 24.114 - __ verify_oop(exception_oop); 24.115 + // verify that there is really a valid exception in rax 24.116 + __ verify_not_null_oop(exception_oop); 24.117 24.118 // get throwing pc (= return address). 24.119 // rdx has been destroyed by the call, so it must be set again 24.120 // the pop is also necessary to simulate the effect of a ret(0) 24.121 __ pop(exception_pc); 24.122 24.123 - // verify that that there is really a valid exception in rax, 24.124 - __ verify_not_null_oop(exception_oop); 24.125 + // Restore SP from BP if the exception PC is a MethodHandle call site. 24.126 + NOT_LP64(__ get_thread(thread);) 24.127 + __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0); 24.128 + __ cmovptr(Assembler::notEqual, rsp, rbp); 24.129 24.130 // continue at exception handler (return address removed) 24.131 // note: do *not* remove arguments when unwinding the 24.132 @@ -808,9 +790,9 @@ 24.133 // all arguments on the stack when entering the 24.134 // runtime to determine the exception handler 24.135 // (GC happens at call site with arguments!) 24.136 - // rax,: exception oop 24.137 + // rax: exception oop 24.138 // rdx: throwing pc 24.139 - // rbx,: exception handler 24.140 + // rbx: exception handler 24.141 __ jmp(handler_addr); 24.142 } 24.143
25.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp Thu Mar 25 16:54:59 2010 -0700 25.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Fri Mar 26 11:10:26 2010 -0400 25.3 @@ -1,5 +1,5 @@ 25.4 /* 25.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 25.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 25.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.8 * 25.9 * This code is free software; you can redistribute it and/or modify it 25.10 @@ -60,13 +60,13 @@ 25.11 } 25.12 25.13 #ifdef ASSERT 25.14 -static void verify_argslot(MacroAssembler* _masm, Register rax_argslot, 25.15 +static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, 25.16 const char* error_message) { 25.17 // Verify that argslot lies within (rsp, rbp]. 25.18 Label L_ok, L_bad; 25.19 - __ cmpptr(rax_argslot, rbp); 25.20 + __ cmpptr(argslot_reg, rbp); 25.21 __ jccb(Assembler::above, L_bad); 25.22 - __ cmpptr(rsp, rax_argslot); 25.23 + __ cmpptr(rsp, argslot_reg); 25.24 __ jccb(Assembler::below, L_ok); 25.25 __ bind(L_bad); 25.26 __ stop(error_message); 25.27 @@ -178,22 +178,6 @@ 25.28 25.29 // Now move the argslot down, to point to the opened-up space. 25.30 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr)); 25.31 - 25.32 - if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) { 25.33 - // The caller has specified a bitmask of tags to put into the opened space. 25.34 - // This only works when the arg_slots value is an assembly-time constant. 25.35 - int constant_arg_slots = arg_slots.as_constant() / stack_move_unit(); 25.36 - int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes(); 25.37 - for (int slot = 0; slot < constant_arg_slots; slot++) { 25.38 - BasicType slot_type = ((arg_mask & (1 << slot)) == 0 ? T_OBJECT : T_INT); 25.39 - int slot_offset = Interpreter::stackElementSize() * slot; 25.40 - Address tag_addr(rax_argslot, slot_offset + tag_offset); 25.41 - __ movptr(tag_addr, frame::tag_for_basic_type(slot_type)); 25.42 - } 25.43 - // Note that the new argument slots are tagged properly but contain 25.44 - // garbage at this point. The value portions must be initialized 25.45 - // by the caller. (Especially references!) 25.46 - } 25.47 } 25.48 25.49 // Helper to remove argument slots from the stack. 25.50 @@ -206,18 +190,9 @@ 25.51 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); 25.52 25.53 #ifdef ASSERT 25.54 - { 25.55 - // Verify that [argslot..argslot+size) lies within (rsp, rbp). 25.56 - Label L_ok, L_bad; 25.57 - __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); 25.58 - __ cmpptr(rbx_temp, rbp); 25.59 - __ jccb(Assembler::above, L_bad); 25.60 - __ cmpptr(rsp, rax_argslot); 25.61 - __ jccb(Assembler::below, L_ok); 25.62 - __ bind(L_bad); 25.63 - __ stop("deleted argument(s) must fall within current frame"); 25.64 - __ bind(L_ok); 25.65 - } 25.66 + // Verify that [argslot..argslot+size) lies within (rsp, rbp). 25.67 + __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); 25.68 + verify_argslot(_masm, rbx_temp, "deleted argument(s) must fall within current frame"); 25.69 if (arg_slots.is_register()) { 25.70 Label L_ok, L_bad; 25.71 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); 25.72 @@ -321,12 +296,6 @@ 25.73 Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() ); 25.74 Address vmarg; // __ argument_address(vmargslot) 25.75 25.76 - int tag_offset = -1; 25.77 - if (TaggedStackInterpreter) { 25.78 - tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes(); 25.79 - assert(tag_offset = wordSize, "stack grows as expected"); 25.80 - } 25.81 - 25.82 const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); 25.83 25.84 if (have_entry(ek)) { 25.85 @@ -372,11 +341,8 @@ 25.86 __ mov(rsp, rsi); // cut the stack back to where the caller started 25.87 25.88 // Repush the arguments as if coming from the interpreter. 25.89 - if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_INT)); 25.90 __ push(rdx_code); 25.91 - if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT)); 25.92 __ push(rcx_fail); 25.93 - if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT)); 25.94 __ push(rax_want); 25.95 25.96 Register rbx_method = rbx_temp; 25.97 @@ -397,7 +363,6 @@ 25.98 // Do something that is at least causes a valid throw from the interpreter. 25.99 __ bind(no_method); 25.100 __ pop(rax_want); 25.101 - if (TaggedStackInterpreter) __ pop(rcx_fail); 25.102 __ pop(rcx_fail); 25.103 __ push(rax_want); 25.104 __ push(rcx_fail); 25.105 @@ -510,18 +475,10 @@ 25.106 case _bound_long_direct_mh: 25.107 { 25.108 bool direct_to_method = (ek >= _bound_ref_direct_mh); 25.109 - BasicType arg_type = T_ILLEGAL; 25.110 - if (ek == _bound_long_mh || ek == _bound_long_direct_mh) { 25.111 - arg_type = T_LONG; 25.112 - } else if (ek == _bound_int_mh || ek == _bound_int_direct_mh) { 25.113 - arg_type = T_INT; 25.114 - } else { 25.115 - assert(ek == _bound_ref_mh || ek == _bound_ref_direct_mh, "must be ref"); 25.116 - arg_type = T_OBJECT; 25.117 - } 25.118 - int arg_slots = type2size[arg_type]; 25.119 - int arg_mask = (arg_type == T_OBJECT ? _INSERT_REF_MASK : 25.120 - arg_slots == 1 ? _INSERT_INT_MASK : _INSERT_LONG_MASK); 25.121 + BasicType arg_type = T_ILLEGAL; 25.122 + int arg_mask = _INSERT_NO_MASK; 25.123 + int arg_slots = -1; 25.124 + get_ek_bound_mh_info(ek, arg_type, arg_mask, arg_slots); 25.125 25.126 // make room for the new argument: 25.127 __ movl(rax_argslot, rcx_bmh_vmargslot); 25.128 @@ -660,13 +617,10 @@ 25.129 } 25.130 break; 25.131 default: 25.132 - assert(false, ""); 25.133 + ShouldNotReachHere(); 25.134 } 25.135 - goto finish_int_conversion; 25.136 - } 25.137 25.138 - finish_int_conversion: 25.139 - { 25.140 + // Do the requested conversion and store the value. 25.141 Register rbx_vminfo = rbx_temp; 25.142 __ movl(rbx_vminfo, rcx_amh_conversion); 25.143 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); 25.144 @@ -692,7 +646,7 @@ 25.145 __ shrl(rdx_temp /*, rcx*/); 25.146 25.147 __ bind(done); 25.148 - __ movl(vmarg, rdx_temp); 25.149 + __ movl(vmarg, rdx_temp); // Store the value. 25.150 __ xchgptr(rcx, rbx_vminfo); // restore rcx_recv 25.151 25.152 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 25.153 @@ -715,9 +669,14 @@ 25.154 switch (ek) { 25.155 case _adapter_opt_i2l: 25.156 { 25.157 +#ifdef _LP64 25.158 + __ movslq(rdx_temp, vmarg1); // Load sign-extended 25.159 + __ movq(vmarg1, rdx_temp); // Store into first slot 25.160 +#else 25.161 __ movl(rdx_temp, vmarg1); 25.162 - __ sarl(rdx_temp, 31); // __ extend_sign() 25.163 + __ sarl(rdx_temp, BitsPerInt - 1); // __ extend_sign() 25.164 __ movl(vmarg2, rdx_temp); // store second word 25.165 +#endif 25.166 } 25.167 break; 25.168 case _adapter_opt_unboxl: 25.169 @@ -727,14 +686,19 @@ 25.170 int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_LONG); 25.171 assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE), ""); 25.172 __ null_check(rdx_temp, value_offset); 25.173 +#ifdef _LP64 25.174 + __ movq(rbx_temp, Address(rdx_temp, value_offset)); 25.175 + __ movq(vmarg1, rbx_temp); 25.176 +#else 25.177 __ movl(rbx_temp, Address(rdx_temp, value_offset + 0*BytesPerInt)); 25.178 __ movl(rdx_temp, Address(rdx_temp, value_offset + 1*BytesPerInt)); 25.179 __ movl(vmarg1, rbx_temp); 25.180 __ movl(vmarg2, rdx_temp); 25.181 +#endif 25.182 } 25.183 break; 25.184 default: 25.185 - assert(false, ""); 25.186 + ShouldNotReachHere(); 25.187 } 25.188 25.189 __ movptr(rcx_recv, rcx_mh_vmtarget); 25.190 @@ -768,20 +732,9 @@ 25.191 if (ek == _adapter_opt_f2d) { 25.192 __ fld_s(vmarg); // load float to ST0 25.193 __ fstp_s(vmarg); // store single 25.194 - } else if (!TaggedStackInterpreter) { 25.195 + } else { 25.196 __ fld_d(vmarg); // load double to ST0 25.197 __ fstp_s(vmarg); // store single 25.198 - } else { 25.199 - Address vmarg_tag = vmarg.plus_disp(tag_offset); 25.200 - Address vmarg2 = vmarg.plus_disp(Interpreter::stackElementSize()); 25.201 - // vmarg2_tag does not participate in this code 25.202 - Register rbx_tag = rbx_temp; 25.203 - __ movl(rbx_tag, vmarg_tag); // preserve tag 25.204 - __ movl(rdx_temp, vmarg2); // get second word of double 25.205 - __ movl(vmarg_tag, rdx_temp); // align with first word 25.206 - __ fld_d(vmarg); // load double to ST0 25.207 - __ movl(vmarg_tag, rbx_tag); // restore tag 25.208 - __ fstp_s(vmarg); // store single 25.209 } 25.210 #endif //_LP64 25.211 25.212 @@ -812,19 +765,8 @@ 25.213 case _adapter_opt_rot_2_up: 25.214 case _adapter_opt_rot_2_down: 25.215 { 25.216 - int rotate = 0, swap_slots = 0; 25.217 - switch ((int)ek) { 25.218 - case _adapter_opt_swap_1: swap_slots = 1; break; 25.219 - case _adapter_opt_swap_2: swap_slots = 2; break; 25.220 - case _adapter_opt_rot_1_up: swap_slots = 1; rotate++; break; 25.221 - case _adapter_opt_rot_1_down: swap_slots = 1; rotate--; break; 25.222 - case _adapter_opt_rot_2_up: swap_slots = 2; rotate++; break; 25.223 - case _adapter_opt_rot_2_down: swap_slots = 2; rotate--; break; 25.224 - default: assert(false, ""); 25.225 - } 25.226 - 25.227 - // the real size of the move must be doubled if TaggedStackInterpreter: 25.228 - int swap_bytes = (int)( swap_slots * Interpreter::stackElementWords() * wordSize ); 25.229 + int swap_bytes = 0, rotate = 0; 25.230 + get_ek_adapter_opt_swap_rot_info(ek, swap_bytes, rotate); 25.231 25.232 // 'argslot' is the position of the first argument to swap 25.233 __ movl(rax_argslot, rcx_amh_vmargslot); 25.234 @@ -925,8 +867,8 @@ 25.235 25.236 // 'stack_move' is negative number of words to duplicate 25.237 Register rdx_stack_move = rdx_temp; 25.238 - __ movl(rdx_stack_move, rcx_amh_conversion); 25.239 - __ sarl(rdx_stack_move, CONV_STACK_MOVE_SHIFT); 25.240 + __ movl2ptr(rdx_stack_move, rcx_amh_conversion); 25.241 + __ sarptr(rdx_stack_move, CONV_STACK_MOVE_SHIFT); 25.242 25.243 int argslot0_num = 0; 25.244 Address argslot0 = __ argument_address(RegisterOrConstant(argslot0_num)); 25.245 @@ -988,8 +930,8 @@ 25.246 25.247 // 'stack_move' is number of words to drop 25.248 Register rdi_stack_move = rdi; 25.249 - __ movl(rdi_stack_move, rcx_amh_conversion); 25.250 - __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT); 25.251 + __ movl2ptr(rdi_stack_move, rcx_amh_conversion); 25.252 + __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT); 25.253 remove_arg_slots(_masm, rdi_stack_move, 25.254 rax_argslot, rbx_temp, rdx_temp); 25.255 25.256 @@ -1014,11 +956,7 @@ 25.257 case _adapter_opt_spread_more: 25.258 { 25.259 // spread an array out into a group of arguments 25.260 - int length_constant = -1; 25.261 - switch (ek) { 25.262 - case _adapter_opt_spread_0: length_constant = 0; break; 25.263 - case _adapter_opt_spread_1: length_constant = 1; break; 25.264 - } 25.265 + int length_constant = get_ek_adapter_opt_spread_info(ek); 25.266 25.267 // find the address of the array argument 25.268 __ movl(rax_argslot, rcx_amh_vmargslot); 25.269 @@ -1079,8 +1017,8 @@ 25.270 __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize())); 25.271 // 'stack_move' is negative number of words to insert 25.272 Register rdi_stack_move = rdi; 25.273 - __ movl(rdi_stack_move, rcx_amh_conversion); 25.274 - __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT); 25.275 + __ movl2ptr(rdi_stack_move, rcx_amh_conversion); 25.276 + __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT); 25.277 Register rsi_temp = rsi_array; // spill this 25.278 insert_arg_slots(_masm, rdi_stack_move, -1, 25.279 rax_argslot, rbx_temp, rsi_temp); 25.280 @@ -1114,10 +1052,6 @@ 25.281 __ movptr(rbx_temp, Address(rsi_source, 0)); 25.282 __ movptr(Address(rax_argslot, 0), rbx_temp); 25.283 __ addptr(rsi_source, type2aelembytes(elem_type)); 25.284 - if (TaggedStackInterpreter) { 25.285 - __ movptr(Address(rax_argslot, tag_offset), 25.286 - frame::tag_for_basic_type(elem_type)); 25.287 - } 25.288 __ addptr(rax_argslot, Interpreter::stackElementSize()); 25.289 __ cmpptr(rax_argslot, rdx_argslot_limit); 25.290 __ jccb(Assembler::less, loop); 25.291 @@ -1131,11 +1065,7 @@ 25.292 __ movptr(rbx_temp, Address(rsi_array, elem_offset)); 25.293 __ movptr(Address(rax_argslot, slot_offset), rbx_temp); 25.294 elem_offset += type2aelembytes(elem_type); 25.295 - if (TaggedStackInterpreter) { 25.296 - __ movptr(Address(rax_argslot, slot_offset + tag_offset), 25.297 - frame::tag_for_basic_type(elem_type)); 25.298 - } 25.299 - slot_offset += Interpreter::stackElementSize(); 25.300 + slot_offset += Interpreter::stackElementSize(); 25.301 } 25.302 } 25.303
26.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700 26.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Mar 26 11:10:26 2010 -0400 26.3 @@ -369,7 +369,7 @@ 26.4 // The pending exception in Thread is converted into a Java-level exception. 26.5 // 26.6 // Contract with Java-level exception handlers: 26.7 - // rax,: exception 26.8 + // rax: exception 26.9 // rdx: throwing pc 26.10 // 26.11 // NOTE: At entry of this stub, exception-pc must be on stack !! 26.12 @@ -377,6 +377,12 @@ 26.13 address generate_forward_exception() { 26.14 StubCodeMark mark(this, "StubRoutines", "forward exception"); 26.15 address start = __ pc(); 26.16 + const Register thread = rcx; 26.17 + 26.18 + // other registers used in this stub 26.19 + const Register exception_oop = rax; 26.20 + const Register handler_addr = rbx; 26.21 + const Register exception_pc = rdx; 26.22 26.23 // Upon entry, the sp points to the return address returning into Java 26.24 // (interpreted or compiled) code; i.e., the return address becomes the 26.25 @@ -389,8 +395,8 @@ 26.26 #ifdef ASSERT 26.27 // make sure this code is only executed if there is a pending exception 26.28 { Label L; 26.29 - __ get_thread(rcx); 26.30 - __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 26.31 + __ get_thread(thread); 26.32 + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 26.33 __ jcc(Assembler::notEqual, L); 26.34 __ stop("StubRoutines::forward exception: no pending exception (1)"); 26.35 __ bind(L); 26.36 @@ -398,33 +404,40 @@ 26.37 #endif 26.38 26.39 // compute exception handler into rbx, 26.40 - __ movptr(rax, Address(rsp, 0)); 26.41 + __ get_thread(thread); 26.42 + __ movptr(exception_pc, Address(rsp, 0)); 26.43 BLOCK_COMMENT("call exception_handler_for_return_address"); 26.44 - __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax); 26.45 - __ mov(rbx, rax); 26.46 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); 26.47 + __ mov(handler_addr, rax); 26.48 26.49 - // setup rax, & rdx, remove return address & clear pending exception 26.50 - __ get_thread(rcx); 26.51 - __ pop(rdx); 26.52 - __ movptr(rax, Address(rcx, Thread::pending_exception_offset())); 26.53 - __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); 26.54 + // setup rax & rdx, remove return address & clear pending exception 26.55 + __ get_thread(thread); 26.56 + __ pop(exception_pc); 26.57 + __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); 26.58 + __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); 26.59 26.60 #ifdef ASSERT 26.61 // make sure exception is set 26.62 { Label L; 26.63 - __ testptr(rax, rax); 26.64 + __ testptr(exception_oop, exception_oop); 26.65 __ jcc(Assembler::notEqual, L); 26.66 __ stop("StubRoutines::forward exception: no pending exception (2)"); 26.67 __ bind(L); 26.68 } 26.69 #endif 26.70 26.71 + // Verify that there is really a valid exception in RAX. 26.72 + __ verify_oop(exception_oop); 26.73 + 26.74 + // Restore SP from BP if the exception PC is a MethodHandle call site. 26.75 + __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0); 26.76 + __ cmovptr(Assembler::notEqual, rsp, rbp); 26.77 + 26.78 // continue at exception handler (return address removed) 26.79 - // rax,: exception 26.80 - // rbx,: exception handler 26.81 + // rax: exception 26.82 + // rbx: exception handler 26.83 // rdx: throwing pc 26.84 - __ verify_oop(rax); 26.85 - __ jmp(rbx); 26.86 + __ jmp(handler_addr); 26.87 26.88 return start; 26.89 } 26.90 @@ -2263,16 +2276,6 @@ 26.91 // arraycopy stubs used by compilers 26.92 generate_arraycopy_stubs(); 26.93 26.94 - // generic method handle stubs 26.95 - if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) { 26.96 - for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; 26.97 - ek < MethodHandles::_EK_LIMIT; 26.98 - ek = MethodHandles::EntryKind(1 + (int)ek)) { 26.99 - StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); 26.100 - MethodHandles::generate_method_handle_stub(_masm, ek); 26.101 - } 26.102 - } 26.103 - 26.104 generate_math_stubs(); 26.105 } 26.106
27.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700 27.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Mar 26 11:10:26 2010 -0400 27.3 @@ -466,7 +466,7 @@ 27.4 BLOCK_COMMENT("call exception_handler_for_return_address"); 27.5 __ call_VM_leaf(CAST_FROM_FN_PTR(address, 27.6 SharedRuntime::exception_handler_for_return_address), 27.7 - c_rarg0); 27.8 + r15_thread, c_rarg0); 27.9 __ mov(rbx, rax); 27.10 27.11 // setup rax & rdx, remove return address & clear pending exception 27.12 @@ -3009,16 +3009,6 @@ 27.13 // arraycopy stubs used by compilers 27.14 generate_arraycopy_stubs(); 27.15 27.16 - // generic method handle stubs 27.17 - if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) { 27.18 - for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; 27.19 - ek < MethodHandles::_EK_LIMIT; 27.20 - ek = MethodHandles::EntryKind(1 + (int)ek)) { 27.21 - StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); 27.22 - MethodHandles::generate_method_handle_stub(_masm, ek); 27.23 - } 27.24 - } 27.25 - 27.26 generate_math_stubs(); 27.27 } 27.28
28.1 --- a/src/cpu/x86/vm/stubRoutines_x86_32.hpp Thu Mar 25 16:54:59 2010 -0700 28.2 +++ b/src/cpu/x86/vm/stubRoutines_x86_32.hpp Fri Mar 26 11:10:26 2010 -0400 28.3 @@ -1,5 +1,5 @@ 28.4 /* 28.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 28.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 28.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.8 * 28.9 * This code is free software; you can redistribute it and/or modify it 28.10 @@ -31,6 +31,11 @@ 28.11 code_size2 = 22000 // simply increase if too small (assembler will crash if too small) 28.12 }; 28.13 28.14 +// MethodHandles adapters 28.15 +enum method_handles_platform_dependent_constants { 28.16 + method_handles_adapters_code_size = 5000 28.17 +}; 28.18 + 28.19 class x86 { 28.20 friend class StubGenerator; 28.21 friend class VMStructs;
29.1 --- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp Thu Mar 25 16:54:59 2010 -0700 29.2 +++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp Fri Mar 26 11:10:26 2010 -0400 29.3 @@ -1,5 +1,5 @@ 29.4 /* 29.5 - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. 29.6 + * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. 29.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.8 * 29.9 * This code is free software; you can redistribute it and/or modify it 29.10 @@ -28,12 +28,14 @@ 29.11 29.12 static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; } 29.13 29.14 -enum platform_dependent_constants 29.15 -{ 29.16 - code_size1 = 19000, // simply increase if too small (assembler will 29.17 - // crash if too small) 29.18 - code_size2 = 22000 // simply increase if too small (assembler will 29.19 - // crash if too small) 29.20 +enum platform_dependent_constants { 29.21 + code_size1 = 19000, // simply increase if too small (assembler will crash if too small) 29.22 + code_size2 = 22000 // simply increase if too small (assembler will crash if too small) 29.23 +}; 29.24 + 29.25 +// MethodHandles adapters 29.26 +enum method_handles_platform_dependent_constants { 29.27 + method_handles_adapters_code_size = 13000 29.28 }; 29.29 29.30 class x86 {
30.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700 30.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Mar 26 11:10:26 2010 -0400 30.3 @@ -1550,6 +1550,7 @@ 30.4 void TemplateInterpreterGenerator::generate_throw_exception() { 30.5 // Entry point in previous activation (i.e., if the caller was interpreted) 30.6 Interpreter::_rethrow_exception_entry = __ pc(); 30.7 + const Register thread = rcx; 30.8 30.9 // Restore sp to interpreter_frame_last_sp even though we are going 30.10 // to empty the expression stack for the exception processing. 30.11 @@ -1598,10 +1599,10 @@ 30.12 // Set the popframe_processing bit in pending_popframe_condition indicating that we are 30.13 // currently handling popframe, so that call_VMs that may happen later do not trigger new 30.14 // popframe handling cycles. 30.15 - __ get_thread(rcx); 30.16 - __ movl(rdx, Address(rcx, JavaThread::popframe_condition_offset())); 30.17 + __ get_thread(thread); 30.18 + __ movl(rdx, Address(thread, JavaThread::popframe_condition_offset())); 30.19 __ orl(rdx, JavaThread::popframe_processing_bit); 30.20 - __ movl(Address(rcx, JavaThread::popframe_condition_offset()), rdx); 30.21 + __ movl(Address(thread, JavaThread::popframe_condition_offset()), rdx); 30.22 30.23 { 30.24 // Check to see whether we are returning to a deoptimized frame. 30.25 @@ -1629,8 +1630,8 @@ 30.26 __ subptr(rdi, rax); 30.27 __ addptr(rdi, wordSize); 30.28 // Save these arguments 30.29 - __ get_thread(rcx); 30.30 - __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), rcx, rax, rdi); 30.31 + __ get_thread(thread); 30.32 + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), thread, rax, rdi); 30.33 30.34 __ remove_activation(vtos, rdx, 30.35 /* throw_monitor_exception */ false, 30.36 @@ -1638,8 +1639,8 @@ 30.37 /* notify_jvmdi */ false); 30.38 30.39 // Inform deoptimization that it is responsible for restoring these arguments 30.40 - __ get_thread(rcx); 30.41 - __ movl(Address(rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit); 30.42 + __ get_thread(thread); 30.43 + __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit); 30.44 30.45 // Continue in deoptimization handler 30.46 __ jmp(rdx); 30.47 @@ -1665,12 +1666,12 @@ 30.48 // expression stack if necessary. 30.49 __ mov(rax, rsp); 30.50 __ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); 30.51 - __ get_thread(rcx); 30.52 + __ get_thread(thread); 30.53 // PC must point into interpreter here 30.54 - __ set_last_Java_frame(rcx, noreg, rbp, __ pc()); 30.55 - __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), rcx, rax, rbx); 30.56 - __ get_thread(rcx); 30.57 - __ reset_last_Java_frame(rcx, true, true); 30.58 + __ set_last_Java_frame(thread, noreg, rbp, __ pc()); 30.59 + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), thread, rax, rbx); 30.60 + __ get_thread(thread); 30.61 + __ reset_last_Java_frame(thread, true, true); 30.62 // Restore the last_sp and null it out 30.63 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); 30.64 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 30.65 @@ -1684,8 +1685,8 @@ 30.66 } 30.67 30.68 // Clear the popframe condition flag 30.69 - __ get_thread(rcx); 30.70 - __ movl(Address(rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); 30.71 + __ get_thread(thread); 30.72 + __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); 30.73 30.74 __ dispatch_next(vtos); 30.75 // end of PopFrame support 30.76 @@ -1694,27 +1695,27 @@ 30.77 30.78 // preserve exception over this code sequence 30.79 __ pop_ptr(rax); 30.80 - __ get_thread(rcx); 30.81 - __ movptr(Address(rcx, JavaThread::vm_result_offset()), rax); 30.82 + __ get_thread(thread); 30.83 + __ movptr(Address(thread, JavaThread::vm_result_offset()), rax); 30.84 // remove the activation (without doing throws on illegalMonitorExceptions) 30.85 __ remove_activation(vtos, rdx, false, true, false); 30.86 // restore exception 30.87 - __ get_thread(rcx); 30.88 - __ movptr(rax, Address(rcx, JavaThread::vm_result_offset())); 30.89 - __ movptr(Address(rcx, JavaThread::vm_result_offset()), NULL_WORD); 30.90 + __ get_thread(thread); 30.91 + __ movptr(rax, Address(thread, JavaThread::vm_result_offset())); 30.92 + __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); 30.93 __ verify_oop(rax); 30.94 30.95 // Inbetween activations - previous activation type unknown yet 30.96 // compute continuation point - the continuation point expects 30.97 // the following registers set up: 30.98 // 30.99 - // rax,: exception 30.100 + // rax: exception 30.101 // rdx: return address/pc that threw exception 30.102 // rsp: expression stack of caller 30.103 - // rbp,: rbp, of caller 30.104 + // rbp: rbp, of caller 30.105 __ push(rax); // save exception 30.106 __ push(rdx); // save return address 30.107 - __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx); 30.108 + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, rdx); 30.109 __ mov(rbx, rax); // save exception handler 30.110 __ pop(rdx); // restore return address 30.111 __ pop(rax); // restore exception 30.112 @@ -1728,6 +1729,7 @@ 30.113 // 30.114 address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) { 30.115 address entry = __ pc(); 30.116 + const Register thread = rcx; 30.117 30.118 __ restore_bcp(); 30.119 __ restore_locals(); 30.120 @@ -1735,8 +1737,8 @@ 30.121 __ empty_FPU_stack(); 30.122 __ load_earlyret_value(state); 30.123 30.124 - __ get_thread(rcx); 30.125 - __ movptr(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset())); 30.126 + __ get_thread(thread); 30.127 + __ movptr(rcx, Address(thread, JavaThread::jvmti_thread_state_offset())); 30.128 const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset()); 30.129 30.130 // Clear the earlyret state
31.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700 31.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Mar 26 11:10:26 2010 -0400 31.3 @@ -1741,7 +1741,7 @@ 31.4 __ push(rdx); // save return address 31.5 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, 31.6 SharedRuntime::exception_handler_for_return_address), 31.7 - rdx); 31.8 + r15_thread, rdx); 31.9 __ mov(rbx, rax); // save exception handler 31.10 __ pop(rdx); // restore return address 31.11 __ pop(rax); // restore exception
32.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Mar 25 16:54:59 2010 -0700 32.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Mar 26 11:10:26 2010 -0400 32.3 @@ -1,5 +1,5 @@ 32.4 /* 32.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 32.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 32.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.8 * 32.9 * This code is free software; you can redistribute it and/or modify it 32.10 @@ -2915,12 +2915,8 @@ 32.11 __ andl(recv, 0xFF); 32.12 // recv count is 0 based? 32.13 Address recv_addr(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1)); 32.14 - if (is_invokedynamic) { 32.15 - __ lea(recv, recv_addr); 32.16 - } else { 32.17 - __ movptr(recv, recv_addr); 32.18 - __ verify_oop(recv); 32.19 - } 32.20 + __ movptr(recv, recv_addr); 32.21 + __ verify_oop(recv); 32.22 } 32.23 32.24 // do null check if needed
33.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Mar 25 16:54:59 2010 -0700 33.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Mar 26 11:10:26 2010 -0400 33.3 @@ -1,5 +1,5 @@ 33.4 /* 33.5 - * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. 33.6 + * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. 33.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.8 * 33.9 * This code is free software; you can redistribute it and/or modify it 33.10 @@ -2860,12 +2860,8 @@ 33.11 __ andl(recv, 0xFF); 33.12 if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 33.13 Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1)); 33.14 - if (is_invokedynamic) { 33.15 - __ lea(recv, recv_addr); 33.16 - } else { 33.17 - __ movptr(recv, recv_addr); 33.18 - __ verify_oop(recv); 33.19 - } 33.20 + __ movptr(recv, recv_addr); 33.21 + __ verify_oop(recv); 33.22 } 33.23 33.24 // do null check if needed
34.1 --- a/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp Thu Mar 25 16:54:59 2010 -0700 34.2 +++ b/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp Fri Mar 26 11:10:26 2010 -0400 34.3 @@ -1,6 +1,6 @@ 34.4 /* 34.5 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. 34.6 - * Copyright 2007, 2008 Red Hat, Inc. 34.7 + * Copyright 2007, 2008, 2010 Red Hat, Inc. 34.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.9 * 34.10 * This code is free software; you can redistribute it and/or modify it 34.11 @@ -29,11 +29,10 @@ 34.12 // 34.13 34.14 define_pd_global(bool, DontYieldALot, false); 34.15 +define_pd_global(intx, ThreadStackSize, 1536); 34.16 #ifdef _LP64 34.17 -define_pd_global(intx, ThreadStackSize, 1536); 34.18 define_pd_global(intx, VMThreadStackSize, 1024); 34.19 #else 34.20 -define_pd_global(intx, ThreadStackSize, 1024); 34.21 define_pd_global(intx, VMThreadStackSize, 512); 34.22 #endif // _LP64 34.23 define_pd_global(intx, SurvivorRatio, 8);
35.1 --- a/src/share/vm/c1/c1_Canonicalizer.cpp Thu Mar 25 16:54:59 2010 -0700 35.2 +++ b/src/share/vm/c1/c1_Canonicalizer.cpp Fri Mar 26 11:10:26 2010 -0400 35.3 @@ -1,5 +1,5 @@ 35.4 /* 35.5 - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 35.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 35.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 35.8 * 35.9 * This code is free software; you can redistribute it and/or modify it 35.10 @@ -222,11 +222,15 @@ 35.11 } 35.12 } else { 35.13 LoadField* lf = x->array()->as_LoadField(); 35.14 - if (lf != NULL && lf->field()->is_constant()) { 35.15 - ciObject* c = lf->field()->constant_value().as_object(); 35.16 - if (c->is_array()) { 35.17 - ciArray* array = (ciArray*) c; 35.18 - set_constant(array->length()); 35.19 + if (lf != NULL) { 35.20 + ciField* field = lf->field(); 35.21 + if (field->is_constant() && field->is_static()) { 35.22 + // final static field 35.23 + ciObject* c = field->constant_value().as_object(); 35.24 + if (c->is_array()) { 35.25 + ciArray* array = (ciArray*) c; 35.26 + set_constant(array->length()); 35.27 + } 35.28 } 35.29 } 35.30 }
36.1 --- a/src/share/vm/c1/c1_CodeStubs.hpp Thu Mar 25 16:54:59 2010 -0700 36.2 +++ b/src/share/vm/c1/c1_CodeStubs.hpp Fri Mar 26 11:10:26 2010 -0400 36.3 @@ -1,5 +1,5 @@ 36.4 /* 36.5 - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 36.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 36.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.8 * 36.9 * This code is free software; you can redistribute it and/or modify it 36.10 @@ -415,6 +415,28 @@ 36.11 }; 36.12 36.13 36.14 +//------------------------------------------------------------------------------ 36.15 +// DeoptimizeStub 36.16 +// 36.17 +class DeoptimizeStub : public CodeStub { 36.18 +private: 36.19 + CodeEmitInfo* _info; 36.20 + 36.21 +public: 36.22 + DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {} 36.23 + 36.24 + virtual void emit_code(LIR_Assembler* e); 36.25 + virtual CodeEmitInfo* info() const { return _info; } 36.26 + virtual bool is_exception_throw_stub() const { return true; } 36.27 + virtual void visit(LIR_OpVisitState* visitor) { 36.28 + visitor->do_slow_case(_info); 36.29 + } 36.30 +#ifndef PRODUCT 36.31 + virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); } 36.32 +#endif // PRODUCT 36.33 +}; 36.34 + 36.35 + 36.36 class SimpleExceptionStub: public CodeStub { 36.37 private: 36.38 LIR_Opr _obj;
37.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Mar 25 16:54:59 2010 -0700 37.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Fri Mar 26 11:10:26 2010 -0400 37.3 @@ -1,5 +1,5 @@ 37.4 /* 37.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 37.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 37.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 37.8 * 37.9 * This code is free software; you can redistribute it and/or modify it 37.10 @@ -1524,18 +1524,14 @@ 37.11 code = Bytecodes::_invokespecial; 37.12 } 37.13 37.14 - if (code == Bytecodes::_invokedynamic) { 37.15 - BAILOUT("invokedynamic NYI"); // FIXME 37.16 - return; 37.17 - } 37.18 - 37.19 // NEEDS_CLEANUP 37.20 // I've added the target-is_loaded() test below but I don't really understand 37.21 // how klass->is_loaded() can be true and yet target->is_loaded() is false. 37.22 // this happened while running the JCK invokevirtual tests under doit. TKR 37.23 ciMethod* cha_monomorphic_target = NULL; 37.24 ciMethod* exact_target = NULL; 37.25 - if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded()) { 37.26 + if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() && 37.27 + !target->is_method_handle_invoke()) { 37.28 Value receiver = NULL; 37.29 ciInstanceKlass* receiver_klass = NULL; 37.30 bool type_is_exact = false; 37.31 @@ -1681,11 +1677,20 @@ 37.32 CHECK_BAILOUT(); 37.33 37.34 // inlining not successful => standard invoke 37.35 - bool is_static = code == Bytecodes::_invokestatic; 37.36 + bool is_loaded = target->is_loaded(); 37.37 + bool has_receiver = 37.38 + code == Bytecodes::_invokespecial || 37.39 + code == Bytecodes::_invokevirtual || 37.40 + code == Bytecodes::_invokeinterface; 37.41 + bool is_invokedynamic = code == Bytecodes::_invokedynamic; 37.42 ValueType* result_type = as_ValueType(target->return_type()); 37.43 + 37.44 + // We require the debug info to be the "state before" because 37.45 + // invokedynamics may deoptimize. 37.46 + ValueStack* state_before = is_invokedynamic ? state()->copy() : NULL; 37.47 + 37.48 Values* args = state()->pop_arguments(target->arg_size_no_receiver()); 37.49 - Value recv = is_static ? NULL : apop(); 37.50 - bool is_loaded = target->is_loaded(); 37.51 + Value recv = has_receiver ? apop() : NULL; 37.52 int vtable_index = methodOopDesc::invalid_vtable_index; 37.53 37.54 #ifdef SPARC 37.55 @@ -1723,7 +1728,7 @@ 37.56 profile_call(recv, target_klass); 37.57 } 37.58 37.59 - Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target); 37.60 + Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before); 37.61 // push result 37.62 append_split(result); 37.63 37.64 @@ -2862,20 +2867,18 @@ 37.65 _initial_state = state_at_entry(); 37.66 start_block->merge(_initial_state); 37.67 37.68 - BlockBegin* sync_handler = NULL; 37.69 - if (method()->is_synchronized() || _compilation->env()->dtrace_method_probes()) { 37.70 - // setup an exception handler to do the unlocking and/or notification 37.71 - sync_handler = new BlockBegin(-1); 37.72 - sync_handler->set(BlockBegin::exception_entry_flag); 37.73 - sync_handler->set(BlockBegin::is_on_work_list_flag); 37.74 - sync_handler->set(BlockBegin::default_exception_handler_flag); 37.75 - 37.76 - ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0); 37.77 - XHandler* h = new XHandler(desc); 37.78 - h->set_entry_block(sync_handler); 37.79 - scope_data()->xhandlers()->append(h); 37.80 - scope_data()->set_has_handler(); 37.81 - } 37.82 + // setup an exception handler to do the unlocking and/or 37.83 + // notification and unwind the frame. 37.84 + BlockBegin* sync_handler = new BlockBegin(-1); 37.85 + sync_handler->set(BlockBegin::exception_entry_flag); 37.86 + sync_handler->set(BlockBegin::is_on_work_list_flag); 37.87 + sync_handler->set(BlockBegin::default_exception_handler_flag); 37.88 + 37.89 + ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0); 37.90 + XHandler* h = new XHandler(desc); 37.91 + h->set_entry_block(sync_handler); 37.92 + scope_data()->xhandlers()->append(h); 37.93 + scope_data()->set_has_handler(); 37.94 37.95 // complete graph 37.96 _vmap = new ValueMap();
38.1 --- a/src/share/vm/c1/c1_IR.cpp Thu Mar 25 16:54:59 2010 -0700 38.2 +++ b/src/share/vm/c1/c1_IR.cpp Fri Mar 26 11:10:26 2010 -0400 38.3 @@ -1,5 +1,5 @@ 38.4 /* 38.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 38.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 38.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 38.8 * 38.9 * This code is free software; you can redistribute it and/or modify it 38.10 @@ -259,10 +259,10 @@ 38.11 } 38.12 38.13 38.14 -void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) { 38.15 +void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool is_method_handle_invoke) { 38.16 // record the safepoint before recording the debug info for enclosing scopes 38.17 recorder->add_safepoint(pc_offset, _oop_map->deep_copy()); 38.18 - _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/); 38.19 + _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/, is_method_handle_invoke); 38.20 recorder->end_safepoint(pc_offset); 38.21 } 38.22
39.1 --- a/src/share/vm/c1/c1_IR.hpp Thu Mar 25 16:54:59 2010 -0700 39.2 +++ b/src/share/vm/c1/c1_IR.hpp Fri Mar 26 11:10:26 2010 -0400 39.3 @@ -1,5 +1,5 @@ 39.4 /* 39.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 39.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 39.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 39.8 * 39.9 * This code is free software; you can redistribute it and/or modify it 39.10 @@ -242,7 +242,7 @@ 39.11 //Whether we should reexecute this bytecode for deopt 39.12 bool should_reexecute(); 39.13 39.14 - void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost) { 39.15 + void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost, bool is_method_handle_invoke = false) { 39.16 if (caller() != NULL) { 39.17 // Order is significant: Must record caller first. 39.18 caller()->record_debug_info(recorder, pc_offset, false/*topmost*/); 39.19 @@ -252,7 +252,6 @@ 39.20 DebugToken* monvals = recorder->create_monitor_values(monitors()); 39.21 // reexecute allowed only for the topmost frame 39.22 bool reexecute = topmost ? should_reexecute() : false; 39.23 - bool is_method_handle_invoke = false; 39.24 bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis. 39.25 recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals); 39.26 } 39.27 @@ -303,7 +302,7 @@ 39.28 int bci() const { return _bci; } 39.29 39.30 void add_register_oop(LIR_Opr opr); 39.31 - void record_debug_info(DebugInformationRecorder* recorder, int pc_offset); 39.32 + void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool is_method_handle_invoke = false); 39.33 39.34 CodeEmitInfo* next() const { return _next; } 39.35 void set_next(CodeEmitInfo* next) { _next = next; }
40.1 --- a/src/share/vm/c1/c1_Instruction.cpp Thu Mar 25 16:54:59 2010 -0700 40.2 +++ b/src/share/vm/c1/c1_Instruction.cpp Fri Mar 26 11:10:26 2010 -0400 40.3 @@ -1,5 +1,5 @@ 40.4 /* 40.5 - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 40.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 40.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 40.8 * 40.9 * This code is free software; you can redistribute it and/or modify it 40.10 @@ -334,13 +334,14 @@ 40.11 40.12 40.13 Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, 40.14 - int vtable_index, ciMethod* target) 40.15 + int vtable_index, ciMethod* target, ValueStack* state_before) 40.16 : StateSplit(result_type) 40.17 , _code(code) 40.18 , _recv(recv) 40.19 , _args(args) 40.20 , _vtable_index(vtable_index) 40.21 , _target(target) 40.22 + , _state_before(state_before) 40.23 { 40.24 set_flag(TargetIsLoadedFlag, target->is_loaded()); 40.25 set_flag(TargetIsFinalFlag, target_is_loaded() && target->is_final_method()); 40.26 @@ -355,6 +356,9 @@ 40.27 _signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0)); 40.28 if (has_receiver()) { 40.29 _signature->append(as_BasicType(receiver()->type())); 40.30 + } else if (is_invokedynamic()) { 40.31 + // Add the synthetic MethodHandle argument to the signature. 40.32 + _signature->append(T_OBJECT); 40.33 } 40.34 for (int i = 0; i < number_of_arguments(); i++) { 40.35 ValueType* t = argument_at(i)->type(); 40.36 @@ -364,6 +368,13 @@ 40.37 } 40.38 40.39 40.40 +void Invoke::state_values_do(void f(Value*)) { 40.41 + StateSplit::state_values_do(f); 40.42 + if (state_before() != NULL) state_before()->values_do(f); 40.43 + if (state() != NULL) state()->values_do(f); 40.44 +} 40.45 + 40.46 + 40.47 // Implementation of Contant 40.48 intx Constant::hash() const { 40.49 if (_state == NULL) {
41.1 --- a/src/share/vm/c1/c1_Instruction.hpp Thu Mar 25 16:54:59 2010 -0700 41.2 +++ b/src/share/vm/c1/c1_Instruction.hpp Fri Mar 26 11:10:26 2010 -0400 41.3 @@ -1,5 +1,5 @@ 41.4 /* 41.5 - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 41.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 41.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41.8 * 41.9 * This code is free software; you can redistribute it and/or modify it 41.10 @@ -1134,17 +1134,18 @@ 41.11 41.12 LEAF(Invoke, StateSplit) 41.13 private: 41.14 - Bytecodes::Code _code; 41.15 - Value _recv; 41.16 - Values* _args; 41.17 - BasicTypeList* _signature; 41.18 - int _vtable_index; 41.19 - ciMethod* _target; 41.20 + Bytecodes::Code _code; 41.21 + Value _recv; 41.22 + Values* _args; 41.23 + BasicTypeList* _signature; 41.24 + int _vtable_index; 41.25 + ciMethod* _target; 41.26 + ValueStack* _state_before; // Required for deoptimization. 41.27 41.28 public: 41.29 // creation 41.30 Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, 41.31 - int vtable_index, ciMethod* target); 41.32 + int vtable_index, ciMethod* target, ValueStack* state_before); 41.33 41.34 // accessors 41.35 Bytecodes::Code code() const { return _code; } 41.36 @@ -1155,6 +1156,7 @@ 41.37 int vtable_index() const { return _vtable_index; } 41.38 BasicTypeList* signature() const { return _signature; } 41.39 ciMethod* target() const { return _target; } 41.40 + ValueStack* state_before() const { return _state_before; } 41.41 41.42 // Returns false if target is not loaded 41.43 bool target_is_final() const { return check_flag(TargetIsFinalFlag); } 41.44 @@ -1162,6 +1164,9 @@ 41.45 // Returns false if target is not loaded 41.46 bool target_is_strictfp() const { return check_flag(TargetIsStrictfpFlag); } 41.47 41.48 + // JSR 292 support 41.49 + bool is_invokedynamic() const { return code() == Bytecodes::_invokedynamic; } 41.50 + 41.51 // generic 41.52 virtual bool can_trap() const { return true; } 41.53 virtual void input_values_do(void f(Value*)) { 41.54 @@ -1169,6 +1174,7 @@ 41.55 if (has_receiver()) f(&_recv); 41.56 for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i)); 41.57 } 41.58 + virtual void state_values_do(void f(Value*)); 41.59 }; 41.60 41.61
42.1 --- a/src/share/vm/c1/c1_LIR.cpp Thu Mar 25 16:54:59 2010 -0700 42.2 +++ b/src/share/vm/c1/c1_LIR.cpp Fri Mar 26 11:10:26 2010 -0400 42.3 @@ -1,5 +1,5 @@ 42.4 /* 42.5 - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. 42.6 + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. 42.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 42.8 * 42.9 * This code is free software; you can redistribute it and/or modify it 42.10 @@ -76,7 +76,7 @@ 42.11 return LIR_OprFact::oopConst(type->as_ObjectType()->encoding()); 42.12 } 42.13 } 42.14 - case addressTag: return LIR_OprFact::intConst(type->as_AddressConstant()->value()); 42.15 + case addressTag: return LIR_OprFact::addressConst(type->as_AddressConstant()->value()); 42.16 case intTag : return LIR_OprFact::intConst(type->as_IntConstant()->value()); 42.17 case floatTag : return LIR_OprFact::floatConst(type->as_FloatConstant()->value()); 42.18 case longTag : return LIR_OprFact::longConst(type->as_LongConstant()->value()); 42.19 @@ -89,7 +89,7 @@ 42.20 LIR_Opr LIR_OprFact::dummy_value_type(ValueType* type) { 42.21 switch (type->tag()) { 42.22 case objectTag: return LIR_OprFact::oopConst(NULL); 42.23 - case addressTag: 42.24 + case addressTag:return LIR_OprFact::addressConst(0); 42.25 case intTag: return LIR_OprFact::intConst(0); 42.26 case floatTag: return LIR_OprFact::floatConst(0.0); 42.27 case longTag: return LIR_OprFact::longConst(0); 42.28 @@ -689,9 +689,10 @@ 42.29 case lir_static_call: 42.30 case lir_optvirtual_call: 42.31 case lir_icvirtual_call: 42.32 - case lir_virtual_call: { 42.33 - assert(op->as_OpJavaCall() != NULL, "must be"); 42.34 - LIR_OpJavaCall* opJavaCall = (LIR_OpJavaCall*)op; 42.35 + case lir_virtual_call: 42.36 + case lir_dynamic_call: { 42.37 + LIR_OpJavaCall* opJavaCall = op->as_OpJavaCall(); 42.38 + assert(opJavaCall != NULL, "must be"); 42.39 42.40 if (opJavaCall->_receiver->is_valid()) do_input(opJavaCall->_receiver); 42.41 42.42 @@ -704,6 +705,7 @@ 42.43 } 42.44 42.45 if (opJavaCall->_info) do_info(opJavaCall->_info); 42.46 + if (opJavaCall->is_method_handle_invoke()) do_temp(FrameMap::method_handle_invoke_SP_save_opr()); 42.47 do_call(); 42.48 if (opJavaCall->_result->is_valid()) do_output(opJavaCall->_result); 42.49 42.50 @@ -1410,6 +1412,7 @@ 42.51 // LIR_Address 42.52 void LIR_Const::print_value_on(outputStream* out) const { 42.53 switch (type()) { 42.54 + case T_ADDRESS:out->print("address:%d",as_jint()); break; 42.55 case T_INT: out->print("int:%d", as_jint()); break; 42.56 case T_LONG: out->print("lng:%lld", as_jlong()); break; 42.57 case T_FLOAT: out->print("flt:%f", as_jfloat()); break; 42.58 @@ -1590,6 +1593,7 @@ 42.59 case lir_optvirtual_call: s = "optvirtual"; break; 42.60 case lir_icvirtual_call: s = "icvirtual"; break; 42.61 case lir_virtual_call: s = "virtual"; break; 42.62 + case lir_dynamic_call: s = "dynamic"; break; 42.63 // LIR_OpArrayCopy 42.64 case lir_arraycopy: s = "arraycopy"; break; 42.65 // LIR_OpLock
43.1 --- a/src/share/vm/c1/c1_LIR.hpp Thu Mar 25 16:54:59 2010 -0700 43.2 +++ b/src/share/vm/c1/c1_LIR.hpp Fri Mar 26 11:10:26 2010 -0400 43.3 @@ -85,9 +85,10 @@ 43.4 43.5 void type_check(BasicType t) const { assert(type() == t, "type check"); } 43.6 void type_check(BasicType t1, BasicType t2) const { assert(type() == t1 || type() == t2, "type check"); } 43.7 + void type_check(BasicType t1, BasicType t2, BasicType t3) const { assert(type() == t1 || type() == t2 || type() == t3, "type check"); } 43.8 43.9 public: 43.10 - LIR_Const(jint i) { _value.set_type(T_INT); _value.set_jint(i); } 43.11 + LIR_Const(jint i, bool is_address=false) { _value.set_type(is_address?T_ADDRESS:T_INT); _value.set_jint(i); } 43.12 LIR_Const(jlong l) { _value.set_type(T_LONG); _value.set_jlong(l); } 43.13 LIR_Const(jfloat f) { _value.set_type(T_FLOAT); _value.set_jfloat(f); } 43.14 LIR_Const(jdouble d) { _value.set_type(T_DOUBLE); _value.set_jdouble(d); } 43.15 @@ -105,7 +106,7 @@ 43.16 virtual BasicType type() const { return _value.get_type(); } 43.17 virtual LIR_Const* as_constant() { return this; } 43.18 43.19 - jint as_jint() const { type_check(T_INT ); return _value.get_jint(); } 43.20 + jint as_jint() const { type_check(T_INT, T_ADDRESS); return _value.get_jint(); } 43.21 jlong as_jlong() const { type_check(T_LONG ); return _value.get_jlong(); } 43.22 jfloat as_jfloat() const { type_check(T_FLOAT ); return _value.get_jfloat(); } 43.23 jdouble as_jdouble() const { type_check(T_DOUBLE); return _value.get_jdouble(); } 43.24 @@ -120,7 +121,7 @@ 43.25 #endif 43.26 43.27 43.28 - jint as_jint_bits() const { type_check(T_FLOAT, T_INT); return _value.get_jint(); } 43.29 + jint as_jint_bits() const { type_check(T_FLOAT, T_INT, T_ADDRESS); return _value.get_jint(); } 43.30 jint as_jint_lo_bits() const { 43.31 if (type() == T_DOUBLE) { 43.32 return low(jlong_cast(_value.get_jdouble())); 43.33 @@ -718,6 +719,7 @@ 43.34 static LIR_Opr intptrConst(void* p) { return (LIR_Opr)(new LIR_Const(p)); } 43.35 static LIR_Opr intptrConst(intptr_t v) { return (LIR_Opr)(new LIR_Const((void*)v)); } 43.36 static LIR_Opr illegal() { return (LIR_Opr)-1; } 43.37 + static LIR_Opr addressConst(jint i) { return (LIR_Opr)(new LIR_Const(i, true)); } 43.38 43.39 static LIR_Opr value_type(ValueType* type); 43.40 static LIR_Opr dummy_value_type(ValueType* type); 43.41 @@ -840,6 +842,7 @@ 43.42 , lir_optvirtual_call 43.43 , lir_icvirtual_call 43.44 , lir_virtual_call 43.45 + , lir_dynamic_call 43.46 , end_opJavaCall 43.47 , begin_opArrayCopy 43.48 , lir_arraycopy 43.49 @@ -1052,6 +1055,16 @@ 43.50 LIR_Opr receiver() const { return _receiver; } 43.51 ciMethod* method() const { return _method; } 43.52 43.53 + // JSR 292 support. 43.54 + bool is_invokedynamic() const { return code() == lir_dynamic_call; } 43.55 + bool is_method_handle_invoke() const { 43.56 + return 43.57 + is_invokedynamic() // An invokedynamic is always a MethodHandle call site. 43.58 + || 43.59 + (method()->holder()->name() == ciSymbol::java_dyn_MethodHandle() && 43.60 + method()->name() == ciSymbol::invoke_name()); 43.61 + } 43.62 + 43.63 intptr_t vtable_offset() const { 43.64 assert(_code == lir_virtual_call, "only have vtable for real vcall"); 43.65 return (intptr_t) addr(); 43.66 @@ -1766,6 +1779,10 @@ 43.67 intptr_t vtable_offset, LIR_OprList* arguments, CodeEmitInfo* info) { 43.68 append(new LIR_OpJavaCall(lir_virtual_call, method, receiver, result, vtable_offset, arguments, info)); 43.69 } 43.70 + void call_dynamic(ciMethod* method, LIR_Opr receiver, LIR_Opr result, 43.71 + address dest, LIR_OprList* arguments, CodeEmitInfo* info) { 43.72 + append(new LIR_OpJavaCall(lir_dynamic_call, method, receiver, result, dest, arguments, info)); 43.73 + } 43.74 43.75 void get_thread(LIR_Opr result) { append(new LIR_Op0(lir_get_thread, result)); } 43.76 void word_align() { append(new LIR_Op0(lir_word_align)); }
44.1 --- a/src/share/vm/c1/c1_LIRAssembler.cpp Thu Mar 25 16:54:59 2010 -0700 44.2 +++ b/src/share/vm/c1/c1_LIRAssembler.cpp Fri Mar 26 11:10:26 2010 -0400 44.3 @@ -1,5 +1,5 @@ 44.4 /* 44.5 - * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. 44.6 + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. 44.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 44.8 * 44.9 * This code is free software; you can redistribute it and/or modify it 44.10 @@ -301,9 +301,9 @@ 44.11 } 44.12 44.13 44.14 -void LIR_Assembler::add_call_info(int pc_offset, CodeEmitInfo* cinfo) { 44.15 +void LIR_Assembler::add_call_info(int pc_offset, CodeEmitInfo* cinfo, bool is_method_handle_invoke) { 44.16 flush_debug_info(pc_offset); 44.17 - cinfo->record_debug_info(compilation()->debug_info_recorder(), pc_offset); 44.18 + cinfo->record_debug_info(compilation()->debug_info_recorder(), pc_offset, is_method_handle_invoke); 44.19 if (cinfo->exception_handlers() != NULL) { 44.20 compilation()->add_exception_handlers_for_pco(pc_offset, cinfo->exception_handlers()); 44.21 } 44.22 @@ -413,6 +413,12 @@ 44.23 void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { 44.24 verify_oop_map(op->info()); 44.25 44.26 + // JSR 292 44.27 + // Preserve the SP over MethodHandle call sites. 44.28 + if (op->is_method_handle_invoke()) { 44.29 + preserve_SP(op); 44.30 + } 44.31 + 44.32 if (os::is_MP()) { 44.33 // must align calls sites, otherwise they can't be updated atomically on MP hardware 44.34 align_call(op->code()); 44.35 @@ -423,19 +429,25 @@ 44.36 44.37 switch (op->code()) { 44.38 case lir_static_call: 44.39 - call(op->addr(), relocInfo::static_call_type, op->info()); 44.40 + call(op, relocInfo::static_call_type); 44.41 break; 44.42 case lir_optvirtual_call: 44.43 - call(op->addr(), relocInfo::opt_virtual_call_type, op->info()); 44.44 + case lir_dynamic_call: 44.45 + call(op, relocInfo::opt_virtual_call_type); 44.46 break; 44.47 case lir_icvirtual_call: 44.48 - ic_call(op->addr(), op->info()); 44.49 + ic_call(op); 44.50 break; 44.51 case lir_virtual_call: 44.52 - vtable_call(op->vtable_offset(), op->info()); 44.53 + vtable_call(op); 44.54 break; 44.55 default: ShouldNotReachHere(); 44.56 } 44.57 + 44.58 + if (op->is_method_handle_invoke()) { 44.59 + restore_SP(op); 44.60 + } 44.61 + 44.62 #if defined(X86) && defined(TIERED) 44.63 // C2 leave fpu stack dirty clean it 44.64 if (UseSSE < 2) {
45.1 --- a/src/share/vm/c1/c1_LIRAssembler.hpp Thu Mar 25 16:54:59 2010 -0700 45.2 +++ b/src/share/vm/c1/c1_LIRAssembler.hpp Fri Mar 26 11:10:26 2010 -0400 45.3 @@ -82,7 +82,7 @@ 45.4 Address as_Address_hi(LIR_Address* addr); 45.5 45.6 // debug information 45.7 - void add_call_info(int pc_offset, CodeEmitInfo* cinfo); 45.8 + void add_call_info(int pc_offset, CodeEmitInfo* cinfo, bool is_method_handle_invoke = false); 45.9 void add_debug_info_for_branch(CodeEmitInfo* info); 45.10 void add_debug_info_for_div0(int pc_offset, CodeEmitInfo* cinfo); 45.11 void add_debug_info_for_div0_here(CodeEmitInfo* info); 45.12 @@ -205,9 +205,13 @@ 45.13 void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op); 45.14 void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result); 45.15 45.16 - void ic_call(address destination, CodeEmitInfo* info); 45.17 - void vtable_call(int vtable_offset, CodeEmitInfo* info); 45.18 - void call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info); 45.19 + void call( LIR_OpJavaCall* op, relocInfo::relocType rtype); 45.20 + void ic_call( LIR_OpJavaCall* op); 45.21 + void vtable_call( LIR_OpJavaCall* op); 45.22 + 45.23 + // JSR 292 45.24 + void preserve_SP(LIR_OpJavaCall* op); 45.25 + void restore_SP( LIR_OpJavaCall* op); 45.26 45.27 void osr_entry(); 45.28
46.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Thu Mar 25 16:54:59 2010 -0700 46.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Fri Mar 26 11:10:26 2010 -0400 46.3 @@ -2284,7 +2284,7 @@ 46.4 46.5 46.6 void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) { 46.7 - int i = x->has_receiver() ? 1 : 0; 46.8 + int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0; 46.9 for (; i < args->length(); i++) { 46.10 LIRItem* param = args->at(i); 46.11 LIR_Opr loc = arg_list->at(i); 46.12 @@ -2322,6 +2322,10 @@ 46.13 LIRItem* receiver = new LIRItem(x->receiver(), this); 46.14 argument_items->append(receiver); 46.15 } 46.16 + if (x->is_invokedynamic()) { 46.17 + // Insert a dummy for the synthetic MethodHandle argument. 46.18 + argument_items->append(NULL); 46.19 + } 46.20 int idx = x->has_receiver() ? 1 : 0; 46.21 for (int i = 0; i < x->number_of_arguments(); i++) { 46.22 LIRItem* param = new LIRItem(x->argument_at(i), this); 46.23 @@ -2371,6 +2375,9 @@ 46.24 46.25 CodeEmitInfo* info = state_for(x, x->state()); 46.26 46.27 + // invokedynamics can deoptimize. 46.28 + CodeEmitInfo* deopt_info = x->is_invokedynamic() ? state_for(x, x->state_before()) : NULL; 46.29 + 46.30 invoke_load_arguments(x, args, arg_list); 46.31 46.32 if (x->has_receiver()) { 46.33 @@ -2407,6 +2414,47 @@ 46.34 __ call_virtual(x->target(), receiver, result_register, vtable_offset, arg_list, info); 46.35 } 46.36 break; 46.37 + case Bytecodes::_invokedynamic: { 46.38 + ciBytecodeStream bcs(x->scope()->method()); 46.39 + bcs.force_bci(x->bci()); 46.40 + assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream"); 46.41 + ciCPCache* cpcache = bcs.get_cpcache(); 46.42 + 46.43 + // Get CallSite offset from constant pool cache pointer. 46.44 + int index = bcs.get_method_index(); 46.45 + size_t call_site_offset = cpcache->get_f1_offset(index); 46.46 + 46.47 + // If this invokedynamic call site hasn't been executed yet in 46.48 + // the interpreter, the CallSite object in the constant pool 46.49 + // cache is still null and we need to deoptimize. 46.50 + if (cpcache->is_f1_null_at(index)) { 46.51 + // Cannot re-use same xhandlers for multiple CodeEmitInfos, so 46.52 + // clone all handlers. This is handled transparently in other 46.53 + // places by the CodeEmitInfo cloning logic but is handled 46.54 + // specially here because a stub isn't being used. 46.55 + x->set_exception_handlers(new XHandlers(x->exception_handlers())); 46.56 + 46.57 + DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info); 46.58 + __ jump(deopt_stub); 46.59 + } 46.60 + 46.61 + // Use the receiver register for the synthetic MethodHandle 46.62 + // argument. 46.63 + receiver = LIR_Assembler::receiverOpr(); 46.64 + LIR_Opr tmp = new_register(objectType); 46.65 + 46.66 + // Load CallSite object from constant pool cache. 46.67 + __ oop2reg(cpcache->constant_encoding(), tmp); 46.68 + __ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp); 46.69 + 46.70 + // Load target MethodHandle from CallSite object. 46.71 + __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver); 46.72 + 46.73 + __ call_dynamic(x->target(), receiver, result_register, 46.74 + SharedRuntime::get_resolve_opt_virtual_call_stub(), 46.75 + arg_list, info); 46.76 + break; 46.77 + } 46.78 default: 46.79 ShouldNotReachHere(); 46.80 break;
47.1 --- a/src/share/vm/c1/c1_LinearScan.cpp Thu Mar 25 16:54:59 2010 -0700 47.2 +++ b/src/share/vm/c1/c1_LinearScan.cpp Fri Mar 26 11:10:26 2010 -0400 47.3 @@ -2479,6 +2479,15 @@ 47.4 return 2; 47.5 } 47.6 47.7 + case T_ADDRESS: { 47.8 +#ifdef _LP64 47.9 + scope_values->append(new ConstantLongValue(c->as_jint())); 47.10 +#else 47.11 + scope_values->append(new ConstantIntValue(c->as_jint())); 47.12 +#endif 47.13 + return 1; 47.14 + } 47.15 + 47.16 default: 47.17 ShouldNotReachHere(); 47.18 return -1;
48.1 --- a/src/share/vm/c1/c1_MacroAssembler.hpp Thu Mar 25 16:54:59 2010 -0700 48.2 +++ b/src/share/vm/c1/c1_MacroAssembler.hpp Fri Mar 26 11:10:26 2010 -0400 48.3 @@ -1,5 +1,5 @@ 48.4 /* 48.5 - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. 48.6 + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. 48.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 48.8 * 48.9 * This code is free software; you can redistribute it and/or modify it 48.10 @@ -34,7 +34,7 @@ 48.11 48.12 void inline_cache_check(Register receiver, Register iCache); 48.13 void build_frame(int frame_size_in_bytes); 48.14 - void method_exit(bool restore_frame); 48.15 + void remove_frame(int frame_size_in_bytes); 48.16 48.17 void unverified_entry(Register receiver, Register ic_klass); 48.18 void verified_entry();
49.1 --- a/src/share/vm/ci/ciCPCache.cpp Thu Mar 25 16:54:59 2010 -0700 49.2 +++ b/src/share/vm/ci/ciCPCache.cpp Fri Mar 26 11:10:26 2010 -0400 49.3 @@ -1,5 +1,5 @@ 49.4 /* 49.5 - * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 49.6 + * Copyright 2009-2010 Sun Microsystems, Inc. All Rights Reserved. 49.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 49.8 * 49.9 * This code is free software; you can redistribute it and/or modify it 49.10 @@ -41,6 +41,16 @@ 49.11 49.12 49.13 // ------------------------------------------------------------------ 49.14 +// ciCPCache::is_f1_null_at 49.15 +bool ciCPCache::is_f1_null_at(int index) { 49.16 + VM_ENTRY_MARK; 49.17 + constantPoolCacheOop cpcache = (constantPoolCacheOop) get_oop(); 49.18 + oop f1 = cpcache->secondary_entry_at(index)->f1(); 49.19 + return (f1 == NULL); 49.20 +} 49.21 + 49.22 + 49.23 +// ------------------------------------------------------------------ 49.24 // ciCPCache::print 49.25 // 49.26 // Print debugging information about the cache.
50.1 --- a/src/share/vm/ci/ciCPCache.hpp Thu Mar 25 16:54:59 2010 -0700 50.2 +++ b/src/share/vm/ci/ciCPCache.hpp Fri Mar 26 11:10:26 2010 -0400 50.3 @@ -1,5 +1,5 @@ 50.4 /* 50.5 - * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 50.6 + * Copyright 2009-2010 Sun Microsystems, Inc. All Rights Reserved. 50.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 50.8 * 50.9 * This code is free software; you can redistribute it and/or modify it 50.10 @@ -39,5 +39,7 @@ 50.11 // requested entry. 50.12 size_t get_f1_offset(int index); 50.13 50.14 + bool is_f1_null_at(int index); 50.15 + 50.16 void print(); 50.17 };
51.1 --- a/src/share/vm/code/codeBlob.cpp Thu Mar 25 16:54:59 2010 -0700 51.2 +++ b/src/share/vm/code/codeBlob.cpp Fri Mar 26 11:10:26 2010 -0400 51.3 @@ -1,5 +1,5 @@ 51.4 /* 51.5 - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. 51.6 + * Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved. 51.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 51.8 * 51.9 * This code is free software; you can redistribute it and/or modify it 51.10 @@ -249,7 +249,6 @@ 51.11 size += round_to(buffer_size, oopSize); 51.12 assert(name != NULL, "must provide a name"); 51.13 { 51.14 - 51.15 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 51.16 blob = new (size) BufferBlob(name, size); 51.17 } 51.18 @@ -271,7 +270,6 @@ 51.19 unsigned int size = allocation_size(cb, sizeof(BufferBlob)); 51.20 assert(name != NULL, "must provide a name"); 51.21 { 51.22 - 51.23 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 51.24 blob = new (size) BufferBlob(name, size, cb); 51.25 } 51.26 @@ -298,10 +296,48 @@ 51.27 MemoryService::track_code_cache_memory_usage(); 51.28 } 51.29 51.30 -bool BufferBlob::is_adapter_blob() const { 51.31 - return (strcmp(AdapterHandlerEntry::name, name()) == 0); 51.32 + 51.33 +//---------------------------------------------------------------------------------------------------- 51.34 +// Implementation of AdapterBlob 51.35 + 51.36 +AdapterBlob* AdapterBlob::create(CodeBuffer* cb) { 51.37 + ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock 51.38 + 51.39 + AdapterBlob* blob = NULL; 51.40 + unsigned int size = allocation_size(cb, sizeof(AdapterBlob)); 51.41 + { 51.42 + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 51.43 + blob = new (size) AdapterBlob(size, cb); 51.44 + } 51.45 + // Track memory usage statistic after releasing CodeCache_lock 51.46 + MemoryService::track_code_cache_memory_usage(); 51.47 + 51.48 + return blob; 51.49 } 51.50 51.51 + 51.52 +//---------------------------------------------------------------------------------------------------- 51.53 +// Implementation of MethodHandlesAdapterBlob 51.54 + 51.55 +MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) { 51.56 + ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock 51.57 + 51.58 + MethodHandlesAdapterBlob* blob = NULL; 51.59 + unsigned int size = sizeof(MethodHandlesAdapterBlob); 51.60 + // align the size to CodeEntryAlignment 51.61 + size = align_code_offset(size); 51.62 + size += round_to(buffer_size, oopSize); 51.63 + { 51.64 + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 51.65 + blob = new (size) MethodHandlesAdapterBlob(size); 51.66 + } 51.67 + // Track memory usage statistic after releasing CodeCache_lock 51.68 + MemoryService::track_code_cache_memory_usage(); 51.69 + 51.70 + return blob; 51.71 +} 51.72 + 51.73 + 51.74 //---------------------------------------------------------------------------------------------------- 51.75 // Implementation of RuntimeStub 51.76
52.1 --- a/src/share/vm/code/codeBlob.hpp Thu Mar 25 16:54:59 2010 -0700 52.2 +++ b/src/share/vm/code/codeBlob.hpp Fri Mar 26 11:10:26 2010 -0400 52.3 @@ -1,5 +1,5 @@ 52.4 /* 52.5 - * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. 52.6 + * Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved. 52.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 52.8 * 52.9 * This code is free software; you can redistribute it and/or modify it 52.10 @@ -90,14 +90,15 @@ 52.11 void flush(); 52.12 52.13 // Typing 52.14 - virtual bool is_buffer_blob() const { return false; } 52.15 - virtual bool is_nmethod() const { return false; } 52.16 - virtual bool is_runtime_stub() const { return false; } 52.17 - virtual bool is_deoptimization_stub() const { return false; } 52.18 - virtual bool is_uncommon_trap_stub() const { return false; } 52.19 - virtual bool is_exception_stub() const { return false; } 52.20 - virtual bool is_safepoint_stub() const { return false; } 52.21 - virtual bool is_adapter_blob() const { return false; } 52.22 + virtual bool is_buffer_blob() const { return false; } 52.23 + virtual bool is_nmethod() const { return false; } 52.24 + virtual bool is_runtime_stub() const { return false; } 52.25 + virtual bool is_deoptimization_stub() const { return false; } 52.26 + virtual bool is_uncommon_trap_stub() const { return false; } 52.27 + virtual bool is_exception_stub() const { return false; } 52.28 + virtual bool is_safepoint_stub() const { return false; } 52.29 + virtual bool is_adapter_blob() const { return false; } 52.30 + virtual bool is_method_handles_adapter_blob() const { return false; } 52.31 52.32 virtual bool is_compiled_by_c2() const { return false; } 52.33 virtual bool is_compiled_by_c1() const { return false; } 52.34 @@ -221,6 +222,9 @@ 52.35 52.36 class BufferBlob: public CodeBlob { 52.37 friend class VMStructs; 52.38 + friend class AdapterBlob; 52.39 + friend class MethodHandlesAdapterBlob; 52.40 + 52.41 private: 52.42 // Creation support 52.43 BufferBlob(const char* name, int size); 52.44 @@ -236,8 +240,7 @@ 52.45 static void free(BufferBlob* buf); 52.46 52.47 // Typing 52.48 - bool is_buffer_blob() const { return true; } 52.49 - bool is_adapter_blob() const; 52.50 + virtual bool is_buffer_blob() const { return true; } 52.51 52.52 // GC/Verification support 52.53 void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ } 52.54 @@ -255,6 +258,40 @@ 52.55 52.56 52.57 //---------------------------------------------------------------------------------------------------- 52.58 +// AdapterBlob: used to hold C2I/I2C adapters 52.59 + 52.60 +class AdapterBlob: public BufferBlob { 52.61 +private: 52.62 + AdapterBlob(int size) : BufferBlob("I2C/C2I adapters", size) {} 52.63 + AdapterBlob(int size, CodeBuffer* cb) : BufferBlob("I2C/C2I adapters", size, cb) {} 52.64 + 52.65 +public: 52.66 + // Creation 52.67 + static AdapterBlob* create(CodeBuffer* cb); 52.68 + 52.69 + // Typing 52.70 + virtual bool is_adapter_blob() const { return true; } 52.71 +}; 52.72 + 52.73 + 52.74 +//---------------------------------------------------------------------------------------------------- 52.75 +// MethodHandlesAdapterBlob: used to hold MethodHandles adapters 52.76 + 52.77 +class MethodHandlesAdapterBlob: public BufferBlob { 52.78 +private: 52.79 + MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {} 52.80 + MethodHandlesAdapterBlob(int size, CodeBuffer* cb) : BufferBlob("MethodHandles adapters", size, cb) {} 52.81 + 52.82 +public: 52.83 + // Creation 52.84 + static MethodHandlesAdapterBlob* create(int buffer_size); 52.85 + 52.86 + // Typing 52.87 + virtual bool is_method_handles_adapter_blob() const { return true; } 52.88 +}; 52.89 + 52.90 + 52.91 +//---------------------------------------------------------------------------------------------------- 52.92 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine 52.93 52.94 class RuntimeStub: public CodeBlob {
53.1 --- a/src/share/vm/compiler/compileBroker.cpp Thu Mar 25 16:54:59 2010 -0700 53.2 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Mar 26 11:10:26 2010 -0400 53.3 @@ -988,10 +988,12 @@ 53.4 } 53.5 if (method->is_not_compilable(comp_level)) return NULL; 53.6 53.7 - nmethod* saved = CodeCache::find_and_remove_saved_code(method()); 53.8 - if (saved != NULL) { 53.9 - method->set_code(method, saved); 53.10 - return saved; 53.11 + if (UseCodeCacheFlushing) { 53.12 + nmethod* saved = CodeCache::find_and_remove_saved_code(method()); 53.13 + if (saved != NULL) { 53.14 + method->set_code(method, saved); 53.15 + return saved; 53.16 + } 53.17 } 53.18 53.19 } else {
54.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Mar 25 16:54:59 2010 -0700 54.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Mar 26 11:10:26 2010 -0400 54.3 @@ -3704,7 +3704,14 @@ 54.4 // enough to point to the next possible object header (the 54.5 // bitmap knows by how much we need to move it as it knows its 54.6 // granularity). 54.7 - move_finger_to(_nextMarkBitMap->nextWord(_finger)); 54.8 + assert(_finger < _region_limit, "invariant"); 54.9 + HeapWord* new_finger = _nextMarkBitMap->nextWord(_finger); 54.10 + // Check if bitmap iteration was aborted while scanning the last object 54.11 + if (new_finger >= _region_limit) { 54.12 + giveup_current_region(); 54.13 + } else { 54.14 + move_finger_to(new_finger); 54.15 + } 54.16 } 54.17 } 54.18 // At this point we have either completed iterating over the
55.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Mar 25 16:54:59 2010 -0700 55.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri Mar 26 11:10:26 2010 -0400 55.3 @@ -24,8 +24,8 @@ 55.4 55.5 class G1CollectedHeap; 55.6 class CMTask; 55.7 -typedef GenericTaskQueue<oop> CMTaskQueue; 55.8 -typedef GenericTaskQueueSet<oop> CMTaskQueueSet; 55.9 +typedef GenericTaskQueue<oop> CMTaskQueue; 55.10 +typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet; 55.11 55.12 // A generic CM bit map. This is essentially a wrapper around the BitMap 55.13 // class, with one bit per (1<<_shifter) HeapWords.
56.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Mar 25 16:54:59 2010 -0700 56.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Mar 26 11:10:26 2010 -0400 56.3 @@ -2102,18 +2102,21 @@ 56.4 size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const { 56.5 // Return the remaining space in the cur alloc region, but not less than 56.6 // the min TLAB size. 56.7 - // Also, no more than half the region size, since we can't allow tlabs to 56.8 - // grow big enough to accomodate humongous objects. 56.9 - 56.10 - // We need to story it locally, since it might change between when we 56.11 - // test for NULL and when we use it later. 56.12 + 56.13 + // Also, this value can be at most the humongous object threshold, 56.14 + // since we can't allow tlabs to grow big enough to accomodate 56.15 + // humongous objects. 56.16 + 56.17 + // We need to store the cur alloc region locally, since it might change 56.18 + // between when we test for NULL and when we use it later. 56.19 ContiguousSpace* cur_alloc_space = _cur_alloc_region; 56.20 + size_t max_tlab_size = _humongous_object_threshold_in_words * wordSize; 56.21 + 56.22 if (cur_alloc_space == NULL) { 56.23 - return HeapRegion::GrainBytes/2; 56.24 + return max_tlab_size; 56.25 } else { 56.26 - return MAX2(MIN2(cur_alloc_space->free(), 56.27 - (size_t)(HeapRegion::GrainBytes/2)), 56.28 - (size_t)MinTLABSize); 56.29 + return MIN2(MAX2(cur_alloc_space->free(), (size_t)MinTLABSize), 56.30 + max_tlab_size); 56.31 } 56.32 } 56.33
57.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Mar 25 16:54:59 2010 -0700 57.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Mar 26 11:10:26 2010 -0400 57.3 @@ -56,8 +56,8 @@ 57.4 # define IF_G1_DETAILED_STATS(code) 57.5 #endif 57.6 57.7 -typedef GenericTaskQueue<StarTask> RefToScanQueue; 57.8 -typedef GenericTaskQueueSet<StarTask> RefToScanQueueSet; 57.9 +typedef GenericTaskQueue<StarTask> RefToScanQueue; 57.10 +typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet; 57.11 57.12 typedef int RegionIdx_t; // needs to hold [ 0..max_regions() ) 57.13 typedef int CardIdx_t; // needs to hold [ 0..CardsPerRegion ) 57.14 @@ -1055,7 +1055,12 @@ 57.15 57.16 // Returns "true" iff the given word_size is "very large". 57.17 static bool isHumongous(size_t word_size) { 57.18 - return word_size >= _humongous_object_threshold_in_words; 57.19 + // Note this has to be strictly greater-than as the TLABs 57.20 + // are capped at the humongous thresold and we want to 57.21 + // ensure that we don't try to allocate a TLAB as 57.22 + // humongous and that we don't allocate a humongous 57.23 + // object in a TLAB. 57.24 + return word_size > _humongous_object_threshold_in_words; 57.25 } 57.26 57.27 // Update mod union table with the set of dirty cards.
58.1 --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Mar 25 16:54:59 2010 -0700 58.2 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Fri Mar 26 11:10:26 2010 -0400 58.3 @@ -101,6 +101,8 @@ 58.4 58.5 GenMarkSweep::_marking_stack = 58.6 new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true); 58.7 + GenMarkSweep::_objarray_stack = 58.8 + new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true); 58.9 58.10 int size = SystemDictionary::number_of_classes() * 2; 58.11 GenMarkSweep::_revisit_klass_stack =
59.1 --- a/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge Thu Mar 25 16:54:59 2010 -0700 59.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge Fri Mar 26 11:10:26 2010 -0400 59.3 @@ -175,6 +175,7 @@ 59.4 psAdaptiveSizePolicy.hpp adaptiveSizePolicy.hpp 59.5 59.6 psCompactionManager.cpp gcTaskManager.hpp 59.7 +psCompactionManager.cpp objArrayKlass.inline.hpp 59.8 psCompactionManager.cpp objectStartArray.hpp 59.9 psCompactionManager.cpp oop.hpp 59.10 psCompactionManager.cpp oop.inline.hpp 59.11 @@ -189,6 +190,9 @@ 59.12 psCompactionManager.hpp allocation.hpp 59.13 psCompactionManager.hpp taskqueue.hpp 59.14 59.15 +psCompactionManager.inline.hpp psCompactionManager.hpp 59.16 +psCompactionManager.inline.hpp psParallelCompact.hpp 59.17 + 59.18 psGCAdaptivePolicyCounters.hpp gcAdaptivePolicyCounters.hpp 59.19 psGCAdaptivePolicyCounters.hpp gcPolicyCounters.hpp 59.20 psGCAdaptivePolicyCounters.hpp psAdaptiveSizePolicy.hpp 59.21 @@ -379,12 +383,12 @@ 59.22 pcTasks.cpp jniHandles.hpp 59.23 pcTasks.cpp jvmtiExport.hpp 59.24 pcTasks.cpp management.hpp 59.25 +pcTasks.cpp objArrayKlass.inline.hpp 59.26 pcTasks.cpp psParallelCompact.hpp 59.27 pcTasks.cpp pcTasks.hpp 59.28 pcTasks.cpp oop.inline.hpp 59.29 pcTasks.cpp oop.pcgc.inline.hpp 59.30 pcTasks.cpp systemDictionary.hpp 59.31 -pcTasks.cpp taskqueue.hpp 59.32 pcTasks.cpp thread.hpp 59.33 pcTasks.cpp universe.hpp 59.34 pcTasks.cpp vmThread.hpp
60.1 --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Thu Mar 25 16:54:59 2010 -0700 60.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Fri Mar 26 11:10:26 2010 -0400 60.3 @@ -48,7 +48,7 @@ 60.4 _vm_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs); 60.5 60.6 // Do the real work 60.7 - cm->drain_marking_stacks(&mark_and_push_closure); 60.8 + cm->follow_marking_stacks(); 60.9 } 60.10 60.11 60.12 @@ -118,7 +118,7 @@ 60.13 } 60.14 60.15 // Do the real work 60.16 - cm->drain_marking_stacks(&mark_and_push_closure); 60.17 + cm->follow_marking_stacks(); 60.18 // cm->deallocate_stacks(); 60.19 } 60.20 60.21 @@ -196,17 +196,19 @@ 60.22 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); 60.23 60.24 oop obj = NULL; 60.25 + ObjArrayTask task; 60.26 int random_seed = 17; 60.27 - while(true) { 60.28 - if (ParCompactionManager::steal(which, &random_seed, obj)) { 60.29 + do { 60.30 + while (ParCompactionManager::steal_objarray(which, &random_seed, task)) { 60.31 + objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); 60.32 + k->oop_follow_contents(cm, task.obj(), task.index()); 60.33 + cm->follow_marking_stacks(); 60.34 + } 60.35 + while (ParCompactionManager::steal(which, &random_seed, obj)) { 60.36 obj->follow_contents(cm); 60.37 - cm->drain_marking_stacks(&mark_and_push_closure); 60.38 - } else { 60.39 - if (terminator()->offer_termination()) { 60.40 - break; 60.41 - } 60.42 + cm->follow_marking_stacks(); 60.43 } 60.44 - } 60.45 + } while (!terminator()->offer_termination()); 60.46 } 60.47 60.48 //
61.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp Thu Mar 25 16:54:59 2010 -0700 61.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp Fri Mar 26 11:10:26 2010 -0400 61.3 @@ -28,6 +28,8 @@ 61.4 PSOldGen* ParCompactionManager::_old_gen = NULL; 61.5 ParCompactionManager** ParCompactionManager::_manager_array = NULL; 61.6 OopTaskQueueSet* ParCompactionManager::_stack_array = NULL; 61.7 +ParCompactionManager::ObjArrayTaskQueueSet* 61.8 + ParCompactionManager::_objarray_queues = NULL; 61.9 ObjectStartArray* ParCompactionManager::_start_array = NULL; 61.10 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL; 61.11 RegionTaskQueueSet* ParCompactionManager::_region_array = NULL; 61.12 @@ -46,6 +48,11 @@ 61.13 61.14 // We want the overflow stack to be permanent 61.15 _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true); 61.16 + 61.17 + _objarray_queue.initialize(); 61.18 + _objarray_overflow_stack = 61.19 + new (ResourceObj::C_HEAP) ObjArrayOverflowStack(10, true); 61.20 + 61.21 #ifdef USE_RegionTaskQueueWithOverflow 61.22 region_stack()->initialize(); 61.23 #else 61.24 @@ -69,6 +76,7 @@ 61.25 61.26 ParCompactionManager::~ParCompactionManager() { 61.27 delete _overflow_stack; 61.28 + delete _objarray_overflow_stack; 61.29 delete _revisit_klass_stack; 61.30 delete _revisit_mdo_stack; 61.31 // _manager_array and _stack_array are statics 61.32 @@ -86,18 +94,21 @@ 61.33 61.34 assert(_manager_array == NULL, "Attempt to initialize twice"); 61.35 _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 ); 61.36 - guarantee(_manager_array != NULL, "Could not initialize promotion manager"); 61.37 + guarantee(_manager_array != NULL, "Could not allocate manager_array"); 61.38 61.39 _stack_array = new OopTaskQueueSet(parallel_gc_threads); 61.40 - guarantee(_stack_array != NULL, "Count not initialize promotion manager"); 61.41 + guarantee(_stack_array != NULL, "Could not allocate stack_array"); 61.42 + _objarray_queues = new ObjArrayTaskQueueSet(parallel_gc_threads); 61.43 + guarantee(_objarray_queues != NULL, "Could not allocate objarray_queues"); 61.44 _region_array = new RegionTaskQueueSet(parallel_gc_threads); 61.45 - guarantee(_region_array != NULL, "Count not initialize promotion manager"); 61.46 + guarantee(_region_array != NULL, "Could not allocate region_array"); 61.47 61.48 // Create and register the ParCompactionManager(s) for the worker threads. 61.49 for(uint i=0; i<parallel_gc_threads; i++) { 61.50 _manager_array[i] = new ParCompactionManager(); 61.51 guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager"); 61.52 stack_array()->register_queue(i, _manager_array[i]->marking_stack()); 61.53 + _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_queue); 61.54 #ifdef USE_RegionTaskQueueWithOverflow 61.55 region_array()->register_queue(i, _manager_array[i]->region_stack()->task_queue()); 61.56 #else 61.57 @@ -203,36 +214,30 @@ 61.58 } 61.59 } 61.60 61.61 -void ParCompactionManager::drain_marking_stacks(OopClosure* blk) { 61.62 -#ifdef ASSERT 61.63 - ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); 61.64 - assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); 61.65 - MutableSpace* to_space = heap->young_gen()->to_space(); 61.66 - MutableSpace* old_space = heap->old_gen()->object_space(); 61.67 - MutableSpace* perm_space = heap->perm_gen()->object_space(); 61.68 -#endif /* ASSERT */ 61.69 - 61.70 - 61.71 +void ParCompactionManager::follow_marking_stacks() { 61.72 do { 61.73 - 61.74 - // Drain overflow stack first, so other threads can steal from 61.75 - // claimed stack while we work. 61.76 - while(!overflow_stack()->is_empty()) { 61.77 - oop obj = overflow_stack()->pop(); 61.78 + // Drain the overflow stack first, to allow stealing from the marking stack. 61.79 + oop obj; 61.80 + while (!overflow_stack()->is_empty()) { 61.81 + overflow_stack()->pop()->follow_contents(this); 61.82 + } 61.83 + while (marking_stack()->pop_local(obj)) { 61.84 obj->follow_contents(this); 61.85 } 61.86 61.87 - oop obj; 61.88 - // obj is a reference!!! 61.89 - while (marking_stack()->pop_local(obj)) { 61.90 - // It would be nice to assert about the type of objects we might 61.91 - // pop, but they can come from anywhere, unfortunately. 61.92 - obj->follow_contents(this); 61.93 + // Process ObjArrays one at a time to avoid marking stack bloat. 61.94 + ObjArrayTask task; 61.95 + if (!_objarray_overflow_stack->is_empty()) { 61.96 + task = _objarray_overflow_stack->pop(); 61.97 + objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); 61.98 + k->oop_follow_contents(this, task.obj(), task.index()); 61.99 + } else if (_objarray_queue.pop_local(task)) { 61.100 + objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); 61.101 + k->oop_follow_contents(this, task.obj(), task.index()); 61.102 } 61.103 - } while((marking_stack()->size() != 0) || (overflow_stack()->length() != 0)); 61.104 + } while (!marking_stacks_empty()); 61.105 61.106 - assert(marking_stack()->size() == 0, "Sanity"); 61.107 - assert(overflow_stack()->length() == 0, "Sanity"); 61.108 + assert(marking_stacks_empty(), "Sanity"); 61.109 } 61.110 61.111 void ParCompactionManager::drain_region_overflow_stack() {
62.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp Thu Mar 25 16:54:59 2010 -0700 62.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp Fri Mar 26 11:10:26 2010 -0400 62.3 @@ -22,18 +22,6 @@ 62.4 * 62.5 */ 62.6 62.7 -// 62.8 -// psPromotionManager is used by a single thread to manage object survival 62.9 -// during a scavenge. The promotion manager contains thread local data only. 62.10 -// 62.11 -// NOTE! Be carefull when allocating the stacks on cheap. If you are going 62.12 -// to use a promotion manager in more than one thread, the stacks MUST be 62.13 -// on cheap. This can lead to memory leaks, though, as they are not auto 62.14 -// deallocated. 62.15 -// 62.16 -// FIX ME FIX ME Add a destructor, and don't rely on the user to drain/flush/deallocate! 62.17 -// 62.18 - 62.19 // Move to some global location 62.20 #define HAS_BEEN_MOVED 0x1501d01d 62.21 // End move to some global location 62.22 @@ -46,8 +34,6 @@ 62.23 class ParallelCompactData; 62.24 class ParMarkBitMap; 62.25 62.26 -// Move to it's own file if this works out. 62.27 - 62.28 class ParCompactionManager : public CHeapObj { 62.29 friend class ParallelTaskTerminator; 62.30 friend class ParMarkBitMap; 62.31 @@ -72,14 +58,27 @@ 62.32 // ------------------------ End don't putback if not needed 62.33 62.34 private: 62.35 + // 32-bit: 4K * 8 = 32KiB; 64-bit: 8K * 16 = 128KiB 62.36 + #define OBJARRAY_QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13)) 62.37 + typedef GenericTaskQueue<ObjArrayTask, OBJARRAY_QUEUE_SIZE> ObjArrayTaskQueue; 62.38 + typedef GenericTaskQueueSet<ObjArrayTaskQueue> ObjArrayTaskQueueSet; 62.39 + #undef OBJARRAY_QUEUE_SIZE 62.40 + 62.41 static ParCompactionManager** _manager_array; 62.42 static OopTaskQueueSet* _stack_array; 62.43 + static ObjArrayTaskQueueSet* _objarray_queues; 62.44 static ObjectStartArray* _start_array; 62.45 static RegionTaskQueueSet* _region_array; 62.46 static PSOldGen* _old_gen; 62.47 62.48 +private: 62.49 OopTaskQueue _marking_stack; 62.50 GrowableArray<oop>* _overflow_stack; 62.51 + 62.52 + typedef GrowableArray<ObjArrayTask> ObjArrayOverflowStack; 62.53 + ObjArrayTaskQueue _objarray_queue; 62.54 + ObjArrayOverflowStack* _objarray_overflow_stack; 62.55 + 62.56 // Is there a way to reuse the _marking_stack for the 62.57 // saving empty regions? For now just create a different 62.58 // type of TaskQueue. 62.59 @@ -128,8 +127,8 @@ 62.60 // Pushes onto the region stack. If the region stack is full, 62.61 // pushes onto the region overflow stack. 62.62 void region_stack_push(size_t region_index); 62.63 - public: 62.64 62.65 +public: 62.66 Action action() { return _action; } 62.67 void set_action(Action v) { _action = v; } 62.68 62.69 @@ -163,6 +162,8 @@ 62.70 // Get a oop for scanning. If returns null, no oop were found. 62.71 oop retrieve_for_scanning(); 62.72 62.73 + inline void push_objarray(oop obj, size_t index); 62.74 + 62.75 // Save region for later processing. Must not fail. 62.76 void save_for_processing(size_t region_index); 62.77 // Get a region for processing. If returns null, no region were found. 62.78 @@ -175,12 +176,17 @@ 62.79 return stack_array()->steal(queue_num, seed, t); 62.80 } 62.81 62.82 + static bool steal_objarray(int queue_num, int* seed, ObjArrayTask& t) { 62.83 + return _objarray_queues->steal(queue_num, seed, t); 62.84 + } 62.85 + 62.86 static bool steal(int queue_num, int* seed, RegionTask& t) { 62.87 return region_array()->steal(queue_num, seed, t); 62.88 } 62.89 62.90 - // Process tasks remaining on any stack 62.91 - void drain_marking_stacks(OopClosure *blk); 62.92 + // Process tasks remaining on any marking stack 62.93 + void follow_marking_stacks(); 62.94 + inline bool marking_stacks_empty() const; 62.95 62.96 // Process tasks remaining on any stack 62.97 void drain_region_stacks(); 62.98 @@ -200,3 +206,8 @@ 62.99 "out of range manager_array access"); 62.100 return _manager_array[index]; 62.101 } 62.102 + 62.103 +bool ParCompactionManager::marking_stacks_empty() const { 62.104 + return _marking_stack.size() == 0 && _overflow_stack->is_empty() && 62.105 + _objarray_queue.size() == 0 && _objarray_overflow_stack->is_empty(); 62.106 +}
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.inline.hpp Fri Mar 26 11:10:26 2010 -0400 63.3 @@ -0,0 +1,32 @@ 63.4 +/* 63.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 63.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 63.7 + * 63.8 + * This code is free software; you can redistribute it and/or modify it 63.9 + * under the terms of the GNU General Public License version 2 only, as 63.10 + * published by the Free Software Foundation. 63.11 + * 63.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 63.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 63.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 63.15 + * version 2 for more details (a copy is included in the LICENSE file that 63.16 + * accompanied this code). 63.17 + * 63.18 + * You should have received a copy of the GNU General Public License version 63.19 + * 2 along with this work; if not, write to the Free Software Foundation, 63.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 63.21 + * 63.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 63.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 63.24 + * have any questions. 63.25 + * 63.26 + */ 63.27 + 63.28 +void ParCompactionManager::push_objarray(oop obj, size_t index) 63.29 +{ 63.30 + ObjArrayTask task(obj, index); 63.31 + assert(task.is_valid(), "bad ObjArrayTask"); 63.32 + if (!_objarray_queue.push(task)) { 63.33 + _objarray_overflow_stack->push(task); 63.34 + } 63.35 +}
64.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Mar 25 16:54:59 2010 -0700 64.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Fri Mar 26 11:10:26 2010 -0400 64.3 @@ -479,6 +479,7 @@ 64.4 _preserved_oop_stack = NULL; 64.5 64.6 _marking_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true); 64.7 + _objarray_stack = new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true); 64.8 64.9 int size = SystemDictionary::number_of_classes() * 2; 64.10 _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true); 64.11 @@ -497,6 +498,7 @@ 64.12 } 64.13 64.14 delete _marking_stack; 64.15 + delete _objarray_stack; 64.16 delete _revisit_klass_stack; 64.17 delete _revisit_mdo_stack; 64.18 }
65.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Mar 25 16:54:59 2010 -0700 65.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Mar 26 11:10:26 2010 -0400 65.3 @@ -785,7 +785,7 @@ 65.4 void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); } 65.5 void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); } 65.6 65.7 -void PSParallelCompact::FollowStackClosure::do_void() { follow_stack(_compaction_manager); } 65.8 +void PSParallelCompact::FollowStackClosure::do_void() { _compaction_manager->follow_marking_stacks(); } 65.9 65.10 void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(_compaction_manager, p); } 65.11 void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); } 65.12 @@ -2376,7 +2376,7 @@ 65.13 // Follow code cache roots. 65.14 CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure, 65.15 purged_class); 65.16 - follow_stack(cm); // Flush marking stack. 65.17 + cm->follow_marking_stacks(); // Flush marking stack. 65.18 65.19 // Update subklass/sibling/implementor links of live klasses 65.20 // revisit_klass_stack is used in follow_weak_klass_links(). 65.21 @@ -2389,8 +2389,7 @@ 65.22 SymbolTable::unlink(is_alive_closure()); 65.23 StringTable::unlink(is_alive_closure()); 65.24 65.25 - assert(cm->marking_stack()->size() == 0, "stack should be empty by now"); 65.26 - assert(cm->overflow_stack()->is_empty(), "stack should be empty by now"); 65.27 + assert(cm->marking_stacks_empty(), "marking stacks should be empty"); 65.28 } 65.29 65.30 // This should be moved to the shared markSweep code! 65.31 @@ -2709,22 +2708,6 @@ 65.32 young_gen->move_and_update(cm); 65.33 } 65.34 65.35 - 65.36 -void PSParallelCompact::follow_stack(ParCompactionManager* cm) { 65.37 - while(!cm->overflow_stack()->is_empty()) { 65.38 - oop obj = cm->overflow_stack()->pop(); 65.39 - obj->follow_contents(cm); 65.40 - } 65.41 - 65.42 - oop obj; 65.43 - // obj is a reference!!! 65.44 - while (cm->marking_stack()->pop_local(obj)) { 65.45 - // It would be nice to assert about the type of objects we might 65.46 - // pop, but they can come from anywhere, unfortunately. 65.47 - obj->follow_contents(cm); 65.48 - } 65.49 -} 65.50 - 65.51 void 65.52 PSParallelCompact::follow_weak_klass_links() { 65.53 // All klasses on the revisit stack are marked at this point. 65.54 @@ -2745,7 +2728,7 @@ 65.55 &keep_alive_closure); 65.56 } 65.57 // revisit_klass_stack is cleared in reset() 65.58 - follow_stack(cm); 65.59 + cm->follow_marking_stacks(); 65.60 } 65.61 } 65.62 65.63 @@ -2776,7 +2759,7 @@ 65.64 rms->at(j)->follow_weak_refs(is_alive_closure()); 65.65 } 65.66 // revisit_mdo_stack is cleared in reset() 65.67 - follow_stack(cm); 65.68 + cm->follow_marking_stacks(); 65.69 } 65.70 } 65.71
66.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Thu Mar 25 16:54:59 2010 -0700 66.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Fri Mar 26 11:10:26 2010 -0400 66.3 @@ -901,7 +901,6 @@ 66.4 // Mark live objects 66.5 static void marking_phase(ParCompactionManager* cm, 66.6 bool maximum_heap_compaction); 66.7 - static void follow_stack(ParCompactionManager* cm); 66.8 static void follow_weak_klass_links(); 66.9 static void follow_mdo_weak_refs(); 66.10 66.11 @@ -1276,7 +1275,7 @@ 66.12 } 66.13 } 66.14 } 66.15 - follow_stack(cm); 66.16 + cm->follow_marking_stacks(); 66.17 } 66.18 66.19 template <class T>
67.1 --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Thu Mar 25 16:54:59 2010 -0700 67.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Fri Mar 26 11:10:26 2010 -0400 67.3 @@ -25,8 +25,9 @@ 67.4 #include "incls/_precompiled.incl" 67.5 #include "incls/_markSweep.cpp.incl" 67.6 67.7 -GrowableArray<oop>* MarkSweep::_marking_stack = NULL; 67.8 -GrowableArray<Klass*>* MarkSweep::_revisit_klass_stack = NULL; 67.9 +GrowableArray<oop>* MarkSweep::_marking_stack = NULL; 67.10 +GrowableArray<ObjArrayTask>* MarkSweep::_objarray_stack = NULL; 67.11 +GrowableArray<Klass*>* MarkSweep::_revisit_klass_stack = NULL; 67.12 GrowableArray<DataLayout*>* MarkSweep::_revisit_mdo_stack = NULL; 67.13 67.14 GrowableArray<oop>* MarkSweep::_preserved_oop_stack = NULL; 67.15 @@ -104,11 +105,19 @@ 67.16 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); } 67.17 67.18 void MarkSweep::follow_stack() { 67.19 - while (!_marking_stack->is_empty()) { 67.20 - oop obj = _marking_stack->pop(); 67.21 - assert (obj->is_gc_marked(), "p must be marked"); 67.22 - obj->follow_contents(); 67.23 - } 67.24 + do { 67.25 + while (!_marking_stack->is_empty()) { 67.26 + oop obj = _marking_stack->pop(); 67.27 + assert (obj->is_gc_marked(), "p must be marked"); 67.28 + obj->follow_contents(); 67.29 + } 67.30 + // Process ObjArrays one at a time to avoid marking stack bloat. 67.31 + if (!_objarray_stack->is_empty()) { 67.32 + ObjArrayTask task = _objarray_stack->pop(); 67.33 + objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); 67.34 + k->oop_follow_contents(task.obj(), task.index()); 67.35 + } 67.36 + } while (!_marking_stack->is_empty() || !_objarray_stack->is_empty()); 67.37 } 67.38 67.39 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
68.1 --- a/src/share/vm/gc_implementation/shared/markSweep.hpp Thu Mar 25 16:54:59 2010 -0700 68.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Fri Mar 26 11:10:26 2010 -0400 68.3 @@ -110,8 +110,9 @@ 68.4 // Vars 68.5 // 68.6 protected: 68.7 - // Traversal stack used during phase1 68.8 + // Traversal stacks used during phase1 68.9 static GrowableArray<oop>* _marking_stack; 68.10 + static GrowableArray<ObjArrayTask>* _objarray_stack; 68.11 // Stack for live klasses to revisit at end of marking phase 68.12 static GrowableArray<Klass*>* _revisit_klass_stack; 68.13 // Set (stack) of MDO's to revisit at end of marking phase 68.14 @@ -188,6 +189,7 @@ 68.15 template <class T> static inline void mark_and_follow(T* p); 68.16 // Check mark and maybe push on marking stack 68.17 template <class T> static inline void mark_and_push(T* p); 68.18 + static inline void push_objarray(oop obj, size_t index); 68.19 68.20 static void follow_stack(); // Empty marking stack. 68.21
69.1 --- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Thu Mar 25 16:54:59 2010 -0700 69.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Fri Mar 26 11:10:26 2010 -0400 69.3 @@ -77,6 +77,12 @@ 69.4 } 69.5 } 69.6 69.7 +void MarkSweep::push_objarray(oop obj, size_t index) { 69.8 + ObjArrayTask task(obj, index); 69.9 + assert(task.is_valid(), "bad ObjArrayTask"); 69.10 + _objarray_stack->push(task); 69.11 +} 69.12 + 69.13 template <class T> inline void MarkSweep::adjust_pointer(T* p, bool isroot) { 69.14 T heap_oop = oopDesc::load_heap_oop(p); 69.15 if (!oopDesc::is_null(heap_oop)) {
70.1 --- a/src/share/vm/includeDB_compiler1 Thu Mar 25 16:54:59 2010 -0700 70.2 +++ b/src/share/vm/includeDB_compiler1 Fri Mar 26 11:10:26 2010 -0400 70.3 @@ -1,5 +1,5 @@ 70.4 // 70.5 -// Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 70.6 +// Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 70.7 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 70.8 // 70.9 // This code is free software; you can redistribute it and/or modify it 70.10 @@ -246,6 +246,7 @@ 70.11 c1_LIRGenerator.cpp c1_LIRGenerator.hpp 70.12 c1_LIRGenerator.cpp c1_ValueStack.hpp 70.13 c1_LIRGenerator.cpp ciArrayKlass.hpp 70.14 +c1_LIRGenerator.cpp ciCPCache.hpp 70.15 c1_LIRGenerator.cpp ciInstance.hpp 70.16 c1_LIRGenerator.cpp heapRegion.hpp 70.17 c1_LIRGenerator.cpp sharedRuntime.hpp
71.1 --- a/src/share/vm/includeDB_core Thu Mar 25 16:54:59 2010 -0700 71.2 +++ b/src/share/vm/includeDB_core Fri Mar 26 11:10:26 2010 -0400 71.3 @@ -541,6 +541,7 @@ 71.4 71.5 ciCPCache.cpp cpCacheOop.hpp 71.6 ciCPCache.cpp ciCPCache.hpp 71.7 +ciCPCache.cpp ciUtilities.hpp 71.8 71.9 ciCPCache.hpp ciClassList.hpp 71.10 ciCPCache.hpp ciObject.hpp 71.11 @@ -2016,6 +2017,7 @@ 71.12 init.cpp icBuffer.hpp 71.13 init.cpp icache.hpp 71.14 init.cpp init.hpp 71.15 +init.cpp methodHandles.hpp 71.16 init.cpp safepoint.hpp 71.17 init.cpp sharedRuntime.hpp 71.18 init.cpp universe.hpp 71.19 @@ -2726,8 +2728,10 @@ 71.20 71.21 markSweep.cpp compileBroker.hpp 71.22 markSweep.cpp methodDataOop.hpp 71.23 +markSweep.cpp objArrayKlass.inline.hpp 71.24 71.25 markSweep.hpp collectedHeap.hpp 71.26 +markSweep.hpp taskqueue.hpp 71.27 71.28 memRegion.cpp globals.hpp 71.29 memRegion.cpp memRegion.hpp 71.30 @@ -2872,6 +2876,7 @@ 71.31 methodHandles.cpp oopFactory.hpp 71.32 methodHandles.cpp reflection.hpp 71.33 methodHandles.cpp signature.hpp 71.34 +methodHandles.cpp stubRoutines.hpp 71.35 methodHandles.cpp symbolTable.hpp 71.36 71.37 methodHandles_<arch>.cpp allocation.inline.hpp 71.38 @@ -3056,8 +3061,10 @@ 71.39 objArrayKlass.cpp genOopClosures.inline.hpp 71.40 objArrayKlass.cpp handles.inline.hpp 71.41 objArrayKlass.cpp instanceKlass.hpp 71.42 +objArrayKlass.cpp markSweep.inline.hpp 71.43 objArrayKlass.cpp mutexLocker.hpp 71.44 objArrayKlass.cpp objArrayKlass.hpp 71.45 +objArrayKlass.cpp objArrayKlass.inline.hpp 71.46 objArrayKlass.cpp objArrayKlassKlass.hpp 71.47 objArrayKlass.cpp objArrayOop.hpp 71.48 objArrayKlass.cpp oop.inline.hpp 71.49 @@ -3068,11 +3075,12 @@ 71.50 objArrayKlass.cpp universe.inline.hpp 71.51 objArrayKlass.cpp vmSymbols.hpp 71.52 71.53 - 71.54 objArrayKlass.hpp arrayKlass.hpp 71.55 objArrayKlass.hpp instanceKlass.hpp 71.56 objArrayKlass.hpp specialized_oop_closures.hpp 71.57 71.58 +objArrayKlass.inline.hpp objArrayKlass.hpp 71.59 + 71.60 objArrayKlassKlass.cpp collectedHeap.inline.hpp 71.61 objArrayKlassKlass.cpp instanceKlass.hpp 71.62 objArrayKlassKlass.cpp javaClasses.hpp 71.63 @@ -4098,6 +4106,7 @@ 71.64 task.hpp top.hpp 71.65 71.66 taskqueue.cpp debug.hpp 71.67 +taskqueue.cpp oop.inline.hpp 71.68 taskqueue.cpp os.hpp 71.69 taskqueue.cpp taskqueue.hpp 71.70 taskqueue.cpp thread_<os_family>.inline.hpp
72.1 --- a/src/share/vm/includeDB_gc_parallel Thu Mar 25 16:54:59 2010 -0700 72.2 +++ b/src/share/vm/includeDB_gc_parallel Fri Mar 26 11:10:26 2010 -0400 72.3 @@ -115,10 +115,14 @@ 72.4 objArrayKlass.cpp g1CollectedHeap.inline.hpp 72.5 objArrayKlass.cpp g1OopClosures.inline.hpp 72.6 objArrayKlass.cpp oop.pcgc.inline.hpp 72.7 +objArrayKlass.cpp psCompactionManager.hpp 72.8 objArrayKlass.cpp psPromotionManager.inline.hpp 72.9 objArrayKlass.cpp psScavenge.inline.hpp 72.10 objArrayKlass.cpp parOopClosures.inline.hpp 72.11 72.12 +objArrayKlass.inline.hpp psCompactionManager.inline.hpp 72.13 +objArrayKlass.inline.hpp psParallelCompact.hpp 72.14 + 72.15 oop.pcgc.inline.hpp parNewGeneration.hpp 72.16 oop.pcgc.inline.hpp parallelScavengeHeap.hpp 72.17 oop.pcgc.inline.hpp psCompactionManager.hpp
73.1 --- a/src/share/vm/memory/genMarkSweep.cpp Thu Mar 25 16:54:59 2010 -0700 73.2 +++ b/src/share/vm/memory/genMarkSweep.cpp Fri Mar 26 11:10:26 2010 -0400 73.3 @@ -159,6 +159,7 @@ 73.4 _preserved_oop_stack = NULL; 73.5 73.6 _marking_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true); 73.7 + _objarray_stack = new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true); 73.8 73.9 int size = SystemDictionary::number_of_classes() * 2; 73.10 _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true); 73.11 @@ -194,7 +195,6 @@ 73.12 73.13 73.14 void GenMarkSweep::deallocate_stacks() { 73.15 - 73.16 if (!UseG1GC) { 73.17 GenCollectedHeap* gch = GenCollectedHeap::heap(); 73.18 gch->release_scratch(); 73.19 @@ -208,6 +208,7 @@ 73.20 } 73.21 73.22 delete _marking_stack; 73.23 + delete _objarray_stack; 73.24 delete _revisit_klass_stack; 73.25 delete _revisit_mdo_stack; 73.26
74.1 --- a/src/share/vm/memory/genOopClosures.hpp Thu Mar 25 16:54:59 2010 -0700 74.2 +++ b/src/share/vm/memory/genOopClosures.hpp Fri Mar 26 11:10:26 2010 -0400 74.3 @@ -28,10 +28,10 @@ 74.4 class CardTableModRefBS; 74.5 class DefNewGeneration; 74.6 74.7 -template<class E> class GenericTaskQueue; 74.8 -typedef GenericTaskQueue<oop> OopTaskQueue; 74.9 -template<class E> class GenericTaskQueueSet; 74.10 -typedef GenericTaskQueueSet<oop> OopTaskQueueSet; 74.11 +template<class E, unsigned int N> class GenericTaskQueue; 74.12 +typedef GenericTaskQueue<oop, TASKQUEUE_SIZE> OopTaskQueue; 74.13 +template<class T> class GenericTaskQueueSet; 74.14 +typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet; 74.15 74.16 // Closure for iterating roots from a particular generation 74.17 // Note: all classes deriving from this MUST call this do_barrier
75.1 --- a/src/share/vm/oops/objArrayKlass.cpp Thu Mar 25 16:54:59 2010 -0700 75.2 +++ b/src/share/vm/oops/objArrayKlass.cpp Fri Mar 26 11:10:26 2010 -0400 75.3 @@ -314,24 +314,24 @@ 75.4 75.5 void objArrayKlass::oop_follow_contents(oop obj) { 75.6 assert (obj->is_array(), "obj must be array"); 75.7 - objArrayOop a = objArrayOop(obj); 75.8 - a->follow_header(); 75.9 - ObjArrayKlass_OOP_ITERATE( \ 75.10 - a, p, \ 75.11 - /* we call mark_and_follow here to avoid excessive marking stack usage */ \ 75.12 - MarkSweep::mark_and_follow(p)) 75.13 + objArrayOop(obj)->follow_header(); 75.14 + if (UseCompressedOops) { 75.15 + objarray_follow_contents<narrowOop>(obj, 0); 75.16 + } else { 75.17 + objarray_follow_contents<oop>(obj, 0); 75.18 + } 75.19 } 75.20 75.21 #ifndef SERIALGC 75.22 void objArrayKlass::oop_follow_contents(ParCompactionManager* cm, 75.23 oop obj) { 75.24 - assert (obj->is_array(), "obj must be array"); 75.25 - objArrayOop a = objArrayOop(obj); 75.26 - a->follow_header(cm); 75.27 - ObjArrayKlass_OOP_ITERATE( \ 75.28 - a, p, \ 75.29 - /* we call mark_and_follow here to avoid excessive marking stack usage */ \ 75.30 - PSParallelCompact::mark_and_follow(cm, p)) 75.31 + assert(obj->is_array(), "obj must be array"); 75.32 + objArrayOop(obj)->follow_header(cm); 75.33 + if (UseCompressedOops) { 75.34 + objarray_follow_contents<narrowOop>(cm, obj, 0); 75.35 + } else { 75.36 + objarray_follow_contents<oop>(cm, obj, 0); 75.37 + } 75.38 } 75.39 #endif // SERIALGC 75.40
76.1 --- a/src/share/vm/oops/objArrayKlass.hpp Thu Mar 25 16:54:59 2010 -0700 76.2 +++ b/src/share/vm/oops/objArrayKlass.hpp Fri Mar 26 11:10:26 2010 -0400 76.3 @@ -91,10 +91,18 @@ 76.4 76.5 // Garbage collection 76.6 void oop_follow_contents(oop obj); 76.7 + inline void oop_follow_contents(oop obj, int index); 76.8 + template <class T> inline void objarray_follow_contents(oop obj, int index); 76.9 + 76.10 int oop_adjust_pointers(oop obj); 76.11 76.12 // Parallel Scavenge and Parallel Old 76.13 PARALLEL_GC_DECLS 76.14 +#ifndef SERIALGC 76.15 + inline void oop_follow_contents(ParCompactionManager* cm, oop obj, int index); 76.16 + template <class T> inline void 76.17 + objarray_follow_contents(ParCompactionManager* cm, oop obj, int index); 76.18 +#endif // !SERIALGC 76.19 76.20 // Iterators 76.21 int oop_oop_iterate(oop obj, OopClosure* blk) { 76.22 @@ -131,5 +139,4 @@ 76.23 void oop_verify_on(oop obj, outputStream* st); 76.24 void oop_verify_old_oop(oop obj, oop* p, bool allow_dirty); 76.25 void oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty); 76.26 - 76.27 };
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/src/share/vm/oops/objArrayKlass.inline.hpp Fri Mar 26 11:10:26 2010 -0400 77.3 @@ -0,0 +1,89 @@ 77.4 +/* 77.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 77.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 77.7 + * 77.8 + * This code is free software; you can redistribute it and/or modify it 77.9 + * under the terms of the GNU General Public License version 2 only, as 77.10 + * published by the Free Software Foundation. 77.11 + * 77.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 77.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 77.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 77.15 + * version 2 for more details (a copy is included in the LICENSE file that 77.16 + * accompanied this code). 77.17 + * 77.18 + * You should have received a copy of the GNU General Public License version 77.19 + * 2 along with this work; if not, write to the Free Software Foundation, 77.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 77.21 + * 77.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 77.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 77.24 + * have any questions. 77.25 + * 77.26 + */ 77.27 + 77.28 +void objArrayKlass::oop_follow_contents(oop obj, int index) { 77.29 + if (UseCompressedOops) { 77.30 + objarray_follow_contents<narrowOop>(obj, index); 77.31 + } else { 77.32 + objarray_follow_contents<oop>(obj, index); 77.33 + } 77.34 +} 77.35 + 77.36 +template <class T> 77.37 +void objArrayKlass::objarray_follow_contents(oop obj, int index) { 77.38 + objArrayOop a = objArrayOop(obj); 77.39 + const size_t len = size_t(a->length()); 77.40 + const size_t beg_index = size_t(index); 77.41 + assert(beg_index < len || len == 0, "index too large"); 77.42 + 77.43 + const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride); 77.44 + const size_t end_index = beg_index + stride; 77.45 + T* const base = (T*)a->base(); 77.46 + T* const beg = base + beg_index; 77.47 + T* const end = base + end_index; 77.48 + 77.49 + // Push the non-NULL elements of the next stride on the marking stack. 77.50 + for (T* e = beg; e < end; e++) { 77.51 + MarkSweep::mark_and_push<T>(e); 77.52 + } 77.53 + 77.54 + if (end_index < len) { 77.55 + MarkSweep::push_objarray(a, end_index); // Push the continuation. 77.56 + } 77.57 +} 77.58 + 77.59 +#ifndef SERIALGC 77.60 +void objArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj, 77.61 + int index) { 77.62 + if (UseCompressedOops) { 77.63 + objarray_follow_contents<narrowOop>(cm, obj, index); 77.64 + } else { 77.65 + objarray_follow_contents<oop>(cm, obj, index); 77.66 + } 77.67 +} 77.68 + 77.69 +template <class T> 77.70 +void objArrayKlass::objarray_follow_contents(ParCompactionManager* cm, oop obj, 77.71 + int index) { 77.72 + objArrayOop a = objArrayOop(obj); 77.73 + const size_t len = size_t(a->length()); 77.74 + const size_t beg_index = size_t(index); 77.75 + assert(beg_index < len || len == 0, "index too large"); 77.76 + 77.77 + const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride); 77.78 + const size_t end_index = beg_index + stride; 77.79 + T* const base = (T*)a->base(); 77.80 + T* const beg = base + beg_index; 77.81 + T* const end = base + end_index; 77.82 + 77.83 + // Push the non-NULL elements of the next stride on the marking stack. 77.84 + for (T* e = beg; e < end; e++) { 77.85 + PSParallelCompact::mark_and_push<T>(cm, e); 77.86 + } 77.87 + 77.88 + if (end_index < len) { 77.89 + cm->push_objarray(a, end_index); // Push the continuation. 77.90 + } 77.91 +} 77.92 +#endif // #ifndef SERIALGC
78.1 --- a/src/share/vm/opto/loopTransform.cpp Thu Mar 25 16:54:59 2010 -0700 78.2 +++ b/src/share/vm/opto/loopTransform.cpp Fri Mar 26 11:10:26 2010 -0400 78.3 @@ -1,5 +1,5 @@ 78.4 /* 78.5 - * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. 78.6 + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. 78.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 78.8 * 78.9 * This code is free software; you can redistribute it and/or modify it 78.10 @@ -2088,29 +2088,41 @@ 78.11 BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl, 78.12 int scale, Node* offset, 78.13 Node* init, Node* limit, Node* stride, 78.14 - Node* range) { 78.15 + Node* range, bool upper) { 78.16 + DEBUG_ONLY(ttyLocker ttyl); 78.17 + if (TraceLoopPredicate) tty->print("rc_predicate "); 78.18 + 78.19 Node* max_idx_expr = init; 78.20 int stride_con = stride->get_int(); 78.21 - if ((stride_con > 0) == (scale > 0)) { 78.22 + if ((stride_con > 0) == (scale > 0) == upper) { 78.23 max_idx_expr = new (C, 3) SubINode(limit, stride); 78.24 register_new_node(max_idx_expr, ctrl); 78.25 + if (TraceLoopPredicate) tty->print("(limit - stride) "); 78.26 + } else { 78.27 + if (TraceLoopPredicate) tty->print("init "); 78.28 } 78.29 78.30 if (scale != 1) { 78.31 ConNode* con_scale = _igvn.intcon(scale); 78.32 max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale); 78.33 register_new_node(max_idx_expr, ctrl); 78.34 + if (TraceLoopPredicate) tty->print("* %d ", scale); 78.35 } 78.36 78.37 if (offset && (!offset->is_Con() || offset->get_int() != 0)){ 78.38 max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset); 78.39 register_new_node(max_idx_expr, ctrl); 78.40 + if (TraceLoopPredicate) 78.41 + if (offset->is_Con()) tty->print("+ %d ", offset->get_int()); 78.42 + else tty->print("+ offset "); 78.43 } 78.44 78.45 CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range); 78.46 register_new_node(cmp, ctrl); 78.47 BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt); 78.48 register_new_node(bol, ctrl); 78.49 + 78.50 + if (TraceLoopPredicate) tty->print_cr("<u range"); 78.51 return bol; 78.52 } 78.53 78.54 @@ -2187,7 +2199,6 @@ 78.55 while (if_proj_list.size() > 0) { 78.56 // Following are changed to nonnull when a predicate can be hoisted 78.57 ProjNode* new_predicate_proj = NULL; 78.58 - BoolNode* new_predicate_bol = NULL; 78.59 78.60 ProjNode* proj = if_proj_list.pop()->as_Proj(); 78.61 IfNode* iff = proj->in(0)->as_If(); 78.62 @@ -2218,93 +2229,120 @@ 78.63 // Invariant test 78.64 new_predicate_proj = create_new_if_for_predicate(predicate_proj); 78.65 Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0); 78.66 - new_predicate_bol = invar.clone(bol, ctrl)->as_Bool(); 78.67 - if (TraceLoopPredicate) tty->print("invariant"); 78.68 + BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool(); 78.69 + 78.70 + // Negate test if necessary 78.71 + bool negated = false; 78.72 + if (proj->_con != predicate_proj->_con) { 78.73 + new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); 78.74 + register_new_node(new_predicate_bol, ctrl); 78.75 + negated = true; 78.76 + } 78.77 + IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If(); 78.78 + _igvn.hash_delete(new_predicate_iff); 78.79 + new_predicate_iff->set_req(1, new_predicate_bol); 78.80 + if (TraceLoopPredicate) tty->print_cr("invariant if%s: %d", negated ? " negated" : "", new_predicate_iff->_idx); 78.81 + 78.82 } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) { 78.83 - // Range check (only for counted loops) 78.84 - new_predicate_proj = create_new_if_for_predicate(predicate_proj); 78.85 - Node *ctrl = new_predicate_proj->in(0)->as_If()->in(0); 78.86 + assert(proj->_con == predicate_proj->_con, "must match"); 78.87 + 78.88 + // Range check for counted loops 78.89 const Node* cmp = bol->in(1)->as_Cmp(); 78.90 Node* idx = cmp->in(1); 78.91 assert(!invar.is_invariant(idx), "index is variant"); 78.92 assert(cmp->in(2)->Opcode() == Op_LoadRange, "must be"); 78.93 - LoadRangeNode* ld_rng = (LoadRangeNode*)cmp->in(2); // LoadRangeNode 78.94 + Node* ld_rng = cmp->in(2); // LoadRangeNode 78.95 assert(invar.is_invariant(ld_rng), "load range must be invariant"); 78.96 - ld_rng = (LoadRangeNode*)invar.clone(ld_rng, ctrl); 78.97 int scale = 1; 78.98 Node* offset = zero; 78.99 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset); 78.100 assert(ok, "must be index expression"); 78.101 + 78.102 + Node* init = cl->init_trip(); 78.103 + Node* limit = cl->limit(); 78.104 + Node* stride = cl->stride(); 78.105 + 78.106 + // Build if's for the upper and lower bound tests. The 78.107 + // lower_bound test will dominate the upper bound test and all 78.108 + // cloned or created nodes will use the lower bound test as 78.109 + // their declared control. 78.110 + ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj); 78.111 + ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj); 78.112 + assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); 78.113 + Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0); 78.114 + 78.115 + // Perform cloning to keep Invariance state correct since the 78.116 + // late schedule will place invariant things in the loop. 78.117 + ld_rng = invar.clone(ld_rng, ctrl); 78.118 if (offset && offset != zero) { 78.119 assert(invar.is_invariant(offset), "offset must be loop invariant"); 78.120 offset = invar.clone(offset, ctrl); 78.121 } 78.122 - Node* init = cl->init_trip(); 78.123 - Node* limit = cl->limit(); 78.124 - Node* stride = cl->stride(); 78.125 - new_predicate_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng); 78.126 - if (TraceLoopPredicate) tty->print("range check"); 78.127 - } 78.128 78.129 - if (new_predicate_proj == NULL) { 78.130 + // Test the lower bound 78.131 + Node* lower_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng, false); 78.132 + IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If(); 78.133 + _igvn.hash_delete(lower_bound_iff); 78.134 + lower_bound_iff->set_req(1, lower_bound_bol); 78.135 + if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx); 78.136 + 78.137 + // Test the upper bound 78.138 + Node* upper_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng, true); 78.139 + IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If(); 78.140 + _igvn.hash_delete(upper_bound_iff); 78.141 + upper_bound_iff->set_req(1, upper_bound_bol); 78.142 + if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx); 78.143 + 78.144 + // Fall through into rest of the clean up code which will move 78.145 + // any dependent nodes onto the upper bound test. 78.146 + new_predicate_proj = upper_bound_proj; 78.147 + } else { 78.148 // The other proj of the "iff" is a uncommon trap projection, and we can assume 78.149 // the other proj will not be executed ("executed" means uct raised). 78.150 continue; 78.151 - } else { 78.152 - // Success - attach condition (new_predicate_bol) to predicate if 78.153 - invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate 78.154 - IfNode* new_iff = new_predicate_proj->in(0)->as_If(); 78.155 + } 78.156 78.157 - // Negate test if necessary 78.158 - if (proj->_con != predicate_proj->_con) { 78.159 - new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); 78.160 - register_new_node(new_predicate_bol, new_iff->in(0)); 78.161 - if (TraceLoopPredicate) tty->print_cr(" if negated: %d", iff->_idx); 78.162 - } else { 78.163 - if (TraceLoopPredicate) tty->print_cr(" if: %d", iff->_idx); 78.164 + // Success - attach condition (new_predicate_bol) to predicate if 78.165 + invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate 78.166 + 78.167 + // Eliminate the old if in the loop body 78.168 + _igvn.hash_delete(iff); 78.169 + iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true); 78.170 + 78.171 + Node* ctrl = new_predicate_proj; // new control 78.172 + ProjNode* dp = proj; // old control 78.173 + assert(get_loop(dp) == loop, "guaranteed at the time of collecting proj"); 78.174 + // Find nodes (depends only on the test) off the surviving projection; 78.175 + // move them outside the loop with the control of proj_clone 78.176 + for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) { 78.177 + Node* cd = dp->fast_out(i); // Control-dependent node 78.178 + if (cd->depends_only_on_test()) { 78.179 + assert(cd->in(0) == dp, ""); 78.180 + _igvn.hash_delete(cd); 78.181 + cd->set_req(0, ctrl); // ctrl, not NULL 78.182 + set_early_ctrl(cd); 78.183 + _igvn._worklist.push(cd); 78.184 + IdealLoopTree *new_loop = get_loop(get_ctrl(cd)); 78.185 + if (new_loop != loop) { 78.186 + if (!loop->_child) loop->_body.yank(cd); 78.187 + if (!new_loop->_child ) new_loop->_body.push(cd); 78.188 + } 78.189 + --i; 78.190 + --imax; 78.191 } 78.192 + } 78.193 78.194 - _igvn.hash_delete(new_iff); 78.195 - new_iff->set_req(1, new_predicate_bol); 78.196 - 78.197 - _igvn.hash_delete(iff); 78.198 - iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true); 78.199 - 78.200 - Node* ctrl = new_predicate_proj; // new control 78.201 - ProjNode* dp = proj; // old control 78.202 - assert(get_loop(dp) == loop, "guarenteed at the time of collecting proj"); 78.203 - // Find nodes (depends only on the test) off the surviving projection; 78.204 - // move them outside the loop with the control of proj_clone 78.205 - for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) { 78.206 - Node* cd = dp->fast_out(i); // Control-dependent node 78.207 - if (cd->depends_only_on_test()) { 78.208 - assert(cd->in(0) == dp, ""); 78.209 - _igvn.hash_delete(cd); 78.210 - cd->set_req(0, ctrl); // ctrl, not NULL 78.211 - set_early_ctrl(cd); 78.212 - _igvn._worklist.push(cd); 78.213 - IdealLoopTree *new_loop = get_loop(get_ctrl(cd)); 78.214 - if (new_loop != loop) { 78.215 - if (!loop->_child) loop->_body.yank(cd); 78.216 - if (!new_loop->_child ) new_loop->_body.push(cd); 78.217 - } 78.218 - --i; 78.219 - --imax; 78.220 - } 78.221 - } 78.222 - 78.223 - hoisted = true; 78.224 - C->set_major_progress(); 78.225 - } 78.226 + hoisted = true; 78.227 + C->set_major_progress(); 78.228 } // end while 78.229 78.230 #ifndef PRODUCT 78.231 - // report that the loop predication has been actually performed 78.232 - // for this loop 78.233 - if (TraceLoopPredicate && hoisted) { 78.234 - tty->print("Loop Predication Performed:"); 78.235 - loop->dump_head(); 78.236 - } 78.237 + // report that the loop predication has been actually performed 78.238 + // for this loop 78.239 + if (TraceLoopPredicate && hoisted) { 78.240 + tty->print("Loop Predication Performed:"); 78.241 + loop->dump_head(); 78.242 + } 78.243 #endif 78.244 78.245 return hoisted;
79.1 --- a/src/share/vm/opto/loopnode.hpp Thu Mar 25 16:54:59 2010 -0700 79.2 +++ b/src/share/vm/opto/loopnode.hpp Fri Mar 26 11:10:26 2010 -0400 79.3 @@ -821,7 +821,7 @@ 79.4 BoolNode* rc_predicate(Node* ctrl, 79.5 int scale, Node* offset, 79.6 Node* init, Node* limit, Node* stride, 79.7 - Node* range); 79.8 + Node* range, bool upper); 79.9 79.10 // Implementation of the loop predication to promote checks outside the loop 79.11 bool loop_predication_impl(IdealLoopTree *loop);
80.1 --- a/src/share/vm/opto/runtime.cpp Thu Mar 25 16:54:59 2010 -0700 80.2 +++ b/src/share/vm/opto/runtime.cpp Fri Mar 26 11:10:26 2010 -0400 80.3 @@ -864,7 +864,7 @@ 80.4 thread->set_exception_handler_pc(handler_address); 80.5 thread->set_exception_stack_size(0); 80.6 80.7 - // Check if the exception PC is a MethodHandle call. 80.8 + // Check if the exception PC is a MethodHandle call site. 80.9 thread->set_is_method_handle_exception(nm->is_method_handle_return(pc)); 80.10 } 80.11 80.12 @@ -952,7 +952,7 @@ 80.13 80.14 thread->set_vm_result(exception); 80.15 // Frame not compiled (handles deoptimization blob) 80.16 - return SharedRuntime::raw_exception_handler_for_return_address(ret_pc); 80.17 + return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc); 80.18 } 80.19 80.20
81.1 --- a/src/share/vm/prims/methodHandles.cpp Thu Mar 25 16:54:59 2010 -0700 81.2 +++ b/src/share/vm/prims/methodHandles.cpp Fri Mar 26 11:10:26 2010 -0400 81.3 @@ -1,5 +1,5 @@ 81.4 /* 81.5 - * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved. 81.6 + * Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved. 81.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 81.8 * 81.9 * This code is free software; you can redistribute it and/or modify it 81.10 @@ -82,6 +82,10 @@ 81.11 NULL 81.12 }; 81.13 81.14 +// Adapters. 81.15 +MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; 81.16 +int MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size; 81.17 + 81.18 jobject MethodHandles::_raise_exception_method; 81.19 81.20 #ifdef ASSERT 81.21 @@ -95,6 +99,41 @@ 81.22 } 81.23 #endif 81.24 81.25 + 81.26 +//------------------------------------------------------------------------------ 81.27 +// MethodHandles::generate_adapters 81.28 +// 81.29 +void MethodHandles::generate_adapters() { 81.30 + if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL) return; 81.31 + 81.32 + assert(_adapter_code == NULL, "generate only once"); 81.33 + 81.34 + ResourceMark rm; 81.35 + TraceTime timer("MethodHandles adapters generation", TraceStartupTime); 81.36 + _adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size); 81.37 + if (_adapter_code == NULL) 81.38 + vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters"); 81.39 + CodeBuffer code(_adapter_code->instructions_begin(), _adapter_code->instructions_size()); 81.40 + 81.41 + MethodHandlesAdapterGenerator g(&code); 81.42 + g.generate(); 81.43 +} 81.44 + 81.45 + 81.46 +//------------------------------------------------------------------------------ 81.47 +// MethodHandlesAdapterGenerator::generate 81.48 +// 81.49 +void MethodHandlesAdapterGenerator::generate() { 81.50 + // Generate generic method handle adapters. 81.51 + for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; 81.52 + ek < MethodHandles::_EK_LIMIT; 81.53 + ek = MethodHandles::EntryKind(1 + (int)ek)) { 81.54 + StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); 81.55 + MethodHandles::generate_method_handle_stub(_masm, ek); 81.56 + } 81.57 +} 81.58 + 81.59 + 81.60 void MethodHandles::set_enabled(bool z) { 81.61 if (_enabled != z) { 81.62 guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles");
82.1 --- a/src/share/vm/prims/methodHandles.hpp Thu Mar 25 16:54:59 2010 -0700 82.2 +++ b/src/share/vm/prims/methodHandles.hpp Fri Mar 26 11:10:26 2010 -0400 82.3 @@ -1,5 +1,5 @@ 82.4 /* 82.5 - * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved. 82.6 + * Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved. 82.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 82.8 * 82.9 * This code is free software; you can redistribute it and/or modify it 82.10 @@ -115,6 +115,10 @@ 82.11 static const char* _entry_names[_EK_LIMIT+1]; 82.12 static jobject _raise_exception_method; 82.13 82.14 + // Adapters. 82.15 + static MethodHandlesAdapterBlob* _adapter_code; 82.16 + static int _adapter_code_size; 82.17 + 82.18 static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; } 82.19 static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; } 82.20 82.21 @@ -133,6 +137,43 @@ 82.22 _entries[ek] = me; 82.23 } 82.24 82.25 + // Some adapter helper functions. 82.26 + static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) { 82.27 + switch (ek) { 82.28 + case _bound_int_mh : // fall-thru 82.29 + case _bound_int_direct_mh : arg_type = T_INT; arg_mask = _INSERT_INT_MASK; break; 82.30 + case _bound_long_mh : // fall-thru 82.31 + case _bound_long_direct_mh: arg_type = T_LONG; arg_mask = _INSERT_LONG_MASK; break; 82.32 + case _bound_ref_mh : // fall-thru 82.33 + case _bound_ref_direct_mh : arg_type = T_OBJECT; arg_mask = _INSERT_REF_MASK; break; 82.34 + default: ShouldNotReachHere(); 82.35 + } 82.36 + arg_slots = type2size[arg_type]; 82.37 + } 82.38 + 82.39 + static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) { 82.40 + int swap_slots = 0; 82.41 + switch (ek) { 82.42 + case _adapter_opt_swap_1: swap_slots = 1; rotate = 0; break; 82.43 + case _adapter_opt_swap_2: swap_slots = 2; rotate = 0; break; 82.44 + case _adapter_opt_rot_1_up: swap_slots = 1; rotate = 1; break; 82.45 + case _adapter_opt_rot_1_down: swap_slots = 1; rotate = -1; break; 82.46 + case _adapter_opt_rot_2_up: swap_slots = 2; rotate = 1; break; 82.47 + case _adapter_opt_rot_2_down: swap_slots = 2; rotate = -1; break; 82.48 + default: ShouldNotReachHere(); 82.49 + } 82.50 + // Return the size of the stack slots to move in bytes. 82.51 + swap_bytes = swap_slots * Interpreter::stackElementSize(); 82.52 + } 82.53 + 82.54 + static int get_ek_adapter_opt_spread_info(EntryKind ek) { 82.55 + switch (ek) { 82.56 + case _adapter_opt_spread_0: return 0; 82.57 + case _adapter_opt_spread_1: return 1; 82.58 + default : return -1; 82.59 + } 82.60 + } 82.61 + 82.62 static methodOop raise_exception_method() { 82.63 oop rem = JNIHandles::resolve(_raise_exception_method); 82.64 assert(rem == NULL || rem->is_method(), ""); 82.65 @@ -230,7 +271,10 @@ 82.66 // bit values for suppress argument to expand_MemberName: 82.67 enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 }; 82.68 82.69 - // called from InterpreterGenerator and StubGenerator 82.70 + // Generate MethodHandles adapters. 82.71 + static void generate_adapters(); 82.72 + 82.73 + // Called from InterpreterGenerator and MethodHandlesAdapterGenerator. 82.74 static address generate_method_handle_interpreter_entry(MacroAssembler* _masm); 82.75 static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek); 82.76 82.77 @@ -385,13 +429,13 @@ 82.78 static void insert_arg_slots(MacroAssembler* _masm, 82.79 RegisterOrConstant arg_slots, 82.80 int arg_mask, 82.81 - Register rax_argslot, 82.82 - Register rbx_temp, Register rdx_temp); 82.83 + Register argslot_reg, 82.84 + Register temp_reg, Register temp2_reg); 82.85 82.86 static void remove_arg_slots(MacroAssembler* _masm, 82.87 RegisterOrConstant arg_slots, 82.88 - Register rax_argslot, 82.89 - Register rbx_temp, Register rdx_temp); 82.90 + Register argslot_reg, 82.91 + Register temp_reg, Register temp2_reg); 82.92 }; 82.93 82.94 82.95 @@ -447,3 +491,14 @@ 82.96 82.97 address MethodHandles::from_compiled_entry(EntryKind ek) { return entry(ek)->from_compiled_entry(); } 82.98 address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->from_interpreted_entry(); } 82.99 + 82.100 + 82.101 +//------------------------------------------------------------------------------ 82.102 +// MethodHandlesAdapterGenerator 82.103 +// 82.104 +class MethodHandlesAdapterGenerator : public StubCodeGenerator { 82.105 +public: 82.106 + MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code) {} 82.107 + 82.108 + void generate(); 82.109 +};
83.1 --- a/src/share/vm/runtime/arguments.cpp Thu Mar 25 16:54:59 2010 -0700 83.2 +++ b/src/share/vm/runtime/arguments.cpp Fri Mar 26 11:10:26 2010 -0400 83.3 @@ -1346,9 +1346,7 @@ 83.4 } 83.5 83.6 if (FLAG_IS_DEFAULT(MarkStackSize)) { 83.7 - // Size as a multiple of TaskQueueSuper::N which is larger 83.8 - // for 64-bit. 83.9 - FLAG_SET_DEFAULT(MarkStackSize, 128 * TaskQueueSuper::total_size()); 83.10 + FLAG_SET_DEFAULT(MarkStackSize, 128 * TASKQUEUE_SIZE); 83.11 } 83.12 if (PrintGCDetails && Verbose) { 83.13 tty->print_cr("MarkStackSize: %uk MarkStackSizeMax: %uk", 83.14 @@ -2859,6 +2857,12 @@ 83.15 } 83.16 #endif // _LP64 83.17 83.18 + // MethodHandles code does not support TaggedStackInterpreter. 83.19 + if (EnableMethodHandles && TaggedStackInterpreter) { 83.20 + warning("TaggedStackInterpreter is not supported by MethodHandles code. Disabling TaggedStackInterpreter."); 83.21 + TaggedStackInterpreter = false; 83.22 + } 83.23 + 83.24 // Check the GC selections again. 83.25 if (!check_gc_consistency()) { 83.26 return JNI_EINVAL;
84.1 --- a/src/share/vm/runtime/globals.hpp Thu Mar 25 16:54:59 2010 -0700 84.2 +++ b/src/share/vm/runtime/globals.hpp Fri Mar 26 11:10:26 2010 -0400 84.3 @@ -1795,6 +1795,10 @@ 84.4 product(uintx, PreserveMarkStackSize, 1024, \ 84.5 "Size for stack used in promotion failure handling") \ 84.6 \ 84.7 + develop(uintx, ObjArrayMarkingStride, 512, \ 84.8 + "Number of ObjArray elements to push onto the marking stack" \ 84.9 + "before pushing a continuation entry") \ 84.10 + \ 84.11 product_pd(bool, UseTLAB, "Use thread-local object allocation") \ 84.12 \ 84.13 product_pd(bool, ResizeTLAB, \
85.1 --- a/src/share/vm/runtime/init.cpp Thu Mar 25 16:54:59 2010 -0700 85.2 +++ b/src/share/vm/runtime/init.cpp Fri Mar 26 11:10:26 2010 -0400 85.3 @@ -1,5 +1,5 @@ 85.4 /* 85.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 85.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 85.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 85.8 * 85.9 * This code is free software; you can redistribute it and/or modify it 85.10 @@ -118,6 +118,9 @@ 85.11 javaClasses_init(); // must happen after vtable initialization 85.12 stubRoutines_init2(); // note: StubRoutines need 2-phase init 85.13 85.14 + // Generate MethodHandles adapters. 85.15 + MethodHandles::generate_adapters(); 85.16 + 85.17 // Although we'd like to, we can't easily do a heap verify 85.18 // here because the main thread isn't yet a JavaThread, so 85.19 // its TLAB may not be made parseable from the usual interfaces.
86.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Mar 25 16:54:59 2010 -0700 86.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Mar 26 11:10:26 2010 -0400 86.3 @@ -256,7 +256,7 @@ 86.4 // The continuation address is the entry point of the exception handler of the 86.5 // previous frame depending on the return address. 86.6 86.7 -address SharedRuntime::raw_exception_handler_for_return_address(address return_address) { 86.8 +address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) { 86.9 assert(frame::verify_return_pc(return_address), "must be a return pc"); 86.10 86.11 // the fastest case first 86.12 @@ -264,6 +264,8 @@ 86.13 if (blob != NULL && blob->is_nmethod()) { 86.14 nmethod* code = (nmethod*)blob; 86.15 assert(code != NULL, "nmethod must be present"); 86.16 + // Check if the return address is a MethodHandle call site. 86.17 + thread->set_is_method_handle_exception(code->is_method_handle_return(return_address)); 86.18 // native nmethods don't have exception handlers 86.19 assert(!code->is_native_method(), "no exception handler"); 86.20 assert(code->header_begin() != code->exception_begin(), "no exception handler"); 86.21 @@ -289,6 +291,8 @@ 86.22 if (blob->is_nmethod()) { 86.23 nmethod* code = (nmethod*)blob; 86.24 assert(code != NULL, "nmethod must be present"); 86.25 + // Check if the return address is a MethodHandle call site. 86.26 + thread->set_is_method_handle_exception(code->is_method_handle_return(return_address)); 86.27 assert(code->header_begin() != code->exception_begin(), "no exception handler"); 86.28 return code->exception_begin(); 86.29 } 86.30 @@ -309,10 +313,11 @@ 86.31 } 86.32 86.33 86.34 -JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(address return_address)) 86.35 - return raw_exception_handler_for_return_address(return_address); 86.36 +JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(JavaThread* thread, address return_address)) 86.37 + return raw_exception_handler_for_return_address(thread, return_address); 86.38 JRT_END 86.39 86.40 + 86.41 address SharedRuntime::get_poll_stub(address pc) { 86.42 address stub; 86.43 // Look up the code blob 86.44 @@ -465,16 +470,6 @@ 86.45 t = table.entry_for(catch_pco, -1, 0); 86.46 } 86.47 86.48 -#ifdef COMPILER1 86.49 - if (nm->is_compiled_by_c1() && t == NULL && handler_bci == -1) { 86.50 - // Exception is not handled by this frame so unwind. Note that 86.51 - // this is not the same as how C2 does this. C2 emits a table 86.52 - // entry that dispatches to the unwind code in the nmethod. 86.53 - return NULL; 86.54 - } 86.55 -#endif /* COMPILER1 */ 86.56 - 86.57 - 86.58 if (t == NULL) { 86.59 tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci); 86.60 tty->print_cr(" Exception:"); 86.61 @@ -587,7 +582,7 @@ 86.62 // 3. Implict null exception in nmethod 86.63 86.64 if (!cb->is_nmethod()) { 86.65 - guarantee(cb->is_adapter_blob(), 86.66 + guarantee(cb->is_adapter_blob() || cb->is_method_handles_adapter_blob(), 86.67 "exception happened outside interpreter, nmethods and vtable stubs (1)"); 86.68 // There is no handler here, so we will simply unwind. 86.69 return StubRoutines::throw_NullPointerException_at_call_entry(); 86.70 @@ -892,12 +887,13 @@ 86.71 RegisterMap cbl_map(thread, false); 86.72 frame caller_frame = thread->last_frame().sender(&cbl_map); 86.73 86.74 - CodeBlob* cb = caller_frame.cb(); 86.75 - guarantee(cb != NULL && cb->is_nmethod(), "must be called from nmethod"); 86.76 + CodeBlob* caller_cb = caller_frame.cb(); 86.77 + guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod"); 86.78 + nmethod* caller_nm = caller_cb->as_nmethod_or_null(); 86.79 // make sure caller is not getting deoptimized 86.80 // and removed before we are done with it. 86.81 // CLEANUP - with lazy deopt shouldn't need this lock 86.82 - nmethodLocker caller_lock((nmethod*)cb); 86.83 + nmethodLocker caller_lock(caller_nm); 86.84 86.85 86.86 // determine call info & receiver 86.87 @@ -929,6 +925,13 @@ 86.88 } 86.89 #endif 86.90 86.91 + // JSR 292 86.92 + // If the resolved method is a MethodHandle invoke target the call 86.93 + // site must be a MethodHandle call site. 86.94 + if (callee_method->is_method_handle_invoke()) { 86.95 + assert(caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site"); 86.96 + } 86.97 + 86.98 // Compute entry points. This might require generation of C2I converter 86.99 // frames, so we cannot be holding any locks here. Furthermore, the 86.100 // computation of the entry points is independent of patching the call. We 86.101 @@ -940,13 +943,12 @@ 86.102 StaticCallInfo static_call_info; 86.103 CompiledICInfo virtual_call_info; 86.104 86.105 - 86.106 // Make sure the callee nmethod does not get deoptimized and removed before 86.107 // we are done patching the code. 86.108 - nmethod* nm = callee_method->code(); 86.109 - nmethodLocker nl_callee(nm); 86.110 + nmethod* callee_nm = callee_method->code(); 86.111 + nmethodLocker nl_callee(callee_nm); 86.112 #ifdef ASSERT 86.113 - address dest_entry_point = nm == NULL ? 0 : nm->entry_point(); // used below 86.114 + address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below 86.115 #endif 86.116 86.117 if (is_virtual) { 86.118 @@ -2077,7 +2079,6 @@ 86.119 86.120 // --------------------------------------------------------------------------- 86.121 // Implementation of AdapterHandlerLibrary 86.122 -const char* AdapterHandlerEntry::name = "I2C/C2I adapters"; 86.123 AdapterHandlerTable* AdapterHandlerLibrary::_adapters = NULL; 86.124 AdapterHandlerEntry* AdapterHandlerLibrary::_abstract_method_handler = NULL; 86.125 const int AdapterHandlerLibrary_size = 16*K; 86.126 @@ -2129,7 +2130,7 @@ 86.127 ResourceMark rm; 86.128 86.129 NOT_PRODUCT(int code_size); 86.130 - BufferBlob *B = NULL; 86.131 + AdapterBlob* B = NULL; 86.132 AdapterHandlerEntry* entry = NULL; 86.133 AdapterFingerPrint* fingerprint = NULL; 86.134 { 86.135 @@ -2179,7 +2180,7 @@ 86.136 86.137 // Create I2C & C2I handlers 86.138 86.139 - BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache 86.140 + BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache 86.141 if (buf != NULL) { 86.142 CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size()); 86.143 short buffer_locs[20]; 86.144 @@ -2208,7 +2209,7 @@ 86.145 } 86.146 #endif 86.147 86.148 - B = BufferBlob::create(AdapterHandlerEntry::name, &buffer); 86.149 + B = AdapterBlob::create(&buffer); 86.150 NOT_PRODUCT(code_size = buffer.code_size()); 86.151 } 86.152 if (B == NULL) { 86.153 @@ -2240,7 +2241,7 @@ 86.154 jio_snprintf(blob_id, 86.155 sizeof(blob_id), 86.156 "%s(%s)@" PTR_FORMAT, 86.157 - AdapterHandlerEntry::name, 86.158 + B->name(), 86.159 fingerprint->as_string(), 86.160 B->instructions_begin()); 86.161 VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
87.1 --- a/src/share/vm/runtime/sharedRuntime.hpp Thu Mar 25 16:54:59 2010 -0700 87.2 +++ b/src/share/vm/runtime/sharedRuntime.hpp Fri Mar 26 11:10:26 2010 -0400 87.3 @@ -96,10 +96,9 @@ 87.4 static jdouble dexp(jdouble x); 87.5 static jdouble dpow(jdouble x, jdouble y); 87.6 87.7 - 87.8 // exception handling across interpreter/compiler boundaries 87.9 - static address raw_exception_handler_for_return_address(address return_address); 87.10 - static address exception_handler_for_return_address(address return_address); 87.11 + static address raw_exception_handler_for_return_address(JavaThread* thread, address return_address); 87.12 + static address exception_handler_for_return_address(JavaThread* thread, address return_address); 87.13 87.14 #ifndef SERIALGC 87.15 // G1 write barriers 87.16 @@ -568,9 +567,6 @@ 87.17 AdapterHandlerEntry(); 87.18 87.19 public: 87.20 - // The name we give all buffer blobs 87.21 - static const char* name; 87.22 - 87.23 address get_i2c_entry() { return _i2c_entry; } 87.24 address get_c2i_entry() { return _c2i_entry; } 87.25 address get_c2i_unverified_entry() { return _c2i_unverified_entry; }
88.1 --- a/src/share/vm/runtime/vframeArray.cpp Thu Mar 25 16:54:59 2010 -0700 88.2 +++ b/src/share/vm/runtime/vframeArray.cpp Fri Mar 26 11:10:26 2010 -0400 88.3 @@ -223,7 +223,7 @@ 88.4 break; 88.5 case Deoptimization::Unpack_exception: 88.6 // exception is pending 88.7 - pc = SharedRuntime::raw_exception_handler_for_return_address(pc); 88.8 + pc = SharedRuntime::raw_exception_handler_for_return_address(thread, pc); 88.9 // [phh] We're going to end up in some handler or other, so it doesn't 88.10 // matter what mdp we point to. See exception_handler_for_exception() 88.11 // in interpreterRuntime.cpp.
89.1 --- a/src/share/vm/utilities/globalDefinitions.hpp Thu Mar 25 16:54:59 2010 -0700 89.2 +++ b/src/share/vm/utilities/globalDefinitions.hpp Fri Mar 26 11:10:26 2010 -0400 89.3 @@ -827,6 +827,8 @@ 89.4 #define badHeapWord (::badHeapWordVal) 89.5 #define badJNIHandle ((oop)::badJNIHandleVal) 89.6 89.7 +// Default TaskQueue size is 16K (32-bit) or 128K (64-bit) 89.8 +#define TASKQUEUE_SIZE (NOT_LP64(1<<14) LP64_ONLY(1<<17)) 89.9 89.10 //---------------------------------------------------------------------------------------------------- 89.11 // Utility functions for bitfield manipulations
90.1 --- a/src/share/vm/utilities/taskqueue.cpp Thu Mar 25 16:54:59 2010 -0700 90.2 +++ b/src/share/vm/utilities/taskqueue.cpp Fri Mar 26 11:10:26 2010 -0400 90.3 @@ -31,10 +31,6 @@ 90.4 uint ParallelTaskTerminator::_total_peeks = 0; 90.5 #endif 90.6 90.7 -bool TaskQueueSuper::peek() { 90.8 - return _bottom != _age.top(); 90.9 -} 90.10 - 90.11 int TaskQueueSetSuper::randomParkAndMiller(int *seed0) { 90.12 const int a = 16807; 90.13 const int m = 2147483647; 90.14 @@ -180,6 +176,13 @@ 90.15 } 90.16 } 90.17 90.18 +#ifdef ASSERT 90.19 +bool ObjArrayTask::is_valid() const { 90.20 + return _obj != NULL && _obj->is_objArray() && _index > 0 && 90.21 + _index < objArrayOop(_obj)->length(); 90.22 +} 90.23 +#endif // ASSERT 90.24 + 90.25 bool RegionTaskQueueWithOverflow::is_empty() { 90.26 return (_region_queue.size() == 0) && 90.27 (_overflow_stack->length() == 0);
91.1 --- a/src/share/vm/utilities/taskqueue.hpp Thu Mar 25 16:54:59 2010 -0700 91.2 +++ b/src/share/vm/utilities/taskqueue.hpp Fri Mar 26 11:10:26 2010 -0400 91.3 @@ -22,6 +22,7 @@ 91.4 * 91.5 */ 91.6 91.7 +template <unsigned int N> 91.8 class TaskQueueSuper: public CHeapObj { 91.9 protected: 91.10 // Internal type for indexing the queue; also used for the tag. 91.11 @@ -30,10 +31,7 @@ 91.12 // The first free element after the last one pushed (mod N). 91.13 volatile uint _bottom; 91.14 91.15 - enum { 91.16 - N = 1 << NOT_LP64(14) LP64_ONLY(17), // Queue size: 16K or 128K 91.17 - MOD_N_MASK = N - 1 // To compute x mod N efficiently. 91.18 - }; 91.19 + enum { MOD_N_MASK = N - 1 }; 91.20 91.21 class Age { 91.22 public: 91.23 @@ -84,12 +82,12 @@ 91.24 91.25 // Returns a number in the range [0..N). If the result is "N-1", it should be 91.26 // interpreted as 0. 91.27 - uint dirty_size(uint bot, uint top) { 91.28 + uint dirty_size(uint bot, uint top) const { 91.29 return (bot - top) & MOD_N_MASK; 91.30 } 91.31 91.32 // Returns the size corresponding to the given "bot" and "top". 91.33 - uint size(uint bot, uint top) { 91.34 + uint size(uint bot, uint top) const { 91.35 uint sz = dirty_size(bot, top); 91.36 // Has the queue "wrapped", so that bottom is less than top? There's a 91.37 // complicated special case here. A pair of threads could perform pop_local 91.38 @@ -111,17 +109,17 @@ 91.39 public: 91.40 TaskQueueSuper() : _bottom(0), _age() {} 91.41 91.42 - // Return "true" if the TaskQueue contains any tasks. 91.43 - bool peek(); 91.44 + // Return true if the TaskQueue contains any tasks. 91.45 + bool peek() { return _bottom != _age.top(); } 91.46 91.47 // Return an estimate of the number of elements in the queue. 91.48 // The "careful" version admits the possibility of pop_local/pop_global 91.49 // races. 91.50 - uint size() { 91.51 + uint size() const { 91.52 return size(_bottom, _age.top()); 91.53 } 91.54 91.55 - uint dirty_size() { 91.56 + uint dirty_size() const { 91.57 return dirty_size(_bottom, _age.top()); 91.58 } 91.59 91.60 @@ -132,19 +130,36 @@ 91.61 91.62 // Maximum number of elements allowed in the queue. This is two less 91.63 // than the actual queue size, for somewhat complicated reasons. 91.64 - uint max_elems() { return N - 2; } 91.65 + uint max_elems() const { return N - 2; } 91.66 91.67 // Total size of queue. 91.68 static const uint total_size() { return N; } 91.69 }; 91.70 91.71 -template<class E> class GenericTaskQueue: public TaskQueueSuper { 91.72 +template<class E, unsigned int N = TASKQUEUE_SIZE> 91.73 +class GenericTaskQueue: public TaskQueueSuper<N> { 91.74 +protected: 91.75 + typedef typename TaskQueueSuper<N>::Age Age; 91.76 + typedef typename TaskQueueSuper<N>::idx_t idx_t; 91.77 + 91.78 + using TaskQueueSuper<N>::_bottom; 91.79 + using TaskQueueSuper<N>::_age; 91.80 + using TaskQueueSuper<N>::increment_index; 91.81 + using TaskQueueSuper<N>::decrement_index; 91.82 + using TaskQueueSuper<N>::dirty_size; 91.83 + 91.84 +public: 91.85 + using TaskQueueSuper<N>::max_elems; 91.86 + using TaskQueueSuper<N>::size; 91.87 + 91.88 private: 91.89 // Slow paths for push, pop_local. (pop_global has no fast path.) 91.90 bool push_slow(E t, uint dirty_n_elems); 91.91 bool pop_local_slow(uint localBot, Age oldAge); 91.92 91.93 public: 91.94 + typedef E element_type; 91.95 + 91.96 // Initializes the queue to empty. 91.97 GenericTaskQueue(); 91.98 91.99 @@ -175,19 +190,19 @@ 91.100 volatile E* _elems; 91.101 }; 91.102 91.103 -template<class E> 91.104 -GenericTaskQueue<E>::GenericTaskQueue():TaskQueueSuper() { 91.105 +template<class E, unsigned int N> 91.106 +GenericTaskQueue<E, N>::GenericTaskQueue() { 91.107 assert(sizeof(Age) == sizeof(size_t), "Depends on this."); 91.108 } 91.109 91.110 -template<class E> 91.111 -void GenericTaskQueue<E>::initialize() { 91.112 +template<class E, unsigned int N> 91.113 +void GenericTaskQueue<E, N>::initialize() { 91.114 _elems = NEW_C_HEAP_ARRAY(E, N); 91.115 guarantee(_elems != NULL, "Allocation failed."); 91.116 } 91.117 91.118 -template<class E> 91.119 -void GenericTaskQueue<E>::oops_do(OopClosure* f) { 91.120 +template<class E, unsigned int N> 91.121 +void GenericTaskQueue<E, N>::oops_do(OopClosure* f) { 91.122 // tty->print_cr("START OopTaskQueue::oops_do"); 91.123 uint iters = size(); 91.124 uint index = _bottom; 91.125 @@ -203,21 +218,21 @@ 91.126 // tty->print_cr("END OopTaskQueue::oops_do"); 91.127 } 91.128 91.129 - 91.130 -template<class E> 91.131 -bool GenericTaskQueue<E>::push_slow(E t, uint dirty_n_elems) { 91.132 +template<class E, unsigned int N> 91.133 +bool GenericTaskQueue<E, N>::push_slow(E t, uint dirty_n_elems) { 91.134 if (dirty_n_elems == N - 1) { 91.135 // Actually means 0, so do the push. 91.136 uint localBot = _bottom; 91.137 - _elems[localBot] = t; 91.138 + // g++ complains if the volatile result of the assignment is unused. 91.139 + const_cast<E&>(_elems[localBot] = t); 91.140 OrderAccess::release_store(&_bottom, increment_index(localBot)); 91.141 return true; 91.142 } 91.143 return false; 91.144 } 91.145 91.146 -template<class E> 91.147 -bool GenericTaskQueue<E>:: 91.148 +template<class E, unsigned int N> 91.149 +bool GenericTaskQueue<E, N>:: 91.150 pop_local_slow(uint localBot, Age oldAge) { 91.151 // This queue was observed to contain exactly one element; either this 91.152 // thread will claim it, or a competing "pop_global". In either case, 91.153 @@ -249,8 +264,8 @@ 91.154 return false; 91.155 } 91.156 91.157 -template<class E> 91.158 -bool GenericTaskQueue<E>::pop_global(E& t) { 91.159 +template<class E, unsigned int N> 91.160 +bool GenericTaskQueue<E, N>::pop_global(E& t) { 91.161 Age oldAge = _age.get(); 91.162 uint localBot = _bottom; 91.163 uint n_elems = size(localBot, oldAge.top()); 91.164 @@ -258,7 +273,7 @@ 91.165 return false; 91.166 } 91.167 91.168 - t = _elems[oldAge.top()]; 91.169 + const_cast<E&>(t = _elems[oldAge.top()]); 91.170 Age newAge(oldAge); 91.171 newAge.increment(); 91.172 Age resAge = _age.cmpxchg(newAge, oldAge); 91.173 @@ -269,8 +284,8 @@ 91.174 return resAge == oldAge; 91.175 } 91.176 91.177 -template<class E> 91.178 -GenericTaskQueue<E>::~GenericTaskQueue() { 91.179 +template<class E, unsigned int N> 91.180 +GenericTaskQueue<E, N>::~GenericTaskQueue() { 91.181 FREE_C_HEAP_ARRAY(E, _elems); 91.182 } 91.183 91.184 @@ -283,16 +298,18 @@ 91.185 virtual bool peek() = 0; 91.186 }; 91.187 91.188 -template<class E> class GenericTaskQueueSet: public TaskQueueSetSuper { 91.189 +template<class T> 91.190 +class GenericTaskQueueSet: public TaskQueueSetSuper { 91.191 private: 91.192 uint _n; 91.193 - GenericTaskQueue<E>** _queues; 91.194 + T** _queues; 91.195 91.196 public: 91.197 + typedef typename T::element_type E; 91.198 + 91.199 GenericTaskQueueSet(int n) : _n(n) { 91.200 - typedef GenericTaskQueue<E>* GenericTaskQueuePtr; 91.201 + typedef T* GenericTaskQueuePtr; 91.202 _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n); 91.203 - guarantee(_queues != NULL, "Allocation failure."); 91.204 for (int i = 0; i < n; i++) { 91.205 _queues[i] = NULL; 91.206 } 91.207 @@ -302,9 +319,9 @@ 91.208 bool steal_best_of_2(uint queue_num, int* seed, E& t); 91.209 bool steal_best_of_all(uint queue_num, int* seed, E& t); 91.210 91.211 - void register_queue(uint i, GenericTaskQueue<E>* q); 91.212 + void register_queue(uint i, T* q); 91.213 91.214 - GenericTaskQueue<E>* queue(uint n); 91.215 + T* queue(uint n); 91.216 91.217 // The thread with queue number "queue_num" (and whose random number seed 91.218 // is at "seed") is trying to steal a task from some other queue. (It 91.219 @@ -316,27 +333,27 @@ 91.220 bool peek(); 91.221 }; 91.222 91.223 -template<class E> 91.224 -void GenericTaskQueueSet<E>::register_queue(uint i, GenericTaskQueue<E>* q) { 91.225 +template<class T> void 91.226 +GenericTaskQueueSet<T>::register_queue(uint i, T* q) { 91.227 assert(i < _n, "index out of range."); 91.228 _queues[i] = q; 91.229 } 91.230 91.231 -template<class E> 91.232 -GenericTaskQueue<E>* GenericTaskQueueSet<E>::queue(uint i) { 91.233 +template<class T> T* 91.234 +GenericTaskQueueSet<T>::queue(uint i) { 91.235 return _queues[i]; 91.236 } 91.237 91.238 -template<class E> 91.239 -bool GenericTaskQueueSet<E>::steal(uint queue_num, int* seed, E& t) { 91.240 +template<class T> bool 91.241 +GenericTaskQueueSet<T>::steal(uint queue_num, int* seed, E& t) { 91.242 for (uint i = 0; i < 2 * _n; i++) 91.243 if (steal_best_of_2(queue_num, seed, t)) 91.244 return true; 91.245 return false; 91.246 } 91.247 91.248 -template<class E> 91.249 -bool GenericTaskQueueSet<E>::steal_best_of_all(uint queue_num, int* seed, E& t) { 91.250 +template<class T> bool 91.251 +GenericTaskQueueSet<T>::steal_best_of_all(uint queue_num, int* seed, E& t) { 91.252 if (_n > 2) { 91.253 int best_k; 91.254 uint best_sz = 0; 91.255 @@ -359,8 +376,8 @@ 91.256 } 91.257 } 91.258 91.259 -template<class E> 91.260 -bool GenericTaskQueueSet<E>::steal_1_random(uint queue_num, int* seed, E& t) { 91.261 +template<class T> bool 91.262 +GenericTaskQueueSet<T>::steal_1_random(uint queue_num, int* seed, E& t) { 91.263 if (_n > 2) { 91.264 uint k = queue_num; 91.265 while (k == queue_num) k = randomParkAndMiller(seed) % _n; 91.266 @@ -375,8 +392,8 @@ 91.267 } 91.268 } 91.269 91.270 -template<class E> 91.271 -bool GenericTaskQueueSet<E>::steal_best_of_2(uint queue_num, int* seed, E& t) { 91.272 +template<class T> bool 91.273 +GenericTaskQueueSet<T>::steal_best_of_2(uint queue_num, int* seed, E& t) { 91.274 if (_n > 2) { 91.275 uint k1 = queue_num; 91.276 while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n; 91.277 @@ -397,8 +414,8 @@ 91.278 } 91.279 } 91.280 91.281 -template<class E> 91.282 -bool GenericTaskQueueSet<E>::peek() { 91.283 +template<class T> 91.284 +bool GenericTaskQueueSet<T>::peek() { 91.285 // Try all the queues. 91.286 for (uint j = 0; j < _n; j++) { 91.287 if (_queues[j]->peek()) 91.288 @@ -468,14 +485,16 @@ 91.289 #endif 91.290 }; 91.291 91.292 -template<class E> inline bool GenericTaskQueue<E>::push(E t) { 91.293 +template<class E, unsigned int N> inline bool 91.294 +GenericTaskQueue<E, N>::push(E t) { 91.295 uint localBot = _bottom; 91.296 assert((localBot >= 0) && (localBot < N), "_bottom out of range."); 91.297 idx_t top = _age.top(); 91.298 uint dirty_n_elems = dirty_size(localBot, top); 91.299 - assert((dirty_n_elems >= 0) && (dirty_n_elems < N), "n_elems out of range."); 91.300 + assert(dirty_n_elems < N, "n_elems out of range."); 91.301 if (dirty_n_elems < max_elems()) { 91.302 - _elems[localBot] = t; 91.303 + // g++ complains if the volatile result of the assignment is unused. 91.304 + const_cast<E&>(_elems[localBot] = t); 91.305 OrderAccess::release_store(&_bottom, increment_index(localBot)); 91.306 return true; 91.307 } else { 91.308 @@ -483,7 +502,8 @@ 91.309 } 91.310 } 91.311 91.312 -template<class E> inline bool GenericTaskQueue<E>::pop_local(E& t) { 91.313 +template<class E, unsigned int N> inline bool 91.314 +GenericTaskQueue<E, N>::pop_local(E& t) { 91.315 uint localBot = _bottom; 91.316 // This value cannot be N-1. That can only occur as a result of 91.317 // the assignment to bottom in this method. If it does, this method 91.318 @@ -497,7 +517,7 @@ 91.319 // This is necessary to prevent any read below from being reordered 91.320 // before the store just above. 91.321 OrderAccess::fence(); 91.322 - t = _elems[localBot]; 91.323 + const_cast<E&>(t = _elems[localBot]); 91.324 // This is a second read of "age"; the "size()" above is the first. 91.325 // If there's still at least one element in the queue, based on the 91.326 // "_bottom" and "age" we've read, then there can be no interference with 91.327 @@ -514,17 +534,23 @@ 91.328 } 91.329 91.330 typedef oop Task; 91.331 -typedef GenericTaskQueue<Task> OopTaskQueue; 91.332 -typedef GenericTaskQueueSet<Task> OopTaskQueueSet; 91.333 +typedef GenericTaskQueue<Task> OopTaskQueue; 91.334 +typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet; 91.335 91.336 - 91.337 -#define COMPRESSED_OOP_MASK 1 91.338 +#ifdef _MSC_VER 91.339 +#pragma warning(push) 91.340 +// warning C4522: multiple assignment operators specified 91.341 +#pragma warning(disable:4522) 91.342 +#endif 91.343 91.344 // This is a container class for either an oop* or a narrowOop*. 91.345 // Both are pushed onto a task queue and the consumer will test is_narrow() 91.346 // to determine which should be processed. 91.347 class StarTask { 91.348 void* _holder; // either union oop* or narrowOop* 91.349 + 91.350 + enum { COMPRESSED_OOP_MASK = 1 }; 91.351 + 91.352 public: 91.353 StarTask(narrowOop* p) { 91.354 assert(((uintptr_t)p & COMPRESSED_OOP_MASK) == 0, "Information loss!"); 91.355 @@ -540,20 +566,61 @@ 91.356 return (narrowOop*)((uintptr_t)_holder & ~COMPRESSED_OOP_MASK); 91.357 } 91.358 91.359 - // Operators to preserve const/volatile in assignments required by gcc 91.360 - void operator=(const volatile StarTask& t) volatile { _holder = t._holder; } 91.361 + StarTask& operator=(const StarTask& t) { 91.362 + _holder = t._holder; 91.363 + return *this; 91.364 + } 91.365 + volatile StarTask& operator=(const volatile StarTask& t) volatile { 91.366 + _holder = t._holder; 91.367 + return *this; 91.368 + } 91.369 91.370 bool is_narrow() const { 91.371 return (((uintptr_t)_holder & COMPRESSED_OOP_MASK) != 0); 91.372 } 91.373 }; 91.374 91.375 -typedef GenericTaskQueue<StarTask> OopStarTaskQueue; 91.376 -typedef GenericTaskQueueSet<StarTask> OopStarTaskQueueSet; 91.377 +class ObjArrayTask 91.378 +{ 91.379 +public: 91.380 + ObjArrayTask(oop o = NULL, int idx = 0): _obj(o), _index(idx) { } 91.381 + ObjArrayTask(oop o, size_t idx): _obj(o), _index(int(idx)) { 91.382 + assert(idx <= size_t(max_jint), "too big"); 91.383 + } 91.384 + ObjArrayTask(const ObjArrayTask& t): _obj(t._obj), _index(t._index) { } 91.385 + 91.386 + ObjArrayTask& operator =(const ObjArrayTask& t) { 91.387 + _obj = t._obj; 91.388 + _index = t._index; 91.389 + return *this; 91.390 + } 91.391 + volatile ObjArrayTask& 91.392 + operator =(const volatile ObjArrayTask& t) volatile { 91.393 + _obj = t._obj; 91.394 + _index = t._index; 91.395 + return *this; 91.396 + } 91.397 + 91.398 + inline oop obj() const { return _obj; } 91.399 + inline int index() const { return _index; } 91.400 + 91.401 + DEBUG_ONLY(bool is_valid() const); // Tasks to be pushed/popped must be valid. 91.402 + 91.403 +private: 91.404 + oop _obj; 91.405 + int _index; 91.406 +}; 91.407 + 91.408 +#ifdef _MSC_VER 91.409 +#pragma warning(pop) 91.410 +#endif 91.411 + 91.412 +typedef GenericTaskQueue<StarTask> OopStarTaskQueue; 91.413 +typedef GenericTaskQueueSet<OopStarTaskQueue> OopStarTaskQueueSet; 91.414 91.415 typedef size_t RegionTask; // index for region 91.416 -typedef GenericTaskQueue<RegionTask> RegionTaskQueue; 91.417 -typedef GenericTaskQueueSet<RegionTask> RegionTaskQueueSet; 91.418 +typedef GenericTaskQueue<RegionTask> RegionTaskQueue; 91.419 +typedef GenericTaskQueueSet<RegionTaskQueue> RegionTaskQueueSet; 91.420 91.421 class RegionTaskQueueWithOverflow: public CHeapObj { 91.422 protected:
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 92.2 +++ b/test/compiler/6930043/Test6930043.java Fri Mar 26 11:10:26 2010 -0400 92.3 @@ -0,0 +1,76 @@ 92.4 +/* 92.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 92.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 92.7 + * 92.8 + * This code is free software; you can redistribute it and/or modify it 92.9 + * under the terms of the GNU General Public License version 2 only, as 92.10 + * published by the Free Software Foundation. 92.11 + * 92.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 92.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 92.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 92.15 + * version 2 for more details (a copy is included in the LICENSE file that 92.16 + * accompanied this code). 92.17 + * 92.18 + * You should have received a copy of the GNU General Public License version 92.19 + * 2 along with this work; if not, write to the Free Software Foundation, 92.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 92.21 + * 92.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 92.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 92.24 + * have any questions. 92.25 + * 92.26 + */ 92.27 + 92.28 +/** 92.29 + * @test 92.30 + * @bug 6930043 92.31 + * @summary C2: SIGSEGV in javasoft.sqe.tests.lang.arr017.arr01702.arr01702.loop_forw(II)I 92.32 + * 92.33 + * @run main Test6930043 92.34 + */ 92.35 + 92.36 +import java.io.PrintStream; 92.37 + 92.38 +public class Test6930043 { 92.39 + int[] a; 92.40 + int idx; 92.41 + 92.42 + public int loop_back(int i, int i_0_) { 92.43 + int i_1_ = 0; 92.44 + int[] is = a; 92.45 + if (is == null) return 0; 92.46 + for (int i_2_ = i; i_2_ >= i_0_; i_2_--) 92.47 + i_1_ += is[idx = i_2_]; 92.48 + return i_1_; 92.49 + } 92.50 + 92.51 + public int loop_forw(int start, int end) { 92.52 + int result = 0; 92.53 + int[] is = a; 92.54 + if (is == null) return 0; 92.55 + for (int index = start; index < end; index++) 92.56 + result += is[index]; 92.57 + // result += is[idx = index]; 92.58 + return result; 92.59 + } 92.60 + 92.61 + public static void main(String[] strings) { 92.62 + Test6930043 var_Test6930043 = new Test6930043(); 92.63 + var_Test6930043.a = new int[1000000]; 92.64 + var_Test6930043.loop_forw(10, 999990); 92.65 + var_Test6930043.loop_forw(10, 999990); 92.66 + for (int i = 0; i < 3; i++) { 92.67 + try { 92.68 + if (var_Test6930043.loop_forw(-1, 999990) != 0) throw new InternalError(); 92.69 + } catch (ArrayIndexOutOfBoundsException e) { } 92.70 + } 92.71 + var_Test6930043.loop_back(999990, 10); 92.72 + var_Test6930043.loop_back(999990, 10); 92.73 + for (int i = 0; i < 3; i++) { 92.74 + try { 92.75 + if (var_Test6930043.loop_back(999990, -1) != 0) throw new InternalError(); 92.76 + } catch (ArrayIndexOutOfBoundsException e) { } 92.77 + } 92.78 + } 92.79 +}
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 93.2 +++ b/test/compiler/6932496/Test6932496.java Fri Mar 26 11:10:26 2010 -0400 93.3 @@ -0,0 +1,51 @@ 93.4 +/* 93.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 93.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 93.7 + * 93.8 + * This code is free software; you can redistribute it and/or modify it 93.9 + * under the terms of the GNU General Public License version 2 only, as 93.10 + * published by the Free Software Foundation. 93.11 + * 93.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 93.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 93.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 93.15 + * version 2 for more details (a copy is included in the LICENSE file that 93.16 + * accompanied this code). 93.17 + * 93.18 + * You should have received a copy of the GNU General Public License version 93.19 + * 2 along with this work; if not, write to the Free Software Foundation, 93.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 93.21 + * 93.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 93.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 93.24 + * have any questions. 93.25 + * 93.26 + */ 93.27 + 93.28 +/** 93.29 + * @test 93.30 + * @bug 6932496 93.31 + * @summary incorrect deopt of jsr subroutine on 64 bit c1 93.32 + * 93.33 + * @compile -source 1.5 -target 1.5 -XDjsrlimit=0 Test6932496.java 93.34 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6932496.m Test6932496 93.35 + */ 93.36 + 93.37 +public class Test6932496 { 93.38 + static class A { 93.39 + volatile boolean flag = false; 93.40 + } 93.41 + 93.42 + static void m() { 93.43 + try { 93.44 + } finally { 93.45 + A a = new A(); 93.46 + a.flag = true; 93.47 + } 93.48 + } 93.49 + 93.50 + 93.51 + static public void main(String[] args) { 93.52 + m(); 93.53 + } 93.54 +}
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 94.2 +++ b/test/compiler/6935535/Test.java Fri Mar 26 11:10:26 2010 -0400 94.3 @@ -0,0 +1,48 @@ 94.4 +/* 94.5 + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. 94.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 94.7 + * 94.8 + * This code is free software; you can redistribute it and/or modify it 94.9 + * under the terms of the GNU General Public License version 2 only, as 94.10 + * published by the Free Software Foundation. 94.11 + * 94.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 94.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 94.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 94.15 + * version 2 for more details (a copy is included in the LICENSE file that 94.16 + * accompanied this code). 94.17 + * 94.18 + * You should have received a copy of the GNU General Public License version 94.19 + * 2 along with this work; if not, write to the Free Software Foundation, 94.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 94.21 + * 94.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 94.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 94.24 + * have any questions. 94.25 + */ 94.26 + 94.27 +/** 94.28 + * @test 94.29 + * @bug 6935535 94.30 + * @summary String.indexOf() returns incorrect result on x86 with SSE4.2 94.31 + * 94.32 + * @run main/othervm -Xcomp Test 94.33 + */ 94.34 + 94.35 +public class Test { 94.36 + 94.37 + static int IndexOfTest(String str) { 94.38 + return str.indexOf("1111111111111xx1x"); 94.39 + } 94.40 + 94.41 + public static void main(String args[]) { 94.42 + String str = "1111111111111xx1111111111111xx1x"; 94.43 + str = str.substring(0, 31); 94.44 + int idx = IndexOfTest(str); 94.45 + System.out.println("IndexOf(" + "1111111111111xx1x" + ") = " + idx + " in " + str); 94.46 + if (idx != -1) { 94.47 + System.exit(97); 94.48 + } 94.49 + } 94.50 +} 94.51 +