Changeset 191905 in webkit


Ignore:
Timestamp:
Nov 2, 2015 1:10:36 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

Snippefy op_add for the baseline JIT.
https://bugs.webkit.org/show_bug.cgi?id=150129

Reviewed by Geoffrey Garen and Saam Barati.

Performance is neutral for both 32-bit and 64-bit on X86_64.

(JSC::JIT::getOperandConstantInt):

  • Move getOperandConstantInt() from the JSVALUE64 section to the common section because the snippet needs it.
  • jit/JITAddGenerator.cpp: Added.

(JSC::JITAddGenerator::generateFastPath):

  • jit/JITAddGenerator.h: Added.

(JSC::JITAddGenerator::JITAddGenerator):
(JSC::JITAddGenerator::endJumpList):
(JSC::JITAddGenerator::slowPathJumpList):

  • JITAddGenerator implements an optimization for the case where 1 of the 2 operands is a constant int32_t. It does not implement an optimization for the case where both operands are constant int32_t. This is because:
    1. For the baseline JIT, the ASTBuilder will fold the 2 constants together.
    2. For the DFG, the AbstractInterpreter will also fold the 2 constants.

Hence, such an optimization path (for 2 constant int32_t operands) would never
be taken, and is why we won't implement it.

  • jit/JITArithmetic.cpp:

(JSC::JIT::compileBinaryArithOp):
(JSC::JIT::compileBinaryArithOpSlowCase):

  • Removed op_add cases. These are no longer used by the op_add emitters.

(JSC::JIT::emit_op_add):
(JSC::JIT::emitSlow_op_add):

  • Moved out from the JSVALUE64 section to the common section, and reimplemented using the snippet.
  • jit/JITArithmetic32_64.cpp:

(JSC::JIT::emitBinaryDoubleOp):
(JSC::JIT::emit_op_add): Deleted.
(JSC::JIT::emitAdd32Constant): Deleted.
(JSC::JIT::emitSlow_op_add): Deleted.

  • Remove 32-bit specific version of op_add. The snippet serves both 32-bit and 64-bit implementations.
  • jit/JITInlines.h:

(JSC::JIT::getOperandConstantInt):

  • Move getOperandConstantInt() from the JSVALUE64 section to the common section because the snippet needs it.
Location:
trunk/Source/JavaScriptCore
Files:
2 added
9 edited

Legend:

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

    r191889 r191905  
    431431    jit/IntrinsicEmitter.cpp
    432432    jit/JIT.cpp
     433    jit/JITAddGenerator.cpp
    433434    jit/JITArithmetic.cpp
    434435    jit/JITArithmetic32_64.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r191901 r191905  
     12015-11-02  Mark Lam  <mark.lam@apple.com>
     2
     3        Snippefy op_add for the baseline JIT.
     4        https://bugs.webkit.org/show_bug.cgi?id=150129
     5
     6        Reviewed by Geoffrey Garen and Saam Barati.
     7
     8        Performance is neutral for both 32-bit and 64-bit on X86_64.
     9
     10        * CMakeLists.txt:
     11        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     12        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     13        * JavaScriptCore.xcodeproj/project.pbxproj:
     14        * jit/JIT.h:
     15        (JSC::JIT::getOperandConstantInt):
     16        - Move getOperandConstantInt() from the JSVALUE64 section to the common section
     17          because the snippet needs it.
     18
     19        * jit/JITAddGenerator.cpp: Added.
     20        (JSC::JITAddGenerator::generateFastPath):
     21        * jit/JITAddGenerator.h: Added.
     22        (JSC::JITAddGenerator::JITAddGenerator):
     23        (JSC::JITAddGenerator::endJumpList):
     24        (JSC::JITAddGenerator::slowPathJumpList):
     25        - JITAddGenerator implements an optimization for the case where 1 of the 2 operands
     26          is a constant int32_t.  It does not implement an optimization for the case where
     27          both operands are constant int32_t.  This is because:
     28          1. For the baseline JIT, the ASTBuilder will fold the 2 constants together.
     29          2. For the DFG, the AbstractInterpreter will also fold the 2 constants.
     30
     31          Hence, such an optimization path (for 2 constant int32_t operands) would never
     32          be taken, and is why we won't implement it.
     33
     34        * jit/JITArithmetic.cpp:
     35        (JSC::JIT::compileBinaryArithOp):
     36        (JSC::JIT::compileBinaryArithOpSlowCase):
     37        - Removed op_add cases.  These are no longer used by the op_add emitters.
     38
     39        (JSC::JIT::emit_op_add):
     40        (JSC::JIT::emitSlow_op_add):
     41        - Moved out from the JSVALUE64 section to the common section, and reimplemented
     42          using the snippet.
     43
     44        * jit/JITArithmetic32_64.cpp:
     45        (JSC::JIT::emitBinaryDoubleOp):
     46        (JSC::JIT::emit_op_add): Deleted.
     47        (JSC::JIT::emitAdd32Constant): Deleted.
     48        (JSC::JIT::emitSlow_op_add): Deleted.
     49        - Remove 32-bit specific version of op_add.  The snippet serves both 32-bit
     50          and 64-bit implementations.
     51
     52        * jit/JITInlines.h:
     53        (JSC::JIT::getOperandConstantInt):
     54        - Move getOperandConstantInt() from the JSVALUE64 section to the common section
     55          because the snippet needs it.
     56
    1572015-11-02  Brian Burg  <bburg@apple.com>
    258
     
    35193575        * jit/GCAwareJITStubRoutine.h:
    35203576
    3521 >>>>>>> .r191351
    352235772015-10-20  Tim Horton  <timothy_horton@apple.com>
    35233578
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r191713 r191905  
    639639    <ClCompile Include="..\jit\IntrinsicEmitter.cpp" />
    640640    <ClCompile Include="..\jit\JIT.cpp" />
     641    <ClCompile Include="..\jit\JITAddGenerator.cpp" />
    641642    <ClCompile Include="..\jit\JITArithmetic.cpp" />
    642643    <ClCompile Include="..\jit\JITArithmetic32_64.cpp" />
     
    14561457    <ClInclude Include="..\jit\HostCallReturnValue.h" />
    14571458    <ClInclude Include="..\jit\JIT.h" />
     1459    <ClInclude Include="..\jit\JITAddGenerator.h" />
    14581460    <ClInclude Include="..\jit\JITCode.h" />
    14591461    <ClInclude Include="..\jit\JITCompilationEffort.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r191713 r191905  
    421421      <Filter>jit</Filter>
    422422    </ClCompile>
     423    <ClCompile Include="..\jit\JITAddGenerator.cpp">
     424      <Filter>jit</Filter>
     425    </ClCompile>
    423426    <ClCompile Include="..\jit\JITArithmetic.cpp">
    424427      <Filter>jit</Filter>
     
    24912494    </ClInclude>
    24922495    <ClInclude Include="..\jit\JIT.h">
     2496      <Filter>jit</Filter>
     2497    </ClInclude>
     2498    <ClInclude Include="..\jit\JITAddGenerator.h">
    24932499      <Filter>jit</Filter>
    24942500    </ClInclude>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r191901 r191905  
    19251925                FE0D4A061AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */; };
    19261926                FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */; };
     1927                FE1220271BE7F58C0039E6F2 /* JITAddGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1220261BE7F5640039E6F2 /* JITAddGenerator.h */; settings = {ASSET_TAGS = (); }; };
     1928                FE1220281BE7F5910039E6F2 /* JITAddGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE1220251BE7F5640039E6F2 /* JITAddGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
    19271929                FE1C0FFD1B193E9800B53FCA /* Exception.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1C0FFC1B193E9800B53FCA /* Exception.h */; settings = {ATTRIBUTES = (Private, ); }; };
    19281930                FE1C0FFF1B194FD100B53FCA /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE1C0FFE1B194FD100B53FCA /* Exception.cpp */; };
     
    40174019                FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GlobalContextWithFinalizerTest.cpp; path = API/tests/GlobalContextWithFinalizerTest.cpp; sourceTree = "<group>"; };
    40184020                FE0D4A081ABA2437002F54BF /* GlobalContextWithFinalizerTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GlobalContextWithFinalizerTest.h; path = API/tests/GlobalContextWithFinalizerTest.h; sourceTree = "<group>"; };
     4021                FE1220251BE7F5640039E6F2 /* JITAddGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITAddGenerator.cpp; sourceTree = "<group>"; };
     4022                FE1220261BE7F5640039E6F2 /* JITAddGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITAddGenerator.h; sourceTree = "<group>"; };
    40194023                FE1C0FFC1B193E9800B53FCA /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Exception.h; sourceTree = "<group>"; };
    40204024                FE1C0FFE1B194FD100B53FCA /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Exception.cpp; sourceTree = "<group>"; };
     
    46524656                                1429D92D0ED22D7000B89619 /* JIT.cpp */,
    46534657                                1429D92E0ED22D7000B89619 /* JIT.h */,
     4658                                FE1220251BE7F5640039E6F2 /* JITAddGenerator.cpp */,
     4659                                FE1220261BE7F5640039E6F2 /* JITAddGenerator.h */,
    46544660                                86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */,
    46554661                                A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */,
     
    72437249                                14874AE615EBDE4A002E3587 /* JSScope.h in Headers */,
    72447250                                A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */,
     7251                                FE1220271BE7F58C0039E6F2 /* JITAddGenerator.h in Headers */,
    72457252                                0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
    72467253                                A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
     
    82978304                                0F898F311B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.cpp in Sources */,
    82988305                                0FC97F3D18202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp in Sources */,
     8306                                FE1220281BE7F5910039E6F2 /* JITAddGenerator.cpp in Sources */,
    82998307                                0FEA0A33170D40BF00BB722C /* DFGJITCode.cpp in Sources */,
    83008308                                86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */,
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r191897 r191905  
    404404        void emitPutVirtualRegister(int dst, JSValueRegs src);
    405405
     406        int32_t getOperandConstantInt(int src);
     407
    406408#if USE(JSVALUE32_64)
    407409        bool getOperandConstantInt(int op1, int op2, int& op, int32_t& constant);
     
    428430
    429431        // Arithmetic opcode helpers
    430         void emitAdd32Constant(int dst, int op, int32_t constant, ResultType opType);
    431432        void emitSub32Constant(int dst, int op, int32_t constant, ResultType opType);
    432433        void emitBinaryDoubleOp(OpcodeID, int dst, int op1, int op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true);
     
    447448            emitPutVirtualRegister(dst, payload);
    448449        }
    449 
    450         int32_t getOperandConstantInt(int src);
    451450
    452451        Jump emitJumpIfJSCell(RegisterID);
  • trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp

    r191224 r191905  
    3030
    3131#include "CodeBlock.h"
     32#include "JITAddGenerator.h"
    3233#include "JITInlines.h"
    3334#include "JITOperations.h"
     
    667668    emitJumpSlowCaseIfNotInt(regT0);
    668669    emitJumpSlowCaseIfNotInt(regT1);
    669     if (opcodeID == op_add)
    670         addSlowCase(branchAdd32(Overflow, regT1, regT0));
    671     else {
    672         ASSERT(opcodeID == op_mul);
    673         if (shouldEmitProfiling()) {
    674             // We want to be able to measure if this is taking the slow case just
    675             // because of negative zero. If this produces positive zero, then we
    676             // don't want the slow case to be taken because that will throw off
    677             // speculative compilation.
    678             move(regT0, regT2);
    679             addSlowCase(branchMul32(Overflow, regT1, regT2));
    680             JumpList done;
    681             done.append(branchTest32(NonZero, regT2));
    682             Jump negativeZero = branch32(LessThan, regT0, TrustedImm32(0));
    683             done.append(branch32(GreaterThanOrEqual, regT1, TrustedImm32(0)));
    684             negativeZero.link(this);
    685             // We only get here if we have a genuine negative zero. Record this,
    686             // so that the speculative JIT knows that we failed speculation
    687             // because of a negative zero.
    688             add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset)->m_counter));
    689             addSlowCase(jump());
    690             done.link(this);
    691             move(regT2, regT0);
    692         } else {
    693             addSlowCase(branchMul32(Overflow, regT1, regT0));
    694             addSlowCase(branchTest32(Zero, regT0));
    695         }
     670    ASSERT_UNUSED(opcodeID, opcodeID == op_mul);
     671    if (shouldEmitProfiling()) {
     672        // We want to be able to measure if this is taking the slow case just
     673        // because of negative zero. If this produces positive zero, then we
     674        // don't want the slow case to be taken because that will throw off
     675        // speculative compilation.
     676        move(regT0, regT2);
     677        addSlowCase(branchMul32(Overflow, regT1, regT2));
     678        JumpList done;
     679        done.append(branchTest32(NonZero, regT2));
     680        Jump negativeZero = branch32(LessThan, regT0, TrustedImm32(0));
     681        done.append(branch32(GreaterThanOrEqual, regT1, TrustedImm32(0)));
     682        negativeZero.link(this);
     683        // We only get here if we have a genuine negative zero. Record this,
     684        // so that the speculative JIT knows that we failed speculation
     685        // because of a negative zero.
     686        add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset)->m_counter));
     687        addSlowCase(jump());
     688        done.link(this);
     689        move(regT2, regT0);
     690    } else {
     691        addSlowCase(branchMul32(Overflow, regT1, regT0));
     692        addSlowCase(branchTest32(Zero, regT0));
    696693    }
    697694    emitTagInt(regT0, regT0);
     
    720717    Label stubFunctionCall(this);
    721718
    722     JITSlowPathCall slowPathCall(this, currentInstruction, opcodeID == op_add ? slow_path_add : slow_path_mul);
     719    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_mul);
    723720    slowPathCall.call();
    724721    Jump end = jump();
     
    764761    }
    765762
    766     if (opcodeID == op_add)
    767         addDouble(fpRegT2, fpRegT1);
    768     else if (opcodeID == op_mul)
     763    if (opcodeID == op_mul)
    769764        mulDouble(fpRegT2, fpRegT1);
    770765    else {
     
    777772
    778773    end.link(this);
    779 }
    780 
    781 void JIT::emit_op_add(Instruction* currentInstruction)
    782 {
    783     int result = currentInstruction[1].u.operand;
    784     int op1 = currentInstruction[2].u.operand;
    785     int op2 = currentInstruction[3].u.operand;
    786     OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
    787 
    788     if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
    789         JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add);
    790         slowPathCall.call();
    791         return;
    792     }
    793 
    794     if (isOperandConstantInt(op1)) {
    795         emitGetVirtualRegister(op2, regT0);
    796         emitJumpSlowCaseIfNotInt(regT0);
    797         addSlowCase(branchAdd32(Overflow, regT0, Imm32(getOperandConstantInt(op1)), regT1));
    798         emitTagInt(regT1, regT0);
    799     } else if (isOperandConstantInt(op2)) {
    800         emitGetVirtualRegister(op1, regT0);
    801         emitJumpSlowCaseIfNotInt(regT0);
    802         addSlowCase(branchAdd32(Overflow, regT0, Imm32(getOperandConstantInt(op2)), regT1));
    803         emitTagInt(regT1, regT0);
    804     } else
    805         compileBinaryArithOp(op_add, result, op1, op2, types);
    806 
    807     emitPutVirtualRegister(result);
    808 }
    809 
    810 void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    811 {
    812     int result = currentInstruction[1].u.operand;
    813     int op1 = currentInstruction[2].u.operand;
    814     int op2 = currentInstruction[3].u.operand;
    815     OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
    816 
    817     RELEASE_ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber());
    818 
    819     bool op1HasImmediateIntFastCase = isOperandConstantInt(op1);
    820     bool op2HasImmediateIntFastCase = !op1HasImmediateIntFastCase && isOperandConstantInt(op2);
    821     compileBinaryArithOpSlowCase(currentInstruction, op_add, iter, result, op1, op2, types, op1HasImmediateIntFastCase, op2HasImmediateIntFastCase);
    822774}
    823775
     
    960912#endif // USE(JSVALUE64)
    961913
    962 void JIT::emit_op_sub(Instruction* currentInstruction)
     914void JIT::emit_op_add(Instruction* currentInstruction)
    963915{
    964916    int result = currentInstruction[1].u.operand;
     
    984936    emitGetVirtualRegister(op2, rightRegs);
    985937
    986     JITSubGenerator gen(resultRegs, leftRegs, rightRegs, types.first(), types.second(),
     938    bool leftIsConstInt32 = isOperandConstantInt(op1);
     939    bool rightIsConstInt32 = isOperandConstantInt(op2);
     940    JITAddGenerator::OperandsConstness operandsConstness;
     941    int32_t rightConstInt32 = 0;
     942    ResultType leftType = types.first();
     943    ResultType rightType = types.second();
     944
     945    ASSERT(!leftIsConstInt32 || !rightIsConstInt32);
     946
     947    if (leftIsConstInt32) {
     948        // JITAddGenerator expects the const value in the right operand.
     949        // Let's swap the operands.
     950        operandsConstness = JITAddGenerator::RightIsConstInt32;
     951        rightConstInt32 = getOperandConstantInt(op1);
     952        rightType = types.first();
     953        emitGetVirtualRegister(op2, leftRegs);
     954        leftType = types.second();
     955    } else if (rightIsConstInt32) {
     956        operandsConstness = JITAddGenerator::RightIsConstInt32;
     957        rightConstInt32 = getOperandConstantInt(op2);
     958        emitGetVirtualRegister(op1, leftRegs);
     959    } else {
     960        operandsConstness = JITAddGenerator::NeitherAreConstInt32;
     961        emitGetVirtualRegister(op1, leftRegs);
     962        emitGetVirtualRegister(op2, rightRegs);
     963    }
     964
     965    JITAddGenerator gen(resultRegs, leftRegs, rightRegs,
     966        operandsConstness, rightConstInt32,
     967        leftType, rightType,
    987968        fpRegT0, fpRegT1, scratchGPR, scratchFPR);
    988969
     
    994975}
    995976
     977void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     978{
     979    linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
     980
     981    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add);
     982    slowPathCall.call();
     983}
     984
     985void JIT::emit_op_sub(Instruction* currentInstruction)
     986{
     987    int result = currentInstruction[1].u.operand;
     988    int op1 = currentInstruction[2].u.operand;
     989    int op2 = currentInstruction[3].u.operand;
     990    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
     991
     992#if USE(JSVALUE64)
     993    JSValueRegs leftRegs = JSValueRegs(regT0);
     994    JSValueRegs rightRegs = JSValueRegs(regT1);
     995    JSValueRegs resultRegs = leftRegs;
     996    GPRReg scratchGPR = regT2;
     997    FPRReg scratchFPR = InvalidFPRReg;
     998#else
     999    JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
     1000    JSValueRegs rightRegs = JSValueRegs(regT3, regT2);
     1001    JSValueRegs resultRegs = leftRegs;
     1002    GPRReg scratchGPR = regT4;
     1003    FPRReg scratchFPR = fpRegT2;
     1004#endif
     1005
     1006    emitGetVirtualRegister(op1, leftRegs);
     1007    emitGetVirtualRegister(op2, rightRegs);
     1008
     1009    JITSubGenerator gen(resultRegs, leftRegs, rightRegs, types.first(), types.second(),
     1010        fpRegT0, fpRegT1, scratchGPR, scratchFPR);
     1011
     1012    gen.generateFastPath(*this);
     1013    gen.endJumpList().link(this);
     1014    emitPutVirtualRegister(result, resultRegs);
     1015
     1016    addSlowCase(gen.slowPathJumpList());
     1017}
     1018
    9961019void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    9971020{
  • trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp

    r191191 r191905  
    481481// Addition (+)
    482482
    483 void JIT::emit_op_add(Instruction* currentInstruction)
    484 {
    485     int dst = currentInstruction[1].u.operand;
    486     int op1 = currentInstruction[2].u.operand;
    487     int op2 = currentInstruction[3].u.operand;
    488     OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
    489 
    490     if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
    491         JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add);
    492         slowPathCall.call();
    493         return;
    494     }
    495 
    496     JumpList notInt32Op1;
    497     JumpList notInt32Op2;
    498 
    499     int op;
    500     int32_t constant;
    501     if (getOperandConstantInt(op1, op2, op, constant)) {
    502         emitAdd32Constant(dst, op, constant, op == op1 ? types.first() : types.second());
    503         return;
    504     }
    505 
    506     emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
    507     notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    508     notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    509 
    510     // Int32 case.
    511     addSlowCase(branchAdd32(Overflow, regT2, regT0));
    512     emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
    513 
    514     if (!supportsFloatingPoint()) {
    515         addSlowCase(notInt32Op1);
    516         addSlowCase(notInt32Op2);
    517         return;
    518     }
    519     Jump end = jump();
    520 
    521     // Double case.
    522     emitBinaryDoubleOp(op_add, dst, op1, op2, types, notInt32Op1, notInt32Op2);
    523     end.link(this);
    524 }
    525 
    526 void JIT::emitAdd32Constant(int dst, int op, int32_t constant, ResultType opType)
    527 {
    528     // Int32 case.
    529     emitLoad(op, regT1, regT2);
    530     Jump notInt32 = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
    531     addSlowCase(branchAdd32(Overflow, regT2, Imm32(constant), regT0));
    532     emitStoreInt32(dst, regT0, (op == dst));
    533 
    534     // Double case.
    535     if (!supportsFloatingPoint()) {
    536         addSlowCase(notInt32);
    537         return;
    538     }
    539     Jump end = jump();
    540 
    541     notInt32.link(this);
    542     if (!opType.definitelyIsNumber())
    543         addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
    544     move(Imm32(constant), regT2);
    545     convertInt32ToDouble(regT2, fpRegT0);
    546     emitLoadDouble(op, fpRegT1);
    547     addDouble(fpRegT1, fpRegT0);
    548     emitStoreDouble(dst, fpRegT0);
    549 
    550     end.link(this);
    551 }
    552 
    553 void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    554 {
    555     int op1 = currentInstruction[2].u.operand;
    556     int op2 = currentInstruction[3].u.operand;
    557     OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
    558 
    559     RELEASE_ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber());
    560 
    561     int op;
    562     int32_t constant;
    563     if (getOperandConstantInt(op1, op2, op, constant)) {
    564         linkSlowCase(iter); // overflow check
    565 
    566         if (!supportsFloatingPoint())
    567             linkSlowCase(iter); // non-sse case
    568         else {
    569             ResultType opType = op == op1 ? types.first() : types.second();
    570             if (!opType.definitelyIsNumber())
    571                 linkSlowCase(iter); // double check
    572         }
    573     } else {
    574         linkSlowCase(iter); // overflow check
    575 
    576         if (!supportsFloatingPoint()) {
    577             linkSlowCase(iter); // int32 check
    578             linkSlowCase(iter); // int32 check
    579         } else {
    580             if (!types.first().definitelyIsNumber())
    581                 linkSlowCase(iter); // double check
    582 
    583             if (!types.second().definitelyIsNumber()) {
    584                 linkSlowCase(iter); // int32 check
    585                 linkSlowCase(iter); // double check
    586             }
    587         }
    588     }
    589 
    590     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add);
    591     slowPathCall.call();
    592 }
    593 
    594 // Subtraction (-)
    595 
    596483void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, int dst, int op1, int op2, OperandTypes types, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters, bool op2IsInRegisters)
    597484{
     
    629516                emitLoadDouble(op1, fpRegT2);
    630517                mulDouble(fpRegT2, fpRegT0);
    631                 emitStoreDouble(dst, fpRegT0);
    632                 break;
    633             case op_add:
    634                 emitLoadDouble(op1, fpRegT2);
    635                 addDouble(fpRegT2, fpRegT0);
    636518                emitStoreDouble(dst, fpRegT0);
    637519                break;
     
    725607                emitLoadDouble(op2, fpRegT2);
    726608                mulDouble(fpRegT2, fpRegT0);
    727                 emitStoreDouble(dst, fpRegT0);
    728                 break;
    729             case op_add:
    730                 emitLoadDouble(op2, fpRegT2);
    731                 addDouble(fpRegT2, fpRegT0);
    732609                emitStoreDouble(dst, fpRegT0);
    733610                break;
  • trunk/Source/JavaScriptCore/jit/JITInlines.h

    r191840 r191905  
    976976}
    977977
     978ALWAYS_INLINE int32_t JIT::getOperandConstantInt(int src)
     979{
     980    return getConstantOperand(src).asInt32();
     981}
     982
    978983#if USE(JSVALUE32_64)
    979984
     
    11931198}
    11941199
    1195 ALWAYS_INLINE int32_t JIT::getOperandConstantInt(int src)
    1196 {
    1197     return getConstantOperand(src).asInt32();
    1198 }
    1199 
    12001200ALWAYS_INLINE bool JIT::isOperandConstantInt(int src)
    12011201{
Note: See TracChangeset for help on using the changeset viewer.