Title: [91966] trunk
Revision
91966
Author
[email protected]
Date
2011-07-28 17:43:15 -0700 (Thu, 28 Jul 2011)

Log Message

Source/_javascript_Core: *_list instructions are only used in one place, where the code is wrong.
https://bugs.webkit.org/show_bug.cgi?id=65348

Patch by Oliver Hunt <[email protected]> on 2011-07-28
Reviewed by Darin Adler.

Simply remove the instructions and all users.  Speeds up the interpreter
slightly due to code motion, but otherwise has no effect (because none
of the _list instructions are ever used).

* bytecode/CodeBlock.cpp:
(JSC::isPropertyAccess):
(JSC::CodeBlock::dump):
(JSC::CodeBlock::visitStructures):
* bytecode/Instruction.h:
* bytecode/Opcode.h:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):

LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=65325
Performance tweak to parseInt

Reviewed by Oliver Hunt.

* fast/js/parseInt-expected.txt: Added.
* fast/js/parseInt.html: Added.
* fast/js/script-tests/parseInt.js: Added.
    - Added test cases.
* sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.2_parseInt/S15.1.2.2_A1_T2-expected.txt:
    - Fixed.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (91965 => 91966)


--- trunk/LayoutTests/ChangeLog	2011-07-29 00:38:32 UTC (rev 91965)
+++ trunk/LayoutTests/ChangeLog	2011-07-29 00:43:15 UTC (rev 91966)
@@ -1,3 +1,17 @@
+2011-07-28  Gavin Barraclough  <[email protected]>
+
+        https://bugs.webkit.org/show_bug.cgi?id=65325
+        Performance tweak to parseInt
+
+        Reviewed by Oliver Hunt.
+
+        * fast/js/parseInt-expected.txt: Added.
+        * fast/js/parseInt.html: Added.
+        * fast/js/script-tests/parseInt.js: Added.
+            - Added test cases.
+        * sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.2_parseInt/S15.1.2.2_A1_T2-expected.txt:
+            - Fixed.
+
 2011-07-28  Anders Carlsson  <[email protected]>
 
         Unreviewed, rolling out r88601. (Requested by Sam Weinig).

Added: trunk/LayoutTests/fast/js/parseInt-expected.txt (0 => 91966)


--- trunk/LayoutTests/fast/js/parseInt-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/parseInt-expected.txt	2011-07-29 00:43:15 UTC (rev 91966)
@@ -0,0 +1,46 @@
+Tests for the parseInt function.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS parseInt('123') is 123
+PASS parseInt('123x4') is 123
+PASS parseInt('-123') is -123
+PASS parseInt('0x123') is 0x123
+PASS parseInt('0x123x4') is 0x123
+PASS parseInt('-0x123x4') is -0x123
+PASS parseInt('-') is Number.NaN
+PASS parseInt('0x') is Number.NaN
+PASS parseInt('-0x') is Number.NaN
+PASS parseInt('123', undefined) is 123
+PASS parseInt('123', null) is 123
+PASS parseInt('123', 0) is 123
+PASS parseInt('123', 10) is 123
+PASS parseInt('123', 16) is 0x123
+PASS parseInt('0x123', undefined) is 0x123
+PASS parseInt('0x123', null) is 0x123
+PASS parseInt('0x123', 0) is 0x123
+PASS parseInt('0x123', 10) is 0
+PASS parseInt('0x123', 16) is 0x123
+PASS parseInt(Math.pow(10, 20)) is 100000000000000000000
+PASS parseInt(Math.pow(10, 21)) is 1
+PASS parseInt(Math.pow(10, -6)) is 0
+PASS parseInt(Math.pow(10, -7)) is 1
+PASS parseInt(-Math.pow(10, 20)) is -100000000000000000000
+PASS parseInt(-Math.pow(10, 21)) is -1
+PASS parseInt(-Math.pow(10, -6)) is -0
+PASS parseInt(-Math.pow(10, -7)) is -1
+PASS parseInt('0') is 0
+PASS parseInt('-0') is -0
+PASS parseInt(0) is 0
+PASS parseInt(-0) is 0
+PASS parseInt(2147483647) is 2147483647
+PASS parseInt(2147483648) is 2147483648
+PASS parseInt('2147483647') is 2147483647
+PASS parseInt('2147483648') is 2147483648
+PASS state = null; try { parseInt('123', throwingRadix); } catch (e) {} state; is "throwingRadix"
+PASS state = null; try { parseInt(throwingString, throwingRadix); } catch (e) {} state; is "throwingString"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/parseInt.html (0 => 91966)


--- trunk/LayoutTests/fast/js/parseInt.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/parseInt.html	2011-07-29 00:43:15 UTC (rev 91966)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/script-tests/parseInt.js (0 => 91966)


--- trunk/LayoutTests/fast/js/script-tests/parseInt.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/parseInt.js	2011-07-29 00:43:15 UTC (rev 91966)
@@ -0,0 +1,56 @@
+description('Tests for the parseInt function.');
+
+// Simple hex & dec integer values.
+shouldBe("parseInt('123')", '123');
+shouldBe("parseInt('123x4')", '123');
+shouldBe("parseInt('-123')", '-123');
+shouldBe("parseInt('0x123')", '0x123');
+shouldBe("parseInt('0x123x4')", '0x123');
+shouldBe("parseInt('-0x123x4')", '-0x123');
+shouldBe("parseInt('-')", 'Number.NaN');
+shouldBe("parseInt('0x')", 'Number.NaN');
+shouldBe("parseInt('-0x')", 'Number.NaN');
+
+// These call default to base 10, unless radix is explicitly 16.
+shouldBe("parseInt('123', undefined)", '123');
+shouldBe("parseInt('123', null)", '123');
+shouldBe("parseInt('123', 0)", '123');
+shouldBe("parseInt('123', 10)", '123');
+shouldBe("parseInt('123', 16)", '0x123');
+// These call default to base 16, unless radix is explicitly 10.
+shouldBe("parseInt('0x123', undefined)", '0x123');
+shouldBe("parseInt('0x123', null)", '0x123');
+shouldBe("parseInt('0x123', 0)", '0x123');
+shouldBe("parseInt('0x123', 10)", '0');
+shouldBe("parseInt('0x123', 16)", '0x123');
+
+// Test edge cases for the Number.toString exponential ranges.
+shouldBe("parseInt(Math.pow(10, 20))", '100000000000000000000');
+shouldBe("parseInt(Math.pow(10, 21))", '1');
+shouldBe("parseInt(Math.pow(10, -6))", '0');
+shouldBe("parseInt(Math.pow(10, -7))", '1');
+shouldBe("parseInt(-Math.pow(10, 20))", '-100000000000000000000');
+shouldBe("parseInt(-Math.pow(10, 21))", '-1');
+shouldBe("parseInt(-Math.pow(10, -6))", '-0');
+shouldBe("parseInt(-Math.pow(10, -7))", '-1');
+
+// Test correct handling for -0.
+shouldBe("parseInt('0')", '0');
+shouldBe("parseInt('-0')", '-0');
+shouldBe("parseInt(0)", '0');
+shouldBe("parseInt(-0)", '0');
+
+// Test edge cases of our optimized int handling.
+shouldBe("parseInt(2147483647)", '2147483647');
+shouldBe("parseInt(2147483648)", '2147483648');
+shouldBe("parseInt('2147483647')", '2147483647');
+shouldBe("parseInt('2147483648')", '2147483648');
+
+// Add test cases where the ToString/ToInt32 conversions throw.
+var state;
+var throwingRadix = { valueOf: function(){ state = "throwingRadix"; throw null; } };
+var throwingString = { toString: function(){ state = "throwingString"; throw null; } };
+shouldBe("state = null; try { parseInt('123', throwingRadix); } catch (e) {} state;", '"throwingRadix"');
+shouldBe("state = null; try { parseInt(throwingString, throwingRadix); } catch (e) {} state;", '"throwingString"');
+
+var successfullyParsed = true;

Modified: trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.2_parseInt/S15.1.2.2_A1_T2-expected.txt (91965 => 91966)


--- trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.2_parseInt/S15.1.2.2_A1_T2-expected.txt	2011-07-29 00:38:32 UTC (rev 91965)
+++ trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.2_parseInt/S15.1.2.2_A1_T2-expected.txt	2011-07-29 00:43:15 UTC (rev 91966)
@@ -1,6 +1,6 @@
 S15.1.2.2_A1_T2
 
-FAIL SputnikError: #4: parseInt(-0) === +0. Actual: 0
+PASS 
 
 TEST COMPLETE
 

Modified: trunk/Source/_javascript_Core/ChangeLog (91965 => 91966)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-29 00:38:32 UTC (rev 91965)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-29 00:43:15 UTC (rev 91966)
@@ -29,6 +29,18 @@
 
         * runtime/JSGlobalObjectFunctions.cpp:
         (JSC::globalFuncParseInt):
+            - This change may an existing optimization redundant,
+              cleanup from Darin's comments, plus fix existing bugs.
+
+2011-07-28  Gavin Barraclough  <[email protected]>
+
+        https://bugs.webkit.org/show_bug.cgi?id=65325
+        Performance tweak to parseInt
+
+        Reviewed by Oliver Hunt.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncParseInt):
             - parseInt applied to small positive numbers = floor.
 
 2011-07-28  Dan Bernstein  <[email protected]>

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (91965 => 91966)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2011-07-29 00:38:32 UTC (rev 91965)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2011-07-29 00:43:15 UTC (rev 91966)
@@ -460,29 +460,29 @@
 EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
 {
     JSValue value = exec->argument(0);
+    JSValue radixValue = exec->argument(1);
 
-    // Optimized case: If the argument is a positive number in the integer
-    // range, and the exponent is 10, then parseInt is equivalent to floor.
+    // Optimized handling for numbers:
+    // If the argument is 0 or a number in range 10^-6 <= n < INT_MAX+1, then parseInt
+    // results in a truncation to integer. In the case of -0, this is converted to 0.
+    //
+    // This is also a truncation for values in the range INT_MAX+1 <= n < 10^21,
+    // however these values cannot be trivially truncated to int since 10^21 exceeds
+    // even the int64_t range. Negative numbers are a little trickier, the case for
+    // values in the range -10^21 < n <= -1 are similar to those for integer, but
+    // values in the range -1 < n <= -10^-6 need to truncate to -0, not 0.
+    static const double tenToTheMinus6 = 0.000001;
+    static const double intMaxPlusOne = 2147483648.0;
     double n;
-    if (value.getNumber(n) && n >= 0 && n < INT_MAX && exec->argument(1).isUndefined())
-        return JSValue::encode(jsNumber(static_cast<int>(n)));
+    if (value.getNumber(n) && ((n < intMaxPlusOne && n >= tenToTheMinus6) || !n) && radixValue.isUndefinedOrNull())
+        return JSValue::encode(jsNumber(static_cast<int32_t>(n)));
 
-    int32_t radix = exec->argument(1).toInt32(exec);
+    // If ToString throws, we shouldn't call ToInt32.
+    UString s = value.toString(exec);
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
 
-    if (radix != 0 && radix != 10)
-        return JSValue::encode(jsNumber(parseInt(value.toString(exec), radix)));
-
-    if (value.isInt32())
-        return JSValue::encode(value);
-
-    if (value.isDouble()) {
-        double d = value.asDouble();
-        if (isfinite(d))
-            return JSValue::encode(jsNumber((d > 0) ? floor(d) : ceil(d)));
-        return JSValue::encode(jsNaN());
-    }
-
-    return JSValue::encode(jsNumber(parseInt(value.toString(exec), radix)));
+    return JSValue::encode(jsNumber(parseInt(s, radixValue.toInt32(exec))));
 }
 
 EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to