Path: blob/master/test/hotspot/jtreg/compiler/codegen/Test6896617.java
41149 views
/*1* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @key randomness26* @bug 689661727* @summary Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() with SSE instructions on x8628* @library /test/lib29* @modules java.base/jdk.internal.misc30* java.base/sun.nio.cs31* java.management32*33* @ignore 819347934* @run main/othervm/timeout=1200 -Xbatch -Xmx256m compiler.codegen.Test689661735*/3637package compiler.codegen;3839import jdk.test.lib.Utils;4041import java.nio.ByteBuffer;42import java.nio.CharBuffer;43import java.nio.charset.Charset;44import java.nio.charset.CharsetDecoder;45import java.nio.charset.CharsetEncoder;46import java.nio.charset.CodingErrorAction;47import java.util.Arrays;48import java.util.Random;4950public class Test6896617 {51final static int SIZE = 256;5253public static void main(String[] args) {54String csn = "ISO-8859-1";55Charset cs = Charset.forName(csn);56CharsetEncoder enc = cs.newEncoder();57enc.onMalformedInput(CodingErrorAction.REPLACE)58.onUnmappableCharacter(CodingErrorAction.REPLACE);59CharsetDecoder dec = cs.newDecoder();60dec.onMalformedInput(CodingErrorAction.REPLACE)61.onUnmappableCharacter(CodingErrorAction.REPLACE);6263byte repl = (byte)'?';64enc.replaceWith(new byte[] { repl });6566// Use internal API for tests.67sun.nio.cs.ArrayEncoder arrenc = (sun.nio.cs.ArrayEncoder)enc;68sun.nio.cs.ArrayDecoder arrdec = (sun.nio.cs.ArrayDecoder)dec;6970// Populate char[] with chars which can be encoded by ISO_8859_1 (<= 0xFF)71Random rnd = Utils.getRandomInstance();72int maxchar = 0xFF;73char[] a = new char[SIZE];74byte[] b = new byte[SIZE];75char[] at = new char[SIZE];76byte[] bt = new byte[SIZE];77for (int i = 0; i < SIZE; i++) {78char c = (char) rnd.nextInt(maxchar);79if (!enc.canEncode(c)) {80System.out.printf("Something wrong: can't encode c=%03x\n", (int)c);81System.exit(97);82}83a[i] = c;84b[i] = (byte)c;85at[i] = (char)-1;86bt[i] = (byte)-1;87}88if (arrenc.encode(a, 0, SIZE, bt) != SIZE || !Arrays.equals(b, bt)) {89System.out.println("Something wrong: ArrayEncoder.encode failed");90System.exit(97);91}92if (arrdec.decode(b, 0, SIZE, at) != SIZE || !Arrays.equals(a, at)) {93System.out.println("Something wrong: ArrayDecoder.decode failed");94System.exit(97);95}96for (int i = 0; i < SIZE; i++) {97at[i] = (char)-1;98bt[i] = (byte)-1;99}100101ByteBuffer bb = ByteBuffer.wrap(b);102CharBuffer ba = CharBuffer.wrap(a);103ByteBuffer bbt = ByteBuffer.wrap(bt);104CharBuffer bat = CharBuffer.wrap(at);105if (!enc.encode(ba, bbt, true).isUnderflow() || !Arrays.equals(b, bt)) {106System.out.println("Something wrong: Encoder.encode failed");107System.exit(97);108}109if (!dec.decode(bb, bat, true).isUnderflow() || !Arrays.equals(a, at)) {110System.out.println("Something wrong: Decoder.decode failed");111System.exit(97);112}113for (int i = 0; i < SIZE; i++) {114at[i] = (char)-1;115bt[i] = (byte)-1;116}117118// Warm up119boolean failed = false;120int result = 0;121for (int i = 0; i < 10000; i++) {122result += arrenc.encode(a, 0, SIZE, bt);123result -= arrdec.decode(b, 0, SIZE, at);124}125for (int i = 0; i < 10000; i++) {126result += arrenc.encode(a, 0, SIZE, bt);127result -= arrdec.decode(b, 0, SIZE, at);128}129for (int i = 0; i < 10000; i++) {130result += arrenc.encode(a, 0, SIZE, bt);131result -= arrdec.decode(b, 0, SIZE, at);132}133if (result != 0 || !Arrays.equals(b, bt) || !Arrays.equals(a, at)) {134failed = true;135System.out.println("Failed: ArrayEncoder.encode char[" + SIZE + "] and ArrayDecoder.decode byte[" + SIZE + "]");136}137for (int i = 0; i < SIZE; i++) {138at[i] = (char)-1;139bt[i] = (byte)-1;140}141142boolean is_underflow = true;143for (int i = 0; i < 10000; i++) {144ba.clear(); bb.clear(); bat.clear(); bbt.clear();145boolean enc_res = enc.encode(ba, bbt, true).isUnderflow();146boolean dec_res = dec.decode(bb, bat, true).isUnderflow();147is_underflow = is_underflow && enc_res && dec_res;148}149for (int i = 0; i < SIZE; i++) {150at[i] = (char)-1;151bt[i] = (byte)-1;152}153for (int i = 0; i < 10000; i++) {154ba.clear(); bb.clear(); bat.clear(); bbt.clear();155boolean enc_res = enc.encode(ba, bbt, true).isUnderflow();156boolean dec_res = dec.decode(bb, bat, true).isUnderflow();157is_underflow = is_underflow && enc_res && dec_res;158}159for (int i = 0; i < SIZE; i++) {160at[i] = (char)-1;161bt[i] = (byte)-1;162}163for (int i = 0; i < 10000; i++) {164ba.clear(); bb.clear(); bat.clear(); bbt.clear();165boolean enc_res = enc.encode(ba, bbt, true).isUnderflow();166boolean dec_res = dec.decode(bb, bat, true).isUnderflow();167is_underflow = is_underflow && enc_res && dec_res;168}169if (!is_underflow || !Arrays.equals(b, bt) || !Arrays.equals(a, at)) {170failed = true;171System.out.println("Failed: Encoder.encode char[" + SIZE + "] and Decoder.decode byte[" + SIZE + "]");172}173174// Test encoder with different source and destination sizes175System.out.println("Testing different source and destination sizes");176for (int i = 1; i <= SIZE; i++) {177for (int j = 1; j <= SIZE; j++) {178bt = new byte[j];179// very source's SIZE180result = arrenc.encode(a, 0, i, bt);181int l = Math.min(i, j);182if (result != l) {183failed = true;184System.out.println("Failed: encode char[" + i + "] to byte[" + j + "]: result = " + result + ", expected " + l);185}186for (int k = 0; k < l; k++) {187if (bt[k] != b[k]) {188failed = true;189System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[k]);190}191}192// very source's offset193int sz = SIZE - i + 1;194result = arrenc.encode(a, i-1, sz, bt);195l = Math.min(sz, j);196if (result != l) {197failed = true;198System.out.println("Failed: encode char[" + sz + "] to byte[" + j + "]: result = " + result + ", expected " + l);199}200for (int k = 0; k < l; k++) {201if (bt[k] != b[i+k-1]) {202failed = true;203System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[i+k-1]);204}205}206}207}208209// Test encoder with char > 0xFF210System.out.println("Testing big char");211212byte orig = (byte)'A';213bt = new byte[SIZE];214for (int i = 1; i <= SIZE; i++) {215for (int j = 0; j < i; j++) {216a[j] += 0x100;217// make sure to replace a different byte218bt[j] = orig;219result = arrenc.encode(a, 0, i, bt);220if (result != i) {221failed = true;222System.out.println("Failed: encode char[" + i + "] to byte[" + i + "]: result = " + result + ", expected " + i);223}224if (bt[j] != repl) {225failed = true;226System.out.println("Failed: encoded replace byte[" + j + "] (" + bt[j] + ") != " + repl);227}228bt[j] = b[j]; // Restore to compare whole array229for (int k = 0; k < i; k++) {230if (bt[k] != b[k]) {231failed = true;232System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[k]);233}234}235a[j] -= 0x100; // Restore236}237}238239// Test sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() performance.240241int itrs = Integer.getInteger("iterations", 1000000);242int size = Integer.getInteger("size", 256);243a = new char[size];244b = new byte[size];245bt = new byte[size];246for (int i = 0; i < size; i++) {247char c = (char) rnd.nextInt(maxchar);248if (!enc.canEncode(c)) {249System.out.printf("Something wrong: can't encode c=%03x\n", (int)c);250System.exit(97);251}252a[i] = c;253b[i] = (byte)-1;254bt[i] = (byte)c;255}256ba = CharBuffer.wrap(a);257bb = ByteBuffer.wrap(b);258boolean enc_res = enc.encode(ba, bb, true).isUnderflow();259if (!enc_res || !Arrays.equals(b, bt)) {260failed = true;261System.out.println("Failed 1: Encoder.encode char[" + size + "]");262}263for (int i = 0; i < size; i++) {264b[i] = (byte)-1;265}266267// Make sure to recompile method if needed before performance run.268for (int i = 0; i < 10000; i++) {269ba.clear(); bb.clear();270enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow();271}272for (int i = 0; i < size; i++) {273b[i] = (byte)-1;274}275for (int i = 0; i < 10000; i++) {276ba.clear(); bb.clear();277enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow();278}279if (!enc_res || !Arrays.equals(b, bt)) {280failed = true;281System.out.println("Failed 2: Encoder.encode char[" + size + "]");282}283for (int i = 0; i < size; i++) {284b[i] = (byte)-1;285}286287System.out.println("Testing ISO_8859_1$Encode.encodeArrayLoop() performance");288long start = System.currentTimeMillis();289for (int i = 0; i < itrs; i++) {290ba.clear(); bb.clear();291enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow();292}293long end = System.currentTimeMillis();294if (!enc_res || !Arrays.equals(b, bt)) {295failed = true;296System.out.println("Failed 3: Encoder.encode char[" + size + "]");297} else {298System.out.println("size: " + size + " time: " + (end - start));299}300301// Test sun.nio.cs.ISO_8859_1$Encode.encode() performance.302303// Make sure to recompile method if needed before performance run.304result = 0;305for (int i = 0; i < size; i++) {306b[i] = (byte)-1;307}308for (int i = 0; i < 10000; i++) {309result += arrenc.encode(a, 0, size, b);310}311for (int i = 0; i < size; i++) {312b[i] = (byte)-1;313}314for (int i = 0; i < 10000; i++) {315result += arrenc.encode(a, 0, size, b);316}317if (result != size*20000 || !Arrays.equals(b, bt)) {318failed = true;319System.out.println("Failed 1: ArrayEncoder.encode char[" + SIZE + "]");320}321for (int i = 0; i < size; i++) {322b[i] = (byte)-1;323}324325System.out.println("Testing ISO_8859_1$Encode.encode() performance");326result = 0;327start = System.currentTimeMillis();328for (int i = 0; i < itrs; i++) {329result += arrenc.encode(a, 0, size, b);330}331end = System.currentTimeMillis();332if (!Arrays.equals(b, bt)) {333failed = true;334System.out.println("Failed 2: ArrayEncoder.encode char[" + size + "]");335} else {336System.out.println("size: " + size + " time: " + (end - start));337}338339if (failed) {340System.out.println("FAILED");341System.exit(97);342}343System.out.println("PASSED");344}345}346347348