8024476: Octane regression on Richards
authorhannesw
Thu, 12 Sep 2013 14:02:15 +0200
changeset 19892 f20bcd3a2ce6
parent 19890 8074a56ed98f
child 19893 8855a9f9f4ae
8024476: Octane regression on Richards Reviewed-by: sundar, jlaskey
nashorn/src/jdk/nashorn/internal/runtime/JSType.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java	Wed Sep 11 22:51:34 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java	Thu Sep 12 14:02:15 2013 +0200
@@ -29,7 +29,6 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 
 import java.lang.invoke.MethodHandles;
-import java.util.Locale;
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.parser.Lexer;
@@ -40,25 +39,28 @@
  */
 public enum JSType {
     /** The undefined type */
-    UNDEFINED,
+    UNDEFINED("undefined"),
 
     /** The null type */
-    NULL,
+    NULL("object"),
 
     /** The boolean type */
-    BOOLEAN,
+    BOOLEAN("boolean"),
 
     /** The number type */
-    NUMBER,
+    NUMBER("number"),
 
     /** The string type */
-    STRING,
+    STRING("string"),
 
     /** The object type */
-    OBJECT,
+    OBJECT("object"),
 
     /** The function type */
-    FUNCTION;
+    FUNCTION("function");
+
+    /** The type name as returned by ECMAScript "typeof" operator*/
+    private final String typeName;
 
     /** Max value for an uint32 in JavaScript */
     public static final long MAX_UINT = 0xFFFF_FFFFL;
@@ -110,13 +112,21 @@
     private static final double INT32_LIMIT = 4294967296.0;
 
     /**
+     * Constructor
+     *
+     * @param typeName the type name
+     */
+    private JSType(final String typeName) {
+        this.typeName = typeName;
+    }
+
+    /**
      * The external type name as returned by ECMAScript "typeof" operator
      *
      * @return type name for this type
      */
     public final String typeName() {
-        // For NULL, "object" has to be returned!
-        return ((this == NULL) ? OBJECT : this).name().toLowerCase(Locale.ENGLISH);
+        return this.typeName;
     }
 
     /**
@@ -127,31 +137,32 @@
      * @return the JSType for the object
      */
     public static JSType of(final Object obj) {
-        if (obj == ScriptRuntime.UNDEFINED) {
-            return JSType.UNDEFINED;
+        // Order of these statements is tuned for performance (see JDK-8024476)
+        if (obj == null) {
+            return JSType.NULL;
         }
 
-        if (obj == null) {
-            return JSType.NULL;
+        if (obj instanceof ScriptObject) {
+            return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT;
         }
 
         if (obj instanceof Boolean) {
             return JSType.BOOLEAN;
         }
 
+        if (obj instanceof String || obj instanceof ConsString) {
+            return JSType.STRING;
+        }
+
         if (obj instanceof Number) {
             return JSType.NUMBER;
         }
 
-        if (obj instanceof String || obj instanceof ConsString) {
-            return JSType.STRING;
+        if (obj == ScriptRuntime.UNDEFINED) {
+            return JSType.UNDEFINED;
         }
 
-        if (Bootstrap.isCallable(obj)) {
-            return JSType.FUNCTION;
-        }
-
-        return JSType.OBJECT;
+        return Bootstrap.isCallable(obj) ? JSType.FUNCTION : JSType.OBJECT;
     }
 
     /**