Changeset 37453 in webkit for trunk/JavaScriptCore/VM/CTI.cpp


Ignore:
Timestamp:
Oct 9, 2008, 4:59:26 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

2008-10-09 Gavin Barraclough <[email protected]>

Reviewed by Cameron Zwarich.

Fix for bug #21160, x=0;1/(x*-1) == -Infinity

  • ChangeLog:
  • VM/CTI.cpp: (JSC::CTI::emitFastArithDeTagImmediate): (JSC::CTI::emitFastArithDeTagImmediateJumpIfZero): (JSC::CTI::compileBinaryArithOp): (JSC::CTI::compileBinaryArithOpSlowCase): (JSC::CTI::privateCompileMainPass): (JSC::CTI::privateCompileSlowCases):
  • VM/CTI.h:
  • masm/X86Assembler.h: (JSC::X86Assembler::): (JSC::X86Assembler::emitUnlinkedJs):

LayoutTests:

2008-10-09 Gavin Barraclough <[email protected]>

Reviewed by Cameron Zwarich.

Correct results for -0 cases.

  • fast/js/math-transforms-expected.txt:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/CTI.cpp

    r37438 r37453  
    415415ALWAYS_INLINE void CTI::emitFastArithDeTagImmediate(X86Assembler::RegisterID reg)
    416416{
    417     // op_mod relies on this being a sub - setting zf if result is 0.
    418417    m_jit.subl_i8r(JSImmediate::TagBitTypeInteger, reg);
     418}
     419
     420ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitFastArithDeTagImmediateJumpIfZero(X86Assembler::RegisterID reg)
     421{
     422    m_jit.subl_i8r(JSImmediate::TagBitTypeInteger, reg);
     423    return m_jit.emitUnlinkedJe();
    419424}
    420425
     
    809814    } else {
    810815        ASSERT(opcodeID == op_mul);
    811         emitFastArithDeTagImmediate(X86::eax);
     816        // convert eax & edx from JSImmediates to ints, and check if either are zero
    812817        emitFastArithImmToInt(X86::edx);
     818        X86Assembler::JmpSrc op1Zero = emitFastArithDeTagImmediateJumpIfZero(X86::eax);
     819        m_jit.testl_rr(X86::edx, X86::edx);
     820        X86Assembler::JmpSrc op2NonZero = m_jit.emitUnlinkedJne();
     821        m_jit.link(op1Zero, m_jit.label());
     822        // if either input is zero, add the two together, and check if the result is < 0.
     823        // If it is, we have a problem (N < 0), (N * 0) == -0, not representatble as a JSImmediate.
     824        m_jit.movl_rr(X86::eax, X86::ecx);
     825        m_jit.addl_rr(X86::edx, X86::ecx);
     826        m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJs(), i));
     827        // Skip the above check if neither input is zero
     828        m_jit.link(op2NonZero, m_jit.label());
    813829        m_jit.imull_rr(X86::edx, X86::eax);
    814830        m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
     
    852868        m_jit.link((++iter)->from, here);
    853869    } else
     870        m_jit.link((++iter)->from, here);
     871
     872    // additional entry point to handle -0 cases.
     873    if (opcodeID == op_mul)
    854874        m_jit.link((++iter)->from, here);
    855875
     
    11401160            unsigned src2 = instruction[i + 3].u.operand;
    11411161
    1142             if (JSValue* src1Value = getConstantImmediateNumericArg(src1)) {
     1162            // For now, only plant a fast int case if the constant operand is greater than zero.
     1163            JSValue* src1Value = getConstantImmediateNumericArg(src1);
     1164            JSValue* src2Value = getConstantImmediateNumericArg(src2);
     1165            int32_t value;
     1166            if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) {
    11431167                emitGetArg(src2, X86::eax);
    11441168                emitJumpSlowCaseIfNotImmNum(X86::eax, i);
    1145                 emitFastArithImmToInt(X86::eax);
    1146                 m_jit.imull_i32r(X86::eax, getDeTaggedConstantImmediate(src1Value), X86::eax);
     1169                emitFastArithDeTagImmediate(X86::eax);
     1170                m_jit.imull_i32r(X86::eax, value, X86::eax);
    11471171                m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
    11481172                emitFastArithReTagImmediate(X86::eax);
    11491173                emitPutResult(dst);
    1150             } else if (JSValue* src2Value = getConstantImmediateNumericArg(src2)) {
     1174            } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) {
    11511175                emitGetArg(src1, X86::eax);
    11521176                emitJumpSlowCaseIfNotImmNum(X86::eax, i);
    1153                 emitFastArithImmToInt(X86::eax);
    1154                 m_jit.imull_i32r(X86::eax, getDeTaggedConstantImmediate(src2Value), X86::eax);
     1177                emitFastArithDeTagImmediate(X86::eax);
     1178                m_jit.imull_i32r(X86::eax, value, X86::eax);
    11551179                m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
    11561180                emitFastArithReTagImmediate(X86::eax);
     
    16281652            emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
    16291653            emitFastArithDeTagImmediate(X86::eax);
    1630             emitFastArithDeTagImmediate(X86::ecx);
    1631             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i)); // This is checking if the last detag resulted in a value 0.
     1654            m_slowCases.append(SlowCaseEntry(emitFastArithDeTagImmediateJumpIfZero(X86::ecx), i));
    16321655            m_jit.cdq();
    16331656            m_jit.idivl_r(X86::ecx);
     
    25102533            int src1 = instruction[i + 2].u.operand;
    25112534            int src2 = instruction[i + 3].u.operand;
    2512             if (getConstantImmediateNumericArg(src1) || getConstantImmediateNumericArg(src2)) {
     2535            JSValue* src1Value = getConstantImmediateNumericArg(src1);
     2536            JSValue* src2Value = getConstantImmediateNumericArg(src2);
     2537            int32_t value;
     2538            if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) {
    25132539                m_jit.link(iter->from, m_jit.label());
     2540                // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
     2541                emitGetPutArg(src1, 0, X86::ecx);
     2542                emitGetPutArg(src2, 4, X86::ecx);
     2543                emitCall(i, Machine::cti_op_mul);
     2544                emitPutResult(dst);
     2545            } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) {
     2546                m_jit.link(iter->from, m_jit.label());
     2547                // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
    25142548                emitGetPutArg(src1, 0, X86::ecx);
    25152549                emitGetPutArg(src2, 4, X86::ecx);
Note: See TracChangeset for help on using the changeset viewer.