Mon, 28 Jul 2014 15:06:38 -0700
8051344: JVM crashed in Compile::start() during method parsing w/ UseRTMDeopt turned on
Summary: call rtm_deopt() only if there were no compilation bailouts before.
Reviewed-by: kvn
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. |
aoqi@0 | 8 | * |
aoqi@0 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 13 | * accompanied this code). |
aoqi@0 | 14 | * |
aoqi@0 | 15 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 18 | * |
aoqi@0 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 20 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 21 | * questions. |
aoqi@0 | 22 | */ |
aoqi@0 | 23 | |
aoqi@0 | 24 | /* |
aoqi@0 | 25 | * @test |
aoqi@0 | 26 | * @bug 6896617 |
aoqi@0 | 27 | * @summary Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() with SSE instructions on x86 |
aoqi@0 | 28 | * @run main/othervm/timeout=1200 -Xbatch -Xmx256m Test6896617 |
aoqi@0 | 29 | * |
aoqi@0 | 30 | */ |
aoqi@0 | 31 | |
aoqi@0 | 32 | import java.util.*; |
aoqi@0 | 33 | import java.nio.*; |
aoqi@0 | 34 | import java.nio.charset.*; |
aoqi@0 | 35 | |
aoqi@0 | 36 | public class Test6896617 { |
aoqi@0 | 37 | final static int SIZE = 256; |
aoqi@0 | 38 | |
aoqi@0 | 39 | public static void main(String[] args) { |
aoqi@0 | 40 | String csn = "ISO-8859-1"; |
aoqi@0 | 41 | Charset cs = Charset.forName(csn); |
aoqi@0 | 42 | CharsetEncoder enc = cs.newEncoder(); |
aoqi@0 | 43 | enc.onMalformedInput(CodingErrorAction.REPLACE) |
aoqi@0 | 44 | .onUnmappableCharacter(CodingErrorAction.REPLACE); |
aoqi@0 | 45 | CharsetDecoder dec = cs.newDecoder(); |
aoqi@0 | 46 | dec.onMalformedInput(CodingErrorAction.REPLACE) |
aoqi@0 | 47 | .onUnmappableCharacter(CodingErrorAction.REPLACE); |
aoqi@0 | 48 | |
aoqi@0 | 49 | byte repl = (byte)'?'; |
aoqi@0 | 50 | enc.replaceWith(new byte[] { repl }); |
aoqi@0 | 51 | |
aoqi@0 | 52 | // Use internal API for tests. |
aoqi@0 | 53 | sun.nio.cs.ArrayEncoder arrenc = (sun.nio.cs.ArrayEncoder)enc; |
aoqi@0 | 54 | sun.nio.cs.ArrayDecoder arrdec = (sun.nio.cs.ArrayDecoder)dec; |
aoqi@0 | 55 | |
aoqi@0 | 56 | // Populate char[] with chars which can be encoded by ISO_8859_1 (<= 0xFF) |
aoqi@0 | 57 | Random rnd = new Random(0); |
aoqi@0 | 58 | int maxchar = 0xFF; |
aoqi@0 | 59 | char[] a = new char[SIZE]; |
aoqi@0 | 60 | byte[] b = new byte[SIZE]; |
aoqi@0 | 61 | char[] at = new char[SIZE]; |
aoqi@0 | 62 | byte[] bt = new byte[SIZE]; |
aoqi@0 | 63 | for (int i = 0; i < SIZE; i++) { |
aoqi@0 | 64 | char c = (char) rnd.nextInt(maxchar); |
aoqi@0 | 65 | if (!enc.canEncode(c)) { |
aoqi@0 | 66 | System.out.printf("Something wrong: can't encode c=%03x\n", (int)c); |
aoqi@0 | 67 | System.exit(97); |
aoqi@0 | 68 | } |
aoqi@0 | 69 | a[i] = c; |
aoqi@0 | 70 | b[i] = (byte)c; |
aoqi@0 | 71 | at[i] = (char)-1; |
aoqi@0 | 72 | bt[i] = (byte)-1; |
aoqi@0 | 73 | } |
aoqi@0 | 74 | if (arrenc.encode(a, 0, SIZE, bt) != SIZE || !Arrays.equals(b, bt)) { |
aoqi@0 | 75 | System.out.println("Something wrong: ArrayEncoder.encode failed"); |
aoqi@0 | 76 | System.exit(97); |
aoqi@0 | 77 | } |
aoqi@0 | 78 | if (arrdec.decode(b, 0, SIZE, at) != SIZE || !Arrays.equals(a, at)) { |
aoqi@0 | 79 | System.out.println("Something wrong: ArrayDecoder.decode failed"); |
aoqi@0 | 80 | System.exit(97); |
aoqi@0 | 81 | } |
aoqi@0 | 82 | for (int i = 0; i < SIZE; i++) { |
aoqi@0 | 83 | at[i] = (char)-1; |
aoqi@0 | 84 | bt[i] = (byte)-1; |
aoqi@0 | 85 | } |
aoqi@0 | 86 | |
aoqi@0 | 87 | ByteBuffer bb = ByteBuffer.wrap(b); |
aoqi@0 | 88 | CharBuffer ba = CharBuffer.wrap(a); |
aoqi@0 | 89 | ByteBuffer bbt = ByteBuffer.wrap(bt); |
aoqi@0 | 90 | CharBuffer bat = CharBuffer.wrap(at); |
aoqi@0 | 91 | if (!enc.encode(ba, bbt, true).isUnderflow() || !Arrays.equals(b, bt)) { |
aoqi@0 | 92 | System.out.println("Something wrong: Encoder.encode failed"); |
aoqi@0 | 93 | System.exit(97); |
aoqi@0 | 94 | } |
aoqi@0 | 95 | if (!dec.decode(bb, bat, true).isUnderflow() || !Arrays.equals(a, at)) { |
aoqi@0 | 96 | System.out.println("Something wrong: Decoder.decode failed"); |
aoqi@0 | 97 | System.exit(97); |
aoqi@0 | 98 | } |
aoqi@0 | 99 | for (int i = 0; i < SIZE; i++) { |
aoqi@0 | 100 | at[i] = (char)-1; |
aoqi@0 | 101 | bt[i] = (byte)-1; |
aoqi@0 | 102 | } |
aoqi@0 | 103 | |
aoqi@0 | 104 | // Warm up |
aoqi@0 | 105 | boolean failed = false; |
aoqi@0 | 106 | int result = 0; |
aoqi@0 | 107 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 108 | result += arrenc.encode(a, 0, SIZE, bt); |
aoqi@0 | 109 | result -= arrdec.decode(b, 0, SIZE, at); |
aoqi@0 | 110 | } |
aoqi@0 | 111 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 112 | result += arrenc.encode(a, 0, SIZE, bt); |
aoqi@0 | 113 | result -= arrdec.decode(b, 0, SIZE, at); |
aoqi@0 | 114 | } |
aoqi@0 | 115 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 116 | result += arrenc.encode(a, 0, SIZE, bt); |
aoqi@0 | 117 | result -= arrdec.decode(b, 0, SIZE, at); |
aoqi@0 | 118 | } |
aoqi@0 | 119 | if (result != 0 || !Arrays.equals(b, bt) || !Arrays.equals(a, at)) { |
aoqi@0 | 120 | failed = true; |
aoqi@0 | 121 | System.out.println("Failed: ArrayEncoder.encode char[" + SIZE + "] and ArrayDecoder.decode byte[" + SIZE + "]"); |
aoqi@0 | 122 | } |
aoqi@0 | 123 | for (int i = 0; i < SIZE; i++) { |
aoqi@0 | 124 | at[i] = (char)-1; |
aoqi@0 | 125 | bt[i] = (byte)-1; |
aoqi@0 | 126 | } |
aoqi@0 | 127 | |
aoqi@0 | 128 | boolean is_underflow = true; |
aoqi@0 | 129 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 130 | ba.clear(); bb.clear(); bat.clear(); bbt.clear(); |
aoqi@0 | 131 | boolean enc_res = enc.encode(ba, bbt, true).isUnderflow(); |
aoqi@0 | 132 | boolean dec_res = dec.decode(bb, bat, true).isUnderflow(); |
aoqi@0 | 133 | is_underflow = is_underflow && enc_res && dec_res; |
aoqi@0 | 134 | } |
aoqi@0 | 135 | for (int i = 0; i < SIZE; i++) { |
aoqi@0 | 136 | at[i] = (char)-1; |
aoqi@0 | 137 | bt[i] = (byte)-1; |
aoqi@0 | 138 | } |
aoqi@0 | 139 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 140 | ba.clear(); bb.clear(); bat.clear(); bbt.clear(); |
aoqi@0 | 141 | boolean enc_res = enc.encode(ba, bbt, true).isUnderflow(); |
aoqi@0 | 142 | boolean dec_res = dec.decode(bb, bat, true).isUnderflow(); |
aoqi@0 | 143 | is_underflow = is_underflow && enc_res && dec_res; |
aoqi@0 | 144 | } |
aoqi@0 | 145 | for (int i = 0; i < SIZE; i++) { |
aoqi@0 | 146 | at[i] = (char)-1; |
aoqi@0 | 147 | bt[i] = (byte)-1; |
aoqi@0 | 148 | } |
aoqi@0 | 149 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 150 | ba.clear(); bb.clear(); bat.clear(); bbt.clear(); |
aoqi@0 | 151 | boolean enc_res = enc.encode(ba, bbt, true).isUnderflow(); |
aoqi@0 | 152 | boolean dec_res = dec.decode(bb, bat, true).isUnderflow(); |
aoqi@0 | 153 | is_underflow = is_underflow && enc_res && dec_res; |
aoqi@0 | 154 | } |
aoqi@0 | 155 | if (!is_underflow || !Arrays.equals(b, bt) || !Arrays.equals(a, at)) { |
aoqi@0 | 156 | failed = true; |
aoqi@0 | 157 | System.out.println("Failed: Encoder.encode char[" + SIZE + "] and Decoder.decode byte[" + SIZE + "]"); |
aoqi@0 | 158 | } |
aoqi@0 | 159 | |
aoqi@0 | 160 | // Test encoder with different source and destination sizes |
aoqi@0 | 161 | System.out.println("Testing different source and destination sizes"); |
aoqi@0 | 162 | for (int i = 1; i <= SIZE; i++) { |
aoqi@0 | 163 | for (int j = 1; j <= SIZE; j++) { |
aoqi@0 | 164 | bt = new byte[j]; |
aoqi@0 | 165 | // very source's SIZE |
aoqi@0 | 166 | result = arrenc.encode(a, 0, i, bt); |
aoqi@0 | 167 | int l = Math.min(i, j); |
aoqi@0 | 168 | if (result != l) { |
aoqi@0 | 169 | failed = true; |
aoqi@0 | 170 | System.out.println("Failed: encode char[" + i + "] to byte[" + j + "]: result = " + result + ", expected " + l); |
aoqi@0 | 171 | } |
aoqi@0 | 172 | for (int k = 0; k < l; k++) { |
aoqi@0 | 173 | if (bt[k] != b[k]) { |
aoqi@0 | 174 | failed = true; |
aoqi@0 | 175 | System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[k]); |
aoqi@0 | 176 | } |
aoqi@0 | 177 | } |
aoqi@0 | 178 | // very source's offset |
aoqi@0 | 179 | int sz = SIZE - i + 1; |
aoqi@0 | 180 | result = arrenc.encode(a, i-1, sz, bt); |
aoqi@0 | 181 | l = Math.min(sz, j); |
aoqi@0 | 182 | if (result != l) { |
aoqi@0 | 183 | failed = true; |
aoqi@0 | 184 | System.out.println("Failed: encode char[" + sz + "] to byte[" + j + "]: result = " + result + ", expected " + l); |
aoqi@0 | 185 | } |
aoqi@0 | 186 | for (int k = 0; k < l; k++) { |
aoqi@0 | 187 | if (bt[k] != b[i+k-1]) { |
aoqi@0 | 188 | failed = true; |
aoqi@0 | 189 | System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[i+k-1]); |
aoqi@0 | 190 | } |
aoqi@0 | 191 | } |
aoqi@0 | 192 | } |
aoqi@0 | 193 | } |
aoqi@0 | 194 | |
aoqi@0 | 195 | // Test encoder with char > 0xFF |
aoqi@0 | 196 | System.out.println("Testing big char"); |
aoqi@0 | 197 | |
aoqi@0 | 198 | byte orig = (byte)'A'; |
aoqi@0 | 199 | bt = new byte[SIZE]; |
aoqi@0 | 200 | for (int i = 1; i <= SIZE; i++) { |
aoqi@0 | 201 | for (int j = 0; j < i; j++) { |
aoqi@0 | 202 | a[j] += 0x100; |
aoqi@0 | 203 | // make sure to replace a different byte |
aoqi@0 | 204 | bt[j] = orig; |
aoqi@0 | 205 | result = arrenc.encode(a, 0, i, bt); |
aoqi@0 | 206 | if (result != i) { |
aoqi@0 | 207 | failed = true; |
aoqi@0 | 208 | System.out.println("Failed: encode char[" + i + "] to byte[" + i + "]: result = " + result + ", expected " + i); |
aoqi@0 | 209 | } |
aoqi@0 | 210 | if (bt[j] != repl) { |
aoqi@0 | 211 | failed = true; |
aoqi@0 | 212 | System.out.println("Failed: encoded replace byte[" + j + "] (" + bt[j] + ") != " + repl); |
aoqi@0 | 213 | } |
aoqi@0 | 214 | bt[j] = b[j]; // Restore to compare whole array |
aoqi@0 | 215 | for (int k = 0; k < i; k++) { |
aoqi@0 | 216 | if (bt[k] != b[k]) { |
aoqi@0 | 217 | failed = true; |
aoqi@0 | 218 | System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[k]); |
aoqi@0 | 219 | } |
aoqi@0 | 220 | } |
aoqi@0 | 221 | a[j] -= 0x100; // Restore |
aoqi@0 | 222 | } |
aoqi@0 | 223 | } |
aoqi@0 | 224 | |
aoqi@0 | 225 | // Test sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() performance. |
aoqi@0 | 226 | |
aoqi@0 | 227 | int itrs = Integer.getInteger("iterations", 1000000); |
aoqi@0 | 228 | int size = Integer.getInteger("size", 256); |
aoqi@0 | 229 | a = new char[size]; |
aoqi@0 | 230 | b = new byte[size]; |
aoqi@0 | 231 | bt = new byte[size]; |
aoqi@0 | 232 | for (int i = 0; i < size; i++) { |
aoqi@0 | 233 | char c = (char) rnd.nextInt(maxchar); |
aoqi@0 | 234 | if (!enc.canEncode(c)) { |
aoqi@0 | 235 | System.out.printf("Something wrong: can't encode c=%03x\n", (int)c); |
aoqi@0 | 236 | System.exit(97); |
aoqi@0 | 237 | } |
aoqi@0 | 238 | a[i] = c; |
aoqi@0 | 239 | b[i] = (byte)-1; |
aoqi@0 | 240 | bt[i] = (byte)c; |
aoqi@0 | 241 | } |
aoqi@0 | 242 | ba = CharBuffer.wrap(a); |
aoqi@0 | 243 | bb = ByteBuffer.wrap(b); |
aoqi@0 | 244 | boolean enc_res = enc.encode(ba, bb, true).isUnderflow(); |
aoqi@0 | 245 | if (!enc_res || !Arrays.equals(b, bt)) { |
aoqi@0 | 246 | failed = true; |
aoqi@0 | 247 | System.out.println("Failed 1: Encoder.encode char[" + size + "]"); |
aoqi@0 | 248 | } |
aoqi@0 | 249 | for (int i = 0; i < size; i++) { |
aoqi@0 | 250 | b[i] = (byte)-1; |
aoqi@0 | 251 | } |
aoqi@0 | 252 | |
aoqi@0 | 253 | // Make sure to recompile method if needed before performance run. |
aoqi@0 | 254 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 255 | ba.clear(); bb.clear(); |
aoqi@0 | 256 | enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow(); |
aoqi@0 | 257 | } |
aoqi@0 | 258 | for (int i = 0; i < size; i++) { |
aoqi@0 | 259 | b[i] = (byte)-1; |
aoqi@0 | 260 | } |
aoqi@0 | 261 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 262 | ba.clear(); bb.clear(); |
aoqi@0 | 263 | enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow(); |
aoqi@0 | 264 | } |
aoqi@0 | 265 | if (!enc_res || !Arrays.equals(b, bt)) { |
aoqi@0 | 266 | failed = true; |
aoqi@0 | 267 | System.out.println("Failed 2: Encoder.encode char[" + size + "]"); |
aoqi@0 | 268 | } |
aoqi@0 | 269 | for (int i = 0; i < size; i++) { |
aoqi@0 | 270 | b[i] = (byte)-1; |
aoqi@0 | 271 | } |
aoqi@0 | 272 | |
aoqi@0 | 273 | System.out.println("Testing ISO_8859_1$Encode.encodeArrayLoop() performance"); |
aoqi@0 | 274 | long start = System.currentTimeMillis(); |
aoqi@0 | 275 | for (int i = 0; i < itrs; i++) { |
aoqi@0 | 276 | ba.clear(); bb.clear(); |
aoqi@0 | 277 | enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow(); |
aoqi@0 | 278 | } |
aoqi@0 | 279 | long end = System.currentTimeMillis(); |
aoqi@0 | 280 | if (!enc_res || !Arrays.equals(b, bt)) { |
aoqi@0 | 281 | failed = true; |
aoqi@0 | 282 | System.out.println("Failed 3: Encoder.encode char[" + size + "]"); |
aoqi@0 | 283 | } else { |
aoqi@0 | 284 | System.out.println("size: " + size + " time: " + (end - start)); |
aoqi@0 | 285 | } |
aoqi@0 | 286 | |
aoqi@0 | 287 | // Test sun.nio.cs.ISO_8859_1$Encode.encode() performance. |
aoqi@0 | 288 | |
aoqi@0 | 289 | // Make sure to recompile method if needed before performance run. |
aoqi@0 | 290 | result = 0; |
aoqi@0 | 291 | for (int i = 0; i < size; i++) { |
aoqi@0 | 292 | b[i] = (byte)-1; |
aoqi@0 | 293 | } |
aoqi@0 | 294 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 295 | result += arrenc.encode(a, 0, size, b); |
aoqi@0 | 296 | } |
aoqi@0 | 297 | for (int i = 0; i < size; i++) { |
aoqi@0 | 298 | b[i] = (byte)-1; |
aoqi@0 | 299 | } |
aoqi@0 | 300 | for (int i = 0; i < 10000; i++) { |
aoqi@0 | 301 | result += arrenc.encode(a, 0, size, b); |
aoqi@0 | 302 | } |
aoqi@0 | 303 | if (result != size*20000 || !Arrays.equals(b, bt)) { |
aoqi@0 | 304 | failed = true; |
aoqi@0 | 305 | System.out.println("Failed 1: ArrayEncoder.encode char[" + SIZE + "]"); |
aoqi@0 | 306 | } |
aoqi@0 | 307 | for (int i = 0; i < size; i++) { |
aoqi@0 | 308 | b[i] = (byte)-1; |
aoqi@0 | 309 | } |
aoqi@0 | 310 | |
aoqi@0 | 311 | System.out.println("Testing ISO_8859_1$Encode.encode() performance"); |
aoqi@0 | 312 | result = 0; |
aoqi@0 | 313 | start = System.currentTimeMillis(); |
aoqi@0 | 314 | for (int i = 0; i < itrs; i++) { |
aoqi@0 | 315 | result += arrenc.encode(a, 0, size, b); |
aoqi@0 | 316 | } |
aoqi@0 | 317 | end = System.currentTimeMillis(); |
aoqi@0 | 318 | if (!Arrays.equals(b, bt)) { |
aoqi@0 | 319 | failed = true; |
aoqi@0 | 320 | System.out.println("Failed 2: ArrayEncoder.encode char[" + size + "]"); |
aoqi@0 | 321 | } else { |
aoqi@0 | 322 | System.out.println("size: " + size + " time: " + (end - start)); |
aoqi@0 | 323 | } |
aoqi@0 | 324 | |
aoqi@0 | 325 | if (failed) { |
aoqi@0 | 326 | System.out.println("FAILED"); |
aoqi@0 | 327 | System.exit(97); |
aoqi@0 | 328 | } |
aoqi@0 | 329 | System.out.println("PASSED"); |
aoqi@0 | 330 | } |
aoqi@0 | 331 | } |