diff options
Diffstat (limited to 'test')
40 files changed, 2805 insertions, 131 deletions
diff --git a/test/115-native-bridge/nativebridge.cc b/test/115-native-bridge/nativebridge.cc index e9946c885c..b70ca4ff3e 100644 --- a/test/115-native-bridge/nativebridge.cc +++ b/test/115-native-bridge/nativebridge.cc @@ -267,11 +267,20 @@ extern "C" bool native_bridge_initialize(const android::NativeBridgeRuntimeCallb const char* app_code_cache_dir, const char* isa ATTRIBUTE_UNUSED) { struct stat st; - if ((app_code_cache_dir != nullptr) - && (stat(app_code_cache_dir, &st) == 0) - && S_ISDIR(st.st_mode)) { - printf("Code cache exists: '%s'.\n", app_code_cache_dir); + if (app_code_cache_dir != nullptr) { + if (stat(app_code_cache_dir, &st) == 0) { + if (S_ISDIR(st.st_mode)) { + printf("Code cache exists: '%s'.\n", app_code_cache_dir); + } else { + printf("Code cache is not a directory.\n"); + } + } else { + perror("Error when stat-ing the code_cache:"); + } + } else { + printf("app_code_cache_dir is null.\n"); } + if (art_cbs != nullptr) { gNativeBridgeArtCallbacks = art_cbs; printf("Native bridge initialized.\n"); diff --git a/test/123-inline-execute2/expected.txt b/test/123-inline-execute2/expected.txt new file mode 100644 index 0000000000..aa74fa3757 --- /dev/null +++ b/test/123-inline-execute2/expected.txt @@ -0,0 +1,299 @@ +Math.sin(0.0) = 0.000000000000 +Math.sinh(0.0) = 0.000000000000 +Math.asin(0.0) = 0.000000000000 +Math.cos(0.0) = 1.000000000000 +Math.cosh(0.0) = 1.000000000000 +Math.acos(0.0) = 1.570796326795 +Math.tan(0.0) = 0.000000000000 +Math.tanh(0.0) = 0.000000000000 +Math.atan(0.0) = 0.000000000000 +Math.atan2(0.0, 1.0) = 0.000000000000 +Math.sin(0.7853981633974483) = 0.707106781187 +Math.sinh(0.7853981633974483) = 0.868670961486 +Math.asin(0.7853981633974483) = 0.903339110767 +Math.cos(0.7853981633974483) = 0.707106781187 +Math.cosh(0.7853981633974483) = 1.324609089252 +Math.acos(0.7853981633974483) = 0.667457216028 +Math.tan(0.7853981633974483) = 1.000000000000 +Math.tanh(0.7853981633974483) = 0.655794202633 +Math.atan(0.7853981633974483) = 0.665773750028 +Math.atan2(0.7853981633974483, 1.7853981633974483) = 0.414423800577 +Math.sin(1.5707963267948966) = 1.000000000000 +Math.sinh(1.5707963267948966) = 2.301298902307 +Math.asin(1.5707963267948966) = NaN +Math.cos(1.5707963267948966) = 0.000000000000 +Math.cosh(1.5707963267948966) = 2.509178478658 +Math.acos(1.5707963267948966) = NaN +Math.tanh(1.5707963267948966) = 0.917152335667 +Math.atan(1.5707963267948966) = 1.003884821854 +Math.atan2(1.5707963267948966, 2.5707963267948966) = 0.548479764417 +Math.sin(2.356194490192345) = 0.707106781187 +Math.sinh(2.356194490192345) = 5.227971924678 +Math.asin(2.356194490192345) = NaN +Math.cos(2.356194490192345) = -0.707106781187 +Math.cosh(2.356194490192345) = 5.322752149520 +Math.acos(2.356194490192345) = NaN +Math.tan(2.356194490192345) = -1.000000000000 +Math.tanh(2.356194490192345) = 0.982193380007 +Math.atan(2.356194490192345) = 1.169422824816 +Math.atan2(2.356194490192345, 3.356194490192345) = 0.612096117380 +Math.sin(3.141592653589793) = 0.000000000000 +Math.sinh(3.141592653589793) = 11.548739357258 +Math.asin(3.141592653589793) = NaN +Math.cos(3.141592653589793) = -1.000000000000 +Math.cosh(3.141592653589793) = 11.591953275522 +Math.acos(3.141592653589793) = NaN +Math.tan(3.141592653589793) = -0.000000000000 +Math.tanh(3.141592653589793) = 0.996272076221 +Math.atan(3.141592653589793) = 1.262627255679 +Math.atan2(3.141592653589793, 4.141592653589793) = 0.648948780815 +Math.sin(3.9269908169872414) = -0.707106781187 +Math.sinh(3.9269908169872414) = 25.367158319374 +Math.asin(3.9269908169872414) = NaN +Math.cos(3.9269908169872414) = -0.707106781187 +Math.cosh(3.9269908169872414) = 25.386861192361 +Math.acos(3.9269908169872414) = NaN +Math.tan(3.9269908169872414) = 1.000000000000 +Math.tanh(3.9269908169872414) = 0.999223894879 +Math.atan(3.9269908169872414) = 1.321447967784 +Math.atan2(3.9269908169872414, 4.926990816987241) = 0.672931229191 +Math.sin(4.71238898038469) = -1.000000000000 +Math.sinh(4.71238898038469) = 55.654397599418 +Math.asin(4.71238898038469) = NaN +Math.cos(4.71238898038469) = -0.000000000000 +Math.cosh(4.71238898038469) = 55.663380890439 +Math.acos(4.71238898038469) = NaN +Math.tanh(4.71238898038469) = 0.999838613989 +Math.atan(4.71238898038469) = 1.361691682971 +Math.atan2(4.71238898038469, 5.71238898038469) = 0.689765469251 +Math.sin(5.497787143782138) = -0.707106781187 +Math.sinh(5.497787143782138) = 122.073483514693 +Math.asin(5.497787143782138) = NaN +Math.cos(5.497787143782138) = 0.707106781187 +Math.cosh(5.497787143782138) = 122.077579339582 +Math.acos(5.497787143782138) = NaN +Math.tan(5.497787143782138) = -1.000000000000 +Math.tanh(5.497787143782138) = 0.999966449000 +Math.atan(5.497787143782138) = 1.390871988014 +Math.atan2(5.497787143782138, 6.497787143782138) = 0.702226398171 +Math.sin(6.283185307179586) = -0.000000000000 +Math.sinh(6.283185307179586) = 267.744894041016 +Math.asin(6.283185307179586) = NaN +Math.cos(6.283185307179586) = 1.000000000000 +Math.cosh(6.283185307179586) = 267.746761483748 +Math.acos(6.283185307179586) = NaN +Math.tan(6.283185307179586) = -0.000000000000 +Math.tanh(6.283185307179586) = 0.999993025340 +Math.atan(6.283185307179586) = 1.412965136507 +Math.atan2(6.283185307179586, 7.283185307179586) = 0.711819549590 +Math.cbrt(-3.0) = -1.442249570307 +Math.log(-3.0) = NaN +Math.log10(-3.0) = NaN +Math.log1p(-3.0) = NaN +Math.exp(-3.0) = 0.049787068368 +Math.expm1(-3.0) = -0.950212931632 +Math.pow(-3.0, -2.0) = 0.111111111111 +Math.hypot(-3.0, -2.0) = 3.605551275464 +Math.cbrt(-2.0) = -1.259921049895 +Math.log(-2.0) = NaN +Math.log10(-2.0) = NaN +Math.log1p(-2.0) = NaN +Math.exp(-2.0) = 0.135335283237 +Math.expm1(-2.0) = -0.864664716763 +Math.pow(-2.0, -1.0) = -0.500000000000 +Math.hypot(-2.0, -1.0) = 2.236067977500 +Math.cbrt(-1.0) = -1.000000000000 +Math.log(-1.0) = NaN +Math.log10(-1.0) = NaN +Math.log1p(-1.0) = -Infinity +Math.exp(-1.0) = 0.367879441171 +Math.expm1(-1.0) = -0.632120558829 +Math.pow(-1.0, 0.0) = 1.000000000000 +Math.hypot(-1.0, 0.0) = 1.000000000000 +Math.cbrt(0.0) = 0.000000000000 +Math.log(0.0) = -Infinity +Math.log10(0.0) = -Infinity +Math.log1p(0.0) = 0.000000000000 +Math.exp(0.0) = 1.000000000000 +Math.expm1(0.0) = 0.000000000000 +Math.pow(0.0, 1.0) = 0.000000000000 +Math.hypot(0.0, 1.0) = 1.000000000000 +Math.cbrt(1.0) = 1.000000000000 +Math.log(1.0) = 0.000000000000 +Math.log10(1.0) = 0.000000000000 +Math.log1p(1.0) = 0.693147180560 +Math.exp(1.0) = 2.718281828459 +Math.expm1(1.0) = 1.718281828459 +Math.pow(1.0, 2.0) = 1.000000000000 +Math.hypot(1.0, 2.0) = 2.236067977500 +Math.cbrt(2.0) = 1.259921049895 +Math.log(2.0) = 0.693147180560 +Math.log10(2.0) = 0.301029995664 +Math.log1p(2.0) = 1.098612288668 +Math.exp(2.0) = 7.389056098931 +Math.expm1(2.0) = 6.389056098931 +Math.pow(2.0, 3.0) = 8.000000000000 +Math.hypot(2.0, 3.0) = 3.605551275464 +Math.cbrt(3.0) = 1.442249570307 +Math.log(3.0) = 1.098612288668 +Math.log10(3.0) = 0.477121254720 +Math.log1p(3.0) = 1.386294361120 +Math.exp(3.0) = 20.085536923188 +Math.expm1(3.0) = 19.085536923188 +Math.pow(3.0, 4.0) = 81.000000000000 +Math.hypot(3.0, 4.0) = 5.000000000000 +Math.ceil(0.0001) = 1.000000000000 +Math.floor(0.0001) = 0.000000000000 +Math.nextAfter(1.0, 2.0) = 1.000000000000 +Math.nextAfter(2.0, 1.0) = 2.000000000000 +Math.rint(0.5000001) = 1.000000000000 +StrictMath.sin(0.0) = 0.0 +StrictMath.sinh(0.0) = 0.0 +StrictMath.asin(0.0) = 0.0 +StrictMath.cos(0.0) = 1.0 +StrictMath.cosh(0.0) = 1.0 +StrictMath.acos(0.0) = 1.5707963267948966 +StrictMath.tan(0.0) = 0.0 +StrictMath.tanh(0.0) = 0.0 +StrictMath.atan(0.0) = 0.0 +StrictMath.atan2(0.0, 1.0) = 0.0 +StrictMath.sin(0.7853981633974483) = 0.7071067811865475 +StrictMath.sinh(0.7853981633974483) = 0.8686709614860095 +StrictMath.asin(0.7853981633974483) = 0.9033391107665127 +StrictMath.cos(0.7853981633974483) = 0.7071067811865476 +StrictMath.cosh(0.7853981633974483) = 1.3246090892520057 +StrictMath.acos(0.7853981633974483) = 0.6674572160283838 +StrictMath.tan(0.7853981633974483) = 0.9999999999999999 +StrictMath.tanh(0.7853981633974483) = 0.6557942026326724 +StrictMath.atan(0.7853981633974483) = 0.6657737500283538 +StrictMath.atan2(0.7853981633974483, 1.7853981633974483) = 0.41442380057704103 +StrictMath.sin(1.5707963267948966) = 1.0 +StrictMath.sinh(1.5707963267948966) = 2.3012989023072947 +StrictMath.asin(1.5707963267948966) = NaN +StrictMath.cos(1.5707963267948966) = 6.123233995736766E-17 +StrictMath.cosh(1.5707963267948966) = 2.5091784786580567 +StrictMath.acos(1.5707963267948966) = NaN +StrictMath.tan(1.5707963267948966) = 1.633123935319537E16 +StrictMath.tanh(1.5707963267948966) = 0.9171523356672744 +StrictMath.atan(1.5707963267948966) = 1.0038848218538872 +StrictMath.atan2(1.5707963267948966, 2.5707963267948966) = 0.5484797644174059 +StrictMath.sin(2.356194490192345) = 0.7071067811865476 +StrictMath.sinh(2.356194490192345) = 5.227971924677803 +StrictMath.asin(2.356194490192345) = NaN +StrictMath.cos(2.356194490192345) = -0.7071067811865475 +StrictMath.cosh(2.356194490192345) = 5.322752149519959 +StrictMath.acos(2.356194490192345) = NaN +StrictMath.tan(2.356194490192345) = -1.0000000000000002 +StrictMath.tanh(2.356194490192345) = 0.9821933800072388 +StrictMath.atan(2.356194490192345) = 1.1694228248157563 +StrictMath.atan2(2.356194490192345, 3.356194490192345) = 0.6120961173796371 +StrictMath.sin(3.141592653589793) = 1.2246467991473532E-16 +StrictMath.sinh(3.141592653589793) = 11.548739357257748 +StrictMath.asin(3.141592653589793) = NaN +StrictMath.cos(3.141592653589793) = -1.0 +StrictMath.cosh(3.141592653589793) = 11.591953275521519 +StrictMath.acos(3.141592653589793) = NaN +StrictMath.tan(3.141592653589793) = -1.2246467991473532E-16 +StrictMath.tanh(3.141592653589793) = 0.99627207622075 +StrictMath.atan(3.141592653589793) = 1.2626272556789115 +StrictMath.atan2(3.141592653589793, 4.141592653589793) = 0.6489487808147751 +StrictMath.sin(3.9269908169872414) = -0.7071067811865475 +StrictMath.sinh(3.9269908169872414) = 25.367158319374152 +StrictMath.asin(3.9269908169872414) = NaN +StrictMath.cos(3.9269908169872414) = -0.7071067811865477 +StrictMath.cosh(3.9269908169872414) = 25.386861192360772 +StrictMath.acos(3.9269908169872414) = NaN +StrictMath.tan(3.9269908169872414) = 0.9999999999999997 +StrictMath.tanh(3.9269908169872414) = 0.9992238948786412 +StrictMath.atan(3.9269908169872414) = 1.3214479677837223 +StrictMath.atan2(3.9269908169872414, 4.926990816987241) = 0.6729312291908799 +StrictMath.sin(4.71238898038469) = -1.0 +StrictMath.sinh(4.71238898038469) = 55.65439759941754 +StrictMath.asin(4.71238898038469) = NaN +StrictMath.cos(4.71238898038469) = -1.8369701987210297E-16 +StrictMath.cosh(4.71238898038469) = 55.66338089043867 +StrictMath.acos(4.71238898038469) = NaN +StrictMath.tan(4.71238898038469) = 5.443746451065123E15 +StrictMath.tanh(4.71238898038469) = 0.9998386139886326 +StrictMath.atan(4.71238898038469) = 1.3616916829711636 +StrictMath.atan2(4.71238898038469, 5.71238898038469) = 0.6897654692509959 +StrictMath.sin(5.497787143782138) = -0.7071067811865477 +StrictMath.sinh(5.497787143782138) = 122.07348351469281 +StrictMath.asin(5.497787143782138) = NaN +StrictMath.cos(5.497787143782138) = 0.7071067811865474 +StrictMath.cosh(5.497787143782138) = 122.07757933958217 +StrictMath.acos(5.497787143782138) = NaN +StrictMath.tan(5.497787143782138) = -1.0000000000000004 +StrictMath.tanh(5.497787143782138) = 0.9999664489997958 +StrictMath.atan(5.497787143782138) = 1.390871988014422 +StrictMath.atan2(5.497787143782138, 6.497787143782138) = 0.7022263981709682 +StrictMath.sin(6.283185307179586) = -2.4492935982947064E-16 +StrictMath.sinh(6.283185307179586) = 267.74489404101644 +StrictMath.asin(6.283185307179586) = NaN +StrictMath.cos(6.283185307179586) = 1.0 +StrictMath.cosh(6.283185307179586) = 267.7467614837482 +StrictMath.acos(6.283185307179586) = NaN +StrictMath.tan(6.283185307179586) = -2.4492935982947064E-16 +StrictMath.tanh(6.283185307179586) = 0.9999930253396107 +StrictMath.atan(6.283185307179586) = 1.4129651365067377 +StrictMath.atan2(6.283185307179586, 7.283185307179586) = 0.7118195495895945 +StrictMath.cbrt(-3.0) = -1.4422495703074083 +StrictMath.log(-3.0) = NaN +StrictMath.log10(-3.0) = NaN +StrictMath.log1p(-3.0) = NaN +StrictMath.exp(-3.0) = 0.049787068367863944 +StrictMath.expm1(-3.0) = -0.950212931632136 +StrictMath.pow(-3.0, -2.0) = 0.1111111111111111 +StrictMath.hypot(-3.0, -2.0) = 3.605551275463989 +StrictMath.cbrt(-2.0) = -1.2599210498948732 +StrictMath.log(-2.0) = NaN +StrictMath.log10(-2.0) = NaN +StrictMath.log1p(-2.0) = NaN +StrictMath.exp(-2.0) = 0.1353352832366127 +StrictMath.expm1(-2.0) = -0.8646647167633873 +StrictMath.pow(-2.0, -1.0) = -0.5 +StrictMath.hypot(-2.0, -1.0) = 2.23606797749979 +StrictMath.cbrt(-1.0) = -1.0 +StrictMath.log(-1.0) = NaN +StrictMath.log10(-1.0) = NaN +StrictMath.log1p(-1.0) = -Infinity +StrictMath.exp(-1.0) = 0.36787944117144233 +StrictMath.expm1(-1.0) = -0.6321205588285577 +StrictMath.pow(-1.0, 0.0) = 1.0 +StrictMath.hypot(-1.0, 0.0) = 1.0 +StrictMath.cbrt(0.0) = 0.0 +StrictMath.log(0.0) = -Infinity +StrictMath.log10(0.0) = -Infinity +StrictMath.log1p(0.0) = 0.0 +StrictMath.exp(0.0) = 1.0 +StrictMath.expm1(0.0) = 0.0 +StrictMath.pow(0.0, 1.0) = 0.0 +StrictMath.hypot(0.0, 1.0) = 1.0 +StrictMath.cbrt(1.0) = 1.0 +StrictMath.log(1.0) = 0.0 +StrictMath.log10(1.0) = 0.0 +StrictMath.log1p(1.0) = 0.6931471805599453 +StrictMath.exp(1.0) = 2.7182818284590455 +StrictMath.expm1(1.0) = 1.718281828459045 +StrictMath.pow(1.0, 2.0) = 1.0 +StrictMath.hypot(1.0, 2.0) = 2.23606797749979 +StrictMath.cbrt(2.0) = 1.2599210498948732 +StrictMath.log(2.0) = 0.6931471805599453 +StrictMath.log10(2.0) = 0.3010299956639812 +StrictMath.log1p(2.0) = 1.0986122886681096 +StrictMath.exp(2.0) = 7.38905609893065 +StrictMath.expm1(2.0) = 6.38905609893065 +StrictMath.pow(2.0, 3.0) = 8.0 +StrictMath.hypot(2.0, 3.0) = 3.605551275463989 +StrictMath.cbrt(3.0) = 1.4422495703074083 +StrictMath.log(3.0) = 1.0986122886681096 +StrictMath.log10(3.0) = 0.47712125471966244 +StrictMath.log1p(3.0) = 1.3862943611198906 +StrictMath.exp(3.0) = 20.085536923187668 +StrictMath.expm1(3.0) = 19.085536923187668 +StrictMath.pow(3.0, 4.0) = 81.0 +StrictMath.hypot(3.0, 4.0) = 5.0 +StrictMath.ceil(0.0001) = 1.0 +StrictMath.floor(0.0001) = 0.0 +StrictMath.nextAfter(1.0, 2.0) = 1.0000000000000002 +StrictMath.rint(0.5000001) = 1.0 diff --git a/test/123-inline-execute2/info.txt b/test/123-inline-execute2/info.txt new file mode 100644 index 0000000000..4a728a7f03 --- /dev/null +++ b/test/123-inline-execute2/info.txt @@ -0,0 +1 @@ +Sanity checks for added InlineNative methods. diff --git a/test/123-inline-execute2/src/Main.java b/test/123-inline-execute2/src/Main.java new file mode 100644 index 0000000000..9fadcfdbb7 --- /dev/null +++ b/test/123-inline-execute2/src/Main.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.Locale; + +public class Main { + public static void main(String args[]) { + for (int i = 0; i <= 360; i += 45) { + double d = i * (Math.PI / 180.0); + System.out.println("Math.sin(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.sin(d))); + + System.out.println("Math.sinh(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.sinh(d))); + System.out.println("Math.asin(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.asin(d))); + System.out.println("Math.cos(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.cos(d))); + System.out.println("Math.cosh(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.cosh(d))); + System.out.println("Math.acos(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.acos(d))); + if ((i + 90) % 180 != 0) { + System.out.println("Math.tan(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.tan(d))); + } + System.out.println("Math.tanh(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.tanh(d))); + System.out.println("Math.atan(" + d + ") = " + + String.format(Locale.US, "%.12f", Math.atan(d))); + System.out.println("Math.atan2(" + d + ", " + (d + 1.0) + ") = " + + String.format(Locale.US, "%.12f", Math.atan2(d, d + 1.0))); + } + + for (int j = -3; j <= 3; j++) { + double e = (double) j; + System.out.println("Math.cbrt(" + e + ") = " + + String.format(Locale.US, "%.12f", Math.cbrt(e))); + System.out.println("Math.log(" + e + ") = " + + String.format(Locale.US, "%.12f", Math.log(e))); + System.out.println("Math.log10(" + e + ") = " + + String.format(Locale.US, "%.12f", Math.log10(e))); + System.out.println("Math.log1p(" + e + ") = " + + String.format(Locale.US, "%.12f", Math.log1p(e))); + System.out.println("Math.exp(" + e + ") = " + + String.format(Locale.US, "%.12f", Math.exp(e))); + System.out.println("Math.expm1(" + e + ") = " + + String.format(Locale.US, "%.12f", Math.expm1(e))); + System.out.println("Math.pow(" + e + ", " + (e + 1.0) + ") = " + + String.format(Locale.US, "%.12f", Math.pow(e, e + 1.0))); + System.out.println("Math.hypot(" + e + ", " + (e + 1.0) + ") = " + + String.format(Locale.US, "%.12f", Math.hypot(e, e + 1.0))); + } + + System.out.println("Math.ceil(0.0001) = " + + String.format(Locale.US, "%.12f", Math.ceil(0.0001))); + System.out.println("Math.floor(0.0001) = " + + String.format(Locale.US, "%.12f", Math.floor(0.0001))); + System.out.println("Math.nextAfter(1.0, 2.0) = " + + String.format(Locale.US, "%.12f", Math.nextAfter(1.0, 2.0))); + System.out.println("Math.nextAfter(2.0, 1.0) = " + + String.format(Locale.US, "%.12f", Math.nextAfter(2.0, 1.0))); + System.out.println("Math.rint(0.5000001) = " + + String.format(Locale.US, "%.12f", Math.rint(0.5000001))); + + for (int i = 0; i <= 360; i += 45) { + double d = i * (StrictMath.PI / 180.0); + System.out.println("StrictMath.sin(" + d + ") = " + StrictMath.sin(d)); + System.out.println("StrictMath.sinh(" + d + ") = " + StrictMath.sinh(d)); + System.out.println("StrictMath.asin(" + d + ") = " + StrictMath.asin(d)); + System.out.println("StrictMath.cos(" + d + ") = " + StrictMath.cos(d)); + System.out.println("StrictMath.cosh(" + d + ") = " + StrictMath.cosh(d)); + System.out.println("StrictMath.acos(" + d + ") = " + StrictMath.acos(d)); + System.out.println("StrictMath.tan(" + d + ") = " + StrictMath.tan(d)); + System.out.println("StrictMath.tanh(" + d + ") = " + StrictMath.tanh(d)); + System.out.println("StrictMath.atan(" + d + ") = " + StrictMath.atan(d)); + System.out.println("StrictMath.atan2(" + d + ", " + (d + 1.0) + ") = " + + StrictMath.atan2(d, d + 1.0)); + } + + for (int j = -3; j <= 3; j++) { + double e = (double) j; + System.out.println("StrictMath.cbrt(" + e + ") = " + StrictMath.cbrt(e)); + System.out.println("StrictMath.log(" + e + ") = " + StrictMath.log(e)); + System.out.println("StrictMath.log10(" + e + ") = " + StrictMath.log10(e)); + System.out.println("StrictMath.log1p(" + e + ") = " + StrictMath.log1p(e)); + System.out.println("StrictMath.exp(" + e + ") = " + StrictMath.exp(e)); + System.out.println("StrictMath.expm1(" + e + ") = " + StrictMath.expm1(e)); + System.out.println("StrictMath.pow(" + e + ", " + (e + 1.0) + ") = " + + StrictMath.pow(e, e + 1.0)); + System.out.println("StrictMath.hypot(" + e + ", " + (e + 1.0) + ") = " + + StrictMath.hypot(e, e + 1.0)); + } + + System.out.println("StrictMath.ceil(0.0001) = " + StrictMath.ceil(0.0001)); + System.out.println("StrictMath.floor(0.0001) = " + StrictMath.floor(0.0001)); + System.out.println("StrictMath.nextAfter(1.0, 2.0) = " + StrictMath.nextAfter(1.0, 2.0)); + System.out.println("StrictMath.rint(0.5000001) = " + StrictMath.rint(0.5000001)); + } + +} diff --git a/test/444-checker-nce/src/Main.java b/test/444-checker-nce/src/Main.java index 32122e4dcd..865355ce97 100644 --- a/test/444-checker-nce/src/Main.java +++ b/test/444-checker-nce/src/Main.java @@ -16,11 +16,11 @@ public class Main { - /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier (before) /// CHECK: NullCheck /// CHECK: InvokeStaticOrDirect - /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier (after) /// CHECK: NullCheck /// CHECK: InvokeStaticOrDirect public Main keepTest(Main m) { @@ -31,7 +31,7 @@ public class Main { /// CHECK: NullCheck /// CHECK: InvokeStaticOrDirect - /// CHECK-START: Main Main.thisTest() instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.thisTest() instruction_simplifier (after) /// CHECK-NOT: NullCheck /// CHECK: InvokeStaticOrDirect public Main thisTest() { @@ -45,7 +45,7 @@ public class Main { /// CHECK: NullCheck /// CHECK: InvokeStaticOrDirect - /// CHECK-START: Main Main.newInstanceRemoveTest() instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.newInstanceRemoveTest() instruction_simplifier (after) /// CHECK-NOT: NullCheck public Main newInstanceRemoveTest() { Main m = new Main(); @@ -57,7 +57,7 @@ public class Main { /// CHECK: NullCheck /// CHECK: ArrayGet - /// CHECK-START: Main Main.newArrayRemoveTest() instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.newArrayRemoveTest() instruction_simplifier (after) /// CHECK: NewArray /// CHECK-NOT: NullCheck /// CHECK: ArrayGet @@ -66,11 +66,11 @@ public class Main { return ms[0]; } - /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier (before) /// CHECK: NewInstance /// CHECK: NullCheck - /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier (after) /// CHECK: NewInstance /// CHECK-NOT: NullCheck public Main ifRemoveTest(boolean flag) { @@ -83,11 +83,11 @@ public class Main { return m.g(); } - /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier (before) /// CHECK: NewInstance /// CHECK: NullCheck - /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier (after) /// CHECK: NewInstance /// CHECK: NullCheck public Main ifKeepTest(boolean flag) { @@ -98,10 +98,10 @@ public class Main { return m.g(); } - /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier (before) /// CHECK: NullCheck - /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier (after) /// CHECK-NOT: NullCheck public Main forRemoveTest(int count) { Main a = new Main(); @@ -114,10 +114,10 @@ public class Main { return m.g(); } - /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier (before) /// CHECK: NullCheck - /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier (after) /// CHECK: NullCheck public Main forKeepTest(int count) { Main a = new Main(); @@ -132,10 +132,10 @@ public class Main { return m.g(); } - /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier (before) /// CHECK: NullCheck - /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier (after) /// CHECK-NOT: NullCheck public Main phiFlowRemoveTest(int count) { Main a = new Main(); @@ -154,10 +154,10 @@ public class Main { return n.g(); } - /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier (before) /// CHECK: NullCheck - /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier (after) /// CHECK: NullCheck public Main phiFlowKeepTest(int count) { Main a = new Main(); @@ -181,7 +181,7 @@ public class Main { /// CHECK-START: Main Main.scopeRemoveTest(int, Main) ssa_builder (after) /// CHECK: NullCheck - /// CHECK-START: Main Main.scopeRemoveTest(int, Main) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.scopeRemoveTest(int, Main) instruction_simplifier (after) /// CHECK-NOT: NullCheck public Main scopeRemoveTest(int count, Main a) { Main m = null; @@ -196,10 +196,10 @@ public class Main { return m; } - /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier (before) /// CHECK: NullCheck - /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier (after) /// CHECK: NullCheck public Main scopeKeepTest(int count, Main a) { Main m = new Main(); @@ -214,10 +214,10 @@ public class Main { return m; } - /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier (before) /// CHECK: NullCheck - /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier (after) /// CHECK-NOT: NullCheck public Main scopeIfNotNullRemove(Main m) { if (m != null) { @@ -226,10 +226,10 @@ public class Main { return m; } - /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier_after_types (before) + /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier (before) /// CHECK: NullCheck - /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier_after_types (after) + /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier (after) /// CHECK: NullCheck public Main scopeIfKeep(Main m) { if (m == null) { @@ -258,11 +258,11 @@ public class Main { class ListElement { private ListElement next; - /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier_after_types (before) + /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier (before) /// CHECK: NullCheck /// CHECK: NullCheck - /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier_after_types (after) + /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier (after) /// CHECK-NOT: NullCheck static boolean isShorter(ListElement x, ListElement y) { ListElement xTail = x; diff --git a/test/450-checker-types/src/Main.java b/test/450-checker-types/src/Main.java index f1f80caff0..fd4dd5ecbf 100644 --- a/test/450-checker-types/src/Main.java +++ b/test/450-checker-types/src/Main.java @@ -72,49 +72,49 @@ final class FinalException extends Exception {} public class Main { - /// CHECK-START: void Main.testSimpleRemove() instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testSimpleRemove() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testSimpleRemove() instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testSimpleRemove() instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testSimpleRemove() { Super s = new SubclassA(); ((SubclassA)s).$noinline$g(); } - /// CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier (after) /// CHECK: CheckCast public void testSimpleKeep(Super s) { ((SubclassA)s).$noinline$f(); } - /// CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier_after_types (before) + /// CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier_after_types (after) + /// CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier (after) /// CHECK-NOT: CheckCast public String testClassRemove() { Object s = SubclassA.class; return ((Class)s).getName(); } - /// CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier_after_types (before) + /// CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier_after_types (after) + /// CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier (after) /// CHECK: CheckCast public String testClassKeep() { Object s = SubclassA.class; return ((SubclassA)s).$noinline$h(); } - /// CHECK-START: void Main.testIfRemove(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testIfRemove(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testIfRemove(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testIfRemove(int) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testIfRemove(int x) { Super s; @@ -126,10 +126,10 @@ public class Main { ((SubclassA)s).$noinline$g(); } - /// CHECK-START: void Main.testIfKeep(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testIfKeep(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testIfKeep(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testIfKeep(int) instruction_simplifier (after) /// CHECK: CheckCast public void testIfKeep(int x) { Super s; @@ -141,10 +141,10 @@ public class Main { ((SubclassA)s).$noinline$g(); } - /// CHECK-START: void Main.testForRemove(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testForRemove(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testForRemove(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testForRemove(int) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testForRemove(int x) { Super s = new SubclassA(); @@ -156,10 +156,10 @@ public class Main { ((SubclassA)s).$noinline$g(); } - /// CHECK-START: void Main.testForKeep(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testForKeep(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testForKeep(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testForKeep(int) instruction_simplifier (after) /// CHECK: CheckCast public void testForKeep(int x) { Super s = new SubclassA(); @@ -171,10 +171,10 @@ public class Main { ((SubclassC)s).$noinline$g(); } - /// CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier (after) /// CHECK: CheckCast public void testPhiFromCall(int i) { Object x; @@ -186,11 +186,12 @@ public class Main { ((SubclassC)x).$noinline$g(); } - /// CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier (before) /// CHECK: CheckCast /// CHECK: CheckCast + /// CHECK-NOT: CheckCast - /// CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOf(Object o) { if (o instanceof SubclassC) { @@ -201,11 +202,101 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier_after_types (before) + public static boolean $inline$InstanceofSubclassB(Object o) { return o instanceof SubclassB; } + public static boolean $inline$InstanceofSubclassC(Object o) { return o instanceof SubclassC; } + + /// CHECK-START: void Main.testInstanceOf_NotInlined(java.lang.Object) ssa_builder (after) + /// CHECK-DAG: <<Cst0:i\d+>> IntConstant 0 + /// CHECK-DAG: <<Cst1:i\d+>> IntConstant 1 + /// CHECK-DAG: <<IOf1:z\d+>> InstanceOf + /// CHECK-DAG: NotEqual [<<IOf1>>,<<Cst1>>] + /// CHECK-DAG: <<IOf2:z\d+>> InstanceOf + /// CHECK-DAG: Equal [<<IOf2>>,<<Cst0>>] + + /// CHECK-START: void Main.testInstanceOf_NotInlined(java.lang.Object) instruction_simplifier (before) + /// CHECK: CheckCast + /// CHECK: CheckCast + /// CHECK-NOT: CheckCast + + /// CHECK-START: void Main.testInstanceOf_NotInlined(java.lang.Object) instruction_simplifier (after) + /// CHECK-NOT: CheckCast + public void testInstanceOf_NotInlined(Object o) { + if ((o instanceof SubclassC) == true) { + ((SubclassC)o).$noinline$g(); + } + if ((o instanceof SubclassB) != false) { + ((SubclassB)o).$noinline$g(); + } + } + + /// CHECK-START: void Main.testNotInstanceOf_NotInlined(java.lang.Object) ssa_builder (after) + /// CHECK-DAG: <<Cst0:i\d+>> IntConstant 0 + /// CHECK-DAG: <<Cst1:i\d+>> IntConstant 1 + /// CHECK-DAG: <<IOf1:z\d+>> InstanceOf + /// CHECK-DAG: Equal [<<IOf1>>,<<Cst1>>] + /// CHECK-DAG: <<IOf2:z\d+>> InstanceOf + /// CHECK-DAG: NotEqual [<<IOf2>>,<<Cst0>>] + + /// CHECK-START: void Main.testNotInstanceOf_NotInlined(java.lang.Object) instruction_simplifier (before) + /// CHECK: CheckCast + /// CHECK: CheckCast + /// CHECK-NOT: CheckCast + + /// CHECK-START: void Main.testNotInstanceOf_NotInlined(java.lang.Object) instruction_simplifier (after) + /// CHECK-NOT: CheckCast + public void testNotInstanceOf_NotInlined(Object o) { + if ((o instanceof SubclassC) != true) { + // Empty branch to flip the condition. + } else { + ((SubclassC)o).$noinline$g(); + } + if ((o instanceof SubclassB) == false) { + // Empty branch to flip the condition. + } else { + ((SubclassB)o).$noinline$g(); + } + } + + /// CHECK-START: void Main.testInstanceOf_Inlined(java.lang.Object) inliner (after) + /// CHECK-DAG: <<IOf:z\d+>> InstanceOf + /// CHECK-DAG: If [<<IOf>>] + + /// CHECK-START: void Main.testInstanceOf_Inlined(java.lang.Object) instruction_simplifier_after_bce (before) + /// CHECK: CheckCast + /// CHECK-NOT: CheckCast + + /// CHECK-START: void Main.testInstanceOf_Inlined(java.lang.Object) instruction_simplifier_after_bce (after) + /// CHECK-NOT: CheckCast + public void testInstanceOf_Inlined(Object o) { + if (!$inline$InstanceofSubclassC(o)) { + // Empty branch to flip the condition. + } else { + ((SubclassC)o).$noinline$g(); + } + } + + /// CHECK-START: void Main.testNotInstanceOf_Inlined(java.lang.Object) inliner (after) + /// CHECK-DAG: <<IOf:z\d+>> InstanceOf + /// CHECK-DAG: <<Not:z\d+>> BooleanNot [<<IOf>>] + /// CHECK-DAG: If [<<Not>>] + + /// CHECK-START: void Main.testNotInstanceOf_Inlined(java.lang.Object) instruction_simplifier_after_bce (before) + /// CHECK: CheckCast + /// CHECK-NOT: CheckCast + + /// CHECK-START: void Main.testNotInstanceOf_Inlined(java.lang.Object) instruction_simplifier_after_bce (after) + /// CHECK-NOT: CheckCast + public void testNotInstanceOf_Inlined(Object o) { + if ($inline$InstanceofSubclassC(o)) { + ((SubclassC)o).$noinline$g(); + } + } + + /// CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier (before) /// CHECK: CheckCast /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier (after) /// CHECK: CheckCast /// CHECK: CheckCast public void testInstanceOfKeep(Object o) { @@ -217,11 +308,11 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier (before) /// CHECK: CheckCast /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOfNested(Object o) { if (o instanceof SubclassC) { @@ -233,10 +324,10 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOfWithPhi(int i) { Object o; @@ -251,10 +342,10 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOfInFor(int n) { Object o = new SubclassA(); @@ -268,10 +359,10 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOfSubclass() { Object o = new SubclassA(); @@ -280,10 +371,10 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOfWithPhiSubclass(int i) { Object o; @@ -298,10 +389,10 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOfWithPhiTop(int i) { Object o; @@ -316,10 +407,10 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOfSubclassInFor(int n) { Object o = new SubclassA(); @@ -333,10 +424,10 @@ public class Main { } } - /// CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceOfTopInFor(int n) { Object o = new SubclassA(); @@ -361,10 +452,10 @@ public class Main { public SubclassA a = new SubclassA(); public static SubclassA b = new SubclassA(); - /// CHECK-START: void Main.testInstanceFieldGetSimpleRemove() instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInstanceFieldGetSimpleRemove() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInstanceFieldGetSimpleRemove() instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInstanceFieldGetSimpleRemove() instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInstanceFieldGetSimpleRemove() { Main m = new Main(); @@ -372,10 +463,10 @@ public class Main { ((SubclassA)a).$noinline$g(); } - /// CHECK-START: void Main.testStaticFieldGetSimpleRemove() instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testStaticFieldGetSimpleRemove() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testStaticFieldGetSimpleRemove() instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testStaticFieldGetSimpleRemove() instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testStaticFieldGetSimpleRemove() { Super b = Main.b; @@ -384,36 +475,36 @@ public class Main { public SubclassA $noinline$getSubclass() { throw new RuntimeException(); } - /// CHECK-START: void Main.testArraySimpleRemove() instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testArraySimpleRemove() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testArraySimpleRemove() instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testArraySimpleRemove() instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testArraySimpleRemove() { Super[] b = new SubclassA[10]; SubclassA[] c = (SubclassA[])b; } - /// CHECK-START: void Main.testInvokeSimpleRemove() instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testInvokeSimpleRemove() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testInvokeSimpleRemove() instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testInvokeSimpleRemove() instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testInvokeSimpleRemove() { Super b = $noinline$getSubclass(); ((SubclassA)b).$noinline$g(); } - /// CHECK-START: void Main.testArrayGetSimpleRemove() instruction_simplifier_after_types (before) + /// CHECK-START: void Main.testArrayGetSimpleRemove() instruction_simplifier (before) /// CHECK: CheckCast - /// CHECK-START: void Main.testArrayGetSimpleRemove() instruction_simplifier_after_types (after) + /// CHECK-START: void Main.testArrayGetSimpleRemove() instruction_simplifier (after) /// CHECK-NOT: CheckCast public void testArrayGetSimpleRemove() { Super[] a = new SubclassA[10]; ((SubclassA)a[0]).$noinline$g(); } - /// CHECK-START: int Main.testLoadExceptionInCatchNonExact(int, int) reference_type_propagation (after) + /// CHECK-START: int Main.testLoadExceptionInCatchNonExact(int, int) ssa_builder (after) /// CHECK: LoadException klass:java.lang.ArithmeticException can_be_null:false exact:false public int testLoadExceptionInCatchNonExact(int x, int y) { try { @@ -423,7 +514,7 @@ public class Main { } } - /// CHECK-START: int Main.testLoadExceptionInCatchExact(int) reference_type_propagation (after) + /// CHECK-START: int Main.testLoadExceptionInCatchExact(int) ssa_builder (after) /// CHECK: LoadException klass:FinalException can_be_null:false exact:true public int testLoadExceptionInCatchExact(int x) { try { @@ -437,7 +528,7 @@ public class Main { } } - /// CHECK-START: int Main.testLoadExceptionInCatchAll(int, int) reference_type_propagation (after) + /// CHECK-START: int Main.testLoadExceptionInCatchAll(int, int) ssa_builder (after) /// CHECK: LoadException klass:java.lang.Throwable can_be_null:false exact:false public int testLoadExceptionInCatchAll(int x, int y) { try { @@ -458,7 +549,7 @@ public class Main { return genericFinal.get(); } - /// CHECK-START: SubclassC Main.inlineGenerics() reference_type_propagation (after) + /// CHECK-START: SubclassC Main.inlineGenerics() ssa_builder (after) /// CHECK: <<Invoke:l\d+>> InvokeStaticOrDirect klass:SubclassC exact:false /// CHECK-NEXT: Return [<<Invoke>>] @@ -470,7 +561,7 @@ public class Main { return c; } - /// CHECK-START: Final Main.inlineGenericsFinal() reference_type_propagation (after) + /// CHECK-START: Final Main.inlineGenericsFinal() ssa_builder (after) /// CHECK: <<Invoke:l\d+>> InvokeStaticOrDirect klass:Final exact:true /// CHECK-NEXT: Return [<<Invoke>>] @@ -512,7 +603,7 @@ public class Main { return new SubclassA(); } - /// CHECK-START: void Main.updateNodesInTheSameBlockAsPhi(boolean) reference_type_propagation (after) + /// CHECK-START: void Main.updateNodesInTheSameBlockAsPhi(boolean) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:Super /// CHECK: NullCheck [<<Phi>>] klass:Super @@ -534,7 +625,7 @@ public class Main { /// CHECK: CheckCast [<<Param>>,<<Clazz>>] /// CHECK: BoundType [<<Param>>] can_be_null:true - /// CHECK-START: java.lang.String Main.checkcastPreserveNullCheck(java.lang.Object) instruction_simplifier_after_types (after) + /// CHECK-START: java.lang.String Main.checkcastPreserveNullCheck(java.lang.Object) instruction_simplifier (after) /// CHECK: <<This:l\d+>> ParameterValue /// CHECK: <<Param:l\d+>> ParameterValue /// CHECK: <<Clazz:l\d+>> LoadClass @@ -546,7 +637,7 @@ public class Main { } - /// CHECK-START: void Main.argumentCheck(Super, double, SubclassA, Final) reference_type_propagation (after) + /// CHECK-START: void Main.argumentCheck(Super, double, SubclassA, Final) ssa_builder (after) /// CHECK: ParameterValue klass:Main can_be_null:false exact:false /// CHECK: ParameterValue klass:Super can_be_null:true exact:false /// CHECK: ParameterValue @@ -562,7 +653,7 @@ public class Main { private int mainField = 0; - /// CHECK-START: SuperInterface Main.getWiderType(boolean, Interface, OtherInterface) reference_type_propagation (after) + /// CHECK-START: SuperInterface Main.getWiderType(boolean, Interface, OtherInterface) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:java.lang.Object /// CHECK: Return [<<Phi>>] private SuperInterface getWiderType(boolean cond, Interface a, OtherInterface b) { @@ -618,7 +709,7 @@ public class Main { getSuper(); } - /// CHECK-START: void Main.testLoopPhiWithNullFirstInput(boolean) reference_type_propagation (after) + /// CHECK-START: void Main.testLoopPhiWithNullFirstInput(boolean) ssa_builder (after) /// CHECK-DAG: <<Null:l\d+>> NullConstant /// CHECK-DAG: <<Main:l\d+>> NewInstance klass:Main exact:true /// CHECK-DAG: <<LoopPhi:l\d+>> Phi [<<Null>>,<<LoopPhi>>,<<Main>>] klass:Main exact:true @@ -631,7 +722,7 @@ public class Main { } } - /// CHECK-START: void Main.testLoopPhisWithNullAndCrossUses(boolean) reference_type_propagation (after) + /// CHECK-START: void Main.testLoopPhisWithNullAndCrossUses(boolean) ssa_builder (after) /// CHECK-DAG: <<Null:l\d+>> NullConstant /// CHECK-DAG: <<PhiA:l\d+>> Phi [<<Null>>,<<PhiB:l\d+>>,<<PhiA>>] klass:java.lang.Object exact:false /// CHECK-DAG: <<PhiB>> Phi [<<Null>>,<<PhiB>>,<<PhiA>>] klass:java.lang.Object exact:false @@ -647,7 +738,7 @@ public class Main { } } - /// CHECK-START: java.lang.Object[] Main.testInstructionsWithUntypedParent() reference_type_propagation (after) + /// CHECK-START: java.lang.Object[] Main.testInstructionsWithUntypedParent() ssa_builder (after) /// CHECK-DAG: <<Null:l\d+>> NullConstant /// CHECK-DAG: <<LoopPhi:l\d+>> Phi [<<Null>>,<<Phi:l\d+>>] klass:java.lang.Object[] exact:true /// CHECK-DAG: <<Array:l\d+>> NewArray klass:java.lang.Object[] exact:true diff --git a/test/477-checker-bound-type/src/Main.java b/test/477-checker-bound-type/src/Main.java index c873702408..0f65e44678 100644 --- a/test/477-checker-bound-type/src/Main.java +++ b/test/477-checker-bound-type/src/Main.java @@ -17,7 +17,7 @@ public class Main { - /// CHECK-START: java.lang.Object Main.boundTypeForIf(java.lang.Object) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.boundTypeForIf(java.lang.Object) ssa_builder (after) /// CHECK: BoundType public static Object boundTypeForIf(Object a) { if (a != null) { @@ -27,7 +27,7 @@ public class Main { } } - /// CHECK-START: java.lang.Object Main.boundTypeForInstanceOf(java.lang.Object) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.boundTypeForInstanceOf(java.lang.Object) ssa_builder (after) /// CHECK: BoundType public static Object boundTypeForInstanceOf(Object a) { if (a instanceof Main) { @@ -37,7 +37,7 @@ public class Main { } } - /// CHECK-START: java.lang.Object Main.noBoundTypeForIf(java.lang.Object) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.noBoundTypeForIf(java.lang.Object) ssa_builder (after) /// CHECK-NOT: BoundType public static Object noBoundTypeForIf(Object a) { if (a == null) { @@ -47,7 +47,7 @@ public class Main { } } - /// CHECK-START: java.lang.Object Main.noBoundTypeForInstanceOf(java.lang.Object) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.noBoundTypeForInstanceOf(java.lang.Object) ssa_builder (after) /// CHECK-NOT: BoundType public static Object noBoundTypeForInstanceOf(Object a) { if (a instanceof Main) { diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java index 17e88ceb21..ced3e50d41 100644 --- a/test/530-checker-lse/src/Main.java +++ b/test/530-checker-lse/src/Main.java @@ -25,6 +25,9 @@ class Circle { } class TestClass { + static { + sTestClassObj = new TestClass(-1, -2); + } TestClass() { } TestClass(int i, int j) { @@ -37,6 +40,7 @@ class TestClass { TestClass next; String str; static int si; + static TestClass sTestClassObj; } class SubTestClass extends TestClass { @@ -115,10 +119,11 @@ public class Main { } /// CHECK-START: int Main.test3(TestClass) load_store_elimination (before) + /// CHECK: NewInstance + /// CHECK: StaticFieldGet + /// CHECK: NewInstance /// CHECK: InstanceFieldSet - /// CHECK: InstanceFieldGet /// CHECK: InstanceFieldSet - /// CHECK: NewInstance /// CHECK: InstanceFieldSet /// CHECK: InstanceFieldSet /// CHECK: InstanceFieldGet @@ -127,24 +132,31 @@ public class Main { /// CHECK: InstanceFieldGet /// CHECK-START: int Main.test3(TestClass) load_store_elimination (after) + /// CHECK: NewInstance + /// CHECK: StaticFieldGet + /// CHECK: NewInstance + /// CHECK: InstanceFieldSet + /// CHECK: InstanceFieldSet /// CHECK: InstanceFieldSet - /// CHECK: InstanceFieldGet /// CHECK: InstanceFieldSet - /// CHECK: NewInstance - /// CHECK-NOT: InstanceFieldSet /// CHECK-NOT: InstanceFieldGet + /// CHECK-NOT: StaticFieldGet - // A new allocation shouldn't alias with pre-existing values. + // A new allocation (even non-singleton) shouldn't alias with pre-existing values. static int test3(TestClass obj) { // Do an allocation here to avoid the HLoadClass and HClinitCheck // at the second allocation. new TestClass(); + TestClass obj1 = TestClass.sTestClassObj; + TestClass obj2 = new TestClass(); // Cannot alias with obj or obj1 which pre-exist. + obj.next = obj2; // Make obj2 a non-singleton. + // All stores below need to stay since obj/obj1/obj2 are not singletons. obj.i = 1; - obj.next.j = 2; - TestClass obj2 = new TestClass(); + obj1.j = 2; + // Following stores won't kill values of obj.i and obj1.j. obj2.i = 3; obj2.j = 4; - return obj.i + obj.next.j + obj2.i + obj2.j; + return obj.i + obj1.j + obj2.i + obj2.j; } /// CHECK-START: int Main.test4(TestClass, boolean) load_store_elimination (before) @@ -441,16 +453,14 @@ public class Main { } /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (before) - /// CHECK: <<IntTypeValue:i\d+>> ArrayGet - /// CHECK: ArraySet - /// CHECK: <<FloatTypeValue:f\d+>> ArrayGet + /// CHECK: {{f\d+}} ArrayGet + /// CHECK: {{f\d+}} ArrayGet /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (after) - /// CHECK: <<IntTypeValue:i\d+>> ArrayGet - /// CHECK: ArraySet - /// CHECK: <<FloatTypeValue:f\d+>> ArrayGet + /// CHECK: {{f\d+}} ArrayGet + /// CHECK-NOT: {{f\d+}} ArrayGet - // I/F, J/D aliasing should keep the load/store. + // I/F, J/D aliasing should not happen any more and LSE should eliminate the load. static float test19(float[] fa1, float[] fa2) { fa1[0] = fa2[0]; return fa1[0]; diff --git a/test/540-checker-rtp-bug/src/Main.java b/test/540-checker-rtp-bug/src/Main.java index e9f16c04d9..9a9f0b6048 100644 --- a/test/540-checker-rtp-bug/src/Main.java +++ b/test/540-checker-rtp-bug/src/Main.java @@ -21,14 +21,14 @@ final class Final { } public class Main { - /// CHECK-START: Final Main.testKeepCheckCast(java.lang.Object, boolean) reference_type_propagation (after) + /// CHECK-START: Final Main.testKeepCheckCast(java.lang.Object, boolean) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:java.lang.Object /// CHECK: <<Class:l\d+>> LoadClass /// CHECK: CheckCast [<<Phi>>,<<Class>>] /// CHECK: <<Ret:l\d+>> BoundType [<<Phi>>] klass:Final /// CHECK: Return [<<Ret>>] - /// CHECK-START: Final Main.testKeepCheckCast(java.lang.Object, boolean) instruction_simplifier_after_types (after) + /// CHECK-START: Final Main.testKeepCheckCast(java.lang.Object, boolean) instruction_simplifier (after) /// CHECK: <<Phi:l\d+>> Phi /// CHECK: <<Class:l\d+>> LoadClass /// CHECK: CheckCast [<<Phi>>,<<Class>>] @@ -43,7 +43,7 @@ public class Main { return (Final) x; } - /// CHECK-START: void Main.testKeepInstanceOf(java.lang.Object, boolean) reference_type_propagation (after) + /// CHECK-START: void Main.testKeepInstanceOf(java.lang.Object, boolean) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:java.lang.Object /// CHECK: <<Class:l\d+>> LoadClass /// CHECK: InstanceOf [<<Phi>>,<<Class>>] @@ -65,7 +65,7 @@ public class Main { } } - /// CHECK-START: java.lang.String Main.testNoInline(java.lang.Object, boolean) reference_type_propagation (after) + /// CHECK-START: java.lang.String Main.testNoInline(java.lang.Object, boolean) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:java.lang.Object /// CHECK: <<NC:l\d+>> NullCheck [<<Phi>>] /// CHECK: <<Ret:l\d+>> InvokeVirtual [<<NC>>] method_name:java.lang.Object.toString diff --git a/test/542-bitfield-rotates/expected.txt b/test/542-bitfield-rotates/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/542-bitfield-rotates/expected.txt diff --git a/test/542-bitfield-rotates/info.txt b/test/542-bitfield-rotates/info.txt new file mode 100644 index 0000000000..961be3bdae --- /dev/null +++ b/test/542-bitfield-rotates/info.txt @@ -0,0 +1 @@ +Tests bitfield rotate simplification in optimizing compiler. diff --git a/test/542-bitfield-rotates/src/Main.java b/test/542-bitfield-rotates/src/Main.java new file mode 100644 index 0000000000..f2bc1531dc --- /dev/null +++ b/test/542-bitfield-rotates/src/Main.java @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + + public static void assertIntEquals(int expected, int actual) { + if (expected != actual) { + throw new Error("Expected: " + expected + ", found: " + actual); + } + } + + public static void assertLongEquals(long expected, long actual) { + if (expected != actual) { + throw new Error("Expected: " + expected + ", found: " + actual); + } + } + + public static void main(String args[]) throws Exception { + test_Integer_right_v_csubv(); + test_Long_right_v_csubv(); + + test_Integer_right_constant_v(); + test_Long_right_constant_v(); + + test_Integer_left_csubv_v(); + test_Long_left_csubv_v(); + + test_Integer_right_v_negv(); + test_Long_right_v_negv(); + + test_Integer_left_negv_v(); + test_Long_left_negv_v(); + + test_Integer_left_constant_v(); + test_Long_left_constant_v(); + } + + public static boolean doThrow = false; + + public static int $noinline$rotate_int_right_reg_v_csubv(int value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> distance) | (value << (32 - distance)); + } + + public static void test_Integer_right_v_csubv() throws Exception { + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, 0), 0x11); + + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, 1), 0x80000008); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, Integer.SIZE - 1), 0x22); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, Integer.SIZE + 1), 0x80000008); + + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, -1), 0x22); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, -(Integer.SIZE - 1)), 0x80000008); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, -Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, -(Integer.SIZE + 1)), 0x22); + + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x80000000, 1), 0x40000000); + } + + public static long $noinline$rotate_long_right_reg_v_csubv(long value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> distance) | (value << (64 - distance)); + } + + public static void test_Long_right_v_csubv() throws Exception { + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, 0), 0x11); + + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, 1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, Long.SIZE - 1), 0x22); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, Long.SIZE + 1), 0x8000000000000008L); + + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, -1), 0x22); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, -(Long.SIZE - 1)), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, -Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, -(Long.SIZE + 1)), 0x22); + + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x8000000000000000L, 1), 0x4000000000000000L); + } + + public static int $noinline$rotate_int_left_reg_csubv_v(int value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> (32 - distance)) | (value << distance); + } + + public static void test_Integer_left_csubv_v() throws Exception { + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, 0), 0x11); + + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, 1), 0x22); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, Integer.SIZE - 1), 0x80000008); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, Integer.SIZE + 1), 0x22); + + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, -1), 0x80000008); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, -(Integer.SIZE - 1)), 0x22); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, -Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, -(Integer.SIZE + 1)), 0x80000008); + + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0xC0000000, 1), 0x80000001); + } + + public static long $noinline$rotate_long_left_reg_csubv_v(long value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> (64 - distance)) | (value << distance); + } + + public static void test_Long_left_csubv_v() throws Exception { + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, 0), 0x11); + + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, 1), 0x22); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, Long.SIZE - 1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, Long.SIZE + 1), 0x22); + + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, -1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, -(Long.SIZE - 1)), 0x22); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, -Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, -(Long.SIZE + 1)), 0x8000000000000008L); + + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0xC000000000000000L, 1), 0x8000000000000001L); + } + + public static int $noinline$rotate_int_right_reg_v_negv(int value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> distance) | (value << -distance); + } + + public static void test_Integer_right_v_negv() throws Exception { + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, 0), 0x11); + + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, 1), 0x80000008); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, Integer.SIZE - 1), 0x22); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, Integer.SIZE + 1), 0x80000008); + + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, -1), 0x22); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, -(Integer.SIZE - 1)), 0x80000008); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, -Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, -(Integer.SIZE + 1)), 0x22); + + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x80000000, 1), 0x40000000); + } + + public static long $noinline$rotate_long_right_reg_v_negv(long value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> distance) | (value << -distance); + } + + public static void test_Long_right_v_negv() throws Exception { + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, 0), 0x11); + + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, 1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, Long.SIZE - 1), 0x22); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, Long.SIZE + 1), 0x8000000000000008L); + + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, -1), 0x22); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, -(Long.SIZE - 1)), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, -Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, -(Long.SIZE + 1)), 0x22); + + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x8000000000000000L, 1), 0x4000000000000000L); + } + + public static int $noinline$rotate_int_left_reg_negv_v(int value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> -distance) | (value << distance); + } + + public static void test_Integer_left_negv_v() throws Exception { + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, 0), 0x11); + + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, 1), 0x22); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, Integer.SIZE - 1), 0x80000008); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, Integer.SIZE + 1), 0x22); + + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, -1), 0x80000008); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, -(Integer.SIZE - 1)), 0x22); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, -Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, -(Integer.SIZE + 1)), 0x80000008); + + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0xC0000000, 1), 0x80000001); + } + + public static long $noinline$rotate_long_left_reg_negv_v(long value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> -distance) | (value << distance); + } + + public static void test_Long_left_negv_v() throws Exception { + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, 0), 0x11); + + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, 1), 0x22); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, Long.SIZE - 1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, Long.SIZE + 1), 0x22); + + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, -1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, -(Long.SIZE - 1)), 0x22); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, -Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, -(Long.SIZE + 1)), 0x8000000000000008L); + + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0xC000000000000000L, 1), 0x8000000000000001L); + } + + public static int $noinline$rotate_int_right_constant_0(int value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 0) | (value << 0); + } + + public static int $noinline$rotate_int_right_constant_1(int value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 1) | (value << -1); + } + + public static int $noinline$rotate_int_right_constant_m1(int value) { + if (doThrow) { + throw new Error(); + } + return (value >>> -1) | (value << 1); + } + + public static int $noinline$rotate_int_right_constant_16(int value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 16) | (value << -16); + } + + public static void test_Integer_right_constant_v() throws Exception { + assertIntEquals($noinline$rotate_int_right_constant_0(0x11), 0x11); + assertIntEquals($noinline$rotate_int_right_constant_1(0x11), 0x80000008); + assertIntEquals($noinline$rotate_int_right_constant_m1(0x11), 0x22); + assertIntEquals($noinline$rotate_int_right_constant_16(0x11), 0x110000); + } + + public static long $noinline$rotate_long_right_constant_0(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 0) | (value << 0); + } + + public static long $noinline$rotate_long_right_constant_1(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 1) | (value << -1); + } + + public static long $noinline$rotate_long_right_constant_m1(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> -1) | (value << 1); + } + + public static long $noinline$rotate_long_right_constant_16(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 16) | (value << -16); + } + + public static long $noinline$rotate_long_right_constant_32(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 32) | (value << -32); + } + + public static long $noinline$rotate_long_right_constant_48(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 48) | (value << -48); + } + + public static long $noinline$rotate_long_right_constant_64(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 64) | (value << -64); + } + + public static void test_Long_right_constant_v() throws Exception { + assertLongEquals($noinline$rotate_long_right_constant_0(0x11), 0x11); + assertLongEquals($noinline$rotate_long_right_constant_1(0x11), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_constant_m1(0x11), 0x22); + assertLongEquals($noinline$rotate_long_right_constant_16(0x11), 0x11000000000000L); + assertLongEquals($noinline$rotate_long_right_constant_32(0x11), 0x1100000000L); + assertLongEquals($noinline$rotate_long_right_constant_48(0x11), 0x110000L); + } + + public static int $noinline$rotate_int_left_constant_0(int value) { + if (doThrow) { + throw new Error(); + } + return (value << 0) | (value >>> 0); + } + + public static int $noinline$rotate_int_left_constant_1(int value) { + if (doThrow) { + throw new Error(); + } + return (value << 1) | (value >>> -1); + } + + public static int $noinline$rotate_int_left_constant_m1(int value) { + if (doThrow) { + throw new Error(); + } + return (value << -1) | (value >>> 1); + } + + public static int $noinline$rotate_int_left_constant_16(int value) { + if (doThrow) { + throw new Error(); + } + return (value << 16) | (value >>> -16); + } + + public static void test_Integer_left_constant_v() throws Exception { + assertIntEquals($noinline$rotate_int_left_constant_0(0x11), 0x11); + assertIntEquals($noinline$rotate_int_left_constant_1(0x11), 0x22); + assertIntEquals($noinline$rotate_int_left_constant_m1(0x11), 0x80000008); + assertIntEquals($noinline$rotate_int_left_constant_16(0x11), 0x110000); + } + + public static long $noinline$rotate_long_left_constant_0(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 0) | (value >>> 0); + } + + public static long $noinline$rotate_long_left_constant_1(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 1) | (value >>> -1); + } + + public static long $noinline$rotate_long_left_constant_m1(long value) { + if (doThrow) { + throw new Error(); + } + return (value << -1) | (value >>> 1); + } + + public static long $noinline$rotate_long_left_constant_16(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 16) | (value >>> -16); + } + + public static long $noinline$rotate_long_left_constant_32(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 32) | (value >>> -32); + } + + public static long $noinline$rotate_long_left_constant_48(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 48) | (value >>> -48); + } + + public static long $noinline$rotate_long_left_constant_64(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 64) | (value >>> -64); + } + + public static void test_Long_left_constant_v() throws Exception { + assertLongEquals($noinline$rotate_long_left_constant_0(0x11), 0x11); + assertLongEquals($noinline$rotate_long_left_constant_1(0x11), 0x22); + assertLongEquals($noinline$rotate_long_left_constant_m1(0x11), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_constant_16(0x11), 0x110000L); + assertLongEquals($noinline$rotate_long_left_constant_32(0x11), 0x1100000000L); + assertLongEquals($noinline$rotate_long_left_constant_48(0x11), 0x11000000000000L); + } + +} diff --git a/test/549-checker-types-merge/src/Main.java b/test/549-checker-types-merge/src/Main.java index dc27f10427..917073b1c9 100644 --- a/test/549-checker-types-merge/src/Main.java +++ b/test/549-checker-types-merge/src/Main.java @@ -38,14 +38,14 @@ class ClassImplementsInterfaceA extends ClassSuper implements InterfaceA {} public class Main { - /// CHECK-START: java.lang.Object Main.testMergeNullContant(boolean) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeNullContant(boolean) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:Main /// CHECK: Return [<<Phi>>] private Object testMergeNullContant(boolean cond) { return cond ? null : new Main(); } - /// CHECK-START: java.lang.Object Main.testMergeClasses(boolean, ClassExtendsA, ClassExtendsB) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeClasses(boolean, ClassExtendsA, ClassExtendsB) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:ClassSuper /// CHECK: Return [<<Phi>>] private Object testMergeClasses(boolean cond, ClassExtendsA a, ClassExtendsB b) { @@ -53,7 +53,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeClasses(boolean, ClassExtendsA, ClassSuper) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeClasses(boolean, ClassExtendsA, ClassSuper) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:ClassSuper /// CHECK: Return [<<Phi>>] private Object testMergeClasses(boolean cond, ClassExtendsA a, ClassSuper b) { @@ -61,7 +61,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeClasses(boolean, ClassSuper, ClassSuper) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeClasses(boolean, ClassSuper, ClassSuper) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:ClassSuper /// CHECK: Return [<<Phi>>] private Object testMergeClasses(boolean cond, ClassSuper a, ClassSuper b) { @@ -69,7 +69,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeClasses(boolean, ClassOtherSuper, ClassSuper) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeClasses(boolean, ClassOtherSuper, ClassSuper) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:java.lang.Object /// CHECK: Return [<<Phi>>] private Object testMergeClasses(boolean cond, ClassOtherSuper a, ClassSuper b) { @@ -77,7 +77,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeClassWithInterface(boolean, ClassImplementsInterfaceA, InterfaceSuper) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeClassWithInterface(boolean, ClassImplementsInterfaceA, InterfaceSuper) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:InterfaceSuper /// CHECK: Return [<<Phi>>] private Object testMergeClassWithInterface(boolean cond, ClassImplementsInterfaceA a, InterfaceSuper b) { @@ -85,7 +85,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeClassWithInterface(boolean, ClassSuper, InterfaceSuper) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeClassWithInterface(boolean, ClassSuper, InterfaceSuper) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:java.lang.Object /// CHECK: Return [<<Phi>>] private Object testMergeClassWithInterface(boolean cond, ClassSuper a, InterfaceSuper b) { @@ -93,7 +93,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeInterfaces(boolean, InterfaceExtendsA, InterfaceSuper) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeInterfaces(boolean, InterfaceExtendsA, InterfaceSuper) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:InterfaceSuper /// CHECK: Return [<<Phi>>] private Object testMergeInterfaces(boolean cond, InterfaceExtendsA a, InterfaceSuper b) { @@ -101,7 +101,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeInterfaces(boolean, InterfaceSuper, InterfaceSuper) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeInterfaces(boolean, InterfaceSuper, InterfaceSuper) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:InterfaceSuper /// CHECK: Return [<<Phi>>] private Object testMergeInterfaces(boolean cond, InterfaceSuper a, InterfaceSuper b) { @@ -109,7 +109,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeInterfaces(boolean, InterfaceExtendsA, InterfaceExtendsB) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeInterfaces(boolean, InterfaceExtendsA, InterfaceExtendsB) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:java.lang.Object /// CHECK: Return [<<Phi>>] private Object testMergeInterfaces(boolean cond, InterfaceExtendsA a, InterfaceExtendsB b) { @@ -117,7 +117,7 @@ public class Main { return cond ? a : b; } - /// CHECK-START: java.lang.Object Main.testMergeInterfaces(boolean, InterfaceSuper, InterfaceOtherSuper) reference_type_propagation (after) + /// CHECK-START: java.lang.Object Main.testMergeInterfaces(boolean, InterfaceSuper, InterfaceOtherSuper) ssa_builder (after) /// CHECK: <<Phi:l\d+>> Phi klass:java.lang.Object /// CHECK: Return [<<Phi>>] private Object testMergeInterfaces(boolean cond, InterfaceSuper a, InterfaceOtherSuper b) { diff --git a/test/552-checker-primitive-typeprop/expected.txt b/test/552-checker-primitive-typeprop/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/552-checker-primitive-typeprop/expected.txt diff --git a/test/552-checker-primitive-typeprop/info.txt b/test/552-checker-primitive-typeprop/info.txt new file mode 100644 index 0000000000..9d69056915 --- /dev/null +++ b/test/552-checker-primitive-typeprop/info.txt @@ -0,0 +1,2 @@ +Test that phis with environment uses which can be properly typed are kept +in --debuggable mode.
\ No newline at end of file diff --git a/test/552-checker-primitive-typeprop/smali/ArrayGet.smali b/test/552-checker-primitive-typeprop/smali/ArrayGet.smali new file mode 100644 index 0000000000..042fa0c80c --- /dev/null +++ b/test/552-checker-primitive-typeprop/smali/ArrayGet.smali @@ -0,0 +1,245 @@ +# Copyright (C) 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +.class public LArrayGet; +.super Ljava/lang/Object; + + +# Test phi with fixed-type ArrayGet as an input and a matching second input. +# The phi should be typed accordingly. + +## CHECK-START: void ArrayGet.matchingFixedType(float[], float) ssa_builder (after) +## CHECK-NOT: Phi + +## CHECK-START-DEBUGGABLE: void ArrayGet.matchingFixedType(float[], float) ssa_builder (after) +## CHECK-DAG: <<Arg1:f\d+>> ParameterValue +## CHECK-DAG: <<Aget:f\d+>> ArrayGet +## CHECK-DAG: {{f\d+}} Phi [<<Aget>>,<<Arg1>>] reg:0 +.method public static matchingFixedType([FF)V + .registers 8 + + const v0, 0x0 + const v1, 0x1 + + aget v0, p0, v0 # read value + add-float v2, v0, v1 # float use fixes type + + float-to-int v2, p1 + if-eqz v2, :after + move v0, p1 + :after + # v0 = Phi [ArrayGet, Arg1] => float + + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + + +# Test phi with fixed-type ArrayGet as an input and a conflicting second input. +# The phi should be eliminated due to the conflict. + +## CHECK-START: void ArrayGet.conflictingFixedType(float[], int) ssa_builder (after) +## CHECK-NOT: Phi + +## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType(float[], int) ssa_builder (after) +## CHECK-NOT: Phi +.method public static conflictingFixedType([FI)V + .registers 8 + + const v0, 0x0 + const v1, 0x1 + + aget v0, p0, v0 # read value + add-float v2, v0, v1 # float use fixes type + + if-eqz p1, :after + move v0, p1 + :after + # v0 = Phi [ArrayGet, Arg1] => conflict + + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + + +# Same test as the one above, only this time tests that type of ArrayGet is not +# changed. + +## CHECK-START: void ArrayGet.conflictingFixedType2(int[], float) ssa_builder (after) +## CHECK-NOT: Phi + +## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType2(int[], float) ssa_builder (after) +## CHECK-NOT: Phi + +## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType2(int[], float) ssa_builder (after) +## CHECK: {{i\d+}} ArrayGet +.method public static conflictingFixedType2([IF)V + .registers 8 + + const v0, 0x0 + const v1, 0x1 + + aget v0, p0, v0 # read value + add-int v2, v0, v1 # int use fixes type + + float-to-int v2, p1 + if-eqz v2, :after + move v0, p1 + :after + # v0 = Phi [ArrayGet, Arg1] => conflict + + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + + +# Test phi with free-type ArrayGet as an input and a matching second input. +# The phi should be typed accordingly. + +## CHECK-START: void ArrayGet.matchingFreeType(float[], float) ssa_builder (after) +## CHECK-NOT: Phi + +## CHECK-START-DEBUGGABLE: void ArrayGet.matchingFreeType(float[], float) ssa_builder (after) +## CHECK-DAG: <<Arg1:f\d+>> ParameterValue +## CHECK-DAG: <<Aget:f\d+>> ArrayGet +## CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Aget>>] +## CHECK-DAG: {{f\d+}} Phi [<<Aget>>,<<Arg1>>] reg:0 +.method public static matchingFreeType([FF)V + .registers 8 + + const v0, 0x0 + const v1, 0x1 + + aget v0, p0, v0 # read value, should be float but has no typed use + aput v0, p0, v1 # aput does not disambiguate the type + + float-to-int v2, p1 + if-eqz v2, :after + move v0, p1 + :after + # v0 = Phi [ArrayGet, Arg1] => float + + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + + +# Test phi with free-type ArrayGet as an input and a conflicting second input. +# The phi will be kept and typed according to the second input despite the +# conflict. + +## CHECK-START: void ArrayGet.conflictingFreeType(int[], float) ssa_builder (after) +## CHECK-NOT: Phi + +## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFreeType(int[], float) ssa_builder (after) +## CHECK-NOT: Phi + +.method public static conflictingFreeType([IF)V + .registers 8 + + const v0, 0x0 + const v1, 0x1 + + aget v0, p0, v0 # read value, should be int but has no typed use + aput v0, p0, v1 + + float-to-int v2, p1 + if-eqz v2, :after + move v0, p1 + :after + # v0 = Phi [ArrayGet, Arg1] => float + + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + + +# Test that real use of ArrayGet is propagated through phis. The following test +# case uses ArrayGet indirectly through two phis. It also creates an unused +# conflicting phi which should not be preserved. + +## CHECK-START: void ArrayGet.conflictingPhiUses(int[], float, boolean, boolean, boolean) ssa_builder (after) +## CHECK: InvokeStaticOrDirect env:[[{{i\d+}},{{i\d+}},_,{{i\d+}},{{.*}} + +.method public static conflictingPhiUses([IFZZZ)V + .registers 10 + + const v0, 0x0 + + # Create v1 = Phi [0x0, int ArrayGet] + move v1, v0 + if-eqz p2, :else1 + aget v1, p0, v0 + :else1 + + # Create v2 = Phi [v1, float] + move v2, v1 + if-eqz p3, :else2 + move v2, p1 + :else2 + + # Create v3 = Phi [v1, int] + move v3, v1 + if-eqz p4, :else3 + move v3, v0 + :else3 + + # Use v3 as int. + add-int/lit8 v4, v3, 0x2a + + # Create env uses. + invoke-static {}, Ljava/lang/System;->nanoTime()J + + return-void +.end method + +# Test that the right ArrayGet equivalent is always selected. The following test +# case uses ArrayGet as float through one phi and as an indeterminate type through +# another. The situation needs to be resolved so that only one instruction +# remains. + +## CHECK-START: void ArrayGet.typedVsUntypedPhiUse(float[], float, boolean, boolean) ssa_builder (after) +## CHECK: {{f\d+}} ArrayGet + +## CHECK-START: void ArrayGet.typedVsUntypedPhiUse(float[], float, boolean, boolean) ssa_builder (after) +## CHECK-NOT: {{i\d+}} ArrayGet + +.method public static typedVsUntypedPhiUse([FFZZ)V + .registers 10 + + const v0, 0x0 + + # v1 = float ArrayGet + aget v1, p0, v0 + + # Create v2 = Phi [v1, 0.0f] + move v2, v1 + if-eqz p2, :else1 + move v2, v0 + :else1 + + # Use v2 as float + cmpl-float v2, v2, p1 + + # Create v3 = Phi [v1, 0.0f] + move v3, v1 + if-eqz p3, :else2 + move v3, v0 + :else2 + + # Use v3 without a determinate type. + aput v3, p0, v0 + + return-void +.end method diff --git a/test/552-checker-primitive-typeprop/smali/SsaBuilder.smali b/test/552-checker-primitive-typeprop/smali/SsaBuilder.smali new file mode 100644 index 0000000000..395feaaf61 --- /dev/null +++ b/test/552-checker-primitive-typeprop/smali/SsaBuilder.smali @@ -0,0 +1,52 @@ +# Copyright (C) 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +.class public LSsaBuilder; +.super Ljava/lang/Object; + +# Check that a dead phi with a live equivalent is replaced in an environment. The +# following test case throws an exception and uses v0 afterwards. However, v0 +# contains a phi that is interpreted as int for the environment, and as float for +# instruction use. SsaBuilder must substitute the int variant before removing it, +# otherwise running the code with an array short enough to throw will crash at +# runtime because v0 is undefined. + +## CHECK-START: int SsaBuilder.environmentPhi(boolean, int[]) ssa_builder (after) +## CHECK-DAG: <<Cst0:f\d+>> FloatConstant 0 +## CHECK-DAG: <<Cst2:f\d+>> FloatConstant 2 +## CHECK-DAG: <<Phi:f\d+>> Phi [<<Cst0>>,<<Cst2>>] +## CHECK-DAG: BoundsCheck env:[[<<Phi>>,{{i\d+}},{{z\d+}},{{l\d+}}]] + +.method public static environmentPhi(Z[I)I + .registers 4 + + const v0, 0x0 + if-eqz p0, :else + const v0, 0x40000000 + :else + # v0 = phi that can be both int and float + + :try_start + const v1, 0x3 + aput v1, p1, v1 + const v0, 0x1 # generate catch phi for v0 + const v1, 0x4 + aput v1, p1, v1 + :try_end + .catchall {:try_start .. :try_end} :use_as_float + + :use_as_float + float-to-int v0, v0 + return v0 +.end method
\ No newline at end of file diff --git a/test/552-checker-primitive-typeprop/smali/TypePropagation.smali b/test/552-checker-primitive-typeprop/smali/TypePropagation.smali new file mode 100644 index 0000000000..58682a1923 --- /dev/null +++ b/test/552-checker-primitive-typeprop/smali/TypePropagation.smali @@ -0,0 +1,136 @@ +# Copyright (C) 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +.class public LTypePropagation; +.super Ljava/lang/Object; + +## CHECK-START-DEBUGGABLE: void TypePropagation.mergeDeadPhi(boolean, boolean, int, float, float) ssa_builder (after) +## CHECK-NOT: Phi +.method public static mergeDeadPhi(ZZIFF)V + .registers 8 + + if-eqz p0, :after1 + move p2, p3 + :after1 + # p2 = merge(int,float) = conflict + + if-eqz p1, :after2 + move p2, p4 + :after2 + # p2 = merge(conflict,float) = conflict + + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + +## CHECK-START-DEBUGGABLE: void TypePropagation.mergeSameType(boolean, int, int) ssa_builder (after) +## CHECK: {{i\d+}} Phi +## CHECK-NOT: Phi +.method public static mergeSameType(ZII)V + .registers 8 + if-eqz p0, :after + move p1, p2 + :after + # p1 = merge(int,int) = int + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + +## CHECK-START-DEBUGGABLE: void TypePropagation.mergeVoidInput(boolean, boolean, int, int) ssa_builder (after) +## CHECK: {{i\d+}} Phi +## CHECK: {{i\d+}} Phi +## CHECK-NOT: Phi +.method public static mergeVoidInput(ZZII)V + .registers 8 + :loop + # p2 = void (loop phi) => p2 = merge(int,int) = int + if-eqz p0, :after + move p2, p3 + :after + # p2 = merge(void,int) = int + if-eqz p1, :loop + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + +## CHECK-START-DEBUGGABLE: void TypePropagation.mergeDifferentSize(boolean, int, long) ssa_builder (after) +## CHECK-NOT: Phi +.method public static mergeDifferentSize(ZIJ)V + .registers 8 + if-eqz p0, :after + move-wide p1, p2 + :after + # p1 = merge(int,long) = conflict + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + +## CHECK-START-DEBUGGABLE: void TypePropagation.mergeRefFloat(boolean, float, java.lang.Object) ssa_builder (after) +## CHECK-NOT: Phi +.method public static mergeRefFloat(ZFLjava/lang/Object;)V + .registers 8 + if-eqz p0, :after + move-object p1, p2 + :after + # p1 = merge(float,reference) = conflict + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + +## CHECK-START-DEBUGGABLE: void TypePropagation.mergeIntFloat_Success(boolean, float) ssa_builder (after) +## CHECK: {{f\d+}} Phi +## CHECK-NOT: Phi +.method public static mergeIntFloat_Success(ZF)V + .registers 8 + if-eqz p0, :after + const/4 p1, 0x0 + :after + # p1 = merge(float,0x0) = float + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + +## CHECK-START-DEBUGGABLE: void TypePropagation.mergeIntFloat_Fail(boolean, int, float) ssa_builder (after) +## CHECK-NOT: Phi +.method public static mergeIntFloat_Fail(ZIF)V + .registers 8 + if-eqz p0, :after + move p1, p2 + :after + # p1 = merge(int,float) = conflict + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method + +## CHECK-START-DEBUGGABLE: void TypePropagation.updateAllUsersOnConflict(boolean, boolean, int, float, int) ssa_builder (after) +## CHECK-NOT: Phi +.method public static updateAllUsersOnConflict(ZZIFI)V + .registers 8 + + :loop1 + # loop phis for all args + # p2 = merge(int,float) = float? => conflict + move p2, p3 + if-eqz p0, :loop1 + + :loop2 + # loop phis for all args + # requests float equivalent of p4 phi in loop1 => conflict + # propagates conflict to loop2's phis + move p2, p4 + if-eqz p1, :loop2 + + invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use + return-void +.end method diff --git a/test/552-checker-primitive-typeprop/src/Main.java b/test/552-checker-primitive-typeprop/src/Main.java new file mode 100644 index 0000000000..fe2343e48a --- /dev/null +++ b/test/552-checker-primitive-typeprop/src/Main.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Method; + +public class Main { + + // Workaround for b/18051191. + class InnerClass {} + + private static void assertEquals(int expected, int actual) { + if (expected != actual) { + throw new Error("Wrong result, expected=" + expected + ", actual=" + actual); + } + } + + public static void main(String[] args) throws Exception { + Class<?> c = Class.forName("SsaBuilder"); + Method m = c.getMethod("environmentPhi", new Class[] { boolean.class, int[].class }); + + int[] array = new int[3]; + int result; + + result = (Integer) m.invoke(null, new Object[] { true, array } ); + assertEquals(2, result); + + result = (Integer) m.invoke(null, new Object[] { false, array } ); + assertEquals(0, result); + } +} diff --git a/test/554-jit-profile-file/expected.txt b/test/554-jit-profile-file/expected.txt new file mode 100644 index 0000000000..cde211e1c0 --- /dev/null +++ b/test/554-jit-profile-file/expected.txt @@ -0,0 +1,7 @@ +JNI_OnLoad called +ProfileInfo: +:classes.dex + java.lang.String Main.hotMethod() + void Main.main(java.lang.String[]) +:classes2.dex + java.lang.String OtherDex.hotMethod() diff --git a/test/554-jit-profile-file/info.txt b/test/554-jit-profile-file/info.txt new file mode 100644 index 0000000000..b1bfe81eb8 --- /dev/null +++ b/test/554-jit-profile-file/info.txt @@ -0,0 +1 @@ +Check that saving and restoring profile files works correctly in a JIT environment. diff --git a/test/554-jit-profile-file/offline_profile.cc b/test/554-jit-profile-file/offline_profile.cc new file mode 100644 index 0000000000..75e441fc87 --- /dev/null +++ b/test/554-jit-profile-file/offline_profile.cc @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dex_file.h" + +#include "jit/offline_profiling_info.h" +#include "jni.h" +#include "mirror/class-inl.h" +#include "oat_file_assistant.h" +#include "oat_file_manager.h" +#include "scoped_thread_state_change.h" +#include "thread.h" + +namespace art { +namespace { + +extern "C" JNIEXPORT jstring JNICALL Java_Main_getProfileInfoDump( + JNIEnv* env, jclass cls, jstring filename) { + std::string dex_location; + { + ScopedObjectAccess soa(Thread::Current()); + dex_location = soa.Decode<mirror::Class*>(cls)->GetDexCache()->GetDexFile()->GetLocation(); + } + const OatFile* oat_file = Runtime::Current()->GetOatFileManager().GetPrimaryOatFile(); + std::vector<std::unique_ptr<const DexFile>> dex_files = + OatFileAssistant::LoadDexFiles(*oat_file, dex_location.c_str()); + const char* filename_chars = env->GetStringUTFChars(filename, nullptr); + + std::vector<const DexFile*> dex_files_raw; + for (size_t i = 0; i < dex_files.size(); i++) { + dex_files_raw.push_back(dex_files[i].get()); + } + + ProfileCompilationInfo info(filename_chars); + + std::string result = info.Load(dex_files_raw) + ? info.DumpInfo(/*print_full_dex_location*/false) + : "Could not load profile info"; + + env->ReleaseStringUTFChars(filename, filename_chars); + // Return the dump of the profile info. It will be compared against a golden value. + return env->NewStringUTF(result.c_str()); +} + +} // namespace +} // namespace art diff --git a/test/554-jit-profile-file/run b/test/554-jit-profile-file/run new file mode 100644 index 0000000000..f93b32f5c7 --- /dev/null +++ b/test/554-jit-profile-file/run @@ -0,0 +1,23 @@ +#!/bin/bash +# +# Copyright 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +exec ${RUN} \ + -Xcompiler-option --compiler-filter=interpret-only \ + --runtime-option -Xjitsaveprofilinginfo \ + --runtime-option -Xusejit:true \ + --runtime-option -Xjitwarmupthreshold:2 \ + --runtime-option -Xjitthreshold:4 \ + "${@}" diff --git a/test/554-jit-profile-file/src-multidex/OtherDex.java b/test/554-jit-profile-file/src-multidex/OtherDex.java new file mode 100644 index 0000000000..51644db5aa --- /dev/null +++ b/test/554-jit-profile-file/src-multidex/OtherDex.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.HashMap; + +public class OtherDex { + public void coldMethod() { + hotMethod(); + } + + public String hotMethod() { + HashMap<String, String> map = new HashMap<String, String>(); + for (int i = 0; i < 10; i++) { + map.put("" + i, "" + i + 1); + } + return map.get("1"); + } +} diff --git a/test/554-jit-profile-file/src/Main.java b/test/554-jit-profile-file/src/Main.java new file mode 100644 index 0000000000..98297ed8ed --- /dev/null +++ b/test/554-jit-profile-file/src/Main.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.HashMap; + +public class Main { + + public void coldMethod() { + hotMethod(); + } + + public String hotMethod() { + HashMap<String, String> map = new HashMap<String, String>(); + for (int i = 0; i < 10; i++) { + map.put("" + i, "" + i + 1); + } + return map.get("1"); + } + + private static final String PKG_NAME = "test.package"; + private static final String APP_DIR_PREFIX = "app_dir_"; + private static final String CODE_CACHE = "code_cache"; + private static final String PROFILE_FILE = PKG_NAME + ".prof"; + private static final String TEMP_FILE_NAME_PREFIX = "dummy"; + private static final String TEMP_FILE_NAME_SUFFIX = "-file"; + private static final int JIT_INVOCATION_COUNT = 200; + + /* needs to match Runtime:: kProfileBackground */ + private static final int PROFILE_BACKGROUND = 1; + + public static void main(String[] args) throws Exception { + System.loadLibrary(args[0]); + + File file = null; + File appDir = null; + File profileDir = null; + File profileFile = null; + try { + // We don't know where we have rights to create the code_cache. So create + // a dummy temporary file and get its parent directory. That will serve as + // the app directory. + file = createTempFile(); + appDir = new File(file.getParent(), APP_DIR_PREFIX + file.getName()); + appDir.mkdir(); + profileDir = new File(appDir, CODE_CACHE); + profileDir.mkdir(); + + // Registering the app info will set the profile file name. + VMRuntime.registerAppInfo(PKG_NAME, appDir.getPath()); + + // Make sure the hot methods are jitted. + Main m = new Main(); + OtherDex o = new OtherDex(); + for (int i = 0; i < JIT_INVOCATION_COUNT; i++) { + m.hotMethod(); + o.hotMethod(); + } + + // Sleep for 2 second to make sure that the methods had a chance to get compiled. + Thread.sleep(2000); + // Updating the process state to BACKGROUND will trigger profile saving. + VMRuntime.updateProcessState(PROFILE_BACKGROUND); + + // Check that the profile file exists. + profileFile = new File(profileDir, PROFILE_FILE); + if (!profileFile.exists()) { + throw new RuntimeException("No profile file found"); + } + // Dump the profile file. + // We know what methods are hot and we compare with the golden `expected` output. + System.out.println(getProfileInfoDump(profileFile.getPath())); + } finally { + if (file != null) { + file.delete(); + } + if (profileFile != null) { + profileFile.delete(); + } + if (profileDir != null) { + profileDir.delete(); + } + if (appDir != null) { + appDir.delete(); + } + } + } + + private static class VMRuntime { + private static final Method registerAppInfoMethod; + private static final Method updateProcessStateMethod; + private static final Method getRuntimeMethod; + static { + try { + Class c = Class.forName("dalvik.system.VMRuntime"); + registerAppInfoMethod = c.getDeclaredMethod("registerAppInfo", + String.class, String.class, String.class); + updateProcessStateMethod = c.getDeclaredMethod("updateProcessState", Integer.TYPE); + getRuntimeMethod = c.getDeclaredMethod("getRuntime"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void registerAppInfo(String pkgName, String appDir) throws Exception { + registerAppInfoMethod.invoke(null, pkgName, appDir, null); + } + public static void updateProcessState(int state) throws Exception { + Object runtime = getRuntimeMethod.invoke(null); + updateProcessStateMethod.invoke(runtime, state); + } + } + + static native String getProfileInfoDump( + String filename); + + private static File createTempFile() throws Exception { + try { + return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); + } catch (IOException e) { + System.setProperty("java.io.tmpdir", "/data/local/tmp"); + try { + return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); + } catch (IOException e2) { + System.setProperty("java.io.tmpdir", "/sdcard"); + return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); + } + } + } +} diff --git a/test/557-checker-instruction-simplifier-ror/expected.txt b/test/557-checker-instruction-simplifier-ror/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/557-checker-instruction-simplifier-ror/expected.txt diff --git a/test/557-checker-instruction-simplifier-ror/info.txt b/test/557-checker-instruction-simplifier-ror/info.txt new file mode 100644 index 0000000000..f9a86f8009 --- /dev/null +++ b/test/557-checker-instruction-simplifier-ror/info.txt @@ -0,0 +1 @@ +Tests simplification of bitfield rotate patterns in optimizing compiler. diff --git a/test/557-checker-instruction-simplifier-ror/src/Main.java b/test/557-checker-instruction-simplifier-ror/src/Main.java new file mode 100644 index 0000000000..027f262db1 --- /dev/null +++ b/test/557-checker-instruction-simplifier-ror/src/Main.java @@ -0,0 +1,659 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + + public static void assertIntEquals(int expected, int actual) { + if (expected != actual) { + throw new Error("Expected: " + expected + ", found: " + actual); + } + } + + public static void assertLongEquals(long expected, long actual) { + if (expected != actual) { + throw new Error("Expected: " + expected + ", found: " + actual); + } + } + + /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Invoke:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateRight + + /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (after) + /// CHECK-NOT: LoadClass + /// CHECK-NOT: ClinitCheck + /// CHECK-NOT: InvokeStaticOrDirect + public static int rotateIntegerRight(int value, int distance) { + return java.lang.Integer.rotateRight(value, distance); + } + + /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Invoke:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateLeft + + /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (after) + /// CHECK-NOT: LoadClass + /// CHECK-NOT: ClinitCheck + /// CHECK-NOT: InvokeStaticOrDirect + public static int rotateIntegerLeft(int value, int distance) { + return java.lang.Integer.rotateLeft(value, distance); + } + + /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Invoke:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateRight + + /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (after) + /// CHECK-NOT: LoadClass + /// CHECK-NOT: ClinitCheck + /// CHECK-NOT: InvokeStaticOrDirect + public static long rotateLongRight(long value, int distance) { + return java.lang.Long.rotateRight(value, distance); + } + + /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Invoke:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateLeft + + /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (after) + /// CHECK-NOT: LoadClass + /// CHECK-NOT: ClinitCheck + /// CHECK-NOT: InvokeStaticOrDirect + public static long rotateLongLeft(long value, int distance) { + return java.lang.Long.rotateLeft(value, distance); + } + + // (i >>> #distance) | (i << #(reg_bits - distance)) + + /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Const30:i\d+>> IntConstant 30 + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Const2>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Const30>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_constant_c_c(int value) { + return (value >>> 2) | (value << 30); + } + + /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_constant_c_c_0(int value) { + return (value >>> 2) | (value << 62); + } + + // (j >>> #distance) | (j << #(reg_bits - distance)) + + /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Const62:i\d+>> IntConstant 62 + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Const2>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Const62>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static long ror_long_constant_c_c(long value) { + return (value >>> 2) | (value << 62); + } + + /// CHECK-START: long Main.ror_long_constant_c_c_0(long) instruction_simplifier (after) + /// CHECK-NOT: Ror + public static long ror_long_constant_c_c_0(long value) { + return (value >>> 2) | (value << 30); + } + + // (i >>> #distance) | (i << #-distance) + + /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2 + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Const2>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ConstNeg2>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_constant_c_negc(int value) { + return (value >>> 2) | (value << -2); + } + + // (j >>> #distance) | (j << #-distance) + + /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2 + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Const2>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ConstNeg2>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static long ror_long_constant_c_negc(long value) { + return (value >>> 2) | (value << -2); + } + + // (i >>> distance) | (i << (#reg_bits - distance) + + /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + /// CHECK-NOT: Sub + public static int ror_int_reg_v_csubv(int value, int distance) { + return (value >>> distance) | (value << (32 - distance)); + } + + // (distance = x - y) + // (i >>> distance) | (i << (#reg_bits - distance) + + /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub32>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<SubDistance>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<SubDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) + /// CHECK: Sub + /// CHECK-NOT: Sub + + /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_subv_csubv(int value, int x, int y) { + int distance = x - y; + return (value >>> distance) | (value << (32 - distance)); + } + + /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<SubDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub32>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: <<Add:i\d+>> Add [<<Or>>,<<Sub32>>] + /// CHECK: Return [<<Add>>] + + /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<SubDistance>>] + /// CHECK: <<Add:i\d+>> Add [<<Ror>>,<<Sub32>>] + /// CHECK: Return [<<Add>>] + + /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_subv_csubv_env(int value, int x, int y) { + int distance = x - y; + int bits_minus_dist = 32 - distance; + return ((value >>> distance) | (value << bits_minus_dist)) + bits_minus_dist; + } + + // (j >>> distance) | (j << (#reg_bits - distance) + + /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const64:i\d+>> IntConstant 64 + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Sub>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + /// CHECK-NOT: Sub + public static long ror_long_reg_v_csubv(long value, int distance) { + return (value >>> distance) | (value << (64 - distance)); + } + + /// CHECK-START: long Main.ror_long_reg_v_csubv_0(long, int) instruction_simplifier (after) + /// CHECK-NOT: Ror + public static long ror_long_reg_v_csubv_0(long value, int distance) { + return (value >>> distance) | (value << (32 - distance)); + } + + /// CHECK-START: long Main.ror_long_subv_csubv_0(long, int, int) instruction_simplifier (after) + /// CHECK-NOT: Ror + public static long ror_long_subv_csubv_0(long value, int x, int y) { + int distance = x - y; + return (value >>> distance) | (value << (32 - distance)); + } + + // (i >>> (#reg_bits - distance)) | (i << distance) + + /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Sub>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Sub>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int rol_int_reg_csubv_v(int value, int distance) { + return (value >>> (32 - distance)) | (value << distance); + } + + // (distance = x - y) + // (i >>> (#reg_bits - distance)) | (i << distance) + + /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<SubDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Sub32>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK: <<Sub:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Sub>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) + /// CHECK: Sub + /// CHECK: Sub + + /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int rol_int_csubv_subv(int value, int x, int y) { + int distance = x - y; + return (value >>> (32 - distance)) | (value << distance); + } + + // (j >>> (#reg_bits - distance)) | (j << distance) + + /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const64:i\d+>> IntConstant 64 + /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Sub>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const64:i\d+>> IntConstant 64 + /// CHECK: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Sub>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static long rol_long_reg_csubv_v(long value, int distance) { + return (value >>> (64 - distance)) | (value << distance); + } + + /// CHECK-START: long Main.rol_long_reg_csubv_v_0(long, int) instruction_simplifier (after) + /// CHECK-NOT: Ror + public static long rol_long_reg_csubv_v_0(long value, int distance) { + return (value >>> (32 - distance)) | (value << distance); + } + + // (i >>> distance) | (i << -distance) (i.e. libcore's Integer.rotateRight) + + /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Neg>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + /// CHECK-NOT: Neg + public static int ror_int_reg_v_negv(int value, int distance) { + return (value >>> distance) | (value << -distance); + } + + /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Neg>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: <<Add:i\d+>> Add [<<Or>>,<<Neg>>] + /// CHECK: Return [<<Add>>] + + /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Sub:i\d+>> Sub [<<Ror>>,<<ArgDistance>>] + /// CHECK: Return [<<Sub>>] + + /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_reg_v_negv_env(int value, int distance) { + int neg_distance = -distance; + return ((value >>> distance) | (value << neg_distance)) + neg_distance; + } + + // (j >>> distance) | (j << -distance) (i.e. libcore's Long.rotateRight) + + /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Neg>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + /// CHECK-NOT: Neg + public static long ror_long_reg_v_negv(long value, int distance) { + return (value >>> distance) | (value << -distance); + } + + // (i << distance) | (i >>> -distance) (i.e. libcore's Integer.rotateLeft) + + /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Neg>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Or:i\d+>> Or [<<Shl>>,<<UShr>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int rol_int_reg_negv_v(int value, int distance) { + return (value << distance) | (value >>> -distance); + } + + // (j << distance) | (j >>> -distance) (i.e. libcore's Long.rotateLeft) + + /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Or:j\d+>> Or [<<Shl>>,<<UShr>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static long rol_long_reg_negv_v(long value, int distance) { + return (value << distance) | (value >>> -distance); + } + + // (j << distance) + (j >>> -distance) + + /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Add:j\d+>> Add [<<Shl>>,<<UShr>>] + /// CHECK: Return [<<Add>>] + + /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after) + /// CHECK-NOT: Add + /// CHECK-NOT: Shl + /// CHECK-NOT: UShr + public static long rol_long_reg_v_negv_add(long value, int distance) { + return (value << distance) + (value >>> -distance); + } + + // (j << distance) ^ (j >>> -distance) + + /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Xor:j\d+>> Xor [<<Shl>>,<<UShr>>] + /// CHECK: Return [<<Xor>>] + + /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after) + /// CHECK-NOT: Xor + /// CHECK-NOT: Shl + /// CHECK-NOT: UShr + public static long rol_long_reg_v_negv_xor(long value, int distance) { + return (value << distance) ^ (value >>> -distance); + } + + public static void main(String[] args) { + assertIntEquals(2, ror_int_constant_c_c(8)); + assertIntEquals(2, ror_int_constant_c_c_0(8)); + assertLongEquals(2L, ror_long_constant_c_c(8L)); + + assertIntEquals(2, ror_int_constant_c_negc(8)); + assertLongEquals(2L, ror_long_constant_c_negc(8L)); + + assertIntEquals(2, ror_int_reg_v_csubv(8, 2)); + assertLongEquals(2L, ror_long_reg_v_csubv(8L, 2)); + + assertIntEquals(2, ror_int_subv_csubv(8, 2, 0)); + assertIntEquals(32, ror_int_subv_csubv_env(8, 2, 0)); + assertIntEquals(32, rol_int_csubv_subv(8, 2, 0)); + + assertIntEquals(32, rol_int_reg_csubv_v(8, 2)); + assertLongEquals(32L, rol_long_reg_csubv_v(8L, 2)); + + assertIntEquals(2, ror_int_reg_v_negv(8, 2)); + assertIntEquals(0, ror_int_reg_v_negv_env(8, 2)); + assertLongEquals(2L, ror_long_reg_v_negv(8L, 2)); + + assertIntEquals(32, rol_int_reg_negv_v(8, 2)); + assertLongEquals(32L, rol_long_reg_negv_v(8L, 2)); + + assertLongEquals(32L, rol_long_reg_v_negv_add(8L, 2)); + assertLongEquals(32L, rol_long_reg_v_negv_xor(8L, 2)); + } +} diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt index ebefeea405..27f5b5d552 100644 --- a/test/800-smali/expected.txt +++ b/test/800-smali/expected.txt @@ -48,4 +48,5 @@ b/23502994 (if-eqz) b/23502994 (check-cast) b/25494456 b/21869691 +b/26143249 Done! diff --git a/test/800-smali/smali/b_26143249.smali b/test/800-smali/smali/b_26143249.smali new file mode 100644 index 0000000000..aa69e84bfa --- /dev/null +++ b/test/800-smali/smali/b_26143249.smali @@ -0,0 +1,20 @@ +# Make sure we accept non-abstract classes with abstract members. + +.class public LB26143249; + +.super Ljava/lang/Object; + +.method public constructor <init>()V + .registers 1 + invoke-direct {p0}, Ljava/lang/Object;-><init>()V + return-void +.end method + +.method public run()V + .registers 1 + invoke-virtual {p0}, LB26143249;->abs()V + return-void +.end method + +.method public abstract abs()V +.end method diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java index 3b62a46fd3..cc3b0b44f9 100644 --- a/test/800-smali/src/Main.java +++ b/test/800-smali/src/Main.java @@ -141,6 +141,8 @@ public class Main { null)); testCases.add(new TestCase("b/21869691", "B21869691A", "run", null, new IncompatibleClassChangeError(), null)); + testCases.add(new TestCase("b/26143249", "B26143249", "run", null, + new AbstractMethodError(), null)); } public void runTests() { diff --git a/test/Android.libarttest.mk b/test/Android.libarttest.mk index f74a516486..f84dfe671e 100644 --- a/test/Android.libarttest.mk +++ b/test/Android.libarttest.mk @@ -38,7 +38,8 @@ LIBARTTEST_COMMON_SRC_FILES := \ 461-get-reference-vreg/get_reference_vreg_jni.cc \ 466-get-live-vreg/get_live_vreg_jni.cc \ 497-inlining-and-class-loader/clear_dex_cache.cc \ - 543-env-long-ref/env_long_ref.cc + 543-env-long-ref/env_long_ref.cc \ + 554-jit-profile-file/offline_profile.cc ART_TARGET_LIBARTTEST_$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libarttest.so ART_TARGET_LIBARTTEST_$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libarttestd.so diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 0925d36058..54ceb753fe 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -276,7 +276,8 @@ TEST_ART_BROKEN_NO_PREBUILD_TESTS := TEST_ART_BROKEN_NO_RELOCATE_TESTS := \ 117-nopatchoat \ 118-noimage-dex2oat \ - 119-noimage-patchoat + 119-noimage-patchoat \ + 554-jit-profile-file ifneq (,$(filter no-relocate,$(RELOCATE_TYPES))) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ @@ -298,6 +299,7 @@ TEST_ART_BROKEN_INTERPRETER_ACCESS_CHECK_TESTS := \ 412-new-array \ 471-uninitialized-locals \ 506-verify-aput \ + 554-jit-profile-file \ 800-smali ifneq (,$(filter interp-ac,$(COMPILER_TYPES))) @@ -356,13 +358,15 @@ ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),ndebug,$(PREB # All these tests check that we have sane behavior if we don't have a patchoat or dex2oat. # Therefore we shouldn't run them in situations where we actually don't have these since they # explicitly test for them. These all also assume we have an image. +# 554-jit-profile-file is disabled because it needs a primary oat file to know what it should save. TEST_ART_BROKEN_FALLBACK_RUN_TESTS := \ 116-nodex2oat \ 117-nopatchoat \ 118-noimage-dex2oat \ 119-noimage-patchoat \ 137-cfi \ - 138-duplicate-classes-check2 + 138-duplicate-classes-check2 \ + 554-jit-profile-file # This test fails without an image. TEST_ART_BROKEN_NO_IMAGE_RUN_TESTS := \ @@ -413,7 +417,8 @@ endif # Known broken tests for the interpreter. # CFI unwinding expects managed frames. TEST_ART_BROKEN_INTERPRETER_RUN_TESTS := \ - 137-cfi + 137-cfi \ + 554-jit-profile-file ifneq (,$(filter interpreter,$(COMPILER_TYPES))) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ @@ -454,6 +459,7 @@ TEST_ART_BROKEN_OPTIMIZING_MIPS_RUN_TESTS := \ 441-checker-inliner \ 510-checker-try-catch \ 536-checker-intrinsic-optimization \ + 557-checker-instruction-simplifier-ror \ ifeq (mips,$(TARGET_ARCH)) ifneq (,$(filter optimizing,$(COMPILER_TYPES))) @@ -466,6 +472,21 @@ endif TEST_ART_BROKEN_OPTIMIZING_MIPS_RUN_TESTS := +# Known broken tests for the mips64 optimizing compiler backend. +TEST_ART_BROKEN_OPTIMIZING_MIPS64_RUN_TESTS := \ + 557-checker-instruction-simplifier-ror \ + +ifeq (mips64,$(TARGET_ARCH)) + ifneq (,$(filter optimizing,$(COMPILER_TYPES))) + ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \ + optimizing,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \ + $(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), \ + $(TEST_ART_BROKEN_OPTIMIZING_MIPS64_RUN_TESTS),$(ALL_ADDRESS_SIZES)) + endif +endif + +TEST_ART_BROKEN_OPTIMIZING_MIPS64_RUN_TESTS := + # Tests that should fail when the optimizing compiler compiles them non-debuggable. TEST_ART_BROKEN_OPTIMIZING_NONDEBUGGABLE_RUN_TESTS := \ 454-get-vreg \ @@ -493,12 +514,17 @@ TEST_ART_BROKEN_OPTIMIZING_DEBUGGABLE_RUN_TESTS := # Tests that should fail in the read barrier configuration. # 055: Exceeds run time limits due to read barrier instrumentation. # 137: Read barrier forces interpreter. Cannot run this with the interpreter. +# 484: Baker's fast path based read barrier compiler instrumentation generates code containing +# more parallel moves (at least on x86), thus some Checker assertions may fail. # 537: Expects an array copy to be intrinsified, but calling-on-slowpath intrinsics are not yet # handled in the read barrier configuration. +# 554: Cannot run in interpreter mode and this rule covers both: the compiler and the interpreter. TEST_ART_BROKEN_READ_BARRIER_RUN_TESTS := \ 055-enum-performance \ 137-cfi \ - 537-checker-arraycopy + 484-checker-register-hints \ + 537-checker-arraycopy \ + 554-jit-profile-file ifeq ($(ART_USE_READ_BARRIER),true) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), \ @@ -520,7 +546,8 @@ TEST_ART_BROKEN_OPTIMIZING_HEAP_POISONING_RUN_TESTS := \ # Tests that should fail in the heap poisoning configuration with the interpreter. # 137: Cannot run this with the interpreter. TEST_ART_BROKEN_INTERPRETER_HEAP_POISONING_RUN_TESTS := \ - 137-cfi + 137-cfi \ + 554-jit-profile-file ifeq ($(ART_HEAP_POISONING),true) ifneq (,$(filter default,$(COMPILER_TYPES))) diff --git a/test/dexdump/bytecodes.txt b/test/dexdump/bytecodes.txt index d14c47c886..4c8b79b7dd 100755 --- a/test/dexdump/bytecodes.txt +++ b/test/dexdump/bytecodes.txt @@ -196,6 +196,7 @@ Class #4 - name : 'icon' type : 'I' access : 0x0019 (PUBLIC STATIC FINAL) + value : 2130837504 Instance fields - Direct methods - #0 : (in Lcom/google/android/test/R$drawable;) diff --git a/test/dexdump/bytecodes.xml b/test/dexdump/bytecodes.xml index 0581677f6a..d08c2e929c 100755 --- a/test/dexdump/bytecodes.xml +++ b/test/dexdump/bytecodes.xml @@ -3,6 +3,7 @@ > <class name="SuppressLint" extends="java.lang.Object" + interface="true" abstract="true" static="false" final="false" @@ -23,6 +24,7 @@ </class> <class name="TargetApi" extends="java.lang.Object" + interface="true" abstract="true" static="false" final="false" @@ -46,6 +48,7 @@ > <class name="BuildConfig" extends="java.lang.Object" + interface="false" abstract="false" static="false" final="true" @@ -70,6 +73,7 @@ </class> <class name="R.attr" extends="java.lang.Object" + interface="false" abstract="false" static="false" final="true" @@ -85,6 +89,7 @@ </class> <class name="R.drawable" extends="java.lang.Object" + interface="false" abstract="false" static="false" final="true" @@ -97,6 +102,7 @@ static="true" final="true" visibility="public" + value="2130837504" > </field> <constructor name="R.drawable" @@ -109,6 +115,7 @@ </class> <class name="R" extends="java.lang.Object" + interface="false" abstract="false" static="false" final="true" @@ -124,6 +131,7 @@ </class> <class name="Test" extends="android.app.Activity" + interface="false" abstract="false" static="false" final="false" diff --git a/test/dexdump/checkers.xml b/test/dexdump/checkers.xml index 232254fd2a..4e56ea2d66 100755 --- a/test/dexdump/checkers.xml +++ b/test/dexdump/checkers.xml @@ -3,6 +3,7 @@ > <class name="Checkers" extends="android.app.Activity" + interface="false" abstract="false" static="false" final="false" @@ -112,6 +113,7 @@ </class> <class name="CheckersView" extends="android.view.View" + interface="false" abstract="false" static="false" final="false" @@ -331,6 +333,7 @@ </class> <class name="a" extends="java.lang.Thread" + interface="false" abstract="false" static="false" final="true" @@ -500,6 +503,7 @@ </class> <class name="g" extends="java.lang.Object" + interface="false" abstract="false" static="false" final="true" diff --git a/test/dexdump/staticfields.dex b/test/dexdump/staticfields.dex Binary files differnew file mode 100644 index 0000000000..a07c46ef59 --- /dev/null +++ b/test/dexdump/staticfields.dex diff --git a/test/dexdump/staticfields.lst b/test/dexdump/staticfields.lst new file mode 100644 index 0000000000..5375b8e0dc --- /dev/null +++ b/test/dexdump/staticfields.lst @@ -0,0 +1,2 @@ +#staticfields.dex +0x000001bc 8 StaticFields <init> ()V StaticFields.java 24 diff --git a/test/dexdump/staticfields.txt b/test/dexdump/staticfields.txt new file mode 100644 index 0000000000..022605f90d --- /dev/null +++ b/test/dexdump/staticfields.txt @@ -0,0 +1,126 @@ +Processing 'staticfields.dex'... +Opened 'staticfields.dex', DEX version '035' +DEX file header: +magic : 'dex\n035\0' +checksum : 52d4fc6d +signature : 6e82...2f27 +file_size : 1264 +header_size : 112 +link_size : 0 +link_off : 0 (0x000000) +string_ids_size : 28 +string_ids_off : 112 (0x000070) +type_ids_size : 12 +type_ids_off : 224 (0x0000e0) +proto_ids_size : 1 +proto_ids_off : 272 (0x000110) +field_ids_size : 12 +field_ids_off : 284 (0x00011c) +method_ids_size : 2 +method_ids_off : 380 (0x00017c) +class_defs_size : 1 +class_defs_off : 396 (0x00018c) +data_size : 836 +data_off : 428 (0x0001ac) + +Class #0 header: +class_idx : 6 +access_flags : 1 (0x0001) +superclass_idx : 7 +interfaces_off : 0 (0x000000) +source_file_idx : 11 +annotations_off : 0 (0x000000) +class_data_off : 1067 (0x00042b) +static_fields_size : 12 +instance_fields_size: 0 +direct_methods_size : 1 +virtual_methods_size: 0 + +Class #0 - + Class descriptor : 'LStaticFields;' + Access flags : 0x0001 (PUBLIC) + Superclass : 'Ljava/lang/Object;' + Interfaces - + Static fields - + #0 : (in LStaticFields;) + name : 'test00_public_static_final_byte_42' + type : 'B' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 42 + #1 : (in LStaticFields;) + name : 'test01_public_static_final_short_43' + type : 'S' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 43 + #2 : (in LStaticFields;) + name : 'test02_public_static_final_char_X' + type : 'C' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 88 + #3 : (in LStaticFields;) + name : 'test03_public_static_final_int_44' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 44 + #4 : (in LStaticFields;) + name : 'test04_public_static_final_long_45' + type : 'J' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 45 + #5 : (in LStaticFields;) + name : 'test05_public_static_final_float_46_47' + type : 'F' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 46.470001 + #6 : (in LStaticFields;) + name : 'test06_public_static_final_double_48_49' + type : 'D' + access : 0x0019 (PUBLIC STATIC FINAL) + value : 48.490000 + #7 : (in LStaticFields;) + name : 'test07_public_static_final_string' + type : 'Ljava/lang/String;' + access : 0x0019 (PUBLIC STATIC FINAL) + value : "abc \\><\"'&\t\r\n" + #8 : (in LStaticFields;) + name : 'test08_public_static_final_object_null' + type : 'Ljava/lang/Object;' + access : 0x0019 (PUBLIC STATIC FINAL) + value : null + #9 : (in LStaticFields;) + name : 'test09_public_static_final_boolean_true' + type : 'Z' + access : 0x0019 (PUBLIC STATIC FINAL) + value : true + #10 : (in LStaticFields;) + name : 'test10_private_static_final_int_50' + type : 'I' + access : 0x001a (PRIVATE STATIC FINAL) + value : 50 + #11 : (in LStaticFields;) + name : 'test99_empty_value' + type : 'I' + access : 0x0019 (PUBLIC STATIC FINAL) + Instance fields - + Direct methods - + #0 : (in LStaticFields;) + name : '<init>' + type : '()V' + access : 0x10001 (PUBLIC CONSTRUCTOR) + code - + registers : 1 + ins : 1 + outs : 1 + insns size : 4 16-bit code units +0001ac: |[0001ac] StaticFields.<init>:()V +0001bc: 7010 0100 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // method@0001 +0001c2: 0e00 |0003: return-void + catches : (none) + positions : + 0x0000 line=24 + locals : + 0x0000 - 0x0004 reg=0 this LStaticFields; + + Virtual methods - + source_file_idx : 11 (StaticFields.java) + diff --git a/test/dexdump/staticfields.xml b/test/dexdump/staticfields.xml new file mode 100644 index 0000000000..c906f0a3dd --- /dev/null +++ b/test/dexdump/staticfields.xml @@ -0,0 +1,130 @@ +<api> +<package name="" +> +<class name="StaticFields" + extends="java.lang.Object" + interface="false" + abstract="false" + static="false" + final="false" + visibility="public" +> +<field name="test00_public_static_final_byte_42" + type="byte" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="42" +> +</field> +<field name="test01_public_static_final_short_43" + type="short" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="43" +> +</field> +<field name="test02_public_static_final_char_X" + type="char" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="88" +> +</field> +<field name="test03_public_static_final_int_44" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="44" +> +</field> +<field name="test04_public_static_final_long_45" + type="long" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="45" +> +</field> +<field name="test05_public_static_final_float_46_47" + type="float" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="46.470001" +> +</field> +<field name="test06_public_static_final_double_48_49" + type="double" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="48.490000" +> +</field> +<field name="test07_public_static_final_string" + type="java.lang.String" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="abc \><"'&	
" +> +</field> +<field name="test08_public_static_final_object_null" + type="java.lang.Object" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="null" +> +</field> +<field name="test09_public_static_final_boolean_true" + type="boolean" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" + value="true" +> +</field> +<field name="test99_empty_value" + type="int" + transient="false" + volatile="false" + static="true" + final="true" + visibility="public" +> +</field> +<constructor name="StaticFields" + type="StaticFields" + static="false" + final="false" + visibility="public" +> +</constructor> +</class> +</package> +</api> |