Changeset 39738 in webkit for trunk/JavaScriptCore/jit/JIT.cpp


Ignore:
Timestamp:
Jan 9, 2009, 12:11:00 AM (16 years ago)
Author:
[email protected]
Message:

2009-01-08 Gavin Barraclough <[email protected]>

Reviewed by Oliver Hunt.

Encode immediates in the low word of JSValuePtrs, on x86-64.

On 32-bit platforms a JSValuePtr may represent a 31-bit signed integer.
On 64-bit platforms, if USE(ALTERNATE_JSIMMEDIATE) is defined, a full
32-bit integer may be stored in an immediate.


Presently USE(ALTERNATE_JSIMMEDIATE) uses the same encoding as the default
immediate format - the value is left shifted by one, so a one bit tag can
be added to indicate the value is an immediate. However this means that
values must be commonly be detagged (by right shifting by one) before
arithmetic operations can be performed on immediates. This patch modifies
the formattting so the the high bits of the immediate mark values as being
integer.

  • assembler/MacroAssembler.h: (JSC::MacroAssembler::not32): (JSC::MacroAssembler::orPtr): (JSC::MacroAssembler::zeroExtend32ToPtr): (JSC::MacroAssembler::jaePtr): (JSC::MacroAssembler::jbPtr): (JSC::MacroAssembler::jnzPtr): (JSC::MacroAssembler::jzPtr):
  • assembler/X86Assembler.h: (JSC::X86Assembler::): (JSC::X86Assembler::notl_r): (JSC::X86Assembler::testq_i32r):
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases): (JSC::JIT::privateCompileCTIMachineTrampolines):
  • jit/JIT.h:
  • jit/JITArithmetic.cpp: (JSC::JIT::compileFastArith_op_lshift): (JSC::JIT::compileFastArith_op_rshift): (JSC::JIT::compileFastArith_op_bitand): (JSC::JIT::compileFastArithSlow_op_bitand): (JSC::JIT::compileFastArith_op_mod): (JSC::JIT::compileFastArithSlow_op_mod): (JSC::JIT::compileFastArith_op_add): (JSC::JIT::compileFastArith_op_mul): (JSC::JIT::compileFastArith_op_post_inc): (JSC::JIT::compileFastArith_op_post_dec): (JSC::JIT::compileFastArith_op_pre_inc): (JSC::JIT::compileFastArith_op_pre_dec): (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate): (JSC::JIT::compileBinaryArithOp):
  • jit/JITCall.cpp: (JSC::JIT::compileOpCallSlowCase):
  • jit/JITInlineMethods.h: (JSC::JIT::emitJumpIfJSCell): (JSC::JIT::emitJumpIfNotJSCell): (JSC::JIT::emitJumpIfImmNum): (JSC::JIT::emitJumpSlowCaseIfNotImmNum): (JSC::JIT::emitJumpSlowCaseIfNotImmNums): (JSC::JIT::emitFastArithDeTagImmediate): (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero): (JSC::JIT::emitFastArithReTagImmediate): (JSC::JIT::emitFastArithImmToInt): (JSC::JIT::emitFastArithIntToImmNoCheck): (JSC::JIT::emitTagAsBoolImmediate):
  • jit/JITPropertyAccess.cpp: (JSC::resizePropertyStorage): (JSC::JIT::privateCompilePutByIdTransition): (JSC::JIT::privateCompilePatchGetArrayLength): (JSC::JIT::privateCompileGetByIdSelf): (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdChain): (JSC::JIT::privateCompilePutByIdReplace):
  • runtime/JSImmediate.h: (JSC::JSImmediate::isNumber): (JSC::JSImmediate::isPositiveNumber): (JSC::JSImmediate::areBothImmediateNumbers): (JSC::JSImmediate::xorImmediateNumbers): (JSC::JSImmediate::rightShiftImmediateNumbers): (JSC::JSImmediate::canDoFastAdditiveOperations): (JSC::JSImmediate::addImmediateNumbers): (JSC::JSImmediate::subImmediateNumbers): (JSC::JSImmediate::makeInt): (JSC::JSImmediate::toBoolean):
  • wtf/Platform.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JIT.cpp

    r39737 r39738  
    349349                emitGetVirtualRegister(op1, X86::eax);
    350350                emitJumpSlowCaseIfNotImmNum(X86::eax);
    351                 addJump(jlPtr(X86::eax, ImmPtr(JSValuePtr::encode(getConstantOperand(op2)))), target + 3);
     351#if USE(ALTERNATE_JSIMMEDIATE)
     352                int32_t op2imm = JSImmediate::intValue(getConstantOperand(op2));
     353#else
     354                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
     355#endif
     356                addJump(jl32(X86::eax, Imm32(op2imm)), target + 3);
    352357            } else {
    353358                emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
    354359                emitJumpSlowCaseIfNotImmNum(X86::eax);
    355360                emitJumpSlowCaseIfNotImmNum(X86::edx);
    356                 addJump(jlPtr(X86::eax, X86::edx), target + 3);
     361                addJump(jl32(X86::eax, X86::edx), target + 3);
    357362            }
    358363            NEXT_OPCODE(op_loop_if_less);
     
    367372                emitGetVirtualRegister(op1, X86::eax);
    368373                emitJumpSlowCaseIfNotImmNum(X86::eax);
    369                 addJump(jlePtr(X86::eax, ImmPtr(JSValuePtr::encode(getConstantOperand(op2)))), target + 3);
     374#if USE(ALTERNATE_JSIMMEDIATE)
     375                int32_t op2imm = JSImmediate::intValue(getConstantOperand(op2));
     376#else
     377                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
     378#endif
     379                addJump(jle32(X86::eax, Imm32(op2imm)), target + 3);
    370380            } else {
    371381                emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
    372382                emitJumpSlowCaseIfNotImmNum(X86::eax);
    373383                emitJumpSlowCaseIfNotImmNum(X86::edx);
    374                 addJump(jlePtr(X86::eax, X86::edx), target + 3);
     384                addJump(jle32(X86::eax, X86::edx), target + 3);
    375385            }
    376386            NEXT_OPCODE(op_loop_if_less);
     
    396406            // check if any are immediates
    397407            move(X86::eax, X86::ebx);
    398             or32(X86::ecx, X86::ebx);
    399             or32(X86::edx, X86::ebx);
     408            orPtr(X86::ecx, X86::ebx);
     409            orPtr(X86::edx, X86::ebx);
    400410            emitJumpSlowCaseIfNotJSCell(X86::ebx);
    401411
     
    564574            emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
    565575            emitJumpSlowCaseIfNotImmNum(X86::edx);
     576#if USE(ALTERNATE_JSIMMEDIATE)
     577            // This is technically incorrect - we're zero-extending an int32.  On the hot path this doesn't matter.
     578            // We check the value as if it was a uint32 against the m_fastAccessCutoff - which will always fail if
     579            // number was signed since m_fastAccessCutoff is always less than intmax (since the total allocation
     580            // size is always less than 4Gb).  As such zero extending wil have been correct (and extending the value
     581            // to 64-bits is necessary since it's used in the address calculation.  We zero extend rather than sign
     582            // extending since it makes it easier to re-tag the value in the slow case.
     583            zeroExtend32ToPtr(X86::edx, X86::edx);
     584#else
    566585            emitFastArithImmToInt(X86::edx);
     586#endif
    567587            emitJumpSlowCaseIfNotJSCell(X86::eax);
    568588            addSlowCase(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
     
    592612            emitGetVirtualRegisters(currentInstruction[1].u.operand, X86::eax, currentInstruction[2].u.operand, X86::edx);
    593613            emitJumpSlowCaseIfNotImmNum(X86::edx);
     614#if USE(ALTERNATE_JSIMMEDIATE)
     615            // See comment in op_get_by_val.
     616            zeroExtend32ToPtr(X86::edx, X86::edx);
     617#else
    594618            emitFastArithImmToInt(X86::edx);
     619#endif
    595620            emitJumpSlowCaseIfNotJSCell(X86::eax);
    596621            addSlowCase(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
     
    620645
    621646            Jump isZero = jePtr(X86::eax, ImmPtr(JSValuePtr::encode(JSImmediate::zeroImmediate())));
    622             addJump(jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger)), target + 2);
     647            addJump(emitJumpIfImmNum(X86::eax), target + 2);
    623648
    624649            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
     
    692717                emitGetVirtualRegister(op1, X86::eax);
    693718                emitJumpSlowCaseIfNotImmNum(X86::eax);
    694                 addJump(jgePtr(X86::eax, ImmPtr(JSValuePtr::encode(getConstantOperand(op2)))), target + 3);
     719#if USE(ALTERNATE_JSIMMEDIATE)
     720                int32_t op2imm = JSImmediate::intValue(getConstantOperand(op2));
     721#else
     722                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
     723#endif
     724                addJump(jge32(X86::eax, Imm32(op2imm)), target + 3);
    695725            } else {
    696726                emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
    697727                emitJumpSlowCaseIfNotImmNum(X86::eax);
    698728                emitJumpSlowCaseIfNotImmNum(X86::edx);
    699                 addJump(jgePtr(X86::eax, X86::edx), target + 3);
     729                addJump(jge32(X86::eax, X86::edx), target + 3);
    700730            }
    701731            NEXT_OPCODE(op_jnless);
     
    703733        case op_not: {
    704734            emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
    705             xorPtr(Imm32(JSImmediate::FullTagTypeBool), X86::eax);
    706             addSlowCase(jnz32(X86::eax, Imm32(JSImmediate::FullTagTypeMask)));
    707             xorPtr(Imm32(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue), X86::eax);
     735            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
     736            addSlowCase(jnzPtr(X86::eax, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
     737            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), X86::eax);
    708738            emitPutVirtualRegister(currentInstruction[1].u.operand);
    709739            NEXT_OPCODE(op_not);
     
    714744
    715745            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(JSImmediate::zeroImmediate()))), target + 2);
    716             Jump isNonZero = jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger));
     746            Jump isNonZero = emitJumpIfImmNum(X86::eax);
    717747
    718748            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))), target + 2);
     
    807837            emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
    808838            emitJumpSlowCaseIfNotImmNum(X86::eax);
    809             xorPtr(Imm32(~JSImmediate::TagBitTypeInteger), X86::eax);
     839#if USE(ALTERNATE_JSIMMEDIATE)
     840            not32(X86::eax);
     841            emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     842#else
     843            xorPtr(Imm32(~JSImmediate::TagTypeInteger), X86::eax);
     844#endif
    810845            emitPutVirtualRegister(currentInstruction[1].u.operand);
    811846            NEXT_OPCODE(op_bitnot);
     
    835870
    836871            Jump isZero = jePtr(X86::eax, ImmPtr(JSValuePtr::encode(JSImmediate::zeroImmediate())));
    837             addJump(jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger)), target + 2);
     872            addJump(emitJumpIfImmNum(X86::eax), target + 2);
    838873
    839874            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
     
    863898            emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, X86::ecx);
    864899            xorPtr(X86::edx, X86::eax);
    865             emitFastArithReTagImmediate(X86::eax);
     900            emitFastArithReTagImmediate(X86::eax, X86::eax);
    866901            emitPutVirtualRegister(currentInstruction[1].u.operand);
    867902            NEXT_OPCODE(op_bitxor);
     
    946981            emitGetVirtualRegister(srcVReg, X86::eax);
    947982           
    948             Jump wasImmediate = jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger));
     983            Jump wasImmediate = emitJumpIfImmNum(X86::eax);
    949984
    950985            emitJumpSlowCaseIfNotJSCell(X86::eax, srcVReg);
     
    12541289            linkSlowCase(iter);
    12551290            linkSlowCase(iter);
    1256             emitFastArithIntToImmNoCheck(X86::edx);
     1291            emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
    12571292            notImm.link(this);
    12581293            emitPutJITStubArg(X86::eax, 1);
     
    13431378            linkSlowCase(iter);
    13441379            linkSlowCase(iter);
    1345             emitFastArithIntToImmNoCheck(X86::edx);
     1380            emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
    13461381            notImm.link(this);
    13471382            emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
     
    13961431        case op_not: {
    13971432            linkSlowCase(iter);
    1398             xorPtr(Imm32(JSImmediate::FullTagTypeBool), X86::eax);
     1433            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
    13991434            emitPutJITStubArg(X86::eax, 1);
    14001435            emitCTICall(Interpreter::cti_op_not);
     
    16901725    Jump array_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt));
    16911726
    1692     // X86::eax contains a 64 bit value (is signed, is zero extended) so we don't need sign extend here.
    1693     emitFastArithIntToImmNoCheck(X86::eax);
     1727    // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
     1728    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
    16941729
    16951730    ret();
     
    17081743    Jump string_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt));
    17091744
    1710     // X86::eax contains a 64 bit value (is signed, is zero extended) so we don't need sign extend here.
    1711     emitFastArithIntToImmNoCheck(X86::eax);
     1745    // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
     1746    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
    17121747   
    17131748    ret();
Note: See TracChangeset for help on using the changeset viewer.