# HG changeset patch # User attila # Date 1409849834 -7200 # Node ID 45f9decf4fb56e5f913649de1983288212eda05b # Parent 7caec82669a440017868b7ae4e23b69e2de4ecad 8056129: AtomicInteger is treated as primitive number with optimistic compilation Reviewed-by: jlaskey, lagergren diff -r 7caec82669a4 -r 45f9decf4fb5 src/jdk/nashorn/internal/runtime/JSType.java --- a/src/jdk/nashorn/internal/runtime/JSType.java Mon Sep 08 15:51:27 2014 +0530 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Thu Sep 04 18:57:14 2014 +0200 @@ -938,11 +938,8 @@ * @return double */ public static int toInt32Optimistic(final Object obj, final int programPoint) { - if (obj != null) { - final Class clz = obj.getClass(); - if (clz == Integer.class) { - return ((Integer)obj).intValue(); - } + if (obj != null && obj.getClass() == Integer.class) { + return ((Integer)obj).intValue(); } throw new UnwarrantedOptimismException(obj, programPoint); } diff -r 7caec82669a4 -r 45f9decf4fb5 src/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java --- a/src/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java Mon Sep 08 15:51:27 2014 +0530 +++ b/src/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java Thu Sep 04 18:57:14 2014 +0200 @@ -191,19 +191,20 @@ } /** - * Returns the argument value as an int. If the argument is not a Number object that can be exactly represented as - * an int, throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code - * can use it. See {code CodeGenerator.ENSURE_INT}. + * Returns the argument value as an int. If the argument is not a wrapper for a primitive numeric type + * with a value that can be exactly represented as an int, throw an {@link UnwarrantedOptimismException}. + * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_INT}. * @param arg the original argument. * @param programPoint the program point used in the exception * @return the value of the argument as an int. - * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as an int. + * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with + * a value that can be exactly represented as an int. */ public static int ensureInt(final Object arg, final int programPoint) { // NOTE: this doesn't delegate to ensureInt(double, int) as in that case if arg were a Long, it would throw a // (potentially imprecise) Double in the UnwarrantedOptimismException. This way, it will put the correct valued // Long into the exception. - if (arg instanceof Number) { + if (isPrimitiveNumberWrapper(arg)) { final double d = ((Number)arg).doubleValue(); if (JSType.isRepresentableAsInt(d) && !JSType.isNegativeZero(d)) { return (int)d; @@ -212,6 +213,15 @@ throw new UnwarrantedOptimismException(arg, programPoint); } + private static boolean isPrimitiveNumberWrapper(final Object obj) { + if (obj == null) { + return false; + } + final Class c = obj.getClass(); + return c == Integer.class || c == Double.class || c == Long.class || + c == Float.class || c == Short.class || c == Byte.class; + } + @SuppressWarnings("unused") private static int ensureInt(final boolean arg, final int programPoint) { throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT); @@ -236,35 +246,40 @@ } /** - * Returns the argument value as a long. If the argument is not a Number object that can be exactly represented as - * a long, throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code - * can use it. See {code CodeGenerator.ENSURE_LONG}. + * Returns the argument value as a long. If the argument is not a wrapper for a primitive numeric type + * with a value that can be exactly represented as a long, throw an {@link UnwarrantedOptimismException}. + * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_LONG}. * @param arg the original argument. * @param programPoint the program point used in the exception * @return the value of the argument as a long. - * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as a long. + * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with + * a value that can be exactly represented as a long */ public static long ensureLong(final Object arg, final int programPoint) { - if (arg instanceof Long) { - // Must check for Long separately, as Long.doubleValue() isn't precise. - return ((Long)arg).longValue(); - } else if (arg instanceof Number) { - return ensureLong(((Number)arg).doubleValue(), programPoint); + if (arg != null) { + final Class c = arg.getClass(); + if (c == Long.class) { + // Must check for Long separately, as Long.doubleValue() isn't precise. + return ((Long)arg).longValue(); + } else if (c == Integer.class || c == Double.class || c == Float.class || c == Short.class || + c == Byte.class) { + return ensureLong(((Number)arg).doubleValue(), programPoint); + } } throw new UnwarrantedOptimismException(arg, programPoint); } /** - * Returns the argument value as a double. If the argument is not a Number object, throw an - * {@link UnwarrantedOptimismException}.This method is only public so that generated script code can use it. See - * {code CodeGenerator.ENSURE_NUMBER}. + * Returns the argument value as a double. If the argument is not a a wrapper for a primitive numeric type + * throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code + * can use it. See {code CodeGenerator.ENSURE_NUMBER}. * @param arg the original argument. * @param programPoint the program point used in the exception * @return the value of the argument as a double. - * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as a long. + * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type. */ public static double ensureNumber(final Object arg, final int programPoint) { - if (arg instanceof Number) { // arg == null -> false + if (isPrimitiveNumberWrapper(arg)) { return ((Number)arg).doubleValue(); } throw new UnwarrantedOptimismException(arg, programPoint); diff -r 7caec82669a4 -r 45f9decf4fb5 src/jdk/nashorn/internal/runtime/arrays/ArrayData.java --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Mon Sep 08 15:51:27 2014 +0530 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Thu Sep 04 18:57:14 2014 +0200 @@ -628,18 +628,20 @@ Class widest = Integer.class; for (final Object item : items) { - final Class itemClass = item == null ? null : item.getClass(); + if (item == null) { + return Object.class; + } + final Class itemClass = item.getClass(); if (itemClass == Long.class) { if (widest == Integer.class) { widest = Long.class; } - } else if (itemClass == Double.class) { + } else if (itemClass == Double.class || itemClass == Float.class) { if (widest == Integer.class || widest == Long.class) { widest = Double.class; } - } else if (!(item instanceof Number)) { - widest = Object.class; - break; + } else if (itemClass != Integer.class && itemClass != Short.class && itemClass != Byte.class) { + return Object.class; } } diff -r 7caec82669a4 -r 45f9decf4fb5 test/script/basic/JDK-8056129.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8056129.js Thu Sep 04 18:57:14 2014 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8056129: AtomicInteger is treated as primitive number with optimistic compilation + * + * @test + * @run + */ + +var AtomicInteger = java.util.concurrent.atomic.AtomicInteger; + +function getAtomic() { + return new AtomicInteger() +} +var x = getAtomic() +print(x instanceof AtomicInteger) + +var a = [] +a.push(x) +var y = a[0] +print(y instanceof AtomicInteger) diff -r 7caec82669a4 -r 45f9decf4fb5 test/script/basic/JDK-8056129.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8056129.js.EXPECTED Thu Sep 04 18:57:14 2014 +0200 @@ -0,0 +1,2 @@ +true +true