Title: [193788] trunk/Source/_javascript_Core
Revision
193788
Author
mark....@apple.com
Date
2015-12-08 15:05:57 -0800 (Tue, 08 Dec 2015)

Log Message

Snippefy shift operators for the baseline JIT.
https://bugs.webkit.org/show_bug.cgi?id=151875

Reviewed by Geoffrey Garen.

* CMakeLists.txt:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
* _javascript_Core.xcodeproj/project.pbxproj:
* jit/JIT.h:

* jit/JITArithmetic.cpp:
(JSC::JIT::emitBitBinaryOpFastPath):
- Don't need GPRInfo:: qualifiers.  Removed them to reduce verbosity.
- Also removed the emitStoreInt32() case for storing the result on 32-bit ports.
  This is because:
  1. The client should not make assumptions about whether the snippet fast path
     only include cases where the result tag already contain the IntTag.
  2. The "(op1 == result || op2 == result)" condition for skipping the IntTag
     storage, is only valid for the bitand, bitor, and bitxor implementations.
     It is invalid for the lshift implementation that uses this code now.
  Instead, we'll always unconditionally store what the result tag that the
  snippet computed for us.

(JSC::JIT::emit_op_lshift):
(JSC::JIT::emitSlow_op_lshift):
(JSC::JIT::emitRightShiftFastPath):
(JSC::JIT::emit_op_rshift):
(JSC::JIT::emitSlow_op_rshift):
(JSC::JIT::emit_op_urshift):
(JSC::JIT::emitSlow_op_urshift):

* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emit_op_lshift): Deleted.
(JSC::JIT::emitSlow_op_lshift): Deleted.
(JSC::JIT::emitRightShift): Deleted.
(JSC::JIT::emitRightShiftSlowCase): Deleted.
(JSC::JIT::emit_op_rshift): Deleted.
(JSC::JIT::emitSlow_op_rshift): Deleted.
(JSC::JIT::emit_op_urshift): Deleted.
(JSC::JIT::emitSlow_op_urshift): Deleted.

* jit/JITLeftShiftGenerator.cpp: Added.
(JSC::JITLeftShiftGenerator::generateFastPath):
* jit/JITLeftShiftGenerator.h: Added.
(JSC::JITLeftShiftGenerator::JITLeftShiftGenerator):
* jit/JITRightShiftGenerator.cpp: Added.
(JSC::JITRightShiftGenerator::generateFastPath):
* jit/JITRightShiftGenerator.h: Added.
(JSC::JITRightShiftGenerator::JITRightShiftGenerator):

* tests/stress/op_lshift.js:
* tests/stress/op_rshift.js:
* tests/stress/op_urshift.js:
- Fixed some values and added others that are meaningful for testing shifts.

* tests/stress/resources/binary-op-test.js:
(stringifyIfNeeded):
(generateBinaryTests):
- Fixed the test generator to give unique names to all the generated test
  functions.  Without this, multiple tests may end up using the same global
  test function.  As a result, with enough test values to test, the function may
  get prematurely JITted, and the computed expected result which is supposed to
  be computed by the LLINT, may end up being computed by a JIT instead.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (193787 => 193788)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2015-12-08 23:05:57 UTC (rev 193788)
@@ -465,12 +465,14 @@
     jit/JITDivGenerator.cpp
     jit/JITExceptions.cpp
     jit/JITInlineCacheGenerator.cpp
+    jit/JITLeftShiftGenerator.cpp
     jit/JITMulGenerator.cpp
     jit/JITOpcodes.cpp
     jit/JITOpcodes32_64.cpp
     jit/JITOperations.cpp
     jit/JITPropertyAccess.cpp
     jit/JITPropertyAccess32_64.cpp
+    jit/JITRightShiftGenerator.cpp
     jit/JITStubRoutine.cpp
     jit/JITSubGenerator.cpp
     jit/JITThunks.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (193787 => 193788)


--- trunk/Source/_javascript_Core/ChangeLog	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-12-08 23:05:57 UTC (rev 193788)
@@ -1,3 +1,70 @@
+2015-12-08  Mark Lam  <mark....@apple.com>
+
+        Snippefy shift operators for the baseline JIT.
+        https://bugs.webkit.org/show_bug.cgi?id=151875
+
+        Reviewed by Geoffrey Garen.
+
+        * CMakeLists.txt:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * jit/JIT.h:
+
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emitBitBinaryOpFastPath):
+        - Don't need GPRInfo:: qualifiers.  Removed them to reduce verbosity.
+        - Also removed the emitStoreInt32() case for storing the result on 32-bit ports.
+          This is because:
+          1. The client should not make assumptions about whether the snippet fast path
+             only include cases where the result tag already contain the IntTag.
+          2. The "(op1 == result || op2 == result)" condition for skipping the IntTag
+             storage, is only valid for the bitand, bitor, and bitxor implementations.
+             It is invalid for the lshift implementation that uses this code now.
+          Instead, we'll always unconditionally store what the result tag that the
+          snippet computed for us.
+
+        (JSC::JIT::emit_op_lshift):
+        (JSC::JIT::emitSlow_op_lshift):
+        (JSC::JIT::emitRightShiftFastPath):
+        (JSC::JIT::emit_op_rshift):
+        (JSC::JIT::emitSlow_op_rshift):
+        (JSC::JIT::emit_op_urshift):
+        (JSC::JIT::emitSlow_op_urshift):
+
+        * jit/JITArithmetic32_64.cpp:
+        (JSC::JIT::emit_op_lshift): Deleted.
+        (JSC::JIT::emitSlow_op_lshift): Deleted.
+        (JSC::JIT::emitRightShift): Deleted.
+        (JSC::JIT::emitRightShiftSlowCase): Deleted.
+        (JSC::JIT::emit_op_rshift): Deleted.
+        (JSC::JIT::emitSlow_op_rshift): Deleted.
+        (JSC::JIT::emit_op_urshift): Deleted.
+        (JSC::JIT::emitSlow_op_urshift): Deleted.
+
+        * jit/JITLeftShiftGenerator.cpp: Added.
+        (JSC::JITLeftShiftGenerator::generateFastPath):
+        * jit/JITLeftShiftGenerator.h: Added.
+        (JSC::JITLeftShiftGenerator::JITLeftShiftGenerator):
+        * jit/JITRightShiftGenerator.cpp: Added.
+        (JSC::JITRightShiftGenerator::generateFastPath):
+        * jit/JITRightShiftGenerator.h: Added.
+        (JSC::JITRightShiftGenerator::JITRightShiftGenerator):
+
+        * tests/stress/op_lshift.js:
+        * tests/stress/op_rshift.js:
+        * tests/stress/op_urshift.js:
+        - Fixed some values and added others that are meaningful for testing shifts.
+
+        * tests/stress/resources/binary-op-test.js:
+        (stringifyIfNeeded):
+        (generateBinaryTests):
+        - Fixed the test generator to give unique names to all the generated test
+          functions.  Without this, multiple tests may end up using the same global
+          test function.  As a result, with enough test values to test, the function may
+          get prematurely JITted, and the computed expected result which is supposed to
+          be computed by the LLINT, may end up being computed by a JIT instead.
+
 2015-12-08  Joseph Pecoraro  <pecor...@apple.com>
 
         Create a Sandbox SPI header

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (193787 => 193788)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-12-08 23:05:57 UTC (rev 193788)
@@ -654,6 +654,7 @@
     <ClCompile Include="..\jit\JITDivGenerator.cpp" />
     <ClCompile Include="..\jit\JITExceptions.cpp" />
     <ClCompile Include="..\jit\JITInlineCacheGenerator.cpp" />
+    <ClCompile Include="..\jit\JITLeftShiftGenerator.cpp" />
     <ClCompile Include="..\jit\JITMulGenerator.cpp" />
     <ClCompile Include="..\jit\JITOpcodes.cpp" />
     <ClCompile Include="..\jit\JITOpcodes32_64.cpp" />
@@ -661,6 +662,7 @@
     <ClCompile Include="..\jit\JITOperationsMSVC64.cpp" />
     <ClCompile Include="..\jit\JITPropertyAccess.cpp" />
     <ClCompile Include="..\jit\JITPropertyAccess32_64.cpp" />
+    <ClCompile Include="..\jit\JITRightShiftGenerator.cpp" />
     <ClCompile Include="..\jit\JITStubRoutine.cpp" />
     <ClCompile Include="..\jit\JITSubGenerator.cpp" />
     <ClCompile Include="..\jit\JITThunks.cpp" />
@@ -1486,8 +1488,10 @@
     <ClInclude Include="..\jit\JITExceptions.h" />
     <ClInclude Include="..\jit\JITInlineCacheGenerator.h" />
     <ClInclude Include="..\jit\JITInlines.h" />
+    <ClInclude Include="..\jit\JITLeftShiftGenerator.h" />
     <ClInclude Include="..\jit\JITMulGenerator.h" />
     <ClInclude Include="..\jit\JITOperations.h" />
+    <ClInclude Include="..\jit\JITRightShiftGenerator.h" />
     <ClInclude Include="..\jit\JITStubRoutine.h" />
     <ClInclude Include="..\jit\JITSubGenerator.h" />
     <ClInclude Include="..\jit\JITThunks.h" />

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (193787 => 193788)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters	2015-12-08 23:05:57 UTC (rev 193788)
@@ -456,6 +456,9 @@
     <ClCompile Include="..\jit\JITExceptions.cpp">
       <Filter>jit</Filter>
     </ClCompile>
+    <ClCompile Include="..\jit\JITLeftShiftGenerator.cpp">
+      <Filter>jit</Filter>
+    </ClCompile>
     <ClCompile Include="..\jit\JITMulGenerator.cpp">
       <Filter>jit</Filter>
     </ClCompile>
@@ -471,6 +474,9 @@
     <ClCompile Include="..\jit\JITPropertyAccess32_64.cpp">
       <Filter>jit</Filter>
     </ClCompile>
+    <ClCompile Include="..\jit\JITRightShiftGenerator.cpp">
+      <Filter>jit</Filter>
+    </ClCompile>
     <ClCompile Include="..\jit\JITStubRoutine.cpp">
       <Filter>jit</Filter>
     </ClCompile>
@@ -2567,9 +2573,15 @@
     <ClInclude Include="..\jit\JITInlines.h">
       <Filter>jit</Filter>
     </ClInclude>
+    <ClInclude Include="..\jit\JITLeftShiftGenerator.h">
+      <Filter>jit</Filter>
+    </ClInclude>
     <ClInclude Include="..\jit\JITMulGenerator.h">
       <Filter>jit</Filter>
     </ClInclude>
+    <ClInclude Include="..\jit\JITRightShiftGenerator.h">
+      <Filter>jit</Filter>
+    </ClInclude>
     <ClInclude Include="..\jit\JITStubRoutine.h">
       <Filter>jit</Filter>
     </ClInclude>

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (193787 => 193788)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-12-08 23:05:57 UTC (rev 193788)
@@ -2022,6 +2022,10 @@
 		FE3A06B21C10CB8900390FDD /* JITBitAndGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */; settings = {ASSET_TAGS = (); }; };
 		FE3A06B31C10CB8E00390FDD /* JITBitXorGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
 		FE3A06B41C10CB9300390FDD /* JITBitXorGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */; settings = {ASSET_TAGS = (); }; };
+		FE3A06BD1C11040D00390FDD /* JITLeftShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B61C1103D900390FDD /* JITLeftShiftGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
+		FE3A06BE1C11041200390FDD /* JITLeftShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B71C1103D900390FDD /* JITLeftShiftGenerator.h */; settings = {ASSET_TAGS = (); }; };
+		FE3A06BF1C11041600390FDD /* JITRightShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
+		FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */; settings = {ASSET_TAGS = (); }; };
 		FE4238901BE18C3C00514737 /* JITSubGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */; };
 		FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
 		FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */; };
@@ -4203,6 +4207,10 @@
 		FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITBitAndGenerator.h; sourceTree = "<group>"; };
 		FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITBitXorGenerator.cpp; sourceTree = "<group>"; };
 		FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITBitXorGenerator.h; sourceTree = "<group>"; };
+		FE3A06B61C1103D900390FDD /* JITLeftShiftGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITLeftShiftGenerator.cpp; sourceTree = "<group>"; };
+		FE3A06B71C1103D900390FDD /* JITLeftShiftGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITLeftShiftGenerator.h; sourceTree = "<group>"; };
+		FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITRightShiftGenerator.cpp; sourceTree = "<group>"; };
+		FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITRightShiftGenerator.h; sourceTree = "<group>"; };
 		FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITSubGenerator.cpp; sourceTree = "<group>"; };
 		FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionOverrides.cpp; sourceTree = "<group>"; };
 		FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionOverrides.h; sourceTree = "<group>"; };
@@ -4902,6 +4910,8 @@
 				0FB14E1C18124ACE009B6B4D /* JITInlineCacheGenerator.cpp */,
 				0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */,
 				86CC85A00EE79A4700288682 /* JITInlines.h */,
+				FE3A06B61C1103D900390FDD /* JITLeftShiftGenerator.cpp */,
+				FE3A06B71C1103D900390FDD /* JITLeftShiftGenerator.h */,
 				FE1879FF1BFBC73C0038BBCA /* JITMulGenerator.cpp */,
 				FE187A001BFBC73C0038BBCA /* JITMulGenerator.h */,
 				BCDD51E90FB8DF74004A8BDC /* JITOpcodes.cpp */,
@@ -4910,6 +4920,8 @@
 				0F24E54617EE274900ABB217 /* JITOperations.h */,
 				86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */,
 				A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */,
+				FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */,
+				FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */,
 				0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */,
 				0F766D1C15A5028D008F363E /* JITStubRoutine.h */,
 				FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */,
@@ -6801,6 +6813,7 @@
 				A5EA70E919F5B1010098F5EC /* AlternateDispatchableAgent.h in Headers */,
 				2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */,
 				BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
+				FE3A06BE1C11041200390FDD /* JITLeftShiftGenerator.h in Headers */,
 				BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
 				0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
 				0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
@@ -7310,6 +7323,7 @@
 				C4703CD5192844CC0013FBEA /* generator_templates.py in Headers */,
 				0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */,
 				0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */,
+				FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */,
 				0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */,
 				0F2B66E017B6B5AB00A7AE3F /* GenericTypedArrayView.h in Headers */,
 				0F2B66E117B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h in Headers */,
@@ -8831,6 +8845,7 @@
 				A1B9E23D1B4E0D6700BC7FED /* IntlCollatorPrototype.cpp in Sources */,
 				A1587D6D1B4DC14100D69849 /* IntlDateTimeFormat.cpp in Sources */,
 				A1587D6F1B4DC14100D69849 /* IntlDateTimeFormatConstructor.cpp in Sources */,
+				FE3A06BF1C11041600390FDD /* JITRightShiftGenerator.cpp in Sources */,
 				262D85B61C0D650F006ACB61 /* AirFixPartialRegisterStalls.cpp in Sources */,
 				70B7919B1C024A46002481E2 /* JSGeneratorFunction.cpp in Sources */,
 				A1587D711B4DC14100D69849 /* IntlDateTimeFormatPrototype.cpp in Sources */,
@@ -8985,6 +9000,7 @@
 				0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
 				A5AB49DC1BEC8082007020FB /* PerGlobalObjectWrapperWorld.cpp in Sources */,
 				14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */,
+				FE3A06BD1C11040D00390FDD /* JITLeftShiftGenerator.cpp in Sources */,
 				0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */,
 				86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */,
 				FEB137571BB11EF900CD5100 /* MacroAssemblerARM64.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/jit/JIT.h (193787 => 193788)


--- trunk/Source/_javascript_Core/jit/JIT.h	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2015-12-08 23:05:57 UTC (rev 193788)
@@ -830,6 +830,12 @@
         template<typename SnippetGenerator>
         void emitBitBinaryOpFastPath(Instruction* currentInstruction);
 
+        enum RightShiftType {
+            SignedShift,
+            UnsignedShift
+        };
+        void emitRightShiftFastPath(Instruction* currentInstruction, RightShiftType);
+
         Jump checkStructure(RegisterID reg, Structure* structure);
 
         void updateTopCallFrame();

Modified: trunk/Source/_javascript_Core/jit/JITArithmetic.cpp (193787 => 193788)


--- trunk/Source/_javascript_Core/jit/JITArithmetic.cpp	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/jit/JITArithmetic.cpp	2015-12-08 23:05:57 UTC (rev 193788)
@@ -35,8 +35,10 @@
 #include "JITBitXorGenerator.h"
 #include "JITDivGenerator.h"
 #include "JITInlines.h"
+#include "JITLeftShiftGenerator.h"
 #include "JITMulGenerator.h"
 #include "JITOperations.h"
+#include "JITRightShiftGenerator.h"
 #include "JITSubGenerator.h"
 #include "JSArray.h"
 #include "JSFunction.h"
@@ -228,141 +230,6 @@
     slowPathCall.call();
 }
 
-void JIT::emit_op_lshift(Instruction* currentInstruction)
-{
-    int result = currentInstruction[1].u.operand;
-    int op1 = currentInstruction[2].u.operand;
-    int op2 = currentInstruction[3].u.operand;
-
-    emitGetVirtualRegisters(op1, regT0, op2, regT2);
-    // FIXME: would we be better using a 'emitJumpSlowCaseIfNotInt' that tests both values at once? - we *probably* ought to be consistent.
-    emitJumpSlowCaseIfNotInt(regT0);
-    emitJumpSlowCaseIfNotInt(regT2);
-    lshift32(regT2, regT0);
-    emitTagInt(regT0, regT0);
-    emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    linkSlowCase(iter);
-    linkSlowCase(iter);
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_lshift);
-    slowPathCall.call();
-}
-
-void JIT::emit_op_rshift(Instruction* currentInstruction)
-{
-    int result = currentInstruction[1].u.operand;
-    int op1 = currentInstruction[2].u.operand;
-    int op2 = currentInstruction[3].u.operand;
-
-    if (isOperandConstantInt(op2)) {
-        // isOperandConstantInt(op2) => 1 SlowCase
-        emitGetVirtualRegister(op1, regT0);
-        emitJumpSlowCaseIfNotInt(regT0);
-        // Mask with 0x1f as per ecma-262 11.7.2 step 7.
-        rshift32(Imm32(getOperandConstantInt(op2) & 0x1f), regT0);
-    } else {
-        emitGetVirtualRegisters(op1, regT0, op2, regT2);
-        if (supportsFloatingPointTruncate()) {
-            Jump lhsIsInt = emitJumpIfInt(regT0);
-            // supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases
-            addSlowCase(emitJumpIfNotNumber(regT0));
-            add64(tagTypeNumberRegister, regT0);
-            move64ToDouble(regT0, fpRegT0);
-            addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
-            lhsIsInt.link(this);
-            emitJumpSlowCaseIfNotInt(regT2);
-        } else {
-            // !supportsFloatingPoint() => 2 SlowCases
-            emitJumpSlowCaseIfNotInt(regT0);
-            emitJumpSlowCaseIfNotInt(regT2);
-        }
-        rshift32(regT2, regT0);
-    }
-    emitTagInt(regT0, regT0);
-    emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    int op2 = currentInstruction[3].u.operand;
-
-    if (isOperandConstantInt(op2))
-        linkSlowCase(iter);
-
-    else {
-        if (supportsFloatingPointTruncate()) {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-        } else {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-        }
-    }
-
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_rshift);
-    slowPathCall.call();
-}
-
-void JIT::emit_op_urshift(Instruction* currentInstruction)
-{
-    int result = currentInstruction[1].u.operand;
-    int op1 = currentInstruction[2].u.operand;
-    int op2 = currentInstruction[3].u.operand;
-
-    if (isOperandConstantInt(op2)) {
-        // isOperandConstantInt(op2) => 1 SlowCase
-        emitGetVirtualRegister(op1, regT0);
-        emitJumpSlowCaseIfNotInt(regT0);
-        // Mask with 0x1f as per ecma-262 11.7.2 step 7.
-        urshift32(Imm32(getOperandConstantInt(op2) & 0x1f), regT0);
-    } else {
-        emitGetVirtualRegisters(op1, regT0, op2, regT2);
-        if (supportsFloatingPointTruncate()) {
-            Jump lhsIsInt = emitJumpIfInt(regT0);
-            // supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases
-            addSlowCase(emitJumpIfNotNumber(regT0));
-            add64(tagTypeNumberRegister, regT0);
-            move64ToDouble(regT0, fpRegT0);
-            addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
-            lhsIsInt.link(this);
-            emitJumpSlowCaseIfNotInt(regT2);
-        } else {
-            // !supportsFloatingPoint() => 2 SlowCases
-            emitJumpSlowCaseIfNotInt(regT0);
-            emitJumpSlowCaseIfNotInt(regT2);
-        }
-        urshift32(regT2, regT0);
-    }
-    emitTagInt(regT0, regT0);
-    emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    int op2 = currentInstruction[3].u.operand;
-
-    if (isOperandConstantInt(op2))
-        linkSlowCase(iter);
-
-    else {
-        if (supportsFloatingPointTruncate()) {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-        } else {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-        }
-    }
-
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_urshift);
-    slowPathCall.call();
-}
-
 void JIT::emit_op_unsigned(Instruction* currentInstruction)
 {
     int result = currentInstruction[1].u.operand;
@@ -639,13 +506,13 @@
     int op2 = currentInstruction[3].u.operand;
 
 #if USE(JSVALUE64)
-    JSValueRegs leftRegs = JSValueRegs(GPRInfo::regT0);
-    JSValueRegs rightRegs = JSValueRegs(GPRInfo::regT1);
+    JSValueRegs leftRegs = JSValueRegs(regT0);
+    JSValueRegs rightRegs = JSValueRegs(regT1);
     JSValueRegs resultRegs = leftRegs;
     GPRReg scratchGPR = GPRInfo::regT2;
 #else
-    JSValueRegs leftRegs = JSValueRegs(GPRInfo::regT1, GPRInfo::regT0);
-    JSValueRegs rightRegs = JSValueRegs(GPRInfo::regT3, GPRInfo::regT2);
+    JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
+    JSValueRegs rightRegs = JSValueRegs(regT3, regT2);
     JSValueRegs resultRegs = leftRegs;
     GPRReg scratchGPR = InvalidGPRReg;
 #endif
@@ -671,11 +538,7 @@
 
     if (gen.didEmitFastPath()) {
         gen.endJumpList().link(this);
-#if USE(JSVALUE32_64)
-        emitStoreInt32(result, resultRegs.payloadGPR(), op1 == result || op2 == result);
-#else
         emitPutVirtualRegister(result, resultRegs);
-#endif
 
         addSlowCase(gen.slowPathJumpList());
     } else {
@@ -725,6 +588,101 @@
     slowPathCall.call();
 }
 
+void JIT::emit_op_lshift(Instruction* currentInstruction)
+{
+    emitBitBinaryOpFastPath<JITLeftShiftGenerator>(currentInstruction);
+}
+
+void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
+
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_lshift);
+    slowPathCall.call();
+}
+
+void JIT::emitRightShiftFastPath(Instruction* currentInstruction, RightShiftType rightShiftType)
+{
+    int result = currentInstruction[1].u.operand;
+    int op1 = currentInstruction[2].u.operand;
+    int op2 = currentInstruction[3].u.operand;
+
+#if USE(JSVALUE64)
+    JSValueRegs leftRegs = JSValueRegs(regT0);
+    JSValueRegs rightRegs = JSValueRegs(regT1);
+    JSValueRegs resultRegs = leftRegs;
+    GPRReg scratchGPR = regT2;
+    FPRReg scratchFPR = InvalidFPRReg;
+#else
+    JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
+    JSValueRegs rightRegs = JSValueRegs(regT3, regT2);
+    JSValueRegs resultRegs = leftRegs;
+    GPRReg scratchGPR = regT4;
+    FPRReg scratchFPR = fpRegT2;
+#endif
+
+    SnippetOperand leftOperand;
+    SnippetOperand rightOperand;
+
+    if (isOperandConstantInt(op1))
+        leftOperand.setConstInt32(getOperandConstantInt(op1));
+    if (isOperandConstantInt(op2))
+        rightOperand.setConstInt32(getOperandConstantInt(op2));
+
+    RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
+
+    if (!leftOperand.isConst())
+        emitGetVirtualRegister(op1, leftRegs);
+    if (!rightOperand.isConst())
+        emitGetVirtualRegister(op2, rightRegs);
+
+    JITRightShiftGenerator::ShiftType snippetShiftType =
+        (rightShiftType == SignedShift) ? JITRightShiftGenerator::SignedShift : JITRightShiftGenerator::UnsignedShift;
+
+    JITRightShiftGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs,
+        fpRegT0, scratchGPR, scratchFPR, snippetShiftType);
+
+    gen.generateFastPath(*this);
+
+    if (gen.didEmitFastPath()) {
+        gen.endJumpList().link(this);
+        emitPutVirtualRegister(result, resultRegs);
+
+        addSlowCase(gen.slowPathJumpList());
+    } else {
+        ASSERT(gen.endJumpList().empty());
+        ASSERT(gen.slowPathJumpList().empty());
+        JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add);
+        slowPathCall.call();
+    }
+}
+
+void JIT::emit_op_rshift(Instruction* currentInstruction)
+{
+    emitRightShiftFastPath(currentInstruction, RightShiftType::SignedShift);
+}
+
+void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
+
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_rshift);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_urshift(Instruction* currentInstruction)
+{
+    emitRightShiftFastPath(currentInstruction, RightShiftType::UnsignedShift);
+}
+
+void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
+
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_urshift);
+    slowPathCall.call();
+}
+
 void JIT::emit_op_add(Instruction* currentInstruction)
 {
     int result = currentInstruction[1].u.operand;

Modified: trunk/Source/_javascript_Core/jit/JITArithmetic32_64.cpp (193787 => 193788)


--- trunk/Source/_javascript_Core/jit/JITArithmetic32_64.cpp	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/jit/JITArithmetic32_64.cpp	2015-12-08 23:05:57 UTC (rev 193788)
@@ -154,155 +154,6 @@
     emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, returnValueGPR), target);
 }
 
-// LeftShift (<<)
-
-void JIT::emit_op_lshift(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int op1 = currentInstruction[2].u.operand;
-    int op2 = currentInstruction[3].u.operand;
-
-    if (isOperandConstantInt(op2)) {
-        emitLoad(op1, regT1, regT0);
-        addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-        lshift32(Imm32(getConstantOperand(op2).asInt32()), regT0);
-        emitStoreInt32(dst, regT0, dst == op1);
-        return;
-    }
-
-    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
-    if (!isOperandConstantInt(op1))
-        addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-    addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
-    lshift32(regT2, regT0);
-    emitStoreInt32(dst, regT0, dst == op1 || dst == op2);
-}
-
-void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    int op1 = currentInstruction[2].u.operand;
-    int op2 = currentInstruction[3].u.operand;
-
-    if (!isOperandConstantInt(op1) && !isOperandConstantInt(op2))
-        linkSlowCase(iter); // int32 check
-    linkSlowCase(iter); // int32 check
-
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_lshift);
-    slowPathCall.call();
-}
-
-// RightShift (>>) and UnsignedRightShift (>>>) helper
-
-void JIT::emitRightShift(Instruction* currentInstruction, bool isUnsigned)
-{
-    int dst = currentInstruction[1].u.operand;
-    int op1 = currentInstruction[2].u.operand;
-    int op2 = currentInstruction[3].u.operand;
-
-    // Slow case of rshift makes assumptions about what registers hold the
-    // shift arguments, so any changes must be updated there as well.
-    if (isOperandConstantInt(op2)) {
-        emitLoad(op1, regT1, regT0);
-        addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-        int shift = getConstantOperand(op2).asInt32() & 0x1f;
-        if (shift) {
-            if (isUnsigned)
-                urshift32(Imm32(shift), regT0);
-            else
-                rshift32(Imm32(shift), regT0);
-        }
-        emitStoreInt32(dst, regT0, dst == op1);
-    } else {
-        emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
-        if (!isOperandConstantInt(op1))
-            addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-        addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
-        if (isUnsigned)
-            urshift32(regT2, regT0);
-        else
-            rshift32(regT2, regT0);
-        emitStoreInt32(dst, regT0, dst == op1);
-    }
-}
-
-void JIT::emitRightShiftSlowCase(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool isUnsigned)
-{
-    int dst = currentInstruction[1].u.operand;
-    int op1 = currentInstruction[2].u.operand;
-    int op2 = currentInstruction[3].u.operand;
-    if (isOperandConstantInt(op2)) {
-        int shift = getConstantOperand(op2).asInt32() & 0x1f;
-        // op1 = regT1:regT0
-        linkSlowCase(iter); // int32 check
-        if (supportsFloatingPointTruncate()) {
-            JumpList failures;
-            failures.append(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
-            emitLoadDouble(op1, fpRegT0);
-            failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
-            if (shift) {
-                if (isUnsigned)
-                    urshift32(Imm32(shift), regT0);
-                else
-                    rshift32(Imm32(shift), regT0);
-            }
-            move(TrustedImm32(JSValue::Int32Tag), regT1);
-            emitStoreInt32(dst, regT0, false);
-            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
-            failures.link(this);
-        }
-    } else {
-        // op1 = regT1:regT0
-        // op2 = regT3:regT2
-        if (!isOperandConstantInt(op1)) {
-            linkSlowCase(iter); // int32 check -- op1 is not an int
-            if (supportsFloatingPointTruncate()) {
-                JumpList failures;
-                failures.append(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag))); // op1 is not a double
-                emitLoadDouble(op1, fpRegT0);
-                failures.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); // op2 is not an int
-                failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
-                if (isUnsigned)
-                    urshift32(regT2, regT0);
-                else
-                    rshift32(regT2, regT0);
-                move(TrustedImm32(JSValue::Int32Tag), regT1);
-                emitStoreInt32(dst, regT0, false);
-                emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
-                failures.link(this);
-            }
-        }
-
-        linkSlowCase(iter); // int32 check - op2 is not an int
-    }
-
-    JITSlowPathCall slowPathCall(this, currentInstruction, isUnsigned ? slow_path_urshift : slow_path_rshift);
-    slowPathCall.call();
-}
-
-// RightShift (>>)
-
-void JIT::emit_op_rshift(Instruction* currentInstruction)
-{
-    emitRightShift(currentInstruction, false);
-}
-
-void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    emitRightShiftSlowCase(currentInstruction, iter, false);
-}
-
-// UnsignedRightShift (>>>)
-
-void JIT::emit_op_urshift(Instruction* currentInstruction)
-{
-    emitRightShift(currentInstruction, true);
-}
-
-void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    emitRightShiftSlowCase(currentInstruction, iter, true);
-}
-
 void JIT::emit_op_unsigned(Instruction* currentInstruction)
 {
     int result = currentInstruction[1].u.operand;

Added: trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.cpp (0 => 193788)


--- trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.cpp	2015-12-08 23:05:57 UTC (rev 193788)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JITLeftShiftGenerator.h"
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+void JITLeftShiftGenerator::generateFastPath(CCallHelpers& jit)
+{
+    ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
+
+    m_didEmitFastPath = true;
+
+    if (m_rightOperand.isConstInt32()) {
+        // Try to do (intVar << intConstant).
+        m_slowPathJumpList.append(jit.branchIfNotInt32(m_left));
+
+        jit.moveValueRegs(m_left, m_result);
+        jit.lshift32(CCallHelpers::Imm32(m_rightOperand.asConstInt32()), m_result.payloadGPR());
+
+    } else {
+        // Try to do (intConstant << intVar) or (intVar << intVar).
+        m_slowPathJumpList.append(jit.branchIfNotInt32(m_right));
+
+        if (m_leftOperand.isConstInt32()) {
+#if USE(JSVALUE32_64)
+            jit.move(m_right.tagGPR(), m_result.tagGPR());
+#endif
+            jit.move(CCallHelpers::Imm32(m_leftOperand.asConstInt32()), m_result.payloadGPR());
+        } else {
+            m_slowPathJumpList.append(jit.branchIfNotInt32(m_left));
+            jit.moveValueRegs(m_left, m_result);
+        }
+
+        jit.lshift32(m_right.payloadGPR(), m_result.payloadGPR());
+    }
+
+#if USE(JSVALUE64)
+    jit.or64(GPRInfo::tagTypeNumberRegister, m_result.payloadGPR());
+#endif
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)

Added: trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.h (0 => 193788)


--- trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.h	2015-12-08 23:05:57 UTC (rev 193788)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JITLeftShiftGenerator_h
+#define JITLeftShiftGenerator_h
+
+#if ENABLE(JIT)
+
+#include "JITBitBinaryOpGenerator.h"
+
+namespace JSC {
+
+class JITLeftShiftGenerator : public JITBitBinaryOpGenerator {
+public:
+    JITLeftShiftGenerator(const SnippetOperand& leftOperand, const SnippetOperand& rightOperand,
+        JSValueRegs result, JSValueRegs left, JSValueRegs right, GPRReg unused = InvalidGPRReg)
+        : JITBitBinaryOpGenerator(leftOperand, rightOperand, result, left, right, unused)
+    { }
+
+    void generateFastPath(CCallHelpers&);
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITLeftShiftGenerator_h

Added: trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp (0 => 193788)


--- trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp	2015-12-08 23:05:57 UTC (rev 193788)
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JITRightShiftGenerator.h"
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+void JITRightShiftGenerator::generateFastPath(CCallHelpers& jit)
+{
+    ASSERT(m_scratchGPR != InvalidGPRReg);
+    ASSERT(m_scratchGPR != m_left.payloadGPR());
+    ASSERT(m_scratchGPR != m_right.payloadGPR());
+#if USE(JSVALUE32_64)
+    ASSERT(m_scratchGPR != m_left.tagGPR());
+    ASSERT(m_scratchGPR != m_right.tagGPR());
+    ASSERT(m_scratchFPR != InvalidFPRReg);
+#endif
+
+    ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
+
+    m_didEmitFastPath = true;
+
+    if (m_rightOperand.isConstInt32()) {
+        // Try to do (intVar >> intConstant).
+        CCallHelpers::Jump notInt = jit.branchIfNotInt32(m_left);
+
+        jit.moveValueRegs(m_left, m_result);
+        int32_t shiftAmount = m_rightOperand.asConstInt32() & 0x1f;
+        if (shiftAmount) {
+            if (m_shiftType == SignedShift)
+                jit.rshift32(CCallHelpers::Imm32(shiftAmount), m_result.payloadGPR());
+            else
+                jit.urshift32(CCallHelpers::Imm32(shiftAmount), m_result.payloadGPR());
+#if USE(JSVALUE64)
+            jit.or64(GPRInfo::tagTypeNumberRegister, m_result.payloadGPR());
+#endif
+        }
+
+        if (jit.supportsFloatingPointTruncate()) {
+            m_endJumpList.append(jit.jump()); // Terminate the above case before emitting more code.
+
+            // Try to do (doubleVar >> intConstant).
+            notInt.link(&jit);
+
+            m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
+
+            jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
+            m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
+
+            if (shiftAmount) {
+                if (m_shiftType == SignedShift)
+                    jit.rshift32(CCallHelpers::Imm32(shiftAmount), m_scratchGPR);
+                else
+                    jit.urshift32(CCallHelpers::Imm32(shiftAmount), m_scratchGPR);
+            }
+            jit.boxInt32(m_scratchGPR, m_result);
+
+        } else
+            m_slowPathJumpList.append(notInt);
+
+    } else {
+        // Try to do (intConstant >> intVar) or (intVar >> intVar).
+        m_slowPathJumpList.append(jit.branchIfNotInt32(m_right));
+
+        CCallHelpers::Jump notInt;
+        if (m_leftOperand.isConstInt32()) {
+#if USE(JSVALUE32_64)
+            jit.move(m_right.tagGPR(), m_result.tagGPR());
+#endif
+            jit.move(CCallHelpers::Imm32(m_leftOperand.asConstInt32()), m_result.payloadGPR());
+        } else {
+            notInt = jit.branchIfNotInt32(m_left);
+            jit.moveValueRegs(m_left, m_result);
+        }
+
+        if (m_shiftType == SignedShift)
+            jit.rshift32(m_right.payloadGPR(), m_result.payloadGPR());
+        else
+            jit.urshift32(m_right.payloadGPR(), m_result.payloadGPR());
+#if USE(JSVALUE64)
+        jit.or64(GPRInfo::tagTypeNumberRegister, m_result.payloadGPR());
+#endif
+        if (m_leftOperand.isConstInt32())
+            return;
+
+        if (jit.supportsFloatingPointTruncate()) {
+            m_endJumpList.append(jit.jump()); // Terminate the above case before emitting more code.
+
+            // Try to do (doubleVar >> intVar).
+            notInt.link(&jit);
+
+            m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
+            jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
+            m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
+
+            if (m_shiftType == SignedShift)
+                jit.rshift32(m_right.payloadGPR(), m_scratchGPR);
+            else
+                jit.urshift32(m_right.payloadGPR(), m_scratchGPR);
+            jit.boxInt32(m_scratchGPR, m_result);
+
+        } else
+            m_slowPathJumpList.append(notInt);
+    }
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)

Added: trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.h (0 => 193788)


--- trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.h	2015-12-08 23:05:57 UTC (rev 193788)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JITRightShiftGenerator_h
+#define JITRightShiftGenerator_h
+
+#if ENABLE(JIT)
+
+#include "JITBitBinaryOpGenerator.h"
+
+namespace JSC {
+
+class JITRightShiftGenerator : public JITBitBinaryOpGenerator {
+public:
+    enum ShiftType {
+        SignedShift,
+        UnsignedShift
+    };
+
+    JITRightShiftGenerator(const SnippetOperand& leftOperand, const SnippetOperand& rightOperand,
+        JSValueRegs result, JSValueRegs left, JSValueRegs right,
+        FPRReg leftFPR, GPRReg scratchGPR, FPRReg scratchFPR, ShiftType type = SignedShift)
+        : JITBitBinaryOpGenerator(leftOperand, rightOperand, result, left, right, scratchGPR)
+        , m_shiftType(type)
+        , m_leftFPR(leftFPR)
+        , m_scratchFPR(scratchFPR)
+    { }
+
+    void generateFastPath(CCallHelpers&);
+
+private:
+    ShiftType m_shiftType;
+    FPRReg m_leftFPR;
+    FPRReg m_scratchFPR;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITRightShiftGenerator_h

Modified: trunk/Source/_javascript_Core/tests/stress/op_lshift.js (193787 => 193788)


--- trunk/Source/_javascript_Core/tests/stress/op_lshift.js	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/tests/stress/op_lshift.js	2015-12-08 23:05:57 UTC (rev 193788)
@@ -30,6 +30,8 @@
     'negInfinity',
     '100.2', // Some random small double value.
     '-100.2',
+    '2147483647.5', // Value that will get truncated down to 0x7fffffff.
+    '-2147483647.5',
     '54294967296.2923', // Some random large double value.
     '-54294967296.2923',
 
@@ -49,8 +51,8 @@
     '-0x7fff',
     '0x10000',
     '-0x10000',
-    '0x7ffffff',
-    '-0x7ffffff',
+    '0x7fffffff',
+    '-0x7fffffff',
     '0x100000000',
     '-0x100000000',
 

Modified: trunk/Source/_javascript_Core/tests/stress/op_rshift.js (193787 => 193788)


--- trunk/Source/_javascript_Core/tests/stress/op_rshift.js	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/tests/stress/op_rshift.js	2015-12-08 23:05:57 UTC (rev 193788)
@@ -31,6 +31,8 @@
     'negInfinity',
     '100.2', // Some random small double value.
     '-100.2',
+    '2147483647.5', // Value that will get truncated down to 0x7fffffff.
+    '-2147483647.5',
     '54294967296.2923', // Some random large double value.
     '-54294967296.2923',
 
@@ -50,8 +52,8 @@
     '-0x7fff',
     '0x10000',
     '-0x10000',
-    '0x7ffffff',
-    '-0x7ffffff',
+    '0x7fffffff',
+    '-0x7fffffff',
     '0x100000000',
     '-0x100000000',
 

Modified: trunk/Source/_javascript_Core/tests/stress/op_urshift.js (193787 => 193788)


--- trunk/Source/_javascript_Core/tests/stress/op_urshift.js	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/tests/stress/op_urshift.js	2015-12-08 23:05:57 UTC (rev 193788)
@@ -31,6 +31,8 @@
     'negInfinity',
     '100.2', // Some random small double value.
     '-100.2',
+    '2147483647.5', // Value that will get truncated down to 0x7fffffff.
+    '-2147483647.5',
     '54294967296.2923', // Some random large double value.
     '-54294967296.2923',
 
@@ -50,8 +52,8 @@
     '-0x7fff',
     '0x10000',
     '-0x10000',
-    '0x7ffffff',
-    '-0x7ffffff',
+    '0x7fffffff',
+    '-0x7fffffff',
     '0x100000000',
     '-0x100000000',
 

Modified: trunk/Source/_javascript_Core/tests/stress/resources/binary-op-test.js (193787 => 193788)


--- trunk/Source/_javascript_Core/tests/stress/resources/binary-op-test.js	2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/tests/stress/resources/binary-op-test.js	2015-12-08 23:05:57 UTC (rev 193788)
@@ -34,8 +34,9 @@
 }
 
 // operandTypes are "VarVar", "VarConst", and "ConstVar".
+var funcIndex = 0;
 function generateBinaryTests(tests, opName, op, operandTypes, leftValues, rightValues) {
-    var funcName = opName + operandTypes;
+    var funcNamePrefix = opName + operandTypes;
     for (var i = 0; i < leftValues.length; i++) {
         for (var j = 0; j < rightValues.length; j++) {
             var test = { };
@@ -44,6 +45,7 @@
             test.x = eval(xStr);
             test.y = eval(yStr);
 
+            var funcName = funcNamePrefix + funcIndex++;
             if (operandTypes == "VarVar") {
                 test.signature = funcName + "(x, y) { return x " + op + " y }";
                 test.name = test.signature + " with x:" + xStr + ", y:" + yStr;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to