Changeset 193471 in webkit


Ignore:
Timestamp:
Dec 4, 2015 2:28:11 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

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

Reviewed by Geoffrey Garen.

This patch has passed the JSC tests on x86 and x86_64. It has also passed the
layout tests on x86_64.

With the DFG enabled, perf is neutral on x86_64 and x86.
With the DFG disabled on x86_64, some AsmBench tests are showing progressions e.g.

gcc-loops.cpp 1.0269x faster
stepanov_container.cpp 1.0180x faster

With the DFG disabled on x86, perf is neutral.

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::moveValueRegs):
(JSC::AssemblyHelpers::branchIfNotInt32):

  • jit/JIT.h:
  • jit/JITArithmetic.cpp:

(JSC::JIT::emitBitwiseBinaryOpFastPath):

  • Template for the bitwise operations.

(JSC::JIT::emit_op_bitand):
(JSC::JIT::emit_op_bitor):
(JSC::JIT::emit_op_bitxor):

  • Specializes emitBitwiseBinaryOpFastPath() with the respective snippet generators.

(JSC::JIT::emitSlow_op_bitand):
(JSC::JIT::emitSlow_op_bitor):
(JSC::JIT::emitSlow_op_bitxor):

  • Implement respective slow paths.
  • jit/JITArithmetic32_64.cpp:

(JSC::JIT::emit_op_bitand): Deleted.
(JSC::JIT::emitSlow_op_bitand): Deleted.
(JSC::JIT::emit_op_bitor): Deleted.
(JSC::JIT::emitSlow_op_bitor): Deleted.
(JSC::JIT::emit_op_bitxor): Deleted.
(JSC::JIT::emitSlow_op_bitxor): Deleted.

  • Now unified with the 64-bit version using snippets.
  • jit/JITBitAndGenerator.cpp: Added.

(JSC::JITBitAndGenerator::generateFastPath):

  • jit/JITBitAndGenerator.h: Added.

(JSC::JITBitAndGenerator::JITBitAndGenerator):

  • jit/JITBitOrGenerator.cpp: Added.

(JSC::JITBitOrGenerator::generateFastPath):

  • jit/JITBitOrGenerator.h: Added.

(JSC::JITBitOrGenerator::JITBitOrGenerator):

  • jit/JITBitXorGenerator.cpp: Added.

(JSC::JITBitXorGenerator::generateFastPath):

  • jit/JITBitXorGenerator.h: Added.

(JSC::JITBitXorGenerator::JITBitXorGenerator):

  • jit/JITBitwiseBinaryOpGenerator.h: Added.

(JSC::JITBitwiseBinaryOpGenerator::JITBitwiseBinaryOpGenerator):
(JSC::JITBitwiseBinaryOpGenerator::didEmitFastPath):
(JSC::JITBitwiseBinaryOpGenerator::endJumpList):
(JSC::JITBitwiseBinaryOpGenerator::slowPathJumpList):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_bitxor): Deleted.
(JSC::JIT::emit_op_bitor): Deleted.
(JSC::JIT::emitSlow_op_bitxor): Deleted.
(JSC::JIT::emitSlow_op_bitor): Deleted.

  • jit/SnippetOperand.h:

(JSC::SnippetOperand::SnippetOperand):

  • tests/stress/op_bitand.js:
  • tests/stress/op_bitor.js:
  • tests/stress/op_bitxor.js:
  • Fix a test value typo: it's supposed to be 0x7fffffff, not 0x7ffffff.
Location:
trunk/Source/JavaScriptCore
Files:
7 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r193426 r193471  
    453453    jit/JITArithmetic.cpp
    454454    jit/JITArithmetic32_64.cpp
     455    jit/JITBitAndGenerator.cpp
     456    jit/JITBitOrGenerator.cpp
     457    jit/JITBitXorGenerator.cpp
    455458    jit/JITCall.cpp
    456459    jit/JITCall32_64.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r193470 r193471  
     12015-12-04  Mark Lam  <mark.lam@apple.com>
     2
     3        Snippefy bitwise operators for the baseline JIT.
     4        https://bugs.webkit.org/show_bug.cgi?id=151680
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        This patch has passed the JSC tests on x86 and x86_64.  It has also passed the
     9        layout tests on x86_64.
     10
     11        With the DFG enabled, perf is neutral on x86_64 and x86.
     12        With the DFG disabled on x86_64, some AsmBench tests are showing progressions e.g.
     13            gcc-loops.cpp           1.0269x faster
     14            stepanov_container.cpp  1.0180x faster
     15
     16        With the DFG disabled on x86, perf is neutral.
     17
     18        * CMakeLists.txt:
     19        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     20        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     21        * JavaScriptCore.xcodeproj/project.pbxproj:
     22
     23        * jit/AssemblyHelpers.h:
     24        (JSC::AssemblyHelpers::moveValueRegs):
     25        (JSC::AssemblyHelpers::branchIfNotInt32):
     26        * jit/JIT.h:
     27        * jit/JITArithmetic.cpp:
     28        (JSC::JIT::emitBitwiseBinaryOpFastPath):
     29        - Template for the bitwise operations.
     30        (JSC::JIT::emit_op_bitand):
     31        (JSC::JIT::emit_op_bitor):
     32        (JSC::JIT::emit_op_bitxor):
     33        - Specializes emitBitwiseBinaryOpFastPath() with the respective snippet generators.
     34        (JSC::JIT::emitSlow_op_bitand):
     35        (JSC::JIT::emitSlow_op_bitor):
     36        (JSC::JIT::emitSlow_op_bitxor):
     37        - Implement respective slow paths.
     38
     39        * jit/JITArithmetic32_64.cpp:
     40        (JSC::JIT::emit_op_bitand): Deleted.
     41        (JSC::JIT::emitSlow_op_bitand): Deleted.
     42        (JSC::JIT::emit_op_bitor): Deleted.
     43        (JSC::JIT::emitSlow_op_bitor): Deleted.
     44        (JSC::JIT::emit_op_bitxor): Deleted.
     45        (JSC::JIT::emitSlow_op_bitxor): Deleted.
     46        - Now unified with the 64-bit version using snippets.
     47
     48        * jit/JITBitAndGenerator.cpp: Added.
     49        (JSC::JITBitAndGenerator::generateFastPath):
     50        * jit/JITBitAndGenerator.h: Added.
     51        (JSC::JITBitAndGenerator::JITBitAndGenerator):
     52        * jit/JITBitOrGenerator.cpp: Added.
     53        (JSC::JITBitOrGenerator::generateFastPath):
     54        * jit/JITBitOrGenerator.h: Added.
     55        (JSC::JITBitOrGenerator::JITBitOrGenerator):
     56        * jit/JITBitXorGenerator.cpp: Added.
     57        (JSC::JITBitXorGenerator::generateFastPath):
     58        * jit/JITBitXorGenerator.h: Added.
     59        (JSC::JITBitXorGenerator::JITBitXorGenerator):
     60        * jit/JITBitwiseBinaryOpGenerator.h: Added.
     61        (JSC::JITBitwiseBinaryOpGenerator::JITBitwiseBinaryOpGenerator):
     62        (JSC::JITBitwiseBinaryOpGenerator::didEmitFastPath):
     63        (JSC::JITBitwiseBinaryOpGenerator::endJumpList):
     64        (JSC::JITBitwiseBinaryOpGenerator::slowPathJumpList):
     65
     66        * jit/JITOpcodes.cpp:
     67        (JSC::JIT::emit_op_bitxor): Deleted.
     68        (JSC::JIT::emit_op_bitor): Deleted.
     69        (JSC::JIT::emitSlow_op_bitxor): Deleted.
     70        (JSC::JIT::emitSlow_op_bitor): Deleted.
     71        * jit/SnippetOperand.h:
     72        (JSC::SnippetOperand::SnippetOperand):
     73
     74        * tests/stress/op_bitand.js:
     75        * tests/stress/op_bitor.js:
     76        * tests/stress/op_bitxor.js:
     77        - Fix a test value typo: it's supposed to be 0x7fffffff, not 0x7ffffff.
     78
    1792015-12-04  Filip Pizlo  <fpizlo@apple.com>
    280
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r192937 r193471  
    645645    <ClCompile Include="..\jit\JITArithmetic.cpp" />
    646646    <ClCompile Include="..\jit\JITArithmetic32_64.cpp" />
     647    <ClCompile Include="..\jit\JITBitAndGenerator.cpp" />
     648    <ClCompile Include="..\jit\JITBitOrGenerator.cpp" />
     649    <ClCompile Include="..\jit\JITBitXorGenerator.cpp" />
    647650    <ClCompile Include="..\jit\JITCall.cpp" />
    648651    <ClCompile Include="..\jit\JITCall32_64.cpp" />
     
    14731476    <ClInclude Include="..\jit\JIT.h" />
    14741477    <ClInclude Include="..\jit\JITAddGenerator.h" />
     1478    <ClInclude Include="..\jit\JITBitAndGenerator.h" />
     1479    <ClInclude Include="..\jit\JITBitOrGenerator.h" />
     1480    <ClInclude Include="..\jit\JITBitXorGenerator.h" />
     1481    <ClInclude Include="..\jit\JITBitwiseBinaryOpGenerator.h" />
    14751482    <ClInclude Include="..\jit\JITCode.h" />
    14761483    <ClInclude Include="..\jit\JITCompilationEffort.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r192937 r193471  
    430430      <Filter>jit</Filter>
    431431    </ClCompile>
     432    <ClCompile Include="..\jit\JITBitAndGenerator.cpp">
     433      <Filter>jit</Filter>
     434    </ClCompile>
     435    <ClCompile Include="..\jit\JITBitOrGenerator.cpp">
     436      <Filter>jit</Filter>
     437    </ClCompile>
     438    <ClCompile Include="..\jit\JITBitXorGenerator.cpp">
     439      <Filter>jit</Filter>
     440    </ClCompile>
    432441    <ClCompile Include="..\jit\JITCall.cpp">
    433442      <Filter>jit</Filter>
     
    25272536    </ClInclude>
    25282537    <ClInclude Include="..\jit\JITAddGenerator.h">
     2538      <Filter>jit</Filter>
     2539    </ClInclude>
     2540    <ClInclude Include="..\jit\JITBitAndGenerator.h">
     2541      <Filter>jit</Filter>
     2542    </ClInclude>
     2543    <ClInclude Include="..\jit\JITBitOrGenerator.h">
     2544      <Filter>jit</Filter>
     2545    </ClInclude>
     2546    <ClInclude Include="..\jit\JITBitXorGenerator.h">
     2547      <Filter>jit</Filter>
     2548    </ClInclude>
     2549    <ClInclude Include="..\jit\JITBitwiseBinaryOpGenerator.h">
    25292550      <Filter>jit</Filter>
    25302551    </ClInclude>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r193362 r193471  
    20082008                FE3913551B794F8A00EDAF71 /* LiveObjectData.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3913511B794AC900EDAF71 /* LiveObjectData.h */; settings = {ATTRIBUTES = (Private, ); }; };
    20092009                FE3913561B794F8F00EDAF71 /* LiveObjectList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3913531B794AC900EDAF71 /* LiveObjectList.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2010                FE3A06A61C10B72D00390FDD /* JITBitOrGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06A41C10B70800390FDD /* JITBitOrGenerator.h */; settings = {ASSET_TAGS = (); }; };
     2011                FE3A06A81C10BC8100390FDD /* JITBitwiseBinaryOpGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06A71C10BC7400390FDD /* JITBitwiseBinaryOpGenerator.h */; settings = {ASSET_TAGS = (); }; };
     2012                FE3A06AC1C10C39E00390FDD /* JITBitOrGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06A31C10B70800390FDD /* JITBitOrGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
     2013                FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06AD1C10CB6F00390FDD /* JITBitAndGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
     2014                FE3A06B21C10CB8900390FDD /* JITBitAndGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */; settings = {ASSET_TAGS = (); }; };
     2015                FE3A06B31C10CB8E00390FDD /* JITBitXorGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
     2016                FE3A06B41C10CB9300390FDD /* JITBitXorGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */; settings = {ASSET_TAGS = (); }; };
    20102017                FE4238901BE18C3C00514737 /* JITSubGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */; };
    20112018                FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
     
    41734180                FE3913521B794AC900EDAF71 /* LiveObjectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LiveObjectList.cpp; sourceTree = "<group>"; };
    41744181                FE3913531B794AC900EDAF71 /* LiveObjectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveObjectList.h; sourceTree = "<group>"; };
     4182                FE3A06A31C10B70800390FDD /* JITBitOrGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITBitOrGenerator.cpp; sourceTree = "<group>"; };
     4183                FE3A06A41C10B70800390FDD /* JITBitOrGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITBitOrGenerator.h; sourceTree = "<group>"; };
     4184                FE3A06A71C10BC7400390FDD /* JITBitwiseBinaryOpGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITBitwiseBinaryOpGenerator.h; sourceTree = "<group>"; };
     4185                FE3A06AD1C10CB6F00390FDD /* JITBitAndGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITBitAndGenerator.cpp; sourceTree = "<group>"; };
     4186                FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITBitAndGenerator.h; sourceTree = "<group>"; };
     4187                FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITBitXorGenerator.cpp; sourceTree = "<group>"; };
     4188                FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITBitXorGenerator.h; sourceTree = "<group>"; };
    41754189                FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITSubGenerator.cpp; sourceTree = "<group>"; };
    41764190                FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionOverrides.cpp; sourceTree = "<group>"; };
     
    48434857                                86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */,
    48444858                                A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */,
     4859                                FE3A06AD1C10CB6F00390FDD /* JITBitAndGenerator.cpp */,
     4860                                FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */,
     4861                                FE3A06A31C10B70800390FDD /* JITBitOrGenerator.cpp */,
     4862                                FE3A06A41C10B70800390FDD /* JITBitOrGenerator.h */,
     4863                                FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */,
     4864                                FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */,
     4865                                FE3A06A71C10BC7400390FDD /* JITBitwiseBinaryOpGenerator.h */,
    48454866                                86CC85A20EE79B7400288682 /* JITCall.cpp */,
    48464867                                146FE51111A710430087AE66 /* JITCall32_64.cpp */,
     
    68486869                                99DA00AA1BD5993100F4575C /* builtins_generate_separate_implementation.py in Headers */,
    68496870                                99DA00A31BD5993100F4575C /* builtins_generator.py in Headers */,
     6871                                FE3A06A61C10B72D00390FDD /* JITBitOrGenerator.h in Headers */,
    68506872                                99DA00A41BD5993100F4575C /* builtins_model.py in Headers */,
    68516873                                99DA00A51BD5993100F4575C /* builtins_templates.py in Headers */,
     
    71137135                                0FD8A32A17D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.h in Headers */,
    71147136                                0FD8A32C17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h in Headers */,
     7137                                FE3A06B41C10CB9300390FDD /* JITBitXorGenerator.h in Headers */,
    71157138                                0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */,
    71167139                                0F63943F15C75F19006A597C /* DFGTypeCheckHoistingPhase.h in Headers */,
     
    73667389                                0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
    73677390                                0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
     7391                                FE3A06A81C10BC8100390FDD /* JITBitwiseBinaryOpGenerator.h in Headers */,
    73687392                                0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
    73697393                                0FB14E1F18124ACE009B6B4D /* JITInlineCacheGenerator.h in Headers */,
     
    76547678                                0FB1058E1675483A00F8AB6E /* ProfilerOSRExitSite.h in Headers */,
    76557679                                0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */,
     7680                                FE3A06B21C10CB8900390FDD /* JITBitAndGenerator.h in Headers */,
    76567681                                0FD3E40E1B618B6600C80E1E /* PropertyCondition.h in Headers */,
    76577682                                A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */,
     
    85928617                                0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */,
    85938618                                0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
     8619                                FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */,
    85948620                                0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */,
    85958621                                0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */,
     
    87568782                                A532438718568335002ED692 /* InspectorBackendDispatchers.cpp in Sources */,
    87578783                                A5FD0081189B191A00633231 /* InspectorConsoleAgent.cpp in Sources */,
     8784                                FE3A06B31C10CB8E00390FDD /* JITBitXorGenerator.cpp in Sources */,
    87588785                                A57D23E51890CEBF0031C7FA /* InspectorDebuggerAgent.cpp in Sources */,
    87598786                                A532438918568335002ED692 /* InspectorFrontendDispatchers.cpp in Sources */,
     
    89318958                                FE68C6381B90DE0B0042BCB3 /* MacroAssemblerPrinter.cpp in Sources */,
    89328959                                A7A4AE0817973B26005612B1 /* MacroAssemblerX86Common.cpp in Sources */,
     8960                                FE3A06AC1C10C39E00390FDD /* JITBitOrGenerator.cpp in Sources */,
    89338961                                A700873917CBE85300C3E643 /* MapConstructor.cpp in Sources */,
    89348962                                A74DEF93182D991400522C22 /* MapIteratorPrototype.cpp in Sources */,
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r193424 r193471  
    150150    }
    151151
     152    void moveValueRegs(JSValueRegs srcRegs, JSValueRegs destRegs)
     153    {
     154#if USE(JSVALUE32_64)
     155        move(srcRegs.tagGPR(), destRegs.tagGPR());
     156#endif
     157        move(srcRegs.payloadGPR(), destRegs.payloadGPR());
     158    }
     159
    152160    void moveValue(JSValue value, JSValueRegs regs)
    153161    {
     
    686694#endif
    687695    }
    688    
     696
     697#if USE(JSVALUE64)
     698    Jump branchIfNotInt32(GPRReg gpr, TagRegistersMode mode = HaveTagRegisters)
     699    {
     700        if (mode == HaveTagRegisters)
     701            return branch64(Below, gpr, GPRInfo::tagTypeNumberRegister);
     702        return branch64(Below, gpr, TrustedImm64(TagTypeNumber));
     703    }
     704#endif
     705
    689706    Jump branchIfNotInt32(JSValueRegs regs, TagRegistersMode mode = HaveTagRegisters)
    690707    {
    691708#if USE(JSVALUE64)
    692         if (mode == HaveTagRegisters)
    693             return branch64(Below, regs.gpr(), GPRInfo::tagTypeNumberRegister);
    694         return branch64(Below, regs.gpr(), TrustedImm64(TagTypeNumber));
     709        return branchIfNotInt32(regs.gpr(), mode);
    695710#else
    696711        UNUSED_PARAM(mode);
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r192937 r193471  
    827827#endif
    828828
     829        template<typename SnippetGenerator>
     830        void emitBitwiseBinaryOpFastPath(Instruction* currentInstruction);
     831
    829832        Jump checkStructure(RegisterID reg, Structure* structure);
    830833
  • trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp

    r192842 r193471  
    3131#include "CodeBlock.h"
    3232#include "JITAddGenerator.h"
     33#include "JITBitAndGenerator.h"
     34#include "JITBitOrGenerator.h"
     35#include "JITBitXorGenerator.h"
    3336#include "JITDivGenerator.h"
    3437#include "JITInlines.h"
     
    526529}
    527530
    528 void JIT::emit_op_bitand(Instruction* currentInstruction)
    529 {
    530     int result = currentInstruction[1].u.operand;
    531     int op1 = currentInstruction[2].u.operand;
    532     int op2 = currentInstruction[3].u.operand;
    533 
    534     if (isOperandConstantInt(op1)) {
    535         emitGetVirtualRegister(op2, regT0);
    536         emitJumpSlowCaseIfNotInt(regT0);
    537         int32_t imm = getOperandConstantInt(op1);
    538         and64(Imm32(imm), regT0);
    539         if (imm >= 0)
    540             emitTagInt(regT0, regT0);
    541     } else if (isOperandConstantInt(op2)) {
    542         emitGetVirtualRegister(op1, regT0);
    543         emitJumpSlowCaseIfNotInt(regT0);
    544         int32_t imm = getOperandConstantInt(op2);
    545         and64(Imm32(imm), regT0);
    546         if (imm >= 0)
    547             emitTagInt(regT0, regT0);
    548     } else {
    549         emitGetVirtualRegisters(op1, regT0, op2, regT1);
    550         and64(regT1, regT0);
    551         emitJumpSlowCaseIfNotInt(regT0);
    552     }
    553     emitPutVirtualRegister(result);
    554 }
    555 
    556 void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    557 {
    558     linkSlowCase(iter);
    559 
    560     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitand);
    561     slowPathCall.call();
    562 }
    563 
    564531void JIT::emit_op_inc(Instruction* currentInstruction)
    565532{
     
    664631
    665632#endif // USE(JSVALUE64)
     633
     634template<typename SnippetGenerator>
     635void JIT::emitBitwiseBinaryOpFastPath(Instruction* currentInstruction)
     636{
     637    int result = currentInstruction[1].u.operand;
     638    int op1 = currentInstruction[2].u.operand;
     639    int op2 = currentInstruction[3].u.operand;
     640
     641#if USE(JSVALUE64)
     642    JSValueRegs leftRegs = JSValueRegs(GPRInfo::regT0);
     643    JSValueRegs rightRegs = JSValueRegs(GPRInfo::regT1);
     644    JSValueRegs resultRegs = leftRegs;
     645    GPRReg scratchGPR = GPRInfo::regT2;
     646#else
     647    JSValueRegs leftRegs = JSValueRegs(GPRInfo::regT1, GPRInfo::regT0);
     648    JSValueRegs rightRegs = JSValueRegs(GPRInfo::regT3, GPRInfo::regT2);
     649    JSValueRegs resultRegs = leftRegs;
     650    GPRReg scratchGPR = InvalidGPRReg;
     651#endif
     652
     653    SnippetOperand leftOperand;
     654    SnippetOperand rightOperand;
     655
     656    if (isOperandConstantInt(op1))
     657        leftOperand.setConstInt32(getOperandConstantInt(op1));
     658    if (isOperandConstantInt(op2))
     659        rightOperand.setConstInt32(getOperandConstantInt(op2));
     660
     661    RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
     662
     663    if (!leftOperand.isConst())
     664        emitGetVirtualRegister(op1, leftRegs);
     665    if (!rightOperand.isConst())
     666        emitGetVirtualRegister(op2, rightRegs);
     667
     668    SnippetGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, scratchGPR);
     669
     670    gen.generateFastPath(*this);
     671
     672    if (gen.didEmitFastPath()) {
     673        gen.endJumpList().link(this);
     674#if USE(JSVALUE32_64)
     675        emitStoreInt32(result, resultRegs.payloadGPR(), op1 == result || op2 == result);
     676#else
     677        emitPutVirtualRegister(result, resultRegs);
     678#endif
     679
     680        addSlowCase(gen.slowPathJumpList());
     681    } else {
     682        ASSERT(gen.endJumpList().empty());
     683        ASSERT(gen.slowPathJumpList().empty());
     684        JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add);
     685        slowPathCall.call();
     686    }
     687}
     688
     689void JIT::emit_op_bitand(Instruction* currentInstruction)
     690{
     691    emitBitwiseBinaryOpFastPath<JITBitAndGenerator>(currentInstruction);
     692}
     693
     694void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     695{
     696    linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
     697
     698    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitand);
     699    slowPathCall.call();
     700}
     701
     702void JIT::emit_op_bitor(Instruction* currentInstruction)
     703{
     704    emitBitwiseBinaryOpFastPath<JITBitOrGenerator>(currentInstruction);
     705}
     706
     707void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     708{
     709    linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
     710
     711    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitor);
     712    slowPathCall.call();
     713}
     714
     715void JIT::emit_op_bitxor(Instruction* currentInstruction)
     716{
     717    emitBitwiseBinaryOpFastPath<JITBitXorGenerator>(currentInstruction);
     718}
     719
     720void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     721{
     722    linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
     723
     724    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitxor);
     725    slowPathCall.call();
     726}
    666727
    667728void JIT::emit_op_add(Instruction* currentInstruction)
  • trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp

    r192836 r193471  
    325325}
    326326
    327 // BitAnd (&)
    328 
    329 void JIT::emit_op_bitand(Instruction* currentInstruction)
    330 {
    331     int dst = currentInstruction[1].u.operand;
    332     int op1 = currentInstruction[2].u.operand;
    333     int op2 = currentInstruction[3].u.operand;
    334 
    335     int op;
    336     int32_t constant;
    337     if (getOperandConstantInt(op1, op2, op, constant)) {
    338         emitLoad(op, regT1, regT0);
    339         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    340         and32(Imm32(constant), regT0);
    341         emitStoreInt32(dst, regT0, dst == op);
    342         return;
    343     }
    344 
    345     emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
    346     addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    347     addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    348     and32(regT2, regT0);
    349     emitStoreInt32(dst, regT0, op1 == dst || op2 == dst);
    350 }
    351 
    352 void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    353 {
    354     int op1 = currentInstruction[2].u.operand;
    355     int op2 = currentInstruction[3].u.operand;
    356 
    357     if (!isOperandConstantInt(op1) && !isOperandConstantInt(op2))
    358         linkSlowCase(iter); // int32 check
    359     linkSlowCase(iter); // int32 check
    360 
    361     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitand);
    362     slowPathCall.call();
    363 }
    364 
    365 // BitOr (|)
    366 
    367 void JIT::emit_op_bitor(Instruction* currentInstruction)
    368 {
    369     int dst = currentInstruction[1].u.operand;
    370     int op1 = currentInstruction[2].u.operand;
    371     int op2 = currentInstruction[3].u.operand;
    372 
    373     int op;
    374     int32_t constant;
    375     if (getOperandConstantInt(op1, op2, op, constant)) {
    376         emitLoad(op, regT1, regT0);
    377         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    378         or32(Imm32(constant), regT0);
    379         emitStoreInt32(dst, regT0, op == dst);
    380         return;
    381     }
    382 
    383     emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
    384     addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    385     addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    386     or32(regT2, regT0);
    387     emitStoreInt32(dst, regT0, op1 == dst || op2 == dst);
    388 }
    389 
    390 void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    391 {
    392     int op1 = currentInstruction[2].u.operand;
    393     int op2 = currentInstruction[3].u.operand;
    394 
    395     if (!isOperandConstantInt(op1) && !isOperandConstantInt(op2))
    396         linkSlowCase(iter); // int32 check
    397     linkSlowCase(iter); // int32 check
    398 
    399     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitor);
    400     slowPathCall.call();
    401 }
    402 
    403 // BitXor (^)
    404 
    405 void JIT::emit_op_bitxor(Instruction* currentInstruction)
    406 {
    407     int dst = currentInstruction[1].u.operand;
    408     int op1 = currentInstruction[2].u.operand;
    409     int op2 = currentInstruction[3].u.operand;
    410 
    411     int op;
    412     int32_t constant;
    413     if (getOperandConstantInt(op1, op2, op, constant)) {
    414         emitLoad(op, regT1, regT0);
    415         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    416         xor32(Imm32(constant), regT0);
    417         emitStoreInt32(dst, regT0, op == dst);
    418         return;
    419     }
    420 
    421     emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
    422     addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    423     addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    424     xor32(regT2, regT0);
    425     emitStoreInt32(dst, regT0, op1 == dst || op2 == dst);
    426 }
    427 
    428 void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    429 {
    430     int op1 = currentInstruction[2].u.operand;
    431     int op2 = currentInstruction[3].u.operand;
    432 
    433     if (!isOperandConstantInt(op1) && !isOperandConstantInt(op2))
    434         linkSlowCase(iter); // int32 check
    435     linkSlowCase(iter); // int32 check
    436 
    437     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitxor);
    438     slowPathCall.call();
    439 }
    440 
    441327void JIT::emit_op_inc(Instruction* currentInstruction)
    442328{
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r192937 r193471  
    402402}
    403403
    404 void JIT::emit_op_bitxor(Instruction* currentInstruction)
    405 {
    406     emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
    407     emitJumpSlowCaseIfNotInt(regT0, regT1, regT2);
    408     xor64(regT1, regT0);
    409     emitTagInt(regT0, regT0);
    410     emitPutVirtualRegister(currentInstruction[1].u.operand);
    411 }
    412 
    413 void JIT::emit_op_bitor(Instruction* currentInstruction)
    414 {
    415     emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
    416     emitJumpSlowCaseIfNotInt(regT0, regT1, regT2);
    417     or64(regT1, regT0);
    418     emitPutVirtualRegister(currentInstruction[1].u.operand);
    419 }
    420 
    421404void JIT::emit_op_throw(Instruction* currentInstruction)
    422405{
     
    818801    callOperation(operationConvertJSValueToBoolean, regT0);
    819802    emitJumpSlowToHot(branchTest32(NonZero, returnValueGPR), currentInstruction[2].u.operand);
    820 }
    821 
    822 void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    823 {
    824     linkSlowCase(iter);
    825     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitxor);
    826     slowPathCall.call();
    827 }
    828 
    829 void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    830 {
    831     linkSlowCase(iter);
    832     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_bitor);
    833     slowPathCall.call();
    834803}
    835804
  • trunk/Source/JavaScriptCore/jit/SnippetOperand.h

    r192842 r193471  
    4141
    4242public:
     43    SnippetOperand()
     44        : m_resultType(ResultType::unknownType())
     45    { }
     46
    4347    SnippetOperand(ResultType resultType)
    4448        : m_resultType(resultType)
  • trunk/Source/JavaScriptCore/tests/stress/op_bitand.js

    r192664 r193471  
    4444    '0x10000',
    4545    '-0x10000',
    46     '0x7ffffff',
    47     '-0x7ffffff',
     46    '0x7fffffff',
     47    '-0x7fffffff',
    4848    '0xa5a5a5a5',
    4949    '0x100000000',
     
    5555    '"1"',
    5656    '"-1"',
    57     '"0x7ffffff"',
    58     '"-0x7ffffff"',
     57    '"0x7fffffff"',
     58    '"-0x7fffffff"',
    5959    '"0xa5a5a5a5"',
    6060    '"0x100000000"',
  • trunk/Source/JavaScriptCore/tests/stress/op_bitor.js

    r192664 r193471  
    4444    '0x10000',
    4545    '-0x10000',
    46     '0x7ffffff',
    47     '-0x7ffffff',
     46    '0x7fffffff',
     47    '-0x7fffffff',
    4848    '0xa5a5a5a5',
    4949    '0x100000000',
     
    5555    '"1"',
    5656    '"-1"',
    57     '"0x7ffffff"',
    58     '"-0x7ffffff"',
     57    '"0x7fffffff"',
     58    '"-0x7fffffff"',
    5959    '"0xa5a5a5a5"',
    6060    '"0x100000000"',
  • trunk/Source/JavaScriptCore/tests/stress/op_bitxor.js

    r192664 r193471  
    4444    '0x10000',
    4545    '-0x10000',
    46     '0x7ffffff',
    47     '-0x7ffffff',
     46    '0x7fffffff',
     47    '-0x7fffffff',
    4848    '0xa5a5a5a5',
    4949    '0x100000000',
     
    5555    '"1"',
    5656    '"-1"',
    57     '"0x7ffffff"',
    58     '"-0x7ffffff"',
     57    '"0x7fffffff"',
     58    '"-0x7fffffff"',
    5959    '"0xa5a5a5a5"',
    6060    '"0x100000000"',
Note: See TracChangeset for help on using the changeset viewer.